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 0000000..f505ab4 Binary files /dev/null and b/src/main/resources/assets/quickiemod/textures/block/itemhoarder.png differ diff --git a/src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_barrel.json b/src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_barrel.json new file mode 100644 index 0000000..0f40891 --- /dev/null +++ b/src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_barrel.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ooo", + "oso", + "ooo" + ], + "key": { + "o": { + "item": "quickiemod:speedpowder" + }, + "s": { + "item": "minecraft:barrel" + } + }, + "result": { + "id": "quickiemod:itemhoarder", + "count": 1 + } +} \ No newline at end of file diff --git a/src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_chest.json b/src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_chest.json new file mode 100644 index 0000000..1e48fe6 --- /dev/null +++ b/src/main/resources/data/quickiemod/recipes/shaped_itemhoarder_from_chest.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ooo", + "oso", + "ooo" + ], + "key": { + "o": { + "item": "quickiemod:speedpowder" + }, + "s": { + "item": "minecraft:chest" + } + }, + "result": { + "id": "quickiemod:itemhoarder", + "count": 1 + } +} \ No newline at end of file