geforkt von Mirrors/Paper
Several fixes and new api for experience merging/stacking (#9242)
Dieser Commit ist enthalten in:
Ursprung
6496275397
Commit
3991e67f19
@ -1,12 +1,15 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Tue, 19 Dec 2017 22:56:24 -0500
|
Date: Tue, 19 Dec 2017 22:56:24 -0500
|
||||||
Subject: [PATCH] ExperienceOrbMergeEvent
|
Subject: [PATCH] ExperienceOrb merging/stacking API
|
||||||
|
|
||||||
|
Adds ExperienceOrbMergeEvent
|
||||||
Fired when the server is about to merge 2 experience orbs
|
Fired when the server is about to merge 2 experience orbs
|
||||||
Plugins can cancel this if they want to ensure experience orbs do not lose important
|
Plugins can cancel this if they want to ensure experience orbs do not lose important
|
||||||
metadata such as spawn reason, or conditionally move data from source to target.
|
metadata such as spawn reason, or conditionally move data from source to target.
|
||||||
|
|
||||||
|
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
|
||||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java
|
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||||
@ -104,3 +107,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ return HANDLER_LIST;
|
+ return HANDLER_LIST;
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
|
diff --git a/src/main/java/org/bukkit/entity/ExperienceOrb.java b/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||||
|
@@ -0,0 +0,0 @@ public interface ExperienceOrb extends Entity {
|
||||||
|
* @param value Amount of experience
|
||||||
|
*/
|
||||||
|
public void setExperience(int value);
|
||||||
|
+
|
||||||
|
+ // Paper start - expose count
|
||||||
|
+ /**
|
||||||
|
+ * Get the stacked count for this experience orb.
|
||||||
|
+ *
|
||||||
|
+ * @return the count
|
||||||
|
+ */
|
||||||
|
+ int getCount();
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Sets the stacked count for this experience orb.
|
||||||
|
+ *
|
||||||
|
+ * @param count the new count
|
||||||
|
+ */
|
||||||
|
+ void setCount(int count);
|
||||||
|
+ // Paper end
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
/**
|
@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
itemstack.setDamageValue(itemstack.getDamageValue() - j);
|
itemstack.setDamageValue(itemstack.getDamageValue() - j);
|
||||||
- int k = amount - this.durabilityToXp(j);
|
- int k = amount - this.durabilityToXp(j);
|
||||||
+ int k = amount - event.getDurabilityToXpOperation().applyAsInt(j); // Paper - Expand PlayerItemMendEvent
|
+ int k = amount - event.getDurabilityToXpOperation().applyAsInt(j); // Paper - Expand PlayerItemMendEvent
|
||||||
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
|
||||||
+ // Paper start - Expand PlayerItemMendEvent
|
+ // Paper start - Expand PlayerItemMendEvent
|
||||||
+ if (j == 0 && amount == k) { // if repair amount is 0 and no xp was removed, don't do recursion; treat as cancelled
|
+ if (j == 0 && amount == k) { // if repair amount is 0 and no xp was removed, don't do recursion; treat as cancelled
|
||||||
+ return k;
|
+ return k;
|
||||||
|
113
patches/server/ExperienceOrb-merging-stacking-API-and-fixes.patch
Normale Datei
113
patches/server/ExperienceOrb-merging-stacking-API-and-fixes.patch
Normale Datei
@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||||
|
@@ -0,0 +0,0 @@ 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) -> {
|
||||||
|
@@ -0,0 +0,0 @@ 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
|
||||||
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||||
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
@@ -0,0 +0,0 @@ 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
|
@ -16,5 +16,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ event = CraftEventFactory.callEntitySpawnEvent(entity); // Call spawn event for ExperienceOrb entities
|
+ event = CraftEventFactory.callEntitySpawnEvent(entity); // Call spawn event for ExperienceOrb entities
|
||||||
+ if (radius > 0 && !event.isCancelled() && !entity.isRemoved()) {
|
+ if (radius > 0 && !event.isCancelled() && !entity.isRemoved()) {
|
||||||
// Paper start - Maximum exp value when merging; Whole section has been tweaked, see comments for specifics
|
// Paper start - Maximum exp value when merging; Whole section has been tweaked, see comments for specifics
|
||||||
final int maxValue = world.paperConfig().entities.behavior.experienceMergeMaxValue;
|
final long maxValue = world.paperConfig().entities.behavior.experienceMergeMaxValue;
|
||||||
final boolean mergeUnconditionally = world.paperConfig().entities.behavior.experienceMergeMaxValue <= 0;
|
final boolean mergeUnconditionally = maxValue <= 0;
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aikar <aikar@aikar.co>
|
|
||||||
Date: Tue, 19 Dec 2017 22:57:26 -0500
|
|
||||||
Subject: [PATCH] ExperienceOrbMergeEvent
|
|
||||||
|
|
||||||
Has to be reimplemented at one point maybe
|
|
||||||
Fired when the server is about to merge 2 experience orbs
|
|
||||||
Plugins can cancel this if they want to ensure experience orbs do not lose important
|
|
||||||
metadata such as spawn reason, or conditionally move data from source to target.
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
||||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
||||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
|
||||||
for (Entity e : entities) {
|
|
||||||
if (e instanceof net.minecraft.world.entity.ExperienceOrb loopItem) {
|
|
||||||
// Paper start
|
|
||||||
- if (!loopItem.isRemoved() && !(maxValue > 0 && loopItem.value >= maxValue)) {
|
|
||||||
+ if (!loopItem.isRemoved() && !(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 - ExperienceOrbMergeEvent
|
|
||||||
long newTotal = (long)xp.value + (long)loopItem.value;
|
|
||||||
if ((int) newTotal < 0) continue; // Overflow
|
|
||||||
if (maxValue > 0 && newTotal > (long)maxValue) {
|
|
@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||||
public int value;
|
public int value;
|
||||||
private int count;
|
public int count;
|
||||||
private Player followingPlayer;
|
private Player followingPlayer;
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ @javax.annotation.Nullable
|
+ @javax.annotation.Nullable
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
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] Option for maximum exp value when merging orbs
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
||||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
||||||
@@ -0,0 +0,0 @@ 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 int maxValue = world.paperConfig().entities.behavior.experienceMergeMaxValue;
|
|
||||||
+ final boolean mergeUnconditionally = world.paperConfig().entities.behavior.experienceMergeMaxValue <= 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() && !(maxValue > 0 && loopItem.value >= maxValue)) {
|
|
||||||
+ long newTotal = (long)xp.value + (long)loopItem.value;
|
|
||||||
+ if ((int) newTotal < 0) continue; // Overflow
|
|
||||||
+ if (maxValue > 0 && newTotal > (long)maxValue) {
|
|
||||||
+ loopItem.value = (int) (newTotal - maxValue);
|
|
||||||
+ xp.value = 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
|
|
||||||
|
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren