Skip to content

Commit

Permalink
Box block keeps inventory when broken
Browse files Browse the repository at this point in the history
  • Loading branch information
andersmmg committed May 2, 2024
1 parent 168d188 commit 90c8ca4
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 37 deletions.
37 changes: 37 additions & 0 deletions src/main/generated/data/fallout-stuff/loot_tables/blocks/box.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,43 @@
"entries": [
{
"type": "minecraft:item",
"functions": [
{
"function": "minecraft:copy_name",
"source": "block_entity"
},
{
"function": "minecraft:copy_nbt",
"ops": [
{
"op": "replace",
"source": "Lock",
"target": "BlockEntityTag.Lock"
},
{
"op": "replace",
"source": "LootTable",
"target": "BlockEntityTag.LootTable"
},
{
"op": "replace",
"source": "LootTableSeed",
"target": "BlockEntityTag.LootTableSeed"
}
],
"source": "block_entity"
},
{
"type": "fallout-stuff:box_be",
"entries": [
{
"type": "minecraft:dynamic",
"name": "minecraft:contents"
}
],
"function": "minecraft:set_contents"
}
],
"name": "fallout-stuff:box"
}
],
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/andersmmg/falloutstuff/block/ModBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*;
import net.minecraft.block.enums.Instrument;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
Expand All @@ -17,8 +18,8 @@ public class ModBlocks {
public static final Block VAULT_LIGHT_BLOCK = registerBlock("vault_light",
new VaultLightBlock(FabricBlockSettings.copyOf(Blocks.GLASS).nonOpaque()));

public static final Block BOX_BLOCK = registerBlock("box",
new BoxBlock(FabricBlockSettings.copyOf(Blocks.OAK_WOOD).nonOpaque()));
public static final Block BOX_BLOCK = registerBlockOnly("box",
new BoxBlock(FabricBlockSettings.create().mapColor(MapColor.BROWN).strength(0.8f).sounds(BlockSoundGroup.WOOL).nonOpaque()));
public static final Block VAULT_CRATE_BLOCK = registerBlock("vault_crate",
new VaultCrateBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()));
public static final Block FILE_CABINET_BLOCK = registerBlock("file_cabinet",
Expand Down Expand Up @@ -60,6 +61,10 @@ private static Block registerBlock(String name, Block block) {
return Registry.register(Registries.BLOCK, new Identifier(FalloutStuff.MOD_ID, name), block);
}

private static Block registerBlockOnly(String name, Block block) {
return Registry.register(Registries.BLOCK, new Identifier(FalloutStuff.MOD_ID, name), block);
}

private static Item registerBlockItem(String name, Block block) {
return Registry.register(Registries.ITEM, new Identifier(FalloutStuff.MOD_ID, name),
new BlockItem(block, new FabricItemSettings()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
package com.andersmmg.falloutstuff.block.custom;

import com.andersmmg.falloutstuff.block.ModBlocks;
import com.andersmmg.falloutstuff.block.entity.BoxBlockEntity;
import com.andersmmg.falloutstuff.block.entity.ModBlockEntities;
import com.andersmmg.falloutstuff.item.ModItems;
import com.andersmmg.falloutstuff.util.VoxelUtils;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.PiglinBrain;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.context.LootContextParameterSet;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.DirectionProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.*;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
Expand All @@ -27,9 +43,12 @@
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class BoxBlock extends BlockWithEntity {
public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING;
public static final BooleanProperty OPEN = Properties.OPEN;
public static final Identifier CONTENTS_DYNAMIC_DROP_ID = new Identifier("contents");

public BoxBlock(AbstractBlock.Settings settings) {
super(settings);
Expand All @@ -55,9 +74,8 @@ public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockSt
return;
}
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof Inventory) {
ItemScatterer.spawn(world, pos, (Inventory)((Object)blockEntity));
world.updateComparators(pos, this);
if (blockEntity instanceof BoxBlockEntity) {
world.updateComparators(pos, state.getBlock());
}
super.onStateReplaced(state, world, pos, newState, moved);
}
Expand All @@ -70,6 +88,79 @@ public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Ran
}
}

@Override
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof BoxBlockEntity boxBlockEntity) {
if (!world.isClient && player.isCreative() && !boxBlockEntity.isEmpty()) {
ItemStack itemStack = BoxBlock.getItemStack();
blockEntity.setStackNbt(itemStack);
if (boxBlockEntity.hasCustomName()) {
itemStack.setCustomName(boxBlockEntity.getCustomName());
}
ItemEntity itemEntity = new ItemEntity(world, (double)pos.getX() + 0.5, (double)pos.getY() + 0.5, (double)pos.getZ() + 0.5, itemStack);
itemEntity.setToDefaultPickupDelay();
world.spawnEntity(itemEntity);
} else {
boxBlockEntity.checkLootInteraction(player);
}
}
super.onBreak(world, pos, state, player);
}

