mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 04:57:27 +00:00
Merge branch 'dev' into janino-scripts
This commit is contained in:
commit
fb0332e5cf
53 files changed
+3017
-376
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;
|
||||
@@ -568,6 +569,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
@@ -92,7 +92,7 @@ public final class LinkedItemScriptPacket extends AbstractPacket {
|
||||
} else {
|
||||
data.saveScript(in);
|
||||
if (ConfigDebug.PlayerLogging && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
|
||||
LogWriter.script(String.format("[%s] (Player) %s SAVED EFFECT %s [%s]", "LINKED ITEM SCRIPTS", player.getCommandSenderName(), linkedItem.getName()));
|
||||
LogWriter.script(String.format("[%s] (Player) %s SAVED LINKED ITEM [%s]", "LINKED ITEM SCRIPTS", player.getCommandSenderName(), linkedItem.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@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")
|
||||
|
||||
@@ -123,8 +123,12 @@ public class NoppesUtilPlayer {
|
||||
}
|
||||
|
||||
public static void teleportPlayer(EntityPlayerMP player, double posX, double posY, double posZ, int dimension) {
|
||||
// Dismount from NPC mount before teleportation to prevent mount desync
|
||||
if (player.ridingEntity instanceof EntityNPCInterface) {
|
||||
player.mountEntity(null);
|
||||
}
|
||||
|
||||
if (player.dimension != dimension) {
|
||||
int dim = player.dimension;
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
WorldServer wor = server.worldServerForDimension(dimension);
|
||||
if (wor == null) {
|
||||
@@ -144,8 +148,12 @@ public class NoppesUtilPlayer {
|
||||
}
|
||||
|
||||
public static void teleportPlayer(EntityPlayerMP player, double posX, double posY, double posZ, float yaw, float pitch, int dimension) {
|
||||
// Dismount from NPC mount before teleportation to prevent mount desync
|
||||
if (player.ridingEntity instanceof EntityNPCInterface) {
|
||||
player.mountEntity(null);
|
||||
}
|
||||
|
||||
if (player.dimension != dimension) {
|
||||
int dim = player.dimension;
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
WorldServer wor = server.worldServerForDimension(dimension);
|
||||
if (wor == null) {
|
||||
|
||||
@@ -44,6 +44,7 @@ import net.minecraftforge.event.world.BlockEvent;
|
||||
import noppes.npcs.api.IWorld;
|
||||
import noppes.npcs.api.entity.IPlayer;
|
||||
import noppes.npcs.api.item.IItemCustomizable;
|
||||
import noppes.npcs.api.item.IItemStack;
|
||||
import noppes.npcs.config.ConfigMain;
|
||||
import noppes.npcs.config.ConfigScript;
|
||||
import noppes.npcs.constants.EnumQuestType;
|
||||
@@ -60,6 +61,8 @@ import noppes.npcs.entity.EntityNPCInterface;
|
||||
import noppes.npcs.items.ItemNpcTool;
|
||||
import noppes.npcs.quests.QuestItem;
|
||||
import noppes.npcs.scripted.NpcAPI;
|
||||
import noppes.npcs.scripted.item.ScriptCustomizableItem;
|
||||
import noppes.npcs.scripted.item.ScriptItemStack;
|
||||
|
||||
import static noppes.npcs.config.ConfigMain.TrackedQuestUpdateFrequency;
|
||||
|
||||
@@ -545,6 +548,18 @@ public class ScriptPlayerEventHandler {
|
||||
}
|
||||
|
||||
if (event.source.getEntity() instanceof EntityPlayerMP) {
|
||||
EntityPlayerMP playerMP = (EntityPlayerMP) event.source.getEntity();
|
||||
if(playerMP.getHeldItem() != null) {
|
||||
IItemStack itemStack = NpcAPI.Instance().getIItemStack(playerMP.getHeldItem());
|
||||
if (itemStack instanceof ScriptCustomizableItem) {
|
||||
ScriptCustomizableItem sci = (ScriptCustomizableItem) itemStack;
|
||||
int attackSpeed = sci.getAttackSpeed();
|
||||
if (event.entityLiving.hurtResistantTime <= event.entityLiving.maxHurtResistantTime - attackSpeed) {
|
||||
event.entityLiving.hurtResistantTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerDataScript handler = ScriptController.Instance.getPlayerScripts((EntityPlayer) event.source.getEntity());
|
||||
float attackAmount = event.ammount;
|
||||
if (ConfigMain.AttributesEnabled && !DBCAddon.IsAvailable())
|
||||
|
||||
@@ -173,19 +173,6 @@ public class ServerEventsHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public void invoke(LivingHurtEvent event) {
|
||||
|
||||
|
||||
|
||||
if(event.source.getEntity() instanceof EntityPlayerMP && event.entity instanceof EntityLivingBase ){
|
||||
EntityPlayerMP ep = (EntityPlayerMP) event.source.getEntity();
|
||||
if(ep.getHeldItem() != null && ep.getHeldItem().getItem() instanceof ItemLinked){
|
||||
int time = ep.getHeldItem().stackTagCompound.getCompoundTag("ItemData").getCompoundTag("LinkedData").getInteger("AttackSpeed");
|
||||
event.entity.hurtResistantTime = time;
|
||||
((EntityLivingBase) event.entity).hurtTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(event.entityLiving instanceof EntityPlayer))
|
||||
return;
|
||||
|
||||
@@ -433,6 +420,8 @@ public class ServerEventsHandler {
|
||||
return;
|
||||
|
||||
String name = EntityList.getEntityString(entity);
|
||||
if (entity instanceof EntityPlayer)
|
||||
name = "Player";
|
||||
QuestKill quest = (QuestKill) data.quest.questInterface;
|
||||
if (data.quest.partyOptions.objectiveRequirement == EnumPartyObjectives.Leader && !party.getLeaderUUID().equals(player.getUniqueID()))
|
||||
return;
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import noppes.npcs.controllers.ScriptController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
import noppes.npcs.controllers.data.action.ActionManager;
|
||||
|
||||
public class ServerTickHandler {
|
||||
@@ -65,6 +66,11 @@ public class ServerTickHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public void playerLogout(PlayerEvent.PlayerLoggedOutEvent event) {
|
||||
// Dismount player from NPC mount before logout to prevent orphaned mount state
|
||||
if (event.player.ridingEntity instanceof EntityNPCInterface) {
|
||||
event.player.mountEntity(null);
|
||||
}
|
||||
|
||||
PlayerData playerData = PlayerData.get(event.player);
|
||||
if (playerData != null) {
|
||||
playerData.onLogout();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -223,6 +223,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;
|
||||
|
||||
@@ -289,8 +290,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();
|
||||
|
||||
@@ -66,6 +66,8 @@ public class MusicController {
|
||||
this.playingSound.stopSound();
|
||||
this.sounds.remove(this.playingSound.sound);
|
||||
this.playingSound = null;
|
||||
this.entity = null;
|
||||
this.playDelay = 20; // Prevent immediate restart when music is stopped
|
||||
} else if (soundHandler != null) {
|
||||
try {
|
||||
soundHandler.stopSounds();
|
||||
@@ -193,4 +195,26 @@ public class MusicController {
|
||||
}
|
||||
this.sounds.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops a specific sound by its resource key.
|
||||
* This is used to stop dialog sounds without affecting Bard music.
|
||||
* @param soundKey The sound resource key to stop
|
||||
*/
|
||||
public void stopSound(String soundKey) {
|
||||
if (soundKey == null || soundKey.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ScriptClientSound sound = this.sounds.remove(soundKey);
|
||||
if (sound != null) {
|
||||
SoundHandler soundHandler = Minecraft.getMinecraft().getSoundHandler();
|
||||
if (soundHandler != null) {
|
||||
try {
|
||||
soundHandler.stopSound(sound);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
sound.stopSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,10 +706,8 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
if (!questCatSearch.equals(newText)) {
|
||||
questCatSearch = newText;
|
||||
if (questCatScroll != null) {
|
||||
if (selectedQuestCategory.isEmpty())
|
||||
questCatScroll.setList(new ArrayList<>());
|
||||
else
|
||||
questCatScroll.setList(filterList(questCatData, questCatSearch));
|
||||
questCatScroll.setList(filterList(questCatData, questCatSearch));
|
||||
questCatScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -718,12 +716,14 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!questFinishedSearch.equals(newText)) {
|
||||
questFinishedSearch = newText;
|
||||
if (questFinishedScroll != null)
|
||||
if (questFinishedScroll != null) {
|
||||
questFinishedScroll.setList(
|
||||
selectedQuestCategory.isEmpty() ?
|
||||
new ArrayList<>() :
|
||||
filterAndTrimListByCategory(questFinishedData, selectedQuestCategory, questFinishedSearch)
|
||||
);
|
||||
questFinishedScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
tf = getTextField(activeFieldId);
|
||||
@@ -731,12 +731,14 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!questActiveSearch.equals(newText)) {
|
||||
questActiveSearch = newText;
|
||||
if (questActiveScroll != null)
|
||||
if (questActiveScroll != null) {
|
||||
questActiveScroll.setList(
|
||||
selectedQuestCategory.isEmpty() ?
|
||||
new ArrayList<>() :
|
||||
filterAndTrimListByCategory(questActiveData, selectedQuestCategory, questActiveSearch)
|
||||
);
|
||||
questActiveScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -747,8 +749,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!questFinishedSearch.equals(newText)) {
|
||||
questFinishedSearch = newText;
|
||||
if (questFinishedScroll != null)
|
||||
if (questFinishedScroll != null) {
|
||||
questFinishedScroll.setList(filterList(questFinishedData, questFinishedSearch));
|
||||
questFinishedScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
tf = getTextField(activeFieldId);
|
||||
@@ -756,8 +760,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!questActiveSearch.equals(newText)) {
|
||||
questActiveSearch = newText;
|
||||
if (questActiveScroll != null)
|
||||
if (questActiveScroll != null) {
|
||||
questActiveScroll.setList(filterList(questActiveData, questActiveSearch));
|
||||
questActiveScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -768,12 +774,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!dialogCatSearch.equals(newText)) {
|
||||
dialogCatSearch = newText;
|
||||
if (dialogCatScroll != null)
|
||||
dialogCatScroll.setList(
|
||||
selectedDialogCategory.isEmpty() ?
|
||||
new ArrayList<>() :
|
||||
filterList(dialogCatData, dialogCatSearch)
|
||||
);
|
||||
if (dialogCatScroll != null) {
|
||||
dialogCatScroll.setList(filterList(dialogCatData, dialogCatSearch));
|
||||
dialogCatScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
tf = getTextField(readFieldId);
|
||||
@@ -781,12 +785,14 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!dialogReadSearch.equals(newText)) {
|
||||
dialogReadSearch = newText;
|
||||
if (dialogReadScroll != null)
|
||||
if (dialogReadScroll != null) {
|
||||
dialogReadScroll.setList(
|
||||
selectedDialogCategory.isEmpty() ?
|
||||
new ArrayList<>() :
|
||||
filterAndTrimListByCategory(dialogReadData, selectedDialogCategory, dialogReadSearch)
|
||||
);
|
||||
dialogReadScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -797,8 +803,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!dialogCompactSearch.equals(newText)) {
|
||||
dialogCompactSearch = newText;
|
||||
if (dialogCompactScroll != null)
|
||||
if (dialogCompactScroll != null) {
|
||||
dialogCompactScroll.setList(filterList(dialogReadData, dialogCompactSearch));
|
||||
dialogCompactScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,12 +817,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!transCatSearch.equals(newText)) {
|
||||
transCatSearch = newText;
|
||||
if (transCatScroll != null)
|
||||
transCatScroll.setList(
|
||||
selectedTransCategory.isEmpty() ?
|
||||
new ArrayList<>() :
|
||||
filterList(transCatData, transCatSearch)
|
||||
);
|
||||
if (transCatScroll != null) {
|
||||
transCatScroll.setList(filterList(transCatData, transCatSearch));
|
||||
transCatScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
tf = getTextField(locFieldId);
|
||||
@@ -822,12 +828,14 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!transLocSearch.equals(newText)) {
|
||||
transLocSearch = newText;
|
||||
if (transLocScroll != null)
|
||||
if (transLocScroll != null) {
|
||||
transLocScroll.setList(
|
||||
selectedTransCategory.isEmpty() ?
|
||||
new ArrayList<>() :
|
||||
filterAndTrimListByCategory(transLocData, selectedTransCategory, transLocSearch)
|
||||
);
|
||||
transLocScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -838,8 +846,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!transCompactSearch.equals(newText)) {
|
||||
transCompactSearch = newText;
|
||||
if (transCompactScroll != null)
|
||||
if (transCompactScroll != null) {
|
||||
transCompactScroll.setList(filterList(transLocData, transCompactSearch));
|
||||
transCompactScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -850,8 +860,10 @@ public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo
|
||||
String newText = tf.getText().toLowerCase();
|
||||
if (!singleSearch.equals(newText)) {
|
||||
singleSearch = newText;
|
||||
if (singleScroll != null)
|
||||
if (singleScroll != null) {
|
||||
singleScroll.setList(filterList(currentTab == 13 ? bankData : factionData, singleSearch));
|
||||
singleScroll.resetScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,6 +262,7 @@ public class GuiNpcNaturalSpawns extends GuiNPCInterface2 implements IGuiData, I
|
||||
public void setSelected(String selected) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeSubGui(SubGuiInterface gui) {
|
||||
super.closeSubGui(gui);
|
||||
if (gui instanceof GuiNpcMobSpawnerSelector && this.spawnEntryScroll.hasSelected()) {
|
||||
@@ -270,6 +271,9 @@ public class GuiNpcNaturalSpawns extends GuiNPCInterface2 implements IGuiData, I
|
||||
this.spawn.spawnCompounds.put(selected, selector.getCompound());
|
||||
initGui();
|
||||
}
|
||||
if (gui instanceof SubGuiNpcBiomes || gui instanceof SubGuiNpcDimensions || gui instanceof SubGuiSpawningOptions) {
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -125,12 +125,6 @@ public class SubGuiLinkedItem extends SubGuiInterface implements ITextfieldListe
|
||||
|
||||
y += spacing;
|
||||
|
||||
// Attack Speed Field (integers only)
|
||||
//addLabel(new GuiNpcLabel(13,"Attack Speed",x,y + 5, CustomNpcResourceListener.DefaultTextColor));
|
||||
|
||||
|
||||
//y += spacing;
|
||||
|
||||
// TEXTURE field
|
||||
addLabel(new GuiNpcLabel(3, "display.texture", x, y + 5, CustomNpcResourceListener.DefaultTextColor));
|
||||
addTextField(new GuiNpcTextField(2, this, x + 60, y, 200, 20, linkedItem.display.texture));
|
||||
|
||||
@@ -75,6 +75,12 @@ public class GuiDialogInteract extends GuiNPCInterface implements IGuiClose {
|
||||
*/
|
||||
private boolean sentClosePacket = false;
|
||||
|
||||
/**
|
||||
* Tracks the dialog sound that was played, so we can stop only this sound
|
||||
* on close without affecting Bard music or other sounds.
|
||||
*/
|
||||
private String dialogSound = null;
|
||||
|
||||
public GuiDialogInteract(EntityNPCInterface npc, Dialog dialog) {
|
||||
super(npc);
|
||||
this.dialog = dialog;
|
||||
@@ -671,8 +677,13 @@ public class GuiDialogInteract extends GuiNPCInterface implements IGuiClose {
|
||||
this.options = new ArrayList<Integer>();
|
||||
|
||||
if (dialog.sound != null && !dialog.sound.isEmpty()) {
|
||||
// Stop any previous dialog sound before playing new one
|
||||
if (this.dialogSound != null) {
|
||||
MusicController.Instance.stopSound(this.dialogSound);
|
||||
}
|
||||
MusicController.Instance.stopMusic();
|
||||
MusicController.Instance.playSound(dialog.sound, (float) npc.posX, (float) npc.posY, (float) npc.posZ);
|
||||
this.dialogSound = dialog.sound;
|
||||
}
|
||||
|
||||
if (!dialog.showPreviousBlocks) {
|
||||
@@ -707,7 +718,11 @@ public class GuiDialogInteract extends GuiNPCInterface implements IGuiClose {
|
||||
super.close();
|
||||
if (parent != null)
|
||||
NoppesUtil.openGUI(player, parent);
|
||||
MusicController.Instance.stopAllSounds();
|
||||
// Only stop the dialog sound, not Bard music or other sounds
|
||||
if (this.dialogSound != null) {
|
||||
MusicController.Instance.stopSound(this.dialogSound);
|
||||
this.dialogSound = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -63,6 +63,12 @@ public class GuiModernDialogInteract extends GuiNPCInterface implements IGuiClos
|
||||
*/
|
||||
private boolean sentClosePacket = false;
|
||||
|
||||
/**
|
||||
* Tracks the dialog sound that was played, so we can stop only this sound
|
||||
* on close without affecting Bard music or other sounds.
|
||||
*/
|
||||
private String dialogSound = null;
|
||||
|
||||
public GuiModernDialogInteract(EntityNPCInterface npc, Dialog dialog) {
|
||||
super(npc);
|
||||
this.dialog = dialog;
|
||||
@@ -380,8 +386,13 @@ public class GuiModernDialogInteract extends GuiNPCInterface implements IGuiClos
|
||||
this.options = new ArrayList<Integer>();
|
||||
|
||||
if (dialog.sound != null && !dialog.sound.isEmpty()) {
|
||||
// Stop any previous dialog sound before playing new one
|
||||
if (this.dialogSound != null) {
|
||||
MusicController.Instance.stopSound(this.dialogSound);
|
||||
}
|
||||
MusicController.Instance.stopMusic();
|
||||
MusicController.Instance.playSound(dialog.sound, (float) npc.posX, (float) npc.posY, (float) npc.posZ);
|
||||
this.dialogSound = dialog.sound;
|
||||
}
|
||||
|
||||
if (!dialog.showPreviousBlocks) {
|
||||
@@ -440,6 +451,11 @@ public class GuiModernDialogInteract extends GuiNPCInterface implements IGuiClos
|
||||
}
|
||||
closed();
|
||||
}
|
||||
// Only stop the dialog sound, not Bard music or other sounds
|
||||
if (this.dialogSound != null) {
|
||||
MusicController.Instance.stopSound(this.dialogSound);
|
||||
this.dialogSound = null;
|
||||
}
|
||||
super.onGuiClosed();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -136,10 +136,14 @@ public class PlayerQuestController {
|
||||
return player.worldObj.getTotalWorldTime() - questTime >= 24000;
|
||||
} else if (quest.repeat == EnumQuestRepeat.MCWEEKLY) {
|
||||
return player.worldObj.getTotalWorldTime() - questTime >= 168000;
|
||||
} else if (quest.repeat == EnumQuestRepeat.MCCUSTOM) {
|
||||
return player.worldObj.getTotalWorldTime() - questTime >= quest.customCooldown;
|
||||
} else if (quest.repeat == EnumQuestRepeat.RLDAILY) {
|
||||
return System.currentTimeMillis() - questTime >= 86400000;
|
||||
} else if (quest.repeat == EnumQuestRepeat.RLWEEKLY) {
|
||||
return System.currentTimeMillis() - questTime >= 604800000;
|
||||
} else if (quest.repeat == EnumQuestRepeat.RLCUSTOM) {
|
||||
return System.currentTimeMillis() - questTime >= quest.customCooldown;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ import noppes.npcs.constants.EnumAnimationPart;
|
||||
import noppes.npcs.controllers.AnimationController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Animation implements IAnimation {
|
||||
public AnimationData parent; //Client-sided only
|
||||
@@ -34,6 +37,12 @@ public class Animation implements IAnimation {
|
||||
//Client-sided
|
||||
public boolean paused;
|
||||
|
||||
protected final Map<String, Object> dataStore = new HashMap<>();
|
||||
|
||||
public Consumer<IAnimation> onAnimationStart;
|
||||
public BiConsumer<Integer, IAnimation> onAnimationFrame;
|
||||
public Consumer<IAnimation> onAnimationEnd;
|
||||
|
||||
public Animation() {
|
||||
}
|
||||
|
||||
@@ -175,6 +184,18 @@ public class Animation implements IAnimation {
|
||||
return time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasData(String key) {return dataStore.containsKey(key);}
|
||||
|
||||
@Override
|
||||
public Object getData(String key) {return dataStore.get(key);}
|
||||
|
||||
@Override
|
||||
public IAnimation setData(String key, Object v) {dataStore.put(key, v);return this;}
|
||||
|
||||
@Override
|
||||
public IAnimation removeData(String key) {dataStore.remove(key);return this;}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
if (compound.hasKey("ID")) {
|
||||
id = compound.getInteger("ID");
|
||||
@@ -254,8 +275,10 @@ public class Animation implements IAnimation {
|
||||
|
||||
if (this.currentFrame() != null) {
|
||||
EventHooks.onAnimationFrameEntered(this, this.currentFrame());
|
||||
fireFrameTask(this.currentFrame);
|
||||
} else {
|
||||
EventHooks.onAnimationEnded(this);
|
||||
fireEndTask();
|
||||
}
|
||||
|
||||
if (nextFrame != null) {
|
||||
@@ -294,4 +317,61 @@ public class Animation implements IAnimation {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAnimation onStart(Consumer<IAnimation> task) {
|
||||
this.onAnimationStart = task;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAnimation onFrame(BiConsumer<Integer, IAnimation> task) {
|
||||
this.onAnimationFrame = task;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAnimation onEnd(Consumer<IAnimation> task) {
|
||||
this.onAnimationEnd = task;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void fireStartTask() {
|
||||
if (this.onAnimationStart != null) {
|
||||
this.onAnimationStart.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fireFrameTask(int frame) {
|
||||
if (this.onAnimationFrame != null) {
|
||||
this.onAnimationFrame.accept(frame, this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fireEndTask() {
|
||||
if (this.onAnimationEnd != null) {
|
||||
this.onAnimationEnd.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called on setAnimation, to transfer tasks from
|
||||
* this global instance stored in AnimationController
|
||||
* to the new local instance on entity's AnimationData,
|
||||
* and clear them from the global instance.
|
||||
*/
|
||||
public void moveFromGlobalToLocal(Animation animation) {
|
||||
this.onAnimationStart = animation.onAnimationStart;
|
||||
this.onAnimationFrame = animation.onAnimationFrame;
|
||||
this.onAnimationEnd = animation.onAnimationEnd;
|
||||
|
||||
animation.onAnimationEnd = null;
|
||||
animation.onAnimationFrame = null;
|
||||
animation.onAnimationStart = null;
|
||||
|
||||
this.dataStore.putAll(animation.dataStore);
|
||||
animation.dataStore.clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -98,15 +98,18 @@ public class AnimationData implements IAnimationData {
|
||||
this.isClientAnimating = this.allowAnimation && this.animation != null;
|
||||
if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.currentClientAnimation)) {
|
||||
EventHooks.onAnimationEnded(this.currentClientAnimation);
|
||||
this.currentClientAnimation.fireEndTask();
|
||||
}
|
||||
if (this.isClientAnimating) {
|
||||
this.currentClientAnimation = this.animation;
|
||||
}
|
||||
|
||||
if (this.animation != null && this.allowAnimation) {
|
||||
this.animation.fireStartTask();
|
||||
if (EventHooks.onAnimationStarted(this.animation))
|
||||
return;
|
||||
EventHooks.onAnimationFrameEntered(this.animation, this.animation.currentFrame());
|
||||
this.animation.fireFrameTask(this.animation.currentFrame);
|
||||
}
|
||||
|
||||
List<EntityPlayer> entities = sendingEntity.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(
|
||||
@@ -269,6 +272,7 @@ public class AnimationData implements IAnimationData {
|
||||
newAnim.currentFrame = 0;
|
||||
newAnim.currentFrameTime = 0;
|
||||
newAnim.parent = this;
|
||||
newAnim.moveFromGlobalToLocal((Animation) animation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class LinkedItem implements ILinkedItem {
|
||||
public boolean isNormalItem = false;
|
||||
public boolean isTool = false;
|
||||
public int digSpeed = 1;
|
||||
public int attackSpeed = 20;
|
||||
public int attackSpeed = 10;
|
||||
public int armorType = -2; //-2: Fits in no armor slot, -1: Fits in all slots, 0 - 3: Fits in Head -> Boots slot respectively
|
||||
public int enchantability;
|
||||
|
||||
@@ -59,7 +59,8 @@ public class LinkedItem implements ILinkedItem {
|
||||
compound.setBoolean("IsTool", this.isTool);
|
||||
compound.setBoolean("IsNormalItem", this.isNormalItem);
|
||||
compound.setInteger("DigSpeed", this.digSpeed);
|
||||
compound.setInteger("AttackSpeed",this.attackSpeed);
|
||||
compound.setInteger("AttackSpeed", this.attackSpeed);
|
||||
|
||||
compound.setInteger("ArmorType", this.armorType);
|
||||
compound.setInteger("Enchantability", this.enchantability);
|
||||
|
||||
@@ -89,7 +90,7 @@ public class LinkedItem implements ILinkedItem {
|
||||
this.isTool = compound.getBoolean("IsTool");
|
||||
this.isNormalItem = compound.getBoolean("IsNormalItem");
|
||||
this.digSpeed = compound.getInteger("DigSpeed");
|
||||
this.attackSpeed = compound.getInteger("AttackSpeed");
|
||||
this.setAttackSpeed(compound.getInteger("AttackSpeed"));
|
||||
this.armorType = compound.getInteger("ArmorType");
|
||||
this.enchantability = compound.getInteger("Enchantability");
|
||||
|
||||
@@ -241,6 +242,19 @@ public class LinkedItem implements ILinkedItem {
|
||||
this.enchantability = enchantability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttackSpeed() {
|
||||
return attackSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttackSpeed(int time) {
|
||||
if(time <= 0) {
|
||||
time = 10;
|
||||
}
|
||||
this.attackSpeed = time;
|
||||
}
|
||||
|
||||
public LinkedItem clone() {
|
||||
NBTTagCompound nbt = this.writeToNBT(true);
|
||||
LinkedItem clone = new LinkedItem(this.name);
|
||||
@@ -254,10 +268,4 @@ public class LinkedItem implements ILinkedItem {
|
||||
setScriptHandler(data = new LinkedItemScript());
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttackSpeed() {return attackSpeed;}
|
||||
|
||||
@Override
|
||||
public void setAttackSpeed(int time) {this.attackSpeed = time;}
|
||||
}
|
||||
@@ -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_);
|
||||
@@ -81,7 +84,6 @@ public abstract class EntityNPCFlying extends EntityNPCInterface {
|
||||
}
|
||||
|
||||
this.updateLimbSwing();
|
||||
this.velocityChanged = true;
|
||||
}
|
||||
|
||||
public void updateLimbSwing() {
|
||||
@@ -97,12 +99,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 +125,21 @@ 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);
|
||||
return;
|
||||
}
|
||||
|
||||
double d3 = this.motionY;
|
||||
super.doMountedMovement(strafe, forward, moveSpeed);
|
||||
super.performMountedMovement(strafe, forward, moveSpeed);
|
||||
this.motionY = d3;
|
||||
|
||||
if (this.getNavigator().noPath()) {
|
||||
@@ -135,6 +147,5 @@ public abstract class EntityNPCFlying extends EntityNPCInterface {
|
||||
}
|
||||
|
||||
this.updateLimbSwing();
|
||||
this.velocityChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -159,7 +159,9 @@ import noppes.npcs.roles.RoleInterface;
|
||||
import noppes.npcs.scripted.NpcAPI;
|
||||
import noppes.npcs.scripted.entity.ScriptNpc;
|
||||
import noppes.npcs.scripted.event.NpcEvent;
|
||||
import noppes.npcs.scripted.item.ScriptCustomizableItem;
|
||||
import noppes.npcs.util.GameProfileAlt;
|
||||
import noppes.npcs.util.NPCMountUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -211,7 +213,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 +286,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() {
|
||||
@@ -634,6 +639,22 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
|
||||
reset();
|
||||
}
|
||||
|
||||
// Check for custom weapon attack speed - bypass immunity if enough time has passed
|
||||
Entity sourceEntity = damagesource.getEntity();
|
||||
if (sourceEntity instanceof EntityPlayer) {
|
||||
EntityPlayer player = (EntityPlayer) sourceEntity;
|
||||
ItemStack heldItem = player.getHeldItem();
|
||||
if (heldItem != null) {
|
||||
IItemStack itemStack = NpcAPI.Instance().getIItemStack(heldItem);
|
||||
if (itemStack instanceof ScriptCustomizableItem) {
|
||||
int attackSpeed = ((ScriptCustomizableItem) itemStack).getAttackSpeed();
|
||||
if (this.hurtResistantTime <= this.maxHurtResistantTime - attackSpeed) {
|
||||
this.hurtResistantTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((float) this.hurtResistantTime > (float) this.maxHurtResistantTime / 2.0F && i <= this.lastDamage)
|
||||
return false;
|
||||
|
||||
@@ -967,7 +988,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 +1507,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 +1645,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 +1919,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 +2139,47 @@ 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;
|
||||
|
||||
boolean flightMode = isMountFlightModeActive();
|
||||
double prevMotionY = this.motionY;
|
||||
|
||||
// Server-side only physics (like vanilla horse)
|
||||
if (!worldObj.isRemote) {
|
||||
this.jumpMovementFactor = getMountedAirStrafeFactor(moveSpeed, flightMode);
|
||||
this.setAIMoveSpeed(moveSpeed);
|
||||
super.moveEntityWithHeading(strafe, forward);
|
||||
|
||||
if (flightMode) {
|
||||
this.motionY = prevMotionY;
|
||||
this.isAirBorne = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Both sides do animation (like vanilla horse)
|
||||
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 updateMountedLimbSwing() {
|
||||
this.prevLimbSwingAmount = this.limbSwingAmount;
|
||||
double deltaX = this.posX - this.prevPosX;
|
||||
double deltaZ = this.posZ - this.prevPosZ;
|
||||
@@ -2162,46 +2195,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 +2233,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;
|
||||
@@ -141,6 +192,10 @@ public class RoleMount extends RoleInterface {
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
// Dismount any rider when mount role is disabled
|
||||
if (npc.riddenByEntity != null) {
|
||||
npc.riddenByEntity.mountEntity(null);
|
||||
}
|
||||
npc.ais.returnToStart = storedReturnToStart;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ public class ScriptCustomItem extends ScriptCustomizableItem implements IItemCus
|
||||
public int digSpeed = 1;
|
||||
public int armorType = -2; //-2: Fits in no armor slot, -1: Fits in all slots, 0 - 4: Fits in Head -> Boots slot respectively
|
||||
public int enchantability;
|
||||
public int attackSpeed = 10;
|
||||
|
||||
public long lastInited = -1;
|
||||
|
||||
@@ -228,6 +229,18 @@ public class ScriptCustomItem extends ScriptCustomizableItem implements IItemCus
|
||||
return this.enchantability;
|
||||
}
|
||||
|
||||
public int getAttackSpeed() {
|
||||
return this.attackSpeed;
|
||||
}
|
||||
|
||||
public void setAttackSpeed(int speed) {
|
||||
if(speed <= 0) {
|
||||
speed = 10;
|
||||
}
|
||||
this.attackSpeed = speed;
|
||||
saveItemData();
|
||||
}
|
||||
|
||||
public void setEnchantability(int enchantability) {
|
||||
this.enchantability = enchantability;
|
||||
saveItemData();
|
||||
@@ -270,6 +283,7 @@ public class ScriptCustomItem extends ScriptCustomizableItem implements IItemCus
|
||||
compound.setInteger("DigSpeed", this.digSpeed);
|
||||
compound.setInteger("ArmorType", this.armorType);
|
||||
compound.setInteger("Enchantability", this.enchantability);
|
||||
compound.setInteger("AttackSpeed", this.attackSpeed);
|
||||
|
||||
compound.setInteger("MaxItemUseDuration", this.maxItemUseDuration);
|
||||
compound.setInteger("ItemUseAction", this.itemUseAction);
|
||||
@@ -286,6 +300,7 @@ public class ScriptCustomItem extends ScriptCustomizableItem implements IItemCus
|
||||
this.digSpeed = compound.getInteger("DigSpeed");
|
||||
this.armorType = compound.getInteger("ArmorType");
|
||||
this.enchantability = compound.getInteger("Enchantability");
|
||||
setAttackSpeed(compound.getInteger("AttackSpeed"));
|
||||
|
||||
this.maxItemUseDuration = compound.getInteger("MaxItemUseDuration");
|
||||
this.itemUseAction = compound.getInteger("ItemUseAction");
|
||||
|
||||
@@ -30,6 +30,7 @@ public abstract class ScriptCustomizableItem extends ScriptItemStack implements
|
||||
|
||||
public abstract int getEnchantability();
|
||||
|
||||
public abstract int getAttackSpeed();
|
||||
|
||||
public String getTexture() {
|
||||
return this.itemDisplay.texture == null ? "" : this.itemDisplay.texture;
|
||||
|
||||
@@ -102,6 +102,11 @@ public class ScriptLinkedItem extends ScriptCustomizableItem implements IItemLin
|
||||
return this.linkedItem.enchantability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttackSpeed() {
|
||||
return this.linkedItem.attackSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTexture() {
|
||||
return this.itemDisplay.texture == null ? this.linkedItem.display.texture : this.itemDisplay.texture;
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
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;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (jumpPressed && npc.onGround) {
|
||||
npc.motionY = jumpFactor;
|
||||
npc.setNpcJumpingState(true);
|
||||
npc.isAirBorne = true;
|
||||
npc.fallDistance = 0.0F;
|
||||
if (!npc.worldObj.isRemote) {
|
||||
net.minecraftforge.common.ForgeHooks.onLivingJump(npc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!npc.onGround) {
|
||||
npc.motionY = Math.max(npc.motionY, -descendSpeed);
|
||||
npc.setNpcFlyingState(!npc.isInWater());
|
||||
} else {
|
||||
npc.setNpcFlyingState(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (npc.onGround) {
|
||||
if (rider.isJumping) {
|
||||
npc.motionY = jumpFactor;
|
||||
npc.setNpcJumpingState(true);
|
||||
npc.isAirBorne = true;
|
||||
npc.fallDistance = 0.0F;
|
||||
if (!npc.worldObj.isRemote) {
|
||||
net.minecraftforge.common.ForgeHooks.onLivingJump(npc);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
// Validate rider is alive and valid - dismount dead/invalid riders
|
||||
if (currentRider != null && !currentRider.isEntityAlive()) {
|
||||
currentRider.mountEntity(null);
|
||||
stabilizeDismountedRider(currentRider);
|
||||
haltMountedMotion(npc, state);
|
||||
applyUnriddenFlightDescent(npc, state, mount);
|
||||
currentRider = null;
|
||||
}
|
||||
|
||||
// Only allow EntityPlayer as riders
|
||||
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) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
npc.motionY = -descendSpeed;
|
||||
npc.isAirBorne = true;
|
||||
npc.fallDistance = 0.0F;
|
||||
npc.setNpcFlyingState(true);
|
||||
npc.setNpcJumpingState(false);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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