From 798865968c19db1fdc52d856e6d5bf3678805023 Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sat, 2 Mar 2024 18:54:31 +0800 Subject: [PATCH 1/4] 1 --- .../minecraft/world/WorldServer.java.patch | 115 ++++++++++-------- .../minecraft/world/chunk/Chunk.java.patch | 25 ++-- .../world/gen/ChunkProviderServer.java.patch | 35 +++++- .../net/minecraftforge/common/ForgeHooks.java | 28 ++++- .../world/structure/IStructureProvider.java | 101 +++++++++++++++ .../structure/SingleStructureProvider.java | 39 ++++++ .../structure/StructureAttachRegistry.java | 43 +++++++ .../world/structure/StructureCollection.java | 67 ++++++++++ .../event/world/StructureAttachEvent.java | 24 ++++ 9 files changed, 406 insertions(+), 71 deletions(-) create mode 100644 src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java create mode 100644 src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java create mode 100644 src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java create mode 100644 src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java create mode 100644 src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java diff --git a/patches/minecraft/net/minecraft/world/WorldServer.java.patch b/patches/minecraft/net/minecraft/world/WorldServer.java.patch index 30893f258..3a8676836 100644 --- a/patches/minecraft/net/minecraft/world/WorldServer.java.patch +++ b/patches/minecraft/net/minecraft/world/WorldServer.java.patch @@ -23,7 +23,15 @@ import net.minecraft.village.VillageCollection; import net.minecraft.village.VillageSiege; import net.minecraft.world.biome.Biome; -@@ -87,47 +88,52 @@ +@@ -68,6 +69,7 @@ + import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + import net.minecraft.world.chunk.storage.IChunkLoader; + import net.minecraft.world.gen.ChunkProviderServer; ++import net.minecraft.world.gen.IChunkGenerator; + import net.minecraft.world.gen.feature.WorldGeneratorBonusChest; + import net.minecraft.world.gen.structure.StructureBoundingBox; + import net.minecraft.world.gen.structure.template.TemplateManager; +@@ -87,47 +89,52 @@ private final MinecraftServer field_73061_a; private final EntityTracker field_73062_L; private final PlayerChunkMap field_73063_M; @@ -88,7 +96,7 @@ } else { -@@ -164,10 +170,10 @@ +@@ -164,10 +171,10 @@ this.func_175723_af().func_177750_a(this.field_72986_A.func_176137_E()); } @@ -100,7 +108,7 @@ public void func_72835_b() { super.func_72835_b(); -@@ -183,8 +189,8 @@ +@@ -183,8 +190,8 @@ { if (this.func_82736_K().func_82766_b("doDaylightCycle")) { @@ -111,7 +119,7 @@ } this.func_73053_d(); -@@ -210,7 +216,7 @@ +@@ -210,7 +217,7 @@ if (this.func_82736_K().func_82766_b("doDaylightCycle")) { @@ -120,7 +128,7 @@ } this.field_72984_F.func_76318_c("tickPending"); -@@ -224,6 +230,10 @@ +@@ -224,6 +231,10 @@ this.field_175740_d.func_75528_a(); this.field_72984_F.func_76318_c("portalForcer"); this.field_85177_Q.func_85189_a(this.func_82737_E()); @@ -131,7 +139,7 @@ this.field_72984_F.func_76319_b(); this.func_147488_Z(); } -@@ -232,16 +242,17 @@ +@@ -232,16 +243,17 @@ public Biome.SpawnListEntry func_175734_a(EnumCreatureType p_175734_1_, BlockPos p_175734_2_) { List list = this.func_72863_F().func_177458_a(p_175734_1_, p_175734_2_); @@ -151,7 +159,7 @@ public void func_72854_c() { this.field_73068_P = false; -@@ -284,10 +295,7 @@ +@@ -284,10 +296,7 @@ private void func_73051_P() { @@ -163,7 +171,7 @@ } public boolean func_73056_e() -@@ -311,7 +319,6 @@ +@@ -311,7 +320,6 @@ } @SideOnly(Side.CLIENT) @@ -171,7 +179,7 @@ public void func_72974_f() { if (this.field_72986_A.func_76075_d() <= 0) -@@ -327,8 +334,9 @@ +@@ -327,8 +335,9 @@ { i += this.field_73012_v.nextInt(8) - this.field_73012_v.nextInt(8); j += this.field_73012_v.nextInt(8) - this.field_73012_v.nextInt(8); @@ -182,7 +190,7 @@ { break; } -@@ -338,7 +346,6 @@ +@@ -338,7 +347,6 @@ this.field_72986_A.func_76087_c(j); } @@ -190,7 +198,7 @@ protected boolean func_175680_a(int p_175680_1_, int p_175680_2_, boolean p_175680_3_) { return this.func_72863_F().func_73149_a(p_175680_1_, p_175680_2_); -@@ -361,7 +368,6 @@ +@@ -361,7 +369,6 @@ this.field_72984_F.func_76319_b(); } @@ -198,7 +206,7 @@ protected void func_147456_g() { this.func_184162_i(); -@@ -372,7 +378,7 @@ +@@ -372,7 +379,7 @@ while (iterator1.hasNext()) { @@ -207,7 +215,7 @@ } } else -@@ -382,7 +388,7 @@ +@@ -382,7 +389,7 @@ boolean flag1 = this.func_72911_I(); this.field_72984_F.func_76320_a("pollingChunks"); @@ -216,7 +224,7 @@ { this.field_72984_F.func_76320_a("getChunk"); Chunk chunk = iterator.next(); -@@ -394,7 +400,7 @@ +@@ -394,7 +401,7 @@ chunk.func_150804_b(false); this.field_72984_F.func_76318_c("thunder"); @@ -225,7 +233,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int l = this.field_73005_l >> 2; -@@ -404,39 +410,32 @@ +@@ -404,39 +411,32 @@ { DifficultyInstance difficultyinstance = this.func_175649_E(blockpos); @@ -270,7 +278,7 @@ if (this.func_175662_w(blockpos2)) { this.func_175656_a(blockpos2, Blocks.field_150432_aD.func_176223_P()); -@@ -491,9 +490,8 @@ +@@ -491,9 +491,8 @@ protected BlockPos func_175736_a(BlockPos p_175736_1_) { BlockPos blockpos = this.func_175725_q(p_175736_1_); @@ -282,7 +290,7 @@ { public boolean apply(@Nullable EntityLivingBase p_apply_1_) { -@@ -503,7 +501,7 @@ +@@ -503,7 +502,7 @@ if (!list.isEmpty()) { @@ -291,7 +299,7 @@ } else { -@@ -516,27 +514,23 @@ +@@ -516,27 +515,23 @@ } } @@ -319,7 +327,7 @@ public void func_175654_a(BlockPos p_175654_1_, Block p_175654_2_, int p_175654_3_, int p_175654_4_) { Material material = p_175654_2_.func_176223_P().func_185904_a(); -@@ -545,7 +539,10 @@ +@@ -545,7 +540,10 @@ { if (p_175654_2_.func_149698_L()) { @@ -331,7 +339,7 @@ { IBlockState iblockstate = this.func_180495_p(p_175654_1_); -@@ -579,9 +576,9 @@ +@@ -579,9 +577,9 @@ } } @@ -342,7 +350,7 @@ NextTickListEntry nextticklistentry = new NextTickListEntry(p_180497_1_, p_180497_2_); nextticklistentry.func_82753_a(p_180497_4_); Material material = p_180497_2_.func_176223_P().func_185904_a(); -@@ -598,10 +595,9 @@ +@@ -598,10 +596,9 @@ } } @@ -354,7 +362,7 @@ { if (this.field_80004_Q++ >= 300) { -@@ -617,7 +613,6 @@ +@@ -617,7 +614,6 @@ super.func_72939_s(); } @@ -362,7 +370,7 @@ protected void func_184147_l() { super.func_184147_l(); -@@ -681,7 +676,6 @@ +@@ -681,7 +677,6 @@ this.field_80004_Q = 0; } @@ -370,7 +378,7 @@ public boolean func_72955_a(boolean p_72955_1_) { if (this.field_72986_A.func_76067_t() == WorldType.field_180272_g) -@@ -727,14 +721,16 @@ +@@ -727,14 +722,16 @@ { NextTickListEntry nextticklistentry1 = iterator.next(); iterator.remove(); @@ -389,7 +397,7 @@ { try { -@@ -763,7 +759,6 @@ +@@ -763,7 +760,6 @@ } @Nullable @@ -397,7 +405,7 @@ public List func_72920_a(Chunk p_72920_1_, boolean p_72920_2_) { ChunkPos chunkpos = p_72920_1_.func_76632_l(); -@@ -775,7 +770,6 @@ +@@ -775,7 +771,6 @@ } @Nullable @@ -405,7 +413,7 @@ public List func_175712_a(StructureBoundingBox p_175712_1_, boolean p_175712_2_) { List list = null; -@@ -798,10 +792,7 @@ +@@ -798,10 +793,7 @@ NextTickListEntry nextticklistentry = iterator.next(); BlockPos blockpos = nextticklistentry.field_180282_a; @@ -417,7 +425,7 @@ { if (p_175712_2_) { -@@ -815,7 +806,7 @@ +@@ -815,7 +807,7 @@ if (list == null) { @@ -426,7 +434,7 @@ } list.add(nextticklistentry); -@@ -826,7 +817,6 @@ +@@ -826,7 +818,6 @@ return list; } @@ -434,7 +442,7 @@ public void func_72866_a(Entity p_72866_1_, boolean p_72866_2_) { if (!this.func_175735_ai() && (p_72866_1_ instanceof EntityAnimal || p_72866_1_ instanceof EntityWaterMob)) -@@ -852,20 +842,21 @@ +@@ -852,20 +843,23 @@ return this.field_73061_a.func_71268_U(); } @@ -442,7 +450,10 @@ protected IChunkProvider func_72970_h() { IChunkLoader ichunkloader = this.field_73019_z.func_75763_a(this.field_73011_w); - return new ChunkProviderServer(this, ichunkloader, this.field_73011_w.func_186060_c()); +- return new ChunkProviderServer(this, ichunkloader, this.field_73011_w.func_186060_c()); ++ IChunkGenerator generator = this.field_73011_w.func_186060_c(); ++ net.minecraftforge.common.ForgeHooks.onCreateChunkProvider(this, ichunkloader, this.field_73011_w, generator); ++ return new ChunkProviderServer(this, ichunkloader, generator); } - @Override @@ -459,7 +470,7 @@ public void func_72963_a(WorldSettings p_72963_1_) { if (!this.field_72986_A.func_76070_v()) -@@ -881,16 +872,17 @@ +@@ -881,16 +875,17 @@ super.func_72963_a(p_72963_1_); } @@ -480,7 +491,7 @@ } throw new ReportedException(crashreport); -@@ -927,6 +919,7 @@ +@@ -927,6 +922,7 @@ } else { @@ -488,7 +499,7 @@ this.field_72987_B = true; BiomeProvider biomeprovider = this.field_73011_w.func_177499_m(); List list = biomeprovider.func_76932_a(); -@@ -952,8 +945,9 @@ +@@ -952,8 +948,9 @@ { i += random.nextInt(64) - random.nextInt(64); k += random.nextInt(64) - random.nextInt(64); @@ -499,7 +510,7 @@ { break; } -@@ -1011,6 +1005,7 @@ +@@ -1011,6 +1008,7 @@ } chunkproviderserver.func_186027_a(p_73044_1_); @@ -507,7 +518,7 @@ for (Chunk chunk : Lists.newArrayList(chunkproviderserver.func_189548_a())) { -@@ -1055,20 +1050,19 @@ +@@ -1055,20 +1053,19 @@ this.field_72986_A.func_176135_e(this.func_175723_af().func_177732_i()); this.field_73019_z.func_75755_a(this.field_72986_A, this.field_73061_a.func_184103_al().func_72378_q()); this.field_72988_C.func_75744_a(); @@ -530,7 +541,7 @@ { this.field_72996_f.add(entity); this.func_72923_a(entity); -@@ -1080,7 +1074,7 @@ +@@ -1080,7 +1077,7 @@ { if (p_184165_1_.field_70128_L) { @@ -539,7 +550,7 @@ return false; } else -@@ -1103,7 +1097,7 @@ +@@ -1103,7 +1100,7 @@ return false; } @@ -548,7 +559,7 @@ } this.func_72973_f(entity); -@@ -1113,7 +1107,6 @@ +@@ -1113,7 +1110,6 @@ } } @@ -556,7 +567,7 @@ public void func_72923_a(Entity p_72923_1_) { super.func_72923_a(p_72923_1_); -@@ -1130,7 +1123,6 @@ +@@ -1130,7 +1126,6 @@ } } @@ -564,7 +575,7 @@ public void func_72847_b(Entity p_72847_1_) { super.func_72847_b(p_72847_1_); -@@ -1147,22 +1139,11 @@ +@@ -1147,22 +1142,11 @@ } } @@ -588,7 +599,7 @@ return true; } else -@@ -1171,7 +1152,6 @@ +@@ -1171,7 +1155,6 @@ } } @@ -596,7 +607,7 @@ public void func_72960_a(Entity p_72960_1_, byte p_72960_2_) { this.func_73039_n().func_151248_b(p_72960_1_, new SPacketEntityStatus(p_72960_1_, p_72960_2_)); -@@ -1182,12 +1162,10 @@ +@@ -1182,12 +1165,10 @@ return (ChunkProviderServer)super.func_72863_F(); } @@ -611,7 +622,7 @@ explosion.func_77278_a(); explosion.func_77279_a(false); -@@ -1198,20 +1176,15 @@ +@@ -1198,20 +1179,15 @@ for (EntityPlayer entityplayer : this.field_73010_i) { @@ -634,7 +645,7 @@ public void func_175641_c(BlockPos p_175641_1_, Block p_175641_2_, int p_175641_3_, int p_175641_4_) { BlockEventData blockeventdata = new BlockEventData(p_175641_1_, p_175641_2_, p_175641_3_, p_175641_4_); -@@ -1238,19 +1211,7 @@ +@@ -1238,19 +1214,7 @@ { if (this.func_147485_a(blockeventdata)) { @@ -655,7 +666,7 @@ } } -@@ -1261,9 +1222,7 @@ +@@ -1261,9 +1225,7 @@ private boolean func_147485_a(BlockEventData p_147485_1_) { IBlockState iblockstate = this.func_180495_p(p_147485_1_.func_180328_a()); @@ -666,7 +677,7 @@ } public void func_73041_k() -@@ -1271,7 +1230,6 @@ +@@ -1271,7 +1233,6 @@ this.field_73019_z.func_75759_a(); } @@ -674,7 +685,7 @@ protected void func_72979_l() { boolean flag = this.func_72896_J(); -@@ -1279,36 +1237,35 @@ +@@ -1279,36 +1240,35 @@ if (this.field_73003_n != this.field_73004_o) { @@ -721,7 +732,7 @@ public MinecraftServer func_73046_m() { return this.field_73061_a; -@@ -1334,51 +1291,14 @@ +@@ -1334,51 +1294,14 @@ return this.field_73019_z.func_186340_h(); } @@ -777,7 +788,7 @@ for (int i = 0; i < this.field_73010_i.size(); ++i) { -@@ -1387,45 +1307,18 @@ +@@ -1387,45 +1310,18 @@ } } @@ -827,7 +838,7 @@ { p_184159_1_.field_71135_a.func_147359_a(p_184159_9_); } -@@ -1437,20 +1330,17 @@ +@@ -1437,20 +1333,17 @@ return this.field_175741_N.get(p_175733_1_); } @@ -848,7 +859,7 @@ public BlockPos func_190528_a(String p_190528_1_, BlockPos p_190528_2_, boolean p_190528_3_) { return this.func_72863_F().func_180513_a(this, p_190528_1_, p_190528_2_, p_190528_3_); -@@ -1464,6 +1354,11 @@ +@@ -1464,6 +1357,11 @@ public FunctionManager func_193037_A() { return this.field_193036_D; diff --git a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch index 05a7141b1..10cd7229d 100644 --- a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch +++ b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch @@ -398,10 +398,11 @@ if (this.func_177419_t()) { if (p_186034_1_.func_185933_a(this, this.field_76635_g, this.field_76647_h)) -@@ -1012,8 +1017,10 @@ +@@ -1012,8 +1017,11 @@ { this.func_150809_p(); p_186034_1_.func_185931_b(this.field_76635_g, this.field_76647_h); ++ net.minecraftforge.common.ForgeHooks.postPopulateGenerate(p_186034_1_, this.field_76637_e, this.field_76635_g, this.field_76647_h); + net.minecraftforge.fml.common.registry.GameRegistry.generateWorld(this.field_76635_g, this.field_76647_h, this.field_76637_e, p_186034_1_, this.field_76637_e.func_72863_F()); this.func_76630_e(); } @@ -409,7 +410,7 @@ } public BlockPos func_177440_h(BlockPos p_177440_1_) -@@ -1068,7 +1075,7 @@ +@@ -1068,7 +1076,7 @@ { BlockPos blockpos = this.field_177447_w.poll(); @@ -418,7 +419,7 @@ { TileEntity tileentity = this.func_177422_i(blockpos); this.field_76637_e.func_175690_a(blockpos, tileentity); -@@ -1121,7 +1128,7 @@ +@@ -1121,7 +1129,7 @@ { if (this.field_76652_q.length != p_76602_1_.length) { @@ -427,7 +428,7 @@ } else { -@@ -1132,6 +1139,13 @@ +@@ -1132,6 +1140,13 @@ @SideOnly(Side.CLIENT) public void func_186033_a(PacketBuffer p_186033_1_, int p_186033_2_, boolean p_186033_3_) { @@ -441,7 +442,7 @@ boolean flag = this.field_76637_e.field_73011_w.func_191066_m(); for (int i = 0; i < this.field_76652_q.length; ++i) -@@ -1180,10 +1194,16 @@ +@@ -1180,10 +1195,16 @@ this.field_76646_k = true; this.func_76590_a(); @@ -458,7 +459,7 @@ } public Biome func_177411_a(BlockPos p_177411_1_, BiomeProvider p_177411_2_) -@@ -1194,9 +1214,14 @@ +@@ -1194,9 +1215,14 @@ if (k == 255) { @@ -475,7 +476,7 @@ } Biome biome1 = Biome.func_150568_d(k); -@@ -1212,7 +1237,7 @@ +@@ -1212,7 +1238,7 @@ { if (this.field_76651_r.length != p_76616_1_.length) { @@ -484,7 +485,7 @@ } else { -@@ -1248,14 +1273,13 @@ +@@ -1248,14 +1274,13 @@ BlockPos blockpos1 = blockpos.func_177982_a(k, (j << 4) + i1, l); boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15; @@ -501,7 +502,7 @@ { this.field_76637_e.func_175664_x(blockpos2); } -@@ -1360,9 +1384,7 @@ +@@ -1360,9 +1385,7 @@ int i = this.func_76625_h(); boolean flag = false; boolean flag1 = false; @@ -512,7 +513,7 @@ for (int j = i + 16 - 1; j > this.field_76637_e.func_181545_F() || j > 0 && !flag1; --j) { -@@ -1388,7 +1410,7 @@ +@@ -1388,7 +1411,7 @@ { blockpos$mutableblockpos.func_181079_c(blockpos$mutableblockpos.func_177958_n(), l, blockpos$mutableblockpos.func_177952_p()); @@ -521,7 +522,7 @@ { this.field_76637_e.func_175664_x(blockpos$mutableblockpos); } -@@ -1422,11 +1444,12 @@ +@@ -1422,11 +1445,12 @@ { if (this.field_76634_f.length != p_177420_1_.length) { @@ -535,7 +536,7 @@ } } -@@ -1495,5 +1518,56 @@ +@@ -1495,5 +1519,56 @@ IMMEDIATE, QUEUED, CHECK; diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch index 4b110857e..3e4779c26 100644 --- a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -111,7 +111,14 @@ public Chunk func_186025_d(int p_186025_1_, int p_186025_2_) { Chunk chunk = this.func_186028_c(p_186025_1_, p_186025_2_); -@@ -117,7 +147,7 @@ +@@ -111,13 +141,14 @@ + try + { + chunk = this.field_186029_c.func_185932_a(p_186025_1_, p_186025_2_); ++ net.minecraftforge.common.ForgeHooks.postGenerateChunk(this.field_186029_c, this.field_73251_h, chunk, p_186025_1_, p_186025_2_); + } + catch (Throwable throwable) + { CrashReport crashreport = CrashReport.func_85055_a(throwable, "Exception generating new chunk"); CrashReportCategory crashreportcategory = crashreport.func_85058_a("Chunk to be generated"); crashreportcategory.func_71507_a("Location", String.format("%d,%d", p_186025_1_, p_186025_2_)); @@ -120,7 +127,7 @@ crashreportcategory.func_71507_a("Generator", this.field_186029_c); throw new ReportedException(crashreport); } -@@ -199,8 +229,9 @@ +@@ -199,8 +230,9 @@ { this.func_73242_b(chunk); chunk.func_177427_f(false); @@ -131,7 +138,7 @@ { return false; } -@@ -215,23 +246,28 @@ +@@ -215,23 +247,28 @@ this.field_73247_e.func_75818_b(); } @@ -162,7 +169,7 @@ this.func_73242_b(chunk); this.func_73243_a(chunk); this.field_73244_f.remove(olong); -@@ -240,6 +276,8 @@ +@@ -240,6 +277,8 @@ } } @@ -171,7 +178,7 @@ this.field_73247_e.func_75817_a(); } -@@ -251,7 +289,6 @@ +@@ -251,7 +290,6 @@ return !this.field_73251_h.field_73058_d; } @@ -179,7 +186,23 @@ public String func_73148_d() { return "ServerChunkCache: " + this.field_73244_f.size() + " Drop: " + this.field_73248_b.size(); -@@ -283,7 +320,6 @@ +@@ -265,12 +303,14 @@ + @Nullable + public BlockPos func_180513_a(World p_180513_1_, String p_180513_2_, BlockPos p_180513_3_, boolean p_180513_4_) + { ++ BlockPos pos = net.minecraftforge.common.ForgeHooks.onGetNearestStructurePos(this.field_186029_c, p_180513_1_, p_180513_2_, p_180513_3_, p_180513_4_); ++ if (pos != null) return pos; + return this.field_186029_c.func_180513_a(p_180513_1_, p_180513_2_, p_180513_3_, p_180513_4_); + } + + public boolean func_193413_a(World p_193413_1_, String p_193413_2_, BlockPos p_193413_3_) + { +- return this.field_186029_c.func_193414_a(p_193413_1_, p_193413_2_, p_193413_3_); ++ return net.minecraftforge.common.ForgeHooks.isInsideStructure(this.field_186029_c, p_193413_1_, p_193413_2_, p_193413_3_) || this.field_186029_c.func_193414_a(p_193413_1_, p_193413_2_, p_193413_3_); + } + + public int func_73152_e() +@@ -283,7 +323,6 @@ return this.field_73244_f.containsKey(ChunkPos.func_77272_a(p_73149_1_, p_73149_2_)); } diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index d3422f3a8..425ade2bd 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -45,7 +45,6 @@ import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementManager; import net.minecraft.block.Block; -import net.minecraft.block.BlockFarmland; import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; @@ -110,8 +109,13 @@ import net.minecraft.util.text.event.ClickEvent; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.WorldProvider; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.GameType; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.IChunkLoader; +import net.minecraft.world.gen.IChunkGenerator; import net.minecraft.world.storage.loot.LootEntry; import net.minecraft.world.storage.loot.LootTable; import net.minecraft.world.storage.loot.LootTableManager; @@ -119,6 +123,7 @@ import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.JsonContext; import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.common.world.structure.StructureAttachRegistry; import net.minecraftforge.event.AnvilUpdateEvent; import net.minecraftforge.event.DifficultyChangeEvent; import net.minecraftforge.event.ForgeEventFactory; @@ -1512,4 +1517,25 @@ public static int getSerializerId(DataSerializer serializer, IntIdentityHashB } return id; } + + public static void postGenerateChunk(IChunkGenerator generator, World world, Chunk chunk, int x, int z){ + StructureAttachRegistry.postGenerateChunk(generator, world, chunk, x, z); + } + + public static void postPopulateGenerate(IChunkGenerator generator, World world, int x, int z){ + StructureAttachRegistry.postPopulate(generator, world, x, z); + } + + public static BlockPos onGetNearestStructurePos(IChunkGenerator generator, World worldIn, String structureName, BlockPos position, boolean findUnexplored) + { + return StructureAttachRegistry.getNearestStructurePos(generator, worldIn, structureName, position, findUnexplored); + } + + public static boolean isInsideStructure(IChunkGenerator generator, World worldIn, String structureName, BlockPos pos){ + return StructureAttachRegistry.isInsideStructure(generator, worldIn, structureName, pos); + } + + public static void onCreateChunkProvider(WorldServer worldServer, IChunkLoader loader ,WorldProvider provider, IChunkGenerator generator){ + StructureAttachRegistry.newStructureCollectionFor(worldServer, generator); + } } diff --git a/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java b/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java new file mode 100644 index 000000000..2a6583393 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java @@ -0,0 +1,101 @@ +package net.minecraftforge.common.world.structure; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.gen.IChunkGenerator; + +import javax.annotation.Nullable; +import java.util.Random; + +public interface IStructureProvider { + String getName() ; + + /** + * generate after {@link IChunkGenerator#generateChunk(int, int)} + * usually invoke {@link net.minecraft.world.gen.structure.MapGenStructure#generate(World, int, int, ChunkPrimer)} here. + * + * @param generator the {@link IChunkGenerator} + * @param world the {@link World} + * @param chunk the {@link ChunkReflection}, a special {@link ChunkPrimer} + * @param x the x of a chunk + * @param z the z of a chunk + */ + void generate(IChunkGenerator generator, World world, ChunkPrimer chunk, int x, int z); + + /** + * invoke after {@link IChunkGenerator#generateStructures(Chunk, int, int)} + * usually invoke {@link net.minecraft.world.gen.structure.MapGenStructure#generateStructure(World, Random, ChunkPos)} here + * + * @param generator the {@link IChunkGenerator} + * @param world the {@link World} + * @param random the random + * @param x the x of a chunk + * @param z the z of a chunk + */ + void generateStructure(IChunkGenerator generator, World world, Random random, int x, int z); + + /** + * locate the structure, for /locate command. + * + * @param generator + * @param worldIn + * @param structureName + * @param position + * @param findUnexplored + * @return null if not found. + */ + @Nullable + BlockPos getNearestStructurePos(IChunkGenerator generator,World worldIn, String structureName, BlockPos position, boolean findUnexplored); + + /** + * @param generator + * @param worldIn + * @param structureName + * @param pos + * @return false if not + */ + boolean isInsideStructure(IChunkGenerator generator,World worldIn, String structureName, BlockPos pos); + + class ChunkReflection extends ChunkPrimer { + private static final IBlockState DEFAULT_STATE = Blocks.AIR.getDefaultState(); + private int x; + private int z; + private Chunk chunk; + public ChunkReflection(Chunk chunk, int x, int z){ + this.chunk = chunk; + this.x = x; + this.z = z; + } + + @Override + public void setBlockState(int x, int y, int z, IBlockState state) { + chunk.setBlockState(new BlockPos(x, y, z), state); + } + + @Override + public IBlockState getBlockState(int x, int y, int z) { + return chunk.getBlockState(x, y, z); + } + + @Override + public int findGroundBlockIdx(int x, int z) + { + for (int j = 255; j >= 0; --j) + { + IBlockState iblockstate = getBlockState(x, j, z); + + if (iblockstate != null && iblockstate != DEFAULT_STATE) + { + return j; + } + } + + return 0; + } + } +} diff --git a/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java b/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java new file mode 100644 index 000000000..e96419d35 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java @@ -0,0 +1,39 @@ +package net.minecraftforge.common.world.structure; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.gen.IChunkGenerator; +import net.minecraft.world.gen.structure.MapGenStructure; + +import javax.annotation.Nullable; +import java.util.Random; + +public record SingleStructureProvider(MapGenStructure structure) implements IStructureProvider { + @Override + public String getName() { + return structure.getStructureName(); + } + + @Override + public void generate(IChunkGenerator generator, World world, ChunkPrimer chunk, int x, int z) { + structure.generate(world, x, z, chunk); + } + + @Override + public void generateStructure(IChunkGenerator generator, World world, Random random, int x, int z) { + structure.generateStructure(world, random, new ChunkPos(x,z)); + } + + @Nullable + @Override + public BlockPos getNearestStructurePos(IChunkGenerator generator, World worldIn, String structureName, BlockPos position, boolean findUnexplored) { + return structure.getNearestStructurePos(worldIn, position, findUnexplored); + } + @Override + public boolean isInsideStructure(IChunkGenerator generator, World worldIn, String structureName, BlockPos pos){ + return structure.isInsideStructure(pos); + } +} diff --git a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java new file mode 100644 index 000000000..37135f678 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java @@ -0,0 +1,43 @@ +package net.minecraftforge.common.world.structure; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.gen.IChunkGenerator; + +import javax.annotation.Nullable; +import java.util.HashMap; + +public class StructureAttachRegistry { + private static final HashMap REGISTRY = new HashMap<>(); + public static StructureCollection newStructureCollectionFor(WorldServer worldServer, IChunkGenerator chunkGenerator){ + StructureCollection collection = new StructureCollection(worldServer.getSeed(), worldServer); + REGISTRY.put(chunkGenerator, collection); + return collection; + } + public static void postGenerateChunk(IChunkGenerator generator, World world, Chunk chunk, int x, int z){ + ChunkPrimer chunkPrimer = new IStructureProvider.ChunkReflection(chunk, x, z); + StructureCollection collection = REGISTRY.get(generator); + if (collection != null) collection.generate(generator, world, chunkPrimer, x, z); + } + public static void postPopulate(IChunkGenerator generator, World world, int x, int z){ + StructureCollection collection = REGISTRY.get(generator); + if (collection != null) collection.generateStructure(generator, world, collection.random, x, z); + } + + @Nullable + public static BlockPos getNearestStructurePos(IChunkGenerator generator, World worldIn, String structureName, BlockPos position, boolean findUnexplored) + { + StructureCollection collection = REGISTRY.get(generator); + if (collection != null) return collection.getNearestStructurePos(generator, worldIn, structureName, position, findUnexplored); + return null; + } + public static boolean isInsideStructure(IChunkGenerator generator, World worldIn, String structureName, BlockPos pos){ + StructureCollection collection = REGISTRY.get(generator); + if (collection != null) return collection.isInsideStructure(generator, worldIn, structureName, pos); + return false; + } +} diff --git a/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java b/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java new file mode 100644 index 000000000..9b54906ec --- /dev/null +++ b/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java @@ -0,0 +1,67 @@ +package net.minecraftforge.common.world.structure; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.gen.IChunkGenerator; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.StructureAttachEvent; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Random; + +public class StructureCollection implements IStructureProvider, Iterable{ + public final HashMap providers = new HashMap<>(); + public final Random random; + public StructureCollection(long seed, WorldServer worldServer) { + this.random = new Random(seed); + MinecraftForge.EVENT_BUS.post(new StructureAttachEvent(this, worldServer)); + } + + public StructureCollection add(IStructureProvider provider){ + providers.put(provider.getName(), provider); + return this; + } + @Override + public String getName() { + return "StructureCollection"; + } + + @Override + public void generate(IChunkGenerator generator, World world, ChunkPrimer chunk, int x, int z) { + for(IStructureProvider structureProvider: providers.values()){ + structureProvider.generate(generator, world, chunk, x, z); + } + } + + @Override + public void generateStructure(IChunkGenerator generator, World world, Random random, int x, int z) { + for(IStructureProvider structureProvider: providers.values()){ + structureProvider.generateStructure(generator, world, random, x, z); + } + } + + @Nullable + @Override + public BlockPos getNearestStructurePos(IChunkGenerator generator, World worldIn, String structureName, BlockPos position, boolean findUnexplored) { + IStructureProvider provider = providers.get(structureName); + if (provider != null) return provider.getNearestStructurePos(generator, worldIn, structureName, position, findUnexplored); + else return null; + } + + @Override + public boolean isInsideStructure(IChunkGenerator generator, World worldIn, String structureName, BlockPos pos) { + IStructureProvider provider = providers.get(structureName); + if (provider != null) return provider.isInsideStructure(generator, worldIn, structureName, pos); + else return false; + } + + @Override + public Iterator iterator() { + return providers.values().iterator(); + } +} diff --git a/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java b/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java new file mode 100644 index 000000000..2e6bd19e5 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java @@ -0,0 +1,24 @@ +package net.minecraftforge.event.world; + +import net.minecraft.world.WorldProvider; +import net.minecraft.world.WorldServer; +import net.minecraft.world.gen.IChunkGenerator; +import net.minecraftforge.common.world.structure.StructureCollection; +import net.minecraftforge.fml.common.eventhandler.Event; + +public class StructureAttachEvent extends Event { + private StructureCollection structureCollection; + private WorldServer worldServer; + public StructureAttachEvent(StructureCollection collection, WorldServer worldServer){ + this.structureCollection = collection; + this.worldServer = worldServer; + } + + public StructureCollection getStructureCollection() { + return structureCollection; + } + + public WorldServer getWorldServer() { + return worldServer; + } +} From c398376d9c7abf11c18475ec5576b32a2f4a9cbc Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sat, 2 Mar 2024 19:10:45 +0800 Subject: [PATCH 2/4] update java doc --- src/main/java/net/minecraftforge/common/ForgeHooks.java | 4 ++++ .../common/world/structure/IStructureProvider.java | 8 ++++++-- .../common/world/structure/StructureAttachRegistry.java | 4 ++++ .../common/world/structure/StructureCollection.java | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 425ade2bd..ab776c810 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -116,6 +116,7 @@ import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.IChunkLoader; import net.minecraft.world.gen.IChunkGenerator; +import net.minecraft.world.gen.structure.MapGenStructureIO; import net.minecraft.world.storage.loot.LootEntry; import net.minecraft.world.storage.loot.LootTable; import net.minecraft.world.storage.loot.LootTableManager; @@ -1538,4 +1539,7 @@ public static boolean isInsideStructure(IChunkGenerator generator, World worldIn public static void onCreateChunkProvider(WorldServer worldServer, IChunkLoader loader ,WorldProvider provider, IChunkGenerator generator){ StructureAttachRegistry.newStructureCollectionFor(worldServer, generator); } + public static void onRecreateStructures(IChunkGenerator generator, World world, int x , int z){ + StructureAttachRegistry.recreateStructures(generator, world, x, z); + } } diff --git a/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java b/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java index 2a6583393..b71be406a 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java +++ b/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java @@ -12,6 +12,9 @@ import javax.annotation.Nullable; import java.util.Random; +/** + * If modder do not have their own special proposal. Use the base implement {@link SingleStructureProvider} is enough. + */ public interface IStructureProvider { String getName() ; @@ -21,11 +24,11 @@ public interface IStructureProvider { * * @param generator the {@link IChunkGenerator} * @param world the {@link World} - * @param chunk the {@link ChunkReflection}, a special {@link ChunkPrimer} + * @param chunk the {@link ChunkReflection}, a special {@link ChunkPrimer} , Nullable. if it is a null, it is recreating Structures * @param x the x of a chunk * @param z the z of a chunk */ - void generate(IChunkGenerator generator, World world, ChunkPrimer chunk, int x, int z); + void generate(IChunkGenerator generator, World world, @Nullable ChunkPrimer chunk, int x, int z); /** * invoke after {@link IChunkGenerator#generateStructures(Chunk, int, int)} @@ -53,6 +56,7 @@ public interface IStructureProvider { BlockPos getNearestStructurePos(IChunkGenerator generator,World worldIn, String structureName, BlockPos position, boolean findUnexplored); /** + * usually invoke {@link net.minecraft.world.gen.structure.MapGenStructure#isInsideStructure(BlockPos)} * @param generator * @param worldIn * @param structureName diff --git a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java index 37135f678..78f11f8a2 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java +++ b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java @@ -18,6 +18,10 @@ public static StructureCollection newStructureCollectionFor(WorldServer worldSer REGISTRY.put(chunkGenerator, collection); return collection; } + public static void recreateStructures(IChunkGenerator generator, World world, int x, int z){ + StructureCollection collection = REGISTRY.get(generator); + if (collection != null) collection.generate(generator, world, null, x, z); + } public static void postGenerateChunk(IChunkGenerator generator, World world, Chunk chunk, int x, int z){ ChunkPrimer chunkPrimer = new IStructureProvider.ChunkReflection(chunk, x, z); StructureCollection collection = REGISTRY.get(generator); diff --git a/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java b/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java index 9b54906ec..8524d5b06 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java +++ b/src/main/java/net/minecraftforge/common/world/structure/StructureCollection.java @@ -32,7 +32,7 @@ public String getName() { } @Override - public void generate(IChunkGenerator generator, World world, ChunkPrimer chunk, int x, int z) { + public void generate(IChunkGenerator generator, World world, ChunkPrimer chunk, int x, int z) { for(IStructureProvider structureProvider: providers.values()){ structureProvider.generate(generator, world, chunk, x, z); } From 95c7d34869ce289b46c5c7a2abb82cf6292a4028 Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sat, 2 Mar 2024 19:17:35 +0800 Subject: [PATCH 3/4] space --- .../command/CommandLocate.java.patch | 11 ++++++++++ .../world/gen/ChunkProviderServer.java.patch | 20 +++++++++++++------ .../structure/MapGenStructureIO.java.patch | 13 ++++++++++++ .../structure/SingleStructureProvider.java | 1 + .../structure/StructureAttachRegistry.java | 10 ++++++++-- 5 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 patches/minecraft/net/minecraft/command/CommandLocate.java.patch create mode 100644 patches/minecraft/net/minecraft/world/gen/structure/MapGenStructureIO.java.patch diff --git a/patches/minecraft/net/minecraft/command/CommandLocate.java.patch b/patches/minecraft/net/minecraft/command/CommandLocate.java.patch new file mode 100644 index 000000000..9da7546c5 --- /dev/null +++ b/patches/minecraft/net/minecraft/command/CommandLocate.java.patch @@ -0,0 +1,11 @@ +--- before/net/minecraft/command/CommandLocate.java ++++ after/net/minecraft/command/CommandLocate.java +@@ -54,7 +54,7 @@ + public List func_184883_a(MinecraftServer p_184883_1_, ICommandSender p_184883_2_, String[] p_184883_3_, @Nullable BlockPos p_184883_4_) + { + return p_184883_3_.length == 1 +- ? func_71530_a(p_184883_3_, new String[] {"Stronghold", "Monument", "Village", "Mansion", "EndCity", "Fortress", "Temple", "Mineshaft"}) ++ ? func_71530_a(p_184883_3_, net.minecraft.world.gen.structure.MapGenStructureIO.getStartNames()) + : Collections.emptyList(); + } + } diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch index 3e4779c26..08e4e546f 100644 --- a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -127,7 +127,15 @@ crashreportcategory.func_71507_a("Generator", this.field_186029_c); throw new ReportedException(crashreport); } -@@ -199,8 +230,9 @@ +@@ -141,6 +172,7 @@ + { + chunk.func_177432_b(this.field_73251_h.func_82737_E()); + this.field_186029_c.func_180514_a(chunk, p_73239_1_, p_73239_2_); ++ net.minecraftforge.common.ForgeHooks.onRecreateStructures(this.field_186029_c, this.field_73251_h, p_73239_1_, p_73239_2_); + } + + return chunk; +@@ -199,8 +231,9 @@ { this.func_73242_b(chunk); chunk.func_177427_f(false); @@ -138,7 +146,7 @@ { return false; } -@@ -215,23 +247,28 @@ +@@ -215,23 +248,28 @@ this.field_73247_e.func_75818_b(); } @@ -169,7 +177,7 @@ this.func_73242_b(chunk); this.func_73243_a(chunk); this.field_73244_f.remove(olong); -@@ -240,6 +277,8 @@ +@@ -240,6 +278,8 @@ } } @@ -178,7 +186,7 @@ this.field_73247_e.func_75817_a(); } -@@ -251,7 +290,6 @@ +@@ -251,7 +291,6 @@ return !this.field_73251_h.field_73058_d; } @@ -186,7 +194,7 @@ public String func_73148_d() { return "ServerChunkCache: " + this.field_73244_f.size() + " Drop: " + this.field_73248_b.size(); -@@ -265,12 +303,14 @@ +@@ -265,12 +304,14 @@ @Nullable public BlockPos func_180513_a(World p_180513_1_, String p_180513_2_, BlockPos p_180513_3_, boolean p_180513_4_) { @@ -202,7 +210,7 @@ } public int func_73152_e() -@@ -283,7 +323,6 @@ +@@ -283,7 +324,6 @@ return this.field_73244_f.containsKey(ChunkPos.func_77272_a(p_73149_1_, p_73149_2_)); } diff --git a/patches/minecraft/net/minecraft/world/gen/structure/MapGenStructureIO.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/MapGenStructureIO.java.patch new file mode 100644 index 000000000..c41813fc0 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/gen/structure/MapGenStructureIO.java.patch @@ -0,0 +1,13 @@ +--- before/net/minecraft/world/gen/structure/MapGenStructureIO.java ++++ after/net/minecraft/world/gen/structure/MapGenStructureIO.java +@@ -120,4 +120,10 @@ + StructureEndCityPieces.func_186200_a(); + WoodlandMansionPieces.func_191153_a(); + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ ++ public static String[] getStartNames(){ ++ return field_143040_a.keySet().toArray(new String[0]); ++ } + } diff --git a/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java b/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java index e96419d35..565259a7f 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java +++ b/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java @@ -32,6 +32,7 @@ public void generateStructure(IChunkGenerator generator, World world, Random ran public BlockPos getNearestStructurePos(IChunkGenerator generator, World worldIn, String structureName, BlockPos position, boolean findUnexplored) { return structure.getNearestStructurePos(worldIn, position, findUnexplored); } + @Override public boolean isInsideStructure(IChunkGenerator generator, World worldIn, String structureName, BlockPos pos){ return structure.isInsideStructure(pos); diff --git a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java index 78f11f8a2..d1b095ae0 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java +++ b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java @@ -5,28 +5,31 @@ import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkPrimer; -import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.IChunkGenerator; import javax.annotation.Nullable; import java.util.HashMap; -public class StructureAttachRegistry { +public final class StructureAttachRegistry { private static final HashMap REGISTRY = new HashMap<>(); + public static StructureCollection newStructureCollectionFor(WorldServer worldServer, IChunkGenerator chunkGenerator){ StructureCollection collection = new StructureCollection(worldServer.getSeed(), worldServer); REGISTRY.put(chunkGenerator, collection); return collection; } + public static void recreateStructures(IChunkGenerator generator, World world, int x, int z){ StructureCollection collection = REGISTRY.get(generator); if (collection != null) collection.generate(generator, world, null, x, z); } + public static void postGenerateChunk(IChunkGenerator generator, World world, Chunk chunk, int x, int z){ ChunkPrimer chunkPrimer = new IStructureProvider.ChunkReflection(chunk, x, z); StructureCollection collection = REGISTRY.get(generator); if (collection != null) collection.generate(generator, world, chunkPrimer, x, z); } + public static void postPopulate(IChunkGenerator generator, World world, int x, int z){ StructureCollection collection = REGISTRY.get(generator); if (collection != null) collection.generateStructure(generator, world, collection.random, x, z); @@ -39,9 +42,12 @@ public static BlockPos getNearestStructurePos(IChunkGenerator generator, World w if (collection != null) return collection.getNearestStructurePos(generator, worldIn, structureName, position, findUnexplored); return null; } + public static boolean isInsideStructure(IChunkGenerator generator, World worldIn, String structureName, BlockPos pos){ StructureCollection collection = REGISTRY.get(generator); if (collection != null) return collection.isInsideStructure(generator, worldIn, structureName, pos); return false; } + + private StructureAttachRegistry(){} } From b35acf6599dee96a0c4f48e6464b518b466d4f7f Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Tue, 21 May 2024 23:39:24 +0800 Subject: [PATCH 4/4] fill java doc --- .../common/world/structure/IStructureProvider.java | 12 ++++++++++-- .../world/structure/SingleStructureProvider.java | 1 + .../world/structure/StructureAttachRegistry.java | 2 +- .../event/world/StructureAttachEvent.java | 9 +++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java b/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java index b71be406a..882d0089b 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java +++ b/src/main/java/net/minecraftforge/common/world/structure/IStructureProvider.java @@ -13,7 +13,7 @@ import java.util.Random; /** - * If modder do not have their own special proposal. Use the base implement {@link SingleStructureProvider} is enough. + * If modder do not have their own special proposal, using the base implement {@link SingleStructureProvider} is enough. */ public interface IStructureProvider { String getName() ; @@ -43,7 +43,9 @@ public interface IStructureProvider { void generateStructure(IChunkGenerator generator, World world, Random random, int x, int z); /** - * locate the structure, for /locate command. + * Get the nearest structure location. + * + * Command /locate or treasure map. * * @param generator * @param worldIn @@ -56,6 +58,7 @@ public interface IStructureProvider { BlockPos getNearestStructurePos(IChunkGenerator generator,World worldIn, String structureName, BlockPos position, boolean findUnexplored); /** + * Checks whether a location is inside a structure. * usually invoke {@link net.minecraft.world.gen.structure.MapGenStructure#isInsideStructure(BlockPos)} * @param generator * @param worldIn @@ -65,6 +68,11 @@ public interface IStructureProvider { */ boolean isInsideStructure(IChunkGenerator generator,World worldIn, String structureName, BlockPos pos); + /** + * {@link ChunkPrimer} is the precursor material for building {@link Chunk|, which can achieve a large number of modifications with little overhead. + * Unfortunately, {@link ChunkPrimer} is generated and consumed internally in {@link IChunkGenerater}, and externally, we can only operate on {@link Chunk}. + * All operations of {@link ChunkReflection} are implemented on adult {@link Chunk}s. + */ class ChunkReflection extends ChunkPrimer { private static final IBlockState DEFAULT_STATE = Blocks.AIR.getDefaultState(); private int x; diff --git a/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java b/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java index 565259a7f..4fcf3aea7 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java +++ b/src/main/java/net/minecraftforge/common/world/structure/SingleStructureProvider.java @@ -12,6 +12,7 @@ import java.util.Random; public record SingleStructureProvider(MapGenStructure structure) implements IStructureProvider { + @Override public String getName() { return structure.getStructureName(); diff --git a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java index d1b095ae0..a10cea019 100644 --- a/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java +++ b/src/main/java/net/minecraftforge/common/world/structure/StructureAttachRegistry.java @@ -11,7 +11,7 @@ import java.util.HashMap; public final class StructureAttachRegistry { - private static final HashMap REGISTRY = new HashMap<>(); + private static final HashMap REGISTRY = new HashMap<>(); public static StructureCollection newStructureCollectionFor(WorldServer worldServer, IChunkGenerator chunkGenerator){ StructureCollection collection = new StructureCollection(worldServer.getSeed(), worldServer); diff --git a/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java b/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java index 2e6bd19e5..52d7a70bd 100644 --- a/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java +++ b/src/main/java/net/minecraftforge/event/world/StructureAttachEvent.java @@ -6,6 +6,15 @@ import net.minecraftforge.common.world.structure.StructureCollection; import net.minecraftforge.fml.common.eventhandler.Event; +/** + * StructureAttachEvent is fired when a dimension is ready to be appended to the structures.
+ *
+ * This event is not {@link net.minecraftforge.fml.common.eventhandler.Cancelable;}.
+ *
+ * This event does not have a result. {@link HasResult}
+ *
+ * This event is fired on the {@link net.minecraftforge.common.MinecraftForge#EVENT_BUS}. + **/ public class StructureAttachEvent extends Event { private StructureCollection structureCollection; private WorldServer worldServer;