From 64cbf5f7796f33d6c6a0315e58ac4871722565b4 Mon Sep 17 00:00:00 2001 From: Gegy Date: Wed, 1 Nov 2023 03:44:39 +0100 Subject: [PATCH] Recycle collectible compass into coins --- .../extras/entity/CollectibleEntity.java | 24 ++++++++++-- .../extras/item/CollectibleCompassItem.java | 39 +++++++++++++------ .../extras/item/ExtraItemProperties.java | 7 ++-- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/lovetropics/extras/entity/CollectibleEntity.java b/src/main/java/com/lovetropics/extras/entity/CollectibleEntity.java index 09f1a8ea..4a2e5967 100644 --- a/src/main/java/com/lovetropics/extras/entity/CollectibleEntity.java +++ b/src/main/java/com/lovetropics/extras/entity/CollectibleEntity.java @@ -1,7 +1,9 @@ package com.lovetropics.extras.entity; +import com.lovetropics.extras.ExtraItems; import com.lovetropics.extras.collectible.Collectible; import com.lovetropics.extras.collectible.CollectibleStore; +import com.lovetropics.extras.item.CollectibleCompassItem; import com.mojang.logging.LogUtils; import net.minecraft.Util; import net.minecraft.nbt.CompoundTag; @@ -12,13 +14,13 @@ import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import org.slf4j.Logger; import javax.annotation.Nullable; -import java.util.UUID; public class CollectibleEntity extends Entity { private static final Logger LOGGER = LogUtils.getLogger(); @@ -51,8 +53,24 @@ protected void defineSynchedData() { public void playerTouch(final Player player) { if (!level().isClientSide && collectible != null) { final CollectibleStore collectibles = CollectibleStore.getNullable(player); - if (collectibles != null) { - collectibles.give(collectible); + if (collectibles != null && collectibles.give(collectible)) { + recycleCollectibleCompass(player); + } + } + } + + private void recycleCollectibleCompass(final Player player) { + final Inventory inventory = player.getInventory(); + for (int i = 0; i < inventory.getContainerSize(); i++) { + final ItemStack stack = inventory.getItem(i); + final CollectibleCompassItem.Target target = CollectibleCompassItem.getTarget(stack); + if (target == null || !target.id().equals(getUUID())) { + continue; + } + inventory.removeItemNoUpdate(i); + final int coinCount = CollectibleCompassItem.getCoinCount(stack); + if (coinCount > 0) { + inventory.placeItemBackInInventory(new ItemStack(ExtraItems.TROPICOIN, coinCount)); } } } diff --git a/src/main/java/com/lovetropics/extras/item/CollectibleCompassItem.java b/src/main/java/com/lovetropics/extras/item/CollectibleCompassItem.java index d2ec4dc2..1205cf1c 100644 --- a/src/main/java/com/lovetropics/extras/item/CollectibleCompassItem.java +++ b/src/main/java/com/lovetropics/extras/item/CollectibleCompassItem.java @@ -5,16 +5,17 @@ import com.lovetropics.extras.collectible.Collectible; import com.lovetropics.extras.collectible.CollectibleStore; import com.lovetropics.extras.entity.CollectibleEntity; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.ChatFormatting; import net.minecraft.SharedConstants; import net.minecraft.Util; -import net.minecraft.core.BlockPos; import net.minecraft.core.GlobalPos; +import net.minecraft.core.UUIDUtil; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResultHolder; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -22,9 +23,11 @@ import javax.annotation.Nullable; import java.util.List; +import java.util.UUID; public class CollectibleCompassItem extends Item { private static final String TAG_TARGET = "target"; + private static final String COIN_COUNT = "coin_count"; private static final String ENTITY_TAG_IGNORE = "compass_hidden"; private static final int COOLDOWN_TICKS = SharedConstants.TICKS_PER_SECOND * 5; @@ -35,20 +38,27 @@ public CollectibleCompassItem(final Properties properties) { } @Nullable - public static GlobalPos getTarget(final ItemStack stack) { + public static Target getTarget(final ItemStack stack) { if (!stack.is(ExtraItems.COLLECTIBLE_COMPASS.get())) { return null; } final CompoundTag tag = stack.getTag(); if (tag != null && tag.contains(TAG_TARGET)) { - return GlobalPos.CODEC.parse(NbtOps.INSTANCE, tag.getCompound(TAG_TARGET)).result().orElse(null); + return Target.CODEC.parse(NbtOps.INSTANCE, tag.getCompound(TAG_TARGET)).result().orElse(null); } return null; } - private static void setTarget(final ItemStack stack, final GlobalPos pos) { + public static int getCoinCount(final ItemStack stack) { + if (stack.getTag() == null) { + return 0; + } + return stack.getTag().getInt(COIN_COUNT); + } + + private static void setTarget(final ItemStack stack, final Target target) { final CompoundTag tag = stack.getOrCreateTag(); - tag.put(TAG_TARGET, Util.getOrThrow(GlobalPos.CODEC.encodeStart(NbtOps.INSTANCE, pos), IllegalStateException::new)); + tag.put(TAG_TARGET, Util.getOrThrow(Target.CODEC.encodeStart(NbtOps.INSTANCE, target), IllegalStateException::new)); } private static boolean hasTarget(final ItemStack stack) { @@ -67,9 +77,9 @@ public InteractionResultHolder use(final Level level, final Player pl player.sendSystemMessage(ExtraLangKeys.COLLECTIBLE_COMPASS_ALREADY_USED.get().withStyle(ChatFormatting.RED)); return InteractionResultHolder.fail(stack); } - final GlobalPos pos = tryLocateCollectible(level, player); - if (pos != null) { - setTarget(stack, pos); + final Target target = tryLocateCollectible(level, player); + if (target != null) { + setTarget(stack, target); player.sendSystemMessage(ExtraLangKeys.COLLECTIBLE_COMPASS_SUCCESS.get().withStyle(ChatFormatting.GOLD)); } else { player.sendSystemMessage(ExtraLangKeys.COLLECTIBLE_COMPASS_FAIL.get().withStyle(ChatFormatting.RED)); @@ -78,7 +88,7 @@ public InteractionResultHolder use(final Level level, final Player pl } @Nullable - private static GlobalPos tryLocateCollectible(final Level level, final Player player) { + private static Target tryLocateCollectible(final Level level, final Player player) { final CollectibleStore collectibles = CollectibleStore.getNullable(player); if (collectibles == null) { return null; @@ -93,7 +103,7 @@ private static GlobalPos tryLocateCollectible(final Level level, final Player pl }); return Util.getRandomSafe(candidates, player.getRandom()) - .map(entity -> GlobalPos.of(level.dimension(), entity.blockPosition())) + .map(entity -> new Target(GlobalPos.of(level.dimension(), entity.blockPosition()), entity.getUUID())) .orElse(null); } @@ -101,4 +111,11 @@ private static GlobalPos tryLocateCollectible(final Level level, final Player pl public boolean isFoil(final ItemStack stack) { return hasTarget(stack); } + + public record Target(GlobalPos pos, UUID id) { + public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( + GlobalPos.CODEC.fieldOf("pos").forGetter(Target::pos), + UUIDUtil.CODEC.fieldOf("id").forGetter(Target::id) + ).apply(i, Target::new)); + } } diff --git a/src/main/java/com/lovetropics/extras/item/ExtraItemProperties.java b/src/main/java/com/lovetropics/extras/item/ExtraItemProperties.java index 8ebde371..5ef5246d 100644 --- a/src/main/java/com/lovetropics/extras/item/ExtraItemProperties.java +++ b/src/main/java/com/lovetropics/extras/item/ExtraItemProperties.java @@ -12,9 +12,10 @@ public class ExtraItemProperties { public static final ResourceLocation UNSEEN = new ResourceLocation(LTExtras.MODID, "unseen"); public static void register() { - ItemProperties.register(ExtraItems.COLLECTIBLE_COMPASS.get(), new ResourceLocation("angle"), new CompassItemPropertyFunction( - (level, stack, entity) -> CollectibleCompassItem.getTarget(stack)) - ); + ItemProperties.register(ExtraItems.COLLECTIBLE_COMPASS.get(), new ResourceLocation("angle"), new CompassItemPropertyFunction((level, stack, entity) -> { + final CollectibleCompassItem.Target target = CollectibleCompassItem.getTarget(stack); + return target != null ? target.pos() : null; + })); ItemProperties.register(ExtraItems.COLLECTIBLE_BASKET.get(), UNSEEN, (ClampedItemPropertyFunction) (stack, level, entity, seed) -> { final ClientCollectiblesList collectibles = ClientCollectiblesList.getOrNull();