9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-26 18:39:23 +00:00

Add back Lithium: equipment tracking

This commit is contained in:
Dreeam
2025-04-18 04:38:18 -04:00
parent 6cd78606b4
commit df9edc4fa1
56 changed files with 191 additions and 270 deletions

View File

@@ -0,0 +1,443 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Tue, 9 Nov 2077 00:00:00 +0800
Subject: [PATCH] Lithium: equipment tracking
Should have special treatment to ArmorStand, since Paper introduced the configurable
ArmorStand no-tick, and still gives it ability to update equipment changes.
Thus added a bypass condition in LivingEntity#collectEquipmentChanges, always send
ArmorStand equipment changes even if the ArmorStand is no-tick
This patch is based on the following mixins:
* "net/caffeinemc/mods/lithium/mixin/util/item_component_and_count_tracking/PatchedDataComponentMapMixin.java"
* "net/caffeinemc/mods/lithium/mixin/util/item_component_and_count_tracking/ItemStackMixin.java"
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/enchantment_ticking/LivingEntityMixin.java"
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/equipment_changes/LivingEntityMixin.java"
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/EntityEquipmentMixin.java"
* "net/caffeinemc/mods/lithium/common/util/change_tracking/ChangePublisher.java"
* "net/caffeinemc/mods/lithium/common/util/change_tracking/ChangeSubscriber.java"
By: 2No2Name <2No2Name@web.de>
As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/core/component/PatchedDataComponentMap.java b/net/minecraft/core/component/PatchedDataComponentMap.java
index 3af6c1e2549ba3aeb60aa9d498a976be3680c0ee..a8ec32ec1a8c5ebbbf64639f97acf8153e1dbdb4 100644
--- a/net/minecraft/core/component/PatchedDataComponentMap.java
+++ b/net/minecraft/core/component/PatchedDataComponentMap.java
@@ -14,10 +14,11 @@ import java.util.Map.Entry;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
-public final class PatchedDataComponentMap implements DataComponentMap {
+public final class PatchedDataComponentMap implements DataComponentMap, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<PatchedDataComponentMap> { // Leaf - Lithium - equipment tracking
private final DataComponentMap prototype;
private Reference2ObjectMap<DataComponentType<?>, Optional<?>> patch;
private boolean copyOnWrite;
+ private net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber; // Leaf - Lithium - equipment tracking
public PatchedDataComponentMap(DataComponentMap prototype) {
this(prototype, Reference2ObjectMaps.emptyMap(), true);
@@ -135,6 +136,11 @@ public final class PatchedDataComponentMap implements DataComponentMap {
}
private void ensureMapOwnership() {
+ // Leaf start - Lithium - equipment tracking
+ if (this.subscriber != null) {
+ this.subscriber.notify(this, 0);
+ }
+ // Leaf end - Lithium - equipment tracking
if (this.copyOnWrite) {
this.patch = new Reference2ObjectArrayMap<>(this.patch);
this.copyOnWrite = false;
@@ -221,6 +227,22 @@ public final class PatchedDataComponentMap implements DataComponentMap {
return (DataComponentMap)(this.patch.isEmpty() ? this.prototype : this.copy());
}
+ // Leaf start - Lithium - equipment tracking
+ @Override
+ public void subscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber, int subscriberData) {
+ if (subscriberData != 0) {
+ throw new UnsupportedOperationException("ComponentMapImpl does not support subscriber data");
+ }
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.combine(this.subscriber, 0, subscriber, 0);
+ }
+
+ @Override
+ public int unsubscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber) {
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.without(this.subscriber, subscriber);
+ return 0;
+ }
+ // Leaf end - Lithium - equipment tracking
+
@Override
public boolean equals(Object other) {
return this == other
diff --git a/net/minecraft/world/entity/EntityEquipment.java b/net/minecraft/world/entity/EntityEquipment.java
index 90814ad07a2686c5a274860395f5aca29cc3bf13..d10b64f8a3ca1fda83612a8765a59538bbd69313 100644
--- a/net/minecraft/world/entity/EntityEquipment.java
+++ b/net/minecraft/world/entity/EntityEquipment.java
@@ -7,7 +7,7 @@ import java.util.Objects;
import java.util.Map.Entry;
import net.minecraft.world.item.ItemStack;
-public class EntityEquipment {
+public class EntityEquipment implements net.caffeinemc.mods.lithium.common.entity.EquipmentInfo, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.CountChangeSubscriber<ItemStack> { // Leaf - Lithium - equipment tracking
public static final Codec<EntityEquipment> CODEC = Codec.unboundedMap(EquipmentSlot.CODEC, ItemStack.CODEC).xmap(map -> {
EnumMap<EquipmentSlot, ItemStack> map1 = new EnumMap<>(EquipmentSlot.class);
map1.putAll((Map<? extends EquipmentSlot, ? extends ItemStack>)map);
@@ -18,6 +18,11 @@ public class EntityEquipment {
return map;
});
private final EnumMap<EquipmentSlot, ItemStack> items;
+ // Leaf start - Lithium - equipment tracking
+ boolean shouldTickEnchantments = false;
+ ItemStack recheckEnchantmentForStack = null;
+ boolean hasUnsentEquipmentChanges = true;
+ // Leaf end - Lithium - equipment tracking
private EntityEquipment(EnumMap<EquipmentSlot, ItemStack> items) {
this.items = items;
@@ -29,7 +34,11 @@ public class EntityEquipment {
public ItemStack set(EquipmentSlot slot, ItemStack stack) {
stack.getItem().verifyComponentsAfterLoad(stack);
- return Objects.requireNonNullElse(this.items.put(slot, stack), ItemStack.EMPTY);
+ // Leaf start - Lithium - equipment tracking
+ ItemStack newStack = Objects.requireNonNullElse(this.items.put(slot, stack), ItemStack.EMPTY);
+ this.onEquipmentReplaced(this.get(slot), newStack);
+ return newStack;
+ // Leaf end - Lithium - equipment tracking
}
public ItemStack get(EquipmentSlot slot) {
@@ -56,8 +65,21 @@ public class EntityEquipment {
}
public void setAll(EntityEquipment equipment) {
+ this.onClear(); // Leaf - Lithium - equipment tracking
this.items.clear();
this.items.putAll(equipment.items);
+ // Leaf start - Lithium - equipment tracking
+ for (ItemStack newStack : this.items.values()) {
+ if (!newStack.isEmpty()) {
+ if (!this.shouldTickEnchantments) {
+ this.shouldTickEnchantments = stackHasTickableEnchantment(newStack);
+ }
+ if (!newStack.isEmpty()) {
+ newStack.subscribe(this, 0);
+ }
+ }
+ }
+ // Leaf end - Lithium - equipment tracking
}
public void dropAll(LivingEntity entity) {
@@ -70,6 +92,7 @@ public class EntityEquipment {
public void clear() {
this.items.replaceAll((equipmentSlot, itemStack) -> ItemStack.EMPTY);
+ this.onClear(); // Leaf - Lithium - equipment tracking
}
// Paper start - EntityDeathEvent
@@ -78,4 +101,99 @@ public class EntityEquipment {
return this.items.containsKey(slot);
}
// Paper end - EntityDeathEvent
+
+ @Override
+ public boolean shouldTickEnchantments() {
+ this.processScheduledEnchantmentCheck(null);
+ return this.shouldTickEnchantments;
+ }
+
+ @Override
+ public boolean hasUnsentEquipmentChanges() {
+ return this.hasUnsentEquipmentChanges;
+ }
+
+ @Override
+ public void onEquipmentChangesSent() {
+ this.hasUnsentEquipmentChanges = false;
+ }
+
+ private void onClear() {
+ this.shouldTickEnchantments = false;
+ this.recheckEnchantmentForStack = null;
+ this.hasUnsentEquipmentChanges = true;
+
+ for (ItemStack oldStack : this.items.values()) {
+ if (!oldStack.isEmpty()) {
+ oldStack.unsubscribeWithData(this, 0);
+ }
+ }
+ }
+
+ private void onEquipmentReplaced(ItemStack oldStack, ItemStack newStack) {
+ if (!this.shouldTickEnchantments) {
+ if (this.recheckEnchantmentForStack == oldStack) {
+ this.recheckEnchantmentForStack = null;
+ }
+ this.shouldTickEnchantments = stackHasTickableEnchantment(newStack);
+ }
+
+ this.hasUnsentEquipmentChanges = true;
+
+ if (!oldStack.isEmpty()) {
+ oldStack.unsubscribeWithData(this, 0);
+ }
+ if (!newStack.isEmpty()) {
+ newStack.subscribe(this, 0);
+ }
+ }
+
+ private static boolean stackHasTickableEnchantment(ItemStack stack) {
+ if (!stack.isEmpty()) {
+ net.minecraft.world.item.enchantment.ItemEnchantments enchantments = stack.get(net.minecraft.core.component.DataComponents.ENCHANTMENTS);
+ if (enchantments != null && !enchantments.isEmpty()) {
+ for (net.minecraft.core.Holder<net.minecraft.world.item.enchantment.Enchantment> enchantmentEntry : enchantments.keySet()) {
+ if (!enchantmentEntry.value().getEffects(net.minecraft.world.item.enchantment.EnchantmentEffectComponents.TICK).isEmpty()) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void notify(@org.jetbrains.annotations.Nullable ItemStack publisher, int zero) {
+ this.hasUnsentEquipmentChanges = true;
+
+ if (!this.shouldTickEnchantments) {
+ this.processScheduledEnchantmentCheck(publisher);
+ this.scheduleEnchantmentCheck(publisher);
+ }
+ }
+
+ private void scheduleEnchantmentCheck(@org.jetbrains.annotations.Nullable ItemStack toCheck) {
+ this.recheckEnchantmentForStack = toCheck;
+ }
+
+ private void processScheduledEnchantmentCheck(@org.jetbrains.annotations.Nullable ItemStack ignoredStack) {
+ if (this.recheckEnchantmentForStack != null && this.recheckEnchantmentForStack != ignoredStack) {
+ this.shouldTickEnchantments = stackHasTickableEnchantment(this.recheckEnchantmentForStack);
+ this.recheckEnchantmentForStack = null;
+ }
+ }
+
+ @Override
+ public void notifyCount(ItemStack publisher, int zero, int newCount) {
+ if (newCount == 0) {
+ publisher.unsubscribeWithData(this, zero);
+ }
+
+ this.onEquipmentReplaced(publisher, ItemStack.EMPTY);
+ }
+
+ @Override
+ public void forceUnsubscribe(ItemStack publisher, int zero) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 7e9ace691bb2662afd2c0fc504007a6d22a8aec0..4a6880c044c016e9e5b0ec88afbfe169eef8e1d3 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -144,7 +144,7 @@ import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityResurrectEvent;
// CraftBukkit end
-public abstract class LivingEntity extends Entity implements Attackable {
+public abstract class LivingEntity extends Entity implements Attackable, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.CountChangeSubscriber<ItemStack> { // Leaf - Lithium - equipment tracking
private static final Logger LOGGER = LogUtils.getLogger();
private static final String TAG_ACTIVE_EFFECTS = "active_effects";
private static final ResourceLocation SPEED_MODIFIER_POWDER_SNOW_ID = ResourceLocation.withDefaultNamespace("powder_snow");
@@ -417,7 +417,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.getSleepingPos().ifPresent(this::setPosToBed);
}
- if (this.level() instanceof ServerLevel serverLevel) {
+ if ((this instanceof Player || this.equipment.shouldTickEnchantments()) && this.level() instanceof ServerLevel serverLevel) { // Leaf - Lithium - equipment tracking
EnchantmentHelper.tickEffects(serverLevel, this);
}
@@ -3394,6 +3394,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
public void detectEquipmentUpdates() {
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
if (map != null) {
+ if (!(this instanceof net.minecraft.world.entity.player.Player)) this.equipment.onEquipmentChangesSent();; // Leaf - Lithium - equipment tracking
this.handleHandSwap(map);
if (!map.isEmpty()) {
this.handleEquipmentChanges(map);
@@ -3403,6 +3404,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
@Nullable
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
+ // Leaf start - Lithium - equipment tracking
+ final boolean isArmorStandUpdateNoTick = this instanceof net.minecraft.world.entity.decoration.ArmorStand stand && !stand.canTick && stand.noTickEquipmentDirty;
+ if (!isArmorStandUpdateNoTick && !this.equipment.hasUnsentEquipmentChanges()) return null;
+ // Leaf end - Lithium - equipment tracking
Map<EquipmentSlot, ItemStack> map = null;
// Paper start - EntityEquipmentChangedEvent
record EquipmentChangeImpl(org.bukkit.inventory.ItemStack oldItem, org.bukkit.inventory.ItemStack newItem) implements io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange {
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
index 49500127eb3a471c41dc3ff32372ad6f20c6d69a..c4ef7ce572a1dc05a9ff2b4aa115ef07fd04902d 100644
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -551,8 +551,8 @@ public class ArmorStand extends LivingEntity {
}
if (this.noTickEquipmentDirty) {
- this.noTickEquipmentDirty = false;
this.detectEquipmentUpdates();
+ this.noTickEquipmentDirty = false; // Leaf - Lithium - equipment tracking - Remove dirty mark after handling equipment update for armor stand
}
return;
@@ -886,4 +886,10 @@ public class ArmorStand extends LivingEntity {
if (this.canMovementTick && this.canMove) super.aiStep();
}
// Purpur end - Movement options for armor stands
+
+ // Leaf start - Lithium - equipment tracking
+ private void trackEquipChange(ItemStack prevStack, ItemStack currStack) {
+ this.onEquipmentReplaced(prevStack, currStack);
+ }
+ // Leaf end - Lithium - equipment tracking
}
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index d2d9619f8156985ba38c0ef8c0f155adc8d40f34..cf5755a313b021c42a194364641cf5cad1ccfba7 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -97,7 +97,7 @@ import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.slf4j.Logger;
-public final class ItemStack implements DataComponentHolder {
+public final class ItemStack implements DataComponentHolder, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<ItemStack>, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> { // Leaf - Lithium - equipment tracking
private static final List<Component> OP_NBT_WARNING = List.of(
Component.translatable("item.op_warning.line1").withStyle(ChatFormatting.RED, ChatFormatting.BOLD),
Component.translatable("item.op_warning.line2").withStyle(ChatFormatting.RED),
@@ -168,6 +168,11 @@ public final class ItemStack implements DataComponentHolder {
PatchedDataComponentMap components;
@Nullable
private Entity entityRepresentation;
+ // Leaf start - Lithium - equipment tracking
+ @Nullable
+ private net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber;
+ private int subscriberData;
+ // Leaf end - Lithium - equipment tracking
public static DataResult<ItemStack> validateStrict(ItemStack stack) {
DataResult<Unit> dataResult = validateComponents(stack.getComponents());
@@ -1403,6 +1408,21 @@ public final class ItemStack implements DataComponentHolder {
}
public void setCount(int count) {
+ // Leaf start - Lithium - equipment tracking
+ if (count != this.count) {
+ if (this.subscriber instanceof net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.CountChangeSubscriber<ItemStack> countChangeSubscriber) {
+ countChangeSubscriber.notifyCount(this, this.subscriberData, count);
+ }
+ if (count == 0) {
+ this.components.unsubscribe(this);
+ if (this.subscriber != null) {
+ this.subscriber.forceUnsubscribe(this, this.subscriberData);
+ this.subscriber = null;
+ this.subscriberData = 0;
+ }
+ }
+ }
+ // Leaf end - Lithium - equipment tracking
this.count = count;
}
@@ -1458,4 +1478,87 @@ public final class ItemStack implements DataComponentHolder {
public boolean canDestroyBlock(BlockState state, Level level, BlockPos pos, Player player) {
return this.getItem().canDestroyBlock(this, state, level, pos, player);
}
+
+ // Leaf start - Lithium - equipment tracking
+ @Override
+ public void subscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
+ if (this.isEmpty()) {
+ throw new IllegalStateException("Cannot subscribe to an empty ItemStack!");
+ }
+
+ if (this.subscriber == null) {
+ this.startTrackingChanges();
+ }
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.combine(this.subscriber, this.subscriberData, subscriber, subscriberData);
+ if (this.subscriber instanceof net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.Multi<?>) {
+ this.subscriberData = 0;
+ } else {
+ this.subscriberData = subscriberData;
+ }
+ }
+
+ @Override
+ public int unsubscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber) {
+ if (this.isEmpty()) {
+ throw new IllegalStateException("Cannot unsubscribe from an empty ItemStack!");
+ }
+
+ int retval = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.dataOf(this.subscriber, subscriber, this.subscriberData);
+ this.subscriberData = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.dataWithout(this.subscriber, subscriber, this.subscriberData);
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.without(this.subscriber, subscriber);
+
+ if (this.subscriber == null) {
+ this.components.unsubscribe(this);
+ }
+ return retval;
+ }
+
+ @Override
+ public void unsubscribeWithData(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
+ if (this.isEmpty()) {
+ throw new IllegalStateException("Cannot unsubscribe from an empty ItemStack!");
+ }
+
+ this.subscriberData = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.dataWithout(this.subscriber, subscriber, this.subscriberData, subscriberData, true);
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.without(this.subscriber, subscriber, subscriberData, true);
+
+ if (this.subscriber == null) {
+ this.components.unsubscribe(this);
+ }
+ }
+
+ @Override
+ public boolean isSubscribedWithData(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
+ if (this.isEmpty()) {
+ throw new IllegalStateException("Cannot be subscribed to an empty ItemStack!");
+ }
+
+ return net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.containsSubscriber(this.subscriber, this.subscriberData, subscriber, subscriberData);
+ }
+
+ @Override
+ public void forceUnsubscribe(PatchedDataComponentMap publisher, int subscriberData) {
+ if (publisher != this.components) {
+ throw new IllegalStateException("Invalid publisher, expected " + this.components + " but got " + publisher);
+ }
+ this.subscriber.forceUnsubscribe(this, this.subscriberData);
+ this.subscriber = null;
+ this.subscriberData = 0;
+ }
+
+ @Override
+ public void notify(PatchedDataComponentMap publisher, int subscriberData) {
+ if (publisher != this.components) {
+ throw new IllegalStateException("Invalid publisher, expected " + this.components + " but got " + publisher);
+ }
+
+ if (this.subscriber != null) {
+ this.subscriber.notify(this, this.subscriberData);
+ }
+ }
+
+ private void startTrackingChanges() {
+ this.components.subscribe(this, 0);
+ }
+ // Leaf end - Lithium - equipment tracking
}

View File

@@ -97,7 +97,7 @@ index fd3d0f6cb53bc8b6186f0d86575f21007b2c20ed..cddeeab73e7b981701a42c5aad6b4777
// Paper end - rewrite chunk system
}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index fc1430cb711a86281cfc7b7c94221e7ef867da9e..d9a9a60e63e652ca83c26dba5d7bfa3a3834af35 100644
index 7b85a9ebdbe3e8bee0a8fc100ede8a3f07eee5ce..c8c99323b6397c3e595e7a9007e5d801ee2ac14a 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -503,7 +503,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Cache random tick block status
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
index 03edf6dc751cc59ae1f16c23340e41668350b32a..963c51d14f87d2557a3d686fb8fe3ec9cba367b3 100644
index df717c545472006b99532280c38c1fbef12bcf82..36c033b0ee63dfc273d721fb4b614733e8fdef19 100644
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -21,6 +21,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_

View File

@@ -9,7 +9,7 @@ By default, the server will start rewriting all map datas to the disk after load
This also slows down world saving a lot if you have a lot of maps
diff --git a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
index 3ae69b17fec1cdb2bee2b5a795026a875f197c30..1196066585582af132f8fb773bab7466d0800461 100644
index df471cd42f4084facb895b229c261b685054c3ae..3e84cb0fe6efa95ccede9ead29cafbf1afb717d9 100644
--- a/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
+++ b/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
@@ -160,6 +160,7 @@ public class MapItemSavedData extends SavedData {

View File

@@ -6,10 +6,10 @@ Subject: [PATCH] Only player pushable
Useful for extreme cases like massive entities collide together in a small area
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index eb40f810d4eb8d6a8cc130719b637a473f19cc82..9d6d8ba96acd688d07bfecc29ff9de95abcd839c 100644
index 4a6880c044c016e9e5b0ec88afbfe169eef8e1d3..2d246bfccb8538391592dec4a0a0e47aa6ff355d 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -3630,7 +3630,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3635,7 +3635,7 @@ public abstract class LivingEntity extends Entity implements Attackable, net.caf
this.checkAutoSpinAttack(boundingBox, this.getBoundingBox());
}
@@ -18,7 +18,7 @@ index eb40f810d4eb8d6a8cc130719b637a473f19cc82..9d6d8ba96acd688d07bfecc29ff9de95
// Paper start - Add EntityMoveEvent
// Purpur start - Ridables
if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) {
@@ -3773,7 +3773,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3778,7 +3778,12 @@ public abstract class LivingEntity extends Entity implements Attackable, net.caf
return;
}
// Paper end - don't run getEntities if we're not going to use its result
@@ -32,7 +32,7 @@ index eb40f810d4eb8d6a8cc130719b637a473f19cc82..9d6d8ba96acd688d07bfecc29ff9de95
if (!pushableEntities.isEmpty()) {
if (this.level() instanceof ServerLevel serverLevel) {
// Paper - don't run getEntities if we're not going to use its result; moved up
@@ -3807,6 +3812,44 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3812,6 +3817,44 @@ public abstract class LivingEntity extends Entity implements Attackable, net.caf
}
}
@@ -78,7 +78,7 @@ index eb40f810d4eb8d6a8cc130719b637a473f19cc82..9d6d8ba96acd688d07bfecc29ff9de95
AABB aabb = boundingBoxBeforeSpin.minmax(boundingBoxAfterSpin);
List<Entity> entities = this.level().getEntities(this, aabb);
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
index 49500127eb3a471c41dc3ff32372ad6f20c6d69a..aee9711b76c76e64056b73f8581cce0ba40b0811 100644
index c4ef7ce572a1dc05a9ff2b4aa115ef07fd04902d..9b1b99c557b06b8b1e7b791e07637333797cc07f 100644
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -247,7 +247,7 @@ public class ArmorStand extends LivingEntity {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Cache eligible players for despawn checks
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index d9a9a60e63e652ca83c26dba5d7bfa3a3834af35..8daa10d2e2f6276fa4c4071928d7ee5aac2054c2 100644
index c8c99323b6397c3e595e7a9007e5d801ee2ac14a..7ca4fd418599cdb1bb1de44f4c3c57f1770a4038 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -723,6 +723,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -1,17 +0,0 @@
package net.caffeinemc.mods.lithium.common.entity;
import net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber;
import net.minecraft.world.item.ItemStack;
public interface EquipmentEntity {
void onEquipmentReplaced(ItemStack oldStack, ItemStack newStack);
interface EquipmentTrackingEntity {
void onEquipmentChanged();
}
interface TickableEnchantmentTrackingEntity extends ChangeSubscriber.EnchantmentSubscriber<ItemStack> {
void updateHasTickableEnchantments(ItemStack oldStack, ItemStack newStack);
}
}

View File

@@ -0,0 +1,10 @@
package net.caffeinemc.mods.lithium.common.entity;
public interface EquipmentInfo {
boolean shouldTickEnchantments();
boolean hasUnsentEquipmentChanges();
void onEquipmentChangesSent();
}