Infraestrutura cliente da promocao de classe (Jobs.1). WBP_JobChangePanel NAO esta neste commit — foi exploracao descartada (criar UI dinamica de botoes via MCP BP graph esbarrou em limites do CreateWidget node). A fundacao C++ fica pronta pra ser usada quando voltarmos pra UI. INFRA C++ NOVA (Source/ZMMOJobs/) * UZMMOJobChangeNetworkHandler (WorldSubsystem novo) — bind no OnJobChangeResult do plugin e re-broadcast via FZMMOOnJobChangeResultBP (dynamic multicast assignavel em BP). WBP futura escuta direto. * UZMMOJobsSubsystem helpers: GetJobsByTier(EZMMOJobTier) + GetEligibleNextJobs(currentClassId) — filtra por ParentClassId. Pure. * UZMMOJobsLibrary BPFL wrappers + SendJobChangeRequest convenience (delega pro UZeusNetworkSubsystem). Dep ZeusNetwork adicionada no Build.cs. ENUM + INPUT * EZMMOInGameUIState ganha JobChangePanel (entre StatusWindow e Inventory). DA_InGameScreenSet pendente de receber entry quando WBP for criada (tecla J vai falhar silenciosamente ate la). * ZMMOPlayerController: tecla J -> ToggleJobChangePanel -> Flow->ToggleScreen(JobChangePanel). Espelha pattern do Alt+A do StatusWindow (InputComponent legacy BindKey + FInputChord). UI TWEAKS * WBP_StatusWindow + DT_UI_Styles: ajustes visuais no Editor durante a sessao (sem mudanca funcional documentavel — provavelmente fontes/ spacing/cores). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
2.7 KiB
C++
97 lines
2.7 KiB
C++
#include "ZMMOJobsSubsystem.h"
|
|
|
|
#include "AssetRegistry/AssetRegistryModule.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "ZMMOJobDataAsset.h"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogZMMOJobs, Log, All);
|
|
|
|
void UZMMOJobsSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|
{
|
|
Super::Initialize(Collection);
|
|
LoadJobsFromAssetRegistry();
|
|
UE_LOG(LogZMMOJobs, Log, TEXT("[ZMMOJobsSubsystem] Initialize: %d job(s) carregados"), CachedJobs.Num());
|
|
}
|
|
|
|
void UZMMOJobsSubsystem::Deinitialize()
|
|
{
|
|
CachedJobs.Empty();
|
|
Super::Deinitialize();
|
|
}
|
|
|
|
void UZMMOJobsSubsystem::LoadJobsFromAssetRegistry()
|
|
{
|
|
FAssetRegistryModule& AssetRegistryModule =
|
|
FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
IAssetRegistry& AR = AssetRegistryModule.Get();
|
|
|
|
// Editor pode chamar antes de scan inicial. Standalone/PIE scan ja' rodou.
|
|
// SearchAllAssets(false) = nao-blocking; assume cache populado em runtime.
|
|
#if WITH_EDITOR
|
|
AR.SearchAllAssets(true); // bloqueia editor; ok em Initialize
|
|
#endif
|
|
|
|
TArray<FAssetData> Assets;
|
|
const FTopLevelAssetPath ClassPath(UZMMOJobDataAsset::StaticClass()->GetClassPathName());
|
|
AR.GetAssetsByClass(ClassPath, Assets, /*bSearchSubClasses*/ true);
|
|
|
|
for (const FAssetData& AssetData : Assets)
|
|
{
|
|
UZMMOJobDataAsset* Job = Cast<UZMMOJobDataAsset>(AssetData.GetAsset());
|
|
if (Job == nullptr) { continue; }
|
|
|
|
if (CachedJobs.Contains(Job->ClassId))
|
|
{
|
|
UE_LOG(LogZMMOJobs, Warning,
|
|
TEXT("[ZMMOJobsSubsystem] Duplicate ClassId=%d (existing=%s, new=%s) — ignorando segundo"),
|
|
Job->ClassId,
|
|
*CachedJobs[Job->ClassId]->GetName(),
|
|
*Job->GetName());
|
|
continue;
|
|
}
|
|
|
|
CachedJobs.Add(Job->ClassId, Job);
|
|
UE_LOG(LogZMMOJobs, Verbose,
|
|
TEXT("[ZMMOJobsSubsystem] Cached classId=%d name=%s display=%s"),
|
|
Job->ClassId, *Job->TechnicalName, *Job->DisplayName.ToString());
|
|
}
|
|
}
|
|
|
|
UZMMOJobDataAsset* UZMMOJobsSubsystem::GetJobData(int32 ClassId) const
|
|
{
|
|
if (const TObjectPtr<UZMMOJobDataAsset>* Found = CachedJobs.Find(ClassId))
|
|
{
|
|
return Found->Get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
TArray<UZMMOJobDataAsset*> UZMMOJobsSubsystem::GetJobsByTier(EZMMOJobTier Tier) const
|
|
{
|
|
TArray<UZMMOJobDataAsset*> Out;
|
|
Out.Reserve(CachedJobs.Num());
|
|
for (const TPair<int32, TObjectPtr<UZMMOJobDataAsset>>& Pair : CachedJobs)
|
|
{
|
|
if (Pair.Value && Pair.Value->Tier == Tier)
|
|
{
|
|
Out.Add(Pair.Value.Get());
|
|
}
|
|
}
|
|
return Out;
|
|
}
|
|
|
|
TArray<UZMMOJobDataAsset*> UZMMOJobsSubsystem::GetEligibleNextJobs(int32 CurrentClassId) const
|
|
{
|
|
TArray<UZMMOJobDataAsset*> Out;
|
|
Out.Reserve(4); // tipico: 2-6 destinos
|
|
for (const TPair<int32, TObjectPtr<UZMMOJobDataAsset>>& Pair : CachedJobs)
|
|
{
|
|
if (Pair.Value && Pair.Value->ParentClassId == CurrentClassId
|
|
&& Pair.Value->ClassId != CurrentClassId)
|
|
{
|
|
Out.Add(Pair.Value.Get());
|
|
}
|
|
}
|
|
return Out;
|
|
}
|