geforkt von Mirrors/Paper
8d8475fc46
Also moved the application of the force parameter inside EntityHuman, to no longer allow bypassing of very essential checks.
453 Zeilen
20 KiB
Diff
453 Zeilen
20 KiB
Diff
--- a/net/minecraft/server/EntityHuman.java
|
|
+++ b/net/minecraft/server/EntityHuman.java
|
|
@@ -12,6 +12,18 @@
|
|
import java.util.function.Predicate;
|
|
import javax.annotation.Nullable;
|
|
|
|
+// CraftBukkit start
|
|
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
|
+import org.bukkit.entity.Item;
|
|
+import org.bukkit.entity.Player;
|
|
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
+import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
|
+import org.bukkit.event.player.PlayerBedLeaveEvent;
|
|
+import org.bukkit.event.player.PlayerDropItemEvent;
|
|
+import org.bukkit.event.player.PlayerVelocityEvent;
|
|
+import org.bukkit.util.Vector;
|
|
+// CraftBukkit end
|
|
+
|
|
public abstract class EntityHuman extends EntityLiving {
|
|
|
|
private static final DataWatcherObject<Float> a = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.c);
|
|
@@ -21,10 +33,10 @@
|
|
protected static final DataWatcherObject<NBTTagCompound> bz = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
|
|
protected static final DataWatcherObject<NBTTagCompound> bA = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
|
|
public PlayerInventory inventory = new PlayerInventory(this);
|
|
- protected InventoryEnderChest enderChest = new InventoryEnderChest();
|
|
+ protected InventoryEnderChest enderChest = new InventoryEnderChest(this); // CraftBukkit - add "this" to constructor
|
|
public Container defaultContainer;
|
|
public Container activeContainer;
|
|
- protected FoodMetaData foodData = new FoodMetaData();
|
|
+ protected FoodMetaData foodData = new FoodMetaData(this); // CraftBukkit - add "this" to constructor
|
|
protected int bG;
|
|
public float bH;
|
|
public float bI;
|
|
@@ -57,6 +69,17 @@
|
|
@Nullable
|
|
public EntityFishingHook hookedFish;
|
|
|
|
+ // CraftBukkit start
|
|
+ public boolean fauxSleeping;
|
|
+ public String spawnWorld = "";
|
|
+ public int oldLevel = -1;
|
|
+
|
|
+ @Override
|
|
+ public CraftHumanEntity getBukkitEntity() {
|
|
+ return (CraftHumanEntity) super.getBukkitEntity();
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
public EntityHuman(World world, GameProfile gameprofile) {
|
|
super(EntityTypes.PLAYER, world);
|
|
this.cd = ItemStack.a;
|
|
@@ -181,7 +204,7 @@
|
|
ItemStack itemstack = this.getEquipment(EnumItemSlot.HEAD);
|
|
|
|
if (itemstack.getItem() == Items.TURTLE_HELMET && !this.a(TagsFluid.WATER)) {
|
|
- this.addEffect(new MobEffect(MobEffects.WATER_BREATHING, 200, 0, false, false, true));
|
|
+ this.addEffect(new MobEffect(MobEffects.WATER_BREATHING, 200, 0, false, false, true), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.TURTLE_HELMET); // CraftBukkit
|
|
}
|
|
|
|
}
|
|
@@ -366,7 +389,8 @@
|
|
|
|
if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.world.getGameRules().getBoolean("naturalRegeneration")) {
|
|
if (this.getHealth() < this.getMaxHealth() && this.ticksLived % 20 == 0) {
|
|
- this.heal(1.0F);
|
|
+ // CraftBukkit - added regain reason of "REGEN" for filtering purposes.
|
|
+ this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN);
|
|
}
|
|
|
|
if (this.foodData.c() && this.ticksLived % 10 == 0) {
|
|
@@ -390,7 +414,7 @@
|
|
|
|
this.o((float) attributeinstance.getValue());
|
|
float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ);
|
|
- float f1 = (float) (Math.atan(-this.motY * 0.20000000298023224D) * 15.0D);
|
|
+ float f1 = (float) ( org.bukkit.craftbukkit.TrigMath.atan(-this.motY * 0.20000000298023224D) * 15.0D); // CraftBukkit
|
|
|
|
if (f > 0.1F) {
|
|
f = 0.1F;
|
|
@@ -513,6 +537,7 @@
|
|
|
|
@Nullable
|
|
public EntityItem a(boolean flag) {
|
|
+ // Called only when dropped by Q or CTRL-Q
|
|
return this.a(this.inventory.splitStack(this.inventory.itemInHandIndex, flag && !this.inventory.getItemInHand().isEmpty() ? this.inventory.getItemInHand().getCount() : 1), false, true);
|
|
}
|
|
|
|
@@ -555,6 +580,30 @@
|
|
entityitem.motZ += Math.sin((double) f1) * (double) f;
|
|
}
|
|
|
|
+ // CraftBukkit start - fire PlayerDropItemEvent
|
|
+ Player player = (Player) this.getBukkitEntity();
|
|
+ Item drop = (Item) entityitem.getBukkitEntity();
|
|
+
|
|
+ PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop);
|
|
+ this.world.getServer().getPluginManager().callEvent(event);
|
|
+
|
|
+ if (event.isCancelled()) {
|
|
+ org.bukkit.inventory.ItemStack cur = player.getInventory().getItemInHand();
|
|
+ if (flag1 && (cur == null || cur.getAmount() == 0)) {
|
|
+ // The complete stack was dropped
|
|
+ player.getInventory().setItemInHand(drop.getItemStack());
|
|
+ } else if (flag1 && cur.isSimilar(drop.getItemStack()) && cur.getAmount() < cur.getMaxStackSize() && drop.getItemStack().getAmount() == 1) {
|
|
+ // Only one item is dropped
|
|
+ cur.setAmount(cur.getAmount() + 1);
|
|
+ player.getInventory().setItemInHand(cur);
|
|
+ } else {
|
|
+ // Fallback
|
|
+ player.getInventory().addItem(drop.getItemStack());
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
ItemStack itemstack1 = this.a(entityitem);
|
|
|
|
if (flag1) {
|
|
@@ -649,6 +698,13 @@
|
|
this.a(true, true, false);
|
|
}
|
|
|
|
+ // CraftBukkit start
|
|
+ this.spawnWorld = nbttagcompound.getString("SpawnWorld");
|
|
+ if ("".equals(spawnWorld)) {
|
|
+ this.spawnWorld = this.world.getServer().getWorlds().get(0).getName();
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
if (nbttagcompound.hasKeyOfType("SpawnX", 99) && nbttagcompound.hasKeyOfType("SpawnY", 99) && nbttagcompound.hasKeyOfType("SpawnZ", 99)) {
|
|
this.e = new BlockPosition(nbttagcompound.getInt("SpawnX"), nbttagcompound.getInt("SpawnY"), nbttagcompound.getInt("SpawnZ"));
|
|
this.f = nbttagcompound.getBoolean("SpawnForced");
|
|
@@ -699,6 +755,7 @@
|
|
if (!this.getShoulderEntityRight().isEmpty()) {
|
|
nbttagcompound.set("ShoulderEntityRight", this.getShoulderEntityRight());
|
|
}
|
|
+ nbttagcompound.setString("SpawnWorld", spawnWorld); // CraftBukkit - fixes bed spawns for multiworld worlds
|
|
|
|
}
|
|
|
|
@@ -716,10 +773,10 @@
|
|
this.a(true, true, false);
|
|
}
|
|
|
|
- this.releaseShoulderEntities();
|
|
+ // this.releaseShoulderEntities(); // CraftBukkit - moved down
|
|
if (damagesource.s()) {
|
|
if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL) {
|
|
- f = 0.0F;
|
|
+ return false; // CraftBukkit - f = 0.0f -> return false
|
|
}
|
|
|
|
if (this.world.getDifficulty() == EnumDifficulty.EASY) {
|
|
@@ -731,7 +788,13 @@
|
|
}
|
|
}
|
|
|
|
- return f == 0.0F ? false : super.damageEntity(damagesource, f);
|
|
+ // CraftBukkit start - Don't filter out 0 damage
|
|
+ boolean damaged = super.damageEntity(damagesource, f);
|
|
+ if (damaged) {
|
|
+ this.releaseShoulderEntities();
|
|
+ }
|
|
+ return damaged;
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
}
|
|
@@ -745,10 +808,29 @@
|
|
}
|
|
|
|
public boolean a(EntityHuman entityhuman) {
|
|
- ScoreboardTeamBase scoreboardteambase = this.getScoreboardTeam();
|
|
- ScoreboardTeamBase scoreboardteambase1 = entityhuman.getScoreboardTeam();
|
|
+ // CraftBukkit start - Change to check OTHER player's scoreboard team according to API
|
|
+ // To summarize this method's logic, it's "Can parameter hurt this"
|
|
+ org.bukkit.scoreboard.Team team;
|
|
+ if (entityhuman instanceof EntityPlayer) {
|
|
+ EntityPlayer thatPlayer = (EntityPlayer) entityhuman;
|
|
+ team = thatPlayer.getBukkitEntity().getScoreboard().getPlayerTeam(thatPlayer.getBukkitEntity());
|
|
+ if (team == null || team.allowFriendlyFire()) {
|
|
+ return true;
|
|
+ }
|
|
+ } else {
|
|
+ // This should never be called, but is implemented anyway
|
|
+ org.bukkit.OfflinePlayer thisPlayer = entityhuman.world.getServer().getOfflinePlayer(entityhuman.getName());
|
|
+ team = entityhuman.world.getServer().getScoreboardManager().getMainScoreboard().getPlayerTeam(thisPlayer);
|
|
+ if (team == null || team.allowFriendlyFire()) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
|
|
- return scoreboardteambase == null ? true : (!scoreboardteambase.isAlly(scoreboardteambase1) ? true : scoreboardteambase.allowFriendlyFire());
|
|
+ if (this instanceof EntityPlayer) {
|
|
+ return !team.hasPlayer(((EntityPlayer) this).getBukkitEntity());
|
|
+ }
|
|
+ return !team.hasPlayer(this.world.getServer().getOfflinePlayer(this.getName()));
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
protected void damageArmor(float f) {
|
|
@@ -791,7 +873,12 @@
|
|
return (float) i / (float) this.inventory.armor.size();
|
|
}
|
|
|
|
- protected void damageEntity0(DamageSource damagesource, float f) {
|
|
+ // CraftBukkit start
|
|
+ protected boolean damageEntity0(DamageSource damagesource, float f) { // void -> boolean
|
|
+ if (true) {
|
|
+ return super.damageEntity0(damagesource, f);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
if (!this.isInvulnerable(damagesource)) {
|
|
f = this.applyArmorModifier(damagesource, f);
|
|
f = this.applyMagicModifier(damagesource, f);
|
|
@@ -817,6 +904,7 @@
|
|
|
|
}
|
|
}
|
|
+ return false; // CraftBukkit
|
|
}
|
|
|
|
public void openSign(TileEntitySign tileentitysign) {}
|
|
@@ -938,8 +1026,15 @@
|
|
if (entity instanceof EntityLiving) {
|
|
f3 = ((EntityLiving) entity).getHealth();
|
|
if (j > 0 && !entity.isBurning()) {
|
|
- flag4 = true;
|
|
- entity.setOnFire(1);
|
|
+ // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item
|
|
+ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 1);
|
|
+ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent);
|
|
+
|
|
+ if (!combustEvent.isCancelled()) {
|
|
+ flag4 = true;
|
|
+ entity.setOnFire(combustEvent.getDuration(), false);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
|
|
@@ -970,8 +1065,11 @@
|
|
EntityLiving entityliving = (EntityLiving) iterator.next();
|
|
|
|
if (entityliving != this && entityliving != entity && !this.r(entityliving) && (!(entityliving instanceof EntityArmorStand) || !((EntityArmorStand) entityliving).isMarker()) && this.h(entityliving) < 9.0D) {
|
|
+ // CraftBukkit start - Only apply knockback if the damage hits
|
|
+ if (entityliving.damageEntity(DamageSource.playerAttack(this).sweep(), f4)) {
|
|
entityliving.a(this, 0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)));
|
|
- entityliving.damageEntity(DamageSource.playerAttack(this), f4);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
|
|
@@ -980,11 +1078,28 @@
|
|
}
|
|
|
|
if (entity instanceof EntityPlayer && entity.velocityChanged) {
|
|
+ // CraftBukkit start - Add Velocity Event
|
|
+ boolean cancelled = false;
|
|
+ Player player = (Player) entity.getBukkitEntity();
|
|
+ org.bukkit.util.Vector velocity = new Vector( d1, d2, d3 );
|
|
+
|
|
+ PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone());
|
|
+ world.getServer().getPluginManager().callEvent(event);
|
|
+
|
|
+ if (event.isCancelled()) {
|
|
+ cancelled = true;
|
|
+ } else if (!velocity.equals(event.getVelocity())) {
|
|
+ player.setVelocity(event.getVelocity());
|
|
+ }
|
|
+
|
|
+ if (!cancelled) {
|
|
((EntityPlayer) entity).playerConnection.sendPacket(new PacketPlayOutEntityVelocity(entity));
|
|
entity.velocityChanged = false;
|
|
entity.motX = d1;
|
|
entity.motY = d2;
|
|
entity.motZ = d3;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
if (flag2) {
|
|
@@ -1033,7 +1148,14 @@
|
|
|
|
this.a(StatisticList.DAMAGE_DEALT, Math.round(f5 * 10.0F));
|
|
if (j > 0) {
|
|
- entity.setOnFire(j * 4);
|
|
+ // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item
|
|
+ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4);
|
|
+ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent);
|
|
+
|
|
+ if (!combustEvent.isCancelled()) {
|
|
+ entity.setOnFire(combustEvent.getDuration());
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
if (this.world instanceof WorldServer && f5 > 2.0F) {
|
|
@@ -1049,6 +1171,11 @@
|
|
if (flag4) {
|
|
entity.extinguish();
|
|
}
|
|
+ // CraftBukkit start - resync on cancelled event
|
|
+ if (this instanceof EntityPlayer) {
|
|
+ ((EntityPlayer) this).getBukkitEntity().updateInventory();
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
|
|
@@ -1110,15 +1237,15 @@
|
|
return this.h;
|
|
}
|
|
|
|
- public EntityHuman.EnumBedResult a(BlockPosition blockposition) {
|
|
- EnumDirection enumdirection = (EnumDirection) this.world.getType(blockposition).get(BlockFacingHorizontal.FACING);
|
|
-
|
|
+ // CraftBukkit start - moved bed result checks from below into separate method
|
|
+ private EntityHuman.EnumBedResult getBedResult(BlockPosition blockposition, EnumDirection enumdirection) {
|
|
if (!this.world.isClientSide) {
|
|
if (this.isSleeping() || !this.isAlive()) {
|
|
return EntityHuman.EnumBedResult.OTHER_PROBLEM;
|
|
}
|
|
|
|
- if (!this.world.worldProvider.isOverworld()) {
|
|
+ // CraftBukkit - moved world and biome check from BlockBed interact handling here
|
|
+ if (!world.worldProvider.canRespawn() || world.getBiome(blockposition) == Biomes.NETHER || !this.world.worldProvider.isOverworld()) {
|
|
return EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE;
|
|
}
|
|
|
|
@@ -1140,6 +1267,34 @@
|
|
}
|
|
}
|
|
}
|
|
+ return EntityHuman.EnumBedResult.OK;
|
|
+ }
|
|
+
|
|
+ public EntityHuman.EnumBedResult a(BlockPosition blockposition) {
|
|
+ // CraftBukkit start - moved checks into separate method above, add force
|
|
+ return this.a(blockposition, false);
|
|
+ }
|
|
+
|
|
+ public EntityHuman.EnumBedResult a(BlockPosition blockposition, boolean force) {
|
|
+ EnumDirection enumdirection = (EnumDirection) this.world.getType(blockposition).get(BlockFacingHorizontal.FACING);
|
|
+ EntityHuman.EnumBedResult bedResult = this.getBedResult(blockposition, enumdirection);
|
|
+
|
|
+ if (bedResult == EntityHuman.EnumBedResult.OTHER_PROBLEM) {
|
|
+ return bedResult; // return immediately if the result is not bypassable by plugins
|
|
+ }
|
|
+
|
|
+ if (force) {
|
|
+ bedResult = EnumBedResult.OK;
|
|
+ }
|
|
+
|
|
+ if (this.getBukkitEntity() instanceof Player) {
|
|
+ bedResult = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBedEnterEvent(this, blockposition, bedResult);
|
|
+
|
|
+ if (bedResult != EntityHuman.EnumBedResult.OK) {
|
|
+ return bedResult;
|
|
+ }
|
|
+ }
|
|
+ // CraftBukkit end
|
|
|
|
if (this.isPassenger()) {
|
|
this.stopRiding();
|
|
@@ -1206,6 +1361,24 @@
|
|
this.world.everyoneSleeping();
|
|
}
|
|
|
|
+ // CraftBukkit start - fire PlayerBedLeaveEvent
|
|
+ if (this.getBukkitEntity() instanceof Player) {
|
|
+ Player player = (Player) this.getBukkitEntity();
|
|
+
|
|
+ org.bukkit.block.Block bed;
|
|
+ BlockPosition blockposition = this.bedPosition;
|
|
+ if (blockposition != null) {
|
|
+ bed = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
|
+ } else {
|
|
+ bed = this.world.getWorld().getBlockAt(player.getLocation());
|
|
+ }
|
|
+
|
|
+ PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed, flag2);
|
|
+ this.world.getServer().getPluginManager().callEvent(event);
|
|
+ flag2 = event.shouldSetSpawnLocation();
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
this.sleepTicks = flag ? 0 : 100;
|
|
if (flag2) {
|
|
this.setRespawnPosition(this.bedPosition, false);
|
|
@@ -1257,9 +1430,11 @@
|
|
if (blockposition != null) {
|
|
this.e = blockposition;
|
|
this.f = flag;
|
|
+ this.spawnWorld = this.world.worldData.getName(); // CraftBukkit
|
|
} else {
|
|
this.e = null;
|
|
this.f = false;
|
|
+ this.spawnWorld = ""; // CraftBukkit
|
|
}
|
|
|
|
}
|
|
@@ -1325,7 +1500,11 @@
|
|
this.motY = d3 * 0.6D;
|
|
this.aU = f3;
|
|
this.fallDistance = 0.0F;
|
|
- this.setFlag(7, false);
|
|
+ // CraftBukkit start
|
|
+ if (getFlag(7) && !org.bukkit.craftbukkit.event.CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) {
|
|
+ this.setFlag(7, false);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
} else {
|
|
super.a(f, f1, f2);
|
|
}
|
|
@@ -1625,13 +1804,17 @@
|
|
}
|
|
|
|
protected void releaseShoulderEntities() {
|
|
- this.spawnEntityFromShoulder(this.getShoulderEntityLeft());
|
|
- this.setShoulderEntityLeft(new NBTTagCompound());
|
|
- this.spawnEntityFromShoulder(this.getShoulderEntityRight());
|
|
- this.setShoulderEntityRight(new NBTTagCompound());
|
|
+ // CraftBukkit start
|
|
+ if (this.spawnEntityFromShoulder(this.getShoulderEntityLeft())) {
|
|
+ this.setShoulderEntityLeft(new NBTTagCompound());
|
|
+ }
|
|
+ if (this.spawnEntityFromShoulder(this.getShoulderEntityRight())) {
|
|
+ this.setShoulderEntityRight(new NBTTagCompound());
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
- private void spawnEntityFromShoulder(@Nullable NBTTagCompound nbttagcompound) {
|
|
+ private boolean spawnEntityFromShoulder(@Nullable NBTTagCompound nbttagcompound) { // CraftBukkit void->boolean
|
|
if (!this.world.isClientSide && !nbttagcompound.isEmpty()) {
|
|
Entity entity = EntityTypes.a(nbttagcompound, this.world);
|
|
|
|
@@ -1640,9 +1823,10 @@
|
|
}
|
|
|
|
entity.setPosition(this.locX, this.locY + 0.699999988079071D, this.locZ);
|
|
- this.world.addEntity(entity);
|
|
+ return this.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY); // CraftBukkit
|
|
}
|
|
|
|
+ return true; // CraftBukkit
|
|
}
|
|
|
|
public abstract boolean isSpectator();
|