物品随机生成预研完成

This commit is contained in:
2025-09-30 23:58:10 +08:00
parent c39b910f83
commit 7e7d2a6474
14 changed files with 42 additions and 11 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,14 +3,14 @@
#include "Level/Actor/BusyStaticResource.h"
#include "Utils/MitchellBestCandidate.h"
static FName GetOneOfAlwaysPresent(TMap<FName, int32>& AlwaysPresentResource)
static FName PeekOneOfAlwaysPresent(TMap<FName, int32>& AlwaysPresentResource)
{
TArray<FName> NeedRemoveKeys;
for (auto& Pair : AlwaysPresentResource)
{
if (Pair.Value <= 0)
{
NeedRemoveKeys.AddUnique(Pair.Key);
NeedRemoveKeys.Add(Pair.Key);
}
}
for (auto& RemovedKey : NeedRemoveKeys)
@ -22,12 +22,27 @@ static FName GetOneOfAlwaysPresent(TMap<FName, int32>& AlwaysPresentResource)
{
return FName();
}
auto &Pair = *AlwaysPresentResource.begin();
Pair.Value -= 1;
const auto &Pair = *AlwaysPresentResource.begin();
return Pair.Key;
}
static void ConsumeOneOfAlwaysPresent(TMap<FName, int32>& AlwaysPresentResource, const FName &ResourceName)
{
if (const int32 *RemainCount = AlwaysPresentResource.Find(ResourceName))
{
if (*RemainCount > 0)
{
AlwaysPresentResource[ResourceName] = *RemainCount - 1;
return;
}
}
UE_LOG(LogMapGenerate, Error, TEXT("ConsumeOneOfAlwaysPresent %s failed"), *ResourceName.ToString());
}
inline static IGameMapInterface * GetMapActor(const UActorComponent* Component)
{
AActor *Owner = Component->GetOwner();
@ -92,6 +107,10 @@ void UStaticResourceLayerComponent::GetAlwaysPresentResourceList(TMap<FName, int
if (RowData->MinGenerateCount > 0)
{
OutAlwaysPresentResource.Add(Pair.Key, RowData->MinGenerateCount);
UE_LOG(LogMapGenerate, Log,
TEXT("UStaticResourceLayerComponent::GetAlwaysPresentResourceList %s: %d"),
*Pair.Key.ToString(), RowData->MinGenerateCount
);
}
}
}
@ -108,8 +127,12 @@ bool UStaticResourceLayerComponent::GenerateAlwaysPresentInfo(TArray<FVector2D>&
for (int i = ResourcePoints.Num() - 1; i >= 0; i--) // 遍历所有的资源点尝试生成资源
{
FName CurrentSelected = GetOneOfAlwaysPresent(AlwaysPresentResource);
if (CurrentSelected.IsNone()) break; // 必须生成的资源已经全部生成了,则结束
FName CurrentSelected = PeekOneOfAlwaysPresent(AlwaysPresentResource);
if (CurrentSelected.IsNone()) // 必须生成的资源已经全部生成了,则结束
{
UE_LOG(LogMapGenerate, Log, TEXT("UStaticResourceLayerComponent::GenerateAlwaysPresentInfo All Always present created."))
break;
}
const FVector2D& CurrentPoint = ResourcePoints[i];
FGameplayTag CurrentTerrain = MapInterface->Execute_GetTerrainAt(Owner, CurrentPoint.X, CurrentPoint.Y); // 获取这个资源点的地形类型
@ -120,15 +143,20 @@ bool UStaticResourceLayerComponent::GenerateAlwaysPresentInfo(TArray<FVector2D>&
if (Config->TerrainTypes.HasTag(CurrentTerrain)) // 资源的地形配置包含当前的地形,则添加进生成的列表
{
GeneratedResourcePoints.Add(TTuple<FName, FVector2D>(
CurrentSelected,
FVector2D(ResourcePoints[i].X, ResourcePoints[i].Y))
);
GeneratedResourcePoints.Add(TTuple<FName, FVector2D>(CurrentSelected, FVector2D(ResourcePoints[i].X, ResourcePoints[i].Y)));
ConsumeOneOfAlwaysPresent(AlwaysPresentResource, CurrentSelected);
ResourcePoints[i].X = ResourcePoints[i].Y = -1;
UE_LOG(LogMapGenerate, Log, TEXT("UStaticResourceLayerComponent::GenerateAlwaysPresentInfo Create %s at (%d, %d)"),
*CurrentSelected.ToString(), int32(ResourcePoints[i].X), int32(ResourcePoints[i].Y))
}
else
{
UE_LOG(LogMapGenerate, Log, TEXT("UStaticResourceLayerComponent::GenerateAlwaysPresentInfo Failed create %s at (%d,%d) in %s"),
*CurrentSelected.ToString(), int32(ResourcePoints[i].X), int32(ResourcePoints[i].Y), *CurrentTerrain.ToString());
}
}
if (!GetOneOfAlwaysPresent(AlwaysPresentResource).IsNone()) // 如果还有必须要生成的没有生成,则生成失败
if (!PeekOneOfAlwaysPresent(AlwaysPresentResource).IsNone()) // 如果还有必须要生成的没有生成,则生成失败
{
GeneratedResourcePoints.Empty();
return false;

View File

@ -1,6 +1,7 @@
#include "Level/Map/GameMapActor.h"
#include "Level/Map/Components/StaticResourceLayerComponent.h"
DEFINE_LOG_CATEGORY(LogMapGenerate);
AGameMapActor::AGameMapActor()
{

View File

@ -6,6 +6,8 @@
#include "GameMapActor.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogMapGenerate, Log, All);
UINTERFACE()
class UGameMapInterface : public UInterface
{