diff --git a/src/main/java/cam72cam/mod/ModCore.java b/src/main/java/cam72cam/mod/ModCore.java index aceb15296..0b624ce0c 100644 --- a/src/main/java/cam72cam/mod/ModCore.java +++ b/src/main/java/cam72cam/mod/ModCore.java @@ -1,6 +1,7 @@ package cam72cam.mod; import cam72cam.mod.config.ConfigFile; +import cam72cam.mod.entity.CustomEntity; import cam72cam.mod.entity.ModdedEntity; import cam72cam.mod.entity.sync.EntitySync; import cam72cam.mod.event.ClientEvents; @@ -256,6 +257,7 @@ public void commonEvent(ModEvent event) { Packet.register(ModdedEntity.PassengerPositionsPacket::new, PacketDirection.ServerToClient); Packet.register(ModdedEntity.PassengerSeatPacket::new, PacketDirection.ServerToClient); Packet.register(Mouse.MousePressPacket::new, PacketDirection.ClientToServer); + Packet.register(CustomEntity.RollPacket::new, PacketDirection.ServerToClient); Command.register(new ModCoreCommand()); Light.register(); ConfigFile.sync(Config.class); diff --git a/src/main/java/cam72cam/mod/entity/CustomEntity.java b/src/main/java/cam72cam/mod/entity/CustomEntity.java index 9ed08d116..409877780 100644 --- a/src/main/java/cam72cam/mod/entity/CustomEntity.java +++ b/src/main/java/cam72cam/mod/entity/CustomEntity.java @@ -1,9 +1,16 @@ package cam72cam.mod.entity; import cam72cam.mod.entity.sync.EntitySync; -import cam72cam.mod.world.World; +import cam72cam.mod.entity.sync.TagSync; +import cam72cam.mod.math.Vec3d; +import cam72cam.mod.net.Packet; +import cam72cam.mod.serialization.TagField; +import net.minecraft.util.math.MathHelper; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; /** * Implement to create a custom modded entity @@ -17,6 +24,12 @@ public class CustomEntity extends Entity { /** Data that is automatically synchronized from server to client on tick */ public final EntitySync sync; + /** Internal roll implementation */ + @TagField + private float rotationRoll; + @TagField + private float prevRotationRoll; + /** Do not use directly. Construct via world on ModdedEntity load */ protected CustomEntity() { super(null); @@ -89,4 +102,61 @@ public List getPassengers() { return internal.getActualPassengers(); } + @Override + public float getRotationRoll() { + return rotationRoll; + } + + @Override + public void setRotationRoll(float roll) { + this.prevRotationRoll = this.rotationRoll; + this.rotationRoll = roll; + while (roll - prevRotationRoll < -180.0F) + { + prevRotationRoll -= 360.0F; + } + while (roll - prevRotationRoll >= 180.0F) + { + prevRotationRoll += 360.0F; + } + } + + @Override + public float getRotationRoll(float partialTicks) { + return (float) MathHelper.clampedLerp(prevRotationRoll, rotationRoll, partialTicks); + } + + @Override + public float getPrevRotationRoll() { + return prevRotationRoll; + } + + public void tickRoll() { + this.prevRotationRoll = rotationRoll; + } + + public static class RollPacket extends Packet { + @TagField("t") + private CustomEntity target; + @TagField("r") + private float roll; + @TagField("p") + private float prevRoll; + + public RollPacket() {} + + public RollPacket(CustomEntity entity) { + this.target = entity; + this.roll = entity.rotationRoll; + this.prevRoll = entity.prevRotationRoll; + } + + @Override + public void handle() { + if (target != null && target.internal instanceof ModdedEntity) { + target.rotationRoll = roll; + target.prevRotationRoll = prevRoll; + } + } + } } diff --git a/src/main/java/cam72cam/mod/entity/Entity.java b/src/main/java/cam72cam/mod/entity/Entity.java index 9e6f460dd..b8664c3fd 100644 --- a/src/main/java/cam72cam/mod/entity/Entity.java +++ b/src/main/java/cam72cam/mod/entity/Entity.java @@ -1,15 +1,17 @@ package cam72cam.mod.entity; import cam72cam.mod.entity.boundingbox.IBoundingBox; +import cam72cam.mod.entity.sync.TagSync; import cam72cam.mod.math.Vec3d; import cam72cam.mod.math.Vec3i; +import cam72cam.mod.serialization.TagField; import cam72cam.mod.util.SingleCache; import cam72cam.mod.world.World; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityVillager; -import net.minecraft.util.DamageSource; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.Explosion; import java.util.List; @@ -76,29 +78,55 @@ public float getRotationYaw() { return internal.rotationYaw; } + public float getRotationPitch() { + return internal.rotationPitch; + } + + public float getRotationRoll() { + return 0; + } + + public float getRotationYaw(float partialTicks) { + return (float) MathHelper.clampedLerp(internal.prevRotationYaw, internal.rotationYaw, partialTicks); + } + + public float getRotationPitch(float partialTicks) { + return (float) MathHelper.clampedLerp(internal.prevRotationPitch, internal.rotationPitch, partialTicks); + } + + public float getRotationRoll(float partialTicks) { + return 0; + } + public void setRotationYaw(float yaw) { internal.prevRotationYaw = internal.rotationYaw; internal.rotationYaw = yaw; - double d0 = internal.prevRotationYaw - yaw; - if (d0 < -180.0D) - { - internal.prevRotationYaw += 360.0F; - } - if (d0 >= 180.0D) + while (internal.rotationYaw - internal.prevRotationYaw < -180.0F) { internal.prevRotationYaw -= 360.0F; } - - } - - public float getRotationPitch() { - return internal.rotationPitch; + while (internal.rotationYaw - internal.prevRotationYaw >= 180.0F) + { + internal.prevRotationYaw += 360.0F; + } } public void setRotationPitch(float pitch) { internal.prevRotationPitch = internal.rotationPitch; internal.rotationPitch = pitch; + + while (internal.rotationPitch - internal.prevRotationPitch < -180.0F) + { + internal.prevRotationPitch -= 360.0F; + } + while (internal.rotationPitch - internal.prevRotationPitch >= 180.0F) + { + internal.prevRotationPitch += 360.0F; + } + } + + public void setRotationRoll(float roll) { } public float getPrevRotationYaw() { @@ -109,6 +137,10 @@ public float getPrevRotationPitch() { return internal.prevRotationPitch; } + public float getPrevRotationRoll() { + return 0; + } + Vec3d eyeCache; public Vec3d getPositionEyes() { if (eyeCache == null || ( diff --git a/src/main/java/cam72cam/mod/entity/ModdedEntity.java b/src/main/java/cam72cam/mod/entity/ModdedEntity.java index dfda57422..078ffa7f7 100644 --- a/src/main/java/cam72cam/mod/entity/ModdedEntity.java +++ b/src/main/java/cam72cam/mod/entity/ModdedEntity.java @@ -15,6 +15,9 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumHand; import net.minecraft.util.math.AxisAlignedBB; @@ -162,6 +165,7 @@ protected final void writeEntityToNBT(NBTTagCompound compound) { */ private void save(TagCompound data) { data.setString("custom_mob_type", type); + try { TagSerializer.serialize(data, this); } catch (SerializationException e) { @@ -226,6 +230,11 @@ public final void writeSpawnData(ByteBuf buffer) { @Override public final void onUpdate() { iTickable.onTick(); + if (!this.world.isRemote) { + self.tickRoll(); + self.setRotationRoll(self.getRotationRoll() + 5); + new CustomEntity.RollPacket(self).sendToObserving(self); + } try { self.sync.send(); } catch (SerializationException e) { diff --git a/src/main/java/cam72cam/mod/entity/sync/EntitySync.java b/src/main/java/cam72cam/mod/entity/sync/EntitySync.java index 68af450ae..5aeea9b5f 100644 --- a/src/main/java/cam72cam/mod/entity/sync/EntitySync.java +++ b/src/main/java/cam72cam/mod/entity/sync/EntitySync.java @@ -63,13 +63,16 @@ public void send() throws SerializationException { .collect(Object2IntOpenHashMap::new, (m, f) -> { TagSync tag = f.getAnnotation(TagSync.class); - TagField tagField = f.getAnnotation(TagField.class); + String name = f.getAnnotation(TagField.class).value(); + if ("".equals(name)) { + name = f.getName(); + } Class type = f.getType(); if (type == float.class || type == Float.class) { - m.put(tagField.value(), Math.max(0, Math.min(tag.floatPrecision(), 8))); + m.put(name, Math.max(0, Math.min(tag.floatPrecision(), 8))); } else if (type == double.class || type == Double.class) { - m.put(tagField.value(), Math.max(0, Math.min(tag.doublePrecision(), 8))); + m.put(name, Math.max(0, Math.min(tag.doublePrecision(), 8))); } }, Object2IntOpenHashMap::putAll); diff --git a/src/main/java/cam72cam/mod/render/EntityRenderer.java b/src/main/java/cam72cam/mod/render/EntityRenderer.java index 7ff9cc8c8..03a2f6f2c 100644 --- a/src/main/java/cam72cam/mod/render/EntityRenderer.java +++ b/src/main/java/cam72cam/mod/render/EntityRenderer.java @@ -102,7 +102,8 @@ public void doRender(ModdedEntity stock, double x, double y, double z, float ent RenderState state = new RenderState(); state.translate(x, y, z); state.rotate(180 - entityYaw, 0, 1, 0); - state.rotate(self.getRotationPitch(), 1, 0, 0); + state.rotate(self.getRotationPitch(partialTicks), 1, 0, 0); + state.rotate(self.getRotationRoll(partialTicks), 0, 0, 1); state.rotate(-90, 0, 1, 0); state.stage(RenderContext.Stage.ENTITY); renderers.get(self.getClass()).render(self, state, partialTicks); @@ -120,7 +121,8 @@ public void renderMultipass(ModdedEntity stock, double x, double y, double z, fl RenderState state = new RenderState(); state.translate(x, y, z); state.rotate(180 - entityYaw, 0, 1, 0); - state.rotate(self.getRotationPitch(), 1, 0, 0); + state.rotate(self.getRotationPitch(partialTicks), 1, 0, 0); + state.rotate(self.getRotationRoll(partialTicks), 0, 0, 1); state.rotate(-90, 0, 1, 0); state.stage(RenderContext.Stage.ENTITY); renderers.get(self.getClass()).postRender(self, state, partialTicks);