Paper/Spigot-Server-Patches/0173-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
Aikar 05466e3b47
[Auto] Update Upstream
Upstream has released updates that appear to apply compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing.

Bukkit Changes:
d2834556 SPIGOT-4219: Event for PigZombies angering.

CraftBukkit Changes:
a9c796f1 SPIGOT-4184: Fix furnaces not matching Vanilla smelt or animations
195f071e SPIGOT-4219: Event for PigZombies angering.
5e3082c7 SPIGOT-4230: Improve legacy block types
2018-08-05 19:46:43 -04:00

262 lines
14 KiB
Diff

From 8c55114fb8480e5ec9da06926509ac8864ad2762 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 19 Dec 2017 16:31:46 -0500
Subject: [PATCH] ExperienceOrbs API for Reason/Source/Triggering player
Adds lots of information about why this orb exists.
Replaces isFromBottle() with logic that persists entity reloads too.
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 43feccef8f..e820bfbd56 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -471,13 +471,13 @@ public class Block implements IMaterial {
}
}
- protected void dropExperience(World world, BlockPosition blockposition, int i) {
+ protected void dropExperience(World world, BlockPosition blockposition, int i, EntityPlayer player) { // Paper
if (!world.isClientSide && world.getGameRules().getBoolean("doTileDrops")) {
while (i > 0) {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, j));
+ world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, player)); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index 131f8a5156..d8ab87e216 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -618,7 +618,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j, org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.killer, this)); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
index 3c888d6015..79d80596df 100644
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java
+++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
@@ -15,9 +15,59 @@ public class EntityExperienceOrb extends Entity {
public int value;
private EntityHuman targetPlayer;
private int targetTime;
+ // Paper start
+ public java.util.UUID sourceEntityId;
+ public java.util.UUID triggerEntityId;
+ public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+
+ private void loadPaperNBT(NBTTagCompound nbttagcompound) {
+ if (!nbttagcompound.hasKeyOfType("Paper.ExpData", 10)) { // 10 = compound
+ return;
+ }
+ NBTTagCompound comp = nbttagcompound.getCompound("Paper.ExpData");
+ if (comp.hasUUID("source")) {
+ this.sourceEntityId = comp.getUUID("source");
+ }
+ if (comp.hasUUID("trigger")) {
+ this.triggerEntityId = comp.getUUID("trigger");
+ }
+ if (comp.hasKey("reason")) {
+ String reason = comp.getString("reason");
+ try {
+ spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
+ } catch (Exception e) {
+ this.world.getServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
+ }
+ }
+ }
+ private void savePaperNBT(NBTTagCompound nbttagcompound) {
+ NBTTagCompound comp = new NBTTagCompound();
+ if (sourceEntityId != null) {
+ comp.setUUID("source", sourceEntityId);
+ }
+ if (triggerEntityId != null) {
+ comp.setUUID("trigger", triggerEntityId);
+ }
+ if (spawnReason != null && spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) {
+ comp.setString("reason", spawnReason.name());
+ }
+ nbttagcompound.set("Paper.ExpData", comp);
+ }
public EntityExperienceOrb(World world, double d0, double d1, double d2, int i) {
+ this(world, d0, d1, d2, i, null, null);
+ }
+
+ public EntityExperienceOrb(World world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId) {
+ this(world, d0, d1, d2, i, reason, triggerId, null);
+ }
+
+ public EntityExperienceOrb(World world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId, Entity sourceId) {
super(EntityTypes.EXPERIENCE_ORB, world);
+ this.sourceEntityId = sourceId != null ? sourceId.getUniqueID() : null;
+ this.triggerEntityId = triggerId != null ? triggerId.getUniqueID() : null;
+ this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+ // Paper end
this.setSize(0.5F, 0.5F);
this.setPosition(d0, d1, d2);
this.yaw = (float) (Math.random() * 360.0D);
@@ -156,12 +206,14 @@ public class EntityExperienceOrb extends Entity {
nbttagcompound.setShort("Health", (short) this.d);
nbttagcompound.setShort("Age", (short) this.b);
nbttagcompound.setShort("Value", (short) this.value);
+ savePaperNBT(nbttagcompound); // Paper
}
public void a(NBTTagCompound nbttagcompound) {
this.d = nbttagcompound.getShort("Health");
this.b = nbttagcompound.getShort("Age");
this.value = nbttagcompound.getShort("Value");
+ loadPaperNBT(nbttagcompound); // Paper
}
public void d(EntityHuman entityhuman) {
diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java
index 1804a49de9..82e4d2eab6 100644
--- a/src/main/java/net/minecraft/server/EntityFishingHook.java
+++ b/src/main/java/net/minecraft/server/EntityFishingHook.java
@@ -467,7 +467,7 @@ public class EntityFishingHook extends Entity {
this.world.addEntity(entityitem);
// CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
if (playerFishEvent.getExpToDrop() > 0) {
- this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX, this.owner.locY + 0.5D, this.owner.locZ + 0.5D, playerFishEvent.getExpToDrop()));
+ this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX, this.owner.locY + 0.5D, this.owner.locZ + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.owner, this)); // Paper
}
// CraftBukkit end
if (itemstack1.getItem().a(TagsItem.D)) {
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 422b826d61..fdfef98a3f 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -354,7 +354,8 @@ public abstract class EntityLiving extends Entity {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j));
+ EntityLiving attacker = killer != null ? killer : lastDamager; // Paper
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j, this instanceof EntityPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, attacker, this)); // Paper
}
this.expToDrop = 0;
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
index a5e1939e05..e73dba09a6 100644
--- a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
+++ b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
@@ -36,7 +36,7 @@ public class EntityThrownExpBottle extends EntityProjectile {
int j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, getShooter(), this)); // Paper
}
this.die();
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
index e8fdf86250..b51543ea7a 100644
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -411,7 +411,7 @@ public class EntityVillager extends EntityAgeable implements NPC, IMerchant {
}
if (merchantrecipe.j()) {
- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY + 0.5D, this.locZ, i));
+ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY + 0.5D, this.locZ, i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, tradingPlayer, this)); // Paper
}
if (this.tradingPlayer instanceof EntityPlayer) {
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java
index 4a128f707b..b870964674 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java
@@ -122,7 +122,7 @@ public class PathfinderGoalBreed extends PathfinderGoal {
if (this.b.getGameRules().getBoolean("doMobLoot")) {
// CraftBukkit start - use event experience
if (experience > 0) {
- this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, experience));
+ this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityageable)); // Paper
}
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
index 54ee305eba..6e524353b5 100644
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
@@ -385,7 +385,7 @@ public class PlayerInteractManager {
// CraftBukkit start - Drop event experience
if (flag && event != null) {
- iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop());
+ iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop(), this.player); // Paper
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/SlotFurnaceResult.java b/src/main/java/net/minecraft/server/SlotFurnaceResult.java
index 998662d9e6..6b4eb7f053 100644
--- a/src/main/java/net/minecraft/server/SlotFurnaceResult.java
+++ b/src/main/java/net/minecraft/server/SlotFurnaceResult.java
@@ -9,7 +9,7 @@ import org.bukkit.event.inventory.FurnaceExtractEvent;
public class SlotFurnaceResult extends Slot {
- private final EntityHuman a;
+ private final EntityHuman a;public EntityHuman getPlayer() { return a; } // Paper OBFHELPER
private int b;
public SlotFurnaceResult(EntityHuman entityhuman, IInventory iinventory, int i, int j, int k) {
@@ -85,7 +85,7 @@ public class SlotFurnaceResult extends Slot {
while (i > 0) {
j = EntityExperienceOrb.getOrbValue(i);
i -= j;
- this.a.world.addEntity(new EntityExperienceOrb(this.a.world, this.a.locX, this.a.locY + 0.5D, this.a.locZ + 0.5D, j));
+ this.a.world.addEntity(new EntityExperienceOrb(this.a.world, this.a.locX, this.a.locY + 0.5D, this.a.locZ + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, getPlayer())); // Paper
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 9cd991c3e7..b3756074b5 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1216,7 +1216,7 @@ public class CraftWorld implements World {
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
entity = new EntityTNTPrimed(world, x, y, z, null);
} else if (ExperienceOrb.class.isAssignableFrom(clazz)) {
- entity = new EntityExperienceOrb(world, x, y, z, 0);
+ entity = new EntityExperienceOrb(world, x, y, z, 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null); // Paper
} else if (Weather.class.isAssignableFrom(clazz)) {
// not sure what this can do
if (LightningStrike.class.isAssignableFrom(clazz)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
index 3a09cab3d4..3302af0e45 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
@@ -18,6 +18,18 @@ public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb {
getHandle().value = value;
}
+ // Paper start
+ public java.util.UUID getTriggerEntityId() {
+ return getHandle().triggerEntityId;
+ }
+ public java.util.UUID getSourceEntityId() {
+ return getHandle().sourceEntityId;
+ }
+ public SpawnReason getSpawnReason() {
+ return getHandle().spawnReason;
+ }
+ // Paper end
+
@Override
public EntityExperienceOrb getHandle() {
return (EntityExperienceOrb) entity;
--
2.18.0