Added compacting drawer
This commit is contained in:
parent
c67ee44d4a
commit
7877be2bc6
|
@ -4,9 +4,13 @@ ad618fbf42f1c54275c29beaa25710bca73acef2 assets/functionalstorage/blockstates/ac
|
|||
3b02d94db9f2f0b4d9b7b4a412427929a6f87d2b assets/functionalstorage/blockstates/birch_wood_x_1.json
|
||||
7bd0dc17af1d849100a423ca36eacb767bb2b1ea assets/functionalstorage/blockstates/birch_wood_x_2.json
|
||||
7e20830acae23717dd782ebf628e5eef778de0c1 assets/functionalstorage/blockstates/birch_wood_x_4.json
|
||||
78ab16e1714fbed8ba98acfe243a89c15587feb0 assets/functionalstorage/blockstates/compacting_drawer.json
|
||||
e0fee0fdb3a3e76bd6ca5a8f92f7c6c5e54b5e23 assets/functionalstorage/blockstates/crimson_hyphae_x_1.json
|
||||
17eec305ac9c19c66a32af11de2e1a528fa00894 assets/functionalstorage/blockstates/crimson_hyphae_x_2.json
|
||||
ffcd4cbf2a5406b7e4f96e87ad643b1feb18caf3 assets/functionalstorage/blockstates/crimson_hyphae_x_4.json
|
||||
243258d54301c9f1cb03b313a6caf248d9c42943 assets/functionalstorage/blockstates/dark_oak_wood_x_1.json
|
||||
a3e62a3fe37312b70cfd621784f782d18e063475 assets/functionalstorage/blockstates/dark_oak_wood_x_2.json
|
||||
586ce6d546f06d679d720166421d049afc7138a2 assets/functionalstorage/blockstates/dark_oak_wood_x_4.json
|
||||
a75ff2ba030156b42ed5e545fbf8e06f9854bf2c assets/functionalstorage/blockstates/jungle_wood_x_1.json
|
||||
19ae7afc5de0593b427309159c299e8d2ddfc4cd assets/functionalstorage/blockstates/jungle_wood_x_2.json
|
||||
228dd78c840b995c601704c32eaf17fe007d0346 assets/functionalstorage/blockstates/jungle_wood_x_4.json
|
||||
|
@ -25,9 +29,13 @@ a0f7a648fc02bbe7951b1616e8b5024e98b9f4bc data/functionalstorage/loot_tables/bloc
|
|||
9e61407957cd64d6bf221214d2766fbf0387f810 data/functionalstorage/loot_tables/blocks/birch_wood_x_1.json
|
||||
6dc0f3e0eb3c0d95946727dc7a94889eba7b3d9d data/functionalstorage/loot_tables/blocks/birch_wood_x_2.json
|
||||
bb380824c89d14571908e3283170112c0425f832 data/functionalstorage/loot_tables/blocks/birch_wood_x_4.json
|
||||
5ca84bb6e4d35893da638b52bb7884426a409719 data/functionalstorage/loot_tables/blocks/compacting_drawer.json
|
||||
751843faeb73f732abf09285fa5db1c22d3e9aa7 data/functionalstorage/loot_tables/blocks/crimson_hyphae_x_1.json
|
||||
f5f4160a7223af9205e2df1917b58bd00a65a1bc data/functionalstorage/loot_tables/blocks/crimson_hyphae_x_2.json
|
||||
598f9907cefdc9a2acd5019ea744979f24c561b2 data/functionalstorage/loot_tables/blocks/crimson_hyphae_x_4.json
|
||||
ae61cae584aed7ecd672d5223992d9949af4acf0 data/functionalstorage/loot_tables/blocks/dark_oak_wood_x_1.json
|
||||
8b7272c3fc37b4683678c95502c80d6e3d1618a9 data/functionalstorage/loot_tables/blocks/dark_oak_wood_x_2.json
|
||||
0e29723f48411634d77aa1f8ccb668761f0f529d data/functionalstorage/loot_tables/blocks/dark_oak_wood_x_4.json
|
||||
a3f6195051ee19033bb167e924645cfff1982c13 data/functionalstorage/loot_tables/blocks/jungle_wood_x_1.json
|
||||
a9054f38503082c4448495eb28477f4aad833b6c data/functionalstorage/loot_tables/blocks/jungle_wood_x_2.json
|
||||
7d0ec816a992ae76cf1b32cffa386a60ed59a7c8 data/functionalstorage/loot_tables/blocks/jungle_wood_x_4.json
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"subfacing=north": {
|
||||
"model": "functionalstorage:block/compacting_drawer"
|
||||
},
|
||||
"subfacing=south": {
|
||||
"model": "functionalstorage:block/compacting_drawer",
|
||||
"y": 180
|
||||
},
|
||||
"subfacing=west": {
|
||||
"model": "functionalstorage:block/compacting_drawer",
|
||||
"y": 270
|
||||
},
|
||||
"subfacing=east": {
|
||||
"model": "functionalstorage:block/compacting_drawer",
|
||||
"y": 90
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1.0,
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:copy_nbt",
|
||||
"source": "block_entity",
|
||||
"ops": [
|
||||
{
|
||||
"source": "handler",
|
||||
"target": "BlockEntityTag.handler",
|
||||
"op": "replace"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "functionalstorage:compacting_drawer"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package com.buuz135.functionalstorage;
|
||||
|
||||
import com.buuz135.functionalstorage.block.CompactingDrawerBlock;
|
||||
import com.buuz135.functionalstorage.block.DrawerBlock;
|
||||
import com.buuz135.functionalstorage.client.CompactingDrawerRenderer;
|
||||
import com.buuz135.functionalstorage.client.DrawerRenderer;
|
||||
import com.buuz135.functionalstorage.data.FunctionalStorageBlockstateProvider;
|
||||
import com.hrznstudio.titanium.block.BasicTileBlock;
|
||||
|
@ -19,7 +21,6 @@ import net.minecraftforge.client.event.EntityRenderersEvent;
|
|||
import net.minecraftforge.common.util.NonNullLazy;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
@ -40,6 +41,8 @@ public class FunctionalStorage extends ModuleController {
|
|||
|
||||
public static List<String> WOOD_TYPES = new ArrayList<>();
|
||||
public static HashMap<DrawerType, List<RegistryObject<Block>>> DRAWER_TYPES = new HashMap<>();
|
||||
public static RegistryObject<Block> COMPACTING_DRAWER;
|
||||
|
||||
public static AdvancedTitaniumTab TAB = new AdvancedTitaniumTab("functionalstorage", true);
|
||||
|
||||
public FunctionalStorage() {
|
||||
|
@ -69,7 +72,7 @@ public class FunctionalStorage extends ModuleController {
|
|||
}
|
||||
DRAWER_TYPES.get(value).forEach(blockRegistryObject -> TAB.addIconStacks(() -> new ItemStack(blockRegistryObject.get())));
|
||||
}
|
||||
|
||||
COMPACTING_DRAWER = getRegistries().register(Block.class, "compacting_drawer", () -> new CompactingDrawerBlock("compacting_drawer"));
|
||||
}
|
||||
|
||||
public enum DrawerType{
|
||||
|
@ -101,6 +104,8 @@ public class FunctionalStorage extends ModuleController {
|
|||
registerRenderers.registerBlockEntityRenderer(((BasicTileBlock)blockRegistryObject.get()).getTileEntityType(), p_173571_ -> new DrawerRenderer());
|
||||
});
|
||||
}
|
||||
registerRenderers.registerBlockEntityRenderer(((BasicTileBlock)COMPACTING_DRAWER.get()).getTileEntityType(), p_173571_ -> new CompactingDrawerRenderer());
|
||||
|
||||
}).subscribe();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
package com.buuz135.functionalstorage.block;
|
||||
|
||||
import com.buuz135.functionalstorage.FunctionalStorage;
|
||||
import com.buuz135.functionalstorage.block.tile.CompactingDrawerTile;
|
||||
import com.buuz135.functionalstorage.block.tile.DrawerTile;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.hrznstudio.titanium.block.RotatableBlock;
|
||||
import com.hrznstudio.titanium.datagenerator.loot.block.BasicBlockLootTables;
|
||||
import com.hrznstudio.titanium.module.DeferredRegistryHelper;
|
||||
import com.hrznstudio.titanium.util.RayTraceUtils;
|
||||
import com.hrznstudio.titanium.util.TileUtil;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootTable;
|
||||
import net.minecraft.world.level.storage.loot.functions.CopyNbtFunction;
|
||||
import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.shapes.BooleanOp;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class CompactingDrawerBlock extends RotatableBlock<CompactingDrawerTile> {
|
||||
|
||||
public static Multimap<Direction, VoxelShape> CACHED_SHAPES = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||
|
||||
static {
|
||||
CACHED_SHAPES.put(Direction.NORTH, Shapes.box(1/16D, 1/16D, 0, 8/16D, 8/16D, 1/16D));
|
||||
CACHED_SHAPES.put(Direction.NORTH, Shapes.box(8/16D, 1/16D, 0, 15/16D, 8/16D, 1/16D));
|
||||
CACHED_SHAPES.put(Direction.NORTH, Shapes.box(1/16D, 8/16D, 0, 15/16D, 15/16D, 1/16D));
|
||||
CACHED_SHAPES.put(Direction.SOUTH, Shapes.box(8/16D, 1/16D, 15/16D, 15/16D, 8/16D, 1));
|
||||
CACHED_SHAPES.put(Direction.SOUTH, Shapes.box(1/16D, 1/16D, 15/16D, 8/16D, 8/16D, 1));
|
||||
CACHED_SHAPES.put(Direction.SOUTH, Shapes.box(1/16D, 8/16D, 15/16D, 15/16D, 15/16D, 1));
|
||||
CACHED_SHAPES.put(Direction.EAST, Shapes.box(15/16D, 1/16D, 1/16D, 1, 8/16D, 7/16D));
|
||||
CACHED_SHAPES.put(Direction.EAST, Shapes.box(15/16D, 1/16D, 8/16D, 1, 8/16D, 15/16D));
|
||||
CACHED_SHAPES.put(Direction.EAST, Shapes.box(15/16D, 8/16D, 1/16D, 1, 15/16D, 15/16D));
|
||||
CACHED_SHAPES.put(Direction.WEST, Shapes.box(0, 1/16D, 8/16D, 1/16D, 8/16D, 15/16D));
|
||||
CACHED_SHAPES.put(Direction.WEST, Shapes.box(0, 1/16D, 1/16D, 1/16D, 8/16D, 7/16D));
|
||||
CACHED_SHAPES.put(Direction.WEST, Shapes.box(0, 8/16D, 1/16D, 1/16D, 15/16D, 15/16D));
|
||||
}
|
||||
|
||||
|
||||
public CompactingDrawerBlock(String name) {
|
||||
super(name, Properties.copy(Blocks.OAK_PLANKS), CompactingDrawerTile.class);
|
||||
setItemGroup(FunctionalStorage.TAB);
|
||||
registerDefaultState(defaultBlockState().setValue(RotatableBlock.FACING_HORIZONTAL, Direction.NORTH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAlternatives(DeferredRegistryHelper registry) {
|
||||
super.addAlternatives(registry);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public RotationType getRotationType() {
|
||||
return RotationType.FOUR_WAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType.BlockEntitySupplier<CompactingDrawerTile> getTileEntityFactory() {
|
||||
return (blockPos, state) -> new CompactingDrawerTile(this, blockPos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VoxelShape> getBoundingBoxes(BlockState state, BlockGetter source, BlockPos pos) {
|
||||
return getShapes(state, source, pos);
|
||||
}
|
||||
|
||||
private static List<VoxelShape> getShapes(BlockState state, BlockGetter source, BlockPos pos){
|
||||
List<VoxelShape> boxes = new ArrayList<>();
|
||||
CACHED_SHAPES.get(state.getValue(RotatableBlock.FACING_HORIZONTAL)).forEach(boxes::add); //TODO
|
||||
VoxelShape total = Shapes.block();
|
||||
boxes.add(total);
|
||||
return boxes;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
|
||||
return Shapes.box(0, 0, 0, 1,1,1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomBoxes(BlockState state, BlockGetter source, BlockPos pos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIndividualRenderVoxelShape() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand hand, BlockHitResult ray) {
|
||||
return TileUtil.getTileEntity(worldIn, pos, CompactingDrawerTile.class).map(drawerTile -> drawerTile.onSlotActivated(player, hand, ray.getDirection(), ray.getLocation().x, ray.getLocation().y, ray.getLocation().z, getHit(state, worldIn, pos, player))).orElse(InteractionResult.PASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(BlockState state, Level worldIn, BlockPos pos, Player player) {
|
||||
TileUtil.getTileEntity(worldIn, pos, CompactingDrawerTile.class).ifPresent(drawerTile -> drawerTile.onClicked(player, getHit(state, worldIn, pos, player)));
|
||||
}
|
||||
|
||||
public int getHit(BlockState state, Level worldIn, BlockPos pos, Player player) {
|
||||
HitResult result = RayTraceUtils.rayTraceSimple(worldIn, player, 32, 0);
|
||||
if (result instanceof BlockHitResult) {
|
||||
VoxelShape hit = RayTraceUtils.rayTraceVoxelShape((BlockHitResult) result, worldIn, player, 32, 0);
|
||||
if (hit != null) {
|
||||
if (hit.equals(Shapes.block())) return -1;
|
||||
List<VoxelShape> shapes = new ArrayList<>(CACHED_SHAPES.get(state.getValue(RotatableBlock.FACING_HORIZONTAL))); //TODO
|
||||
for (int i = 0; i < shapes.size(); i++) {
|
||||
if (Shapes.joinIsNotEmpty(shapes.get(i), hit, BooleanOp.AND)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootTable.Builder getLootTable(@Nonnull BasicBlockLootTables blockLootTables) {
|
||||
CopyNbtFunction.Builder nbtBuilder = CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY);
|
||||
nbtBuilder.copy("handler", "BlockEntityTag.handler");
|
||||
return blockLootTables.droppingSelfWithNbt(this, nbtBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NonNullList<ItemStack> getDynamicDrops(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
return NonNullList.create();
|
||||
}
|
||||
|
||||
}
|
|
@ -66,15 +66,15 @@ public class DrawerBlock extends RotatableBlock<DrawerTile> {
|
|||
for (VoxelShape voxelShape : CACHED_SHAPES.get(FunctionalStorage.DrawerType.X_2).get(direction)) {
|
||||
AABB bounding = voxelShape.toAabbs().get(0);
|
||||
if (direction == Direction.NORTH || direction == Direction.SOUTH) {
|
||||
CACHED_SHAPES.computeIfAbsent(FunctionalStorage.DrawerType.X_4, type1 -> MultimapBuilder.hashKeys().arrayListValues().build()).
|
||||
put(direction, Shapes.box(bounding.minX, bounding.minY, bounding.minZ , 7/16D, bounding.maxY, bounding.maxZ));
|
||||
CACHED_SHAPES.computeIfAbsent(FunctionalStorage.DrawerType.X_4, type1 -> MultimapBuilder.hashKeys().arrayListValues().build()).
|
||||
put(direction, Shapes.box(9/16D, bounding.minY, bounding.minZ ,bounding.maxX, bounding.maxY, bounding.maxZ));
|
||||
CACHED_SHAPES.computeIfAbsent(FunctionalStorage.DrawerType.X_4, type1 -> MultimapBuilder.hashKeys().arrayListValues().build()).
|
||||
put(direction, Shapes.box(bounding.minX, bounding.minY, bounding.minZ , 7/16D, bounding.maxY, bounding.maxZ));
|
||||
} else {
|
||||
CACHED_SHAPES.computeIfAbsent(FunctionalStorage.DrawerType.X_4, type1 -> MultimapBuilder.hashKeys().arrayListValues().build()).
|
||||
put(direction, Shapes.box(bounding.minX, bounding.minY, 7/16D,bounding.maxX, bounding.maxY, bounding.maxZ));
|
||||
put(direction, Shapes.box(bounding.minX, bounding.minY, bounding.minZ , bounding.maxX, bounding.maxY, 7/16D));
|
||||
CACHED_SHAPES.computeIfAbsent(FunctionalStorage.DrawerType.X_4, type1 -> MultimapBuilder.hashKeys().arrayListValues().build()).
|
||||
put(direction, Shapes.box(bounding.minX, bounding.minY, bounding.minZ , bounding.maxX, bounding.maxY, 9/16D));
|
||||
put(direction, Shapes.box(bounding.minX, bounding.minY, 9/16D,bounding.maxX, bounding.maxY, bounding.maxZ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
package com.buuz135.functionalstorage.block.tile;
|
||||
|
||||
import com.buuz135.functionalstorage.FunctionalStorage;
|
||||
import com.buuz135.functionalstorage.inventory.BigInventoryHandler;
|
||||
import com.buuz135.functionalstorage.inventory.CompactingInventoryHandler;
|
||||
import com.buuz135.functionalstorage.util.CompactingUtil;
|
||||
import com.hrznstudio.titanium.annotation.Save;
|
||||
import com.hrznstudio.titanium.block.BasicTileBlock;
|
||||
import com.hrznstudio.titanium.block.tile.ActiveTile;
|
||||
import com.hrznstudio.titanium.util.RayTraceUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.datafix.fixes.ItemStackTheFlatteningFix;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CompactingDrawerTile extends ActiveTile<CompactingDrawerTile> {
|
||||
|
||||
private static HashMap<UUID, Long> INTERACTION_LOGGER = new HashMap<>();
|
||||
|
||||
@Save
|
||||
public CompactingInventoryHandler handler;
|
||||
private final LazyOptional<IItemHandler> lazyStorage;
|
||||
|
||||
public CompactingDrawerTile(BasicTileBlock<CompactingDrawerTile> base, BlockPos pos, BlockState state) {
|
||||
super(base, pos, state);
|
||||
this.handler = new CompactingInventoryHandler() {
|
||||
@Override
|
||||
public void onChange() {
|
||||
CompactingDrawerTile.this.markForUpdate();
|
||||
}
|
||||
};
|
||||
lazyStorage = LazyOptional.of(() -> this.handler);
|
||||
//TODO Check for the recipe on load
|
||||
}
|
||||
|
||||
public InteractionResult onSlotActivated(Player playerIn, InteractionHand hand, Direction facing, double hitX, double hitY, double hitZ, int slot) {
|
||||
if (super.onActivated(playerIn, hand, facing, hitX, hitY, hitZ) == InteractionResult.SUCCESS) {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
if (slot == -1){
|
||||
openGui(playerIn);
|
||||
} else if (isServer()){
|
||||
if (!handler.isSetup()){
|
||||
ItemStack stack = playerIn.getItemInHand(hand).copy();
|
||||
stack.setCount(1);
|
||||
CompactingUtil compactingUtil = new CompactingUtil(this.level);
|
||||
compactingUtil.setup(stack);
|
||||
handler.setup(compactingUtil);
|
||||
for (int i = 0; i < handler.getResultList().size(); i++) {
|
||||
if (ItemStack.isSame(handler.getResultList().get(i).getResult(), stack)){
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemStack stack = playerIn.getItemInHand(hand);
|
||||
if (!stack.isEmpty() && handler.isItemValid(slot, stack)) {
|
||||
playerIn.setItemInHand(hand, handler.insertItem(slot, stack, false));
|
||||
} else if (System.currentTimeMillis() - INTERACTION_LOGGER.getOrDefault(playerIn.getUUID(), System.currentTimeMillis()) < 300) {
|
||||
for (ItemStack itemStack : playerIn.getInventory().items) {
|
||||
if (!itemStack.isEmpty() && handler.insertItem(slot, itemStack, true).isEmpty()) {
|
||||
handler.insertItem(slot, itemStack.copy(), false);
|
||||
itemStack.setCount(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
INTERACTION_LOGGER.put(playerIn.getUUID(), System.currentTimeMillis());
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public void onClicked(Player playerIn, int slot) {
|
||||
if (isServer()){
|
||||
HitResult rayTraceResult = RayTraceUtils.rayTraceSimple(this.level, playerIn, 16, 0);
|
||||
if (rayTraceResult.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockResult = (BlockHitResult) rayTraceResult;
|
||||
Direction facing = blockResult.getDirection();
|
||||
if (facing.equals(this.getFacingDirection())){
|
||||
ItemHandlerHelper.giveItemToPlayer(playerIn, handler.extractItem(slot, playerIn.isShiftKeyDown() ? 64 : 1, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <U> LazyOptional<U> getCapability(@Nonnull Capability<U> cap, @Nullable Direction side) {
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
return lazyStorage.cast();
|
||||
}
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CompactingDrawerTile getSelf() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompactingInventoryHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
|
@ -75,7 +75,7 @@ public class DrawerTile extends ActiveTile<DrawerTile> {
|
|||
}
|
||||
|
||||
public void onClicked(Player playerIn, int slot) {
|
||||
if (isServer()){
|
||||
if (isServer() && slot != -1){
|
||||
HitResult rayTraceResult = RayTraceUtils.rayTraceSimple(this.level, playerIn, 16, 0);
|
||||
if (rayTraceResult.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockResult = (BlockHitResult) rayTraceResult;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package com.buuz135.functionalstorage.client;
|
||||
|
||||
import com.buuz135.functionalstorage.FunctionalStorage;
|
||||
import com.buuz135.functionalstorage.block.tile.CompactingDrawerTile;
|
||||
import com.buuz135.functionalstorage.block.tile.DrawerTile;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Matrix3f;
|
||||
import com.mojang.math.Quaternion;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class CompactingDrawerRenderer implements BlockEntityRenderer<CompactingDrawerTile> {
|
||||
|
||||
private static final Matrix3f FAKE_NORMALS;
|
||||
|
||||
static {
|
||||
Vector3f NORMAL = new Vector3f(1, 1, 1);
|
||||
NORMAL.normalize();
|
||||
FAKE_NORMALS = new Matrix3f(new Quaternion(NORMAL, 0, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(CompactingDrawerTile tile, float partialTicks, PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn) {
|
||||
matrixStack.pushPose();
|
||||
|
||||
Direction facing = tile.getFacingDirection();
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(-180));
|
||||
matrixStack.last().normal().load(FAKE_NORMALS);
|
||||
if (facing == Direction.NORTH) {
|
||||
//matrixStack.translate(0, 0, 1.016 / 16D);
|
||||
matrixStack.translate(-1, 0, 0);
|
||||
}
|
||||
if (facing == Direction.EAST) {
|
||||
matrixStack.translate(-1, 0, -1);
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(-90));
|
||||
}
|
||||
if (facing == Direction.SOUTH) {
|
||||
matrixStack.translate(0, 0,-1);
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(-180));
|
||||
}
|
||||
if (facing == Direction.WEST) {
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(90));
|
||||
}
|
||||
combinedLightIn = LevelRenderer.getLightColor(tile.getLevel(), tile.getBlockPos().relative(facing));
|
||||
ItemStack stack = tile.getHandler().getResultList().get(0).getResult();
|
||||
if (!stack.isEmpty()){
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.725, 0.30f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
DrawerRenderer.renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, tile.getHandler().getStackInSlot(0).getCount(), 0.02f);
|
||||
matrixStack.popPose();
|
||||
}
|
||||
stack = tile.getHandler().getResultList().get(1).getResult();
|
||||
if (!stack.isEmpty()){
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.275, 0.30f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
DrawerRenderer.renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, tile.getHandler().getStackInSlot(1).getCount(), 0.02f);
|
||||
matrixStack.popPose();
|
||||
}
|
||||
stack = tile.getHandler().getResultList().get(2).getResult();
|
||||
if (!stack.isEmpty()){
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.5, 0.75f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
DrawerRenderer.renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, tile.getHandler().getStackInSlot(2).getCount(), 0.02f);
|
||||
matrixStack.popPose();
|
||||
}
|
||||
matrixStack.popPose();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,6 +14,7 @@ import net.minecraft.client.renderer.LevelRenderer;
|
|||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
|
@ -36,7 +37,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
|
||||
Direction facing = tile.getFacingDirection();
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(-180));
|
||||
matrixStack.last().normal().load(FAKE_NORMALS);
|
||||
if (facing != Direction.SOUTH) matrixStack.last().normal().load(FAKE_NORMALS);
|
||||
if (facing == Direction.NORTH) {
|
||||
//matrixStack.translate(0, 0, 1.016 / 16D);
|
||||
matrixStack.translate(-1, 0, 0);
|
||||
|
@ -52,6 +53,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
if (facing == Direction.WEST) {
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(90));
|
||||
}
|
||||
matrixStack.translate(0,0,-0.5/16D);
|
||||
combinedLightIn = LevelRenderer.getLightColor(tile.getLevel(), tile.getBlockPos().relative(facing));
|
||||
if (tile.getDrawerType() == FunctionalStorage.DrawerType.X_1) render1Slot(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, tile);
|
||||
if (tile.getDrawerType() == FunctionalStorage.DrawerType.X_2) render2Slot(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, tile);
|
||||
|
@ -70,7 +72,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
private void render2Slot(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, DrawerTile tile){
|
||||
if (!tile.getHandler().getStackInSlot(0).isEmpty()){
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.5, 0.30f, 0.0005f);
|
||||
matrixStack.translate(0.5, 0.27f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
ItemStack stack = tile.getHandler().getStackInSlot(0);
|
||||
renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f);
|
||||
|
@ -78,7 +80,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
}
|
||||
if (!tile.getHandler().getStackInSlot(1).isEmpty()){
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.5, 0.75f, 0.0005f);
|
||||
matrixStack.translate(0.5, 0.77f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
ItemStack stack = tile.getHandler().getStackInSlot(1);
|
||||
renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f);
|
||||
|
@ -88,7 +90,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
private void render4Slot(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, DrawerTile tile){
|
||||
if (!tile.getHandler().getStackInSlot(0).isEmpty()){ //BOTTOM RIGHT
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.725, 0.30f, 0.0005f);
|
||||
matrixStack.translate(0.75, 0.27f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
ItemStack stack = tile.getHandler().getStackInSlot(0);
|
||||
renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f);
|
||||
|
@ -96,7 +98,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
}
|
||||
if (!tile.getHandler().getStackInSlot(1).isEmpty()){ //BOTTOM LEFT
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.275, 0.30f, 0.0005f);
|
||||
matrixStack.translate(0.25, 0.27f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
ItemStack stack = tile.getHandler().getStackInSlot(1);
|
||||
renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f);
|
||||
|
@ -104,7 +106,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
}
|
||||
if (!tile.getHandler().getStackInSlot(2).isEmpty()){ //TOP RIGHT
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.725, 0.75f, 0.0005f);
|
||||
matrixStack.translate(0.75, 0.77f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
ItemStack stack = tile.getHandler().getStackInSlot(2);
|
||||
renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f);
|
||||
|
@ -112,7 +114,7 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
}
|
||||
if (!tile.getHandler().getStackInSlot(3).isEmpty()){ //TOP LEFT
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(0.275, 0.75f, 0.0005f);
|
||||
matrixStack.translate(0.25, 0.77f, 0.0005f);
|
||||
matrixStack.scale(0.5f, 0.5f, 1);
|
||||
ItemStack stack = tile.getHandler().getStackInSlot(3);
|
||||
renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f);
|
||||
|
@ -121,25 +123,30 @@ public class DrawerRenderer implements BlockEntityRenderer<DrawerTile> {
|
|||
}
|
||||
|
||||
|
||||
private void renderStack(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, ItemStack stack, int amount, float scale){
|
||||
if (stack.getItem() instanceof BlockItem){
|
||||
matrixStack.scale(0.5f, 0.5f, 0.0001f);
|
||||
public static void renderStack(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, ItemStack stack, int amount, float scale){
|
||||
BakedModel model = Minecraft.getInstance().getItemRenderer().getModel(stack, Minecraft.getInstance().level, null, 0);
|
||||
if (model.isGui3d()){
|
||||
matrixStack.translate(0,0, -0.23f);
|
||||
matrixStack.scale(0.5f, 0.5f, 0.5f);
|
||||
} else {
|
||||
matrixStack.scale(0.4f, 0.4f, 0.0001f);
|
||||
matrixStack.scale(0.4f, 0.4f, 0.4f);
|
||||
}
|
||||
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemTransforms.TransformType.GUI, combinedLightIn, combinedOverlayIn, matrixStack, bufferIn, 0);
|
||||
if (!(stack.getItem() instanceof BlockItem)){
|
||||
|
||||
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemTransforms.TransformType.NONE, combinedLightIn, combinedOverlayIn, matrixStack, bufferIn, 0);
|
||||
if (!model.isGui3d()){
|
||||
matrixStack.scale(1/0.4f, 1/0.4f, 1/0.0001f);
|
||||
matrixStack.scale(0.5f, 0.5f, 0.0001f);
|
||||
}else {
|
||||
matrixStack.translate(0,0, 0.23f*2);
|
||||
}
|
||||
renderText(matrixStack, bufferIn, combinedOverlayIn, new TextComponent(ChatFormatting.WHITE + "" + stack.getCount()), Direction.NORTH, scale);
|
||||
renderText(matrixStack, bufferIn, combinedOverlayIn, new TextComponent(ChatFormatting.WHITE + "" + amount), Direction.NORTH, scale);
|
||||
}
|
||||
|
||||
|
||||
/* Thanks Mekanism */
|
||||
private void renderText(PoseStack matrix, MultiBufferSource renderer, int overlayLight, Component text, Direction side, float maxScale) {
|
||||
public static void renderText(PoseStack matrix, MultiBufferSource renderer, int overlayLight, Component text, Direction side, float maxScale) {
|
||||
|
||||
matrix.translate(0, -0.8, 0);
|
||||
matrix.translate(0, -0.745, 0);
|
||||
|
||||
|
||||
float displayWidth = 1;
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
package com.buuz135.functionalstorage.inventory;
|
||||
|
||||
import com.buuz135.functionalstorage.util.CompactingUtil;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CompactingInventoryHandler implements IItemHandler, INBTSerializable<CompoundTag> {
|
||||
|
||||
public static String VOID = "Void";
|
||||
public static String BIG_ITEMS = "BigItems";
|
||||
public static String STACK = "Stack";
|
||||
public static String AMOUNT = "Amount";
|
||||
|
||||
private final int TOTAL_AMOUNT = 8192 * 9 * 9;
|
||||
|
||||
private int amount;
|
||||
private boolean voidItems;
|
||||
private List<CompactingUtil.Result> resultList;
|
||||
|
||||
public CompactingInventoryHandler(){
|
||||
this.resultList = new ArrayList<>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
this.resultList.add(i, new CompactingUtil.Result(ItemStack.EMPTY, 1));
|
||||
}
|
||||
this.voidItems = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
CompactingUtil.Result bigStack = this.resultList.get(slot);
|
||||
ItemStack copied = bigStack.getResult().copy();
|
||||
copied.setCount(this.amount / bigStack.getNeeded());
|
||||
return copied;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||
if (isItemValid(slot, stack)) {
|
||||
CompactingUtil.Result result = this.resultList.get(slot);
|
||||
int inserted = Math.min(TOTAL_AMOUNT - amount, stack.getCount() * result.getNeeded());
|
||||
inserted = (int) (Math.floor(inserted / result.getNeeded()) * result.getNeeded());
|
||||
if (!simulate){
|
||||
this.amount = Math.min(this.amount + inserted, TOTAL_AMOUNT);
|
||||
onChange();
|
||||
}
|
||||
if (inserted == stack.getCount() * result.getNeeded() || voidItems) return ItemStack.EMPTY;
|
||||
return ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - inserted / result.getNeeded());
|
||||
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetup(){
|
||||
return !this.resultList.get(this.resultList.size() -1).getResult().isEmpty();
|
||||
}
|
||||
|
||||
public void setup(CompactingUtil compactingUtil){
|
||||
this.resultList = compactingUtil.getResults();
|
||||
onChange();
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
this.resultList.forEach(result -> {
|
||||
result.setResult(ItemStack.EMPTY);
|
||||
result.setNeeded(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
if (amount == 0) return ItemStack.EMPTY;
|
||||
if (slot < 3){
|
||||
CompactingUtil.Result bigStack = this.resultList.get(slot);
|
||||
if (bigStack.getResult().isEmpty()) return ItemStack.EMPTY;
|
||||
int stackAmount = bigStack.getNeeded() * amount;
|
||||
if (stackAmount >= this.amount) {
|
||||
ItemStack out = bigStack.getResult().copy();
|
||||
int newAmount = (int) Math.floor(this.amount / bigStack.getNeeded());
|
||||
if (!simulate) {
|
||||
//TODO Dont change if locked
|
||||
this.amount -= (newAmount * bigStack.getNeeded());
|
||||
if (this.amount == 0) reset();
|
||||
onChange();
|
||||
}
|
||||
out.setCount(newAmount);
|
||||
return out;
|
||||
} else {
|
||||
if (!simulate) {
|
||||
this.amount -= stackAmount;
|
||||
onChange();
|
||||
}
|
||||
return ItemHandlerHelper.copyStackWithSize(bigStack.getResult(), amount);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return (int) Math.floor(TOTAL_AMOUNT / this.resultList.get(slot).getNeeded());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
|
||||
if (slot < 3){
|
||||
CompactingUtil.Result bigStack = this.resultList.get(slot);
|
||||
ItemStack fl = bigStack.getResult();
|
||||
return !fl.isEmpty() && fl.sameItem(stack) && ItemStack.tagMatches(fl, stack);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
compoundTag.putBoolean(VOID, voidItems);
|
||||
compoundTag.putInt(AMOUNT, this.amount);
|
||||
CompoundTag items = new CompoundTag();
|
||||
for (int i = 0; i < this.resultList.size(); i++) {
|
||||
CompoundTag bigStack = new CompoundTag();
|
||||
bigStack.put(STACK, this.resultList.get(i).getResult().serializeNBT());
|
||||
bigStack.putInt(AMOUNT, this.resultList.get(i).getNeeded());
|
||||
items.put(i + "", bigStack);
|
||||
}
|
||||
compoundTag.put(BIG_ITEMS, items);
|
||||
return compoundTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag nbt) {
|
||||
this.voidItems = nbt.getBoolean(VOID);
|
||||
this.amount = nbt.getInt(AMOUNT);
|
||||
for (String allKey : nbt.getCompound(BIG_ITEMS).getAllKeys()) {
|
||||
this.resultList.get(Integer.parseInt(allKey)).setResult(ItemStack.of(nbt.getCompound(BIG_ITEMS).getCompound(allKey).getCompound(STACK)));
|
||||
this.resultList.get(Integer.parseInt(allKey)).setNeeded(Math.max(1, nbt.getCompound(BIG_ITEMS).getCompound(allKey).getInt(AMOUNT)));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void onChange();
|
||||
|
||||
public List<CompactingUtil.Result> getResultList() {
|
||||
return resultList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
package com.buuz135.functionalstorage.util;
|
||||
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.CraftingContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.CraftingRecipe;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Some code in this class is from the original Storage Drawers
|
||||
* findSimilar
|
||||
* findAllMatchingRecipes
|
||||
* tryMatch
|
||||
* findLowerTier
|
||||
*/
|
||||
public class CompactingUtil {
|
||||
|
||||
private final Level level;
|
||||
private List<Result> results;
|
||||
|
||||
public CompactingUtil(Level level) {
|
||||
this.level = level;
|
||||
this.results = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setup(ItemStack stack){
|
||||
results.add(new Result(stack, 1));
|
||||
Result result = findUpperTier(stack);
|
||||
if (!result.getResult().isEmpty()){
|
||||
results.add(result);
|
||||
result = findUpperTier(result.getResult());
|
||||
if (!result.getResult().isEmpty()){
|
||||
result.setNeeded(result.getNeeded() * this.results.get(this.results.size() - 1).getNeeded());
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
boolean canFind = true;
|
||||
while (canFind && results.size() < 3){
|
||||
result = findLowerTier(results.get(0).getResult());
|
||||
if (!result.getResult().isEmpty()){
|
||||
for (Result result1 : results) {
|
||||
result1.setNeeded(result1.getNeeded() * result.getNeeded());
|
||||
}
|
||||
result.setNeeded(1);
|
||||
results.add(0, result);
|
||||
}else{
|
||||
canFind = false;
|
||||
}
|
||||
}
|
||||
while (results.size() < 3){
|
||||
results.add(0, new Result(ItemStack.EMPTY, 1));
|
||||
}
|
||||
}
|
||||
|
||||
public List<Result> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
private Result findUpperTier(ItemStack stack){
|
||||
//Checking 3x3
|
||||
int sizeCheck = 9;
|
||||
CraftingContainer container = createContainerAndFill(3, stack);
|
||||
List<ItemStack> outputs = findAllMatchingRecipes(container);
|
||||
List<ItemStack> realOutputs = new ArrayList<>();
|
||||
if (outputs.size() == 0){
|
||||
//Checking 2x2
|
||||
sizeCheck = 4;
|
||||
container = createContainerAndFill(2, stack);
|
||||
outputs = findAllMatchingRecipes(container);
|
||||
}
|
||||
if (outputs.size() > 0){
|
||||
for (ItemStack output : outputs) {
|
||||
container = createContainerAndFill(1, output);
|
||||
List<ItemStack> reversed = findAllMatchingRecipes(container);
|
||||
for (ItemStack reversedStack : reversed) {
|
||||
if (reversedStack.getCount() != sizeCheck || !ItemStack.isSame(reversedStack, stack)){
|
||||
continue;
|
||||
}
|
||||
realOutputs.add(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack similar = findSimilar(stack, realOutputs);
|
||||
if (!similar.isEmpty()){
|
||||
return new Result(similar, sizeCheck);
|
||||
}
|
||||
if (realOutputs.size() > 0){
|
||||
return new Result(realOutputs.get(0), sizeCheck);
|
||||
}
|
||||
return new Result(ItemStack.EMPTY, 0);
|
||||
}
|
||||
|
||||
private Result findLowerTier(ItemStack stack){
|
||||
List<ItemStack> candidates = new ArrayList<>();
|
||||
Map<ItemStack, Integer> candidatesRate = new HashMap<>();
|
||||
for (CraftingRecipe craftingRecipe : level.getRecipeManager().getAllRecipesFor(RecipeType.CRAFTING)) {
|
||||
ItemStack output = craftingRecipe.getResultItem();
|
||||
if (!ItemStack.isSame(stack, output)) continue;
|
||||
ItemStack match = tryMatch(stack, craftingRecipe.getIngredients());
|
||||
if (!match.isEmpty()){
|
||||
CraftingContainer container = createContainerAndFill(1, output);
|
||||
List<ItemStack> matchStacks = findAllMatchingRecipes(container);
|
||||
for (ItemStack matchStack : matchStacks) {
|
||||
int recipeSize = craftingRecipe.getIngredients().size();
|
||||
if (ItemStack.isSame(match, matchStack) && matchStack.getCount() == recipeSize){
|
||||
candidates.add(match);
|
||||
candidatesRate.put(match, recipeSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemStack similar = findSimilar(stack, candidates);
|
||||
if (!similar.isEmpty()){
|
||||
return new Result(similar, candidatesRate.get(similar));
|
||||
}
|
||||
if (candidates.size() > 0){
|
||||
return new Result(candidates.get(0), candidatesRate.get(candidates.get(0)));
|
||||
}
|
||||
return new Result(ItemStack.EMPTY, 0);
|
||||
}
|
||||
|
||||
private List<ItemStack> findAllMatchingRecipes(CraftingContainer crafting) {
|
||||
List<ItemStack> candidates = new ArrayList<>();
|
||||
for (CraftingRecipe recipe : level.getRecipeManager().getRecipesFor(RecipeType.CRAFTING, crafting, level)) {
|
||||
if (recipe.matches(crafting, level)) {
|
||||
ItemStack result = recipe.assemble(crafting);
|
||||
if (!result.isEmpty())
|
||||
candidates.add(result);
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private ItemStack findSimilar(ItemStack reference, List<ItemStack> candidates) {
|
||||
ResourceLocation referenceName = reference.getItem().getRegistryName();
|
||||
if (referenceName != null) {
|
||||
for (ItemStack candidate : candidates) {
|
||||
ResourceLocation matchName = candidate.getItem().getRegistryName();
|
||||
if (matchName != null) {
|
||||
if (referenceName.getNamespace().equals(matchName.getNamespace()))
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
private ItemStack tryMatch(ItemStack stack, NonNullList<Ingredient> ingredients) {
|
||||
if (ingredients.size() != 9 && ingredients.size() != 4)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
Ingredient refIngredient = ingredients.get(0);
|
||||
ItemStack[] refMatchingStacks = refIngredient.getItems();
|
||||
if (refMatchingStacks.length == 0)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
for (int i = 1, n = ingredients.size(); i < n; i++) {
|
||||
Ingredient ingredient = ingredients.get(i);
|
||||
ItemStack match = ItemStack.EMPTY;
|
||||
|
||||
for (ItemStack ingItemMatch : refMatchingStacks) {
|
||||
if (ingredient.test(ingItemMatch)) {
|
||||
match = ingItemMatch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match.isEmpty())
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack match = findSimilar(stack, Arrays.asList(refMatchingStacks));
|
||||
if (match.isEmpty())
|
||||
match = refMatchingStacks[0];
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
private CraftingContainer createContainerAndFill(int size, ItemStack stack){
|
||||
CraftingContainer inventoryCrafting = new CraftingContainer(new AbstractContainerMenu(null, 0) {
|
||||
@Override
|
||||
public boolean stillValid(Player playerIn) {
|
||||
return false;
|
||||
}
|
||||
}, size, size);
|
||||
for (int i = 0; i < size * size; i++) {
|
||||
inventoryCrafting.setItem(i, stack.copy());
|
||||
}
|
||||
return inventoryCrafting;
|
||||
}
|
||||
|
||||
public static class Result{
|
||||
|
||||
private ItemStack result;
|
||||
private int needed;
|
||||
|
||||
public Result(ItemStack result, int needed) {
|
||||
this.result = result;
|
||||
this.needed = needed;
|
||||
}
|
||||
|
||||
public ItemStack getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(ItemStack result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public int getNeeded() {
|
||||
return needed;
|
||||
}
|
||||
|
||||
public void setNeeded(int needed) {
|
||||
this.needed = needed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Result{" +
|
||||
"result=" + result +
|
||||
", needed=" + needed +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user