package com.rwtema.funkylocomotion; import java.util.List; import java.util.WeakHashMap; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.Side; public class EntityMovingEventHandler { public static final WeakHashMap<Entity, Vec3d> client = new WeakHashMap<>(); public static final WeakHashMap<Entity, Vec3d> server = new WeakHashMap<>(); private EntityMovingEventHandler() { } public static void init() { MinecraftForge.EVENT_BUS.register(new EntityMovingEventHandler()); } public static WeakHashMap<Entity, Vec3d> getMovementMap(Side side) { return side == Side.CLIENT ? client : server; } public static void moveEntity(Entity entity, double dx, double dy, double dz) { double x = entity.posX; double y = entity.posY; double z = entity.posZ; entity.resetPositionToBB(); double kx, ky, kz; if (entity.noClip) { entity.setEntityBoundingBox(entity.getEntityBoundingBox().offset(dx, dy, dz)); entity.resetPositionToBB(); } else { double xspeed = dx; double yspeed = dy; double zpeed = dz; boolean flag = entity.onGround && entity.isSneaking() && entity instanceof EntityPlayer; if (flag) { for ( ; dx != 0.0D && entity.getEntityWorld().getCollisionBoxes(entity, entity.getEntityBoundingBox().offset(dx, -1.0D, 0.0D)).isEmpty(); xspeed = dx) { if (dx < 0.05D && dx >= -0.05D) { dx = 0.0D; } else if (dx > 0.0D) { dx -= 0.05D; } else { dx += 0.05D; } } for (; dz != 0.0D && entity.getEntityWorld().getCollisionBoxes(entity, entity.getEntityBoundingBox().offset(0.0D, -1.0D, dz)).isEmpty(); zpeed = dz) { if (dz < 0.05D && dz >= -0.05D) { dz = 0.0D; } else if (dz > 0.0D) { dz -= 0.05D; } else { dz += 0.05D; } } for (; dx != 0.0D && dz != 0.0D && entity.getEntityWorld().getCollisionBoxes(entity, entity.getEntityBoundingBox().offset(dx, -1.0D, dz)).isEmpty(); zpeed = dz) { if (dx < 0.05D && dx >= -0.05D) { dx = 0.0D; } else if (dx > 0.0D) { dx -= 0.05D; } else { dx += 0.05D; } xspeed = dx; if (dz < 0.05D && dz >= -0.05D) { dz = 0.0D; } else if (dz > 0.0D) { dz -= 0.05D; } else { dz += 0.05D; } } } List<AxisAlignedBB> list1 = entity.getEntityWorld().getCollisionBoxes(entity, entity.getEntityBoundingBox().addCoord(dx, dy, dz)); AxisAlignedBB axisalignedbb = entity.getEntityBoundingBox(); int i = 0; for (int j = list1.size(); i < j; ++i) { dy = list1.get(i).calculateYOffset(entity.getEntityBoundingBox(), dy); } entity.setEntityBoundingBox(entity.getEntityBoundingBox().offset(0.0D, dy, 0.0D)); boolean i_ = entity.onGround || yspeed != dy && yspeed < 0.0D; int j4 = 0; for (int k = list1.size(); j4 < k; ++j4) { dx = list1.get(j4).calculateXOffset(entity.getEntityBoundingBox(), dx); } entity.setEntityBoundingBox(entity.getEntityBoundingBox().offset(dx, 0.0D, 0.0D)); j4 = 0; for (int k4 = list1.size(); j4 < k4; ++j4) { dz = list1.get(j4).calculateZOffset(entity.getEntityBoundingBox(), dz); } entity.setEntityBoundingBox(entity.getEntityBoundingBox().offset(0.0D, 0.0D, dz)); if (entity.stepHeight > 0.0F && i_ && (xspeed != dx || zpeed != dz)) { double d11 = dx; double d7 = dy; double d8 = dz; AxisAlignedBB axisalignedbb1 = entity.getEntityBoundingBox(); entity.setEntityBoundingBox(axisalignedbb); dy = (double) entity.stepHeight; List<AxisAlignedBB> list = entity.getEntityWorld().getCollisionBoxes(entity, entity.getEntityBoundingBox().addCoord(xspeed, dy, zpeed)); AxisAlignedBB axisalignedbb2 = entity.getEntityBoundingBox(); AxisAlignedBB axisalignedbb3 = axisalignedbb2.addCoord(xspeed, 0.0D, zpeed); double d9 = dy; int l = 0; for (int i1 = list.size(); l < i1; ++l) { d9 = list.get(l).calculateYOffset(axisalignedbb3, d9); } axisalignedbb2 = axisalignedbb2.offset(0.0D, d9, 0.0D); double d15 = xspeed; int j1 = 0; for (int k1 = list.size(); j1 < k1; ++j1) { d15 = list.get(j1).calculateXOffset(axisalignedbb2, d15); } axisalignedbb2 = axisalignedbb2.offset(d15, 0.0D, 0.0D); double d16 = zpeed; int l1 = 0; for (int i2 = list.size(); l1 < i2; ++l1) { d16 = list.get(l1).calculateZOffset(axisalignedbb2, d16); } axisalignedbb2 = axisalignedbb2.offset(0.0D, 0.0D, d16); AxisAlignedBB axisalignedbb4 = entity.getEntityBoundingBox(); double d17 = dy; int j2 = 0; for (int k2 = list.size(); j2 < k2; ++j2) { d17 = list.get(j2).calculateYOffset(axisalignedbb4, d17); } axisalignedbb4 = axisalignedbb4.offset(0.0D, d17, 0.0D); double d18 = xspeed; int l2 = 0; for (int i3 = list.size(); l2 < i3; ++l2) { d18 = list.get(l2).calculateXOffset(axisalignedbb4, d18); } axisalignedbb4 = axisalignedbb4.offset(d18, 0.0D, 0.0D); double d19 = zpeed; int j3 = 0; for (int k3 = list.size(); j3 < k3; ++j3) { d19 = list.get(j3).calculateZOffset(axisalignedbb4, d19); } axisalignedbb4 = axisalignedbb4.offset(0.0D, 0.0D, d19); double d20 = d15 * d15 + d16 * d16; double d10 = d18 * d18 + d19 * d19; if (d20 > d10) { dx = d15; dz = d16; dy = -d9; entity.setEntityBoundingBox(axisalignedbb2); } else { dx = d18; dz = d19; dy = -d17; entity.setEntityBoundingBox(axisalignedbb4); } int l3 = 0; for (int i4 = list.size(); l3 < i4; ++l3) { dy = list.get(l3).calculateYOffset(entity.getEntityBoundingBox(), dy); } entity.setEntityBoundingBox(entity.getEntityBoundingBox().offset(0.0D, dy, 0.0D)); if (d11 * d11 + d8 * d8 >= dx * dx + dz * dz) { dx = d11; dy = d7; dz = d8; entity.setEntityBoundingBox(axisalignedbb1); } } entity.resetPositionToBB(); entity.isCollidedHorizontally = xspeed != dx || zpeed != dz; entity.isCollidedVertically = yspeed != dy; if (dy != 0) { entity.onGround = entity.isCollidedVertically && yspeed < 0.0D; } entity.isCollided = entity.isCollidedHorizontally || entity.isCollidedVertically; if (xspeed != dx) { entity.motionX = 0.0D; } if (zpeed != dz) { entity.motionZ = 0.0D; } } kx = entity.posX - x; ky = entity.posY - y; kz = entity.posZ - z; entity.prevPosX += kx; entity.prevPosY += ky; entity.prevPosZ += kz; } @SubscribeEvent public void moveEntities(TickEvent.ServerTickEvent event) { move(event); } @SubscribeEvent public void moveEntities(TickEvent.ClientTickEvent event) { move(event); } public void move(TickEvent event) { final WeakHashMap<Entity, Vec3d> map = getMovementMap(event.side); map.clear(); } }