diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java index 538d58b59..cc785f299 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java @@ -16,6 +16,7 @@ import noppes.npcs.client.gui.util.ITextfieldListener; import noppes.npcs.constants.EnumCombatPolicy; import noppes.npcs.constants.EnumNavType; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.roles.RoleMount; public class GuiNpcAI extends GuiNPCInterface2 implements ITextfieldListener, IGuiData { private DataAI ai; @@ -44,7 +45,12 @@ public class GuiNpcAI extends GuiNPCInterface2 implements ITextfieldListener, IG addLabel(new GuiNpcLabel(10, "ai.avoidwater", guiLeft + 150, guiTop + 17)); addButton(new GuiNpcButton(5, guiLeft + 230, guiTop + 10, 60, 20, new String[]{"gui.no", "gui.yes"}, npc.ais.avoidsWater ? 1 : 0)); addLabel(new GuiNpcLabel(11, "ai.return", guiLeft + 150, guiTop + 40)); - addButton(new GuiNpcButton(6, guiLeft + 230, guiTop + 35, 60, 20, new String[]{"gui.no", "gui.yes"}, npc.ais.returnToStart ? 1 : 0)); + int returnValue = npc.ais.returnToStart ? 1 : 0; + if (npc.advanced.role == EnumRoleType.Mount && npc.roleInterface instanceof RoleMount) { + returnValue = ((RoleMount) npc.roleInterface).getReturnToStartPreference() ? 1 : 0; + } + addButton(new GuiNpcButton(6, guiLeft + 230, guiTop + 35, 60, 20, new String[]{"gui.no", "gui.yes"}, returnValue)); + getButton(6).setEnabled(npc.advanced.role != EnumRoleType.Mount); addLabel(new GuiNpcLabel(17, "ai.leapattarget", guiLeft + 150, guiTop + 65)); addButton(new GuiNpcButton(15, guiLeft + 230, guiTop + 60, 60, 20, new String[]{"gui.no", "ai.jump", "ai.pounce"}, npc.ais.leapType)); addLabel(new GuiNpcLabel(15, "ai.indirect", guiLeft + 150, guiTop + 90)); @@ -132,7 +138,13 @@ public class GuiNpcAI extends GuiNPCInterface2 implements ITextfieldListener, IG } else if (button.id == 5) { npc.setAvoidWater(button.getValue() == 1); } else if (button.id == 6) { - ai.returnToStart = (button.getValue() == 1); + if (npc.advanced.role == EnumRoleType.Mount && npc.roleInterface instanceof RoleMount) { + ((RoleMount) npc.roleInterface).setReturnToStartPreference(button.getValue() == 1); + ai.returnToStart = false; + initGui(); + } else { + ai.returnToStart = (button.getValue() == 1); + } } else if (button.id == 7) { ai.canSwim = (button.getValue() == 1); } else if (button.id == 9) { diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index fb125982e..5602ba027 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -65,6 +65,7 @@ import net.minecraft.util.IChatComponent; import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.MinecraftForge; @@ -209,6 +210,8 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public ResourceLocation textureLocation = null; + private Entity lastRider; + public EnumAnimation currentAnimation = EnumAnimation.NONE; public int npcVersion = VersionCompatibility.ModRev; @@ -469,6 +472,8 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti super.onLivingUpdate(); + handleMountRiderState(); + if (worldObj.isRemote) { if (roleInterface != null) { roleInterface.clientUpdate(); @@ -1479,10 +1484,13 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti this.spawnExplosionParticle(); delete(); } else { - if (this.riddenByEntity != null) + if (this.riddenByEntity != null) { + stabilizeDismountedRider(this.riddenByEntity); this.riddenByEntity.mountEntity(null); + } if (this.ridingEntity != null) this.mountEntity(null); + lastRider = null; setHealth(-1); setSprinting(false); getNavigator().clearPathEntity(); @@ -2158,21 +2166,60 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti @Override public void updateRiderPosition() { - super.updateRiderPosition(); if (advanced.role == EnumRoleType.Mount && roleInterface instanceof RoleMount && riddenByEntity != null) { RoleMount mount = (RoleMount) roleInterface; - double yaw = Math.toRadians(this.renderYawOffset); - double offsetX = mount.getOffsetX(); - double offsetZ = mount.getOffsetZ(); - double rotatedX = offsetX * Math.cos(yaw) - offsetZ * Math.sin(yaw); - double rotatedZ = offsetX * Math.sin(yaw) + offsetZ * Math.cos(yaw); - double offsetY = mount.getOffsetY(); - riddenByEntity.setPosition(this.posX + rotatedX, - this.posY + this.getMountedYOffset() + riddenByEntity.getYOffset() + offsetY, - this.posZ + rotatedZ); + double scale = Math.max(0.1D, this.display.modelSize / 5.0D); + Vec3 seat = Vec3.createVectorHelper(mount.getOffsetX(), 0.0D, mount.getOffsetZ() + (0.8D * scale)); + seat.rotateAroundY((float) Math.toRadians(-this.renderYawOffset)); + double px = this.posX + seat.xCoord; + double py = this.posY + this.getMountedYOffset() + riddenByEntity.getYOffset() + mount.getOffsetY(); + double pz = this.posZ + seat.zCoord; + + riddenByEntity.setPosition(px, py, pz); + + if (riddenByEntity instanceof EntityLivingBase) { + EntityLivingBase rider = (EntityLivingBase) riddenByEntity; + rider.prevRotationPitch = rider.rotationPitch; + rider.prevRotationYaw = rider.rotationYaw; + rider.setRenderYawOffset(this.renderYawOffset); + rider.setRotationYawHead(this.renderYawOffset); + } + } else { + super.updateRiderPosition(); } } + private void handleMountRiderState() { + if (worldObj.isRemote) { + if (advanced.role != EnumRoleType.Mount || !(roleInterface instanceof RoleMount)) { + lastRider = null; + } + return; + } + + if (advanced.role != EnumRoleType.Mount || !(roleInterface instanceof RoleMount)) { + lastRider = null; + return; + } + + Entity currentRider = this.riddenByEntity; + if (currentRider != lastRider) { + if (lastRider != null) { + stabilizeDismountedRider(lastRider); + } + lastRider = currentRider; + } + } + + private void stabilizeDismountedRider(Entity rider) { + rider.motionX = 0.0D; + rider.motionY = 0.0D; + rider.motionZ = 0.0D; + rider.fallDistance = 0.0F; + rider.velocityChanged = true; + rider.onGround = true; + } + // Model Types: 0: Steve 64x32, 1: Steve 64x64, 2: Alex 64x64 public int getModelType() { return this.display.modelType; diff --git a/src/main/java/noppes/npcs/roles/RoleMount.java b/src/main/java/noppes/npcs/roles/RoleMount.java index 455f8f329..e3ee3bf25 100644 --- a/src/main/java/noppes/npcs/roles/RoleMount.java +++ b/src/main/java/noppes/npcs/roles/RoleMount.java @@ -62,6 +62,7 @@ public class RoleMount extends RoleInterface { @Override public boolean aiShouldExecute() { if (npc.ais.returnToStart) { + storedReturnToStart = true; npc.ais.returnToStart = false; } return false; @@ -91,6 +92,15 @@ public class RoleMount extends RoleInterface { return offsetZ; } + public void setReturnToStartPreference(boolean value) { + this.storedReturnToStart = value; + npc.ais.returnToStart = false; + } + + public boolean getReturnToStartPreference() { + return storedReturnToStart; + } + private float clamp(float value) { return ValueUtil.clamp(value, -5.0F, 5.0F); } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java index 53f26f5d9..8b632f7ce 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java @@ -32,6 +32,7 @@ import noppes.npcs.controllers.data.DialogOption; import noppes.npcs.controllers.data.Line; import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.roles.RoleMount; import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.constants.AnimationType; import noppes.npcs.scripted.constants.EntityType; @@ -269,13 +270,20 @@ public class ScriptNpc extends ScriptLiving imp * @param bo Whether or not the npc will try to return to his home position */ public void setReturnToHome(boolean bo) { - npc.ais.returnToStart = bo; + if (npc.advanced.role == EnumRoleType.Mount && npc.roleInterface instanceof RoleMount) { + ((RoleMount) npc.roleInterface).setReturnToStartPreference(bo); + } else { + npc.ais.returnToStart = bo; + } } /** * @return Whether or not the npc returns home */ public boolean getReturnToHome() { + if (npc.advanced.role == EnumRoleType.Mount && npc.roleInterface instanceof RoleMount) { + return ((RoleMount) npc.roleInterface).getReturnToStartPreference(); + } return npc.ais.returnToStart; }