diff --git a/.classpath b/.classpath
index 14fe4f12f..f170b8c90 100644
--- a/.classpath
+++ b/.classpath
@@ -2,8 +2,9 @@
-
+
+
diff --git a/build.gradle b/build.gradle
index a8c441323..c8ab1b060 100644
--- a/build.gradle
+++ b/build.gradle
@@ -95,6 +95,19 @@ minecraft {
// 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'
+ // }
+ maven {
+ url = "https://maven.theillusivec4.top/"
+ }
+}
+
def gottschcore_path="../gottsch-minecraft-GottschCore/build/libs/GottschCore-mc${mc_version}-f${gottschcore_forge_version}-v${gottschcore_version}.jar"
println gottschcore_path
dependencies {
@@ -102,7 +115,9 @@ dependencies {
// that the dep is a ForgeGradle 'patcher' dependency. And it's 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:${mc_version}-${forge_version}"
- compile files('../../ModCommonLibs/libs/commons-cli-1.4.jar')
+ runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:1.16.5-4.0.5.2")
+ compileOnly fg.deobf("top.theillusivec4.curios:curios-forge:1.16.5-4.0.5.2:api")
+ //compile files('../../ModCommonLibs/libs/commons-cli-1.4.jar')
compile files(gottschcore_path)
//shadow files(gottschcore_path)
}
diff --git a/gradle.properties b/gradle.properties
index f06fa38a5..5b669fb7e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,22 +1,23 @@
-# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
-# This is required to provide enough memory for the Minecraft decompilation process.
-org.gradle.jvmargs=-Xmx3G
-
-mod_name=Treasure2
-package_group=someguyssoftware.treasure2
-# use alpha, beta, or v (for version)
-mod_version_type=v
-
-mod_version=1.5.1
-
-#versions
-mc_version=1.16.5
-forge_version=36.2.0
-mappings_channel=official
-mappings_version=1.16.5
-gottschcore_version=1.3.0
-gottschcore_forge_version=36.1.0
-
-# paths
-mods_folder=F:/Development/minecraft/mods
-dest_folder=E:/Minecraft/mods/
+# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
+# This is required to provide enough memory for the Minecraft decompilation process.
+org.gradle.jvmargs=-Xmx3G
+
+mod_name=Treasure2
+package_group=someguyssoftware.treasure2
+# use alpha, beta, or v (for version)
+mod_version_type=v
+
+mod_version=1.6.0
+
+
+#versions
+mc_version=1.16.5
+forge_version=36.2.0
+mappings_channel=official
+mappings_version=1.16.5
+gottschcore_version=1.3.0
+gottschcore_forge_version=36.1.0
+
+# paths
+mods_folder=F:/Development/minecraft/mods
+dest_folder=E:/Minecraft/mods/
diff --git a/src/main/java/com/someguyssoftware/treasure2/Treasure.java b/src/main/java/com/someguyssoftware/treasure2/Treasure.java
index 9c3a2ffdf..998264acf 100644
--- a/src/main/java/com/someguyssoftware/treasure2/Treasure.java
+++ b/src/main/java/com/someguyssoftware/treasure2/Treasure.java
@@ -1,158 +1,159 @@
-package com.someguyssoftware.treasure2;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import com.someguyssoftware.gottschcore.annotation.Credits;
-import com.someguyssoftware.gottschcore.annotation.ModInfo;
-import com.someguyssoftware.gottschcore.config.IConfig;
-import com.someguyssoftware.gottschcore.mod.IMod;
-import com.someguyssoftware.treasure2.config.TreasureConfig;
-import com.someguyssoftware.treasure2.entity.TreasureEntities;
-import com.someguyssoftware.treasure2.eventhandler.PlayerEventHandler;
-import com.someguyssoftware.treasure2.eventhandler.WorldEventHandler;
-import com.someguyssoftware.treasure2.init.TreasureSetup;
-import com.someguyssoftware.treasure2.network.TreasureNetworking;
-import com.someguyssoftware.treasure2.particle.TreasureParticles;
-
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.eventbus.api.IEventBus;
-import net.minecraftforge.fml.ModLoadingContext;
-import net.minecraftforge.fml.common.Mod;
-import net.minecraftforge.fml.config.ModConfig;
-import net.minecraftforge.fml.config.ModConfig.ModConfigEvent;
-import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
-import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
-import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
-import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
-import net.minecraftforge.fml.loading.FMLPaths;
-
-/**
- *
- * @author Mark Gottschling on Aug 11, 2020
- *
- */
-@Mod(value = Treasure.MODID)
-@ModInfo(
- modid = Treasure.MODID,
- name = Treasure.NAME,
- version = Treasure.VERSION,
- minecraftVersion = "1.16.5",
- forgeVersion = "36.1.0",
- updateJsonUrl = Treasure.UPDATE_JSON_URL)
-@Credits(values = { "Treasure was first developed by Mark Gottschling on Aug 27, 2014.",
- "Treasure2 was first developed by Mark Gottschling on Jan 2018.",
- "Credits to Mason Gottschling for ideas and debugging.",
- "Credits to CuddleBeak for some Keys and Locks textures.",
- "Credits to mn_ti for Chinese and to DarkKnightComes for Polish translation.",
- "Credits to Mythical Sausage for tutorials on house/tower designs.",
- "Credits to OdinsRagnarok for Spanish translation and DarvinSlav for Russian translation." })
-public class Treasure implements IMod {
- // logger
- public static Logger LOGGER = LogManager.getLogger(Treasure.NAME);
-
- // constants
- public static final String MODID = "treasure2";
- protected static final String NAME = "Treasure2";
- protected static final String VERSION = "1.5.1";
- protected static final String UPDATE_JSON_URL = "https://raw.githubusercontent.com/gottsch/gottsch-minecraft-Treasure/1.16.5-master/update.json";
-
- public static Treasure instance;
- private static TreasureConfig config;
- public static IEventBus MOD_EVENT_BUS;
-
- public Treasure() {
- Treasure.instance = this;
- Treasure.config = new TreasureConfig(this);
-
- ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, TreasureConfig.COMMON_CONFIG);
-
- TreasureConfig.loadConfig(TreasureConfig.COMMON_CONFIG,
- FMLPaths.CONFIGDIR.get().resolve("treasure2-common.toml"));
-
- // Register the setup method for modloading
- IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();
- // deferred register
- TreasureParticles.PARTICLE_TYPES.register(eventBus);
- // regular register
- eventBus.addListener(this::config);
- eventBus.addListener(TreasureNetworking::common);
- eventBus.addListener(TreasureSetup::common);
- eventBus.addListener(this::clientSetup);
-
- // needs to be registered here instead of @Mod.EventBusSubscriber because we need to pass in a constructor argument
- MinecraftForge.EVENT_BUS.register(new WorldEventHandler(getInstance()));
- MinecraftForge.EVENT_BUS.register(new PlayerEventHandler());
-// MinecraftForge.EVENT_BUS.register(new TreasureParticles());
-// MOD_EVENT_BUS.register(TreasureParticles.class);
-// DistExecutor.runWhenOn(Dist.CLIENT, () -> Treasure::clientOnly);
- }
-
- public static void clientOnly() {
-
- }
-
- private void clientSetup(final FMLClientSetupEvent event) {
- Treasure.LOGGER.info("in client setup event");
- TreasureEntities.registerEntityRenderers();
- }
-
- private void postSetup(final FMLLoadCompleteEvent event) {
- Treasure.LOGGER.info("in post setup event");
- }
-
- private void config(final ModConfigEvent evt) {
- Treasure.LOGGER.info("in config event");
- }
-
- private void onServerStarted(final FMLDedicatedServerSetupEvent event) {
- Treasure.LOGGER.info("in onServerStarted");
- }
-
-// /**
-// *
-// */
-// @EventHandler
-// public void postInit(FMLPostInitializationEvent event) {
-// if (!getConfig().isModEnabled())
-// return;
-//
-// // perform any post init
-// super.postInit(event);
-//
-// // associate painting items to painting blocks and vice versa
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_BRICKS).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_BRICKS);
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_COBBLESTONE)
-// .setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_COBBLESTONE);
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_DIRT).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_DIRT);
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_LAVA).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_LAVA);
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_SAND).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_SAND);
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_WATER).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_WATER);
-// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_WOOD).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_WOOD);
-//
-// TreasureBlocks.PAINTING_BLOCKS_BRICKS.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_BRICKS);
-// TreasureBlocks.PAINTING_BLOCKS_COBBLESTONE.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_COBBLESTONE);
-// TreasureBlocks.PAINTING_BLOCKS_DIRT.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_DIRT);
-// TreasureBlocks.PAINTING_BLOCKS_LAVA.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_LAVA);
-// TreasureBlocks.PAINTING_BLOCKS_SAND.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_SAND);
-// TreasureBlocks.PAINTING_BLOCKS_WATER.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_WATER);
-// TreasureBlocks.PAINTING_BLOCKS_WOOD.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_WOOD);
-
-
-
- @Override
- public IMod getInstance() {
- return Treasure.instance;
- }
-
- @Override
- public String getId() {
- return Treasure.MODID;
- }
-
- @Override
- public IConfig getConfig() {
- return Treasure.config;
- }
-
-}
+package com.someguyssoftware.treasure2;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.someguyssoftware.gottschcore.annotation.Credits;
+import com.someguyssoftware.gottschcore.annotation.ModInfo;
+import com.someguyssoftware.gottschcore.config.IConfig;
+import com.someguyssoftware.gottschcore.mod.IMod;
+import com.someguyssoftware.treasure2.charm.TreasureCharms;
+import com.someguyssoftware.treasure2.config.TreasureConfig;
+import com.someguyssoftware.treasure2.entity.TreasureEntities;
+import com.someguyssoftware.treasure2.eventhandler.PlayerEventHandler;
+import com.someguyssoftware.treasure2.eventhandler.WorldEventHandler;
+import com.someguyssoftware.treasure2.init.TreasureSetup;
+import com.someguyssoftware.treasure2.network.TreasureNetworking;
+import com.someguyssoftware.treasure2.particle.TreasureParticles;
+
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.eventbus.api.IEventBus;
+import net.minecraftforge.fml.ModLoadingContext;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.config.ModConfig;
+import net.minecraftforge.fml.config.ModConfig.ModConfigEvent;
+import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
+import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
+import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import net.minecraftforge.fml.loading.FMLPaths;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 11, 2020
+ *
+ */
+@Mod(value = Treasure.MODID)
+@ModInfo(
+ modid = Treasure.MODID,
+ name = Treasure.NAME,
+ version = Treasure.VERSION,
+ minecraftVersion = "1.16.5",
+ forgeVersion = "36.1.0",
+ updateJsonUrl = Treasure.UPDATE_JSON_URL)
+@Credits(values = { "Treasure was first developed by Mark Gottschling on Aug 27, 2014.",
+ "Treasure2 was first developed by Mark Gottschling on Jan 2018.",
+ "Credits to Mason Gottschling for ideas and debugging.",
+ "Credits to CuddleBeak for some Keys and Locks textures.",
+ "Credits to mn_ti for Chinese and to DarkKnightComes for Polish translation.",
+ "Credits to Mythical Sausage for tutorials on house/tower designs.",
+ "Credits to OdinsRagnarok for Spanish translation and DarvinSlav for Russian translation." })
+public class Treasure implements IMod {
+ // logger
+ public static Logger LOGGER = LogManager.getLogger(Treasure.NAME);
+
+ // constants
+ public static final String MODID = "treasure2";
+ protected static final String NAME = "Treasure2";
+ protected static final String VERSION = "1.6.0";
+
+ protected static final String UPDATE_JSON_URL = "https://raw.githubusercontent.com/gottsch/gottsch-minecraft-Treasure/1.16.5-master/update.json";
+
+ public static Treasure instance;
+ private static TreasureConfig config;
+ public static IEventBus MOD_EVENT_BUS;
+
+ public Treasure() {
+ Treasure.instance = this;
+ Treasure.config = new TreasureConfig(this);
+
+ ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, TreasureConfig.COMMON_CONFIG);
+
+ TreasureConfig.loadConfig(TreasureConfig.COMMON_CONFIG,
+ FMLPaths.CONFIGDIR.get().resolve("treasure2-common.toml"));
+
+ // Register the setup method for modloading
+ IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();
+ // deferred register
+ TreasureParticles.PARTICLE_TYPES.register(eventBus);
+ // regular register
+ eventBus.addListener(this::config);
+ eventBus.addListener(TreasureNetworking::common);
+ eventBus.addListener(TreasureSetup::common);
+ eventBus.addListener(TreasureCharms::setup);
+ eventBus.addListener(TreasureSetup::clientSetup);
+ eventBus.addListener(this::clientSetup);
+
+ // needs to be registered here instead of @Mod.EventBusSubscriber because we need to pass in a constructor argument
+ MinecraftForge.EVENT_BUS.register(new WorldEventHandler(getInstance()));
+ MinecraftForge.EVENT_BUS.register(new PlayerEventHandler()); // need to register here?
+ }
+
+ public static void clientOnly() {
+
+ }
+
+ private void clientSetup(final FMLClientSetupEvent event) {
+ Treasure.LOGGER.info("in client setup event");
+ TreasureEntities.registerEntityRenderers();
+ }
+
+ private void postSetup(final FMLLoadCompleteEvent event) {
+ Treasure.LOGGER.info("in post setup event");
+ }
+
+ private void config(final ModConfigEvent evt) {
+ Treasure.LOGGER.info("in config event");
+ }
+
+ private void onServerStarted(final FMLDedicatedServerSetupEvent event) {
+ Treasure.LOGGER.info("in onServerStarted");
+ }
+
+// /**
+// *
+// */
+// @EventHandler
+// public void postInit(FMLPostInitializationEvent event) {
+// if (!getConfig().isModEnabled())
+// return;
+//
+// // perform any post init
+// super.postInit(event);
+//
+// // associate painting items to painting blocks and vice versa
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_BRICKS).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_BRICKS);
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_COBBLESTONE)
+// .setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_COBBLESTONE);
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_DIRT).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_DIRT);
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_LAVA).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_LAVA);
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_SAND).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_SAND);
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_WATER).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_WATER);
+// ((PaintingItem) TreasureItems.PAINTING_BLOCKS_WOOD).setPaintingBlock(TreasureBlocks.PAINTING_BLOCKS_WOOD);
+//
+// TreasureBlocks.PAINTING_BLOCKS_BRICKS.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_BRICKS);
+// TreasureBlocks.PAINTING_BLOCKS_COBBLESTONE.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_COBBLESTONE);
+// TreasureBlocks.PAINTING_BLOCKS_DIRT.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_DIRT);
+// TreasureBlocks.PAINTING_BLOCKS_LAVA.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_LAVA);
+// TreasureBlocks.PAINTING_BLOCKS_SAND.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_SAND);
+// TreasureBlocks.PAINTING_BLOCKS_WATER.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_WATER);
+// TreasureBlocks.PAINTING_BLOCKS_WOOD.setItem((PaintingItem) TreasureItems.PAINTING_BLOCKS_WOOD);
+
+
+
+ @Override
+ public IMod getInstance() {
+ return Treasure.instance;
+ }
+
+ @Override
+ public String getId() {
+ return Treasure.MODID;
+ }
+
+ @Override
+ public IConfig getConfig() {
+ return Treasure.config;
+ }
+
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/block/TreasureBlocks.java b/src/main/java/com/someguyssoftware/treasure2/block/TreasureBlocks.java
index 268ef86b9..69a13387f 100644
--- a/src/main/java/com/someguyssoftware/treasure2/block/TreasureBlocks.java
+++ b/src/main/java/com/someguyssoftware/treasure2/block/TreasureBlocks.java
@@ -142,6 +142,8 @@ public class TreasureBlocks {
public static Block WITHER_PLANKS;
public static Block SPANISH_MOSS;
+ public static Block TOPAZ_ORE;
+ public static Block ONYX_ORE;
public static Block RUBY_ORE;
public static Block SAPPHIRE_ORE;
@@ -410,6 +412,10 @@ public static void registerBlocks(RegistryEvent.Register event) {
.strength(3.0F).sound(SoundType.STONE));
// ORES
+ TOPAZ_ORE = new TreasureOreBlock(Treasure.MODID, TreasureConfig.BlockID.TOPAZ_ORE_ID, Block.Properties.of(Material.STONE, MaterialColor.STONE)
+ .strength(3.0F, 5.0F).harvestLevel(3));
+ ONYX_ORE = new TreasureOreBlock(Treasure.MODID, TreasureConfig.BlockID.ONYX_ORE_ID, Block.Properties.of(Material.STONE, MaterialColor.STONE)
+ .strength(3.0F, 5.0F).harvestLevel(3));
RUBY_ORE = new TreasureOreBlock(Treasure.MODID, TreasureConfig.BlockID.RUBY_ORE_ID, Block.Properties.of(Material.STONE, MaterialColor.STONE)
.strength(3.0F, 5.0F).harvestLevel(3));
SAPPHIRE_ORE = new TreasureOreBlock(Treasure.MODID, TreasureConfig.BlockID.SAPPHIRE_ORE_ID, Block.Properties.of(Material.STONE, MaterialColor.STONE)
@@ -499,6 +505,8 @@ public static void registerBlocks(RegistryEvent.Register event) {
BLOCKS.add(SKULL_CROSSBONES);
BLOCKS.add(WISHING_WELL_BLOCK);
BLOCKS.add(DESERT_WISHING_WELL_BLOCK);
+ BLOCKS.add(TOPAZ_ORE);
+ BLOCKS.add(ONYX_ORE);
BLOCKS.add(RUBY_ORE);
BLOCKS.add(SAPPHIRE_ORE);
BLOCKS.add(WITHER_BROKEN_LOG);
diff --git a/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapability.java b/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapability.java
index f4c33a1e8..eeef6c8cc 100644
--- a/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapability.java
+++ b/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapability.java
@@ -1,32 +1,548 @@
-/**
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
*
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
*/
package com.someguyssoftware.treasure2.capability;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.charm.CharmableMaterial;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+import com.someguyssoftware.treasure2.charm.TreasureCharms;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+
/**
+ * The CharmableCapability provides any item with a Charm Inventory, which is a datatype of Map, List>.
+ * The Charm Inventory can support three types: INNATE, IMBUE or SOCKET.
+ * INNATE - Charms that are added on Item spawn and can not be renewed. Once expired, the charm is removed and the space is decremented.
+ * IMBUE - Charms that can be added via Books, or any IMBUING item.
+ * SOCKET - Charms that can be added to sockets via Coins or Gems, or any BINDING item.
* @author Mark Gottschling on Apr 27, 2020
*
*/
public class CharmableCapability implements ICharmableCapability {
-// private List charmInstances = new ArrayList<>(3);
-
+ /*
+ * Properties that refer to the Item that has this capability
+ */
+ @SuppressWarnings("unchecked")
+ ArrayList[] charmEntities = (ArrayList[])new ArrayList[3];
+ // is this item a charm source/originator ie. not an adornment or an item that is imbued or socketed with a charm
+ private boolean source;
+ // can this item cast/execute its charms
+ private boolean executing;
+ // is this item bindable to a target item that is socketable
+ private boolean bindable;
+ // does this item have sockets - accepts bindable items
+ private boolean socketable;
+ // can this item imbue atarget item
+ private boolean imbuing;
+ // can this item be imbued
+ private boolean imbuable;
+ // does this item have "built-in" innate charms
+ private boolean innate;
+
+ // the base material this item is made of
+ private ResourceLocation baseMaterial;
+ // the item that this capability belongs to
+ private ResourceLocation sourceItem;
+ // the current charm with the highest level
+ private ICharmEntity highestLevel;
+
+ /*
+ * Propeties that refer to the Charm Inventory the the Item that has this capability
+ */
+ private int maxSocketsSize;
+ private int maxImbueSize;
+ private int maxInnateSize;
+
+
/**
*
*/
public CharmableCapability() {
+ init();
}
-
-// @Override
-// public List getCharmInstances() {
-// if (charmInstances == null) {
-// this.charmInstances = new ArrayList<>(3);
+
+ /**
+ *
+ * @param builder
+ */
+ public CharmableCapability(Builder builder) {
+ this();
+ this.source = builder.source;
+ this.executing = builder.executing;
+ this.bindable = builder.bindable;
+ this.innate = builder.innate;
+ this.maxInnateSize = innate ? Math.max(1, builder.maxInnateSize) : 0;
+ this.imbuable = builder.imbuable;
+ this.maxImbueSize = imbuable ? Math.max(1, builder.maxImbueSize) : 0;
+ this.socketable = builder.socketable;
+ this.maxSocketsSize = socketable ? Math.max(1, builder.maxSocketsSize) : 0;
+ this.baseMaterial = builder.baseMaterial;
+ this.sourceItem = builder.sourceItem;
+ }
+
+ /**
+ *
+ */
+ protected void init() {
+ charmEntities[InventoryType.INNATE.value] = new ArrayList<>(1);
+ charmEntities[InventoryType.IMBUE.value] = new ArrayList<>(1);
+ charmEntities[InventoryType.SOCKET.value] = new ArrayList<>(1);
+ }
+
+ /**
+ * Convenience method.
+ * @param type
+ * @param entity
+ */
+ @Override
+ public void add(InventoryType type, ICharmEntity entity) {
+ // test if the level of charm item/cap is >= entity.level; else return
+// if (entity.getCharm().getLevel() > this.getMaxCharmLevel()) {
+// Treasure.LOGGER.debug("supplied charm entity has a greater level than the max allowed");
+// return;
// }
-// return charmInstances;
-// }
-//
-// @Override
-// public void setCharmInstances(List instances) {
-// this.charmInstances = instances;
-//
-// }
+
+ // test if there is enough space to add
+ // Treasure.LOGGER.debug("adding type -> {} charm -> {}", type, entity.getCharm());
+ if (charmEntities[type.value].size() < getMaxSize(type)) {
+ charmEntities[type.value].add(entity);
+
+ // record highest level charm
+ if (highestLevel == null || entity.getCharm().getLevel() > highestLevel.getCharm().getLevel()) {
+ highestLevel = entity;
+ }
+ }
+ // Treasure.LOGGER.debug("ther are {} type -> {} charms", charmEntities[type.value].size(), type);
+ }
+
+ public void remove(InventoryType type, ICharmEntity entity) {
+ // STUB
+ }
+
+ /**
+ *
+ * @param type
+ * @param index
+ */
+ @Override
+ public void remove(InventoryType type, int index) {
+ getCharmEntities()[type.getValue()].remove(index);
+ // recalc highest level
+ highestLevel = null;
+ getAllCharmEntities().forEach(entity -> {
+ if (highestLevel == null || entity.getCharm().getLevel() > highestLevel.getCharm().getLevel()) {
+ highestLevel = entity;
+ }
+ });
+ }
+
+ /**
+ *
+ * @param charm
+ * @return
+ */
+ @Override
+ public boolean contains(ICharm charm) {
+ for (ICharmEntity entity : getAllCharmEntities()) {
+ if (entity.getCharm().getType().equalsIgnoreCase(charm.getType()) ||
+ entity.getCharm().getName().equals(charm.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public List getAllCharmEntities() {
+ return Stream.of(charmEntities[InventoryType.INNATE.value], charmEntities[InventoryType.IMBUE.value], charmEntities[InventoryType.SOCKET.value])
+ .flatMap(x -> x.stream())
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Convenience method
+ * @param type
+ * @return
+ */
+ @Override
+ public int getMaxSize(InventoryType type) {
+ // check against SOCKET first as this will be the most common
+ return (type == InventoryType.SOCKET ? getMaxSocketsSize() : type == InventoryType.IMBUE ? getMaxImbueSize() : getMaxInnateSize());
+ }
+
+ @Override
+ public boolean isCharmed() {
+ int size = 0;
+ for (List list : charmEntities) {
+ if (list != null) {
+ size += list.size();
+ }
+ }
+ if (size > 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int getMaxCharmLevel() {
+ Optional base = TreasureCharms.getBaseMaterial(baseMaterial);
+ Optional source = TreasureCharms.getSourceItem(sourceItem);
+ CharmableMaterial effectiveBase = base.isPresent() ? base.get() : TreasureCharms.COPPER;
+ return effectiveBase.getMaxLevel() + (int) Math.floor(effectiveBase.getLevelMultiplier() * (source.isPresent() ? source.get().getMaxLevel() : 0));
+ }
+
+ @Override
+ public void appendHoverText(ItemStack stack, World world, List tooltip, ITooltipFlag flag) {
+// tooltip.add(new TranslationTextComponent("tooltip.charmable.usage").withStyle(TextFormatting.GOLD, TextFormatting.ITALIC));
+ tooltip.add(new TranslationTextComponent("tooltip.label.charms").withStyle(TextFormatting.YELLOW, TextFormatting.BOLD));
+
+ // create header text for inventory type
+ appendHoverText(stack, world, tooltip, flag, InventoryType.INNATE, false);
+ appendHoverText(stack, world, tooltip, flag, InventoryType.IMBUE, true);
+ appendHoverText(stack, world, tooltip, flag, InventoryType.SOCKET, true);
+ }
+
+ /**
+ *
+ * @param stack
+ * @param world
+ * @param tooltip
+ * @param flag
+ * @param inventoryType
+ * @param titleFlag
+ */
+ private void appendHoverText(ItemStack stack, World world, List tooltip, ITooltipFlag flag, InventoryType inventoryType, boolean titleFlag) {
+ List entityList = getCharmEntities()[inventoryType.value];
+ if (entityList != null && !entityList.isEmpty()) {
+ // add title
+ if (titleFlag) {
+ TextFormatting color = inventoryType == InventoryType.SOCKET ? TextFormatting.BLUE : TextFormatting.DARK_RED;
+ tooltip.add(
+ new TranslationTextComponent("tooltip.label.charm.type." + inventoryType.name().toLowerCase()).withStyle(color)
+ .append(getCapacityHoverText(stack, world, entityList).withStyle(TextFormatting.WHITE))
+ );
+ }
+ // add charms
+ for (ICharmEntity entity : entityList) {
+ entity.getCharm().appendHoverText(stack, world, tooltip, flag, entity);
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void appendCapacityHoverText(ItemStack stack, World world, List tooltip, ITooltipFlag flag, List entities) {
+
+ // tooltip.add(new TranslationTextComponent("tooltip.charmable.slots").withStyle(TextFormatting.GRAY));
+ tooltip.add(new TranslationTextComponent("tooltip.charmable.slots",
+ String.valueOf(Math.toIntExact(Math.round(entities.size()))), // used
+ String.valueOf(Math.toIntExact(Math.round(this.maxSocketsSize)))) // max
+ .withStyle(TextFormatting.WHITE));
+ }
+
+ @SuppressWarnings("deprecation")
+ public TranslationTextComponent getCapacityHoverText(ItemStack stack, World world, List entities) {
+ return new TranslationTextComponent("tooltip.charmable.slots",
+ String.valueOf(Math.toIntExact(Math.round(entities.size()))), // used
+ String.valueOf(Math.toIntExact(Math.round(this.maxSocketsSize)))); // max
+ }
+
+ @Override
+ // TODO need to rename to getCharmEntityLists()
+ public List[] getCharmEntities() {
+ if (charmEntities == null) {
+ this.charmEntities = (ArrayList[])new ArrayList[3];
+ }
+ return charmEntities;
+ }
+
+ @Override
+ public void setCharmEntities(List[] entities) {
+ this.charmEntities = (ArrayList[]) entities;
+ }
+
+ // TODO probably could use a rename
+ @Override
+ public boolean isSource() {
+ return source;
+ }
+
+ @Override
+ public void setSource(boolean source) {
+ this.source = source;
+ }
+
+ @Override
+ public boolean isBindable() {
+ return bindable;
+ }
+
+ @Override
+ public void setBindable(boolean bindable) {
+ this.bindable = bindable;
+ }
+
+ @Override
+ public boolean isSocketable() {
+ return socketable;
+ }
+
+ @Override
+ public void setSocketable(boolean socketable) {
+ this.socketable = socketable;
+ }
+
+ @Override
+ public boolean isImbuing() {
+ return imbuing;
+ }
+
+ @Override
+ public void setImbuing(boolean imbuing) {
+ this.imbuing = imbuing;
+ }
+
+ @Override
+ public boolean isImbuable() {
+ return imbuable;
+ }
+
+ @Override
+ public void setImbuable(boolean imbuable) {
+ this.imbuable = imbuable;
+ }
+
+ @Override
+ public boolean isInnate() {
+ return innate;
+ }
+
+ @Override
+ public void setInnate(boolean innate) {
+ this.innate = innate;
+ }
+
+ @Override
+ public int getMaxInnateSize() {
+ return maxInnateSize;
+ }
+
+ @Override
+ public int getMaxSocketsSize() {
+ return maxSocketsSize;
+ }
+
+ @Override
+ public int getMaxImbueSize() {
+ return maxImbueSize;
+ }
+
+ @Override
+ public void setMaxSocketsSize(int maxSocketsSize) {
+ this.maxSocketsSize = maxSocketsSize;
+ }
+
+ @Override
+ public void setMaxImbueSize(int maxImbueSize) {
+ this.maxImbueSize = maxImbueSize;
+ }
+
+ @Override
+ public void setMaxInnateSize(int maxInnateSize) {
+ this.maxInnateSize = maxInnateSize;
+ }
+
+ @Override
+ public ResourceLocation getBaseMaterial() {
+ return baseMaterial;
+ }
+
+ @Override
+ public void setBaseMaterial(ResourceLocation baseMaterial) {
+ this.baseMaterial = baseMaterial;
+ }
+
+ @Override
+ public ResourceLocation getSourceItem() {
+ return sourceItem;
+ }
+ @Override
+ public void setSourceItem(ResourceLocation sourceItem) {
+ this.sourceItem = sourceItem;
+ }
+
+ @Override
+ public boolean isExecuting() {
+ return executing;
+ }
+
+ @Override
+ public void setExecuting(boolean executing) {
+ this.executing = executing;
+ }
+
+ /**
+ *
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+ public enum InventoryType {
+ INNATE(0),
+ IMBUE(1),
+ SOCKET(2);
+
+ private static final Map values = new HashMap();
+ Integer value;
+
+ // setup reverse lookup
+ static {
+ for (InventoryType x : EnumSet.allOf(InventoryType.class)) {
+ values.put(x.getValue(), x);
+ }
+ }
+
+ InventoryType(Integer value) {
+ this.value = value;
+ }
+
+ public Integer getValue() {
+ return value;
+ }
+
+ /**
+ *
+ * @param value
+ * @return
+ */
+ public static InventoryType getByValue(Integer value) {
+ return (InventoryType) values.get(value);
+ }
+ }
+
+ /**
+ *
+ * @author Mark Gottschling on Aug 16, 2021
+ *
+ */
+ public static class Builder {
+ public boolean source;
+ public boolean executing = true;
+ public boolean bindable;
+ public boolean socketable;
+ public boolean imbuing;
+ public boolean imbuable;
+ public boolean innate;
+
+ public ResourceLocation baseMaterial = TreasureCharms.COPPER.getName();
+
+ // required property
+ public ResourceLocation sourceItem;
+
+ public int maxSocketsSize;
+ public int maxImbueSize;
+ public int maxInnateSize;
+
+ // required to pass the source Item here
+ public Builder(ResourceLocation sourceItem) {
+ this.sourceItem = sourceItem;
+ }
+
+ public Builder with(Consumer builder) {
+ builder.accept(this);
+ return this;
+ }
+
+ public Builder source(boolean source) {
+ this.source = source;
+ return this;
+ }
+
+ public Builder executing(boolean executing) {
+ this.executing = executing;
+ return this;
+ }
+
+ public Builder bindable(boolean bindable) {
+ this.bindable = bindable;
+ return this;
+ }
+
+ public Builder socketable(boolean socketable, int size) {
+ this.socketable = socketable;
+ this.maxSocketsSize = size;
+ return this;
+ }
+
+ public Builder innate(boolean innate, int size) {
+ this.innate = innate;
+ this.maxInnateSize = size;
+ return this;
+ }
+
+ public Builder imbue(boolean imbue, int size) {
+ this.imbuable = imbue;
+ this.maxImbueSize = size;
+ return this;
+ }
+
+ public Builder imbuing(boolean imbuing) {
+ this.imbuing = imbuing;
+ return this;
+ }
+
+ public Builder baseMaterial(ResourceLocation material) {
+ this.baseMaterial = material;
+ return this;
+ }
+
+ public ICharmableCapability build() {
+ // calculate the max charm level based on baseMaterial and the source item.
+ // Treasure.LOGGER.debug("charm source item -> {}", sourceItem);
+ // Optional level = TreasureCharms.getCharmLevel(sourceItem);
+ // this.maxCharmLevel = baseMaterial.getMaxLevel() + (level.isPresent() ? level.get() : 0) ;
+ return new CharmableCapability(this);
+ }
+ }
+
+ @Override
+ public ICharmEntity getHighestLevel() {
+ return highestLevel;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapabilityProvider.java b/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapabilityProvider.java
new file mode 100644
index 000000000..c350f1635
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapabilityProvider.java
@@ -0,0 +1,50 @@
+package com.someguyssoftware.treasure2.capability;
+
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.CHARMABLE;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.Direction;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.common.capabilities.ICapabilityProvider;
+import net.minecraftforge.common.capabilities.ICapabilitySerializable;
+import net.minecraftforge.common.util.LazyOptional;
+
+public class CharmableCapabilityProvider implements ICapabilityProvider, ICapabilitySerializable {
+
+ // capabilities for item
+ private final ICharmableCapability instance;// = new CharmableCapability();
+
+ /**
+ *
+ */
+ public CharmableCapabilityProvider() {
+ instance = new CharmableCapability();
+ }
+
+ /**
+ *
+ * @param capability
+ */
+ public CharmableCapabilityProvider(ICharmableCapability capability) {
+ instance = capability;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public LazyOptional getCapability(Capability capability, Direction side) {
+ if (capability == CHARMABLE) {
+ return (LazyOptional) LazyOptional.of(() -> instance);
+ }
+ return LazyOptional.empty();
+ }
+
+ @Override
+ public CompoundNBT serializeNBT() {
+ CompoundNBT tag = (CompoundNBT)CHARMABLE.getStorage().writeNBT(CHARMABLE, instance, null);
+ return tag;
+ }
+
+ @Override
+ public void deserializeNBT(CompoundNBT nbt) {
+ CHARMABLE.getStorage().readNBT(CHARMABLE, instance, null, nbt);
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapabilityStorage.java b/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapabilityStorage.java
new file mode 100644
index 000000000..d23fda82e
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/capability/CharmableCapabilityStorage.java
@@ -0,0 +1,191 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.capability;
+
+import java.util.List;
+import java.util.Optional;
+
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.charm.BaseMaterial2;
+import com.someguyssoftware.treasure2.charm.Charm;
+import com.someguyssoftware.treasure2.charm.CharmableMaterial;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+import com.someguyssoftware.treasure2.charm.TreasureCharms;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.INBT;
+import net.minecraft.nbt.ListNBT;
+import net.minecraft.util.Direction;
+import net.minecraftforge.common.capabilities.Capability;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 14, 2021
+ *
+ */
+public class CharmableCapabilityStorage implements Capability.IStorage {
+
+ private static final String SOURCE = "source";
+ private static final String EXECUTING = "executing";
+ private static final String BINDABLE = "bindable";
+ private static final String INNATE = "innate";
+ private static final String MAX_INNATE_SIZE = "maxInnateSize";
+ private static final String IMBUABLE = "imbuable";
+ private static final String IMBUING = "imbuing";
+ private static final String MAX_IMBUE_SIZE = "maxImbueSize";
+ private static final String SOCKETABLE = "socketable";
+ private static final String SOCKETING = "socketing";
+ private static final String MAX_SOCKET_SIZE = "maxSocketSize";
+ private static final String BASE_MATERIAL = "baseMaterial";
+ private static final String SOURCE_ITEM = "sourceItem";
+ private static final String MAX_CHARM_LEVEL = "maxCharmLevel";
+ private static final String CHARM = "charm";
+
+ @Override
+ public INBT writeNBT(Capability capability, ICharmableCapability instance, Direction side) {
+ CompoundNBT nbt = new CompoundNBT();
+ try {
+ /*
+ * save charm cap inventories
+ */
+ // create a new list nbt for each inventory type
+ for (int index = 0; index < instance.getCharmEntities().length; index++) {
+ List entityList = instance.getCharmEntities()[index];
+ if (entityList != null && !entityList.isEmpty()) {
+ ListNBT listNbt = new ListNBT();
+ for (ICharmEntity entity : entityList) {
+ CompoundNBT entityNbt = new CompoundNBT();
+ listNbt.add(entity.save(entityNbt));
+ }
+ nbt.put(InventoryType.getByValue(index).name(), listNbt);
+ }
+ }
+
+ /*
+ * save charm cap properties
+ */
+ nbt.putBoolean(SOURCE, instance.isSource());
+ nbt.putBoolean(EXECUTING, instance.isExecuting());;
+ nbt.putBoolean(BINDABLE, instance.isBindable());
+
+ nbt.putBoolean(INNATE, instance.isInnate());
+ nbt.putInt(MAX_INNATE_SIZE, instance.getMaxInnateSize());
+
+ nbt.putBoolean(IMBUABLE, instance.isImbuable());
+ nbt.putBoolean(IMBUING, instance.isImbuing());
+ nbt.putInt(MAX_IMBUE_SIZE, instance.getMaxImbueSize());
+
+ nbt.putBoolean(SOCKETABLE, instance.isSocketable());
+ nbt.putInt(MAX_SOCKET_SIZE, instance.getMaxSocketsSize());
+ nbt.putString(BASE_MATERIAL, instance.getBaseMaterial().toString());
+ nbt.putString(SOURCE_ITEM, instance.getSourceItem().toString());
+
+ } catch (Exception e) {
+ Treasure.LOGGER.error("Unable to write state to NBT:", e);
+ }
+ return nbt;
+ }
+
+ @Override
+ public void readNBT(Capability capability, ICharmableCapability instance, Direction side,
+ INBT nbt) {
+ if (nbt instanceof CompoundNBT) {
+ CompoundNBT tag = (CompoundNBT) nbt;
+ for (InventoryType type : InventoryType.values()) {
+ // clear the list
+ instance.getCharmEntities()[type.getValue()].clear();
+ /*
+ * load the list
+ */
+ if (tag.contains(type.name())) {
+ ListNBT listNbt = tag.getList(type.name(), 10);
+ listNbt.forEach(e -> {
+ // load the charm
+ Optional charm = Charm.load((CompoundNBT) ((CompoundNBT)e).get(CHARM));
+ if (!charm.isPresent()) {
+ return;
+ }
+ // create an entity
+ ICharmEntity entity = charm.get().createEntity();
+
+ // load entity
+ entity.load((CompoundNBT)e);
+// Optional entity = ICharmEntity.load((CompoundNBT)e);
+// if (!entity.isPresent()) {
+// return;
+// }
+
+ // add the entity to the list
+// instance.getCharmEntities()[type.getValue()].add(entity.get());
+ instance.getCharmEntities()[type.getValue()].add(entity);
+ });
+ }
+
+ // load cap properties
+ if (tag.contains(SOURCE)) {
+ instance.setSource(tag.getBoolean(SOURCE));
+ }
+ if (tag.contains(EXECUTING)) {
+ instance.setExecuting(tag.getBoolean(EXECUTING));
+ }
+
+ if (tag.contains(BINDABLE)) {
+ instance.setBindable(tag.getBoolean(BINDABLE));
+ }
+
+ if (tag.contains(INNATE)) {
+ instance.setInnate(tag.getBoolean(INNATE));
+ }
+ if (tag.contains(MAX_INNATE_SIZE)) {
+ instance.setMaxInnateSize(tag.getInt(MAX_INNATE_SIZE));
+ }
+
+ if (tag.contains(IMBUABLE)) {
+ instance.setImbuable(tag.getBoolean(IMBUABLE));
+ }
+ if (tag.contains(MAX_IMBUE_SIZE)) {
+ instance.setMaxImbueSize(tag.getInt(MAX_IMBUE_SIZE));
+ }
+ if (tag.contains(IMBUING)) {
+ instance.setImbuing(tag.getBoolean(IMBUING));
+ }
+
+ if (tag.contains(SOCKETABLE)) {
+ instance.setSocketable(tag.getBoolean(SOCKETABLE));
+ }
+ if (tag.contains(MAX_SOCKET_SIZE)) {
+ instance.setMaxSocketsSize(tag.getInt(MAX_SOCKET_SIZE));
+ }
+ if (tag.contains(BASE_MATERIAL)) {
+// Optional material = TreasureCharms.getBaseMaterial(ModUtils.asLocation(tag.getString(BASE_MATERIAL)));
+// Optional material = TreasureCharms.getBaseMaterial(ModUtils.asLocation(tag.getString(BASE_MATERIAL)));
+ instance.setBaseMaterial(ModUtils.asLocation(tag.getString(BASE_MATERIAL))); //BaseMaterial.valueOf(tag.getString(BASE_MATERIAL).toUpperCase()));
+ }
+
+ if (tag.contains(SOURCE_ITEM)) {
+ instance.setSourceItem(ModUtils.asLocation(tag.getString(SOURCE_ITEM)));
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/capability/ICharmableCapability.java b/src/main/java/com/someguyssoftware/treasure2/capability/ICharmableCapability.java
index ed3f883ec..49617f0cf 100644
--- a/src/main/java/com/someguyssoftware/treasure2/capability/ICharmableCapability.java
+++ b/src/main/java/com/someguyssoftware/treasure2/capability/ICharmableCapability.java
@@ -1,14 +1,96 @@
-/**
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
*
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
*/
package com.someguyssoftware.treasure2.capability;
+import java.util.List;
+
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.world.World;
+
/**
- * Revamped Charm Capability
- * @author Mark Gottschling on Jan 16, 2021
+ * CharmableCapability is a capability that has an ICharmEntity inventory
+ *
+ * @author Mark Gottschling on Apr 27, 2020
*
*/
public interface ICharmableCapability {
-// public List getCharmInstances();
-// public void setCharmInstances(List instances);
+ public List[] getCharmEntities();
+ public void setCharmEntities(List[] entities);
+
+ /**
+ * Convenience method.
+ * @param type
+ * @param entity
+ */
+ void add(InventoryType type, ICharmEntity entity);
+
+ public boolean isCharmed();
+ int getMaxCharmLevel();
+ public void appendHoverText(ItemStack stack, World world, List tooltip, ITooltipFlag flag);
+
+ public boolean isSource();
+ public void setSource(boolean source);
+
+ public boolean isBindable();
+ public void setBindable(boolean bindable);
+
+ public boolean isInnate();
+ public void setInnate(boolean innate);
+ public int getMaxInnateSize();
+
+ public boolean isImbuable();
+ public void setImbuable(boolean imbue);
+ public int getMaxImbueSize();
+
+ public boolean isImbuing();
+ public void setImbuing(boolean imbuing);
+
+ public boolean isSocketable();
+ public void setSocketable(boolean socketable);
+ public int getMaxSocketsSize();
+
+ public int getMaxSize(InventoryType type);
+
+ void setMaxSocketsSize(int maxSocketsSize);
+ void setMaxImbueSize(int maxImbueSize);
+ void setMaxInnateSize(int maxInnateSize);
+
+ ResourceLocation getBaseMaterial();
+ void setBaseMaterial(ResourceLocation baseMaterial);
+
+ ResourceLocation getSourceItem();
+ void setSourceItem(ResourceLocation sourceItem);
+
+ public boolean contains(ICharm charm);
+ public List getAllCharmEntities();
+ ICharmEntity getHighestLevel();
+
+ void remove(InventoryType type, int index);
+ boolean isExecuting();
+ public void setExecuting(boolean executing);
+
}
\ No newline at end of file
diff --git a/src/main/java/com/someguyssoftware/treasure2/capability/PouchCapabilityProvider.java b/src/main/java/com/someguyssoftware/treasure2/capability/PouchCapabilityProvider.java
new file mode 100644
index 000000000..b53512ed6
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/capability/PouchCapabilityProvider.java
@@ -0,0 +1,64 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.capability;
+
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.POUCH_CAPABILITY;
+
+import com.someguyssoftware.treasure2.inventory.PouchInventory;
+
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.Direction;
+import net.minecraftforge.common.capabilities.Capability;
+import net.minecraftforge.common.capabilities.ICapabilityProvider;
+import net.minecraftforge.common.capabilities.ICapabilitySerializable;
+import net.minecraftforge.common.util.LazyOptional;
+import net.minecraftforge.items.ItemStackHandler;
+
+/**
+ *
+ * @author Mark Gottschling on May 14, 2020
+ *
+ */
+public class PouchCapabilityProvider implements ICapabilityProvider, ICapabilitySerializable {
+
+ // capabilities for item
+ private final ItemStackHandler instance = new ItemStackHandler(PouchInventory.INVENTORY_SIZE);
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public LazyOptional getCapability(Capability capability, Direction side) {
+ if (capability ==POUCH_CAPABILITY) {
+ return (LazyOptional) LazyOptional.of(() -> instance);
+ }
+ return LazyOptional.empty();
+ }
+
+ @Override
+ public CompoundNBT serializeNBT() {
+ CompoundNBT tag = this.instance.serializeNBT();
+ return tag;
+ }
+
+ @Override
+ public void deserializeNBT(CompoundNBT nbt) {
+// POUCH_CAPABILITY.getStorage().readNBT(POUCH_CAPABILITY, instance, null, nbt);
+ this.instance.deserializeNBT(nbt);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/someguyssoftware/treasure2/capability/TreasureCapabilities.java b/src/main/java/com/someguyssoftware/treasure2/capability/TreasureCapabilities.java
index a1b23c84c..22455c669 100644
--- a/src/main/java/com/someguyssoftware/treasure2/capability/TreasureCapabilities.java
+++ b/src/main/java/com/someguyssoftware/treasure2/capability/TreasureCapabilities.java
@@ -37,11 +37,18 @@ public class TreasureCapabilities {
@CapabilityInject(IKeyRingCapability.class)
public static Capability KEY_RING_CAPABILITY = null;
+ @CapabilityInject(ICharmableCapability.class)
+ public static Capability CHARMABLE = null;
+
+ @CapabilityInject(IItemHandler.class)
+ public static Capability POUCH_CAPABILITY = null;
+
/**
*
*/
public static void register() {
CapabilityManager.INSTANCE.register(IDurabilityCapability.class, new DurabilityCapabilityStorage(), DurabilityCapability::new);
CapabilityManager.INSTANCE.register(IKeyRingCapability.class, new KeyRingCapabilityStorage(), KeyRingCapability::new);
- }
+ CapabilityManager.INSTANCE.register(ICharmableCapability.class, new CharmableCapabilityStorage(), CharmableCapability::new);
+ }
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/AegisCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/AegisCharm.java
new file mode 100644
index 000000000..1bf7119a1
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/AegisCharm.java
@@ -0,0 +1,70 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.item.ItemStack;
+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;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class AegisCharm extends ShieldingCharm {
+
+ AegisCharm(Builder builder) {
+ super(builder);
+ }
+
+ public static String AEGIS_TYPE = "aegis";
+
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.BLUE;
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent("tooltip.charm.rate.aegis", 100).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC)));
+
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(AEGIS_TYPE, level)), AEGIS_TYPE, level);
+ this.percent = 100D;
+ }
+
+ @Override
+ public ICharm build() {
+ return new AegisCharm(this);
+ }
+ }
+
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/BaseMaterial2.java b/src/main/java/com/someguyssoftware/treasure2/charm/BaseMaterial2.java
new file mode 100644
index 000000000..4d4f55141
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/BaseMaterial2.java
@@ -0,0 +1,106 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import com.someguyssoftware.gottschcore.measurement.Quantity;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.TranslationTextComponent;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 19, 2021
+ *
+ */
+@Deprecated
+public class BaseMaterial2 {
+// use a class instead of an enum so more materials can easily be added. might have special charms/adornments like platinum etc.
+ private ResourceLocation name;
+ private int maxLevel;
+ private Quantity levelRange;
+
+ /**
+ *
+ * @param name
+ * @param maxLevel
+ * @param levelRange
+ */
+ public BaseMaterial2(String name, int maxLevel, Quantity levelRange) {
+ this.name = ModUtils.asLocation(name);
+ this.maxLevel = maxLevel;
+ this.levelRange = levelRange;
+ }
+
+ /**
+ *
+ * @param name
+ * @param maxLevel
+ * @param minRange
+ * @param maxRange
+ */
+ public BaseMaterial2(String name, int maxLevel, Double minRange, Double maxRange) {
+ this(name, maxLevel, new Quantity(minRange, maxRange));
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getDisplayName() {
+ return new TranslationTextComponent("base_material." + name.toString().replace(":", ".")).getString();
+ }
+
+ public ResourceLocation getName() {
+ return name;
+ }
+
+ public void setName(ResourceLocation name) {
+ this.name = name;
+ }
+
+ public int getMaxLevel() {
+ return maxLevel;
+ }
+
+ public void setMaxLevel(int maxLevel) {
+ this.maxLevel = maxLevel;
+ }
+
+ public Quantity getLevelRange() {
+ return levelRange;
+ }
+
+ public void setLevelRange(Quantity levelRange) {
+ this.levelRange = levelRange;
+ }
+
+ /**
+ * Convenience methods.
+ * @return
+ */
+ public double getMinRangeLevel() {
+ return getLevelRange().getMin();
+ }
+
+ public double getMaxRangeLevel() {
+ return getLevelRange().getMax();
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/Charm.java b/src/main/java/com/someguyssoftware/treasure2/charm/Charm.java
new file mode 100644
index 000000000..01a5b0624
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/Charm.java
@@ -0,0 +1,325 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.enums.Rarity;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+
+/**
+ * @author Mark Gottschling on Apr 25, 2020
+ */
+public abstract class Charm implements ICharm {
+ public static final int TICKS_PER_SECOND = 20;
+
+ private ResourceLocation name;
+ private String type;
+ private int level;
+ private double maxValue;
+ private double maxPercent;
+ private int maxDuration;
+ private Rarity rarity;
+ private int priority;
+
+ /*
+ * if multiple charms of the same type are being processed, only 1 should be updated/executed.
+ * ex. if multiple harvesting charms are held, only one should update.
+ */
+ private boolean effectStackable = false;
+
+ /**
+ *
+ * @param builder
+ */
+ protected Charm(Builder builder) {
+ this.name = builder.name;
+ this.type = builder.type;
+ this.level = builder.level;
+ this.maxValue = builder.value;
+ this.maxDuration = builder.duration.intValue();
+ this.maxPercent = builder.percent;
+ this.rarity = builder.rarity;
+ this.priority = builder.priority;
+ this.effectStackable = builder.effectStackable;
+ }
+
+ abstract public Class> getRegisteredEvent();
+
+
+ /**
+ *
+ */
+ @Override
+ public ICharmEntity createEntity() {
+ ICharmEntity entity = new CharmEntity(this, this.getMaxValue(),this.getMaxDuration(), this.getMaxPercent());
+ return entity;
+ }
+
+ @Override
+ public boolean isCurse() {
+ return false;
+ }
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+ public static Optional load(CompoundNBT nbt) {
+ Optional charm = Optional.empty();
+ // read the name of the charm and fetch from the registry
+ try {
+ String charmName = nbt.getString("name");
+ ResourceLocation resource = ModUtils.asLocation(charmName);
+ charm = TreasureCharmRegistry.get(resource);
+ if (!charm.isPresent()) {
+ throw new Exception(String.format("Unable to locate charm %s in registry.", resource.toString()));
+ }
+ }
+ catch(Exception e) {
+ Treasure.LOGGER.error("Unable to read state to NBT:", e);
+ }
+ return charm;
+ }
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+ @Override
+ public CompoundNBT save(CompoundNBT nbt) {
+ try {
+ nbt.putString("name", this.name.toString());
+ }
+ catch(Exception e) {
+ Treasure.LOGGER.error("Unable to write state to NBT:", e);
+ }
+ return nbt;
+ }
+
+ /**
+ *
+ * @param data
+ * @return
+ */
+ @SuppressWarnings("deprecation")
+ public String getLabel(ICharmEntity entity) {
+ return new TranslationTextComponent("tooltip.charm.type." + getType().toLowerCase()).getString() + " " + String.valueOf(getLevel()) + " " + getUsesGauge(entity);
+
+ /*
+ * 1. check for mod item specific label
+ * 2. check for specific type prefix (levels 1-10)
+ * 3. check for general prefix (levels 1-10)
+ * OR
+ * 4. check for specific type suffix (levels 11+)
+ * 5. check for general suffix (levels 11+)
+ * ex. tooltip.charm.shielding.prefix.level[x], else look for tooltip.charm.prefix.level[x] + tooltip.charm.[type]
+ */
+ // String tooltipKey = "tooltip.charm." + getName().toString().toLowerCase();
+ // String label = I18n.translateToLocalFormatted(tooltipKey,
+ // String.valueOf(Math.toIntExact(Math.round(data.getValue()))),
+ // String.valueOf(Math.toIntExact(Math.round(getMaxValue()))));
+ // String prefix = "";
+ // String suffix = "";
+ // String type = "";
+ // if (label.equals(tooltipKey)) {
+ // type = I18n.translateToLocalFormatted("tooltip.charm." + getType(),
+ // String.valueOf(Math.toIntExact(Math.round(data.getValue()))),
+ // String.valueOf(Math.toIntExact(Math.round(getMaxValue()))));
+ // if (this.getLevel() <= 10) {
+ // String prefixKey = "tooltip.charm." + getType() + ".prefix.level" + String.valueOf(this.getLevel());
+ // prefix = I18n.translateToLocalFormatted(prefixKey);
+ // if (prefix.equals(prefixKey)) {
+ // prefix = I18n.translateToLocalFormatted("tooltip.charm.prefix.level" + String.valueOf(this.getLevel()));
+ // }
+ // label = prefix + " " + type;
+ // }
+ // else {
+ // String suffixKey = "tooltip.charm." + getType() + ".suffix.level" + String.valueOf(this.getLevel());
+ // suffix = I18n.translateToLocalFormatted(suffixKey);
+ // if (suffix.equals(suffixKey)) {
+ // suffix = I18n.translateToLocalFormatted("tooltip.charm.suffix.level" + String.valueOf(this.getLevel()));
+ // }
+ // label = type + " " + suffix;
+ // }
+ // }
+ // // TODO redo this in future.
+ // return label + " " + getUsesGauge(data) + " " + (this.isAllowMultipleUpdates() ? (TextFormatting.DARK_PURPLE + "* combinable") : "");
+ }
+
+ /**
+ *
+ * @param data
+ * @return
+ */
+ @SuppressWarnings("deprecation")
+ public String getUsesGauge(ICharmEntity entity) {
+ return new TranslationTextComponent("tooltip.charm.uses_gauge",
+ String.valueOf(Math.toIntExact(Math.round(entity.getValue()))),
+ String.valueOf(Math.toIntExact(Math.round(getMaxValue())))).getString();
+ }
+
+ @Override
+ public ResourceLocation getName() {
+ return name;
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ @Override
+ public int getLevel() {
+ return level;
+ }
+
+ @Override
+ public double getMaxValue() {
+ return maxValue;
+ }
+
+ public double getMaxPercent() {
+ return maxPercent;
+ }
+
+ @Override
+ public int getMaxDuration() {
+ return maxDuration;
+ }
+
+ @Override
+ public Rarity getRarity() {
+ return rarity;
+ }
+
+ @Override
+ public int getPriority() {
+ return priority;
+ }
+
+ @Override
+ public boolean isEffectStackable() {
+ return effectStackable;
+ }
+
+ /**
+ *
+ * @author Mark Gottschling on Dec 18, 2020
+ *
+ */
+ abstract public static class Builder {
+ public ResourceLocation name;
+ public String type;
+ public Integer level;
+ public Double value = 0.0;
+ public Double duration = 0.0;
+ public Double percent = 0.0;
+ public Rarity rarity = Rarity.COMMON;
+ public int priority = 10;
+ public boolean effectStackable = false;
+
+ /**
+ *
+ * @param name
+ * @param type
+ * @param level
+ * @param charmClass
+ */
+ public Builder(ResourceLocation name, String type, Integer level) {
+ this.name = name;
+ this.type = type;
+ this.level = level;
+ }
+
+ /**
+ *
+ * @return
+ */
+ abstract public ICharm build();
+
+ /**
+ *
+ * @param type
+ * @param level
+ * @return
+ */
+ public static String makeName(String type, int level) {
+ return type + "_" + level;
+ }
+
+ /**
+ *
+ * @param builder
+ * @return
+ */
+ public Builder with(Consumer builder) {
+ builder.accept(this);
+ return this;
+ }
+
+ public Builder withValue(Double value) {
+ this.value = value;
+ return Charm.Builder.this;
+ }
+
+ public Builder withDuration(Double duration) {
+ this.duration = duration;
+ return Charm.Builder.this;
+ }
+
+ public Builder withPercent(Double percent) {
+ this.percent = percent;
+ return Charm.Builder.this;
+ }
+
+ public Builder withRarity(Rarity rarity) {
+ this.rarity = rarity;
+ return Charm.Builder.this;
+ }
+
+ public Builder withPriority(int priority) {
+ this.priority = priority;
+ return Charm.Builder.this;
+ }
+
+ public Builder withAllowMultipleUpdates(boolean allow) {
+ this.effectStackable = allow;
+ return Charm.Builder.this;
+ }
+ }
+
+
+ @Override
+ public String toString() {
+ return "Charm [name=" + name + ", type=" + type + ", level=" + level + ", maxValue=" + maxValue
+ + ", maxPercent=" + maxPercent + ", maxDuration=" + maxDuration + ", rarity=" + rarity + ", priority="
+ + priority + ", effectStackable=" + effectStackable + "]";
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/CharmContext.java b/src/main/java/com/someguyssoftware/treasure2/charm/CharmContext.java
new file mode 100644
index 000000000..92a1dba58
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/CharmContext.java
@@ -0,0 +1,134 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Comparator;
+import java.util.function.Consumer;
+
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Hand;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 19, 2021
+ *
+ */
+public class CharmContext {
+ private Hand hand;
+ private String slotProviderId;
+ private String slot;
+ private ItemStack itemStack;
+ private ICharmableCapability capability;
+ private InventoryType type;
+ private int index;
+ private ICharmEntity entity;
+
+ /**
+ *
+ * @param builder
+ */
+ CharmContext(Builder builder) {
+ this.hand = builder.hand;
+ this.slotProviderId = builder.slotProviderId;
+ this.slot = builder.slot;
+ this.itemStack = builder.itemStack;
+ this.capability = builder.capability;
+ this.type = builder.type;
+ this.index = builder.index;
+ this.entity = builder.entity;
+ }
+
+ public static Comparator priorityComparator = new Comparator() {
+ @Override
+ public int compare(CharmContext p1, CharmContext p2) {
+ // use p1 < p2 because the sort should be ascending
+ if (p1.getEntity().getCharm().getPriority() < p2.getEntity().getCharm().getPriority()) {
+ // greater than
+ return 1;
+ }
+ else {
+ // less than
+ return -1;
+ }
+ }
+ };
+
+ public Hand getHand() {
+ return hand;
+ }
+
+ public String getSlotProviderId() {
+ return slotProviderId;
+ }
+
+ public String getSlot() {
+ return slot;
+ }
+
+ public ItemStack getItemStack() {
+ return itemStack;
+ }
+
+ public InventoryType getType() {
+ return type;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public ICharmEntity getEntity() {
+ return entity;
+ }
+
+ public static class Builder {
+ public Hand hand;
+ public String slotProviderId;
+ public String slot;
+ public ItemStack itemStack;
+ public ICharmableCapability capability;
+ public InventoryType type;
+ public int index;
+ public ICharmEntity entity;
+
+ public Builder with(Consumer builder) {
+ builder.accept(this);
+ return this;
+ }
+
+ public CharmContext build() {
+ return new CharmContext(this);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "CharmContext [hand=" + hand + ", slotProviderId=" + slotProviderId + ", slot=" + slot
+ + ", itemStack=" + itemStack == null ? "N/A" : itemStack.getDisplayName().getString()
+ + "type=" + type + "]";
+ }
+
+ public ICharmableCapability getCapability() {
+ return capability;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/CharmEntity.java b/src/main/java/com/someguyssoftware/treasure2/charm/CharmEntity.java
new file mode 100644
index 000000000..0211b1783
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/CharmEntity.java
@@ -0,0 +1,148 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import net.minecraft.nbt.CompoundNBT;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 19, 2021
+ *
+ */
+public class CharmEntity implements ICharmEntity {
+
+ private ICharm charm;
+ private double value;
+ private int duration;
+ private double percent;
+
+ /**
+ *
+ */
+ public CharmEntity() { }
+
+ /**
+ *
+ * @param charm
+ * @param value
+ * @param duration
+ * @param percent
+ */
+ public CharmEntity(ICharm charm, double value, int duration, double percent) {
+ setCharm(charm);
+ setValue(value);
+ setDuration(duration);
+ setPercent(percent);
+ }
+
+ @Override
+ public void update(ICharmEntity entity) {
+ this.setValue(entity.getValue());
+ this.setDuration(entity.getDuration());
+ this.setPercent(entity.getPercent());
+ }
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+// public static Optional load(CompoundNBT nbt) {
+// Optional charm = Charm.load((CompoundNBT) nbt.get(COPPER_CHARM));
+// if (!charm.isPresent()) {
+// return Optional.empty();
+// }
+//
+// ICharmEntity entity = charm.get().createEntity();
+// if (nbt.contains(VALUE)) {
+// entity.setValue(nbt.getDouble(VALUE));
+// }
+// if (nbt.contains("duration")) {
+// entity.setDuration(nbt.getInt("duration"));
+// }
+// if (nbt.contains("percent")) {
+// entity.setPercent(nbt.getDouble("percent"));
+// }
+// return Optional.of(entity);
+// }
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+ @Override
+ public CompoundNBT save(CompoundNBT nbt) {
+ CompoundNBT charmNbt = new CompoundNBT();
+ // save the charm
+ nbt.put(CHARM, getCharm().save(charmNbt));
+ // save the entity data
+ nbt.putDouble(VALUE, getValue());
+ nbt.putInt("duration", getDuration());
+ nbt.putDouble("percent", getPercent());
+ return nbt;
+ }
+
+ @Override
+ public ICharm getCharm() {
+ return charm;
+ }
+
+ @Override
+ public void setCharm(ICharm charm) {
+ this.charm = charm;
+ }
+
+ @Override
+ public double getValue() {
+ return value;
+ }
+
+ @Override
+ public void setValue(double value) {
+ this.value = value;
+ }
+
+ @Override
+ public int getDuration() {
+ return duration;
+ }
+
+ @Override
+ public void setDuration(int duration) {
+ this.duration = duration;
+ }
+
+ @Override
+ public double getPercent() {
+ return percent;
+ }
+
+ @Override
+ public void setPercent(double percent) {
+ this.percent = percent;
+ }
+
+ @Override
+ public String toString() {
+ return "CharmEntity [charm=" + charm + ", value=" + value + ", duration=" + duration + ", percent=" + percent
+ + "]";
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/CharmableMaterial.java b/src/main/java/com/someguyssoftware/treasure2/charm/CharmableMaterial.java
new file mode 100644
index 000000000..840d40dd8
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/CharmableMaterial.java
@@ -0,0 +1,131 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.TranslationTextComponent;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 20, 2021
+ *
+ */
+public class CharmableMaterial {
+ private int id;
+ private ResourceLocation name;
+ private int maxLevel;
+ private int minSpawnLevel = 1;
+ private double levelMultiplier = 1.0;
+
+ /**
+ *
+ * @param name
+ * @param maxLevel
+ * @param levelRange
+ */
+ public CharmableMaterial(int id, String name, int maxLevel, int minSpawnLevel) {
+ this.id = id;
+ this.name = ModUtils.asLocation(name);
+ this.maxLevel = maxLevel;
+ this.minSpawnLevel = minSpawnLevel;
+ }
+
+ public CharmableMaterial(int id, String name, int maxLevel) {
+ this(id, name, maxLevel, 1);
+ }
+
+ /**
+ * Full constructor
+ * @param name
+ * @param maxLevel
+ * @param levelRange
+ */
+ public CharmableMaterial(int id, ResourceLocation name, int maxLevel, int minSpawnLevel, double levelMultiplier) {
+ this.id = id;
+ this.name = name;
+ this.maxLevel = maxLevel;
+ this.minSpawnLevel = minSpawnLevel;
+ this.levelMultiplier = levelMultiplier;
+ }
+
+ /**
+ *
+ * @param name
+ * @param maxLevel
+ * @param levelRange
+ */
+ public CharmableMaterial(int id, ResourceLocation name, int maxLevel, int minSpawnLevel) {
+ this(id, name, maxLevel, minSpawnLevel, 1D);
+ }
+
+ public CharmableMaterial(int id, ResourceLocation name, int maxLevel) {
+ this(id, name, maxLevel, 1, 1D);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getDisplayName() {
+ return new TranslationTextComponent("charmable_component." + name.toString().replace(":", ".")).getString();
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public ResourceLocation getName() {
+ return name;
+ }
+
+ public void setName(ResourceLocation name) {
+ this.name = name;
+ }
+
+ public int getMaxLevel() {
+ return maxLevel;
+ }
+
+ public void setMaxLevel(int maxLevel) {
+ this.maxLevel = maxLevel;
+ }
+
+ public int getMinSpawnLevel() {
+ return minSpawnLevel;
+ }
+
+ public void setMinSpawnLevel(int minSpawnLevel) {
+ this.minSpawnLevel = minSpawnLevel;
+ }
+
+ public double getLevelMultiplier() {
+ return levelMultiplier;
+ }
+
+ public void setLevelMultiplier(double levelMultiplier) {
+ this.levelMultiplier = levelMultiplier;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/DecayCurse.java b/src/main/java/com/someguyssoftware/treasure2/charm/DecayCurse.java
new file mode 100644
index 000000000..f2b42d543
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/DecayCurse.java
@@ -0,0 +1,98 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class DecayCurse extends Charm implements IDecay {
+ public static String DECAY_TYPE = "decay";
+ private static float DECAY_RATE = 2F;
+
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ DecayCurse(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean isCurse() {
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public float getDecayRate() {
+ return DECAY_RATE;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (world.getGameTime() % 20 == 0) {
+ if (player.isAlive() && entity.getValue() > 0 && player.getHealth() > 0.0) {
+ if (world.getGameTime() % 100 == 0) {
+ player.setHealth(MathHelper.clamp(player.getHealth() - getDecayRate(), 0.0F, player.getMaxHealth()));
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1.0, 0D, entity.getValue()));
+ // Treasure.logger.debug("new data -> {}", data);
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.DARK_RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.decay").withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(DECAY_TYPE, level)), DECAY_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new DecayCurse(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/DecrepitCurse.java b/src/main/java/com/someguyssoftware/treasure2/charm/DecrepitCurse.java
new file mode 100644
index 000000000..6a34e1e95
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/DecrepitCurse.java
@@ -0,0 +1,84 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class DecrepitCurse extends Charm {
+ public static String DECREPIT_TYPE = "decrepit";
+
+ private static final Class> REGISTERED_EVENT = LivingDamageEvent.class;
+
+ DecrepitCurse(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean isCurse() {
+ return true;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (world.getGameTime() % 20 == 0) {
+ if (player.isAlive() && entity.getValue() > 0 && player.getHealth() > 0.0) {
+ double amount = ((LivingDamageEvent)event).getAmount();
+ ((LivingDamageEvent)event).setAmount((float) (amount * entity.getPercent()));
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1.0, 0D, entity.getValue()));
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.DARK_RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.decrepit", Math.round((this.getMaxPercent()-1)*100)).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(DECREPIT_TYPE, level)), DECREPIT_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new DecrepitCurse(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/DirtFillCurse.java b/src/main/java/com/someguyssoftware/treasure2/charm/DirtFillCurse.java
new file mode 100644
index 000000000..4252d3066
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/DirtFillCurse.java
@@ -0,0 +1,131 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.MathHelper;
+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.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 24, 2021
+ *
+ */
+public class DirtFillCurse extends Charm {
+ public static final String DIRT_FILL_TYPE = "dirt_fill";
+
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ DirtFillCurse(Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean isCurse() {
+ return true;
+ }
+
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ // update every 10 seconds
+ if (world.getGameTime() % 200 == 0) {
+ if (player.isAlive() && entity.getValue() > 0) {
+ // randomly select an empty inventory slot and fill it with dirt
+ List emptySlots = getEmptySlotsRandomized(player.inventory, random);
+ if (emptySlots != null && !emptySlots.isEmpty()) {
+ player.inventory.setItem(((Integer)emptySlots.get(emptySlots.size() - 1)).intValue(), new ItemStack(Blocks.DIRT, 1));
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1.0, 0D, entity.getValue()));
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.DARK_RED;
+ tooltip.add(new StringTextComponent(" ").append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ }
+
+ /**
+ *
+ * @param inventory
+ * @param rand
+ * @return
+ */
+ private List getEmptySlotsRandomized(IInventory inventory, Random rand) {
+ List list = Lists.newArrayList();
+ for (int i = 0; i < Math.min(36, inventory.getContainerSize()); ++i) {
+ if (inventory.getItem(i).isEmpty()) {
+ list.add(Integer.valueOf(i));
+ }
+ }
+ Collections.shuffle(list, rand);
+ return list;
+ }
+
+ /**
+ *
+ */
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(DIRT_FILL_TYPE, level)), DIRT_FILL_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new DirtFillCurse(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/DirtWalkCurse.java b/src/main/java/com/someguyssoftware/treasure2/charm/DirtWalkCurse.java
new file mode 100644
index 000000000..a8475c2b9
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/DirtWalkCurse.java
@@ -0,0 +1,115 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.MathHelper;
+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.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 24, 2021
+ *
+ */
+public class DirtWalkCurse extends Charm {
+ public static final String DIRT_WALK_TYPE = "dirt_walk";
+
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ DirtWalkCurse(Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean isCurse() {
+ return true;
+ }
+
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ // update every 10 seconds
+ if (world.getGameTime() % 200 == 0) {
+ if (player.isAlive() && entity.getValue() > 0) {
+ // if the current position where standing isn't already dirt, change it to dirt
+ BlockState state = world.getBlockState(coords.down(1).toPos());
+ if (state.getBlock() != Blocks.DIRT) {
+ world.setBlockAndUpdate(coords.down(1).toPos(), Blocks.DIRT.defaultBlockState());
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1.0, 0D, entity.getValue()));
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.DARK_RED;
+ tooltip.add(new StringTextComponent(" ").append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ }
+
+ /**
+ *
+ */
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(DIRT_WALK_TYPE, level)), DIRT_WALK_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new DirtWalkCurse(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/DrainCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/DrainCharm.java
new file mode 100644
index 000000000..cec5bca79
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/DrainCharm.java
@@ -0,0 +1,110 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.charm.Charm.Builder;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * drains 1 health; value = uses, duration = range
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class DrainCharm extends Charm {
+ public static final String DRAIN_TYPE = "drain";
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ DrainCharm(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ if (world.getGameTime() % (TICKS_PER_SECOND * 5) == 0) {
+ if (entity.getValue() > 0 && player.getHealth() < player.getMaxHealth() && player.isAlive()) {
+ // get player position
+ double px = player.position().x;
+ double py = player.position().y;
+ double pz = player.position().z;
+
+ // calculate the new amount
+ int range = entity.getDuration();
+ AtomicInteger drainedHealth = new AtomicInteger(0);
+ List mobs = world.getEntitiesOfClass(MobEntity.class, new AxisAlignedBB(px - range, py - range, pz - range, px + range, py + range, pz + range));
+ if (mobs.isEmpty()) {
+ return result;
+ }
+ mobs.forEach(mob -> {
+ boolean flag = mob.hurt(DamageSource.playerAttack(player), (float) 1.0F);
+ Treasure.LOGGER.debug("health drained from mob -> {} was successful -> {}", mob.getName(), flag);
+ if (flag) {
+ drainedHealth.getAndAdd(1);
+ }
+ });
+
+ if (drainedHealth.get() > 0) {
+ player.setHealth(MathHelper.clamp(player.getHealth() + drainedHealth.get(), 0.0F, player.getMaxHealth()));
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1D, 0D, entity.getValue()));
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.drain", this.getMaxDuration()).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(DRAIN_TYPE, level)), DRAIN_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new DrainCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/FireImmunityCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/FireImmunityCharm.java
new file mode 100644
index 000000000..013be1e79
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/FireImmunityCharm.java
@@ -0,0 +1,89 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class FireImmunityCharm extends Charm {
+ public static final String FIRE_IMMUNITY_TYPE = "fire_immunity";
+ private static final Class> REGISTERED_EVENT = LivingDamageEvent.class;
+
+ FireImmunityCharm(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ if (entity.getValue() > 0 && player.isAlive() && ((LivingDamageEvent)event).getSource().isFire()) {
+ // get the fire damage amount
+ double amount = ((LivingDamageEvent)event).getAmount();
+
+ // if damage is fire damage
+ if (entity.getValue() >= amount) {
+ entity.setValue(entity.getValue() - amount);
+ }
+ else {
+ entity.setValue(0);
+ }
+ ((LivingDamageEvent)event).setAmount(0F);
+ result = true;
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.fire_immunity").withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(FIRE_IMMUNITY_TYPE, level)), FIRE_IMMUNITY_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new FireImmunityCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/FireResistenceCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/FireResistenceCharm.java
new file mode 100644
index 000000000..83fc6c393
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/FireResistenceCharm.java
@@ -0,0 +1,95 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class FireResistenceCharm extends Charm {
+ public static final String FIRE_RESISTENCE_TYPE = "fire_resistence";
+ private static final Class> REGISTERED_EVENT = LivingDamageEvent.class;
+
+ FireResistenceCharm(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ if (((LivingDamageEvent)event).getSource().isFire() && entity.getValue() > 0 && player.isAlive()) {
+ // get the fire damage amount
+ double amount = ((LivingDamageEvent)event).getAmount();
+ // calculate the new amount
+ double newAmount = 0;
+ double amountToCharm = amount * entity.getPercent();
+ double amountToPlayer = amount - amountToCharm;
+
+ if (entity.getValue() >= amountToCharm) {
+ entity.setValue(entity.getValue() - amountToCharm);
+ newAmount = amountToPlayer;
+ }
+ else {
+ newAmount = amount - entity.getValue();
+ entity.setValue(0);
+ }
+ ((LivingDamageEvent)event).setAmount((float) newAmount);
+
+ result = true;
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.fire_resistence", Math.toIntExact(Math.round(entity.getPercent() * 100))).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(FIRE_RESISTENCE_TYPE, level)), FIRE_RESISTENCE_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new FireResistenceCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/GreaterHealingCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/GreaterHealingCharm.java
new file mode 100644
index 000000000..e37ffda4e
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/GreaterHealingCharm.java
@@ -0,0 +1,89 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class GreaterHealingCharm extends Charm implements IHealing {
+ public static String HEALING_TYPE = "greater_healing";
+ private static float HEAL_RATE = 2F;
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ GreaterHealingCharm(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public float getHealRate() {
+ return HEAL_RATE;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (world.getGameTime() % 20 == 0) {
+ if (entity.getValue() > 0 && player.getHealth() < player.getMaxHealth() && player.isAlive()) {
+ float amount = Math.min(getHealRate(), player.getMaxHealth() - player.getHealth());
+ player.setHealth(MathHelper.clamp(player.getHealth() + amount, 0.0F, player.getMaxHealth()));
+ entity.setValue(MathHelper.clamp(entity.getValue() - amount, 0D, entity.getValue()));
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.greater_healing").withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(HEALING_TYPE, level)), HEALING_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new GreaterHealingCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/HealingCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/HealingCharm.java
new file mode 100644
index 000000000..229f868ce
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/HealingCharm.java
@@ -0,0 +1,90 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class HealingCharm extends Charm implements IHealing {
+ public static String HEALING_TYPE = "healing";
+ private static float HEAL_RATE = 1F;
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ HealingCharm(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public float getHealRate() {
+ return HEAL_RATE;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (world.getGameTime() % 20 == 0) {
+ if (entity.getValue() > 0 && player.getHealth() < player.getMaxHealth() && player.isAlive()) {
+ float amount = Math.min(getHealRate(), player.getMaxHealth() - player.getHealth());
+ player.setHealth(MathHelper.clamp(player.getHealth() + amount, 0.0F, player.getMaxHealth()));
+ entity.setValue(MathHelper.clamp(entity.getValue() - amount, 0D, entity.getValue()));
+ // Treasure.logger.debug("new data -> {}", data);
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.healing").withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(HEALING_TYPE, level)), HEALING_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new HealingCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/ICharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/ICharm.java
new file mode 100644
index 000000000..a38601787
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/ICharm.java
@@ -0,0 +1,73 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.enums.Rarity;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Jan 16, 2021
+ *
+ */
+public interface ICharm {
+
+ public ResourceLocation getName();
+ public String getType();
+ public int getLevel();
+ public double getMaxValue();
+ public int getMaxDuration();
+ public double getMaxPercent();
+ public Rarity getRarity();
+ public int getPriority();
+ boolean isEffectStackable();
+
+ /**
+ *
+ */
+ ICharmEntity createEntity();
+
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity);
+
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity);
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+ CompoundNBT save(CompoundNBT nbt);
+
+ public Class> getRegisteredEvent();
+
+ public boolean isCurse();
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/ICharmData.java b/src/main/java/com/someguyssoftware/treasure2/charm/ICharmData.java
new file mode 100644
index 000000000..9525dfca9
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/ICharmData.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import net.minecraft.nbt.CompoundNBT;
+
+/**
+ * @author Mark Gottschling on Apr 27, 2020
+ *
+ */
+@Deprecated
+public interface ICharmData {
+ public double getValue();
+ public void setValue(double value);
+
+ public int getDuration();
+ public void setDuration(int duration);
+
+ public double getPercent();
+ public void setPercent(double percent);
+
+ public CompoundNBT writeToNBT(CompoundNBT nbt);
+ public void readFromNBT(CompoundNBT tag);
+}
\ No newline at end of file
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/ICharmEntity.java b/src/main/java/com/someguyssoftware/treasure2/charm/ICharmEntity.java
new file mode 100644
index 000000000..7fd4440bb
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/ICharmEntity.java
@@ -0,0 +1,92 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Optional;
+
+import net.minecraft.nbt.CompoundNBT;
+
+/**
+ *
+ * @author Mark Gottschling on Jan 16, 2021
+ *
+ */
+public interface ICharmEntity {
+ static String CHARM = "charm";
+ static String VALUE = "value";
+
+ ICharm getCharm();
+ void setCharm(ICharm charm);
+
+ double getValue();
+ void setValue(double value);
+
+ int getDuration();
+ void setDuration(int duration);
+
+ double getPercent();
+ void setPercent(double percent);
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+ CompoundNBT save(CompoundNBT nbt);
+
+ /**
+ *
+ * @param nbt
+ * @return
+ */
+// public static Optional load(CompoundNBT nbt) {
+// Optional charm = Charm.load((CompoundNBT) nbt.get(CHARM));
+// if (!charm.isPresent()) {
+// return Optional.empty();
+// }
+//
+// ICharmEntity entity = charm.get().createEntity();
+// if (nbt.contains(VALUE)) {
+// entity.setValue(nbt.getDouble(VALUE));
+// }
+// if (nbt.contains("duration")) {
+// entity.setDuration(nbt.getInt("duration"));
+// }
+// if (nbt.contains("percent")) {
+// entity.setPercent(nbt.getDouble("percent"));
+// }
+// return Optional.of(entity);
+// }
+
+ default public boolean load(CompoundNBT nbt) {
+ if (nbt.contains(VALUE)) {
+ setValue(nbt.getDouble(VALUE));
+ }
+ if (nbt.contains("duration")) {
+ setDuration(nbt.getInt("duration"));
+ }
+ if (nbt.contains("percent")) {
+ setPercent(nbt.getDouble("percent"));
+ }
+ return true;
+ }
+
+ void update(ICharmEntity entity);
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/IDecay.java b/src/main/java/com/someguyssoftware/treasure2/charm/IDecay.java
new file mode 100644
index 000000000..fab8efad8
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/IDecay.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 24, 2021
+ *
+ */
+public interface IDecay {
+ public float getDecayRate();
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/IHealing.java b/src/main/java/com/someguyssoftware/treasure2/charm/IHealing.java
new file mode 100644
index 000000000..3af27390f
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/IHealing.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public interface IHealing {
+ public float getHealRate();
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/ILifeStrike.java b/src/main/java/com/someguyssoftware/treasure2/charm/ILifeStrike.java
new file mode 100644
index 000000000..2a1c7a681
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/ILifeStrike.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public interface ILifeStrike {
+ public float getLifeAmount();
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/IlluminationCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/IlluminationCharm.java
new file mode 100644
index 000000000..c7b6e4c29
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/IlluminationCharm.java
@@ -0,0 +1,164 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.block.BlockContext;
+import com.someguyssoftware.gottschcore.spatial.Coords;
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.Blocks;
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class IlluminationCharm extends Charm {
+ public static String ILLUMINATION_TYPE = "illumination";
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ IlluminationCharm(Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public ICharmEntity createEntity() {
+ ICharmEntity entity = new IlluminationCharmEntity(this, this.getMaxValue(),this.getMaxDuration(), this.getMaxPercent());
+ return entity;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (world.getGameTime() % 100 == 0) {
+ if (entity.getValue() > 0 && player.isAlive()) {
+ ICoords currentCoords = new Coords((int)Math.floor(player.position().x), (int)Math.floor(player.position().y), (int)Math.floor(player.position().z));
+
+ /*
+ * validation checks
+ */
+ // check that the block at current position is air or replaceable
+ BlockContext cube = new BlockContext(world, currentCoords);
+ if (!cube.isAir() && !cube.isReplaceable()) {
+ return false;
+ }
+ // check that the block underneath is solid
+ cube = new BlockContext(world, currentCoords.down(1));
+ if (!cube.isSolid()) {
+ Treasure.LOGGER.debug("not solid at -> {}", currentCoords.down(1));
+ return false;
+ }
+ if (!(entity instanceof IlluminationCharmEntity)) {
+ Treasure.LOGGER.debug("entity are not instance of IlluminationCharmData -> {}.{}", this.getClass().getSimpleName(), entity.getClass().getSimpleName());
+ return false;
+ }
+
+ IlluminationCharmEntity charmEntity = (IlluminationCharmEntity)entity;
+ // cast as linked list
+ List list = (List)charmEntity.getCoordsList();
+ Treasure.LOGGER.debug("charm coords list size -> {}", list.size());
+ double value = entity.getValue();
+
+ boolean isUpdated = false;
+ // check if the coordsList is empty or not
+ if (list.isEmpty()) {
+ // add current position
+ list.add(0, currentCoords);
+ isUpdated = true;
+ }
+ else {
+ // determine if new position is different than last position - ie first element in entity.coordsList
+ ICoords firstCoords = list.get(0);
+ if (!currentCoords.equals(firstCoords) && firstCoords.getDistanceSq(currentCoords) >= 25) {
+ // add current coords to coords list
+ list.add(0, currentCoords);
+ // check if coords list is greater than max (entity.value)
+ if (list.size() > (int)charmEntity.getValue()) {
+ // get difference in size
+ int diff = (int) (list.size() - charmEntity.getValue());
+ // Treasure.logger.debug("diff -> {}", diff);
+ for (int index = 0; index < diff; index++) {
+ ICoords lastCoords = list.get(list.size()-1);
+ Block block = world.getBlockState(lastCoords.toPos()).getBlock();
+ if (block == Blocks.TORCH) {
+ // Treasure.logger.debug("set torch to air at -> {}", lastCoords.toShortString());
+// world.setBlockToAir(lastCoords.toPos());
+ Block.updateOrDestroy(world.getBlockState(lastCoords.toPos()), Blocks.AIR.defaultBlockState(), world, lastCoords.toPos(), 3);
+ }
+ else {
+ // Treasure.logger.debug("torch no longer found at -> {}", currentCoords.toShortString());
+ // decrement value since torch was harvested
+ value -= 1;
+ }
+ list.remove(lastCoords);
+ // Treasure.logger.debug("remove torch from list at -> {}; new size ->{}", lastCoords.toShortString(), list.size());
+ }
+ }
+ isUpdated = true;
+ }
+ }
+ if (isUpdated == true ) {
+ world.setBlockAndUpdate(currentCoords.toPos(), Blocks.TORCH.defaultBlockState());
+ // Treasure.logger.debug("set torch at -> {}", currentCoords.toShortString());
+ if (value < 0) value = 0;
+ entity.setValue(value);
+ // Treasure.logger.debug("new entity -> {}", entity);
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.illumination").withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(ILLUMINATION_TYPE, level)), ILLUMINATION_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new IlluminationCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/IlluminationCharmEntity.java b/src/main/java/com/someguyssoftware/treasure2/charm/IlluminationCharmEntity.java
new file mode 100644
index 000000000..cb8878a5a
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/IlluminationCharmEntity.java
@@ -0,0 +1,118 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.ListNBT;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 24, 2021
+ *
+ */
+public class IlluminationCharmEntity extends CharmEntity {
+ private List coordsList;
+
+ /**
+ *
+ * @param charm
+ * @param value
+ * @param duration
+ * @param percent
+ */
+ public IlluminationCharmEntity(ICharm charm, double value, int duration, double percent) {
+ super(charm, value, duration, percent);
+ setCoordsList(Collections.synchronizedList(new LinkedList<>()));
+ }
+
+ /**
+ *
+ */
+ @Override
+ public boolean load(CompoundNBT nbt) {
+ super.load(nbt);
+ ListNBT list = nbt.getList("illuminationCoords", 10);
+// Treasure.logger.debug("illumination tag list size -> {}", list.tagCount());
+ for (int i = 0; i < list.size(); i++) {
+ CompoundNBT tag = (CompoundNBT) list.get(i);
+ ICoords coords = ICoords.readFromNBT(tag);
+ if (coords != null) {
+ getCoordsList().add(coords);
+ }
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public List getCoordsList() {
+ if (coordsList == null) {
+ coordsList = new LinkedList<>();
+ }
+ return coordsList;
+ }
+
+ /**
+ *
+ * @param blockList
+ */
+ public void setCoordsList(List blockList) {
+ this.coordsList = blockList;
+ }
+
+ @Override
+ public String toString() {
+ return "IlluminationCharmEntity [" + /*coordsList=" + coordsList + ",*/ " toString()=" + super.toString() + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((coordsList == null) ? 0 : coordsList.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IlluminationCharmEntity other = (IlluminationCharmEntity) obj;
+ if (coordsList == null) {
+ if (other.coordsList != null)
+ return false;
+ } else if (!coordsList.equals(other.coordsList))
+ return false;
+ return true;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/LifeStrikeCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/LifeStrikeCharm.java
new file mode 100644
index 000000000..57349e713
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/LifeStrikeCharm.java
@@ -0,0 +1,116 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingHurtEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class LifeStrikeCharm extends Charm implements ILifeStrike {
+ public static String LIFE_STRIKE_TYPE = "life_strike";
+ private static float LIFE_AMOUNT = 2F;
+ private static final Class> REGISTERED_EVENT = LivingHurtEvent.class;
+
+ LifeStrikeCharm(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public float getLifeAmount() {
+ return LIFE_AMOUNT;
+ }
+
+ /**
+ * NOTE: it is assumed that only the allowable events are calling this action.
+ */
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (entity.getValue() > 0 && player.isAlive()) {
+ DamageSource source = ((LivingHurtEvent) event).getSource();
+
+ if (source.getEntity() instanceof PlayerEntity) {
+ if (player.getHealth() > 5.0F) {
+ // get the source and amount
+ double amount = ((LivingHurtEvent)event).getAmount();
+ // increase damage amount
+ ((LivingHurtEvent)event).setAmount((float) (Math.max(2F, amount * entity.getPercent())));
+ // reduce players health
+ player.setHealth(MathHelper.clamp(player.getHealth() - LIFE_AMOUNT, 0.0F, player.getMaxHealth()));
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1, 0D, entity.getValue()));
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.RED;
+ tooltip.add(new TranslationTextComponent(getLabel(entity)).withStyle(color));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.life_strike", Math.round((this.getMaxPercent()-1)*100)).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(LIFE_STRIKE_TYPE, level)), LIFE_STRIKE_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new LifeStrikeCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/ReflectionCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/ReflectionCharm.java
new file mode 100644
index 000000000..d2b1844d1
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/ReflectionCharm.java
@@ -0,0 +1,122 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.math.AxisAlignedBB;
+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.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ * reflection: value = # of uses, duration = range, percent = % of damage reflected
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class ReflectionCharm extends Charm {
+ public static String REFLECTION_TYPE = "reflection";
+
+ private static final Class> REGISTERED_EVENT = LivingDamageEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ public ReflectionCharm(Builder builder) {
+ super(builder);
+ }
+
+ protected ReflectionCharm(Charm.Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+ if (entity.getValue() > 0 && player.isAlive()) {
+ // get player position
+ double px = player.position().x;
+ double py = player.position().y;
+ double pz = player.position().z;
+
+ // get the source and amount
+ double amount = ((LivingDamageEvent)event).getAmount();
+ // calculate the new amount
+ double reflectedAmount = amount * entity.getPercent();
+ int range = entity.getDuration();
+
+ List mobs = world.getEntitiesOfClass(MobEntity.class, new AxisAlignedBB(px - range, py - range, pz - range, px + range, py + range, pz + range));
+ mobs.forEach(mob -> {
+ boolean flag = mob.hurt(DamageSource.playerAttack(player), (float) reflectedAmount);
+ Treasure.LOGGER.debug("reflected damage {} onto mob -> {} was successful -> {}", reflectedAmount, mob.getName(), flag);
+ });
+
+ // get all the mob within a radius
+ entity.setValue(entity.getValue() - 1.0);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.BLUE;
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ tooltip.add(new StringTextComponent(" ")
+ // TODO crud all these rates need to pull from the charm!
+ .append(new TranslationTextComponent("tooltip.charm.rate.reflection", Math.round(this.getMaxPercent()*100), entity.getDuration()).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC)));
+
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(REFLECTION_TYPE, level)), REFLECTION_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new ReflectionCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/RuinCurse.java b/src/main/java/com/someguyssoftware/treasure2/charm/RuinCurse.java
new file mode 100644
index 000000000..73cb9d46c
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/RuinCurse.java
@@ -0,0 +1,134 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.util.math.MathHelper;
+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.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 24, 2021
+ *
+ */
+public class RuinCurse extends Charm {
+ public static final String RUIN_TYPE = "ruin";
+
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ RuinCurse(Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean isCurse() {
+ return true;
+ }
+
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ // update every 10 seconds
+ if (player.isAlive() && entity.getValue() > 0 && player.getHealth() > 0.0) {
+ if (world.getGameTime() % (entity.getDuration() * TICKS_PER_SECOND) == 0) {
+ FluentIterable inventoryEquipment = (FluentIterable) player.getArmorSlots();
+ inventoryEquipment.append(player.getHandSlots());
+
+ List actualEquipment = new ArrayList<>(5);
+ inventoryEquipment.forEach(itemStack -> {
+ if (itemStack.getItem() != Items.AIR) {
+ actualEquipment.add(itemStack);
+ }
+ });
+ if (actualEquipment != null && actualEquipment.size() > 0) {
+ // randomly pick an item
+ ItemStack selectedItemStack = actualEquipment.get(random.nextInt(actualEquipment.size()));
+ Treasure.LOGGER.debug("damaging item -> {}, current damage -> {} of {}", selectedItemStack.getDisplayName(), selectedItemStack.getDamageValue(), selectedItemStack.getMaxDamage());
+ // damage the item
+ if (selectedItemStack.isDamageableItem()) {
+ selectedItemStack.hurt(1, random, null);
+ Treasure.LOGGER.debug("damaged item -> {}, now at damaged -> {} of {}", selectedItemStack.getDisplayName(), selectedItemStack.getDamageValue(), selectedItemStack.getMaxDamage());
+ entity.setValue(MathHelper.clamp(entity.getValue() - 1.0, 0D, entity.getValue()));
+ }
+ }
+ Treasure.LOGGER.debug("charm {} new data -> {}", this.getName(), entity);
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.DARK_RED;
+ tooltip.add(new StringTextComponent(" ").append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ tooltip.add(new TranslationTextComponent("tooltip.charm.rate.ruin").withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+ }
+
+ /**
+ *
+ */
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(RUIN_TYPE, level)), RUIN_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new RuinCurse(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/SatietyCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/SatietyCharm.java
new file mode 100644
index 000000000..60046764b
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/SatietyCharm.java
@@ -0,0 +1,101 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+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.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 23, 2021
+ *
+ */
+public class SatietyCharm extends Charm {
+ public static final String SATIETY_TYPE = "satiety";
+ public static final int MAX_FOOD_LEVEL = 20;
+
+ private static final Class> REGISTERED_EVENT = LivingUpdateEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ SatietyCharm(Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity entity) {
+ boolean result = false;
+
+ if (world.getGameTime() % TICKS_PER_SECOND == 0) {
+ if (player.isAlive() && entity.getValue() > 0 && player.getFoodData().getFoodLevel() < MAX_FOOD_LEVEL) {
+ player.getFoodData().eat(1, 1);
+ entity.setValue(entity.getValue() - 1);
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.BLUE;
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent("tooltip.charm.rate.satiety")).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC));
+
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(SATIETY_TYPE, level)), SATIETY_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new SatietyCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/ShieldingCharm.java b/src/main/java/com/someguyssoftware/treasure2/charm/ShieldingCharm.java
new file mode 100644
index 000000000..1d6130e35
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/ShieldingCharm.java
@@ -0,0 +1,114 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.List;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+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.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.eventbus.api.Event;
+
+/**
+ *
+ * @author Mark Gottschling on Apr 30, 2020
+ *
+ */
+public class ShieldingCharm extends Charm {
+ public static String SHIELDING_TYPE = "shielding";
+
+ private static final Class> REGISTERED_EVENT = LivingDamageEvent.class;
+
+ /**
+ *
+ * @param builder
+ */
+ public ShieldingCharm(Builder builder) {
+ super(builder);
+ }
+
+ protected ShieldingCharm(Charm.Builder builder) {
+ super(builder);
+ }
+
+ public Class> getRegisteredEvent() {
+ return REGISTERED_EVENT;
+ }
+
+ @Override
+ public boolean update(World world, Random random, ICoords coords, PlayerEntity player, Event event, final ICharmEntity data) {
+ boolean result = false;
+ if (data.getValue() > 0 && player.isAlive()) {
+ // get the source and amount
+ double amount = ((LivingDamageEvent)event).getAmount();
+ // calculate the new amount
+ double newAmount = 0;
+ double amountToCharm = amount * data.getPercent();
+ double amountToPlayer = amount - amountToCharm;
+ // Treasure.logger.debug("amount to charm -> {}); amount to player -> {}", amountToCharm, amountToPlayer);
+ if (data.getValue() >= amountToCharm) {
+ data.setValue(data.getValue() - amountToCharm);
+ newAmount = amountToPlayer;
+ }
+ else {
+ newAmount = amount - data.getValue();
+ data.setValue(0);
+ }
+ ((LivingDamageEvent)event).setAmount((float) newAmount);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn, ICharmEntity entity) {
+ TextFormatting color = TextFormatting.BLUE;
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent(getLabel(entity)).withStyle(color)));
+ tooltip.add(new StringTextComponent(" ")
+ .append(new TranslationTextComponent("tooltip.charm.rate.shielding", Math.round(this.getMaxPercent()*100)).withStyle(TextFormatting.GRAY, TextFormatting.ITALIC)));
+
+ }
+
+ public static class Builder extends Charm.Builder {
+
+ public Builder(Integer level) {
+ super(ModUtils.asLocation(makeName(SHIELDING_TYPE, level)), SHIELDING_TYPE, level);
+ }
+
+ @Override
+ public ICharm build() {
+ return new ShieldingCharm(this);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/TreasureCharmRegistry.java b/src/main/java/com/someguyssoftware/treasure2/charm/TreasureCharmRegistry.java
new file mode 100644
index 000000000..8c30426ee
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/TreasureCharmRegistry.java
@@ -0,0 +1,126 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+
+import net.minecraft.util.ResourceLocation;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class TreasureCharmRegistry {
+ private static final Map REGISTRY = new HashMap<>();
+ private static final Map> REGISTRY_BY_LEVEL = new HashMap<>();
+
+ /**
+ *
+ * @param charm
+ */
+ public static void register(ICharm charm) {
+ if (!REGISTRY.containsKey(charm.getName())) {
+ REGISTRY.put(charm.getName(), charm);
+ }
+ if (!REGISTRY_BY_LEVEL.containsKey(Integer.valueOf(charm.getLevel()))) {
+ List charmList = new ArrayList<>();
+ charmList.add(charm);
+ REGISTRY_BY_LEVEL.put(Integer.valueOf(charm.getLevel()), charmList);
+ }
+ else {
+ REGISTRY_BY_LEVEL.get(Integer.valueOf(charm.getLevel())).add(charm);
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ public static Optional get(ResourceLocation name) {
+
+ if (REGISTRY.containsKey(name)) {
+ return Optional.of(REGISTRY.get(name));
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * @param level
+ * @return
+ */
+ public static Optional> get(Integer level) {
+ if (REGISTRY_BY_LEVEL.containsKey(level)) {
+ return Optional.of(REGISTRY_BY_LEVEL.get(level));
+ }
+ return Optional.empty();
+ }
+
+ /**
+ *
+ * @param predicate
+ * @return
+ */
+ public static Optional> get(Predicate predicate) {
+ List charms = new ArrayList<>();
+ for (ICharm c : TreasureCharmRegistry.values()) {
+ if (predicate.test(c.getLevel())) {
+ charms.add(c);
+ }
+ }
+ if (charms.size() == 0) {
+ return Optional.empty();
+ }
+ return Optional.of(charms);
+ }
+
+ /**
+ *
+ * @param predicate
+ * @return
+ */
+ public static Optional> getBy(Predicate predicate) {
+ List charms = new ArrayList<>();
+ for (ICharm c : TreasureCharmRegistry.values()) {
+ if (predicate.test(c)) {
+ charms.add(c);
+ }
+ }
+ if (charms.size() == 0) {
+ return Optional.empty();
+ }
+ return Optional.of(charms);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static List values() {
+ return new ArrayList<>(REGISTRY.values());
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/charm/TreasureCharms.java b/src/main/java/com/someguyssoftware/treasure2/charm/TreasureCharms.java
new file mode 100644
index 000000000..517239d85
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/charm/TreasureCharms.java
@@ -0,0 +1,496 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.charm;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.someguyssoftware.treasure2.enums.Rarity;
+import com.someguyssoftware.treasure2.item.TreasureItems;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.item.Items;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 15, 2021
+ *
+ */
+public class TreasureCharms {
+ private static final Map METAL_REGISTRY = new HashMap<>();
+ private static final Map GEM_REGISTRY = new HashMap<>();
+
+ public static CharmableMaterial COPPER = new CharmableMaterial(1, ModUtils.asLocation("copper"), 2, 1, 0.5D);
+ public static CharmableMaterial SILVER = new CharmableMaterial(2, ModUtils.asLocation("silver"), 3, 1, 0.75D);
+ public static CharmableMaterial GOLD = new CharmableMaterial(3, ModUtils.asLocation("gold"), 4);
+
+ public static CharmableMaterial DIAMOND;
+ public static CharmableMaterial EMERALD;
+ public static CharmableMaterial TOPAZ;
+ public static CharmableMaterial ONYX;
+ public static CharmableMaterial RUBY;
+ public static CharmableMaterial SAPPHIRE;
+ public static CharmableMaterial WHITE_PEARL;
+ public static CharmableMaterial BLACK_PEARL;
+
+ // charms
+ public static final ICharm HEALING_1 = makeHealing(1);
+ public static final ICharm HEALING_2 = makeHealing(2);
+ public static final ICharm HEALING_3 = makeHealing(3);
+ public static final ICharm HEALING_4 = makeHealing(4);
+ public static final ICharm HEALING_5 = makeHealing(5);
+ public static final ICharm HEALING_6 = makeHealing(6);
+ public static final ICharm HEALING_7 = makeHealing(7);
+ public static final ICharm HEALING_8 = makeHealing(8);
+ public static final ICharm HEALING_9 = makeHealing(9);
+ public static final ICharm HEALING_10 = makeHealing(10);
+ public static final ICharm HEALING_11 = makeHealing(11);
+ public static final ICharm HEALING_12 = makeHealing(12);
+ public static final ICharm HEALING_13 = makeHealing(13);
+ public static final ICharm HEALING_14 = makeHealing(14);
+ public static final ICharm HEALING_15 = makeHealing(15);
+
+ public static final ICharm GREATER_HEALING_8 = makeGreaterHealing(8);
+ public static final ICharm GREATER_HEALING_9 = makeGreaterHealing(9);
+ public static final ICharm GREATER_HEALING_10 = makeGreaterHealing(10);
+ public static final ICharm GREATER_HEALING_11 = makeGreaterHealing(11);
+ public static final ICharm GREATER_HEALING_12 = makeGreaterHealing(12);
+ public static final ICharm GREATER_HEALING_13 = makeGreaterHealing(13);
+ public static final ICharm GREATER_HEALING_14 = makeGreaterHealing(14);
+ public static final ICharm GREATER_HEALING_15 = makeGreaterHealing(15);
+
+ public static final ICharm SHIELDING_1 = makeShielding(1);
+ public static final ICharm SHIELDING_2 = makeShielding(2);
+ public static final ICharm SHIELDING_3 = makeShielding(3);
+ public static final ICharm SHIELDING_4 = makeShielding(4);
+ public static final ICharm SHIELDING_5 = makeShielding(5);
+ public static final ICharm SHIELDING_6 = makeShielding(6);
+ public static final ICharm SHIELDING_7 = makeShielding(7);
+ public static final ICharm SHIELDING_8 = makeShielding(8);
+ public static final ICharm SHIELDING_9 = makeShielding(9);
+ public static final ICharm SHIELDING_10 = makeShielding(10);
+ public static final ICharm SHIELDING_11 = makeShielding(11);
+ public static final ICharm SHIELDING_12 = makeShielding(12);
+ public static final ICharm SHIELDING_13 = makeShielding(13);
+ public static final ICharm SHIELDING_14 = makeShielding(14);
+ public static final ICharm SHIELDING_15 = makeShielding(15);
+
+ public static final ICharm AEGIS_1 = makeAegis(1);
+ public static final ICharm AEGIS_2 = makeAegis(2);
+ public static final ICharm AEGIS_3 = makeAegis(3);
+ public static final ICharm AEGIS_4 = makeAegis(4);
+ public static final ICharm AEGIS_5 = makeAegis(5);
+ public static final ICharm AEGIS_6 = makeAegis(6);
+ public static final ICharm AEGIS_7 = makeAegis(7);
+ public static final ICharm AEGIS_8 = makeAegis(8);
+ public static final ICharm AEGIS_9 = makeAegis(9);
+ public static final ICharm AEGIS_10 = makeAegis(10);
+ public static final ICharm AEGIS_11 = makeAegis(11);
+ public static final ICharm AEGIS_12 = makeAegis(12);
+ public static final ICharm AEGIS_13 = makeAegis(13);
+ public static final ICharm AEGIS_14 = makeAegis(14);
+ public static final ICharm AEGIS_15 = makeAegis(15);
+
+ public static final ICharm FIRE_IMMUNITY_1 = makeFireImmunity(1);
+ public static final ICharm FIRE_IMMUNITY_2 = makeFireImmunity(2);
+ public static final ICharm FIRE_IMMUNITY_3 = makeFireImmunity(3);
+ public static final ICharm FIRE_IMMUNITY_4 = makeFireImmunity(4);
+ public static final ICharm FIRE_IMMUNITY_5 = makeFireImmunity(5);
+ public static final ICharm FIRE_IMMUNITY_6 = makeFireImmunity(6);
+ public static final ICharm FIRE_IMMUNITY_7 = makeFireImmunity(7);
+ public static final ICharm FIRE_IMMUNITY_8 = makeFireImmunity(8);
+ public static final ICharm FIRE_IMMUNITY_9 = makeFireImmunity(9);
+ public static final ICharm FIRE_IMMUNITY_10 = makeFireImmunity(10);
+ public static final ICharm FIRE_IMMUNITY_11 = makeFireImmunity(11);
+ public static final ICharm FIRE_IMMUNITY_12 = makeFireImmunity(12);
+ public static final ICharm FIRE_IMMUNITY_13 = makeFireImmunity(13);
+ public static final ICharm FIRE_IMMUNITY_14 = makeFireImmunity(14);
+ public static final ICharm FIRE_IMMUNITY_15 = makeFireImmunity(15);
+
+ public static final ICharm FIRE_RESISTENCE_1 = makeFireResistence(1);
+ public static final ICharm FIRE_RESISTENCE_2 = makeFireResistence(2);
+ public static final ICharm FIRE_RESISTENCE_3 = makeFireResistence(3);
+ public static final ICharm FIRE_RESISTENCE_4 = makeFireResistence(4);
+ public static final ICharm FIRE_RESISTENCE_5 = makeFireResistence(5);
+ public static final ICharm FIRE_RESISTENCE_6 = makeFireResistence(6);
+ public static final ICharm FIRE_RESISTENCE_7 = makeFireResistence(7);
+ public static final ICharm FIRE_RESISTENCE_8 = makeFireResistence(8);
+ public static final ICharm FIRE_RESISTENCE_9 = makeFireResistence(9);
+ public static final ICharm FIRE_RESISTENCE_10 = makeFireResistence(10);
+ public static final ICharm FIRE_RESISTENCE_11 = makeFireResistence(11);
+ public static final ICharm FIRE_RESISTENCE_12 = makeFireResistence(12);
+ public static final ICharm FIRE_RESISTENCE_13 = makeFireResistence(13);
+ public static final ICharm FIRE_RESISTENCE_14 = makeFireResistence(14);
+ public static final ICharm FIRE_RESISTENCE_15 = makeFireResistence(15);
+
+ public static final ICharm SATIETY_1 = makeSatiety(1);
+ public static final ICharm SATIETY_2 = makeSatiety(2);
+ public static final ICharm SATIETY_3 = makeSatiety(3);
+ public static final ICharm SATIETY_4 = makeSatiety(4);
+ public static final ICharm SATIETY_5 = makeSatiety(5);
+ public static final ICharm SATIETY_6 = makeSatiety(6);
+ public static final ICharm SATIETY_7 = makeSatiety(7);
+ public static final ICharm SATIETY_8 = makeSatiety(8);
+ public static final ICharm SATIETY_9 = makeSatiety(9);
+ public static final ICharm SATIETY_10 = makeSatiety(10);
+ public static final ICharm SATIETY_11 = makeSatiety(11);
+ public static final ICharm SATIETY_12 = makeSatiety(12);
+ public static final ICharm SATIETY_13 = makeSatiety(13);
+ public static final ICharm SATIETY_14 = makeSatiety(14);
+ public static final ICharm SATIETY_15 = makeSatiety(15);
+
+ public static final ICharm LIFE_STRIKE_1 = makeLifeStrike(1);
+ public static final ICharm LIFE_STRIKE_2 = makeLifeStrike(2);
+ public static final ICharm LIFE_STRIKE_3 = makeLifeStrike(3);
+ public static final ICharm LIFE_STRIKE_4 = makeLifeStrike(4);
+ public static final ICharm LIFE_STRIKE_5 = makeLifeStrike(5);
+ public static final ICharm LIFE_STRIKE_6 = makeLifeStrike(6);
+ public static final ICharm LIFE_STRIKE_7 = makeLifeStrike(7);
+ public static final ICharm LIFE_STRIKE_8 = makeLifeStrike(8);
+ public static final ICharm LIFE_STRIKE_9 = makeLifeStrike(9);
+ public static final ICharm LIFE_STRIKE_10 = makeLifeStrike(10);
+ public static final ICharm LIFE_STRIKE_11 = makeLifeStrike(11);
+ public static final ICharm LIFE_STRIKE_12 = makeLifeStrike(12);
+ public static final ICharm LIFE_STRIKE_13 = makeLifeStrike(13);
+ public static final ICharm LIFE_STRIKE_14 = makeLifeStrike(14);
+ public static final ICharm LIFE_STRIKE_15 = makeLifeStrike(15);
+
+ public static final ICharm REFLECTION_1 = makeReflection(1);
+ public static final ICharm REFLECTION_2 = makeReflection(2);
+ public static final ICharm REFLECTION_3 = makeReflection(3);
+ public static final ICharm REFLECTION_4 = makeReflection(4);
+ public static final ICharm REFLECTION_5 = makeReflection(5);
+ public static final ICharm REFLECTION_6 = makeReflection(6);
+ public static final ICharm REFLECTION_7 = makeReflection(7);
+ public static final ICharm REFLECTION_8 = makeReflection(8);
+ public static final ICharm REFLECTION_9 = makeReflection(9);
+ public static final ICharm REFLECTION_10 = makeReflection(10);
+ public static final ICharm REFLECTION_11 = makeReflection(11);
+ public static final ICharm REFLECTION_12 = makeReflection(12);
+ public static final ICharm REFLECTION_13 = makeReflection(13);
+ public static final ICharm REFLECTION_14 = makeReflection(14);
+ public static final ICharm REFLECTION_15 = makeReflection(15);
+
+ public static final ICharm DRAIN_1 = makeDrain(1);
+ public static final ICharm DRAIN_2 = makeDrain(2);
+ public static final ICharm DRAIN_3 = makeDrain(3);
+ public static final ICharm DRAIN_4 = makeDrain(4);
+ public static final ICharm DRAIN_5 = makeDrain(5);
+ public static final ICharm DRAIN_6 = makeDrain(6);
+ public static final ICharm DRAIN_7 = makeDrain(7);
+ public static final ICharm DRAIN_8 = makeDrain(8);
+ public static final ICharm DRAIN_9 = makeDrain(9);
+ public static final ICharm DRAIN_10 = makeDrain(10);
+ public static final ICharm DRAIN_11 = makeDrain(11);
+ public static final ICharm DRAIN_12 = makeDrain(12);
+ public static final ICharm DRAIN_13 = makeDrain(13);
+ public static final ICharm DRAIN_14 = makeDrain(14);
+ public static final ICharm DRAIN_15 = makeDrain(15);
+
+ public static final ICharm ILLUMINATION_3 = makeIllumination(3);
+ public static final ICharm ILLUMINATION_6 = makeIllumination(6);
+ public static final ICharm ILLUMINATION_9 = makeIllumination(9);
+ public static final ICharm ILLUMINATION_12 = makeIllumination(12);
+ public static final ICharm ILLUMINATION_15 = makeIllumination(15);
+
+ // HARVESTING
+
+ // curses
+ public static final ICharm DECAY_1 = makeDecay(1);
+ public static final ICharm DECAY_3 = makeDecay(3);
+ public static final ICharm DECAY_5 = makeDecay(5);
+ public static final ICharm DECAY_7 = makeDecay(7);
+
+ public static final ICharm DECREPIT_1 = makeDecrepit(1);
+ public static final ICharm DECREPIT_2 = makeDecrepit(2);
+ public static final ICharm DECREPIT_3 = makeDecrepit(3);
+ public static final ICharm DECREPIT_4 = makeDecrepit(4);
+ public static final ICharm DECREPIT_5 = makeDecrepit(5);
+ public static final ICharm DECREPIT_6 = makeDecrepit(6);
+ public static final ICharm DECREPIT_7 = makeDecrepit(7);
+ public static final ICharm DECREPIT_8 = makeDecrepit(8);
+
+ public static final ICharm DIRT_FILL_2 = makeDirtFill(2);
+ public static final ICharm DIRT_FILL_4 = makeDirtFill(4);
+ public static final ICharm DIRT_FILL_6 = makeDirtFill(6);
+
+ public static final ICharm DIRT_WALK_2 = makeDirtWalk(2);
+ public static final ICharm DIRT_WALK_4 = makeDirtWalk(4);
+ public static final ICharm DIRT_WALK_6 = makeDirtWalk(6);
+
+ public static final ICharm RUIN_1 = makeRuin(1);
+ public static final ICharm RUIN_3 = makeRuin(3);
+ public static final ICharm RUIN_5 = makeRuin(5);
+ public static final ICharm RUIN_7 = makeRuin(7);
+ public static final ICharm RUIN_9 = makeRuin(9);
+ public static final ICharm RUIN_11 = makeRuin(11);
+
+ static {
+ // register
+ METAL_REGISTRY.put(COPPER.getName(), COPPER);
+ METAL_REGISTRY.put(SILVER.getName(), SILVER);
+ METAL_REGISTRY.put(GOLD.getName(), GOLD);
+ }
+
+ /**
+ * The gem/sourceItem portion of a charm capability takes in a RegistryName of an Item,
+ * there it needs to be setup and registered in a FML event so that the Items being referenced
+ * are already create and registered.
+ * @param event
+ */
+ public static void setup(FMLCommonSetupEvent event) {
+ TOPAZ = new CharmableMaterial(1, TreasureItems.TOPAZ.getRegistryName(), 4, 1);
+ DIAMOND = new CharmableMaterial(2, Items.DIAMOND.getRegistryName(), 5, 3);
+ ONYX = new CharmableMaterial(3, TreasureItems.ONYX.getRegistryName(), 6, 3);
+ EMERALD = new CharmableMaterial(4, Items.EMERALD.getRegistryName(), 7, 3);
+ RUBY = new CharmableMaterial(5, TreasureItems.RUBY.getRegistryName(), 9, 4);
+ SAPPHIRE = new CharmableMaterial(6, TreasureItems.SAPPHIRE.getRegistryName() , 11, 6);
+ WHITE_PEARL = new CharmableMaterial(7, TreasureItems.WHITE_PEARL.getRegistryName() , 9, 8);
+ BLACK_PEARL = new CharmableMaterial(8, TreasureItems.BLACK_PEARL.getRegistryName() , 11, 10);
+
+ // regerister
+ GEM_REGISTRY.put(DIAMOND.getName(), DIAMOND);
+ GEM_REGISTRY.put(EMERALD.getName(), EMERALD);
+ GEM_REGISTRY.put(TOPAZ.getName(), TOPAZ);
+ GEM_REGISTRY.put(ONYX.getName(), ONYX);
+ GEM_REGISTRY.put(RUBY.getName(), RUBY);
+ GEM_REGISTRY.put(SAPPHIRE.getName(), SAPPHIRE);
+ GEM_REGISTRY.put(WHITE_PEARL.getName(), WHITE_PEARL);
+ GEM_REGISTRY.put(BLACK_PEARL.getName(), WHITE_PEARL);
+ }
+
+ public static Comparator levelComparator = new Comparator() {
+ @Override
+ public int compare(CharmableMaterial p1, CharmableMaterial p2) {
+ return Integer.compare(p1.getMaxLevel(), p2.getMaxLevel());
+ }
+ };
+
+ public static List getGemValues() {
+ return new ArrayList<>(GEM_REGISTRY.values());
+ }
+
+ /**
+ * Convenience method to build Healing Charm.
+ * @param level
+ * @return
+ */
+ public static ICharm makeHealing(int level) {
+ ICharm charm = new HealingCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeGreaterHealing(int level) {
+ ICharm charm = new GreaterHealingCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeShielding(int level) {
+ ICharm charm = new ShieldingCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.percent = level < 4 ? 0.5 : level < 7 ? 0.6 : level < 10 ? 0.7 : 0.8;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeAegis(int level) {
+ ICharm charm = new AegisCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.effectStackable = false;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeFireImmunity(int level) {
+ ICharm charm = new FireImmunityCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.effectStackable = false;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeFireResistence(int level) {
+ ICharm charm = new FireResistenceCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.percent = level < 6 ? 0.3 : level < 11 ? 0.5 : 0.8;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeSatiety(int level) {
+ ICharm charm = new SatietyCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeLifeStrike(int level) {
+ ICharm charm = new LifeStrikeCharm.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.percent = level < 4 ? 1.2 : level < 7 ? 1.4 : level < 10 ? 1.6 : level < 13 ? 1.8 : 2.0;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeReflection(int level) {
+ ICharm charm = new ReflectionCharm.Builder(level).with($ -> {
+ $.value = level < 8 ? (level * 10.0 + 10.0) : ((level -7) * 10.0 + 10.0);
+ $.percent = level < 3 ? 0.2 : level < 5 ? 0.35 : level < 7 ? 0.50 : level <9 ? 0.65 : level < 11 ? 0.8 : level < 13 ? 0.95 : 1.1;
+ $.duration = level < 4 ? 2D : level < 7 ? 3D : level < 10 ? 4D : level < 13 ? 5D : 6D;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeDrain(int level) {
+ ICharm charm = new DrainCharm.Builder(level).with($ -> {
+ $.value = level < 8 ? (level * 10.0 + 10.0) : ((level -7) * 10.0 + 10.0);
+ $.duration = level < 4 ? 2D : level < 7 ? 3D : level < 10 ? 4D : level < 13 ? 5D : 6D;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static ICharm makeIllumination(int level) {
+ ICharm charm = new IlluminationCharm.Builder(level).with($ -> {
+ $.value = level < 4 ? 3D : level < 7 ? 6D : 30D;
+ $.effectStackable = false;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ // curses
+ public static ICharm makeDecay(int level) {
+ ICharm curse = new DecayCurse.Builder(level).with($ -> {
+ $.value = level * 20.0;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(curse);
+ return curse;
+ }
+
+ public static ICharm makeDecrepit(int level) {
+ ICharm curse = new DecrepitCurse.Builder(level).with($ -> {
+ $.value = level * 10.0 + 10.0;
+ $.percent = 1D + ((level + (level % 2))/20);
+// $.duration = 20.0; set in 1.12.2 but not used.
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(curse);
+ return curse;
+ }
+
+ public static ICharm makeDirtFill(int level) {
+ ICharm curse = new DirtFillCurse.Builder(level).with($ -> {
+ $.value = level * 25D;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(curse);
+ return curse;
+ }
+
+ public static ICharm makeDirtWalk(int level) {
+ ICharm curse = new DirtWalkCurse.Builder(level).with($ -> {
+ $.value = level * 25D;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(curse);
+ return curse;
+ }
+
+ public static ICharm makeRuin(int level) {
+ ICharm charm = new RuinCurse.Builder(level).with($ -> {
+ $.value = level *20D;
+ $.duration = level < 4 ? 20D : level < 7 ? 17D : level < 10 ? 15D : level < 13 ? 13D : 10D;
+ $.effectStackable = true;
+ $.rarity = level < 4 ? Rarity.COMMON : level < 7 ? Rarity.UNCOMMON : level < 10 ? Rarity.SCARCE : level < 13 ? Rarity.RARE : Rarity .EPIC;
+ }) .build();
+ TreasureCharmRegistry.register(charm);
+ return charm;
+ }
+
+ public static Optional getBaseMaterial(ResourceLocation name) {
+ if (name != null && METAL_REGISTRY.containsKey(name)) {
+ return Optional.of(METAL_REGISTRY.get(name));
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Accessor wrapper method to return Optional sourceItem
+ * @param name
+ * @return
+ */
+ public static Optional getSourceItem(ResourceLocation sourceItem) {
+ if (sourceItem != null && GEM_REGISTRY.containsKey(sourceItem)) {
+ return Optional.of(GEM_REGISTRY.get(sourceItem));
+ }
+ return Optional.empty();
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/command/CharmItemArgument.java b/src/main/java/com/someguyssoftware/treasure2/command/CharmItemArgument.java
new file mode 100644
index 000000000..9be720dc0
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/command/CharmItemArgument.java
@@ -0,0 +1,16 @@
+package com.someguyssoftware.treasure2.command;
+
+import java.util.concurrent.CompletableFuture;
+
+import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+
+import net.minecraft.command.arguments.ItemArgument;
+
+public class CharmItemArgument extends ItemArgument {
+
+ public CompletableFuture listSuggestions(CommandContext p_listSuggestions_1_, SuggestionsBuilder sb) {
+ return sb.suggest("treasure2:copper_charm").buildFuture();
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/command/SpawnCharmCommand.java b/src/main/java/com/someguyssoftware/treasure2/command/SpawnCharmCommand.java
new file mode 100644
index 000000000..621e851c8
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/command/SpawnCharmCommand.java
@@ -0,0 +1,107 @@
+/**
+ *
+ */
+package com.someguyssoftware.treasure2.command;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import com.mojang.brigadier.suggestion.SuggestionProvider;
+import com.someguyssoftware.gottschcore.loot.LootTableShell;
+import com.someguyssoftware.gottschcore.random.RandomWeightedCollection;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.block.TreasureBlocks;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.data.TreasureData;
+import com.someguyssoftware.treasure2.enums.ChestGeneratorType;
+import com.someguyssoftware.treasure2.enums.Rarity;
+import com.someguyssoftware.treasure2.enums.WorldGenerators;
+import com.someguyssoftware.treasure2.generator.chest.IChestGenerator;
+import com.someguyssoftware.treasure2.item.CharmItem;
+import com.someguyssoftware.treasure2.tileentity.AbstractTreasureChestTileEntity;
+
+import net.minecraft.block.Block;
+import net.minecraft.command.CommandSource;
+import net.minecraft.command.Commands;
+import net.minecraft.command.ISuggestionProvider;
+import net.minecraft.command.arguments.BlockPosArgument;
+import net.minecraft.command.arguments.EntityArgument;
+import net.minecraft.command.arguments.ItemArgument;
+import net.minecraft.command.arguments.ItemInput;
+import net.minecraft.command.arguments.ResourceLocationArgument;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.inventory.ItemStackHelper;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.registry.Registry;
+import net.minecraft.world.server.ServerWorld;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 20, 2021
+ *
+ */
+public class SpawnCharmCommand {
+ public static void register(CommandDispatcher dispatcher) {
+ dispatcher
+ .register(Commands.literal("t2-charm")
+ .requires(source -> {
+ return source.hasPermission(2);
+ })
+ .then(Commands.argument("targets", EntityArgument.players())
+ .then(Commands.argument("charm",ResourceLocationArgument.id())
+ .suggests(SUGGEST_CHARM)
+ .executes((source) -> {
+ return giveCharm(source.getSource(), ResourceLocationArgument.getId(source, "charm"), EntityArgument.getPlayers(source, "targets"), 1);
+ })
+
+ // .then(Commands.argument("pos", BlockPosArgument.blockPos())
+ // .executes(source -> {
+ // return spawn(source.getSource(), BlockPosArgument.getOrLoadBlockPos(source, "pos"), "");
+ // })
+ // .then(Commands.argument("name", StringArgumentType.string())
+ // .suggests(SUGGEST_CHARM).executes(source -> {
+ // return spawn(source.getSource(), BlockPosArgument.getOrLoadBlockPos(source, "pos"),
+ // StringArgumentType.getString(source, "name"));
+ // })
+ // )
+ // )
+ )
+ )
+ );
+ }
+
+ private static final SuggestionProvider SUGGEST_CHARM = (source, builder) -> {
+ return ISuggestionProvider.suggest(Arrays.asList("treasure2:copper_charm", "treasure2:silver_charm", "treasure2:gold_charm").stream(), builder);
+ };
+
+ private static int giveCharm(CommandSource source, ResourceLocation charmLocation, Collection players, int p_198497_3_) throws CommandSyntaxException {
+ Treasure.LOGGER.debug("spawn charm resource location -> {}", charmLocation);
+ // ResourceLocation charmLocation = new ResourceLocation(charmItemName);
+ Item item = Registry.ITEM.getOptional(charmLocation).orElseThrow(IllegalStateException::new);
+ if (item instanceof CharmItem) {
+ for(ServerPlayerEntity player : players) {
+ ItemStack stack = new ItemStack(item, 1);
+ // TODO get capability
+ // TODO add random charms
+
+
+ boolean flag = player.inventory.add(stack);
+// TODO look at give for rest of it.
+ }
+ }
+ return 1;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/command/SpawnChestCommand.java b/src/main/java/com/someguyssoftware/treasure2/command/SpawnChestCommand.java
index b4cf8a0fb..9a6710f60 100644
--- a/src/main/java/com/someguyssoftware/treasure2/command/SpawnChestCommand.java
+++ b/src/main/java/com/someguyssoftware/treasure2/command/SpawnChestCommand.java
@@ -20,6 +20,7 @@
import com.someguyssoftware.treasure2.block.TreasureBlocks;
import com.someguyssoftware.treasure2.data.TreasureData;
import com.someguyssoftware.treasure2.enums.ChestGeneratorType;
+import com.someguyssoftware.treasure2.enums.PitTypes;
import com.someguyssoftware.treasure2.enums.Rarity;
import com.someguyssoftware.treasure2.enums.WorldGenerators;
import com.someguyssoftware.treasure2.generator.chest.IChestGenerator;
@@ -72,6 +73,10 @@ public static List getNames() {
}
}
+ private static final SuggestionProvider SUGGEST_RARITY = (source, builder) -> {
+ return ISuggestionProvider.suggest(Rarity.getNames().stream(), builder);
+ };
+
private static final SuggestionProvider SUGGEST_CHEST = (source, builder) -> {
return ISuggestionProvider.suggest(TreasureData.CHESTS_BY_NAME.keySet().stream(), builder);
};
@@ -84,13 +89,19 @@ public static void register(CommandDispatcher dispatcher) {
})
.then(Commands.argument("pos", BlockPosArgument.blockPos())
.executes(source -> {
- return spawn(source.getSource(), BlockPosArgument.getOrLoadBlockPos(source, "pos"), "");
+ return spawn(source.getSource(), BlockPosArgument.getOrLoadBlockPos(source, "pos"), "", Rarity.COMMON.name());
})
.then(Commands.argument("name", StringArgumentType.string())
.suggests(SUGGEST_CHEST).executes(source -> {
return spawn(source.getSource(), BlockPosArgument.getOrLoadBlockPos(source, "pos"),
- StringArgumentType.getString(source, "name"));
+ StringArgumentType.getString(source, "name"), Rarity.COMMON.name());
})
+ .then(Commands.argument("rarity", StringArgumentType.string())
+ .suggests(SUGGEST_RARITY).executes(source -> {
+ return spawn(source.getSource(), BlockPosArgument.getOrLoadBlockPos(source, "pos"),
+ StringArgumentType.getString(source, "name"), StringArgumentType.getString(source, "rarity"));
+ })
+ )
)
)
);
@@ -103,12 +114,12 @@ public static void register(CommandDispatcher dispatcher) {
* @param name
* @return
*/
- private static int spawn(CommandSource source, BlockPos pos, String name) {
- Treasure.LOGGER.info("executing spawn chest, pos -> {}, name -> {}", pos, name);
+ private static int spawn(CommandSource source, BlockPos pos, String name, String rarityName) {
+ Treasure.LOGGER.info("executing spawn chest, pos -> {}, name -> {}, rarity -> {}", pos, name, rarityName);
try {
ServerWorld world = source.getLevel();
Random random = new Random();
- Rarity rarity = Rarity.COMMON;
+ Rarity rarity = rarityName.isEmpty() ? Rarity.COMMON : Rarity.valueOf(rarityName.toUpperCase());
Optional chests = Optional.empty();
// get the chest world generator
diff --git a/src/main/java/com/someguyssoftware/treasure2/command/TreasureCommands.java b/src/main/java/com/someguyssoftware/treasure2/command/TreasureCommands.java
index fdd2a15e8..55365531b 100644
--- a/src/main/java/com/someguyssoftware/treasure2/command/TreasureCommands.java
+++ b/src/main/java/com/someguyssoftware/treasure2/command/TreasureCommands.java
@@ -23,5 +23,6 @@ public static void onServerStarting(RegisterCommandsEvent event) {
SpawnWellCommand.register(event.getDispatcher());
SpawnRuinsCommand.register(event.getDispatcher());
SpawnProximitySpawnerCommand.register(event.getDispatcher());
+ SpawnCharmCommand.register(event.getDispatcher());
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/config/TreasureConfig.java b/src/main/java/com/someguyssoftware/treasure2/config/TreasureConfig.java
index 9d3c35e21..2f445cc9b 100644
--- a/src/main/java/com/someguyssoftware/treasure2/config/TreasureConfig.java
+++ b/src/main/java/com/someguyssoftware/treasure2/config/TreasureConfig.java
@@ -55,6 +55,7 @@ public class TreasureConfig extends AbstractConfig {
public static final String PITS_CATEGORY = "pits";
public static final String MARKERS_CATEGORY = "markers";
public static final String KEYS_AND_LOCKS_CATEGORY = "keys and locks";
+ public static final String BOOTY_CATEGORY = "booty";
public static final String COINS_CATEGORY = "coins";
public static final String GEMS_AND_ORES_CATEGORY = "gems and ores";
public static final String FOG_CATEGORY = "fog";
@@ -68,6 +69,7 @@ public class TreasureConfig extends AbstractConfig {
public static final Markers MARKERS;
public static final Wells WELLS;
public static final KeysAndLocks KEYS_LOCKS;
+ public static final Booty BOOTY;
public static final Coins COINS;
public static final GemsAndOres GEMS_AND_ORES;
public static final Fog FOG;
@@ -85,6 +87,7 @@ public class TreasureConfig extends AbstractConfig {
MARKERS = new Markers(COMMON_BUILDER);
WELLS = new Wells(COMMON_BUILDER);
KEYS_LOCKS = new KeysAndLocks(COMMON_BUILDER);
+ BOOTY = new Booty(COMMON_BUILDER);
COINS = new Coins(COMMON_BUILDER);
GEMS_AND_ORES = new GemsAndOres(COMMON_BUILDER);
FOG = new Fog(COMMON_BUILDER);
@@ -106,9 +109,11 @@ public TreasureConfig(IMod mod) {
}
public static class ItemID {
-
+ public static final String COPPER_COIN_ID = "copper_coin";
public static final String SILVER_COIN_ID = "silver_coin";
public static final String GOLD_COIN_ID = "gold_coin";
+ public static final String TOPAZ_ID = "topaz";
+ public static final String ONYX_ID = "onyx";
public static final String SAPPHIRE_ID = "sapphire";
public static final String RUBY_ID = "ruby";
public static final String WHITE_PEARL_ID = "white_pearl";
@@ -119,6 +124,10 @@ public static class ItemID {
public static final String SKELETON_ITEM_ID = "skeleton";
public static final String EYE_PATCH_ID = "eye_patch";
public static final String SPANISH_MOSS_ITEM_ID = "spanish_moss_item";
+ public static final String CHARM_BOOK = "charm_book";
+ public static final String COPPER_CHARM = "copper_charm";
+ public static final String SILVER_CHARM = "silver_charm";
+ public static final String GOLD_CHARM = "gold_charm";
}
public static class LockID {
@@ -199,7 +208,9 @@ public static class BlockID {
public static final String SKELETON_ID = "skeleton";
public static final String WITHER_BRANCH_ID = "wither_branch";
- public static final String WITHER_ROOT_ID = "wither_root";
+ public static final String WITHER_ROOT_ID = "wither_root";
+ public static final String TOPAZ_ORE_ID = "topaz_ore";
+ public static final String ONYX_ORE_ID = "onyx_ore";
public static final String RUBY_ORE_ID = "ruby_ore";
public static final String SAPPHIRE_ORE_ID = "sapphire_ore";
public static final String WITHER_BROKEN_LOG_ID = "wither_broken_log";
@@ -210,6 +221,7 @@ public static class BlockID {
public static final String FALLING_GRASS_ID = "falling_grass";
public static final String FALLING_SAND_ID = "falling_sand";
public static final String FALLING_RED_SAND_ID = "falling_red_sand";
+
}
public static class ChestID {
@@ -288,7 +300,9 @@ public static class General {
builder.comment(CATEGORY_DIV, " General properties for Treasure mod.", CATEGORY_DIV).push("general");
enableDefaultLootTablesCheck = builder
- .comment(" Enable/Disable a check to ensure the default loot tables exist on the file system.", "If enabled, then you will not be able to remove any default loot tables (but they can be edited).", "Only disable if you know what you're doing.")
+ .comment(" Enable/Disable a check to ensure the default loot tables exist on the file system.", "If enabled, then you will not be able to remove any default loot tables (but they can be edited).",
+ "This option should be enabled at least for the first run of the mod to create the default settings.",
+ "Only disable if you know what you're doing.")
.define("Enable default loot tables check:", true);
enableDefaultTemplatesCheck = builder
@@ -715,11 +729,26 @@ public static class KeysAndLocks {
}
}
+ public static class Booty {
+ public ForgeConfigSpec.ConfigValue wealthMaxStackSize;
+
+ public Booty(final ForgeConfigSpec.Builder builder) {
+ builder.comment(CATEGORY_DIV, " Treasure Loot and Valuables properties", CATEGORY_DIV)
+ .push(BOOTY_CATEGORY);
+
+ wealthMaxStackSize = builder
+ .comment(" The maximum size of a wealth item stacks. ex. Coins, Gems, Pearls")
+ .defineInRange("Maximum Stack Size:", 8, 1, 64);
+ builder.pop();
+ }
+ }
+
/**
*
* @author Mark Gottschling on Jan 13, 2021
*
*/
+ // TODO replace with Booty
public static class Coins {
// @RequiresMcRestart
public ForgeConfigSpec.ConfigValue coinMaxStackSize;
@@ -738,17 +767,31 @@ public Coins(final ForgeConfigSpec.Builder builder) {
public static class GemsAndOres {
public ForgeConfigSpec.BooleanValue enableGemOreSpawn;
+ public ForgeConfigSpec.ConfigValue topazGenProbability;
+ public ForgeConfigSpec.ConfigValue topazOreMaxY;
+ public ForgeConfigSpec.ConfigValue topazOreMinY;
+ public ForgeConfigSpec.ConfigValue topazOreVeinSize;
+ public ForgeConfigSpec.ConfigValue topazOreVeinsPerChunk;
+
+ public ForgeConfigSpec.ConfigValue onyxGenProbability;
+ public ForgeConfigSpec.ConfigValue onyxOreMaxY;
+ public ForgeConfigSpec.ConfigValue onyxOreMinY;
+ public ForgeConfigSpec.ConfigValue onyxOreVeinSize;
+ public ForgeConfigSpec.ConfigValue onyxOreVeinsPerChunk;
+
public ForgeConfigSpec.ConfigValue rubyGenProbability;
public ForgeConfigSpec.ConfigValue rubyOreMaxY;
public ForgeConfigSpec.ConfigValue rubyOreMinY;
public ForgeConfigSpec.ConfigValue rubyOreVeinSize;
public ForgeConfigSpec.ConfigValue rubyOreVeinsPerChunk;
+
public ForgeConfigSpec.ConfigValue sapphireGenProbability;
public ForgeConfigSpec.ConfigValue sapphireOreMaxY;
public ForgeConfigSpec.ConfigValue sapphireOreMinY;
public ForgeConfigSpec.ConfigValue sapphireOreVeinSize;
public ForgeConfigSpec.ConfigValue sapphireOreVeinsPerChunk;
+ // TODO rename to Ores
public GemsAndOres(final ForgeConfigSpec.Builder builder) {
builder.comment(CATEGORY_DIV, " Gems and Ores properties", CATEGORY_DIV)
.push(GEMS_AND_ORES_CATEGORY);
@@ -759,11 +802,11 @@ public GemsAndOres(final ForgeConfigSpec.Builder builder) {
rubyGenProbability = builder
.comment(" The probability that a ruby ore will spawn.")
- .defineInRange("Probability of ruby ore spawn:", 70.0, 0.0, 100.0);
+ .defineInRange("Probability of ruby ore spawn:", 65.0, 0.0, 100.0);
rubyOreMinY= builder
.comment(" The minimum y-value where a ruby ore can spawn.")
- .defineInRange("Minimum y-value for ruby ore spawn location:", 8, 1, 255);
+ .defineInRange("Minimum y-value for ruby ore spawn location:", 6, 1, 255);
rubyOreMaxY= builder
.comment(" The maximum y-value where a ruby ore can spawn.")
@@ -779,11 +822,11 @@ public GemsAndOres(final ForgeConfigSpec.Builder builder) {
sapphireGenProbability = builder
.comment(" The probability that a sapphire ore will spawn.")
- .defineInRange("Probability of sapphire ore spawn:", 70.0, 0.0, 100.0);
+ .defineInRange("Probability of sapphire ore spawn:", 65.0, 0.0, 100.0);
sapphireOreMinY= builder
.comment(" The minimum y-value where a sapphire ore can spawn.")
- .defineInRange("Minimum y-value for sapphire ore spawn location:", 8, 1, 255);
+ .defineInRange("Minimum y-value for sapphire ore spawn location:", 6, 1, 255);
sapphireOreMaxY= builder
.comment(" The maximum y-value where a sapphire ore can spawn.")
@@ -797,6 +840,46 @@ public GemsAndOres(final ForgeConfigSpec.Builder builder) {
.comment(" The number of sapphire ore veins in a chunk.")
.defineInRange("Sapphire ore veins per chunk:", 1, 3, 20);
+ topazGenProbability = builder
+ .comment(" The probability that a topaz ore will spawn.")
+ .defineInRange("Probability of topaz ore spawn:", 75.0, 0.0, 100.0);
+
+ topazOreMinY= builder
+ .comment(" The minimum y-value where a topaz ore can spawn.")
+ .defineInRange("Minimum y-value for topaz ore spawn location:", 9, 1, 255);
+
+ topazOreMaxY= builder
+ .comment(" The maximum y-value where a topaz ore can spawn.")
+ .defineInRange("Maximum y-value for topaz ore spawn location:", 25, 1, 255);
+
+ topazOreVeinSize = builder
+ .comment(" The number of topaz ore blocks in a vein.")
+ .defineInRange("Topaz ore vein size:", 3, 3, 20);
+
+ topazOreVeinsPerChunk = builder
+ .comment(" The number of topaz ore veins in a chunk.")
+ .defineInRange("Topaz ore veins per chunk:", 1, 1, 20);
+
+ onyxGenProbability = builder
+ .comment(" The probability that a onyx ore will spawn.")
+ .defineInRange("Probability of onyx ore spawn:", 70.0, 0.0, 100.0);
+
+ onyxOreMinY= builder
+ .comment(" The minimum y-value where a onyx ore can spawn.")
+ .defineInRange("Minimum y-value for onyx ore spawn location:", 9, 1, 255);
+
+ onyxOreMaxY= builder
+ .comment(" The maximum y-value where a onyx ore can spawn.")
+ .defineInRange("Maximum y-value for onyx ore spawn location:", 24, 1, 255);
+
+ onyxOreVeinSize = builder
+ .comment(" The number of onyx ore blocks in a vein.")
+ .defineInRange("Onyx ore vein size:", 3, 3, 20);
+
+ onyxOreVeinsPerChunk = builder
+ .comment(" The number of onyx ore veins in a chunk.")
+ .defineInRange("Onyx ore veins per chunk:", 1, 1, 20);
+
builder.pop();
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/enums/Coins.java b/src/main/java/com/someguyssoftware/treasure2/enums/Coins.java
index e962722e8..8b4bafa7e 100644
--- a/src/main/java/com/someguyssoftware/treasure2/enums/Coins.java
+++ b/src/main/java/com/someguyssoftware/treasure2/enums/Coins.java
@@ -13,9 +13,11 @@
* @author Mark Gottschling on Sep 13, 2014
*
*/
+@Deprecated
public enum Coins implements IEnum {
- SILVER(0, "Silver Coin"),
- GOLD(1, "Gold Coin");
+ COPPER(0, "Copper Coin"),
+ SILVER(1, "Silver Coin"),
+ GOLD(2, "Gold Coin");
private static final Map codes = new HashMap();
private static final Map values = new HashMap();
diff --git a/src/main/java/com/someguyssoftware/treasure2/enums/Pearls.java b/src/main/java/com/someguyssoftware/treasure2/enums/Pearls.java
index 4db1b2dea..a57b73574 100644
--- a/src/main/java/com/someguyssoftware/treasure2/enums/Pearls.java
+++ b/src/main/java/com/someguyssoftware/treasure2/enums/Pearls.java
@@ -12,6 +12,7 @@
* @author Mark Gottschling on Aug 18, 2019
*
*/
+@Deprecated
public enum Pearls implements IEnum {
WHITE(0, "White PearlItem"),
BLACK(1, "Black PearlItem");
diff --git a/src/main/java/com/someguyssoftware/treasure2/eventhandler/AnvilEventHandler.java b/src/main/java/com/someguyssoftware/treasure2/eventhandler/AnvilEventHandler.java
index 81675ece9..04c35d23c 100644
--- a/src/main/java/com/someguyssoftware/treasure2/eventhandler/AnvilEventHandler.java
+++ b/src/main/java/com/someguyssoftware/treasure2/eventhandler/AnvilEventHandler.java
@@ -19,11 +19,21 @@
*/
package com.someguyssoftware.treasure2.eventhandler;
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.CHARMABLE;
import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.DURABILITY_CAPABILITY;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+
import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
import com.someguyssoftware.treasure2.capability.IDurabilityCapability;
+import com.someguyssoftware.treasure2.capability.TreasureCapabilities;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+import com.someguyssoftware.treasure2.item.KeyItem;
+import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.AnvilUpdateEvent;
@@ -45,8 +55,12 @@ public static void onAnvilUpdate(AnvilUpdateEvent event) {
ItemStack leftItemStack = event.getLeft();
ItemStack rightItemStack = event.getRight();
- if (leftItemStack.getCapability(DURABILITY_CAPABILITY).isPresent()
- && rightItemStack.getCapability(DURABILITY_CAPABILITY).isPresent()) {
+// Treasure.LOGGER.debug("is imbuing -> {}", leftItemStack.getCapability(CHARMABLE).map(cap -> cap.isImbuing()).orElse(false));
+// Treasure.LOGGER.debug("is imbuable -> {}", rightItemStack.getCapability(CHARMABLE).map(cap -> cap.isImbuable()).orElse(false));
+
+ // check for KeyItems and having the durability capability
+ if (leftItemStack.getItem() instanceof KeyItem && leftItemStack.getCapability(DURABILITY_CAPABILITY).isPresent()
+ && rightItemStack.getItem() instanceof KeyItem && rightItemStack.getCapability(DURABILITY_CAPABILITY).isPresent()) {
event.setCost(1);
LazyOptional leftItemCap = leftItemStack.getCapability(DURABILITY_CAPABILITY);
LazyOptional rightItemCap = rightItemStack.getCapability(DURABILITY_CAPABILITY);
@@ -78,6 +92,87 @@ public static void onAnvilUpdate(AnvilUpdateEvent event) {
}
event.setOutput(outputItem);
}
+ // else check for Book -> Charm or Book -> Adornment
+// else if (leftItemStack.getItem() instanceof CharmBook && rightItemStack.getCapability(TreasureCapabilities.CHARMABLE).isPresent()) {}
+
+ // TODO add logging
+ // TODO reenable when add adornments
+// else if (leftItemStack.getCapability(CHARMABLE).map(cap -> cap.isImbuing()).orElse(false) &&
+// rightItemStack.getCapability(CHARMABLE).map(cap -> cap.isImbuable()).orElse(false)) {
+// event.setCost(1);
+// if (Treasure.LOGGER.isDebugEnabled()) {
+// Treasure.LOGGER.debug("book -> charm");
+// }
+// doImbueItem(event, leftItemStack, rightItemStack);
+// }
+ }
+
+ /**
+ *
+ * @param left
+ * @param right
+ * @return
+ * @return
+ */
+ public static void doImbueItem(AnvilUpdateEvent event, ItemStack left, ItemStack right) {
+// ItemStack outputItem = new ItemStack(right.getItem());
+
+ // TODO determine if the right is a high enough level
+ left.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(leftCap -> {
+ Treasure.LOGGER.debug("have left cap");
+ right.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(rightCap -> {
+ Treasure.LOGGER.debug("have right cap");
+ ICharmEntity leftEntity = leftCap.getCharmEntities()[InventoryType.INNATE.getValue()].get(0);
+ if (Treasure.LOGGER.isDebugEnabled()) {
+ Treasure.LOGGER.debug("leftEntity.level -> {}, rightCap.maxLevel -> {}", leftEntity.getCharm().getLevel(), rightCap.getMaxCharmLevel());
+ }
+ if (rightCap.getMaxCharmLevel() >= leftEntity.getCharm().getLevel()) {
+ Treasure.LOGGER.debug("charm can take imbuing");
+
+ Optional output;
+ if (rightCap.isSource()) {
+ Treasure.LOGGER.debug("charm is a source -> do innate");
+ // TODO create method. all the same steps, just different inventories
+ // check the innate size
+// if (rightCap.getCharmEntities()[InventoryType.INNATE.getValue()].size() < rightCap.getMaxInnateSize()) {
+// outputItem.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(outputCap -> {
+// // copy existing charms from right to output
+// outputCap.setCharmEntities(rightCap.getCharmEntities());
+// // copy left charm to output innate
+// outputCap.add(InventoryType.INNATE, leftEntity);
+// // TODO set the output
+// });
+// }
+ output = createCharmOutputStack(right.getItem(), leftEntity, rightCap, InventoryType.INNATE);
+ }
+ else {
+ Treasure.LOGGER.debug("charm is not a source -> do imbue");
+ // check the imbue size
+ output = createCharmOutputStack(right.getItem(), leftEntity, rightCap, InventoryType.IMBUE);
+ }
+ if (output.isPresent()) {
+ Treasure.LOGGER.debug("output is present");
+ event.setOutput(output.get());
+ }
+ }
+ });
+ });
+ }
+
+ private static Optional createCharmOutputStack(Item item, ICharmEntity entity, ICharmableCapability rightCap, InventoryType type) {
+ ItemStack outputStack = new ItemStack(item);
+ AtomicReference stackRef = new AtomicReference<>();
+ if (rightCap.getCharmEntities()[type.getValue()].size() < rightCap.getMaxSize(type)) {
+ outputStack.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(outputCap -> {
+ // copy existing charms from right to output
+ outputCap.setCharmEntities(rightCap.getCharmEntities());
+ // copy left charm to output innate
+ outputCap.add(type, entity);
+ // reference the output
+ stackRef.set(outputStack);
+ });
+ }
+ return stackRef.get() == null ? Optional.empty() : Optional.of(stackRef.get());
}
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/eventhandler/PlayerEventHandler.java b/src/main/java/com/someguyssoftware/treasure2/eventhandler/PlayerEventHandler.java
index 83b5d80fb..c321179de 100644
--- a/src/main/java/com/someguyssoftware/treasure2/eventhandler/PlayerEventHandler.java
+++ b/src/main/java/com/someguyssoftware/treasure2/eventhandler/PlayerEventHandler.java
@@ -1,24 +1,317 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.eventhandler;
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.someguyssoftware.gottschcore.spatial.Coords;
import com.someguyssoftware.gottschcore.world.WorldInfo;
import com.someguyssoftware.treasure2.Treasure;
-import com.someguyssoftware.treasure2.item.CoinItem;
-import com.someguyssoftware.treasure2.item.PearlItem;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.capability.TreasureCapabilities;
+import com.someguyssoftware.treasure2.charm.CharmContext;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+import com.someguyssoftware.treasure2.charm.TreasureCharms;
+import com.someguyssoftware.treasure2.item.IWishable;
+import com.someguyssoftware.treasure2.network.CharmMessageToClient;
+import com.someguyssoftware.treasure2.network.TreasureNetworking;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.Hand;
+import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.entity.item.ItemTossEvent;
+import net.minecraftforge.event.entity.living.LivingDamageEvent;
+import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
+import net.minecraftforge.event.entity.living.LivingHurtEvent;
+import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
+import net.minecraftforge.fml.network.PacketDistributor;
+import top.theillusivec4.curios.api.CuriosApi;
+import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
+import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
/**
* @author Mark Gottschling on Apr 26, 2018
*
*/
-//@Mod.EventBusSubscriber(modid = Treasure.MODID, bus = EventBusSubscriber.Bus.FORGE)
+@Mod.EventBusSubscriber(modid = Treasure.MODID, bus = EventBusSubscriber.Bus.FORGE)
public class PlayerEventHandler {
+ private static final String CURIOS_ID = "curios";
+ private static final List CURIOS_SLOTS = Arrays.asList("necklace", "bracelet", "ring", "charm");
+
+ /*
+ * Subscribing to multiple types of Living events for Charm Interactions so that instanceof doesn't have to be called everytime.
+ */
+
+ /**
+ *
+ * @param event
+ */
+ @SubscribeEvent
+ public static void checkCharmsInteraction(LivingUpdateEvent event) {
+ if (WorldInfo.isClientSide(event.getEntity().level)) {
+ return;
+ }
+
+ // do something to player every update tick:
+ if (event.getEntity() instanceof PlayerEntity) {
+
+ // get the player
+ ServerPlayerEntity player = (ServerPlayerEntity) event.getEntity();
+ processCharms(event, player);
+ }
+ }
+
+ /**
+ *
+ * @param event
+ */
+ @SubscribeEvent
+ public void checkCharmsInteractionWithDamage(LivingDamageEvent event) {
+ if (WorldInfo.isClientSide(event.getEntity().level)) {
+ return;
+ }
+
+ // do something to player every update tick:
+ if (event.getEntity() instanceof PlayerEntity) {
+ // get the player
+ ServerPlayerEntity player = (ServerPlayerEntity) event.getEntity();
+ processCharms(event, player);
+ }
+ }
+
+ /**
+ *
+ * @param event
+ */
+ @SubscribeEvent
+ public void checkCharmsInteractionWithAttack(LivingHurtEvent event) {
+ if (WorldInfo.isClientSide(event.getEntity().level)) {
+ return;
+ }
+
+ if (event.getSource().getDirectEntity() instanceof PlayerEntity) {
+ // get the player
+ ServerPlayerEntity player = (ServerPlayerEntity) event.getSource().getDirectEntity();
+ processCharms(event, player);
+ }
+ }
+
+ // Maybe use BlockEvent.BreakBlock and then use Global Loot Modifiers??
+ // @SubscribeEvent
+ // public void checkCharmsInteractionWithBlock(BlockEvent.HarvestDropsEvent event) {
+ // if (WorldInfo.isClientSide(event.getWorld())) {
+ // return;
+ // }
+ //
+ // if (event.getHarvester() == null) {
+ // return;
+ // }
+ //
+ // // if the harvested blcok has a tile entity then don't process
+ // // NOTE this may exclude non-inventory blocks
+ // IBlockState harvestedState = event.getState();
+ // Block harvestedBlock = harvestedState.getBlock();
+ // if (harvestedBlock.hasTileEntity(harvestedState)) {
+ // return;
+ // }
+ //
+ // // get the player
+ // EntityPlayerMP player = (EntityPlayerMP) event.getHarvester();
+ // processCharms(event, player);
+ // }
+
+ /**
+ *
+ * @param event
+ * @param player
+ */
+ private static void processCharms(Event event, ServerPlayerEntity player) {
+ /*
+ * a list of charm contexts to execute
+ */
+ List charmsToExecute;
+
+ // gather all charms
+ charmsToExecute = gatherCharms(event, player);
+
+ // TODO filter charms ??
+
+ // sort charms
+ Collections.sort(charmsToExecute, CharmContext.priorityComparator);
+
+ // execute charms
+ executeCharms(event, player, charmsToExecute);
+ }
+
+ /**
+ * Examine and collect all Charms (not CharmEntity nor CharmItems) that the player has in valid slots.
+ * @param event
+ * @param player
+ * @return
+ */
+ private static List gatherCharms(Event event, ServerPlayerEntity player) {
+ final List contexts = new ArrayList<>(5);
+
+ // get the slot provider - curios (general slots) or minecraft (hotbar)
+ String slotProviderId = ModList.get().isLoaded(CURIOS_ID) ? CURIOS_ID : "minecaft";
+
+ // check each hand
+ for (Hand hand : Hand.values()) {
+ ItemStack heldStack = player.getItemInHand(hand);
+// Treasure.LOGGER.debug("is executing -> {}", heldStack.getCapability(CHARMABLE).map(cap -> cap.isExecuting()).orElse(false));
+ if (heldStack.getCapability(CHARMABLE).map(cap -> cap.isExecuting()).orElse(false)) {
+ heldStack.getCapability(CHARMABLE).ifPresent(cap -> {
+ for (InventoryType type : InventoryType.values()) {
+ AtomicInteger index = new AtomicInteger();
+ // requires indexed for-loop
+ for (int i = 0; i < cap.getCharmEntities()[type.getValue()].size(); i++) {
+ ICharmEntity entity = cap.getCharmEntities()[type.getValue()].get(i);
+ // OR just check with the charm for allowable event
+ // if (!TreasureCharms.isCharmEventRegistered(event.getClass(), entity.getCharm().getType())) {
+ if (!entity.getCharm().getRegisteredEvent().equals(event.getClass())) {
+// Treasure.LOGGER.debug("charm type -> {} is not register for this event -> {}", entity.getCharm().getType(), event.getClass().getSimpleName());
+ continue;
+ }
+ index.set(i);
+ CharmContext context = new CharmContext.Builder().with($ -> {
+ $.hand = hand;
+ $.itemStack = heldStack;
+ $.capability = cap;
+ $.type = type;
+ $.index = index.get();
+ $.entity = entity;
+ }).build();
+ contexts.add(context);
+ }
+ }
+ });
+ }
+ }
+
+ // check slots
+ if (slotProviderId.equals(CURIOS_ID)) {
+ // check curio slots
+ LazyOptional handler = CuriosApi.getCuriosHelper().getCuriosHandler(player);
+ handler.ifPresent(itemHandler -> {
+ // curios type names -> head, necklace, back, bracelet, hands, ring, belt, charm, feet
+ CURIOS_SLOTS.forEach(slot -> {
+ Optional stacksOptional = itemHandler.getStacksHandler(slot);
+ stacksOptional.ifPresent(stacksHandler -> {
+ ItemStack curiosStack = stacksHandler.getStacks().getStackInSlot(0);
+ curiosStack.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(cap -> {
+ for (InventoryType type : InventoryType.values()) {
+ AtomicInteger index = new AtomicInteger();
+ // requires indexed for-loop
+ for (int i = 0; i < cap.getCharmEntities()[type.getValue()].size(); i++) {
+ ICharmEntity entity = cap.getCharmEntities()[type.getValue()].get(i);
+ // if (!TreasureCharms.isCharmEventRegistered(event.getClass(), entity.getCharm().getType())) {
+ if (!entity.getCharm().getRegisteredEvent().equals(event.getClass())) {
+ // Treasure.LOGGER.debug("charm type -> {} is not register for this event -> {}", entity.getCharm().getType(), event.getClass().getSimpleName());
+ continue;
+ }
+ index.set(i);
+ CharmContext curiosContext = new CharmContext.Builder().with($ -> {
+ $.slotProviderId = slotProviderId;
+ $.slot = slot;
+ $.itemStack = curiosStack;
+ $.capability = cap;
+ $.type = type;
+ $.index = index.get();
+ $.entity = entity;
+ }).build();
+ contexts.add(curiosContext);
+ }
+ }
+ });
+ });
+ });
+ });
+ }
+ else {
+ // TODO check hotbar slots
+ // TODO only allow IAdornments from hotbar
+ }
+ return contexts;
+ }
+
+ /**
+ *
+ * @param event
+ * @param player
+ * @param contexts
+ */
+ private static void executeCharms(Event event, ServerPlayerEntity player, List contexts) {
+ /*
+ * a list of charm types that are non-stackable that should not be executed more than once.
+ */
+ final List executeOnceCharmTypes = new ArrayList<>(5);
+
+ contexts.forEach(context -> {
+ ICharm charm = (ICharm)context.getEntity().getCharm();
+ if (!charm.isEffectStackable()) {
+ // check if this charm type is already in the monitored list
+ if (executeOnceCharmTypes.contains(charm.getType())) {
+ return;
+ }
+ else {
+ Treasure.LOGGER.debug("adding charm to execute once list");
+ // add the charm type to the monitored list
+ executeOnceCharmTypes.add(charm.getType());
+ }
+ }
+
+ // if charm is executable and executes successfully
+ if (context.getEntity().getCharm().update(player.level, new Random(), new Coords(player.position()), player, event, context.getEntity())) {
+ // send state message to client
+ CharmMessageToClient message = new CharmMessageToClient(player.getStringUUID(), context);
+ TreasureNetworking.simpleChannel.send(PacketDistributor.PLAYER.with(() -> player), message);
+ }
+
+ // remove if uses are empty and the capability is bindable ie. charm, not adornment
+ // NOTE this leaves empty charms on non-bindables for future recharge
+ if (context.getEntity().getValue() <= 0.0 && context.getCapability().isBindable()) {
+ Treasure.LOGGER.debug("charm is empty -> remove");
+ // TODO call cap.remove() -> recalcs highestLevel
+ // locate the charm from context and remove
+ // context.getCapability().getCharmEntities()[context.getType().getValue()].remove(context.getIndex());
+ context.getCapability().remove(context.getType(), context.getIndex());
+ }
+ });
+ }
/**
*
@@ -29,15 +322,23 @@ public void onTossCoinEvent(ItemTossEvent event) {
if (WorldInfo.isClientSide(event.getPlayer().level)) {
return;
}
- Treasure.LOGGER.debug("is remote? -> {}", !event.getPlayer().level.isClientSide);
-Treasure.LOGGER.debug("{} tossing coin -> {}", event.getPlayer().getName().getString(), event.getEntityItem().getItem().getDisplayName());
+ // Treasure.LOGGER.debug("is remote? -> {}", !event.getPlayer().level.isClientSide);
+ // Treasure.LOGGER.debug("{} tossing item -> {}", event.getPlayer().getName().getString(), event.getEntityItem().getItem().getDisplayName().getString());
Item item = event.getEntityItem().getItem().getItem();
- if (item instanceof /*IWishable*/CoinItem || item instanceof PearlItem) {
+ if (item instanceof IWishable) {
ItemStack stack = event.getEntityItem().getItem();
CompoundNBT nbt = new CompoundNBT();
- nbt.putString(CoinItem.DROPPED_BY_KEY, event.getPlayer().getName().getString());
- Treasure.LOGGER.debug("adding tag to coin stack...");
+ nbt.putString(IWishable.DROPPED_BY_KEY, event.getPlayer().getName().getString());
+ // Treasure.LOGGER.debug("adding tag to wishable stack...");
stack.setTag(nbt);
}
}
+
+ // TODO test - remove
+ // @SubscribeEvent
+ // public void onItemInfo(ItemTooltipEvent event) {
+ // if (event.getItemStack().getItem() == Items.EMERALD) {
+ // event.getToolTip().add(new TranslationTextComponent("tooltip.label.coin").withStyle(TextFormatting.GOLD, TextFormatting.ITALIC));
+ // }
+ // }
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/generator/chest/IChestGenerator.java b/src/main/java/com/someguyssoftware/treasure2/generator/chest/IChestGenerator.java
index 3abda259e..884ef24c1 100644
--- a/src/main/java/com/someguyssoftware/treasure2/generator/chest/IChestGenerator.java
+++ b/src/main/java/com/someguyssoftware/treasure2/generator/chest/IChestGenerator.java
@@ -252,7 +252,9 @@ default public void fillChest(final World world, Random random, final TileEntity
if (lootPool != null) {
// geneate loot from pools
- if (pool.getName().equalsIgnoreCase("treasure")) {
+ if (pool.getName().equalsIgnoreCase("treasure") ||
+ pool.getName().equalsIgnoreCase("charms")) {
+ LOGGER.debug("generating loot from treasure/charm pool -> {}", pool.getName());
lootPool.addRandomItems(treasureStacks::add, lootContext);
}
else {
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/PouchContainerScreen.java b/src/main/java/com/someguyssoftware/treasure2/gui/PouchContainerScreen.java
new file mode 100644
index 000000000..990276c21
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/PouchContainerScreen.java
@@ -0,0 +1,91 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.gui;
+
+import java.awt.Color;
+
+import com.mojang.blaze3d.matrix.MatrixStack;
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.inventory.PouchContainer;
+
+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;
+/**
+ *
+ * @author Mark Gottschling on May 14, 2020
+ *
+ */
+public class PouchContainerScreen extends ContainerScreen {
+ // This is the resource location for the background image for the GUI
+ private static final ResourceLocation TEXTURE = new ResourceLocation(Treasure.MODID, "textures/gui/container/pouch.png");
+
+ /**
+ *
+ * @param screenContainer
+ * @param playerInventory
+ * @param title
+ */
+ public PouchContainerScreen(PouchContainer screenContainer, PlayerInventory playerInventory,
+ ITextComponent title) {
+ super(screenContainer, playerInventory, title);
+ // Set the width and height of the gui. Should match the size of the TEXTURE!
+ imageWidth = 177;
+ imageHeight = 200;
+ }
+
+ @Override
+ public void render(MatrixStack matrix, int mouseX, int mouseY, float p_230430_4_) {
+ this.renderBackground(matrix);
+ super.render(matrix, mouseX, mouseY, p_230430_4_);
+ this.renderTooltip(matrix, mouseX, mouseY);
+ }
+
+ /**
+ * Draw the foreground layer for the GuiContainer (everything in front of the items)
+ * Taken directly from ChestScreen
+ */
+ @Override
+ public void renderLabels(MatrixStack matrixStack, int mouseX, int mouseY ) {
+ final float LABEL_XPOS = 5;
+ final float FONT_Y_SPACING = 10;
+ final float CHEST_LABEL_YPOS = 5;
+ font.draw(matrixStack, this.title.getString(), LABEL_XPOS, CHEST_LABEL_YPOS, Color.darkGray.getRGB());
+ final float PLAYER_INV_LABEL_YPOS = getMenu().getPlayerInventoryYPos() - FONT_Y_SPACING;
+ this.font.draw(matrixStack, this.inventory.getDisplayName().getString(),
+ LABEL_XPOS, PLAYER_INV_LABEL_YPOS, Color.darkGray.getRGB());
+ }
+
+ @Override
+ protected void renderBg(MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) {
+ RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+ this.minecraft.getTextureManager().bind(TEXTURE);
+
+ // width and height are the size provided to the window when initialised after creation.
+ // xSize, ySize are the expected size of the TEXTURE-? usually seems to be left as a default.
+ // The code below is typical for vanilla containers, so I've just copied that- it appears to centre the TEXTURE within
+ // the available window
+ int edgeSpacingX = (this.width - this.imageWidth) / 2;
+ int edgeSpacingY = (this.height - this.imageHeight) / 2;
+ this.blit(matrixStack, edgeSpacingX, edgeSpacingY, 0, 0, this.imageWidth, this.imageHeight);
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/TreasureGuis.java b/src/main/java/com/someguyssoftware/treasure2/gui/TreasureGuis.java
index 9bee6044c..1d8831a39 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/TreasureGuis.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/TreasureGuis.java
@@ -68,6 +68,7 @@ public static void onClientSetupEvent(FMLClientSetupEvent event) {
ScreenManager.register(TreasureContainers.COMPRESSOR_CHEST_CONTAINER_TYPE, CompressorChestContainerScreen::new);
ScreenManager.register(TreasureContainers.KEY_RING_CONTAINER_TYPE, KeyRingContainerScreen::new);
+ ScreenManager.register(TreasureContainers.POUCH_CONTAINER_TYPE, PouchContainerScreen::new);
// tell the renderer that the base is rendered using CUTOUT_MIPPED (to match the Block Hopper)
RenderTypeLookup.setRenderLayer(TreasureBlocks.WOOD_CHEST, RenderType.cutoutMipped());
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/AbstractChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/AbstractChestTileEntityRenderer.java
index 81cda077e..f3a7a5afc 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/AbstractChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/AbstractChestTileEntityRenderer.java
@@ -1,5 +1,21 @@
-/**
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
*
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
*/
package com.someguyssoftware.treasure2.gui.render.tileentity;
@@ -20,8 +36,6 @@
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.math.vector.Vector3d;
-import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.World;
/**
@@ -71,21 +85,31 @@ public void render(AbstractTreasureChestTileEntity tileEntity, float partialTick
// push the current transformation matrix + normals matrix
matrixStack.pushPose();
+ // initial position (centered moved up)
+ updateTranslation(matrixStack);
+
// The model is defined centred on [0,0,0], so if we drew it at the current render origin, its centre would be
// at the corner of the block, sunk halfway into the ground and overlapping into the adjacent blocks.
// We want it to hover above the centre of the hopper base, so we need to translate up and across to the desired position
- final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 1.5, 0.5);
- matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z); // translate
+ // final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 1.5, 0.5);
+ // matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z); // translate
+
+ // setup scale
matrixStack.scale(-1, -1, 1);
- float f = getHorizontalAngle(facing);
- matrixStack.mulPose(Vector3f.YP.rotationDegrees(-f));
+
+ // adjust the scale of the model
+ updateScale(matrixStack);
+
+ updateRotation(matrixStack, facing);
+ // float f = getHorizontalAngle(facing);
+ // matrixStack.mulPose(Vector3f.YP.rotationDegrees(-f));
// TEST scale to half size to see if locks are rendered
// matrixStack.scale(0.5F, 0.5F, 0.5F);
// update the lid rotation
- updateModelRotationAngles(tileEntity, partialTicks);
+ updateModelLidRotation(tileEntity, partialTicks);
IVertexBuilder renderBuffer = renderTypeBuffer.getBuffer(model.getChestRenderType(getTexture()));
@@ -128,73 +152,16 @@ public void renderLocks(AbstractTreasureChestTileEntity tileEntity, MatrixStack
// of the block
matrixStack.translate(lockState.getSlot().getXOffset(), lockState.getSlot().getYOffset(), lockState.getSlot().getZOffset());
- matrixStack.mulPose(Vector3f.YP.rotationDegrees(lockState.getSlot().getRotation()));
- matrixStack.scale(getLocksScaleModifier(), getLocksScaleModifier(), getLocksScaleModifier());
+ updateLockRotation(matrixStack, lockState);
+ // matrixStack.mulPose(Vector3f.YP.rotationDegrees(lockState.getSlot().getRotation()));
+ updateLockScale(matrixStack);
+ // matrixStack.scale(getLocksScaleModifier(), getLocksScaleModifier(), getLocksScaleModifier());
Minecraft.getInstance().getItemRenderer().renderStatic(lockStack, ItemCameraTransforms.TransformType.NONE, combinedLight, OverlayTexture.NO_OVERLAY, matrixStack, renderBuffer);
matrixStack.popPose();
}
}
}
- /**
- *
- * @param tileEntity
- * @param partialTicks
- */
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
- float lidRotation = tileEntity.prevLidAngle + (tileEntity.lidAngle - tileEntity.prevLidAngle) * partialTicks;
- lidRotation = 1.0F - lidRotation;
- lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
- model.getLid().xRot = -(lidRotation * (float) Math.PI / getAngleModifier());
- }
-
- /**
- * Modifies the max angle that the lid can swing.
- * The max swing angle by default is 180 degrees. The max swing angle is divided the modifier.
- * Increasing the size of the modifier reduces the size of the max swing angle.
- * Ex:
- * Return 2.0 = 90 degrees
- * Return 3.0 = 60 degrees
- * Return 4.0 = 45 degrees
- *
- * @return
- */
- public float getAngleModifier() {
- return 2.0F;
- }
-
- /**
- * Modifies teh scale of the Lock item(s).
- * Ranges from 0.0F to x.xF.
- * Ex:
- * Return 1.0F = full size
- * Return 0.5 = half size
- *
- * @return
- */
- public float getLocksScaleModifier() {
- return 0.5F;
- }
-
- /**
- * Helper method since all my models face the opposite direction of vanilla models
- * @param meta
- * @return
- */
- public int getHorizontalAngle(Direction facing) {
- switch (facing) {
- default:
- case NORTH:
- return 0;
- case SOUTH:
- return 180;
- case WEST:
- return 90;
- case EAST:
- return -90;
- }
- }
-
/**
* @return the texture
*/
@@ -203,8 +170,7 @@ public ResourceLocation getTexture() {
}
/**
- * @param texture
- * the texture to set
+ * @param texture the texture to set
*/
public void setTexture(ResourceLocation texture) {
this.texture = texture;
@@ -213,16 +179,16 @@ public void setTexture(ResourceLocation texture) {
/**
* @return the model
*/
+ @Override
public ITreasureChestModel getModel() {
return model;
}
/**
- * @param model
- * the model to set
+ * @param model the model to set
*/
+ @Override
public void setModel(ITreasureChestModel model) {
this.model = model;
}
-
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CardboardBoxTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CardboardBoxTileEntityRenderer.java
index 1453d4854..c5d9a4750 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CardboardBoxTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CardboardBoxTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.mojang.blaze3d.matrix.MatrixStack;
@@ -34,13 +53,8 @@ public CardboardBoxTileEntityRenderer(TileEntityRendererDispatcher tileEntityRen
}
@Override
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
+ public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
CardboardBoxTileEntity cte = (CardboardBoxTileEntity) tileEntity;
-// float lidRotation = cte.prevLidAngle + (cte.lidAngle - cte.prevLidAngle) * partialTicks;
-// lidRotation = 1.0F - lidRotation;
-// lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
-// // NOTE positive rotation here (getLid() returns lidLeft property)
-// getModel().getLid().zRot = (lidRotation * (float)Math.PI / getAngleModifier());
// update in the inner lid
float innerLidRotation = cte.prevInnerLidAngle + (cte.innerLidAngle - cte.prevInnerLidAngle) * partialTicks;
@@ -60,34 +74,13 @@ public float getAngleModifier() {
}
@Override
- public void renderLocks(AbstractTreasureChestTileEntity te, MatrixStack matrixStack, IRenderTypeBuffer renderBuffer, int combinedLight, int combinedOverlay) {
- // Treasure.LOGGER.debug("=====================================================================");
- if (te.getLockStates().isEmpty()) {
- return;
- }
-
- // render locks
- for (LockState lockState : te.getLockStates()) {
- if (lockState.getLock() != null) {
- // convert lock to an item stack
- ItemStack lockStack = new ItemStack(lockState.getLock());
-
- matrixStack.pushPose();
-
- // NOTE when rotating the item to match the face of chest, must adjust the
- // amount of offset to the x,z axises and
- // not rotate() the item - rotate() just spins it in place, not around the axis
- // of the block
- matrixStack.translate(lockState.getSlot().getXOffset(), lockState.getSlot().getYOffset(), lockState.getSlot().getZOffset());
-
- // rotate the locks on the x axis to lay flat
- matrixStack.mulPose(Vector3f.XP.rotationDegrees(90)); // NOTE changed from Y to X axis
- matrixStack.mulPose(Vector3f.ZP.rotationDegrees(lockState.getSlot().getRotation())); // NOTE now Z axis is the Y axis since we rotated on the X axis first.
- matrixStack.scale(0.35F, 0.35F, 0.35F);
- Minecraft.getInstance().getItemRenderer().renderStatic(lockStack, ItemCameraTransforms.TransformType.NONE, combinedLight, OverlayTexture.NO_OVERLAY, matrixStack, renderBuffer);
- matrixStack.popPose();
+ public void updateLockRotation(MatrixStack matrixStack, LockState lockState) {
+ matrixStack.mulPose(Vector3f.XP.rotationDegrees(90)); // NOTE changed from Y to X axis
+ matrixStack.mulPose(Vector3f.ZP.rotationDegrees(lockState.getSlot().getRotation())); // NOTE now Z axis is the Y axis since we rotated on the X axis first.
+ }
- }
- }
+ @Override
+ public float getLockScaleModifier() {
+ return 0.35F;
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CauldronChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CauldronChestTileEntityRenderer.java
index b2e1ed9e6..9a0cd8573 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CauldronChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CauldronChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.mojang.blaze3d.matrix.MatrixStack;
@@ -29,7 +48,7 @@ public CauldronChestTileEntityRenderer(TileEntityRendererDispatcher tileEntityRe
}
@Override
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
+ public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
CauldronChestTileEntity cte = (CauldronChestTileEntity) tileEntity;
float lidRotation = cte.prevLidAngle + (cte.lidAngle - cte.prevLidAngle) * partialTicks;
lidRotation = 1.0F - lidRotation;
@@ -39,34 +58,14 @@ public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity
}
@Override
- public void renderLocks(AbstractTreasureChestTileEntity te, MatrixStack matrixStack, IRenderTypeBuffer renderBuffer, int combinedLight, int combinedOverlay) {
- // Treasure.LOGGER.debug("=====================================================================");
- if (te.getLockStates().isEmpty()) {
- return;
- }
-
- // render locks
- for (LockState lockState : te.getLockStates()) {
- if (lockState.getLock() != null) {
- // convert lock to an item stack
- ItemStack lockStack = new ItemStack(lockState.getLock());
-
- matrixStack.pushPose();
-
- // NOTE when rotating the item to match the face of chest, must adjust the
- // amount of offset to the x,z axises and
- // not rotate() the item - rotate() just spins it in place, not around the axis
- // of the block
- matrixStack.translate(lockState.getSlot().getXOffset(), lockState.getSlot().getYOffset(), lockState.getSlot().getZOffset());
-
- // rotate the locks on the x axis to lay flat
- matrixStack.mulPose(Vector3f.XP.rotationDegrees(90)); // NOTE changed from Y to X axis
- matrixStack.mulPose(Vector3f.ZP.rotationDegrees(lockState.getSlot().getRotation())); // NOTE now Z axis is the Y axis since we rotated on the X axis first.
- matrixStack.scale(0.35F, 0.35F, 0.35F);
- Minecraft.getInstance().getItemRenderer().renderStatic(lockStack, ItemCameraTransforms.TransformType.NONE, combinedLight, OverlayTexture.NO_OVERLAY, matrixStack, renderBuffer);
- matrixStack.popPose();
+ public void updateLockRotation(MatrixStack matrixStack, LockState lockState) {
+ // rotate the locks on the x axis to lay flat
+ matrixStack.mulPose(Vector3f.XP.rotationDegrees(90)); // NOTE changed from Y to X axis
+ matrixStack.mulPose(Vector3f.ZP.rotationDegrees(lockState.getSlot().getRotation())); // NOTE now Z axis is the Y axis since we rotated on the X axis first.
+ }
- }
- }
+ @Override
+ public float getLockScaleModifier() {
+ return 0.35F;
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CompressorChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CompressorChestTileEntityRenderer.java
index bb651a449..126ee35f0 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CompressorChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CompressorChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.mojang.blaze3d.matrix.MatrixStack;
@@ -29,59 +48,19 @@ public CompressorChestTileEntityRenderer(TileEntityRendererDispatcher tileEntity
}
@Override
- public void render(AbstractTreasureChestTileEntity tileEntity, float partialTicks, MatrixStack matrixStack,
- IRenderTypeBuffer renderTypeBuffer, int combinedLight, int combinedOverlay) {
-
- if (!(tileEntity instanceof AbstractTreasureChestTileEntity)) {
- return; // should never happen
- }
-
- // TODO this block goes into method / use template pattern
- World world = tileEntity.getLevel();
- boolean hasWorld = (world != null);
- BlockState state = tileEntity.getBlockState();
- Direction facing = Direction.NORTH;
- if (hasWorld) {
- facing = state.getValue(StandardChestBlock.FACING);
- }
-
- // push the current transformation matrix + normals matrix
- matrixStack.pushPose();
-
- // TODO this block goes into method / use template pattern
- // The model is defined centred on [0,0,0], so if we drew it at the current render origin, its centre would be
- // at the corner of the block, sunk halfway into the ground and overlapping into the adjacent blocks.
- // We want it to hover above the centre of the hopper base, so we need to translate up and across to the desired position
- final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 0.75, 0.5);
- matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z); // translate
- matrixStack.scale(-1, -1, 1);
- float f = getHorizontalAngle(facing);
- matrixStack.mulPose(Vector3f.YP.rotationDegrees(-f));
-
+ public void updateScale(MatrixStack matrixStack) {
// shrink the size of the chest by half
- matrixStack.scale(0.5F, 0.5F, 0.5F);
-
- //////////////// custom lid code /////////////
- updateModelRotationAngles(tileEntity, partialTicks);
- //////////////// end of lid code //////////////
-
- // TODO this block goes into method / use template pattern
- IVertexBuilder renderBuffer = renderTypeBuffer.getBuffer(getModel().getChestRenderType(getTexture()));
- getModel().renderAll(matrixStack, renderBuffer, combinedLight, combinedOverlay, tileEntity);
- matrixStack.popPose();
-
- // TODO this block goes into method / use template pattern
- ////////////// render the locks //////////////////////////////////////
- renderLocks(tileEntity, matrixStack, renderTypeBuffer, combinedLight, combinedOverlay);
- // if (!te.getLockStates().isEmpty()) {
- // renderLocks(te, x, y, z);
- // }
- ////////////// end of render the locks //////////////////////////////////////
+ matrixStack.scale(0.5F, 0.5F, 0.5F);
+ }
+ @Override
+ public void updateTranslation(MatrixStack matrixStack) {
+ final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 0.75, 0.5);
+ matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z);
}
@Override
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
+ public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
float lidRotation = tileEntity.prevLidAngle + (tileEntity.lidAngle - tileEntity.prevLidAngle) * partialTicks;
lidRotation = 1.0F - lidRotation;
lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
@@ -89,7 +68,7 @@ public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity
}
@Override
- public float getLocksScaleModifier() {
+ public float getLockScaleModifier() {
return 0.20F;
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CrateChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CrateChestTileEntityRenderer.java
index 01d2f80a3..cf4e130fe 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CrateChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/CrateChestTileEntityRenderer.java
@@ -1,22 +1,31 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
-import com.mojang.blaze3d.matrix.MatrixStack;
-import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.someguyssoftware.treasure2.Treasure;
-import com.someguyssoftware.treasure2.block.AbstractChestBlock;
-import com.someguyssoftware.treasure2.block.StandardChestBlock;
import com.someguyssoftware.treasure2.gui.model.CrateChestModel;
import com.someguyssoftware.treasure2.tileentity.AbstractTreasureChestTileEntity;
import com.someguyssoftware.treasure2.tileentity.CrateChestTileEntity;
-import net.minecraft.block.BlockState;
-import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
-import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.math.vector.Vector3d;
-import net.minecraft.util.math.vector.Vector3f;
-import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -31,62 +40,16 @@ public CrateChestTileEntityRenderer(TileEntityRendererDispatcher tileEntityRende
}
@Override
- public void render(AbstractTreasureChestTileEntity tileEntity, float partialTicks, MatrixStack matrixStack,
- IRenderTypeBuffer renderTypeBuffer, int combinedLight, int combinedOverlay) {
-
- if (!(tileEntity instanceof AbstractTreasureChestTileEntity)) {
- return; // should never happen
- }
-
- // TODO this block goes into method / use template pattern
- World world = tileEntity.getLevel();
- boolean hasWorld = (world != null);
- BlockState state = tileEntity.getBlockState();
- Direction facing = Direction.NORTH;
- if (hasWorld) {
- facing = AbstractChestBlock.getFacing(state);
- }
-
- // push the current transformation matrix + normals matrix
- matrixStack.pushPose();
-
- // TODO this block goes into method / use template pattern
- // The model is defined centred on [0,0,0], so if we drew it at the current render origin, its centre would be
- // at the corner of the block, sunk halfway into the ground and overlapping into the adjacent blocks.
- // We want it to hover above the centre of the hopper base, so we need to translate up and across to the desired position
- final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 1.5, 0.5);
- matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z); // translate
- matrixStack.scale(-1, -1, 1);
- float f = getHorizontalAngle(facing);
- matrixStack.mulPose(Vector3f.YP.rotationDegrees(-f));
-
- // TODO this block goes into method / use template pattern
- //////////////// custom lid code /////////////
+ public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
CrateChestTileEntity cte = (CrateChestTileEntity) tileEntity;
float latchRotation = cte.prevLatchAngle + (cte.latchAngle - cte.prevLatchAngle) * partialTicks;
latchRotation = 1.0F - latchRotation;
latchRotation = 1.0F - latchRotation * latchRotation * latchRotation;
- ((CrateChestModel)getModel()).getLatch1().xRot = -(latchRotation * (float)Math.PI / 2.0F);
+ ((CrateChestModel)getModel()).getLatch1().xRot = -(latchRotation * (float)Math.PI / getAngleModifier());
float lidRotation = cte.prevLidAngle + (cte.lidAngle - cte.prevLidAngle) * partialTicks;
lidRotation = 1.0F - lidRotation;
lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
- getModel().getLid().yRot = -(lidRotation * (float)Math.PI / 2.0F);
-
- //////////////// end of lid code //////////////
-
- // TODO this block goes into method / use template pattern
- IVertexBuilder renderBuffer = renderTypeBuffer.getBuffer(getModel().getChestRenderType(getTexture()));
- getModel().renderAll(matrixStack, renderBuffer, combinedLight, combinedOverlay, tileEntity);
- matrixStack.popPose();
-
- // TODO this block goes into method / use template pattern
- ////////////// render the locks //////////////////////////////////////
- renderLocks(tileEntity, matrixStack, renderTypeBuffer, combinedLight, combinedOverlay);
-// if (!te.getLockStates().isEmpty()) {
-// renderLocks(te, x, y, z);
-// }
- ////////////// end of render the locks //////////////////////////////////////
-
+ getModel().getLid().yRot = -(lidRotation * (float)Math.PI / getAngleModifier());
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/DreadPirateChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/DreadPirateChestTileEntityRenderer.java
index d067f90fc..0e4b3634c 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/DreadPirateChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/DreadPirateChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/GoldStrongboxTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/GoldStrongboxTileEntityRenderer.java
index c8e122ffc..90b5b30f5 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/GoldStrongboxTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/GoldStrongboxTileEntityRenderer.java
@@ -1,5 +1,21 @@
-/**
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
*
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
*/
package com.someguyssoftware.treasure2.gui.render.tileentity;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/ITreasureChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/ITreasureChestTileEntityRenderer.java
index f3cd13413..bdc6b93a4 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/ITreasureChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/ITreasureChestTileEntityRenderer.java
@@ -3,6 +3,7 @@
import com.mojang.blaze3d.matrix.MatrixStack;
import com.someguyssoftware.treasure2.block.StandardChestBlock;
import com.someguyssoftware.treasure2.gui.model.ITreasureChestModel;
+import com.someguyssoftware.treasure2.lock.LockState;
import com.someguyssoftware.treasure2.tileentity.AbstractTreasureChestTileEntity;
import net.minecraft.block.BlockState;
@@ -10,12 +11,45 @@
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.util.math.vector.Vector3f;
public interface ITreasureChestTileEntityRenderer {
void renderLocks(AbstractTreasureChestTileEntity tileEntity, MatrixStack matrixStack,
IRenderTypeBuffer renderBuffer, int combinedLight, int combinedOverlay);
+ /**
+ */
+ default public void updateTranslation(MatrixStack matrixStack) {
+ // The model is defined centred on [0,0,0], so if we drew it at the current render origin, its centre would be
+ // at the corner of the block, sunk halfway into the ground and overlapping into the adjacent blocks.
+ // We want it to hover above the centre of the hopper base, so we need to translate up and across to the desired position
+ final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 1.5, 0.5);
+ matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z);
+ }
+
+ default public void updateScale(MatrixStack matrixStack) {
+ matrixStack.scale(1, 1, 1);
+ }
+
+ default public void updateRotation(MatrixStack matrixStack, Direction direction) {
+ float angle = getHorizontalAngle(direction);
+ matrixStack.mulPose(Vector3f.YP.rotationDegrees(-angle));
+ }
+
+ /**
+ *
+ * @param tileEntity
+ * @param partialTicks
+ */
+ default public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
+ float lidRotation = tileEntity.prevLidAngle + (tileEntity.lidAngle - tileEntity.prevLidAngle) * partialTicks;
+ lidRotation = 1.0F - lidRotation;
+ lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
+ getModel().getLid().xRot = -(lidRotation * (float) Math.PI / getAngleModifier());
+ }
+
/**
*
* @param tileEntity
@@ -32,7 +66,7 @@ default public Direction getDirection(TileEntity tileEntity) {
/**
* Helper method since all my models face the opposite direction of vanilla models
- * @param meta
+ * @param facing
* @return
*/
default public int getHorizontalAngle(Direction facing) {
@@ -48,7 +82,49 @@ default public int getHorizontalAngle(Direction facing) {
return -90;
}
}
+
+ /**
+ * Modifies the max angle that the lid can swing.
+ * The max swing angle by default is 180 degrees. The max swing angle is divided the modifier.
+ * Increasing the size of the modifier reduces the size of the max swing angle.
+ * Ex:
+ * Return 0.8 = 225 degrees
+ * Return 1.0 = 180 degrees
+ * Return 2.0 = 90 degrees
+ * Return 3.0 = 60 degrees
+ * Return 4.0 = 45 degrees
+ *
+ * @return
+ */
+ default public float getAngleModifier() {
+ return 2.0F;
+ }
+ /**
+ * Modifies teh scale of the Lock item(s).
+ * Ranges from 0.0F to x.xF.
+ * Ex:
+ * Return 1.0F = full size
+ * Return 0.5 = half size
+ *
+ * @return
+ */
+ default public float getLockScaleModifier() {
+ return 0.5F;
+ }
+
+ default public void updateLockScale(MatrixStack matrixStack) {
+ matrixStack.scale(getLockScaleModifier(), getLockScaleModifier(), getLockScaleModifier());
+ }
+
+ /**
+ *
+ * @param lockState
+ */
+ default public void updateLockRotation(MatrixStack matrixStack, LockState lockState) {
+ matrixStack.mulPose(Vector3f.YP.rotationDegrees(lockState.getSlot().getRotation()));
+ }
+
/**
*
* @return
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronStrongboxTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronStrongboxTileEntityRenderer.java
index 287c71350..a96ba98a2 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronStrongboxTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronStrongboxTileEntityRenderer.java
@@ -1,5 +1,21 @@
-/**
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
*
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
*/
package com.someguyssoftware.treasure2.gui.render.tileentity;
@@ -25,40 +41,8 @@ public IronStrongboxTileEntityRenderer(TileEntityRendererDispatcher tileEntityRe
setModel(new StrongboxModel());
}
- /**
- *
- * @param te
- * @param x
- * @param y
- * @param z
- */
-// public void renderLocks(AbstractTreasureChestTileEntity tileEntity, MatrixStack matrixStack, IRenderTypeBuffer renderBuffer, int combinedLight, int combinedOverlay) {
-// if (tileEntity.getLockStates().isEmpty()) {
-// return;
-// }
-//
-// // render locks
-// tileEntity.getLockStates().forEach(lockState -> {
-// // for (LockState lockState : tileEntity.getLockStates()) {
-//
-// if (lockState.getLock() != null) {
-// // convert lock to an item stack
-// ItemStack lockStack = new ItemStack(lockState.getLock());
-//
-// matrixStack.pushPose();
-// matrixStack.translate(lockState.getSlot().getXOffset(), lockState.getSlot().getYOffset(), lockState.getSlot().getZOffset());
-// matrixStack.mulPose(Vector3f.YP.rotationDegrees(lockState.getSlot().getRotation()));
-//// if this works, can remove this method altogether and update abstract super to use getLocksScaleModifier
-// matrixStack.scale(getLocksScaleModifier(), getLocksScaleModifier(), getLocksScaleModifier());
-// Minecraft.getInstance().getItemRenderer().renderItem(lockStack, ItemCameraTransforms.TransformType.NONE, combinedLight, OverlayTexture.NO_OVERLAY, matrixStack, renderBuffer);
-// matrixStack.popPose();
-// }
-// // }
-// });
-// }
-
@Override
- public float getLocksScaleModifier() {
+ public float getLockScaleModifier() {
return 0.25F;
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronboundChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronboundChestTileEntityRenderer.java
index 01ecbb1f0..31a641083 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronboundChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/IronboundChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MilkCreateTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MilkCreateTileEntityRenderer.java
index 5e68dce2b..5f7ea5ab2 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MilkCreateTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MilkCreateTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.mojang.blaze3d.matrix.MatrixStack;
@@ -29,67 +48,19 @@ public MilkCreateTileEntityRenderer(TileEntityRendererDispatcher tileEntityRende
}
@Override
- public void render(AbstractTreasureChestTileEntity tileEntity, float partialTicks, MatrixStack matrixStack,
- IRenderTypeBuffer renderTypeBuffer, int combinedLight, int combinedOverlay) {
-
- if (!(tileEntity instanceof AbstractTreasureChestTileEntity)) {
- return; // should never happen
- }
-
- // TODO this block goes into method / use template pattern
- World world = tileEntity.getLevel();
- boolean hasWorld = (world != null);
- BlockState state = tileEntity.getBlockState();
- Direction facing = Direction.NORTH;
- if (hasWorld) {
- facing = state.getValue(StandardChestBlock.FACING);
- }
-
- // push the current transformation matrix + normals matrix
- matrixStack.pushPose();
-
- // TODO this block goes into method / use template pattern
- // The model is defined centred on [0,0,0], so if we drew it at the current render origin, its centre would be
- // at the corner of the block, sunk halfway into the ground and overlapping into the adjacent blocks.
- // We want it to hover above the centre of the hopper base, so we need to translate up and across to the desired position
- final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 1.15625F, 0.5);
- matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z); // translate
- matrixStack.scale(-1, -1, 1);
- float f = getHorizontalAngle(facing);
- matrixStack.mulPose(Vector3f.YP.rotationDegrees(-f));
-
- // shrink the size of the chest by half
- matrixStack.scale(0.75F, 0.75F, 0.75F);
-
- //////////////// custom lid code /////////////
- updateModelRotationAngles(tileEntity, partialTicks);
- //////////////// end of lid code //////////////
-
- // TODO this block goes into method / use template pattern
- IVertexBuilder renderBuffer = renderTypeBuffer.getBuffer(getModel().getChestRenderType(getTexture()));
- getModel().renderAll(matrixStack, renderBuffer, combinedLight, combinedOverlay, tileEntity);
- matrixStack.popPose();
-
- // TODO this block goes into method / use template pattern
- ////////////// render the locks //////////////////////////////////////
- renderLocks(tileEntity, matrixStack, renderTypeBuffer, combinedLight, combinedOverlay);
- // if (!te.getLockStates().isEmpty()) {
- // renderLocks(te, x, y, z);
- // }
- ////////////// end of render the locks //////////////////////////////////////
-
+ public float getLockScaleModifier() {
+ return 0.28F;
}
@Override
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
- float lidRotation = tileEntity.prevLidAngle + (tileEntity.lidAngle - tileEntity.prevLidAngle) * partialTicks;
- lidRotation = 1.0F - lidRotation;
- lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
- getModel().getLid().xRot = -(lidRotation * (float)Math.PI / 2.0F);
+ public void updateScale(MatrixStack matrixStack) {
+ // shrink the size of the chest by half
+ matrixStack.scale(0.75F, 0.75F, 0.75F);
}
@Override
- public float getLocksScaleModifier() {
- return 0.28F;
+ public void updateTranslation(MatrixStack matrixStack) {
+ final Vector3d TRANSLATION_OFFSET = new Vector3d(0.5, 1.15625F, 0.5);
+ matrixStack.translate(TRANSLATION_OFFSET.x, TRANSLATION_OFFSET.y, TRANSLATION_OFFSET.z);
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MoldyCrateChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MoldyCrateChestTileEntityRenderer.java
index 8789bc8f1..f17973764 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MoldyCrateChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/MoldyCrateChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/PirateChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/PirateChestTileEntityRenderer.java
index 3088c9037..b18bc9703 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/PirateChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/PirateChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SafeTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SafeTileEntityRenderer.java
index ced78f29e..d2ffc0ef4 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SafeTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SafeTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
@@ -22,14 +41,14 @@ public SafeTileEntityRenderer(TileEntityRendererDispatcher tileEntityRendererDis
}
@Override
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
+ public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
SafeTileEntity ste = (SafeTileEntity) tileEntity;
if (ste.isLidClosed) {
float handleRotation = ste.prevHandleAngle + (ste.handleAngle - ste.prevHandleAngle) * partialTicks;
handleRotation = 1.0F - handleRotation;
handleRotation = 1.0F - handleRotation * handleRotation * handleRotation;
- ((SafeModel)getModel()).getHandleA1().zRot = (handleRotation * (float)Math.PI / 2.0F);
+ ((SafeModel)getModel()).getHandleA1().zRot = (handleRotation * (float)Math.PI / getAngleModifier());
}
else {
// render handleB rotating around y-axis
@@ -37,11 +56,11 @@ public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity
float lidRotation = ste.prevLidAngle + (ste.lidAngle - ste.prevLidAngle) * partialTicks;
lidRotation = 1.0F - lidRotation;
lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
- getModel().getLid().yRot = (lidRotation * (float)Math.PI / 2.0F);
+ getModel().getLid().yRot = (lidRotation * (float)Math.PI / getAngleModifier());
}
@Override
- public float getLocksScaleModifier() {
+ public float getLockScaleModifier() {
return 0.3F;
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SkullChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SkullChestTileEntityRenderer.java
index 36a37d254..c25e4f940 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SkullChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SkullChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
@@ -55,7 +74,7 @@ public float getAngleModifier() {
}
@Override
- public float getLocksScaleModifier() {
+ public float getLockScaleModifier() {
return 0.25F;
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SpiderChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SpiderChestTileEntityRenderer.java
index a42da34f4..0e9260e37 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SpiderChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/SpiderChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/VikingChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/VikingChestTileEntityRenderer.java
index cb9e6c8af..86dcecd18 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/VikingChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/VikingChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WitherChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WitherChestTileEntityRenderer.java
index 465e61905..f007c7ee4 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WitherChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WitherChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
@@ -20,10 +39,10 @@ public WitherChestTileEntityRenderer(TileEntityRendererDispatcher tileEntityRend
}
@Override
- public void updateModelRotationAngles(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
+ public void updateModelLidRotation(AbstractTreasureChestTileEntity tileEntity, float partialTicks) {
float lidRotation = tileEntity.prevLidAngle + (tileEntity.lidAngle - tileEntity.prevLidAngle) * partialTicks;
lidRotation = 1.0F - lidRotation;
lidRotation = 1.0F - lidRotation * lidRotation * lidRotation;
- ((WitherChestModel)getModel()).getRightFrontDoor().yRot = -(lidRotation * (float)Math.PI / 2.0F);
+ ((WitherChestModel)getModel()).getRightFrontDoor().yRot = -(lidRotation * (float)Math.PI / getAngleModifier());
}
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WoodChestTileEntityRenderer.java b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WoodChestTileEntityRenderer.java
index e6190bdc9..dce7c9f1b 100644
--- a/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WoodChestTileEntityRenderer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/gui/render/tileentity/WoodChestTileEntityRenderer.java
@@ -1,3 +1,22 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
package com.someguyssoftware.treasure2.gui.render.tileentity;
import com.someguyssoftware.treasure2.Treasure;
@@ -18,5 +37,4 @@ public WoodChestTileEntityRenderer(TileEntityRendererDispatcher tileEntityRender
setTexture(new ResourceLocation(Treasure.MODID + ":textures/entity/chest/wood-chest.png"));
setModel(new StandardChestModel());
}
-
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/init/TreasureSetup.java b/src/main/java/com/someguyssoftware/treasure2/init/TreasureSetup.java
index f53bb0f16..c0eec0eb7 100644
--- a/src/main/java/com/someguyssoftware/treasure2/init/TreasureSetup.java
+++ b/src/main/java/com/someguyssoftware/treasure2/init/TreasureSetup.java
@@ -19,14 +19,26 @@
*/
package com.someguyssoftware.treasure2.init;
+import java.util.Optional;
+
+import com.google.common.util.concurrent.AtomicDouble;
import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.capability.CharmableCapability;
import com.someguyssoftware.treasure2.capability.TreasureCapabilities;
+import com.someguyssoftware.treasure2.charm.CharmableMaterial;
+import com.someguyssoftware.treasure2.charm.TreasureCharms;
import com.someguyssoftware.treasure2.data.TreasureData;
+import com.someguyssoftware.treasure2.item.TreasureItems;
+import com.someguyssoftware.treasure2.loot.TreasureLootFunctions;
import com.someguyssoftware.treasure2.loot.TreasureLootTableRegistry;
import com.someguyssoftware.treasure2.registry.TreasureDecayRegistry;
import com.someguyssoftware.treasure2.registry.TreasureMetaRegistry;
import com.someguyssoftware.treasure2.registry.TreasureTemplateRegistry;
+import com.someguyssoftware.treasure2.util.ModUtils;
+import net.minecraft.item.ItemModelsProperties;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
/**
@@ -43,17 +55,63 @@ public static void common(final FMLCommonSetupEvent event) {
Treasure.LOGGER.debug("registering in TreasureSetup");
// add mod specific logging
IModSetup.addRollingFileAppender(Treasure.instance.getName(), null);
+
+ // regsiter functions
+ TreasureLootFunctions.register();
// register capabilities
TreasureCapabilities.register();
// initialize all the data lists, maps, etc
TreasureData.initialize();
-
+
// start the treasure registries
TreasureLootTableRegistry.create(Treasure.instance);
TreasureMetaRegistry.create(Treasure.instance);
TreasureTemplateRegistry.create(Treasure.instance);
TreasureDecayRegistry.create(Treasure.instance);
}
+
+ /**
+ *
+ * @param event
+ */
+ public static void clientSetup(final FMLClientSetupEvent event) {
+ Treasure.LOGGER.debug("setting up item properties dynamically...");
+ event.enqueueWork(() -> {
+ ItemModelsProperties.register(TreasureItems.COPPER_CHARM,
+ new ResourceLocation(Treasure.MODID, "gem"), (stack, world, living) -> {
+ AtomicDouble d = new AtomicDouble(0);
+ stack.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(cap -> {
+ Optional source = TreasureCharms.getSourceItem(cap.getSourceItem());
+ if (source.isPresent()) {
+ d.set(source.get().getId());
+ }
+ });
+ return d.floatValue();
+ });
+ ItemModelsProperties.register(TreasureItems.SILVER_CHARM,
+ new ResourceLocation(Treasure.MODID, "gem"), (stack, world, living) -> {
+ AtomicDouble d = new AtomicDouble(0);
+ stack.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(cap -> {
+ Optional source = TreasureCharms.getSourceItem(cap.getSourceItem());
+ if (source.isPresent()) {
+ d.set(source.get().getId());
+ }
+ });
+ return d.floatValue();
+ });
+ ItemModelsProperties.register(TreasureItems.GOLD_CHARM,
+ new ResourceLocation(Treasure.MODID, "gem"), (stack, world, living) -> {
+ AtomicDouble d = new AtomicDouble(0);
+ stack.getCapability(TreasureCapabilities.CHARMABLE).ifPresent(cap -> {
+ Optional source = TreasureCharms.getSourceItem(cap.getSourceItem());
+ if (source.isPresent()) {
+ d.set(source.get().getId());
+ }
+ });
+ return d.floatValue();
+ });
+ });
+ }
}
diff --git a/src/main/java/com/someguyssoftware/treasure2/inventory/KeyRingContainer.java b/src/main/java/com/someguyssoftware/treasure2/inventory/KeyRingContainer.java
index 624a1257f..1ea9ebe2c 100644
--- a/src/main/java/com/someguyssoftware/treasure2/inventory/KeyRingContainer.java
+++ b/src/main/java/com/someguyssoftware/treasure2/inventory/KeyRingContainer.java
@@ -19,6 +19,9 @@
*/
package com.someguyssoftware.treasure2.inventory;
+import com.someguyssoftware.treasure2.item.KeyRingItem;
+import com.someguyssoftware.treasure2.item.TreasureItems;
+
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
@@ -75,7 +78,8 @@ public KeyRingContainer(int windowID, ContainerType> containerType, PlayerInve
public void buildHotbar(PlayerInventory player) {
for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) {
int slotNumber = x;
- if (slotNumber == player.selected) {
+ // TODO determine if the item is in left hand
+ if (slotNumber == player.selected && player.offhand.get(0).getItem() != TreasureItems.KEY_RING) {
addSlot(new NoSlot(player, slotNumber, getHotbarXPos() + getSlotXSpacing() * x, getHotbarYPos()));
}
else {
diff --git a/src/main/java/com/someguyssoftware/treasure2/inventory/PouchContainer.java b/src/main/java/com/someguyssoftware/treasure2/inventory/PouchContainer.java
new file mode 100644
index 000000000..fccd652bc
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/inventory/PouchContainer.java
@@ -0,0 +1,113 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.inventory;
+
+import com.someguyssoftware.treasure2.item.TreasureItems;
+
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.Inventory;
+import net.minecraft.inventory.container.ContainerType;
+import net.minecraft.inventory.container.Slot;
+import net.minecraft.network.PacketBuffer;
+
+/**
+ *
+ * @author Mark Gottschling on Jan 16, 2018
+ *
+ */
+public class PouchContainer extends AbstractChestContainer {
+ public static PouchContainer create(int windowID, PlayerInventory playerInventory, PacketBuffer extraData) {
+ return new PouchContainer(windowID, TreasureContainers.POUCH_CONTAINER_TYPE, playerInventory, PouchInventory.INVENTORY_SIZE);
+ }
+
+ /**
+ * Client-side constructor
+ * @param windowID
+ * @param skullChestContainerType
+ * @param playerInventory
+ * @param slotCount
+ */
+ private PouchContainer(int windowID, ContainerType> containerType, PlayerInventory playerInventory, int slotCount) {
+ this(windowID, containerType, playerInventory, new Inventory(slotCount));
+
+ }
+
+ /**
+ * Server-side constructor
+ * @param windowID
+ * @param playerInventory
+ * @param inventory
+ */
+ public PouchContainer(int windowID, ContainerType> containerType, PlayerInventory playerInventory, IInventory inventory) {
+ super(windowID, containerType, playerInventory, inventory);
+
+ // set the dimensions
+ setHotbarYPos(176);
+ setPlayerInventoryYPos(118);
+
+ // set the dimensions
+ setContainerInventoryColumnCount(3);
+ setContainerInventoryRowCount(3);
+ // skull has 13 less columns - to center move the xpos over by xspacing*2
+ setContainerInventoryXPos(8 + getSlotXSpacing() * 3);
+ setContainerInventoryYPos(52);
+
+ // build the container
+ buildContainer(playerInventory, inventory);
+ }
+
+ /**
+ * Pouch prevents the held slot (which contains the key ring itself) from being moved.
+ */
+ @Override
+ public void buildHotbar(PlayerInventory player) {
+ for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) {
+ int slotNumber = x;
+ if (slotNumber == player.selected && player.offhand.get(0).getItem() != TreasureItems.POUCH) {
+ addSlot(new NoSlot(player, slotNumber, getHotbarXPos() + getSlotXSpacing() * x, getHotbarYPos()));
+ }
+ else {
+ addSlot(new Slot(player, slotNumber, getHotbarXPos() + getSlotXSpacing() * x, getHotbarYPos()));
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void buildContainerInventory() {
+ for (int y = 0; y < getContainerInventoryRowCount(); y++) {
+ for (int x = 0; x < getContainerInventoryColumnCount(); x++) {
+ int slotNumber = (y * getContainerInventoryColumnCount()) + x;
+ int xpos = getContainerInventoryXPos() + x * getSlotXSpacing();
+ int ypos = getContainerInventoryYPos() + y * getSlotYSpacing();
+ // pouches use PouchSlot
+ addSlot(new PouchSlot(this.contents, slotNumber, xpos, ypos));
+ }
+ }
+ }
+
+ @Override
+ public int getContainerInventorySlotCount() {
+ return 9;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/inventory/PouchInventory.java b/src/main/java/com/someguyssoftware/treasure2/inventory/PouchInventory.java
new file mode 100644
index 000000000..f1b14b2b2
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/inventory/PouchInventory.java
@@ -0,0 +1,135 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.inventory;
+
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.POUCH_CAPABILITY;
+
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.config.TreasureConfig;
+
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.Inventory;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.items.IItemHandler;
+
+/**
+ * @author Mark Gottschling on Mar 9, 2018
+ *
+ */
+public class PouchInventory extends Inventory {
+ public static int INVENTORY_SIZE = 9;
+
+ /*
+ * Reference to the owning ItemStack
+ */
+ private ItemStack itemStack;
+
+ /**
+ *
+ * @param stack
+ */
+ public PouchInventory(ItemStack stack) {
+ super(INVENTORY_SIZE);
+ // save a ref to the item stack
+ this.itemStack = stack;
+ IItemHandler itemHandler = stack.getCapability(POUCH_CAPABILITY, null).orElseThrow(IllegalStateException::new);
+ readInventoryFromHandler(itemHandler);
+ }
+
+ /**
+ *
+ * @param handler
+ */
+ public void readInventoryFromHandler(IItemHandler handler) {
+ try {
+ // read the inventory
+ for (int i = 0; i < INVENTORY_SIZE; i++) {
+ setItem(i, handler.getStackInSlot(i));
+ }
+ }
+ catch(Exception e) {
+ Treasure.LOGGER.error("Error reading items from IItemHandler:", e);
+ }
+ }
+
+ /**
+ *
+ * @param handler
+ */
+ public void writeInventoryToHandler(IItemHandler handler) {
+ try {
+ for (int i = 0; i < INVENTORY_SIZE; i++) {
+ handler.insertItem(i, getItem(i), false);
+ }
+ }
+ catch(Exception e) {
+ Treasure.LOGGER.error("Error writing Inventory to IItemHandler:", e);
+ }
+ }
+
+ ///////////// IInventory Method
+
+ /* (non-Javadoc)
+ * @see net.minecraft.inventory.IInventory#getSizeInventory()
+ */
+ @Override
+ public int getContainerSize() {
+ return INVENTORY_SIZE;
+ }
+
+ /* (non-Javadoc)
+ * @see net.minecraft.inventory.IInventory#getInventoryStackLimit()
+ *
+ * If using custom Slots, this value must equal Slot.getItemStackLimit()
+ */
+ @Override
+ public int getMaxStackSize() {
+ return TreasureConfig.BOOTY.wealthMaxStackSize.get();
+ }
+
+ /* (non-Javadoc)
+ * @see net.minecraft.inventory.IInventory#closeInventory(net.minecraft.entity.player.EntityPlayer)
+ */
+ @Override
+ public void stopOpen(PlayerEntity player) {
+ /*
+ * write the locked state to the nbt
+ */
+ IItemHandler itemHandler = getItemStack().getCapability(POUCH_CAPABILITY, null).orElseThrow(IllegalStateException::new);
+ writeInventoryToHandler(itemHandler);
+ }
+
+ /**
+ * @return the itemStack
+ */
+ public ItemStack getItemStack() {
+ return itemStack;
+ }
+
+ /**
+ * @param itemStack the itemStack to set
+ */
+ public void setItemStack(ItemStack itemStack) {
+ this.itemStack = itemStack;
+ }
+
+ /////////// End of IInventory methods
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/someguyssoftware/treasure2/inventory/PouchSlot.java b/src/main/java/com/someguyssoftware/treasure2/inventory/PouchSlot.java
new file mode 100644
index 000000000..9e61bcefe
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/inventory/PouchSlot.java
@@ -0,0 +1,43 @@
+package com.someguyssoftware.treasure2.inventory;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.item.CharmItem;
+import com.someguyssoftware.treasure2.item.WealthItem;
+
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.container.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+
+/**
+ *
+ * @author Mark Gottschling on May 14, 2020
+ *
+ */
+public class PouchSlot extends Slot {
+
+ /**
+ *
+ * @param inventoryIn
+ * @param index
+ * @param xPosition
+ * @param yPosition
+ */
+ public PouchSlot(IInventory inventoryIn, int index, int xPosition, int yPosition) {
+ super(inventoryIn, index, xPosition, yPosition);
+ }
+
+
+ @Override
+ public boolean mayPlace(ItemStack stack) {
+ Set tags = stack.getItem().getTags().stream().filter(tag -> tag.getNamespace().equals(Treasure.MODID)) .map(ResourceLocation::getPath).collect(Collectors.toSet());
+ // TODO in next releases replace CharmItem with some sort of tag
+ if (stack.getItem() instanceof WealthItem || stack.getItem() instanceof CharmItem || tags.contains("pouch")) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/inventory/TreasureContainers.java b/src/main/java/com/someguyssoftware/treasure2/inventory/TreasureContainers.java
index fe0edd5a1..e5a5b2eb7 100644
--- a/src/main/java/com/someguyssoftware/treasure2/inventory/TreasureContainers.java
+++ b/src/main/java/com/someguyssoftware/treasure2/inventory/TreasureContainers.java
@@ -24,6 +24,7 @@ public class TreasureContainers {
public static ContainerType WITHER_CHEST_CONTAINER_TYPE;
public static ContainerType KEY_RING_CONTAINER_TYPE;
+ public static ContainerType POUCH_CONTAINER_TYPE;
@Mod.EventBusSubscriber(modid = Treasure.MODID, bus = EventBusSubscriber.Bus.MOD)
public static class RegistrationHandler {
@@ -53,6 +54,10 @@ public static void registerContainers(final RegistryEvent.Register.
+ */
+package com.someguyssoftware.treasure2.item;
+
+import java.util.List;
+
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+
+/**
+ *
+ * @author Mark Gottschling on Aug 27, 2021
+ *
+ */
+public class CharmBook extends CharmItem {
+
+ /**
+ *
+ * @param modID
+ * @param name
+ * @param properties
+ */
+ public CharmBook(String modID, String name, Properties properties) {
+ super(modID, name, properties.tab(TreasureItemGroups.MOD_ITEM_GROUP).stacksTo(1));
+ }
+
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) {
+ tooltip.add(new TranslationTextComponent("tooltip.label.charm_book").withStyle(TextFormatting.GOLD, TextFormatting.ITALIC));
+ // charmable info
+ ICharmableCapability cap = getCap(stack);
+ if (cap.isCharmed()) {
+ cap.appendHoverText(stack, worldIn, tooltip, flagIn);
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/CharmItem.java b/src/main/java/com/someguyssoftware/treasure2/item/CharmItem.java
new file mode 100644
index 000000000..c1a931da2
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/item/CharmItem.java
@@ -0,0 +1,259 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.item;
+
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.*;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+
+import com.someguyssoftware.gottschcore.item.ModItem;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.capability.CharmableCapabilityProvider;
+import com.someguyssoftware.treasure2.capability.CharmableCapabilityStorage;
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
+import com.someguyssoftware.treasure2.capability.TreasureCapabilities;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.charm.Charm;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+import com.someguyssoftware.treasure2.config.TreasureConfig;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+import net.minecraft.client.util.ITooltipFlag;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.ListNBT;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.World;
+import net.minecraftforge.common.capabilities.ICapabilityProvider;
+
+/**
+ * @author Mark Gottschling on Aug 17, 2021
+ *
+ */
+public class CharmItem extends ModItem {
+
+ /**
+ *
+ * @param modID
+ * @param name
+ * @param properties
+ */
+ public CharmItem(String modID, String name, Properties properties) {
+ super(modID, name, properties.tab(TreasureItemGroups.MOD_ITEM_GROUP).stacksTo(1));
+ }
+
+
+ @Override
+ public ICapabilityProvider initCapabilities(ItemStack stack, CompoundNBT nbt) {
+ // TODO create new CharmItemCapProvider which includes POUCHABLE cap (not everything that is charmable is pouchable)
+ Treasure.LOGGER.debug("{} item initiating caps", stack.getItem().getRegistryName().toString());
+ CharmableCapabilityProvider provider = new CharmableCapabilityProvider();
+ return provider;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) {
+ super.appendHoverText(stack, worldIn, tooltip, flagIn);
+ // charmable info
+ tooltip.add(new TranslationTextComponent("tooltip.charmable.usage").withStyle(TextFormatting.GOLD, TextFormatting.ITALIC));
+ ICharmableCapability cap = getCap(stack);
+ if (cap.isCharmed()) {
+ cap.appendHoverText(stack, worldIn, tooltip, flagIn);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * @param stack
+ * @return
+ */
+ public ICharmableCapability getCap(ItemStack stack) {
+ return stack.getCapability(TreasureCapabilities.CHARMABLE, null).orElseThrow(IllegalStateException::new);
+ }
+
+ /**
+ *
+ */
+ @Override
+ public boolean isFoil(ItemStack stack) {
+ ICharmableCapability cap = getCap(stack);
+ if (cap.isCharmed()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ // ///////////////////////////////////////////////////////////
+ private static final String SOURCE = "source";
+ private static final String EXECUTING = "executing";
+ private static final String BINDABLE = "bindable";
+ private static final String INNATE = "innate";
+ private static final String MAX_INNATE_SIZE = "maxInnateSize";
+ private static final String IMBUABLE = "imbuable";
+ private static final String IMBUING = "imbuing";
+ private static final String MAX_IMBUE_SIZE = "maxImbueSize";
+ private static final String SOCKETABLE = "socketable";
+ private static final String MAX_SOCKET_SIZE = "maxSocketSize";
+ private static final String BASE_MATERIAL = "baseMaterial";
+ private static final String SOURCE_ITEM = "sourceItem";
+ private static final String CHARM = "charm";
+
+ /**
+ * NOTE getShareTag() and readShareTag() are required to sync item capabilities server -> client. I needed this when holding charms in hands and then swapping hands.
+ */
+ @Override
+ public CompoundNBT getShareTag(ItemStack stack) {
+ CompoundNBT nbt = stack.getOrCreateTag();
+ ICharmableCapability cap = stack.getCapability(CHARMABLE).orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!"));
+
+ // TODO is there a way to call CharmableCapabilityStorage.write() from here? This is an exact duplicate
+ try {
+ /*
+ * save charm cap inventories
+ */
+ // create a new list nbt for each inventory type
+ for (int index = 0; index < cap.getCharmEntities().length; index++) {
+ List entityList = cap.getCharmEntities()[index];
+ if (entityList != null && !entityList.isEmpty()) {
+ ListNBT listNbt = new ListNBT();
+ for (ICharmEntity entity : entityList) {
+ CompoundNBT entityNbt = new CompoundNBT();
+ listNbt.add(entity.save(entityNbt));
+ }
+ nbt.put(InventoryType.getByValue(index).name(), listNbt);
+ }
+ }
+
+ /*
+ * save charm cap properties
+ */
+ nbt.putBoolean(SOURCE, cap.isSource());
+ nbt.putBoolean(EXECUTING, cap.isExecuting());;
+ nbt.putBoolean(BINDABLE, cap.isBindable());
+
+ nbt.putBoolean(INNATE, cap.isInnate());
+ nbt.putInt(MAX_INNATE_SIZE, cap.getMaxInnateSize());
+
+ nbt.putBoolean(IMBUABLE, cap.isImbuable());
+ nbt.putBoolean(IMBUING, cap.isImbuing());
+ nbt.putInt(MAX_IMBUE_SIZE, cap.getMaxImbueSize());
+
+ nbt.putBoolean(SOCKETABLE, cap.isSocketable());
+ nbt.putInt(MAX_SOCKET_SIZE, cap.getMaxSocketsSize());
+ nbt.putString(BASE_MATERIAL, cap.getBaseMaterial().toString());
+ nbt.putString(SOURCE_ITEM, cap.getSourceItem().toString());
+
+ } catch (Exception e) {
+ Treasure.LOGGER.error("Unable to write state to NBT:", e);
+ }
+ return nbt;
+ }
+
+ @Override
+ public void readShareTag(ItemStack stack, @Nullable CompoundNBT nbt) {
+ super.readShareTag(stack, nbt);
+
+ if (nbt instanceof CompoundNBT) {
+ ICharmableCapability cap = stack.getCapability(CHARMABLE).orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!"));
+
+ CompoundNBT tag = (CompoundNBT) nbt;
+ for (InventoryType type : InventoryType.values()) {
+ // clear the list
+ cap.getCharmEntities()[type.getValue()].clear();
+ /*
+ * load the list
+ */
+ if (tag.contains(type.name())) {
+ ListNBT listNbt = tag.getList(type.name(), 10);
+ listNbt.forEach(e -> {
+ // load the charm
+ Optional charm = Charm.load((CompoundNBT) ((CompoundNBT)e).get(CHARM));
+ if (!charm.isPresent()) {
+ return;
+ }
+ // create an entity
+ ICharmEntity entity = charm.get().createEntity();
+
+ // load entity
+ entity.load((CompoundNBT)e);
+
+ // add the entity to the list
+ cap.getCharmEntities()[type.getValue()].add(entity);
+ });
+ }
+
+ // load cap properties
+ if (tag.contains(SOURCE)) {
+ cap.setSource(tag.getBoolean(SOURCE));
+ }
+ if (tag.contains(EXECUTING)) {
+ cap.setExecuting(tag.getBoolean(EXECUTING));
+ }
+
+ if (tag.contains(BINDABLE)) {
+ cap.setBindable(tag.getBoolean(BINDABLE));
+ }
+
+ if (tag.contains(INNATE)) {
+ cap.setInnate(tag.getBoolean(INNATE));
+ }
+ if (tag.contains(MAX_INNATE_SIZE)) {
+ cap.setMaxInnateSize(tag.getInt(MAX_INNATE_SIZE));
+ }
+
+ if (tag.contains(IMBUABLE)) {
+ cap.setImbuable(tag.getBoolean(IMBUABLE));
+ }
+ if (tag.contains(MAX_IMBUE_SIZE)) {
+ cap.setMaxImbueSize(tag.getInt(MAX_IMBUE_SIZE));
+ }
+ if (tag.contains(IMBUING)) {
+ cap.setImbuing(tag.getBoolean(IMBUING));
+ }
+
+ if (tag.contains(SOCKETABLE)) {
+ cap.setSocketable(tag.getBoolean(SOCKETABLE));
+ }
+ if (tag.contains(MAX_SOCKET_SIZE)) {
+ cap.setMaxSocketsSize(tag.getInt(MAX_SOCKET_SIZE));
+ }
+ if (tag.contains(BASE_MATERIAL)) {
+ cap.setBaseMaterial(ModUtils.asLocation(tag.getString(BASE_MATERIAL))); //BaseMaterial.valueOf(tag.getString(BASE_MATERIAL).toUpperCase()));
+ }
+
+ if (tag.contains(SOURCE_ITEM)) {
+ cap.setSourceItem(ModUtils.asLocation(tag.getString(SOURCE_ITEM)));
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/CoinItem.java b/src/main/java/com/someguyssoftware/treasure2/item/CoinItem.java
index b3b95f1dc..acafa7c73 100644
--- a/src/main/java/com/someguyssoftware/treasure2/item/CoinItem.java
+++ b/src/main/java/com/someguyssoftware/treasure2/item/CoinItem.java
@@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.Random;
import com.someguyssoftware.gottschcore.block.BlockContext;
@@ -17,10 +18,15 @@
import com.someguyssoftware.gottschcore.spatial.Coords;
import com.someguyssoftware.gottschcore.spatial.ICoords;
import com.someguyssoftware.gottschcore.world.WorldInfo;
+import com.someguyssoftware.treasure2.Treasure;
import com.someguyssoftware.treasure2.block.IWishingWellBlock;
+import com.someguyssoftware.treasure2.capability.CharmableCapabilityProvider;
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
+import com.someguyssoftware.treasure2.capability.TreasureCapabilities;
import com.someguyssoftware.treasure2.config.TreasureConfig;
import com.someguyssoftware.treasure2.enums.Coins;
import com.someguyssoftware.treasure2.enums.Rarity;
+import com.someguyssoftware.treasure2.item.TreasureItems;
import com.someguyssoftware.treasure2.loot.TreasureLootTableRegistry;
import net.minecraft.block.Blocks;
@@ -30,7 +36,6 @@
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.LootParameterSets;
import net.minecraft.loot.LootParameters;
@@ -42,19 +47,18 @@
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.common.capabilities.ICapabilityProvider;
/**
*
* @author Mark Gottschling on Sep 13, 2014
*
*/
-public class CoinItem extends ModItem {
+@Deprecated
+public class CoinItem extends ModItem implements IWishable {
private static final int MAX_CUSTOM_STACK_SIZE = 64;
public static final int MAX_STACK_SIZE = 8;
- // TODO move to IWishable when added
- public static final String DROPPED_BY_KEY = "droppedBy";
-
private Coins coin;
/**
@@ -67,13 +71,48 @@ public CoinItem (String modID, String name, Item.Properties properties) {
this.coin = Coins.GOLD;
}
+ @Override
+ public ICapabilityProvider initCapabilities(ItemStack stack, CompoundNBT nbt) {
+ CharmableCapabilityProvider provider = new CharmableCapabilityProvider();
+ return provider;
+ }
+
/**
*
*/
@Override
public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) {
- super.appendHoverText(stack, worldIn, tooltip, flagIn);
+ super.appendHoverText(stack, worldIn, tooltip, flagIn);
+ // standard coin info
tooltip.add(new TranslationTextComponent("tooltip.label.coin").withStyle(TextFormatting.GOLD, TextFormatting.ITALIC));
+ // charmable info
+ ICharmableCapability cap = getCap(stack);
+ if (cap.isCharmed()) {
+ cap.appendHoverText(stack, worldIn, tooltip, flagIn);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * @param stack
+ * @return
+ */
+ public ICharmableCapability getCap(ItemStack stack) {
+ return stack.getCapability(TreasureCapabilities.CHARMABLE, null).orElseThrow(IllegalStateException::new);
+ }
+
+ /**
+ *
+ */
+ @Override
+ public boolean isFoil(ItemStack stack) {
+ ICharmableCapability cap = getCap(stack);
+ if (cap.isCharmed()) {
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -113,8 +152,14 @@ public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entityItem) {
Random random = new Random();
for (int itemIndex = 0; itemIndex < entityItemStack.getCount(); itemIndex++) {
// generate an item for each item in the stack
- generateLootItem(world, random, entityItem, coords);
+ Optional lootStack = generateLoot(world, random, entityItem.getItem(), coords);
+ if (lootStack.isPresent()) {
+ // spawn the item
+ InventoryHelper.dropItemStack(world, (double)coords.getX(), (double)coords.getY()+1, (double)coords.getZ(), stack);
+ }
}
+ // remove the item entity
+ entityItem.remove();
return true;
}
}
@@ -126,14 +171,18 @@ public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entityItem) {
*
* @param world
* @param random
- * @param entityItem
+ * @param itemStack
* @param coords
*/
- private void generateLootItem(World world, Random random, ItemEntity entityItem, ICoords coords) {
+ @Override
+ public Optional generateLoot(World world, Random random, ItemStack itemStack, ICoords coords) {
List lootTables = new ArrayList<>();
// determine coin type
- if (getCoin() == Coins.SILVER) {
+ if (getCoin() == Coins.COPPER) {
+ lootTables.addAll(TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.COMMON));
+ }
+ else if (getCoin() == Coins.SILVER) {
lootTables.addAll(TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.UNCOMMON));
lootTables.addAll(TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.SCARCE));
}
@@ -142,15 +191,19 @@ else if (getCoin() == Coins.GOLD) {
lootTables.addAll(TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.RARE));
}
- ItemStack stack = null;
+ // TODO most of this seems repeated from IChestGenerator. Make a common class/methods
+
+ ItemStack outputStack = null;
// handle if loot tables is null or size = 0. return an item (apple) to ensure continuing functionality
if (lootTables == null || lootTables.size() == 0) {
// TODO change to a randomized treasure key
- stack = new ItemStack(Items.APPLE);
+// stack = new ItemStack(Items.APPLE);
+ List keys = new ArrayList<>(TreasureItems.keys.get((getCoin() == Coins.SILVER) ? Rarity.UNCOMMON : Rarity.SCARCE));
+ outputStack = new ItemStack(keys.get(random.nextInt(keys.size())));
}
else {
// attempt to get the player who dropped the coin
- ItemStack coinItem = entityItem.getItem();
+ ItemStack coinItem = itemStack;
CompoundNBT nbt = coinItem.getTag();
LOGGER.debug("item as a tag");
PlayerEntity player = null;
@@ -173,7 +226,7 @@ else if (getCoin() == Coins.GOLD) {
// select a table shell
LootTableShell tableShell = lootTables.get(RandomHelper.randomInt(random, 0, lootTables.size()-1));
if (tableShell.getResourceLocation() == null) {
- return;
+ return Optional.empty();
}
// get the vanilla table from shell
@@ -194,46 +247,29 @@ else if (getCoin() == Coins.GOLD) {
LootPool lootPool = table.getPool(pool.getName());
// geneate loot from pools
- lootPool.addRandomItems(itemStacks::add, lootContext);
+ // TODO https://github.com/gottsch/gottsch-minecraft-Treasure/issues/242
+ // lootPool is null.
+ if (lootPool != null) {
+ lootPool.addRandomItems(itemStacks::add, lootContext);
+ }
+ else {
+ Treasure.LOGGER.warn("loot pool -> {} is null", pool.getName());
+ }
}
-
- // TODO add back when inject loot tables are working
+
// get effective rarity
-// Rarity effectiveRarity = Treasure.LOOT_TABLE_MASTER.getEffectiveRarity(tableShell, (getCoin() == Coins.SILVER) ? Rarity.UNCOMMON : Rarity.SCARCE);
-// LOGGER.debug("coin: using effective rarity -> {}", effectiveRarity);
-//
-// // get all injected loot tables
-// LOGGER.debug("coin: searching for injectable tables for category ->{}, rarity -> {}", tableShell.getCategory(), effectiveRarity);
-// Optional> injectLootTableShells = buildInjectedLootTableList(tableShell.getCategory(), effectiveRarity);
-// if (injectLootTableShells.isPresent()) {
-// LOGGER.debug("coin: found injectable tables for category ->{}, rarity -> {}", tableShell.getCategory(), effectiveRarity);
-// LOGGER.debug("coin: size of injectable tables -> {}", injectLootTableShells.get().size());
-//
-// // attempt to get the player who dropped the coin
-// ItemStack coinItem = entityItem.getItem();
-// NBTTagCompound nbt = coinItem.getTagCompound();
-// EntityPlayer player = null;
-// if (nbt != null && nbt.hasKey(DROPPED_BY_KEY)) {
-// player = world.getPlayerEntityByName(nbt.getString(DROPPED_BY_KEY));
-// if (player != null && LOGGER.isDebugEnabled()) {
-// LOGGER.debug("coin dropped by player -> {}", player.getName());
-// }
-// }
-// itemStacks.addAll(getLootItems(world, random, injectLootTableShells.get(), getLootContext(world, player)));
-// }
+ Rarity effectiveRarity = TreasureLootTableRegistry.getLootTableMaster().getEffectiveRarity(tableShell, (getCoin() == Coins.SILVER) ? Rarity.UNCOMMON : Rarity.SCARCE);
+ LOGGER.debug("coin: using effective rarity -> {}", effectiveRarity);
+
+ // get all injected loot tables
+ injectLoot(world, random, itemStacks, tableShell.getCategory(), effectiveRarity, lootContext);
// select one item randomly
- stack = itemStacks.get(RandomHelper.randomInt(0, itemStacks.size()-1));
+ outputStack = itemStacks.get(RandomHelper.randomInt(0, itemStacks.size()-1));
}
-
- // spawn the item
- if (stack != null) {
- InventoryHelper.dropItemStack(world, (double)coords.getX(), (double)coords.getY()+1, (double)coords.getZ(), stack);
- }
- // remove the item entity
- entityItem.remove();
+ return Optional.of(outputStack);
}
-
+
/**
* @return the coin
*/
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/IWishable.java b/src/main/java/com/someguyssoftware/treasure2/item/IWishable.java
new file mode 100644
index 000000000..77c271935
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/item/IWishable.java
@@ -0,0 +1,105 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.item;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Random;
+
+import com.someguyssoftware.gottschcore.loot.LootTableShell;
+import com.someguyssoftware.gottschcore.spatial.ICoords;
+import com.someguyssoftware.treasure2.enums.Rarity;
+import com.someguyssoftware.treasure2.loot.TreasureLootTableMaster2;
+import com.someguyssoftware.treasure2.loot.TreasureLootTableRegistry;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.world.World;
+
+/**
+ * @author Mark Gottschling on Aug 14, 2021
+ *
+ */
+public interface IWishable {
+ public static final String DROPPED_BY_KEY = "droppedBy";
+
+ /**
+ *
+ * @param world
+ * @param random
+ * @param entityItem
+ * @param coords
+ */
+ public Optional generateLoot(World world, Random random, ItemStack itemStack, ICoords coords);
+
+ /**
+ *
+ * @param world
+ * @param random
+ * @param itemStacks
+ * @param category
+ * @param rarity
+ * @param lootContext
+ */
+ default public void injectLoot(World world, Random random, List itemStacks, String category, Rarity rarity, LootContext lootContext) {
+ Optional> injectLootTableShells = buildInjectedLootTableList(category, rarity);
+ if (injectLootTableShells.isPresent()) {
+ itemStacks.addAll(TreasureLootTableRegistry.getLootTableMaster().getInjectedLootItems(world, random, injectLootTableShells.get(), lootContext));
+ }
+ }
+
+ /**
+ *
+ * @param key
+ * @param rarity
+ * @return
+ */
+ default public Optional> buildInjectedLootTableList(String key, Rarity rarity) {
+ return Optional.ofNullable(TreasureLootTableRegistry.getLootTableMaster().getLootTableByKeyRarity(TreasureLootTableMaster2.ManagedTableType.INJECT, key, rarity));
+ }
+
+ /**
+ *
+ * @return
+ */
+ default public List getLootTables() {
+ return TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.COMMON);
+ }
+
+ /**
+ *
+ * @param random
+ * @return
+ */
+ default public ItemStack getDefaultLootKey (Random random) {
+ List keys = new ArrayList<>(TreasureItems.keys.get(Rarity.COMMON));
+ return new ItemStack(keys.get(random.nextInt(keys.size())));
+ }
+
+ /**
+ *
+ * @param random
+ * @return
+ */
+ default public Rarity getDefaultEffectiveRarity(Random random) {
+ return Rarity.UNCOMMON;
+ }
+}
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/KeyItem.java b/src/main/java/com/someguyssoftware/treasure2/item/KeyItem.java
index 1fb8b6574..d169d4708 100644
--- a/src/main/java/com/someguyssoftware/treasure2/item/KeyItem.java
+++ b/src/main/java/com/someguyssoftware/treasure2/item/KeyItem.java
@@ -52,10 +52,13 @@
import net.minecraft.util.SoundEvents;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.text.IFormattableTextComponent;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
+import net.minecraft.util.text.TextComponentUtils;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.util.text.event.HoverEvent;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
@@ -113,7 +116,7 @@ public KeyItem(String modID, String name, Item.Properties properties) {
setCraftable(false);
setSuccessProbability(90D);
}
-
+
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, CompoundNBT nbt) {
DurabilityCapabilityProvider provider = new DurabilityCapabilityProvider();
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/PearlItem.java b/src/main/java/com/someguyssoftware/treasure2/item/PearlItem.java
index fdbcd21ec..933810b99 100644
--- a/src/main/java/com/someguyssoftware/treasure2/item/PearlItem.java
+++ b/src/main/java/com/someguyssoftware/treasure2/item/PearlItem.java
@@ -58,6 +58,7 @@ public class PearlItem extends ModItem /*implements IWishable, IPouchable*/ {
/**
*
*/
+ @Deprecated
public PearlItem (String modID, String name, Item.Properties properties) {
super(modID, name, properties.tab(TreasureItemGroups.MOD_ITEM_GROUP)
.stacksTo(MAX_STACK_SIZE));
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/PouchItem.java b/src/main/java/com/someguyssoftware/treasure2/item/PouchItem.java
new file mode 100644
index 000000000..b87f469eb
--- /dev/null
+++ b/src/main/java/com/someguyssoftware/treasure2/item/PouchItem.java
@@ -0,0 +1,157 @@
+/*
+ * This file is part of Treasure2.
+ * Copyright (c) 2021, Mark Gottschling (gottsch)
+ *
+ * All rights reserved.
+ *
+ * Treasure2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Treasure2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Treasure2. If not, see .
+ */
+package com.someguyssoftware.treasure2.item;
+
+import static com.someguyssoftware.treasure2.capability.TreasureCapabilities.*;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+
+import com.someguyssoftware.gottschcore.item.ModItem;
+import com.someguyssoftware.gottschcore.world.WorldInfo;
+import com.someguyssoftware.treasure2.Treasure;
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
+import com.someguyssoftware.treasure2.capability.PouchCapabilityProvider;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.charm.Charm;
+import com.someguyssoftware.treasure2.charm.ICharm;
+import com.someguyssoftware.treasure2.charm.ICharmEntity;
+import com.someguyssoftware.treasure2.inventory.PouchContainer;
+import com.someguyssoftware.treasure2.inventory.PouchInventory;
+import com.someguyssoftware.treasure2.inventory.TreasureContainers;
+import com.someguyssoftware.treasure2.util.ModUtils;
+
+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.inventory.IInventory;
+import net.minecraft.inventory.container.Container;
+import net.minecraft.inventory.container.INamedContainerProvider;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.ListNBT;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Hand;
+import net.minecraft.util.text.ITextComponent;
+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.IItemHandler;
+
+/**
+ * @author Mark Gottschling on May 13, 2020
+ *
+ */
+public class PouchItem extends ModItem implements INamedContainerProvider {
+
+ public PouchItem(String modID, String name, Properties properties) {
+ super(modID, name, properties.tab(TreasureItemGroups.MOD_ITEM_GROUP).stacksTo(1));
+ }
+
+ @Override
+ public ICapabilityProvider initCapabilities(ItemStack stack, CompoundNBT nbt) {
+ PouchCapabilityProvider provider = new PouchCapabilityProvider();
+ return provider;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void appendHoverText(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) {
+ super.appendHoverText(stack, worldIn, tooltip, flagIn);
+ tooltip.add(new TranslationTextComponent("tooltip.label.pouch").withStyle(TextFormatting.GOLD));
+ }
+
+ @Override
+ public ActionResult use(World worldIn, PlayerEntity playerIn, Hand handIn) {
+ // exit if on the client
+ if (WorldInfo.isClientSide(worldIn)) {
+ return new ActionResult(ActionResultType.PASS, playerIn.getItemInHand(handIn));
+ }
+
+ // get the container provider
+ INamedContainerProvider namedContainerProvider = this;
+
+ // open the chest
+ NetworkHooks.openGui((ServerPlayerEntity)playerIn, namedContainerProvider, (packetBuffer)->{});
+ // NOTE: (packetBuffer)->{} is just a do-nothing because we have no extra data to send
+
+ return new ActionResult(ActionResultType.SUCCESS, playerIn.getItemInHand(handIn));
+ }
+
+ @Override
+ public Container createMenu(int windowID, PlayerInventory inventory, PlayerEntity player) {
+ // get the held item
+ ItemStack heldItem = player.getItemInHand(Hand.MAIN_HAND);
+ if (heldItem == null || !(heldItem.getItem() instanceof PouchItem)) {
+ heldItem = player.getItemInHand(Hand.OFF_HAND);
+ if (heldItem == null || !(heldItem.getItem() instanceof PouchItem))
+ return null;
+ }
+
+ // create inventory from item
+ IInventory itemInventory = new PouchInventory(heldItem);
+ // open the container
+ return new PouchContainer(windowID, TreasureContainers.POUCH_CONTAINER_TYPE, inventory, itemInventory);
+ }
+
+ @Override
+ public ITextComponent getDisplayName() {
+ return new TranslationTextComponent("item.treasure2.pouch");
+ }
+
+ ////////////////////////
+ /**
+ * NOTE getShareTag() and readShareTag() are required to sync item capabilities server -> client. I needed this when holding charms in hands and then swapping hands.
+ */
+ @Override
+ public CompoundNBT getShareTag(ItemStack stack) {
+ CompoundNBT nbt = stack.getOrCreateTag();
+ IItemHandler cap = stack.getCapability(POUCH_CAPABILITY).orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!"));
+
+ try {
+
+ } catch (Exception e) {
+ Treasure.LOGGER.error("Unable to write state to NBT:", e);
+ }
+ return nbt;
+ }
+
+ @Override
+ public void readShareTag(ItemStack stack, @Nullable CompoundNBT nbt) {
+ super.readShareTag(stack, nbt);
+
+ if (nbt instanceof CompoundNBT) {
+ IItemHandler cap = stack.getCapability(POUCH_CAPABILITY).orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!"));
+
+ CompoundNBT tag = (CompoundNBT) nbt;
+
+ }
+ }
+}
+
+
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/TreasureItemTier.java b/src/main/java/com/someguyssoftware/treasure2/item/TreasureItemTier.java
index 64c1d17e1..47dd7921b 100644
--- a/src/main/java/com/someguyssoftware/treasure2/item/TreasureItemTier.java
+++ b/src/main/java/com/someguyssoftware/treasure2/item/TreasureItemTier.java
@@ -21,7 +21,7 @@ public enum TreasureItemTier implements IItemTier {
private final int level;
private final int uses;
- private final float spped;
+ private final float speed;
private final float attackDamageBonus;
private final int enchantmentValue;
private final LazyValue repairIngredient;
@@ -29,7 +29,7 @@ public enum TreasureItemTier implements IItemTier {
private TreasureItemTier(int harvestLevelIn, int maxUsesIn, float speedIn, float attackDamageBonusIn, int enchantmentValueIn, Supplier repairIngredientIn) {
this.level = harvestLevelIn;
this.uses = maxUsesIn;
- this.spped = speedIn;
+ this.speed = speedIn;
this.attackDamageBonus = attackDamageBonusIn;
this.enchantmentValue = enchantmentValueIn;
this.repairIngredient = new LazyValue<>(repairIngredientIn);
@@ -42,7 +42,7 @@ public int getUses() {
@Override
public float getSpeed() {
- return spped;
+ return speed;
}
@Override
diff --git a/src/main/java/com/someguyssoftware/treasure2/item/TreasureItems.java b/src/main/java/com/someguyssoftware/treasure2/item/TreasureItems.java
index 28de4479d..ed51db68c 100644
--- a/src/main/java/com/someguyssoftware/treasure2/item/TreasureItems.java
+++ b/src/main/java/com/someguyssoftware/treasure2/item/TreasureItems.java
@@ -19,20 +19,29 @@
*/
package com.someguyssoftware.treasure2.item;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
import java.util.function.Supplier;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.someguyssoftware.gottschcore.item.ModItem;
+import com.someguyssoftware.gottschcore.loot.LootTableShell;
import com.someguyssoftware.treasure2.Treasure;
import com.someguyssoftware.treasure2.block.TreasureBlocks;
+import com.someguyssoftware.treasure2.capability.CharmableCapability;
+import com.someguyssoftware.treasure2.capability.CharmableCapability.InventoryType;
+import com.someguyssoftware.treasure2.capability.CharmableCapabilityProvider;
+import com.someguyssoftware.treasure2.capability.ICharmableCapability;
+import com.someguyssoftware.treasure2.charm.TreasureCharms;
import com.someguyssoftware.treasure2.config.TreasureConfig;
import com.someguyssoftware.treasure2.config.TreasureConfig.KeyID;
import com.someguyssoftware.treasure2.config.TreasureConfig.LockID;
import com.someguyssoftware.treasure2.enums.Category;
-import com.someguyssoftware.treasure2.enums.Coins;
-import com.someguyssoftware.treasure2.enums.Pearls;
import com.someguyssoftware.treasure2.enums.Rarity;
+import com.someguyssoftware.treasure2.loot.TreasureLootTableMaster2.SpecialLootTables;
+import com.someguyssoftware.treasure2.loot.TreasureLootTableRegistry;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.color.BlockColors;
@@ -42,10 +51,14 @@
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
import net.minecraft.item.SwordItem;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.ColorHandlerEvent;
+import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@@ -92,7 +105,8 @@ public class TreasureItems {
public static KeyItem THIEFS_LOCK_PICK;
public static KeyRingItem KEY_RING;
-
+ public static PouchItem POUCH;
+
// locks
public static LockItem WOOD_LOCK;
public static LockItem STONE_LOCK;
@@ -108,26 +122,37 @@ public class TreasureItems {
public static LockItem WITHER_LOCK;
// coins
+ public static Item COPPER_COIN;
public static Item SILVER_COIN;
public static Item GOLD_COIN;
-
+
// gems
+ public static Item TOPAZ;
+ public static Item ONYX;
public static Item SAPPHIRE;
public static Item RUBY;
public static Item WHITE_PEARL;
public static Item BLACK_PEARL;
-
+
+ // charms
+ public static CharmItem COPPER_CHARM;
+ public static CharmItem SILVER_CHARM;
+ public static CharmItem GOLD_CHARM;
+ public static CharmItem CHARM_BOOK;
+
// wither items
public static Item WITHER_STICK_ITEM;
public static Item WITHER_ROOT_ITEM;
// other
public static Item SKELETON;
-// public static Item EYE_PATCH;
-
+ // public static Item EYE_PATCH;
+
// swords
public static Item SKULL_SWORD;
-
+
+ // key map
+ public static Multimap keys;
// lock map
public static Multimap locks;
@@ -138,13 +163,13 @@ public class TreasureItems {
*/
@SubscribeEvent
public static void registerItems(RegistryEvent.Register- event) {
-
+
/*
* initialize items
*/
LOGO = new ModItem(Treasure.MODID, "treasure_tab", new Item.Properties());
TREASURE_TOOL = new TreasureToolItem(Treasure.MODID, "treasure_tool", new Item.Properties());
-
+
// KEYS
WOOD_KEY = new KeyItem(Treasure.MODID, KeyID.WOOD_KEY_ID, new Item.Properties().durability(TreasureConfig.KEYS_LOCKS.woodKeyMaxUses.get()))
.setCategory(Category.ELEMENTAL)
@@ -254,7 +279,11 @@ public static void registerItems(RegistryEvent.Register
- event) {
.setSuccessProbability(32);
KEY_RING = new KeyRingItem(Treasure.MODID, KeyID.KEY_RING_ID, new Item.Properties());
-
+
+ keys = ArrayListMultimap.create();
+ keys.put(WOOD_KEY.getRarity(), WOOD_KEY);
+ // TODO finish list
+
// LOCKS
WOOD_LOCK = new LockItem(Treasure.MODID, LockID.WOOD_LOCK_ID, new Item.Properties(), new KeyItem[] {WOOD_KEY})
.setCategory(Category.ELEMENTAL)
@@ -309,31 +338,174 @@ public static void registerItems(RegistryEvent.Register
- event) {
locks.put(SAPPHIRE_LOCK.getRarity(), SAPPHIRE_LOCK);
locks.put(SPIDER_LOCK.getRarity(), SPIDER_LOCK);
// NOTE wither lock is a special and isn't used in the general locks list
-
+
// COINS
- SILVER_COIN = new CoinItem(Treasure.MODID, TreasureConfig.ItemID.SILVER_COIN_ID, new Item.Properties()).setCoin(Coins.SILVER);
- GOLD_COIN = new CoinItem(Treasure.MODID, TreasureConfig.ItemID.GOLD_COIN_ID, new Item.Properties());
-
+ COPPER_COIN = new WealthItem(Treasure.MODID, TreasureConfig.ItemID.COPPER_COIN_ID, new Item.Properties());
+ SILVER_COIN = new WealthItem(Treasure.MODID, TreasureConfig.ItemID.SILVER_COIN_ID, new Item.Properties()) {
+ @Override
+ public List getLootTables() {
+ List lootTables = new ArrayList<>();
+ lootTables.addAll(TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.UNCOMMON));
+ lootTables.addAll(TreasureLootTableRegistry.getLootTableMaster().getLootTableByRarity(Rarity.SCARCE));
+ return lootTables;
+ }
+ @Override
+ public ItemStack getDefaultLootKey (Random random) {
+ List