feat(ui): sistema de UI Style (tokens C++ por tema) + fontes Aurora Arcana
Camada de estilo data-driven do cliente ZMMO, portando o nucleo do projeto de referencia (Hyper) para C++ conforme ARQUITETURA.md (BP Struct proibido): - Source/ZMMO/Data/UI: UIStyleTypes.h (enums EUI*), UIStyleTokens.h (tokens primitive/semantic/component), UIStyleRow.h (FUIStyle + FUIStyleRow). - ZMMOThemeSubsystem: GetActiveUIStyle() resolve DT_UI_Styles por ThemeId com fallback Default. - Fontes: 8 UFontFace Inline (Cinzel/Rajdhani) em Content/ZMMO/UI/Fonts + DT_UI_Styles preenchido. - ARQUITETURA.md: prefixo de widget UI_, classes base UUI*_Base (UCLASS Abstract) sem prefixo ZMMO. - Config/DefaultGame.ini: UIStyleTable apontando DT_UI_Styles. - Scripts/import_fonts.py (importador idempotente). Inclui tambem o scaffolding do modulo ZMMO ainda nao versionado (Source/ZMMO/Data, Game/UI, Content/ZMMO, uproject, Build.cs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
84
Source/ZMMO/Data/Abilities/AbilityRow.h
Normal file
84
Source/ZMMO/Data/Abilities/AbilityRow.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "AbilityRow.generated.h"
|
||||
|
||||
class UTexture2D;
|
||||
class UAnimMontage;
|
||||
class UNiagaraSystem;
|
||||
class USoundBase;
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EAbilityCategory : uint8
|
||||
{
|
||||
Combat UMETA(DisplayName = "Combat"),
|
||||
Buff UMETA(DisplayName = "Buff"),
|
||||
Heal UMETA(DisplayName = "Heal"),
|
||||
Movement UMETA(DisplayName = "Movement"),
|
||||
Passive UMETA(DisplayName = "Passive")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EAbilityTarget : uint8
|
||||
{
|
||||
Self UMETA(DisplayName = "Self"),
|
||||
Single UMETA(DisplayName = "Single Target"),
|
||||
Area UMETA(DisplayName = "Area"),
|
||||
Cone UMETA(DisplayName = "Cone"),
|
||||
Line UMETA(DisplayName = "Line")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FAbilityRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Ability")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Ability", meta = (MultiLine = true))
|
||||
FText Description;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Ability")
|
||||
EAbilityCategory Category = EAbilityCategory::Combat;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Targeting")
|
||||
EAbilityTarget TargetMode = EAbilityTarget::Single;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Targeting")
|
||||
float Range = 500.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Targeting", meta = (EditCondition = "TargetMode == EAbilityTarget::Area || TargetMode == EAbilityTarget::Cone"))
|
||||
float Radius = 200.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cost")
|
||||
int32 ManaCost = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cost")
|
||||
int32 StaminaCost = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Timing")
|
||||
float CastTime = 0.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Timing")
|
||||
float Cooldown = 1.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Effect")
|
||||
int32 BaseDamage = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Effect")
|
||||
FName StatusEffectRow;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UTexture2D> Icon;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UAnimMontage> CastMontage;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UNiagaraSystem> CastVFX;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Audio")
|
||||
TSoftObjectPtr<USoundBase> CastSound;
|
||||
};
|
||||
51
Source/ZMMO/Data/Abilities/StatusEffectRow.h
Normal file
51
Source/ZMMO/Data/Abilities/StatusEffectRow.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "StatusEffectRow.generated.h"
|
||||
|
||||
class UTexture2D;
|
||||
class UNiagaraSystem;
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EStatusEffectKind : uint8
|
||||
{
|
||||
Buff UMETA(DisplayName = "Buff"),
|
||||
Debuff UMETA(DisplayName = "Debuff"),
|
||||
DoT UMETA(DisplayName = "Damage Over Time"),
|
||||
HoT UMETA(DisplayName = "Heal Over Time"),
|
||||
Crowd UMETA(DisplayName = "Crowd Control")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FStatusEffectRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status", meta = (MultiLine = true))
|
||||
FText Description;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status")
|
||||
EStatusEffectKind Kind = EStatusEffectKind::Buff;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status")
|
||||
float Duration = 5.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status")
|
||||
float TickInterval = 1.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status")
|
||||
int32 TickValue = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Status")
|
||||
int32 MaxStacks = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UTexture2D> Icon;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UNiagaraSystem> AttachedVFX;
|
||||
};
|
||||
46
Source/ZMMO/Data/Items/ItemRow.h
Normal file
46
Source/ZMMO/Data/Items/ItemRow.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "Items/ItemTypes.h"
|
||||
#include "ItemRow.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UStaticMesh;
|
||||
class UTexture2D;
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FItemRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item", meta = (MultiLine = true))
|
||||
FText Description;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
|
||||
EItemType Type = EItemType::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
|
||||
EItemRarity Rarity = EItemRarity::Common;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Equipment", meta = (EditCondition = "Type == EItemType::Weapon || Type == EItemType::Armor || Type == EItemType::Accessory"))
|
||||
EEquipSlot EquipSlot = EEquipSlot::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
|
||||
int32 MaxStack = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
|
||||
int32 BasePrice = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UTexture2D> Icon;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals")
|
||||
TSoftObjectPtr<UStaticMesh> WorldMesh;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Behavior")
|
||||
TSoftClassPtr<AActor> BehaviorClass;
|
||||
};
|
||||
45
Source/ZMMO/Data/Items/ItemTypes.h
Normal file
45
Source/ZMMO/Data/Items/ItemTypes.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "ItemTypes.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EItemType : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Weapon UMETA(DisplayName = "Weapon"),
|
||||
Armor UMETA(DisplayName = "Armor"),
|
||||
Accessory UMETA(DisplayName = "Accessory"),
|
||||
Consumable UMETA(DisplayName = "Consumable"),
|
||||
Material UMETA(DisplayName = "Material"),
|
||||
Quest UMETA(DisplayName = "Quest"),
|
||||
Currency UMETA(DisplayName = "Currency")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EItemRarity : uint8
|
||||
{
|
||||
Common UMETA(DisplayName = "Common"),
|
||||
Uncommon UMETA(DisplayName = "Uncommon"),
|
||||
Rare UMETA(DisplayName = "Rare"),
|
||||
Epic UMETA(DisplayName = "Epic"),
|
||||
Legendary UMETA(DisplayName = "Legendary"),
|
||||
Mythic UMETA(DisplayName = "Mythic")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EEquipSlot : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Head UMETA(DisplayName = "Head"),
|
||||
Chest UMETA(DisplayName = "Chest"),
|
||||
Legs UMETA(DisplayName = "Legs"),
|
||||
Hands UMETA(DisplayName = "Hands"),
|
||||
Feet UMETA(DisplayName = "Feet"),
|
||||
MainHand UMETA(DisplayName = "Main Hand"),
|
||||
OffHand UMETA(DisplayName = "Off Hand"),
|
||||
TwoHand UMETA(DisplayName = "Two Hand"),
|
||||
Ring UMETA(DisplayName = "Ring"),
|
||||
Necklace UMETA(DisplayName = "Necklace"),
|
||||
Cape UMETA(DisplayName = "Cape")
|
||||
};
|
||||
48
Source/ZMMO/Data/Mobs/MobRow.h
Normal file
48
Source/ZMMO/Data/Mobs/MobRow.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "Mobs/MobTypes.h"
|
||||
#include "Players/StatBlock.h"
|
||||
#include "MobRow.generated.h"
|
||||
|
||||
class APawn;
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FMobRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Mob")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Mob")
|
||||
TSoftClassPtr<APawn> BlueprintRef;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Mob")
|
||||
EMobFamily Family = EMobFamily::Beast;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Mob")
|
||||
EMobFaction Faction = EMobFaction::Hostile;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Mob")
|
||||
EMobBehavior Behavior = EMobBehavior::Aggressive;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Mob")
|
||||
int32 Level = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stats")
|
||||
FStatBlock Stats;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Combat")
|
||||
float AggroRadius = 800.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Combat")
|
||||
float LeashRadius = 2000.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Rewards")
|
||||
int32 ExperienceReward = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Rewards")
|
||||
FName DropTableRow;
|
||||
};
|
||||
35
Source/ZMMO/Data/Mobs/MobTypes.h
Normal file
35
Source/ZMMO/Data/Mobs/MobTypes.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MobTypes.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EMobFaction : uint8
|
||||
{
|
||||
Neutral UMETA(DisplayName = "Neutral"),
|
||||
Hostile UMETA(DisplayName = "Hostile"),
|
||||
Friendly UMETA(DisplayName = "Friendly"),
|
||||
Boss UMETA(DisplayName = "Boss")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EMobBehavior : uint8
|
||||
{
|
||||
Passive UMETA(DisplayName = "Passive"),
|
||||
Defensive UMETA(DisplayName = "Defensive"),
|
||||
Aggressive UMETA(DisplayName = "Aggressive"),
|
||||
Patrol UMETA(DisplayName = "Patrol"),
|
||||
Stationary UMETA(DisplayName = "Stationary")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EMobFamily : uint8
|
||||
{
|
||||
Beast UMETA(DisplayName = "Beast"),
|
||||
Undead UMETA(DisplayName = "Undead"),
|
||||
Humanoid UMETA(DisplayName = "Humanoid"),
|
||||
Dragon UMETA(DisplayName = "Dragon"),
|
||||
Elemental UMETA(DisplayName = "Elemental"),
|
||||
Demon UMETA(DisplayName = "Demon"),
|
||||
Construct UMETA(DisplayName = "Construct")
|
||||
};
|
||||
32
Source/ZMMO/Data/NPCs/DialogRow.h
Normal file
32
Source/ZMMO/Data/NPCs/DialogRow.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "DialogRow.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FDialogChoice
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dialog")
|
||||
FText Text;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dialog")
|
||||
FName NextNode;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dialog")
|
||||
FName RequiredQuestState;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FDialogRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dialog", meta = (MultiLine = true))
|
||||
FText SpeakerLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dialog")
|
||||
TArray<FDialogChoice> Choices;
|
||||
};
|
||||
40
Source/ZMMO/Data/NPCs/NPCRow.h
Normal file
40
Source/ZMMO/Data/NPCs/NPCRow.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "NPCRow.generated.h"
|
||||
|
||||
class APawn;
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ENPCRole : uint8
|
||||
{
|
||||
Generic UMETA(DisplayName = "Generic"),
|
||||
Vendor UMETA(DisplayName = "Vendor"),
|
||||
Questgiver UMETA(DisplayName = "Questgiver"),
|
||||
Trainer UMETA(DisplayName = "Trainer"),
|
||||
Banker UMETA(DisplayName = "Banker"),
|
||||
Innkeeper UMETA(DisplayName = "Innkeeper"),
|
||||
Guard UMETA(DisplayName = "Guard")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FNPCRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "NPC")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "NPC")
|
||||
TSoftClassPtr<APawn> BlueprintRef;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "NPC")
|
||||
ENPCRole Role = ENPCRole::Generic;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Shop", meta = (EditCondition = "Role == ENPCRole::Vendor"))
|
||||
TArray<FName> ShopInventory;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dialog")
|
||||
FName DialogRoot;
|
||||
};
|
||||
29
Source/ZMMO/Data/Players/ClassRow.h
Normal file
29
Source/ZMMO/Data/Players/ClassRow.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "Players/StatBlock.h"
|
||||
#include "ClassRow.generated.h"
|
||||
|
||||
class APawn;
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FClassRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Class")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Class")
|
||||
TSoftClassPtr<APawn> BlueprintRef;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stats")
|
||||
FStatBlock BaseStats;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stats")
|
||||
FStatBlock LevelUpStats;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Class")
|
||||
TArray<FName> StartingAbilities;
|
||||
};
|
||||
31
Source/ZMMO/Data/Players/StatBlock.h
Normal file
31
Source/ZMMO/Data/Players/StatBlock.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "StatBlock.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FStatBlock
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
int32 Health = 100;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
int32 Mana = 50;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
int32 Stamina = 100;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
int32 Attack = 10;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
int32 Defense = 5;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
float MoveSpeed = 600.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
|
||||
float AttackSpeed = 1.0f;
|
||||
};
|
||||
77
Source/ZMMO/Data/Quests/QuestRow.h
Normal file
77
Source/ZMMO/Data/Quests/QuestRow.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "QuestRow.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EQuestKind : uint8
|
||||
{
|
||||
Main UMETA(DisplayName = "Main"),
|
||||
Side UMETA(DisplayName = "Side"),
|
||||
Daily UMETA(DisplayName = "Daily"),
|
||||
Repeatable UMETA(DisplayName = "Repeatable"),
|
||||
Event UMETA(DisplayName = "Event")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EQuestObjectiveType : uint8
|
||||
{
|
||||
Kill UMETA(DisplayName = "Kill"),
|
||||
Collect UMETA(DisplayName = "Collect"),
|
||||
Talk UMETA(DisplayName = "Talk"),
|
||||
Reach UMETA(DisplayName = "Reach Location"),
|
||||
Use UMETA(DisplayName = "Use Item"),
|
||||
Escort UMETA(DisplayName = "Escort")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FQuestObjective
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Objective")
|
||||
EQuestObjectiveType Type = EQuestObjectiveType::Kill;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Objective")
|
||||
FName TargetId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Objective")
|
||||
int32 Required = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Objective")
|
||||
FText Description;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FQuestRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest", meta = (MultiLine = true))
|
||||
FText Description;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
EQuestKind Kind = EQuestKind::Side;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
int32 LevelRequirement = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
FName GiverNPC;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
FName TurnInNPC;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
TArray<FQuestObjective> Objectives;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
FName RewardRow;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
|
||||
TArray<FName> Prerequisites;
|
||||
};
|
||||
29
Source/ZMMO/Data/UI/ThemeCalendarRow.h
Normal file
29
Source/ZMMO/Data/UI/ThemeCalendarRow.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "ThemeCalendarRow.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FThemeCalendarRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Calendar")
|
||||
FName ThemeId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Calendar", meta = (ClampMin = "1", ClampMax = "12"))
|
||||
int32 StartMonth = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Calendar", meta = (ClampMin = "1", ClampMax = "31"))
|
||||
int32 StartDay = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Calendar", meta = (ClampMin = "1", ClampMax = "12"))
|
||||
int32 EndMonth = 12;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Calendar", meta = (ClampMin = "1", ClampMax = "31"))
|
||||
int32 EndDay = 31;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Calendar", meta = (ToolTip = "Higher priority wins when ranges overlap."))
|
||||
int32 Priority = 0;
|
||||
};
|
||||
29
Source/ZMMO/Data/UI/ThemeKeys.h
Normal file
29
Source/ZMMO/Data/UI/ThemeKeys.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "ThemeKeys.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EZMMOThemeKey : uint8
|
||||
{
|
||||
// HUD
|
||||
HUD_Frame UMETA(DisplayName = "HUD - Frame"),
|
||||
HUD_HotbarBackground UMETA(DisplayName = "HUD - Hotbar Background"),
|
||||
HUD_HealthBar UMETA(DisplayName = "HUD - Health Bar"),
|
||||
HUD_ManaBar UMETA(DisplayName = "HUD - Mana Bar"),
|
||||
|
||||
// Login / Character Select
|
||||
Login_Background UMETA(DisplayName = "Login - Background"),
|
||||
Login_Logo UMETA(DisplayName = "Login - Logo"),
|
||||
Login_Music UMETA(DisplayName = "Login - Music"),
|
||||
Login_AmbientVFX UMETA(DisplayName = "Login - Ambient VFX"),
|
||||
CharSelect_Background UMETA(DisplayName = "Character Select - Background"),
|
||||
|
||||
// Inventory
|
||||
Inventory_SlotEmpty UMETA(DisplayName = "Inventory - Empty Slot"),
|
||||
Inventory_Background UMETA(DisplayName = "Inventory - Background"),
|
||||
|
||||
// Generic
|
||||
MainMenu_Music UMETA(DisplayName = "Main Menu Music"),
|
||||
LoadingScreen UMETA(DisplayName = "Loading Screen")
|
||||
};
|
||||
41
Source/ZMMO/Data/UI/ThemeRow.h
Normal file
41
Source/ZMMO/Data/UI/ThemeRow.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "UObject/SoftObjectPtr.h"
|
||||
#include "ThemeRow.generated.h"
|
||||
|
||||
class UObject;
|
||||
class UTexture2D;
|
||||
class USoundBase;
|
||||
class UNiagaraSystem;
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FThemeEntry
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
TSoftObjectPtr<UTexture2D> Texture;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
TSoftObjectPtr<USoundBase> Sound;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
TSoftObjectPtr<UNiagaraSystem> VFX;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
TSoftObjectPtr<UObject> Generic;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FThemeRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
FName ThemeId;
|
||||
};
|
||||
70
Source/ZMMO/Data/UI/UIStyleRow.h
Normal file
70
Source/ZMMO/Data/UI/UIStyleRow.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "UIStyleTypes.h"
|
||||
#include "UIStyleTokens.h"
|
||||
#include "UIStyleRow.generated.h"
|
||||
|
||||
/**
|
||||
* Struct raiz que agrega todos os tokens de estilo de um tema.
|
||||
*
|
||||
* Adicionar membros aqui (fase 2/3) é mudança aditiva e segura para a
|
||||
* DataTable existente — mas, ao alterar este struct em produção, fazer
|
||||
* backup de DT_UI_Styles (UHT invalida rows serializadas se a coluna não
|
||||
* preservar valores). Ver ARQUITETURA.md / docs Epic sobre DataTable.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyle
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStylePalette Palette;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyleSemantic Semantic;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyleText Text;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyleButton Button;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStylePanel Panel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyleBorders Borders;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyleProgressBar ProgressBar;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyleTooltip Tooltip;
|
||||
};
|
||||
|
||||
/**
|
||||
* Linha de DT_UI_Styles. O Row Name é o ThemeId (ex.: "Default", "RPG"),
|
||||
* espelhando DT_ThemeCalendar e ThemeRegistry — assim a camada de estilo
|
||||
* é consumidora do ThemeId já resolvido pelo UZMMOThemeSubsystem.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FText DisplayName;
|
||||
|
||||
/** Validação tipada de design-time; runtime resolve por ThemeId/Row Name. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
EUITheme Theme = EUITheme::None;
|
||||
|
||||
/** Ponte para o ThemeId resolvido pelo UZMMOThemeSubsystem. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FName ThemeId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style")
|
||||
FUIStyle Style;
|
||||
};
|
||||
364
Source/ZMMO/Data/UI/UIStyleTokens.h
Normal file
364
Source/ZMMO/Data/UI/UIStyleTokens.h
Normal file
@@ -0,0 +1,364 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Fonts/SlateFontInfo.h"
|
||||
#include "Layout/Margin.h"
|
||||
#include "UIStyleTypes.h"
|
||||
#include "UIStyleTokens.generated.h"
|
||||
|
||||
/**
|
||||
* Tokens de estilo da UI organizados em 3 camadas (design tokens):
|
||||
*
|
||||
* 1. Primitive (FUIStylePalette) — paleta crua "Aurora Arcana".
|
||||
* Espelha Tools/Templates/Zeus_Widget/shared/styles.css (:root).
|
||||
* 2. Semantic (FUIStyleSemantic) — papéis (Accent, Surface, OnSurface...)
|
||||
* que referenciam a primitive. Trocar de tema mexe sobretudo aqui.
|
||||
* 3. Component (FUIStyle*) — por componente, consome a camada semantic.
|
||||
*
|
||||
* Defaults faithful ao tema padrão; tudo é sobrescrito por linha em
|
||||
* DT_UI_Styles (FUIStyleRow). Cores em FColor(R,G,B[,A]) sRGB convertidas
|
||||
* implicitamente para FLinearColor.
|
||||
*/
|
||||
|
||||
// =====================================================================
|
||||
// 1. Primitive — paleta Aurora Arcana
|
||||
// =====================================================================
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStylePalette
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Bg0 = FLinearColor(FColor(7, 10, 18)); // --bg-0 #070A12
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Bg1 = FLinearColor(FColor(11, 16, 32)); // --bg-1 #0B1020
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Panel = FLinearColor(FColor(12, 18, 34, 235)); // --panel rgba(..,.92)
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Panel2 = FLinearColor(FColor(17, 24, 42)); // --panel-2 #11182A
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Panel3 = FLinearColor(FColor(14, 20, 36)); // --panel-3 #0E1424
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Border = FLinearColor(FColor(58, 75, 120)); // --border #3A4B78
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor BorderSoft = FLinearColor(FColor(58, 75, 120, 140)); // --border-soft
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Gold = FLinearColor(FColor(201, 167, 90)); // --gold #C9A75A
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor GoldHi = FLinearColor(FColor(231, 200, 115)); // --gold-hi #E7C873
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Blue = FLinearColor(FColor(78, 163, 255)); // --blue #4EA3FF
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Violet = FLinearColor(FColor(123, 92, 255)); // --violet #7B5CFF
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Text = FLinearColor(FColor(244, 240, 230)); // --text #F4F0E6
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Text2 = FLinearColor(FColor(174, 182, 200)); // --text-2 #AEB6C8
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor TextDim = FLinearColor(FColor(105, 115, 138)); // --text-dim #69738A
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Danger = FLinearColor(FColor(217, 92, 92)); // --danger #D95C5C
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Online = FLinearColor(FColor(80, 216, 144)); // --online #50D890
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Palette")
|
||||
FLinearColor Warn = FLinearColor(FColor(230, 180, 80)); // --warn #E6B450
|
||||
};
|
||||
|
||||
// =====================================================================
|
||||
// 2. Semantic — papéis (referenciam a primitive)
|
||||
// =====================================================================
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleSemantic
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Accent = FLinearColor(FColor(201, 167, 90)); // Gold
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor AccentHover = FLinearColor(FColor(231, 200, 115)); // GoldHi
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Focus = FLinearColor(FColor(78, 163, 255)); // Blue
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Glow = FLinearColor(FColor(123, 92, 255)); // Violet
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor SurfaceBase = FLinearColor(FColor(7, 10, 18)); // Bg0
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Surface = FLinearColor(FColor(12, 18, 34, 235)); // Panel
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor SurfaceRaised = FLinearColor(FColor(17, 24, 42)); // Panel2
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor SurfaceSunken = FLinearColor(FColor(14, 20, 36)); // Panel3
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor OutlineStrong = FLinearColor(FColor(58, 75, 120)); // Border
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor OutlineSoft = FLinearColor(FColor(58, 75, 120, 140)); // BorderSoft
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor OnSurface = FLinearColor(FColor(244, 240, 230)); // Text
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor OnSurfaceMuted = FLinearColor(FColor(174, 182, 200)); // Text2
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor OnSurfaceDim = FLinearColor(FColor(105, 115, 138)); // TextDim
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Danger = FLinearColor(FColor(217, 92, 92)); // Danger
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Success = FLinearColor(FColor(80, 216, 144)); // Online
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Semantic")
|
||||
FLinearColor Warning = FLinearColor(FColor(230, 180, 80)); // Warn
|
||||
};
|
||||
|
||||
// =====================================================================
|
||||
// 3. Component
|
||||
// =====================================================================
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleText
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
FSlateFontInfo TitleFont; // Cinzel ExtraBold (display)
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
FSlateFontInfo SectionFont; // Cinzel Bold (section title)
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
FSlateFontInfo BodyFont; // Rajdhani Regular
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
FSlateFontInfo ButtonFont; // Rajdhani Bold
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
FSlateFontInfo LabelFont; // Rajdhani Bold (label/caps)
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
bool bLabelUppercase = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Text")
|
||||
float TitleLetterSpacing = 0.f; // informativo (RichText/futuro)
|
||||
};
|
||||
|
||||
/** Cores de uma variante de botão (primary/secondary/danger/ghost). */
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleButtonVariant
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor BgNormal = FLinearColor::Transparent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor BgHover = FLinearColor::Transparent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor BgPressed = FLinearColor::Transparent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor BgDisabled = FLinearColor(0.f, 0.f, 0.f, 0.42f);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor BorderNormal = FLinearColor::Transparent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor BorderHover = FLinearColor::Transparent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FLinearColor TextColor = FLinearColor::White;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleButton
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// .btn-primary — dourado, texto quase preto
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FUIStyleButtonVariant Primary;
|
||||
|
||||
// .btn-secondary — painel sólido + borda
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FUIStyleButtonVariant Secondary;
|
||||
|
||||
// .btn-danger
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FUIStyleButtonVariant Danger;
|
||||
|
||||
// .btn-ghost — transparente + borda suave
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FUIStyleButtonVariant Ghost;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
FMargin Padding = FMargin(22.f, 12.f);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
float MinHeight = 48.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
float CornerRadius = 8.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
float BorderWidth = 1.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
float HoverScale = 1.02f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
float PressedScale = 0.98f;
|
||||
|
||||
/** Tamanho por silhueta (Square/Rectangle/Topbar/Header). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||
TMap<EUIButtonShape, FVector2D> ShapeSizes;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStylePanel
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor Bg = FLinearColor(FColor(12, 18, 34, 235)); // Panel
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor BgRaised = FLinearColor(FColor(17, 24, 42)); // Panel2
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor BgSunken = FLinearColor(FColor(14, 20, 36)); // Panel3
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor BorderColor = FLinearColor(FColor(58, 75, 120));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor BorderSoftColor = FLinearColor(FColor(58, 75, 120, 140));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
float CornerRadius = 12.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
float CornerRadiusSmall = 10.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
float BorderWidth = 1.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FMargin Padding = FMargin(30.f);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FMargin PaddingSmall = FMargin(20.f);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor CardSelectedBorder = FLinearColor(FColor(201, 167, 90)); // Accent
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
||||
FLinearColor CardSelectedBg = FLinearColor(FColor(24, 32, 58));
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleBorders
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
FLinearColor Color = FLinearColor(FColor(58, 75, 120));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
FLinearColor SoftColor = FLinearColor(FColor(58, 75, 120, 140));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
float Width = 1.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
float Radius = 12.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
float RadiusSmall = 8.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
FLinearColor RuleColor = FLinearColor(FColor(201, 167, 90, 166)); // Gold ~.65
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
float RuleThickness = 2.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Borders")
|
||||
float RuleSoftThickness = 1.f;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleProgressBar
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
FLinearColor TrackColor = FLinearColor(FColor(14, 20, 36)); // Panel3
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
FLinearColor BorderColor = FLinearColor(FColor(58, 75, 120, 140));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
float Height = 10.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
float CornerRadius = 6.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
float BorderWidth = 1.f;
|
||||
|
||||
/** Cor de preenchimento por tipo (Health/Mana/XP...). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
TMap<EUIProgressBarType, FLinearColor> FillByType;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleTooltip
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
FLinearColor Bg = FLinearColor(FColor(17, 24, 42)); // Panel2
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
FLinearColor BorderColor = FLinearColor(FColor(58, 75, 120));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
float CornerRadius = 10.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
float BorderWidth = 1.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
FMargin Padding = FMargin(18.f, 14.f);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
FSlateFontInfo Font;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Tooltip")
|
||||
FLinearColor TextColor = FLinearColor(FColor(244, 240, 230)); // Text
|
||||
};
|
||||
74
Source/ZMMO/Data/UI/UIStyleTypes.h
Normal file
74
Source/ZMMO/Data/UI/UIStyleTypes.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UIStyleTypes.generated.h"
|
||||
|
||||
/**
|
||||
* Enums do sistema de UI Style (tokens de tema visual).
|
||||
*
|
||||
* Espelha ThemeKeys.h: enums fortes, BlueprintType, primeiro valor None.
|
||||
* O conceito de "tema ativo" continua sendo do UZMMOThemeSubsystem
|
||||
* (resolvido por FName ThemeId). EUITheme é apenas validação tipada de
|
||||
* design-time ao preencher DT_UI_Styles — não é a chave de runtime.
|
||||
*/
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EUITheme : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
MMORPG UMETA(DisplayName = "MMORPG"),
|
||||
Survival UMETA(DisplayName = "Survival"),
|
||||
RPG UMETA(DisplayName = "RPG")
|
||||
};
|
||||
|
||||
/** Forma/silhueta de um botão — usada pelo widget para escolher dimensões. */
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIButtonShape : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Square UMETA(DisplayName = "Square"),
|
||||
Rectangle UMETA(DisplayName = "Rectangle"),
|
||||
Topbar UMETA(DisplayName = "Topbar"),
|
||||
HeaderButton UMETA(DisplayName = "Header Button")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIPanelType : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Primary UMETA(DisplayName = "Primary"),
|
||||
Secondary UMETA(DisplayName = "Secondary"),
|
||||
Tertiary UMETA(DisplayName = "Tertiary"),
|
||||
Card UMETA(DisplayName = "Card")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIProgressBarType : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Health UMETA(DisplayName = "Health"),
|
||||
Mana UMETA(DisplayName = "Mana"),
|
||||
Experience UMETA(DisplayName = "Experience"),
|
||||
Cast UMETA(DisplayName = "Cast"),
|
||||
Generic UMETA(DisplayName = "Generic")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIHeaderType : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Section UMETA(DisplayName = "Section"),
|
||||
Panel UMETA(DisplayName = "Panel"),
|
||||
SubPanel UMETA(DisplayName = "Sub Panel")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIIconType : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Inventory UMETA(DisplayName = "Inventory"),
|
||||
Equipment UMETA(DisplayName = "Equipment"),
|
||||
Skill UMETA(DisplayName = "Skill"),
|
||||
Status UMETA(DisplayName = "Status"),
|
||||
Currency UMETA(DisplayName = "Currency")
|
||||
};
|
||||
45
Source/ZMMO/Data/World/ZoneRow.h
Normal file
45
Source/ZMMO/Data/World/ZoneRow.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "Engine/World.h"
|
||||
#include "ZoneRow.generated.h"
|
||||
|
||||
class USoundBase;
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EZoneRules : uint8
|
||||
{
|
||||
Safe UMETA(DisplayName = "Safe"),
|
||||
PvE UMETA(DisplayName = "PvE"),
|
||||
PvP UMETA(DisplayName = "PvP"),
|
||||
Dungeon UMETA(DisplayName = "Dungeon"),
|
||||
Instance UMETA(DisplayName = "Instance")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FZoneRow : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
TSoftObjectPtr<UWorld> Map;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
EZoneRules Rules = EZoneRules::PvE;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
int32 RecommendedLevelMin = 1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
int32 RecommendedLevelMax = 10;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
TSoftObjectPtr<USoundBase> AmbientMusic;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Zone")
|
||||
TSoftObjectPtr<USoundBase> AmbientSound;
|
||||
};
|
||||
11
Source/ZMMO/Game/UI/ZMMOThemeDataAsset.cpp
Normal file
11
Source/ZMMO/Game/UI/ZMMOThemeDataAsset.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "ZMMOThemeDataAsset.h"
|
||||
|
||||
bool UZMMOThemeDataAsset::HasKey(EZMMOThemeKey Key) const
|
||||
{
|
||||
return Entries.Contains(Key);
|
||||
}
|
||||
|
||||
const FThemeEntry* UZMMOThemeDataAsset::FindEntry(EZMMOThemeKey Key) const
|
||||
{
|
||||
return Entries.Find(Key);
|
||||
}
|
||||
26
Source/ZMMO/Game/UI/ZMMOThemeDataAsset.h
Normal file
26
Source/ZMMO/Game/UI/ZMMOThemeDataAsset.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "UI/ThemeKeys.h"
|
||||
#include "UI/ThemeRow.h"
|
||||
#include "ZMMOThemeDataAsset.generated.h"
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class ZMMO_API UZMMOThemeDataAsset : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
FName ThemeId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme")
|
||||
FText DisplayName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Theme", meta = (ToolTip = "Only fill the keys this theme overrides. Missing keys fall back to the Default theme."))
|
||||
TMap<EZMMOThemeKey, FThemeEntry> Entries;
|
||||
|
||||
bool HasKey(EZMMOThemeKey Key) const;
|
||||
const FThemeEntry* FindEntry(EZMMOThemeKey Key) const;
|
||||
};
|
||||
216
Source/ZMMO/Game/UI/ZMMOThemeSubsystem.cpp
Normal file
216
Source/ZMMO/Game/UI/ZMMOThemeSubsystem.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "ZMMOThemeSubsystem.h"
|
||||
|
||||
#include "ZMMOThemeDataAsset.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "Engine/Texture2D.h"
|
||||
#include "Sound/SoundBase.h"
|
||||
#include "NiagaraSystem.h"
|
||||
#include "Misc/DateTime.h"
|
||||
#include "UI/ThemeCalendarRow.h"
|
||||
#include "UI/UIStyleRow.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
/** Row Name da linha de estilo de fallback em DT_UI_Styles. */
|
||||
const FName GUIStyleDefaultRow(TEXT("Default"));
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
Super::Initialize(Collection);
|
||||
|
||||
DefaultTheme = DefaultThemeAsset.LoadSynchronous();
|
||||
if (!DefaultTheme)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning,
|
||||
TEXT("[ZMMOThemeSubsystem] DefaultThemeAsset is not set. UI will have no theme."));
|
||||
}
|
||||
|
||||
ResolveActiveTheme();
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::Deinitialize()
|
||||
{
|
||||
ActiveTheme = nullptr;
|
||||
DefaultTheme = nullptr;
|
||||
Super::Deinitialize();
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::ApplyServerTheme(FName ThemeId)
|
||||
{
|
||||
ServerThemeId = ThemeId;
|
||||
ResolveActiveTheme();
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::ForceTheme(FName ThemeId)
|
||||
{
|
||||
ForcedThemeId = ThemeId;
|
||||
ResolveActiveTheme();
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::ClearForcedTheme()
|
||||
{
|
||||
ForcedThemeId = NAME_None;
|
||||
ResolveActiveTheme();
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::ResolveActiveTheme()
|
||||
{
|
||||
FName Resolved = NAME_None;
|
||||
|
||||
if (!ForcedThemeId.IsNone())
|
||||
{
|
||||
Resolved = ForcedThemeId;
|
||||
}
|
||||
#if !UE_BUILD_SHIPPING
|
||||
else if (!DevThemeOverride.IsNone())
|
||||
{
|
||||
Resolved = DevThemeOverride;
|
||||
}
|
||||
#endif
|
||||
else if (!ServerThemeId.IsNone())
|
||||
{
|
||||
Resolved = ServerThemeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
Resolved = ResolveByCalendar();
|
||||
}
|
||||
|
||||
UZMMOThemeDataAsset* NewActive = !Resolved.IsNone() ? LoadThemeById(Resolved) : nullptr;
|
||||
if (!NewActive)
|
||||
{
|
||||
NewActive = DefaultTheme;
|
||||
Resolved = DefaultTheme ? DefaultTheme->ThemeId : NAME_None;
|
||||
}
|
||||
|
||||
if (NewActive != ActiveTheme || Resolved != ActiveThemeId)
|
||||
{
|
||||
ActiveTheme = NewActive;
|
||||
ActiveThemeId = Resolved;
|
||||
ResolveActiveUIStyle(ActiveThemeId);
|
||||
OnThemeChanged.Broadcast(ActiveThemeId);
|
||||
}
|
||||
}
|
||||
|
||||
void UZMMOThemeSubsystem::ResolveActiveUIStyle(FName ThemeId)
|
||||
{
|
||||
// Reset para os defaults do struct antes de aplicar a linha resolvida —
|
||||
// assim um tema sem linha cai num estado coerente (paleta Aurora Arcana).
|
||||
ActiveUIStyle = FUIStyle();
|
||||
|
||||
UDataTable* Table = UIStyleTable.LoadSynchronous();
|
||||
if (!Table)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FUIStyleRow* Row = nullptr;
|
||||
if (!ThemeId.IsNone())
|
||||
{
|
||||
Row = Table->FindRow<FUIStyleRow>(ThemeId, TEXT("UIStyle"));
|
||||
}
|
||||
if (!Row)
|
||||
{
|
||||
// Fallback: linha "Default" (mesma política dos assets, §5).
|
||||
Row = Table->FindRow<FUIStyleRow>(GUIStyleDefaultRow, TEXT("UIStyle"));
|
||||
}
|
||||
if (Row)
|
||||
{
|
||||
ActiveUIStyle = Row->Style;
|
||||
}
|
||||
}
|
||||
|
||||
FName UZMMOThemeSubsystem::ResolveByCalendar() const
|
||||
{
|
||||
UDataTable* Table = CalendarTable.LoadSynchronous();
|
||||
if (!Table)
|
||||
{
|
||||
return NAME_None;
|
||||
}
|
||||
|
||||
const FDateTime Now = FDateTime::Now();
|
||||
const int32 NowMonth = Now.GetMonth();
|
||||
const int32 NowDay = Now.GetDay();
|
||||
const int32 NowMD = NowMonth * 100 + NowDay;
|
||||
|
||||
FName Best = NAME_None;
|
||||
int32 BestPriority = MIN_int32;
|
||||
|
||||
TArray<FName> RowNames = Table->GetRowNames();
|
||||
for (const FName& RowName : RowNames)
|
||||
{
|
||||
const FThemeCalendarRow* Row = Table->FindRow<FThemeCalendarRow>(RowName, TEXT("ThemeCalendar"));
|
||||
if (!Row || Row->ThemeId.IsNone())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const int32 StartMD = Row->StartMonth * 100 + Row->StartDay;
|
||||
const int32 EndMD = Row->EndMonth * 100 + Row->EndDay;
|
||||
|
||||
const bool bInRange = (StartMD <= EndMD)
|
||||
? (NowMD >= StartMD && NowMD <= EndMD)
|
||||
: (NowMD >= StartMD || NowMD <= EndMD); // wraps across year (e.g. 12-15 -> 01-05)
|
||||
|
||||
if (bInRange && Row->Priority > BestPriority)
|
||||
{
|
||||
Best = Row->ThemeId;
|
||||
BestPriority = Row->Priority;
|
||||
}
|
||||
}
|
||||
|
||||
return Best;
|
||||
}
|
||||
|
||||
UZMMOThemeDataAsset* UZMMOThemeSubsystem::LoadThemeById(FName ThemeId) const
|
||||
{
|
||||
if (const TSoftObjectPtr<UZMMOThemeDataAsset>* Soft = ThemeRegistry.Find(ThemeId))
|
||||
{
|
||||
return Soft->LoadSynchronous();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const FThemeEntry* UZMMOThemeSubsystem::FindEntryWithFallback(EZMMOThemeKey Key) const
|
||||
{
|
||||
if (ActiveTheme)
|
||||
{
|
||||
if (const FThemeEntry* Entry = ActiveTheme->FindEntry(Key))
|
||||
{
|
||||
return Entry;
|
||||
}
|
||||
}
|
||||
if (DefaultTheme && DefaultTheme != ActiveTheme)
|
||||
{
|
||||
if (const FThemeEntry* Entry = DefaultTheme->FindEntry(Key))
|
||||
{
|
||||
return Entry;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UTexture2D* UZMMOThemeSubsystem::GetTexture(EZMMOThemeKey Key) const
|
||||
{
|
||||
const FThemeEntry* Entry = FindEntryWithFallback(Key);
|
||||
return Entry ? Entry->Texture.LoadSynchronous() : nullptr;
|
||||
}
|
||||
|
||||
USoundBase* UZMMOThemeSubsystem::GetSound(EZMMOThemeKey Key) const
|
||||
{
|
||||
const FThemeEntry* Entry = FindEntryWithFallback(Key);
|
||||
return Entry ? Entry->Sound.LoadSynchronous() : nullptr;
|
||||
}
|
||||
|
||||
UNiagaraSystem* UZMMOThemeSubsystem::GetVFX(EZMMOThemeKey Key) const
|
||||
{
|
||||
const FThemeEntry* Entry = FindEntryWithFallback(Key);
|
||||
return Entry ? Entry->VFX.LoadSynchronous() : nullptr;
|
||||
}
|
||||
|
||||
UObject* UZMMOThemeSubsystem::GetGeneric(EZMMOThemeKey Key) const
|
||||
{
|
||||
const FThemeEntry* Entry = FindEntryWithFallback(Key);
|
||||
return Entry ? Entry->Generic.LoadSynchronous() : nullptr;
|
||||
}
|
||||
124
Source/ZMMO/Game/UI/ZMMOThemeSubsystem.h
Normal file
124
Source/ZMMO/Game/UI/ZMMOThemeSubsystem.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Subsystems/GameInstanceSubsystem.h"
|
||||
#include "UI/ThemeKeys.h"
|
||||
#include "UI/ThemeRow.h"
|
||||
#include "UI/UIStyleRow.h"
|
||||
#include "ZMMOThemeSubsystem.generated.h"
|
||||
|
||||
class UZMMOThemeDataAsset;
|
||||
class UDataTable;
|
||||
class UTexture2D;
|
||||
class USoundBase;
|
||||
class UNiagaraSystem;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnZMMOThemeChanged, FName, NewThemeId);
|
||||
|
||||
/**
|
||||
* Resolves which UI theme is active and answers asset lookups by EZMMOThemeKey.
|
||||
*
|
||||
* Resolution precedence (see ARQUITETURA.md §1.10):
|
||||
* 1. Dev override (.ini DevThemeOverride) — ignored in Shipping builds.
|
||||
* 2. Authoritative server theme (set via ApplyServerTheme).
|
||||
* 3. Local calendar (DT_ThemeCalendar).
|
||||
* 4. DA_Theme_Default.
|
||||
*
|
||||
* Widgets must never hold hard refs to theme textures/sounds. They consume the
|
||||
* active theme through Get* methods on this subsystem.
|
||||
*/
|
||||
UCLASS(Config = Game)
|
||||
class ZMMO_API UZMMOThemeSubsystem : public UGameInstanceSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// USubsystem
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
|
||||
/** Server-authoritative theme. Call from the ZeusNetwork ServerHello handler. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme")
|
||||
void ApplyServerTheme(FName ThemeId);
|
||||
|
||||
/** Forces a specific theme regardless of precedence. Use only for debug UI. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme|Debug")
|
||||
void ForceTheme(FName ThemeId);
|
||||
|
||||
/** Resets to the precedence-resolved theme. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme|Debug")
|
||||
void ClearForcedTheme();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Theme")
|
||||
FName GetActiveThemeId() const { return ActiveThemeId; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme")
|
||||
UTexture2D* GetTexture(EZMMOThemeKey Key) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme")
|
||||
USoundBase* GetSound(EZMMOThemeKey Key) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme")
|
||||
UNiagaraSystem* GetVFX(EZMMOThemeKey Key) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Theme")
|
||||
UObject* GetGeneric(EZMMOThemeKey Key) const;
|
||||
|
||||
/**
|
||||
* Tokens de estilo (cores/fontes/dimensões) do tema ativo, resolvidos de
|
||||
* DT_UI_Styles pelo ThemeId. Faz fallback para a linha "Default" quando o
|
||||
* tema ativo não tem linha própria — mesma política dos assets (§5).
|
||||
*/
|
||||
UFUNCTION(BlueprintPure, Category = "Theme|Style")
|
||||
const FUIStyle& GetActiveUIStyle() const { return ActiveUIStyle; }
|
||||
|
||||
/** Fired whenever the active theme actually changes. */
|
||||
UPROPERTY(BlueprintAssignable, Category = "Theme")
|
||||
FOnZMMOThemeChanged OnThemeChanged;
|
||||
|
||||
protected:
|
||||
/** Default theme. Must be filled with every key — it is the final fallback. */
|
||||
UPROPERTY(Config, EditDefaultsOnly, Category = "Theme")
|
||||
TSoftObjectPtr<UZMMOThemeDataAsset> DefaultThemeAsset;
|
||||
|
||||
/** Registry of seasonal/event themes keyed by ThemeId. */
|
||||
UPROPERTY(Config, EditDefaultsOnly, Category = "Theme")
|
||||
TMap<FName, TSoftObjectPtr<UZMMOThemeDataAsset>> ThemeRegistry;
|
||||
|
||||
/** Local calendar table (FThemeCalendarRow). Optional. */
|
||||
UPROPERTY(Config, EditDefaultsOnly, Category = "Theme")
|
||||
TSoftObjectPtr<UDataTable> CalendarTable;
|
||||
|
||||
/** Tabela de tokens de estilo (FUIStyleRow), keyed por ThemeId. */
|
||||
UPROPERTY(Config, EditDefaultsOnly, Category = "Theme")
|
||||
TSoftObjectPtr<UDataTable> UIStyleTable;
|
||||
|
||||
/** Dev-only override read from DefaultGame.ini. Empty in Shipping. */
|
||||
UPROPERTY(Config, EditDefaultsOnly, Category = "Theme|Debug")
|
||||
FName DevThemeOverride;
|
||||
|
||||
private:
|
||||
void ResolveActiveTheme();
|
||||
FName ResolveByCalendar() const;
|
||||
UZMMOThemeDataAsset* LoadThemeById(FName ThemeId) const;
|
||||
const FThemeEntry* FindEntryWithFallback(EZMMOThemeKey Key) const;
|
||||
void ResolveActiveUIStyle(FName ThemeId);
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UZMMOThemeDataAsset> ActiveTheme;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TObjectPtr<UZMMOThemeDataAsset> DefaultTheme;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
FName ActiveThemeId;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
FName ServerThemeId;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
FName ForcedThemeId;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
FUIStyle ActiveUIStyle;
|
||||
};
|
||||
@@ -14,6 +14,7 @@ public class ZMMO : ModuleRules
|
||||
"EnhancedInput",
|
||||
"UMG",
|
||||
"Slate",
|
||||
"Niagara",
|
||||
"ZeusNetwork"
|
||||
});
|
||||
|
||||
@@ -27,7 +28,17 @@ public class ZMMO : ModuleRules
|
||||
"ZMMO/Game/Entity",
|
||||
"ZMMO/Game/Controller",
|
||||
"ZMMO/Game/Modes",
|
||||
"ZMMO/Game/Network"
|
||||
"ZMMO/Game/Network",
|
||||
"ZMMO/Game/UI",
|
||||
"ZMMO/Data",
|
||||
"ZMMO/Data/Items",
|
||||
"ZMMO/Data/Mobs",
|
||||
"ZMMO/Data/Players",
|
||||
"ZMMO/Data/NPCs",
|
||||
"ZMMO/Data/Abilities",
|
||||
"ZMMO/Data/Quests",
|
||||
"ZMMO/Data/UI",
|
||||
"ZMMO/Data/World"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user