diff --git a/src/main/java/com/minelittlepony/unicopia/compat/trinkets/TrinketsDelegate.java b/src/main/java/com/minelittlepony/unicopia/compat/trinkets/TrinketsDelegate.java index 6c896cf4..c9e17eb8 100644 --- a/src/main/java/com/minelittlepony/unicopia/compat/trinkets/TrinketsDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/compat/trinkets/TrinketsDelegate.java @@ -30,7 +30,7 @@ public interface TrinketsDelegate { TrinketsDelegate EMPTY = new TrinketsDelegate() {}; static TrinketsDelegate getInstance(@Nullable LivingEntity entity) { - if (!(entity instanceof PlayerEntity && hasTrinkets())) { + if (!hasTrinkets() || (entity != null && !(entity instanceof PlayerEntity))) { return EMPTY; } return TrinketsDelegateImpl.INSTANCE; diff --git a/src/main/java/com/minelittlepony/unicopia/compat/trinkets/UnicopiaTrinket.java b/src/main/java/com/minelittlepony/unicopia/compat/trinkets/UnicopiaTrinket.java index 5fad88d2..c8ce7e96 100644 --- a/src/main/java/com/minelittlepony/unicopia/compat/trinkets/UnicopiaTrinket.java +++ b/src/main/java/com/minelittlepony/unicopia/compat/trinkets/UnicopiaTrinket.java @@ -3,6 +3,8 @@ package com.minelittlepony.unicopia.compat.trinkets; import java.util.UUID; import com.google.common.collect.Multimap; +import com.minelittlepony.unicopia.entity.ItemTracker; +import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.item.FriendshipBraceletItem; import com.minelittlepony.unicopia.item.WearableItem; @@ -30,8 +32,19 @@ public class UnicopiaTrinket implements Trinket { return; } + if (!(stack.getItem() instanceof ItemTracker.Trackable) && stack.getItem() instanceof Equipment q) { + entity.playSound(q.getEquipSound(), 1, 1); + } + } + + @Override + public void onUnequip(ItemStack stack, SlotReference slot, LivingEntity entity) { + if (stack.getItem() instanceof ItemTracker.Trackable t) { + Living l = Living.living(entity); + t.onUnequipped(l, l.getArmour().forceRemove(t)); + } if (stack.getItem() instanceof Equipment q) { - entity.playSound( q.getEquipSound(), 1, 1); + entity.playSound(q.getEquipSound(), 1, 1); } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ItemTracker.java b/src/main/java/com/minelittlepony/unicopia/entity/ItemTracker.java index 5155a4cd..dbd889d1 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ItemTracker.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ItemTracker.java @@ -4,6 +4,8 @@ import java.util.*; import java.util.function.Predicate; import java.util.stream.Stream; +import org.jetbrains.annotations.Nullable; + import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.util.*; @@ -33,6 +35,7 @@ public class ItemTracker implements NbtSerialisable, Copyable, Tick } private final Map items = new HashMap<>(); + private final Map forced = new HashMap<>(); public static Predicate wearing(Trackable charm, Predicate range) { return e -> Living.getOrEmpty(e) @@ -67,19 +70,23 @@ public class ItemTracker implements NbtSerialisable, Copyable, Tick @Override public void tick() { - update(living, living.getArmourStacks()); + update(living.getArmourStacks()); } - private void update(Living living, Stream stacks) { + private void update(Stream stacks) { final Set found = new HashSet<>(); final Set foundStacks = new HashSet<>(); + stacks.forEach(stack -> { if (stack.getItem() instanceof Trackable trackable) { - items.compute(trackable, (item, prev) -> prev == null ? 1 : prev + 1); + if (items.compute(trackable, (item, prev) -> prev == null ? 1 : prev + 1) == 1) { + trackable.onEquipped(this.living); + } found.add(trackable); foundStacks.add(stack); } }); + items.entrySet().removeIf(e -> { if (!found.contains(e.getKey())) { e.getKey().onUnequipped(living, e.getValue()); @@ -90,13 +97,16 @@ public class ItemTracker implements NbtSerialisable, Copyable, Tick if (!(living instanceof Pony)) { foundStacks.forEach(stack -> { - if (getTicks((Trackable)stack.getItem()) == 1) { - stack.inventoryTick(living.asWorld(), living.asEntity(), 0, false); - } + stack.inventoryTick(living.asWorld(), living.asEntity(), 0, false); }); } } + public long forceRemove(Trackable charm) { + @Nullable Long time = items.remove(charm); + return time == null ? 0 : time; + } + public long getTicks(Trackable charm) { return items.getOrDefault(charm.asItem(), 0L); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java b/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java index b84967f1..da56c65b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/AlicornAmuletItem.java @@ -134,7 +134,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab @Override public void onEquipped(Living wearer) { - wearer.playSound(USounds.ITEM_ALICORN_AMULET_CURSE, 3, 1); + wearer.playSound(USounds.ITEM_ALICORN_AMULET_CURSE, 0.5F, 1); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java b/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java index b59a878e..cb3426d5 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/AmuletItem.java @@ -68,7 +68,7 @@ public class AmuletItem extends WearableItem implements ChargeableItem { @Override public EquipmentSlot getSlotType(ItemStack stack) { - return EquipmentSlot.CHEST; + return TrinketsDelegate.hasTrinkets() ? EquipmentSlot.OFFHAND : EquipmentSlot.CHEST; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/util/SoundEmitter.java b/src/main/java/com/minelittlepony/unicopia/util/SoundEmitter.java index 033898ad..d9c8736a 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/SoundEmitter.java +++ b/src/main/java/com/minelittlepony/unicopia/util/SoundEmitter.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.util; import com.minelittlepony.unicopia.EntityConvertable; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; import net.minecraft.util.math.random.Random; @@ -26,7 +27,11 @@ public interface SoundEmitter extends EntityConvertable { } static void playSoundAt(Entity entity, SoundEvent sound, SoundCategory category, float volume, float pitch) { - entity.getWorld().playSound(null, entity.getX(), entity.getY(), entity.getZ(), sound, category, volume, pitch); + if (entity.getWorld().isClient && entity instanceof PlayerEntity p) { + entity.getWorld().playSound(p, entity.getX(), entity.getY(), entity.getZ(), sound, category, volume, pitch); + } else { + entity.getWorld().playSound(null, entity.getX(), entity.getY(), entity.getZ(), sound, category, volume, pitch); + } } static float getRandomPitch(Random rng) {