forked from xjboss/KCauldronX
783 lines
33 KiB
Diff
783 lines
33 KiB
Diff
--- ../src-base/minecraft/net/minecraft/entity/Entity.java
|
|
+++ ../src-work/minecraft/net/minecraft/entity/Entity.java
|
|
@@ -45,13 +45,51 @@
|
|
import net.minecraft.world.Explosion;
|
|
import net.minecraft.world.World;
|
|
import net.minecraft.world.WorldServer;
|
|
+import net.minecraftforge.cauldron.CauldronHooks;
|
|
import net.minecraftforge.common.IExtendedEntityProperties;
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import net.minecraftforge.event.entity.EntityEvent;
|
|
import net.minecraftforge.fluids.IFluidBlock;
|
|
|
|
+// CraftBukkit start
|
|
+import net.minecraft.entity.passive.EntityTameable;
|
|
+import net.minecraft.entity.player.EntityPlayerMP;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.Server;
|
|
+import org.bukkit.TravelAgent;
|
|
+import org.bukkit.block.BlockFace;
|
|
+import org.bukkit.entity.Hanging;
|
|
+import org.bukkit.entity.LivingEntity;
|
|
+import org.bukkit.entity.Painting;
|
|
+import org.bukkit.entity.Vehicle;
|
|
+import org.spigotmc.CustomTimingsHandler; // Spigot
|
|
+import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
|
+import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
|
+import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
|
|
+import org.bukkit.event.vehicle.VehicleEnterEvent;
|
|
+import org.bukkit.event.vehicle.VehicleExitEvent;
|
|
+import org.bukkit.craftbukkit.CraftWorld;
|
|
+import org.bukkit.craftbukkit.entity.CraftEntity;
|
|
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
+import org.bukkit.event.entity.EntityCombustEvent;
|
|
+import org.bukkit.event.entity.EntityPortalEvent;
|
|
+import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
|
+import org.bukkit.plugin.PluginManager;
|
|
+// CraftBukkit end
|
|
+import net.minecraft.world.Teleporter; // Cauldron
|
|
+
|
|
public abstract class Entity
|
|
{
|
|
+ // CraftBukkit start
|
|
+ private static final int CURRENT_LEVEL = 2;
|
|
+ static boolean isLevelAtLeast(NBTTagCompound tag, int level)
|
|
+ {
|
|
+ return tag.hasKey("Bukkit.updateLevel") && tag.getInteger("Bukkit.updateLevel") >= level;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
private static int nextEntityID;
|
|
private int entityId;
|
|
public double renderDistanceWeight;
|
|
@@ -100,12 +138,12 @@
|
|
protected Random rand;
|
|
public int ticksExisted;
|
|
public int fireResistance;
|
|
- private int fire;
|
|
- protected boolean inWater;
|
|
+ public int fire; // CraftBukkit - private -> public
|
|
+ public boolean inWater; // Spigot - protected -> public
|
|
public int hurtResistantTime;
|
|
private boolean firstUpdate;
|
|
protected boolean isImmuneToFire;
|
|
- protected DataWatcher dataWatcher;
|
|
+ public DataWatcher dataWatcher; // CraftBukkit - protected -> public
|
|
private double entityRiderPitchDelta;
|
|
private double entityRiderYawDelta;
|
|
public boolean addedToChunk;
|
|
@@ -126,8 +164,10 @@
|
|
public int dimension;
|
|
protected int teleportDirection;
|
|
private boolean invulnerable;
|
|
- protected UUID entityUniqueID;
|
|
+ public UUID entityUniqueID; // CraftBukkit - protected -> public
|
|
public Entity.EnumEntitySize myEntitySize;
|
|
+ public boolean valid; // CraftBukkit
|
|
+ public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
|
|
private static final String __OBFID = "CL_00001533";
|
|
/** Forge: Used to store custom data for each entity. */
|
|
private NBTTagCompound customEntityData;
|
|
@@ -135,7 +175,16 @@
|
|
public ArrayList<EntityItem> capturedDrops = new ArrayList<EntityItem>();
|
|
private UUID persistentID;
|
|
|
|
+ // Spigot start
|
|
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
|
|
+ public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
|
|
+ public final boolean defaultActivationState;
|
|
+ public long activatedTick = 0;
|
|
+ public boolean fromMobSpawner;
|
|
+ public void inactiveTick() { }
|
|
+ // Spigot end
|
|
protected HashMap<String, IExtendedEntityProperties> extendedProperties;
|
|
+ public String spawnReason; // Cauldron - used to handle CraftBukkit's SpawnReason with CustomSpawners
|
|
|
|
public int getEntityId()
|
|
{
|
|
@@ -159,7 +208,7 @@
|
|
this.rand = new Random();
|
|
this.fireResistance = 1;
|
|
this.firstUpdate = true;
|
|
- this.entityUniqueID = UUID.randomUUID();
|
|
+ this.entityUniqueID = new UUID(rand.nextLong(), rand.nextLong()); // Spigot
|
|
this.myEntitySize = Entity.EnumEntitySize.SIZE_2;
|
|
this.worldObj = p_i1582_1_;
|
|
this.setPosition(0.0D, 0.0D, 0.0D);
|
|
@@ -167,8 +216,15 @@
|
|
if (p_i1582_1_ != null)
|
|
{
|
|
this.dimension = p_i1582_1_.provider.dimensionId;
|
|
+ // Spigot start
|
|
+ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, p_i1582_1_.getSpigotConfig()); // Cauldron
|
|
}
|
|
+ else
|
|
+ {
|
|
+ this.defaultActivationState = false;
|
|
+ }
|
|
|
|
+ // Spigot end
|
|
this.dataWatcher = new DataWatcher(this);
|
|
this.dataWatcher.addObject(0, Byte.valueOf((byte)0));
|
|
this.dataWatcher.addObject(1, Short.valueOf((short)300));
|
|
@@ -277,6 +333,41 @@
|
|
|
|
protected void setRotation(float p_70101_1_, float p_70101_2_)
|
|
{
|
|
+ // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0
|
|
+ if (Float.isNaN(p_70101_1_))
|
|
+ {
|
|
+ p_70101_1_ = 0;
|
|
+ }
|
|
+
|
|
+ if ((p_70101_1_ == Float.POSITIVE_INFINITY) || (p_70101_1_ == Float.NEGATIVE_INFINITY))
|
|
+ {
|
|
+ if (this instanceof EntityPlayerMP)
|
|
+ {
|
|
+ this.worldObj.getServer().getLogger().warning(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid yaw");
|
|
+ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope");
|
|
+ }
|
|
+
|
|
+ p_70101_1_ = 0;
|
|
+ }
|
|
+
|
|
+ // pitch was sometimes set to NaN, so we need to set it back to 0.
|
|
+ if (Float.isNaN(p_70101_2_))
|
|
+ {
|
|
+ p_70101_2_ = 0;
|
|
+ }
|
|
+
|
|
+ if ((p_70101_2_ == Float.POSITIVE_INFINITY) || (p_70101_2_ == Float.NEGATIVE_INFINITY))
|
|
+ {
|
|
+ if (this instanceof EntityPlayerMP)
|
|
+ {
|
|
+ this.worldObj.getServer().getLogger().warning(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid pitch");
|
|
+ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope");
|
|
+ }
|
|
+
|
|
+ p_70101_2_ = 0;
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
this.rotationYaw = p_70101_1_ % 360.0F;
|
|
this.rotationPitch = p_70101_2_ % 360.0F;
|
|
}
|
|
@@ -343,7 +434,7 @@
|
|
|
|
if (this.inPortal)
|
|
{
|
|
- if (minecraftserver.getAllowNether())
|
|
+ if (true || minecraftserver.getAllowNether()) // CraftBukkit
|
|
{
|
|
if (this.ridingEntity == null && this.portalCounter++ >= i)
|
|
{
|
|
@@ -457,7 +548,35 @@
|
|
{
|
|
if (!this.isImmuneToFire)
|
|
{
|
|
- this.attackEntityFrom(DamageSource.lava, 4.0F);
|
|
+ // CraftBukkit start - Fallen in lava TODO: this event spams!
|
|
+ this.attackEntityFrom(DamageSource.lava, 4);
|
|
+
|
|
+ if (this instanceof EntityLivingBase)
|
|
+ {
|
|
+ if (this.fire <= 0)
|
|
+ {
|
|
+ // not on fire yet
|
|
+ // TODO: shouldn't be sending null for the block.
|
|
+ org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k);
|
|
+ org.bukkit.entity.Entity damagee = this.getBukkitEntity();
|
|
+ EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15);
|
|
+ this.worldObj.getServer().getPluginManager().callEvent(combustEvent);
|
|
+
|
|
+ if (!combustEvent.isCancelled())
|
|
+ {
|
|
+ this.setFire(combustEvent.getDuration());
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // This will be called every single tick the entity is in lava, so don't throw an event
|
|
+ this.setFire(15);
|
|
+ }
|
|
+
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls
|
|
this.setFire(15);
|
|
}
|
|
}
|
|
@@ -492,6 +611,30 @@
|
|
|
|
public void moveEntity(double p_70091_1_, double p_70091_3_, double p_70091_5_)
|
|
{
|
|
+ // CraftBukkit start - Don't do anything if we aren't moving
|
|
+ // We need to do this regardless of whether or not we are moving thanks to portals
|
|
+ try
|
|
+ {
|
|
+ this.func_145775_I();
|
|
+ }
|
|
+ catch (Throwable throwable)
|
|
+ {
|
|
+ CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Checking entity block collision");
|
|
+ CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being checked for collision");
|
|
+ this.addEntityCrashInfo(crashreportcategory);
|
|
+ throw new ReportedException(crashreport);
|
|
+ }
|
|
+
|
|
+ // Check if we're moving
|
|
+ if (p_70091_1_ == 0 && p_70091_3_ == 0 && p_70091_5_ == 0 && this.ridingEntity == null && this.riddenByEntity == null)
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
+ if (!CauldronHooks.checkEntitySpeed(this, p_70091_1_, p_70091_3_, p_70091_5_)) return; // Check for entities violating the speed limit
|
|
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
|
|
+
|
|
if (this.noClip)
|
|
{
|
|
this.boundingBox.offset(p_70091_1_, p_70091_3_, p_70091_5_);
|
|
@@ -756,6 +899,34 @@
|
|
d10 = this.posY - d4;
|
|
d11 = this.posZ - d5;
|
|
|
|
+ // CraftBukkit start
|
|
+ if (this.isCollidedHorizontally && this.getBukkitEntity() instanceof Vehicle && this.worldObj.getWorld() != null)
|
|
+ {
|
|
+ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
|
|
+ org.bukkit.block.Block block = this.worldObj.getWorld().getBlockAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - (double) this.yOffset), MathHelper.floor_double(this.posZ));
|
|
+
|
|
+ if (d6 > p_70091_1_)
|
|
+ {
|
|
+ block = block.getRelative(BlockFace.EAST);
|
|
+ }
|
|
+ else if (d6 < p_70091_1_)
|
|
+ {
|
|
+ block = block.getRelative(BlockFace.WEST);
|
|
+ }
|
|
+ else if (d8 > p_70091_5_)
|
|
+ {
|
|
+ block = block.getRelative(BlockFace.SOUTH);
|
|
+ }
|
|
+ else if (d8 < p_70091_5_)
|
|
+ {
|
|
+ block = block.getRelative(BlockFace.NORTH);
|
|
+ }
|
|
+
|
|
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, block);
|
|
+ this.worldObj.getServer().getPluginManager().callEvent(event);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
if (this.canTriggerWalking() && !flag && this.ridingEntity == null)
|
|
{
|
|
int j1 = MathHelper.floor_double(this.posX);
|
|
@@ -798,6 +969,8 @@
|
|
}
|
|
}
|
|
|
|
+ // CraftBukkit start - Move to the top of the method
|
|
+ /*
|
|
try
|
|
{
|
|
this.func_145775_I();
|
|
@@ -809,7 +982,8 @@
|
|
this.addEntityCrashInfo(crashreportcategory);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
-
|
|
+ */
|
|
+ // CraftBukkit end
|
|
boolean flag2 = this.isWet();
|
|
|
|
if (this.worldObj.func_147470_e(this.boundingBox.contract(0.001D, 0.001D, 0.001D)))
|
|
@@ -820,8 +994,20 @@
|
|
{
|
|
++this.fire;
|
|
|
|
- if (this.fire == 0)
|
|
+ // CraftBukkit start - Not on fire yet
|
|
+ if (this.fire <= 0) // Only throw events on the first combust, otherwise it spams
|
|
{
|
|
+ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8);
|
|
+ this.worldObj.getServer().getPluginManager().callEvent(event);
|
|
+
|
|
+ if (!event.isCancelled())
|
|
+ {
|
|
+ this.setFire(event.getDuration());
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // CraftBukkit end
|
|
this.setFire(8);
|
|
}
|
|
}
|
|
@@ -839,6 +1025,8 @@
|
|
|
|
this.worldObj.theProfiler.endSection();
|
|
}
|
|
+
|
|
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
|
|
}
|
|
|
|
protected String getSwimSound()
|
|
@@ -867,7 +1055,18 @@
|
|
|
|
try
|
|
{
|
|
- block.onEntityCollidedWithBlock(this.worldObj, k1, l1, i2, this);
|
|
+ // Cauldron start - damage hook for custom blocks
|
|
+ if (this.worldObj.getWorld() != null)
|
|
+ {
|
|
+ CraftEventFactory.blockDamage = this.worldObj.getWorld().getBlockAt(k1, l1, i2);
|
|
+ block.onEntityCollidedWithBlock(this.worldObj, k1, l1, i2, this);
|
|
+ CraftEventFactory.blockDamage = null;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ block.onEntityCollidedWithBlock(this.worldObj, k1, l1, i2, this);
|
|
+ }
|
|
+ // Cauldron end
|
|
}
|
|
catch (Throwable throwable)
|
|
{
|
|
@@ -928,6 +1127,7 @@
|
|
return null;
|
|
}
|
|
|
|
+ // Cauldron start - vanilla compatibility
|
|
protected void dealFireDamage(int p_70081_1_)
|
|
{
|
|
if (!this.isImmuneToFire)
|
|
@@ -935,7 +1135,16 @@
|
|
this.attackEntityFrom(DamageSource.inFire, (float)p_70081_1_);
|
|
}
|
|
}
|
|
+ // Cauldron end
|
|
|
|
+ protected void dealFireDamage(float par1) // CraftBukkit signature change
|
|
+ {
|
|
+ if (!this.isImmuneToFire)
|
|
+ {
|
|
+ this.attackEntityFrom(DamageSource.inFire, (float)par1);
|
|
+ }
|
|
+ }
|
|
+
|
|
public final boolean isImmuneToFire()
|
|
{
|
|
return this.isImmuneToFire;
|
|
@@ -1184,6 +1393,8 @@
|
|
|
|
public void onCollideWithPlayer(EntityPlayer p_70100_1_) {}
|
|
|
|
+ int numCollisions = 0; // Spigot
|
|
+
|
|
public void applyEntityCollision(Entity p_70108_1_)
|
|
{
|
|
if (p_70108_1_.riddenByEntity != this && p_70108_1_.ridingEntity != this)
|
|
@@ -1310,6 +1521,20 @@
|
|
{
|
|
p_70109_1_.setTag("Pos", this.newDoubleNBTList(new double[] {this.posX, this.posY + (double)this.ySize, this.posZ}));
|
|
p_70109_1_.setTag("Motion", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ}));
|
|
+
|
|
+ // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero
|
|
+ // TODO: make sure this is the best way to address this.
|
|
+ if (Float.isNaN(this.rotationYaw))
|
|
+ {
|
|
+ this.rotationYaw = 0;
|
|
+ }
|
|
+
|
|
+ if (Float.isNaN(this.rotationPitch))
|
|
+ {
|
|
+ this.rotationPitch = 0;
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
p_70109_1_.setTag("Rotation", this.newFloatNBTList(new float[] {this.rotationYaw, this.rotationPitch}));
|
|
p_70109_1_.setFloat("FallDistance", this.fallDistance);
|
|
p_70109_1_.setShort("Fire", (short)this.fire);
|
|
@@ -1320,6 +1545,12 @@
|
|
p_70109_1_.setInteger("PortalCooldown", this.timeUntilPortal);
|
|
p_70109_1_.setLong("UUIDMost", this.getUniqueID().getMostSignificantBits());
|
|
p_70109_1_.setLong("UUIDLeast", this.getUniqueID().getLeastSignificantBits());
|
|
+ // CraftBukkit start
|
|
+ p_70109_1_.setLong("WorldUUIDLeast", this.worldObj.getSaveHandler().getUUID().getLeastSignificantBits());
|
|
+ p_70109_1_.setLong("WorldUUIDMost", this.worldObj.getSaveHandler().getUUID().getMostSignificantBits());
|
|
+ p_70109_1_.setInteger("Bukkit.updateLevel", CURRENT_LEVEL);
|
|
+ p_70109_1_.setInteger("Spigot.ticksLived", this.ticksExisted);
|
|
+ // CraftBukkit end
|
|
if (customEntityData != null)
|
|
{
|
|
p_70109_1_.setTag("ForgeData", customEntityData);
|
|
@@ -1370,7 +1601,7 @@
|
|
this.motionX = nbttaglist1.func_150309_d(0);
|
|
this.motionY = nbttaglist1.func_150309_d(1);
|
|
this.motionZ = nbttaglist1.func_150309_d(2);
|
|
-
|
|
+ /* CraftBukkit start - Moved section down
|
|
if (Math.abs(this.motionX) > 10.0D)
|
|
{
|
|
this.motionX = 0.0D;
|
|
@@ -1385,7 +1616,7 @@
|
|
{
|
|
this.motionZ = 0.0D;
|
|
}
|
|
-
|
|
+ // CraftBukkit end */
|
|
this.prevPosX = this.lastTickPosX = this.posX = nbttaglist.func_150309_d(0);
|
|
this.prevPosY = this.lastTickPosY = this.posY = nbttaglist.func_150309_d(1);
|
|
this.prevPosZ = this.lastTickPosZ = this.posZ = nbttaglist.func_150309_d(2);
|
|
@@ -1436,6 +1667,76 @@
|
|
{
|
|
this.setPosition(this.posX, this.posY, this.posZ);
|
|
}
|
|
+
|
|
+ // CraftBukkit start
|
|
+ if (this instanceof EntityLivingBase)
|
|
+ {
|
|
+ EntityLivingBase entity = (EntityLivingBase) this;
|
|
+ this.ticksExisted = p_70020_1_.getInteger("Spigot.ticksLived");
|
|
+
|
|
+ // Reset the persistence for tamed animals
|
|
+ if (entity instanceof EntityTameable && !isLevelAtLeast(p_70020_1_, 2) && !p_70020_1_.getBoolean("PersistenceRequired"))
|
|
+ {
|
|
+ EntityLiving entityliving = (EntityLiving) entity;
|
|
+ entityliving.persistenceRequired = !entityliving.canDespawn();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
+
|
|
+ // CraftBukkit start - Exempt Vehicles from notch's sanity check
|
|
+ if (!(this.getBukkitEntity() instanceof Vehicle))
|
|
+ {
|
|
+ if (Math.abs(this.motionX) > 10.0D)
|
|
+ {
|
|
+ this.motionX = 0.0D;
|
|
+ }
|
|
+
|
|
+ if (Math.abs(this.motionY) > 10.0D)
|
|
+ {
|
|
+ this.motionY = 0.0D;
|
|
+ }
|
|
+
|
|
+ if (Math.abs(this.motionZ) > 10.0D)
|
|
+ {
|
|
+ this.motionZ = 0.0D;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
+
|
|
+ // CraftBukkit start - Reset world
|
|
+ if (this instanceof EntityPlayerMP)
|
|
+ {
|
|
+ Server server = Bukkit.getServer();
|
|
+ org.bukkit.World bworld = null;
|
|
+ // TODO: Remove World related checks, replaced with WorldUID.
|
|
+ String worldName = p_70020_1_.getString("World");
|
|
+
|
|
+ if (p_70020_1_.hasKey("WorldUUIDMost") && p_70020_1_.hasKey("WorldUUIDLeast"))
|
|
+ {
|
|
+ UUID uid = new UUID(p_70020_1_.getLong("WorldUUIDMost"), p_70020_1_.getLong("WorldUUIDLeast"));
|
|
+ bworld = server.getWorld(uid);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ bworld = server.getWorld(worldName);
|
|
+ }
|
|
+
|
|
+ if (bworld == null)
|
|
+ {
|
|
+ EntityPlayerMP entityPlayer = (EntityPlayerMP) this;
|
|
+ // Cauldron start - use CraftBukkit's fallback world code if no valid world is found.
|
|
+ entityPlayer.setWorld(MinecraftServer.getServer().worldServerForDimension(entityPlayer.dimension));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ this.setWorld(((CraftWorld) bworld).getHandle());
|
|
+ // Cauldron end
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
}
|
|
catch (Throwable throwable)
|
|
{
|
|
@@ -1653,6 +1954,31 @@
|
|
|
|
public void mountEntity(Entity p_70078_1_)
|
|
{
|
|
+ // CraftBukkit start
|
|
+ this.setPassengerOf(p_70078_1_);
|
|
+ }
|
|
+
|
|
+ protected CraftEntity bukkitEntity;
|
|
+
|
|
+ public CraftEntity getBukkitEntity()
|
|
+ {
|
|
+ if (this.bukkitEntity == null)
|
|
+ {
|
|
+ this.bukkitEntity = CraftEntity.getEntity(this.worldObj.getServer(), this);
|
|
+ }
|
|
+
|
|
+ return this.bukkitEntity;
|
|
+ }
|
|
+
|
|
+ public void setPassengerOf(Entity p_70078_1_)
|
|
+ {
|
|
+ // mountEntity(null) doesn't really fly for overloaded methods,
|
|
+ // so this method is needed
|
|
+ Entity originalVehicle = this.ridingEntity;
|
|
+ Entity originalPassenger = this.ridingEntity == null ? null : this.ridingEntity.riddenByEntity;
|
|
+ PluginManager pluginManager = Bukkit.getPluginManager();
|
|
+ this.getBukkitEntity(); // make sure bukkitEntity is initialised
|
|
+ // CraftBukkit end
|
|
this.entityRiderPitchDelta = 0.0D;
|
|
this.entityRiderYawDelta = 0.0D;
|
|
|
|
@@ -1660,6 +1986,20 @@
|
|
{
|
|
if (this.ridingEntity != null)
|
|
{
|
|
+ // CraftBukkit start
|
|
+ if ((this.bukkitEntity instanceof LivingEntity) && (this.ridingEntity.getBukkitEntity() instanceof Vehicle))
|
|
+ {
|
|
+ VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.ridingEntity.getBukkitEntity(), (LivingEntity) this.bukkitEntity);
|
|
+ pluginManager.callEvent(event);
|
|
+
|
|
+ if (event.isCancelled() || this.ridingEntity != originalVehicle)
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
+ pluginManager.callEvent(new org.spigotmc.event.entity.EntityDismountEvent(this.getBukkitEntity(), this.ridingEntity.getBukkitEntity())); // Spigot
|
|
this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double)this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch);
|
|
this.ridingEntity.riddenByEntity = null;
|
|
}
|
|
@@ -1668,22 +2008,61 @@
|
|
}
|
|
else
|
|
{
|
|
- if (this.ridingEntity != null)
|
|
+ // CraftBukkit start
|
|
+ if ((this.bukkitEntity instanceof LivingEntity) && (p_70078_1_.getBukkitEntity() instanceof Vehicle) && p_70078_1_.worldObj.chunkExists((int) p_70078_1_.posX >> 4, (int) p_70078_1_.posZ >> 4))
|
|
{
|
|
- this.ridingEntity.riddenByEntity = null;
|
|
- }
|
|
+ // It's possible to move from one vehicle to another. We need to check if they're already in a vehicle, and fire an exit event if they are.
|
|
+ VehicleExitEvent exitEvent = null;
|
|
|
|
- if (p_70078_1_ != null)
|
|
- {
|
|
- for (Entity entity1 = p_70078_1_.ridingEntity; entity1 != null; entity1 = entity1.ridingEntity)
|
|
+ if (this.ridingEntity != null && this.ridingEntity.getBukkitEntity() instanceof Vehicle)
|
|
{
|
|
- if (entity1 == this)
|
|
+ exitEvent = new VehicleExitEvent((Vehicle) this.ridingEntity.getBukkitEntity(), (LivingEntity) this.bukkitEntity);
|
|
+ pluginManager.callEvent(exitEvent);
|
|
+
|
|
+ if (exitEvent.isCancelled() || this.ridingEntity != originalVehicle || (this.ridingEntity != null && this.ridingEntity.riddenByEntity != originalPassenger))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
+
|
|
+ VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) p_70078_1_.getBukkitEntity(), this.bukkitEntity);
|
|
+ pluginManager.callEvent(event);
|
|
+
|
|
+ // If a plugin messes with the vehicle or the vehicle's passenger
|
|
+ if (event.isCancelled() || this.ridingEntity != originalVehicle || (this.ridingEntity != null && this.ridingEntity.riddenByEntity != originalPassenger))
|
|
+ {
|
|
+ // If we only cancelled the enterevent then we need to put the player in a decent position.
|
|
+ if (exitEvent != null && this.ridingEntity == originalVehicle && this.ridingEntity != null && this.ridingEntity.riddenByEntity == originalPassenger)
|
|
+ {
|
|
+ this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double) this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch);
|
|
+ this.ridingEntity.riddenByEntity = null;
|
|
+ this.ridingEntity = null;
|
|
+ }
|
|
+
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
+ // CraftBukkit end
|
|
+ // Spigot Start
|
|
+ if (p_70078_1_.worldObj.chunkExists((int) p_70078_1_.posX >> 4, (int) p_70078_1_.posZ >> 4))
|
|
+ {
|
|
+ org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent(this.getBukkitEntity(), p_70078_1_.getBukkitEntity());
|
|
+ pluginManager.callEvent(event);
|
|
+
|
|
+ if (event.isCancelled())
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Spigot End
|
|
+
|
|
+ if (this.ridingEntity != null)
|
|
+ {
|
|
+ this.ridingEntity.riddenByEntity = null;
|
|
+ }
|
|
+
|
|
this.ridingEntity = p_70078_1_;
|
|
p_70078_1_.riddenByEntity = this;
|
|
}
|
|
@@ -1860,12 +2239,59 @@
|
|
|
|
public void onStruckByLightning(EntityLightningBolt p_70077_1_)
|
|
{
|
|
- this.dealFireDamage(5);
|
|
+ // CraftBukkit start
|
|
+ final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity();
|
|
+ if (thisBukkitEntity == null) return; // Cauldron - skip mod entities with no wrapper (TODO: create a wrapper)
|
|
+ if (p_70077_1_ == null) return; // Cauldron - skip null entities, see #392
|
|
+ final org.bukkit.entity.Entity stormBukkitEntity = p_70077_1_.getBukkitEntity();
|
|
+ if (stormBukkitEntity == null) return; // Cauldron - skip mod entities with no wrapper (TODO: create a wrapper)
|
|
+ final PluginManager pluginManager = Bukkit.getPluginManager();
|
|
+
|
|
+ if (thisBukkitEntity instanceof Hanging)
|
|
+ {
|
|
+ HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity);
|
|
+ PaintingBreakByEntityEvent paintingEvent = null;
|
|
+
|
|
+ if (thisBukkitEntity instanceof Painting) {
|
|
+ paintingEvent = new PaintingBreakByEntityEvent((Painting) thisBukkitEntity, stormBukkitEntity);
|
|
+ }
|
|
+
|
|
+ pluginManager.callEvent(hangingEvent);
|
|
+
|
|
+ if (paintingEvent != null) {
|
|
+ paintingEvent.setCancelled(hangingEvent.isCancelled());
|
|
+ pluginManager.callEvent(paintingEvent);
|
|
+ }
|
|
+
|
|
+ if (hangingEvent.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (this.isImmuneToFire) {
|
|
+ return;
|
|
+ }
|
|
+ CraftEventFactory.entityDamage = p_70077_1_;
|
|
+ if (!this.attackEntityFrom(DamageSource.inFire, 5.0F)) {
|
|
+ CraftEventFactory.entityDamage = null;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
++this.fire;
|
|
|
|
if (this.fire == 0)
|
|
{
|
|
- this.setFire(8);
|
|
+ // CraftBukkit start - Call a combust event when lightning strikes
|
|
+ EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8);
|
|
+ pluginManager.callEvent(entityCombustEvent);
|
|
+
|
|
+ if (!entityCombustEvent.isCancelled())
|
|
+ {
|
|
+ this.setFire(entityCombustEvent.getDuration());
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
|
|
@@ -2038,36 +2464,62 @@
|
|
{
|
|
this.worldObj.theProfiler.startSection("changeDimension");
|
|
MinecraftServer minecraftserver = MinecraftServer.getServer();
|
|
- int j = this.dimension;
|
|
- WorldServer worldserver = minecraftserver.worldServerForDimension(j);
|
|
- WorldServer worldserver1 = minecraftserver.worldServerForDimension(p_71027_1_);
|
|
- this.dimension = p_71027_1_;
|
|
+ // CraftBukkit start - Move logic into new function "teleportToLocation"
|
|
+ // int j = this.dimension;
|
|
+ // Cauldron start - Allow Forge hotloading on teleport
|
|
+ WorldServer exitWorld = minecraftserver.worldServerForDimension(p_71027_1_);
|
|
|
|
- if (j == 1 && p_71027_1_ == 1)
|
|
+ Location enter = this.getBukkitEntity().getLocation();
|
|
+ Location exit = exitWorld != null ? minecraftserver.getConfigurationManager().calculateTarget(enter, minecraftserver.worldServerForDimension(p_71027_1_)) : null;
|
|
+ boolean useTravelAgent = exitWorld != null && !(this.dimension == 1 && exitWorld.dimension == 1); // don't use agent for custom worlds or return from THE_END
|
|
+ // Cauldron start - check if teleporter is instance of TravelAgent before attempting to cast to it
|
|
+ Teleporter teleporter = exit != null ? ((CraftWorld) exit.getWorld()).getHandle().getDefaultTeleporter() : null;
|
|
+ TravelAgent agent = (teleporter != null && teleporter instanceof TravelAgent) ? (TravelAgent)teleporter : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins
|
|
+ // Cauldron end
|
|
+ EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent);
|
|
+ event.useTravelAgent(useTravelAgent);
|
|
+ event.getEntity().getServer().getPluginManager().callEvent(event);
|
|
+
|
|
+ if (event.isCancelled() || event.getTo() == null || !this.isEntityAlive())
|
|
{
|
|
- worldserver1 = minecraftserver.worldServerForDimension(0);
|
|
- this.dimension = 0;
|
|
+ return;
|
|
}
|
|
|
|
+ exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo();
|
|
+ this.teleportTo(exit, true);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void teleportTo(Location exit, boolean portal)
|
|
+ {
|
|
+ if (true)
|
|
+ {
|
|
+ WorldServer worldserver = ((CraftWorld) this.getBukkitEntity().getLocation().getWorld()).getHandle();
|
|
+ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle();
|
|
+ int i = worldserver1.dimension;
|
|
+ // CraftBukkit end
|
|
+ this.dimension = i;
|
|
this.worldObj.removeEntity(this);
|
|
this.isDead = false;
|
|
this.worldObj.theProfiler.startSection("reposition");
|
|
- minecraftserver.getConfigurationManager().transferEntityToWorld(this, j, worldserver, worldserver1);
|
|
+ // CraftBukkit start - Ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create
|
|
+ // minecraftserver.getPlayerList().a(this, j, worldserver, worldserver1);
|
|
+ boolean before = worldserver1.theChunkProviderServer.loadChunkOnProvideRequest; // Cauldron start - load chunks on provide request
|
|
+ worldserver1.theChunkProviderServer.loadChunkOnProvideRequest = true;
|
|
+ worldserver1.func_73046_m().getConfigurationManager().repositionEntity(this, exit, portal);
|
|
+ worldserver1.theChunkProviderServer.loadChunkOnProvideRequest = before; // Cauldron end
|
|
+ // CraftBukkit end
|
|
this.worldObj.theProfiler.endStartSection("reloading");
|
|
Entity entity = EntityList.createEntityByName(EntityList.getEntityString(this), worldserver1);
|
|
|
|
if (entity != null)
|
|
{
|
|
entity.copyDataFrom(this, true);
|
|
-
|
|
- if (j == 1 && p_71027_1_ == 1)
|
|
- {
|
|
- ChunkCoordinates chunkcoordinates = worldserver1.getSpawnPoint();
|
|
- chunkcoordinates.posY = this.worldObj.getTopSolidOrLiquidBlock(chunkcoordinates.posX, chunkcoordinates.posZ);
|
|
- entity.setLocationAndAngles((double)chunkcoordinates.posX, (double)chunkcoordinates.posY, (double)chunkcoordinates.posZ, entity.rotationYaw, entity.rotationPitch);
|
|
- }
|
|
-
|
|
worldserver1.spawnEntityInWorld(entity);
|
|
+ // CraftBukkit start - Forward the CraftEntity to the new entity
|
|
+ this.getBukkitEntity().setHandle(entity);
|
|
+ entity.bukkitEntity = this.getBukkitEntity();
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
this.isDead = true;
|
|
@@ -2077,7 +2529,6 @@
|
|
this.worldObj.theProfiler.endSection();
|
|
}
|
|
}
|
|
-
|
|
public float func_145772_a(Explosion p_145772_1_, World p_145772_2_, int p_145772_3_, int p_145772_4_, int p_145772_5_, Block p_145772_6_)
|
|
{
|
|
return p_145772_6_.getExplosionResistance(this, p_145772_2_, p_145772_3_, p_145772_4_, p_145772_5_, posX, posY + getEyeHeight(), posZ);
|