-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Several fixes and new api for experience merging/stacking (#9242)
- Loading branch information
1 parent
ed85aac
commit a31dc90
Showing
693 changed files
with
318 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
patches/server/0361-ExperienceOrb-merging-stacking-API-and-fixes.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: BillyGalbreath <Blake.Galbreath@GMail.com> | ||
Date: Fri, 10 Nov 2017 23:03:12 -0500 | ||
Subject: [PATCH] ExperienceOrb merging/stacking API and fixes | ||
|
||
Adds an option for maximum exp value when merging orbs | ||
|
||
Adds ExperienceOrbMergeEvent | ||
Fired when the server is about to merge 2 experience orbs | ||
as entities. Plugins can cancel it if they want to ensure experience orbs do not lose important | ||
metadata such as spawn reason, or conditionally move data from source to target. | ||
|
||
Fixes an issue where the stacked count was not taking into account | ||
for mending repairs and when merging with spigot's merge-on-spawn | ||
logic | ||
|
||
== AT == | ||
public net.minecraft.world.entity.ExperienceOrb count | ||
|
||
Co-authored-by: Aikar <aikar@aikar.co> | ||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com> | ||
|
||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java | ||
index 8007d323023655052acd0cf1f3a753101e9ee74a..a933061d4f0c45a34b5678c2b317b670f20b8a45 100644 | ||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java | ||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java | ||
@@ -241,6 +241,7 @@ public class ExperienceOrb extends Entity { | ||
} | ||
|
||
private static boolean tryMergeToExisting(ServerLevel world, Vec3 pos, int amount) { | ||
+ // Paper - TODO some other event for this kind of merge | ||
AABB axisalignedbb = AABB.ofSize(pos, 1.0D, 1.0D, 1.0D); | ||
int j = world.getRandom().nextInt(40); | ||
List<ExperienceOrb> list = world.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), axisalignedbb, (entityexperienceorb) -> { | ||
@@ -267,6 +268,11 @@ public class ExperienceOrb extends Entity { | ||
} | ||
|
||
private void merge(ExperienceOrb other) { | ||
+ // Paper start - call orb merge event | ||
+ if (!new com.destroystokyo.paper.event.entity.ExperienceOrbMergeEvent((org.bukkit.entity.ExperienceOrb) this.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) other.getBukkitEntity()).callEvent()) { | ||
+ return; | ||
+ } | ||
+ // Paper end - call orb merge event | ||
this.count += other.count; | ||
this.age = Math.min(this.age, other.age); | ||
other.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause | ||
@@ -353,7 +359,7 @@ public class ExperienceOrb extends Entity { | ||
|
||
itemstack.setDamageValue(itemstack.getDamageValue() - j); | ||
int k = amount - this.durabilityToXp(j); | ||
- this.value = k; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls | ||
+ // this.value = k; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account | ||
|
||
return k > 0 ? this.repairPlayerItems(player, k) : 0; | ||
} else { | ||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java | ||
index 5a7d314ec0562e472f5dc45924a7b24841cff126..650e4a01cecc4cc08e7ff9ebcc4c367084351f21 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 { | ||
this.getHandle().value = value; | ||
} | ||
|
||
+ // Paper start - expose count | ||
+ @Override | ||
+ public int getCount() { | ||
+ return this.getHandle().count; | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void setCount(final int count) { | ||
+ this.getHandle().count = count; | ||
+ } | ||
+ // Paper end | ||
+ | ||
// Paper start | ||
public java.util.UUID getTriggerEntityId() { | ||
return getHandle().triggerEntityId; | ||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java | ||
index ac4a8c9d4f727f3caa16f6dc5497d69f9db52aab..53f5eb1682c88abf7b09e16f010ebbd8fe2ac059 100644 | ||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java | ||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java | ||
@@ -703,15 +703,29 @@ public class CraftEventFactory { | ||
if (entity instanceof net.minecraft.world.entity.ExperienceOrb xp) { | ||
double radius = world.spigotConfig.expMerge; | ||
if (radius > 0) { | ||
+ // Paper start - Maximum exp value when merging; Whole section has been tweaked, see comments for specifics | ||
+ final long maxValue = world.paperConfig().entities.behavior.experienceMergeMaxValue; | ||
+ final boolean mergeUnconditionally = maxValue <= 0; | ||
+ if (mergeUnconditionally || xp.value < maxValue) { // Paper - Skip iteration if unnecessary | ||
+ | ||
List<Entity> entities = world.getEntities(entity, entity.getBoundingBox().inflate(radius, radius, radius)); | ||
for (Entity e : entities) { | ||
if (e instanceof net.minecraft.world.entity.ExperienceOrb loopItem) { | ||
- if (!loopItem.isRemoved()) { | ||
+ // Paper start | ||
+ if (!loopItem.isRemoved() && xp.count == loopItem.count && (mergeUnconditionally || loopItem.value < maxValue) && new com.destroystokyo.paper.event.entity.ExperienceOrbMergeEvent((org.bukkit.entity.ExperienceOrb) entity.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) loopItem.getBukkitEntity()).callEvent()) { // Paper - ExperienceOrbMergeEvent | ||
+ long newTotal = (long)xp.value + (long)loopItem.value; | ||
+ if ((int) newTotal < 0) continue; // Overflow | ||
+ if (!mergeUnconditionally && newTotal > maxValue) { | ||
+ loopItem.value = (int) (newTotal - maxValue); | ||
+ xp.value = (int) maxValue; | ||
+ } else { | ||
xp.value += loopItem.value; | ||
loopItem.discard(null); // Add Bukkit remove cause | ||
+ } // Paper end - Maximum exp value when merging | ||
} | ||
} | ||
} | ||
+ } // Paper end - End iteration skip check - All tweaking ends here | ||
} | ||
} | ||
// Spigot end |
42 changes: 0 additions & 42 deletions
42
patches/server/0361-Option-for-maximum-exp-value-when-merging-orbs.patch
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
Oops, something went wrong.