diff --git a/gradle.properties b/gradle.properties index 56fb3b2542..68e8fe379e 100755 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx3G # forge minecraft_version=1.20.1 minecraft_version_range=[1.20.1,1.21) -forge_version=47.1.21 +forge_version=47.1.0 forge_version_range=[47,) loader_version_range=[47,) mappings_channel=parchment diff --git a/src/main/java/de/teamlapen/vampirism/VampirismMod.java b/src/main/java/de/teamlapen/vampirism/VampirismMod.java index 8f66f81274..300b1c1329 100755 --- a/src/main/java/de/teamlapen/vampirism/VampirismMod.java +++ b/src/main/java/de/teamlapen/vampirism/VampirismMod.java @@ -284,6 +284,7 @@ private void setup(final @NotNull FMLCommonSetupEvent event) { } MinecraftForge.EVENT_BUS.register(new ModPlayerEventHandler()); + ModPlayerEventHandler.registerEyeHeight(); MinecraftForge.EVENT_BUS.register(new ModEntityEventHandler()); MinecraftForge.EVENT_BUS.addListener(ModLootTables::onLootLoad); diff --git a/src/main/java/de/teamlapen/vampirism/entity/ModEntityEventHandler.java b/src/main/java/de/teamlapen/vampirism/entity/ModEntityEventHandler.java index 22fb34bddc..6a013c7549 100755 --- a/src/main/java/de/teamlapen/vampirism/entity/ModEntityEventHandler.java +++ b/src/main/java/de/teamlapen/vampirism/entity/ModEntityEventHandler.java @@ -20,6 +20,7 @@ import de.teamlapen.vampirism.entity.minion.MinionEntity; import de.teamlapen.vampirism.entity.player.VampirismPlayerAttributes; import de.teamlapen.vampirism.entity.player.vampire.VampirePlayer; +import de.teamlapen.vampirism.entity.player.vampire.actions.BatVampireAction; import de.teamlapen.vampirism.entity.vampire.VampireBaseEntity; import de.teamlapen.vampirism.items.VampirismVampireSwordItem; import de.teamlapen.vampirism.items.oil.EvasionOil; @@ -62,6 +63,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.HashSet; import java.util.Optional; import java.util.Set; @@ -247,15 +250,25 @@ public void onEntityVisibilityCheck(LivingEvent.@NotNull LivingVisibilityEvent e } @SubscribeEvent - public void onEyeHeightSet(EntityEvent.@NotNull EyeHeight event) { + public void onEyeHeightSet(EntityEvent.@NotNull Size event) { if (event.getEntity() instanceof VampireBaseEntity || event.getEntity() instanceof HunterBaseEntity) { - event.setNewEyeHeight(event.getOriginalEyeHeight() * 0.875f); + event.setNewEyeHeight(event.getOldEyeHeight() * 0.875f); } if (event.getEntity() instanceof LivingEntity) { //(CoffinBlock.setSleepSize(event, ((LivingEntity) event.getEntity())); } } + /** + * This is a workaround because the class {@link EntityEvent.EyeHeight} may not be available on runtime. Take a look at {@link de.teamlapen.vampirism.entity.player.ModPlayerEventHandler#registerEyeHeight()} + */ + @Deprecated + public static void eyeHeightReflect(Method setNewEyeHeight, Method getOldEyeHeight, T event) throws InvocationTargetException, IllegalAccessException { + if (event.getEntity() instanceof VampireBaseEntity || event.getEntity() instanceof HunterBaseEntity) { + setNewEyeHeight.invoke(event, ((Float) getOldEyeHeight.invoke(event)) * 0.875f); + } + } + @SubscribeEvent public void onItemUseFinish(LivingEntityUseItemEvent.@NotNull Finish event) { if (event.getEntity() instanceof MinionEntity) { diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/ModPlayerEventHandler.java b/src/main/java/de/teamlapen/vampirism/entity/player/ModPlayerEventHandler.java index 0f46e1730c..c02391a332 100755 --- a/src/main/java/de/teamlapen/vampirism/entity/player/ModPlayerEventHandler.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/ModPlayerEventHandler.java @@ -23,6 +23,7 @@ import de.teamlapen.vampirism.core.ModItems; import de.teamlapen.vampirism.effects.VampirismPoisonEffect; import de.teamlapen.vampirism.effects.VampirismPotion; +import de.teamlapen.vampirism.entity.ModEntityEventHandler; import de.teamlapen.vampirism.entity.factions.FactionPlayerHandler; import de.teamlapen.vampirism.entity.player.hunter.HunterPlayer; import de.teamlapen.vampirism.entity.player.vampire.VampirePlayer; @@ -62,6 +63,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.event.AttachCapabilitiesEvent; @@ -76,14 +78,21 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import net.minecraftforge.registries.ForgeRegistries; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; +import java.io.Console; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; import java.util.HashSet; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; /** * Event handler for player related events @@ -144,31 +153,75 @@ public void blockDestroyed(BlockEvent.@NotNull BreakEvent event) { } @SubscribeEvent - public void size(EntityEvent.@NotNull Size event) { + public void sizeEvent(EntityEvent.@NotNull Size event) { if (event.getEntity() instanceof Player && ((Player) event.getEntity()).getInventory() != null /*make sure we are not in the player's contructor*/) { if (event.getEntity().isAlive() && event.getEntity().position().lengthSqr() != 0 && event.getEntity().getVehicle() == null) { //Do not attempt to get capability while entity is being initialized if (VampirismPlayerAttributes.get((Player) event.getEntity()).getVampSpecial().bat) { event.setNewSize(BatVampireAction.BAT_SIZE); + event.setNewEyeHeight(BatVampireAction.BAT_EYE_HEIGHT); } else if (VampirismPlayerAttributes.get((Player) event.getEntity()).getVampSpecial().isDBNO) { event.setNewSize(EntityDimensions.fixed(0.6f, 0.95f)); + event.setNewEyeHeight(0.725f); } } } } - @SubscribeEvent - public void eyeHeight(EntityEvent.@NotNull EyeHeight event) { + /** + * This is a workaround because the class {@link EntityEvent.EyeHeight} may not be available on runtime. Take a look at {@link #registerEyeHeight()} + */ + @Deprecated + private static void eyeHeightReflect(Method setNewEyeHeight, Method getOldEyeHeight, T event) throws InvocationTargetException, IllegalAccessException { if (event.getEntity() instanceof Player && ((Player) event.getEntity()).getInventory() != null /*make sure we are not in the player's contructor*/) { if (event.getEntity().isAlive() && event.getEntity().position().lengthSqr() != 0 && event.getEntity().getVehicle() == null) { //Do not attempt to get capability while entity is being initialized if (VampirismPlayerAttributes.get((Player) event.getEntity()).getVampSpecial().bat) { - event.setNewEyeHeight(BatVampireAction.BAT_EYE_HEIGHT); + setNewEyeHeight.invoke(event, BatVampireAction.BAT_EYE_HEIGHT); } else if (VampirismPlayerAttributes.get((Player) event.getEntity()).getVampSpecial().isDBNO) { - event.setNewEyeHeight(0.725f); + setNewEyeHeight.invoke(event, 0.725f); } } } } + /** + * Performs a {@link net.minecraftforge.eventbus.api.SubscribeEvent} for {@link #eyeHeightReflect(java.lang.reflect.Method, java.lang.reflect.Method, net.minecraftforge.event.entity.EntityEvent)} because {@link EntityEvent.EyeHeight} is not available + * on compile time and may not be available on runtime depending on the forge version. + *

