From bb81595c3a273e287141d5a469eb9f9a7345dc9a Mon Sep 17 00:00:00 2001 From: Christian Knaapen Date: Sun, 5 Dec 2021 17:26:21 +0100 Subject: [PATCH] Added golden and diamond randomizer bags. Using deferred registries. Revamped radial menu: fixed clicking. Removed old code. --- build.gradle | 2 +- .../EffortlessBuilding.java | 85 ++---- .../effortlessbuilding/EventHandler.java | 16 -- .../effortlessbuilding/ModEventHandler.java | 35 --- .../buildmodifier/Array.java | 12 +- .../buildmodifier/BuildModifiers.java | 7 +- .../buildmodifier/Mirror.java | 14 +- .../buildmodifier/RadialMirror.java | 10 +- .../ItemHandlerCapabilityProvider.java | 8 +- .../compatibility/CompatHelper.java | 96 +------ .../gui/DiamondRandomizerBagContainer.java | 149 +++++++++++ .../gui/DiamondRandomizerBagScreen.java | 47 ++++ .../gui/GoldenRandomizerBagContainer.java | 147 ++++++++++ .../gui/GoldenRandomizerBagScreen.java | 47 ++++ .../gui/RandomizerBagContainer.java | 20 +- .../gui/RandomizerBagScreen.java | 4 +- .../gui/buildmode/RadialMenu.java | 142 ++++++---- .../helper/SurvivalHelper.java | 2 +- .../item/AbstractRandomizerBagItem.java | 221 +++++++++++++++ .../item/DiamondRandomizerBagItem.java | 46 ++++ .../item/GoldenRandomizerBagItem.java | 46 ++++ .../item/ItemRandomizerBag.java | 251 ------------------ .../item/RandomizerBagItem.java | 46 ++++ ...chUpgrade1.java => ReachUpgrade1Item.java} | 5 +- ...chUpgrade2.java => ReachUpgrade2Item.java} | 5 +- ...chUpgrade3.java => ReachUpgrade3Item.java} | 5 +- .../effortlessbuilding/proxy/ClientProxy.java | 121 ++++----- .../render/BlockPreviewRenderer.java | 4 +- .../render/RenderHandler.java | 98 ------- .../assets/effortlessbuilding/lang/en_us.json | 6 +- .../models/item/diamond_randomizer_bag.json | 6 + .../models/item/golden_randomizer_bag.json | 6 + .../gui/container/diamondrandomizerbag.png | Bin 0 -> 920 bytes .../gui/container/goldenrandomizerbag.png | Bin 0 -> 10503 bytes .../textures/items/diamondrandomizerbag.png | Bin 0 -> 6121 bytes .../textures/items/goldenrandomizerbag.png | Bin 0 -> 5939 bytes .../textures/items/reachupgrade1.png | Bin 625 -> 603 bytes .../textures/items/reachupgrade2.png | Bin 603 -> 625 bytes .../recipes/diamond_randomizer_bag.json | 22 ++ .../recipes/golden_randomizer_bag.json | 22 ++ .../recipes/reach_upgrade1.json | 13 +- .../recipes/reach_upgrade2.json | 18 +- .../recipes/reach_upgrade3.json | 20 +- 43 files changed, 1062 insertions(+), 742 deletions(-) delete mode 100644 src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagContainer.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagContainer.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/item/DiamondRandomizerBagItem.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/item/GoldenRandomizerBagItem.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java rename src/main/java/nl/requios/effortlessbuilding/item/{ItemReachUpgrade1.java => ReachUpgrade1Item.java} (95%) rename src/main/java/nl/requios/effortlessbuilding/item/{ItemReachUpgrade2.java => ReachUpgrade2Item.java} (95%) rename src/main/java/nl/requios/effortlessbuilding/item/{ItemReachUpgrade3.java => ReachUpgrade3Item.java} (95%) create mode 100644 src/main/resources/assets/effortlessbuilding/models/item/diamond_randomizer_bag.json create mode 100644 src/main/resources/assets/effortlessbuilding/models/item/golden_randomizer_bag.json create mode 100644 src/main/resources/assets/effortlessbuilding/textures/gui/container/diamondrandomizerbag.png create mode 100644 src/main/resources/assets/effortlessbuilding/textures/gui/container/goldenrandomizerbag.png create mode 100644 src/main/resources/assets/effortlessbuilding/textures/items/diamondrandomizerbag.png create mode 100644 src/main/resources/assets/effortlessbuilding/textures/items/goldenrandomizerbag.png create mode 100644 src/main/resources/data/effortlessbuilding/recipes/diamond_randomizer_bag.json create mode 100644 src/main/resources/data/effortlessbuilding/recipes/golden_randomizer_bag.json diff --git a/build.gradle b/build.gradle index 4727e68..5427158 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '1.16.3-2.24' +version = '1.16.3-2.28' group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'effortlessbuilding' diff --git a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java index b658ff9..eb70704 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java @@ -1,14 +1,10 @@ package nl.requios.effortlessbuilding; -import net.minecraft.block.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.ContainerType; import net.minecraft.item.Item; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.Registry; import net.minecraft.util.text.StringTextComponent; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; @@ -18,22 +14,17 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; -import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; -import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.network.IContainerFactory; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; -import nl.requios.effortlessbuilding.command.CommandReach; import nl.requios.effortlessbuilding.compatibility.CompatHelper; +import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagContainer; +import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagContainer; import nl.requios.effortlessbuilding.gui.RandomizerBagContainer; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; -import nl.requios.effortlessbuilding.item.ItemReachUpgrade1; -import nl.requios.effortlessbuilding.item.ItemReachUpgrade2; -import nl.requios.effortlessbuilding.item.ItemReachUpgrade3; +import nl.requios.effortlessbuilding.item.*; import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.IProxy; @@ -47,43 +38,36 @@ import org.apache.logging.log4j.Logger; public class EffortlessBuilding { public static final String MODID = "effortlessbuilding"; public static final Logger logger = LogManager.getLogger(); - public static final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag(); - public static final ItemReachUpgrade1 ITEM_REACH_UPGRADE_1 = new ItemReachUpgrade1(); - public static final ItemReachUpgrade2 ITEM_REACH_UPGRADE_2 = new ItemReachUpgrade2(); - public static final ItemReachUpgrade3 ITEM_REACH_UPGRADE_3 = new ItemReachUpgrade3(); - public static final Block[] BLOCKS = { - }; - public static final Item[] ITEMS = { - ITEM_RANDOMIZER_BAG, - ITEM_REACH_UPGRADE_1, - ITEM_REACH_UPGRADE_2, - ITEM_REACH_UPGRADE_3 - }; - public static final DeferredRegister> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, EffortlessBuilding.MODID); - public static final RegistryObject> RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("randomizer_bag", () -> registerContainer(RandomizerBagContainer::new)); - public static final ResourceLocation RANDOMIZER_BAG_GUI = new ResourceLocation(EffortlessBuilding.MODID, "randomizer_bag"); + public static EffortlessBuilding instance; public static IProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> ServerProxy::new); + //Registration + private static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); + private static final DeferredRegister> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, EffortlessBuilding.MODID); + + public static final RegistryObject RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new); + public static final RegistryObject GOLDEN_RANDOMIZER_BAG_ITEM = ITEMS.register("golden_randomizer_bag", GoldenRandomizerBagItem::new); + public static final RegistryObject DIAMOND_RANDOMIZER_BAG_ITEM = ITEMS.register("diamond_randomizer_bag", DiamondRandomizerBagItem::new); + public static final RegistryObject REACH_UPGRADE_1_ITEM = ITEMS.register("reach_upgrade1", ReachUpgrade1Item::new); + public static final RegistryObject REACH_UPGRADE_2_ITEM = ITEMS.register("reach_upgrade2", ReachUpgrade2Item::new); + public static final RegistryObject REACH_UPGRADE_3_ITEM = ITEMS.register("reach_upgrade3", ReachUpgrade3Item::new); + + public static final RegistryObject> RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("randomizer_bag", () -> registerContainer(RandomizerBagContainer::new)); + public static final RegistryObject> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new)); + public static final RegistryObject> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new)); + public EffortlessBuilding() { instance = this; - // Register the setup method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - // Register the enqueueIMC method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC); - // Register the processIMC method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC); - // Register the clientSetup method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); + // Register ourselves for server and other game events we are interested in + FMLJavaModLoadingContext.get().getModEventBus().register(this); + + ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus()); + CONTAINERS.register(FMLJavaModLoadingContext.get().getModEventBus()); //Register config ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, BuildConfig.spec); - - // Register ourselves for server and other game events we are interested in - MinecraftForge.EVENT_BUS.register(this); - - CONTAINERS.register(FMLJavaModLoadingContext.get().getModEventBus()); } public static ContainerType registerContainer(IContainerFactory fact){ @@ -128,25 +112,4 @@ public class EffortlessBuilding { proxy.clientSetup(event); } - - @SubscribeEvent - public void enqueueIMC(final InterModEnqueueEvent event) { - - // some example code to dispatch IMC to another mod -// InterModComms.sendTo("examplemod", "helloworld", () -> { logger.info("Hello world from the MDK"); return "Hello world";}); - } - - @SubscribeEvent - public void processIMC(final InterModProcessEvent event) { - - // some example code to receive and process InterModComms from other mods -// logger.info("Got IMC {}", event.getIMCStream(). -// map(m->m.getMessageSupplier().get()). -// collect(Collectors.toList())); - } - - @SubscribeEvent - public void onServerStarting(FMLServerStartingEvent event) { - CommandReach.register(event.getServer().getCommands().getDispatcher()); - } } diff --git a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java index ac51a93..43f6741 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java @@ -43,23 +43,7 @@ public class EventHandler { } } - //TODO 1.13 config -// @SubscribeEvent -// public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event) -// { -// if (event.getModID().equals(EffortlessBuilding.MODID)) -// { -// ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE); -// } -// } - -// @SubscribeEvent -// public static void onServerTick(TickEvent.ServerTickEvent event) { -// -// } - @SubscribeEvent - //Only called serverside (except with lilypads...) public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event) { if (event.getWorld().isClientSide()) return; diff --git a/src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java b/src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java deleted file mode 100644 index 7001f50..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package nl.requios.effortlessbuilding; - -import net.minecraft.block.Block; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD -// Event bus for receiving Registry Events) -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) -public class ModEventHandler { - - @SubscribeEvent - public static void registerBlocks(RegistryEvent.Register event) { - event.getRegistry().registerAll(EffortlessBuilding.BLOCKS); - } - - @SubscribeEvent - public static void registerItems(RegistryEvent.Register event) { - event.getRegistry().registerAll(EffortlessBuilding.ITEMS); - - for (Block block : EffortlessBuilding.BLOCKS) { - event.getRegistry().register(new BlockItem(block, new Item.Properties()).setRegistryName(block.getRegistryName())); - } - } - -// @SubscribeEvent -// public static void registerContainerTypes(RegistryEvent.Register> event) { -// event.getRegistry().register() -// } - - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java index aa57236..6a08a68 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java @@ -9,7 +9,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3i; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import java.util.ArrayList; import java.util.List; @@ -45,17 +45,19 @@ public class Array { Vector3i offset = new Vector3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); //Randomizer bag synergy + AbstractRandomizerBagItem randomizerBagItem = null; IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) { - bagInventory = ItemRandomizerBag.getBagInventory(itemStack); + if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { + randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem(); + bagInventory = randomizerBagItem.getBagInventory(itemStack); } for (int i = 0; i < a.count; i++) { pos = pos.offset(offset); //Randomizer bag synergy - if (bagInventory != null) { - itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); + if (randomizerBagItem != null) { + itemStack = randomizerBagItem.pickRandomStack(bagInventory); blockState = BuildModifiers .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vector3d(0, 0, 0), Hand.MAIN_HAND); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java index a87fca2..0bca35a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java @@ -17,11 +17,10 @@ import net.minecraft.world.World; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.InventoryHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import nl.requios.effortlessbuilding.render.BlockPreviewRenderer; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -30,7 +29,7 @@ public class BuildModifiers { //Called from BuildModes public static void onBlockPlaced(PlayerEntity player, List startCoordinates, Direction sideHit, Vector3d hitVec, boolean placeStartPos) { World world = player.level; - ItemRandomizerBag.renewRandomness(); + AbstractRandomizerBagItem.renewRandomness(); //Format hitvec to 0.x hitVec = new Vector3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z))); @@ -193,7 +192,7 @@ public class BuildModifiers { ItemStack itemBlock = ItemStack.EMPTY; if (itemStack.getItem() instanceof BlockItem) itemBlock = itemStack; else itemBlock = CompatHelper.getItemBlockFromStack(itemStack); - ItemRandomizerBag.resetRandomness(); + AbstractRandomizerBagItem.resetRandomness(); //Add blocks in posList first for (BlockPos blockPos : posList) { diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java index dcd8f5d..736061d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java @@ -10,7 +10,7 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import java.util.ArrayList; import java.util.List; @@ -65,9 +65,11 @@ public class Mirror { if (!isEnabled(m, startPos)) return blockStates; //Randomizer bag synergy + AbstractRandomizerBagItem randomizerBagItem = null; IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) { - bagInventory = ItemRandomizerBag.getBagInventory(itemStack); + if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { + randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem(); + bagInventory = randomizerBagItem.getBagInventory(itemStack); } if (m.mirrorX) @@ -88,7 +90,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); + itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vector3d(0, 0, 0), hand); } @@ -113,7 +115,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); + itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vector3d(0, 0, 0), hand); } @@ -136,7 +138,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); + itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vector3d(0, 0, 0), hand); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java index bd3c066..08b8616 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java @@ -11,7 +11,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import java.util.ArrayList; import java.util.List; @@ -74,9 +74,11 @@ public class RadialMirror { blockState = rotateOriginalBlockState(startAngleToCenter, blockState); //Randomizer bag synergy + AbstractRandomizerBagItem randomizerBagItem = null; IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemRandomizerBag) { - bagInventory = ItemRandomizerBag.getBagInventory(itemStack); + if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { + randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem(); + bagInventory = randomizerBagItem.getBagInventory(itemStack); } BlockState newBlockState; @@ -96,7 +98,7 @@ public class RadialMirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); + itemStack = randomizerBagItem.pickRandomStack(bagInventory); newBlockState = BuildModifiers .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vector3d(0, 0, 0), Hand.MAIN_HAND); diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java b/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java index 875f6c1..7b464fb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java @@ -8,13 +8,17 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.RandomizerBagItem; import javax.annotation.Nonnull; import javax.annotation.Nullable; public class ItemHandlerCapabilityProvider implements ICapabilitySerializable { - IItemHandler itemHandler = new ItemStackHandler(ItemRandomizerBag.INV_SIZE); + IItemHandler itemHandler; + + public ItemHandlerCapabilityProvider(int size) { + itemHandler = new ItemStackHandler(size); + } @Nonnull @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java index 775aa68..629d092 100644 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java @@ -1,37 +1,16 @@ package nl.requios.effortlessbuilding.compatibility; import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; public class CompatHelper { - //TODO 1.13 compatibility -// // Get a handle to the dank null item instance. This will remain null if the mod doesn't load -// // and all checks will fail, so it works. -// @GameRegistry.ObjectHolder("danknull:dank_null") -// public static final Item dankNullItem = null; -// -// public static IChiselsAndBitsProxy chiselsAndBitsProxy; -// + public static void setup() { - //TODO 1.13 compatibility -// if (Loader.isModLoaded("chiselsandbits")) { -// // reflection to avoid hard dependency -// try { -// chiselsAndBitsProxy = Class.forName("nl.requios.effortlessbuilding.compatibility.ActiveChiselsAndBitsProxy").asSubclass(ActiveChiselsAndBitsProxy.class).newInstance(); -// } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { -// e.printStackTrace(); -// } -// } else { -// chiselsAndBitsProxy = new DummyChiselsAndBitsProxy(); -// } + } // Check if the item given is a proxy for blocks. For now, we check for the randomizer bag, @@ -40,10 +19,7 @@ public class CompatHelper { Item item = stack.getItem(); if (item instanceof BlockItem) return true; - return item instanceof ItemRandomizerBag; - //TODO 1.13 compatibility -// if (item == dankNullItem) -// return true; + return item instanceof AbstractRandomizerBagItem; } // Get the block to be placed by this proxy. For the /dank/null, it's the slot stack @@ -55,24 +31,17 @@ public class CompatHelper { return proxy; //Randomizer Bag - if (proxyItem instanceof ItemRandomizerBag) { + if (proxyItem instanceof AbstractRandomizerBagItem) { ItemStack itemStack = proxy; while (!(itemStack.getItem() instanceof BlockItem || itemStack.isEmpty())) { - if (itemStack.getItem() instanceof ItemRandomizerBag) - itemStack = ItemRandomizerBag.pickRandomStack(ItemRandomizerBag.getBagInventory(itemStack)); + if (itemStack.getItem() instanceof AbstractRandomizerBagItem) { + AbstractRandomizerBagItem randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem(); + itemStack = randomizerBagItem.pickRandomStack(randomizerBagItem.getBagInventory(itemStack)); + } } return itemStack; } - //TODO 1.13 compatibility - //Dank Null -// if (proxyItem == dankNullItem) { -// int index = 0; -// if (proxy.hasTagCompound() && proxy.getTagCompound().hasKey("selectedIndex")) -// index = proxy.getTagCompound().getInteger("selectedIndex"); -// return proxy.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); -// } - return ItemStack.EMPTY; } @@ -82,49 +51,12 @@ public class CompatHelper { Item blockItem = Item.byBlock(state.getBlock()); if (stack.getItem() instanceof BlockItem) return stack; - else if (stack.getItem() instanceof ItemRandomizerBag) { - IItemHandler bagInventory = ItemRandomizerBag.getBagInventory(stack); - return ItemRandomizerBag.findStack(bagInventory, blockItem); + else if (stack.getItem() instanceof AbstractRandomizerBagItem) { + AbstractRandomizerBagItem randomizerBagItem = (AbstractRandomizerBagItem) stack.getItem(); + IItemHandler bagInventory = randomizerBagItem.getBagInventory(stack); + return randomizerBagItem.findStack(bagInventory, blockItem); } - //TODO 1.13 compatibility -// else if (stack.getItem() == dankNullItem) { -// int index = itemHandlerSlotForItem(stack, blockItem); -// if (index >= 0) -// return stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); -// } + return ItemStack.EMPTY; } - - // Handle IItemHandler slot stacks not being modifiable. We must call IItemHandler#extractItem, - // because the ItemStack returned by IItemHandler#getStackInSlot isn't modifiable. - public static void shrinkStack(ItemStack origStack, ItemStack curStack, PlayerEntity player) { - //TODO 1.13 compatibility, offhand support - //Hacky way to get the origstack, because given origStack is itemblock stack and never proxy -// origStack = player.getHeldItem(EnumHand.MAIN_HAND); - -// if (origStack.getItem() == dankNullItem) { -// int index = itemHandlerSlotForItem(origStack, curStack.getItem()); -// origStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).extractItem(index, 1, false); -// } else - curStack.shrink(1); - } - - private static int itemHandlerSlotForItem(ItemStack stack, Item blockItem) { - LazyOptional itemHandlerLazyOptional = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); - IItemHandler handler = itemHandlerLazyOptional.orElse(null); - - if (handler == null) { - EffortlessBuilding.logger.warn("Itemblock proxy has no item handler capability!"); - return -1; - } - - for (int i = 0; i < handler.getSlots(); i++) { - ItemStack ref = handler.getStackInSlot(i); - if (ref.getItem() instanceof BlockItem) - if (ref.getItem() == blockItem) - return i; - } - return -1; - } - } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagContainer.java b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagContainer.java new file mode 100644 index 0000000..ab2f6a4 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagContainer.java @@ -0,0 +1,149 @@ +package nl.requios.effortlessbuilding.gui; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.ClickType; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Hand; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.SlotItemHandler; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.item.DiamondRandomizerBagItem; + +public class DiamondRandomizerBagContainer extends Container { + + private static final int INV_START = DiamondRandomizerBagItem.INV_SIZE, + INV_END = INV_START + 26, + HOTBAR_START = INV_END + 1, + HOTBAR_END = HOTBAR_START + 8; + private final IItemHandler bagInventory; + + public DiamondRandomizerBagContainer(ContainerType type, int id){ + super(type, id); + bagInventory = null; + } + + //Client + public DiamondRandomizerBagContainer(int id, PlayerInventory playerInventory, PacketBuffer packetBuffer) { + this(id, playerInventory); + } + + //Server? + public DiamondRandomizerBagContainer(int containerId, PlayerInventory playerInventory) { + this(containerId, playerInventory, new ItemStackHandler(DiamondRandomizerBagItem.INV_SIZE)); + } + + public DiamondRandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) { + super(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), containerId); + bagInventory = inventory; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.addSlot(new SlotItemHandler(bagInventory, j + i * 9, 8 + j * 18, 18 + i * 18)); + } + } + + // add player inventory slots + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + // add hotbar slots + for (int i = 0; i < 9; ++i) { + addSlot(new Slot(playerInventory, i, 8 + i * 18, 142)); + } + } + + @Override + public boolean stillValid(PlayerEntity playerIn) { + return true; + } + + @Override + public Slot getSlot(int parSlotIndex) { + if (parSlotIndex >= slots.size()) + parSlotIndex = slots.size() - 1; + return super.getSlot(parSlotIndex); + } + + @Override + public ItemStack quickMoveStack(PlayerEntity playerIn, int slotIndex) { + ItemStack itemstack = ItemStack.EMPTY; + Slot slot = this.slots.get(slotIndex); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + itemstack = itemstack1.copy(); + + // If item is in our custom inventory + if (slotIndex < INV_START) { + // try to place in player inventory / action bar + if (!this.moveItemStackTo(itemstack1, INV_START, HOTBAR_END + 1, true)) { + return ItemStack.EMPTY; + } + + slot.onQuickCraft(itemstack1, itemstack); + } + // Item is in inventory / hotbar, try to place in custom inventory or armor slots + else { + /** + * Implementation number 1: Shift-click into your custom inventory + */ + if (slotIndex >= INV_START) { + // place in custom inventory + if (!this.moveItemStackTo(itemstack1, 0, INV_START, false)) { + return ItemStack.EMPTY; + } + } + } + + if (itemstack1.getCount() == 0) { + slot.set(ItemStack.EMPTY); + } else { + slot.setChanged(); + } + + if (itemstack1.getCount() == itemstack.getCount()) { + return ItemStack.EMPTY; + } + + slot.onTake(playerIn, itemstack1); + } + + return itemstack; + } + + /** + * You should override this method to prevent the player from moving the stack that + * opened the inventory, otherwise if the player moves it, the inventory will not + * be able to save properly + * @return + */ + @Override + public ItemStack clicked(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) { + // this will prevent the player from interacting with the item that opened the inventory: + if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getItem().equals(player.getItemInHand(Hand.MAIN_HAND))) { + //Do nothing; + return ItemStack.EMPTY; + } + return super.clicked(slot, dragType, clickTypeIn, player); + } + + /** + * Callback for when the crafting gui is closed. + */ + @Override + public void removed(PlayerEntity player) { + super.removed(player); + if (!player.level.isClientSide) { + broadcastChanges(); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java new file mode 100644 index 0000000..f1fa2ac --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java @@ -0,0 +1,47 @@ +package nl.requios.effortlessbuilding.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import nl.requios.effortlessbuilding.EffortlessBuilding; + +import javax.annotation.ParametersAreNonnullByDefault; + +@OnlyIn(Dist.CLIENT) +@ParametersAreNonnullByDefault +public class DiamondRandomizerBagScreen extends ContainerScreen { + private static final ResourceLocation guiTextures = + new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/diamondrandomizerbag.png"); + + public DiamondRandomizerBagScreen(DiamondRandomizerBagContainer randomizerBagContainer, PlayerInventory playerInventory, ITextComponent title) { + super(randomizerBagContainer, playerInventory, title); + imageHeight = 167; + } + + @Override + public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + renderBackground(ms); + super.render(ms, mouseX, mouseY, partialTicks); + this.renderTooltip(ms, mouseX, mouseY); + } + + @Override + protected void renderLabels(MatrixStack ms, int mouseX, int mouseY) { + font.draw(ms, this.title, 8, 6, 0x404040); + font.draw(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040); + } + + @Override + protected void renderBg(MatrixStack ms, float partialTicks, int mouseX, int mouseY) { + RenderSystem.color3f(1.0F, 1.0F, 1.0F); + minecraft.getTextureManager().bind(guiTextures); + int marginHorizontal = (width - imageWidth) / 2; + int marginVertical = (height - imageHeight) / 2; + blit(ms, marginHorizontal, marginVertical, 0, 0, imageWidth, imageHeight); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagContainer.java b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagContainer.java new file mode 100644 index 0000000..065d6f1 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagContainer.java @@ -0,0 +1,147 @@ +package nl.requios.effortlessbuilding.gui; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.ClickType; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Hand; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.SlotItemHandler; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.item.GoldenRandomizerBagItem; + +public class GoldenRandomizerBagContainer extends Container { + + private static final int INV_START = GoldenRandomizerBagItem.INV_SIZE, + INV_END = INV_START + 26, + HOTBAR_START = INV_END + 1, + HOTBAR_END = HOTBAR_START + 8; + private final IItemHandler bagInventory; + + public GoldenRandomizerBagContainer(ContainerType type, int id){ + super(type, id); + bagInventory = null; + } + + //Client + public GoldenRandomizerBagContainer(int id, PlayerInventory playerInventory, PacketBuffer packetBuffer) { + this(id, playerInventory); + } + + //Server? + public GoldenRandomizerBagContainer(int containerId, PlayerInventory playerInventory) { + this(containerId, playerInventory, new ItemStackHandler(GoldenRandomizerBagItem.INV_SIZE)); + } + + public GoldenRandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) { + super(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), containerId); + bagInventory = inventory; + + for (int i = 0; i < GoldenRandomizerBagItem.INV_SIZE; ++i) { + this.addSlot(new SlotItemHandler(bagInventory, i, 8 + (18 * i), 20)); + } + + // add player inventory slots + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 51 + i * 18)); + } + } + + // add hotbar slots + for (int i = 0; i < 9; ++i) { + addSlot(new Slot(playerInventory, i, 8 + i * 18, 109)); + } + } + + @Override + public boolean stillValid(PlayerEntity playerIn) { + return true; + } + + @Override + public Slot getSlot(int parSlotIndex) { + if (parSlotIndex >= slots.size()) + parSlotIndex = slots.size() - 1; + return super.getSlot(parSlotIndex); + } + + @Override + public ItemStack quickMoveStack(PlayerEntity playerIn, int slotIndex) { + ItemStack itemstack = ItemStack.EMPTY; + Slot slot = this.slots.get(slotIndex); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + itemstack = itemstack1.copy(); + + // If item is in our custom inventory + if (slotIndex < INV_START) { + // try to place in player inventory / action bar + if (!this.moveItemStackTo(itemstack1, INV_START, HOTBAR_END + 1, true)) { + return ItemStack.EMPTY; + } + + slot.onQuickCraft(itemstack1, itemstack); + } + // Item is in inventory / hotbar, try to place in custom inventory or armor slots + else { + /** + * Implementation number 1: Shift-click into your custom inventory + */ + if (slotIndex >= INV_START) { + // place in custom inventory + if (!this.moveItemStackTo(itemstack1, 0, INV_START, false)) { + return ItemStack.EMPTY; + } + } + } + + if (itemstack1.getCount() == 0) { + slot.set(ItemStack.EMPTY); + } else { + slot.setChanged(); + } + + if (itemstack1.getCount() == itemstack.getCount()) { + return ItemStack.EMPTY; + } + + slot.onTake(playerIn, itemstack1); + } + + return itemstack; + } + + /** + * You should override this method to prevent the player from moving the stack that + * opened the inventory, otherwise if the player moves it, the inventory will not + * be able to save properly + * @return + */ + @Override + public ItemStack clicked(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) { + // this will prevent the player from interacting with the item that opened the inventory: + if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getItem().equals(player.getItemInHand(Hand.MAIN_HAND))) { + //Do nothing; + return ItemStack.EMPTY; + } + return super.clicked(slot, dragType, clickTypeIn, player); + } + + /** + * Callback for when the crafting gui is closed. + */ + @Override + public void removed(PlayerEntity player) { + super.removed(player); + if (!player.level.isClientSide) { + broadcastChanges(); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java new file mode 100644 index 0000000..0ce8e1a --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java @@ -0,0 +1,47 @@ +package nl.requios.effortlessbuilding.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import nl.requios.effortlessbuilding.EffortlessBuilding; + +import javax.annotation.ParametersAreNonnullByDefault; + +@OnlyIn(Dist.CLIENT) +@ParametersAreNonnullByDefault +public class GoldenRandomizerBagScreen extends ContainerScreen { + private static final ResourceLocation guiTextures = + new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/goldenrandomizerbag.png"); + + public GoldenRandomizerBagScreen(GoldenRandomizerBagContainer randomizerBagContainer, PlayerInventory playerInventory, ITextComponent title) { + super(randomizerBagContainer, playerInventory, title); + imageHeight = 134; + } + + @Override + public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + renderBackground(ms); + super.render(ms, mouseX, mouseY, partialTicks); + this.renderTooltip(ms, mouseX, mouseY); + } + + @Override + protected void renderLabels(MatrixStack ms, int mouseX, int mouseY) { + font.draw(ms, this.title, 8, 6, 0x404040); + font.draw(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040); + } + + @Override + protected void renderBg(MatrixStack ms, float partialTicks, int mouseX, int mouseY) { + RenderSystem.color3f(1.0F, 1.0F, 1.0F); + minecraft.getTextureManager().bind(guiTextures); + int marginHorizontal = (width - imageWidth) / 2; + int marginVertical = (height - imageHeight) / 2; + blit(ms, marginHorizontal, marginVertical, 0, 0, imageWidth, imageHeight); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java index 984d3bd..05f3ea1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java @@ -13,12 +13,14 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.SlotItemHandler; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.RandomizerBagItem; public class RandomizerBagContainer extends Container { - private static final int INV_START = ItemRandomizerBag.INV_SIZE, INV_END = INV_START + 26, - HOTBAR_START = INV_END + 1, HOTBAR_END = HOTBAR_START + 8; + private static final int INV_START = RandomizerBagItem.INV_SIZE, + INV_END = INV_START + 26, + HOTBAR_START = INV_END + 1, + HOTBAR_END = HOTBAR_START + 8; private final IItemHandler bagInventory; public RandomizerBagContainer(ContainerType type, int id){ @@ -33,27 +35,26 @@ public class RandomizerBagContainer extends Container { //Server? public RandomizerBagContainer(int containerId, PlayerInventory playerInventory) { - this(containerId, playerInventory, new ItemStackHandler(ItemRandomizerBag.INV_SIZE)); + this(containerId, playerInventory, new ItemStackHandler(RandomizerBagItem.INV_SIZE)); } public RandomizerBagContainer(int containerId, PlayerInventory playerInventory, IItemHandler inventory) { super(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), containerId); bagInventory = inventory; - for (int i = 0; i < ItemRandomizerBag.INV_SIZE; ++i) { + for (int i = 0; i < RandomizerBagItem.INV_SIZE; ++i) { this.addSlot(new SlotItemHandler(bagInventory, i, 44 + (18 * i), 20)); } // add player inventory slots - int i; - for (i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) { for (int j = 0; j < 9; ++j) { addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 51 + i * 18)); } } // add hotbar slots - for (i = 0; i < 9; ++i) { + for (int i = 0; i < 9; ++i) { addSlot(new Slot(playerInventory, i, 8 + i * 18, 109)); } } @@ -99,7 +100,6 @@ public class RandomizerBagContainer extends Container { return ItemStack.EMPTY; } } - } if (itemstack1.getCount() == 0) { @@ -122,11 +122,13 @@ public class RandomizerBagContainer extends Container { * You should override this method to prevent the player from moving the stack that * opened the inventory, otherwise if the player moves it, the inventory will not * be able to save properly + * @return */ @Override public ItemStack clicked(int slot, int dragType, ClickType clickTypeIn, PlayerEntity player) { // this will prevent the player from interacting with the item that opened the inventory: if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getItem().equals(player.getItemInHand(Hand.MAIN_HAND))) { + //Do nothing; return ItemStack.EMPTY; } return super.clicked(slot, dragType, clickTypeIn, player); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java index 31b8cbb..524f3fd 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java @@ -32,8 +32,8 @@ public class RandomizerBagScreen extends ContainerScreen @Override protected void renderLabels(MatrixStack ms, int mouseX, int mouseY) { - font.drawShadow(ms, this.title, 8, 6, 0x404040); - font.drawShadow(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040); + font.draw(ms, this.title, 8, 6, 0x404040); + font.draw(ms, inventory.getDisplayName(), 8, imageHeight - 96 + 2, 0x404040); } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java index 3af11d2..84e469f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.gui.buildmode; -import com.google.common.base.Stopwatch; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.SimpleSound; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.Tessellator; @@ -12,22 +12,26 @@ import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.resources.I18n; -import net.minecraft.client.settings.KeyBinding; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Direction; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TranslationTextComponent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.ModClientEventHandler; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; +import nl.requios.effortlessbuilding.network.ModeActionMessage; +import nl.requios.effortlessbuilding.network.ModeSettingsMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.proxy.ClientProxy; import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.opengl.GL11; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; -import java.util.concurrent.TimeUnit; -import static nl.requios.effortlessbuilding.buildmode.BuildModes.BuildModeEnum; import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*; import nl.requios.effortlessbuilding.buildmode.BuildModes.BuildModeEnum; @@ -35,7 +39,7 @@ import nl.requios.effortlessbuilding.buildmode.ModeOptions.ActionEnum; import nl.requios.effortlessbuilding.buildmode.ModeOptions.OptionEnum; /** - * From Chisels and Bits by AlgorithmX2 + * Initially from Chisels and Bits by AlgorithmX2 * https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/client/gui/ChiselsAndBitsMenu.java */ @@ -44,55 +48,45 @@ import nl.requios.effortlessbuilding.buildmode.ModeOptions.OptionEnum; public class RadialMenu extends Screen { public static final RadialMenu instance = new RadialMenu(); - private final float TIME_SCALE = 0.01f; public BuildModeEnum switchTo = null; public ActionEnum doAction = null; - public boolean actionUsed = false; - private float visibility = 0.0f; - private Stopwatch lastChange = Stopwatch.createStarted(); + public boolean performedActionUsingMouse; + private float visibility; public RadialMenu() { super(new TranslationTextComponent("effortlessbuilding.screen.radial_menu")); } - private float clampVis(final float f) { - return Math.max(0.0f, Math.min(1.0f, f)); - } - - public void raiseVisibility() { - visibility = clampVis(visibility + lastChange.elapsed(TimeUnit.MILLISECONDS) * TIME_SCALE); - lastChange = Stopwatch.createStarted(); - } - - public void decreaseVisibility() { - visibility = clampVis(visibility - lastChange.elapsed(TimeUnit.MILLISECONDS) * TIME_SCALE); - lastChange = Stopwatch.createStarted(); - } - - public void setVisibility(float visibility) { - this.visibility = visibility; - } - public boolean isVisible() { - return visibility > 0.001; + return Minecraft.getInstance().screen instanceof RadialMenu; } - public void configure(final int scaledWidth, final int scaledHeight) { - Minecraft mc = Minecraft.getInstance(); - font = mc.font; - width = scaledWidth; - height = scaledHeight; + @Override + protected void init() { + super.init(); + performedActionUsingMouse = false; + visibility = 0f; + } + + @Override + public void tick() { + super.tick(); + + if (!ClientProxy.isKeybindDown(2)) { + onClose(); + } } @Override public void render(MatrixStack ms, final int mouseX, final int mouseY, final float partialTicks) { - if (!isVisible()) return; - - BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(Minecraft.getInstance().player).getBuildMode(); + BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(minecraft.player).getBuildMode(); RenderSystem.pushMatrix(); RenderSystem.translatef(0.0F, 0.0F, 200.0F); + visibility += 0.3f * partialTicks; + if (visibility > 1f) visibility = 1f; + final int startColor = (int) (visibility * 98) << 24; final int endColor = (int) (visibility * 128) << 24; @@ -142,9 +136,9 @@ public class RadialMenu extends Screen { //Add actions buttons.add(new MenuButton(ActionEnum.UNDO.name, ActionEnum.UNDO, -buttonDistance - 26, -13, Direction.UP)); buttons.add(new MenuButton(ActionEnum.REDO.name, ActionEnum.REDO, -buttonDistance, -13, Direction.UP)); - buttons.add(new MenuButton(ActionEnum.OPEN_PLAYER_SETTINGS.name, ActionEnum.OPEN_PLAYER_SETTINGS, -buttonDistance - 26 - 13, 13, Direction.DOWN)); - buttons.add(new MenuButton(ActionEnum.OPEN_MODIFIER_SETTINGS.name, ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 13, 13, Direction.DOWN)); - buttons.add(new MenuButton(ActionEnum.REPLACE.name, ActionEnum.REPLACE, -buttonDistance + 13, 13, Direction.DOWN)); +// buttons.add(new MenuButton(ActionEnum.OPEN_PLAYER_SETTINGS.name, ActionEnum.OPEN_PLAYER_SETTINGS, -buttonDistance - 26 - 13, 13, Direction.DOWN)); + buttons.add(new MenuButton(ActionEnum.OPEN_MODIFIER_SETTINGS.name, ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 26, 13, Direction.DOWN)); + buttons.add(new MenuButton(ActionEnum.REPLACE.name, ActionEnum.REPLACE, -buttonDistance, 13, Direction.DOWN)); //Add buildmode dependent options OptionEnum[] options = currentBuildMode.options; @@ -370,10 +364,10 @@ public class RadialMenu extends Screen { //Add keybind in brackets if (button.action == ActionEnum.UNDO) { - keybind = I18n.get(ClientProxy.keyBindings[4].saveString()); + keybind = I18n.get(ClientProxy.keyBindings[3].saveString()); } if (button.action == ActionEnum.REDO) { - keybind = I18n.get(ClientProxy.keyBindings[5].saveString()); + keybind = I18n.get(ClientProxy.keyBindings[4].saveString()); } if (button.action == ActionEnum.REPLACE) { keybind = I18n.get(ClientProxy.keyBindings[1].saveString()); @@ -385,7 +379,7 @@ public class RadialMenu extends Screen { //Add (ctrl) to first two actions of first option if (button.action == currentBuildMode.options[0].actions[0] || button.action == currentBuildMode.options[0].actions[1]) { - keybind = I18n.get(ClientProxy.keyBindings[6].saveString()); + keybind = I18n.get(ClientProxy.keyBindings[5].saveString()); if (keybind.equals("Left Control")) keybind = "Ctrl"; } } @@ -438,26 +432,62 @@ public class RadialMenu extends Screen { return n > 0 ? 1 : -1; } - /** - * Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton - */ + @Override + public boolean isPauseScreen() { + return false; + } + @Override public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { - EffortlessBuilding.log("mouse clicked"); + performAction(true); - KeyBinding.setAll(); - KeyBinding.set(ClientProxy.keyBindings[3].getKey(), true); - - if (mouseButton == 0) { - this.minecraft.setScreen(null); - - if (this.minecraft.screen == null) { - this.minecraft.setWindowActive(true); - } - } return super.mouseClicked(mouseX, mouseY, mouseButton); } + @Override + public void onClose() { + super.onClose(); + //After onClose so it can open another screen + if (!performedActionUsingMouse) performAction(false); + } + + private void performAction(boolean fromMouseClick) { + PlayerEntity player = Minecraft.getInstance().player; + + ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); + + if (switchTo != null) { + playRadialMenuSound(); + + modeSettings.setBuildMode(switchTo); + ModeSettingsManager.setModeSettings(player, modeSettings); + PacketHandler.INSTANCE.sendToServer(new ModeSettingsMessage(modeSettings)); + + EffortlessBuilding.log(player, I18n.get(modeSettings.getBuildMode().name), true); + + if (fromMouseClick) performedActionUsingMouse = true; + } + + //Perform button action + ModeOptions.ActionEnum action = doAction; + if (action != null) { + playRadialMenuSound(); + + ModeOptions.performAction(player, action); + PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); + + if (fromMouseClick) performedActionUsingMouse = true; + } + } + + public static void playRadialMenuSound() { + final float volume = 0.1f; + if (volume >= 0.0001f) { + SimpleSound sound = new SimpleSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, volume, 1.0f, Minecraft.getInstance().player.blockPosition()); + Minecraft.getInstance().getSoundManager().play(sound); + } + } + private static class MenuButton { public final ActionEnum action; diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java index d0b72a0..10b857b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java @@ -74,7 +74,7 @@ public class SurvivalHelper { } if (!player.isCreative() && Block.byItem(itemstack.getItem()) == block) { - CompatHelper.shrinkStack(origstack, itemstack, player); + itemstack.shrink(1); } return true; diff --git a/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java b/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java new file mode 100644 index 0000000..8be495d --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java @@ -0,0 +1,221 @@ +package nl.requios.effortlessbuilding.item; + +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.fluid.Fluids; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.*; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.ActionResult; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.fml.network.NetworkHooks; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import nl.requios.effortlessbuilding.buildmode.BuildModes; +import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; +import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; +import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; +import nl.requios.effortlessbuilding.helper.SurvivalHelper; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Random; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public abstract class AbstractRandomizerBagItem extends Item { + + private static long currentSeed = 1337; + private static final Random rand = new Random(currentSeed); + + public AbstractRandomizerBagItem() { + super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1)); + } + + public abstract int getInventorySize(); + + public abstract INamedContainerProvider getContainerProvider(ItemStack item); + + /** + * Get the inventory of a randomizer bag by checking the capability. + */ + public IItemHandler getBagInventory(ItemStack bag) { + return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null); + } + + /** + * Pick a random slot from the bag. Empty slots will never get chosen. + */ + public ItemStack pickRandomStack(IItemHandler bagInventory) { + //Find how many stacks are non-empty, and save them in a list + int nonempty = 0; + List nonEmptyStacks = new ArrayList<>(); + List originalSlots = new ArrayList<>(getInventorySize()); + for (int i = 0; i < bagInventory.getSlots(); i++) { + ItemStack stack = bagInventory.getStackInSlot(i); + if (!stack.isEmpty()) { + nonempty++; + nonEmptyStacks.add(stack); + originalSlots.add(i); + } + } + + if (nonEmptyStacks.size() != originalSlots.size()) + throw new Error("NonEmptyStacks and OriginalSlots not same size"); + + if (nonempty == 0) return ItemStack.EMPTY; + + //Pick random slot + int randomSlot = rand.nextInt(nonempty); + if (randomSlot < 0 || randomSlot > bagInventory.getSlots()) return ItemStack.EMPTY; + + int originalSlot = originalSlots.get(randomSlot); + if (originalSlot < 0 || originalSlot > bagInventory.getSlots()) return ItemStack.EMPTY; + + return bagInventory.getStackInSlot(originalSlot); + } + + public ItemStack findStack(IItemHandler bagInventory, Item item) { + for (int i = 0; i < bagInventory.getSlots(); i++) { + ItemStack stack = bagInventory.getStackInSlot(i); + if (!stack.isEmpty() && stack.getItem() == item) { + return stack; + } + } + return ItemStack.EMPTY; + } + + public static void resetRandomness() { + rand.setSeed(currentSeed); + } + + public static void renewRandomness() { + currentSeed = Calendar.getInstance().getTimeInMillis(); + rand.setSeed(currentSeed); + } + + @Override + public ActionResultType useOn(ItemUseContext ctx) { + PlayerEntity player = ctx.getPlayer(); + World world = ctx.getLevel(); + BlockPos pos = ctx.getClickedPos(); + Direction facing = ctx.getClickedFace(); + ItemStack item = ctx.getItemInHand(); + Vector3d hitVec = ctx.getClickLocation(); + + if (player == null) return ActionResultType.FAIL; + + if (ctx.getPlayer() != null && ctx.getPlayer().isShiftKeyDown()) { //ctx.isPlacerSneaking() + if (world.isClientSide) return ActionResultType.SUCCESS; + //Open inventory + NetworkHooks.openGui((ServerPlayerEntity) player, getContainerProvider(item)); + } else { + if (world.isClientSide) return ActionResultType.SUCCESS; + + //Only place manually if in normal vanilla mode + BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); + ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); + if (buildMode != BuildModes.BuildModeEnum.NORMAL || modifierSettings.doQuickReplace()) { + return ActionResultType.FAIL; + } + + //Use item + //Get bag inventory + //TODO offhand support + ItemStack bag = player.getItemInHand(Hand.MAIN_HAND); + IItemHandler bagInventory = getBagInventory(bag); + if (bagInventory == null) + return ActionResultType.FAIL; + + ItemStack toPlace = pickRandomStack(bagInventory); + if (toPlace.isEmpty()) return ActionResultType.FAIL; + + //Previously: use onItemUse to place block (no synergy) + //bag.setItemDamage(toPlace.getMetadata()); + //toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); + + //TODO replaceable + if (!world.getBlockState(pos).getBlock().canBeReplaced(world.getBlockState(pos), Fluids.EMPTY)) { + pos = pos.relative(facing); + } + + BlockItemUseContext blockItemUseContext = new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, new BlockRayTraceResult(hitVec, facing, pos, false))); + BlockState blockState = Block.byItem(toPlace.getItem()).getStateForPlacement(blockItemUseContext); + + SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, hitVec, false, false, true); + + //Synergy + //Works without calling +// BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState); +// BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand); +// Mirror.onBlockPlaced(placeEvent); +// Array.onBlockPlaced(placeEvent); + } + return ActionResultType.SUCCESS; + } + + @Override + public ActionResult use(World world, PlayerEntity player, Hand hand) { + ItemStack bag = player.getItemInHand(hand); + + if (player.isShiftKeyDown()) { + if (world.isClientSide) return new ActionResult<>(ActionResultType.SUCCESS, bag); + //Open inventory + NetworkHooks.openGui((ServerPlayerEntity) player, getContainerProvider(bag)); + } else { + //Use item + //Get bag inventory + IItemHandler bagInventory = getBagInventory(bag); + if (bagInventory == null) + return new ActionResult<>(ActionResultType.FAIL, bag); + + ItemStack toUse = pickRandomStack(bagInventory); + if (toUse.isEmpty()) return new ActionResult<>(ActionResultType.FAIL, bag); + + return toUse.use(world, player, hand); + } + return new ActionResult<>(ActionResultType.PASS, bag); + } + + @Override + public int getUseDuration(ItemStack p_77626_1_) { + return 1; + } + + @Nullable + @Override + public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) { + return new ItemHandlerCapabilityProvider(getInventorySize()); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block")); + tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory")); + if (world != null && world.players().size() > 1) { + tooltip.add(new StringTextComponent(TextFormatting.YELLOW + "Experimental on servers: may lose inventory")); + } + } + + @Override + public String getDescriptionId() { + return this.getRegistryName().toString(); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/DiamondRandomizerBagItem.java b/src/main/java/nl/requios/effortlessbuilding/item/DiamondRandomizerBagItem.java new file mode 100644 index 0000000..e5ace61 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/DiamondRandomizerBagItem.java @@ -0,0 +1,46 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagContainer; + +import javax.annotation.Nullable; + +public class DiamondRandomizerBagItem extends AbstractRandomizerBagItem{ + public static final int INV_SIZE = 27; + + @Override + public int getInventorySize() { + return 27; + } + + @Override + public INamedContainerProvider getContainerProvider(ItemStack bag) { + return new ContainerProvider(bag); + } + + public static class ContainerProvider implements INamedContainerProvider { + + private final ItemStack bag; + + public ContainerProvider(ItemStack bag) { + this.bag = bag; + } + + @Override + public ITextComponent getDisplayName() { + return new TranslationTextComponent("effortlessbuilding:diamond_randomizer_bag"); + } + + @Nullable + @Override + public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) { + return new DiamondRandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag)); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/GoldenRandomizerBagItem.java b/src/main/java/nl/requios/effortlessbuilding/item/GoldenRandomizerBagItem.java new file mode 100644 index 0000000..aab3dc8 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/GoldenRandomizerBagItem.java @@ -0,0 +1,46 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagContainer; + +import javax.annotation.Nullable; + +public class GoldenRandomizerBagItem extends AbstractRandomizerBagItem{ + public static final int INV_SIZE = 9; + + @Override + public int getInventorySize() { + return 9; + } + + @Override + public INamedContainerProvider getContainerProvider(ItemStack bag) { + return new ContainerProvider(bag); + } + + public static class ContainerProvider implements INamedContainerProvider { + + private final ItemStack bag; + + public ContainerProvider(ItemStack bag) { + this.bag = bag; + } + + @Override + public ITextComponent getDisplayName() { + return new TranslationTextComponent("effortlessbuilding:golden_randomizer_bag"); + } + + @Nullable + @Override + public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) { + return new GoldenRandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag)); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java b/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java deleted file mode 100644 index b056e8d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java +++ /dev/null @@ -1,251 +0,0 @@ -package nl.requios.effortlessbuilding.item; - -import mcp.MethodsReturnNonnullByDefault; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.fluid.Fluids; -import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.INamedContainerProvider; -import net.minecraft.item.*; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.ActionResult; -import net.minecraft.util.ActionResultType; -import net.minecraft.util.Direction; -import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.StringTextComponent; -import net.minecraft.util.text.TextFormatting; -import net.minecraft.util.text.TranslationTextComponent; -import net.minecraft.world.World; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.fml.network.NetworkHooks; -import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmode.BuildModes; -import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; -import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; -import nl.requios.effortlessbuilding.gui.RandomizerBagContainer; -import nl.requios.effortlessbuilding.helper.SurvivalHelper; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Random; - -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class ItemRandomizerBag extends Item { - public static final int INV_SIZE = 5; - - private static long currentSeed = 1337; - private static final Random rand = new Random(currentSeed); - - public ItemRandomizerBag() { - super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1)); - - this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag"); - } - - /** - * Get the inventory of a randomizer bag by checking the capability. - * - * @param bag - * @return - */ - public static IItemHandler getBagInventory(ItemStack bag) { - return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null); - } - - /** - * Pick a random slot from the bag. Empty slots will never get chosen. - * - * @param bagInventory - * @return - */ - public static ItemStack pickRandomStack(IItemHandler bagInventory) { - //Find how many stacks are non-empty, and save them in a list - int nonempty = 0; - List nonEmptyStacks = new ArrayList<>(INV_SIZE); - List originalSlots = new ArrayList<>(INV_SIZE); - for (int i = 0; i < bagInventory.getSlots(); i++) { - ItemStack stack = bagInventory.getStackInSlot(i); - if (!stack.isEmpty()) { - nonempty++; - nonEmptyStacks.add(stack); - originalSlots.add(i); - } - } - - if (nonEmptyStacks.size() != originalSlots.size()) - throw new Error("NonEmptyStacks and OriginalSlots not same size"); - - if (nonempty == 0) return ItemStack.EMPTY; - - //Pick random slot - int randomSlot = rand.nextInt(nonempty); - if (randomSlot < 0 || randomSlot > bagInventory.getSlots()) return ItemStack.EMPTY; - - int originalSlot = originalSlots.get(randomSlot); - if (originalSlot < 0 || originalSlot > bagInventory.getSlots()) return ItemStack.EMPTY; - - return bagInventory.getStackInSlot(originalSlot); - } - - public static ItemStack findStack(IItemHandler bagInventory, Item item) { - for (int i = 0; i < bagInventory.getSlots(); i++) { - ItemStack stack = bagInventory.getStackInSlot(i); - if (!stack.isEmpty() && stack.getItem() == item) { - return stack; - } - } - return ItemStack.EMPTY; - } - - public static void resetRandomness() { - rand.setSeed(currentSeed); - } - - public static void renewRandomness() { - currentSeed = Calendar.getInstance().getTimeInMillis(); - rand.setSeed(currentSeed); - } - - @Override - public ActionResultType useOn(ItemUseContext ctx) { - PlayerEntity player = ctx.getPlayer(); - World world = ctx.getLevel(); - BlockPos pos = ctx.getClickedPos(); - Direction facing = ctx.getClickedFace(); - ItemStack item = ctx.getItemInHand(); - Vector3d hitVec = ctx.getClickLocation(); - - if (player == null) return ActionResultType.FAIL; - - if (ctx.getPlayer() != null && ctx.getPlayer().isShiftKeyDown()) { //ctx.isPlacerSneaking() - if (world.isClientSide) return ActionResultType.SUCCESS; - //Open inventory - NetworkHooks.openGui((ServerPlayerEntity) player, new ContainerProvider(item)); - } else { - if (world.isClientSide) return ActionResultType.SUCCESS; - - //Only place manually if in normal vanilla mode - BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); - ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); - if (buildMode != BuildModes.BuildModeEnum.NORMAL || modifierSettings.doQuickReplace()) { - return ActionResultType.FAIL; - } - - //Use item - //Get bag inventory - //TODO offhand support - ItemStack bag = player.getItemInHand(Hand.MAIN_HAND); - IItemHandler bagInventory = getBagInventory(bag); - if (bagInventory == null) - return ActionResultType.FAIL; - - ItemStack toPlace = pickRandomStack(bagInventory); - if (toPlace.isEmpty()) return ActionResultType.FAIL; - - //Previously: use onItemUse to place block (no synergy) - //bag.setItemDamage(toPlace.getMetadata()); - //toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); - - //TODO replaceable - if (!world.getBlockState(pos).getBlock().canBeReplaced(world.getBlockState(pos), Fluids.EMPTY)) { - pos = pos.relative(facing); - } - - BlockItemUseContext blockItemUseContext = new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, new BlockRayTraceResult(hitVec, facing, pos, false))); - BlockState blockState = Block.byItem(toPlace.getItem()).getStateForPlacement(blockItemUseContext); - - SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, hitVec, false, false, true); - - //Synergy - //Works without calling -// BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, pos, blockState); -// BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, hand); -// Mirror.onBlockPlaced(placeEvent); -// Array.onBlockPlaced(placeEvent); - } - return ActionResultType.SUCCESS; - } - - @Override - public ActionResult use(World world, PlayerEntity player, Hand hand) { - ItemStack bag = player.getItemInHand(hand); - - if (player.isShiftKeyDown()) { - if (world.isClientSide) return new ActionResult<>(ActionResultType.SUCCESS, bag); - //Open inventory - NetworkHooks.openGui((ServerPlayerEntity) player, new ContainerProvider(bag)); - } else { - //Use item - //Get bag inventory - IItemHandler bagInventory = getBagInventory(bag); - if (bagInventory == null) - return new ActionResult<>(ActionResultType.FAIL, bag); - - ItemStack toUse = pickRandomStack(bagInventory); - if (toUse.isEmpty()) return new ActionResult<>(ActionResultType.FAIL, bag); - - return toUse.use(world, player, hand); - } - return new ActionResult<>(ActionResultType.PASS, bag); - } - - @Override - public int getUseDuration(ItemStack p_77626_1_) { - return 1; - } - - @Nullable - @Override - public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) { - return new ItemHandlerCapabilityProvider(); - } - - @Override - public void appendHoverText(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { - tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block")); - tooltip.add(new StringTextComponent(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory")); - if (world != null && world.players().size() > 1) { - tooltip.add(new StringTextComponent(TextFormatting.YELLOW + "Experimental on servers: may lose inventory")); - } - } - - @Override - public String getDescriptionId() { - return this.getRegistryName().toString(); - } - - public static class ContainerProvider implements INamedContainerProvider { - - private final ItemStack bag; - - public ContainerProvider(ItemStack bag) { - this.bag = bag; - } - - @Override - public ITextComponent getDisplayName() { - return new TranslationTextComponent("effortlessbuilding.screen.randomizer_bag"); - } - - @Nullable - @Override - public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) { - return new RandomizerBagContainer(containerId, playerInventory, ItemRandomizerBag.getBagInventory(bag)); - } - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java b/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java new file mode 100644 index 0000000..4e27d31 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java @@ -0,0 +1,46 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import nl.requios.effortlessbuilding.gui.RandomizerBagContainer; + +import javax.annotation.Nullable; + +public class RandomizerBagItem extends AbstractRandomizerBagItem{ + public static final int INV_SIZE = 5; + + @Override + public int getInventorySize() { + return 5; + } + + @Override + public INamedContainerProvider getContainerProvider(ItemStack bag) { + return new ContainerProvider(bag); + } + + public static class ContainerProvider implements INamedContainerProvider { + + private final ItemStack bag; + + public ContainerProvider(ItemStack bag) { + this.bag = bag; + } + + @Override + public ITextComponent getDisplayName() { + return new TranslationTextComponent("effortlessbuilding:randomizer_bag"); + } + + @Nullable + @Override + public Container createMenu(int containerId, PlayerInventory playerInventory, PlayerEntity player) { + return new RandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag)); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java similarity index 95% rename from src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java rename to src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java index 56c3f63..c8c064c 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java @@ -22,11 +22,10 @@ import java.util.List; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class ItemReachUpgrade1 extends Item { +public class ReachUpgrade1Item extends Item { - public ItemReachUpgrade1() { + public ReachUpgrade1Item() { super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1)); - this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade1"); } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java similarity index 95% rename from src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java rename to src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java index 83f0833..997e4c1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java @@ -22,11 +22,10 @@ import java.util.List; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class ItemReachUpgrade2 extends Item { +public class ReachUpgrade2Item extends Item { - public ItemReachUpgrade2() { + public ReachUpgrade2Item() { super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1)); - this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade2"); } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java similarity index 95% rename from src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java rename to src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java index 281cb9e..ad2567f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java @@ -22,11 +22,10 @@ import java.util.List; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class ItemReachUpgrade3 extends Item { +public class ReachUpgrade3Item extends Item { - public ItemReachUpgrade3() { + public ReachUpgrade3Item() { super(new Item.Properties().tab(ItemGroup.TAB_TOOLS).stacksTo(1)); - this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade3"); } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index 5b2e437..5671680 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -42,6 +42,8 @@ import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.compatibility.CompatHelper; +import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagScreen; +import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagScreen; import nl.requios.effortlessbuilding.gui.RandomizerBagScreen; import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; @@ -66,6 +68,33 @@ public class ClientProxy implements IProxy { private static int breakCooldown = 0; private static boolean shadersInitialized = false; + @Override + public void setup(FMLCommonSetupEvent event) { + } + + @Override + public void clientSetup(FMLClientSetupEvent event) { + // register key bindings + keyBindings = new KeyBinding[6]; + + // instantiate the key bindings + keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, InputMappings.getKey(GLFW.GLFW_KEY_KP_ADD, 0), "key.effortlessbuilding.category"); + keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_KP_SUBTRACT, 0), "key.effortlessbuilding.category"); + keyBindings[2] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_LEFT_ALT, 0), "key.effortlessbuilding.category"); + keyBindings[3] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category"); + keyBindings[4] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getKey(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category"); + keyBindings[5] = new KeyBinding("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category"); + + // register all the key bindings + for (KeyBinding keyBinding : keyBindings) { + ClientRegistry.registerKeyBinding(keyBinding); + } + + ScreenManager.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new); + ScreenManager.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new); + ScreenManager.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new); + } + @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent event) { @@ -233,31 +262,33 @@ public class ClientProxy implements IProxy { PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings)); } - //Creative/survival mode toggle - if (keyBindings[2].consumeClick()) { - if (player.isCreative()) { - player.chat("/gamemode survival"); + //Radial menu + if (keyBindings[2].isDown()) { + if (ReachHelper.getMaxReach(player) > 0) { + if (!RadialMenu.instance.isVisible()) { + Minecraft.getInstance().setScreen(RadialMenu.instance); + } } else { - player.chat("/gamemode creative"); + EffortlessBuilding.log(player, "Build modes are disabled until your reach has increased. Increase your reach with craftable reach upgrades."); } } //Undo (Ctrl+Z) - if (keyBindings[4].consumeClick()) { + if (keyBindings[3].consumeClick()) { ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO; ModeOptions.performAction(player, action); PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); } //Redo (Ctrl+Y) - if (keyBindings[5].consumeClick()) { + if (keyBindings[4].consumeClick()) { ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO; ModeOptions.performAction(player, action); PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); } //Change placement mode - if (keyBindings[6].consumeClick()) { + if (keyBindings[5].consumeClick()) { //Toggle between first two actions of the first option of the current build mode BuildModes.BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); if (currentBuildMode.options.length > 0) { @@ -273,49 +304,24 @@ public class ClientProxy implements IProxy { } } } - - //For shader development - if (keyBindings.length >= 8 && keyBindings[7].consumeClick()) { - ShaderHandler.init(); - EffortlessBuilding.log(player, "Reloaded shaders"); - } - } public static void openModifierSettings() { Minecraft mc = Minecraft.getInstance(); - ClientPlayerEntity player = mc.player; - if (player == null) - return; - - RadialMenu.instance.setVisibility(0f); + PlayerEntity player = mc.player; + if (player == null) return; //Disabled if max reach is 0, might be set in the config that way. if (ReachHelper.getMaxReach(player) == 0) { EffortlessBuilding.log(player, "Build modifiers are disabled until your reach has increased. Increase your reach with craftable reach upgrades."); } else { - if (mc.screen == null) { - mc.setScreen(new ModifierSettingsGui()); - } else { - player.closeContainer(); - } + mc.setScreen(new ModifierSettingsGui()); } } public static void openPlayerSettings() { Minecraft mc = Minecraft.getInstance(); - ClientPlayerEntity player = mc.player; - if (player == null) - return; - - RadialMenu.instance.setVisibility(0f); - - //Disabled if max reach is 0, might be set in the config that way. - if (mc.screen == null) { - mc.setScreen(new PlayerSettingsGui()); - } else { - player.closeContainer(); - } + mc.setScreen(new PlayerSettingsGui()); } @SubscribeEvent @@ -326,6 +332,12 @@ public class ClientProxy implements IProxy { } } + public static boolean isKeybindDown(int keybindIndex) { + return InputMappings.isKeyDown( + Minecraft.getInstance().getWindow().getWindow(), + ClientProxy.keyBindings[2].getKey().getValue()); + } + public static RayTraceResult getLookingAt(PlayerEntity player) { World world = player.level; @@ -340,41 +352,6 @@ public class ClientProxy implements IProxy { return world.clip(new RayTraceContext(start, end, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, player)); } - @Override - public void setup(FMLCommonSetupEvent event) { - } - - @Override - public void clientSetup(FMLClientSetupEvent event) { - // register key bindings - keyBindings = new KeyBinding[7]; - - // instantiate the key bindings - keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, InputMappings.getKey(GLFW.GLFW_KEY_KP_ADD, 0), "key.effortlessbuilding.category"); - keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_KP_SUBTRACT, 0), "key.effortlessbuilding.category"); - keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_F4, 0), "key.effortlessbuilding.category"); - keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_LEFT_ALT, 0), "key.effortlessbuilding.category") { - @Override - public boolean same(KeyBinding other) { - //Does not conflict with Chisels and Bits radial menu - if (other.getKey().getValue() == getKey().getValue() && other.getName().equals("mod.chiselsandbits.other.mode")) - return false; - return super.same(other); - } - }; - keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category"); - keyBindings[5] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getKey(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category"); - keyBindings[6] = new KeyBinding("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputMappings.getKey(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category"); - //keyBindings[7] = new KeyBinding("Reload shaders", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_TAB, 0), "key.effortlessbuilding.category"); - - // register all the key bindings - for (KeyBinding keyBinding : keyBindings) { - ClientRegistry.registerKeyBinding(keyBinding); - } - - DeferredWorkQueue.runLater(() -> ScreenManager.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new)); - } - public PlayerEntity getPlayerEntityFromContext(Supplier ctx) { return (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT ? Minecraft.getInstance().player : ctx.get().getSender()); } diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java index d3fa858..190da99 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java @@ -32,7 +32,7 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.Modif import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; -import nl.requios.effortlessbuilding.item.ItemRandomizerBag; +import nl.requios.effortlessbuilding.item.RandomizerBagItem; import nl.requios.effortlessbuilding.proxy.ClientProxy; import java.util.ArrayList; @@ -168,7 +168,7 @@ public class BlockPreviewRenderer { previousSecondPos = secondPos; //if so, renew randomness of randomizer bag - ItemRandomizerBag.renewRandomness(); + RandomizerBagItem.renewRandomness(); //and play sound (max once every tick) if (newCoordinates.size() > 1 && blockStates.size() > 1 && soundTime < ClientProxy.ticksInGame - 0) { soundTime = ClientProxy.ticksInGame; diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index d398f87..d89426b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -4,36 +4,22 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.SimpleSound; -import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.I18n; -import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvents; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; -import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; -import nl.requios.effortlessbuilding.helper.ReachHelper; -import nl.requios.effortlessbuilding.network.ModeActionMessage; -import nl.requios.effortlessbuilding.network.ModeSettingsMessage; -import nl.requios.effortlessbuilding.network.PacketHandler; -import nl.requios.effortlessbuilding.proxy.ClientProxy; /*** * Main render class for Effortless Building @@ -70,90 +56,6 @@ public class RenderHandler { matrixStack.popPose(); } - @SubscribeEvent - //Display Radial Menu - public static void onRenderGameOverlay(final RenderGameOverlayEvent.Post event) { - Minecraft mc = Minecraft.getInstance(); - ClientPlayerEntity player = mc.player; - - //check if chisel and bits tool in hand (and has menu) -// final boolean hasChiselInHand = CompatHelper.chiselsAndBitsProxy.isHoldingChiselTool(EnumHand.MAIN_HAND); - - final RenderGameOverlayEvent.ElementType type = event.getType(); - //TODO 1.13 compatibility - if (type == RenderGameOverlayEvent.ElementType.ALL /*&& !hasChiselInHand*/) { - final boolean wasVisible = RadialMenu.instance.isVisible(); - - if (ClientProxy.keyBindings[3].isDown()) { - if (ReachHelper.getMaxReach(player) > 0) { - RadialMenu.instance.actionUsed = false; - RadialMenu.instance.raiseVisibility(); - } else if (ClientProxy.keyBindings[3].consumeClick()) { - EffortlessBuilding.log(player, "Build modes are disabled until your reach has increased. Increase your reach with craftable reach upgrades."); - } - } else { - if (!RadialMenu.instance.actionUsed) { - ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); - - if (RadialMenu.instance.switchTo != null) { - playRadialMenuSound(); - modeSettings.setBuildMode(RadialMenu.instance.switchTo); - ModeSettingsManager.setModeSettings(player, modeSettings); - PacketHandler.INSTANCE.sendToServer(new ModeSettingsMessage(modeSettings)); - - EffortlessBuilding.log(player, I18n.get(modeSettings.getBuildMode().name), true); - } - - //Perform button action - ModeOptions.ActionEnum action = RadialMenu.instance.doAction; - if (action != null) { - ModeOptions.performAction(player, action); - PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); - } - - playRadialMenuSound(); - } - - RadialMenu.instance.actionUsed = true; - RadialMenu.instance.decreaseVisibility(); - } - - if (RadialMenu.instance.isVisible()) { - - int scaledWidth = mc.getWindow().getGuiScaledWidth(); - int scaledHeight = mc.getWindow().getGuiScaledHeight(); - RadialMenu.instance.configure(scaledWidth, scaledHeight); - - if (!wasVisible) { - mc.mouseHandler.releaseMouse(); - } - - if (mc.mouseHandler.isMouseGrabbed()) { - KeyBinding.releaseAll(); - } - - final int mouseX = ((int) mc.mouseHandler.xpos()) * scaledWidth / mc.getWindow().getWidth(); - final int mouseY = scaledHeight - ((int) mc.mouseHandler.ypos()) * scaledHeight / mc.getWindow().getHeight() - 1; - - net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, event.getMatrixStack(), mouseX, mouseY, event.getPartialTicks()); - } else { - if (wasVisible && - RadialMenu.instance.doAction != ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS && - RadialMenu.instance.doAction != ModeOptions.ActionEnum.OPEN_PLAYER_SETTINGS) { - mc.mouseHandler.grabMouse(); - } - } - } - } - - public static void playRadialMenuSound() { - final float volume = 0.1f; - if (volume >= 0.0001f) { - SimpleSound sound = new SimpleSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, volume, 1.0f, Minecraft.getInstance().player.blockPosition()); - Minecraft.getInstance().getSoundManager().play(sound); - } - } - protected static IVertexBuilder beginLines(IRenderTypeBuffer.Impl renderTypeBuffer) { return renderTypeBuffer.getBuffer(BuildRenderTypes.LINES); } diff --git a/src/main/resources/assets/effortlessbuilding/lang/en_us.json b/src/main/resources/assets/effortlessbuilding/lang/en_us.json index 3a74bbc..aebc911 100644 --- a/src/main/resources/assets/effortlessbuilding/lang/en_us.json +++ b/src/main/resources/assets/effortlessbuilding/lang/en_us.json @@ -1,19 +1,19 @@ { "effortlessbuilding.screen.modifier_settings": "Modifier Settings", "effortlessbuilding.screen.radial_menu": "Build Modes", - "effortlessbuilding.screen.randomizer_bag": "Randomizer Bag", "effortlessbuilding.screen.player_settings": "Player Settings", "key.effortlessbuilding.category": "Effortless Building", "key.effortlessbuilding.hud.desc": "Modifier Menu", "key.effortlessbuilding.replace.desc": "Toggle QuickReplace", - "key.effortlessbuilding.creative.desc": "Toggle Survival/Creative Mode", "key.effortlessbuilding.mode.desc": "Radial Menu", "key.effortlessbuilding.undo.desc": "Undo", "key.effortlessbuilding.redo.desc": "Redo", "key.effortlessbuilding.altplacement.desc": "Alternative placement", - "effortlessbuilding:randomizer_bag": "Randomizer Bag", + "effortlessbuilding:randomizer_bag": "Leather Randomizer Bag", + "effortlessbuilding:golden_randomizer_bag": "Golden Randomizer Bag", + "effortlessbuilding:diamond_randomizer_bag": "Diamond Randomizer Bag", "effortlessbuilding:reach_upgrade1": "Reach Upgrade 1", "effortlessbuilding:reach_upgrade2": "Reach Upgrade 2", "effortlessbuilding:reach_upgrade3": "Reach Upgrade 3", diff --git a/src/main/resources/assets/effortlessbuilding/models/item/diamond_randomizer_bag.json b/src/main/resources/assets/effortlessbuilding/models/item/diamond_randomizer_bag.json new file mode 100644 index 0000000..73c973c --- /dev/null +++ b/src/main/resources/assets/effortlessbuilding/models/item/diamond_randomizer_bag.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "effortlessbuilding:items/diamondrandomizerbag" + } +} diff --git a/src/main/resources/assets/effortlessbuilding/models/item/golden_randomizer_bag.json b/src/main/resources/assets/effortlessbuilding/models/item/golden_randomizer_bag.json new file mode 100644 index 0000000..ca4e43f --- /dev/null +++ b/src/main/resources/assets/effortlessbuilding/models/item/golden_randomizer_bag.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "effortlessbuilding:items/goldenrandomizerbag" + } +} diff --git a/src/main/resources/assets/effortlessbuilding/textures/gui/container/diamondrandomizerbag.png b/src/main/resources/assets/effortlessbuilding/textures/gui/container/diamondrandomizerbag.png new file mode 100644 index 0000000000000000000000000000000000000000..5210658afa50bbb258ae7c364cd95580c959cf09 GIT binary patch literal 920 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