From 674d80a3de59fa7a80e900e484e7b53916d3bba4 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Fri, 19 Mar 2021 00:11:18 +0300 Subject: [PATCH] Custom End Portal --- .../mixin/common/EndPortalFeatureMixin.java | 48 ++++++++++++++++-- .../mixin/common/ServerWorldMixin.java | 40 ++++----------- .../java/ru/betterend/util/WorldDataUtil.java | 41 +++++++++++++++ .../world/generator/GeneratorOptions.java | 15 ++++++ .../structures/portal/end_portal_active.nbt | Bin 0 -> 2159 bytes .../structures/portal/end_portal_inactive.nbt | Bin 0 -> 2093 bytes 6 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 src/main/java/ru/betterend/util/WorldDataUtil.java create mode 100644 src/main/resources/data/betterend/structures/portal/end_portal_active.nbt create mode 100644 src/main/resources/data/betterend/structures/portal/end_portal_inactive.nbt diff --git a/src/main/java/ru/betterend/mixin/common/EndPortalFeatureMixin.java b/src/main/java/ru/betterend/mixin/common/EndPortalFeatureMixin.java index bd8fe824..fc69f5a8 100644 --- a/src/main/java/ru/betterend/mixin/common/EndPortalFeatureMixin.java +++ b/src/main/java/ru/betterend/mixin/common/EndPortalFeatureMixin.java @@ -2,33 +2,71 @@ package ru.betterend.mixin.common; import java.util.Random; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.structure.Structure; +import net.minecraft.structure.StructurePlacementData; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.Heightmap.Type; import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.Heightmap.Type; import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.feature.DefaultFeatureConfig; import net.minecraft.world.gen.feature.EndPortalFeature; +import ru.betterend.BetterEnd; +import ru.betterend.util.StructureHelper; +import ru.betterend.util.WorldDataUtil; import ru.betterend.world.generator.GeneratorOptions; @Mixin(EndPortalFeature.class) public class EndPortalFeatureMixin { + @Final + @Shadow + private boolean open; + @Inject(method = "generate", at = @At("HEAD"), cancellable = true) - private void bePortalGenerate(StructureWorldAccess structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, DefaultFeatureConfig defaultFeatureConfig, CallbackInfoReturnable info) { + private void bePortalGenerate(StructureWorldAccess world, ChunkGenerator generator, Random random, BlockPos blockPos, DefaultFeatureConfig config, CallbackInfoReturnable info) { if (!GeneratorOptions.hasPortal()) { info.setReturnValue(false); info.cancel(); } + else if (GeneratorOptions.replacePortal()) { + blockPos = be_updatePos(blockPos, world); + Structure structure = StructureHelper.readStructure(BetterEnd.makeID(open ? "portal/end_portal_active" : "portal/end_portal_inactive")); + BlockPos size = structure.getSize(); + blockPos = blockPos.add(-(size.getX() >> 1), -3, -(size.getZ() >> 1)); + structure.place(world, blockPos, new StructurePlacementData(), random); + info.setReturnValue(true); + info.cancel(); + } } @ModifyVariable(method = "generate", ordinal = 0, at = @At("HEAD")) - private BlockPos be_setPosOnGround(BlockPos blockPos, StructureWorldAccess structureWorldAccess) { - int y = structureWorldAccess.getChunk(blockPos).sampleHeightmap(Type.WORLD_SURFACE, blockPos.getX() & 15, blockPos.getZ() & 15); - return new BlockPos(blockPos.getX(), y, blockPos.getZ()); + private BlockPos be_setPosOnGround(BlockPos blockPos, StructureWorldAccess world) { + return be_updatePos(blockPos, world); + } + + private BlockPos be_updatePos(BlockPos blockPos, StructureWorldAccess world) { + if (GeneratorOptions.useNewGenerator()) { + BlockPos pos = GeneratorOptions.getPortalPos(); + if (pos.equals(BlockPos.ORIGIN)) { + int y = world.getChunk(blockPos).sampleHeightmap(Type.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()); + if (y < 1) { + y = 65; + } + pos = new BlockPos(pos.getX(), y, pos.getZ()); + GeneratorOptions.setPortalPos(pos); + WorldDataUtil.getRootTag().put("portal", NbtHelper.fromBlockPos(pos)); + WorldDataUtil.saveFile(); + } + return pos; + } + return blockPos; } } diff --git a/src/main/java/ru/betterend/mixin/common/ServerWorldMixin.java b/src/main/java/ru/betterend/mixin/common/ServerWorldMixin.java index 35a1f5e2..afc357d1 100644 --- a/src/main/java/ru/betterend/mixin/common/ServerWorldMixin.java +++ b/src/main/java/ru/betterend/mixin/common/ServerWorldMixin.java @@ -1,7 +1,6 @@ package ru.betterend.mixin.common; import java.io.File; -import java.io.IOException; import java.util.List; import java.util.concurrent.Executor; @@ -14,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.metadata.ModMetadata; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtIo; +import net.minecraft.nbt.NbtHelper; import net.minecraft.server.MinecraftServer; import net.minecraft.server.WorldGenerationProgressListener; import net.minecraft.server.world.ServerWorld; @@ -28,6 +27,7 @@ import net.minecraft.world.level.ServerWorldProperties; import net.minecraft.world.level.storage.LevelStorage; import ru.betterend.BetterEnd; import ru.betterend.util.DataFixerUtil; +import ru.betterend.util.WorldDataUtil; import ru.betterend.world.generator.GeneratorOptions; @Mixin(ServerWorld.class) @@ -37,26 +37,17 @@ public class ServerWorldMixin { File beData = new File(FabricLoader.getInstance().getGameDir().getParent().toString(), "saves/" + properties.getLevelName() + "/betterend_data.nbt"); ModMetadata meta = FabricLoader.getInstance().getModContainer(BetterEnd.MOD_ID).get().getMetadata(); String version = BetterEnd.isDevEnvironment() ? "development" : meta.getVersion().toString(); - boolean fix = false; - if (beData.exists()) { - CompoundTag root; - try { - root = NbtIo.read(beData); - } - catch (IOException e) { - BetterEnd.LOGGER.error("World data loading failed", e); - return; - } - String dataVersion = root.getString("version"); - fix = !dataVersion.equals(version); - } - else { - fix = true; - } + + WorldDataUtil.load(beData); + CompoundTag root = WorldDataUtil.getRootTag(); + String dataVersion = root.getString("version"); + GeneratorOptions.setPortalPos(NbtHelper.toBlockPos(root.getCompound("portal"))); + boolean fix = !dataVersion.equals(version); if (fix) { DataFixerUtil.fixData(beData.getParentFile()); - be_writeDataFile(beData, version); + root.putString("version", version); + WorldDataUtil.saveFile(); } } @@ -69,15 +60,4 @@ public class ServerWorldMixin { } } } - - private void be_writeDataFile(File file, String version) { - CompoundTag root = new CompoundTag(); - root.putString("version", version); - try { - NbtIo.write(root, file); - } - catch (IOException e) { - BetterEnd.LOGGER.error("World data saving failed", e); - } - } } diff --git a/src/main/java/ru/betterend/util/WorldDataUtil.java b/src/main/java/ru/betterend/util/WorldDataUtil.java new file mode 100644 index 00000000..4ba51df2 --- /dev/null +++ b/src/main/java/ru/betterend/util/WorldDataUtil.java @@ -0,0 +1,41 @@ +package ru.betterend.util; + +import java.io.File; +import java.io.IOException; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import ru.betterend.BetterEnd; + +public class WorldDataUtil { + private static CompoundTag root; + private static File saveFile; + + public static void load(File file) { + saveFile = file; + if (file.exists()) { + try { + root = NbtIo.read(file); + } + catch (IOException e) { + BetterEnd.LOGGER.error("World data loading failed", e); + root = new CompoundTag(); + } + return; + } + root = new CompoundTag(); + } + + public static CompoundTag getRootTag() { + return root; + } + + public static void saveFile() { + try { + NbtIo.write(root, saveFile); + } + catch (IOException e) { + BetterEnd.LOGGER.error("World data saving failed", e); + } + } +} diff --git a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java index 7e5cc0ee..baee736f 100644 --- a/src/main/java/ru/betterend/world/generator/GeneratorOptions.java +++ b/src/main/java/ru/betterend/world/generator/GeneratorOptions.java @@ -23,6 +23,8 @@ public class GeneratorOptions { public static LayerOptions smallOptions; private static boolean changeSpawn; private static BlockPos spawn; + private static BlockPos portal = BlockPos.ORIGIN; + private static boolean replacePortal; public static void init() { biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256); @@ -47,6 +49,7 @@ public class GeneratorOptions { Configs.GENERATOR_CONFIG.getInt("spawn.point", "y", 65), Configs.GENERATOR_CONFIG.getInt("spawn.point", "z", 0) ); + replacePortal = Configs.GENERATOR_CONFIG.getBooleanRoot("customEndPortal", true); } public static int getBiomeSizeLand() { @@ -108,4 +111,16 @@ public class GeneratorOptions { public static BlockPos getSpawn() { return spawn; } + + public static BlockPos getPortalPos() { + return portal; + } + + public static void setPortalPos(BlockPos portal) { + GeneratorOptions.portal = portal; + } + + public static boolean replacePortal() { + return replacePortal; + } } diff --git a/src/main/resources/data/betterend/structures/portal/end_portal_active.nbt b/src/main/resources/data/betterend/structures/portal/end_portal_active.nbt new file mode 100644 index 0000000000000000000000000000000000000000..27ef1e47fff50c2b685f7e51291bf988f87c588d GIT binary patch literal 2159 zcmaJ>3pA8z7#2s_nWDBB*PLV>I?6CAEymf}wAxWN6*3t2Tx&6?F__L`Ta#V18BXO` zvc%vom)vG(YGMsjuEQ8&YV4SXWl%0N_Wy^~h3!A@Isf~8-}`>g`#sNlUj0-Rg_Vz* z(|*d`WtV-qm_S@kydS)Ucq`3%qN3|B2kaMLkyLEPxigMBd(AQoBveOYx@kd$6`D{k zl1S2vgP4WH1}T9alp}bzFd_;eETIoEWD}POk9c;6o|Oarw8f}p8K2*6DN0}lNM6g* zy+%uhEqQ$J7*1|HpAdlesa7tu=-5t~z3zsfIFf?k7#G|bF|s(Ca#HL|%7(G9xH3hC zBpusih(NX~VXcWCMzw##4&XB2ayQXo zo$EvJIj?Lqf6al0%P^z7g0FM;(aMy%4!2x3x{~5Bid8N0pTR18;LLO_j#!Rbb zHZTk)k*yoMi?07DXT~)fdLdg8nCW${bMwZpT-jwQ%W0@fXf9YpVAlO0lAfOX>S|G4y&S=)2ZG)Y7l3D6a`xF$#YnI5yY2-=q75MqV7!0-m;c)x&- zZsldeDUKAijl_r~0b9lQQX{p}YZHO3?bs&Q(_<(EQl3`Q6eWKF+5e(Ik!fKW zxye^6XEoFi!QBb2i7L}*}u2t(dr z{3H|)$s?$PP;*z6+BgP;mO#{lfi$SR55O?f2i4_01{Dm!E59!`6Uz$3-fl}^{f|Z; zMt;(<;BBcQR27|BFaTCdIMPwOHEjQ6)z{{&edF8su4$Fw)7q+;z1u*<-s#fEU}05^ zv%xiB5PKiy!eLyewv46zNjYoWRf42$P%d;1wf`FbALj$M<|f~Rg0*kV!_zE(lhezm z@Zgdp}|_u=GqYs390s7j&sJ`!((YVIz&WH$!3U&17DE3BJEk7<9t~ z8I7pk{g~syxvJtD<0{%i=Gm6mR@RSA)$?qrcF5?yhq5M)2YW#&a{;9>t_`0&sLmt- z1QONG*&7`>lAQ~WybF&^1|$z{b&%2V)qzUP4t8%KRhyxTGYge55~_X z)h!(E_FojH1Jaq60%??S_rYD`+AzFh5}LuG`Lg$ssVQ@w$m$MmTp5gyMc5%cMzlmQ zb}(Mon#-{&)f=9y6}f;DRSU+_q*NnwtC9K?T2sN1nxrE!foSV;^DvTpmOw*7KC_)k z*-DJN8CO*@A$zpHyGm|72*Kcg#`64a!Dg3W)f&7zirKz-Wq?zkYZ2UtxY@fia69xn zqqbuGSlyW+5ds^zp%4Pb)xbqz8>%S;Gror`uD!#mwKW$;zR(yChU2S} z>IRN_h;_yvGz#B6Xyh&^`4VbCKIg(kYGg65N5&Znv;7HZ~K_4l}0kUj3zCEcr_|bCz=*0_9UPSf2;LLbM=gy@tWF{#(IdgA$V?;?;!j?Fj!C|pZ z{5yV)K8>3Y`zT>~YW_suaC~JwF;+Gvk#H>~m+Bc4ze*W=v6R=RCF@**w|!$EvGh|= F_!r1vFP{Ja literal 0 HcmV?d00001 diff --git a/src/main/resources/data/betterend/structures/portal/end_portal_inactive.nbt b/src/main/resources/data/betterend/structures/portal/end_portal_inactive.nbt new file mode 100644 index 0000000000000000000000000000000000000000..30047c922db30a555bbe5c01d0cc9e940a09825b GIT binary patch literal 2093 zcmZ`)4OCKh6gNApjyP@01gz%SaxT9q{MaOOJI=FlBA2dJ8ulQMnt^6fl8DV*>LyH= zZu-!KBisCFB_jhf1uagrQY5v+GUMv%(grM6}f4xpG^ zwo$IVN~*O(VILug=Qd=oF&`YelSFVO%i_+?yi@K36(k~XsQN;3PBP@pVuyB{+E>DW zEF{>s#+*fIu9LIez&@n?d@@0{#w?n=uoaB@JQeo{Pn@#Iu9n-4V~v|X>)LDUQy5_1 zPW$*YLMJ85xT*8&UgszSft>rsn_ThUNHO%#QA2Keg|uIDgFEcG8*5}nZ;E>Pk7G+2 z;8T6{q<6p2iBjg;l~X8X735NpoR?omD)!#Sg<;yb1nQ^65ILpE#sXI3%>x_~nJY=P zG(R6>a@;^bhyy5L_?H?}#a?&%hA>QCWs)J|SZahTq-D92LBE_rE)re$q#nTuKlK`# zO&W27pWx|08LWFyhK%g&hXb$>+6`3XhC8UfKjQ@cHF07^0;qU=8U(GDL(onN1ckM! zKL}^?Ur&Ek7^(yZAZ}Vj_Ua>GLMY;t*b3g2RqPCn5L{c1lB#o-L1UZrR?eD@gUF%0 zgwspb&^$%vqc4Z6a|)yTq-CzesS7h1YSE4;T%X4d`lwQrBvFav`OMU&ydkG0F$uCNOa zy9{HqST%K<@ruh_YLs4-2{m@nN zHgn3z*z<-bW4wNTobL8~ZEL7XvoVa}lW$4PQxy&jAF5UdRaCBcMF2K%H z3nI{X-}dqiVf~Q_p5&258a*{iL+g*s$8idxqW5Ftio~**blqJSu)l_jEO!7$Q$)BR zy|<($vxn+Dgz1_*Avu~cMXPP?^m$yqCluZO4S)H_VXTB70({%3p3acbe0^{dK975w z-{23>8`Y#~u@ya4l=zVM9s0QCsFX}As9=_{)s+susHz@J`!>~Sy?2~Mr0%wun&DN& z|L`1De;7-@x5HGP80ic?RhJD=k4}r77TTo03qQubU<5(06J27UN>&o-IK)k7772Kz zC6TT}TsBi9;8m9NA9_mPJ#?7>Eiv;5rK#M^@OF3e2M#o@l)-xP`AFO2mab;MbHfC-)xW`4&5<9%}^<_e$o32a>-YCc5q3O?>=6A~msKB(? zZ6Pl`uUMcdEs1wLt)X4h>_d5|{FU@T?P5k=^EFFAo23)@-tJ+#^hUaMms!h(d|``YDyMuT!OjZ+8K?zLV*6-%OYHoa+9LL1VZ3H zX=N1&grx&i$Avt$Od}9h4j@-P7$d}!F!U!FY6nBJTiZ;-BHz#dkW)aQr5@M=xhh&& zaq~hH9%b$9?R?