Skip to content

Commit

Permalink
feat: implement hidden explosive detonation
Browse files Browse the repository at this point in the history
  • Loading branch information
fenn7 committed Sep 8, 2023
1 parent 07f659f commit b37f62b
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package fenn7.grenadesandgadgets.commonside.block.custom;

import java.util.List;

import fenn7.grenadesandgadgets.commonside.block.GrenadesModBlockEntities;
import fenn7.grenadesandgadgets.commonside.block.entity.HiddenExplosiveBlockEntity;
import fenn7.grenadesandgadgets.commonside.item.custom.block.HiddenExplosiveBlockItem;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
Expand All @@ -13,6 +16,8 @@
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.context.LootContext;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
Expand Down Expand Up @@ -74,6 +79,17 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt
return ActionResult.SUCCESS;
}

@Override
public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) {
if (blockEntity instanceof HiddenExplosiveBlockEntity h) {
var blockNbt = h.createNbt();
if (blockNbt.contains(HiddenExplosiveBlockItem.DISGUISE_KEY)) {
Block.dropStack(world, pos, ItemStack.fromNbt(blockNbt.getCompound(HiddenExplosiveBlockItem.DISGUISE_KEY)));
}
}
super.afterBreak(world, player, pos, state, blockEntity, stack);
}

@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
Expand All @@ -100,4 +116,14 @@ public BlockState getPlacementState(ItemPlacementContext ctx) {
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.ENTITYBLOCK_ANIMATED;
}

@Override
public boolean hasComparatorOutput(BlockState state) {
return true;
}

@Override
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
return world.getBlockEntity(pos) instanceof HiddenExplosiveBlockEntity h && !h.getStack(0).isEmpty() ? 15 : 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package fenn7.grenadesandgadgets.commonside.block.entity;

import java.util.UUID;

import fenn7.grenadesandgadgets.client.screen.HiddenExplosiveScreenHandler;
import fenn7.grenadesandgadgets.commonside.block.GrenadesModBlockEntities;
import fenn7.grenadesandgadgets.commonside.block.custom.HiddenExplosiveBlock;
import fenn7.grenadesandgadgets.commonside.item.custom.block.HiddenExplosiveBlockItem;
import fenn7.grenadesandgadgets.commonside.item.custom.grenades.AbstractGrenadeItem;
import fenn7.grenadesandgadgets.commonside.item.custom.grenades.GrenadeItem;
import fenn7.grenadesandgadgets.commonside.util.GrenadesModUtil;
import fenn7.grenadesandgadgets.commonside.util.ImplementedInventory;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.minecraft.block.BlockState;
import net.minecraft.block.SculkSensorBlock;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.SculkSensorBlockEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories;
Expand All @@ -22,10 +29,16 @@
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
import net.minecraft.world.event.listener.GameEventListener;
import net.minecraft.world.event.listener.SculkSensorListener;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
Expand All @@ -35,13 +48,16 @@
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;

