feat(client): AttributeSystem (Fase 1-3) + ZMMOJobs + UI in-game #3
@@ -110,20 +110,26 @@ void UZMMOStatusWindowWidget::RefreshFromSnapshot(const FZMMOAttributesSnapshot&
|
|||||||
FString::Printf(TEXT("Status Points: %d"), S.StatusPoint)));
|
FString::Printf(TEXT("Status Points: %d"), S.StatusPoint)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derivados — sempre vem prontos do servidor (camadas equip/buff ja somadas).
|
// Derivados — formato RO "STAT base + equip" (ex.: "ATK 51 + 0").
|
||||||
// CritX10 vem internamente x10 (1.0 = 10); divide pra exibicao com 1 casa.
|
// Servidor manda os dois separados; cliente NUNCA recalcula.
|
||||||
if (AtkText) AtkText->SetText(FText::FromString(FString::Printf(TEXT("ATK %d"), S.Atk)));
|
if (AtkText) AtkText->SetText(FText::FromString(FString::Printf(TEXT("ATK %d + %d"), S.AtkBase, S.AtkEquipBonus)));
|
||||||
if (MatkText) MatkText->SetText(FText::FromString(FString::Printf(TEXT("MATK %d"), S.Matk)));
|
if (MatkText) MatkText->SetText(FText::FromString(FString::Printf(TEXT("MATK %d + %d"), S.MatkBase, S.MatkEquipBonus)));
|
||||||
if (DefText) DefText->SetText(FText::FromString(FString::Printf(TEXT("DEF %d"), S.Def)));
|
if (DefText) DefText->SetText(FText::FromString(FString::Printf(TEXT("DEF %d + %d"), S.DefBase, S.DefEquipBonus)));
|
||||||
if (MdefText) MdefText->SetText(FText::FromString(FString::Printf(TEXT("MDEF %d"), S.Mdef)));
|
if (MdefText) MdefText->SetText(FText::FromString(FString::Printf(TEXT("MDEF %d + %d"), S.MdefBase, S.MdefEquipBonus)));
|
||||||
if (HitText) HitText->SetText(FText::FromString(FString::Printf(TEXT("HIT %d"), S.Hit)));
|
if (HitText) HitText->SetText(FText::FromString(FString::Printf(TEXT("HIT %d + %d"), S.HitBase, S.HitEquipBonus)));
|
||||||
if (FleeText) FleeText->SetText(FText::FromString(FString::Printf(TEXT("FLEE %d"), S.Flee)));
|
if (FleeText) FleeText->SetText(FText::FromString(FString::Printf(TEXT("FLEE %d + %d"), S.FleeBase, S.FleeEquipBonus)));
|
||||||
if (CritText)
|
if (CritText)
|
||||||
{
|
{
|
||||||
const int32 CritInt = S.CritX10 / 10;
|
// CRIT vem ×10 em ambas as camadas — soma X10 antes de converter pra
|
||||||
const int32 CritFrac = S.CritX10 % 10;
|
// decimal (10 = 1.0). Display: "CRIT base + equip" com 1 casa cada.
|
||||||
CritText->SetText(FText::FromString(FString::Printf(TEXT("CRIT %d.%d"), CritInt, CritFrac)));
|
const int32 BaseInt = S.CritBaseX10 / 10;
|
||||||
|
const int32 BaseFrac = S.CritBaseX10 % 10;
|
||||||
|
const int32 EquipInt = S.CritEquipBonusX10 / 10;
|
||||||
|
const int32 EquipFrac = S.CritEquipBonusX10 % 10;
|
||||||
|
CritText->SetText(FText::FromString(FString::Printf(
|
||||||
|
TEXT("CRIT %d.%d + %d.%d"), BaseInt, BaseFrac, EquipInt, EquipFrac)));
|
||||||
}
|
}
|
||||||
|
// ASPD nao splita (calculo nao-linear server-side via aspd_base × stats).
|
||||||
if (AspdText) AspdText->SetText(FText::FromString(FString::Printf(TEXT("ASPD %d"), S.Aspd)));
|
if (AspdText) AspdText->SetText(FText::FromString(FString::Printf(TEXT("ASPD %d"), S.Aspd)));
|
||||||
// Habilita botões `+` somente se ha status_point disponível.
|
// Habilita botões `+` somente se ha status_point disponível.
|
||||||
const bool bCanAlloc = S.StatusPoint > 0;
|
const bool bCanAlloc = S.StatusPoint > 0;
|
||||||
|
|||||||
@@ -35,14 +35,21 @@ namespace
|
|||||||
S.Sp = P.Sp;
|
S.Sp = P.Sp;
|
||||||
S.MaxSp = P.MaxSp;
|
S.MaxSp = P.MaxSp;
|
||||||
S.Money = P.Money;
|
S.Money = P.Money;
|
||||||
S.Atk = P.Atk;
|
S.AtkBase = P.AtkBase;
|
||||||
S.Matk = P.Matk;
|
S.AtkEquipBonus = P.AtkEquipBonus;
|
||||||
S.Def = P.Def;
|
S.MatkBase = P.MatkBase;
|
||||||
S.Mdef = P.Mdef;
|
S.MatkEquipBonus = P.MatkEquipBonus;
|
||||||
S.Hit = P.Hit;
|
S.DefBase = P.DefBase;
|
||||||
S.Flee = P.Flee;
|
S.DefEquipBonus = P.DefEquipBonus;
|
||||||
S.CritX10 = P.CritX10;
|
S.MdefBase = P.MdefBase;
|
||||||
S.Aspd = P.Aspd;
|
S.MdefEquipBonus = P.MdefEquipBonus;
|
||||||
|
S.HitBase = P.HitBase;
|
||||||
|
S.HitEquipBonus = P.HitEquipBonus;
|
||||||
|
S.FleeBase = P.FleeBase;
|
||||||
|
S.FleeEquipBonus = P.FleeEquipBonus;
|
||||||
|
S.CritBaseX10 = P.CritBaseX10;
|
||||||
|
S.CritEquipBonusX10 = P.CritEquipBonusX10;
|
||||||
|
S.Aspd = P.Aspd;
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,14 +50,31 @@ struct ZMMOATTRIBUTES_API FZMMOAttributesSnapshot
|
|||||||
// === Moeda ===
|
// === Moeda ===
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") int64 Money = 0;
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") int64 Money = 0;
|
||||||
|
|
||||||
// === Derivados (efetivos; servidor sempre recalcula) ===
|
// === Derivados split em pares (base, equipBonus) ===
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Atk = 0;
|
// Padrao RO: display mostra "ATK 51 + 0" (base + equip). Cliente NUNCA
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Matk = 0;
|
// recalcula — servidor envia ambos prontos no S_ATTRIBUTE_SNAPSHOT_FULL.
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Def = 0;
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 AtkBase = 0;
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Mdef = 0;
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 AtkEquipBonus = 0;
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Hit = 0;
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Flee = 0;
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 MatkBase = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 MatkEquipBonus = 0;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 DefBase = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 DefEquipBonus = 0;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 MdefBase = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 MdefEquipBonus = 0;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 HitBase = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 HitEquipBonus = 0;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 FleeBase = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 FleeEquipBonus = 0;
|
||||||
|
|
||||||
/** Critico × 10 internamente (10 = 1.0). Divida por 10 para exibir. */
|
/** Critico × 10 internamente (10 = 1.0). Divida por 10 para exibir. */
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 CritX10 = 0;
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 CritBaseX10 = 0;
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 CritEquipBonusX10 = 0;
|
||||||
|
|
||||||
|
/** ASPD nao splita — calculo nao-linear via aspd_base × stats. Display direto. */
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Aspd = 0;
|
UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes|Derived") int32 Aspd = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user