Skip to content

Commit

Permalink
feat: fix remote bomb crash glitch
Browse files Browse the repository at this point in the history
  • Loading branch information
fenn7 committed Nov 9, 2023
1 parent 605ce1b commit 0d98152
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class RemoteExplosiveScreen extends HandledScreen<RemoteExplosiveScreenHandler> {
private static final Identifier SCREEN = new Identifier(GrenadesMod.MOD_ID, "textures/gui/remote_explosive_block_gui.png");
private static final String TIME_TITLE = "container.grenadesandgadgets.time_ticks";
private static final String ARMED = "container.grenadesandgadgets.armed";
private static final String ARMED = "container.grenadesandgadgets.armed_remote";
private static final int TPS = 20;
private static final int INCREMENT_BUTTONS = 4;
private static final int BUTTON_DIMENSION = 14;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.TntEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
Expand All @@ -24,14 +23,18 @@
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public abstract class AbstractDisguisedExplosiveBlockEntity extends BlockEntity implements ExtendedScreenHandlerFactory, ImplementedInventory {
protected static final String LAST_USER = "last.user";
protected static final Map<Item, String> PAYLOAD_TO_ENTITY = Map.of(
Items.TNT, "TNT"
Items.TNT, "TNT",
Items.TNT_MINECART, "TNT"
);
protected Item disguiseBlockItem;
protected @Nullable PlayerEntity lastUser;
Expand Down Expand Up @@ -61,7 +64,31 @@ protected void setLastUser(PlayerEntity player) {
this.lastUserUUID = player.getUuid();
}

public abstract void detonate(World world, BlockPos pos);
public void detonate(World world, BlockPos pos) {
if (!world.isClient()) {
this.handleDetonation(world, pos);
}
}

protected abstract void handleDetonation(World world, BlockPos pos);

protected void handlePayload(ItemStack stack, World world, BlockPos pos) {
Entity payload;
switch (PAYLOAD_TO_ENTITY.getOrDefault(stack.getItem(), "")) {
case "TNT" -> {
payload = new TntEntity(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, this.getLastUser());
((TntEntity) payload).setFuse(0);
}
default -> payload = null;
};
if (payload != null) {
payload.setNoGravity(true);
payload.setPosition(Vec3d.ofCenter(pos));
world.playSound(null, pos, SoundEvents.BLOCK_NOTE_BLOCK_HARP, SoundCategory.HOSTILE, 20.0F, 0.5F);
world.breakBlock(pos, false);
world.spawnEntity(payload);
}
}

public PropertyDelegate getDelegate() {
return this.delegate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.TntEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories;
Expand Down Expand Up @@ -104,21 +105,24 @@ public static void tick(World world, BlockPos pos, BlockState state, HiddenExplo
}
}

public void detonate(World world, BlockPos pos) {
@Override
protected void handleDetonation(World world, BlockPos pos) {
ItemStack stack = this.getStack(0);
if (stack.getItem() instanceof AbstractGrenadeItem grenadeItem && this.getLastUser() != null) {
this.removeStack(0);
if (stack.getItem() instanceof AbstractGrenadeItem grenadeItem) {
var grenadeEntity = grenadeItem.createGrenadeAt(world, this.getLastUser(), stack);
grenadeEntity.setItem(stack);
GrenadeItem.addNbtModifier(stack, grenadeEntity);
this.removeStack(0);
grenadeEntity.setMaxAgeTicks(5);
grenadeEntity.setNoGravity(true);
BlockPos potentialPos = pos.offset(Direction.byId(this.directionID));
grenadeEntity.setPosition(Vec3d.ofCenter(this.directionID > 0 ? (!world.getBlockState(potentialPos).isSolidBlock(world, pos) ? potentialPos : pos) : pos));
grenadeEntity.setPower(grenadeEntity.getPower() * (INCREASED_POWER_BASE + (0.9F - (MathHelper.clamp(this.detectRange, 1, 4) * INCREASED_POWER_PER_RANGE))));
world.playSound(null, pos, SoundEvents.BLOCK_NOTE_BLOCK_BASS, SoundCategory.HOSTILE, 20.0F, 0.5F);
world.playSound(null, pos, SoundEvents.BLOCK_NOTE_BLOCK_HARP, SoundCategory.HOSTILE, 20.0F, 0.5F);
world.breakBlock(pos, false);
world.spawnEntity(grenadeEntity);
} else {
this.handlePayload(stack, world, pos);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ public static void tick(World world, BlockPos pos, BlockState state, RemoteExplo
}
}

public void detonate(World world, BlockPos pos) {
@Override
protected void handleDetonation(World world, BlockPos pos) {
ItemStack stack = this.getStack(0);
this.removeStack(0);
if (stack.getItem() instanceof AbstractGrenadeItem grenadeItem && this.getLastUser() != null) {
if (stack.getItem() instanceof AbstractGrenadeItem grenadeItem) {
var grenadeEntity = grenadeItem.createGrenadeAt(world, this.getLastUser(), stack);
grenadeEntity.setItem(stack);
GrenadeItem.addNbtModifier(stack, grenadeEntity);
Expand All @@ -90,24 +91,8 @@ public void detonate(World world, BlockPos pos) {
world.playSound(null, pos, SoundEvents.BLOCK_NOTE_BLOCK_HARP, SoundCategory.HOSTILE, 20.0F, 0.5F);
world.breakBlock(pos, false);
world.spawnEntity(grenadeEntity);
//world.setBlockState(pos, Blocks.AIR.getDefaultState());
} else {
Entity payload;
switch (PAYLOAD_TO_ENTITY.get(stack.getItem())) {
case "TNT" -> {
payload = new TntEntity(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, this.getLastUser());
((TntEntity) payload).setFuse(0);
}
default -> payload = null;
};
if (payload != null) {
payload.setNoGravity(true);
payload.setPosition(Vec3d.ofCenter(pos));
world.playSound(null, pos, SoundEvents.BLOCK_NOTE_BLOCK_HARP, SoundCategory.HOSTILE, 20.0F, 0.5F);
world.breakBlock(pos, false);
world.spawnEntity(payload);
//world.setBlockState(pos, Blocks.AIR.getDefaultState());
}
this.handlePayload(stack, world, pos);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import fenn7.grenadesandgadgets.commonside.GrenadesMod;
import fenn7.grenadesandgadgets.commonside.block.custom.HiddenExplosiveBlock;
import fenn7.grenadesandgadgets.commonside.block.custom.RemoteExplosiveBlock;
import fenn7.grenadesandgadgets.commonside.block.entity.AbstractDisguisedExplosiveBlockEntity;
import fenn7.grenadesandgadgets.commonside.block.entity.HiddenExplosiveBlockEntity;
import fenn7.grenadesandgadgets.commonside.block.entity.RemoteExplosiveBlockEntity;
import fenn7.grenadesandgadgets.commonside.item.GrenadesModItems;
import fenn7.grenadesandgadgets.commonside.item.custom.misc.RemoteDetonatorItem;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;

public class GrenadesModCallbacks {
Expand All @@ -14,8 +20,15 @@ public static void registerCallbacks() {
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
BlockState state = world.getBlockState(pos);
BlockEntity blockEntity = world.getBlockEntity(pos);
if (!player.isSpectator() && blockEntity instanceof HiddenExplosiveBlockEntity h && state.get(HiddenExplosiveBlock.ARMED)) {
h.detonate(world, pos);
ItemStack stack = player.getStackInHand(hand);
if (!player.isSpectator()) {
if (blockEntity instanceof AbstractDisguisedExplosiveBlockEntity h) {
if (state.get(HiddenExplosiveBlock.ARMED)) {
h.detonate(world, pos);
} else if (h instanceof RemoteExplosiveBlockEntity && stack.getItem() instanceof RemoteDetonatorItem r) {
r.removeExplosivePosFromNbt(pos, stack.getOrCreateNbt(), player);
}
}
}
return ActionResult.PASS;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class RemoteDetonatorItem extends Item {
private static final String ALREADY = "container.grenadesandgadgets.already";
private static final String ADDED = "container.grenadesandgadgets.added";
private static final String MAXSIZE = "container.grenadesandgadgets.maxsize";
private static final String NOTFOUND = "container.grenadesandgadgets.notfound";
private static final String REMOVED = "container.grenadesandgadgets.removed";
private static final int MAX_LINKED_EXPLOSIVES = 8;

public RemoteDetonatorItem(Settings settings) {
Expand All @@ -46,7 +48,7 @@ public ActionResult useOnBlock(ItemUsageContext context) {
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context) {
super.appendTooltip(stack, world, tooltip, context);
var positions = stack.getOrCreateNbt().getLongArray(NBT_TAG);
tooltip.add(GrenadesModUtil.textOf("Linked Explosives: " + positions.length));
tooltip.add(GrenadesModUtil.textOf("Linked Explosives: " + positions.length + "/" + MAX_LINKED_EXPLOSIVES));
}

private void addExplosivePosToNbt(BlockPos explosivePos, NbtCompound nbt, PlayerEntity player) {
Expand All @@ -64,22 +66,38 @@ private void addExplosivePosToNbt(BlockPos explosivePos, NbtCompound nbt, Player
nbt.putLongArray(NBT_TAG, explosivePosList.stream().mapToLong(BlockPos::asLong).toArray());
}

public void removeExplosivePosFromNbt(BlockPos explosivePos, NbtCompound nbt, PlayerEntity player) {
var explosivePosList = new ArrayList<>(Arrays.stream(nbt.getLongArray(NBT_TAG)).mapToObj(BlockPos::fromLong).toList());
if (!explosivePosList.contains(explosivePos)) {
player.sendMessage(GrenadesModUtil.translatableTextOf(NOTFOUND), false);
} else {
if (!player.world.isClient) {
player.sendMessage(GrenadesModUtil.translatableTextOf(REMOVED).append(explosivePos.toShortString()), false);
}
explosivePosList.remove(explosivePos);
}
nbt.putLongArray(NBT_TAG, explosivePosList.stream().mapToLong(BlockPos::asLong).toArray());
}

@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
NbtCompound nbt = user.getStackInHand(hand).getOrCreateNbt();
var explosivePosList = new ArrayList<>(Arrays.stream(nbt.getLongArray(NBT_TAG)).mapToObj(BlockPos::fromLong).toList());
var usedPosList = new ArrayList<BlockPos>();
explosivePosList.forEach(pos -> {
if (user.isSneaking()) {
NbtCompound nbt = user.getStackInHand(hand).getOrCreateNbt();
var explosivePosList = new ArrayList<>(Arrays.stream(nbt.getLongArray(NBT_TAG)).mapToObj(BlockPos::fromLong).toList());
var usedPosList = new ArrayList<BlockPos>();
explosivePosList.forEach(pos -> {
if (world.getBlockEntity(pos) instanceof RemoteExplosiveBlockEntity) {
world.setBlockState(pos, world.getBlockState(pos).with(RemoteExplosiveBlock.ARMED, true));
usedPosList.add(pos);
}
});
if (!world.isClient) {
user.sendMessage(Text.of(pos.toShortString()), false);
user.sendMessage(GrenadesModUtil.textOf("Detonating " + usedPosList.size() + " explosives!"), false);
}
if (world.getBlockEntity(pos) instanceof RemoteExplosiveBlockEntity) {
world.setBlockState(pos, world.getBlockState(pos).with(RemoteExplosiveBlock.ARMED, true));
usedPosList.add(pos);
}
});
explosivePosList.removeAll(usedPosList);
nbt.putLongArray(NBT_TAG, explosivePosList.stream().mapToLong(BlockPos::asLong).toArray());
return TypedActionResult.consume(user.getStackInHand(hand));
explosivePosList.removeAll(usedPosList);
nbt.putLongArray(NBT_TAG, explosivePosList.stream().mapToLong(BlockPos::asLong).toArray());
return TypedActionResult.consume(user.getStackInHand(hand));
}
return super.use(world, user, hand);
}
}

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/main/resources/assets/grenadesandgadgets/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
"container.grenadesandgadgets.time_ticks": "Delay:",
"container.grenadesandgadgets.already": "§cAlready linked to this detonator!",
"container.grenadesandgadgets.added": "Linked to explosive at: ",
"container.grenadesandgadgets.maxsize": "§cCannot link any more explosives to this detonator!"
"container.grenadesandgadgets.maxsize": "§cCannot link any more explosives to this detonator!",
"container.grenadesandgadgets.notfound": "§cExplosive is not linked to this detonator!",
"container.grenadesandgadgets.removed": "Removed explosive at: ",
"container.grenadesandgadgets.armed_remote": "ARMED"
}

0 comments on commit 0d98152

Please sign in to comment.