diff --git a/common/src/main/java/toughasnails/api/enchantment/TANEnchantments.java b/common/src/main/java/toughasnails/api/enchantment/TANEnchantments.java index e20a7c7b..5085097c 100644 --- a/common/src/main/java/toughasnails/api/enchantment/TANEnchantments.java +++ b/common/src/main/java/toughasnails/api/enchantment/TANEnchantments.java @@ -9,4 +9,5 @@ public class TANEnchantments { public static Enchantment THERMAL_TUNING; + public static Enchantment WATER_CLEANSING; } diff --git a/common/src/main/java/toughasnails/enchantment/WaterCleansingEnchantment.java b/common/src/main/java/toughasnails/enchantment/WaterCleansingEnchantment.java new file mode 100644 index 00000000..56ddafa0 --- /dev/null +++ b/common/src/main/java/toughasnails/enchantment/WaterCleansingEnchantment.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2023, the Glitchfiend Team. + * All rights reserved. + ******************************************************************************/ +package toughasnails.enchantment; + +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentCategory; +import toughasnails.item.EmptyCanteenItem; + +public class WaterCleansingEnchantment extends Enchantment +{ + public WaterCleansingEnchantment() + { + // EnchantmentCategory is irrelevant for treasure only enchantments + super(Enchantment.Rarity.RARE, EnchantmentCategory.BREAKABLE, new EquipmentSlot[] { EquipmentSlot.MAINHAND } ); + } + + @Override + public boolean isTreasureOnly() + { + return true; + } + + @Override + public boolean canEnchant(ItemStack stack) + { + return stack.getItem() instanceof EmptyCanteenItem; + } +} diff --git a/common/src/main/java/toughasnails/init/ModEnchantments.java b/common/src/main/java/toughasnails/init/ModEnchantments.java index bbc6f72a..208c8423 100644 --- a/common/src/main/java/toughasnails/init/ModEnchantments.java +++ b/common/src/main/java/toughasnails/init/ModEnchantments.java @@ -9,6 +9,7 @@ import toughasnails.api.TANAPI; import toughasnails.api.enchantment.TANEnchantments; import toughasnails.enchantment.ThermalTuningEnchantment; +import toughasnails.enchantment.WaterCleansingEnchantment; import java.util.function.BiConsumer; @@ -17,6 +18,7 @@ public class ModEnchantments public static void registerEnchantments(BiConsumer func) { TANEnchantments.THERMAL_TUNING = register(func, "thermal_tuning", new ThermalTuningEnchantment()); + TANEnchantments.WATER_CLEANSING = register(func, "water_cleansing", new WaterCleansingEnchantment()); } private static Enchantment register(BiConsumer func, String name, Enchantment enchantment) diff --git a/common/src/main/java/toughasnails/item/EmptyCanteenItem.java b/common/src/main/java/toughasnails/item/EmptyCanteenItem.java index f9de9de5..49c3c8b1 100644 --- a/common/src/main/java/toughasnails/item/EmptyCanteenItem.java +++ b/common/src/main/java/toughasnails/item/EmptyCanteenItem.java @@ -16,13 +16,17 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemUtils; +import net.minecraft.world.item.Vanishable; +import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; +import org.jetbrains.annotations.NotNull; import toughasnails.api.block.TANBlocks; +import toughasnails.api.enchantment.TANEnchantments; import toughasnails.api.item.TANItems; import toughasnails.block.RainCollectorBlock; import toughasnails.init.ModTags; @@ -38,53 +42,57 @@ public EmptyCanteenItem(int tier, Properties properties) } @Override - public InteractionResultHolder use(Level world, Player player, InteractionHand hand) + public InteractionResultHolder use(@NotNull Level level, Player player, @NotNull InteractionHand hand) { - ItemStack stack = player.getItemInHand(hand); - HitResult rayTraceResult = getPlayerPOVHitResult(world, player, ClipContext.Fluid.SOURCE_ONLY); + return this.fillCanteen(level, player, player.getItemInHand(hand)); + } + + protected InteractionResultHolder fillCanteen(Level level, Player player, ItemStack stack) + { + HitResult rayTraceResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.SOURCE_ONLY); if (rayTraceResult.getType() == HitResult.Type.BLOCK) { BlockPos pos = ((BlockHitResult)rayTraceResult).getBlockPos(); - if (world.mayInteract(player, pos)) + if (level.mayInteract(player, pos)) { - BlockState state = world.getBlockState(pos); + BlockState state = level.getBlockState(pos); if (state.getBlock() instanceof RainCollectorBlock) { // Fill the canteen from purified water from a rain collector int waterLevel = state.getValue(RainCollectorBlock.LEVEL); - if (waterLevel > 0 && !world.isClientSide()) + if (waterLevel > 0 && !level.isClientSide()) { - world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); - ((RainCollectorBlock) TANBlocks.RAIN_COLLECTOR).setWaterLevel(world, pos, state, waterLevel - 1); + level.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); + ((RainCollectorBlock) TANBlocks.RAIN_COLLECTOR).setWaterLevel(level, pos, state, waterLevel - 1); return InteractionResultHolder.success(this.replaceCanteen(stack, player, new ItemStack(getPurifiedWaterCanteen()))); } } - else if (world.getFluidState(pos).is(FluidTags.WATER)) + else if (level.getFluidState(pos).is(FluidTags.WATER)) { // Fill the canteen with water in the world - world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); + level.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); Holder biome = player.level().getBiome(player.blockPosition()); Item canteenItem; - if (biome.is(ModTags.Biomes.DIRTY_WATER_BIOMES)) + if (EnchantmentHelper.getItemEnchantmentLevel(TANEnchantments.WATER_CLEANSING, stack) > 0 || biome.is(ModTags.Biomes.PURIFIED_WATER_BIOMES)) { - canteenItem = getDirtyWaterCanteen(); + canteenItem = getPurifiedWaterCanteen(); } - else if (biome.is(ModTags.Biomes.PURIFIED_WATER_BIOMES)) + else if (biome.is(ModTags.Biomes.DIRTY_WATER_BIOMES)) { - canteenItem = getPurifiedWaterCanteen(); + canteenItem = getDirtyWaterCanteen(); } else { canteenItem = getWaterCanteen(); } - return InteractionResultHolder.sidedSuccess(this.replaceCanteen(stack, player, new ItemStack(canteenItem)), world.isClientSide()); + return InteractionResultHolder.sidedSuccess(this.replaceCanteen(stack, player, new ItemStack(canteenItem)), level.isClientSide()); } } } @@ -92,9 +100,24 @@ else if (biome.is(ModTags.Biomes.PURIFIED_WATER_BIOMES)) return InteractionResultHolder.pass(stack); } + @Override + public boolean isEnchantable(ItemStack stack) + { + return true; + } + + @Override + public boolean canBeDepleted() + { + return true; + } + protected ItemStack replaceCanteen(ItemStack oldStack, Player player, ItemStack newStack) { player.awardStat(Stats.ITEM_USED.get(this)); + + // Copy enchantments from the old stack to the new stack + EnchantmentHelper.setEnchantments(EnchantmentHelper.getEnchantments(oldStack), newStack); return ItemUtils.createFilledResult(oldStack, player, newStack); } diff --git a/common/src/main/java/toughasnails/item/FilledCanteenItem.java b/common/src/main/java/toughasnails/item/FilledCanteenItem.java index f4ef863f..8e6e1279 100644 --- a/common/src/main/java/toughasnails/item/FilledCanteenItem.java +++ b/common/src/main/java/toughasnails/item/FilledCanteenItem.java @@ -4,106 +4,62 @@ ******************************************************************************/ package toughasnails.item; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; import net.minecraft.stats.Stats; -import net.minecraft.tags.FluidTags; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemUtils; import net.minecraft.world.item.UseAnim; -import net.minecraft.world.level.ClipContext; +import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; -import toughasnails.api.block.TANBlocks; import toughasnails.api.item.TANItems; import toughasnails.api.thirst.ThirstHelper; -import toughasnails.block.RainCollectorBlock; -import toughasnails.init.ModTags; -public class FilledCanteenItem extends Item -{ - int tier; +import java.util.concurrent.atomic.AtomicBoolean; +public class FilledCanteenItem extends EmptyCanteenItem +{ public FilledCanteenItem(int tier, Properties properties) { - super(properties); - this.tier = tier; + super(tier, properties); + } + + @Override + public void inventoryTick(ItemStack stack, Level level, Entity entity, int slot, boolean selected) + { + if (!(entity instanceof Player player) || stack.getItem() == getPurifiedWaterCanteen() || EnchantmentHelper.getEnchantments(stack).isEmpty()) + return; + + // Create a new stack with the same damage value, except purified + ItemStack newStack = new ItemStack(getPurifiedWaterCanteen()); + newStack.setDamageValue(stack.getDamageValue()); + EnchantmentHelper.setEnchantments(EnchantmentHelper.getEnchantments(stack), newStack); + + // Replace the current stack in the player's inventory + player.getInventory().setItem(slot, newStack); } @Override - public InteractionResultHolder use(Level world, Player player, InteractionHand hand) + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); - HitResult rayTraceResult = getPlayerPOVHitResult(world, player, ClipContext.Fluid.SOURCE_ONLY); + InteractionResultHolder result; - if (rayTraceResult.getType() == HitResult.Type.BLOCK) + if ((result = this.fillCanteen(level, player, stack)).getResult().consumesAction()) { - BlockPos pos = ((BlockHitResult)rayTraceResult).getBlockPos(); - - if (world.mayInteract(player, pos)) - { - BlockState state = world.getBlockState(pos); - - if (state.getBlock() instanceof RainCollectorBlock) - { - // Fill the canteen from purified water from a rain collector - int waterLevel = state.getValue(RainCollectorBlock.LEVEL); - - if (waterLevel > 0 && !world.isClientSide()) - { - world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); - ((RainCollectorBlock) TANBlocks.RAIN_COLLECTOR).setWaterLevel(world, pos, state, waterLevel - 1); - return InteractionResultHolder.success(this.replaceCanteen(stack, player, new ItemStack(getPurifiedWaterCanteen()))); - } - } - else if (world.getFluidState(pos).is(FluidTags.WATER)) - { - // Fill the canteen with water in the world - world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0F, 1.0F); - - Holder biome = player.level().getBiome(player.blockPosition()); - Item canteenItem; - - if (biome.is(ModTags.Biomes.DIRTY_WATER_BIOMES)) - { - canteenItem = getDirtyWaterCanteen(); - } - else if (biome.is(ModTags.Biomes.PURIFIED_WATER_BIOMES)) - { - canteenItem = getPurifiedWaterCanteen(); - } - else - { - canteenItem = getWaterCanteen(); - } - - return InteractionResultHolder.sidedSuccess(this.replaceCanteen(stack, player, new ItemStack(canteenItem)), world.isClientSide()); - } - } + return result; } if (ThirstHelper.canDrink(player, this.canAlwaysDrink())) { - return ItemUtils.startUsingInstantly(world, player, hand); + return ItemUtils.startUsingInstantly(level, player, hand); } - return InteractionResultHolder.fail(player.getItemInHand(hand)); - } - - protected ItemStack replaceCanteen(ItemStack oldStack, Player player, ItemStack newStack) - { - player.awardStat(Stats.ITEM_USED.get(this)); - return ItemUtils.createFilledResult(oldStack, player, newStack); + return InteractionResultHolder.fail(stack); } @Override @@ -120,11 +76,14 @@ public ItemStack finishUsingItem(ItemStack stack, Level worldIn, LivingEntity en // Damage the item if we're on the server and the player isn't in creative mode if (!worldIn.isClientSide && !player.getAbilities().instabuild) { - boolean[] broken = new boolean[]{false}; - stack.hurtAndBreak(1, player, (entity) -> broken[0] = true); - if (broken[0]) + ItemStack emptyStack = new ItemStack(getEmptyCanteen()); + EnchantmentHelper.setEnchantments(EnchantmentHelper.getEnchantments(stack), emptyStack); + + AtomicBoolean broken = new AtomicBoolean(false); + stack.hurtAndBreak(1, player, (entity) -> broken.set(true)); + if (broken.get()) { - return new ItemStack(getEmptyCanteen()); + return emptyStack; } } @@ -143,12 +102,6 @@ public UseAnim getUseAnimation(ItemStack stack) return UseAnim.DRINK; } - @Override - public boolean isEnchantable(ItemStack stack) - { - return false; - } - public boolean canAlwaysDrink() { return false; @@ -166,43 +119,4 @@ public Item getEmptyCanteen() case 5: return TANItems.EMPTY_NETHERITE_CANTEEN; } } - - public Item getDirtyWaterCanteen() - { - switch (this.tier) - { - default: case 0: return TANItems.LEATHER_DIRTY_WATER_CANTEEN; - case 1: return TANItems.COPPER_DIRTY_WATER_CANTEEN; - case 2: return TANItems.IRON_DIRTY_WATER_CANTEEN; - case 3: return TANItems.GOLD_DIRTY_WATER_CANTEEN; - case 4: return TANItems.DIAMOND_DIRTY_WATER_CANTEEN; - case 5: return TANItems.NETHERITE_DIRTY_WATER_CANTEEN; - } - } - - public Item getWaterCanteen() - { - switch (this.tier) - { - default: case 0: return TANItems.LEATHER_WATER_CANTEEN; - case 1: return TANItems.COPPER_WATER_CANTEEN; - case 2: return TANItems.IRON_WATER_CANTEEN; - case 3: return TANItems.GOLD_WATER_CANTEEN; - case 4: return TANItems.DIAMOND_WATER_CANTEEN; - case 5: return TANItems.NETHERITE_WATER_CANTEEN; - } - } - - public Item getPurifiedWaterCanteen() - { - switch (this.tier) - { - default: case 0: return TANItems.LEATHER_PURIFIED_WATER_CANTEEN; - case 1: return TANItems.COPPER_PURIFIED_WATER_CANTEEN; - case 2: return TANItems.IRON_PURIFIED_WATER_CANTEEN; - case 3: return TANItems.GOLD_PURIFIED_WATER_CANTEEN; - case 4: return TANItems.DIAMOND_PURIFIED_WATER_CANTEEN; - case 5: return TANItems.NETHERITE_PURIFIED_WATER_CANTEEN; - } - } } diff --git a/common/src/main/resources/assets/toughasnails/lang/en_us.json b/common/src/main/resources/assets/toughasnails/lang/en_us.json index e188c46b..ab919a09 100644 --- a/common/src/main/resources/assets/toughasnails/lang/en_us.json +++ b/common/src/main/resources/assets/toughasnails/lang/en_us.json @@ -27,6 +27,7 @@ "effect.toughasnails.internal_chill": "Internal Chill", "effect.toughasnails.internal_chill.description": "Provides a slight decrease in body temperature for the duration. Will not cause hypothermia.", "enchantment.toughasnails.thermal_tuning": "Thermal Tuning", + "enchantment.toughasnails.water_cleansing": "Water Cleansing", "block.toughasnails.rain_collector": "Rain Collector", "block.toughasnails.temperature_gauge": "Temperature Gauge",