9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-24 01:09:29 +00:00

add back clump experience orbs

This commit is contained in:
NONPLAYT
2025-06-05 18:39:56 +03:00
parent bffc3f8cc7
commit b02fce198f
3 changed files with 59 additions and 58 deletions

View File

@@ -12,9 +12,6 @@ datapacks (including vanilla generation) to JVM bytecode to increase
performance by allowing JVM JIT to better optimize the code.
All functions provided by vanilla are implemented.
Not all server will benefit performance from this feature, as it
can sometimes slow down chunk performance than speed it up
diff --git a/net/minecraft/util/CubicSpline.java b/net/minecraft/util/CubicSpline.java
index f36f8f2d49d4eba5c80eb243883749d6f831eb8a..b43b7e242ea0a4f87704853c03201144ce355565 100644
--- a/net/minecraft/util/CubicSpline.java

View File

@@ -5,11 +5,11 @@ Subject: [PATCH] Clump experience orbs
diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java
index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474673e8df8 100644
index 81aa1a91a2ecda3053b22c2eb9e59f0ea2faf7b5..e441aac80736910dfa726788ee34fb1e8a73a1f4 100644
--- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -49,6 +49,10 @@ public class ExperienceOrb extends Entity {
@javax.annotation.Nullable
@@ -47,6 +47,10 @@ public class ExperienceOrb extends Entity {
@Nullable
public java.util.UUID triggerEntityId;
public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
+ // DivineMC start - Clump experience orbs
@@ -18,8 +18,8 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
+ // DivineMC end - Clump experience orbs
private void loadPaperNBT(CompoundTag tag) {
if (!tag.contains("Paper.ExpData", net.minecraft.nbt.Tag.TAG_COMPOUND)) {
@@ -239,6 +243,28 @@ public class ExperienceOrb extends Entity {
CompoundTag expData = tag.getCompoundOrEmpty("Paper.ExpData");
@@ -244,6 +248,28 @@ public class ExperienceOrb extends Entity {
}
private static boolean tryMergeToExisting(ServerLevel level, Vec3 pos, int amount) {
@@ -47,22 +47,22 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
+ // DivineMC end - Clump experience orbs
// Paper - TODO some other event for this kind of merge
AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0);
int randomInt = level.getRandom().nextInt(40);
@@ -254,11 +280,11 @@ public class ExperienceOrb extends Entity {
int randomInt = level.getRandom().nextInt(io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA)); // Paper - Configure how many orb groups per area
@@ -259,11 +285,11 @@ public class ExperienceOrb extends Entity {
}
private boolean canMerge(ExperienceOrb orb) {
- return orb != this && canMerge(orb, this.getId(), this.value);
+ return org.bxteam.divinemc.DivineConfig.clumpOrbs ? orb.isAlive() && !this.is(orb) : orb != this && canMerge(orb, this.getId(), this.value); // DivineMC - Clump experience orbs
- return orb != this && canMerge(orb, this.getId(), this.getValue());
+ return org.bxteam.divinemc.DivineConfig.clumpOrbs ? orb.isAlive() && !this.is(orb) : orb != this && ExperienceOrb.canMerge(orb, this.getId(), this.getValue()); // DivineMC - Clump experience orbs
}
private static boolean canMerge(ExperienceOrb orb, int amount, int other) {
- return !orb.isRemoved() && (orb.getId() - amount) % 40 == 0 && orb.value == other;
+ return org.bxteam.divinemc.DivineConfig.clumpOrbs ? orb.isAlive() : !orb.isRemoved() && (orb.getId() - amount) % 40 == 0 && orb.value == other; // DivineMC - Clump experience orbs
- return !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together
+ return org.bxteam.divinemc.DivineConfig.clumpOrbs ? orb.isAlive() : !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together // Canvas - optimize orbs
}
private void merge(ExperienceOrb orb) {
@@ -267,6 +293,18 @@ public class ExperienceOrb extends Entity {
@@ -272,6 +298,18 @@ public class ExperienceOrb extends Entity {
return;
}
// Paper end - call orb merge event
@@ -74,15 +74,15 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
+ clumps$setClumpedMap(java.util.stream.Stream.of(clumps$getClumpedMap(), otherMap)
+ .flatMap(map -> map.entrySet().stream())
+ .collect(java.util.stream.Collectors.toMap(java.util.Map.Entry::getKey, java.util.Map.Entry::getValue, Integer::sum)));
+ orb.discard(EntityRemoveEvent.Cause.MERGE); // DivineMC - add Bukkit remove cause
+ orb.discard();
+ return;
+ }
+ // DivineMC end - Clump experience orbs
this.count = this.count + orb.count;
this.age = Math.min(this.age, orb.age);
orb.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause
@@ -308,6 +346,13 @@ public class ExperienceOrb extends Entity {
compound.putInt("Value", this.value); // Paper - save as Integer
orb.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause
@@ -313,6 +351,13 @@ public class ExperienceOrb extends Entity {
compound.putInt("Value", this.getValue()); // Paper - save as Integer
compound.putInt("Count", this.count);
this.savePaperNBT(compound); // Paper
+ // DivineMC start - Clump experience orbs
@@ -95,19 +95,19 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
}
@Override
@@ -317,10 +362,51 @@ public class ExperienceOrb extends Entity {
this.value = compound.getInt("Value"); // Paper - load as Integer
this.count = Math.max(compound.getInt("Count"), 1);
@@ -322,10 +367,53 @@ public class ExperienceOrb extends Entity {
this.setValue(compound.getIntOr("Value", 0)); // Paper - load as Integer
this.count = compound.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1);
this.loadPaperNBT(compound); // Paper
+ // DivineMC start - Clump experience orbs
+ java.util.Map<Integer, Integer> map = new java.util.HashMap<>();
+ if (compound.contains("clumpedMap")) {
+ CompoundTag clumpedMap = compound.getCompound("clumpedMap");
+ for (String s : clumpedMap.getAllKeys()) {
+ map.put(Integer.parseInt(s), clumpedMap.getInt(s));
+ CompoundTag clumpedMap = compound.getCompound("clumpedMap").orElseThrow();
+ for (String s : clumpedMap.keySet()) {
+ map.put(Integer.parseInt(s), clumpedMap.getInt(s).orElseThrow());
+ }
+ } else {
+ map.put(value, count);
+ map.put(this.getValue(), count);
+ }
+
+ clumps$setClumpedMap(map);
@@ -117,15 +117,14 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
@Override
public void playerTouch(Player entity) {
+ // DivineMC start - Clump experience orbs
+ if(entity instanceof ServerPlayer && org.bxteam.divinemc.DivineConfig.clumpOrbs) {
+ if (entity instanceof ServerPlayer serverPlayer && org.bxteam.divinemc.DivineConfig.clumpOrbs && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) {
+ entity.takeXpDelay = 0;
+ entity.take(this, 1);
+
+ if(this.value != 0 || clumps$resolve()) {
+ if (this.getValue() != 0 || clumps$resolve()) {
+ java.util.concurrent.atomic.AtomicInteger toGive = new java.util.concurrent.atomic.AtomicInteger();
+ clumps$getClumpedMap().forEach((value, amount) -> {
+ int actualValue = value;
+
+ for (int i = 0; i < amount; i++) {
+ int leftOver = actualValue;
+ if (leftOver == actualValue) {
@@ -140,21 +139,20 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
+ entity.giveExperiencePoints(toGive.get());
+ }
+ }
+ this.discard();
+
+ this.count = 0;
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP);
+
+ return;
+ }
+ // DivineMC end - Clump experience orbs
+ // Canvas end
if (entity instanceof ServerPlayer serverPlayer) {
if (entity.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent
entity.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(entity, this.level().purpurConfig.playerExpPickupDelay, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; // Purpur - Configurable player pickup exp delay
@@ -338,10 +424,57 @@ public class ExperienceOrb extends Entity {
entity.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(entity, this.level().purpurConfig.playerExpPickupDelay, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; // Purpur - Configurable player pickup exp delay
@@ -343,10 +431,60 @@ public class ExperienceOrb extends Entity {
}
}
- private int repairPlayerItems(ServerPlayer player, int value) {
- Optional<EnchantedItemInUse> randomItemWith = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith( // Purpur - Add option to mend the most damaged equipment first
- EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged
- );
+ // DivineMC start - Clump experience orbs
+ public Optional<EnchantedItemInUse> clumps$captureCurrentEntry(Optional<EnchantedItemInUse> entry) {
+ clumps$currentEntry = entry;
@@ -164,7 +162,7 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
+ public java.util.Map<Integer, Integer> clumps$getClumpedMap() {
+ if (clumps$clumpedMap == null) {
+ clumps$clumpedMap = new java.util.HashMap<>();
+ clumps$clumpedMap.put(this.value, 1);
+ clumps$clumpedMap.put(this.getValue(), 1);
+ }
+
+ return clumps$clumpedMap;
@@ -176,36 +174,42 @@ index a43e5190c0f9ae14ccecccd5b58dc0e17f18b0a1..06ffba13f211851e8f6d630a72b41474
+ }
+
+ public boolean clumps$resolve() {
+ value = clumps$getClumpedMap().entrySet()
+ this.setValue(clumps$getClumpedMap().entrySet()
+ .stream()
+ .map(entry -> entry.getKey() * entry.getValue())
+ .reduce(Integer::sum)
+ .orElse(1);
+ .orElse(1));
+
+ return value > 0;
+ return this.getValue() > 0;
+ }
+ // DivineMC end - Clump experience orbs
+
+ private int repairPlayerItems(ServerPlayer player, int amount) {
+ Optional<EnchantedItemInUse> randomItemWith = clumps$captureCurrentEntry(level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged)); // Purpur - Add option to mend the most damaged equipment first
private int repairPlayerItems(ServerPlayer player, int value) {
- Optional<EnchantedItemInUse> randomItemWith = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith( // Purpur - Add option to mend the most damaged equipment first
- EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged
- );
+ Optional<EnchantedItemInUse> randomItemWith = clumps$captureCurrentEntry(level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged)); // Purpur - Add option to mend the most damaged equipment first // DivineMC - Clump experience orbs
+
+ // DivineMC start - Clump experience orbs
+ if (org.bxteam.divinemc.DivineConfig.clumpOrbs) {
+ return clumps$currentEntry
+ .map(foundItem -> {
+ ItemStack itemstack = foundItem.itemStack();
+ int xpToRepair = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemstack, (int) (amount * 1));
+ int xpToRepair = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemstack, (int) (value * 1));
+ int toRepair = Math.min(xpToRepair, itemstack.getDamageValue());
+ itemstack.setDamageValue(itemstack.getDamageValue() - toRepair);
+ if (toRepair > 0) {
+ int used = amount - toRepair * amount / xpToRepair;
+ int used = value - toRepair * value / xpToRepair;
+ if (used > 0) {
+ return this.repairPlayerItems(player, used);
+ }
+ }
+ return 0;
+ })
+ .orElse(amount);
+ .orElse(value);
+ }
+ // DivineMC end - Clump experience orbs
+
if (randomItemWith.isPresent()) {
ItemStack itemStack = randomItemWith.get().itemStack();
int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemStack, value);

View File

@@ -247,10 +247,7 @@ public class DivineConfig {
"This functionality compiles density functions from world generation",
"datapacks (including vanilla generation) to JVM bytecode to increase",
"performance by allowing JVM JIT to better optimize the code.",
"All functions provided by vanilla are implemented.",
"",
"Please test if this optimization actually benefits your server, as",
"it can sometimes slow down chunk performance than speed it up.");
"All functions provided by vanilla are implemented.");
enableStructureLayoutOptimizer = getBoolean("settings.chunks.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer,
"Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation");
deduplicateShuffledTemplatePoolElementList = getBoolean("settings.chunks.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList,
@@ -264,6 +261,7 @@ public class DivineConfig {
}
public static boolean skipUselessSecondaryPoiSensor = true;
public static boolean clumpOrbs = true;
public static boolean ignoreMovedTooQuicklyWhenLagging = true;
public static boolean alwaysAllowWeirdMovement = true;
public static boolean updateSuppressionCrashFix = true;
@@ -278,6 +276,8 @@ public class DivineConfig {
public static int hopperThrottleSkipTicks = 0;
private static void miscSettings() {
skipUselessSecondaryPoiSensor = getBoolean("settings.misc.skip-useless-secondary-poi-sensor", skipUselessSecondaryPoiSensor);
clumpOrbs = getBoolean("settings.misc.clump-orbs", clumpOrbs,
"Clumps experience orbs together to reduce entity count");
ignoreMovedTooQuicklyWhenLagging = getBoolean("settings.misc.ignore-moved-too-quickly-when-lagging", ignoreMovedTooQuicklyWhenLagging,
"Improves general gameplay experience of the player when the server is lagging, as they won't get lagged back (message 'moved too quickly')");
alwaysAllowWeirdMovement = getBoolean("settings.misc.always-allow-weird-movement", alwaysAllowWeirdMovement,