From 99668e129dba4d89fe531efe7af0f61a2847f0cb Mon Sep 17 00:00:00 2001 From: Jottyfan Date: Mon, 10 Jun 2024 20:08:51 +0200 Subject: [PATCH] added item hoarder --- .../blockentity/ItemHoarderBlockEntity.java | 155 ++++++++++++++++++ .../quickiemod/blocks/BlockItemhoarder.java | 92 +++++++++++ .../quickiemod/blocks/QuickieBlocks.java | 1 + .../quickiemod/init/RegistryManager.java | 2 + .../quickiemod/blockstates/itemhoarder.json | 7 + .../quickiemod/models/block/itemhoarder.json | 6 + .../quickiemod/models/item/itemhoarder.json | 10 ++ .../quickiemod/textures/block/itemhoarder.png | Bin 0 -> 2894 bytes .../shaped_itemhoarder_from_barrel.json | 20 +++ .../shaped_itemhoarder_from_chest.json | 20 +++ 10 files changed, 313 insertions(+) create mode 100644 src/main/java/de/jottyfan/quickiemod/blockentity/ItemHoarderBlockEntity.java create mode 100644 src/main/java/de/jottyfan/quickiemod/blocks/BlockItemhoarder.java create mode 100644 src/main/resources/assets/quickiemod/blockstates/itemhoarder.json create mode 100644 src/main/resources/assets/quickiemod/models/block/itemhoarder.json create mode 100644 src/main/resources/assets/quickiemod/models/item/itemhoarder.json create mode 100644 src/main/resources/assets/quickiemod/textures/block/itemhoarder.png create mode 100644 src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_barrel.json create mode 100644 src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_chest.json diff --git a/src/main/java/de/jottyfan/quickiemod/blockentity/ItemHoarderBlockEntity.java b/src/main/java/de/jottyfan/quickiemod/blockentity/ItemHoarderBlockEntity.java new file mode 100644 index 0000000..9a83ffc --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/blockentity/ItemHoarderBlockEntity.java @@ -0,0 +1,155 @@ +package de.jottyfan.quickiemod.blockentity; + +import java.util.ArrayList; +import java.util.List; + +import de.jottyfan.quickiemod.init.RegistryManager; +import de.jottyfan.quickiemod.text.PrefixedText; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.LootableContainerBlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.Entity.RemovalReason; +import net.minecraft.entity.ItemEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventories; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper.WrapperLookup; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.text.Text; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.World; + +/** + * + * @author jotty + * + */ +public class ItemHoarderBlockEntity extends LootableContainerBlockEntity { + private DefaultedList stacks; + private float suckradius; + + public ItemHoarderBlockEntity(BlockPos pos, BlockState state) { + super(RegistryManager.ITEMHOARDER, pos, state); + stacks = DefaultedList.ofSize(54, ItemStack.EMPTY); + setSuckradius(4f); // TODO: make it level up - able and start with 2 + } + + // TODO: see https://fabricmc.net/wiki/tutorial:containers for a real chest + + public final static boolean setStackToSlots(ItemStack stack, List stacks) { + for (ItemStack slot : stacks) { + if (slot.getItem().equals(stack.getItem())) { + slot.increment(stack.getCount()); + return true; + } + } // if not found, seek for an empty stack instead + for (ItemStack slot : stacks) { + if (slot.isEmpty()) { + Integer index = stacks.indexOf(slot); + stacks.set(index, stack.copy()); + return true; + } + } + return false; + } + + public static void tick(World world, BlockPos pos, BlockState state, BlockEntity be) { + if (be instanceof ItemHoarderBlockEntity) { + ItemHoarderBlockEntity ihbe = (ItemHoarderBlockEntity) be; + Box box = new Box(pos).expand(ihbe.getSuckradius()); + List entities = world.getOtherEntities(null, box); + for (Entity entity : entities) { + if (entity instanceof ItemEntity) { + ItemEntity itemEntity = (ItemEntity) entity; + if (itemEntity.isAlive()) { + ItemStack stack = itemEntity.getStack(); + if (stack != null) { + if (ItemHoarderBlockEntity.setStackToSlots(stack, ihbe.getStacks())) { + itemEntity.remove(RemovalReason.DISCARDED); + } // else inventory is full + } + } + } + } + } + } + + @Override + protected void writeNbt(NbtCompound nbt, WrapperLookup registryLookup) { + super.writeNbt(nbt, registryLookup); + if (!this.writeLootTable(nbt)) { + Inventories.writeNbt(nbt, this.stacks, registryLookup); + } + } + + @Override + protected void readNbt(NbtCompound nbt, WrapperLookup registryLookup) { + super.readNbt(nbt, registryLookup); + this.stacks = DefaultedList.ofSize(this.size(), ItemStack.EMPTY); + if (!this.readLootTable(nbt)) { + Inventories.readNbt(nbt, this.stacks, registryLookup); + } + } + + public List getStacks() { + return stacks; + } + + @Override + public int size() { + return 54; // container chest size (9 * 6) + } + + @Override + protected DefaultedList getHeldStacks() { + return stacks; + } + + @Override + protected void setHeldStacks(DefaultedList list) { + this.stacks = list; + } + + @Override + protected ScreenHandler createScreenHandler(int syncId, PlayerInventory playerInventory) { + // TODO: implement, see https://fabricmc.net/wiki/tutorial:containers + return null; + } + + @Override + protected Text getContainerName() { + return Text.translatable("container.itemhoarder"); + } + + /** + * get a summary of content for the chat box + * + * @return the summary + */ + public List getSummary() { + List list = new ArrayList<>(); + for (ItemStack stack : stacks) { + Item item = stack.getItem(); + if (item != Items.AIR) { + Text text = PrefixedText.instance(String.format("%dx ", stack.getCount()).concat("%s"), + Text.translatable(stack.getTranslationKey())); + list.add(text); + } + } + return list; + } + + public float getSuckradius() { + return suckradius; + } + + public void setSuckradius(float suckradius) { + this.suckradius = suckradius; + } +} diff --git a/src/main/java/de/jottyfan/quickiemod/blocks/BlockItemhoarder.java b/src/main/java/de/jottyfan/quickiemod/blocks/BlockItemhoarder.java new file mode 100644 index 0000000..1091546 --- /dev/null +++ b/src/main/java/de/jottyfan/quickiemod/blocks/BlockItemhoarder.java @@ -0,0 +1,92 @@ +package de.jottyfan.quickiemod.blocks; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import de.jottyfan.quickiemod.blockentity.ItemHoarderBlockEntity; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContextParameterSet.Builder; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Formatting; +import net.minecraft.util.ItemScatterer; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +/** + * + * @author jotty + * + */ +public class BlockItemhoarder extends Block implements BlockEntityProvider { + + public BlockItemhoarder() { + super(AbstractBlock.Settings.create().hardness(2.5f)); + } + + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState blockState) { + return new ItemHoarderBlockEntity(pos, blockState); + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + @Override + public BlockEntityTicker getTicker(World world, BlockState state, + BlockEntityType type) { + return (world1, pos, state1, be) -> ItemHoarderBlockEntity.tick(world1, pos, state1, be); + } + + @Override + public List getDroppedStacks(BlockState state, Builder builder) { + List list = new ArrayList<>(); + list.add(new ItemStack(QuickieBlocks.ITEMHOARDER.getBlock())); + return list; + } + + @Override + public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof ItemHoarderBlockEntity) { + ItemHoarderBlockEntity ihbe = (ItemHoarderBlockEntity) blockEntity; + for (ItemStack stack : ihbe.getStacks()) { + ItemScatterer.spawn(world, pos.getX(), pos.getY(), pos.getZ(), stack); + } + } + return super.onBreak(world, pos, state, player); + } + + @Override + protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { + if (!world.isClient) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof ItemHoarderBlockEntity) { + ItemHoarderBlockEntity ihbe = (ItemHoarderBlockEntity) blockEntity; + player.sendMessage( + Text.translatable("msg.itemhoarder.summary", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date())) + .setStyle(Style.EMPTY.withColor(Formatting.BOLD)), + false); + for (Text text : ihbe.getSummary()) { + player.sendMessage(text, false); + } + } + } + return ActionResult.SUCCESS; + } +} diff --git a/src/main/java/de/jottyfan/quickiemod/blocks/QuickieBlocks.java b/src/main/java/de/jottyfan/quickiemod/blocks/QuickieBlocks.java index d0ff038..bacfb0f 100644 --- a/src/main/java/de/jottyfan/quickiemod/blocks/QuickieBlocks.java +++ b/src/main/java/de/jottyfan/quickiemod/blocks/QuickieBlocks.java @@ -9,6 +9,7 @@ import net.minecraft.block.Block; */ public enum QuickieBlocks { // @formatter:off + ITEMHOARDER(new BlockItemhoarder(), "itemhoarder"), LAVAHOARDER(new BlockLavahoarder(), "lavahoarder", false), EMPTYLAVAHOARDER(new BlockEmptyLavahoarder(), "emptylavahoarder"), KELPSTACK(new BlockKelpstack(), "kelpstack"), diff --git a/src/main/java/de/jottyfan/quickiemod/init/RegistryManager.java b/src/main/java/de/jottyfan/quickiemod/init/RegistryManager.java index c9219fa..9fb44ab 100644 --- a/src/main/java/de/jottyfan/quickiemod/init/RegistryManager.java +++ b/src/main/java/de/jottyfan/quickiemod/init/RegistryManager.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import de.jottyfan.quickiemod.QuickieMod; import de.jottyfan.quickiemod.blockentity.EmptyLavaHoarderBlockEntity; +import de.jottyfan.quickiemod.blockentity.ItemHoarderBlockEntity; import de.jottyfan.quickiemod.blocks.QuickieBlocks; import de.jottyfan.quickiemod.items.QuickieItems; import net.fabricmc.fabric.api.biome.v1.BiomeModifications; @@ -33,6 +34,7 @@ public class RegistryManager { private static final Logger LOGGER = LoggerFactory.getLogger(QuickieMod.MODID); public static final BlockEntityType EMPTYLAVAHOARDER = Registry.register(Registries.BLOCK_ENTITY_TYPE, BlockEntityIdentity.EMPTYLAVALHOARDER, BlockEntityType.Builder.create(EmptyLavaHoarderBlockEntity::new, QuickieBlocks.EMPTYLAVAHOARDER.getBlock(), QuickieBlocks.LAVAHOARDER.getBlock()).build(null)); + public static final BlockEntityType ITEMHOARDER = Registry.register(Registries.BLOCK_ENTITY_TYPE, BlockEntityIdentity.ITEMHOARDER, BlockEntityType.Builder.create(ItemHoarderBlockEntity::new, QuickieBlocks.ITEMHOARDER.getBlock()).build(null)); public static final void registerItemGroup() { Registry.register(Registries.ITEM_GROUP, RegistryKey.of(RegistryKeys.ITEM_GROUP, new Identifier(QuickieMod.MODID, "itemgroups")), diff --git a/src/main/resources/assets/quickiemod/blockstates/itemhoarder.json b/src/main/resources/assets/quickiemod/blockstates/itemhoarder.json new file mode 100644 index 0000000..95b8e31 --- /dev/null +++ b/src/main/resources/assets/quickiemod/blockstates/itemhoarder.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "quickiemod:block/itemhoarder" + } + } +} diff --git a/src/main/resources/assets/quickiemod/models/block/itemhoarder.json b/src/main/resources/assets/quickiemod/models/block/itemhoarder.json new file mode 100644 index 0000000..dc55e95 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/block/itemhoarder.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "quickiemod:block/itemhoarder" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/models/item/itemhoarder.json b/src/main/resources/assets/quickiemod/models/item/itemhoarder.json new file mode 100644 index 0000000..b9128a8 --- /dev/null +++ b/src/main/resources/assets/quickiemod/models/item/itemhoarder.json @@ -0,0 +1,10 @@ +{ + "parent": "quickiemod:block/itemhoarder", + "display": { + "thirdperson": { + "rotation": [ 10, -45, 170 ], + "translation": [ 0, 1.5, -2.75 ], + "scale": [ 0.375, 0.375, 0.375 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/quickiemod/textures/block/itemhoarder.png b/src/main/resources/assets/quickiemod/textures/block/itemhoarder.png new file mode 100644 index 0000000000000000000000000000000000000000..f505ab41a89f00a96dc6c80e021216882a4fff3c GIT binary patch literal 2894 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