添加拆弹器功能

This commit is contained in:
17146 2025-03-21 18:38:30 +08:00
parent 14d0731c07
commit e9cb7f5fa8
3 changed files with 82 additions and 7 deletions

View file

@ -22,6 +22,7 @@ import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.*; import net.minecraft.world.entity.*;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.entity.projectile.ProjectileUtil; import net.minecraft.world.entity.projectile.ProjectileUtil;
@ -46,6 +47,8 @@ public class C4Entity extends Projectile implements GeoEntity {
protected static final EntityDataAccessor<String> TARGET_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING); protected static final EntityDataAccessor<String> TARGET_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING);
public static final EntityDataAccessor<Boolean> IS_CONTROLLABLE = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.BOOLEAN); public static final EntityDataAccessor<Boolean> IS_CONTROLLABLE = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.BOOLEAN);
public static final int DEFAULT_DEFUSE_PROGRESS = 100;
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
protected boolean inGround; protected boolean inGround;
protected boolean onEntity; protected boolean onEntity;
@ -112,16 +115,12 @@ public class C4Entity extends Projectile implements GeoEntity {
} }
if (!player.getAbilities().instabuild) { if (!player.getAbilities().instabuild) {
ItemStack stack = new ItemStack(ModItems.C4_BOMB.get()); ItemHandlerHelper.giveItemToPlayer(player, this.getItemStack());
if (this.getEntityData().get(IS_CONTROLLABLE)) {
stack.getOrCreateTag().putBoolean("Control", true);
} }
ItemHandlerHelper.giveItemToPlayer(player, stack);
}
}
return InteractionResult.sidedSuccess(this.level().isClientSide()); return InteractionResult.sidedSuccess(this.level().isClientSide());
} }
return InteractionResult.PASS;
}
@Override @Override
public void tick() { public void tick() {
@ -374,4 +373,20 @@ public class C4Entity extends Projectile implements GeoEntity {
public boolean isPickable() { public boolean isPickable() {
return true; 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);
}
}
} }

View file

@ -1,6 +1,18 @@
package com.atsuishio.superbwarfare.item; 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.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
public class Defuser extends Item { public class Defuser extends Item {
@ -8,4 +20,44 @@ public class Defuser extends Item {
super(new Properties().durability(8)); super(new Properties().durability(8));
} }
@Override
public InteractionResultHolder<ItemStack> 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;
}
} }

View file

@ -44,4 +44,12 @@ public class FormatTool {
public static String format1DZ(double num, String str) { public static String format1DZ(double num, String str) {
return DECIMAL_FORMAT_1Z.format(num) + 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;
}
} }