From c39b910f83e92034ea7345640f4a5da12a2ae5c9 Mon Sep 17 00:00:00 2001 From: wyatt Date: Tue, 30 Sep 2025 02:52:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E6=BA=90=E9=9A=8F=E6=9C=BA=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=88=9D=E6=AD=A5=E6=8E=A5=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Config/DefaultEngine.ini | 2 +- .../Level/Actor/Role/BP_Rabbit.uasset | Bin 27600 -> 27916 bytes Content/Blueprint/Level/BP_LevelMap.uasset | Bin 25168 -> 25724 bytes .../LevelStaticResourceGenerateConfig.uasset | Bin 0 -> 3911 bytes Content/Level/FalconPlain.umap | Bin 110004 -> 25626 bytes Content/Lua/Level/LevelGameMode.lua | 9 ++ .../Level/Map/ClimateLayerComponent.cpp | 1 - .../Map/Components/ClimateLayerComponent.cpp | 1 + .../Map/Components/CreatureLayerComponent.cpp | 1 + .../Components/DecorationLayerComponent.cpp | 1 + .../Map/Components/LightingLayerComponent.cpp | 1 + .../StaticResourceLayerComponent.cpp | 138 ++++++++++++++++++ .../TerrainLayerComponent.cpp | 57 +++++--- .../Level/Map/CreatureLayerComponent.cpp | 1 - .../Level/Map/DecorationLayerComponent.cpp | 1 - .../Private/Level/Map/GameMapActor.cpp | 24 ++- .../Level/Map/LightingLayerComponent.cpp | 1 - .../Level/Map/PlacementLayerComponent.cpp | 1 - .../MitchellBestCandidate.cpp | 2 +- .../Level/Generator/VoronoiTerrainGenerator.h | 2 +- .../{ => Components}/ClimateLayerComponent.h | 0 .../{ => Components}/CreatureLayerComponent.h | 0 .../DecorationLayerComponent.h | 0 .../{ => Components}/LightingLayerComponent.h | 0 .../Components/StaticResourceLayerComponent.h | 63 ++++++++ .../{ => Components}/TerrainLayerComponent.h | 19 ++- .../Public/Level/Map/GameMapActor.h | 59 +++++++- .../Level/Map/PlacementLayerComponent.h | 7 - .../MitchellBestCandidate.h | 0 29 files changed, 345 insertions(+), 46 deletions(-) create mode 100644 Content/Data/Level/LevelStaticResourceGenerateConfig.uasset delete mode 100644 Source/BusyRabbit/Private/Level/Map/ClimateLayerComponent.cpp create mode 100644 Source/BusyRabbit/Private/Level/Map/Components/ClimateLayerComponent.cpp create mode 100644 Source/BusyRabbit/Private/Level/Map/Components/CreatureLayerComponent.cpp create mode 100644 Source/BusyRabbit/Private/Level/Map/Components/DecorationLayerComponent.cpp create mode 100644 Source/BusyRabbit/Private/Level/Map/Components/LightingLayerComponent.cpp create mode 100644 Source/BusyRabbit/Private/Level/Map/Components/StaticResourceLayerComponent.cpp rename Source/BusyRabbit/Private/Level/Map/{ => Components}/TerrainLayerComponent.cpp (85%) delete mode 100644 Source/BusyRabbit/Private/Level/Map/CreatureLayerComponent.cpp delete mode 100644 Source/BusyRabbit/Private/Level/Map/DecorationLayerComponent.cpp delete mode 100644 Source/BusyRabbit/Private/Level/Map/LightingLayerComponent.cpp delete mode 100644 Source/BusyRabbit/Private/Level/Map/PlacementLayerComponent.cpp rename Source/BusyRabbit/Private/{Level/Generator => Utils}/MitchellBestCandidate.cpp (97%) rename Source/BusyRabbit/Public/Level/Map/{ => Components}/ClimateLayerComponent.h (100%) rename Source/BusyRabbit/Public/Level/Map/{ => Components}/CreatureLayerComponent.h (100%) rename Source/BusyRabbit/Public/Level/Map/{ => Components}/DecorationLayerComponent.h (100%) rename Source/BusyRabbit/Public/Level/Map/{ => Components}/LightingLayerComponent.h (100%) create mode 100644 Source/BusyRabbit/Public/Level/Map/Components/StaticResourceLayerComponent.h rename Source/BusyRabbit/Public/Level/Map/{ => Components}/TerrainLayerComponent.h (74%) delete mode 100644 Source/BusyRabbit/Public/Level/Map/PlacementLayerComponent.h rename Source/BusyRabbit/Public/{Level/Generator => Utils}/MitchellBestCandidate.h (100%) diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index cabb876..1abe330 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -20,7 +20,7 @@ GameDefaultMap=/Game/Level/HomeLand.HomeLand [/Script/Engine.RendererSettings] r.Mobile.AntiAliasing=0 -r.AntiAliasingMethod=3 +r.AntiAliasingMethod=1 r.DefaultFeature.MotionBlur=False [CoreRedirects] diff --git a/Content/Blueprint/Level/Actor/Role/BP_Rabbit.uasset b/Content/Blueprint/Level/Actor/Role/BP_Rabbit.uasset index 0f8d221b5a7f724e7b0f34856231171b622d44ee..967d3783244e52d8797c4b3ca1f91c6d948e4530 100644 GIT binary patch delta 6074 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 W=UW^_wH0}ByxyJ;=hyq~`F{apChLv> diff --git a/Content/Blueprint/Level/BP_LevelMap.uasset b/Content/Blueprint/Level/BP_LevelMap.uasset index e6e6b2e02c2a6f8fbe45c73c2321060d488073a1..7d1edeb7d5e9f03589292ca03e7f5e97110c805f 100644 GIT binary patch delta 4472 zcmcInc}$c?6rXQ7gd(sAyWEtrxSr)GD4?jo3d^xvatL1RvMg%Lp@3JlT}>%kH9ed^ z{KF>N_77uhF=U%yO_SQxnl_pSlUf_wsI6DEN~N~7R#W@ld^5|phl*`F;rrgqd%yY3 zdvD&%w+tPV?tdY@c}Zn5(rDG>3558PorI8B6(R6PwujP0Xeyyds%|>Dl4XYjRj@L<3lh7lid?Z*V*3eV-ynC1flCyaHEc@UOS0;*xR)P~vy-c^ z@W#gj8E*R+aXZF`3vvT+B6G^Edx6_UJz;IF z;W`7YjED`!0UmE`qnhQiLZMmVp;_snk$qS4i1kOAMao7sB9>8&kCK^%)h0Atq7b@Q zx$b9(Z5{6`bKs7<4!BKYz+D5}YlI&NC82OwRK!gH)_5Tlp>E~2OMpxBf)hy+hZ*@Q zojANlc@w}Le2l=Qysvcd4|*^{haZts)d_SsV!Hl!0N#g35Uu8&K#=3Pn>nR)K$Ae1 zX>zqa+?)e)3-1?}(beUX=$(kz6mi?#Rxl#TiyRsN@+00qE>AORb$WNWRRJI1eY=UR zGN{ea;ws3BZ1p~}J*}LXCq>F;+z2!;@|DefRm{Abn{g7FTeirSe1pZih{|HeZ1MVIPF6wD!D+6IsC`znVfHZ$g|7@hu>0*;R09V6hvk#SZA z-yf5q6-9;%r*O7(D=b`)qUXcE6pZMrC^wvPjboau^j1titBCWv+rF4*M8JG*=q9#7)JP#ilpV z?xM`#23f^iuBVoYNP40uP*csdN~;a6yNnuX0Ua>L#S2oM7bqi2z(4~qt&d;}2r=*V z+jtZ}d9y~^jxy>nLH!)4u@%yD#u+Z2X3D4Om(bnC zIU!EeFR)3lc5!}!Q}vsosBk^sfL`(^ol_ENcS1nxgC(!ttbzxdn=u`(L(nR{AhitW0VM>2cu>G==w3;VMqJd&?Pe*a=2FeHC+GaIH2vY6 zyNrHRTc%EOp%q75>A`GjFN&m1Wq$K!JuHwr5C~rN*px>A?@m&VFK7mOw<3{#R<aIpMr5w?7LmEUg=STIiHP0 z#Y}KHs%XlkXPdIKJk*igYqz_J5d4`DC5*Jh949TKt>zh;7OwLaCOv6Z+h=fq$Kj6U z1{WXLmk$gc>*N0lE=ag8S@S>+gQufNL1^aiY%cMm(LhTqI{5syTcTz*a=nL}OSnN$ jUI2P0n7(d_nk6hhDlL2#3U-x=A0h($1A0k=n+^W}B&5{Y delta 4227 zcmcIndr*{B6u;jF4m&6hWp`0lgoSo8Nd+MVGz1rc-C%*m1tDR1WSXz2EYk`YAJfz{ znrBA;sLA@vY8)HeY0Re5oMwE~6#mip_`@EOkF?0F6vxKSxqB{t>;t!Hy2F0w-uwG~ zzjMw#_q*T6t)p817uvRg*cIhM*x>KP>xmob#isw{u!m8T$y=od;YO% z;*-u6cti8p@~lEwJ8-CLx3N(?T{xG~;ZHWa8{snn%LK2#sz2?8?ok9^V2ljyb831)6`-E?Xn+=hr@}(g(ou;FqIoPz z9%d)or~#6H74@h@{o7X|MM z@;2S!*|~csyFQ*7L}HyHf^R}v=>?pbsb+@n6GAPtIvwcFmN2~QkYdg9AJfuTckEWut_@o0x6CsmqL@7wLkH9DX}ScE#x?Tv|K0 zCuQ5O>F7jxGQbd1(caJfy=_wcU=W>RRE3|4Z&fGLPql$D&1wH#r<{P$M*OL`FEG{S zlghi&vh7!ObP9ydD@9j<7~3U1(VA~o`-U7}VzpWAaLl@QGTrq9s!@DR3@v8c4BhT2 zuz#{G<}kj@Vc%FQ3{4(C=4%|Zl>3v@*WIh-LHEKV{yN76Lqi5BTpzs6t1Ltn%Q)DQ zkrkrd8PAgi!JtZq<{hxDBE{rm3RhPq>VN|kIhq5`SLBq$oP`O)tlzMd=*3x@K0NiOZg0{}F>#y35Tv^-J;M~7rTr$GLA@VQA0Q$VPPitRN_i;VV4qgs0Yk1rQywGwGSPBb?PoTx>b_}v z)%i}zq|2QHRd0pYhkjQ|1o;mh&W$V&Db-1~5t8Z&)<;qVzDmoqg%o2U2O5(54P5y- z49 zv>R}uz6%b!@6(n*t0xm@GcBaw*N_KadZxqo4aN~0O~&i^7x8jbWaumxF1lc&6f%tS zWnYK_$f$cIs)Taub1=Nt`Y_4F(n7g7^gJl^WQR@4tCfSTVXkcf`&KogyLl>L{>N3Q zR=$H)Vf~`$R)G$x-Cio|N8T_ifn{xVcfr=iNM-djE!UjzX;TI&bi1=aTU--bX5W7( zbGu5AZRFiKxERye-dr5ER?`i*QBF4xXmjDSmZ@5s|6)tOHas}DWcQuHhix�~qkV zu2n#9`@-?6x*UfP#c-;94yK*lky;$`sL_`|DpNy1dbixH$QSv~p~w=ycv;6@&V_- diff --git a/Content/Data/Level/LevelStaticResourceGenerateConfig.uasset b/Content/Data/Level/LevelStaticResourceGenerateConfig.uasset new file mode 100644 index 0000000000000000000000000000000000000000..744625c690b8ac6bae1136554f511c92c0a7b855 GIT binary patch literal 3911 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�u$u&Ur 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 K=#V5}p#OibMt?2< diff --git a/Content/Lua/Level/LevelGameMode.lua b/Content/Lua/Level/LevelGameMode.lua index 7c4ee56..70ebc2e 100644 --- a/Content/Lua/Level/LevelGameMode.lua +++ b/Content/Lua/Level/LevelGameMode.lua @@ -2,6 +2,15 @@ local Vector = import("Vector") local GameplayStatics = import("GameplayStatics") local BusyGameplayLibrary = import("BusyGameplayLibrary") + +--[[****************************私有函数区域******************************]]-- + +--- 生成资源点 +local function GenerateResourcePoint() + +end + + --- 保留到以后做联机内容时拓展 --- @class LevelGameMode --- @field GameMapActorClass table diff --git a/Source/BusyRabbit/Private/Level/Map/ClimateLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/ClimateLayerComponent.cpp deleted file mode 100644 index f7bcef0..0000000 --- a/Source/BusyRabbit/Private/Level/Map/ClimateLayerComponent.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Level/Map/ClimateLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/Components/ClimateLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/Components/ClimateLayerComponent.cpp new file mode 100644 index 0000000..28b1a75 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/Map/Components/ClimateLayerComponent.cpp @@ -0,0 +1 @@ +#include "Level/Map/Components/ClimateLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/Components/CreatureLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/Components/CreatureLayerComponent.cpp new file mode 100644 index 0000000..ef80184 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/Map/Components/CreatureLayerComponent.cpp @@ -0,0 +1 @@ +#include "Level/Map/Components/CreatureLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/Components/DecorationLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/Components/DecorationLayerComponent.cpp new file mode 100644 index 0000000..56b7131 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/Map/Components/DecorationLayerComponent.cpp @@ -0,0 +1 @@ +#include "Level/Map/Components/DecorationLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/Components/LightingLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/Components/LightingLayerComponent.cpp new file mode 100644 index 0000000..45dc41e --- /dev/null +++ b/Source/BusyRabbit/Private/Level/Map/Components/LightingLayerComponent.cpp @@ -0,0 +1 @@ +#include "Level/Map/Components/LightingLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/Components/StaticResourceLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/Components/StaticResourceLayerComponent.cpp new file mode 100644 index 0000000..16c0ee8 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/Map/Components/StaticResourceLayerComponent.cpp @@ -0,0 +1,138 @@ +#include "Level/Map/Components/StaticResourceLayerComponent.h" +#include "Level/Map/GameMapActor.h" +#include "Level/Actor/BusyStaticResource.h" +#include "Utils/MitchellBestCandidate.h" + +static FName GetOneOfAlwaysPresent(TMap& AlwaysPresentResource) +{ + TArray NeedRemoveKeys; + for (auto& Pair : AlwaysPresentResource) + { + if (Pair.Value <= 0) + { + NeedRemoveKeys.AddUnique(Pair.Key); + } + } + for (auto& RemovedKey : NeedRemoveKeys) + { + AlwaysPresentResource.Remove(RemovedKey); + } + + if (AlwaysPresentResource.Num() == 0) + { + return FName(); + } + auto &Pair = *AlwaysPresentResource.begin(); + Pair.Value -= 1; + return Pair.Key; +} + + +inline static IGameMapInterface * GetMapActor(const UActorComponent* Component) +{ + AActor *Owner = Component->GetOwner(); + if (!Owner) return nullptr; + return Cast(Owner); +} + + +void UStaticResourceLayerComponent::GenerateResources() +{ + TArray ResourcePoints; + GenerateResourcePoints(ResourcePoints); + GenerateAlwaysPresentInfo(ResourcePoints); + + AActor *Owner = GetOwner(); + UWorld* World = GetWorld(); + + const IGameMapInterface* GameMap = Cast(Owner); + if(!Owner || !GameMap || !World) return; + + const float MapFieldSize = GameMap->Execute_GetMapFieldSize(Owner); + for (int32 Index = 0; Index < GeneratedResourcePoints.Num(); Index++) + { + const TTuple &Info = GeneratedResourcePoints[Index]; + + const auto Config = GenerateConfig->FindRow(Info.Key, TEXT("")); + + FActorSpawnParameters SpawnParameters; + SpawnParameters.Owner = Owner; + World->SpawnActor( + Config->ResourceClass, + FVector(Info.Value.X * MapFieldSize, Info.Value.Y * MapFieldSize, 50.0f), + FRotator::ZeroRotator + ); + } + + +} + +void UStaticResourceLayerComponent::GenerateResourcePoints(TArray& OutResourcePoint) +{ + OutResourcePoint.Empty(); + AActor *Owner = GetOwner(); + if (!Owner) return; + const IGameMapInterface * MapInterface = Cast(Owner); + if (!MapInterface) return; + + float MapWidth, MapHeight; + MapInterface->Execute_GetMapSize(Owner, MapWidth, MapHeight); + + const UMitchellBestCandidate *PointCreator = NewObject(); + OutResourcePoint = PointCreator->GeneratePoints(ResourcePointCount, MapWidth, MapHeight); +} + +void UStaticResourceLayerComponent::GetAlwaysPresentResourceList(TMap& OutAlwaysPresentResource)const +{ + OutAlwaysPresentResource.Empty(); + if (!GenerateConfig) return; + for (const auto& Pair : GenerateConfig->GetRowMap()) + { + const FStaticResourceGenerateConfig* RowData = reinterpret_cast(Pair.Value); + if (RowData->MinGenerateCount > 0) + { + OutAlwaysPresentResource.Add(Pair.Key, RowData->MinGenerateCount); + } + } +} + +bool UStaticResourceLayerComponent::GenerateAlwaysPresentInfo(TArray& ResourcePoints) +{ + AActor *Owner = GetOwner(); + if (!Owner) return false; + const IGameMapInterface * MapInterface = Cast(Owner); + if (!MapInterface) return false; + + TMap AlwaysPresentResource; + GetAlwaysPresentResourceList(AlwaysPresentResource); + + for (int i = ResourcePoints.Num() - 1; i >= 0; i--) // 遍历所有的资源点尝试生成资源 + { + FName CurrentSelected = GetOneOfAlwaysPresent(AlwaysPresentResource); + if (CurrentSelected.IsNone()) break; // 必须生成的资源已经全部生成了,则结束 + + const FVector2D& CurrentPoint = ResourcePoints[i]; + FGameplayTag CurrentTerrain = MapInterface->Execute_GetTerrainAt(Owner, CurrentPoint.X, CurrentPoint.Y); // 获取这个资源点的地形类型 + const auto Config = GenerateConfig->FindRow( + CurrentSelected, TEXT("") + ); + if (!Config) continue; + + if (Config->TerrainTypes.HasTag(CurrentTerrain)) // 资源的地形配置包含当前的地形,则添加进生成的列表 + { + GeneratedResourcePoints.Add(TTuple( + CurrentSelected, + FVector2D(ResourcePoints[i].X, ResourcePoints[i].Y)) + ); + ResourcePoints[i].X = ResourcePoints[i].Y = -1; + } + } + + if (!GetOneOfAlwaysPresent(AlwaysPresentResource).IsNone()) // 如果还有必须要生成的没有生成,则生成失败 + { + GeneratedResourcePoints.Empty(); + return false; + } + ResourcePoints.RemoveAll([](const FVector2D Element){ return Element.X < 0 && Element.Y < 0; }); + return true; +} diff --git a/Source/BusyRabbit/Private/Level/Map/TerrainLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/Components/TerrainLayerComponent.cpp similarity index 85% rename from Source/BusyRabbit/Private/Level/Map/TerrainLayerComponent.cpp rename to Source/BusyRabbit/Private/Level/Map/Components/TerrainLayerComponent.cpp index 777e33c..21628f3 100644 --- a/Source/BusyRabbit/Private/Level/Map/TerrainLayerComponent.cpp +++ b/Source/BusyRabbit/Private/Level/Map/Components/TerrainLayerComponent.cpp @@ -1,4 +1,4 @@ -#include "Level/Map/TerrainLayerComponent.h" +#include "Level/Map/Components/TerrainLayerComponent.h" #include "Level/Generator/VoronoiTerrainGenerator.h" #include "Paper2D/Classes/PaperTileLayer.h" #include "Paper2D/Classes/PaperTileMapComponent.h" @@ -163,7 +163,6 @@ void UTerrainLayerComponent::BeginPlay() TArray Priority; TArray TerrainData; TArray TerrainTypes; - TArray FilteredTerrainData; for (auto TileSetConfig : TileSetConfigs) { TerrainTypes.Add(TileSetConfig.Key); @@ -172,18 +171,10 @@ void UTerrainLayerComponent::BeginPlay() GenerateTerrain(TerrainTypes, Priority, MapWidth, TerrainData); - for (auto TerrainType : TerrainTypes) - { - FilteredTerrainData.Init(false, TerrainData.Num()); - for (int32 i = 0; i < TerrainData.Num(); i++) - { - FilteredTerrainData[i] = (TerrainData[i] == TerrainType); - } - SetTerrainData(TerrainType, FilteredTerrainData); - } + SetTerrainData(TerrainData); } -void UTerrainLayerComponent::SetTerrainData(const FGameplayTag& InTerrainType, const TArray& TerrainData) +void UTerrainLayerComponent::SetTerrainDataWithType(const FGameplayTag& InTerrainType, const TArray& InTerrainData) { // 将给定的数据绘制到TileMapLayer上 UPaperTileSet* TileSet = GetMapTileSet(InTerrainType, TileSetConfigs); @@ -193,7 +184,7 @@ void UTerrainLayerComponent::SetTerrainData(const FGameplayTag& InTerrainType, c UE_LOG(LogTemp, Warning, TEXT("UTerrainLayerComponent::SetTerrainData")); return; } - if (TerrainData.Num() != MapWidth * MapHeight) + if (InTerrainData.Num() != MapWidth * MapHeight) { UE_LOG(LogTemp, Warning, TEXT("UTerrainLayerComponent::SetTerrainData")); return; @@ -206,10 +197,10 @@ void UTerrainLayerComponent::SetTerrainData(const FGameplayTag& InTerrainType, c const int32 CurRow = i * MapWidth; const int32 NextRow = (i + 1) * MapWidth; const int32 NeighborIndex = GetTileSetIndex( - TerrainData[CurRow + j], - TerrainData[CurRow + j + 1], - TerrainData[NextRow + j], - TerrainData[NextRow + j + 1] + InTerrainData[CurRow + j], + InTerrainData[CurRow + j + 1], + InTerrainData[NextRow + j], + InTerrainData[NextRow + j + 1] ); TileInfo.TileSet = TileSet; TileInfo.PackedTileIndex = DefaultNeighborDataToIdxMappings[NeighborIndex]; @@ -218,6 +209,33 @@ void UTerrainLayerComponent::SetTerrainData(const FGameplayTag& InTerrainType, c } } +void UTerrainLayerComponent::SetTerrainData(const TArray& InTerrainData) +{ + TArray Priority; + TArray FilteredTerrainData; + + for (auto &TileSetConfig : TileSetConfigs) + { + FilteredTerrainData.Init(false, InTerrainData.Num()); + for (int32 i = 0; i < InTerrainData.Num(); i++) + { + FilteredTerrainData[i] = (InTerrainData[i] == TileSetConfig.Key); + } + SetTerrainDataWithType(TileSetConfig.Key, FilteredTerrainData); + } + TerrainLayerData = InTerrainData; +} + +FGameplayTag UTerrainLayerComponent::GetTerrainAt(const int32 X, const int32 Y) +{ + const int32 Index = X + Y * MapWidth; + if (TerrainLayerData.IsValidIndex(Index)) + { + return TerrainLayerData[Index]; + } + return FGameplayTag(); +} + void UTerrainLayerComponent::SetupTerrainMeshes() { @@ -246,9 +264,8 @@ void UTerrainLayerComponent::SetupTerrainMeshes() NewTileMap->MapWidth = MapWidth; NewTileMap->MapHeight = MapHeight; - NewTileMap->TileWidth = 128; - NewTileMap->TileHeight = 128; - + NewTileMap->TileWidth = TileSetSize; + NewTileMap->TileHeight = TileSetSize; UPaperTileLayer* NewLayer = NewObject(NewTileMap); NewLayer->LayerName = FText::FromString("TerrainLayer"); diff --git a/Source/BusyRabbit/Private/Level/Map/CreatureLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/CreatureLayerComponent.cpp deleted file mode 100644 index 1d0fe19..0000000 --- a/Source/BusyRabbit/Private/Level/Map/CreatureLayerComponent.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Level/Map/CreatureLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/DecorationLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/DecorationLayerComponent.cpp deleted file mode 100644 index 0329493..0000000 --- a/Source/BusyRabbit/Private/Level/Map/DecorationLayerComponent.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Level/Map/DecorationLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/GameMapActor.cpp b/Source/BusyRabbit/Private/Level/Map/GameMapActor.cpp index 7b75303..c44578a 100644 --- a/Source/BusyRabbit/Private/Level/Map/GameMapActor.cpp +++ b/Source/BusyRabbit/Private/Level/Map/GameMapActor.cpp @@ -1,19 +1,35 @@ #include "Level/Map/GameMapActor.h" +#include "Level/Map/Components/StaticResourceLayerComponent.h" + AGameMapActor::AGameMapActor() { SceneComp = CreateDefaultSubobject(TEXT("SceneComp")); - - TerrainLayer = CreateDefaultSubobject(TEXT("TerrainLayer")); - - + ResourceLayer = CreateDefaultSubobject(TEXT("ResourceLayer")); this->RootComponent = SceneComp; } +void AGameMapActor::GetMapSize_Implementation(float& OutWidth, float& OutHeight) +{ + OutWidth = MapWidth; + OutHeight = MapHeight; +} + +FGameplayTag AGameMapActor::GetTerrainAt_Implementation(const float X, const float Y) +{ + return TerrainLayer->GetTerrainAt(X, Y); +} + +float AGameMapActor::GetMapFieldSize_Implementation() +{ + return MapFieldSize; +} + void AGameMapActor::BeginPlay() { Super::BeginPlay(); + ResourceLayer->GenerateResources(); } void AGameMapActor::EndPlay(const EEndPlayReason::Type EndPlayReason) diff --git a/Source/BusyRabbit/Private/Level/Map/LightingLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/LightingLayerComponent.cpp deleted file mode 100644 index 423b87a..0000000 --- a/Source/BusyRabbit/Private/Level/Map/LightingLayerComponent.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Level/Map/LightingLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Map/PlacementLayerComponent.cpp b/Source/BusyRabbit/Private/Level/Map/PlacementLayerComponent.cpp deleted file mode 100644 index 1bd86f2..0000000 --- a/Source/BusyRabbit/Private/Level/Map/PlacementLayerComponent.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Level/Map/PlacementLayerComponent.h" diff --git a/Source/BusyRabbit/Private/Level/Generator/MitchellBestCandidate.cpp b/Source/BusyRabbit/Private/Utils/MitchellBestCandidate.cpp similarity index 97% rename from Source/BusyRabbit/Private/Level/Generator/MitchellBestCandidate.cpp rename to Source/BusyRabbit/Private/Utils/MitchellBestCandidate.cpp index 7ee2a7c..4b283e2 100644 --- a/Source/BusyRabbit/Private/Level/Generator/MitchellBestCandidate.cpp +++ b/Source/BusyRabbit/Private/Utils/MitchellBestCandidate.cpp @@ -1,4 +1,4 @@ -#include "Level/Generator/MitchellBestCandidate.h" +#include "Utils/MitchellBestCandidate.h" #include "Math/UnrealMathUtility.h" UMitchellBestCandidate::UMitchellBestCandidate() diff --git a/Source/BusyRabbit/Public/Level/Generator/VoronoiTerrainGenerator.h b/Source/BusyRabbit/Public/Level/Generator/VoronoiTerrainGenerator.h index 5f89d13..2820466 100644 --- a/Source/BusyRabbit/Public/Level/Generator/VoronoiTerrainGenerator.h +++ b/Source/BusyRabbit/Public/Level/Generator/VoronoiTerrainGenerator.h @@ -2,7 +2,7 @@ #include "CoreMinimal.h" #include "GameplayTagContainer.h" -#include "Level/Generator/MitchellBestCandidate.h" +#include "Utils/MitchellBestCandidate.h" #include "Level/Generator/VoronoiDiagram.h" #include "Level/Generator/TerrainGeneratorBase.h" #include "VoronoiTerrainGenerator.generated.h" diff --git a/Source/BusyRabbit/Public/Level/Map/ClimateLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/Components/ClimateLayerComponent.h similarity index 100% rename from Source/BusyRabbit/Public/Level/Map/ClimateLayerComponent.h rename to Source/BusyRabbit/Public/Level/Map/Components/ClimateLayerComponent.h diff --git a/Source/BusyRabbit/Public/Level/Map/CreatureLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/Components/CreatureLayerComponent.h similarity index 100% rename from Source/BusyRabbit/Public/Level/Map/CreatureLayerComponent.h rename to Source/BusyRabbit/Public/Level/Map/Components/CreatureLayerComponent.h diff --git a/Source/BusyRabbit/Public/Level/Map/DecorationLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/Components/DecorationLayerComponent.h similarity index 100% rename from Source/BusyRabbit/Public/Level/Map/DecorationLayerComponent.h rename to Source/BusyRabbit/Public/Level/Map/Components/DecorationLayerComponent.h diff --git a/Source/BusyRabbit/Public/Level/Map/LightingLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/Components/LightingLayerComponent.h similarity index 100% rename from Source/BusyRabbit/Public/Level/Map/LightingLayerComponent.h rename to Source/BusyRabbit/Public/Level/Map/Components/LightingLayerComponent.h diff --git a/Source/BusyRabbit/Public/Level/Map/Components/StaticResourceLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/Components/StaticResourceLayerComponent.h new file mode 100644 index 0000000..4cd996c --- /dev/null +++ b/Source/BusyRabbit/Public/Level/Map/Components/StaticResourceLayerComponent.h @@ -0,0 +1,63 @@ +#pragma once + +#include "Engine/DataTable.h" +#include "GameplayTagContainer.h" +#include "StaticResourceLayerComponent.generated.h" + + + +USTRUCT(BlueprintType, Blueprintable) +struct FStaticResourceGenerateConfig: public FTableRowBase +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="备注") + FString Desc; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="生成的最少数量") + int MinGenerateCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="生成权重") + int GenerateWeight = 1; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="可以在哪些地形生成") + FGameplayTagContainer TerrainTypes; + + // 用于该资源生成时应该与某些资源保持多远的距离 + UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="生成距离规则") + TMap GenerateDistanceLimit; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName="需要生成的放置物类") + TSubclassOf ResourceClass; +}; + + +UCLASS(Blueprintable, Blueprintable) +class UStaticResourceLayerComponent :public UActorComponent +{ + GENERATED_BODY() +public: + void GenerateResources(); + + + +protected: + virtual void GenerateResourcePoints(TArray& OutResourcePoint); + + void GetAlwaysPresentResourceList(TMap& OutAlwaysPresentResource)const; + + bool GenerateAlwaysPresentInfo(TArray& ResourcePoints); + + +public: + UPROPERTY(EditAnywhere) + TObjectPtr GenerateConfig; + + UPROPERTY(EditAnywhere) + int ResourcePointCount = 64; + + TArray> GeneratedResourcePoints; + +protected: + +}; diff --git a/Source/BusyRabbit/Public/Level/Map/TerrainLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/Components/TerrainLayerComponent.h similarity index 74% rename from Source/BusyRabbit/Public/Level/Map/TerrainLayerComponent.h rename to Source/BusyRabbit/Public/Level/Map/Components/TerrainLayerComponent.h index c0c4c10..b7d60d8 100644 --- a/Source/BusyRabbit/Public/Level/Map/TerrainLayerComponent.h +++ b/Source/BusyRabbit/Public/Level/Map/Components/TerrainLayerComponent.h @@ -44,23 +44,34 @@ public: virtual void BeginPlay() override; public: - void SetTerrainData(const FGameplayTag& InTerrainType, const TArray &TerrainData); - + UFUNCTION(BlueprintCallable) + void SetTerrainData(const TArray& InTerrainData); + UFUNCTION(BlueprintCallable) + FGameplayTag GetTerrainAt(const int32 X, const int32 Y); + protected: void SetupTerrainMeshes(); + + void SetTerrainDataWithType(const FGameplayTag& InTerrainType, const TArray &InTerrainData); protected: - UPROPERTY(EditAnywhere, BlueprintReadOnly) + UPROPERTY(EditAnywhere, BlueprintReadWrite) int32 MapWidth = 32; - UPROPERTY(EditAnywhere, BlueprintReadOnly) + UPROPERTY(EditAnywhere, BlueprintReadWrite) int32 MapHeight = 32; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + int32 TileSetSize = 128; UPROPERTY(EditAnywhere, BlueprintReadOnly) TMap> TileSetConfigs; UPROPERTY(EditAnywhere, BlueprintReadOnly) TMap> TerrainMeshes; + + UPROPERTY(BlueprintReadOnly) + TArray TerrainLayerData; }; diff --git a/Source/BusyRabbit/Public/Level/Map/GameMapActor.h b/Source/BusyRabbit/Public/Level/Map/GameMapActor.h index 76cd1a8..933ed5d 100644 --- a/Source/BusyRabbit/Public/Level/Map/GameMapActor.h +++ b/Source/BusyRabbit/Public/Level/Map/GameMapActor.h @@ -1,25 +1,78 @@ #pragma once -#include "Level/Map/TerrainLayerComponent.h" +#include "Engine/DataTable.h" +#include "LuaActor.h" +#include "Level/Map/Components/TerrainLayerComponent.h" +#include "Level/Map/Components/StaticResourceLayerComponent.h" #include "GameMapActor.generated.h" + +UINTERFACE() +class UGameMapInterface : public UInterface +{ + GENERATED_BODY() +}; + +class IGameMapInterface +{ + GENERATED_BODY() +public: + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + void GetMapSize(float &OutX, float &OutY); + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + float GetMapFieldSize(); + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + FGameplayTag GetTerrainAt(const float X, const float Y); +}; + + + UCLASS(Blueprintable, Blueprintable) -class AGameMapActor : public AActor +class AGameMapActor : public ALuaActor, public IGameMapInterface { GENERATED_BODY() public: AGameMapActor(); +public: + virtual void GetMapSize_Implementation(float& OutWidth, float& OutHeight) override; + virtual FGameplayTag GetTerrainAt_Implementation(const float X, const float Y) override; + virtual float GetMapFieldSize_Implementation() override; + public: virtual void BeginPlay() override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + +public: + UFUNCTION(BlueprintCallable) + const UTerrainLayerComponent* GetTerrainLayer() const + { + return TerrainLayer; + } + + + protected: - UPROPERTY(EditDefaultsOnly) + UPROPERTY(EditAnywhere, BlueprintReadOnly) + float MapWidth = 32; + UPROPERTY(EditAnywhere, BlueprintReadOnly) + float MapHeight = 32; + UPROPERTY(EditAnywhere, BlueprintReadOnly) + float MapFieldSize = 128; + + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) TObjectPtr TerrainLayer; + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) + TObjectPtr ResourceLayer; + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) TObjectPtr SceneComp; + }; diff --git a/Source/BusyRabbit/Public/Level/Map/PlacementLayerComponent.h b/Source/BusyRabbit/Public/Level/Map/PlacementLayerComponent.h deleted file mode 100644 index 42ad5de..0000000 --- a/Source/BusyRabbit/Public/Level/Map/PlacementLayerComponent.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -class PlacementLayerComponent -{ -public: - -}; diff --git a/Source/BusyRabbit/Public/Level/Generator/MitchellBestCandidate.h b/Source/BusyRabbit/Public/Utils/MitchellBestCandidate.h similarity index 100% rename from Source/BusyRabbit/Public/Level/Generator/MitchellBestCandidate.h rename to Source/BusyRabbit/Public/Utils/MitchellBestCandidate.h