Custom End Portal

This commit is contained in:
paulevsGitch 2021-03-19 00:11:18 +03:00
parent 22e916f4a1
commit 674d80a3de
6 changed files with 109 additions and 35 deletions

View file

@ -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<Boolean> info) {
private void bePortalGenerate(StructureWorldAccess world, ChunkGenerator generator, Random random, BlockPos blockPos, DefaultFeatureConfig config, CallbackInfoReturnable<Boolean> 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;
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}