2018-07-04 15:55:24 +08:00
|
|
|
From 6fab4174f4e7fc320a124b1b8d083541b49701fe Mon Sep 17 00:00:00 2001
|
2017-12-20 05:46:27 +08:00
|
|
|
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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 352310960..3e2f52647 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/Block.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Block.java
|
|
|
|
@@ -388,13 +388,13 @@ public class Block {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- 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
|
2018-01-18 14:00:51 +08:00
|
|
|
index a8cc6b61a..c925de971 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- 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
|
2018-01-18 14:00:51 +08:00
|
|
|
index bf5f1f0e8..d567ad4a5 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
|
|
|
|
@@ -15,9 +15,54 @@ 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, 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) {
|
|
|
|
+ public EntityExperienceOrb(World world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId, Entity sourceId) {
|
|
|
|
super(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);
|
|
|
|
@@ -149,12 +194,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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 6ac89d1e3..177d8582f 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/EntityFishingHook.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/EntityFishingHook.java
|
|
|
|
@@ -458,7 +458,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
|
|
|
|
Item item = itemstack.getItem();
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
2018-05-19 07:40:33 +08:00
|
|
|
index 9e864864d..38c043375 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
|
|
@@ -347,7 +347,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
|
2018-05-19 07:40:33 +08:00
|
|
|
+ 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
|
2017-12-20 05:46:27 +08:00
|
|
|
}
|
|
|
|
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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 0255986fd..e14f614f5 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java
|
|
|
|
@@ -40,7 +40,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
|
2018-04-22 22:40:36 +08:00
|
|
|
index 57fcc3c05..a9c4ab10d 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/EntityVillager.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
|
2018-04-22 22:40:36 +08:00
|
|
|
@@ -437,7 +437,7 @@ public class EntityVillager extends EntityAgeable implements NPC, IMerchant {
|
2017-12-20 05:46:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 059671b54..444792ea0 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- 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.a.getGameRules().getBoolean("doMobLoot")) {
|
|
|
|
// CraftBukkit start - use event experience
|
|
|
|
if (experience > 0) {
|
|
|
|
- this.a.addEntity(new EntityExperienceOrb(this.a, this.animal.locX, this.animal.locY, this.animal.locZ, experience));
|
|
|
|
+ this.a.addEntity(new EntityExperienceOrb(this.a, 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
|
2018-01-18 14:00:51 +08:00
|
|
|
index a1689c065..a49b5c81a 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
|
|
|
|
@@ -383,7 +383,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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 1dcf967a1..ed394f7a5 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/net/minecraft/server/SlotFurnaceResult.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/SlotFurnaceResult.java
|
|
|
|
@@ -7,7 +7,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) {
|
|
|
|
@@ -71,7 +71,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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 4ffe0d208..568a50ec4 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
|
|
|
@@ -1218,7 +1218,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
|
2018-01-18 14:00:51 +08:00
|
|
|
index 3a09cab3d..3302af0e4 100644
|
2017-12-20 05:46:27 +08:00
|
|
|
--- 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;
|
|
|
|
--
|
2018-07-04 15:55:24 +08:00
|
|
|
2.18.0
|
2017-12-20 05:46:27 +08:00
|
|
|
|