mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-14 00:14:09 +00:00
Merge branch 'mount-movement-fix' into dev
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user