diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/C4Model.java b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/C4Model.java index 443965a4f..7d290d5f8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/C4Model.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/C4Model.java @@ -1,7 +1,7 @@ package com.atsuishio.superbwarfare.client.model.entity; import com.atsuishio.superbwarfare.ModUtils; -import com.atsuishio.superbwarfare.entity.C4Entity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import net.minecraft.resources.ResourceLocation; import software.bernie.geckolib.model.GeoModel; diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java index cf25d5321..4ebc196c6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java @@ -1,7 +1,7 @@ package com.atsuishio.superbwarfare.client.renderer.entity; import com.atsuishio.superbwarfare.client.model.entity.C4Model; -import com.atsuishio.superbwarfare.entity.C4Entity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java similarity index 89% rename from src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java rename to src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java index b1d493f71..9d0f5045a 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/C4Entity.java @@ -1,4 +1,4 @@ -package com.atsuishio.superbwarfare.entity; +package com.atsuishio.superbwarfare.entity.projectile; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.init.ModDamageTypes; @@ -44,6 +44,8 @@ public class C4Entity extends Projectile implements GeoEntity { protected static final EntityDataAccessor LAST_ATTACKER_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING); protected static final EntityDataAccessor TARGET_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING); + public static final EntityDataAccessor IS_CONTROLLABLE = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.BOOLEAN); + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); protected boolean inGround; protected boolean onEntity; @@ -56,18 +58,27 @@ public class C4Entity extends Projectile implements GeoEntity { public C4Entity(LivingEntity owner, Level level) { super(ModEntities.C_4.get(), level); + this.setOwner(owner); + } + + public C4Entity(LivingEntity owner, Level level, boolean isControllable) { + super(ModEntities.C_4.get(), level); + this.setOwner(owner); + this.entityData.set(IS_CONTROLLABLE, isControllable); } @Override protected void defineSynchedData() { this.entityData.define(LAST_ATTACKER_UUID, "undefined"); this.entityData.define(TARGET_UUID, "undefined"); + this.entityData.define(IS_CONTROLLABLE, false); } @Override public void addAdditionalSaveData(CompoundTag compound) { compound.putString("Target", this.entityData.get(TARGET_UUID)); compound.putString("LastAttacker", this.entityData.get(LAST_ATTACKER_UUID)); + compound.putBoolean("IsControllable", this.entityData.get(IS_CONTROLLABLE)); if (this.lastState != null) { compound.put("InBlockState", NbtUtils.writeBlockState(this.lastState)); @@ -87,6 +98,10 @@ public class C4Entity extends Projectile implements GeoEntity { if (compound.contains("InBlockState", 10)) { this.lastState = NbtUtils.readBlockState(this.level().holderLookup(Registries.BLOCK), compound.getCompound("InBlockState")); } + + if (compound.contains("IsControllable")) { + this.entityData.set(IS_CONTROLLABLE, compound.getBoolean("IsControllable")); + } } @Override @@ -108,16 +123,19 @@ public class C4Entity extends Projectile implements GeoEntity { public void tick() { super.tick(); - if (this.tickCount >= ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get()) { - this.explode(); - } + if (!this.entityData.get(IS_CONTROLLABLE)) { + if (this.tickCount >= ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get()) { + this.explode(); + } - if (ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get() - tickCount > 39 && tickCount %((20 * (ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get() - tickCount)) / ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get() + 1) == 0) { - this.level().playSound(null, this.getOnPos(), ModSounds.C4_BEEP.get(), SoundSource.PLAYERS, 1, 1); - } + int countdown = ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get(); + if (countdown - tickCount > 39 && tickCount % ((20 * (countdown - tickCount)) / countdown + 1) == 0) { + this.level().playSound(null, this.getOnPos(), ModSounds.C4_BEEP.get(), SoundSource.PLAYERS, 1, 1); + } - if (tickCount == ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get() - 39) { - this.level().playSound(null, this.getOnPos(), ModSounds.C4_FINAL.get(), SoundSource.PLAYERS, 2, 1); + if (tickCount == countdown - 39) { + this.level().playSound(null, this.getOnPos(), ModSounds.C4_FINAL.get(), SoundSource.PLAYERS, 2, 1); + } } Vec3 motion = this.getDeltaMovement(); @@ -347,4 +365,9 @@ public class C4Entity extends Projectile implements GeoEntity { protected float getWaterInertia() { return 0.6F; } + + @Override + public boolean isPickable() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java index 463605930..3096226a5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java @@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; -import com.atsuishio.superbwarfare.entity.C4Entity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.EnergyVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java index 6467e99ee..1699600cb 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java @@ -1,11 +1,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; -import com.atsuishio.superbwarfare.entity.C4Entity; -import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; -import com.atsuishio.superbwarfare.entity.projectile.LaserEntity; -import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; -import com.atsuishio.superbwarfare.entity.projectile.RgoGrenadeEntity; +import com.atsuishio.superbwarfare.entity.projectile.*; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModEntities; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java index 018495c95..b09d57b5e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java @@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; -import com.atsuishio.superbwarfare.entity.C4Entity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.LandArmorEntity; diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java b/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java index d55d71bbe..c8b347722 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java @@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.init; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.item.ArmorPlate; import com.atsuishio.superbwarfare.item.BatteryItem; +import com.atsuishio.superbwarfare.item.C4Bomb; import com.atsuishio.superbwarfare.item.gun.handgun.*; import com.atsuishio.superbwarfare.item.gun.heavy.Ntw20Item; import com.atsuishio.superbwarfare.item.gun.launcher.JavelinItem; @@ -107,6 +108,10 @@ public class ModTabs { ModItems.AMMO.getEntries().forEach(registryObject -> { if (registryObject.get() != ModItems.POTION_MORTAR_SHELL.get()) { output.accept(registryObject.get()); + + if (registryObject.get() == ModItems.C4_BOMB.get()) { + output.accept(C4Bomb.makeInstance()); + } } }); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java b/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java index 9c8603a23..2831f8409 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java @@ -1,7 +1,8 @@ package com.atsuishio.superbwarfare.item; import com.atsuishio.superbwarfare.client.TooltipTool; -import com.atsuishio.superbwarfare.entity.C4Entity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; +import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; @@ -19,6 +20,8 @@ import java.util.List; public class C4Bomb extends Item { + public static final String TAG_CONTROL = "Control"; + public C4Bomb() { super(new Item.Properties()); } @@ -28,7 +31,9 @@ public class C4Bomb extends Item { ItemStack stack = player.getItemInHand(hand); if (!level.isClientSide) { - C4Entity entity = new C4Entity(player, level); + boolean flag = stack.getOrCreateTag().getBoolean(TAG_CONTROL); + + C4Entity entity = new C4Entity(player, level, flag); entity.setPos(player.getX() + 0.25 * player.getLookAngle().x, player.getEyeY() - 0.2f + 0.25 * player.getLookAngle().y, player.getZ() + 0.25 * player.getLookAngle().z); entity.setDeltaMovement(0.5 * player.getLookAngle().x, 0.5 * player.getLookAngle().y, 0.5 * player.getLookAngle().z); entity.setOwner(player); @@ -52,5 +57,14 @@ public class C4Bomb extends Item { @Override public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, TooltipFlag pIsAdvanced) { TooltipTool.addDevelopingText(pTooltipComponents); + if (pStack.getOrCreateTag().getBoolean(TAG_CONTROL)) { + pTooltipComponents.add(Component.literal("Control")); + } + } + + public static ItemStack makeInstance() { + ItemStack stack = new ItemStack(ModItems.C4_BOMB.get()); + stack.getOrCreateTag().putBoolean(TAG_CONTROL, true); + return stack; } } diff --git a/src/main/java/com/atsuishio/superbwarfare/item/Detonator.java b/src/main/java/com/atsuishio/superbwarfare/item/Detonator.java index 612e1e911..89ed87e90 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/Detonator.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/Detonator.java @@ -1,6 +1,6 @@ package com.atsuishio.superbwarfare.item; -import com.atsuishio.superbwarfare.entity.C4Entity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.tools.EntityFindUtil; import net.minecraft.server.level.ServerPlayer; @@ -17,7 +17,8 @@ import java.util.List; import java.util.stream.StreamSupport; public class Detonator extends Item { -public Detonator() { + + public Detonator() { super(new Properties().stacksTo(1)); } @@ -26,6 +27,7 @@ public Detonator() { .filter(e -> e instanceof C4Entity c4 && c4.getOwner() == player) .toList(); } + @Override public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); @@ -35,11 +37,11 @@ public Detonator() { serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.C4_DETONATOR_CLICK.get(), SoundSource.PLAYERS, 1, 1); } - releaseUsing(stack, player.level(), player, 1); + this.releaseUsing(stack, player.level(), player, 1); List entities = getC4(player, player.level()); for (var e : entities) { - if (e instanceof C4Entity c4) { + if (e instanceof C4Entity c4 && c4.getEntityData().get(C4Entity.IS_CONTROLLABLE)) { c4.explode(); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java index e3a65efa8..a30a09dd9 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java @@ -1,8 +1,8 @@ package com.atsuishio.superbwarfare.tools; import com.atsuishio.superbwarfare.config.server.VehicleConfig; -import com.atsuishio.superbwarfare.entity.C4Entity; import com.atsuishio.superbwarfare.entity.ClaymoreEntity; +import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.AreaEffectCloud;