filter for the block stacker
This commit is contained in:
parent
7992e5d9ba
commit
4ff86faf91
@ -9,7 +9,7 @@
|
|||||||
loader_version=0.14.9
|
loader_version=0.14.9
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.19.2.0
|
mod_version = 1.19.2.1
|
||||||
maven_group = de.jottyfan.minecraft
|
maven_group = de.jottyfan.minecraft
|
||||||
archives_base_name = quickiefabric
|
archives_base_name = quickiefabric
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@ package de.jottyfan.minecraft.quickiefabric;
|
|||||||
|
|
||||||
import de.jottyfan.minecraft.quickiefabric.blocks.QuickieBlocks;
|
import de.jottyfan.minecraft.quickiefabric.blocks.QuickieBlocks;
|
||||||
import de.jottyfan.minecraft.quickiefabric.container.BackpackScreen;
|
import de.jottyfan.minecraft.quickiefabric.container.BackpackScreen;
|
||||||
|
import de.jottyfan.minecraft.quickiefabric.container.BlockStackerScreen;
|
||||||
import de.jottyfan.minecraft.quickiefabric.init.RegistryManager;
|
import de.jottyfan.minecraft.quickiefabric.init.RegistryManager;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
import net.minecraft.client.gui.screen.ingame.HandledScreens;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,7 +20,8 @@ import net.minecraft.client.render.RenderLayer;
|
|||||||
public class QuickieFabricClient implements ClientModInitializer {
|
public class QuickieFabricClient implements ClientModInitializer {
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
ScreenRegistry.register(RegistryManager.BACKPACK_SCREEN_HANDLER, BackpackScreen::new);
|
HandledScreens.register(RegistryManager.BACKPACK_SCREEN_HANDLER, BackpackScreen::new);
|
||||||
|
HandledScreens.register(RegistryManager.BLOCKSTACKER_SCREEN_HANDLER, BlockStackerScreen::new);
|
||||||
// make cotton plant block transparent
|
// make cotton plant block transparent
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.COTTONPLANT, RenderLayer.getCutout());
|
BlockRenderLayerMap.INSTANCE.putBlock(QuickieBlocks.COTTONPLANT, RenderLayer.getCutout());
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,28 @@
|
|||||||
package de.jottyfan.minecraft.quickiefabric.blockentity;
|
package de.jottyfan.minecraft.quickiefabric.blockentity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.quickiefabric.blocks.help.BlockStacker;
|
import de.jottyfan.minecraft.quickiefabric.blocks.help.BlockStacker;
|
||||||
|
import de.jottyfan.minecraft.quickiefabric.container.BlockStackerScreenHandler;
|
||||||
|
import de.jottyfan.minecraft.quickiefabric.container.ImplementedInventory;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.LootableContainerBlockEntity;
|
import net.minecraft.block.entity.LootableContainerBlockEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
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.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
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.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@ -17,13 +31,55 @@ import net.minecraft.world.World;
|
|||||||
* @author jotty
|
* @author jotty
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BlockStackerEntity extends BlockEntity {
|
public class BlockStackerEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory {
|
||||||
private static final Logger LOGGER = LogManager.getLogger(BlockStackerEntity.class);
|
private static final Logger LOGGER = LogManager.getLogger(BlockStackerEntity.class);
|
||||||
|
|
||||||
|
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(9, ItemStack.EMPTY);
|
||||||
|
|
||||||
public BlockStackerEntity(BlockPos blockPos, BlockState blockState) {
|
public BlockStackerEntity(BlockPos blockPos, BlockState blockState) {
|
||||||
super(QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY, blockPos, blockState);
|
super(QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY, blockPos, blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultedList<ItemStack> getItems() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
|
||||||
|
return new BlockStackerScreenHandler(syncId, playerInventory, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getDisplayName() {
|
||||||
|
return Text.translatable(getCachedState().getBlock().getTranslationKey());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void readNbt(NbtCompound nbt) {
|
||||||
|
super.readNbt(nbt);
|
||||||
|
Inventories.readNbt(nbt, inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNbt(NbtCompound nbt) {
|
||||||
|
Inventories.writeNbt(nbt, inventory);
|
||||||
|
super.writeNbt(nbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if whitelist, return true if current == pattern; return false otherwise
|
||||||
|
*
|
||||||
|
* @param current the current item stack
|
||||||
|
* @param pattern the item stack to compare with
|
||||||
|
* @param whitelist if true, filter only current == pattern, if false, filter
|
||||||
|
* all but that
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
public static final Boolean filter(ItemStack current, ItemStack pattern, Boolean whitelist) {
|
||||||
|
Boolean matches = pattern.getItem().equals(current.getItem());
|
||||||
|
return whitelist ? matches : !matches;
|
||||||
|
}
|
||||||
|
|
||||||
public static void tick(World world, BlockPos pos, BlockState state, BlockStackerEntity entity) {
|
public static void tick(World world, BlockPos pos, BlockState state, BlockStackerEntity entity) {
|
||||||
if (!world.isClient) {
|
if (!world.isClient) {
|
||||||
pos.down();
|
pos.down();
|
||||||
@ -35,13 +91,23 @@ public class BlockStackerEntity extends BlockEntity {
|
|||||||
if (sourceIsLootable && destIsLootable) {
|
if (sourceIsLootable && destIsLootable) {
|
||||||
LootableContainerBlockEntity lootableSource = (LootableContainerBlockEntity) source;
|
LootableContainerBlockEntity lootableSource = (LootableContainerBlockEntity) source;
|
||||||
LootableContainerBlockEntity lootableDest = (LootableContainerBlockEntity) dest;
|
LootableContainerBlockEntity lootableDest = (LootableContainerBlockEntity) dest;
|
||||||
transferOneStack(lootableSource, lootableDest);
|
List<Item> checked = new ArrayList<>();
|
||||||
|
Boolean found = false;
|
||||||
|
Item item = findNextItem(entity.getItems(), checked);
|
||||||
|
while(!found && item != null) {
|
||||||
|
checked.add(item);
|
||||||
|
Boolean whitelist = true;
|
||||||
|
found = transferOneStack(lootableSource, lootableDest, item, whitelist);
|
||||||
|
item = findNextItem(entity.getItems(), checked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final void transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest) {
|
private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest,
|
||||||
Integer sourceSlot = findItemStackPos(source, false);
|
Item filterItem, Boolean whitelist) {
|
||||||
|
Boolean result = false;
|
||||||
|
Integer sourceSlot = findItemStackPos(source, filterItem, whitelist);
|
||||||
if (sourceSlot != null && !Items.AIR.equals(source.getStack(sourceSlot).getItem())) {
|
if (sourceSlot != null && !Items.AIR.equals(source.getStack(sourceSlot).getItem())) {
|
||||||
ItemStack sourceStack = source.getStack(sourceSlot);
|
ItemStack sourceStack = source.getStack(sourceSlot);
|
||||||
Integer destSlot = findItemStackPos(dest, sourceStack);
|
Integer destSlot = findItemStackPos(dest, sourceStack);
|
||||||
@ -51,21 +117,38 @@ public class BlockStackerEntity extends BlockEntity {
|
|||||||
Integer candidates = source.getStack(sourceSlot).getCount();
|
Integer candidates = source.getStack(sourceSlot).getCount();
|
||||||
Integer travellers = candidates > free ? free : candidates;
|
Integer travellers = candidates > free ? free : candidates;
|
||||||
if (travellers > 0) {
|
if (travellers > 0) {
|
||||||
LOGGER.debug("transfer {}/{} of {} from slot {} to slot {} on top of {} ones", travellers, candidates, source.getStack(sourceSlot).getItem().toString(), sourceSlot, destSlot, occupied);
|
LOGGER.debug("transfer {}/{} of {} from slot {} to slot {} on top of {} ones", travellers, candidates,
|
||||||
|
source.getStack(sourceSlot).getItem().toString(), sourceSlot, destSlot, occupied);
|
||||||
source.getStack(sourceSlot).decrement(travellers);
|
source.getStack(sourceSlot).decrement(travellers);
|
||||||
if (source.getStack(sourceSlot).getCount() < 1) {
|
if (source.getStack(sourceSlot).getCount() < 1) {
|
||||||
source.removeStack(sourceSlot); // make empty slots really empty
|
source.removeStack(sourceSlot); // make empty slots really empty
|
||||||
}
|
}
|
||||||
dest.getStack(destSlot).increment(travellers);
|
dest.getStack(destSlot).increment(travellers);
|
||||||
|
result = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Integer destFreeSlot = findItemStackPos(dest, true);
|
Integer destFreeSlot = findItemStackPos(dest, true);
|
||||||
if (destFreeSlot != null) {
|
if (destFreeSlot != null) {
|
||||||
LOGGER.debug("transfer all of {} from slot {} to slot {}", source.getStack(sourceSlot).getItem().toString(), sourceSlot, destSlot);
|
LOGGER.debug("transfer all of {} from slot {} to slot {}", source.getStack(sourceSlot).getItem().toString(),
|
||||||
|
sourceSlot, destSlot);
|
||||||
dest.setStack(destFreeSlot, source.removeStack(sourceSlot));
|
dest.setStack(destFreeSlot, source.removeStack(sourceSlot));
|
||||||
|
result = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Item findNextItem(List<ItemStack> inventory, List<Item> exclude) {
|
||||||
|
for (ItemStack stack : inventory) {
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
if (!exclude.contains(item)) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, ItemStack sourceStack) {
|
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, ItemStack sourceStack) {
|
||||||
@ -73,7 +156,7 @@ public class BlockStackerEntity extends BlockEntity {
|
|||||||
while (counter > 0) {
|
while (counter > 0) {
|
||||||
counter--;
|
counter--;
|
||||||
ItemStack stack = lcbe.getStack(counter);
|
ItemStack stack = lcbe.getStack(counter);
|
||||||
if (stack.getItem().equals(sourceStack.getItem())) {
|
if (sourceStack.getItem().equals(stack.getItem())) {
|
||||||
if (stack.getCount() < stack.getMaxCount()) {
|
if (stack.getCount() < stack.getMaxCount()) {
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
@ -93,4 +176,30 @@ public class BlockStackerEntity extends BlockEntity {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, Item item, Boolean whitelist) {
|
||||||
|
if (item == null) {
|
||||||
|
return findItemStackPos(lcbe, false);
|
||||||
|
} else {
|
||||||
|
if (whitelist == null) {
|
||||||
|
whitelist = true;
|
||||||
|
LOGGER.error("whitelist is null");
|
||||||
|
}
|
||||||
|
Integer counter = lcbe.size();
|
||||||
|
while (counter > 0) {
|
||||||
|
counter--;
|
||||||
|
ItemStack stack = lcbe.getStack(counter);
|
||||||
|
Boolean found = item.equals(stack.getItem());
|
||||||
|
if (whitelist ? found : !found) {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return inventory.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ import net.minecraft.block.Material;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.loot.context.LootContext.Builder;
|
import net.minecraft.loot.context.LootContext.Builder;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.ItemScatterer;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -64,4 +71,39 @@ public class BlockStackerDown extends BlockWithEntity implements BlockStacker {
|
|||||||
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
||||||
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||||
|
if (screenHandlerFactory != null) {
|
||||||
|
player.openHandledScreen(screenHandlerFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
if (state.getBlock() != newState.getBlock()) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BlockStackerEntity) {
|
||||||
|
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
|
||||||
|
// update comparators
|
||||||
|
world.updateComparators(pos, this);
|
||||||
|
}
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComparatorOutput(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||||
|
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ import net.minecraft.block.Material;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.loot.context.LootContext.Builder;
|
import net.minecraft.loot.context.LootContext.Builder;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.ItemScatterer;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -64,4 +71,39 @@ public class BlockStackerEast extends BlockWithEntity implements BlockStacker {
|
|||||||
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
||||||
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||||
|
if (screenHandlerFactory != null) {
|
||||||
|
player.openHandledScreen(screenHandlerFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
if (state.getBlock() != newState.getBlock()) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BlockStackerEntity) {
|
||||||
|
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
|
||||||
|
// update comparators
|
||||||
|
world.updateComparators(pos, this);
|
||||||
|
}
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComparatorOutput(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||||
|
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ import net.minecraft.block.Material;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.loot.context.LootContext.Builder;
|
import net.minecraft.loot.context.LootContext.Builder;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.ItemScatterer;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -64,4 +71,39 @@ public class BlockStackerNorth extends BlockWithEntity implements BlockStacker {
|
|||||||
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
||||||
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||||
|
if (screenHandlerFactory != null) {
|
||||||
|
player.openHandledScreen(screenHandlerFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
if (state.getBlock() != newState.getBlock()) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BlockStackerEntity) {
|
||||||
|
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
|
||||||
|
// update comparators
|
||||||
|
world.updateComparators(pos, this);
|
||||||
|
}
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComparatorOutput(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||||
|
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ import net.minecraft.block.Material;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.loot.context.LootContext.Builder;
|
import net.minecraft.loot.context.LootContext.Builder;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.ItemScatterer;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -64,4 +71,39 @@ public class BlockStackerSouth extends BlockWithEntity implements BlockStacker {
|
|||||||
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
||||||
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||||
|
if (screenHandlerFactory != null) {
|
||||||
|
player.openHandledScreen(screenHandlerFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
if (state.getBlock() != newState.getBlock()) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BlockStackerEntity) {
|
||||||
|
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
|
||||||
|
// update comparators
|
||||||
|
world.updateComparators(pos, this);
|
||||||
|
}
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComparatorOutput(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||||
|
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ import net.minecraft.block.Material;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.loot.context.LootContext.Builder;
|
import net.minecraft.loot.context.LootContext.Builder;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.ItemScatterer;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -64,4 +71,39 @@ public class BlockStackerUp extends BlockWithEntity implements BlockStacker {
|
|||||||
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
||||||
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||||
|
if (screenHandlerFactory != null) {
|
||||||
|
player.openHandledScreen(screenHandlerFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
if (state.getBlock() != newState.getBlock()) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BlockStackerEntity) {
|
||||||
|
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
|
||||||
|
// update comparators
|
||||||
|
world.updateComparators(pos, this);
|
||||||
|
}
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComparatorOutput(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||||
|
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ import net.minecraft.block.Material;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.loot.context.LootContext.Builder;
|
import net.minecraft.loot.context.LootContext.Builder;
|
||||||
|
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.ItemScatterer;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -64,4 +71,39 @@ public class BlockStackerWest extends BlockWithEntity implements BlockStacker {
|
|||||||
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
return checkType(type, QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY,
|
||||||
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
(world1, pos, state1, be) -> BlockStackerEntity.tick(world1, pos, state1, be));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockHitResult hit) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
|
||||||
|
if (screenHandlerFactory != null) {
|
||||||
|
player.openHandledScreen(screenHandlerFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
if (state.getBlock() != newState.getBlock()) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BlockStackerEntity) {
|
||||||
|
ItemScatterer.spawn(world, pos, (BlockStackerEntity) blockEntity);
|
||||||
|
// update comparators
|
||||||
|
world.updateComparators(pos, this);
|
||||||
|
}
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasComparatorOutput(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||||
|
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.jottyfan.minecraft.quickiefabric.blocks.help;
|
package de.jottyfan.minecraft.quickiefabric.blocks.help;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockEntityProvider;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7,7 +8,7 @@ import net.minecraft.util.math.Direction;
|
|||||||
* @author jotty
|
* @author jotty
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface BlockStacker {
|
public interface BlockStacker extends BlockEntityProvider {
|
||||||
/**
|
/**
|
||||||
* define the source offset
|
* define the source offset
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,176 @@
|
|||||||
|
package de.jottyfan.minecraft.quickiefabric.container;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.quickiefabric.items.ItemBackpack;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.SimpleInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.nbt.NbtElement;
|
||||||
|
import net.minecraft.nbt.NbtList;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockStackerInventory extends SimpleInventory {
|
||||||
|
private static final String NBT_BLOCKSTACKER = "blockstacer";
|
||||||
|
private static final String NBT_SLOT = "slot";
|
||||||
|
private static final String NBT_ITEMS = "items";
|
||||||
|
|
||||||
|
private Hand hand;
|
||||||
|
|
||||||
|
private BlockStackerInventory(NbtCompound tag, BlockStackerScreenHandler handler) {
|
||||||
|
super(1);
|
||||||
|
readItemsFromTag(super.size(), tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockStackerInventory(ItemStack stack) {
|
||||||
|
this(init(stack).getOrCreateNbt().getCompound(NBT_BLOCKSTACKER), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final BlockStackerInventory getInventory(BlockStackerScreenHandler handler, PlayerEntity player,
|
||||||
|
ItemStack stack) {
|
||||||
|
return new BlockStackerInventory(init(stack).getOrCreateNbt().getCompound(NBT_BLOCKSTACKER), handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static ItemStack init(ItemStack stack) {
|
||||||
|
if (stack != null) {
|
||||||
|
if (!stack.getOrCreateNbt().contains(NBT_BLOCKSTACKER)) {
|
||||||
|
stack.getOrCreateNbt().put(NBT_BLOCKSTACKER, new NbtCompound());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(PlayerEntity player) {
|
||||||
|
super.onOpen(player);
|
||||||
|
player.playSound(SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.PLAYERS, 1f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(PlayerEntity player) {
|
||||||
|
super.onClose(player);
|
||||||
|
ItemStack stack = player.getStackInHand(hand);
|
||||||
|
if (stack != null) {
|
||||||
|
stack.getOrCreateNbt().put(NBT_BLOCKSTACKER, writeItemsToTag(super.size()));
|
||||||
|
}
|
||||||
|
player.getStackInHand(hand).setNbt(stack.getNbt());
|
||||||
|
player.playSound(SoundEvents.BLOCK_CHEST_CLOSE, SoundCategory.PLAYERS, 1f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readItemsFromTag(Integer size, NbtCompound tag) {
|
||||||
|
NbtList listTag = tag.getList(NBT_ITEMS, NbtElement.COMPOUND_TYPE);
|
||||||
|
for (int i = 0; i < listTag.size(); ++i) {
|
||||||
|
NbtCompound compoundTag = listTag.getCompound(i);
|
||||||
|
int slot = compoundTag.getInt(NBT_SLOT);
|
||||||
|
if (slot >= 0 && slot < size) {
|
||||||
|
super.setStack(slot, ItemStack.fromNbt(compoundTag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NbtCompound writeItemsToTag(int slotsize) {
|
||||||
|
NbtList listTag = new NbtList();
|
||||||
|
for (int slot = 0; slot < slotsize; ++slot) {
|
||||||
|
ItemStack itemStack = super.getStack(slot);
|
||||||
|
if (!(itemStack == null) && !itemStack.isEmpty()) {
|
||||||
|
listTag.add(prepareCompoundTag(slot, itemStack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NbtCompound tag = new NbtCompound();
|
||||||
|
tag.put(NBT_ITEMS, listTag);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final NbtCompound prepareCompoundTag(Integer slot, ItemStack stack) {
|
||||||
|
NbtCompound compoundTag = new NbtCompound();
|
||||||
|
compoundTag.putInt(NBT_SLOT, slot);
|
||||||
|
stack.writeNbt(compoundTag);
|
||||||
|
return compoundTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHand(Hand hand) {
|
||||||
|
this.hand = hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the items from the itemStack that contains the backpack
|
||||||
|
*
|
||||||
|
* @param itemStack the itemStack of the backpack
|
||||||
|
* @return the list of found itemStacks in the backpack
|
||||||
|
*/
|
||||||
|
public static List<ItemStack> getItemsFromBackpack(ItemStack itemStack) {
|
||||||
|
NbtCompound backpackNbt = init(itemStack).getOrCreateNbt().getCompound(NBT_BLOCKSTACKER);
|
||||||
|
NbtList listTag = backpackNbt.getList(NBT_ITEMS, NbtElement.COMPOUND_TYPE);
|
||||||
|
List<ItemStack> items = new ArrayList<>();
|
||||||
|
for (int i = 0; i < listTag.size(); ++i) {
|
||||||
|
NbtCompound compoundTag = listTag.getCompound(i);
|
||||||
|
int slot = compoundTag.getInt(NBT_SLOT);
|
||||||
|
if (slot >= 0 && slot < ItemBackpack.SLOTSIZE) {
|
||||||
|
ItemStack stack = ItemStack.fromNbt(compoundTag);
|
||||||
|
items.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the items in the itemStack that contains the backpack
|
||||||
|
*
|
||||||
|
* @param itemStack the backpack's itemStack
|
||||||
|
* @param itemStacks the collection of lists of itemStacks for the backpack
|
||||||
|
*/
|
||||||
|
public static void setItemsToBackpack(ItemStack itemStack, Collection<List<ItemStack>> itemStacks) {
|
||||||
|
NbtList listTag = new NbtList();
|
||||||
|
Integer slot = 0;
|
||||||
|
for (List<ItemStack> stacks : itemStacks) {
|
||||||
|
if (stacks != null && stacks.size() > 0) {
|
||||||
|
ItemStack stack = stacks.get(0);
|
||||||
|
Integer leftCount = 0;
|
||||||
|
for (ItemStack is : stacks) {
|
||||||
|
leftCount += is.getCount();
|
||||||
|
}
|
||||||
|
while (leftCount > 0) {
|
||||||
|
if (leftCount > stack.getMaxCount()) {
|
||||||
|
stack.setCount(stack.getMaxCount());
|
||||||
|
leftCount = leftCount - stack.getMaxCount();
|
||||||
|
} else {
|
||||||
|
stack.setCount(leftCount);
|
||||||
|
leftCount = 0;
|
||||||
|
}
|
||||||
|
listTag.add(prepareCompoundTag(slot, stack));
|
||||||
|
slot++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NbtCompound tag = new NbtCompound();
|
||||||
|
tag.put(NBT_ITEMS, listTag);
|
||||||
|
itemStack.getOrCreateNbt().put(NBT_BLOCKSTACKER, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace every slot of the backpack with the content of backpackInventory
|
||||||
|
*
|
||||||
|
* @param itemStack the backpack's itemStack
|
||||||
|
* @param backpackInventory the replacement inventory
|
||||||
|
*/
|
||||||
|
public static void setItemsToBackpack(ItemStack itemStack, BlockStackerInventory backpackInventory) {
|
||||||
|
Collection<List<ItemStack>> itemStacks = new ArrayList<>();
|
||||||
|
for (int i = 0; i < backpackInventory.size(); i++) {
|
||||||
|
ItemStack stack = backpackInventory.getStack(i);
|
||||||
|
List<ItemStack> list = new ArrayList<>();
|
||||||
|
list.add(stack);
|
||||||
|
itemStacks.add(list);
|
||||||
|
}
|
||||||
|
setItemsToBackpack(itemStack, itemStacks);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package de.jottyfan.minecraft.quickiefabric.container;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||||
|
import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
|
||||||
|
import net.minecraft.client.render.GameRenderer;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class BlockStackerScreen extends HandledScreen<BlockStackerScreenHandler>
|
||||||
|
implements ScreenHandlerProvider<BlockStackerScreenHandler> {
|
||||||
|
private final static Identifier TEXTURE = new Identifier("minecraft", "textures/gui/container/dispenser.png");
|
||||||
|
|
||||||
|
public BlockStackerScreen(BlockStackerScreenHandler handler, PlayerInventory inventory, Text text) {
|
||||||
|
super(handler, inventory, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
this.titleX = (backgroundWidth - textRenderer.getWidth(title)) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
this.renderBackground(matrices);
|
||||||
|
super.render(matrices, mouseX, mouseY, partialTicks);
|
||||||
|
this.drawMouseoverTooltip(matrices, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) {
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||||
|
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
RenderSystem.setShaderTexture(0, TEXTURE);
|
||||||
|
int x = (width - backgroundWidth) / 2;
|
||||||
|
int y = (height - backgroundHeight) / 2;
|
||||||
|
drawTexture(matrices, x, y, 0, 0, backgroundWidth, backgroundHeight);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package de.jottyfan.minecraft.quickiefabric.container;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.quickiefabric.init.RegistryManager;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.inventory.SimpleInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockStackerScreenHandler extends ScreenHandler {
|
||||||
|
|
||||||
|
public static final Integer SLOTSIZE = 9;
|
||||||
|
|
||||||
|
private final Inventory inventory;
|
||||||
|
|
||||||
|
public BlockStackerScreenHandler(int syncId, PlayerInventory playerInventory) {
|
||||||
|
this(syncId, playerInventory, new SimpleInventory(SLOTSIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockStackerScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
|
||||||
|
super(RegistryManager.BLOCKSTACKER_SCREEN_HANDLER, syncId);
|
||||||
|
checkSize(inventory, SLOTSIZE);
|
||||||
|
this.inventory = inventory;
|
||||||
|
inventory.onOpen(playerInventory.player);
|
||||||
|
int m;
|
||||||
|
int l;
|
||||||
|
for (m = 0; m < 3; ++m) {
|
||||||
|
for (l = 0; l < 3; ++l) {
|
||||||
|
this.addSlot(new Slot(inventory, l + m * 3, 62 + l * 18, 17 + m * 18));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (m = 0; m < 3; ++m) {
|
||||||
|
for (l = 0; l < 9; ++l) {
|
||||||
|
this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 84 + m * 18));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (m = 0; m < 9; ++m) {
|
||||||
|
this.addSlot(new Slot(playerInventory, m, 8 + m * 18, 142));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUse(PlayerEntity player) {
|
||||||
|
return this.inventory.canPlayerUse(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack transferSlot(PlayerEntity player, int invSlot) {
|
||||||
|
ItemStack newStack = ItemStack.EMPTY;
|
||||||
|
Slot slot = this.slots.get(invSlot);
|
||||||
|
if (slot != null && slot.hasStack()) {
|
||||||
|
ItemStack originalStack = slot.getStack();
|
||||||
|
newStack = originalStack.copy();
|
||||||
|
if (invSlot < this.inventory.size()) {
|
||||||
|
if (!this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true)) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
} else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
if (originalStack.isEmpty()) {
|
||||||
|
slot.setStack(ItemStack.EMPTY);
|
||||||
|
} else {
|
||||||
|
slot.markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newStack;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
package de.jottyfan.minecraft.quickiefabric.container;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.Inventories;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
* @see https://fabricmc.net/wiki/tutorial:inventory
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ImplementedInventory extends Inventory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the item list of this inventory.
|
||||||
|
* Must return the same instance every time it's called.
|
||||||
|
*/
|
||||||
|
DefaultedList<ItemStack> getItems();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an inventory from the item list.
|
||||||
|
*/
|
||||||
|
static ImplementedInventory of(DefaultedList<ItemStack> items) {
|
||||||
|
return () -> items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new inventory with the specified size.
|
||||||
|
*/
|
||||||
|
static ImplementedInventory ofSize(int size) {
|
||||||
|
return of(DefaultedList.ofSize(size, ItemStack.EMPTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the inventory size.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default int size() {
|
||||||
|
return getItems().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the inventory is empty.
|
||||||
|
* @return true if this inventory has only empty stacks, false otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default boolean isEmpty() {
|
||||||
|
for (int i = 0; i < size(); i++) {
|
||||||
|
ItemStack stack = getStack(i);
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the item in the slot.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ItemStack getStack(int slot) {
|
||||||
|
return getItems().get(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes items from an inventory slot.
|
||||||
|
* @param slot The slot to remove from.
|
||||||
|
* @param count How many items to remove. If there are less items in the slot than what are requested,
|
||||||
|
* takes all items in that slot.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ItemStack removeStack(int slot, int count) {
|
||||||
|
ItemStack result = Inventories.splitStack(getItems(), slot, count);
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all items from an inventory slot.
|
||||||
|
* @param slot The slot to remove from.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ItemStack removeStack(int slot) {
|
||||||
|
return Inventories.removeStack(getItems(), slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the current stack in an inventory slot with the provided stack.
|
||||||
|
* @param slot The inventory slot of which to replace the itemstack.
|
||||||
|
* @param stack The replacing itemstack. If the stack is too big for
|
||||||
|
* this inventory ({@link Inventory#getMaxCountPerStack()}),
|
||||||
|
* it gets resized to this inventory's maximum amount.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default void setStack(int slot, ItemStack stack) {
|
||||||
|
getItems().set(slot, stack);
|
||||||
|
if (stack.getCount() > stack.getMaxCount()) {
|
||||||
|
stack.setCount(stack.getMaxCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the inventory.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default void clear() {
|
||||||
|
getItems().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the state as dirty.
|
||||||
|
* Must be called after changes in the inventory, so that the game can properly save
|
||||||
|
* the inventory contents and notify neighboring blocks of inventory changes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default void markDirty() {
|
||||||
|
// Override if you want behavior.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the player can use the inventory, false otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default boolean canPlayerUse(PlayerEntity player) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,6 @@ import java.util.function.Predicate;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.quickiefabric.blockentity.BlockSpreaderEntity;
|
|
||||||
import de.jottyfan.minecraft.quickiefabric.blockentity.BlockStackerEntity;
|
import de.jottyfan.minecraft.quickiefabric.blockentity.BlockStackerEntity;
|
||||||
import de.jottyfan.minecraft.quickiefabric.blockentity.DrillBlockDownEntity;
|
import de.jottyfan.minecraft.quickiefabric.blockentity.DrillBlockDownEntity;
|
||||||
import de.jottyfan.minecraft.quickiefabric.blockentity.DrillBlockEastEntity;
|
import de.jottyfan.minecraft.quickiefabric.blockentity.DrillBlockEastEntity;
|
||||||
@ -19,6 +18,7 @@ import de.jottyfan.minecraft.quickiefabric.blockentity.MonsterHoarderBlockEntity
|
|||||||
import de.jottyfan.minecraft.quickiefabric.blockentity.QuickieFabricBlockEntity;
|
import de.jottyfan.minecraft.quickiefabric.blockentity.QuickieFabricBlockEntity;
|
||||||
import de.jottyfan.minecraft.quickiefabric.blocks.QuickieBlocks;
|
import de.jottyfan.minecraft.quickiefabric.blocks.QuickieBlocks;
|
||||||
import de.jottyfan.minecraft.quickiefabric.container.BackpackScreenHandler;
|
import de.jottyfan.minecraft.quickiefabric.container.BackpackScreenHandler;
|
||||||
|
import de.jottyfan.minecraft.quickiefabric.container.BlockStackerScreenHandler;
|
||||||
import de.jottyfan.minecraft.quickiefabric.event.BreakBlockCallback;
|
import de.jottyfan.minecraft.quickiefabric.event.BreakBlockCallback;
|
||||||
import de.jottyfan.minecraft.quickiefabric.event.EventBlockBreak;
|
import de.jottyfan.minecraft.quickiefabric.event.EventBlockBreak;
|
||||||
import de.jottyfan.minecraft.quickiefabric.items.QuickieItems;
|
import de.jottyfan.minecraft.quickiefabric.items.QuickieItems;
|
||||||
@ -72,6 +72,9 @@ public class RegistryManager {
|
|||||||
public static final Identifier BACKPACK_IDENTIFIER = new Identifier(QUICKIEFABRIC, "backpack");
|
public static final Identifier BACKPACK_IDENTIFIER = new Identifier(QUICKIEFABRIC, "backpack");
|
||||||
public static final ScreenHandlerType<BackpackScreenHandler> BACKPACK_SCREEN_HANDLER = ScreenHandlerRegistry
|
public static final ScreenHandlerType<BackpackScreenHandler> BACKPACK_SCREEN_HANDLER = ScreenHandlerRegistry
|
||||||
.registerExtended(RegistryManager.BACKPACK_IDENTIFIER, BackpackScreenHandler::new);
|
.registerExtended(RegistryManager.BACKPACK_IDENTIFIER, BackpackScreenHandler::new);
|
||||||
|
public static final Identifier STACKER_IDENTIFIER = new Identifier(QUICKIEFABRIC, "stacker");
|
||||||
|
public static final ScreenHandlerType<BlockStackerScreenHandler> BLOCKSTACKER_SCREEN_HANDLER = ScreenHandlerRegistry
|
||||||
|
.registerSimple(RegistryManager.STACKER_IDENTIFIER, BlockStackerScreenHandler::new);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static final ConfiguredFeature<?, ?> CF_ORESULPHOR = new ConfiguredFeature(Feature.ORE, new OreFeatureConfig(
|
public static final ConfiguredFeature<?, ?> CF_ORESULPHOR = new ConfiguredFeature(Feature.ORE, new OreFeatureConfig(
|
||||||
@ -216,8 +219,6 @@ public class RegistryManager {
|
|||||||
"blockstackerentity", BlockStackerEntity::new, QuickieBlocks.BLOCKSTACKERUP, QuickieBlocks.BLOCKSTACKERDOWN,
|
"blockstackerentity", BlockStackerEntity::new, QuickieBlocks.BLOCKSTACKERUP, QuickieBlocks.BLOCKSTACKERDOWN,
|
||||||
QuickieBlocks.BLOCKSTACKEREAST, QuickieBlocks.BLOCKSTACKERWEST, QuickieBlocks.BLOCKSTACKERNORTH,
|
QuickieBlocks.BLOCKSTACKEREAST, QuickieBlocks.BLOCKSTACKERWEST, QuickieBlocks.BLOCKSTACKERNORTH,
|
||||||
QuickieBlocks.BLOCKSTACKERSOUTH);
|
QuickieBlocks.BLOCKSTACKERSOUTH);
|
||||||
QuickieFabricBlockEntity.BLOCKSPREADER_ENTITY = (BlockEntityType<BlockSpreaderEntity>) registerBlockEntity(
|
|
||||||
"blockspreaderentity", BlockSpreaderEntity::new, QuickieBlocks.BLOCKSPREADER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void registerBlocks() {
|
public static final void registerBlocks() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user