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

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"),
};