diff --git a/src/main/java/xyz/pixelatedw/finalbeta/ModConfig.java b/src/main/java/xyz/pixelatedw/finalbeta/ModConfig.java index 4c4b01d..5614a96 100644 --- a/src/main/java/xyz/pixelatedw/finalbeta/ModConfig.java +++ b/src/main/java/xyz/pixelatedw/finalbeta/ModConfig.java @@ -30,6 +30,8 @@ public class ModConfig { "0 - Vanilla behavior\n1 - Boats will never break regardless of their speed\n2 - Boats will only break when crashing with almost max speed"); public static final Option STACK_DROP = make("Drop Held Stack", true, "Allows the player to drop the entire stack they're holding using Shift + Q (or whatever drop key they have set)"); + public static final Option ENABLE_TIME_TRACKING = make("Enable Time Tracking", true, + "Adds a Days Played entry in the F3 overlay displaying number of ingame days and real life days played in that world"); public static final Option FIX_BOW_MODEL = make("Fix bow model", true, "Makes the box model held by players and skeletons bigger and facing forward"); @@ -51,6 +53,8 @@ public class ModConfig { "Fixes furnaces consuming the bucket when using lava buckets as fuel"); public static final Option FIX_BOOKSHELVES_DROP = make("Fix Bookshelves Drops", true, "Drops 3 books when breaking a bookshelf"); + public static final Option FIX_DOUBLE_DOORS = make("Fix Double Doors", true, + "Fixes double doors not being in their correct state when pressure plates are used to open them"); private static ModConfig instance = new ModConfig(); public static final ModConfig instance() { diff --git a/src/main/java/xyz/pixelatedw/finalbeta/WyHelper.java b/src/main/java/xyz/pixelatedw/finalbeta/WyHelper.java index c03807d..c5d579e 100644 --- a/src/main/java/xyz/pixelatedw/finalbeta/WyHelper.java +++ b/src/main/java/xyz/pixelatedw/finalbeta/WyHelper.java @@ -3,6 +3,7 @@ package xyz.pixelatedw.finalbeta; import java.lang.management.ManagementFactory; import java.lang.reflect.Field; import java.time.Duration; +import java.util.HashMap; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.Player; @@ -14,6 +15,13 @@ public class WyHelper { public static final String PLAY_TIME_TAG = "PlayTime"; public static long playTime; + + // Look if they're allowed to hold all block and item data in fucking arrays + // I am also allowed to abuse maps to extend the shitty metadata excuse + // doors have ok ? I don't even care about the overhead at this point. + public static final HashMap DOOR_UPDATES = new HashMap<>(); + public static final HashMap DOOR_STATES = new HashMap<>(); + static { INSTANCE = getInstance(); } @@ -57,7 +65,7 @@ public class WyHelper { public static void cheatCommand(Player player) { -// player.dropItem(new ItemInstance(ItemType.boat, 1)); +// player.dropItem(new ItemInstance(Tile.LEVER, 1)); // int x = MathsHelper.floor(player.x); // int y = MathsHelper.floor(player.boundingBox.minY); @@ -70,7 +78,7 @@ public class WyHelper { // player.dropItem(new ItemInstance(Tile.BED, 64)); // player.dropItem(new ItemInstance(Tile.FENCE, 64)); -// player.dropItem(new ItemInstance(Tile.STONE_PRESSURE_PLATE, 64)); +// player.dropItem(new ItemInstance(Tile.BUTTON, 64)); // player.dropItem(new ItemInstance(Tile.BOOKSHELF, 64)); @@ -99,10 +107,10 @@ public class WyHelper { // animal.setPositionAndAngles(player.x + 2, player.y, player.z, 0.0f, 0.0f); // player.level.spawnEntity(animal); -// player.level.setLevelTime(0); -// player.level.getProperties().setRaining(false); -// player.level.getProperties().setRainTime(0); -// player.level.getProperties().setThundering(false); -// player.level.getProperties().setThunderTime(0); + player.level.setLevelTime(0); + player.level.getProperties().setRaining(false); + player.level.getProperties().setRainTime(0); + player.level.getProperties().setThundering(false); + player.level.getProperties().setThunderTime(0); } } diff --git a/src/main/java/xyz/pixelatedw/finalbeta/mixin/DoorTileMixin.java b/src/main/java/xyz/pixelatedw/finalbeta/mixin/DoorTileMixin.java new file mode 100644 index 0000000..526b9d7 --- /dev/null +++ b/src/main/java/xyz/pixelatedw/finalbeta/mixin/DoorTileMixin.java @@ -0,0 +1,147 @@ +package xyz.pixelatedw.finalbeta.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.Player; +import net.minecraft.level.Level; +import net.minecraft.tile.DoorTile; +import net.minecraft.tile.Tile; +import net.minecraft.tile.material.Material; +import xyz.pixelatedw.finalbeta.ModConfig; +import xyz.pixelatedw.finalbeta.WyHelper; + +@Mixin(DoorTile.class) +public class DoorTileMixin extends Tile { + + protected DoorTileMixin(int i, int j, Material arg) { + super(i, j, arg); + } + + /* + * This is horrible and with edge cases, not the best of fixes, needs more + * work preferably changing the metadata of doors to allow for more states. + * + * When times get hard always remember: + * "If it's stupid but it works, it's still stupid but it works so fuck it." + */ + + @Inject(method = "activate", at = @At("HEAD"), cancellable = true) + public void activate(Level level, int x, int y, int z, Player player, CallbackInfoReturnable cir) { + if (!ModConfig.FIX_DOUBLE_DOORS.get()) { + return; + } + + DoorTile tile = ((DoorTile) (Object) this); + if (tile.material != Material.METAL) { + int tileMeta = level.getTileMeta(x, y, z); + int yOffset = 0; + + if ((tileMeta & 8) != 0) { + setDoorTileMeta(level, x, y - 1, z, (tileMeta ^ 4) - 8); + yOffset = 1; + } else { + setDoorTileMeta(level, x, y, z, tileMeta ^ 4); + } + + boolean state = false; + int hash = generatePosHash(x, y - yOffset, z); + if (WyHelper.DOOR_STATES.containsKey(hash)) { + state = WyHelper.DOOR_STATES.get(hash); + } + WyHelper.DOOR_STATES.put(hash, !state); + cir.setReturnValue(true); + } + } + + @Inject(method = "method_837", at = @At("HEAD"), cancellable = true) + public void updateRedstoneSignal(Level level, int x, int y, int z, boolean openSignal, CallbackInfo ci) { + + if (!ModConfig.FIX_DOUBLE_DOORS.get()) { + return; + } + + // Top Tile Meta + // Open: 12 11 - 13 8 - 14 9 - 15 10 + // Close: 8 15 - 9 12 - 10 13 - 11 14 + + // Bottom Tile Meta + // Open: 4 3 - 5 0 - 6 1 - 7 2 + // Close: 0 7 - 1 4 - 2 5 - 3 6 + + int hash = generatePosHash(x, y, z); + if (WyHelper.DOOR_UPDATES.containsKey(hash)) { + long lastUpdate = System.currentTimeMillis() - WyHelper.DOOR_UPDATES.get(hash); + if (lastUpdate < 200) { + ci.cancel(); + return; + } + } + + int tileMeta = level.getTileMeta(x, y, z); + + if (openSignal) { + if (WyHelper.DOOR_STATES.containsKey(hash) && WyHelper.DOOR_STATES.get(hash)) { + ci.cancel(); + return; + } + setDoorTileMeta(level, x, y, z, Math.floorMod((tileMeta + 4), 8)); + WyHelper.DOOR_STATES.put(hash, true); + } else { + if (WyHelper.DOOR_STATES.containsKey(hash) && !WyHelper.DOOR_STATES.get(hash)) { + ci.cancel(); + return; + } + setDoorTileMeta(level, x, y, z, Math.floorMod((tileMeta - 4), 8)); + WyHelper.DOOR_STATES.put(hash, false); + } + + ci.cancel(); + } + + @Override + public void beforeDestroyedByExplosion(Level level, int x, int y, int z, int i1, float f) { + int tileMeta = level.getTileMeta(x, y, z); + int yOffset = 0; + + if ((tileMeta & 8) != 0) { + yOffset = 1; + } + + int hash = generatePosHash(x, y - yOffset, z); + WyHelper.DOOR_UPDATES.remove(hash); + WyHelper.DOOR_STATES.remove(hash); + super.beforeDestroyedByExplosion(level, x, y, z, i1, f); + } + + @Override + public void afterPlaced(Level level, int x, int y, int z, LivingEntity entity) { + int hash = generatePosHash(x, y, z); + WyHelper.DOOR_STATES.put(hash, false); + } + + private void setDoorTileMeta(Level level, int x, int y, int z, int meta) { + int tileId = level.getTileId(x, y, z); + level.setTileMeta(x, y, z, meta); + generateAndSaveHash(x, y, z); + if (level.getTileId(x, y + 1, z) == tileId) { + level.setTileMeta(x, y + 1, z, meta + 8); + generateAndSaveHash(x, y, z); + } + + level.updateRedstone(x, y - 1, z, x, y, z); + level.playLevelEvent((Player) null, 1003, x, y, z, 0); + } + + public int generatePosHash(int x, int y, int z) { + return (y * 31) + (z * 15) + x; + } + + private void generateAndSaveHash(int x, int y, int z) { + WyHelper.DOOR_UPDATES.put(generatePosHash(x, y, z), System.currentTimeMillis()); + } +} diff --git a/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelMixin.java b/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelMixin.java index 5b68dc6..b906c63 100644 --- a/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelMixin.java +++ b/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelMixin.java @@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.level.Level; +import xyz.pixelatedw.finalbeta.ModConfig; import xyz.pixelatedw.finalbeta.WyHelper; @Mixin(Level.class) @@ -13,7 +14,9 @@ public class LevelMixin { @Inject(method = "method_242", at = @At(value = "INVOKE", target = "Lnet/minecraft/level/LevelMonsterSpawner;method_1870")) public void tick(CallbackInfo ci) { - WyHelper.playTime++; + if (ModConfig.ENABLE_TIME_TRACKING.get()) { + WyHelper.playTime++; + } } } diff --git a/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelPropertiesMixin.java b/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelPropertiesMixin.java index db29ff6..4693490 100644 --- a/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelPropertiesMixin.java +++ b/src/main/java/xyz/pixelatedw/finalbeta/mixin/LevelPropertiesMixin.java @@ -1,5 +1,7 @@ package xyz.pixelatedw.finalbeta.mixin; +import java.util.Map.Entry; + import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -7,6 +9,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.level.LevelProperties; import net.minecraft.util.io.CompoundTag; +import net.minecraft.util.io.ListTag; +import xyz.pixelatedw.finalbeta.ModConfig; import xyz.pixelatedw.finalbeta.WyHelper; @Mixin(LevelProperties.class) @@ -16,17 +20,44 @@ public class LevelPropertiesMixin { @Inject(method = "", at = @At("TAIL")) public void settingSpawnTime(CompoundTag nbt, CallbackInfo ci) { - if (!nbt.containsKey(WyHelper.SPAWN_TIME_TAG)) { - this.spawnTime = System.currentTimeMillis(); - } else { - this.spawnTime = nbt.getLong(WyHelper.SPAWN_TIME_TAG); + if (ModConfig.ENABLE_TIME_TRACKING.get()) { + if (!nbt.containsKey(WyHelper.SPAWN_TIME_TAG)) { + this.spawnTime = System.currentTimeMillis(); + } else { + this.spawnTime = nbt.getLong(WyHelper.SPAWN_TIME_TAG); + } + WyHelper.playTime = nbt.getLong(WyHelper.PLAY_TIME_TAG); } - WyHelper.playTime = nbt.getLong(WyHelper.PLAY_TIME_TAG); + + if (ModConfig.FIX_DOUBLE_DOORS.get()) { + WyHelper.DOOR_STATES.clear(); + ListTag doorStates = nbt.getListTag("DoorStates"); + for (int i = 0; i < doorStates.size(); i++) { + CompoundTag doorTag = (CompoundTag) doorStates.get(i); + int hash = doorTag.getInt("hash"); + boolean state = doorTag.getBoolean("state"); + WyHelper.DOOR_STATES.put(hash, state); + } + } + } @Inject(method = "updateProperties", at = @At("TAIL")) public void updateSpawnTime(CompoundTag worldNbt, CompoundTag playerNbt, CallbackInfo ci) { - worldNbt.put(WyHelper.SPAWN_TIME_TAG, this.spawnTime); - worldNbt.put(WyHelper.PLAY_TIME_TAG, WyHelper.playTime); + if (ModConfig.ENABLE_TIME_TRACKING.get()) { + worldNbt.put(WyHelper.SPAWN_TIME_TAG, this.spawnTime); + worldNbt.put(WyHelper.PLAY_TIME_TAG, WyHelper.playTime); + } + + if (ModConfig.FIX_DOUBLE_DOORS.get()) { + ListTag doorStates = new ListTag(); + for (Entry entry : WyHelper.DOOR_STATES.entrySet()) { + CompoundTag doorTag = new CompoundTag(); + doorTag.put("hash", entry.getKey()); + doorTag.put("state", entry.getValue()); + doorStates.add(doorTag); + } + worldNbt.put("DoorStates", doorStates); + } } } diff --git a/src/main/java/xyz/pixelatedw/finalbeta/mixin/OverlayMixin.java b/src/main/java/xyz/pixelatedw/finalbeta/mixin/OverlayMixin.java index 8c3182a..98b3675 100644 --- a/src/main/java/xyz/pixelatedw/finalbeta/mixin/OverlayMixin.java +++ b/src/main/java/xyz/pixelatedw/finalbeta/mixin/OverlayMixin.java @@ -12,6 +12,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.Overlay; import net.minecraft.client.render.TextRenderer; +import xyz.pixelatedw.finalbeta.ModConfig; import xyz.pixelatedw.finalbeta.WyHelper; @Mixin(Overlay.class) @@ -39,7 +40,9 @@ public class OverlayMixin extends DrawableHelper { ) ) public void render(float f, boolean flag, int i, int j, CallbackInfo ci) { - TextRenderer textRenderer = this.minecraft.textRenderer; - this.drawTextWithShadow(textRenderer, "Days Played: " + WyHelper.getGameDaysPlayed() + " (" + WyHelper.getRealDaysPlayed() + ")", 2, 96, 14737632); + if (ModConfig.ENABLE_TIME_TRACKING.get()) { + TextRenderer textRenderer = this.minecraft.textRenderer; + this.drawTextWithShadow(textRenderer, "Days Played: " + WyHelper.getGameDaysPlayed() + " (" + WyHelper.getRealDaysPlayed() + ")", 2, 96, 14737632); + } } } diff --git a/src/main/resources/finalbeta.mixins.json b/src/main/resources/finalbeta.mixins.json index bf4a738..76bac15 100644 --- a/src/main/resources/finalbeta.mixins.json +++ b/src/main/resources/finalbeta.mixins.json @@ -35,7 +35,8 @@ "BedTileMixin", "BoatMixin", "LevelPropertiesMixin", - "LevelMixin" + "LevelMixin", + "DoorTileMixin" ], "injectors": { "defaultRequire": -1