mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
remove Lithium: equipment tracking (#367)
This commit is contained in:
@@ -0,0 +1,514 @@
|
||||
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/equipment_changes/LivingEntityMixin.java"
|
||||
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/ArmorStandMixin.java"
|
||||
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/LivingEntityMixin.java"
|
||||
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/MobMixin.java"
|
||||
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/enchantment_ticking/LivingEntityMixin.java"
|
||||
* "net/caffeinemc/mods/lithium/common/entity/EquipmentEntity.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 a8c6549f772208cd543607224fef2c2389b14f24..709631db548a16a969a373e26ebbcd6983e35590 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/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index cbd68d1d5b92e426062776658a6bf525553ecb1b..668722c44bac3a9731d175a93aad8435e0c2c1c0 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -159,7 +159,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||
// 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>, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity.TickableEnchantmentTrackingEntity, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity.EquipmentTrackingEntity { // 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");
|
||||
@@ -305,6 +305,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||
protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight
|
||||
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ private boolean maybeHasTickableEnchantments = this instanceof net.minecraft.world.entity.player.Player;
|
||||
+ private boolean equipmentChanged = true;
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
@Override
|
||||
public float getBukkitYaw() {
|
||||
return this.getYHeadRot();
|
||||
@@ -445,7 +449,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.getSleepingPos().ifPresent(this::setPosToBed);
|
||||
}
|
||||
|
||||
- if (this.level() instanceof ServerLevel serverLevel) {
|
||||
+ if (this.maybeHasTickableEnchantments && this.level() instanceof ServerLevel serverLevel) { // Leaf - Lithium - equipment tracking
|
||||
EnchantmentHelper.tickEffects(serverLevel, this);
|
||||
}
|
||||
|
||||
@@ -738,6 +742,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.level().isClientSide() && !this.isSpectator()) {
|
||||
boolean flag = newItem.isEmpty() && oldItem.isEmpty();
|
||||
if (!flag && !ItemStack.isSameItemSameComponents(oldItem, newItem) && !this.firstTick) {
|
||||
+ this.onEquipmentReplaced(oldItem, newItem); // Leaf - Lithium - equipment tracking
|
||||
Equippable equippable = newItem.get(DataComponents.EQUIPPABLE);
|
||||
if (!this.isSilent() && equippable != null && slot == equippable.slot() && !silent) { // CraftBukkit
|
||||
this.level()
|
||||
@@ -3355,6 +3360,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
public void detectEquipmentUpdatesPublic() { // CraftBukkit
|
||||
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
|
||||
if (map != null) {
|
||||
+ if (!(this instanceof net.minecraft.world.entity.player.Player)) this.equipmentChanged = false; // Leaf - Lithium - equipment tracking
|
||||
this.handleHandSwap(map);
|
||||
if (!map.isEmpty()) {
|
||||
this.handleEquipmentChanges(map);
|
||||
@@ -3364,6 +3370,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.equipmentChanged) 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 {
|
||||
@@ -4723,6 +4733,81 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return this.lastHurtByPlayerTime;
|
||||
}
|
||||
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ @Override
|
||||
+ public void updateHasTickableEnchantments(ItemStack oldStack, ItemStack newStack) {
|
||||
+ if (!this.maybeHasTickableEnchantments) {
|
||||
+ this.maybeHasTickableEnchantments = stackHasTickableEnchantment(newStack);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void notifyAfterEnchantmentChange(ItemStack publisher, int subscriberData) {
|
||||
+ if (!this.maybeHasTickableEnchantments) {
|
||||
+ this.maybeHasTickableEnchantments = stackHasTickableEnchantment(publisher);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onEquipmentChanged() {
|
||||
+ this.equipmentChanged = true;
|
||||
+ }
|
||||
+
|
||||
+ private static boolean stackHasTickableEnchantment(ItemStack stack) {
|
||||
+ if (!stack.isEmpty()) {
|
||||
+ net.minecraft.world.item.enchantment.ItemEnchantments enchantments = stack.get(DataComponents.ENCHANTMENTS);
|
||||
+ if (enchantments != null && !enchantments.isEmpty()) {
|
||||
+ for (Holder<Enchantment> enchantmentEntry : enchantments.keySet()) {
|
||||
+ if (!enchantmentEntry.value().getEffects(net.minecraft.world.item.enchantment.EnchantmentEffectComponents.TICK).isEmpty()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void notify(@Nullable ItemStack publisher, int zero) {
|
||||
+ if (this instanceof EquipmentTrackingEntity equipmentTrackingEntity) {
|
||||
+ equipmentTrackingEntity.onEquipmentChanged();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @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();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onEquipmentReplaced(ItemStack oldStack, ItemStack newStack) {
|
||||
+ if (this instanceof TickableEnchantmentTrackingEntity enchantmentTrackingEntity) {
|
||||
+ enchantmentTrackingEntity.updateHasTickableEnchantments(oldStack, newStack);
|
||||
+ }
|
||||
+
|
||||
+ if (this instanceof EquipmentTrackingEntity equipmentTrackingEntity) {
|
||||
+ equipmentTrackingEntity.onEquipmentChanged();
|
||||
+ }
|
||||
+
|
||||
+ if (!oldStack.isEmpty()) {
|
||||
+ oldStack.unsubscribeWithData(this, 0);
|
||||
+ }
|
||||
+ if (!newStack.isEmpty()) {
|
||||
+ newStack.subscribe(this, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
+
|
||||
public record Fallsounds(SoundEvent small, SoundEvent big) {
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index faf05f0c8f273bc723bbe54c70aebdd26c479a6b..54eeb0b112112bc5d3f4165c0ea43cf67931a739 100644
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -94,7 +94,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
|
||||
import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
|
||||
// CraftBukkit end
|
||||
|
||||
-public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting {
|
||||
+public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity { // Leaf - Lithium - equipment tracking
|
||||
private static final EntityDataAccessor<Byte> DATA_MOB_FLAGS_ID = SynchedEntityData.defineId(Mob.class, EntityDataSerializers.BYTE);
|
||||
private static final int MOB_FLAG_NO_AI = 1;
|
||||
private static final int MOB_FLAG_LEFTHANDED = 2;
|
||||
@@ -516,6 +516,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
+ ItemStack prevBodyArmor = this.bodyArmorItem; // Leaf - Lithium - equipment tracking
|
||||
super.readAdditionalSaveData(compound);
|
||||
// CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
|
||||
if (compound.contains("CanPickUpLoot", 99)) {
|
||||
@@ -535,7 +536,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
|
||||
for (int i = 0; i < this.armorItems.size(); i++) {
|
||||
CompoundTag compound1 = list.getCompound(i);
|
||||
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), compound1);
|
||||
+ ItemStack prevStack = this.armorItems.set(i, currStack);
|
||||
+ this.trackEquipChange(prevStack, currStack);
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
} else {
|
||||
this.armorItems.replaceAll(itemStack -> ItemStack.EMPTY);
|
||||
@@ -556,7 +561,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
|
||||
for (int i = 0; i < this.handItems.size(); i++) {
|
||||
CompoundTag compound1 = list.getCompound(i);
|
||||
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), compound1);
|
||||
+ ItemStack prevStack = this.handItems.set(i, currStack);
|
||||
+ this.trackEquipChange(prevStack, currStack);
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
} else {
|
||||
this.handItems.replaceAll(itemStack -> ItemStack.EMPTY);
|
||||
@@ -599,6 +608,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
this.ticksSinceLastInteraction = compound.getInt("Purpur.ticksSinceLastInteraction");
|
||||
}
|
||||
// Purpur end - Entity lifespan
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ if (prevBodyArmor != this.bodyArmorItem) {
|
||||
+ this.trackEquipChange(prevBodyArmor, this.bodyArmorItem);
|
||||
+ }
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1750,4 +1764,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
}
|
||||
}
|
||||
// Purpur end - Ridables
|
||||
+
|
||||
+ // 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/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index a31bbd8f3fff4fb4b1b33877d5835b93fc248f65..21153f37c169e987d7876d1b914105223ac10ee7 100644
|
||||
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -46,7 +46,7 @@ import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
-public class ArmorStand extends LivingEntity {
|
||||
+public class ArmorStand extends LivingEntity implements net.caffeinemc.mods.lithium.common.entity.EquipmentEntity { // Leaf - Lithium - equipment tracking
|
||||
public static final int WOBBLE_TIME = 5;
|
||||
private static final boolean ENABLE_ARMS = true;
|
||||
public static final Rotations DEFAULT_HEAD_POSE = new Rotations(0.0F, 0.0F, 0.0F);
|
||||
@@ -233,7 +233,11 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
for (int i = 0; i < this.armorItems.size(); i++) {
|
||||
CompoundTag compound1 = list.getCompound(i);
|
||||
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ ItemStack currElement = ItemStack.parseOptional(this.registryAccess(), compound1);
|
||||
+ ItemStack prevElement = this.armorItems.set(i, currElement);
|
||||
+ this.trackEquipChange(prevElement, currElement);
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +246,11 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
for (int i = 0; i < this.handItems.size(); i++) {
|
||||
CompoundTag compound1 = list.getCompound(i);
|
||||
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), compound1);
|
||||
+ ItemStack prevStack = this.handItems.set(i, currStack);
|
||||
+ this.trackEquipChange(prevStack, currStack);
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,7 +586,11 @@ public class ArmorStand extends LivingEntity {
|
||||
ItemStack itemStack = this.handItems.get(i);
|
||||
if (!itemStack.isEmpty()) {
|
||||
this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
- this.handItems.set(i, ItemStack.EMPTY);
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ ItemStack emptyStack = ItemStack.EMPTY;
|
||||
+ ItemStack prevStack = this.handItems.set(i, emptyStack);
|
||||
+ this.trackEquipChange(prevStack, emptyStack);
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +598,11 @@ public class ArmorStand extends LivingEntity {
|
||||
ItemStack itemStack = this.armorItems.get(ix);
|
||||
if (!itemStack.isEmpty()) {
|
||||
this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
- this.armorItems.set(ix, ItemStack.EMPTY);
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
+ ItemStack emptyStack = ItemStack.EMPTY;
|
||||
+ ItemStack prevStack = this.armorItems.set(ix, ItemStack.EMPTY);
|
||||
+ this.trackEquipChange(prevStack, emptyStack);
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
}
|
||||
}
|
||||
return this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved from above // Paper
|
||||
@@ -632,10 +648,12 @@ public class ArmorStand extends LivingEntity {
|
||||
this.updatePose();
|
||||
}
|
||||
|
||||
+ // Leaf start - Lithium - equipment tracking
|
||||
if (this.noTickEquipmentDirty) {
|
||||
- this.noTickEquipmentDirty = false;
|
||||
this.detectEquipmentUpdatesPublic();
|
||||
+ this.noTickEquipmentDirty = false; // Remove dirty mark after handling equipment update for armor stand
|
||||
}
|
||||
+ // Leaf end - Lithium - equipment tracking
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -968,4 +986,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 aa2c00be86f42a6674694a20545399e441b75199..fd7c1e800cbd4919a1a47f6c468c8776535bd028 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -95,7 +95,7 @@ import net.minecraft.world.level.saveddata.maps.MapId;
|
||||
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),
|
||||
@@ -202,6 +202,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
|
||||
|
||||
private static DataResult<ItemStack> validateStrict(ItemStack stack) {
|
||||
DataResult<Unit> dataResult = validateComponents(stack.getComponents());
|
||||
@@ -1375,6 +1380,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;
|
||||
}
|
||||
|
||||
@@ -1430,4 +1450,87 @@ public final class ItemStack implements DataComponentHolder {
|
||||
Repairable repairable = this.get(DataComponents.REPAIRABLE);
|
||||
return repairable != null && repairable.isValidRepairItem(item);
|
||||
}
|
||||
+
|
||||
+ // 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
|
||||
}
|
||||
Reference in New Issue
Block a user