public static ItemStack getItemStack() {
return new ItemStack(ModBlocks.BOX_BLOCK);
}

@Override
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
BlockEntity blockEntity = builder.getOptional(LootContextParameters.BLOCK_ENTITY);
if (blockEntity instanceof BoxBlockEntity boxBlockEntity) {
builder = builder.addDynamicDrop(CONTENTS_DYNAMIC_DROP_ID, lootConsumer -> {
for (int i = 0; i < boxBlockEntity.size(); ++i) {
lootConsumer.accept(boxBlockEntity.getStack(i));
}
});
}
return super.getDroppedStacks(state, builder);
}

@Override
public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) {
ItemStack itemStack = super.getPickStack(world, pos, state);
world.getBlockEntity(pos, ModBlockEntities.BOX_ENTITY).ifPresent(blockEntity -> blockEntity.setStackNbt(itemStack));
return itemStack;
}

@Override
public void appendTooltip(ItemStack stack, @Nullable BlockView world, List<Text> tooltip, TooltipContext options) {
super.appendTooltip(stack, world, tooltip, options);
NbtCompound nbtCompound = BlockItem.getBlockEntityNbt(stack);
if (nbtCompound != null) {
if (nbtCompound.contains("LootTable", NbtElement.STRING_TYPE)) {
tooltip.add(Text.literal("???????"));
}
if (nbtCompound.contains("Items", NbtElement.LIST_TYPE)) {
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(27, ItemStack.EMPTY);
Inventories.readNbt(nbtCompound, defaultedList);
int i = 0;
int j = 0;
for (ItemStack itemStack : defaultedList) {
if (itemStack.isEmpty()) continue;
++j;
if (i > 4) continue;
++i;
MutableText mutableText = itemStack.getName().copy();
mutableText.append(" x").append(String.valueOf(itemStack.getCount()));
tooltip.add(mutableText.formatted(Formatting.GRAY));
}
if (j - i > 0) {
tooltip.add(Text.translatable("container.box.more", j - i).formatted(Formatting.ITALIC).formatted(Formatting.GRAY));
}
}
}
}

@Override
@Nullable
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.screen.GenericContainerScreenHandler;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.sound.SoundCategory;
Expand All @@ -26,7 +27,9 @@

