Files
CustomNPC-Plus/src/main/java/noppes/npcs/entity/EntityProjectile.java
T

907 lines
41 KiB
Java
Raw Normal View History

2018-09-13 12:03:28 -04:00
package noppes.npcs.entity;
2023-01-12 21:33:06 -05:00
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
2025-01-29 13:20:04 -05:00
import kamkeel.npcs.addon.DBCAddon;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.packets.data.script.ScriptedParticlePacket;
2018-09-13 12:03:28 -04:00
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.play.server.S27PacketExplosion;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
2023-01-12 21:33:06 -05:00
import net.minecraft.util.*;
2018-09-13 12:03:28 -04:00
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import noppes.npcs.DataStats;
2023-03-16 02:51:40 -05:00
import noppes.npcs.EventHooks;
import noppes.npcs.api.IPos;
import noppes.npcs.api.IWorld;
2023-12-31 16:10:38 -05:00
import noppes.npcs.api.entity.IEntity;
2023-03-16 02:51:40 -05:00
import noppes.npcs.api.entity.IProjectile;
2018-09-13 12:03:28 -04:00
import noppes.npcs.constants.EnumParticleType;
import noppes.npcs.constants.EnumPotionType;
2023-03-16 02:51:40 -05:00
import noppes.npcs.controllers.ScriptContainer;
import noppes.npcs.scripted.NpcAPI;
import noppes.npcs.scripted.ScriptParticle;
2023-03-16 02:51:40 -05:00
import noppes.npcs.scripted.event.ProjectileEvent;
2018-09-13 12:03:28 -04:00
import noppes.npcs.util.IProjectileCallback;
2023-01-12 21:33:06 -05:00
2023-03-16 02:51:40 -05:00
import java.util.ArrayList;
2023-01-12 21:33:06 -05:00
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
2018-09-13 12:03:28 -04:00
public class EntityProjectile extends EntityThrowable {
2025-03-13 17:14:45 -04:00
private int xTile = -1;
2018-09-13 12:03:28 -04:00
private int yTile = -1;
private int zTile = -1;
private Block inTile;
protected boolean inGround = false;
private int inData = 0;
public int throwableShake = 0;
public int arrowShake = 0;
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean canBePickedUp = false;
public boolean destroyedOnEntityHit = true;
/**
* Is the entity that throws this 'thing' (snowball, ender pearl, eye of ender or potion)
*/
private EntityLivingBase thrower;
private EntityNPCInterface npc;
public EntityItem entityitem;
private String throwerName = null;
private int ticksInGround;
public int ticksInAir = 0;
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
private double accelerationX;
private double accelerationY;
private double accelerationZ;
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
/**
* Properties settable by GUI
*/
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public float damage = 5;
public int punch = 0;
public boolean accelerate = false;
public boolean explosive = false;
public boolean explosiveDamage = true;
public boolean destroyTerrain = true;
2018-09-13 12:03:28 -04:00
public int explosiveRadius = 0;
public EnumPotionType effect = EnumPotionType.None;
2025-03-19 17:46:12 -04:00
public boolean burnItem = true;
2018-09-13 12:03:28 -04:00
public int duration = 5;
public int amplify = 0;
2025-03-13 17:14:45 -04:00
public int accuracy = 60;
2018-09-13 12:03:28 -04:00
public IProjectileCallback callback;
public ItemStack callbackItem;
2025-03-13 17:14:45 -04:00
public List<ScriptContainer> scripts = new ArrayList<ScriptContainer>();
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
public EntityProjectile(World par1World) {
2018-09-13 12:03:28 -04:00
super(par1World);
this.setSize(0.25F, 0.25F);
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
protected void entityInit() {
this.dataWatcher.addObjectByDataType(21, 5);
this.dataWatcher.addObject(22, String.valueOf(""));//particle
this.dataWatcher.addObject(23, Integer.valueOf(5));//size
2025-03-13 17:14:45 -04:00
this.dataWatcher.addObject(24, Byte.valueOf((byte) 0));//glows
2018-09-13 12:03:28 -04:00
this.dataWatcher.addObject(25, Integer.valueOf(10));//velocity
2025-03-13 17:14:45 -04:00
this.dataWatcher.addObject(26, Byte.valueOf((byte) 0));//gravity
this.dataWatcher.addObject(27, Byte.valueOf((byte) 0));//Arrow
this.dataWatcher.addObject(28, Byte.valueOf((byte) 0));//3D
this.dataWatcher.addObject(29, Byte.valueOf((byte) 0));//Rotating
this.dataWatcher.addObject(30, Byte.valueOf((byte) 0));//Sticks
this.dataWatcher.addObject(31, Byte.valueOf((byte) 0));//FakeExplosion
2018-09-13 12:03:28 -04:00
}
@SideOnly(Side.CLIENT)
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
/**
* Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
* length * 64 * renderDistanceWeight Args: distance
*/
2025-03-13 17:14:45 -04:00
public boolean isInRangeToRenderDist(double par1) {
2018-09-13 12:03:28 -04:00
double d1 = this.boundingBox.getAverageEdgeLength() * 4.0D;
d1 *= 64.0D;
return par1 < d1 * d1;
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
public EntityProjectile(World par1World, EntityLivingBase par2EntityLiving, ItemStack item, boolean isNPC) {
2018-09-13 12:03:28 -04:00
super(par1World);
this.thrower = par2EntityLiving;
2025-03-13 17:14:45 -04:00
if (this.thrower != null)
this.throwerName = this.thrower.getUniqueID().toString();
2018-09-13 12:03:28 -04:00
setThrownItem(item);
this.dataWatcher.updateObject(27, Byte.valueOf((byte) ((this.getItem() == Items.arrow) ? 1 : 0)));
2025-03-13 17:14:45 -04:00
this.setSize(this.dataWatcher.getWatchableObjectInt(23) / 10, this.dataWatcher.getWatchableObjectInt(23) / 10);
this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight(), par2EntityLiving.posZ, par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch);
this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.1F);
2018-09-13 12:03:28 -04:00
this.posY -= 0.1f;
2025-03-13 17:14:45 -04:00
this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.1F);
2018-09-13 12:03:28 -04:00
this.setPosition(this.posX, this.posY, this.posZ);
this.yOffset = 0.0F;
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
if (isNPC) {
2025-03-13 17:14:45 -04:00
this.npc = (EntityNPCInterface) this.thrower;
this.getStatProperties(this.npc.stats);
this.destroyTerrain = !this.npc.stats.projectilesKeepTerrain;
2018-09-13 12:03:28 -04:00
}
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
public void setThrownItem(ItemStack item) {
2018-09-13 12:03:28 -04:00
dataWatcher.updateObject(21, item);
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
/**
* Par: X, Y, Z, Angle, Accuracy
*/
@Override
2025-03-13 17:14:45 -04:00
public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) {
2018-09-13 12:03:28 -04:00
float f2 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5);
float f3 = MathHelper.sqrt_double(par1 * par1 + par5 * par5);
2025-03-13 17:14:45 -04:00
float yaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI);
float pitch = this.hasGravity() ? par7 : (float) (Math.atan2(par3, (double) f3) * 180.0D / Math.PI);
2018-09-13 12:03:28 -04:00
this.prevRotationYaw = this.rotationYaw = yaw;
this.prevRotationPitch = this.rotationPitch = pitch;
2025-03-13 17:14:45 -04:00
this.motionX = (double) (MathHelper.sin(yaw / 180.0F * (float) Math.PI) * MathHelper.cos(pitch / 180.0F * (float) Math.PI));
this.motionZ = (double) (MathHelper.cos(yaw / 180.0F * (float) Math.PI) * MathHelper.cos(pitch / 180.0F * (float) Math.PI));
this.motionY = (double) (MathHelper.sin((pitch + 1.0F) / 180.0F * (float) Math.PI));
this.motionX += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8;
this.motionZ += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8;
this.motionY += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8;
2018-09-13 12:03:28 -04:00
this.motionX *= this.getSpeed();
this.motionZ *= this.getSpeed();
this.motionY *= this.getSpeed();
this.accelerationX = par1 / f2 * 0.1D;
this.accelerationY = par3 / f2 * 0.1D;
this.accelerationZ = par5 / f2 * 0.1D;
this.ticksInGround = 0;
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
/**
* get an angle for firing at coordinates XYZ
* Par: X Distance, Y Distance, Z Distance, Horizontial Distance
*/
public float getAngleForXYZ(double varX, double varY, double varZ, double horiDist, boolean arc) {
2025-03-13 17:14:45 -04:00
float g = this.getGravityVelocity();
float var1 = this.getSpeed() * this.getSpeed();
double var2 = (g * horiDist);
double var3 = ((g * horiDist * horiDist) + (2 * varY * var1));
double var4 = (var1 * var1) - (g * var3);
if (var4 < 0) return 30.0F;
float var6 = arc ? var1 + MathHelper.sqrt_double(var4) : var1 - MathHelper.sqrt_double(var4);
float var7 = (float) (Math.atan2(var6, var2) * 180.0D / Math.PI);
return var7;
}
public void shoot(float speed) {
double varX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI));
double varZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI));
double varY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI));
2018-09-13 12:03:28 -04:00
this.setThrowableHeading(varX, varY, varZ, -rotationPitch, speed);
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
@SideOnly(Side.CLIENT)
/**
* Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
* posY, posZ, yaw, pitch
*/
2025-03-13 17:14:45 -04:00
public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) {
if (worldObj.isRemote && inGround)
return;
2018-09-13 12:03:28 -04:00
this.setPosition(par1, par3, par5);
this.setRotation(par7, par8);
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
@Override
2025-03-13 17:14:45 -04:00
public void onUpdate() {
2018-09-13 12:03:28 -04:00
super.onEntityUpdate();
2025-03-13 17:14:45 -04:00
if (ticksExisted >= 1200) {
this.setDead();
}
if (++ticksExisted % 10 == 0) {
EventHooks.onProjectileTick(this);
}
if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) {
2018-09-13 12:03:28 -04:00
float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
2025-03-13 17:14:45 -04:00
this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(this.motionY, (double) f) * 180.0D / Math.PI);
2018-09-13 12:03:28 -04:00
if (this.isRotating()) {
2025-03-13 17:14:45 -04:00
this.rotationPitch -= 20;
2018-09-13 12:03:28 -04:00
}
}
2025-03-19 17:46:12 -04:00
if (this.effect == EnumPotionType.Fire && !this.inGround && this.burnItem)
2025-03-13 17:14:45 -04:00
this.setFire(1);
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
Block block = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile);
2025-03-13 17:14:45 -04:00
if ((this.isArrow() || this.sticksToWalls()) && block != null) {
2018-09-13 12:03:28 -04:00
block.setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile);
AxisAlignedBB axisalignedbb = block.getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, this.yTile, this.zTile);
2025-03-13 17:14:45 -04:00
if (axisalignedbb != null && axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) {
2018-09-13 12:03:28 -04:00
this.inGround = true;
}
}
2025-03-13 17:14:45 -04:00
if (this.arrowShake > 0) {
2018-09-13 12:03:28 -04:00
--this.arrowShake;
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
if (this.inGround) {
2018-09-13 12:03:28 -04:00
int j = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile);
2025-03-13 17:14:45 -04:00
if (block == this.inTile && j == this.inData) {
2018-09-13 12:03:28 -04:00
++this.ticksInGround;
2025-03-13 17:14:45 -04:00
if (this.ticksInGround >= 1200) {
2018-09-13 12:03:28 -04:00
this.setDead();
}
2025-03-13 17:14:45 -04:00
} else {
2018-09-13 12:03:28 -04:00
this.inGround = false;
2025-03-13 17:14:45 -04:00
this.motionX *= (double) (this.rand.nextFloat() * 0.2F);
this.motionY *= (double) (this.rand.nextFloat() * 0.2F);
this.motionZ *= (double) (this.rand.nextFloat() * 0.2F);
2018-09-13 12:03:28 -04:00
this.ticksInGround = 0;
this.ticksInAir = 0;
}
2025-03-13 17:14:45 -04:00
} else {
2018-09-13 12:03:28 -04:00
++this.ticksInAir;
2025-03-13 17:14:45 -04:00
if (this.ticksInAir >= 1200) {
2018-09-13 12:03:28 -04:00
this.setDead();
}
2025-03-13 17:14:45 -04:00
Vec3 vec3 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
Vec3 vec31 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
MovingObjectPosition movingobjectposition = this.worldObj.func_147447_a(vec3, vec31, false, true, false);//rayTraceBlocks_do_do
vec3 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ);
vec31 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
if (movingobjectposition != null) {
vec31 = Vec3.createVectorHelper(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord);
}
if (!this.worldObj.isRemote) {
Entity entity = null;
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
double d0 = 0.0D;
EntityLivingBase entityliving = this.getThrower();
for (int k = 0; k < list.size(); ++k) {
Entity entity1 = (Entity) list.get(k);
if (entity1.canBeCollidedWith() && (!entity1.isEntityEqual(this.thrower) || this.ticksInAir >= 25)) {
float f = 0.3F;
AxisAlignedBB axisalignedbb = entity1.boundingBox.expand((double) f, (double) f, (double) f);
MovingObjectPosition movingobjectposition1 = axisalignedbb.calculateIntercept(vec3, vec31);
if (movingobjectposition1 != null) {
double d1 = vec3.distanceTo(movingobjectposition1.hitVec);
if (d1 < d0 || d0 == 0.0D) {
entity = entity1;
d0 = d1;
}
}
}
}
if (entity != null) {
movingobjectposition = new MovingObjectPosition(entity);
}
if (npc != null && movingobjectposition != null && movingobjectposition.entityHit != null && movingobjectposition.entityHit instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) movingobjectposition.entityHit;
if (this.npc.faction.isFriendlyToPlayer(entityplayer)) {
movingobjectposition = null;
}
}
}
if (movingobjectposition != null) {
if (movingobjectposition.typeOfHit == MovingObjectType.BLOCK && this.worldObj.getBlock(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ) == Blocks.portal) {
this.setInPortal();
} else {
this.dataWatcher.updateObject(29, Byte.valueOf((byte) 0));
this.onImpact(movingobjectposition);
}
}
this.posX += this.motionX;
this.posY += this.motionY;
this.posZ += this.motionZ;
float f1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) f1) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) {
;
}
while (this.rotationPitch - this.prevRotationPitch >= 180.0F) {
this.prevRotationPitch += 360.0F;
}
while (this.rotationYaw - this.prevRotationYaw < -180.0F) {
this.prevRotationYaw -= 360.0F;
}
while (this.rotationYaw - this.prevRotationYaw >= 180.0F) {
this.prevRotationYaw += 360.0F;
}
float f = this.isArrow() ? 0.0F : 225.0F;
this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) + f * 0.2F;
this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
if (this.isRotating()) {
int spin = isBlock() ? 10 : 20;
this.rotationPitch -= (this.ticksInAir % 15) * spin * getSpeed();
}
float f2 = this.getMotionFactor();
float f3 = this.getGravityVelocity();
if (this.isInWater()) {
if (worldObj.isRemote) {
for (int k = 0; k < 4; ++k) {
float f4 = 0.25F;
this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) f4, this.posY - this.motionY * (double) f4, this.posZ - this.motionZ * (double) f4, this.motionX, this.motionY, this.motionZ);
}
}
f2 = 0.8F;
}
this.motionX *= (double) f2;
this.motionY *= (double) f2;
this.motionZ *= (double) f2;
if (hasGravity())
this.motionY -= (double) f3;
if (accelerate) {
this.motionX += this.accelerationX;
this.motionY += this.accelerationY;
this.motionZ += this.accelerationZ;
}
if (worldObj.isRemote && !this.dataWatcher.getWatchableObjectString(22).isEmpty()) {
2025-03-19 00:57:41 -04:00
String particle = this.dataWatcher.getWatchableObjectString(22);
2025-05-20 13:53:26 -04:00
if (!particle.equals("custom")) {
2025-03-19 00:57:41 -04:00
this.worldObj.spawnParticle(particle, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
}
2025-05-20 13:53:26 -04:00
} else if (!worldObj.isRemote) {
if (this.npc != null && this.npc.stats.pTrail == EnumParticleType.Custom) {
this.npc.stats.pCustom.setPosition(this.posX, this.posY, this.posZ);
spawnScriptedParticle(this.npc.stats.pCustom.writeToNBT(), this.npc);
2025-03-19 00:57:41 -04:00
}
2025-03-13 17:14:45 -04:00
}
this.setPosition(this.posX, this.posY, this.posZ);
this.func_145775_I();//doBlockCollisions
2018-09-13 12:03:28 -04:00
}
}
2025-03-13 17:14:45 -04:00
public static void spawnScriptedParticle(NBTTagCompound compound, EntityNPCInterface entity) {
PacketHandler.Instance.sendTracking(new ScriptedParticlePacket(compound), entity);
}
2025-03-13 17:14:45 -04:00
public boolean isBlock() {
ItemStack item = this.getItemDisplay();
if (item == null)
return false;
return item.getItem() instanceof ItemBlock;
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
private Item getItem() {
ItemStack item = this.getItemDisplay();
if (item == null)
return null;
return item.getItem();
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
protected float getMotionFactor() {
2018-09-13 12:03:28 -04:00
return accelerate ? 0.95F : 1.0F;
}
/**
* Called when this EntityThrowable hits a block or entity.
*/
@Override
2025-03-13 17:14:45 -04:00
protected void onImpact(MovingObjectPosition movingobjectposition) {
if (!this.worldObj.isRemote) {
ProjectileEvent.ImpactEvent event;
if (movingobjectposition.entityHit != null) {
IEntity target = NpcAPI.Instance().getIEntity(movingobjectposition.entityHit);
event = new ProjectileEvent.ImpactEvent((IProjectile) NpcAPI.Instance().getIEntity(this), 0, target);
} else {
IPos pos = NpcAPI.Instance().getIPos(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ);
IWorld world = NpcAPI.Instance().getIWorld(this.worldObj);
event = new ProjectileEvent.ImpactEvent((IProjectile) NpcAPI.Instance().getIEntity(this), 1, NpcAPI.Instance().getIBlock(world, pos));
}
if (movingobjectposition.entityHit != null) {
if (callback != null && callbackItem != null && movingobjectposition.entityHit instanceof EntityLivingBase && callback.onImpact(this, (EntityLivingBase) movingobjectposition.entityHit, callbackItem)) {
return;
}
}
EventHooks.onProjectileImpact(this, event);
}
if (movingobjectposition.entityHit != null) {
float damage = this.damage;
if (damage == 0)
damage = 0.001f;
2018-09-13 12:03:28 -04:00
2024-04-09 20:35:53 -04:00
boolean didDBCAttack = false;
2025-03-13 17:14:45 -04:00
if (npc != null) {
if (DBCAddon.instance.canDBCAttack(npc, this.damage, movingobjectposition.entityHit)) {
2024-04-09 20:35:53 -04:00
damage = 0.001f;
didDBCAttack = true;
}
}
2025-03-13 17:14:45 -04:00
if (movingobjectposition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), damage)) {
if (didDBCAttack)
DBCAddon.instance.doDBCDamage(npc, this.damage, movingobjectposition.entityHit);
if (movingobjectposition.entityHit instanceof EntityLivingBase && (this.isArrow() || this.sticksToWalls())) {
EntityLivingBase entityliving = (EntityLivingBase) movingobjectposition.entityHit;
if (!this.worldObj.isRemote) {
entityliving.setArrowCountInEntity(entityliving.getArrowCountInEntity() + 1);
}
if (destroyedOnEntityHit && !(movingobjectposition.entityHit instanceof EntityEnderman)) {
2018-09-13 12:03:28 -04:00
this.setDead();
}
2025-03-13 17:14:45 -04:00
}
if (this.isBlock()) {
this.worldObj.playAuxSFX(2001, (int) movingobjectposition.entityHit.posX, (int) movingobjectposition.entityHit.posY, (int) movingobjectposition.entityHit.posZ, Item.getIdFromItem(getItem()));
} else if (!this.isArrow() && !this.sticksToWalls()) {
for (int i = 0; i < 8; ++i) {
this.worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(getItem()), this.posX, this.posY, this.posZ, this.rand.nextGaussian() * 0.15D, this.rand.nextGaussian() * 0.2D, this.rand.nextGaussian() * 0.15D);
}
}
if (this.punch > 0) {
float f3 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
if (f3 > 0.0F) {
movingobjectposition.entityHit.addVelocity(this.motionX * (double) this.punch * 0.6000000238418579D / (double) f3, 0.1D, this.motionZ * (double) this.punch * 0.6000000238418579D / (double) f3);
}
}
if (this.effect != EnumPotionType.None && movingobjectposition.entityHit instanceof EntityLivingBase) {
if (this.effect != EnumPotionType.Fire) {
int p = this.getPotionEffect(effect);
((EntityLivingBase) movingobjectposition.entityHit).addPotionEffect(new PotionEffect(p, this.duration * 20, this.amplify));
} else {
movingobjectposition.entityHit.setFire(duration);
}
}
} else if (this.hasGravity() && (this.isArrow() || this.sticksToWalls())) {
this.motionX *= -0.10000000149011612D;
2018-09-13 12:03:28 -04:00
this.motionY *= -0.10000000149011612D;
this.motionZ *= -0.10000000149011612D;
this.rotationYaw += 180.0F;
this.prevRotationYaw += 180.0F;
this.ticksInAir = 0;
}
2025-03-13 17:14:45 -04:00
} else {
if (this.isArrow() || this.sticksToWalls()) {
2018-09-13 12:03:28 -04:00
// if (this.sticksToWalls()) {
// float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
// float f1 = this.isArrow() ? 0.0F :this.isRotating() ? 180.0F : 225.0F;
// this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(this.motionY, (double)f) * 180.0D / Math.PI) + f1;
// }
2025-03-13 17:14:45 -04:00
this.xTile = movingobjectposition.blockX;
this.yTile = movingobjectposition.blockY;
this.zTile = movingobjectposition.blockZ;
this.inTile = this.worldObj.getBlock(this.xTile, this.yTile, this.zTile);
this.inData = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile);
this.motionX = (double) ((float) (movingobjectposition.hitVec.xCoord - this.posX));
this.motionY = (double) ((float) (movingobjectposition.hitVec.yCoord - this.posY));
this.motionZ = (double) ((float) (movingobjectposition.hitVec.zCoord - this.posZ));
float f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
this.posX -= this.motionX / (double) f2 * 0.05000000074505806D;
this.posY -= this.motionY / (double) f2 * 0.05000000074505806D;
this.posZ -= this.motionZ / (double) f2 * 0.05000000074505806D;
this.inGround = true;
if (this.isArrow())
this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
else
this.playSound("random.break", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
this.arrowShake = 7;
if (!this.hasGravity()) {
this.dataWatcher.updateObject(26, Byte.valueOf((byte) 1));
}
if (this.inTile != null) {//onEntityCollidedWithBlock
inTile.onEntityCollidedWithBlock(this.worldObj, this.xTile, this.yTile, this.zTile, this);
}
} else {
if (this.isBlock()) {
this.worldObj.playAuxSFX(2001, MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ), Item.getIdFromItem(getItem()));
} else {
for (int i = 0; i < 8; ++i) {
this.worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(getItem()), this.posX, this.posY, this.posZ, this.rand.nextGaussian() * 0.15D, this.rand.nextGaussian() * 0.2D, this.rand.nextGaussian() * 0.15D);
}
}
}
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
if (explosive) {
if (this.explosiveRadius != 0 || this.effect == EnumPotionType.None) {
boolean terraindamage = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing") && explosiveDamage && destroyTerrain;
Explosion explosion = new Explosion(worldObj, this, posX, posY, posZ, explosiveRadius);
explosion.isFlaming = this.effect == EnumPotionType.Fire;
explosion.isSmoking = terraindamage;
if (terraindamage)
explosion.doExplosionA();
explosion.doExplosionB(worldObj.isRemote);
//this.worldObj.newExplosion(null, this.posX, this.posY, this.posZ, this.explosiveRadius, this.effect == EnumPotionType.Fire, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing") && explosiveDamage);
if (!worldObj.isRemote) {
Iterator iterator = worldObj.playerEntities.iterator();
while (iterator.hasNext()) {
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
if (entityplayer.getDistanceSq(posX, posY, posZ) < 4096.0D) {
((EntityPlayerMP) entityplayer).playerNetServerHandler.sendPacket(new S27PacketExplosion(posX, posY, posZ, explosiveRadius, explosion.affectedBlockPositions, (Vec3) explosion.func_77277_b().get(entityplayer)));
}
}
2018-09-13 12:03:28 -04:00
}
2025-03-13 17:14:45 -04:00
if (this.explosiveRadius != 0 && (this.isArrow() || this.sticksToWalls()))
this.setDead();
} else if (this.effect == EnumPotionType.Fire) {
int i = movingobjectposition.blockX;
2018-09-13 12:03:28 -04:00
int j = movingobjectposition.blockY;
int k = movingobjectposition.blockZ;
2025-03-13 17:14:45 -04:00
switch (movingobjectposition.sideHit) {
2018-09-13 12:03:28 -04:00
case 0:
--j;
break;
case 1:
++j;
break;
case 2:
--k;
break;
case 3:
++k;
break;
case 4:
--i;
break;
case 5:
++i;
}
2025-03-13 17:14:45 -04:00
if (this.worldObj.isAirBlock(i, j, k)) {
2018-09-13 12:03:28 -04:00
this.worldObj.setBlock(i, j, k, Blocks.fire);
}
2025-03-13 17:14:45 -04:00
} else {
AxisAlignedBB axisalignedbb = this.boundingBox.expand(4.0D, 2.0D, 4.0D);
List list1 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, axisalignedbb);
if (list1 != null && !list1.isEmpty()) {
Iterator iterator = list1.iterator();
while (iterator.hasNext()) {
EntityLivingBase entitylivingbase = (EntityLivingBase) iterator.next();
2018-09-13 12:03:28 -04:00
double d0 = this.getDistanceSqToEntity(entitylivingbase);
2025-03-13 17:14:45 -04:00
if (d0 < 16.0D) {
2018-09-13 12:03:28 -04:00
double d1 = 1.0D - Math.sqrt(d0) / 4.0D;
2025-03-13 17:14:45 -04:00
if (entitylivingbase == movingobjectposition.entityHit) {
2018-09-13 12:03:28 -04:00
d1 = 1.0D;
}
int i = this.getPotionEffect(effect);
2025-03-13 17:14:45 -04:00
if (Potion.potionTypes[i].isInstant()) {
2018-09-13 12:03:28 -04:00
Potion.potionTypes[i].affectEntity(this.getThrower(), entitylivingbase, this.amplify, d1);
2025-03-13 17:14:45 -04:00
} else {
int j = (int) (d1 * (double) this.duration + 0.5D);
2018-09-13 12:03:28 -04:00
2025-03-13 17:14:45 -04:00
if (j > 20) {
2018-09-13 12:03:28 -04:00
entitylivingbase.addPotionEffect(new PotionEffect(i, j, this.amplify));
}
}
}
}
}
2025-03-13 17:14:45 -04:00
this.worldObj.playAuxSFX(2002, (int) Math.round(this.posX), (int) Math.round(this.posY), (int) Math.round(this.posZ), this.getPotionColor(this.effect));
}
}
2018-09-13 12:03:28 -04:00
2025-03-13 17:14:45 -04:00
if (!this.worldObj.isRemote && !this.isArrow() && !this.sticksToWalls()) {
2018-09-13 12:03:28 -04:00
this.setDead();
}
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {
par1NBTTagCompound.setShort("xTile", (short) this.xTile);
par1NBTTagCompound.setShort("yTile", (short) this.yTile);
par1NBTTagCompound.setShort("zTile", (short) this.zTile);
par1NBTTagCompound.setByte("inTile", (byte) Block.getIdFromBlock(this.inTile));
par1NBTTagCompound.setByte("inData", (byte) this.inData);
par1NBTTagCompound.setByte("shake", (byte) this.throwableShake);
par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0));
par1NBTTagCompound.setByte("isArrow", (byte) (this.isArrow() ? 1 : 0));
par1NBTTagCompound.setTag("direction", this.newDoubleNBTList(new double[]{this.motionX, this.motionY, this.motionZ}));
2018-09-13 12:03:28 -04:00
par1NBTTagCompound.setBoolean("canBePickedUp", canBePickedUp);
2025-03-13 17:14:45 -04:00
if ((this.throwerName == null || this.throwerName.length() == 0) && this.thrower != null && this.thrower instanceof EntityPlayer) {
2018-09-13 12:03:28 -04:00
this.throwerName = this.thrower.getUniqueID().toString();
}
par1NBTTagCompound.setString("ownerName", this.throwerName == null ? "" : this.throwerName);
2025-03-13 17:14:45 -04:00
if (this.getItemDisplay() != null) {
2018-09-13 12:03:28 -04:00
par1NBTTagCompound.setTag("Item", this.getItemDisplay().writeToNBT(new NBTTagCompound()));
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
par1NBTTagCompound.setFloat("damagev2", damage);
2025-03-13 17:14:45 -04:00
par1NBTTagCompound.setInteger("punch", punch);
par1NBTTagCompound.setInteger("size", this.dataWatcher.getWatchableObjectInt(23));
par1NBTTagCompound.setInteger("velocity", this.dataWatcher.getWatchableObjectInt(25));
par1NBTTagCompound.setInteger("explosiveRadius", explosiveRadius);
par1NBTTagCompound.setInteger("effectDuration", duration);
par1NBTTagCompound.setBoolean("gravity", this.hasGravity());
par1NBTTagCompound.setBoolean("accelerate", this.accelerate);
par1NBTTagCompound.setByte("glows", this.dataWatcher.getWatchableObjectByte(24));
par1NBTTagCompound.setBoolean("explosive", explosive);
par1NBTTagCompound.setInteger("accuracy", accuracy);
par1NBTTagCompound.setInteger("PotionEffect", effect.ordinal());
par1NBTTagCompound.setString("trail", this.dataWatcher.getWatchableObjectString(22));
par1NBTTagCompound.setByte("Render3D", this.dataWatcher.getWatchableObjectByte(28));
par1NBTTagCompound.setByte("Spins", this.dataWatcher.getWatchableObjectByte(29));
par1NBTTagCompound.setByte("Sticks", this.dataWatcher.getWatchableObjectByte(30));
par1NBTTagCompound.setByte("trailCustom", this.dataWatcher.getWatchableObjectByte(31));
2018-09-13 12:03:28 -04:00
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
2025-03-13 17:14:45 -04:00
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {
2018-09-13 12:03:28 -04:00
this.xTile = par1NBTTagCompound.getShort("xTile");
this.yTile = par1NBTTagCompound.getShort("yTile");
this.zTile = par1NBTTagCompound.getShort("zTile");
this.inTile = Block.getBlockById(par1NBTTagCompound.getByte("inTile") & 255);
this.inData = par1NBTTagCompound.getByte("inData") & 255;
this.throwableShake = par1NBTTagCompound.getByte("shake") & 255;
this.inGround = par1NBTTagCompound.getByte("inGround") == 1;
this.dataWatcher.updateObject(27, par1NBTTagCompound.getByte("isArrow"));
this.throwerName = par1NBTTagCompound.getString("ownerName");
this.canBePickedUp = par1NBTTagCompound.getBoolean("canBePickedUp");
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
this.damage = par1NBTTagCompound.getFloat("damagev2");
2025-03-13 17:14:45 -04:00
this.punch = par1NBTTagCompound.getInteger("punch");
this.explosiveRadius = par1NBTTagCompound.getInteger("explosiveRadius");
this.duration = par1NBTTagCompound.getInteger("effectDuration");
this.accelerate = par1NBTTagCompound.getBoolean("accelerate");
this.explosive = par1NBTTagCompound.getBoolean("explosive");
this.accuracy = par1NBTTagCompound.getInteger("accuracy");
this.effect = EnumPotionType.values()[par1NBTTagCompound.getInteger("PotionEffect") % EnumPotionType.values().length];
2018-09-13 12:03:28 -04:00
this.dataWatcher.updateObject(22, par1NBTTagCompound.getString("trail"));
2025-03-13 17:14:45 -04:00
this.dataWatcher.updateObject(23, Integer.valueOf(par1NBTTagCompound.getInteger("size")));
this.dataWatcher.updateObject(24, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("glows") ? 1 : 0)));
this.dataWatcher.updateObject(25, Integer.valueOf(par1NBTTagCompound.getInteger("velocity")));
this.dataWatcher.updateObject(26, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("gravity") ? 1 : 0)));
this.dataWatcher.updateObject(28, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("Render3D") ? 1 : 0)));
this.dataWatcher.updateObject(29, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("Spins") ? 1 : 0)));
this.dataWatcher.updateObject(30, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("Sticks") ? 1 : 0)));
this.dataWatcher.updateObject(31, par1NBTTagCompound.getString("trailCustom"));
2025-03-13 17:14:45 -04:00
if (this.throwerName != null && this.throwerName.length() == 0) {
2018-09-13 12:03:28 -04:00
this.throwerName = null;
}
2025-03-13 17:14:45 -04:00
if (par1NBTTagCompound.hasKey("direction")) {
NBTTagList nbttaglist = par1NBTTagCompound.getTagList("direction", 6);
2018-09-13 12:03:28 -04:00
this.motionX = nbttaglist.func_150309_d(0);
this.motionY = nbttaglist.func_150309_d(1);
this.motionZ = nbttaglist.func_150309_d(2);
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Item");
ItemStack item = ItemStack.loadItemStackFromNBT(var2);
if (item == null)
this.setDead();
else
2025-03-13 17:14:45 -04:00
dataWatcher.updateObject(21, item);
2018-09-13 12:03:28 -04:00
}
@Override
2025-03-13 17:14:45 -04:00
public EntityLivingBase getThrower() {
if (throwerName == null || throwerName.isEmpty())
return null;
try {
UUID uuid = UUID.fromString(throwerName);
if (this.thrower == null && uuid != null)
this.thrower = this.worldObj.func_152378_a(uuid);
} catch (IllegalArgumentException ex) {
}
2018-09-13 12:03:28 -04:00
return this.thrower;
}
2024-02-15 17:54:28 -05:00
2025-03-13 17:14:45 -04:00
private int getPotionEffect(EnumPotionType p) {
switch (p) {
case Poison:
return Potion.poison.id;
case Hunger:
return Potion.hunger.id;
case Weakness:
return Potion.weakness.id;
case Slowness:
return Potion.moveSlowdown.id;
case Nausea:
return Potion.confusion.id;
case Blindness:
return Potion.blindness.id;
case Wither:
return Potion.wither.id;
default:
return 0;
}
}
private int getPotionColor(EnumPotionType p) {
switch (p) {
case Poison:
return 32660;
case Hunger:
return 32660;
case Weakness:
return 32696;
case Slowness:
return 32698;
case Nausea:
return 32732;
case Blindness:
return Potion.blindness.id;
case Wither:
return 32732;
default:
return 0;
}
}
public void getStatProperties(DataStats stats) {
this.damage = stats.pDamage;
this.punch = stats.pImpact;
this.accelerate = stats.pXlr8;
this.explosive = stats.pExplode;
this.explosiveRadius = stats.pArea;
this.effect = stats.pEffect;
2025-03-19 17:46:12 -04:00
this.burnItem = stats.pBurnItem;
2025-03-13 17:14:45 -04:00
this.duration = stats.pDur;
this.amplify = stats.pEffAmp;
this.setParticleEffect(stats.pTrail);
this.dataWatcher.updateObject(23, Integer.valueOf(stats.pSize));
this.dataWatcher.updateObject(24, Byte.valueOf((byte) (stats.pGlows ? 1 : 0)));
this.setSpeed(stats.pSpeed);
this.setHasGravity(stats.pPhysics);
setIs3D(stats.pRender3D);
this.setRotating(stats.pSpin);
this.setStickInWall(stats.pStick);
}
public void setParticleEffect(EnumParticleType type) {
this.dataWatcher.updateObject(22, type.particleName);
}
public void setCustomParticle(ScriptParticle particle) {
}
2025-03-13 17:14:45 -04:00
public void setHasGravity(boolean bo) {
this.dataWatcher.updateObject(26, Byte.valueOf((byte) (bo ? 1 : 0)));
}
public void setIs3D(boolean bo) {
this.dataWatcher.updateObject(28, Byte.valueOf((byte) (bo ? 1 : 0)));
}
public void setStickInWall(boolean bo) {
this.dataWatcher.updateObject(30, Byte.valueOf((byte) (bo ? 1 : 0)));
}
public ItemStack getItemDisplay() {
return dataWatcher.getWatchableObjectItemStack(21);
}
public float getBrightness(float par1) {
2018-09-13 12:03:28 -04:00
return this.dataWatcher.getWatchableObjectByte(24) == 1 ? 1.0F : super.getBrightness(par1);
}
@SideOnly(Side.CLIENT)
2025-03-13 17:14:45 -04:00
public int getBrightnessForRender(float par1) {
2018-09-13 12:03:28 -04:00
return this.dataWatcher.getWatchableObjectByte(24) == 1 ? 15728880 : super.getBrightnessForRender(par1);
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean hasGravity() {
2025-03-13 17:14:45 -04:00
return this.dataWatcher.getWatchableObjectByte(26) == 1;
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public void setSpeed(int speed) {
2025-03-13 17:14:45 -04:00
this.dataWatcher.updateObject(25, speed);
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public float getSpeed() {
2025-03-13 17:14:45 -04:00
return this.dataWatcher.getWatchableObjectInt(25) / 10.0F;
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean isArrow() {
2025-03-13 17:14:45 -04:00
return this.dataWatcher.getWatchableObjectByte(27) == 1;
2018-09-13 12:03:28 -04:00
}
2025-03-13 17:14:45 -04:00
public void setRotating(boolean bo) {
dataWatcher.updateObject(29, Byte.valueOf((byte) (bo ? 1 : 0)));
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean isRotating() {
2025-03-13 17:14:45 -04:00
return this.dataWatcher.getWatchableObjectByte(29) == 1;
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean glows() {
2025-03-13 17:14:45 -04:00
return this.dataWatcher.getWatchableObjectByte(24) == 1;
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean is3D() {
2025-03-13 17:14:45 -04:00
return this.dataWatcher.getWatchableObjectByte(28) == 1 || isBlock();
2018-09-13 12:03:28 -04:00
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
public boolean sticksToWalls() {
2025-03-13 17:14:45 -04:00
return this.is3D() && this.dataWatcher.getWatchableObjectByte(30) == 1;
2018-09-13 12:03:28 -04:00
}
@Override
2025-03-13 17:14:45 -04:00
public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) {
2018-09-13 12:03:28 -04:00
if (this.worldObj.isRemote || !canBePickedUp || !this.inGround || this.arrowShake > 0)
2025-03-13 17:14:45 -04:00
return;
if (par1EntityPlayer.inventory.addItemStackToInventory(getItemDisplay())) {
inGround = false;
2018-09-13 12:03:28 -04:00
this.playSound("random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F);
par1EntityPlayer.onItemPickup(this, 1);
this.setDead();
}
2024-02-15 17:54:28 -05:00
2018-09-13 12:03:28 -04:00
}
@Override
2025-03-13 17:14:45 -04:00
protected boolean canTriggerWalking() {
2018-09-13 12:03:28 -04:00
return false;
}
@Override
2025-03-13 17:14:45 -04:00
public IChatComponent func_145748_c_() {
if (getItemDisplay() != null)
return new ChatComponentTranslation(getItemDisplay().getDisplayName());
return super.func_145748_c_();
2018-09-13 12:03:28 -04:00
}
}