+ * This will only subscribe if the Class is available. + *

+ * @see + * + */ + @SuppressWarnings("SuspiciousInvocationHandlerImplementation") + @Deprecated + public static void registerEyeHeight() { + try { + var EyeHeight = Class.forName("net.minecraftforge.event.entity.EntityEvent$EyeHeight"); + Method hashCode = Object.class.getDeclaredMethod("hashCode"); + Method equals = Object.class.getDeclaredMethod("equals", Object.class); + Method toString = Object.class.getDeclaredMethod("toString"); + Method accept = Consumer.class.getDeclaredMethod("accept", Object.class); + Method setNewEyeHeight = EyeHeight.getDeclaredMethod("setNewEyeHeight", float.class); + Method getOldEyeHeight = EyeHeight.getDeclaredMethod("getOriginalEyeHeight"); + var proxy = Proxy.newProxyInstance(Consumer.class.getClassLoader(), new Class[]{Consumer.class}, (object, method, args) -> { + if (method.equals(accept)) { + eyeHeightReflect(setNewEyeHeight, getOldEyeHeight, ((EntityEvent) args[0])); + ModEntityEventHandler.eyeHeightReflect(setNewEyeHeight, getOldEyeHeight, ((EntityEvent) args[0])); + return null; + } else if (method.equals(hashCode)) { + return System.identityHashCode(object); + } else if (method.equals(equals)) { + return object == args[0]; + } else if (method.equals(toString)) { + return object.getClass().getName() + "@" + Integer.toHexString(object.hashCode()); + } + throw new UnsupportedOperationException("Method " + method + " is not supported in this proxy implementation."); + }); + MinecraftForge.EVENT_BUS.addListener(EventPriority.NORMAL, false, (Class) EyeHeight, (Consumer) proxy); + } catch (ClassNotFoundException | NoSuchMethodException ignored) { + } + } + @SubscribeEvent public void onTryMount(@NotNull EntityMountEvent event) { if (event.getEntity() instanceof Player && VampirismPlayerAttributes.get((Player) event.getEntity()).getVampSpecial().isCannotInteract()) {