A really stupid fix for double doors, absolute going schizo over this old metadata stuff

master
Wynd 2024-01-07 19:49:07 +02:00
parent 2ab1a2ab8a
commit ed4b7f4672
7 changed files with 215 additions and 18 deletions

View File

@ -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<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> FIX_BOOKSHELVES_DROP = make("Fix Bookshelves Drops", true,
"Drops 3 books when breaking a bookshelf");
public static final Option<Boolean> 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() {

View File

@ -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<Integer, Long> DOOR_UPDATES = new HashMap<>();
public static final HashMap<Integer, Boolean> 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);
}
}

View File

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

View File

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

View File

@ -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 = "<init>", 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<Integer, Boolean> 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);
}
}
}

View File

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

View File

@ -35,7 +35,8 @@
"BedTileMixin",
"BoatMixin",
"LevelPropertiesMixin",
"LevelMixin"
"LevelMixin",
"DoorTileMixin"
],
"injectors": {
"defaultRequire": -1