Fix EXP orb merging causing values to go negative - Closes #1169
This commit is contained in:
parent
17dca0a0fe
commit
56b92ff216
|
@ -1,11 +1,11 @@
|
|||
From d3ad905c6a3156cbf9484834eea088efb106b4dd Mon Sep 17 00:00:00 2001
|
||||
From 076f4e8c2a78146df199092bb435153a87ceb89c Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 10 Nov 2017 23:03:12 -0500
|
||||
Subject: [PATCH] Option for maximum exp value when merging orbs
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 4d30cdbc8..535a8d3ed 100644
|
||||
index 4d30cdbc8b..535a8d3ed1 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -457,4 +457,10 @@ public class PaperWorldConfig {
|
||||
|
@ -20,16 +20,16 @@ index 4d30cdbc8..535a8d3ed 100644
|
|||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 29dffc3ac..2c69ae748 100644
|
||||
index 3561507de1..b6b4d52718 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1143,16 +1143,30 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1143,16 +1143,31 @@ public abstract class World implements IBlockAccess {
|
||||
EntityExperienceOrb xp = (EntityExperienceOrb) entity;
|
||||
double radius = spigotConfig.expMerge;
|
||||
if (radius > 0) {
|
||||
+ // Paper start - Maximum exp value when merging - Whole section has been tweaked, see comments for specifics
|
||||
+ final int maxValue = paperConfig.expMergeMaxValue;
|
||||
+ final boolean mergeUnconditionally = maxValue <= 0;
|
||||
+ final boolean mergeUnconditionally = paperConfig.expMergeMaxValue <= 0;
|
||||
+ if (mergeUnconditionally || xp.value < maxValue) { // Paper - Skip iteration if unnecessary
|
||||
+
|
||||
List<Entity> entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius));
|
||||
|
@ -37,16 +37,19 @@ index 29dffc3ac..2c69ae748 100644
|
|||
if (e instanceof EntityExperienceOrb) {
|
||||
EntityExperienceOrb loopItem = (EntityExperienceOrb) e;
|
||||
- if (!loopItem.dead) {
|
||||
+ if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) { // Paper
|
||||
xp.value += loopItem.value;
|
||||
+ // Paper start
|
||||
+ if (!mergeUnconditionally && xp.value > maxValue) {
|
||||
- xp.value += loopItem.value;
|
||||
- loopItem.die();
|
||||
+ // Paper start
|
||||
+ if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) {
|
||||
+ long newTotal = (long)xp.value + (long)loopItem.value;
|
||||
+ if (newTotal > (long)maxValue) {
|
||||
+ loopItem.value = xp.value - maxValue;
|
||||
+ xp.value = maxValue;
|
||||
+ break;
|
||||
+ } else {
|
||||
+ xp.value += loopItem.value;
|
||||
+ loopItem.die();
|
||||
+ }
|
||||
+ // Paper end
|
||||
loopItem.die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 4104f9583f512022acc4fe898d4487df59a1029a Mon Sep 17 00:00:00 2001
|
||||
From 2c072e94e1c963916f63e2ff8fb41b0f933b1ccb Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 22:57:26 -0500
|
||||
Subject: [PATCH] ExperienceOrbMergeEvent
|
||||
|
@ -8,18 +8,18 @@ Plugins can cancel this if they want to ensure experience orbs do not lose impor
|
|||
metadata such as spawn reason, or conditionally move data from source to target.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 39b90fb4c..c0816b9f8 100644
|
||||
index c0e79796bd..986670f689 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1153,7 +1153,7 @@ public abstract class World implements IBlockAccess {
|
||||
for (Entity e : entities) {
|
||||
@@ -1154,7 +1154,7 @@ public abstract class World implements IBlockAccess {
|
||||
if (e instanceof EntityExperienceOrb) {
|
||||
EntityExperienceOrb loopItem = (EntityExperienceOrb) e;
|
||||
- if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) { // Paper
|
||||
+ if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue) && new com.destroystokyo.paper.event.entity.ExperienceOrbMergeEvent((org.bukkit.entity.ExperienceOrb) entity.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) loopItem.getBukkitEntity()).callEvent()) { // Paper
|
||||
xp.value += loopItem.value;
|
||||
// Paper start
|
||||
if (!mergeUnconditionally && xp.value > maxValue) {
|
||||
// Paper start
|
||||
- if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue)) {
|
||||
+ if (!loopItem.dead && !(maxValue > 0 && loopItem.value >= maxValue) && new com.destroystokyo.paper.event.entity.ExperienceOrbMergeEvent((org.bukkit.entity.ExperienceOrb) entity.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) loopItem.getBukkitEntity()).callEvent()) {
|
||||
long newTotal = (long)xp.value + (long)loopItem.value;
|
||||
if (newTotal > (long)maxValue) {
|
||||
loopItem.value = xp.value - maxValue;
|
||||
--
|
||||
2.18.0
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From dbe49167504d8c10b0dd8fbd271f186cf752057e Mon Sep 17 00:00:00 2001
|
||||
From bc6e2c6add8004c4e8a231cedcf175565100c441 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 Jul 2018 03:39:51 -0400
|
||||
Subject: [PATCH] Avoid Chunk Lookups for Entity/TileEntity Current Chunk
|
||||
|
@ -10,7 +10,7 @@ to the object directly on the Entity/TileEntity object we can directly grab.
|
|||
Use that local value instead to reduce lookups in many hot places.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index 81bf60efa..04adf4e3c 100644
|
||||
index d24d45fdd3..4757081090 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -702,6 +702,7 @@ public class Chunk {
|
||||
|
@ -22,10 +22,10 @@ index 81bf60efa..04adf4e3c 100644
|
|||
this.a(entity, entity.ac);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index c0816b9f8..52adee880 100644
|
||||
index 986670f689..a01488e985 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1511,12 +1511,15 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1512,12 +1512,15 @@ public abstract class World implements IBlockAccess {
|
||||
int j;
|
||||
// Paper start - Set based removal lists
|
||||
for (Entity e : this.f) {
|
||||
|
@ -42,7 +42,7 @@ index c0816b9f8..52adee880 100644
|
|||
}
|
||||
|
||||
for (Entity e : this.f) {
|
||||
@@ -1577,12 +1580,17 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1578,12 +1581,17 @@ public abstract class World implements IBlockAccess {
|
||||
this.methodProfiler.b();
|
||||
this.methodProfiler.a("remove");
|
||||
if (entity.dead) {
|
||||
|
@ -62,7 +62,7 @@ index c0816b9f8..52adee880 100644
|
|||
|
||||
guardEntityList = false; // Spigot
|
||||
this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable
|
||||
@@ -1627,7 +1635,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1628,7 +1636,7 @@ public abstract class World implements IBlockAccess {
|
||||
BlockPosition blockposition = tileentity.getPosition();
|
||||
|
||||
// Paper start - Skip ticking in chunks scheduled for unload
|
||||
|
@ -71,7 +71,7 @@ index c0816b9f8..52adee880 100644
|
|||
boolean shouldTick = chunk != null;
|
||||
if(this.paperConfig.skipEntityTickingInChunksScheduledForUnload)
|
||||
shouldTick = shouldTick && !chunk.isUnloading() && chunk.scheduledForUnload == null;
|
||||
@@ -1663,8 +1671,11 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1664,8 +1672,11 @@ public abstract class World implements IBlockAccess {
|
||||
tilesThisCycle--;
|
||||
this.tileEntityListTick.remove(tileTickPosition--);
|
||||
//this.tileEntityList.remove(tileentity); // Paper - remove unused list
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 84507c90ff4af6aa9e32dc69f6d8c64b4d230345 Mon Sep 17 00:00:00 2001
|
||||
From df4224f8e69e3eecc619f3832f5660c09eeeecfa Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 26 Jul 2018 00:11:12 -0400
|
||||
Subject: [PATCH] Prevent Saving Bad entities to chunks
|
||||
|
@ -57,10 +57,10 @@ index bcce5e8b7e..bad287fca4 100644
|
|||
nbttagcompound.set("Entities", nbttaglist1);
|
||||
NBTTagList nbttaglist2 = new NBTTagList();
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index b4de3b515a..d2d2ab794b 100644
|
||||
index 3012768cb9..0aa2f99838 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1202,7 +1202,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1203,7 +1203,7 @@ public abstract class World implements IBlockAccess {
|
||||
}
|
||||
|
||||
this.getChunkAt(i, j).a(entity);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 529731e4258b21416a555ed6c2d0200b8449f1d7 Mon Sep 17 00:00:00 2001
|
||||
From 1102ec474b6e3afd75431427134a4992ee08c5e8 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 28 Jul 2018 12:09:20 -0400
|
||||
Subject: [PATCH] Always process chunk removal in removeEntity
|
||||
|
@ -8,10 +8,10 @@ which can keep them in the chunk when they shouldnt be if done
|
|||
during entity ticking.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index d2d2ab794..df98a4f44 100644
|
||||
index 0aa2f99838..8822d17745 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1272,7 +1272,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1273,7 +1273,7 @@ public abstract class World implements IBlockAccess {
|
||||
this.everyoneSleeping();
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ index d2d2ab794..df98a4f44 100644
|
|||
int i = entity.ab;
|
||||
int j = entity.ad;
|
||||
|
||||
@@ -1280,6 +1280,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1281,6 +1281,7 @@ public abstract class World implements IBlockAccess {
|
||||
this.getChunkAt(i, j).b(entity);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 9b87108547b8a12487adcc4aea181f103a24cf53 Mon Sep 17 00:00:00 2001
|
||||
From 485cc40d70fcb82a5538f2dac8713c253c943aed Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 28 Jul 2018 12:18:27 -0400
|
||||
Subject: [PATCH] Ignore Dead Entities in entityList iteration
|
||||
|
@ -11,7 +11,7 @@ This will ensure that dead entities are skipped from iteration since
|
|||
they shouldn't of been in the list in the first place.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
index ecd1c65a9..1898ab897 100644
|
||||
index ecd1c65a98..1898ab897c 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
@@ -128,6 +128,7 @@ public class PaperCommand extends Command {
|
||||
|
@ -23,7 +23,7 @@ index ecd1c65a9..1898ab897 100644
|
|||
MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
|
||||
ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ());
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index 1e64d5fcd..45e149f4a 100644
|
||||
index 1e64d5fcd6..45e149f4a3 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
||||
@@ -124,6 +124,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
|
||||
|
@ -35,10 +35,10 @@ index 1e64d5fcd..45e149f4a 100644
|
|||
public float length;
|
||||
public float I;
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 0dca11b2c..dadd4b839 100644
|
||||
index 8822d17745..3ce6f9778b 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1214,6 +1214,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1215,6 +1215,7 @@ public abstract class World implements IBlockAccess {
|
||||
}
|
||||
|
||||
entity.valid = true; // CraftBukkit
|
||||
|
@ -46,7 +46,7 @@ index 0dca11b2c..dadd4b839 100644
|
|||
new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid
|
||||
}
|
||||
|
||||
@@ -1279,6 +1280,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -1280,6 +1281,7 @@ public abstract class World implements IBlockAccess {
|
||||
if (entity.aa && this.isChunkLoaded(i, j, true)) {
|
||||
this.getChunkAt(i, j).b(entity);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ index 0dca11b2c..dadd4b839 100644
|
|||
|
||||
if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - always remove from current chunk above
|
||||
// CraftBukkit start - Decrement loop variable field if we've already ticked this entity
|
||||
@@ -2633,6 +2635,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -2634,6 +2636,7 @@ public abstract class World implements IBlockAccess {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = (Entity) iterator.next();
|
||||
|
@ -62,7 +62,7 @@ index 0dca11b2c..dadd4b839 100644
|
|||
|
||||
if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply((T) entity)) {
|
||||
arraylist.add(entity);
|
||||
@@ -2719,6 +2722,7 @@ public abstract class World implements IBlockAccess {
|
||||
@@ -2720,6 +2723,7 @@ public abstract class World implements IBlockAccess {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = (Entity) iterator.next();
|
||||
|
@ -71,7 +71,7 @@ index 0dca11b2c..dadd4b839 100644
|
|||
if (entity instanceof EntityInsentient) {
|
||||
EntityInsentient entityinsentient = (EntityInsentient) entity;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 210e3bc4e..e6ecd1796 100644
|
||||
index 210e3bc4e6..e6ecd1796c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -678,6 +678,7 @@ public class CraftWorld implements World {
|
||||
|
@ -107,5 +107,5 @@ index 210e3bc4e..e6ecd1796 100644
|
|||
|
||||
if (bukkitEntity == null) {
|
||||
--
|
||||
2.17.1
|
||||
2.18.0
|
||||
|
||||
|
|
Loading…
Reference in New Issue