public class HiddenExplosiveBlockEntity extends BlockEntity implements IAnimatable, ExtendedScreenHandlerFactory, ImplementedInventory {
public class HiddenExplosiveBlockEntity extends BlockEntity implements IAnimatable, ExtendedScreenHandlerFactory, ImplementedInventory, SculkSensorListener.Callback {
public static final int MAX_ARMING_TICKS = 40;
private static final String NBT_TAG = "configuration.data";
private static final String LAST_USER = "last.user";
private static final String TITLE = "container.grenadesandgadgets.hidden_explosive";
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(1, ItemStack.EMPTY);
private final AnimationFactory factory = GrenadesModUtil.getAnimationFactoryFor(this);
private Item disguiseBlockItem;
private @Nullable PlayerEntity lastUser;
private @Nullable UUID lastUserUUID;

private final PropertyDelegate delegate;
private int currentArmingTicks = 0;
Expand Down Expand Up @@ -82,15 +98,40 @@ public int size() {

public static void tick(World world, BlockPos pos, BlockState state, HiddenExplosiveBlockEntity entity) {
if (!world.isClient) {
if (entity.armingFlag == 1 && !entity.getStack(0).isEmpty()) {
if (entity.currentArmingTicks < MAX_ARMING_TICKS) {
++entity.currentArmingTicks;
if (entity.currentArmingTicks >= MAX_ARMING_TICKS) {
world.setBlockState(pos, state.with(HiddenExplosiveBlock.ARMED, true));
}
entity.tickArming(world, pos, state);
if (state.get(HiddenExplosiveBlock.ARMED)) {
entity.detonate(world, pos);
}
}
}

private void detonate(World world, BlockPos pos) {
ItemStack stack = this.getStack(0);
if (stack.getItem() instanceof AbstractGrenadeItem grenadeItem && this.getLastUser() != null) {
var grenadeEntity = grenadeItem.createGrenadeAt(world, this.lastUser, stack);
GrenadeItem.addNbtModifier(stack, grenadeEntity);
this.removeStack(0);
grenadeEntity.setMaxAgeTicks(10);
grenadeEntity.setNoGravity(true);
grenadeEntity.setInvisible(true);
grenadeEntity.setPosition(Vec3d.ofCenter(this.directionID > 0 ? pos.offset(Direction.byId(this.directionID)) : pos));
world.spawnEntity(grenadeEntity);
world.breakBlock(pos, false);
}
}

private void tickArming(World world, BlockPos pos, BlockState state) {
if (this.armingFlag == 1 && !this.getStack(0).isEmpty()) {
if (this.currentArmingTicks < MAX_ARMING_TICKS) {
++this.currentArmingTicks;
if (this.currentArmingTicks >= MAX_ARMING_TICKS) {
world.setBlockState(pos, state.with(HiddenExplosiveBlock.ARMED, true));
}
} else {
entity.resetArming(world, pos, state);
}
} else {
world.setBlockState(pos, state.with(HiddenExplosiveBlock.ARMED, false));
if (this.currentArmingTicks > 0) {
--this.currentArmingTicks;
}
}
}
Expand All @@ -99,17 +140,30 @@ public PropertyDelegate getDelegate() {
return this.delegate;
}

public void resetArming(World world, BlockPos pos, BlockState state) {
world.setBlockState(pos, state.with(HiddenExplosiveBlock.ARMED, false));
if (this.currentArmingTicks > 0) {
--this.currentArmingTicks;
};
}

public Item getDisguiseBlockItem() {
return this.disguiseBlockItem;
}

private PlayerEntity getLastUser() {
if (this.lastUser != null && !this.lastUser.isRemoved()) {
return this.lastUser;
}
if (this.lastUserUUID != null && this.world instanceof ServerWorld) {
return this.world.getPlayerByUuid(this.lastUserUUID);
}
return null;
}

private void setLastUser(PlayerEntity player) {
this.lastUser = player;
this.lastUserUUID = player.getUuid();
}

@Override
public void onOpen(PlayerEntity player) {
this.setLastUser(player);
}

@Override
public void readNbt(NbtCompound nbt) {
Inventories.readNbt(nbt, this.inventory);
Expand All @@ -122,8 +176,9 @@ public void readNbt(NbtCompound nbt) {
for (int i = 0; i < configData.length; ++i) {
this.delegate.set(i, configData[i]);
}
//this.currentArmingTicks = nbt.getInt("current.arming.ticks");
//this.armingFlag = nbt.getInt("arming.flag");
if (nbt.containsUuid(LAST_USER)) {
this.lastUserUUID = nbt.getUuid(LAST_USER);
}
}

@Override
Expand All @@ -133,9 +188,10 @@ protected void writeNbt(NbtCompound nbt) {
if (this.disguiseBlockItem != null) {
nbt.put(HiddenExplosiveBlockItem.DISGUISE_KEY, this.disguiseBlockItem.getDefaultStack().writeNbt(new NbtCompound()));
}
//nbt.putInt("current.arming.ticks", this.currentArmingTicks);
//nbt.putInt("arming.flag", this.armingFlag);
nbt.putIntArray(NBT_TAG, new int[]{this.currentArmingTicks, this.armingFlag, this.detectRange, this.directionID});
if (this.lastUserUUID != null) {
nbt.putUuid(LAST_USER, this.lastUserUUID);
}
}

@Nullable
Expand Down Expand Up @@ -184,4 +240,19 @@ public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity pl
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
buf.writeBlockPos(this.pos);
}

@Override
public boolean accepts(World world, GameEventListener listener, BlockPos pos, GameEvent event, @Nullable Entity entity) {
boolean bl = event == GameEvent.BLOCK_DESTROY && pos.equals(this.getPos());
boolean bl2 = event == GameEvent.BLOCK_PLACE && pos.equals(this.getPos());
return !bl && !bl2 && SculkSensorBlock.isInactive(this.getCachedState());
}

@Override
public void accept(World world, GameEventListener listener, GameEvent event, int distance) {
BlockState blockState = this.getCachedState();
if (!world.isClient() && SculkSensorBlock.isInactive(blockState)) {
SculkSensorBlock.setActive(world, this.pos, blockState, SculkSensorBlockEntity.getPower(distance, listener.getRange()));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package fenn7.grenadesandgadgets.commonside.item.custom.grenades;

import static fenn7.grenadesandgadgets.client.network.GrenadesModS2CPackets.SYNC_GRENADE_S2C;
import static fenn7.grenadesandgadgets.commonside.item.recipe.custom.GrenadeModifierRecipe.CATACLYSMIC;
import static fenn7.grenadesandgadgets.commonside.item.recipe.custom.GrenadeModifierRecipe.ECHOING;
import static fenn7.grenadesandgadgets.commonside.item.recipe.custom.GrenadeModifierRecipe.ELASTIC;
Expand All @@ -16,14 +15,11 @@
import fenn7.grenadesandgadgets.commonside.entity.grenades.AbstractGrenadeEntity;
import fenn7.grenadesandgadgets.commonside.item.recipe.custom.GrenadeModifierRecipe;
import fenn7.grenadesandgadgets.commonside.util.GrenadesModUtil;
import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
Expand Down Expand Up @@ -54,7 +50,30 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand han
user.getItemCooldownManager().set(this, 20);
AbstractGrenadeEntity grenade = this.createGrenadeAt(world, user, user.getStackInHand(hand));
grenade.setItem(stack);
float speed = this.defaultSpeed;
float speed = this.defaultSpeed * addNbtModifier(stack, grenade);
this.setPitchYawVelocity(user, grenade, this.defaultRoll, speed, this.defaultDiv);
if (!world.isClient()) {
world.spawnEntity(grenade);
//ServerPlayNetworking.send((ServerPlayerEntity) user, SYNC_GRENADE_S2C, this.buildGrenadeBuf(grenade));
}
if (!user.isCreative()) {
stack.decrement(1);
}
return TypedActionResult.success(stack, world.isClient());
}

/*private PacketByteBuf buildGrenadeBuf(AbstractGrenadeEntity grenade) {
var buf = new PacketByteBuf(Unpooled.buffer());
buf.writeInt(grenade.getId());
buf.writeInt(grenade.getMaxAgeTicks());
buf.writeBoolean(grenade.getShouldBounce());
buf.writeFloat(grenade.getBounceMultiplier());
buf.writeFloat(grenade.getPower());
return buf;
}*/

public static float addNbtModifier(ItemStack stack, AbstractGrenadeEntity grenade) {
float speed = 1.0F;
switch (stack.getOrCreateNbt().getString(GrenadeModifierRecipe.MODIFIER_KEY)) {
case STICKY, ECHOING -> grenade.setShouldBounce(false);
case ELASTIC -> grenade.setBounceMultiplier(ELASTIC_BOUNCE_FACTOR);
Expand All @@ -79,25 +98,7 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand han
grenade.setBounceMultiplier(grenade.getBounceMultiplier() * CATACLYSMIC_BOUNCE_MULTIPLIER);
}
}
this.setPitchYawVelocity(user, grenade, this.defaultRoll, speed, this.defaultDiv);
if (!world.isClient()) {
world.spawnEntity(grenade);
ServerPlayNetworking.send((ServerPlayerEntity) user, SYNC_GRENADE_S2C, this.buildGrenadeBuf(grenade));
}
if (!user.isCreative()) {
stack.decrement(1);
}
return TypedActionResult.success(stack, world.isClient());
}

private PacketByteBuf buildGrenadeBuf(AbstractGrenadeEntity grenade) {
var buf = new PacketByteBuf(Unpooled.buffer());
buf.writeInt(grenade.getId());
buf.writeInt(grenade.getMaxAgeTicks());
buf.writeBoolean(grenade.getShouldBounce());
buf.writeFloat(grenade.getBounceMultiplier());
buf.writeFloat(grenade.getPower());
return buf;
return speed;
}

@Override
Expand All @@ -112,9 +113,10 @@ protected void setPitchYawVelocity(PlayerEntity user, AbstractGrenadeEntity gren
grenade.setVelocity(user, user.getPitch(), user.getYaw(), roll, speed, divergence);
}

protected abstract AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack);
public abstract AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack);

public float getDefaultSpeed() {
return this.defaultSpeed;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public ConvergenceGrenadeItem(Settings settings) {
}

@Override
protected AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
public AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
return new ConvergenceGrenadeEntity(world, player);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public DecoyGrenadeItem(Settings settings) {
}

@Override
protected AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
public AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
return new DecoyGrenadeEntity(world, player);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fenn7.grenadesandgadgets.commonside.item.custom.grenades;

import fenn7.grenadesandgadgets.commonside.entity.grenades.AbstractGrenadeEntity;
import fenn7.grenadesandgadgets.commonside.entity.grenades.ConvergenceGrenadeEntity;
import fenn7.grenadesandgadgets.commonside.entity.grenades.DivergenceGrenadeEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
Expand All @@ -14,7 +13,7 @@ public DivergenceGrenadeItem(Settings settings) {
}

@Override
protected AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
public AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
return new DivergenceGrenadeEntity(world, player);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package fenn7.grenadesandgadgets.commonside.item.custom.grenades;

import fenn7.grenadesandgadgets.commonside.entity.GrenadesModEntities;
import fenn7.grenadesandgadgets.commonside.entity.grenades.AbstractGrenadeEntity;
import fenn7.grenadesandgadgets.commonside.entity.grenades.IceGrenadeEntity;
import fenn7.grenadesandgadgets.commonside.status.GrenadesModStatus;
import fenn7.grenadesandgadgets.commonside.util.GrenadesModUtil;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;

public class IceGrenadeItem extends AbstractGrenadeItem {
Expand All @@ -21,7 +15,7 @@ public IceGrenadeItem(Settings settings) {
}

@Override
protected AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
public AbstractGrenadeEntity createGrenadeAt(World world, PlayerEntity player, ItemStack stack) {
return new IceGrenadeEntity(world, player);
}
}
Loading

0 comments on commit b37f62b

Please sign in to comment.