2025-03-11 00:23:54 +01:00
|
|
|
package game.entity.npc;
|
|
|
|
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.util.List;
|
2025-03-16 17:40:47 +01:00
|
|
|
|
|
|
|
import com.google.common.base.Predicate;
|
2025-03-11 00:23:54 +01:00
|
|
|
|
|
|
|
import game.Game;
|
|
|
|
import game.ai.AIRangedAttack;
|
|
|
|
import game.ai.EntityAIAttackOnCollide;
|
|
|
|
import game.ai.EntityAIAvoidEntity;
|
|
|
|
import game.ai.EntityAIHurtByTarget;
|
|
|
|
import game.ai.EntityAILookAtTalkingPlayer;
|
|
|
|
import game.ai.EntityAINagPlayer;
|
|
|
|
import game.ai.EntityAINearestAttackableTarget;
|
|
|
|
import game.ai.EntityAINpcInteract;
|
|
|
|
import game.ai.EntityAINpcMate;
|
|
|
|
import game.ai.EntityAIOpenDoor;
|
|
|
|
import game.ai.EntityAIPlay;
|
|
|
|
import game.ai.EntityAISwimming;
|
|
|
|
import game.ai.EntityAIWander;
|
|
|
|
import game.ai.EntityAIWatchClosest;
|
|
|
|
import game.ai.EntityAIWatchClosest2;
|
|
|
|
import game.audio.MovingSoundMinecartRiding;
|
|
|
|
import game.block.Block;
|
|
|
|
import game.block.BlockBed;
|
|
|
|
import game.enchantment.Enchantment;
|
|
|
|
import game.enchantment.EnchantmentHelper;
|
|
|
|
import game.entity.DamageSource;
|
|
|
|
import game.entity.Entity;
|
|
|
|
import game.entity.animal.EntityDragonPart;
|
|
|
|
import game.entity.animal.EntityHorse;
|
|
|
|
import game.entity.animal.EntityPig;
|
|
|
|
import game.entity.attributes.AttributeInstance;
|
|
|
|
import game.entity.attributes.Attributes;
|
|
|
|
import game.entity.item.EntityBoat;
|
|
|
|
import game.entity.item.EntityCart;
|
|
|
|
import game.entity.item.EntityItem;
|
|
|
|
import game.entity.projectile.EntityArrow;
|
|
|
|
import game.entity.projectile.EntityBullet;
|
|
|
|
import game.entity.projectile.EntityHook;
|
|
|
|
import game.entity.projectile.EntityPotion;
|
|
|
|
import game.entity.projectile.EntitySnowball;
|
|
|
|
import game.entity.types.EntityLiving;
|
|
|
|
import game.entity.types.IEntityMultiPart;
|
2025-03-11 10:26:48 +01:00
|
|
|
import game.gui.GuiSign;
|
2025-03-11 19:38:37 +01:00
|
|
|
import game.gui.container.GuiBrewing;
|
|
|
|
import game.gui.container.GuiChest;
|
|
|
|
import game.gui.container.GuiCrafting;
|
|
|
|
import game.gui.container.GuiDispenser;
|
|
|
|
import game.gui.container.GuiEnchant;
|
|
|
|
import game.gui.container.GuiFurnace;
|
|
|
|
import game.gui.container.GuiHopper;
|
|
|
|
import game.gui.container.GuiHorse;
|
|
|
|
import game.gui.container.GuiMerchant;
|
|
|
|
import game.gui.container.GuiRepair;
|
2025-03-11 00:23:54 +01:00
|
|
|
import game.init.Config;
|
|
|
|
import game.init.ItemRegistry;
|
|
|
|
import game.init.Items;
|
|
|
|
import game.init.NameRegistry;
|
|
|
|
import game.init.SoundEvent;
|
|
|
|
import game.init.SpeciesRegistry;
|
|
|
|
import game.init.SpeciesRegistry.ModelType;
|
|
|
|
import game.init.TradeRegistry;
|
|
|
|
import game.inventory.Container;
|
|
|
|
import game.inventory.ContainerPlayer;
|
|
|
|
import game.inventory.IInventory;
|
|
|
|
import game.inventory.InventoryBasic;
|
|
|
|
import game.inventory.InventoryPlayer;
|
|
|
|
import game.inventory.InventoryWarpChest;
|
|
|
|
import game.item.Item;
|
|
|
|
import game.item.ItemAction;
|
|
|
|
import game.item.ItemArmor;
|
|
|
|
import game.item.ItemBow;
|
|
|
|
import game.item.ItemGunBase;
|
|
|
|
import game.item.ItemHoe;
|
|
|
|
import game.item.ItemShears;
|
|
|
|
import game.item.ItemStack;
|
|
|
|
import game.item.ItemSword;
|
|
|
|
import game.item.ItemTool;
|
|
|
|
import game.nbt.NBTTagCompound;
|
|
|
|
import game.nbt.NBTTagList;
|
|
|
|
import game.network.NetHandlerPlayClient;
|
|
|
|
import game.network.NetHandlerPlayServer;
|
|
|
|
import game.packet.CPacketAction;
|
|
|
|
import game.packet.CPacketBreak;
|
|
|
|
import game.packet.CPacketInput;
|
|
|
|
import game.packet.CPacketPlayer;
|
|
|
|
import game.packet.SPacketEntityEquipment;
|
|
|
|
import game.packet.SPacketEntityVelocity;
|
|
|
|
import game.pathfinding.PathNavigateGround;
|
|
|
|
import game.potion.Potion;
|
|
|
|
import game.potion.PotionEffect;
|
|
|
|
import game.renderer.layers.LayerExtra;
|
|
|
|
import game.renderer.particle.ParticleType;
|
|
|
|
import game.renderer.texture.EntityTexManager;
|
|
|
|
import game.rng.Random;
|
|
|
|
import game.tileentity.IInteractionObject;
|
|
|
|
import game.tileentity.LockCode;
|
|
|
|
import game.tileentity.TileEntitySign;
|
2025-03-11 10:26:48 +01:00
|
|
|
import game.util.ExtMath;
|
2025-03-11 00:23:54 +01:00
|
|
|
import game.village.MerchantRecipeList;
|
|
|
|
import game.world.BlockPos;
|
|
|
|
import game.world.BoundingBox;
|
|
|
|
import game.world.Facing;
|
|
|
|
import game.world.PortalType;
|
|
|
|
import game.world.Vec3;
|
|
|
|
import game.world.World;
|
|
|
|
import game.world.WorldClient;
|
|
|
|
import game.world.WorldPos;
|
|
|
|
import game.world.WorldServer;
|
|
|
|
|
|
|
|
public abstract class EntityNPC extends EntityLiving
|
|
|
|
{
|
|
|
|
public static class CharacterTypeData
|
|
|
|
{
|
|
|
|
public final CharacterInfo character;
|
|
|
|
|
|
|
|
public CharacterTypeData(CharacterInfo character)
|
|
|
|
{
|
|
|
|
this.character = character;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class AlignmentData
|
|
|
|
{
|
|
|
|
public final Alignment alignment;
|
|
|
|
|
|
|
|
public AlignmentData(Alignment alignment)
|
|
|
|
{
|
|
|
|
this.alignment = alignment;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getSkinTexture(String skin)
|
|
|
|
{
|
|
|
|
return "textures/entity/" + skin + ".png";
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getCapeTexture(String cape)
|
|
|
|
{
|
|
|
|
return "textures/entity/cape_" + cape + ".png";
|
|
|
|
}
|
|
|
|
|
|
|
|
// public static String getSpeciesName(String character) {
|
|
|
|
// return (character.substring(0, 1).toUpperCase() + character.substring(1)).replace('_', ' ').replaceAll("( [a-z])", "$1");
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected final EntityAIAttackOnCollide aiMelee = new EntityAIAttackOnCollide(this, EntityLiving.class, 1.0D, true, true) {
|
|
|
|
public boolean shouldExecute()
|
|
|
|
{
|
|
|
|
return !EntityNPC.this.fleeing && super.shouldExecute();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean continueExecuting()
|
|
|
|
{
|
|
|
|
return !EntityNPC.this.fleeing && super.shouldExecute();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
protected final AIRangedAttack aiRanged = new AIRangedAttack(this, 1.0D, this.getAttackSpeed(), this.getAttackSpeed() * 3, 15.0F) {
|
|
|
|
// public void startExecuting()
|
|
|
|
// {
|
|
|
|
// super.startExecuting();
|
|
|
|
// EntityNPC.this.setUsingItem(true);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public void resetTask()
|
|
|
|
// {
|
|
|
|
// super.resetTask();
|
|
|
|
// EntityNPC.this.setUsingItem(false);
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean shouldExecute()
|
|
|
|
{
|
|
|
|
return !EntityNPC.this.fleeing && super.shouldExecute();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean continueExecuting()
|
|
|
|
{
|
|
|
|
return !EntityNPC.this.fleeing && super.shouldExecute();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
protected final SpeciesInfo species;
|
|
|
|
|
|
|
|
private EntityNPC talkingPlayer;
|
|
|
|
private boolean isWilling;
|
|
|
|
private boolean fleeing;
|
|
|
|
private boolean playing;
|
|
|
|
protected boolean noPickup;
|
|
|
|
private ItemStack[] equipment = new ItemStack[5];
|
|
|
|
private final ItemStack[] prevEquipment = new ItemStack[5];
|
|
|
|
private InventoryBasic extraInventory;
|
|
|
|
private int inLove;
|
|
|
|
protected Alignment alignment = Alignment.NEUTRAL;
|
|
|
|
private MerchantRecipeList trades;
|
|
|
|
private int healTimer;
|
|
|
|
private byte[] skin;
|
|
|
|
|
|
|
|
public NetHandlerPlayServer connection;
|
|
|
|
public NetHandlerPlayClient sendQueue;
|
|
|
|
private Game gm;
|
|
|
|
|
|
|
|
public InventoryPlayer inventory;
|
|
|
|
protected InventoryWarpChest warpChest;
|
|
|
|
public ContainerPlayer inventoryContainer;
|
|
|
|
public Container openContainer;
|
|
|
|
public boolean flying;
|
|
|
|
public boolean noclip;
|
|
|
|
protected int flyToggleTimer;
|
|
|
|
public float prevCameraYaw;
|
|
|
|
public float cameraYaw;
|
|
|
|
public int xpCooldown;
|
|
|
|
public double prevChasingPosX;
|
|
|
|
public double prevChasingPosY;
|
|
|
|
public double prevChasingPosZ;
|
|
|
|
public double chasingPosX;
|
|
|
|
public double chasingPosY;
|
|
|
|
public double chasingPosZ;
|
|
|
|
private WorldPos spawnPos;
|
|
|
|
// private BlockPos startMinecartRidingCoordinate;
|
|
|
|
public int experienceLevel;
|
|
|
|
public int experienceTotal;
|
|
|
|
public float experience;
|
|
|
|
protected int xpSeed;
|
|
|
|
private ItemStack itemInUse;
|
|
|
|
private int itemInUseCount;
|
|
|
|
protected float speedInAir = 0.02F;
|
|
|
|
private int lastXPSound;
|
|
|
|
public EntityHook fishEntity;
|
|
|
|
protected int sinceLastAttack;
|
|
|
|
|
|
|
|
private boolean otherPlayerUsing;
|
|
|
|
private int otherPlayerMPPosRotationIncrements;
|
|
|
|
private double otherPlayerMPX;
|
|
|
|
private double otherPlayerMPY;
|
|
|
|
private double otherPlayerMPZ;
|
|
|
|
private double otherPlayerMPYaw;
|
|
|
|
private double otherPlayerMPPitch;
|
|
|
|
|
|
|
|
private double lastReportedPosX;
|
|
|
|
private double lastReportedPosY;
|
|
|
|
private double lastReportedPosZ;
|
|
|
|
private float lastReportedYaw;
|
|
|
|
private float lastReportedPitch;
|
|
|
|
private boolean serverSneakState;
|
|
|
|
private boolean serverSprintState;
|
|
|
|
private int positionUpdateTicks;
|
|
|
|
private boolean hasValidHealth;
|
|
|
|
protected int sprintToggleTimer;
|
|
|
|
public int sprintingTicksLeft;
|
|
|
|
public float renderArmYaw;
|
|
|
|
public float renderArmPitch;
|
|
|
|
public float prevRenderArmYaw;
|
|
|
|
public float prevRenderArmPitch;
|
|
|
|
private int horseJumpPowerCounter;
|
|
|
|
private float horseJumpPower;
|
|
|
|
// public float nausea;
|
|
|
|
// public float prevNausea;
|
|
|
|
|
|
|
|
public EntityNPC(World worldIn)
|
|
|
|
{
|
|
|
|
super(worldIn);
|
|
|
|
this.species = SpeciesRegistry.CLASSES.get(this.getClass());
|
|
|
|
this.extraInventory = new InventoryBasic("Items", false, 8);
|
|
|
|
// this.setCharacter("");
|
|
|
|
if(this.species != null)
|
|
|
|
this.setSize(this.species.size * this.species.renderer.width / this.species.renderer.height, this.species.size); // /* 0.6F, */ 1.8F);
|
|
|
|
if(this.getNavigator() instanceof PathNavigateGround) {
|
|
|
|
((PathNavigateGround)this.getNavigator()).setBreakDoors(true);
|
|
|
|
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
|
|
|
}
|
|
|
|
this.tasks.addTask(0, new EntityAISwimming(this));
|
|
|
|
// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true));
|
|
|
|
// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true));
|
|
|
|
this.tasks.addTask(1, new EntityAINpcMate(this));
|
|
|
|
this.tasks.addTask(2, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate<EntityLiving>() {
|
2025-03-16 17:40:47 +01:00
|
|
|
public boolean apply(EntityLiving entity) {
|
2025-03-11 00:23:54 +01:00
|
|
|
return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity);
|
|
|
|
}
|
|
|
|
}, 8.0F, 1.1D, 1.1D) {
|
|
|
|
{
|
|
|
|
this.setMutexBits(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void startExecuting() {
|
|
|
|
EntityNPC.this.setAttackTarget(null);
|
|
|
|
EntityNPC.this.fleeing = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean continueExecuting() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateTask()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void resetTask() {
|
|
|
|
// super.resetTask();
|
|
|
|
// EntityNPC.this.isFleeing = false;
|
|
|
|
// }
|
|
|
|
});
|
|
|
|
this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate<EntityLiving>() {
|
2025-03-16 17:40:47 +01:00
|
|
|
public boolean apply(EntityLiving entity) {
|
2025-03-11 00:23:54 +01:00
|
|
|
return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity);
|
|
|
|
}
|
|
|
|
}, 8.0F, 1.1D, 1.1D) {
|
|
|
|
public void startExecuting() {
|
|
|
|
super.startExecuting();
|
|
|
|
EntityNPC.this.setAttackTarget(null);
|
|
|
|
EntityNPC.this.fleeing = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void resetTask() {
|
|
|
|
super.resetTask();
|
|
|
|
EntityNPC.this.fleeing = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false));
|
|
|
|
this.tasks.addTask(4, new EntityAIOpenDoor(this, true));
|
|
|
|
this.tasks.addTask(5, new EntityAINagPlayer(this));
|
|
|
|
this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this));
|
|
|
|
this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) {
|
|
|
|
private int sneakTime;
|
|
|
|
|
|
|
|
public void updateTask()
|
|
|
|
{
|
|
|
|
super.updateTask();
|
|
|
|
boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking();
|
|
|
|
if(this.sneakTime > 0) {
|
|
|
|
if(--this.sneakTime == 0) {
|
|
|
|
EntityNPC.this.setSneaking(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) {
|
|
|
|
EntityNPC.this.setSneaking(true);
|
|
|
|
this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120);
|
|
|
|
}
|
|
|
|
else if(EntityNPC.this.getAttackTarget() != null) {
|
|
|
|
EntityNPC.this.setSneaking(false);
|
|
|
|
this.sneakTime = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void resetTask()
|
|
|
|
{
|
|
|
|
super.resetTask();
|
|
|
|
EntityNPC.this.setSneaking(false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.tasks.addTask(7, new EntityAINpcInteract(this));
|
|
|
|
this.tasks.addTask(8, new EntityAIWander(this, 1.0D));
|
|
|
|
this.tasks.addTask(8, new EntityAIPlay(this, 1.1D));
|
|
|
|
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F));
|
|
|
|
this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) {
|
|
|
|
protected boolean isSuitableTarget(EntityLiving entity) {
|
|
|
|
if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) {
|
|
|
|
EntityNPC.this.setAttackTarget(null);
|
|
|
|
EntityNPC.this.fleeing = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4))
|
|
|
|
&& EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate<EntityLiving>() {
|
2025-03-16 17:40:47 +01:00
|
|
|
public boolean apply(EntityLiving entity) {
|
2025-03-11 00:23:54 +01:00
|
|
|
if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) {
|
|
|
|
EntityNPC.this.setAttackTarget(null);
|
|
|
|
EntityNPC.this.fleeing = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity);
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// this.setCanPickUpLoot(true);
|
|
|
|
|
|
|
|
if (worldIn != null && !worldIn.client)
|
|
|
|
{
|
|
|
|
this.setCombatTask();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void initPlayer() {
|
|
|
|
this.inventory = new InventoryPlayer(this);
|
|
|
|
this.warpChest = new InventoryWarpChest();
|
|
|
|
// this.setHeight(1.8f);
|
|
|
|
this.inventoryContainer = new ContainerPlayer(this.inventory, !this.worldObj.client, this);
|
|
|
|
this.openContainer = this.inventoryContainer;
|
|
|
|
this.setLocationAndAngles(0.5D, 1.0D, 0.5D, 0.0F, 0.0F);
|
|
|
|
this.fireResistance = 20;
|
|
|
|
this.noPickup = true;
|
|
|
|
// this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(1.0D);
|
|
|
|
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.getEntityAttribute(Attributes.MOVEMENT_SPEED).getBaseValue() / 3.0); // 0.10000000149011612D);
|
|
|
|
}
|
|
|
|
|
|
|
|
public final void setServerPlayer(NetHandlerPlayServer connection) {
|
|
|
|
this.initPlayer();
|
|
|
|
this.connection = connection;
|
|
|
|
this.stepHeight = 0.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final void setClientPlayer(Game gm, NetHandlerPlayClient connection) {
|
|
|
|
this.initPlayer();
|
|
|
|
this.gm = gm;
|
|
|
|
this.sendQueue = connection;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final void setOtherPlayer(Game gm) {
|
|
|
|
this.initPlayer();
|
|
|
|
this.gm = gm;
|
|
|
|
this.stepHeight = 0.0F;
|
|
|
|
this.noClip = true;
|
|
|
|
this.renderDistWeight = 10.0D;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final boolean isPlayer() {
|
|
|
|
return this.connection != null || this.gm != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean canInfight(Alignment align) {
|
|
|
|
return this.alignment.chaotic || (!this.alignment.lawful &&
|
|
|
|
((this.alignment.good && align.evil) || (this.alignment.evil && align.good)));
|
|
|
|
}
|
|
|
|
|
|
|
|
public final boolean canMurder(Alignment align) {
|
|
|
|
return this.alignment.chaotic && ((this.alignment.good && align.evil) || (this.alignment.evil && align.good));
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canCounter(EntityLiving entity) {
|
|
|
|
return !(entity instanceof EntityNPC) ||
|
|
|
|
(this.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).alignment) :
|
|
|
|
!this.isPeaceful(((EntityNPC)entity).getClass()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canAttack(EntityLiving entity) {
|
|
|
|
return entity instanceof EntityNPC && (this.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).alignment) :
|
|
|
|
this.isAggressive(((EntityNPC)entity).getClass()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canAmbush(EntityLiving entity) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean shouldFlee(EntityLiving entity) {
|
|
|
|
return (this.getHealth() <= (this.getMaxHealth() / 4) || !this.canCounter(entity)) &&
|
|
|
|
((entity instanceof EntityNPC && (((EntityNPC)entity).canAttack(this)) ||
|
|
|
|
(entity == this.getAttackedBy() && ((EntityNPC)entity).canCounter(this))));
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void setCombatTask()
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean isRangedWeapon(ItemStack stack) {
|
|
|
|
return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase ||
|
|
|
|
stack.getItem() == Items.snowball || stack.getItem() == Items.potion);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean isSneaking()
|
|
|
|
// {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected int getAttackSpeed() {
|
|
|
|
return 20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void setScaleForAge()
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public float getRenderScale()
|
|
|
|
// {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean isAttacking()
|
|
|
|
{
|
|
|
|
return this.getFlag(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAttacking(boolean atk)
|
|
|
|
{
|
|
|
|
this.setFlag(3, atk);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean isUsingItem()
|
|
|
|
// {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void setUsingItem(boolean use)
|
|
|
|
{
|
|
|
|
this.setFlag(4, use);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isMating()
|
|
|
|
{
|
|
|
|
return this.getFlag(5);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setMating(boolean mating)
|
|
|
|
{
|
|
|
|
this.setFlag(5, mating);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasArmsRaised()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasPowerRods() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasDualWings() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasSlimArms() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isCharged()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected boolean getNpcFlag(int flag)
|
|
|
|
// {
|
|
|
|
// return (this.dataWatcher.getWatchableObjectByte(20) & 1 << flag) != 0;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// protected void setNpcFlag(int flag, boolean set)
|
|
|
|
// {
|
|
|
|
// byte b0 = this.dataWatcher.getWatchableObjectByte(20);
|
|
|
|
//
|
|
|
|
// if (set)
|
|
|
|
// {
|
|
|
|
// this.dataWatcher.updateObject(20, Byte.valueOf((byte)(b0 | 1 << flag)));
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// this.dataWatcher.updateObject(20, Byte.valueOf((byte)(b0 & ~(1 << flag))));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected void applyEntityAttributes()
|
|
|
|
{
|
|
|
|
super.applyEntityAttributes();
|
|
|
|
this.getEntityAttribute(Attributes.FOLLOW_RANGE).setBaseValue(20.0D);
|
|
|
|
this.getAttributeMap().registerAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(2.0D);
|
|
|
|
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.3D);
|
|
|
|
this.setMaxHealth(this.getBaseHealth(this.rand));
|
|
|
|
this.getAttributeMap().registerAttribute(Attributes.MANA_CAPACITY);
|
|
|
|
this.getEntityAttribute(Attributes.MANA_CAPACITY).setBaseValue(20.0D);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected int getExperiencePoints(EntityNPC player)
|
|
|
|
// {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected void consumeItemFromStack(EntityNPC player, ItemStack stack)
|
|
|
|
{
|
|
|
|
// if (!player.creative)
|
|
|
|
// {
|
|
|
|
--stack.stackSize;
|
|
|
|
|
|
|
|
if (stack.stackSize <= 0)
|
|
|
|
{
|
|
|
|
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected boolean canDropLoot()
|
|
|
|
// {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected float getSoundPitch()
|
|
|
|
// {
|
|
|
|
// return (this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F;
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected void updateAITasks()
|
|
|
|
{
|
|
|
|
if (this.getGrowingAge() != 0)
|
|
|
|
{
|
|
|
|
this.setMating(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
super.updateAITasks();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void onNpcUpdate()
|
|
|
|
{
|
|
|
|
super.onLivingUpdate();
|
|
|
|
|
|
|
|
if(!this.worldObj.client && /* this.canPickUpLoot() && */ !this.noPickup && Config.mobGrief) {
|
|
|
|
for(EntityItem entityitem : this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(1.0D, 0.0D, 1.0D))) {
|
|
|
|
if(!entityitem.dead && entityitem.getEntityItem() != null && !entityitem.cannotPickup()) {
|
|
|
|
this.updateEquipmentIfNeeded(entityitem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.getGrowingAge() != 0)
|
|
|
|
{
|
|
|
|
this.setMating(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.worldObj.client) {
|
|
|
|
if (this.isMating())
|
|
|
|
{
|
|
|
|
++this.inLove;
|
|
|
|
|
|
|
|
if (this.inLove == 10)
|
|
|
|
{
|
|
|
|
this.inLove = 0;
|
|
|
|
double d0 = this.rand.gaussian() * 0.02D;
|
|
|
|
double d1 = this.rand.gaussian() * 0.02D;
|
|
|
|
double d2 = this.rand.gaussian() * 0.02D;
|
|
|
|
this.worldObj.spawnParticle(ParticleType.HEART, this.posX + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.floatv() * this.height), this.posZ + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.inLove = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean interact(EntityNPC player)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = player.inventory.getCurrentItem();
|
|
|
|
boolean flag = itemstack != null && !(itemstack.getItem() instanceof ItemTool || itemstack.getItem() instanceof ItemSword ||
|
|
|
|
itemstack.getItem() instanceof ItemHoe || itemstack.getItem() instanceof ItemShears);
|
|
|
|
|
|
|
|
if (itemstack != null && !this.isPlayer() && this.isBreedingItem(itemstack) && this.getGrowingAge() == 0 && !this.isMating())
|
|
|
|
{
|
|
|
|
this.consumeItemFromStack(player, itemstack);
|
|
|
|
if (!this.worldObj.client)
|
|
|
|
{
|
|
|
|
this.setIsWillingToMate(true);
|
|
|
|
this.setMating(true);
|
|
|
|
this.worldObj.setEntityState(this, (byte)12);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (itemstack != null && !this.isPlayer() && this.isBreedingItem(itemstack) && this.getGrowingAge() < 0)
|
|
|
|
{
|
|
|
|
this.consumeItemFromStack(player, itemstack);
|
|
|
|
if (!this.worldObj.client)
|
|
|
|
{
|
|
|
|
this.grow(this.rand.range(200, 250));
|
|
|
|
}
|
|
|
|
// else if (this.particleTimer == 0) {
|
|
|
|
// this.particleTimer = 40;
|
|
|
|
// }
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (!flag && !this.isPlayer() && this.isEntityAlive() && !this.isTalking())
|
|
|
|
{
|
|
|
|
if (!this.worldObj.client && this.canTrade() && this.getAttackTarget() == null)
|
|
|
|
{
|
|
|
|
this.setTalking(player);
|
|
|
|
player.connection.displayTradeGui(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// player.triggerAchievement(StatRegistry.timesTalkedToNpcStat);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return super.interact(player);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean attackEntityFrom(DamageSource source, int amount)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean attackEntityAsMob(Entity entityIn)
|
|
|
|
{
|
|
|
|
if(!this.worldObj.client && !Config.damageMobs)
|
|
|
|
return false;
|
|
|
|
int f = (int)this.getEntityAttribute(Attributes.ATTACK_DAMAGE).getAttributeValue();
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (entityIn instanceof EntityLiving)
|
|
|
|
{
|
|
|
|
f += EnchantmentHelper.getDamageModifier(this.getHeldItem());
|
|
|
|
i += EnchantmentHelper.getKnockbackModifier(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean flag = entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), f);
|
|
|
|
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
entityIn.addKnockback((double)(-ExtMath.sin(this.rotYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F), 0.1D, (double)(ExtMath.cos(this.rotYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F));
|
|
|
|
this.motionX *= 0.6D;
|
|
|
|
this.motionZ *= 0.6D;
|
|
|
|
}
|
|
|
|
|
|
|
|
int j = EnchantmentHelper.getFireAspectModifier(this);
|
|
|
|
|
|
|
|
if (j > 0)
|
|
|
|
{
|
|
|
|
entityIn.setFire(j * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.applyEnchantments(this, entityIn);
|
|
|
|
}
|
|
|
|
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void attackEntityWithRangedAttack(EntityLiving target, float range)
|
|
|
|
{
|
|
|
|
ItemStack stack = this.getHeldItem();
|
|
|
|
if(stack == null)
|
|
|
|
return;
|
|
|
|
if(stack.getItem() == Items.bow) {
|
|
|
|
EntityArrow entityarrow = new EntityArrow(this.worldObj, this, target, 1.6F, 2.0f);
|
|
|
|
int i = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem());
|
|
|
|
int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem());
|
|
|
|
entityarrow.setDamage((double)(range * 2.0F) + this.rand.gaussian() * 0.25D + (double)(/* (float)this.worldObj.getDifficulty().getId() */ 3.0f * 0.11F));
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
entityarrow.setDamage(entityarrow.getDamage() + (double)i * 0.5D + 0.5D);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j > 0)
|
|
|
|
{
|
|
|
|
entityarrow.setKnockbackStrength(j);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0)
|
|
|
|
{
|
|
|
|
entityarrow.setFire(100);
|
|
|
|
}
|
|
|
|
|
2025-03-18 12:03:56 +01:00
|
|
|
this.playSound(SoundEvent.THROW, 1.0F);
|
2025-03-11 00:23:54 +01:00
|
|
|
this.worldObj.spawnEntityInWorld(entityarrow);
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemGunBase) {
|
|
|
|
EntityBullet bullet = new EntityBullet(this.worldObj, this, target, ((ItemGunBase)stack.getItem()).getVelocity(), 0.75f);
|
|
|
|
int i = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem());
|
|
|
|
// int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem());
|
|
|
|
bullet.setDamage(((ItemGunBase)stack.getItem()).getAmmo().getDamage(stack));
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
bullet.setDamage(bullet.getDamage() + i);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (j > 0)
|
|
|
|
// {
|
|
|
|
// entityarrow.setKnockbackStrength(j);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0)
|
|
|
|
// {
|
|
|
|
// entityarrow.setFire(100);
|
|
|
|
// }
|
|
|
|
|
2025-03-18 12:03:56 +01:00
|
|
|
this.playSound(SoundEvent.EXPLODE_ALT, 1.0f);
|
2025-03-11 00:23:54 +01:00
|
|
|
this.worldObj.spawnEntityInWorld(bullet);
|
|
|
|
}
|
|
|
|
else if(stack.getItem() == Items.snowball) {
|
|
|
|
EntitySnowball entitysnowball = new EntitySnowball(this.worldObj, this);
|
|
|
|
double d0 = target.posY + (double)target.getEyeHeight() - 1.100000023841858D;
|
|
|
|
double d1 = target.posX - this.posX;
|
|
|
|
double d2 = d0 - entitysnowball.posY;
|
|
|
|
double d3 = target.posZ - this.posZ;
|
|
|
|
float f = ExtMath.sqrtd(d1 * d1 + d3 * d3) * 0.2F;
|
|
|
|
entitysnowball.setThrowableHeading(d1, d2 + (double)f, d3, 1.6F, 12.0F);
|
2025-03-18 12:03:56 +01:00
|
|
|
this.playSound(SoundEvent.THROW, 1.0F);
|
2025-03-11 00:23:54 +01:00
|
|
|
this.worldObj.spawnEntityInWorld(entitysnowball);
|
|
|
|
}
|
|
|
|
else if(stack.getItem() == Items.potion) {
|
|
|
|
EntityPotion entitypotion = new EntityPotion(this.worldObj, this, 32732);
|
|
|
|
double d0 = target.posY + (double)target.getEyeHeight() - 1.100000023841858D;
|
|
|
|
entitypotion.rotPitch -= -20.0F;
|
|
|
|
double d1 = target.posX + target.motionX - this.posX;
|
|
|
|
double d2 = d0 - this.posY;
|
|
|
|
double d3 = target.posZ + target.motionZ - this.posZ;
|
|
|
|
float f = ExtMath.sqrtd(d1 * d1 + d3 * d3);
|
|
|
|
|
|
|
|
if (f >= 8.0F && !target.hasEffect(Potion.moveSlowdown))
|
|
|
|
{
|
|
|
|
entitypotion.setPotionDamage(32698);
|
|
|
|
}
|
|
|
|
else if (target.getHealth() >= 8 && !target.hasEffect(Potion.poison))
|
|
|
|
{
|
|
|
|
entitypotion.setPotionDamage(32660);
|
|
|
|
}
|
|
|
|
else if (f <= 3.0F && !target.hasEffect(Potion.weakness) && this.rand.floatv() < 0.25F)
|
|
|
|
{
|
|
|
|
entitypotion.setPotionDamage(32696);
|
|
|
|
}
|
|
|
|
|
|
|
|
entitypotion.setThrowableHeading(d1, d2 + (double)(f * 0.2F), d3, 1.5F, 0.5F);
|
|
|
|
this.worldObj.spawnEntityInWorld(entitypotion);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void entityInit()
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void writeEntityToNBT(NBTTagCompound tagCompound)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void readEntityFromNBT(NBTTagCompound tagCompund)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected boolean canDespawn()
|
|
|
|
// {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected String getHurtSound()
|
|
|
|
// {
|
|
|
|
// return "mob.npc.hit";
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// protected String getDeathSound()
|
|
|
|
// {
|
|
|
|
// return "mob.npc.death";
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void setChar(String character)
|
|
|
|
{
|
|
|
|
this.dataWatcher.updateObject(16, character);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getChar()
|
|
|
|
{
|
|
|
|
return this.dataWatcher.getWatchableObjectString(16);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setCape(String cape)
|
|
|
|
{
|
|
|
|
this.dataWatcher.updateObject(17, cape);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getCape()
|
|
|
|
{
|
|
|
|
return this.dataWatcher.getWatchableObjectString(17);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setNpcClass(Enum type)
|
|
|
|
{
|
|
|
|
this.dataWatcher.updateObject(22, (byte)(type == null ? -1 : type.ordinal()));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Enum getNpcClass()
|
|
|
|
{
|
|
|
|
byte n = this.dataWatcher.getWatchableObjectByte(22);
|
|
|
|
return n < 0 || this.species == null || this.species.classEnum == null ? null :
|
|
|
|
this.species.classEnum.getEnumConstants()[n % this.species.classEnum.getEnumConstants().length];
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAlignment(Alignment align)
|
|
|
|
{
|
|
|
|
this.alignment = align;
|
|
|
|
this.dataWatcher.updateObject(18, (byte)align.ordinal());
|
|
|
|
}
|
|
|
|
|
|
|
|
public Alignment getAlignment()
|
|
|
|
{
|
|
|
|
return Alignment.values()[this.dataWatcher.getWatchableObjectByte(18) % Alignment.values().length];
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setHeight(float height)
|
|
|
|
{
|
|
|
|
this.dataWatcher.updateObject(29, ExtMath.clampf(height, 0.2f, 10.0f));
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getHeight()
|
|
|
|
{
|
|
|
|
return this.dataWatcher.getWatchableObjectFloat(29);
|
|
|
|
}
|
|
|
|
|
|
|
|
public SpeciesInfo getSpecies() {
|
|
|
|
return this.species;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ClassInfo getSpClass() {
|
|
|
|
if(this.species == null)
|
|
|
|
return null;
|
|
|
|
Enum type = this.getNpcClass();
|
|
|
|
return type == null ? null : this.species.classmap.get(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAttackedBy(EntityLiving livingBase)
|
|
|
|
{
|
|
|
|
if(livingBase != null && /* livingBase.isPlayer() && */ this.isEntityAlive() && /* !this.isPeaceful() && */ this.getAttackedBy() != livingBase &&
|
|
|
|
Config.mobAttacks) {
|
|
|
|
this.worldObj.setEntityState(this, (byte)13);
|
|
|
|
}
|
|
|
|
super.setAttackedBy(livingBase);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void onDeath(DamageSource cause)
|
|
|
|
// {
|
|
|
|
//
|
|
|
|
// super.onDeath(cause);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected void dropEquipment()
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void setTalking(EntityNPC player)
|
|
|
|
{
|
|
|
|
this.talkingPlayer = player;
|
|
|
|
}
|
|
|
|
|
|
|
|
public EntityNPC getTalking()
|
|
|
|
{
|
|
|
|
return this.talkingPlayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isTalking()
|
|
|
|
{
|
|
|
|
return this.talkingPlayer != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canMate()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean getIsWillingToMate(boolean update)
|
|
|
|
{
|
|
|
|
if (!this.isWilling && update && this.canMate())
|
|
|
|
{
|
|
|
|
this.isWilling = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.isWilling;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setIsWillingToMate(boolean willing)
|
|
|
|
{
|
|
|
|
this.isWilling = willing;
|
|
|
|
if(!this.isWilling) {
|
|
|
|
this.setMating(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getPrefix() {
|
|
|
|
Enum cls = this.species.prefix ? this.getNpcClass() : null;
|
|
|
|
return cls == null ? null : cls.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
// public String getName()
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public String formatStats() {
|
|
|
|
// return super.formatStats();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public float getEyeHeight()
|
|
|
|
// {
|
|
|
|
//// float f = 1.62F;
|
|
|
|
////
|
|
|
|
//// if (this.isChild())
|
|
|
|
//// {
|
|
|
|
//// f = (float)((double)f - 0.81D);
|
|
|
|
//// }
|
|
|
|
//
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void handleStatusUpdate(byte id)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public Object onInitialSpawn(Object livingdata)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean isPropogatingSpawnData(boolean newGroup) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setItemInfo(CharacterInfo info) {
|
|
|
|
for(int z = 0; z < 5; z++) {
|
|
|
|
this.setItem(z, info.pickItem(z, this.rand));
|
|
|
|
}
|
|
|
|
int items = this.rand.zrange(4);
|
|
|
|
ItemStack stack;
|
|
|
|
this.extraInventory.clear();
|
|
|
|
for(int z = 0; z < items; z++) {
|
|
|
|
stack = info.pickItem(5, this.rand);
|
|
|
|
if(stack == null) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
this.extraInventory.addStack(stack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// public EntityNPC createChild(EntityLiving ageable)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void onStruckByLightning(EntityLightning lightningBolt)
|
|
|
|
// {
|
|
|
|
// if (!this.worldObj.client && !this.isDead)
|
|
|
|
// {
|
|
|
|
//
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// super.onStruckByLightning(lightningBolt);
|
|
|
|
// }
|
|
|
|
|
|
|
|
public InventoryBasic getExtendedInventory()
|
|
|
|
{
|
|
|
|
return this.extraInventory;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void updateEquipmentIfNeeded(EntityItem itemEntity)
|
|
|
|
// {
|
|
|
|
// super.updateEquipmentIfNeeded(itemEntity);
|
|
|
|
// if(!itemEntity.dead) {
|
|
|
|
// ItemStack stack = itemEntity.getEntityItem();
|
|
|
|
// Item item = stack.getItem();
|
|
|
|
//
|
|
|
|
// if (this.canPickUpExtraItem(item))
|
|
|
|
// {
|
|
|
|
// ItemStack remain = this.extraInventory.addStack(stack);
|
|
|
|
//
|
|
|
|
// if (remain == null)
|
|
|
|
// {
|
|
|
|
// itemEntity.setDead();
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// stack.stackSize = remain.stackSize;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
private boolean canPickUpExtraItem(Item itemIn)
|
|
|
|
{
|
|
|
|
return itemIn == Items.golden_apple || itemIn == Items.sugar;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public LayerExtra getExtrasLayer()
|
|
|
|
// {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public String getLocationSkin()
|
|
|
|
// {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected boolean hasSlimSkin()
|
|
|
|
{
|
|
|
|
return this.getChar().startsWith("~");
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getLocationCape()
|
|
|
|
{
|
|
|
|
return !this.getCape().isEmpty() ? EntityTexManager.getCape(this.getCape()) : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean canRenderExtras()
|
|
|
|
// {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public boolean isWearing(ModelPart part)
|
|
|
|
// {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public int getLeashColor() {
|
|
|
|
return 0x202020;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getManaPoints() {
|
|
|
|
return this.dataWatcher.getWatchableObjectInt(21);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setManaPoints(int pts) {
|
|
|
|
this.dataWatcher.updateObject(21, pts);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public final boolean isAggressive() {
|
|
|
|
// return this.alignment.evil;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public final boolean isPeaceful() {
|
|
|
|
// return this.alignment.good;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canUseMagic() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public abstract int getBaseHealth(Random rand);
|
|
|
|
|
|
|
|
// public final int getBaseEnergy(Random rand) {
|
|
|
|
// return 0;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public float getHeightDeviation(Random rand) {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public abstract Alignment getNaturalAlign(Random rand);
|
|
|
|
|
|
|
|
// public float getBaseSize(Random rand) {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean isBreedingItem(ItemStack stack)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canTrade()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NameRegistry getNameType()
|
|
|
|
{
|
|
|
|
return NameRegistry.FANTASY;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String pickRandomName(Random rand, Enum type)
|
|
|
|
{
|
|
|
|
return this.getNameType().generate(rand, rand.chance(40) ? (rand.chance(15) ? 5 : 4) : (rand.chance() ? 3 : 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
// public int getColor() {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void setPlaying(boolean playing) {
|
|
|
|
this.playing = playing;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPlaying() {
|
|
|
|
return this.playing;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isFleeing() {
|
|
|
|
return this.fleeing;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean canPlay() {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public boolean isChild() {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected int decreaseAirSupply(int air) {
|
|
|
|
// return air;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public int getMaxMana() {
|
|
|
|
return (int)this.getEntityAttribute(Attributes.MANA_CAPACITY).getAttributeValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
public MerchantRecipeList getTrades(EntityNPC player) {
|
|
|
|
if(this.trades == null) {
|
|
|
|
this.trades = new MerchantRecipeList();
|
|
|
|
int n = this.rand.range(5, 25);
|
|
|
|
for(int z = 0; z < n; z++) {
|
|
|
|
this.rand.pick(TradeRegistry.TRADES).modifyMerchantRecipeList(this.trades, this.rand);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this.trades;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean isNotColliding() {
|
|
|
|
// return this.canSpawnInLiquid() ?
|
|
|
|
// (this.worldObj.checkNoEntityCollision(this.getEntityBoundingBox(), this) &&
|
|
|
|
// this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty()
|
|
|
|
// /* && !this.worldObj.isAnyLiquid(this.getEntityBoundingBox()) */) : super.isNotColliding();
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected int applyPotionDamageCalculations(DamageSource source, int damage) {
|
|
|
|
damage = super.applyPotionDamageCalculations(source, damage);
|
|
|
|
if(this.canUseMagic() && source.isMagicDamage())
|
|
|
|
damage = source.getEntity() == this ? 0 : (int)((double)damage * 0.15D);
|
|
|
|
return damage;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected boolean teleportRandomly() {
|
|
|
|
double x = this.posX + (this.rand.doublev() - 0.5D) * 64.0D;
|
|
|
|
double y = this.posY + (double)(this.rand.excl(-32, 32));
|
|
|
|
double z = this.posZ + (this.rand.doublev() - 0.5D) * 64.0D;
|
|
|
|
return this.teleportTo(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean teleportToEntity(Entity entity) {
|
|
|
|
Vec3 vec3 = new Vec3(this.posX - entity.posX,
|
|
|
|
this.getEntityBoundingBox().minY + (double)(this.height / 2.0F) - entity.posY + (double)entity.getEyeHeight(),
|
|
|
|
this.posZ - entity.posZ);
|
|
|
|
vec3 = vec3.normalize();
|
|
|
|
double dist = 16.0D;
|
|
|
|
double x = this.posX + (this.rand.doublev() - 0.5D) * 8.0D - vec3.xCoord * dist;
|
|
|
|
double y = this.posY + (double)(this.rand.excl(-8, 8)) - vec3.yCoord * dist;
|
|
|
|
double z = this.posZ + (this.rand.doublev() - 0.5D) * 8.0D - vec3.zCoord * dist;
|
|
|
|
return this.teleportTo(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean teleportTo(double x, double y, double z) {
|
|
|
|
double ox = this.posX;
|
|
|
|
double oy = this.posY;
|
|
|
|
double oz = this.posZ;
|
|
|
|
this.posX = x;
|
|
|
|
this.posY = y;
|
|
|
|
this.posZ = z;
|
|
|
|
boolean done = false;
|
|
|
|
BlockPos pos = new BlockPos(this.posX, this.posY, this.posZ);
|
|
|
|
|
|
|
|
if(this.worldObj.isBlockLoaded(pos)) {
|
|
|
|
boolean ground = false;
|
|
|
|
|
|
|
|
while(!ground && pos.getY() > 0) {
|
|
|
|
BlockPos down = pos.down();
|
|
|
|
Block block = this.worldObj.getState(down).getBlock();
|
|
|
|
|
|
|
|
if(block.getMaterial().blocksMovement()) {
|
|
|
|
ground = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
--this.posY;
|
|
|
|
pos = down;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ground) {
|
|
|
|
super.setPositionAndUpdate(this.posX, this.posY, this.posZ);
|
|
|
|
|
|
|
|
if(this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty()
|
|
|
|
&& !this.worldObj.isAnyLiquid(this.getEntityBoundingBox())) {
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!done) {
|
|
|
|
this.setPosition(ox, oy, oz);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.worldObj.playAuxSFX(1013, new BlockPos(ox, oy, oz), 0);
|
|
|
|
((WorldServer)this.worldObj).spawnParticle(ParticleType.PORTAL,
|
|
|
|
ox + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D,
|
|
|
|
oy + this.rand.doublev() * (double)this.height,
|
|
|
|
oz + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D, 8,
|
|
|
|
(this.rand.floatv() - 0.5F) * 0.2F, (this.rand.floatv() - 0.5F) * 0.2F, (this.rand.floatv() - 0.5F) * 0.2F,
|
|
|
|
0.15D);
|
|
|
|
this.worldObj.playAuxSFX(1005, this.getPosition(), 0);
|
|
|
|
((WorldServer)this.worldObj).spawnParticle(ParticleType.PORTAL,
|
|
|
|
this.posX + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D,
|
|
|
|
this.posY + this.rand.doublev() * (double)this.height,
|
|
|
|
this.posZ + (this.rand.doublev() - 0.5D) * (double)this.width * 2.0D, 8,
|
|
|
|
(this.rand.floatv() - 0.5F) * 0.2F, (this.rand.floatv() - 0.5F) * 0.2F, (this.rand.floatv() - 0.5F) * 0.2F,
|
|
|
|
0.15D);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// public boolean setSlot(int slot, ItemStack stack) {
|
|
|
|
// int i;
|
|
|
|
//
|
|
|
|
// if(slot == 99) {
|
|
|
|
// i = 0;
|
|
|
|
// }
|
|
|
|
// else {
|
|
|
|
// i = slot - 100 + 1;
|
|
|
|
//
|
|
|
|
// if(i < 0 || i >= this.equipment.length) {
|
|
|
|
//// return false;
|
|
|
|
// i = slot - 300;
|
|
|
|
//
|
|
|
|
// if (i >= 0 && i < this.extraInventory.getSizeInventory())
|
|
|
|
// {
|
|
|
|
// this.extraInventory.setInventorySlotContents(i, stack);
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if(stack != null && ItemArmor.getArmorPosition(stack) != i && (i != 4 || !(stack.getItem() instanceof ItemBlock))) {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// else {
|
|
|
|
// this.setItem(i, stack);
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public boolean setSlot(int slot, ItemStack stack)
|
|
|
|
// {
|
|
|
|
// if (super.setSlot(slot, stack))
|
|
|
|
// {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// int i = slot - 300;
|
|
|
|
//
|
|
|
|
// if (i >= 0 && i < this.extraInventory.getSizeInventory())
|
|
|
|
// {
|
|
|
|
// this.extraInventory.setInventorySlotContents(i, stack);
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected void updateEquipmentIfNeeded(EntityItem itemEntity) {
|
|
|
|
ItemStack stack = itemEntity.getEntityItem();
|
|
|
|
if(stack.getItem().getRadiation(stack) > 0.0f)
|
|
|
|
return;
|
|
|
|
int slot = ItemArmor.getArmorPosition(stack);
|
|
|
|
|
|
|
|
if(slot > -1) {
|
|
|
|
boolean flag = true;
|
|
|
|
ItemStack old = this.getItem(slot);
|
|
|
|
|
|
|
|
if(old != null) {
|
|
|
|
if(slot == 0) {
|
|
|
|
if(stack.getItem() instanceof ItemSword && !(old.getItem() instanceof ItemSword)) {
|
|
|
|
flag = true;
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemSword && old.getItem() instanceof ItemSword) {
|
|
|
|
ItemSword itemsword = (ItemSword)stack.getItem();
|
|
|
|
ItemSword itemsword1 = (ItemSword)old.getItem();
|
|
|
|
|
|
|
|
if(itemsword.getDamageVsEntity() != itemsword1.getDamageVsEntity()) {
|
|
|
|
flag = itemsword.getDamageVsEntity() > itemsword1.getDamageVsEntity();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
flag = stack.getMetadata() > old.getMetadata() || stack.hasTagCompound() && !old.hasTagCompound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemBow && old.getItem() instanceof ItemBow) {
|
|
|
|
flag = stack.hasTagCompound() && !old.hasTagCompound();
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemGunBase && !(old.getItem() instanceof ItemBow)) {
|
|
|
|
flag = true;
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemBow && !(old.getItem() instanceof ItemBow) && !(old.getItem() instanceof ItemSword)) {
|
|
|
|
flag = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
flag = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemArmor && !(old.getItem() instanceof ItemArmor)) {
|
|
|
|
flag = true;
|
|
|
|
}
|
|
|
|
else if(stack.getItem() instanceof ItemArmor && old.getItem() instanceof ItemArmor) {
|
|
|
|
ItemArmor itemarmor = (ItemArmor)stack.getItem();
|
|
|
|
ItemArmor itemarmor1 = (ItemArmor)old.getItem();
|
|
|
|
|
|
|
|
if(itemarmor.damageReduceAmount != itemarmor1.damageReduceAmount) {
|
|
|
|
flag = itemarmor.damageReduceAmount > itemarmor1.damageReduceAmount;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
flag = stack.getMetadata() > old.getMetadata() || stack.hasTagCompound() && !old.hasTagCompound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
flag = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(flag) { // && this.canPickUpItem(stack)) {
|
|
|
|
if(old != null) { // && this.rand.floatv() - 0.1F < this.dropChances[slot]) {
|
|
|
|
this.entityDropItem(old, 0.0F);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if(stack.getItem() == Items.diamond && itemEntity.getThrower() != null) {
|
|
|
|
// EntityNPC entityplayer = this.worldObj.getPlayer(itemEntity.getThrower());
|
|
|
|
//
|
|
|
|
// if(entityplayer != null) {
|
|
|
|
// entityplayer.triggerAchievement(AchievementList.diamondsToYou);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
this.setItem(slot, stack);
|
|
|
|
// this.dropChances[slot] = 2.0F;
|
|
|
|
// this.noDespawn = true;
|
|
|
|
this.onItemPickup(itemEntity, 1);
|
|
|
|
itemEntity.setDead();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!itemEntity.dead) {
|
|
|
|
stack = itemEntity.getEntityItem();
|
|
|
|
Item item = stack.getItem();
|
|
|
|
|
|
|
|
if (this.canPickUpExtraItem(item))
|
|
|
|
{
|
|
|
|
ItemStack remain = this.extraInventory.addStack(stack);
|
|
|
|
|
|
|
|
if (remain == null)
|
|
|
|
{
|
|
|
|
itemEntity.setDead();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
stack.stackSize = remain.stackSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void dropEquipment(boolean wasRecentlyHit, int lootingModifier) {
|
|
|
|
// for(int i = 0; i < this.getInventory().length; ++i) {
|
|
|
|
// ItemStack itemstack = this.getItem(i);
|
|
|
|
// boolean flag = this.dropChances[i] > 1.0F;
|
|
|
|
//
|
|
|
|
// if(itemstack != null && (wasRecentlyHit || flag) && this.rand.floatv() - (float)lootingModifier * 0.01F < this.dropChances[i]) {
|
|
|
|
// if(!flag && itemstack.isItemStackDamageable()) {
|
|
|
|
// int j = Math.max(itemstack.getMaxDamage() - 25, 1);
|
|
|
|
// int k = itemstack.getMaxDamage() - this.rand.zrange(this.rand.roll(j));
|
|
|
|
//
|
|
|
|
// if(k > j) {
|
|
|
|
// k = j;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if(k < 1) {
|
|
|
|
// k = 1;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// itemstack.setItemDamage(k);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// this.entityDropItem(itemstack, 0.0F);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected boolean canPickUpItem(ItemStack stack) {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public boolean canPickUpLoot() {
|
|
|
|
// return this.canPickUpLoot;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public void setCanPickUpLoot(boolean canPickup) {
|
|
|
|
// this.canPickUpLoot = canPickup;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) {
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// public static Item getArmorItemForSlot(int armorSlot, int itemTier) {
|
|
|
|
// switch(armorSlot)
|
|
|
|
// {
|
|
|
|
// case 4:
|
|
|
|
// if(itemTier == 0) {
|
|
|
|
// return Items.leather_helmet;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 1) {
|
|
|
|
// return Items.gold_helmet;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 2) {
|
|
|
|
// return Items.chain_helmet;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 3) {
|
|
|
|
// return Items.iron_helmet;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 4) {
|
|
|
|
// return Items.diamond_helmet;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// case 3:
|
|
|
|
// if(itemTier == 0) {
|
|
|
|
// return Items.leather_chestplate;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 1) {
|
|
|
|
// return Items.gold_chestplate;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 2) {
|
|
|
|
// return Items.chain_chestplate;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 3) {
|
|
|
|
// return Items.iron_chestplate;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 4) {
|
|
|
|
// return Items.diamond_chestplate;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// case 2:
|
|
|
|
// if(itemTier == 0) {
|
|
|
|
// return Items.leather_leggings;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 1) {
|
|
|
|
// return Items.gold_leggings;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 2) {
|
|
|
|
// return Items.chain_leggings;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 3) {
|
|
|
|
// return Items.iron_leggings;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 4) {
|
|
|
|
// return Items.diamond_leggings;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// case 1:
|
|
|
|
// if(itemTier == 0) {
|
|
|
|
// return Items.leather_boots;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 1) {
|
|
|
|
// return Items.gold_boots;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 2) {
|
|
|
|
// return Items.chain_boots;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 3) {
|
|
|
|
// return Items.iron_boots;
|
|
|
|
// }
|
|
|
|
// else if(itemTier == 4) {
|
|
|
|
// return Items.diamond_boots;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// default:
|
|
|
|
// return null;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public ItemStack getHeldItem() {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public ItemStack getItem(int slot) {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public ItemStack getArmor(int slot) {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void setItem(int slot, ItemStack stack) {
|
|
|
|
// this.equipment[slot] = stack;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void setItem(int slot, ItemStack stack)
|
|
|
|
// {
|
|
|
|
//// super.setItem(slot, stack);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public void setItemNoUpdate(int slot, ItemStack stack)
|
|
|
|
// {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public ItemStack[] getInventory() {
|
|
|
|
// return ;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public int getTrackingRange() {
|
|
|
|
// return 80;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public int getUpdateFrequency() {
|
|
|
|
// return 3;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public boolean isSendingVeloUpdates() {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) {
|
|
|
|
// if(this.rand.floatv() < 0.15F * difficulty.getDifficulty()) {
|
|
|
|
// int i = this.rand.zrange(2);
|
|
|
|
//// float f = this.worldObj.getDifficulty() == Difficulty.HARD ? 0.1F : 0.25F;
|
|
|
|
// float f = 0.1F;
|
|
|
|
//
|
|
|
|
// if(this.rand.floatv() < 0.095F) {
|
|
|
|
// ++i;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if(this.rand.floatv() < 0.095F) {
|
|
|
|
// ++i;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if(this.rand.floatv() < 0.095F) {
|
|
|
|
// ++i;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// for(int j = 3; j >= 0; --j) {
|
|
|
|
// ItemStack itemstack = this.getArmor(j);
|
|
|
|
//
|
|
|
|
// if(j < 3 && this.rand.floatv() < f) {
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if(itemstack == null) {
|
|
|
|
// Item item = getArmorItemForSlot(j + 1, i);
|
|
|
|
//
|
|
|
|
// if(item != null) {
|
|
|
|
// this.setItem(j + 1, new ItemStack(item));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected void setEnchantmentBasedOnDifficulty(DifficultyInstance difficulty) {
|
|
|
|
// float f = difficulty.getDifficulty();
|
|
|
|
//
|
|
|
|
// if(this.getHeldItem() != null && this.rand.floatv() < 0.25F * f) {
|
|
|
|
// EnchantmentHelper.addRandomEnchantment(this.rand, this.getHeldItem(), (int)(5.0F + f * (float)this.rand.zrange(18)));
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// for(int i = 0; i < 4; ++i) {
|
|
|
|
// ItemStack itemstack = this.getArmor(i);
|
|
|
|
//
|
|
|
|
// if(itemstack != null && this.rand.floatv() < 0.5F * f) {
|
|
|
|
// EnchantmentHelper.addRandomEnchantment(this.rand, itemstack, (int)(5.0F + f * (float)this.rand.zrange(18)));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean useMana(int pts) {
|
|
|
|
int mana = this.getManaPoints();
|
|
|
|
if(mana >= pts)
|
|
|
|
this.setManaPoints(mana - pts);
|
|
|
|
return mana >= pts;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateNpc()
|
|
|
|
{
|
|
|
|
if(!this.worldObj.client) {
|
|
|
|
for (int j = 0; j < 5; ++j)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.prevEquipment[j];
|
|
|
|
ItemStack itemstack1 = this.getItem(j);
|
|
|
|
|
|
|
|
if (!ItemStack.areItemStacksEqual(itemstack1, itemstack))
|
|
|
|
{
|
|
|
|
((WorldServer)this.worldObj).sendToAllTrackingEntity(this, new SPacketEntityEquipment(this.getId(), j, itemstack1));
|
|
|
|
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
this.getAttributeMap().removeAttributeModifiers(itemstack.getAttributeModifiers(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemstack1 != null)
|
|
|
|
{
|
|
|
|
this.getAttributeMap().applyAttributeModifiers(itemstack1.getAttributeModifiers(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.prevEquipment[j] = itemstack1 == null ? null : itemstack1.copy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
super.onUpdate();
|
|
|
|
if(!this.worldObj.client && Config.regeneration && this.shouldHeal()) {
|
|
|
|
++this.healTimer;
|
|
|
|
|
|
|
|
if(this.healTimer >= 80) {
|
|
|
|
this.heal(1);
|
|
|
|
this.healTimer = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void sendDeathMessage() {
|
|
|
|
// this.sendDeathMessage(false, true);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// protected boolean canRegenerateHealth() {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected boolean shouldHeal() {
|
|
|
|
return this.canRegenerateHealth() && Config.healChance > 0 && this.getHealth() > 0 && this.getHealth() < this.getMaxHealth()
|
|
|
|
&& this.rand.chance(Config.healChance);
|
|
|
|
}
|
|
|
|
|
|
|
|
public byte[] getSkin() {
|
|
|
|
return this.skin;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSkin(byte[] skin) {
|
|
|
|
this.skin = skin;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// START SP
|
|
|
|
|
|
|
|
public boolean attackEntityFrom(DamageSource source, int amount)
|
|
|
|
{
|
|
|
|
if(this.gm != null)
|
|
|
|
return this.sendQueue == null;
|
|
|
|
if(this.isEntityInvulnerable(source))
|
|
|
|
return false;
|
|
|
|
if(this.connection != null) {
|
|
|
|
if(this.getHealth() <= 0)
|
|
|
|
return false;
|
|
|
|
// Entity entity = source.getEntity();
|
|
|
|
// if(entity instanceof EntityArrow && ((EntityArrow)entity).shootingEntity != null)
|
|
|
|
// entity = ((EntityArrow)entity).shootingEntity;
|
|
|
|
// return super.attackEntityFrom(source, amount);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.setIsWillingToMate(false);
|
|
|
|
this.setMating(false);
|
|
|
|
}
|
|
|
|
return super.attackEntityFrom(source, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Heal living entity (param: amount of half-hearts)
|
|
|
|
*/
|
|
|
|
public void heal(int healAmount)
|
|
|
|
{
|
|
|
|
if(this.sendQueue == null)
|
|
|
|
super.heal(healAmount);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void healMana(int amount)
|
|
|
|
{
|
|
|
|
if(this.sendQueue == null)
|
|
|
|
super.healMana(amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when a player mounts an entity. e.g. mounts a pig, mounts a boat.
|
|
|
|
*/
|
|
|
|
public void mountEntity(Entity entityIn)
|
|
|
|
{
|
|
|
|
Entity entity = this.vehicle;
|
|
|
|
super.mountEntity(entityIn);
|
|
|
|
if(this.connection != null && entityIn != entity)
|
|
|
|
this.connection.mountEntity(entityIn);
|
|
|
|
// super.mountEntity(entityIn);
|
|
|
|
|
|
|
|
if (this.sendQueue != null && entityIn instanceof EntityCart)
|
|
|
|
{
|
|
|
|
this.gm.getSoundManager().playSound(new MovingSoundMinecartRiding(this, (EntityCart)entityIn));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called to update the entity's position/logic.
|
|
|
|
*/
|
|
|
|
public void onUpdate()
|
|
|
|
{
|
|
|
|
if(this.sendQueue != null) {
|
|
|
|
if (this.worldObj.isBlockLoaded(new BlockPos(this.posX, 0.0D, this.posZ)))
|
|
|
|
{
|
|
|
|
// super.onUpdate();
|
|
|
|
this.updatePlayer();
|
|
|
|
|
|
|
|
if (this.isRiding())
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround));
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketInput(this.moveStrafe, this.moveForward, this.gm.jump, this.gm.sneak));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.onUpdateWalkingPlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.connection != null) {
|
|
|
|
this.connection.updateEntity();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.gm != null) {
|
|
|
|
// this.renderOffsetY = 0.0F;
|
|
|
|
// super.onUpdate();
|
|
|
|
this.updatePlayer();
|
|
|
|
this.prevLswingAmount = this.lswingAmount;
|
|
|
|
double d0 = this.posX - this.prevX;
|
|
|
|
double d1 = this.posZ - this.prevZ;
|
|
|
|
float f = ExtMath.sqrtd(d0 * d0 + d1 * d1) * 4.0F;
|
|
|
|
|
|
|
|
if (f > 1.0F)
|
|
|
|
{
|
|
|
|
f = 1.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.lswingAmount += (f - this.lswingAmount) * 0.4F;
|
|
|
|
this.limbSwing += this.lswingAmount;
|
|
|
|
|
|
|
|
if (!this.otherPlayerUsing && this.isUsingItem() && this.inventory.mainInventory[this.inventory.currentItem] != null)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.inventory.mainInventory[this.inventory.currentItem];
|
|
|
|
this.setItemInUse(this.inventory.mainInventory[this.inventory.currentItem], itemstack.getItem().getMaxItemUseDuration(itemstack));
|
|
|
|
this.otherPlayerUsing = true;
|
|
|
|
}
|
|
|
|
else if (this.otherPlayerUsing && !this.isUsingItem())
|
|
|
|
{
|
|
|
|
this.clearItemInUse();
|
|
|
|
this.otherPlayerUsing = false;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.updateNpc();
|
|
|
|
// this.updatePlayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updatePlayer() {
|
|
|
|
this.noClip = this.noclip;
|
|
|
|
|
|
|
|
if (this.noclip)
|
|
|
|
{
|
|
|
|
this.onGround = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.itemInUse != null)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.inventory.getCurrentItem();
|
|
|
|
|
|
|
|
if (itemstack == this.itemInUse)
|
|
|
|
{
|
|
|
|
if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0)
|
|
|
|
{
|
|
|
|
this.updateItemUse(itemstack, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (--this.itemInUseCount == 0 && !this.worldObj.client)
|
|
|
|
{
|
|
|
|
this.onItemUseFinish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.clearItemInUse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.xpCooldown > 0)
|
|
|
|
{
|
|
|
|
--this.xpCooldown;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.updateNpc();
|
|
|
|
// super.onUpdate();
|
|
|
|
|
|
|
|
if (!this.worldObj.client && this.openContainer != null && !this.openContainer.canInteractWith(this))
|
|
|
|
{
|
|
|
|
this.closeScreen();
|
|
|
|
this.openContainer = this.inventoryContainer;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.prevChasingPosX = this.chasingPosX;
|
|
|
|
this.prevChasingPosY = this.chasingPosY;
|
|
|
|
this.prevChasingPosZ = this.chasingPosZ;
|
|
|
|
double d5 = this.posX - this.chasingPosX;
|
|
|
|
double d0 = this.posY - this.chasingPosY;
|
|
|
|
double d1 = this.posZ - this.chasingPosZ;
|
|
|
|
double d2 = 10.0D;
|
|
|
|
|
|
|
|
if (d5 > d2)
|
|
|
|
{
|
|
|
|
this.prevChasingPosX = this.chasingPosX = this.posX;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d1 > d2)
|
|
|
|
{
|
|
|
|
this.prevChasingPosZ = this.chasingPosZ = this.posZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d0 > d2)
|
|
|
|
{
|
|
|
|
this.prevChasingPosY = this.chasingPosY = this.posY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d5 < -d2)
|
|
|
|
{
|
|
|
|
this.prevChasingPosX = this.chasingPosX = this.posX;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d1 < -d2)
|
|
|
|
{
|
|
|
|
this.prevChasingPosZ = this.chasingPosZ = this.posZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d0 < -d2)
|
|
|
|
{
|
|
|
|
this.prevChasingPosY = this.chasingPosY = this.posY;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.chasingPosX += d5 * 0.25D;
|
|
|
|
this.chasingPosZ += d1 * 0.25D;
|
|
|
|
this.chasingPosY += d0 * 0.25D;
|
|
|
|
|
|
|
|
// if (this.vehicle == null)
|
|
|
|
// {
|
|
|
|
// this.startMinecartRidingCoordinate = null;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (!this.worldObj.client)
|
|
|
|
// {
|
|
|
|
// this.triggerAchievement(StatRegistry.minutesPlayedStat);
|
|
|
|
|
|
|
|
// if (this.isEntityAlive())
|
|
|
|
// {
|
|
|
|
// this.triggerAchievement(StatRegistry.timeSinceDeathStat);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
double d3 = ExtMath.clampd(this.posX, -World.MAX_SIZE + 1, World.MAX_SIZE - 1);
|
|
|
|
double d4 = ExtMath.clampd(this.posZ, -World.MAX_SIZE + 1, World.MAX_SIZE - 1);
|
|
|
|
|
|
|
|
if (d3 != this.posX || d4 != this.posZ)
|
|
|
|
{
|
|
|
|
this.setPosition(d3, this.posY, d4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when player presses the drop item key
|
|
|
|
*/
|
|
|
|
public EntityItem dropOneItem(boolean dropAll)
|
|
|
|
{
|
|
|
|
if(this.sendQueue != null) {
|
|
|
|
CPacketBreak.Action c07packetplayerdigging$action = dropAll ? CPacketBreak.Action.DROP_ALL_ITEMS : CPacketBreak.Action.DROP_ITEM;
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketBreak(c07packetplayerdigging$action, BlockPos.ORIGIN, Facing.DOWN));
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.dropItem(this.inventory.decrStackSize(this.inventory.currentItem, dropAll && this.inventory.getCurrentItem() != null ? this.inventory.getCurrentItem().stackSize : 1), false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Joins the passed in entity item with the world. Args: entityItem
|
|
|
|
*/
|
|
|
|
protected void joinEntityItemWithWorld(EntityItem itemIn)
|
|
|
|
{
|
|
|
|
if(this.sendQueue == null)
|
|
|
|
this.worldObj.spawnEntityInWorld(itemIn);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void changeSize(float width, float height) {
|
|
|
|
super.changeSize(width, height);
|
|
|
|
if(this.sendQueue != null)
|
|
|
|
this.stepHeight = height / 3.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Swings the item the player is holding.
|
|
|
|
*/
|
|
|
|
public void swingItem()
|
|
|
|
{
|
|
|
|
super.swingItem();
|
|
|
|
if(this.sendQueue != null)
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.SWING_ARM));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deals damage to the entity. If its a EntityNPC then will take damage from the armor first and then health
|
|
|
|
* second with the reduced value. Args: damageAmount
|
|
|
|
*/
|
|
|
|
protected void damageEntity(DamageSource damageSrc, int damageAmount)
|
|
|
|
{
|
|
|
|
if(this.sendQueue != null) {
|
|
|
|
if(!this.isEntityInvulnerable(damageSrc))
|
|
|
|
this.setHealth(this.getHealth() - damageAmount);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.damageEntity(damageSrc, damageAmount);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.isEntityInvulnerable(damageSrc))
|
|
|
|
{
|
|
|
|
if (!damageSrc.isUnblockable() && this.isBlocking() && damageAmount > 0)
|
|
|
|
{
|
|
|
|
damageAmount = (1 + damageAmount) / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
damageAmount = this.applyArmorCalculations(damageSrc, damageAmount);
|
|
|
|
damageAmount = this.applyPotionDamageCalculations(damageSrc, damageAmount);
|
|
|
|
int f = damageAmount;
|
|
|
|
damageAmount = Math.max(damageAmount - this.getAbsorptionAmount(), 0);
|
|
|
|
this.setAbsorptionAmount(this.getAbsorptionAmount() - (f - damageAmount));
|
|
|
|
|
|
|
|
if (damageAmount != 0)
|
|
|
|
{
|
|
|
|
// float f1 = this.getHealth();
|
|
|
|
this.setHealth(this.getHealth() - damageAmount);
|
|
|
|
this.trackDamage(damageSrc, damageAmount);
|
|
|
|
|
|
|
|
// if ((float)damageAmount < 3.4028235E37F)
|
|
|
|
// {
|
|
|
|
// if(damageAmount < Integer.MAX_VALUE)
|
|
|
|
// this.addStat(StatRegistry.damageTakenStat, damageAmount);
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set current crafting inventory back to the 2x2 square
|
|
|
|
*/
|
|
|
|
public void closeScreen()
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.closeScreen();
|
|
|
|
else if(this.sendQueue != null) {
|
|
|
|
// this.setScreenClosed();
|
|
|
|
// this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_CONTAINER)); // , this.openContainer.windowId));
|
|
|
|
// this.closeScreenAndDropStack();
|
|
|
|
this.gm.displayGuiScreen(null);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
this.openContainer = this.inventoryContainer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setScreenClosed() {
|
|
|
|
if(this.sendQueue != null) {
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_CONTAINER, this.openContainer.windowId));
|
|
|
|
this.inventory.setItemStack((ItemStack)null);
|
|
|
|
this.openContainer = this.inventoryContainer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean pushOutOfBlocks(double x, double y, double z)
|
|
|
|
{
|
|
|
|
if(this.sendQueue == null)
|
|
|
|
return super.pushOutOfBlocks(x, y, z);
|
|
|
|
if (this.noClip)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BlockPos blockpos = new BlockPos(x, y, z);
|
|
|
|
double d0 = x - (double)blockpos.getX();
|
|
|
|
double d1 = z - (double)blockpos.getZ();
|
|
|
|
|
|
|
|
if (!this.isOpenBlockSpace(blockpos))
|
|
|
|
{
|
|
|
|
int i = -1;
|
|
|
|
double d2 = 9999.0D;
|
|
|
|
|
|
|
|
if (this.isOpenBlockSpace(blockpos.west()) && d0 < d2)
|
|
|
|
{
|
|
|
|
d2 = d0;
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isOpenBlockSpace(blockpos.east()) && 1.0D - d0 < d2)
|
|
|
|
{
|
|
|
|
d2 = 1.0D - d0;
|
|
|
|
i = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isOpenBlockSpace(blockpos.north()) && d1 < d2)
|
|
|
|
{
|
|
|
|
d2 = d1;
|
|
|
|
i = 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isOpenBlockSpace(blockpos.south()) && 1.0D - d1 < d2)
|
|
|
|
{
|
|
|
|
d2 = 1.0D - d1;
|
|
|
|
i = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
float f = 0.1F;
|
|
|
|
|
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
this.motionX = (double)(-f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 1)
|
|
|
|
{
|
|
|
|
this.motionX = (double)f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 4)
|
|
|
|
{
|
|
|
|
this.motionZ = (double)(-f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 5)
|
|
|
|
{
|
|
|
|
this.motionZ = (double)f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set sprinting switch for Entity.
|
|
|
|
*/
|
|
|
|
public void setSprinting(boolean sprinting)
|
|
|
|
{
|
|
|
|
super.setSprinting(sprinting);
|
|
|
|
if(this.sendQueue != null)
|
|
|
|
this.sprintingTicksLeft = sprinting ? 600 : 0;
|
|
|
|
}
|
|
|
|
|
2025-03-18 12:03:56 +01:00
|
|
|
public void playSound(SoundEvent name, float volume)
|
2025-03-11 00:23:54 +01:00
|
|
|
{
|
|
|
|
if(this.connection != null)
|
2025-03-18 12:03:56 +01:00
|
|
|
this.connection.playSound(name, volume);
|
2025-03-11 00:23:54 +01:00
|
|
|
else if(this.sendQueue != null)
|
2025-03-18 12:03:56 +01:00
|
|
|
((WorldClient)this.worldObj).playSound(this.posX, this.posY, this.posZ, name, volume);
|
2025-03-11 00:23:54 +01:00
|
|
|
else if(this.gm == null)
|
2025-03-18 12:03:56 +01:00
|
|
|
super.playSound(name, volume);
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isTicked()
|
|
|
|
{
|
|
|
|
return (!this.worldObj.client && (Config.mobTick || this.connection != null)) || this.sendQueue != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void openEditSign(TileEntitySign signTile)
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.openEditSign(signTile);
|
|
|
|
else if(this.sendQueue != null)
|
|
|
|
this.gm.displayGuiScreen(new GuiSign(signTile.getPos(), signTile.signText));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays the GUI for interacting with a book.
|
|
|
|
*/
|
|
|
|
// public void displayGUIBook(ItemStack bookStack)
|
|
|
|
// {
|
|
|
|
// if(this.connection != null)
|
|
|
|
// this.connection.displayGUIBook(bookStack);
|
|
|
|
// else if(this.sendQueue != null) {
|
|
|
|
// Item item = bookStack.getItem();
|
|
|
|
//
|
|
|
|
// if (item == Items.writable_book)
|
|
|
|
// {
|
|
|
|
// this.gm.displayGuiScreen(new GuiBook(bookStack));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays the GUI for interacting with a chest inventory. Args: chestInventory
|
|
|
|
*/
|
|
|
|
public void displayGUIChest(IInventory chestInventory)
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.displayGUIChest(chestInventory);
|
|
|
|
else if(this.sendQueue != null) {
|
|
|
|
String s = chestInventory instanceof IInteractionObject ? ((IInteractionObject)chestInventory).getGuiID() : "container";
|
|
|
|
|
|
|
|
if ("chest".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiChest(this.inventory, chestInventory));
|
|
|
|
}
|
|
|
|
else if ("hopper".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiHopper(this.inventory, chestInventory));
|
|
|
|
}
|
|
|
|
else if ("furnace".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiFurnace(this.inventory, chestInventory));
|
|
|
|
}
|
|
|
|
else if ("brewing_stand".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiBrewing(this.inventory, chestInventory));
|
|
|
|
}
|
|
|
|
// else if ("beacon".equals(s))
|
|
|
|
// {
|
|
|
|
// this.gm.displayGuiScreen(new GuiBeacon(this.inventory, chestInventory));
|
|
|
|
// }
|
|
|
|
else if (!"dispenser".equals(s) && !"dropper".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiChest(this.inventory, chestInventory));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiDispenser(this.inventory, chestInventory));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayGUIHorse(EntityHorse horse, IInventory horseInventory)
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.displayGUIHorse(horse, horseInventory);
|
|
|
|
else if(this.sendQueue != null)
|
|
|
|
this.gm.displayGuiScreen(new GuiHorse(this.inventory, horseInventory, horse));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayGui(IInteractionObject guiOwner)
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.displayGui(guiOwner);
|
|
|
|
else if(this.sendQueue != null) {
|
|
|
|
String s = guiOwner.getGuiID();
|
|
|
|
|
|
|
|
if ("crafting_table".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiCrafting(this.inventory, this.worldObj));
|
|
|
|
}
|
|
|
|
else if ("enchanting_table".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiEnchant(this.inventory, this.worldObj, guiOwner));
|
|
|
|
}
|
|
|
|
else if ("anvil".equals(s))
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiRepair(this.inventory, this.worldObj));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when the player performs a critical hit on the Entity. Args: entity that was hit critically
|
|
|
|
*/
|
|
|
|
public void onCriticalHit(Entity entityHit)
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onCriticalHit(entityHit);
|
|
|
|
else if(this.sendQueue != null)
|
|
|
|
this.gm.effectRenderer.emitParticleAtEntity(entityHit, ParticleType.CRIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onEnchantmentCritical(Entity entityHit)
|
|
|
|
{
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onEnchantmentCritical(entityHit);
|
|
|
|
else if(this.sendQueue != null)
|
|
|
|
this.gm.effectRenderer.emitParticleAtEntity(entityHit, ParticleType.CRIT_MAGIC);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns if this entity is sneaking.
|
|
|
|
*/
|
|
|
|
public boolean isSneaking()
|
|
|
|
{
|
|
|
|
return this.sendQueue != null ? this.gm.sneak : super.isSneaking();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateEntityActionState()
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.updateEntityActionState();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.updateArmSwingProgress();
|
|
|
|
this.headYaw = this.rotYaw;
|
|
|
|
// super.updateEntityActionState();
|
|
|
|
|
|
|
|
if (this.sendQueue != null && this.isCurrentViewEntity())
|
|
|
|
{
|
|
|
|
this.moveStrafe = this.gm.moveStrafe;
|
|
|
|
this.moveForward = this.gm.moveForward;
|
|
|
|
this.jumping = this.gm.jump;
|
|
|
|
this.prevRenderArmYaw = this.renderArmYaw;
|
|
|
|
this.prevRenderArmPitch = this.renderArmPitch;
|
|
|
|
this.renderArmPitch = (float)((double)this.renderArmPitch + (double)(this.rotPitch - this.renderArmPitch) * 0.5D);
|
|
|
|
this.renderArmYaw = (float)((double)this.renderArmYaw + (double)(this.rotYaw - this.renderArmYaw) * 0.5D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
|
|
|
* use this to react to sunlight and start to burn.
|
|
|
|
*/
|
|
|
|
public void onLivingUpdate()
|
|
|
|
{
|
|
|
|
if(this.sendQueue != null) {
|
|
|
|
if (this.sprintingTicksLeft > 0)
|
|
|
|
{
|
|
|
|
--this.sprintingTicksLeft;
|
|
|
|
|
|
|
|
if (this.sprintingTicksLeft == 0)
|
|
|
|
{
|
|
|
|
this.setSprinting(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.sprintToggleTimer > 0)
|
|
|
|
{
|
|
|
|
--this.sprintToggleTimer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.prevNausea = this.nausea;
|
|
|
|
|
|
|
|
// if (this.inStandingPortal)
|
|
|
|
// {
|
|
|
|
// if (this.gm.openGui != null && !this.gm.openGui.doesGuiPauseGame())
|
|
|
|
// {
|
|
|
|
// this.gm.displayGuiScreen((GuiScreen)null);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//// if (this.timeInPortal == 0.0F)
|
|
|
|
//// {
|
|
|
|
//// this.gm.getSoundHandler().playSound(new PositionedSoundRecord("portal.trigger", this.rand.floatv() * 0.4F + 0.8F));
|
|
|
|
//// }
|
|
|
|
//
|
|
|
|
//// this.timeInPortal += 0.0125F;
|
|
|
|
////
|
|
|
|
//// if (this.timeInPortal >= 1.0F)
|
|
|
|
//// {
|
|
|
|
//// this.timeInPortal = 1.0F;
|
|
|
|
//// }
|
|
|
|
//
|
|
|
|
// this.inStandingPortal = false;
|
|
|
|
// }
|
|
|
|
// if (this.hasEffect(Potion.confusion) && this.getEffect(Potion.confusion).getDuration() > 60)
|
|
|
|
// {
|
|
|
|
// this.nausea += 0.006666667F;
|
|
|
|
//
|
|
|
|
// if (this.nausea > 1.0F)
|
|
|
|
// {
|
|
|
|
// this.nausea = 1.0F;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// if (this.nausea > 0.0F)
|
|
|
|
// {
|
|
|
|
// this.nausea -= 0.05F;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if (this.nausea < 0.0F)
|
|
|
|
// {
|
|
|
|
// this.nausea = 0.0F;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (this.portalTimer > 0)
|
|
|
|
// {
|
|
|
|
// --this.portalTimer;
|
|
|
|
// }
|
|
|
|
|
|
|
|
boolean flag = this.gm.jump;
|
|
|
|
boolean flag1 = this.gm.sneak;
|
|
|
|
float f = 0.8F;
|
|
|
|
boolean flag2 = this.gm.moveForward >= f;
|
|
|
|
this.gm.updatePlayerMoveState();
|
|
|
|
|
|
|
|
if (this.isUsingItem() && !this.isRiding())
|
|
|
|
{
|
|
|
|
this.gm.moveStrafe *= 0.2F;
|
|
|
|
this.gm.moveForward *= 0.2F;
|
|
|
|
this.sprintToggleTimer = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.pushOutOfBlocks(this.posX - (double)this.width * 0.35D, this.getEntityBoundingBox().minY + 0.5D, this.posZ + (double)this.width * 0.35D);
|
|
|
|
this.pushOutOfBlocks(this.posX - (double)this.width * 0.35D, this.getEntityBoundingBox().minY + 0.5D, this.posZ - (double)this.width * 0.35D);
|
|
|
|
this.pushOutOfBlocks(this.posX + (double)this.width * 0.35D, this.getEntityBoundingBox().minY + 0.5D, this.posZ - (double)this.width * 0.35D);
|
|
|
|
this.pushOutOfBlocks(this.posX + (double)this.width * 0.35D, this.getEntityBoundingBox().minY + 0.5D, this.posZ + (double)this.width * 0.35D);
|
|
|
|
boolean canSprint = true; // (float)this.getFoodStats().getFoodLevel() > 6.0F || this.allowFlying;
|
|
|
|
|
|
|
|
if (this.onGround && !flag1 && !flag2 && this.gm.moveForward >= f && !this.isSprinting() && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.blindness))
|
|
|
|
{
|
|
|
|
if (this.sprintToggleTimer <= 0 && !this.gm.sprint)
|
|
|
|
{
|
|
|
|
this.sprintToggleTimer = 7;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.setSprinting(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.isSprinting() && this.gm.moveForward >= f && canSprint && !this.isUsingItem() && !this.hasEffect(Potion.blindness) && this.gm.sprint)
|
|
|
|
{
|
|
|
|
this.setSprinting(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isSprinting() && (this.gm.moveForward < f || this.collidedHorizontally || !canSprint))
|
|
|
|
{
|
|
|
|
this.setSprinting(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasEffect(Potion.flying) || this.noclip)
|
|
|
|
{
|
|
|
|
if (this.noclip)
|
|
|
|
{
|
|
|
|
if (!this.flying)
|
|
|
|
{
|
|
|
|
this.flying = true;
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_FLYING));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!flag && this.gm.jump)
|
|
|
|
{
|
|
|
|
if (this.flyToggleTimer == 0)
|
|
|
|
{
|
|
|
|
this.flyToggleTimer = 7;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.flying = !this.flying;
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(this.flying ?
|
|
|
|
CPacketAction.Action.START_FLYING : CPacketAction.Action.STOP_FLYING));
|
|
|
|
this.flyToggleTimer = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { // if(!this.firstEffectUpdate) {
|
|
|
|
this.flying = false;
|
|
|
|
}
|
|
|
|
// this.firstEffectUpdate = false;
|
|
|
|
|
|
|
|
if (this.isFlying() && this.isCurrentViewEntity())
|
|
|
|
{
|
|
|
|
if (this.gm.sneak)
|
|
|
|
{
|
|
|
|
this.motionY -= (double)(
|
|
|
|
this.flying ? (this.landMovement * 0.5f * 3.0F) : 0.05F);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.gm.jump)
|
|
|
|
{
|
|
|
|
this.motionY += (double)(
|
|
|
|
this.flying ? (this.landMovement * 0.5f * 3.0F) : 0.05F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isRidingHorse())
|
|
|
|
{
|
|
|
|
if (this.horseJumpPowerCounter < 0)
|
|
|
|
{
|
|
|
|
++this.horseJumpPowerCounter;
|
|
|
|
|
|
|
|
if (this.horseJumpPowerCounter == 0)
|
|
|
|
{
|
|
|
|
this.horseJumpPower = 0.0F;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag && !this.gm.jump)
|
|
|
|
{
|
|
|
|
this.horseJumpPowerCounter = -10;
|
|
|
|
this.sendHorseJump();
|
|
|
|
}
|
|
|
|
else if (!flag && this.gm.jump)
|
|
|
|
{
|
|
|
|
this.horseJumpPowerCounter = 0;
|
|
|
|
this.horseJumpPower = 0.0F;
|
|
|
|
}
|
|
|
|
else if (flag)
|
|
|
|
{
|
|
|
|
++this.horseJumpPowerCounter;
|
|
|
|
|
|
|
|
if (this.horseJumpPowerCounter < 10)
|
|
|
|
{
|
|
|
|
this.horseJumpPower = (float)this.horseJumpPowerCounter * 0.1F;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.horseJumpPower = 0.8F + 2.0F / (float)(this.horseJumpPowerCounter - 9) * 0.1F;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.horseJumpPower = 0.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.onPlayerUpdate();
|
|
|
|
// super.onLivingUpdate();
|
|
|
|
|
|
|
|
if (this.onGround && this.flying && !this.noclip)
|
|
|
|
{
|
|
|
|
this.flying = false;
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_FLYING));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.gm != null) {
|
|
|
|
if (this.otherPlayerMPPosRotationIncrements > 0)
|
|
|
|
{
|
|
|
|
double d0 = this.posX + (this.otherPlayerMPX - this.posX) / (double)this.otherPlayerMPPosRotationIncrements;
|
|
|
|
double d1 = this.posY + (this.otherPlayerMPY - this.posY) / (double)this.otherPlayerMPPosRotationIncrements;
|
|
|
|
double d2 = this.posZ + (this.otherPlayerMPZ - this.posZ) / (double)this.otherPlayerMPPosRotationIncrements;
|
|
|
|
double d3;
|
|
|
|
|
|
|
|
for (d3 = this.otherPlayerMPYaw - (double)this.rotYaw; d3 < -180.0D; d3 += 360.0D)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (d3 >= 180.0D)
|
|
|
|
{
|
|
|
|
d3 -= 360.0D;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.rotYaw = (float)((double)this.rotYaw + d3 / (double)this.otherPlayerMPPosRotationIncrements);
|
|
|
|
this.rotPitch = (float)((double)this.rotPitch + (this.otherPlayerMPPitch - (double)this.rotPitch) / (double)this.otherPlayerMPPosRotationIncrements);
|
|
|
|
--this.otherPlayerMPPosRotationIncrements;
|
|
|
|
this.setPosition(d0, d1, d2);
|
|
|
|
this.setRotation(this.rotYaw, this.rotPitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.prevCameraYaw = this.cameraYaw;
|
|
|
|
this.updateArmSwingProgress();
|
|
|
|
float f1 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
|
|
|
float f = (float)Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F;
|
|
|
|
|
|
|
|
if (f1 > 0.1F)
|
|
|
|
{
|
|
|
|
f1 = 0.1F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.onGround || this.getHealth() <= 0)
|
|
|
|
{
|
|
|
|
f1 = 0.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.onGround || this.getHealth() <= 0)
|
|
|
|
{
|
|
|
|
f = 0.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.cameraYaw += (f1 - this.cameraYaw) * 0.4F;
|
|
|
|
this.camPitch += (f - this.camPitch) * 0.8F;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(this.connection != null) {
|
|
|
|
this.onPlayerUpdate();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// if(!(this.isPlayer()))
|
|
|
|
this.updateArmSwingProgress();
|
|
|
|
this.onNpcUpdate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void onPlayerUpdate() {
|
|
|
|
if (this.flyToggleTimer > 0)
|
|
|
|
{
|
|
|
|
--this.flyToggleTimer;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.worldObj.client && this.sinceLastAttack < Integer.MAX_VALUE)
|
|
|
|
{
|
|
|
|
++this.sinceLastAttack;
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.inventory.decrementAnimations();
|
|
|
|
this.prevCameraYaw = this.cameraYaw;
|
|
|
|
// super.onLivingUpdate();
|
|
|
|
this.onNpcUpdate();
|
|
|
|
AttributeInstance iattributeinstance = this.getEntityAttribute(Attributes.MOVEMENT_SPEED);
|
|
|
|
|
|
|
|
this.jumpMovement = this.speedInAir;
|
|
|
|
|
|
|
|
if (this.isSprinting())
|
|
|
|
{
|
|
|
|
this.jumpMovement = (float)((double)this.jumpMovement + (double)this.speedInAir * 0.3D);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setAIMoveSpeed((float)iattributeinstance.getAttributeValue());
|
|
|
|
float f = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
|
|
|
float f1 = (float)(Math.atan(-this.motionY * 0.20000000298023224D) * 15.0D);
|
|
|
|
|
|
|
|
if (f > 0.1F)
|
|
|
|
{
|
|
|
|
f = 0.1F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.onGround || this.getHealth() <= 0)
|
|
|
|
{
|
|
|
|
f = 0.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.onGround || this.getHealth() <= 0)
|
|
|
|
{
|
|
|
|
f1 = 0.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.cameraYaw += (f - this.cameraYaw) * 0.4F;
|
|
|
|
this.camPitch += (f1 - this.camPitch) * 0.8F;
|
|
|
|
|
|
|
|
if (this.getHealth() > 0 && !this.noclip)
|
|
|
|
{
|
|
|
|
BoundingBox axisalignedbb = null;
|
|
|
|
|
|
|
|
if (this.vehicle != null && !this.vehicle.dead)
|
|
|
|
{
|
|
|
|
axisalignedbb = this.getEntityBoundingBox().union(this.vehicle.getEntityBoundingBox()).expand(1.0D, 0.0D, 1.0D);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
axisalignedbb = this.getEntityBoundingBox().expand(1.0D, 0.5D, 1.0D);
|
|
|
|
}
|
|
|
|
|
|
|
|
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, axisalignedbb);
|
|
|
|
|
|
|
|
for (int i = 0; i < list.size(); ++i)
|
|
|
|
{
|
|
|
|
Entity entity = (Entity)list.get(i);
|
|
|
|
|
|
|
|
if (!entity.dead)
|
|
|
|
{
|
|
|
|
this.collideWithPlayer(entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// END SP
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// START SP SPEC
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* called every tick when the player is on foot. Performs all the things that normally happen during movement.
|
|
|
|
*/
|
|
|
|
public void onUpdateWalkingPlayer()
|
|
|
|
{
|
|
|
|
boolean flag = this.isSprinting();
|
|
|
|
|
|
|
|
if (flag != this.serverSprintState)
|
|
|
|
{
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_SPRINTING));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_SPRINTING));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.serverSprintState = flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean flag1 = this.isSneaking();
|
|
|
|
|
|
|
|
if (flag1 != this.serverSneakState)
|
|
|
|
{
|
|
|
|
if (flag1)
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.START_SNEAKING));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.STOP_SNEAKING));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.serverSneakState = flag1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isCurrentViewEntity())
|
|
|
|
{
|
|
|
|
double d0 = this.posX - this.lastReportedPosX;
|
|
|
|
double d1 = this.getEntityBoundingBox().minY - this.lastReportedPosY;
|
|
|
|
double d2 = this.posZ - this.lastReportedPosZ;
|
|
|
|
double d3 = (double)(this.rotYaw - this.lastReportedYaw);
|
|
|
|
double d4 = (double)(this.rotPitch - this.lastReportedPitch);
|
|
|
|
boolean flag2 = d0 * d0 + d1 * d1 + d2 * d2 > 9.0E-4D || this.positionUpdateTicks >= 20;
|
|
|
|
boolean flag3 = d3 != 0.0D || d4 != 0.0D;
|
|
|
|
|
|
|
|
if (this.vehicle == null)
|
|
|
|
{
|
|
|
|
if (flag2 && flag3)
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.rotYaw, this.rotPitch, this.onGround));
|
|
|
|
}
|
|
|
|
else if (flag2)
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketPlayer.C04PacketPlayerPosition(this.posX, this.getEntityBoundingBox().minY, this.posZ, this.onGround));
|
|
|
|
}
|
|
|
|
else if (flag3)
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketPlayer.C05PacketPlayerLook(this.rotYaw, this.rotPitch, this.onGround));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketPlayer(this.onGround));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketPlayer.C06PacketPlayerPosLook(this.motionX, -999.0D, this.motionZ, this.rotYaw, this.rotPitch, this.onGround));
|
|
|
|
flag2 = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
++this.positionUpdateTicks;
|
|
|
|
|
|
|
|
if (flag2)
|
|
|
|
{
|
|
|
|
this.lastReportedPosX = this.posX;
|
|
|
|
this.lastReportedPosY = this.getEntityBoundingBox().minY;
|
|
|
|
this.lastReportedPosZ = this.posZ;
|
|
|
|
this.positionUpdateTicks = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag3)
|
|
|
|
{
|
|
|
|
this.lastReportedYaw = this.rotYaw;
|
|
|
|
this.lastReportedPitch = this.rotPitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void respawnPlayer()
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.PERFORM_RESPAWN));
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void closeScreenAndDropStack()
|
|
|
|
// {
|
|
|
|
// this.inventory.setItemStack((ItemStack)null);
|
|
|
|
// this.openContainer = this.inventoryContainer;
|
|
|
|
//// super.closeScreen();
|
|
|
|
// this.gm.displayGuiScreen(null);
|
|
|
|
// }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates health locally.
|
|
|
|
*/
|
|
|
|
public void setPlayerSPHealth(int health)
|
|
|
|
{
|
|
|
|
if (this.hasValidHealth)
|
|
|
|
{
|
|
|
|
int f = this.getHealth() - health;
|
|
|
|
|
|
|
|
if (f <= 0)
|
|
|
|
{
|
|
|
|
this.setHealth(health);
|
|
|
|
|
|
|
|
if (f < 0)
|
|
|
|
{
|
|
|
|
this.hurtResistance = this.hurtCooldown / 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.lastDamage = f;
|
|
|
|
this.setHealth(this.getHealth());
|
|
|
|
this.hurtResistance = this.hurtCooldown;
|
|
|
|
this.damageEntity(DamageSource.generic, f);
|
|
|
|
this.hurtTime = this.maxHurtTime = 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.setHealth(health);
|
|
|
|
this.hasValidHealth = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void sendHorseJump()
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.RIDING_JUMP, (int)(this.getHorseJumpPower() * 100.0F)));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendHorseInventory()
|
|
|
|
{
|
|
|
|
this.sendQueue.addToSendQueue(new CPacketAction(CPacketAction.Action.OPEN_INVENTORY));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the block at the given BlockPos and the block above it are NOT full cubes.
|
|
|
|
*/
|
|
|
|
private boolean isOpenBlockSpace(BlockPos pos)
|
|
|
|
{
|
|
|
|
return !this.worldObj.getState(pos).getBlock().isNormalCube() && (this.height <= 1.0f || !this.worldObj.getState(pos.up()).getBlock().isNormalCube());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the current XP, total XP, and level number.
|
|
|
|
*/
|
|
|
|
public void setXPStats(float currentXP, int maxXP, int level)
|
|
|
|
{
|
|
|
|
this.experience = currentXP;
|
|
|
|
this.experienceTotal = maxXP;
|
|
|
|
this.experienceLevel = level;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isRidingHorse()
|
|
|
|
{
|
|
|
|
return this.vehicle != null && this.vehicle instanceof EntityHorse && ((EntityHorse)this.vehicle).isHorseSaddled();
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getHorseJumpPower()
|
|
|
|
{
|
|
|
|
return this.horseJumpPower;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void displayTradeGui(String title)
|
|
|
|
{
|
|
|
|
this.gm.displayGuiScreen(new GuiMerchant(this.inventory, title, this.worldObj));
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean isCurrentViewEntity()
|
|
|
|
{
|
|
|
|
return this.gm.getRenderViewEntity() == this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// END SP SPEC
|
|
|
|
|
|
|
|
// START OTHER
|
|
|
|
|
|
|
|
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)
|
|
|
|
{
|
|
|
|
if(this.gm != null && this.sendQueue == null) {
|
|
|
|
this.otherPlayerMPX = x;
|
|
|
|
this.otherPlayerMPY = y;
|
|
|
|
this.otherPlayerMPZ = z;
|
|
|
|
this.otherPlayerMPYaw = (double)yaw;
|
|
|
|
this.otherPlayerMPPitch = (double)pitch;
|
|
|
|
this.otherPlayerMPPosRotationIncrements = posRotationIncrements;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
super.setPositionAndRotation2(x, y, z, yaw, pitch, posRotationIncrements, p_180426_10_);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setItem(int slot, ItemStack stack)
|
|
|
|
{
|
|
|
|
if(this.gm != null && this.sendQueue == null) {
|
|
|
|
if (slot == 0)
|
|
|
|
this.inventory.mainInventory[this.inventory.currentItem] = stack;
|
|
|
|
else
|
|
|
|
this.inventory.armorInventory[slot - 1] = stack;
|
|
|
|
}
|
|
|
|
else if(this.isPlayer()) {
|
|
|
|
this.inventory.armorInventory[slot] = stack;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.setItemNoUpdate(slot, stack);
|
|
|
|
if(!this.worldObj.client && slot == 0)
|
|
|
|
this.setCombatTask();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// END OTHER
|
|
|
|
|
|
|
|
|
|
|
|
// START MP
|
|
|
|
|
|
|
|
public void addExperienceLevel(int levels) {
|
|
|
|
this.experienceLevel += levels;
|
|
|
|
|
|
|
|
if (this.experienceLevel < 0)
|
|
|
|
{
|
|
|
|
this.experienceLevel = 0;
|
|
|
|
this.experience = 0.0F;
|
|
|
|
this.experienceTotal = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (levels > 0 && this.experienceLevel % 5 == 0 && (float)this.lastXPSound < (float)this.ticksExisted - 100.0F)
|
|
|
|
{
|
|
|
|
float f = this.experienceLevel > 30 ? 1.0F : (float)this.experienceLevel / 30.0F;
|
2025-03-18 12:03:56 +01:00
|
|
|
this.worldObj.playSoundAtEntity(this, SoundEvent.LEVELUP, f * 0.75F);
|
2025-03-11 00:23:54 +01:00
|
|
|
this.lastXPSound = this.ticksExisted;
|
|
|
|
}
|
|
|
|
// super.addExperienceLevel(levels);
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.resetLastExperience();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeExperienceLevel(int levels) {
|
|
|
|
this.experienceLevel -= levels;
|
|
|
|
|
|
|
|
if (this.experienceLevel < 0)
|
|
|
|
{
|
|
|
|
this.experienceLevel = 0;
|
|
|
|
this.experience = 0.0F;
|
|
|
|
this.experienceTotal = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.xpSeed = this.rand.intv();
|
|
|
|
// super.removeExperienceLevel(levels);
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.resetLastExperience();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onDeath(DamageSource cause) {
|
|
|
|
if(this.connection != null) {
|
|
|
|
this.connection.onEntityDeath();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.onDeath(cause);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.noPickup = true;
|
|
|
|
super.onDeath(cause);
|
|
|
|
if(this.gm != null) {
|
|
|
|
this.changeSize(0.2F, 0.2F);
|
|
|
|
this.setPosition(this.posX, this.posY, this.posZ);
|
|
|
|
this.motionY = 0.10000000149011612D;
|
|
|
|
|
|
|
|
if (this.worldObj.client || (!Config.keepInventory && Config.playerDrop))
|
|
|
|
{
|
|
|
|
this.inventory.dropAllItems();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cause != null)
|
|
|
|
{
|
|
|
|
this.motionX = (double)(-ExtMath.cos((this.attackedYaw + this.rotYaw) * (float)Math.PI / 180.0F) * 0.1F);
|
|
|
|
this.motionZ = (double)(-ExtMath.sin((this.attackedYaw + this.rotYaw) * (float)Math.PI / 180.0F) * 0.1F);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.motionX = this.motionZ = 0.0D;
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.triggerAchievement(StatRegistry.deathsStat);
|
|
|
|
// this.removeStat(StatRegistry.timeSinceDeathStat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Entity travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal) {
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.travelToDimension(dimensionId, pos, yaw, pitch, portal);
|
|
|
|
return this.isPlayer() ? this : super.travelToDimension(dimensionId, pos, yaw, pitch, portal);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void teleport(double x, double y, double z, float yaw, float pitch, int dimension) {
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.teleport(x, y, z, yaw, pitch, dimension);
|
|
|
|
else if(!this.isPlayer())
|
|
|
|
super.teleport(x, y, z, yaw, pitch, dimension);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onItemPickup(Entity entity, int amount) {
|
|
|
|
super.onItemPickup(entity, amount);
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onItemPickup(entity, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void updateFallState(double y, boolean onGroundIn, Block blockIn, BlockPos pos) {
|
|
|
|
if(this.connection == null)
|
|
|
|
super.updateFallState(y, onGroundIn, blockIn, pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addStat(int amount) {
|
|
|
|
// if(this.connection != null)
|
|
|
|
// this.connection.addStat(amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void removeStat(StatBase stat) {
|
|
|
|
// if(this.connection != null)
|
|
|
|
// this.connection.removeStat(stat);
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected void onItemUseFinish() {
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onItemUseFinish();
|
|
|
|
// super.onItemUseFinish();
|
|
|
|
if (this.itemInUse != null)
|
|
|
|
{
|
|
|
|
this.updateItemUse(this.itemInUse, 16);
|
|
|
|
int i = this.itemInUse.stackSize;
|
|
|
|
ItemStack itemstack = this.itemInUse.onItemUseFinish(this.worldObj, this);
|
|
|
|
|
|
|
|
if (itemstack != this.itemInUse || itemstack != null && itemstack.stackSize != i)
|
|
|
|
{
|
|
|
|
this.inventory.mainInventory[this.inventory.currentItem] = itemstack;
|
|
|
|
|
|
|
|
if (itemstack.stackSize == 0)
|
|
|
|
{
|
|
|
|
this.inventory.mainInventory[this.inventory.currentItem] = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.clearItemInUse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void onNewEffect(PotionEffect id) {
|
|
|
|
super.onNewEffect(id);
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onNewEffect(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void onChangedEffect(PotionEffect id, boolean added) {
|
|
|
|
super.onChangedEffect(id, added);
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onChangedEffect(id, added);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void onFinishedEffect(PotionEffect effect) {
|
|
|
|
super.onFinishedEffect(effect);
|
|
|
|
if(this.isPlayer() && effect.getPotionID() == Potion.flying.id)
|
|
|
|
this.flying = false;
|
|
|
|
// super.onFinishedEffect(effect);
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.onFinishedEffect(effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPositionAndUpdate(double x, double y, double z) {
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.setPositionAndUpdate(x, y, z);
|
|
|
|
else
|
|
|
|
super.setPositionAndUpdate(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateEffectMeta() {
|
|
|
|
super.updateEffectMeta();
|
|
|
|
if(this.connection != null)
|
|
|
|
this.connection.updateEffectMeta();
|
|
|
|
}
|
|
|
|
|
|
|
|
public final WorldServer getServerWorld() {
|
|
|
|
return (WorldServer)this.worldObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onUpdateEntity() {
|
|
|
|
// super.onUpdate();
|
|
|
|
this.updatePlayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateEntityFall(double y, boolean onGroundIn, Block blockIn, BlockPos pos) {
|
|
|
|
super.updateFallState(y, onGroundIn, blockIn, pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// END MP
|
|
|
|
|
|
|
|
|
|
|
|
// START PLAYER
|
|
|
|
|
|
|
|
public boolean isOnLadder()
|
|
|
|
{
|
|
|
|
return (!this.isPlayer() || !this.noclip) && super.isOnLadder();
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void applyEntityAttributes()
|
|
|
|
// {
|
|
|
|
// super.applyEntityAttributes();
|
|
|
|
// }
|
|
|
|
|
|
|
|
protected void entityInit()
|
|
|
|
{
|
|
|
|
super.entityInit();
|
|
|
|
this.dataWatcher.addObject(16, "");
|
|
|
|
this.dataWatcher.addObject(17, "");
|
|
|
|
this.dataWatcher.addObject(18, Byte.valueOf((byte)Alignment.NEUTRAL.ordinal()));
|
|
|
|
// this.dataWatcher.addObject(20, Byte.valueOf((byte)0));
|
|
|
|
this.dataWatcher.addObject(21, 0);
|
|
|
|
this.dataWatcher.addObject(22, Byte.valueOf((byte)-1));
|
|
|
|
this.dataWatcher.addObject(29, 1.0f);
|
|
|
|
// super.entityInit();
|
|
|
|
this.dataWatcher.addObject(30, Integer.valueOf(0));
|
|
|
|
// this.dataWatcher.addObject(10, Integer.valueOf(~ModelPart.ARMS_SLIM.getMask()));
|
|
|
|
// this.dataWatcher.addObject(11, Byte.valueOf((byte)0));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns the ItemStack containing the itemInUse
|
|
|
|
*/
|
|
|
|
public ItemStack getItemInUse()
|
|
|
|
{
|
|
|
|
return this.itemInUse;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the item in use count
|
|
|
|
*/
|
|
|
|
public int getItemInUseCount()
|
|
|
|
{
|
|
|
|
return this.itemInUseCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the entity is currently using an item (e.g., bow, food, sword) by holding down the useItemButton
|
|
|
|
*/
|
|
|
|
public boolean isUsingItem()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? this.itemInUse != null : this.getFlag(4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gets the duration for how long the current itemInUse has been in use
|
|
|
|
*/
|
|
|
|
public int getItemInUseDuration()
|
|
|
|
{
|
|
|
|
return this.isUsingItem() ? this.itemInUse.getMaxItemUseDuration() - this.itemInUseCount : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void stopUsingItem()
|
|
|
|
{
|
|
|
|
if (this.itemInUse != null)
|
|
|
|
{
|
|
|
|
this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.clearItemInUse();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearItemInUse()
|
|
|
|
{
|
|
|
|
this.itemInUse = null;
|
|
|
|
this.itemInUseCount = 0;
|
|
|
|
|
|
|
|
if (!this.worldObj.client)
|
|
|
|
{
|
|
|
|
this.setUsingItem(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isBlocking()
|
|
|
|
{
|
|
|
|
return this.isUsingItem() && this.itemInUse.getItem().getItemUseAction(this.itemInUse) == ItemAction.BLOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Plays sounds and makes particles for item in use state
|
|
|
|
*/
|
|
|
|
protected void updateItemUse(ItemStack itemStackIn, int p_71010_2_)
|
|
|
|
{
|
|
|
|
if (itemStackIn.getItemUseAction() == ItemAction.DRINK)
|
|
|
|
{
|
2025-03-18 12:03:56 +01:00
|
|
|
this.playSound(SoundEvent.DRINK, 0.5F);
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (itemStackIn.getItemUseAction() == ItemAction.EAT)
|
|
|
|
{
|
2025-03-18 12:03:56 +01:00
|
|
|
this.playSound(SoundEvent.EAT, 0.5F + 0.5F * (float)this.rand.zrange(2));
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void handleStatusUpdate(byte id)
|
|
|
|
{
|
|
|
|
if (this.isPlayer() && id == 9)
|
|
|
|
{
|
|
|
|
this.onItemUseFinish();
|
|
|
|
}
|
|
|
|
else if (id == 12)
|
|
|
|
{
|
|
|
|
this.spawnParticles(ParticleType.HEART);
|
|
|
|
}
|
|
|
|
else if (id == 13)
|
|
|
|
{
|
|
|
|
this.spawnParticles(ParticleType.SMOKE_NORMAL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
super.handleStatusUpdate(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * Dead and sleeping entities cannot move
|
|
|
|
// */
|
|
|
|
// protected boolean isMovementBlocked()
|
|
|
|
// {
|
|
|
|
// return this.getHealth() <= 0; // || this.isPlayerSleeping();
|
|
|
|
// }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles updating while being ridden by an entity
|
|
|
|
*/
|
|
|
|
public void updateRidden()
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.updateRidden();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!this.worldObj.client && this.isSneaking())
|
|
|
|
{
|
|
|
|
this.mountEntity((Entity)null);
|
|
|
|
this.setSneaking(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double d0 = this.posX;
|
|
|
|
double d1 = this.posY;
|
|
|
|
double d2 = this.posZ;
|
|
|
|
float f = this.rotYaw;
|
|
|
|
float f1 = this.rotPitch;
|
|
|
|
super.updateRidden();
|
|
|
|
this.prevCameraYaw = this.cameraYaw;
|
|
|
|
this.cameraYaw = 0.0F;
|
|
|
|
this.addMountedMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2);
|
|
|
|
|
|
|
|
if (this.vehicle instanceof EntityPig)
|
|
|
|
{
|
|
|
|
this.rotPitch = f1;
|
|
|
|
this.rotYaw = f;
|
|
|
|
this.yawOffset = ((EntityPig)this.vehicle).yawOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned
|
|
|
|
* (only actually used on players though its also on Entity)
|
|
|
|
*/
|
|
|
|
public void preparePlayerToSpawn()
|
|
|
|
{
|
|
|
|
if(this.isPlayer()) {
|
|
|
|
this.updateSize();
|
|
|
|
super.preparePlayerToSpawn();
|
|
|
|
this.setHealth(this.getMaxHealth());
|
|
|
|
this.deathTime = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
super.preparePlayerToSpawn();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onDataWatcherUpdate(int data) {
|
|
|
|
if(this.isPlayer() && (data == 29 || data == 11)) // && this.worldObj.client)
|
|
|
|
this.updateSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateSize() {
|
|
|
|
// ModelType model = this.getModel();
|
|
|
|
// this.changeSize(this.getHeight() * this.species.renderer.width / this.species.renderer.height, this.getHeight());
|
|
|
|
this.changeSize(this.getHeight() * this.species.renderer.width, this.getHeight() * this.species.renderer.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getReachDistance()
|
|
|
|
{
|
|
|
|
return Math.max(1.5, 5.0 * (double)this.getHeight()); // / 1.8);
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getRenderScale()
|
|
|
|
{
|
|
|
|
return /* this.isPlayer() ? (0.9375f * this.height / this.getModel().height) : ( */ 0.9375f * this.height / this.species.renderer.height; // );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void handleJumpLava()
|
|
|
|
{
|
|
|
|
this.motionY += 0.03999999910593033D * (this.getHeight() * 1.8f + 2.2f) / 4.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected float getJumpUpwardsMotion()
|
|
|
|
{
|
|
|
|
return 0.42F * (this.getHeight() * 1.8f + 2.2f) / 4.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAIMoveSpeed(float speedIn)
|
|
|
|
{
|
|
|
|
this.landMovement = speedIn;
|
|
|
|
if(!this.isPlayer())
|
|
|
|
this.setMoveForward(speedIn);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void collideWithPlayer(Entity p_71044_1_)
|
|
|
|
{
|
|
|
|
p_71044_1_.onCollideWithPlayer(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Args: itemstack, flag
|
|
|
|
*/
|
|
|
|
public EntityItem dropPlayerItemWithRandomChoice(ItemStack itemStackIn, boolean traceItem)
|
|
|
|
{
|
|
|
|
return this.dropItem(itemStackIn, false, traceItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
public EntityItem dropItem(ItemStack droppedItem, boolean dropAround, boolean traceItem)
|
|
|
|
{
|
|
|
|
if (droppedItem == null)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else if (droppedItem.stackSize == 0)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(traceItem && !this.worldObj.client)
|
|
|
|
this.connection.sendThrowMessage(droppedItem);
|
|
|
|
|
|
|
|
double d0 = this.posY - 0.30000001192092896D + (double)this.getEyeHeight();
|
|
|
|
EntityItem entityitem = new EntityItem(this.worldObj, this.posX, d0, this.posZ, droppedItem);
|
|
|
|
entityitem.setPickupDelay(40);
|
|
|
|
|
|
|
|
// if (traceItem)
|
|
|
|
// {
|
|
|
|
// entityitem.setThrower(this.getUser());
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (dropAround)
|
|
|
|
{
|
|
|
|
float f = this.rand.floatv() * 0.5F;
|
|
|
|
float f1 = this.rand.floatv() * (float)Math.PI * 2.0F;
|
|
|
|
entityitem.motionX = (double)(-ExtMath.sin(f1) * f);
|
|
|
|
entityitem.motionZ = (double)(ExtMath.cos(f1) * f);
|
|
|
|
entityitem.motionY = 0.20000000298023224D;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float f2 = 0.3F;
|
|
|
|
entityitem.motionX = (double)(-ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI) * f2);
|
|
|
|
entityitem.motionZ = (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI) * f2);
|
|
|
|
entityitem.motionY = (double)(-ExtMath.sin(this.rotPitch / 180.0F * (float)Math.PI) * f2 + 0.1F);
|
|
|
|
float f3 = this.rand.floatv() * (float)Math.PI * 2.0F;
|
|
|
|
f2 = 0.02F * this.rand.floatv();
|
|
|
|
entityitem.motionX += Math.cos((double)f3) * (double)f2;
|
|
|
|
entityitem.motionY += (double)((this.rand.floatv() - this.rand.floatv()) * 0.1F);
|
|
|
|
entityitem.motionZ += Math.sin((double)f3) * (double)f2;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.joinEntityItemWithWorld(entityitem);
|
|
|
|
|
|
|
|
// if (traceItem)
|
|
|
|
// {
|
|
|
|
// this.triggerAchievement(StatRegistry.dropStat);
|
|
|
|
// }
|
|
|
|
|
|
|
|
return entityitem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Block hardness will be further counted in game/block/Block.getPlayerRelativeBlockHardness
|
|
|
|
*/
|
|
|
|
public float getToolDigEfficiency(Block p_180471_1_)
|
|
|
|
{
|
|
|
|
float f = this.inventory.getStrVsBlock(p_180471_1_);
|
|
|
|
|
|
|
|
if (f > 1.0F)
|
|
|
|
{
|
|
|
|
int i = EnchantmentHelper.getEfficiencyModifier(this);
|
|
|
|
ItemStack itemstack = this.inventory.getCurrentItem();
|
|
|
|
|
|
|
|
if (i > 0 && itemstack != null)
|
|
|
|
{
|
|
|
|
f += (float)(i * i + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasEffect(Potion.digSpeed))
|
|
|
|
{
|
|
|
|
int speed = this.getEffect(Potion.digSpeed).getAmplifier();
|
|
|
|
if(speed >= 255)
|
|
|
|
return 1000000.0f;
|
|
|
|
f *= 1.0F + (float)(speed + 1) * 0.2F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasEffect(Potion.digSlowdown))
|
|
|
|
{
|
|
|
|
float f1 = 1.0F;
|
|
|
|
|
|
|
|
switch (this.getEffect(Potion.digSlowdown).getAmplifier())
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
f1 = 0.3F;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
f1 = 0.09F;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
f1 = 0.0027F;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
default:
|
|
|
|
f1 = 8.1E-4F;
|
|
|
|
}
|
|
|
|
|
|
|
|
f *= f1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the player has the ability to harvest a block (checks current inventory item for a tool if necessary)
|
|
|
|
*/
|
|
|
|
public boolean canHarvestBlock(Block blockToHarvest)
|
|
|
|
{
|
|
|
|
return this.inventory.canHeldItemHarvest(blockToHarvest);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* (abstract) Protected helper method to read subclass entity data from NBT.
|
|
|
|
*/
|
|
|
|
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
|
|
|
{
|
|
|
|
// super.readEntityFromNBT(tagCompund);
|
|
|
|
super.readEntityFromNBT(tagCompund);
|
|
|
|
|
|
|
|
// if(tagCompund.hasKey("CanPickUpLoot", 1)) {
|
|
|
|
// this.setCanPickUpLoot(tagCompund.getBoolean("CanPickUpLoot"));
|
|
|
|
// }
|
|
|
|
|
|
|
|
if(tagCompund.hasKey("Equipment", 9)) {
|
|
|
|
NBTTagList nbttaglist = tagCompund.getTagList("Equipment", 10);
|
|
|
|
|
|
|
|
for(int i = 0; i < this.equipment.length; ++i) {
|
|
|
|
this.equipment[i] = ItemStack.loadItemStackFromNBT(nbttaglist.getCompoundTagAt(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// this.setSpecies(tagCompund.getString("Species"));
|
|
|
|
this.setChar(tagCompund.getString("Char"));
|
|
|
|
this.setCape(tagCompund.getString("Cape"));
|
|
|
|
this.isWilling = tagCompund.getBoolean("Willing");
|
|
|
|
this.setMating(tagCompund.getBoolean("Mating"));
|
|
|
|
Alignment // align;
|
|
|
|
// try {
|
|
|
|
align = Alignment.getByName(tagCompund.getString("Align"));
|
|
|
|
// }
|
|
|
|
// catch(IllegalArgumentException e) {
|
|
|
|
// align = this.getNaturalAlign(this.rand);
|
|
|
|
// }
|
|
|
|
this.setAlignment(align);
|
|
|
|
this.setHeight(tagCompund.hasKey("Height", 5) ? tagCompund.getFloat("Height") : this.getBaseSize(this.rand));
|
|
|
|
this.setManaPoints(tagCompund.getInteger("Mana"));
|
|
|
|
Enum type = null;
|
|
|
|
if(tagCompund.hasKey("ClassType", 8) && this.species != null && this.species.classEnum != null) {
|
|
|
|
type = this.species.classnames.get(tagCompund.getString("ClassType"));
|
|
|
|
// try {
|
|
|
|
// type = Enum.valueOf(this.species.classEnum, tagCompund.getString("ClassType").toUpperCase());
|
|
|
|
// }
|
|
|
|
// catch(IllegalArgumentException e) {
|
|
|
|
// type = null;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
this.setNpcClass(type);
|
|
|
|
|
|
|
|
NBTTagList nbttaglist = tagCompund.getTagList("Items", 10);
|
|
|
|
|
|
|
|
for (int i = 0; i < nbttaglist.tagCount(); ++i)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttaglist.getCompoundTagAt(i));
|
|
|
|
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
this.extraInventory.addStack(itemstack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(tagCompund.hasKey("Offers", 10))
|
|
|
|
this.trades = new MerchantRecipeList(tagCompund.getCompoundTag("Offers"));
|
|
|
|
this.healTimer = tagCompund.getInteger("healTimer");
|
|
|
|
if(tagCompund.hasKey("Skin", 7))
|
|
|
|
this.skin = tagCompund.getByteArray("Skin");
|
|
|
|
|
|
|
|
// this.setCanPickUpLoot(true);
|
|
|
|
this.setCombatTask();
|
|
|
|
|
|
|
|
if(this.isPlayer()) {
|
|
|
|
// this.entityUniqueID = getOfflineUUID(this.user);
|
|
|
|
NBTTagList nbttaglist0 = tagCompund.getTagList("Inventory", 10);
|
|
|
|
this.inventory.readFromNBT(nbttaglist0);
|
|
|
|
this.inventory.currentItem = tagCompund.getInteger("SelectedItemSlot");
|
|
|
|
// this.sleeping = tagCompund.getBoolean("Sleeping");
|
|
|
|
// this.sleepTimer = tagCompund.getShort("SleepTimer");
|
|
|
|
this.experience = tagCompund.getFloat("XpP");
|
|
|
|
this.experienceLevel = tagCompund.getInteger("XpLevel");
|
|
|
|
this.experienceTotal = tagCompund.getInteger("XpTotal");
|
|
|
|
this.xpSeed = tagCompund.getInteger("XpSeed");
|
|
|
|
|
|
|
|
if (this.xpSeed == 0)
|
|
|
|
{
|
|
|
|
this.xpSeed = this.rand.intv();
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.setScore(tagCompund.getInteger("Score"));
|
|
|
|
// this.setManaPoints(tagCompund.getInteger("Mana"));
|
|
|
|
|
|
|
|
// if (this.sleeping)
|
|
|
|
// {
|
|
|
|
// this.playerLocation = new BlockPos(this);
|
|
|
|
// this.wakeUpPlayer();
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (tagCompund.hasKey("SpawnX", 99) && tagCompund.hasKey("SpawnY", 99) && tagCompund.hasKey("SpawnZ", 99))
|
|
|
|
{
|
|
|
|
this.spawnPos = new WorldPos(tagCompund.getInteger("SpawnX"), tagCompund.getInteger("SpawnY"),
|
|
|
|
tagCompund.getInteger("SpawnZ"), tagCompund.getInteger("SpawnDim"));
|
|
|
|
// this.spawnForced = tagCompund.getBoolean("SpawnForced");
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.foodStats.readNBT(tagCompund);
|
|
|
|
// this.readCapabilitiesFromNBT(tagCompund);
|
|
|
|
this.flying = tagCompund.getBoolean("flying") && this.hasEffect(Potion.flying);
|
|
|
|
// if(tagCompund.hasKey("speed", 99))
|
|
|
|
// this.speed = tagCompund.getFloat("speed");
|
|
|
|
// this.disableDamagePersist = tagCompund.getBoolean("alwaysInvulnerable");
|
|
|
|
// this.disableTargetPersist = tagCompund.getBoolean("neverTarget");
|
|
|
|
// this.allowFlyingPersist = tagCompund.getBoolean("alwaysFly");
|
|
|
|
this.noclip = tagCompund.getBoolean("noClip");
|
|
|
|
|
|
|
|
if (tagCompund.hasKey("WarpItems", 9))
|
|
|
|
{
|
|
|
|
NBTTagList nbttaglist1 = tagCompund.getTagList("WarpItems", 10);
|
|
|
|
this.warpChest.loadInventoryFromNBT(nbttaglist1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ModelType // model;
|
|
|
|
// try {
|
|
|
|
// model = ModelType.getByName(tagCompund.getString("Model"));
|
|
|
|
// }
|
|
|
|
// catch(IllegalArgumentException e) {
|
|
|
|
// model = ModelType.HUMANOID;
|
|
|
|
// }
|
|
|
|
// this.setModel(model);
|
|
|
|
// this.setModelParts(tagCompund.hasKey("PartFlags", 3) ? tagCompund.getInteger("PartFlags") : ~ModelPart.ARMS_SLIM.getMask());
|
|
|
|
// if(tagCompund.hasKey("PlayerScale", 5))
|
|
|
|
// this.setPlayerHeight(tagCompund.getFloat("PlayerScale"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* (abstract) Protected helper method to write subclass entity data to NBT.
|
|
|
|
*/
|
|
|
|
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
|
|
|
{
|
|
|
|
if(this.isPlayer()) {
|
|
|
|
for (int z = 0; z < this.inventory.mainInventory.length; z++)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.inventory.mainInventory[z];
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
this.getAttributeMap().removeAttributeModifiers(itemstack.getAttributeModifiers(2), z, itemstack.stackSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// super.writeEntityToNBT(tagCompound);
|
|
|
|
super.writeEntityToNBT(tagCompound);
|
|
|
|
|
|
|
|
// tagCompound.setBoolean("CanPickUpLoot", this.canPickUpLoot());
|
|
|
|
NBTTagList nbttaglist0 = new NBTTagList();
|
|
|
|
|
|
|
|
for(int i = 0; i < this.equipment.length; ++i) {
|
|
|
|
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
|
|
|
|
|
|
|
if(this.equipment[i] != null) {
|
|
|
|
this.equipment[i].writeToNBT(nbttagcompound);
|
|
|
|
}
|
|
|
|
|
|
|
|
nbttaglist0.appendTag(nbttagcompound);
|
|
|
|
}
|
|
|
|
|
|
|
|
tagCompound.setTag("Equipment", nbttaglist0);
|
|
|
|
// tagCompound.setString("Species", this.getSpecies());
|
|
|
|
tagCompound.setString("Char", this.getChar());
|
|
|
|
tagCompound.setString("Cape", this.getCape());
|
|
|
|
tagCompound.setBoolean("Willing", this.isWilling);
|
|
|
|
tagCompound.setBoolean("Mating", this.isMating());
|
|
|
|
tagCompound.setString("Align", this.alignment.name);
|
|
|
|
tagCompound.setFloat("Height", this.getHeight());
|
|
|
|
tagCompound.setInteger("Mana", this.getManaPoints());
|
|
|
|
Enum type = this.getNpcClass();
|
|
|
|
if(type != null)
|
|
|
|
tagCompound.setString("ClassType", this.species.classnames.inverse().get(type));
|
|
|
|
|
|
|
|
NBTTagList nbttaglist = new NBTTagList();
|
|
|
|
|
|
|
|
for (int i = 0; i < this.extraInventory.getSizeInventory(); ++i)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.extraInventory.getStackInSlot(i);
|
|
|
|
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
nbttaglist.appendTag(itemstack.writeToNBT(new NBTTagCompound()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tagCompound.setTag("Items", nbttaglist);
|
|
|
|
if(this.trades != null)
|
|
|
|
tagCompound.setTag("Offers", this.trades.getRecipiesAsTags());
|
|
|
|
tagCompound.setInteger("healTimer", this.healTimer);
|
|
|
|
if(this.skin != null)
|
|
|
|
tagCompound.setByteArray("Skin", this.skin);
|
|
|
|
|
|
|
|
if(this.isPlayer()) {
|
|
|
|
for (int z = 0; z < this.inventory.mainInventory.length; z++)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.inventory.mainInventory[z];
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
this.getAttributeMap().applyAttributeModifiers(itemstack.getAttributeModifiers(2), z, itemstack.stackSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList()));
|
|
|
|
tagCompound.setInteger("SelectedItemSlot", this.inventory.currentItem);
|
|
|
|
// tagCompound.setBoolean("Sleeping", this.sleeping);
|
|
|
|
// tagCompound.setShort("SleepTimer", (short)this.sleepTimer);
|
|
|
|
tagCompound.setFloat("XpP", this.experience);
|
|
|
|
tagCompound.setInteger("XpLevel", this.experienceLevel);
|
|
|
|
tagCompound.setInteger("XpTotal", this.experienceTotal);
|
|
|
|
tagCompound.setInteger("XpSeed", this.xpSeed);
|
|
|
|
// tagCompound.setInteger("Score", this.getScore());
|
|
|
|
// tagCompound.setInteger("Mana", this.getManaPoints());
|
|
|
|
|
|
|
|
if (this.spawnPos != null)
|
|
|
|
{
|
|
|
|
tagCompound.setInteger("SpawnX", this.spawnPos.getX());
|
|
|
|
tagCompound.setInteger("SpawnY", this.spawnPos.getY());
|
|
|
|
tagCompound.setInteger("SpawnZ", this.spawnPos.getZ());
|
|
|
|
tagCompound.setInteger("SpawnDim", this.spawnPos.getDimension());
|
|
|
|
// tagCompound.setBoolean("SpawnForced", this.spawnForced);
|
|
|
|
}
|
|
|
|
|
|
|
|
// this.foodStats.writeNBT(tagCompound);
|
|
|
|
// this.writeCapabilitiesToNBT(tagCompound);
|
|
|
|
tagCompound.setBoolean("flying", this.flying);
|
|
|
|
// tagCompound.setFloat("speed", this.speed);
|
|
|
|
// tagCompound.setBoolean("alwaysInvulnerable", this.disableDamagePersist);
|
|
|
|
// tagCompound.setBoolean("neverTarget", this.disableTargetPersist);
|
|
|
|
// tagCompound.setBoolean("alwaysFly", this.allowFlyingPersist);
|
|
|
|
tagCompound.setBoolean("noClip", this.noclip);
|
|
|
|
|
|
|
|
tagCompound.setTag("WarpItems", this.warpChest.saveInventoryToNBT());
|
|
|
|
ItemStack itemstack = this.inventory.getCurrentItem();
|
|
|
|
|
|
|
|
if (itemstack != null && itemstack.getItem() != null)
|
|
|
|
{
|
|
|
|
tagCompound.setTag("SelectedItem", itemstack.writeToNBT(new NBTTagCompound()));
|
|
|
|
}
|
|
|
|
|
|
|
|
// tagCompound.setString("Model", this.getModel().name);
|
|
|
|
// tagCompound.setInteger("PartFlags", this.getModelParts());
|
|
|
|
// tagCompound.setFloat("PlayerScale", this.getPlayerHeight());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void damageArmor(int p_70675_1_)
|
|
|
|
{
|
|
|
|
if(this.isPlayer())
|
|
|
|
this.inventory.damageArmor(p_70675_1_);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
|
|
|
|
*/
|
|
|
|
public int getTotalArmorValue()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? this.inventory.getTotalArmorValue() : super.getTotalArmorValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean interactWith(Entity targetEntity)
|
|
|
|
{
|
|
|
|
// if (this.isSpectator())
|
|
|
|
// {
|
|
|
|
// if (targetEntity instanceof IInventory)
|
|
|
|
// {
|
|
|
|
// this.displayGUIChest((IInventory)targetEntity);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
ItemStack itemstack = this.getCurrentEquippedItem();
|
|
|
|
ItemStack itemstack1 = itemstack != null ? itemstack.copy() : null;
|
|
|
|
|
|
|
|
if (!targetEntity.interactFirst(this))
|
|
|
|
{
|
|
|
|
if (itemstack != null && targetEntity instanceof EntityLiving)
|
|
|
|
{
|
|
|
|
// if (this.creative)
|
|
|
|
// {
|
|
|
|
// itemstack = itemstack1;
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (itemstack.interactWithEntity(this, (EntityLiving)targetEntity))
|
|
|
|
{
|
|
|
|
if (itemstack.stackSize <= 0) // && !this.creative)
|
|
|
|
{
|
|
|
|
this.destroyCurrentEquippedItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (itemstack != null && itemstack == this.getCurrentEquippedItem())
|
|
|
|
{
|
|
|
|
if (itemstack.stackSize <= 0) // && !this.creative)
|
|
|
|
{
|
|
|
|
this.destroyCurrentEquippedItem();
|
|
|
|
}
|
|
|
|
// else if (itemstack.stackSize < itemstack1.stackSize && this.creative)
|
|
|
|
// {
|
|
|
|
// itemstack.stackSize = itemstack1.stackSize;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the currently being used item by the player.
|
|
|
|
*/
|
|
|
|
public ItemStack getCurrentEquippedItem()
|
|
|
|
{
|
|
|
|
return this.inventory.getCurrentItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroys the currently equipped item from the player's inventory.
|
|
|
|
*/
|
|
|
|
public void destroyCurrentEquippedItem()
|
|
|
|
{
|
|
|
|
this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack)null);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the Y Offset of this entity.
|
|
|
|
*/
|
|
|
|
public double getYOffset()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? -0.35D : super.getYOffset();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attacks for the player the targeted entity with the currently equipped item. The equipped item has hitEntity
|
|
|
|
* called on it. Args: targetEntity
|
|
|
|
*/
|
|
|
|
public void attackTargetEntityWithCurrentItem(Entity targetEntity)
|
|
|
|
{
|
|
|
|
if(!this.worldObj.client) {
|
|
|
|
if(/* !this.creative && */ this.sinceLastAttack < Config.attackDelay)
|
|
|
|
return;
|
|
|
|
this.sinceLastAttack = 0;
|
|
|
|
}
|
|
|
|
if (targetEntity.canAttackWithItem())
|
|
|
|
{
|
|
|
|
if (!targetEntity.hitByEntity(this))
|
|
|
|
{
|
|
|
|
int f = (int)this.getEntityAttribute(Attributes.ATTACK_DAMAGE).getAttributeValue();
|
|
|
|
int i = 0;
|
|
|
|
int f1 = // 0;
|
|
|
|
|
|
|
|
// if (targetEntity instanceof EntityLivingBase)
|
|
|
|
// {
|
|
|
|
// f1 = EnchantmentHelper.getModifierForCreature(this.getHeldItem());
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// f1 =
|
|
|
|
EnchantmentHelper.getDamageModifier(this.getHeldItem());
|
|
|
|
// }
|
|
|
|
|
|
|
|
i = i + EnchantmentHelper.getKnockbackModifier(this);
|
|
|
|
|
|
|
|
if (this.isSprinting())
|
|
|
|
{
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f > 0 || f1 > 0)
|
|
|
|
{
|
|
|
|
boolean flag = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInLiquid() && !this.hasEffect(Potion.blindness) && this.vehicle == null && targetEntity instanceof EntityLiving;
|
|
|
|
|
|
|
|
if (flag && f > 0)
|
|
|
|
{
|
|
|
|
f = (int)((float)f * 1.5F);
|
|
|
|
}
|
|
|
|
|
|
|
|
f = f + f1;
|
|
|
|
boolean flag1 = false;
|
|
|
|
int j = EnchantmentHelper.getFireAspectModifier(this);
|
|
|
|
|
|
|
|
if (targetEntity instanceof EntityLiving && j > 0 && !targetEntity.isBurning())
|
|
|
|
{
|
|
|
|
flag1 = true;
|
|
|
|
targetEntity.setFire(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
double d0 = targetEntity.motionX;
|
|
|
|
double d1 = targetEntity.motionY;
|
|
|
|
double d2 = targetEntity.motionZ;
|
|
|
|
boolean flag2 = (this.worldObj.client || Config.attack) && targetEntity.attackEntityFrom(DamageSource.causeMobDamage(this), f);
|
|
|
|
|
|
|
|
if (flag2)
|
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
targetEntity.addKnockback((double)(-ExtMath.sin(this.rotYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F), 0.1D, (double)(ExtMath.cos(this.rotYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F));
|
|
|
|
this.motionX *= 0.6D;
|
|
|
|
this.motionZ *= 0.6D;
|
|
|
|
this.setSprinting(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.worldObj.client && targetEntity.isPlayer() && targetEntity.veloChanged)
|
|
|
|
{
|
|
|
|
((EntityNPC)targetEntity).connection.sendPacket(new SPacketEntityVelocity(targetEntity));
|
|
|
|
targetEntity.veloChanged = false;
|
|
|
|
targetEntity.motionX = d0;
|
|
|
|
targetEntity.motionY = d1;
|
|
|
|
targetEntity.motionZ = d2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
this.onCriticalHit(targetEntity);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f1 > 0.0F)
|
|
|
|
{
|
|
|
|
this.onEnchantmentCritical(targetEntity);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setLastAttack(targetEntity);
|
|
|
|
|
|
|
|
if (targetEntity instanceof EntityLiving)
|
|
|
|
{
|
|
|
|
EnchantmentHelper.applyThornEnchantments((EntityLiving)targetEntity, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
EnchantmentHelper.applyArthropodEnchantments(this, targetEntity);
|
|
|
|
ItemStack itemstack = this.getCurrentEquippedItem();
|
|
|
|
Entity entity = targetEntity;
|
|
|
|
|
|
|
|
if (targetEntity instanceof EntityDragonPart)
|
|
|
|
{
|
|
|
|
IEntityMultiPart ientitymultipart = ((EntityDragonPart)targetEntity).entityDragonObj;
|
|
|
|
|
|
|
|
if (ientitymultipart instanceof EntityLiving)
|
|
|
|
{
|
|
|
|
entity = (EntityLiving)ientitymultipart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemstack != null && entity instanceof EntityLiving)
|
|
|
|
{
|
|
|
|
itemstack.hitEntity((EntityLiving)entity, this);
|
|
|
|
|
|
|
|
if (itemstack.stackSize <= 0)
|
|
|
|
{
|
|
|
|
this.destroyCurrentEquippedItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (targetEntity instanceof EntityLiving)
|
|
|
|
{
|
|
|
|
// this.addStat(StatRegistry.damageDealtStat, f);
|
|
|
|
|
|
|
|
if (j > 0)
|
|
|
|
{
|
|
|
|
targetEntity.setFire(j * 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (flag1)
|
|
|
|
{
|
|
|
|
targetEntity.extinguish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Will get destroyed next tick.
|
|
|
|
*/
|
|
|
|
public void setDead()
|
|
|
|
{
|
|
|
|
super.setDead();
|
|
|
|
if(this.isPlayer()) {
|
|
|
|
this.inventoryContainer.onContainerClosed(this);
|
|
|
|
|
|
|
|
if (this.openContainer != null)
|
|
|
|
{
|
|
|
|
this.openContainer.onContainerClosed(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return null if bed is invalid
|
|
|
|
*/
|
|
|
|
public static BlockPos getBedSpawnLocation(World worldIn, BlockPos bedLocation)
|
|
|
|
{
|
|
|
|
Block block = worldIn.getState(bedLocation).getBlock();
|
|
|
|
|
|
|
|
if (!(block instanceof BlockBed))
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return BlockBed.getSafeExitLocation(worldIn, bedLocation, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public WorldPos getSpawnPoint()
|
|
|
|
{
|
|
|
|
return this.spawnPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSpawnPoint(WorldPos pos)
|
|
|
|
{
|
|
|
|
this.spawnPos = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * Will trigger the specified trigger.
|
|
|
|
// */
|
|
|
|
// public void triggerAchievement(StatBase achievementIn)
|
|
|
|
// {
|
|
|
|
// this.addStat(1);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * Causes this entity to do an upwards motion (jumping).
|
|
|
|
// */
|
|
|
|
// public void jump()
|
|
|
|
// {
|
|
|
|
// super.jump();
|
|
|
|
// if(this.isPlayer())
|
|
|
|
// this.triggerAchievement(StatRegistry.jumpStat);
|
|
|
|
// }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Moves the entity based on the specified heading. Args: strafe, forward
|
|
|
|
*/
|
|
|
|
public void moveEntityWithHeading(float strafe, float forward)
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.moveEntityWithHeading(strafe, forward);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
double d0 = this.posX;
|
|
|
|
double d1 = this.posY;
|
|
|
|
double d2 = this.posZ;
|
|
|
|
|
|
|
|
if (this.isFlying() && this.vehicle == null)
|
|
|
|
{
|
|
|
|
double d3 = this.motionY;
|
|
|
|
float f = this.jumpMovement;
|
|
|
|
if(this.flying)
|
|
|
|
this.jumpMovement = this.landMovement * 0.5f * (float)(this.isSprinting() ? 2 : 1);
|
|
|
|
super.moveEntityWithHeading(strafe, forward);
|
|
|
|
this.motionY = d3 * 0.6D;
|
|
|
|
this.jumpMovement = f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
super.moveEntityWithHeading(strafe, forward);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.addMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the movespeed used for the new AI system
|
|
|
|
*/
|
|
|
|
public float getAIMoveSpeed()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? (float)this.getEntityAttribute(Attributes.MOVEMENT_SPEED).getAttributeValue() : super.getAIMoveSpeed();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a value to a movement statistic field - like run, walk, swin or climb.
|
|
|
|
*/
|
|
|
|
public void addMovementStat(double p_71000_1_, double p_71000_3_, double p_71000_5_)
|
|
|
|
{
|
|
|
|
if (this.vehicle == null)
|
|
|
|
{
|
|
|
|
if (this.isInsideOfLiquid())
|
|
|
|
{
|
|
|
|
int i = Math.round(ExtMath.sqrtd(p_71000_1_ * p_71000_1_ + p_71000_3_ * p_71000_3_ + p_71000_5_ * p_71000_5_) * 100.0F);
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
this.addStat(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.isInLiquid())
|
|
|
|
{
|
|
|
|
int j = Math.round(ExtMath.sqrtd(p_71000_1_ * p_71000_1_ + p_71000_5_ * p_71000_5_) * 100.0F);
|
|
|
|
|
|
|
|
if (j > 0)
|
|
|
|
{
|
|
|
|
this.addStat(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.isOnLadder())
|
|
|
|
{
|
|
|
|
if (p_71000_3_ > 0.0D)
|
|
|
|
{
|
|
|
|
this.addStat((int)Math.round(p_71000_3_ * 100.0D));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.onGround)
|
|
|
|
{
|
|
|
|
int k = Math.round(ExtMath.sqrtd(p_71000_1_ * p_71000_1_ + p_71000_5_ * p_71000_5_) * 100.0F);
|
|
|
|
|
|
|
|
if (k > 0)
|
|
|
|
{
|
|
|
|
this.addStat(k);
|
|
|
|
|
|
|
|
// if (this.isSprinting())
|
|
|
|
// {
|
|
|
|
// this.addStat(StatRegistry.distanceSprintedStat, k);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// if (this.isSneaking())
|
|
|
|
// {
|
|
|
|
// this.addStat(StatRegistry.distanceCrouchedStat, k);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int l = Math.round(ExtMath.sqrtd(p_71000_1_ * p_71000_1_ + p_71000_5_ * p_71000_5_) * 100.0F);
|
|
|
|
|
|
|
|
if (l > 25)
|
|
|
|
{
|
|
|
|
this.addStat(l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a value to a mounted movement statistic field - by minecart, boat, or pig.
|
|
|
|
*/
|
|
|
|
private void addMountedMovementStat(double p_71015_1_, double p_71015_3_, double p_71015_5_)
|
|
|
|
{
|
|
|
|
if (this.vehicle != null)
|
|
|
|
{
|
|
|
|
int i = Math.round(ExtMath.sqrtd(p_71015_1_ * p_71015_1_ + p_71015_3_ * p_71015_3_ + p_71015_5_ * p_71015_5_) * 100.0F);
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
if (this.vehicle instanceof EntityCart)
|
|
|
|
{
|
|
|
|
this.addStat(i);
|
|
|
|
|
|
|
|
// if (this.startMinecartRidingCoordinate == null)
|
|
|
|
// {
|
|
|
|
// this.startMinecartRidingCoordinate = new BlockPos(this);
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
else if (this.vehicle instanceof EntityBoat)
|
|
|
|
{
|
|
|
|
this.addStat(i);
|
|
|
|
}
|
|
|
|
else if (this.vehicle instanceof EntityPig)
|
|
|
|
{
|
|
|
|
this.addStat(i);
|
|
|
|
}
|
|
|
|
else if (this.vehicle instanceof EntityHorse)
|
|
|
|
{
|
|
|
|
this.addStat(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void fall(float distance, float damageMultiplier)
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.fall(distance, damageMultiplier);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!this.noclip && this.worldObj.gravity != 0.0)
|
|
|
|
{
|
|
|
|
if (distance >= 2.0F)
|
|
|
|
{
|
|
|
|
this.addStat((int)Math.round((double)distance * 100.0D));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!this.hasEffect(Potion.flying))
|
|
|
|
super.fall(distance, damageMultiplier);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void makeLandingParticles(BlockPos pos)
|
|
|
|
{
|
|
|
|
if (!this.isPlayer() || (!this.noclip && this.worldObj.gravity != 0.0))
|
|
|
|
{
|
|
|
|
super.makeLandingParticles(pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void onEnterLiquid()
|
|
|
|
{
|
|
|
|
if (!this.isPlayer() || !this.noclip)
|
|
|
|
{
|
|
|
|
super.onEnterLiquid();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * This method gets called when the entity kills another one.
|
|
|
|
// */
|
|
|
|
// public void onKillEntity(EntityLiving entityLivingIn)
|
|
|
|
// {
|
|
|
|
// if(this.isPlayer()) {
|
|
|
|
// EntityEggInfo entitylist$entityegginfo = (EntityEggInfo)EntityRegistry.SPAWN_EGGS.get(EntityRegistry.getEntityString(entityLivingIn));
|
|
|
|
//
|
|
|
|
// if (entitylist$entityegginfo != null)
|
|
|
|
// {
|
|
|
|
// this.triggerAchievement(entitylist$entityegginfo.killStat);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the Entity inside a web block.
|
|
|
|
*/
|
|
|
|
public void setInWeb()
|
|
|
|
{
|
|
|
|
if (!this.isPlayer() || !this.flying)
|
|
|
|
{
|
|
|
|
super.setInWeb();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public ItemStack getArmor(int slot)
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? this.inventory.armorItemInSlot(slot) : this.equipment[slot + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add experience points to player.
|
|
|
|
*/
|
|
|
|
public void addExperience(int amount)
|
|
|
|
{
|
|
|
|
int i = Integer.MAX_VALUE - this.experienceTotal;
|
|
|
|
|
|
|
|
if (amount > i)
|
|
|
|
{
|
|
|
|
amount = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.experience += (float)amount / (float)this.xpBarCap();
|
|
|
|
|
|
|
|
for (this.experienceTotal += amount; this.experience >= 1.0F; this.experience /= (float)this.xpBarCap())
|
|
|
|
{
|
|
|
|
this.experience = (this.experience - 1.0F) * (float)this.xpBarCap();
|
|
|
|
this.addExperienceLevel(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getXPSeed()
|
|
|
|
{
|
|
|
|
return this.xpSeed;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setXPSeed(int xpSeed)
|
|
|
|
{
|
|
|
|
this.xpSeed = xpSeed;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method returns the cap amount of experience that the experience bar can hold. With each level, the
|
|
|
|
* experience cap on the player's experience bar is raised by 10.
|
|
|
|
*/
|
|
|
|
public int xpBarCap()
|
|
|
|
{
|
|
|
|
return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration
|
|
|
|
*/
|
|
|
|
public void setItemInUse(ItemStack stack, int duration)
|
|
|
|
{
|
|
|
|
if (stack != this.itemInUse)
|
|
|
|
{
|
|
|
|
this.itemInUse = stack;
|
|
|
|
this.itemInUseCount = duration;
|
|
|
|
|
|
|
|
if (!this.worldObj.client)
|
|
|
|
{
|
|
|
|
this.setUsingItem(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canPlayerEdit(BlockPos pos, Facing side, ItemStack stack)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the experience points the entity currently has.
|
|
|
|
*/
|
|
|
|
protected int getExperiencePoints(EntityNPC player)
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? 0 : this.worldObj.rand.range(2, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
|
|
|
* prevent them from trampling crops
|
|
|
|
*/
|
|
|
|
protected boolean canTriggerWalking()
|
|
|
|
{
|
|
|
|
return !this.isPlayer() || !this.flying;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the InventoryWarpChest of this player.
|
|
|
|
*/
|
|
|
|
public InventoryWarpChest getWarpChest()
|
|
|
|
{
|
|
|
|
return this.warpChest;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setWarpChest(InventoryWarpChest warpChest)
|
|
|
|
{
|
|
|
|
this.warpChest = warpChest;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 0: Tool in Hand; 1-4: Armor
|
|
|
|
*/
|
|
|
|
public ItemStack getItem(int slot)
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? (slot == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[slot - 1]) : this.equipment[slot];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the item that this EntityLiving is holding, if any.
|
|
|
|
*/
|
|
|
|
public ItemStack getHeldItem()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? this.inventory.getCurrentItem() : this.equipment[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns the inventory of this entity (only used in EntityNPCMP it seems)
|
|
|
|
*/
|
|
|
|
public ItemStack[] getInventory()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? this.inventory.armorInventory : this.equipment;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPushedByWater()
|
|
|
|
{
|
|
|
|
return !this.isPlayer() || !this.flying;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getName()
|
|
|
|
{
|
|
|
|
if(this.isPlayer())
|
|
|
|
return this.getAlignment().color + (this.hasCustomName() ? this.getCustomNameTag() : "<?>");
|
|
|
|
String text = this.getPrefix();
|
|
|
|
// Enum cls = this.getNpcClass();
|
|
|
|
if(text == null) {
|
|
|
|
text = this.getTypeName();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// text = new TextComponent("entity.className." + cls.name().toLowerCase());
|
|
|
|
if(this.hasCustomName())
|
|
|
|
text += " " + this.getCustomNameTag();
|
|
|
|
}
|
|
|
|
return this.getAlignment().color + text;
|
|
|
|
// this.formatComponent(comp);
|
|
|
|
// text.setColor();
|
|
|
|
// return comp;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getEyeHeight()
|
|
|
|
{
|
|
|
|
if(!this.isPlayer())
|
|
|
|
return 1.62F * this.height / 1.8f;
|
|
|
|
float f = 1.62F * this.getHeight(); // / 1.8f;
|
|
|
|
|
|
|
|
if (this.isSneaking())
|
|
|
|
{
|
|
|
|
f -= 0.08F * this.getHeight(); // / 1.8f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAbsorptionAmount(int amount)
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.setAbsorptionAmount(amount);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (amount < 0)
|
|
|
|
{
|
|
|
|
amount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.getDataWatcher().updateObject(30, Integer.valueOf(amount));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getAbsorptionAmount()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? this.getDataWatcher().getWatchableObjectInt(30) : super.getAbsorptionAmount();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canOpen(LockCode code)
|
|
|
|
{
|
|
|
|
if (code.isEmpty())
|
|
|
|
return true;
|
|
|
|
ItemStack stack = this.getCurrentEquippedItem();
|
|
|
|
return stack != null && stack.getItem() == Items.key &&
|
|
|
|
stack.hasDisplayName() && stack.getDisplayName().equals(code.getLock());
|
|
|
|
}
|
|
|
|
|
|
|
|
// public boolean isWearing(ModelPart part)
|
|
|
|
// {
|
|
|
|
// return this.isPlayer() ? (this.getDataWatcher().getWatchableObjectInt(10) & part.getMask()) == part.getMask()
|
|
|
|
// : (part != ModelPart.ARMS_SLIM || this.hasSlimSkin());
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public int getModelParts()
|
|
|
|
// {
|
|
|
|
// return this.getDataWatcher().getWatchableObjectInt(10);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public void setModelParts(int parts)
|
|
|
|
// {
|
|
|
|
// this.getDataWatcher().updateObject(10, Integer.valueOf(parts));
|
|
|
|
// }
|
|
|
|
|
|
|
|
public int getTrackingRange() {
|
|
|
|
return this.isPlayer() ? 512 : 80;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getUpdateFrequency() {
|
|
|
|
return this.isPlayer() ? 2 : 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSendingVeloUpdates() {
|
|
|
|
return !this.isPlayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isFlying() {
|
|
|
|
return this.flying || this.worldObj.gravity == 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getEnergy(Energy type) { // TODO
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasEnergyEffect(Energy type) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isEnergyDrawn(Energy type) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// livingbase override
|
|
|
|
|
|
|
|
protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier)
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
super.dropFewItems(wasRecentlyHit, lootingModifier);
|
|
|
|
this.dropEquipment();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Object onInitialSpawn(Object livingdata) {
|
|
|
|
// if(this.isPlayer()) {
|
|
|
|
// this.setCustomNameTag(this.pickRandomName(this.rand, null));
|
|
|
|
// return livingdata;
|
|
|
|
// }
|
|
|
|
livingdata = super.onInitialSpawn(livingdata);
|
|
|
|
CharacterInfo info = (livingdata instanceof CharacterTypeData) ? ((CharacterTypeData)livingdata).character :
|
|
|
|
this.species.pickCharacter(this.worldObj.rand);
|
|
|
|
AlignmentData align = livingdata instanceof AlignmentData ? ((AlignmentData)livingdata) : null;
|
|
|
|
this.setNpcClass(info.spclass == null ? null : info.spclass.type);
|
|
|
|
this.setChar(info.skin);
|
|
|
|
this.setCape(info.cape);
|
|
|
|
this.setCustomNameTag(info.name.isEmpty() ? this.pickRandomName(this.rand, info.spclass == null ? null :
|
|
|
|
info.spclass.type) : info.name);
|
|
|
|
if(!this.isPlayer())
|
|
|
|
this.setItemInfo(info);
|
|
|
|
this.setAlignment(align != null ? align.alignment : this.getNaturalAlign(this.rand));
|
|
|
|
this.setHeight(this.getBaseSize(this.rand));
|
|
|
|
return align != null ? align : new AlignmentData(this.alignment);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean interactFirst(EntityNPC playerIn)
|
|
|
|
{
|
|
|
|
return !this.isPlayer() && super.interactFirst(playerIn);
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getMaxFallHeight()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? 3 : super.getMaxFallHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void updateLeashedState() {
|
|
|
|
if(!this.isPlayer())
|
|
|
|
super.updateLeashedState();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setLeashedTo(Entity entity, boolean pkt) {
|
|
|
|
if(!this.isPlayer())
|
|
|
|
super.setLeashedTo(entity, pkt);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean allowLeashing() {
|
|
|
|
return !this.isPlayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearLeashed(boolean pkt, boolean dropLead) {
|
|
|
|
if(!this.isPlayer())
|
|
|
|
super.clearLeashed(pkt, dropLead);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected float updateDistance(float p_110146_1_, float p_110146_2_)
|
|
|
|
{
|
|
|
|
if(!this.isPlayer())
|
|
|
|
return super.updateDistance(p_110146_1_, p_110146_2_);
|
|
|
|
float f = ExtMath.wrapf(p_110146_1_ - this.yawOffset);
|
|
|
|
this.yawOffset += f * 0.3F;
|
|
|
|
float f1 = ExtMath.wrapf(this.rotYaw - this.yawOffset);
|
|
|
|
boolean flag = f1 < -90.0F || f1 >= 90.0F;
|
|
|
|
|
|
|
|
if (f1 < -75.0F)
|
|
|
|
{
|
|
|
|
f1 = -75.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f1 >= 75.0F)
|
|
|
|
{
|
|
|
|
f1 = 75.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.yawOffset = this.rotYaw - f1;
|
|
|
|
|
|
|
|
if (f1 * f1 > 2500.0F)
|
|
|
|
{
|
|
|
|
this.yawOffset += f1 * 0.2F;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
p_110146_2_ *= -1.0F;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p_110146_2_;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean getCanSpawnHere() {
|
|
|
|
return this.isPlayer() || super.getCanSpawnHere();
|
|
|
|
}
|
|
|
|
|
|
|
|
// npc overrides
|
|
|
|
|
|
|
|
|
|
|
|
public void setScaleForAge() {
|
|
|
|
if(!this.isPlayer())
|
|
|
|
this.setScale((float)((int)(100.0f * this.getHeight() * (this.getGrowingAge() < 0 ? 1.0f +
|
|
|
|
((float)Math.max(-24000, this.getGrowingAge()) / 24000.0f) * 0.6f : 1.0f))) / 100.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void dropEquipment()
|
|
|
|
{
|
|
|
|
if(this.isPlayer())
|
|
|
|
return;
|
|
|
|
for (int i = 0; i < this.getInventory().length; ++i)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.getItem(i);
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
this.entityDropItem(itemstack, 0.0F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < this.extraInventory.getSizeInventory(); ++i)
|
|
|
|
{
|
|
|
|
ItemStack itemstack = this.extraInventory.getStackInSlot(i);
|
|
|
|
if (itemstack != null)
|
|
|
|
{
|
|
|
|
this.entityDropItem(itemstack, 0.0F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public EntityNPC createChild(EntityLiving ageable)
|
|
|
|
{
|
|
|
|
// if(this.isPlayer())
|
|
|
|
// return null;
|
|
|
|
EntityNPC template = (ageable instanceof EntityNPC && this.worldObj.rand.chance() ? ((EntityNPC)ageable) : this);
|
|
|
|
EntityNPC entity;
|
|
|
|
try {
|
|
|
|
entity = template.getClass().getConstructor(World.class).newInstance(this.worldObj);
|
|
|
|
}
|
|
|
|
catch(InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
entity.onInitialSpawn(new CharacterTypeData(
|
|
|
|
template.species.pickCharacter(this.worldObj.rand)));
|
|
|
|
// EntityNPC base = ;
|
|
|
|
// entity.setSpecies(base.getSpecies());
|
|
|
|
// entity.setChar(base.getChar());
|
|
|
|
// entity.setCape(base.getCape());
|
|
|
|
// entity.setCustomNameTag(base.getCustomNameTag());
|
|
|
|
// for(int z = 0; z < 5; z++) {
|
|
|
|
// entity.setCurrentItemOrArmor(z, base.getEquipmentInSlot(z) == null ? null : base.getEquipmentInSlot(z).copy());
|
|
|
|
// }
|
|
|
|
// entity.extraInventory.clear();
|
|
|
|
return entity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setItemNoUpdate(int slot, ItemStack stack)
|
|
|
|
{
|
|
|
|
if(!this.isPlayer())
|
|
|
|
this.equipment[slot] = stack;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setCombatTask()
|
|
|
|
{
|
|
|
|
if(!this.isPlayer()) {
|
|
|
|
this.tasks.removeTask(this.aiMelee);
|
|
|
|
this.tasks.removeTask(this.aiRanged);
|
|
|
|
ItemStack itemstack = this.getHeldItem();
|
|
|
|
|
|
|
|
if (this.isRangedWeapon(itemstack))
|
|
|
|
{
|
|
|
|
this.tasks.addTask(3, this.aiRanged);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.tasks.addTask(3, this.aiMelee);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public abstract int getBaseHealth(Random rand); // {
|
|
|
|
// return 20;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public abstract Alignment getNaturalAlign(Random rand); // {
|
|
|
|
// return Alignment.NEUTRAL;
|
|
|
|
// }
|
|
|
|
|
|
|
|
public boolean canPlay() {
|
|
|
|
return !this.isPlayer() && this.getGrowingAge() <= -14000;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getBaseSize(Random rand) {
|
|
|
|
return /* this.isPlayer() ? 1.8f : ( */ (this.species.size + this.getHeightDeviation(rand)) / this.species.size; // );
|
|
|
|
}
|
|
|
|
|
|
|
|
public ModelType getModel() {
|
|
|
|
return this.species.renderer;
|
|
|
|
// return ModelType.values()[this.dataWatcher.getWatchableObjectByte(11) % ModelType.values().length];
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// public void setModel(ModelType model) {
|
|
|
|
// this.dataWatcher.updateObject(11, (byte)model.ordinal());
|
|
|
|
// }
|
|
|
|
|
|
|
|
public int getColor() {
|
|
|
|
return this.isPlayer() ? 0xff00ff : 0x5000ad;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LayerExtra getExtrasLayer()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? EntityTexManager.getLayer(this.getId()) : EntityTexManager.getNpcLayer(this.getChar());
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getLocationSkin()
|
|
|
|
{
|
|
|
|
return this.isPlayer() ? EntityTexManager.getSkin(this.getId(), this.species.renderer) : EntityTexManager.getNpcSkin(this.getChar(), this.species.renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendDeathMessage() {
|
|
|
|
this.sendDeathMessage(this.isPlayer(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean canRegenerateHealth() {
|
|
|
|
return this.isPlayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
// END PLAYER
|
|
|
|
|
|
|
|
public Item getItem() {
|
|
|
|
for(int z = 0; z < this.species.chars.length; z++) {
|
|
|
|
if(this.species.chars[z].spawner && this.species.chars[z].skin.equals(this.getChar())) {
|
|
|
|
return ItemRegistry.getRegisteredItem(this.species.chars[z].skin.replace("~", "") + "_spawner");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return super.getItem();
|
|
|
|
}
|
|
|
|
}
|