diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java index 1b3f8331b..fc27ef976 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java @@ -22,6 +22,7 @@ import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.*; +import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.ProjectileUtil; @@ -46,6 +47,8 @@ public class C4Entity extends Projectile implements GeoEntity { protected static final EntityDataAccessor TARGET_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor IS_CONTROLLABLE = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.BOOLEAN); + public static final int DEFAULT_DEFUSE_PROGRESS = 100; + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); protected boolean inGround; protected boolean onEntity; @@ -112,15 +115,11 @@ public class C4Entity extends Projectile implements GeoEntity { } if (!player.getAbilities().instabuild) { - ItemStack stack = new ItemStack(ModItems.C4_BOMB.get()); - if (this.getEntityData().get(IS_CONTROLLABLE)) { - stack.getOrCreateTag().putBoolean("Control", true); - } - ItemHandlerHelper.giveItemToPlayer(player, stack); + ItemHandlerHelper.giveItemToPlayer(player, this.getItemStack()); } + return InteractionResult.sidedSuccess(this.level().isClientSide()); } - - return InteractionResult.sidedSuccess(this.level().isClientSide()); + return InteractionResult.PASS; } @Override @@ -374,4 +373,20 @@ public class C4Entity extends Projectile implements GeoEntity { public boolean isPickable() { return true; } + + public ItemStack getItemStack() { + ItemStack stack = new ItemStack(ModItems.C4_BOMB.get()); + if (this.getEntityData().get(IS_CONTROLLABLE)) { + stack.getOrCreateTag().putBoolean("Control", true); + } + return stack; + } + + public void defuse() { + this.discard(); + ItemEntity entity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), this.getItemStack()); + if (!this.level().isClientSide) { + this.level().addFreshEntity(entity); + } + } } \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/item/Defuser.java b/src/main/java/com/atsuishio/superbwarfare/item/Defuser.java index 563eabe43..ca7382e39 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/Defuser.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/Defuser.java @@ -1,6 +1,18 @@ package com.atsuishio.superbwarfare.item; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; +import com.atsuishio.superbwarfare.tools.FormatTool; +import com.atsuishio.superbwarfare.tools.TraceTool; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +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.level.Level; public class Defuser extends Item { @@ -8,4 +20,44 @@ public class Defuser extends Item { super(new Properties().durability(8)); } + @Override + public InteractionResultHolder use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) { + ItemStack stack = pPlayer.getItemInHand(pUsedHand); + if (findBombInSight(pPlayer) != null) { + pPlayer.startUsingItem(pUsedHand); + return InteractionResultHolder.consume(stack); + } + return InteractionResultHolder.fail(stack); + } + + private static C4Entity findBombInSight(Player player) { + Entity target = TraceTool.findLookingEntity(player, 4); + return target instanceof C4Entity c4Entity ? c4Entity : null; + } + + @Override + public void onUseTick(Level pLevel, LivingEntity pLivingEntity, ItemStack pStack, int pRemainingUseDuration) { + if (!(pLivingEntity instanceof Player player)) return; + var target = findBombInSight(player); + if (target == null) return; + + int useTick = pStack.getUseDuration() - pRemainingUseDuration; + + if (!pLevel.isClientSide) { + player.displayClientMessage(Component.literal( + FormatTool.format1DZZ((C4Entity.DEFAULT_DEFUSE_PROGRESS - useTick) / 20d, "s") + ).withStyle(ChatFormatting.GREEN), true); + } + + if (useTick >= C4Entity.DEFAULT_DEFUSE_PROGRESS) { + player.stopUsingItem(); + pStack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(player.getUsedItemHand())); + target.defuse(); + } + } + + @Override + public int getUseDuration(ItemStack pStack) { + return 72000; + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/FormatTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/FormatTool.java index 805c8a950..a9ab20249 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/FormatTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/FormatTool.java @@ -44,4 +44,12 @@ public class FormatTool { public static String format1DZ(double num, String str) { return DECIMAL_FORMAT_1Z.format(num) + str; } + + public static String format1DZZ(double num) { + return format1DZZ(num, ""); + } + + public static String format1DZZ(double num, String str) { + return DECIMAL_FORMAT_1ZZ.format(num) + str; + } }