public class BoxBlockEntity extends LootableContainerBlockEntity {
private DefaultedList<ItemStack> items = DefaultedList.ofSize(size(), ItemStack.EMPTY);
private final ViewerCountManager stateManager = new ViewerCountManager(){
public static final String ITEMS_KEY = "Items";

private final ViewerCountManager stateManager = new ViewerCountManager() {

@Override
protected void onContainerOpen(World world, BlockPos pos, BlockState state) {
Expand All @@ -47,7 +50,7 @@ protected void onViewerCountUpdate(World world, BlockPos pos, BlockState state,
@Override
protected boolean isPlayerViewing(PlayerEntity player) {
if (player.currentScreenHandler instanceof GenericContainerScreenHandler) {
Inventory inventory = ((GenericContainerScreenHandler)player.currentScreenHandler).getInventory();
Inventory inventory = ((GenericContainerScreenHandler) player.currentScreenHandler).getInventory();
return inventory == BoxBlockEntity.this;
}
return false;
Expand All @@ -73,17 +76,25 @@ protected Text getContainerName() {
return Text.translatable(getCachedState().getBlock().getTranslationKey());
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
this.readInventoryNbt(nbt);
}

@Override
protected void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
Inventories.writeNbt(nbt, items);
if (!this.serializeLootTable(nbt)) {
Inventories.writeNbt(nbt, this.items, false);
}
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
Inventories.readNbt(nbt, items);
public void readInventoryNbt(NbtCompound nbt) {
this.items = DefaultedList.ofSize(this.size(), ItemStack.EMPTY);
if (!this.deserializeLootTable(nbt) && nbt.contains(ITEMS_KEY, NbtElement.LIST_TYPE)) {
Inventories.readNbt(nbt, this.items);
}
}

@Override
Expand Down Expand Up @@ -112,7 +123,7 @@ public void tick() {
}

void setOpen(BlockState state, boolean open) {
this.world.setBlockState(this.getPos(), (BlockState)state.with(FileCabinetBlock.OPEN, open), Block.NOTIFY_ALL);
this.world.setBlockState(this.getPos(), (BlockState) state.with(FileCabinetBlock.OPEN, open), Block.NOTIFY_ALL);
}

@Override
Expand All @@ -122,9 +133,9 @@ public int size() {

void playSound(BlockState state, SoundEvent soundEvent) {
Vec3i vec3i = state.get(VaultCrateBlock.FACING).getVector();
double d = (double)this.pos.getX() + 0.5 + (double)vec3i.getX() / 2.0;
double e = (double)this.pos.getY() + 0.5 + (double)vec3i.getY() / 2.0;
double f = (double)this.pos.getZ() + 0.5 + (double)vec3i.getZ() / 2.0;
double d = (double) this.pos.getX() + 0.5 + (double) vec3i.getX() / 2.0;
double e = (double) this.pos.getY() + 0.5 + (double) vec3i.getY() / 2.0;
double f = (double) this.pos.getZ() + 0.5 + (double) vec3i.getZ() / 2.0;
this.world.playSound(null, d, e, f, soundEvent, SoundCategory.BLOCKS, 0.5f, this.world.random.nextFloat() * 0.1f + 0.9f);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
package com.andersmmg.falloutstuff.datagen;

import com.andersmmg.falloutstuff.block.ModBlocks;
import com.andersmmg.falloutstuff.block.custom.BoxBlock;
import com.andersmmg.falloutstuff.block.entity.ModBlockEntities;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
import net.minecraft.block.Block;
import net.minecraft.loot.LootPool;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.entry.DynamicEntry;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.entry.LeafEntry;
import net.minecraft.loot.function.CopyNameLootFunction;
import net.minecraft.loot.function.CopyNbtLootFunction;
import net.minecraft.loot.function.SetContentsLootFunction;
import net.minecraft.loot.provider.nbt.ContextLootNbtProvider;
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;

public class ModLootTableProvider extends FabricBlockLootTableProvider {
public ModLootTableProvider(FabricDataOutput dataOutput) {
Expand All @@ -11,26 +24,30 @@ public ModLootTableProvider(FabricDataOutput dataOutput) {

@Override
public void generate() {
addDrop(ModBlocks.DANGER_IRON_BLOCK);
addDrop(ModBlocks.DANGER_STRIPES_BLOCK);
addDrop(ModBlocks.VAULT_LIGHT_BLOCK);

addDrop(ModBlocks.VAULT_CRATE_BLOCK);
addDrop(ModBlocks.BOX_BLOCK);
addDrop(ModBlocks.FILE_CABINET_BLOCK);
addDrop(ModBlocks.FILE_CABINET_DARK_BLOCK);

addDrop(ModBlocks.RED_BUTTON);
addDrop(ModBlocks.PLAIN_DARK_WOOD_DOOR, doorDrops(ModBlocks.PLAIN_DARK_WOOD_DOOR));

addDrop(ModBlocks.VAULT_POSTER_BLOCK_1);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_2);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_3);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_4);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_5);
addDrop(ModBlocks.MR_PEBBLES_POSTER_BLOCK);
addDrop(ModBlocks.NUKA_GIRL_POSTER_BLOCK);
addDrop(ModBlocks.VAULT_BOY_STATUE);
addDrop(ModBlocks.DANGER_IRON_BLOCK);
addDrop(ModBlocks.DANGER_STRIPES_BLOCK);
addDrop(ModBlocks.VAULT_LIGHT_BLOCK);

addDrop(ModBlocks.VAULT_CRATE_BLOCK);
addDrop(ModBlocks.BOX_BLOCK, boxBlockDrops(ModBlocks.BOX_BLOCK));
addDrop(ModBlocks.FILE_CABINET_BLOCK);
addDrop(ModBlocks.FILE_CABINET_DARK_BLOCK);

addDrop(ModBlocks.RED_BUTTON);
addDrop(ModBlocks.PLAIN_DARK_WOOD_DOOR, doorDrops(ModBlocks.PLAIN_DARK_WOOD_DOOR));

addDrop(ModBlocks.VAULT_POSTER_BLOCK_1);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_2);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_3);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_4);
addDrop(ModBlocks.VAULT_POSTER_BLOCK_5);
addDrop(ModBlocks.MR_PEBBLES_POSTER_BLOCK);
addDrop(ModBlocks.NUKA_GIRL_POSTER_BLOCK);
addDrop(ModBlocks.VAULT_BOY_STATUE);
}

public LootTable.Builder boxBlockDrops(Block drop) {
return LootTable.builder().pool(this.addSurvivesExplosionCondition(drop, LootPool.builder().rolls(ConstantLootNumberProvider.create(1.0f)).with(((LeafEntry.Builder<?>) ((LeafEntry.Builder<?>) ItemEntry.builder(drop).apply(CopyNameLootFunction.builder(CopyNameLootFunction.Source.BLOCK_ENTITY))).apply(CopyNbtLootFunction.builder(ContextLootNbtProvider.BLOCK_ENTITY).withOperation("Lock", "BlockEntityTag.Lock").withOperation("LootTable", "BlockEntityTag.LootTable").withOperation("LootTableSeed", "BlockEntityTag.LootTableSeed"))).apply(SetContentsLootFunction.builder(ModBlockEntities.BOX_ENTITY).withEntry(DynamicEntry.builder(BoxBlock.CONTENTS_DYNAMIC_DROP_ID))))));
}

}
4 changes: 4 additions & 0 deletions src/main/java/com/andersmmg/falloutstuff/item/ModItems.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.andersmmg.falloutstuff.item;

import com.andersmmg.falloutstuff.FalloutStuff;
import com.andersmmg.falloutstuff.block.ModBlocks;
import com.andersmmg.falloutstuff.item.custom.NukaColaItem;
import com.andersmmg.falloutstuff.item.custom.StimpakItem;

import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.block.Blocks;
import net.minecraft.item.*;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
Expand All @@ -19,6 +21,8 @@ public class ModItems {
public static final Item NUKA_COLA = registerItem("nuka_cola", new NukaColaItem(new FabricItemSettings().recipeRemainder(ModItems.NUKA_COLA_BOTTLE).food(ModFoodComponents.NUKA_COLA).maxCount(16)));
public static final Item NUKA_COLA_BOTTLE = registerItem("nuka_cola_bottle", new Item(new FabricItemSettings()));

public static final Item BOX_BLOCK = Items.register(new BlockItem(ModBlocks.BOX_BLOCK, new Item.Settings().maxCount(1)));

private static void addItemsToIngredientItemGroup(FabricItemGroupEntries entries) {
entries.add(CAP);
}
Expand Down
Loading

0 comments on commit 90c8ca4

Please sign in to comment.