diff --git a/build.gradle b/build.gradle index fafa9e1..e301bd2 100644 --- a/build.gradle +++ b/build.gradle @@ -77,6 +77,9 @@ repositories { name = "Progwml6 maven" url = "https://dvs1.progwml6.com/files/maven/" } + maven { + url = "https://www.cursemaven.com" + } } dependencies { @@ -85,7 +88,7 @@ dependencies { implementation fg.deobf (project.dependencies.create('com.hrznstudio:titanium:1.18-3.4.0-21')) compileOnly fg.deobf("mezz.jei:jei-1.18.1:9.1.0.46:api") runtimeOnly fg.deobf("mezz.jei:jei-1.18.1:9.1.0.46") - + runtimeOnly fg.deobf("curse.maven:refined-storage-243076:3569563") } // Example for how to get properties into the manifest for reading at runtime. diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index ffe9109..e78ae22 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -20,10 +20,11 @@ e00984d2e6551ae9bb54afe92770e8c9e51d79d6 assets/functionalstorage/blockstates/oa d4d22c9ecc3622c578ccff9c8b38de4112a842f6 assets/functionalstorage/blockstates/spruce_1.json b14ae1d5fe1d5f8f045b057cc786c7b576844612 assets/functionalstorage/blockstates/spruce_2.json a0ff8d6c8f3d10d7773039df53dd3b6a5412bc10 assets/functionalstorage/blockstates/spruce_4.json +3232a9056ec6b919b6dbbe02eaf5d3a336730a9b assets/functionalstorage/blockstates/storage_controller.json e27f738dc4aeda4f45831ab1665a7f44a189a6eb assets/functionalstorage/blockstates/warped_1.json d219b51e15094f26af1f2e1c4578707c74a8892e assets/functionalstorage/blockstates/warped_2.json 9957ebb8beafe7cfa8634e1b19c3b9ed70a23ae5 assets/functionalstorage/blockstates/warped_4.json -7dfd29bec67fc31cc2b834f80cb034ef576b115c assets/functionalstorage/lang/en_us.json +9659c4f1025e1eeab4769a982ac3853e3ebc002b assets/functionalstorage/lang/en_us.json 6414c7bf11830af3646da15cb16e601930f785bd data/functionalstorage/loot_tables/blocks/acacia_1.json f0235fd68df6fd2797155af3d56fbe57bef2f0b0 data/functionalstorage/loot_tables/blocks/acacia_2.json db076fb77db0c54a6c9f45307d8c173bf87fb7a9 data/functionalstorage/loot_tables/blocks/acacia_4.json @@ -46,6 +47,7 @@ b64501320484c817174006830f28134d29e9b39a data/functionalstorage/loot_tables/bloc 04aa6aabcc0c5924370259e3d3663f2a4a9b8e11 data/functionalstorage/loot_tables/blocks/spruce_1.json 2effa67e8ffb8a6bb6305b237e0d1f79d55a0b9f data/functionalstorage/loot_tables/blocks/spruce_2.json 4a73c1ae9defb7037aea7ae293821ea4a5c99caa data/functionalstorage/loot_tables/blocks/spruce_4.json +4475a8cc23e9c657c58da5406aa97ff770f320e1 data/functionalstorage/loot_tables/blocks/storage_controller.json 8be1cfcdff30d37c151232db05fcde3b29464740 data/functionalstorage/loot_tables/blocks/warped_1.json 13434fb87cc92dabc7b8050ee4c1abd9177faa8b data/functionalstorage/loot_tables/blocks/warped_2.json 7cec2d7779fd9759bb1725e0c09bcaa105a4649b data/functionalstorage/loot_tables/blocks/warped_4.json @@ -74,4 +76,4 @@ ff234dac4f0b0b4f83ffa92f2d2fb1074c68df43 data/functionalstorage/recipes/spruce_4 bcb281904eac23183c45786e3d703d24bba92be6 data/functionalstorage/recipes/warped_1.json 8fc3f76a2c57eb4d80ce86947fabebe48fa6f692 data/functionalstorage/recipes/warped_2.json 7510a8ca1f1e3bb63f4c4f4add0bb6b713feaa0b data/functionalstorage/recipes/warped_4.json -0f4c6dba10677b5d217ee704be3d1deb92517fad data/functionalstorage/tags/items/drawer.json +db0122948639b122cb0c1df7530996e9784356b0 data/functionalstorage/tags/items/drawer.json diff --git a/src/generated/resources/assets/functionalstorage/blockstates/storage_controller.json b/src/generated/resources/assets/functionalstorage/blockstates/storage_controller.json new file mode 100644 index 0000000..bc29c2f --- /dev/null +++ b/src/generated/resources/assets/functionalstorage/blockstates/storage_controller.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "functionalstorage:block/storage_controller" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/functionalstorage/lang/en_us.json b/src/generated/resources/assets/functionalstorage/lang/en_us.json index 4082e18..c43a257 100644 --- a/src/generated/resources/assets/functionalstorage/lang/en_us.json +++ b/src/generated/resources/assets/functionalstorage/lang/en_us.json @@ -21,8 +21,20 @@ "block.functionalstorage.spruce_1": "Spruce Drawer (1x1)", "block.functionalstorage.spruce_2": "Spruce Drawer (2x2)", "block.functionalstorage.spruce_4": "Spruce Drawer (4x4)", + "block.functionalstorage.storage_controller": "Storage Controller", "block.functionalstorage.warped_1": "Warped Drawer (1x1)", "block.functionalstorage.warped_2": "Warped Drawer (2x2)", "block.functionalstorage.warped_4": "Warped Drawer (4x4)", - "itemGroup.functionalstorage": "Functional Storage" + "item.functionalstorage.linking_tool": "Linking Tool", + "itemGroup.functionalstorage": "Functional Storage", + "linkingtool.controller": "Controller: ", + "linkingtool.linkingaction": "Linking Action: ", + "linkingtool.linkingaction.add": "Add", + "linkingtool.linkingaction.remove": "Remove", + "linkingtool.linkingmode": "Linking Mode: ", + "linkingtool.linkingmode.multiple": "Multiple", + "linkingtool.linkingmode.multiple.desc": "Links multiple drawers between 2 points", + "linkingtool.linkingmode.single": "Single", + "linkingtool.linkingmode.single.desc": "Links a drawer to a controller", + "linkingtool.use": "Sneak + Right Click in the air to change modes. Right Click in the air to change actions. Right click a controller to setup the tool then use it nearby drawers to link." } \ No newline at end of file diff --git a/src/generated/resources/assets/functionalstorage/models/item/storage_controller.json b/src/generated/resources/assets/functionalstorage/models/item/storage_controller.json new file mode 100644 index 0000000..62a0591 --- /dev/null +++ b/src/generated/resources/assets/functionalstorage/models/item/storage_controller.json @@ -0,0 +1,3 @@ +{ + "parent": "functionalstorage:block/storage_controller" +} \ No newline at end of file diff --git a/src/generated/resources/data/functionalstorage/loot_tables/blocks/storage_controller.json b/src/generated/resources/data/functionalstorage/loot_tables/blocks/storage_controller.json new file mode 100644 index 0000000..cd3b3f4 --- /dev/null +++ b/src/generated/resources/data/functionalstorage/loot_tables/blocks/storage_controller.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "functionalstorage:storage_controller" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/functionalstorage/tags/items/drawer.json b/src/generated/resources/data/functionalstorage/tags/items/drawer.json index eafefad..6dff867 100644 --- a/src/generated/resources/data/functionalstorage/tags/items/drawer.json +++ b/src/generated/resources/data/functionalstorage/tags/items/drawer.json @@ -9,14 +9,6 @@ "functionalstorage:dark_oak_1", "functionalstorage:crimson_1", "functionalstorage:warped_1", - "functionalstorage:oak_2", - "functionalstorage:spruce_2", - "functionalstorage:birch_2", - "functionalstorage:jungle_2", - "functionalstorage:acacia_2", - "functionalstorage:dark_oak_2", - "functionalstorage:crimson_2", - "functionalstorage:warped_2", "functionalstorage:oak_4", "functionalstorage:spruce_4", "functionalstorage:birch_4", @@ -24,6 +16,14 @@ "functionalstorage:acacia_4", "functionalstorage:dark_oak_4", "functionalstorage:crimson_4", - "functionalstorage:warped_4" + "functionalstorage:warped_4", + "functionalstorage:oak_2", + "functionalstorage:spruce_2", + "functionalstorage:birch_2", + "functionalstorage:jungle_2", + "functionalstorage:acacia_2", + "functionalstorage:dark_oak_2", + "functionalstorage:crimson_2", + "functionalstorage:warped_2" ] } \ No newline at end of file diff --git a/src/main/java/com/buuz135/functionalstorage/FunctionalStorage.java b/src/main/java/com/buuz135/functionalstorage/FunctionalStorage.java index 8924ab3..d4b2696 100644 --- a/src/main/java/com/buuz135/functionalstorage/FunctionalStorage.java +++ b/src/main/java/com/buuz135/functionalstorage/FunctionalStorage.java @@ -2,11 +2,13 @@ package com.buuz135.functionalstorage; import com.buuz135.functionalstorage.block.CompactingDrawerBlock; import com.buuz135.functionalstorage.block.DrawerBlock; +import com.buuz135.functionalstorage.block.DrawerControllerBlock; import com.buuz135.functionalstorage.client.CompactingDrawerRenderer; import com.buuz135.functionalstorage.client.DrawerRenderer; import com.buuz135.functionalstorage.data.FunctionalStorageBlockstateProvider; import com.buuz135.functionalstorage.data.FunctionalStorageLangProvider; import com.buuz135.functionalstorage.data.FunctionalStorageTagsProvider; +import com.buuz135.functionalstorage.item.LinkingToolItem; import com.buuz135.functionalstorage.util.DrawerWoodType; import com.buuz135.functionalstorage.util.IWoodType; import com.hrznstudio.titanium.block.BasicBlock; @@ -20,6 +22,7 @@ import com.hrznstudio.titanium.tab.AdvancedTitaniumTab; import net.minecraft.data.recipes.FinishedRecipe; import net.minecraft.data.tags.BlockTagsProvider; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -49,8 +52,12 @@ public class FunctionalStorage extends ModuleController { private static final Logger LOGGER = LogManager.getLogger(); public static List WOOD_TYPES = new ArrayList<>(); + public static HashMap>> DRAWER_TYPES = new HashMap<>(); public static RegistryObject COMPACTING_DRAWER; + public static RegistryObject DRAWER_CONTROLLER; + + public static RegistryObject LINKING_TOOL; public static AdvancedTitaniumTab TAB = new AdvancedTitaniumTab("functionalstorage", true); @@ -70,6 +77,8 @@ 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")); + DRAWER_CONTROLLER = getRegistries().register(Block.class, "storage_controller", DrawerControllerBlock::new); + LINKING_TOOL = getRegistries().register(Item.class, "linking_tool", LinkingToolItem::new); } public enum DrawerType{ diff --git a/src/main/java/com/buuz135/functionalstorage/block/CompactingDrawerBlock.java b/src/main/java/com/buuz135/functionalstorage/block/CompactingDrawerBlock.java index ed1f81f..92dd63d 100644 --- a/src/main/java/com/buuz135/functionalstorage/block/CompactingDrawerBlock.java +++ b/src/main/java/com/buuz135/functionalstorage/block/CompactingDrawerBlock.java @@ -2,7 +2,9 @@ package com.buuz135.functionalstorage.block; import com.buuz135.functionalstorage.FunctionalStorage; import com.buuz135.functionalstorage.block.tile.CompactingDrawerTile; +import com.buuz135.functionalstorage.block.tile.DrawerControllerTile; import com.buuz135.functionalstorage.block.tile.DrawerTile; +import com.buuz135.functionalstorage.item.LinkingToolItem; import com.buuz135.functionalstorage.util.StorageTags; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; @@ -165,4 +167,17 @@ public class CompactingDrawerBlock extends RotatableBlock .define('I', Tags.Items.INGOTS_IRON) .save(consumer); } + + @Override + public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + TileUtil.getTileEntity(worldIn, pos, DrawerTile.class).ifPresent(tile -> { + if (tile.getControllerPos() != null){ + System.out.println(TileUtil.getTileEntity(worldIn, tile.getControllerPos()).get()); + TileUtil.getTileEntity(worldIn, tile.getControllerPos(), DrawerControllerTile.class).ifPresent(drawerControllerTile -> { + drawerControllerTile.addConnectedDrawers(LinkingToolItem.ActionMode.REMOVE, pos); + }); + } + }); + super.onRemove(state, worldIn, pos, newState, isMoving); + } } diff --git a/src/main/java/com/buuz135/functionalstorage/block/DrawerBlock.java b/src/main/java/com/buuz135/functionalstorage/block/DrawerBlock.java index 4598add..673ac8f 100644 --- a/src/main/java/com/buuz135/functionalstorage/block/DrawerBlock.java +++ b/src/main/java/com/buuz135/functionalstorage/block/DrawerBlock.java @@ -1,7 +1,9 @@ package com.buuz135.functionalstorage.block; import com.buuz135.functionalstorage.FunctionalStorage; +import com.buuz135.functionalstorage.block.tile.DrawerControllerTile; import com.buuz135.functionalstorage.block.tile.DrawerTile; +import com.buuz135.functionalstorage.item.LinkingToolItem; import com.buuz135.functionalstorage.util.IWoodType; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; @@ -39,6 +41,7 @@ import net.minecraftforge.common.Tags; import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; +import java.awt.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -67,6 +70,7 @@ public class DrawerBlock extends RotatableBlock { put(direction, Shapes.box(bounding.minX, 9/16D, bounding.minZ ,bounding.maxX, bounding.maxY, bounding.maxZ)); } } + //TODO Fix 4x4 they are backwards for (Direction direction : CACHED_SHAPES.get(FunctionalStorage.DrawerType.X_2).keySet()) { for (VoxelShape voxelShape : CACHED_SHAPES.get(FunctionalStorage.DrawerType.X_2).get(direction)) { AABB bounding = voxelShape.toAabbs().get(0); @@ -213,4 +217,17 @@ public class DrawerBlock extends RotatableBlock { public IWoodType getWoodType() { return woodType; } + + @Override + public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + TileUtil.getTileEntity(worldIn, pos, DrawerTile.class).ifPresent(tile -> { + if (tile.getControllerPos() != null){ + System.out.println(TileUtil.getTileEntity(worldIn, tile.getControllerPos()).get()); + TileUtil.getTileEntity(worldIn, tile.getControllerPos(), DrawerControllerTile.class).ifPresent(drawerControllerTile -> { + drawerControllerTile.addConnectedDrawers(LinkingToolItem.ActionMode.REMOVE, pos); + }); + } + }); + super.onRemove(state, worldIn, pos, newState, isMoving); + } } diff --git a/src/main/java/com/buuz135/functionalstorage/block/DrawerControllerBlock.java b/src/main/java/com/buuz135/functionalstorage/block/DrawerControllerBlock.java new file mode 100644 index 0000000..f8c3fed --- /dev/null +++ b/src/main/java/com/buuz135/functionalstorage/block/DrawerControllerBlock.java @@ -0,0 +1,18 @@ +package com.buuz135.functionalstorage.block; + +import com.buuz135.functionalstorage.block.tile.DrawerControllerTile; +import com.hrznstudio.titanium.block.RotatableBlock; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntityType; + +public class DrawerControllerBlock extends RotatableBlock { + + public DrawerControllerBlock() { + super("storage_controller", Properties.copy(Blocks.IRON_BLOCK), DrawerControllerTile.class); + } + + @Override + public BlockEntityType.BlockEntitySupplier getTileEntityFactory() { + return (p_155268_, p_155269_) -> new DrawerControllerTile(this, p_155268_, p_155269_); + } +} diff --git a/src/main/java/com/buuz135/functionalstorage/block/tile/CompactingDrawerTile.java b/src/main/java/com/buuz135/functionalstorage/block/tile/CompactingDrawerTile.java index 5e454bd..70cb2f3 100644 --- a/src/main/java/com/buuz135/functionalstorage/block/tile/CompactingDrawerTile.java +++ b/src/main/java/com/buuz135/functionalstorage/block/tile/CompactingDrawerTile.java @@ -31,9 +31,7 @@ import javax.annotation.Nullable; import java.util.HashMap; import java.util.UUID; -public class CompactingDrawerTile extends ActiveTile { - - private static HashMap INTERACTION_LOGGER = new HashMap<>(); +public class CompactingDrawerTile extends ControllableDrawerTile { @Save public CompactingInventoryHandler handler; @@ -52,52 +50,31 @@ public class CompactingDrawerTile extends ActiveTile { } 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; - } + 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()); } + super.onSlotActivated(playerIn, hand, facing, hitX, hitY, hitZ, slot); 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)); - } - } - } + @Override + public IItemHandler getStorage() { + return handler; + } + + @Override + public LazyOptional getOptional() { + return lazyStorage; } @Nonnull diff --git a/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java b/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java new file mode 100644 index 0000000..88a043e --- /dev/null +++ b/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java @@ -0,0 +1,96 @@ +package com.buuz135.functionalstorage.block.tile; + +import com.buuz135.functionalstorage.item.LinkingToolItem; +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 com.hrznstudio.titanium.util.TileUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +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.util.LazyOptional; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.UUID; + +public abstract class ControllableDrawerTile> extends ActiveTile { + + private static HashMap INTERACTION_LOGGER = new HashMap<>(); + + @Save + private BlockPos controllerPos; + + public ControllableDrawerTile(BasicTileBlock base, BlockPos pos, BlockState state) { + super(base, pos, state); + } + + public BlockPos getControllerPos() { + return controllerPos; + } + + public void setControllerPos(BlockPos controllerPos) { + if (this.controllerPos != null){ + TileUtil.getTileEntity(getLevel(), this.controllerPos, DrawerControllerTile.class).ifPresent(drawerControllerTile -> { + drawerControllerTile.addConnectedDrawers(LinkingToolItem.ActionMode.REMOVE, getBlockPos()); + }); + } + this.controllerPos = controllerPos; + } + + 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()){ + ItemStack stack = playerIn.getItemInHand(hand); + if (!stack.isEmpty() && getStorage().isItemValid(slot, stack)) { + playerIn.setItemInHand(hand, getStorage().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() && getStorage().insertItem(slot, itemStack, true).isEmpty()) { + getStorage().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() && slot != -1){ + 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, getStorage().extractItem(slot, playerIn.isShiftKeyDown() ? 64 : 1, false)); + } + } + } + } + + + public abstract IItemHandler getStorage(); + + public abstract LazyOptional getOptional(); + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + getOptional().invalidate(); + } +} diff --git a/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerControllerTile.java b/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerControllerTile.java new file mode 100644 index 0000000..cf9a5f3 --- /dev/null +++ b/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerControllerTile.java @@ -0,0 +1,154 @@ +package com.buuz135.functionalstorage.block.tile; + +import com.buuz135.functionalstorage.block.DrawerControllerBlock; +import com.buuz135.functionalstorage.inventory.BigInventoryHandler; +import com.buuz135.functionalstorage.inventory.ControllerInventoryHandler; +import com.buuz135.functionalstorage.item.LinkingToolItem; +import com.hrznstudio.titanium.annotation.Save; +import com.hrznstudio.titanium.block.BasicTileBlock; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.INBTSerializable; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class DrawerControllerTile extends ControllableDrawerTile{ + + @Save + private ConnectedDrawers connectedDrawers; + public ControllerInventoryHandler handler; + private LazyOptional lazyStorage; + + public DrawerControllerTile(BasicTileBlock base, BlockPos pos, BlockState state) { + super(base, pos, state); + this.connectedDrawers = new ConnectedDrawers(null); + this.handler = new ControllerInventoryHandler() { + @Override + public ConnectedDrawers getDrawers() { + return connectedDrawers; + } + }; + this.lazyStorage = LazyOptional.of(() -> this.handler); + } + + @Override + public void serverTick(Level level, BlockPos pos, BlockState state, DrawerControllerTile blockEntity) { + super.serverTick(level, pos, state, blockEntity); + if (this.connectedDrawers.getConnectedDrawers().size() != this.connectedDrawers.getHandlers().size()){ + this.connectedDrawers.setLevel(getLevel()); + this.connectedDrawers.rebuild(); + //this.lazyStorage.invalidate(); + //this.lazyStorage = LazyOptional.of(() -> this.handler); + markForUpdate(); + updateNeigh(); + } + } + + @Override + public IItemHandler getStorage() { + return handler; + } + + @Override + public LazyOptional getOptional() { + return lazyStorage; + } + + @NotNull + @Override + public DrawerControllerTile getSelf() { + return this; + } + + public void addConnectedDrawers(LinkingToolItem.ActionMode action, BlockPos... positions){ + for (BlockPos position : positions) { + if (this.getBlockPos().closerThan(position, 8)){ + if (action == LinkingToolItem.ActionMode.ADD){ + if (!connectedDrawers.getConnectedDrawers().contains(position.asLong())) this.connectedDrawers.getConnectedDrawers().add(position.asLong()); + } + } + if (action == LinkingToolItem.ActionMode.REMOVE){ + this.connectedDrawers.getConnectedDrawers().removeIf(aLong -> aLong == position.asLong()); + } + } + this.connectedDrawers.rebuild(); + markForUpdate(); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return lazyStorage.cast(); + } + return super.getCapability(cap, side); + } + + public static class ConnectedDrawers implements INBTSerializable { + + private List connectedDrawers; + private List handlers; + private Level level; + + public ConnectedDrawers(Level level) { + this.connectedDrawers = new ArrayList<>(); + this.handlers = new ArrayList<>(); + this.level = level; + } + + public void setLevel(Level level) { + this.level = level; + } + + private void rebuild(){ + this.handlers = new ArrayList<>(); + if (level != null && !level.isClientSide()){ + for (Long connectedDrawer : this.connectedDrawers) { + BlockPos pos = BlockPos.of(connectedDrawer); + BlockEntity entity = level.getBlockEntity(pos); + if (entity instanceof ControllableDrawerTile){ + this.handlers.add(((ControllableDrawerTile) entity).getStorage()); + } + } + } + } + + @Override + public CompoundTag serializeNBT() { + CompoundTag compoundTag = new CompoundTag(); + for (int i = 0; i < this.connectedDrawers.size(); i++) { + compoundTag.putLong(i + "", this.connectedDrawers.get(i)); + } + return compoundTag; + } + + @Override + public void deserializeNBT(CompoundTag nbt) { + this.connectedDrawers = new ArrayList<>(); + for (String allKey : nbt.getAllKeys()) { + connectedDrawers.add(nbt.getLong(allKey)); + } + rebuild(); + } + + public List getConnectedDrawers() { + return connectedDrawers; + } + + public List getHandlers() { + return handlers; + } + } +} diff --git a/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerTile.java b/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerTile.java index 20781cf..c0dedd5 100644 --- a/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerTile.java +++ b/src/main/java/com/buuz135/functionalstorage/block/tile/DrawerTile.java @@ -30,9 +30,7 @@ import javax.annotation.Nullable; import java.util.HashMap; import java.util.UUID; -public class DrawerTile extends ActiveTile { - - private static HashMap INTERACTION_LOGGER = new HashMap<>(); +public class DrawerTile extends ControllableDrawerTile { @Save public BigInventoryHandler handler; @@ -51,42 +49,6 @@ public class DrawerTile extends ActiveTile { lazyStorage = LazyOptional.of(() -> this.handler); } - 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()){ - 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() && slot != -1){ - 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 LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { @@ -102,11 +64,17 @@ public class DrawerTile extends ActiveTile { return this; } - public BigInventoryHandler getHandler() { - return handler; - } - public FunctionalStorage.DrawerType getDrawerType() { return type; } + + @Override + public IItemHandler getStorage() { + return handler; + } + + @Override + public LazyOptional getOptional() { + return lazyStorage; + } } diff --git a/src/main/java/com/buuz135/functionalstorage/client/DrawerRenderer.java b/src/main/java/com/buuz135/functionalstorage/client/DrawerRenderer.java index 4847788..9e4e1d3 100644 --- a/src/main/java/com/buuz135/functionalstorage/client/DrawerRenderer.java +++ b/src/main/java/com/buuz135/functionalstorage/client/DrawerRenderer.java @@ -23,6 +23,8 @@ import net.minecraft.world.item.ItemStack; public class DrawerRenderer implements BlockEntityRenderer { + //TODO Fix rotation so it shows the front + private static final Matrix3f FAKE_NORMALS; static { @@ -62,61 +64,61 @@ public class DrawerRenderer implements BlockEntityRenderer { } private void render1Slot(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, DrawerTile tile){ - if (!tile.getHandler().getStackInSlot(0).isEmpty()){ + if (!tile.getStorage().getStackInSlot(0).isEmpty()){ matrixStack.translate(0.5, 0.5, 0.0005f); - ItemStack stack = tile.getHandler().getStackInSlot(0); + ItemStack stack = tile.getStorage().getStackInSlot(0); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.015f); } } private void render2Slot(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, DrawerTile tile){ - if (!tile.getHandler().getStackInSlot(0).isEmpty()){ + if (!tile.getStorage().getStackInSlot(0).isEmpty()){ matrixStack.pushPose(); matrixStack.translate(0.5, 0.27f, 0.0005f); matrixStack.scale(0.5f, 0.5f, 1); - ItemStack stack = tile.getHandler().getStackInSlot(0); + ItemStack stack = tile.getStorage().getStackInSlot(0); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f); matrixStack.popPose(); } - if (!tile.getHandler().getStackInSlot(1).isEmpty()){ + if (!tile.getStorage().getStackInSlot(1).isEmpty()){ matrixStack.pushPose(); matrixStack.translate(0.5, 0.77f, 0.0005f); matrixStack.scale(0.5f, 0.5f, 1); - ItemStack stack = tile.getHandler().getStackInSlot(1); + ItemStack stack = tile.getStorage().getStackInSlot(1); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f); matrixStack.popPose(); } } private void render4Slot(PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn, DrawerTile tile){ - if (!tile.getHandler().getStackInSlot(0).isEmpty()){ //BOTTOM RIGHT + if (!tile.getStorage().getStackInSlot(0).isEmpty()){ //BOTTOM RIGHT matrixStack.pushPose(); matrixStack.translate(0.75, 0.27f, 0.0005f); matrixStack.scale(0.5f, 0.5f, 1); - ItemStack stack = tile.getHandler().getStackInSlot(0); + ItemStack stack = tile.getStorage().getStackInSlot(0); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f); matrixStack.popPose(); } - if (!tile.getHandler().getStackInSlot(1).isEmpty()){ //BOTTOM LEFT + if (!tile.getStorage().getStackInSlot(1).isEmpty()){ //BOTTOM LEFT matrixStack.pushPose(); matrixStack.translate(0.25, 0.27f, 0.0005f); matrixStack.scale(0.5f, 0.5f, 1); - ItemStack stack = tile.getHandler().getStackInSlot(1); + ItemStack stack = tile.getStorage().getStackInSlot(1); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f); matrixStack.popPose(); } - if (!tile.getHandler().getStackInSlot(2).isEmpty()){ //TOP RIGHT + if (!tile.getStorage().getStackInSlot(2).isEmpty()){ //TOP RIGHT matrixStack.pushPose(); matrixStack.translate(0.75, 0.77f, 0.0005f); matrixStack.scale(0.5f, 0.5f, 1); - ItemStack stack = tile.getHandler().getStackInSlot(2); + ItemStack stack = tile.getStorage().getStackInSlot(2); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f); matrixStack.popPose(); } - if (!tile.getHandler().getStackInSlot(3).isEmpty()){ //TOP LEFT + if (!tile.getStorage().getStackInSlot(3).isEmpty()){ //TOP LEFT matrixStack.pushPose(); matrixStack.translate(0.25, 0.77f, 0.0005f); matrixStack.scale(0.5f, 0.5f, 1); - ItemStack stack = tile.getHandler().getStackInSlot(3); + ItemStack stack = tile.getStorage().getStackInSlot(3); renderStack(matrixStack, bufferIn, combinedLightIn, combinedOverlayIn, stack, stack.getCount(), 0.02f); matrixStack.popPose(); } @@ -128,6 +130,7 @@ public class DrawerRenderer implements BlockEntityRenderer { if (model.isGui3d()){ matrixStack.translate(0,0, -0.23f); matrixStack.scale(0.5f, 0.5f, 0.5f); + matrixStack.mulPose(Vector3f.YP.rotationDegrees(180)); } else { matrixStack.scale(0.4f, 0.4f, 0.4f); } @@ -137,6 +140,7 @@ public class DrawerRenderer implements BlockEntityRenderer { matrixStack.scale(1/0.4f, 1/0.4f, 1/0.0001f); matrixStack.scale(0.5f, 0.5f, 0.0001f); }else { + matrixStack.mulPose(Vector3f.YP.rotationDegrees(-180)); matrixStack.translate(0,0, 0.23f*2); } renderText(matrixStack, bufferIn, combinedOverlayIn, new TextComponent(ChatFormatting.WHITE + "" + amount), Direction.NORTH, scale); diff --git a/src/main/java/com/buuz135/functionalstorage/data/FunctionalStorageLangProvider.java b/src/main/java/com/buuz135/functionalstorage/data/FunctionalStorageLangProvider.java index ffadce9..221de0b 100644 --- a/src/main/java/com/buuz135/functionalstorage/data/FunctionalStorageLangProvider.java +++ b/src/main/java/com/buuz135/functionalstorage/data/FunctionalStorageLangProvider.java @@ -24,5 +24,17 @@ public class FunctionalStorageLangProvider extends LanguageProvider { } } this.add(FunctionalStorage.COMPACTING_DRAWER.get(), "Compacting Drawer"); + this.add("linkingtool.linkingmode", "Linking Mode: "); + this.add("linkingtool.linkingmode.single", "Single"); + this.add("linkingtool.linkingmode.single.desc", "Links a drawer to a controller"); + this.add("linkingtool.linkingmode.multiple", "Multiple"); + this.add("linkingtool.linkingmode.multiple.desc", "Links multiple drawers between 2 points"); + this.add("linkingtool.controller", "Controller: "); + this.add("linkingtool.linkingaction", "Linking Action: "); + this.add("linkingtool.use", "Sneak + Right Click in the air to change modes. Right Click in the air to change actions. Right click a controller to setup the tool then use it nearby drawers to link."); + this.add("linkingtool.linkingaction.add", "Add"); + this.add("linkingtool.linkingaction.remove", "Remove"); + this.add(FunctionalStorage.LINKING_TOOL.get(), "Linking Tool"); + this.add(FunctionalStorage.DRAWER_CONTROLLER.get(), "Storage Controller"); } } diff --git a/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java b/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java new file mode 100644 index 0000000..b871ff9 --- /dev/null +++ b/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java @@ -0,0 +1,88 @@ +package com.buuz135.functionalstorage.inventory; + +import com.buuz135.functionalstorage.block.tile.DrawerControllerTile; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.items.IItemHandler; +import org.jetbrains.annotations.NotNull; + +public abstract class ControllerInventoryHandler implements IItemHandler { + + public ControllerInventoryHandler() { + + } + + @Override + public int getSlots() { + return getDrawers().getHandlers().stream().map(IItemHandler::getSlots).mapToInt(Integer::intValue).sum(); + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + int index = 0; + for (IItemHandler handler : getDrawers().getHandlers()) { + int relativeIndex = slot - index; + if (relativeIndex < handler.getSlots()){ + return handler.getStackInSlot(relativeIndex); + } + index += handler.getSlots(); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + int index = 0; + for (IItemHandler handler : getDrawers().getHandlers()) { + int relativeIndex = slot - index; + if (relativeIndex < handler.getSlots()){ + return handler.insertItem(relativeIndex, stack, simulate); + } + index += handler.getSlots(); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + int index = 0; + for (IItemHandler handler : getDrawers().getHandlers()) { + int relativeIndex = slot - index; + if (relativeIndex < handler.getSlots()){ + return handler.extractItem(relativeIndex, amount, simulate); + } + index += handler.getSlots(); + } + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + int index = 0; + for (IItemHandler handler : getDrawers().getHandlers()) { + int relativeIndex = slot - index; + if (relativeIndex < handler.getSlots()){ + return handler.getSlotLimit(relativeIndex); + } + index += handler.getSlots(); + } + return 0; + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + int index = 0; + for (IItemHandler handler : getDrawers().getHandlers()) { + int relativeIndex = slot - index; + if (relativeIndex < handler.getSlots()){ + return handler.isItemValid(relativeIndex, stack); + } + index += handler.getSlots(); + } + return false; + } + + public abstract DrawerControllerTile.ConnectedDrawers getDrawers(); +} diff --git a/src/main/java/com/buuz135/functionalstorage/item/LinkingToolItem.java b/src/main/java/com/buuz135/functionalstorage/item/LinkingToolItem.java new file mode 100644 index 0000000..e1b4b6a --- /dev/null +++ b/src/main/java/com/buuz135/functionalstorage/item/LinkingToolItem.java @@ -0,0 +1,178 @@ +package com.buuz135.functionalstorage.item; + +import com.buuz135.functionalstorage.FunctionalStorage; +import com.buuz135.functionalstorage.block.tile.ControllableDrawerTile; +import com.buuz135.functionalstorage.block.tile.DrawerControllerTile; +import com.hrznstudio.titanium.item.BasicItem; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.TextColor; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.List; +import java.util.Locale; + +public class LinkingToolItem extends BasicItem { + + private final String NBT_MODE = "Mode"; + private final String NBT_CONTROLLER = "Controller"; + private final String NBT_ACTION = "Action"; + + public LinkingToolItem() { + super(new Properties().tab(FunctionalStorage.TAB).stacksTo(1)); + } + + @Override + public void onCraftedBy(ItemStack p_41447_, Level p_41448_, Player p_41449_) { + super.onCraftedBy(p_41447_, p_41448_, p_41449_); + initNbt(p_41447_); + } + + private ItemStack initNbt(ItemStack stack){ + stack.getOrCreateTag().putString(NBT_MODE, LinkingMode.SINGLE.name()); + stack.getOrCreateTag().putString(NBT_ACTION, ActionMode.ADD.name()); + return stack; + } + + @Override + public void fillItemCategory(CreativeModeTab group, NonNullList items) { + if (allowdedIn(group)) { + items.add(initNbt(new ItemStack(this))); + } + } + + @Override + public InteractionResult useOn(UseOnContext context) { + BlockPos pos = context.getClickedPos(); + ItemStack stack = context.getItemInHand(); + Level level = context.getLevel(); + BlockEntity blockEntity = level.getBlockEntity(pos); + LinkingMode linkingMode = LinkingMode.valueOf(stack.getOrCreateTag().getString(NBT_MODE)); + ActionMode linkingAction = ActionMode.valueOf(stack.getOrCreateTag().getString(NBT_ACTION)); + if (blockEntity instanceof DrawerControllerTile){ + CompoundTag controller = new CompoundTag(); + controller.putInt("X", pos.getX()); + controller.putInt("Y", pos.getY()); + controller.putInt("Z", pos.getZ()); + stack.getOrCreateTag().put(NBT_CONTROLLER, controller); + context.getPlayer().playSound(SoundEvents.ITEM_FRAME_ADD_ITEM, 0.5f, 1); + return InteractionResult.SUCCESS; + } else if (blockEntity instanceof ControllableDrawerTile && stack.getOrCreateTag().contains(NBT_CONTROLLER)){ + CompoundTag controllerNBT = stack.getOrCreateTag().getCompound(NBT_CONTROLLER); + BlockEntity controller = level.getBlockEntity(new BlockPos(controllerNBT.getInt("X"), controllerNBT.getInt("Y"), controllerNBT.getInt("Z"))); + if (controller instanceof DrawerControllerTile){ + if (linkingMode == LinkingMode.SINGLE){ + ((ControllableDrawerTile) blockEntity).setControllerPos(controller.getBlockPos()); + ((DrawerControllerTile) controller).addConnectedDrawers(linkingAction, pos); + context.getPlayer().displayClientMessage(new TextComponent("Added").setStyle(Style.EMPTY.withColor(linkingMode.color)), true); + }//TODO add to the drawer + context.getPlayer().playSound(SoundEvents.ITEM_FRAME_ROTATE_ITEM, 0.5f, 1); + return InteractionResult.SUCCESS; + } + } + return super.useOn(context); + } + + @Override + public InteractionResultHolder use(Level p_41432_, Player player, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + if (!stack.isEmpty() && stack.hasTag()){ + if (player.isShiftKeyDown()){ + LinkingMode linkingMode = LinkingMode.valueOf(stack.getOrCreateTag().getString(NBT_MODE)); + if (linkingMode == LinkingMode.SINGLE){ + stack.getOrCreateTag().putString(NBT_MODE, LinkingMode.MULTIPLE.name()); + } else { + stack.getOrCreateTag().putString(NBT_MODE, LinkingMode.SINGLE.name()); + } + } else { + ActionMode linkingMode = ActionMode.valueOf(stack.getOrCreateTag().getString(NBT_ACTION)); + if (linkingMode == ActionMode.ADD){ + stack.getOrCreateTag().putString(NBT_ACTION, ActionMode.REMOVE.name()); + } else { + stack.getOrCreateTag().putString(NBT_ACTION, ActionMode.ADD.name()); + } + } + player.playSound(SoundEvents.ITEM_FRAME_REMOVE_ITEM, 0.5f, 1); + return InteractionResultHolder.success(stack); + } + return super.use(p_41432_, player, hand); + } + + @Override + public void addTooltipDetails(@Nullable BasicItem.Key key, ItemStack stack, List tooltip, boolean advanced) { + super.addTooltipDetails(key, stack, tooltip, advanced); + if (stack.hasTag()){ + LinkingMode linkingMode = LinkingMode.valueOf(stack.getOrCreateTag().getString(NBT_MODE)); + ActionMode linkingAction = ActionMode.valueOf(stack.getOrCreateTag().getString(NBT_ACTION)); + if (key == null){ + tooltip.add(new TranslatableComponent("linkingtool.linkingmode").withStyle(ChatFormatting.YELLOW) + .append(new TranslatableComponent("linkingtool.linkingmode." + linkingMode.name().toLowerCase(Locale.ROOT) ).withStyle(Style.EMPTY.withColor(linkingMode.getColor())))); + tooltip.add(new TranslatableComponent("linkingtool.linkingaction").withStyle(ChatFormatting.YELLOW) + .append(new TranslatableComponent("linkingtool.linkingaction." + linkingAction.name().toLowerCase(Locale.ROOT)).withStyle(Style.EMPTY.withColor(linkingAction.getColor())))); + if (stack.getOrCreateTag().contains(NBT_CONTROLLER)){ + tooltip.add(new TranslatableComponent("linkingtool.controller").withStyle(ChatFormatting.YELLOW) + .append(new TextComponent(stack.getOrCreateTag().getCompound(NBT_CONTROLLER).getInt("X") +""+ ChatFormatting.WHITE + ", " + ChatFormatting.DARK_AQUA + stack.getOrCreateTag().getCompound(NBT_CONTROLLER).getInt("Y") + ChatFormatting.WHITE + ", " + ChatFormatting.DARK_AQUA + stack.getOrCreateTag().getCompound(NBT_CONTROLLER).getInt("Z")).withStyle(ChatFormatting.DARK_AQUA))); + } else { + tooltip.add(new TranslatableComponent("linkingtool.controller").withStyle(ChatFormatting.YELLOW).append(new TextComponent("???").withStyle(ChatFormatting.DARK_AQUA))); + } + tooltip.add(new TextComponent("")); + tooltip.add(new TranslatableComponent("linkingtool.linkingmode." + linkingMode.name().toLowerCase(Locale.ROOT) + ".desc").withStyle(ChatFormatting.GRAY)); + tooltip.add(new TranslatableComponent("linkingtool.use").withStyle(ChatFormatting.GRAY)); + + } + } + } + + @Override + public boolean hasTooltipDetails(@Nullable BasicItem.Key key) { + return key == null; + } + + public enum LinkingMode{ + SINGLE(TextColor.fromRgb(Color.cyan.getRGB())), + MULTIPLE(TextColor.fromRgb(Color.GREEN.getRGB())); + + private final TextColor color; + + LinkingMode(TextColor color) { + this.color = color; + } + + public TextColor getColor() { + return color; + } + } + + public enum ActionMode{ + ADD(TextColor.fromRgb(new Color(40, 131, 250).getRGB())), + REMOVE(TextColor.fromRgb(new Color(250, 145, 40).getRGB())); + + private final TextColor color; + + ActionMode(TextColor color) { + this.color = color; + } + + public TextColor getColor() { + return color; + } + } +}