From f45d3ffad79aa6a1b02f9f323dfec2aeb8f82074 Mon Sep 17 00:00:00 2001 From: Christian Knaapen Date: Sun, 31 Oct 2021 16:52:08 +0100 Subject: [PATCH] Added golden and diamond randomizer bags (with container, screen, icon and recipe). Updated recipes for reach upgrades. --- build - kopie.gradle | 159 ------------ build.gradle | 2 +- .../EffortlessBuilding.java | 16 +- .../buildmodifier/Array.java | 12 +- .../buildmodifier/BuildModifiers.java | 6 +- .../buildmodifier/Mirror.java | 14 +- .../buildmodifier/RadialMirror.java | 12 +- .../ItemHandlerCapabilityProvider.java | 7 +- .../compatibility/CompatHelper.java | 16 +- .../gui/DiamondRandomizerBagContainer.java | 148 +++++++++++ .../gui/DiamondRandomizerBagScreen.java | 49 ++++ .../gui/GoldenRandomizerBagContainer.java | 146 +++++++++++ .../gui/GoldenRandomizerBagScreen.java | 49 ++++ .../gui/RandomizerBagContainer.java | 13 +- .../gui/RandomizerBagScreen.java | 5 +- .../item/AbstractRandomizerBagItem.java | 230 +++++++++++++++++ .../item/DiamondRandomizerBagItem.java | 46 ++++ .../item/GoldenRandomizerBagItem.java | 46 ++++ .../item/RandomizerBagItem.java | 234 +----------------- .../effortlessbuilding/proxy/ClientProxy.java | 6 +- .../render/BlockPreviewRenderer.java | 4 +- .../assets/effortlessbuilding/lang/en_us.json | 5 +- .../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 +- 35 files changed, 875 insertions(+), 457 deletions(-) delete mode 100644 build - kopie.gradle 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 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 - kopie.gradle b/build - kopie.gradle deleted file mode 100644 index 1686e24..0000000 --- a/build - kopie.gradle +++ /dev/null @@ -1,159 +0,0 @@ -buildscript { - repositories { - // These repositories are only for Gradle plugins, put any other repositories in the repository block further below - maven { url = 'https://maven.minecraftforge.net' } - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true - } -} -apply plugin: 'net.minecraftforge.gradle' -// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -apply plugin: 'eclipse' -apply plugin: 'maven-publish' - -version = '1.17.1-2.24' -group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'effortlessbuilding' - -// Mojang ships Java 16 to end users in 1.17+ instead of Java 8 in 1.16 or lower, so your mod should target Java 16. -java.toolchain.languageVersion = JavaLanguageVersion.of(16) - -minecraft { - // The mappings can be changed at any time and must be in the following format. - // Channel: Version: - // snapshot YYYYMMDD Snapshot are built nightly. - // stable # Stables are built at the discretion of the MCP team. - // official MCVersion Official field/method names from Mojang mapping files - // - // You must be aware of the Mojang license when using the 'official' mappings. - // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md - // - // Use non-default mappings at your own risk. They may not always work. - // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.17.1' - - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. - - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. - runs { - client { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment (SCAN,REGISTRIES,REGISTRYDUMP) - property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - property 'forge.logging.console.level', 'debug' - - mods { - effortlessbuilding { - source sourceSets.main - } - } - } - - server { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment (SCAN,REGISTRIES,REGISTRYDUMP) - property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - property 'forge.logging.console.level', 'debug' - - mods { - effortlessbuilding { - source sourceSets.main - } - } - } - - data { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment (SCAN,REGISTRIES,REGISTRYDUMP) - property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - property 'forge.logging.console.level', 'debug' - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', 'effortlessbuilding', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - - mods { - effortlessbuilding { - source sourceSets.main - } - } - } - } -} - -// Include resources generated by data generators. -sourceSets.main.resources { srcDir 'src/generated/resources' } - -repositories { - // Put repositories for dependencies here - // ForgeGradle automatically adds the Forge maven and Maven Central for you - - // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: - // flatDir { - // dir 'libs' - // } -} - -dependencies { - // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed - // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. - // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.17.1-37.0.50' - - // Real mod deobf dependency examples - these get remapped to your current mappings - // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency - // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency - // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency - - // Examples using mod jars from ./libs - // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") - - // For more info... - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html -} - -// Example for how to get properties into the manifest for reading by the runtime.. -jar { - manifest { - attributes([ - "Specification-Title": "effortlessbuilding", - "Specification-Vendor": "requios", - "Specification-Version": "1", // We are version 1 of ourselves - "Implementation-Title": project.name, - "Implementation-Version": "${version}", - "Implementation-Vendor" :"requios", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) - } -} - -// Example configuration to allow publishing using the maven-publish task -// This is the preferred method to reobfuscate your jar file -jar.finalizedBy('reobfJar') -// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing -//publish.dependsOn('reobfJar') - -publishing { - publications { - mavenJava(MavenPublication) { - artifact jar - } - } - repositories { - maven { - url "file:///${project.projectDir}/mcmodsrepo" - } - } -} \ No newline at end of file diff --git a/build.gradle b/build.gradle index cb2d8f1..4389b0c 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '1.17.1-2.24' +version = '1.17.1-2.26' 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 5e45fce..fe95ef9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java @@ -6,7 +6,6 @@ import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.Item; import net.minecraft.resources.ResourceLocation; import net.minecraft.network.chat.TextComponent; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; @@ -18,18 +17,15 @@ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fmllegacy.RegistryObject; import net.minecraftforge.fmllegacy.network.IContainerFactory; -import net.minecraftforge.fmlserverevents.FMLServerStartingEvent; 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.RandomizerBagItem; -import nl.requios.effortlessbuilding.item.ReachUpgrade1Item; -import nl.requios.effortlessbuilding.item.ReachUpgrade2Item; -import nl.requios.effortlessbuilding.item.ReachUpgrade3Item; +import nl.requios.effortlessbuilding.item.*; import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.IProxy; @@ -51,13 +47,15 @@ public class EffortlessBuilding { 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 ResourceLocation RANDOMIZER_BAG_GUI = new ResourceLocation(EffortlessBuilding.MODID, "randomizer_bag"); + 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; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java index f34c07b..a90703f 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.core.BlockPos; import net.minecraft.world.phys.Vec3; import net.minecraft.core.Vec3i; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.RandomizerBagItem; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import java.util.ArrayList; import java.util.List; @@ -45,17 +45,19 @@ public class Array { Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); //Randomizer bag synergy + AbstractRandomizerBagItem randomizerBagItem = null; IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof RandomizerBagItem) { - bagInventory = RandomizerBagItem.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 = RandomizerBagItem.pickRandomStack(bagInventory); + if (randomizerBagItem != null) { + itemStack = randomizerBagItem.pickRandomStack(bagInventory); blockState = BuildModifiers .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3(0, 0, 0), InteractionHand.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 f34602c..2564f42 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java @@ -17,7 +17,7 @@ import net.minecraft.world.level.Level; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.InventoryHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; -import nl.requios.effortlessbuilding.item.RandomizerBagItem; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import nl.requios.effortlessbuilding.render.BlockPreviewRenderer; import java.util.ArrayList; @@ -29,7 +29,7 @@ public class BuildModifiers { //Called from BuildModes public static void onBlockPlaced(Player player, List startCoordinates, Direction sideHit, Vec3 hitVec, boolean placeStartPos) { Level world = player.level; - RandomizerBagItem.renewRandomness(); + AbstractRandomizerBagItem.renewRandomness(); //Format hitvec to 0.x hitVec = new Vec3(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z))); @@ -192,7 +192,7 @@ public class BuildModifiers { ItemStack itemBlock = ItemStack.EMPTY; if (itemStack.getItem() instanceof BlockItem) itemBlock = itemStack; else itemBlock = CompatHelper.getItemBlockFromStack(itemStack); - RandomizerBagItem.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 c764ce9..1e358b1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java @@ -9,7 +9,7 @@ import net.minecraft.world.InteractionHand; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.RandomizerBagItem; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import java.util.ArrayList; import java.util.List; @@ -70,9 +70,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 RandomizerBagItem) { - bagInventory = RandomizerBagItem.getBagInventory(itemStack); + if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { + randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem() ; + bagInventory = randomizerBagItem.getBagInventory(itemStack); } if (m.mirrorX) @@ -93,7 +95,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = RandomizerBagItem.pickRandomStack(bagInventory); + itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3(0, 0, 0), hand); } @@ -118,7 +120,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = RandomizerBagItem.pickRandomStack(bagInventory); + itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3(0, 0, 0), hand); } @@ -141,7 +143,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { - itemStack = RandomizerBagItem.pickRandomStack(bagInventory); + itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3(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 6ae0939..eabe117 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.core.BlockPos; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.RandomizerBagItem; +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 RandomizerBagItem) { - bagInventory = RandomizerBagItem.getBagInventory(itemStack); + if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { + randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem() ; + bagInventory = randomizerBagItem.getBagInventory(itemStack); } BlockState newBlockState; @@ -95,8 +97,8 @@ public class RadialMirror { coordinates.add(newBlockPos); //Randomizer bag synergy - if (bagInventory != null) { - itemStack = RandomizerBagItem.pickRandomStack(bagInventory); + if (randomizerBagItem != null) { + itemStack = randomizerBagItem.pickRandomStack(bagInventory); newBlockState = BuildModifiers .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3(0, 0, 0), InteractionHand.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 0a99d23..9c44516 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java @@ -8,13 +8,16 @@ 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.RandomizerBagItem; import javax.annotation.Nonnull; import javax.annotation.Nullable; public class ItemHandlerCapabilityProvider implements ICapabilitySerializable { - IItemHandler itemHandler = new ItemStackHandler(RandomizerBagItem.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 a8a6a3a..ce9a918 100644 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java @@ -9,7 +9,7 @@ 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.RandomizerBagItem; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; public class CompatHelper { //TODO 1.13 compatibility @@ -40,7 +40,7 @@ public class CompatHelper { Item item = stack.getItem(); if (item instanceof BlockItem) return true; - return item instanceof RandomizerBagItem; + return item instanceof AbstractRandomizerBagItem; //TODO 1.13 compatibility // if (item == dankNullItem) // return true; @@ -55,11 +55,11 @@ public class CompatHelper { return proxy; //Randomizer Bag - if (proxyItem instanceof RandomizerBagItem) { + if (proxyItem instanceof AbstractRandomizerBagItem) { ItemStack itemStack = proxy; while (!(itemStack.getItem() instanceof BlockItem || itemStack.isEmpty())) { - if (itemStack.getItem() instanceof RandomizerBagItem) - itemStack = RandomizerBagItem.pickRandomStack(RandomizerBagItem.getBagInventory(itemStack)); + if (itemStack.getItem() instanceof AbstractRandomizerBagItem randomizerBagItem) + itemStack = randomizerBagItem.pickRandomStack(randomizerBagItem.getBagInventory(itemStack)); } return itemStack; } @@ -82,9 +82,9 @@ public class CompatHelper { Item blockItem = Item.byBlock(state.getBlock()); if (stack.getItem() instanceof BlockItem) return stack; - else if (stack.getItem() instanceof RandomizerBagItem) { - IItemHandler bagInventory = RandomizerBagItem.getBagInventory(stack); - return RandomizerBagItem.findStack(bagInventory, blockItem); + else if (stack.getItem() instanceof AbstractRandomizerBagItem randomizerBagItem) { + IItemHandler bagInventory = randomizerBagItem.getBagInventory(stack); + return randomizerBagItem.findStack(bagInventory, blockItem); } //TODO 1.13 compatibility // else if (stack.getItem() == dankNullItem) { 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..8e4c50c --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagContainer.java @@ -0,0 +1,148 @@ +package nl.requios.effortlessbuilding.gui; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +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 AbstractContainerMenu { + + 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(MenuType type, int id){ + super(type, id); + bagInventory = null; + } + + //Client + public DiamondRandomizerBagContainer(int id, Inventory playerInventory, FriendlyByteBuf packetBuffer) { + this(id, playerInventory); + } + + //Server? + public DiamondRandomizerBagContainer(int containerId, Inventory playerInventory) { + this(containerId, playerInventory, new ItemStackHandler(DiamondRandomizerBagItem.INV_SIZE)); + } + + public DiamondRandomizerBagContainer(int containerId, Inventory 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(Player 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(Player 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 + */ + @Override + public void clicked(int slot, int dragType, ClickType clickTypeIn, Player 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(InteractionHand.MAIN_HAND))) { + //Do nothing; + return; + } + super.clicked(slot, dragType, clickTypeIn, player); + } + + /** + * Callback for when the crafting gui is closed. + */ + @Override + public void removed(Player 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..520623f --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java @@ -0,0 +1,49 @@ +package nl.requios.effortlessbuilding.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +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 AbstractContainerScreen { + private Inventory inventory; + + private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/diamondrandomizerbag.png"); + + public DiamondRandomizerBagScreen(DiamondRandomizerBagContainer randomizerBagContainer, Inventory playerInventory, Component title) { + super(randomizerBagContainer, playerInventory, title); + this.inventory = playerInventory; + imageHeight = 167; + } + + @Override + public void render(PoseStack ms, int mouseX, int mouseY, float partialTicks) { + renderBackground(ms); + super.render(ms, mouseX, mouseY, partialTicks); + this.renderTooltip(ms, mouseX, mouseY); + } + + @Override + protected void renderLabels(PoseStack ms, int mouseX, int mouseY) { + this.font.draw(ms, this.title, 8, 6, 0x404040); + this.font.draw(ms, this.playerInventoryTitle, 8, imageHeight - 96 + 2, 0x404040); + } + + @Override + protected void renderBg(PoseStack ms, float partialTicks, int mouseX, int mouseY) { + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1f); + RenderSystem.setShaderTexture(0, 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..cb0e4ff --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagContainer.java @@ -0,0 +1,146 @@ +package nl.requios.effortlessbuilding.gui; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +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 AbstractContainerMenu { + + 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(MenuType type, int id){ + super(type, id); + bagInventory = null; + } + + //Client + public GoldenRandomizerBagContainer(int id, Inventory playerInventory, FriendlyByteBuf packetBuffer) { + this(id, playerInventory); + } + + //Server? + public GoldenRandomizerBagContainer(int containerId, Inventory playerInventory) { + this(containerId, playerInventory, new ItemStackHandler(GoldenRandomizerBagItem.INV_SIZE)); + } + + public GoldenRandomizerBagContainer(int containerId, Inventory 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(Player 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(Player 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 + */ + @Override + public void clicked(int slot, int dragType, ClickType clickTypeIn, Player 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(InteractionHand.MAIN_HAND))) { + //Do nothing; + return; + } + super.clicked(slot, dragType, clickTypeIn, player); + } + + /** + * Callback for when the crafting gui is closed. + */ + @Override + public void removed(Player 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..45a68b7 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java @@ -0,0 +1,49 @@ +package nl.requios.effortlessbuilding.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +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 AbstractContainerScreen { + private Inventory inventory; + + private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/goldenrandomizerbag.png"); + + public GoldenRandomizerBagScreen(GoldenRandomizerBagContainer randomizerBagContainer, Inventory playerInventory, Component title) { + super(randomizerBagContainer, playerInventory, title); + this.inventory = playerInventory; + imageHeight = 134; + } + + @Override + public void render(PoseStack ms, int mouseX, int mouseY, float partialTicks) { + renderBackground(ms); + super.render(ms, mouseX, mouseY, partialTicks); + this.renderTooltip(ms, mouseX, mouseY); + } + + @Override + protected void renderLabels(PoseStack ms, int mouseX, int mouseY) { + this.font.draw(ms, this.title, 8, 6, 0x404040); + this.font.draw(ms, this.playerInventoryTitle, 8, imageHeight - 96 + 2, 0x404040); + } + + @Override + protected void renderBg(PoseStack ms, float partialTicks, int mouseX, int mouseY) { + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1f); + RenderSystem.setShaderTexture(0, 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 08fb7b8..32a6dbc 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java @@ -17,8 +17,10 @@ import nl.requios.effortlessbuilding.item.RandomizerBagItem; public class RandomizerBagContainer extends AbstractContainerMenu { - 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 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(MenuType type, int id){ @@ -45,15 +47,14 @@ public class RandomizerBagContainer extends AbstractContainerMenu { } // 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 AbstractContainerMenu { return ItemStack.EMPTY; } } - } if (itemstack1.getCount() == 0) { @@ -128,6 +128,7 @@ public class RandomizerBagContainer extends AbstractContainerMenu { // 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(InteractionHand.MAIN_HAND))) { //Do nothing; + 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 9da4691..44aa710 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java @@ -17,11 +17,10 @@ import javax.annotation.ParametersAreNonnullByDefault; public class RandomizerBagScreen extends AbstractContainerScreen { private Inventory inventory; - private static final ResourceLocation guiTextures = - new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png"); + private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png"); public RandomizerBagScreen(RandomizerBagContainer randomizerBagContainer, Inventory playerInventory, Component title) { - super(randomizerBagContainer, playerInventory, title);//new TranslationTextComponent("effortlessbuilding.screen.randomizer_bag")); + super(randomizerBagContainer, playerInventory, title); this.inventory = playerInventory; imageHeight = 134; } 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..b5302cd --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java @@ -0,0 +1,230 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.MenuProvider; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.InteractionResult; +import net.minecraft.core.Direction; +import net.minecraft.world.InteractionHand; +import net.minecraft.core.BlockPos; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.level.Level; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.fmllegacy.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.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; + +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.item.context.UseOnContext; + +@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(CreativeModeTab.TAB_TOOLS).stacksTo(1)); + } + + public abstract int getInventorySize(); + + public abstract MenuProvider 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 InteractionResult useOn(UseOnContext ctx) { + Player player = ctx.getPlayer(); + Level world = ctx.getLevel(); + BlockPos pos = ctx.getClickedPos(); + Direction facing = ctx.getClickedFace(); + ItemStack item = ctx.getItemInHand(); + Vec3 hitVec = ctx.getClickLocation(); + + if (player == null) return InteractionResult.FAIL; + + if (ctx.getPlayer() != null && ctx.getPlayer().isShiftKeyDown()) { //ctx.isPlacerSneaking() + if (world.isClientSide) return InteractionResult.SUCCESS; + //Open inventory + NetworkHooks.openGui((ServerPlayer) player, getContainerProvider(item)); + } else { + if (world.isClientSide) return InteractionResult.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 InteractionResult.FAIL; + } + + //Use item + //Get bag inventory + //TODO offhand support + ItemStack bag = player.getItemInHand(InteractionHand.MAIN_HAND); + IItemHandler bagInventory = getBagInventory(bag); + if (bagInventory == null) + return InteractionResult.FAIL; + + ItemStack toPlace = pickRandomStack(bagInventory); + if (toPlace.isEmpty()) return InteractionResult.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); + } + + BlockPlaceContext blockItemUseContext = new BlockPlaceContext(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(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 InteractionResult.SUCCESS; + } + + @Override + public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + ItemStack bag = player.getItemInHand(hand); + + if (player.isShiftKeyDown()) { + if (world.isClientSide) return new InteractionResultHolder<>(InteractionResult.SUCCESS, bag); + //Open inventory + NetworkHooks.openGui((ServerPlayer) player, getContainerProvider(bag)); + } else { + //Use item + //Get bag inventory + IItemHandler bagInventory = getBagInventory(bag); + if (bagInventory == null) + return new InteractionResultHolder<>(InteractionResult.FAIL, bag); + + ItemStack toUse = pickRandomStack(bagInventory); + if (toUse.isEmpty()) return new InteractionResultHolder<>(InteractionResult.FAIL, bag); + + return toUse.use(world, player, hand); + } + return new InteractionResultHolder<>(InteractionResult.PASS, bag); + } + + @Override + public int getUseDuration(ItemStack p_77626_1_) { + return 1; + } + + @Nullable + @Override + public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) { + return new ItemHandlerCapabilityProvider(getInventorySize()); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { + tooltip.add(new TextComponent(ChatFormatting.BLUE + "Rightclick" + ChatFormatting.GRAY + " to place a random block")); + tooltip.add(new TextComponent(ChatFormatting.BLUE + "Sneak + rightclick" + ChatFormatting.GRAY + " to open inventory")); + if (world != null && world.players().size() > 1) { + tooltip.add(new TextComponent(ChatFormatting.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..af762db --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/DiamondRandomizerBagItem.java @@ -0,0 +1,46 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +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 MenuProvider getContainerProvider(ItemStack bag) { + return new ContainerProvider(bag); + } + + public static class ContainerProvider implements MenuProvider { + + private final ItemStack bag; + + public ContainerProvider(ItemStack bag) { + this.bag = bag; + } + + @Override + public Component getDisplayName() { + return new TranslatableComponent("effortlessbuilding:diamond_randomizer_bag"); + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player 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..34dea54 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/item/GoldenRandomizerBagItem.java @@ -0,0 +1,46 @@ +package nl.requios.effortlessbuilding.item; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +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 MenuProvider getContainerProvider(ItemStack bag) { + return new ContainerProvider(bag); + } + + public static class ContainerProvider implements MenuProvider { + + private final ItemStack bag; + + public ContainerProvider(ItemStack bag) { + this.bag = bag; + } + + @Override + public Component getDisplayName() { + return new TranslatableComponent("effortlessbuilding:golden_randomizer_bag"); + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { + return new GoldenRandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag)); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java b/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java index 9180053..c07c5cd 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/RandomizerBagItem.java @@ -1,235 +1,27 @@ package nl.requios.effortlessbuilding.item; -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.MenuProvider; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.InteractionResultHolder; -import net.minecraft.world.InteractionResult; -import net.minecraft.core.Direction; -import net.minecraft.world.InteractionHand; -import net.minecraft.core.BlockPos; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.ChatFormatting; import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.level.Level; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.fmllegacy.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 net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; 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; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.item.context.UseOnContext; - -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class RandomizerBagItem extends Item { +public class RandomizerBagItem extends AbstractRandomizerBagItem { public static final int INV_SIZE = 5; - private static long currentSeed = 1337; - private static final Random rand = new Random(currentSeed); - - public RandomizerBagItem() { - super(new Item.Properties().tab(CreativeModeTab.TAB_TOOLS).stacksTo(1)); - } - - /** - * 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 int getInventorySize() { + return 5; } @Override - public InteractionResult useOn(UseOnContext ctx) { - Player player = ctx.getPlayer(); - Level world = ctx.getLevel(); - BlockPos pos = ctx.getClickedPos(); - Direction facing = ctx.getClickedFace(); - ItemStack item = ctx.getItemInHand(); - Vec3 hitVec = ctx.getClickLocation(); - - if (player == null) return InteractionResult.FAIL; - - if (ctx.getPlayer() != null && ctx.getPlayer().isShiftKeyDown()) { //ctx.isPlacerSneaking() - if (world.isClientSide) return InteractionResult.SUCCESS; - //Open inventory - NetworkHooks.openGui((ServerPlayer) player, new ContainerProvider(item)); - } else { - if (world.isClientSide) return InteractionResult.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 InteractionResult.FAIL; - } - - //Use item - //Get bag inventory - //TODO offhand support - ItemStack bag = player.getItemInHand(InteractionHand.MAIN_HAND); - IItemHandler bagInventory = getBagInventory(bag); - if (bagInventory == null) - return InteractionResult.FAIL; - - ItemStack toPlace = pickRandomStack(bagInventory); - if (toPlace.isEmpty()) return InteractionResult.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); - } - - BlockPlaceContext blockItemUseContext = new BlockPlaceContext(new UseOnContext(player, InteractionHand.MAIN_HAND, new BlockHitResult(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 InteractionResult.SUCCESS; - } - - @Override - public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { - ItemStack bag = player.getItemInHand(hand); - - if (player.isShiftKeyDown()) { - if (world.isClientSide) return new InteractionResultHolder<>(InteractionResult.SUCCESS, bag); - //Open inventory - NetworkHooks.openGui((ServerPlayer) player, new ContainerProvider(bag)); - } else { - //Use item - //Get bag inventory - IItemHandler bagInventory = getBagInventory(bag); - if (bagInventory == null) - return new InteractionResultHolder<>(InteractionResult.FAIL, bag); - - ItemStack toUse = pickRandomStack(bagInventory); - if (toUse.isEmpty()) return new InteractionResultHolder<>(InteractionResult.FAIL, bag); - - return toUse.use(world, player, hand); - } - return new InteractionResultHolder<>(InteractionResult.PASS, bag); - } - - @Override - public int getUseDuration(ItemStack p_77626_1_) { - return 1; - } - - @Nullable - @Override - public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) { - return new ItemHandlerCapabilityProvider(); - } - - @Override - public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { - tooltip.add(new TextComponent(ChatFormatting.BLUE + "Rightclick" + ChatFormatting.GRAY + " to place a random block")); - tooltip.add(new TextComponent(ChatFormatting.BLUE + "Sneak + rightclick" + ChatFormatting.GRAY + " to open inventory")); - if (world != null && world.players().size() > 1) { - tooltip.add(new TextComponent(ChatFormatting.YELLOW + "Experimental on servers: may lose inventory")); - } - } - - @Override - public String getDescriptionId() { - return this.getRegistryName().toString(); + public MenuProvider getContainerProvider(ItemStack bag) { + return new ContainerProvider(bag); } public static class ContainerProvider implements MenuProvider { @@ -242,13 +34,13 @@ public class RandomizerBagItem extends Item { @Override public Component getDisplayName() { - return new TranslatableComponent("effortlessbuilding.screen.randomizer_bag"); + return new TranslatableComponent("effortlessbuilding:randomizer_bag"); } @Nullable @Override public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { - return new RandomizerBagContainer(containerId, playerInventory, RandomizerBagItem.getBagInventory(bag)); + return new RandomizerBagContainer(containerId, playerInventory, ((AbstractRandomizerBagItem)bag.getItem()).getBagInventory(bag)); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index 258ac6b..d4b2d33 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -1,6 +1,5 @@ package nl.requios.effortlessbuilding.proxy; -import com.mojang.blaze3d.platform.ScreenManager; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.world.level.block.state.BlockState; @@ -42,7 +41,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.RandomizerBagContainer; +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; @@ -359,6 +359,8 @@ public class ClientProxy implements IProxy { } MenuScreens.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new); + MenuScreens.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new); + MenuScreens.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new); } public Player getPlayerEntityFromContext(Supplier ctx) { diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java index 232b0ab..be0f083 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.RandomizerBagItem; +import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; 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 - RandomizerBagItem.renewRandomness(); + AbstractRandomizerBagItem.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/resources/assets/effortlessbuilding/lang/en_us.json b/src/main/resources/assets/effortlessbuilding/lang/en_us.json index 3a74bbc..197528f 100644 --- a/src/main/resources/assets/effortlessbuilding/lang/en_us.json +++ b/src/main/resources/assets/effortlessbuilding/lang/en_us.json @@ -1,7 +1,6 @@ { "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", @@ -13,7 +12,9 @@ "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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