feat(jobs): Jobs.1 client — DA expandido + 7 DA_Job assets organizados por tier

* UZMMOJobDataAsset (Source/ZMMOJobs/Public/) ganha 3 campos novos
  espelhando o JobDef do server:
    - Tier             (EZMMOJobTier)
    - ParentClassId    (int32)
    - AllowedWeapons   (TArray<EZMMOWeaponType>)

* Novo header ZMMOJobTypes.h com 2 UENUM(BlueprintType):
    - EZMMOJobTier      (6 valores: Beginner..Mastery)
    - EZMMOWeaponType   (19 valores: Fist..Gun)
  Todos com UMETA(DisplayName="pt-BR") pro Editor mostrar nomes
  amigaveis em dropdowns. Ordem casa byte-a-byte com EJobTier/
  EWeaponType do server (necessario pq snapshot carrega tier u8 + mask).

* 7 DA_Job_*.uasset criados via MCP Python, organizados por tier:
    Content/ZMMO/Data/Jobs/Beginner/
      DA_Job_Novice    (ClassId=0, AllowedWeapons=[Fist,Dagger])
    Content/ZMMO/Data/Jobs/Vocation/
      DA_Job_Warrior   (ClassId=1, 8 armas: Sword+Spear+Axe variations)
      DA_Job_Arcanist  (ClassId=2, 5 armas: Staff+Book)
      DA_Job_Ranger    (ClassId=3, 5 armas: Bow+Musical+Whip)
      DA_Job_Artisan   (ClassId=4, 5 armas: Sword1H+Mace1H+Axe1H)
      DA_Job_Rogue     (ClassId=5, 5 armas: Sword1H+Bow+Katar)
      DA_Job_Devout    (ClassId=6, 5 armas: Mace+Staff1H+Knuckle)
  ParentClassId=0 (Novice) em todas Vocacoes. Tier=Vocation.
  JobIcon/Sound/Anim ficam None — preencher conforme arte for produzida.

  ZMMOJobsSubsystem busca por classe (GetAssetsByClass), entao a
  reorganizacao em subpastas NAO requer mudanca em .cpp/.h.

* ZMMOAttributeTypes.h: comentario de opcode 1200 -> 1500 (espelha
  refactor Open-Closed do server ranges; valores wire format mudaram).

Boot esperado: [ZMMOJobsSubsystem] Initialize: 7 job(s) carregados.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 23:53:34 -03:00
parent a354d9eefc
commit c3df705a7a
11 changed files with 77 additions and 2 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -5,7 +5,7 @@
/**
* Snapshot completo dos atributos do char vindo do server via
* S_ATTRIBUTE_SNAPSHOT_FULL (opcode 1200).
* S_ATTRIBUTE_SNAPSHOT_FULL (opcode 1500).
*
* Cliente NUNCA recalcula derivados — apenas exibe o que recebe. Os campos
* HP/MaxHp/SP/MaxSp ja sao os "efetivos" (base + equip + buff somados no

View File

@@ -2,6 +2,7 @@
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "ZMMOJobTypes.h"
#include "ZMMOJobDataAsset.generated.h"
class UTexture2D;
@@ -39,11 +40,28 @@ public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
FString TechnicalName;
/// Nome localizado exibido na UI (pt-BR no projeto base). Ex: "Aprendiz".
/// Nome localizado exibido na UI (pt-BR no projeto base). Ex: "Novato".
/// Pode usar FText Localization tables pra multi-idioma futuro.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
FText DisplayName;
/// Tier hierarquico — espelha `JobDef::tier` do server. UI usa pra agrupar
/// jobs (ex: lista de Vocacoes possiveis quando promovendo Novato).
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
EZMMOJobTier Tier = EZMMOJobTier::Beginner;
/// ClassId do parent na arvore de promocao. 0 = sem parent (Novato eh root).
/// Espelha `JobDef::parentJobId` do server. UI usa pra filtrar destinos
/// possiveis ao mostrar painel de promocao.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
int32 ParentClassId = 0;
/// Lista de armas que o job pode equipar. Espelha `JobDef::allowedWeaponsMask`
/// do server (mas como TArray pra editor visual em vez de bitmask cru).
/// Inventory UI usa pra hint "nao pode equipar" + filtro de catalogo.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job")
TArray<EZMMOWeaponType> AllowedWeapons;
/// Icone do job — usado em StatusWindow, CharacterCard, JobChangeUI.
/// Soft ptr: nao carrega ate alguem chamar LoadSynchronous() ou async load.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Zeus|Job|Assets")

View File

@@ -0,0 +1,57 @@
#pragma once
#include "CoreMinimal.h"
#include "ZMMOJobTypes.generated.h"
/**
* Tier hierarquico de um job. Espelha `EJobTier` do server em
* `Server/.../JobsSystem/Public/JobTypes.hpp`. Valores TEM que bater
* byte-a-byte com a enum do server porque o snapshot pode carregar
* tier como uint8 no futuro.
*
* Renascer (RO pre-renewal): char no Tier 2 (Specialization) que cumpre
* condicao volta pra Tier 3 (RebornBeginner) com bonus permanente,
* abrindo path paralelo RebornVocation → Mastery (coroa final).
*/
UENUM(BlueprintType)
enum class EZMMOJobTier : uint8
{
Beginner = 0 UMETA(DisplayName = "Iniciante"),
Vocation = 1 UMETA(DisplayName = "Vocacao"),
Specialization = 2 UMETA(DisplayName = "Especializacao"),
RebornBeginner = 3 UMETA(DisplayName = "Iniciante Renascido"),
RebornVocation = 4 UMETA(DisplayName = "Vocacao Renascida"),
Mastery = 5 UMETA(DisplayName = "Mestria"),
};
/**
* Tipos de arma. Espelha `EWeaponType` do server. Usado em `AllowedWeapons`
* do DA pra UI (filtrar items equipaveis) + validacao server-side futura
* quando InventorySystem entrar.
*
* Ordem TEM que bater com server porque o bitmask `allowedWeaponsMask` no
* JobDef usa bit N = EWeaponType(N).
*/
UENUM(BlueprintType)
enum class EZMMOWeaponType : uint8
{
Fist = 0 UMETA(DisplayName = "Punho"),
Dagger = 1 UMETA(DisplayName = "Adaga"),
Sword1H = 2 UMETA(DisplayName = "Espada 1M"),
Sword2H = 3 UMETA(DisplayName = "Espada 2M"),
Spear1H = 4 UMETA(DisplayName = "Lanca 1M"),
Spear2H = 5 UMETA(DisplayName = "Lanca 2M"),
Axe1H = 6 UMETA(DisplayName = "Machado 1M"),
Axe2H = 7 UMETA(DisplayName = "Machado 2M"),
Mace1H = 8 UMETA(DisplayName = "Maca 1M"),
Mace2H = 9 UMETA(DisplayName = "Maca 2M"),
Staff1H = 10 UMETA(DisplayName = "Cajado 1M"),
Staff2H = 11 UMETA(DisplayName = "Cajado 2M"),
Bow = 12 UMETA(DisplayName = "Arco"),
Knuckle = 13 UMETA(DisplayName = "Soqueira"),
Musical = 14 UMETA(DisplayName = "Instrumento Musical"),
Whip = 15 UMETA(DisplayName = "Chicote"),
Book = 16 UMETA(DisplayName = "Livro"),
Katar = 17 UMETA(DisplayName = "Katar"),
Gun = 18 UMETA(DisplayName = "Arma de Fogo"),
};