#include "ZeusJobsSubsystem.h" #include "AssetRegistry/AssetRegistryModule.h" #include "Modules/ModuleManager.h" #include "ZeusJobDataAsset.h" DEFINE_LOG_CATEGORY_STATIC(LogZeusJobs, Log, All); void UZeusJobsSubsystem::Initialize(FSubsystemCollectionBase& Collection) { Super::Initialize(Collection); LoadJobsFromAssetRegistry(); UE_LOG(LogZeusJobs, Log, TEXT("[ZeusJobsSubsystem] Initialize: %d job(s) carregados"), CachedJobs.Num()); } void UZeusJobsSubsystem::Deinitialize() { CachedJobs.Empty(); Super::Deinitialize(); } void UZeusJobsSubsystem::LoadJobsFromAssetRegistry() { FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked("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 Assets; const FTopLevelAssetPath ClassPath(UZeusJobDataAsset::StaticClass()->GetClassPathName()); AR.GetAssetsByClass(ClassPath, Assets, /*bSearchSubClasses*/ true); for (const FAssetData& AssetData : Assets) { UZeusJobDataAsset* Job = Cast(AssetData.GetAsset()); if (Job == nullptr) { continue; } if (CachedJobs.Contains(Job->ClassId)) { UE_LOG(LogZeusJobs, Warning, TEXT("[ZeusJobsSubsystem] 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(LogZeusJobs, Verbose, TEXT("[ZeusJobsSubsystem] Cached classId=%d name=%s display=%s"), Job->ClassId, *Job->TechnicalName, *Job->DisplayName.ToString()); } } UZeusJobDataAsset* UZeusJobsSubsystem::GetJobData(int32 ClassId) const { if (const TObjectPtr* Found = CachedJobs.Find(ClassId)) { return Found->Get(); } return nullptr; } TArray UZeusJobsSubsystem::GetJobsByTier(EZeusJobTier Tier) const { TArray Out; Out.Reserve(CachedJobs.Num()); for (const TPair>& Pair : CachedJobs) { if (Pair.Value && Pair.Value->Tier == Tier) { Out.Add(Pair.Value.Get()); } } return Out; } TArray UZeusJobsSubsystem::GetEligibleNextJobs(int32 CurrentClassId) const { TArray Out; Out.Reserve(4); // tipico: 2-6 destinos for (const TPair>& Pair : CachedJobs) { if (Pair.Value && Pair.Value->ParentClassId == CurrentClassId && Pair.Value->ClassId != CurrentClassId) { Out.Add(Pair.Value.Get()); } } return Out; }