working itemhoarder

This commit is contained in:
Jörg Henke 2020-07-31 23:38:19 +02:00
parent cf72acf5a8
commit 600482aba9
3 changed files with 112 additions and 90 deletions

View File

@ -1,130 +1,123 @@
package de.jottyfan.minecraft.quickiefabric.blockentity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
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.ItemEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Tickable;
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 BlockEntity {
private final String NBT_STACKS = "stacks";
private final List<ItemStack> stacks;
public class ItemHoarderBlockEntity extends LootableContainerBlockEntity implements Tickable {
private DefaultedList<ItemStack> stacks;
public ItemHoarderBlockEntity() {
super(QuickieFabricBlockEntity.ITEMHOARDER);
stacks = new ArrayList<>();
}
private final Integer getNextFreeEmptyStackPosition() {
Integer emptyStackPosition = null;
Iterator<ItemStack> it = stacks.iterator();
Integer index = 0;
while (emptyStackPosition == null && it.hasNext()) {
ItemStack s = it.next();
if (s.isEmpty()) {
emptyStackPosition = index;
}
index++;
}
return emptyStackPosition;
stacks = DefaultedList.ofSize(54, ItemStack.EMPTY);
}
// TODO: see https://fabricmc.net/wiki/tutorial:containers for a real chest
// TODO: find a way to suck in the surrounding items
// @Override
// public void tick() {
// BlockPos pos = getPos();
// World world = getWorld();
// // list all items around here
// AxisAlignedBB aabb = new AxisAlignedBB(pos).grow(4);
// List<ItemEntity> itemEntities = world.getEntitiesWithinAABB(ItemEntity.class, aabb);
// boolean dirty = false;
// for (ItemEntity itemEntity : itemEntities) {
// if (itemEntity.isAlive()) {
// ItemStack stack = itemEntity.getItem();
// if (stack != null) {
// Integer emptyStackPosition = getNextFreeEmptyStackPosition();
// if (emptyStackPosition == null) {
// } else {
// stacks.set(emptyStackPosition, stack);
// itemEntity.remove();
// dirty = true;
// }
// }
// } else {
// itemEntity.getItem().getItem().getRegistryName().getPath());
// }
// }
// if (dirty) {
// resortStacks();
// }
// }
/**
* resort item stacks to be more efficient
*/
private void resortStacks() {
Map<Text, ItemStack> map = new HashMap<>();
Integer clearAmount = stacks.size();
for (ItemStack stack : stacks) {
ItemStack found = map.get(stack.getName());
if (found == null) {
found = stack;
map.put(stack.getName(), found);
} else {
found.setCount(found.getCount() + stack.getCount());
private final boolean setStackToSlots(ItemStack stack) {
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;
}
}
for (Integer i = 0; i < clearAmount; i++) {
stacks.set(i, ItemStack.EMPTY);
}
Integer index = 0;
for (ItemStack stack : map.values()) {
stacks.set(index++, stack);
return false;
}
@Override
public void tick() {
BlockPos pos = getPos();
World world = getWorld();
float suckradius = 4f; // TODO: make it level up - able and start with 2
Box box = new Box(pos).expand(suckradius);
List<Entity> entities = world.getEntities(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 (setStackToSlots(stack)) {
itemEntity.remove();
} // else inventory is full
}
}
}
}
}
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
ListTag listTag = new ListTag();
for (ItemStack stack : stacks) {
listTag.add(stack.toTag(tag));
if (!this.serializeLootTable(tag)) {
Inventories.toTag(tag, this.stacks);
}
tag.put(NBT_STACKS, listTag);
return tag;
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
ListTag listTag = (ListTag) tag.get(NBT_STACKS);
ListIterator<Tag> i = listTag.listIterator();
stacks.clear();
while (i.hasNext()) {
CompoundTag foundTag = (CompoundTag) i.next();
ItemStack stack = ItemStack.fromTag(foundTag);
stacks.add(stack);
this.stacks = DefaultedList.ofSize(this.size(), ItemStack.EMPTY);
if (!this.deserializeLootTable(tag)) {
Inventories.fromTag(tag, this.stacks);
}
}
public List<ItemStack> getStacks() {
return stacks;
}
@Override
public int size() {
return 54; // container chest size (9 * 6)
}
@Override
protected DefaultedList<ItemStack> getInvStackList() {
return stacks;
}
@Override
protected void setInvStackList(DefaultedList<ItemStack> 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 new TranslatableText("container.itemhoarder");
}
}

View File

@ -1,12 +1,22 @@
package de.jottyfan.minecraft.quickiefabric.blocks;
import java.util.ArrayList;
import java.util.List;
import de.jottyfan.minecraft.quickiefabric.blockentity.ItemHoarderBlockEntity;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.context.LootContext.Builder;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
/**
*
@ -20,7 +30,26 @@ public class BlockItemhoarder extends Block implements BlockEntityProvider {
}
@Override
public BlockEntity createBlockEntity(BlockView arg0) {
public BlockEntity createBlockEntity(BlockView blockView) {
return new ItemHoarderBlockEntity();
}
@Override
public List<ItemStack> getDroppedStacks(BlockState state, Builder builder) {
List<ItemStack> list = new ArrayList<>();
list.add(new ItemStack(QuickieBlocks.ITEMHOARDER));
return list;
}
@Override
public void 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);
}
}
super.onBreak(world, pos, state, player);
}
}

View File

@ -73,7 +73,7 @@ public class BlockLavahoarder extends Block {
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
Set<String> positions = new HashSet<>();
Integer counter = 8;
Integer counter = 8; // TODO: make it level up - able
findAllAttachedLavaBlocks(positions, pos.up(), world, counter);
findAllAttachedLavaBlocks(positions, pos.down(), world, counter);
findAllAttachedLavaBlocks(positions, pos.north(), world, counter);