Merge branch 'mount-movement-fix' into dev

This commit is contained in:
Kam committed 2025-12-30 17:49:27 -05:00
commit 2065d5dde5
33 files changed
+934 -313

No files matched your search

@@ -60,6 +60,7 @@ import kamkeel.npcs.network.packets.player.MailActionPacket;
import kamkeel.npcs.network.packets.player.SaveBookPacket;
import kamkeel.npcs.network.packets.player.SaveSignPacket;
import kamkeel.npcs.network.packets.player.ScreenSizePacket;
import kamkeel.npcs.network.packets.player.SpecialKeyStatePacket;
import kamkeel.npcs.network.packets.player.TransportPacket;
import kamkeel.npcs.network.packets.player.customgui.CustomGuiButtonPacket;
import kamkeel.npcs.network.packets.player.customgui.CustomGuiClosePacket;
@@ -575,6 +576,7 @@ public class PacketHandler {
PLAYER_PACKET.registerPacket(new InputDevicePacket());
PLAYER_PACKET.registerPacket(new ScreenSizePacket());
PLAYER_PACKET.registerPacket(new SpecialKeyStatePacket());
PLAYER_PACKET.registerPacket(new SyncRevisionInfoPacket());
@@ -14,6 +14,7 @@ public enum EnumPlayerPacket {
CompanionAction,
GetRole,
InputDevice,
SpecialKeyState,
ScreenSize,
MagicCycles,
@@ -0,0 +1,60 @@
package kamkeel.npcs.network.packets.player;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import kamkeel.npcs.network.AbstractPacket;
import kamkeel.npcs.network.PacketChannel;
import kamkeel.npcs.network.PacketClient;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumPlayerPacket;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import noppes.npcs.controllers.PlayerDataController;
import noppes.npcs.controllers.data.PlayerData;
import java.io.IOException;
public final class SpecialKeyStatePacket extends AbstractPacket {
private boolean pressed;
public SpecialKeyStatePacket() {
}
private SpecialKeyStatePacket(boolean pressed) {
this.pressed = pressed;
}
public static void send(boolean pressed) {
PacketClient.sendClient(new SpecialKeyStatePacket(pressed));
}
@Override
public Enum getType() {
return EnumPlayerPacket.SpecialKeyState;
}
@Override
public PacketChannel getChannel() {
return PacketHandler.PLAYER_PACKET;
}
@Override
@SideOnly(Side.CLIENT)
public void sendData(ByteBuf out) throws IOException {
out.writeBoolean(pressed);
}
@Override
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
boolean keyDown = in.readBoolean();
if (!(player instanceof EntityPlayerMP)) {
return;
}
PlayerData data = PlayerDataController.Instance.getPlayerData((EntityPlayerMP) player);
if (data != null) {
data.setSpecialKeyDown(keyDown);
}
}
}
+1 -1
View File
@@ -100,7 +100,7 @@ import noppes.npcs.scripted.NpcAPI;
import java.io.File;
import java.util.Set;
@Mod(modid = "customnpcs", name = "CustomNPC+", version = "1.10.2")
@Mod(modid = "customnpcs", name = "CustomNPC+", version = "1.10.3")
public class CustomNpcs {
@SidedProxy(clientSide = "noppes.npcs.client.ClientProxy", serverSide = "noppes.npcs.CommonProxy")
@@ -0,0 +1,63 @@
package noppes.npcs.ai;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.util.MathHelper;
import noppes.npcs.entity.EntityNPCInterface;
public class EntityAILeapAtTargetNpc extends EntityAIBase {
private final EntityNPCInterface npc;
private EntityLivingBase leapTarget;
private final float leapMotionY;
public EntityAILeapAtTargetNpc(EntityNPCInterface npc, float leapMotionY) {
this.npc = npc;
this.leapMotionY = leapMotionY;
this.setMutexBits(5);
}
@Override
public boolean shouldExecute() {
this.leapTarget = this.npc.getAttackTarget();
if (this.leapTarget == null) {
return false;
}
double distanceSq = this.npc.getDistanceSqToEntity(this.leapTarget);
if (distanceSq < 4.0D || distanceSq > 16.0D) {
return false;
}
if (!this.npc.onGround) {
return false;
}
return this.npc.getRNG().nextInt(5) == 0;
}
@Override
public boolean continueExecuting() {
boolean airborne = !this.npc.onGround;
if (!airborne) {
this.npc.setNpcJumpingState(false);
}
return airborne;
}
@Override
public void startExecuting() {
double d0 = this.leapTarget.posX - this.npc.posX;
double d1 = this.leapTarget.posZ - this.npc.posZ;
float f = MathHelper.sqrt_double(d0 * d0 + d1 * d1);
if ((double) f >= 1.0E-4D) {
this.npc.motionX += d0 / (double) f * 0.5D * 0.8D + this.npc.motionX * 0.2D;
this.npc.motionZ += d1 / (double) f * 0.5D * 0.8D + this.npc.motionZ * 0.2D;
}
this.npc.motionY = this.leapMotionY;
this.npc.setNpcJumpingState(true);
}
@Override
public void resetTask() {
this.npc.setNpcJumpingState(false);
}
}
@@ -30,7 +30,11 @@ public class EntityAIPounceTarget extends EntityAIBase {
@Override
public boolean continueExecuting() {
return !this.npc.onGround;
boolean airborne = !this.npc.onGround;
if (!airborne) {
this.npc.setNpcJumpingState(false);
}
return airborne;
}
@Override
@@ -47,6 +51,12 @@ public class EntityAIPounceTarget extends EntityAIBase {
this.npc.motionX *= this.leapSpeed;
this.npc.motionZ *= this.leapSpeed;
this.npc.motionY *= this.leapSpeed;
this.npc.setNpcJumpingState(true);
}
@Override
public void resetTask() {
this.npc.setNpcJumpingState(false);
}
public float getAngleForXYZ(double varX, double varY, double varZ, double horiDist) {
@@ -222,6 +222,7 @@ import java.util.Random;
public class ClientProxy extends CommonProxy {
public static KeyBinding NPCButton;
public static KeyBinding SpecialKey;
public static final Random RAND = new Random();
public static FontContainer Font;
@@ -288,8 +289,10 @@ public class ClientProxy extends CommonProxy {
Minecraft mc = Minecraft.getMinecraft();
NPCButton = new KeyBinding("NPC Inventory", Keyboard.KEY_N, "key.categories.customnpc");
SpecialKey = new KeyBinding("key.customnpcs.special", Keyboard.KEY_C, "key.categories.customnpc");
ClientRegistry.registerKeyBinding(NPCButton);
ClientRegistry.registerKeyBinding(SpecialKey);
new PresetController(CustomNpcs.Dir);
@@ -8,6 +8,7 @@ import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import kamkeel.npcs.network.PacketClient;
import kamkeel.npcs.network.packets.player.CheckPlayerValue;
import kamkeel.npcs.network.packets.player.InputDevicePacket;
import kamkeel.npcs.network.packets.player.SpecialKeyStatePacket;
import kamkeel.npcs.network.packets.player.ScreenSizePacket;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
@@ -23,9 +24,12 @@ import noppes.npcs.client.gui.hud.EnumHudComponent;
import noppes.npcs.client.gui.hud.HudComponent;
import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory;
import noppes.npcs.client.renderer.RenderNPCInterface;
import noppes.npcs.constants.EnumRoleType;
import noppes.npcs.constants.MarkType;
import noppes.npcs.controllers.data.MarkData;
import noppes.npcs.controllers.data.PlayerData;
import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.roles.RoleMount;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import tconstruct.client.tabs.InventoryTabCustomNpc;
@@ -42,6 +46,7 @@ public class ClientTickHandler {
private int buttonPressed = -1;
private long buttonTime = 0L;
private final int[] ignoreKeys = new int[]{157, 29, 54, 42, 184, 56, 220, 219};
private boolean lastSpecialKeyDown = false;
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onClientTick(TickEvent.ClientTickEvent event) {
@@ -52,6 +57,30 @@ public class ClientTickHandler {
}
this.prevWorld = mc.theWorld;
}
if (event.phase == Phase.START) {
EntityPlayer player = mc.thePlayer;
if (player != null) {
boolean specialKeyDown = ClientProxy.SpecialKey != null && Keyboard.isKeyDown(ClientProxy.SpecialKey.getKeyCode());
if (specialKeyDown != lastSpecialKeyDown) {
PlayerData data = CustomNpcs.proxy.getPlayerData(player);
if (data != null) {
data.setSpecialKeyDown(specialKeyDown);
}
SpecialKeyStatePacket.send(specialKeyDown);
lastSpecialKeyDown = specialKeyDown;
}
if (player.ridingEntity instanceof EntityNPCInterface) {
EntityNPCInterface mount = (EntityNPCInterface) player.ridingEntity;
if (mount.advanced.role == EnumRoleType.Mount && mount.roleInterface instanceof RoleMount) {
RoleMount role = (RoleMount) mount.roleInterface;
if (!role.isSprintAllowed() && player.isSprinting()) {
player.setSprinting(false);
}
}
}
}
}
if (event.phase == Phase.END) {
if (mc.thePlayer != null && mc.theWorld != null && !mc.isGamePaused() && ClientEventHandler.hasOverlays(mc.thePlayer)) {
renderCNPCPlayer.itemRenderer.updateEquippedItem();
@@ -4,7 +4,6 @@ import kamkeel.npcs.network.PacketClient;
import kamkeel.npcs.network.packets.request.role.RoleSavePacket;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.StatCollector;
import noppes.npcs.client.gui.util.GuiNPCInterface2;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
@@ -13,8 +12,6 @@ import noppes.npcs.client.gui.util.ITextfieldListener;
import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.roles.RoleMount;
import java.util.Locale;
public class GuiNpcMount extends GuiNPCInterface2 implements ITextfieldListener {
private final RoleMount role;
@@ -32,55 +29,82 @@ public class GuiNpcMount extends GuiNPCInterface2 implements ITextfieldListener
return;
}
int y = guiTop + 6;
addOffsetRow(0, "role.mount.offsetx", role.getOffsetX(), y);
y += 24;
addOffsetRow(1, "role.mount.offsety", role.getOffsetY(), y);
y += 24;
addOffsetRow(2, "role.mount.offsetz", role.getOffsetZ(), y);
y += 24;
addJumpRow(3, "role.mount.jumpheight", role.getJumpStrength(), y);
y += 24;
int leftLabelX = guiLeft + 4;
int leftFieldX = guiLeft + 116;
int leftY = guiTop + 6;
addLabel(new GuiNpcLabel(5, "role.mount.sprint", guiLeft + 4, y + 5));
addButton(new GuiNpcButton(5, guiLeft + 140, y, 60, 20, new String[]{"gui.no", "gui.yes"}, role.isSprintAllowed() ? 1 : 0));
leftY = addOffsetRow(0, 10, "role.mount.offsetx", role.getOffsetX(), leftLabelX, leftFieldX, leftY);
leftY = addOffsetRow(1, 11, "role.mount.offsety", role.getOffsetY(), leftLabelX, leftFieldX, leftY);
leftY = addOffsetRow(2, 12, "role.mount.offsetz", role.getOffsetZ(), leftLabelX, leftFieldX, leftY);
leftY = addJumpRow(3, 13, "role.mount.jumpheight", role.getJumpStrength(), leftLabelX, leftFieldX, leftY);
addButton(new GuiNpcButton(4, guiLeft + 4, y + 30, 80, 20, "role.mount.reset"));
addLabel(new GuiNpcLabel(4, "role.mount.sprint", leftLabelX, leftY + 5));
addButton(new GuiNpcButton(101, leftFieldX, leftY, 60, 20, new String[]{"gui.no", "gui.yes"}, role.isSprintAllowed() ? 1 : 0));
leftY += 24;
GuiNpcLabel speedLabel = new GuiNpcLabel(6, "", guiLeft + 4, y + 56);
speedLabel.label = StatCollector.translateToLocalFormatted("role.mount.walkspeed", npc.ais.getWalkingSpeed());
addLabel(speedLabel);
int rightLabelX = guiLeft + 214;
int rightFieldX = guiLeft + 320;
int rightY = guiTop + 6;
addLabel(new GuiNpcLabel(20, "role.mount.fly", rightLabelX, rightY + 5));
addButton(new GuiNpcButton(102, rightFieldX, rightY, 60, 20, new String[]{"gui.no", "gui.yes"}, role.isFlyingMountEnabled() ? 1 : 0));
rightY += 24;
if (role.isFlyingMountEnabled()) {
addLabel(new GuiNpcLabel(21, "role.mount.hover", rightLabelX, rightY + 5));
addButton(new GuiNpcButton(103, rightFieldX, rightY, 60, 20, new String[]{"gui.no", "gui.yes"}, role.isHoverModeEnabled() ? 1 : 0));
rightY += 24;
rightY = addSpeedRow(22, 14, "role.mount.ascendspeed", role.getFlyingAscendSpeed(), rightLabelX, rightFieldX, rightY, 0.1F, 3.0F, 0.60F);
rightY = addSpeedRow(23, 15, "role.mount.descendspeed", role.getFlyingDescendSpeed(), rightLabelX, rightFieldX, rightY, 0.05F, 3.0F, 0.35F);
}
}
private void addOffsetRow(int id, String translationKey, float value, int y) {
addLabel(new GuiNpcLabel(id, translationKey, guiLeft + 4, y + 5));
GuiNpcTextField field = new GuiNpcTextField(id, this, guiLeft + 140, y, 80, 20, format(value));
private int addOffsetRow(int labelId, int fieldId, String translationKey, float value, int labelX, int fieldX, int y) {
addLabel(new GuiNpcLabel(labelId, translationKey, labelX, y + 5));
GuiNpcTextField field = new GuiNpcTextField(fieldId, this, fieldX, y, 80, 20, format(value));
field.floatsOnly = true;
field.setMinMaxDefaultFloat(-5.0F, 5.0F, 0.0F);
addTextField(field);
return y + 24;
}
private void addJumpRow(int id, String translationKey, float value, int y) {
addLabel(new GuiNpcLabel(id, translationKey, guiLeft + 4, y + 5));
GuiNpcTextField field = new GuiNpcTextField(id, this, guiLeft + 140, y, 80, 20, format(value));
private int addJumpRow(int labelId, int fieldId, String translationKey, float value, int labelX, int fieldX, int y) {
addLabel(new GuiNpcLabel(labelId, translationKey, labelX, y + 5));
GuiNpcTextField field = new GuiNpcTextField(fieldId, this, fieldX, y, 80, 20, format(value));
field.floatsOnly = true;
field.setMinMaxDefaultFloat(0.1F, 15.0F, 1.0F);
addTextField(field);
return y + 24;
}
private int addSpeedRow(int labelId, int fieldId, String translationKey, float value, int labelX, int fieldX, int y, float min, float max, float defaultValue) {
addLabel(new GuiNpcLabel(labelId, translationKey, labelX, y + 5));
GuiNpcTextField field = new GuiNpcTextField(fieldId, this, fieldX, y, 80, 20, format(value));
field.floatsOnly = true;
field.setMinMaxDefaultFloat(min, max, defaultValue);
addTextField(field);
return y + 24;
}
private String format(float value) {
return String.format(Locale.ROOT, "%.2f", value);
return String.format(java.util.Locale.ROOT, "%.2f", value);
}
@Override
public void buttonEvent(GuiButton guibutton) {
if (role == null)
return;
if (guibutton.id == 4) {
role.resetOffsets();
initGui();
} else if (guibutton.id == 5 && guibutton instanceof GuiNpcButton) {
role.setSprintAllowed(((GuiNpcButton) guibutton).getValue() == 1);
if (guibutton instanceof GuiNpcButton) {
GuiNpcButton button = (GuiNpcButton) guibutton;
if (guibutton.id == 101) {
role.setSprintAllowed(button.getValue() == 1);
} else if (guibutton.id == 102) {
role.setFlyingMountEnabled(button.getValue() == 1);
initGui();
} else if (guibutton.id == 103) {
role.setHoverModeEnabled(button.getValue() == 1);
}
}
}
@@ -90,32 +114,42 @@ public class GuiNpcMount extends GuiNPCInterface2 implements ITextfieldListener
return;
float value = textfield.isFloat() ? textfield.getFloat() : 0.0F;
switch (textfield.id) {
case 0:
case 10:
role.setOffsetX(value);
break;
case 1:
case 11:
role.setOffsetY(value);
break;
case 2:
case 12:
role.setOffsetZ(value);
break;
case 3:
case 13:
role.setJumpStrength(value);
break;
case 14:
role.setFlyingAscendSpeed(value);
break;
case 15:
role.setFlyingDescendSpeed(value);
break;
}
textfield.setText(format(valueForField(textfield.id)));
}
private float valueForField(int id) {
switch (id) {
case 0:
case 10:
return role.getOffsetX();
case 1:
case 11:
return role.getOffsetY();
case 2:
case 12:
return role.getOffsetZ();
case 3:
case 13:
return role.getJumpStrength();
case 14:
return role.getFlyingAscendSpeed();
case 15:
return role.getFlyingDescendSpeed();
default:
return 0.0F;
}
@@ -84,6 +84,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData {
public ScreenSize screenSize = new ScreenSize(-1, -1);
public int profileSlot = 0;
private boolean specialKeyDown = false;
public void onLogin() {
// Continue playing animation for self when re-logging
@@ -267,6 +268,14 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData {
return this.isGUIOpen;
}
public boolean isSpecialKeyDown() {
return specialKeyDown;
}
public void setSpecialKeyDown(boolean specialKeyDown) {
this.specialKeyDown = specialKeyDown;
}
public ScreenSize getScreenSize() {
return screenSize;
}
@@ -45,6 +45,7 @@ public abstract class EntityNPCFlying extends EntityNPCInterface {
if (handleMountedMovement(p_70612_1_, p_70612_2_))
return;
if (!this.canFly() || this.hurtTime != 0 || !this.canBreathe()) {
setNpcFlyingState(false);
super.moveEntityWithHeading(p_70612_1_, p_70612_2_);
return;
}
@@ -66,11 +67,13 @@ public abstract class EntityNPCFlying extends EntityNPCInterface {
if (!this.getNavigator().noPath() && this.motionY > 0) {
this.motionY = 0;
} else {
setNpcFlyingState(false);
super.moveEntityWithHeading(p_70612_1_, p_70612_2_);
return;
}
}
this.flyLimitAllow = true;
setNpcFlyingState(true);
double d3 = this.motionY;
super.moveEntityWithHeading(p_70612_1_, p_70612_2_);
@@ -97,12 +100,15 @@ public abstract class EntityNPCFlying extends EntityNPCInterface {
}
@Override
protected void doMountedMovement(float strafe, float forward, float moveSpeed) {
public void performMountedMovement(float strafe, float forward, float moveSpeed) {
if (!this.canFly() || this.hurtTime != 0 || !this.canBreathe()) {
super.doMountedMovement(strafe, forward, moveSpeed);
setNpcFlyingState(false);
super.performMountedMovement(strafe, forward, moveSpeed);
return;
}
boolean flightModeActive = isMountFlightModeActive();
boolean aboveLimit = false;
double heightOffGround = this.posY - this.worldObj.getTopSolidOrLiquidBlock((int) this.posX, (int) this.posZ);
if (heightOffGround < 0) {
@@ -120,14 +126,22 @@ public abstract class EntityNPCFlying extends EntityNPCInterface {
if (!this.getNavigator().noPath() && this.motionY > 0) {
this.motionY = 0;
} else {
super.doMountedMovement(strafe, forward, moveSpeed);
setNpcFlyingState(false);
super.performMountedMovement(strafe, forward, moveSpeed);
return;
}
}
this.flyLimitAllow = true;
setNpcFlyingState(true);
if (flightModeActive) {
super.performMountedMovement(strafe, forward, moveSpeed);
this.velocityChanged = true;
return;
}
double d3 = this.motionY;
super.doMountedMovement(strafe, forward, moveSpeed);
super.performMountedMovement(strafe, forward, moveSpeed);
this.motionY = d3;
if (this.getNavigator().noPath()) {
@@ -32,7 +32,6 @@ import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILeapAtTarget;
import net.minecraft.entity.ai.EntityAIOpenDoor;
import net.minecraft.entity.ai.EntityAIRestrictSun;
import net.minecraft.entity.ai.EntityAISwimming;
@@ -101,6 +100,7 @@ import noppes.npcs.ai.EntityAIMoveIndoors;
import noppes.npcs.ai.EntityAIMovingPath;
import noppes.npcs.ai.EntityAIOrbitTarget;
import noppes.npcs.ai.EntityAIPanic;
import noppes.npcs.ai.EntityAILeapAtTargetNpc;
import noppes.npcs.ai.EntityAIPounceTarget;
import noppes.npcs.ai.EntityAIRangedAttack;
import noppes.npcs.ai.EntityAIReturn;
@@ -160,6 +160,7 @@ import noppes.npcs.scripted.NpcAPI;
import noppes.npcs.scripted.entity.ScriptNpc;
import noppes.npcs.scripted.event.NpcEvent;
import noppes.npcs.util.GameProfileAlt;
import noppes.npcs.util.NPCMountUtil;
import java.io.IOException;
import java.util.ArrayList;
@@ -211,7 +212,9 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
public ResourceLocation textureLocation = null;
private Entity lastRider;
private final NPCMountUtil.MountState mountState = new NPCMountUtil.MountState();
private static final int NPC_STATE_FLAG_FLYING = 1;
private static final int NPC_STATE_FLAG_JUMPING = 1 << 1;
public EnumAnimation currentAnimation = EnumAnimation.NONE;
@@ -282,6 +285,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
this.dataWatcher.addObject(14, Integer.valueOf(0)); // Animation
this.dataWatcher.addObject(15, Integer.valueOf(0)); // isWalking
this.dataWatcher.addObject(16, ""); // Role
this.dataWatcher.addObject(17, Byte.valueOf((byte) 0)); // Mount state flags
}
protected boolean isAIEnabled() {
@@ -967,7 +971,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
*/
public void setLeapTask() {
if (this.ais.leapType == 1)
this.tasks.addTask(this.taskCount++, aiLeap = new EntityAILeapAtTarget(this, 0.4F));
this.tasks.addTask(this.taskCount++, aiLeap = new EntityAILeapAtTargetNpc(this, 0.4F));
if (this.ais.leapType == 2)
this.tasks.addTask(this.taskCount++, aiLeap = new EntityAIPounceTarget(this));
}
@@ -1486,13 +1490,14 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
delete();
} else {
if (this.riddenByEntity != null) {
stabilizeDismountedRider(this.riddenByEntity);
NPCMountUtil.stabilizeDismountedRider(this.riddenByEntity);
this.riddenByEntity.mountEntity(null);
haltMountedMotion();
NPCMountUtil.haltMountedMotion(this, mountState);
}
if (this.ridingEntity != null)
this.mountEntity(null);
lastRider = null;
mountState.lastRider = null;
NPCMountUtil.resetMountedFlightState(this, mountState);
setHealth(-1);
setSprinting(false);
getNavigator().clearPathEntity();
@@ -1623,7 +1628,32 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
}
public boolean isFlying() {
return isWalking() && !onGround;
return isNpcFlying();
}
public boolean isNpcFlying() {
return (dataWatcher.getWatchableObjectByte(17) & NPC_STATE_FLAG_FLYING) != 0;
}
public boolean isNpcJumping() {
return (dataWatcher.getWatchableObjectByte(17) & NPC_STATE_FLAG_JUMPING) != 0;
}
private void setNpcStateFlag(int mask, boolean value) {
byte current = dataWatcher.getWatchableObjectByte(17);
byte updated = value ? (byte) (current | mask) : (byte) (current & ~mask);
if (current != updated) {
dataWatcher.updateObject(17, updated);
}
}
public void setNpcFlyingState(boolean flying) {
setNpcStateFlag(NPC_STATE_FLAG_FLYING, flying);
}
public void setNpcJumpingState(boolean jumping) {
setNpcStateFlag(NPC_STATE_FLAG_JUMPING, jumping);
this.isJumping = jumping;
}
public void setBoolFlag(boolean bo, int id) {
@@ -1872,9 +1902,12 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
}
@Override
protected void fall(float par1) {
protected void fall(float distance) {
if (NPCMountUtil.isFlyingMountWithFlightEnabled(this)) {
return;
}
if (!this.stats.noFallDamage)
super.fall(par1);
super.fall(distance);
}
@Override
@@ -2089,64 +2122,83 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
}
protected boolean handleMountedMovement(float strafe, float forward) {
if (advanced.role != EnumRoleType.Mount || !(roleInterface instanceof RoleMount))
return false;
if (riddenByEntity != null && !(riddenByEntity instanceof EntityPlayer)) {
riddenByEntity.mountEntity(null);
return false;
}
if (!(riddenByEntity instanceof EntityPlayer))
return false;
RoleMount mount = (RoleMount) roleInterface;
EntityPlayer rider = (EntityPlayer) riddenByEntity;
this.prevRotationYaw = this.rotationYaw = rider.rotationYaw;
this.rotationPitch = rider.rotationPitch * 0.5F;
this.setRotation(this.rotationYaw, this.rotationPitch);
this.renderYawOffset = this.rotationYaw;
this.rotationYawHead = this.rotationYaw;
float controlledStrafe = rider.moveStrafing * 0.5F;
float controlledForward = rider.moveForward;
if (controlledForward <= 0.0F) {
controlledForward *= 0.25F;
}
float moveSpeed = Math.max(0.1F, getSpeed());
boolean riderSprinting = rider.isSprinting() && mount.isSprintAllowed();
if (riderSprinting) {
moveSpeed *= 1.2F;
}
if (!mount.isSprintAllowed() && rider.isSprinting()) {
rider.setSprinting(false);
}
this.setSprinting(riderSprinting);
this.stepHeight = 1.0F;
this.jumpMovementFactor = moveSpeed * 0.1F;
this.getNavigator().clearPathEntity();
this.setAttackTarget(null);
this.setRevengeTarget(null);
this.fallDistance = 0.0F;
rider.fallDistance = 0.0F;
applyMountedVerticalMotion(rider, moveSpeed, controlledForward);
doMountedMovement(controlledStrafe, controlledForward, moveSpeed);
return true;
return NPCMountUtil.handleMountedMovement(this, mountState, strafe, forward);
}
protected void doMountedMovement(float strafe, float forward, float moveSpeed) {
public void performMountedMovement(float strafe, float forward, float moveSpeed) {
this.moveStrafing = strafe;
this.moveForward = forward;
if (!worldObj.isRemote) {
this.setAIMoveSpeed(moveSpeed);
super.moveEntityWithHeading(strafe, forward);
boolean flightMode = isMountFlightModeActive();
double prevMotionX = this.motionX;
double prevMotionY = this.motionY;
double prevMotionZ = this.motionZ;
float previousJumpFactor = this.jumpMovementFactor;
float appliedJumpFactor = getMountedAirStrafeFactor(moveSpeed, flightMode);
this.jumpMovementFactor = appliedJumpFactor;
this.setAIMoveSpeed(moveSpeed);
super.moveEntityWithHeading(strafe, forward);
if (flightMode) {
this.motionY = prevMotionY;
this.isAirBorne = true;
}
this.jumpMovementFactor = previousJumpFactor;
if (!worldObj.isRemote) {
double newMotionX = this.motionX;
double newMotionY = this.motionY;
double newMotionZ = this.motionZ;
if (Math.abs(newMotionX - prevMotionX) > 1.0E-5D || Math.abs(newMotionY - prevMotionY) > 1.0E-5D || Math.abs(newMotionZ - prevMotionZ) > 1.0E-5D) {
this.velocityChanged = true;
}
}
syncMountedRiderVelocity();
updateMountedLimbSwing();
}
protected boolean isMountFlightModeActive() {
return NPCMountUtil.isMountInFlightMode(mountState);
}
private float getMountedAirStrafeFactor(float moveSpeed, boolean flightMode) {
if (moveSpeed <= 0.0F) {
return 0.0F;
}
if (!flightMode) {
return moveSpeed * 0.1F;
}
return moveSpeed * 0.5F;
}
private void syncMountedRiderVelocity() {
if (!(this.riddenByEntity instanceof EntityLivingBase)) {
return;
}
EntityLivingBase rider = (EntityLivingBase) this.riddenByEntity;
double riderPrevMotionX = rider.motionX;
double riderPrevMotionY = rider.motionY;
double riderPrevMotionZ = rider.motionZ;
rider.motionX = this.motionX;
rider.motionY = this.motionY;
rider.motionZ = this.motionZ;
rider.fallDistance = 0.0F;
rider.isAirBorne = !this.onGround;
if (!worldObj.isRemote) {
if (Math.abs(rider.motionX - riderPrevMotionX) > 1.0E-5D || Math.abs(rider.motionY - riderPrevMotionY) > 1.0E-5D || Math.abs(rider.motionZ - riderPrevMotionZ) > 1.0E-5D) {
rider.velocityChanged = true;
}
}
}
private void updateMountedLimbSwing() {
this.prevLimbSwingAmount = this.limbSwingAmount;
double deltaX = this.posX - this.prevPosX;
double deltaZ = this.posZ - this.prevPosZ;
@@ -2162,46 +2214,6 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
this.limbSwing += this.limbSwingAmount;
}
protected void applyMountedVerticalMotion(EntityLivingBase rider, float moveSpeed, float forward) {
if (!(roleInterface instanceof RoleMount)) {
return;
}
RoleMount mount = (RoleMount) roleInterface;
double jumpFactor = MathHelper.clamp_double(mount.getJumpStrength(), 0.1D, 3.0D);
if (canFly()) {
double verticalBase = Math.max(0.1D, moveSpeed * 0.6D);
double vertical = MathHelper.clamp_double(verticalBase * jumpFactor, 0.05D, 2.0D);
if (rider.isJumping) {
this.motionY = Math.min(this.motionY + vertical, vertical);
this.isAirBorne = true;
this.velocityChanged = true;
} else {
float pitch = rider.rotationPitch;
if (pitch < -10F) {
this.motionY = vertical;
} else if (pitch > 10F) {
this.motionY = -vertical;
} else if (!this.onGround) {
this.motionY *= 0.6D;
}
}
} else if (rider.isJumping && this.onGround) {
double baseVelocity = MathHelper.clamp_double(0.4D + moveSpeed * 1.5D, 0.2D, 1.2D);
double jumpVelocity = MathHelper.clamp_double(baseVelocity * jumpFactor, 0.2D, 2.0D);
this.motionY = jumpVelocity;
this.isAirBorne = true;
this.velocityChanged = true;
if (forward > 0.0F) {
float yawRadians = this.rotationYaw * (float) Math.PI / 180.0F;
double boost = 0.4D * forward;
this.motionX += -MathHelper.sin(yawRadians) * boost;
this.motionZ += MathHelper.cos(yawRadians) * boost;
}
ForgeHooks.onLivingJump(this);
}
}
@Override
public boolean allowLeashing() {
return false;
@@ -2240,71 +2252,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
}
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 != null && !(currentRider instanceof EntityPlayer)) {
Entity dismount = currentRider;
dismount.mountEntity(null);
stabilizeDismountedRider(dismount);
haltMountedMotion();
currentRider = null;
}
if (currentRider != lastRider) {
if (lastRider != null) {
stabilizeDismountedRider(lastRider);
haltMountedMotion();
}
lastRider = currentRider;
}
}
private void stabilizeDismountedRider(Entity rider) {
boolean wasOnGround = rider.onGround;
double previousMotionX = rider.motionX;
double previousMotionY = rider.motionY;
double previousMotionZ = rider.motionZ;
float previousFall = rider.fallDistance;
if (wasOnGround) {
rider.motionX = 0.0D;
rider.motionY = 0.0D;
rider.motionZ = 0.0D;
rider.fallDistance = 0.0F;
rider.onGround = true;
} else {
rider.motionX = previousMotionX;
rider.motionY = previousMotionY;
rider.motionZ = previousMotionZ;
rider.fallDistance = previousFall;
}
rider.velocityChanged = true;
}
private void haltMountedMotion() {
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
this.velocityChanged = true;
this.isAirBorne = false;
this.setSprinting(false);
this.moveForward = 0.0F;
this.moveStrafing = 0.0F;
this.setAIMoveSpeed(0.0F);
this.limbSwingAmount = 0.0F;
this.limbSwing = 0.0F;
this.getNavigator().clearPathEntity();
NPCMountUtil.handleMountRiderState(this, mountState);
}
// Model Types: 0: Steve 64x32, 1: Steve 64x64, 2: Alex 64x64
@@ -94,6 +94,7 @@ public class EntityNpcDragon extends EntityNPCInterface {
field_40172_ax += f1 * 0.5F;
}
super.onLivingUpdate();
this.isFlying = isNpcFlying();
}
// public float ticks = 0.0f;
@@ -35,4 +35,10 @@ public class EntityNpcPony extends EntityNPCInterface {
super.onUpdate();
}
@Override
public void onLivingUpdate() {
super.onLivingUpdate();
this.isFlying = isNpcFlying();
}
}
+55 -4
View File
@@ -10,12 +10,13 @@ public class RoleMount extends RoleInterface {
private float offsetX;
private float offsetY;
private float offsetZ;
private static final float MIN_JUMP_STRENGTH = 0.1F;
private static final float MAX_JUMP_STRENGTH = 3.0F;
private boolean storedReturnToStart;
private float jumpStrength = 1.0F;
private boolean allowSprint = true;
private boolean flyingMountEnabled = false;
private boolean hoverMode = false;
private float flyingAscendSpeed = 0.60F;
private float flyingDescendSpeed = 0.35F;
public RoleMount(EntityNPCInterface npc) {
super(npc);
@@ -31,6 +32,10 @@ public class RoleMount extends RoleInterface {
compound.setBoolean("MountReturnFlag", storedReturnToStart);
compound.setFloat("MountJumpStrength", jumpStrength);
compound.setBoolean("MountAllowSprint", allowSprint);
compound.setBoolean("MountAllowFlying", flyingMountEnabled);
compound.setBoolean("MountHoverMode", hoverMode);
compound.setFloat("MountFlyingAscendSpeed", flyingAscendSpeed);
compound.setFloat("MountFlyingDescendSpeed", flyingDescendSpeed);
return compound;
}
@@ -50,6 +55,20 @@ public class RoleMount extends RoleInterface {
jumpStrength = 1.0F;
}
allowSprint = !compound.hasKey("MountAllowSprint") || compound.getBoolean("MountAllowSprint");
flyingMountEnabled = compound.hasKey("MountAllowFlying") && compound.getBoolean("MountAllowFlying");
hoverMode = compound.hasKey("MountHoverMode") && compound.getBoolean("MountHoverMode");
if (compound.hasKey("MountFlyingAscendSpeed")) {
setFlyingAscendSpeed(compound.getFloat("MountFlyingAscendSpeed"));
} else {
flyingAscendSpeed = 0.60F;
}
if (compound.hasKey("MountFlyingDescendSpeed")) {
setFlyingDescendSpeed(compound.getFloat("MountFlyingDescendSpeed"));
} else if (compound.hasKey("MountFlyingFallSpeed")) {
setFlyingDescendSpeed(compound.getFloat("MountFlyingFallSpeed"));
} else {
flyingDescendSpeed = 0.35F;
}
npc.ais.returnToStart = false;
}
@@ -106,7 +125,7 @@ public class RoleMount extends RoleInterface {
}
public void setJumpStrength(float value) {
this.jumpStrength = ValueUtil.clamp(value, MIN_JUMP_STRENGTH, MAX_JUMP_STRENGTH);
this.jumpStrength = ValueUtil.clamp(value, 0.1F, 3.0F);
}
public float getJumpStrength() {
@@ -121,6 +140,38 @@ public class RoleMount extends RoleInterface {
return allowSprint;
}
public void setFlyingMountEnabled(boolean enabled) {
this.flyingMountEnabled = enabled;
}
public boolean isFlyingMountEnabled() {
return flyingMountEnabled;
}
public void setHoverModeEnabled(boolean enabled) {
this.hoverMode = enabled;
}
public boolean isHoverModeEnabled() {
return hoverMode;
}
public void setFlyingAscendSpeed(float value) {
this.flyingAscendSpeed = ValueUtil.clamp(value, 0.1F, 3.0F);
}
public float getFlyingAscendSpeed() {
return flyingAscendSpeed;
}
public void setFlyingDescendSpeed(float value) {
this.flyingDescendSpeed = ValueUtil.clamp(value, 0.05F, 3.0F);
}
public float getFlyingDescendSpeed() {
return flyingDescendSpeed;
}
public void setReturnToStartPreference(boolean value) {
this.storedReturnToStart = value;
npc.ais.returnToStart = false;
@@ -0,0 +1,371 @@
package noppes.npcs.util;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import noppes.npcs.CustomNpcs;
import noppes.npcs.controllers.PlayerDataController;
import noppes.npcs.controllers.data.PlayerData;
import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.constants.EnumRoleType;
import noppes.npcs.roles.RoleMount;
public final class NPCMountUtil {
private static final int MOUNT_FLIGHT_TOGGLE_WINDOW = 7;
private NPCMountUtil() {
}
public static class MountState {
public Entity lastRider;
public boolean flightMode;
public boolean jumpPressed;
public int flightToggleTimer;
}
public static boolean handleMountedMovement(EntityNPCInterface npc, MountState state, float strafe, float forward) {
if (npc.advanced.role != EnumRoleType.Mount || !(npc.roleInterface instanceof RoleMount)) {
resetMountedFlightState(npc, state);
return false;
}
if (npc.riddenByEntity != null && !(npc.riddenByEntity instanceof EntityPlayer)) {
npc.riddenByEntity.mountEntity(null);
return false;
}
if (!(npc.riddenByEntity instanceof EntityPlayer)) {
resetMountedFlightState(npc, state);
return false;
}
RoleMount mount = (RoleMount) npc.roleInterface;
EntityPlayer rider = (EntityPlayer) npc.riddenByEntity;
updateMountedFlightState(npc, state, mount, rider);
npc.prevRotationYaw = npc.rotationYaw = rider.rotationYaw;
npc.rotationPitch = rider.rotationPitch * 0.5F;
npc.setPositionAndRotation(npc.posX, npc.posY, npc.posZ, npc.rotationYaw, npc.rotationPitch);
npc.renderYawOffset = npc.rotationYaw;
npc.rotationYawHead = npc.rotationYaw;
float controlledStrafe = rider.moveStrafing;
float controlledForward = rider.moveForward;
if (controlledForward <= 0.0F) {
controlledForward *= 0.25F;
}
float moveSpeed = getMountMoveSpeed(npc);
boolean riderSprinting = rider.isSprinting() && mount.isSprintAllowed();
if (riderSprinting) {
moveSpeed *= 1.2F;
}
if (!mount.isSprintAllowed() && rider.isSprinting()) {
rider.setSprinting(false);
}
if (moveSpeed <= 0.0F) {
controlledStrafe = 0.0F;
controlledForward = 0.0F;
}
npc.setSprinting(riderSprinting);
npc.stepHeight = 1.0F;
npc.getNavigator().clearPathEntity();
npc.setAttackTarget(null);
npc.setRevengeTarget(null);
npc.fallDistance = 0.0F;
rider.fallDistance = 0.0F;
applyMountedVerticalMotion(npc, state, mount, rider, moveSpeed, controlledForward);
npc.performMountedMovement(controlledStrafe, controlledForward, moveSpeed);
return true;
}
private static float getMountMoveSpeed(EntityNPCInterface npc) {
return Math.max(0.0F, npc.getSpeed());
}
private static void applyMountedVerticalMotion(EntityNPCInterface npc, MountState state, RoleMount mount, EntityLivingBase rider, float moveSpeed, float forward) {
if (mount == null) {
return;
}
double jumpFactor = MathHelper.clamp_double(mount.getJumpStrength(), 0.1D, 3.0D);
boolean flyingEnabled = mount.isFlyingMountEnabled();
npc.setNpcJumpingState(false);
if (flyingEnabled) {
double ascendSpeed = MathHelper.clamp_double(mount.getFlyingAscendSpeed(), 0.1D, 3.0D);
double descendSpeed = MathHelper.clamp_double(mount.getFlyingDescendSpeed(), 0.05D, 3.0D);
boolean flightMode = isMountInFlightMode(state);
boolean jumpPressed = rider.isJumping;
boolean descendPressed = rider instanceof EntityPlayer && isSpecialKeyDown((EntityPlayer) rider);
if (flightMode) {
double previousMotionY = npc.motionY;
double newMotionY = 0.0D;
if (jumpPressed) {
newMotionY += ascendSpeed;
} else if (descendPressed) {
newMotionY -= descendSpeed;
}
newMotionY = MathHelper.clamp_double(newMotionY, -descendSpeed, ascendSpeed);
npc.motionY = newMotionY;
npc.setNpcFlyingState(true);
npc.setNpcJumpingState(jumpPressed);
npc.isAirBorne = true;
npc.fallDistance = 0.0F;
if (!npc.worldObj.isRemote && Math.abs(previousMotionY - newMotionY) > 1.0E-4D) {
npc.velocityChanged = true;
}
if (!npc.worldObj.isRemote && rider instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) rider;
if (!player.capabilities.isFlying) {
double playerPrevMotion = player.motionY;
player.motionY = npc.motionY;
if (Math.abs(playerPrevMotion - player.motionY) > 1.0E-4D) {
player.velocityChanged = true;
}
}
}
return;
}
if (jumpPressed && npc.onGround) {
double previousMotionY = npc.motionY;
npc.motionY = jumpFactor;
npc.setNpcJumpingState(true);
npc.isAirBorne = true;
npc.fallDistance = 0.0F;
if (!npc.worldObj.isRemote) {
if (Math.abs(previousMotionY - npc.motionY) > 1.0E-4D) {
npc.velocityChanged = true;
}
net.minecraftforge.common.ForgeHooks.onLivingJump(npc);
}
return;
}
if (!npc.onGround) {
double previousMotionY = npc.motionY;
double limitedMotionY = Math.max(npc.motionY, -descendSpeed);
if (Math.abs(previousMotionY - limitedMotionY) > 1.0E-4D) {
npc.motionY = limitedMotionY;
if (!npc.worldObj.isRemote) {
npc.velocityChanged = true;
}
} else {
npc.motionY = limitedMotionY;
}
npc.setNpcFlyingState(!npc.isInWater());
} else {
npc.setNpcFlyingState(false);
}
return;
}
if (npc.onGround) {
double previousMotionY = npc.motionY;
if (rider.isJumping) {
npc.motionY = jumpFactor;
npc.setNpcJumpingState(true);
npc.isAirBorne = true;
npc.fallDistance = 0.0F;
if (!npc.worldObj.isRemote) {
if (Math.abs(previousMotionY - npc.motionY) > 1.0E-4D) {
npc.velocityChanged = true;
}
net.minecraftforge.common.ForgeHooks.onLivingJump(npc);
}
} else {
npc.motionY = 0.0D;
}
return;
}
npc.setNpcFlyingState(false);
}
public static void handleMountRiderState(EntityNPCInterface npc, MountState state) {
if (npc.worldObj.isRemote) {
if (npc.advanced.role != EnumRoleType.Mount || !(npc.roleInterface instanceof RoleMount)) {
state.lastRider = null;
}
return;
}
if (npc.advanced.role != EnumRoleType.Mount || !(npc.roleInterface instanceof RoleMount)) {
state.lastRider = null;
return;
}
RoleMount mount = (RoleMount) npc.roleInterface;
Entity currentRider = npc.riddenByEntity;
if (currentRider != null && !(currentRider instanceof EntityPlayer)) {
Entity dismount = currentRider;
dismount.mountEntity(null);
stabilizeDismountedRider(dismount);
haltMountedMotion(npc, state);
applyUnriddenFlightDescent(npc, state, mount);
currentRider = null;
}
if (currentRider != state.lastRider) {
if (state.lastRider != null) {
stabilizeDismountedRider(state.lastRider);
}
if (currentRider == null) {
haltMountedMotion(npc, state);
applyUnriddenFlightDescent(npc, state, mount);
} else {
resetMountedFlightState(npc, state);
}
state.lastRider = currentRider;
} else if (currentRider == null) {
applyUnriddenFlightDescent(npc, state, mount);
}
}
public static boolean isFlyingMountWithFlightEnabled(EntityNPCInterface npc) {
return npc.advanced.role == EnumRoleType.Mount && npc.roleInterface instanceof RoleMount && ((RoleMount) npc.roleInterface).isFlyingMountEnabled();
}
public static void haltMountedMotion(EntityNPCInterface npc, MountState state) {
double prevMotionX = npc.motionX;
double prevMotionY = npc.motionY;
double prevMotionZ = npc.motionZ;
npc.motionX = 0.0D;
npc.motionY = 0.0D;
npc.motionZ = 0.0D;
npc.isAirBorne = false;
npc.setSprinting(false);
npc.moveForward = 0.0F;
npc.moveStrafing = 0.0F;
npc.setAIMoveSpeed(0.0F);
npc.limbSwingAmount = 0.0F;
npc.limbSwing = 0.0F;
npc.getNavigator().clearPathEntity();
npc.fallDistance = 0.0F;
if (!npc.worldObj.isRemote && (Math.abs(prevMotionX) > 1.0E-4D || Math.abs(prevMotionY) > 1.0E-4D || Math.abs(prevMotionZ) > 1.0E-4D)) {
npc.velocityChanged = true;
}
resetMountedFlightState(npc, state);
}
public static void applyUnriddenFlightDescent(EntityNPCInterface npc, MountState state, RoleMount mount) {
if (mount == null || !mount.isFlyingMountEnabled()) {
npc.setNpcFlyingState(false);
npc.setNpcJumpingState(false);
return;
}
if (npc.canFly()) {
return;
}
if (npc.onGround) {
npc.motionY = 0.0D;
npc.setNpcFlyingState(false);
npc.setNpcJumpingState(false);
return;
}
double descendSpeed = MathHelper.clamp_double(mount.getFlyingDescendSpeed(), 0.05D, 3.0D);
if (descendSpeed <= 0.0D) {
npc.setNpcFlyingState(false);
npc.setNpcJumpingState(false);
return;
}
double desired = -descendSpeed;
double previousMotionY = npc.motionY;
npc.motionY = desired;
npc.isAirBorne = true;
npc.fallDistance = 0.0F;
npc.setNpcFlyingState(true);
npc.setNpcJumpingState(false);
if (!npc.worldObj.isRemote && Math.abs(previousMotionY - desired) > 1.0E-4D) {
npc.velocityChanged = true;
}
}
public static void stabilizeDismountedRider(Entity rider) {
boolean wasOnGround = rider.onGround;
double previousMotionX = rider.motionX;
double previousMotionY = rider.motionY;
double previousMotionZ = rider.motionZ;
float previousFall = rider.fallDistance;
if (wasOnGround) {
rider.motionX = 0.0D;
rider.motionY = 0.0D;
rider.motionZ = 0.0D;
rider.fallDistance = 0.0F;
rider.onGround = true;
} else {
rider.motionX = previousMotionX;
rider.motionY = previousMotionY;
rider.motionZ = previousMotionZ;
rider.fallDistance = previousFall;
}
rider.velocityChanged = true;
}
private static void updateMountedFlightState(EntityNPCInterface npc, MountState state, RoleMount mount, EntityPlayer rider) {
if (mount == null || rider == null || !mount.isFlyingMountEnabled()) {
resetMountedFlightState(npc, state);
return;
}
if (npc.onGround) {
state.flightMode = false;
}
boolean jumpPressed = rider.isJumping;
if (jumpPressed && !state.jumpPressed) {
if (state.flightToggleTimer > 0) {
state.flightMode = !state.flightMode;
state.flightToggleTimer = 0;
} else {
state.flightToggleTimer = MOUNT_FLIGHT_TOGGLE_WINDOW;
}
}
if (state.flightToggleTimer > 0) {
state.flightToggleTimer--;
}
state.jumpPressed = jumpPressed;
}
public static boolean isMountInFlightMode(MountState state) {
return state.flightMode;
}
public static void resetMountedFlightState(EntityNPCInterface npc, MountState state) {
state.flightMode = false;
state.jumpPressed = false;
state.flightToggleTimer = 0;
npc.setNpcFlyingState(false);
npc.setNpcJumpingState(false);
}
private static boolean isSpecialKeyDown(EntityPlayer rider) {
if (rider == null) {
return false;
}
if (rider.worldObj.isRemote) {
PlayerData data = CustomNpcs.proxy.getPlayerData(rider);
return data != null && data.isSpecialKeyDown();
}
PlayerData data = PlayerDataController.Instance.getPlayerData(rider);
return data != null && data.isSpecialKeyDown();
}
}