#include "Subsystems/RRDADataAssetSubsystem.h" #include "RefinedRDApi.h" #include "DataAssets/RRDADirtDataAsset.h" #include "Engine/AssetManager.h" #include "AssetRegistry/AssetRegistryModule.h" #include "DataAssets/RRDABoilerDataAsset.h" #include "DataAssets/RRDACoolerDataAsset.h" #include "DataAssets/RRDADataAssetDSModAdapter.h" #include "DataAssets/RRDAHeaterDataAsset.h" #include "DataAssets/RRDATurbineDataAsset.h" #include "Logging/StructuredLog.h" URRDADataAssetSubsystem::URRDADataAssetSubsystem() {} URRDADataAssetSubsystem* URRDADataAssetSubsystem::Get(UObject* Context) { if (IsValid(Context)) { return Context->GetWorld()->GetGameInstance()->GetSubsystem(); } return nullptr; } URRDADataAssetSubsystem* URRDADataAssetSubsystem::GetChecked(UObject* Context) { URRDADataAssetSubsystem* Subsystem = Get(Context); fgcheck(Subsystem); return Subsystem; } void URRDADataAssetSubsystem::Initialize(FSubsystemCollectionBase& Collection) { Super::Initialize(Collection); FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(FName("AssetRegistry")); IAssetRegistry& AssetRegistry = AssetRegistryModule.Get(); // Must wait until all assets are discovered before populating list of assets. if (AssetRegistry.IsLoadingAssets()) { AssetRegistry.OnFilesLoaded().AddUObject(this, &URRDADataAssetSubsystem::StartScanForDataAssets); } else { StartScanForDataAssets(); } } void URRDADataAssetSubsystem::Deinitialize() { Super::Deinitialize(); mEnabledDataAssets.Empty(); mDisabledDataAssets.Empty(); mDirtAssets.Empty(); mTurbineAssets.Empty(); mBoilerAssets.Empty(); mCoolerAssets.Empty(); mHeaterAssets.Empty(); mGeneratorAssets.Empty(); mDSBuildingData.Empty(); } void URRDADataAssetSubsystem::StartScanForDataAssets() { mDisabledDataAssets.Empty(); mEnabledDataAssets.Empty(); ReCacheBoilerDataAssets(); ReCacheCoolerDataAssets(); ReCacheDirtDataAssets(); ReCacheHeaterDataAssets(); ReCacheTurbineDataAssets(); ReCacheGeneratorDataAssets(); mDSBuildingData.Empty(); ReCacheDSModAdapterDataAssets(); ReCacheDSAdapterCoversDataAssets(); } void URRDADataAssetSubsystem::ReCacheDirtDataAssets() { mDirtAssets.Empty(); TSet DataAssets; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDADirtDataAsset* DataAsset : DataAssets) { mDirtAssets.Add(DataAsset->mItem, DataAsset); } } UE_LOG(LogRRDApi, Log, TEXT("ReCacheDirtDataAssets: %d"), mDirtAssets.Num()); } void URRDADataAssetSubsystem::ReCacheTurbineDataAssets() { mTurbineAssets.Empty(); TSet DataAssets; int32 Added = 0; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDATurbineDataAsset* DataAsset : DataAssets) { if (!mTurbineAssets.Contains(DataAsset->mTier)) { mTurbineAssets.Add(DataAsset->mTier, FRRDADataHolderTurbineData()); } fgcheckf(DataAsset->mItem.ItemClass, TEXT("TurbineDataAsset %s has no ItemClass"), *DataAsset->GetPathName()); mTurbineAssets[DataAsset->mTier].Data.Add(DataAsset->mItem.ItemClass, DataAsset); Added++; } } UE_LOG(LogRRDApi, Log, TEXT("ReCacheTurbineDataAssets: %d"), Added); } void URRDADataAssetSubsystem::ReCacheBoilerDataAssets() { mBoilerAssets.Empty(); TSet DataAssets; int32 Added = 0; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDABoilerDataAsset* DataAsset : DataAssets) { if (!mBoilerAssets.Contains(DataAsset->mTier)) { mBoilerAssets.Add(DataAsset->mTier, FRRDADataHolderBoilerData()); } fgcheckf(DataAsset->mInput.ItemClass, TEXT("BoilerDataAsset %s has no ItemClass"), *DataAsset->GetPathName()); mBoilerAssets[DataAsset->mTier].Data.Add(DataAsset->mInput.ItemClass, DataAsset); Added++; } } UE_LOG(LogRRDApi, Log, TEXT("ReCacheBoilerDataAssets: %d"), Added); } void URRDADataAssetSubsystem::ReCacheCoolerDataAssets() { mCoolerAssets.Empty(); TSet DataAssets; int32 Added = 0; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDACoolerDataAsset* DataAsset : DataAssets) { if (!mCoolerAssets.Contains(DataAsset->mType)) { mCoolerAssets.Add(DataAsset->mType, FRRDADataHolderCoolerData()); } fgcheckf(DataAsset->mItem, TEXT("CoolerDataAsset %s has no ItemClass"), *DataAsset->GetPathName()); mCoolerAssets[DataAsset->mType].Data.Add(DataAsset->mItem, DataAsset); Added++; } } UE_LOG(LogRRDApi, Log, TEXT("ReCacheCoolerDataAssets: %d"), Added); } void URRDADataAssetSubsystem::ReCacheHeaterDataAssets() { mHeaterAssets.Empty(); TSet DataAssets; int32 Added = 0; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDAHeaterDataAsset* DataAsset : DataAssets) { if (!mHeaterAssets.Contains(DataAsset->mType)) { mHeaterAssets.Add(DataAsset->mType, FRRDADataHolderHeaterData()); } fgcheckf(DataAsset->mInput.ItemClass, TEXT("HeaterDataAsset %s has no ItemClass"), *DataAsset->GetPathName()); mHeaterAssets[DataAsset->mType].Data.Add(DataAsset->mInput.ItemClass, DataAsset); Added++; } } UE_LOG(LogRRDApi, Log, TEXT("ReCacheHeaterDataAssets: %d"), Added); } void URRDADataAssetSubsystem::ReCacheGeneratorDataAssets() { mGeneratorAssets.Empty(); TSet DataAssets; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDAGeneratorDataAsset* DataAsset : DataAssets) { mGeneratorAssets.Add(DataAsset->mTier, DataAsset); } } UE_LOG(LogRRDApi, Log, TEXT("ReCacheGeneratorDataAssets: %d"), mGeneratorAssets.Num()); } void URRDADataAssetSubsystem::ReCacheDSModAdapterDataAssets() { TSet DataAssets; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDADataAssetDSModAdapter* DataAsset : DataAssets) { FRRDADataHolderDSBuildingData* existingData = mDSBuildingData.Find(DataAsset->mBuildingClass); if (existingData == nullptr) { FRRDADataHolderDSBuildingData newData = FRRDADataHolderDSBuildingData(); newData.ModAdapter = DataAsset; mDSBuildingData.Add(DataAsset->mBuildingClass, newData); } else { existingData->ModAdapter = DataAsset; } } } UE_LOGFMT(LogRRDApi, Log, "ReCacheDSModAdapterDataAssets: {0}", mDSBuildingData.Num()); } void URRDADataAssetSubsystem::ReCacheDSAdapterCoversDataAssets() { TSet DataAssets; if (FindAllDataAssetsOfClass(DataAssets)) { for (URRDADataAssetDSAdapterCovers* DataAsset : DataAssets) { FRRDADataHolderDSBuildingData* existingData = mDSBuildingData.Find(DataAsset->mBuildingClass); if (existingData == nullptr) { FRRDADataHolderDSBuildingData newData = FRRDADataHolderDSBuildingData(); newData.AdapterCovers = DataAsset; mDSBuildingData.Add(DataAsset->mBuildingClass, newData); } else { existingData->AdapterCovers = DataAsset; } } } UE_LOGFMT(LogRRDApi, Log, "ReCacheDSAdapterCoversDataAssets: {0}", mDSBuildingData.Num()); } int32 URRDADataAssetSubsystem::GetAllDirtItems(TArray>& Items) const { if (!mDirtAssets.Num()) { UE_LOG(LogRRDApi, Error, TEXT("No Dirts found!")); } return mDirtAssets.GetKeys(Items); } URRDADirtDataAsset* URRDADataAssetSubsystem::GetDataForDirtItem(TSubclassOf Item) const { if (!Item) return nullptr; URRDADirtDataAsset* const* Desc = mDirtAssets.Find(Item); if (!Desc) return nullptr; return *Desc; } TArray URRDADataAssetSubsystem::GetAllDirtAssets() const { TArray Assets; mDirtAssets.GenerateValueArray(Assets); return Assets; } int32 URRDADataAssetSubsystem::GetAllDSBuildingClasses(TArray>& OutBuildingClasses) const { if (!mDSBuildingData.Num()) { UE_LOG(LogRRDApi, Error, TEXT("No DS Buildings found!")); } return mDSBuildingData.GetKeys(OutBuildingClasses); } URRDADataAssetDSModAdapter* URRDADataAssetSubsystem::GetModAdapterDataAssetForBuildingClass(TSubclassOf BuildingClass) const { if (!BuildingClass) return nullptr; const FRRDADataHolderDSBuildingData* data = mDSBuildingData.Find(BuildingClass); if (data == nullptr) return nullptr; URRDADataAssetDSModAdapter* DataAsset = data->ModAdapter; if (!DataAsset) return nullptr; return DataAsset; } TArray URRDADataAssetSubsystem::GetAllModAdapterDataAssets() const { TArray Assets; TArray buildingDatas; mDSBuildingData.GenerateValueArray(buildingDatas); for (FRRDADataHolderDSBuildingData& buildingData : buildingDatas) { Assets.AddUnique(buildingData.ModAdapter); } return Assets; } bool URRDADataAssetSubsystem::HasDSModAdapterForBuildingClass(TSubclassOf BuildingClass) { return IsValid(GetModAdapterDataAssetForBuildingClass(BuildingClass)); } URRDADataAssetDSAdapterCovers* URRDADataAssetSubsystem::GetDSAdapterCoverDataAssetForBuildingClass(TSubclassOf BuildingClass) const { if (!BuildingClass) return nullptr; const FRRDADataHolderDSBuildingData* data = mDSBuildingData.Find(BuildingClass); if (data == nullptr) return nullptr; URRDADataAssetDSAdapterCovers* DataAsset = data->AdapterCovers; if (!DataAsset) return nullptr; return DataAsset; } TArray URRDADataAssetSubsystem::GetAllDSAdapterCoverDataAssets() const { TArray Assets; TArray buildingDatas; mDSBuildingData.GenerateValueArray(buildingDatas); for (FRRDADataHolderDSBuildingData& buildingData : buildingDatas) { Assets.AddUnique(buildingData.AdapterCovers); } return Assets; } bool URRDADataAssetSubsystem::HasDSAdaperCoversForBuildingClass(TSubclassOf BuildingClass) { return IsValid(GetDSAdapterCoverDataAssetForBuildingClass(BuildingClass)); } bool URRDADataAssetSubsystem::GetAllTurbineItems(TArray>& Items, int32 Tier) const { if (!mTurbineAssets.Contains(Tier)) { return false; } Items.Empty(); mTurbineAssets[Tier].Data.GetKeys(Items); return true; } bool URRDADataAssetSubsystem::GetAllTurbineRelevantItems(TArray>& Items, int32 Tier) const { Items.Empty(); for (URRDATurbineDataAsset* Asset : GetAllTurbineAssets(Tier)) { Items.AddUnique(Asset->mItem.ItemClass); if (Asset->mWasteItem.ItemClass) { Items.AddUnique(Asset->mWasteItem.ItemClass); } } return Items.Num() > 0; } TArray URRDADataAssetSubsystem::GetAllTurbineAssets(int32 Tier) const { if (!mTurbineAssets.Contains(Tier)) { UE_LOG(LogRRDApi, Error, TEXT("No TurbineAssets found for Type: %d"), Tier); return TArray(); } TArray Assets; mTurbineAssets[Tier].Data.GenerateValueArray(Assets); return Assets; } URRDATurbineDataAsset* URRDADataAssetSubsystem::GetDefaultTurbineAsset(int32 Tier) const { return GetAllTurbineAssets(Tier).Top(); } URRDATurbineDataAsset* URRDADataAssetSubsystem::GetTurbineItemData(TSubclassOf Item, int32 Tier) const { if (!mTurbineAssets.Contains(Tier)) { return nullptr; } return mTurbineAssets[Tier].Data.FindRef(Item); } bool URRDADataAssetSubsystem::GetAllCoolerItems(TArray>& Items, ERRDACoolerType Type) const { if (!mCoolerAssets.Contains(Type)) return false; Items.Empty(); mCoolerAssets[Type].Data.GetKeys(Items); return Items.Num() > 0; } URRDACoolerDataAsset* URRDADataAssetSubsystem::GetCoolerItemData(TSubclassOf Item, ERRDACoolerType Type) const { if (!mCoolerAssets.Contains(Type)) return nullptr; return mCoolerAssets[Type].Data.FindRef(Item); } URRDACoolerDataAsset* URRDADataAssetSubsystem::GetDefaultCoolerAsset(ERRDACoolerType Type) const { return GetAllCoolerAssets(Type).Top(); } TArray URRDADataAssetSubsystem::GetAllCoolerAssets(ERRDACoolerType Type) const { if (!mCoolerAssets.Contains(Type)) { UE_LOG(LogRRDApi, Error, TEXT("No CoolerAssets found for Type: %d"), Type); return TArray(); } TArray Assets; mCoolerAssets[Type].Data.GenerateValueArray(Assets); return Assets; } URRDAGeneratorDataAsset* URRDADataAssetSubsystem::GetGeneratorItemData(int32 Tier) const { UE_LOG(LogRRDApi, Log, TEXT("GetGeneratorItemData: %d"), Tier); if (!mGeneratorAssets.Contains(Tier)) return nullptr; return mGeneratorAssets.FindRef(Tier); } bool URRDADataAssetSubsystem::GetAllBoilerItems(TArray>& Items, int32 Tier) const { if (!mBoilerAssets.Contains(Tier)) return false; mBoilerAssets[Tier].Data.GetKeys(Items); return Items.Num() > 0; } URRDABoilerDataAsset* URRDADataAssetSubsystem::GetBoilerItemData(TSubclassOf Item, int32 Tier) const { if (!mBoilerAssets.Contains(Tier)) return nullptr; return mBoilerAssets[Tier].Data.FindRef(Item); } bool URRDADataAssetSubsystem::GetAllBoilerRelevantItems(TArray>& Items, int32 Tier) const { Items.Empty(); for (URRDABoilerDataAsset* Asset : GetAllBoilerAssets(Tier)) { Items.AddUnique(Asset->mInput.ItemClass); if (Asset->mOutput.ItemClass) { Items.AddUnique(Asset->mOutput.ItemClass); } } return Items.Num() > 0; } URRDABoilerDataAsset* URRDADataAssetSubsystem::GetDefaultBoilerAsset(int32 Tier) const { return GetAllBoilerAssets(Tier).Top(); } TArray URRDADataAssetSubsystem::GetAllBoilerAssets(int32 Tier) const { if (!mBoilerAssets.Contains(Tier)) { UE_LOG(LogRRDApi, Error, TEXT("No BoilerAssets found for Type: %d"), Tier); return TArray(); } TArray Assets; mBoilerAssets[Tier].Data.GenerateValueArray(Assets); return Assets; } bool URRDADataAssetSubsystem::GetAllHeaterItems(TArray>& Items, ERRDAHeaterType Type) const { if (!mHeaterAssets.Contains(Type)) return false; mHeaterAssets[Type].Data.GetKeys(Items); return Items.Num() > 0; } URRDAHeaterDataAsset* URRDADataAssetSubsystem::GetHeaterItemData(TSubclassOf Item, ERRDAHeaterType Type) const { if (!mHeaterAssets.Contains(Type)) return nullptr; return mHeaterAssets[Type].Data.FindRef(Item); } bool URRDADataAssetSubsystem::GetAllHeaterRelevantItems(TArray>& Items, ERRDAHeaterType Type) const { Items.Empty(); for (URRDAHeaterDataAsset* HeaterAsset : GetAllHeaterAssets(Type)) { Items.AddUnique(HeaterAsset->mInput.ItemClass); if (HeaterAsset->mOutput.ItemClass) { Items.AddUnique(HeaterAsset->mOutput.ItemClass); } } return Items.Num() > 0; } URRDAHeaterDataAsset* URRDADataAssetSubsystem::GetDefaultHeaterAsset(ERRDAHeaterType Type) const { return GetAllHeaterAssets(Type).Top(); } TArray URRDADataAssetSubsystem::GetAllHeaterAssets(ERRDAHeaterType Type) const { if (!mHeaterAssets.Contains(Type)) { UE_LOG(LogRRDApi, Error, TEXT("No HeaterAssets found for Type: %d"), Type); return TArray(); } TArray Assets; mHeaterAssets[Type].Data.GenerateValueArray(Assets); return Assets; }