From a8357839dd428c14db695f59a308b858ce3b230f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 9 Apr 2021 03:54:14 -0500 Subject: [PATCH] Add Cake Fuel Tooltip (#20) * Display the fuel used to refill cakes in the item's tooltip * Implement config caching with event-triggered invalidation to support accurate display of tooltips when multiple custom cakes are defined * Implement TOP and WAILA information for fuel Co-authored-by: Exa <11907282+Exaxxion@users.noreply.github.com> Co-authored-by: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> --- .../DimensionalEdibles.java | 31 ++-- .../block/BlockCakeBase.java | 48 +++++- .../block/BlockCustomCake.java | 127 +++++++++++----- .../item/ItemBlockCustomCake.java | 7 +- .../item/ItemCustomApple.java | 137 ++++++++++-------- .../registry/ModConfig.java | 62 +++++--- .../jackyy/dimensionaledibles/util/Cache.java | 48 ++++++ .../assets/dimensionaledibles/lang/en_US.lang | 4 + 8 files changed, 323 insertions(+), 141 deletions(-) create mode 100644 src/main/java/jackyy/dimensionaledibles/util/Cache.java diff --git a/src/main/java/jackyy/dimensionaledibles/DimensionalEdibles.java b/src/main/java/jackyy/dimensionaledibles/DimensionalEdibles.java index fae60bc..4379cd0 100644 --- a/src/main/java/jackyy/dimensionaledibles/DimensionalEdibles.java +++ b/src/main/java/jackyy/dimensionaledibles/DimensionalEdibles.java @@ -1,17 +1,23 @@ package jackyy.dimensionaledibles; -import jackyy.dimensionaledibles.command.DimensionalEdiblesCommand; -import jackyy.dimensionaledibles.proxy.CommonProxy; -import jackyy.dimensionaledibles.registry.ModBlocks; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.SidedProxy; +import jackyy.dimensionaledibles.block.*; +import jackyy.dimensionaledibles.command.*; +import jackyy.dimensionaledibles.proxy.*; +import jackyy.dimensionaledibles.registry.*; +import net.minecraft.creativetab.*; +import net.minecraft.item.*; +import net.minecraftforge.fml.common.*; import net.minecraftforge.fml.common.event.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.*; -@Mod(modid = DimensionalEdibles.MODID, name = DimensionalEdibles.MODNAME, version = DimensionalEdibles.VERSION, acceptedMinecraftVersions = DimensionalEdibles.MCVERSION, dependencies = DimensionalEdibles.DEPENDS, certificateFingerprint = "@FINGERPRINT@", useMetadata = true) +@Mod(modid = DimensionalEdibles.MODID, + name = DimensionalEdibles.MODNAME, + version = DimensionalEdibles.VERSION, + acceptedMinecraftVersions = DimensionalEdibles.MCVERSION, + dependencies = DimensionalEdibles.DEPENDS, + certificateFingerprint = "@FINGERPRINT@", + useMetadata = true) +@SuppressWarnings("unused") public class DimensionalEdibles { public static final String VERSION = "GRADLE:VERSION"; @@ -33,6 +39,7 @@ public ItemStack createIcon() { @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { proxy.preInit(event); + BlockCustomCake.rebuildCache(); } @Mod.EventHandler @@ -47,7 +54,9 @@ public void postInit(FMLPostInitializationEvent event) { @Mod.EventHandler public void onFingerprintViolation(FMLFingerprintViolationEvent event) { - logger.warn("Invalid fingerprint detected! The file " + event.getSource().getName() + " may have been modified. This will NOT be supported by the mod author!"); + logger.warn( + "Invalid fingerprint detected! The file \"{}\" may have been modified. This will NOT be supported by the mod author!", + event.getSource().getName()); } @Mod.EventHandler diff --git a/src/main/java/jackyy/dimensionaledibles/block/BlockCakeBase.java b/src/main/java/jackyy/dimensionaledibles/block/BlockCakeBase.java index 91baf9c..9470615 100644 --- a/src/main/java/jackyy/dimensionaledibles/block/BlockCakeBase.java +++ b/src/main/java/jackyy/dimensionaledibles/block/BlockCakeBase.java @@ -9,6 +9,8 @@ import net.minecraft.block.material.*; import net.minecraft.block.properties.*; import net.minecraft.block.state.*; +import net.minecraft.client.resources.*; +import net.minecraft.client.util.*; import net.minecraft.creativetab.*; import net.minecraft.entity.*; import net.minecraft.entity.player.*; @@ -23,6 +25,8 @@ import javax.annotation.*; import java.util.*; +import static jackyy.dimensionaledibles.DimensionalEdibles.*; +import static jackyy.dimensionaledibles.item.ItemBlockCustomCake.*; import static jackyy.dimensionaledibles.util.TeleporterHandler.*; /** @@ -117,7 +121,7 @@ public boolean onBlockActivated(World worldIn, ItemStack stack = playerIn.getHeldItem(hand); if (!stack.isEmpty() && - ItemStack.areItemsEqual(stack, getFuelItemStack()) && + ItemStack.areItemsEqual(stack, getFuelItemStack(this.cakeDimension())) && fuelUntilFull != 0) { if (meta >= 0) { worldIn.setBlockState(pos, state.withProperty(BITES, meta), 2); @@ -212,11 +216,21 @@ public void addProbeInfo(ProbeMode mode, World world, IBlockState blockState, IProbeHitData data) { + + ItemStack fuelStack = getFuelItemStack(this.cakeDimension()); + //Only the custom cake falls back to a default empty ItemStack, so if the ItemStack is empty, the cake is a + //custom cake with a bad fuel entry + String fuel = fuelStack.isEmpty() ? I18n.format("tooltip.dimensionaledibles.custom_cake.bad_config") : + I18n.format(fuelStack.getTranslationKey() + ".name"); + if (world.getBlockState(data.getPos()).getBlock() instanceof BlockCakeBase) { probeInfo.horizontal(probeInfo.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER)) .item(new ItemStack(Items.CAKE)) .text(TextFormatting.GREEN + "Bites: ") .progress(MAX_BITES - blockState.getValue(BITES), MAX_BITES); + probeInfo.horizontal(probeInfo.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER)) + .item(fuelStack.isEmpty() ? new ItemStack(Blocks.BARRIER) : fuelStack) + .text(TextFormatting.GREEN + "Refill: " + fuel); } } @@ -225,9 +239,15 @@ public List getWailaBody(ItemStack itemStack, List currentTip, IWailaDataAccessor accessor, IWailaConfigHandler config) { + + ItemStack fuelStack = getFuelItemStack(this.cakeDimension()); + String fuel = fuelStack.isEmpty() ? I18n.format("tooltip.dimensionaledibles.custom_cake.bad_config") : + I18n.format(fuelStack.getTranslationKey() + ".name"); + if (accessor.getBlockState().getBlock() instanceof BlockCakeBase) { currentTip.add(TextFormatting.GRAY + "Bites: " + (MAX_BITES - accessor.getBlockState().getValue(BITES)) + " / " + MAX_BITES); + currentTip.add(TextFormatting.GRAY + "Refill: " + fuel); } return currentTip; } @@ -255,8 +275,8 @@ protected void teleportPlayer(World world, EntityPlayer player) { EntityPlayerMP playerMP = (EntityPlayerMP) player; BlockPos coords; - if (config().useCustomCoordinates()) - coords = config().customCoords().toBlockPos(); + if (config().useCustomCoordinates(this.cakeDimension())) + coords = config().customCoords(this.cakeDimension()).toBlockPos(); else coords = calculateCoordinates(playerMP); @@ -293,8 +313,13 @@ protected void consumeCake(World world, * @return The Fuel as an ItemStack if the Config entry is well-formed, * {@link #defaultFuel} otherwise. */ - private ItemStack getFuelItemStack() { - Item configItem = Item.REGISTRY.getObject(new ResourceLocation(config().fuel())); + private ItemStack getFuelItemStack(int dim) { + String fuel = config().fuel(dim); + if (fuel == null || fuel.equals("")) { + logger.error("Could not parse fuel for cake (dimension \"{}\"). Falling back to default fuel.", dim); + return defaultFuel(); + } + Item configItem = Item.REGISTRY.getObject(new ResourceLocation(fuel)); return configItem == null ? defaultFuel() : new ItemStack(configItem); } @@ -305,4 +330,17 @@ public void getSubBlocks(CreativeTabs tab, if (registerItem()) list.add(new ItemStack(this)); } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) { + super.addInformation(stack, worldIn, tooltip, flagIn); + ItemStack fuelStack = getFuelItemStack(getDimID(stack)); + if (fuelStack == ItemStack.EMPTY) + tooltip.add(I18n.format("tooltip.dimensionaledibles.custom_cake.bad_config")); + else + // Why do I need to add ".name"? Thank you Lex. + tooltip.add(I18n.format("tooltip.dimensionaledibles.cake", + I18n.format(fuelStack.getTranslationKey() + ".name"))); + } } \ No newline at end of file diff --git a/src/main/java/jackyy/dimensionaledibles/block/BlockCustomCake.java b/src/main/java/jackyy/dimensionaledibles/block/BlockCustomCake.java index 7cd2833..b588474 100644 --- a/src/main/java/jackyy/dimensionaledibles/block/BlockCustomCake.java +++ b/src/main/java/jackyy/dimensionaledibles/block/BlockCustomCake.java @@ -2,12 +2,13 @@ import jackyy.dimensionaledibles.*; import jackyy.dimensionaledibles.block.tile.*; +import jackyy.dimensionaledibles.item.*; import jackyy.dimensionaledibles.registry.*; +import jackyy.dimensionaledibles.util.*; import net.minecraft.block.*; import net.minecraft.block.state.*; import net.minecraft.creativetab.*; import net.minecraft.entity.player.*; -import net.minecraft.init.*; import net.minecraft.item.*; import net.minecraft.nbt.*; import net.minecraft.tileentity.*; @@ -16,7 +17,6 @@ import net.minecraft.world.*; import net.minecraftforge.common.*; import net.minecraftforge.fml.relauncher.*; -import org.apache.logging.log4j.*; import javax.annotation.*; @@ -24,12 +24,26 @@ public class BlockCustomCake extends BlockCakeBase implements ITileEntityProvider { - private int customX = 0; - private int customY = 0; - private int customZ = 0; + /** Dimension of the last-clicked cake. */ + private int cakeDimension; - private String cakeFuel; - private int cakeDimension = 0; + private static class CustomCake { + public ModConfig.CustomCoords customCoords = new ModConfig.CustomCoords(0,0,0); + private String cakeFuel = null; + private final int cakeDimension; + + public CustomCake(int dim) { + this.cakeDimension = dim; + } + + @Override + public String toString() { + return String.format("CustomCake[dim: %d, fuel: %s, coords: %s]", + cakeDimension, cakeFuel, customCoords); + } + } + + private static Cache cache = new Cache<>(); public BlockCustomCake() { super(); @@ -47,9 +61,16 @@ public boolean onBlockActivated(World world, float hitX, float hitY, float hitZ) { - this.cakeDimension = getDimension(world, pos); - this.cakeFuel = determineCakeFuel(); - updateCustomCoordinates(); + + + + int dim = getDimension(world, pos); + if(!cache.containsKey(dim)) { + logger.error("No such dimension: \"{}\"", dim); + return true; + } + + this.cakeDimension = dim; return super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ); } @@ -62,46 +83,63 @@ private int getDimension(World world, throw new IllegalArgumentException("Specified position does not contain a Custom Cake"); } - private void updateCustomCoordinates() { + /** + * DO NOT CALL THIS METHOD OUTSIDE OF PREINIT AND CONFIG CHANGE EVENT HANDLERS. + * This should be private but Forge forced my hand. + */ + public static void rebuildCache() { + Cache newCache = new Cache<>(); + + NonNullList subBlocks = NonNullList.create(); + new BlockCustomCake().getSubBlocks(CreativeTabs.BUILDING_BLOCKS, subBlocks); + for(ItemStack stack : subBlocks) { + int dimID = ItemBlockCustomCake.getDimID(stack); + newCache.putIfAbsent(dimID, new CustomCake(dimID)); + } + for(String s : ModConfig.tweaks.customEdible.customCoords) { try { String[] parts = s.split(","); if (parts.length < 4) { - logger.log(Level.ERROR, - s + " is not a valid input line! Format needs to be: , , , "); + logger.error("\"{}\" is not a valid input line! Format needs to be: , , , ", s); continue; } - if (Integer.parseInt(parts[0].trim()) == cakeDimension) { - customX = Integer.parseInt(parts[1].trim()); - customY = Integer.parseInt(parts[2].trim()); - customZ = Integer.parseInt(parts[3].trim()); + int dim = Integer.parseInt(parts[0].trim()); + if(!newCache.containsKey(dim)) { + logger.error("Unrecognized dimension: \"{}\"", dim); + return; } + CustomCake cake = newCache.get(dim); + + ModConfig.CustomCoords cc = cake.customCoords; + cc.x = Integer.parseInt(parts[1].trim()); + cc.y = Integer.parseInt(parts[2].trim()); + cc.z = Integer.parseInt(parts[3].trim()); + } catch(NumberFormatException e) { - logger.log(Level.ERROR, - s + " is not a valid line input! The dimension ID needs to be a number!"); + logger.error("\"{}\" is not a valid line input! The dimension ID needs to be a number!", s, e); + return; } } - } - private String determineCakeFuel() { - String fuel = "minecraft:air"; for(String s : ModConfig.tweaks.customEdible.customCake.fuel) { try { String[] parts = s.split(","); if (parts.length < 2) { - logger.log(Level.ERROR, - s + " is not a valid input line! Format needs to be: , "); - continue; - } - if (Integer.parseInt(parts[0].trim()) == cakeDimension) { - fuel = parts[1].trim(); + logger.error("\"{}\" is not a valid input line! Format needs to be: , ", s); + return; } + int dim = Integer.parseInt(parts[0].trim()); + CustomCake cake = newCache.get(dim); + + cake.cakeFuel = parts[1].trim(); } catch(NumberFormatException e) { - logger.log(Level.ERROR, - s + " is not a valid line input! The dimension ID needs to be a number!"); + logger.error("\"{}\" is not a valid line input! The dimension ID needs to be a number!", s, e); + return; } } - return fuel; + + cache = newCache; } @Override @@ -114,8 +152,7 @@ public void getSubBlocks(CreativeTabs tab, try { String[] parts = s.split(","); if (parts.length < 2) { - logger.log(Level.ERROR, - s + " is not a valid input line! Format needs to be: , "); + logger.error("\"{}\" is not a valid input line! Format needs to be: , ", s); continue; } int dimension = Integer.parseInt(parts[0].trim()); @@ -130,12 +167,10 @@ public void getSubBlocks(CreativeTabs tab, nbt.setString("cakeName", parts[1].trim()); list.add(stack); } else { - logger.log(Level.ERROR, - parts[0] + " is not a valid dimension ID! (Needs to be a number)"); + logger.error("\"{}\" is not a valid dimension ID!", parts[0]); } } catch(NumberFormatException e) { - logger.log(Level.ERROR, - s + " is not a valid line input! The dimension ID needs to be a number!"); + logger.error("\"{}\" is not a valid line input! The dimension ID needs to be a number!", s, e); } } } @@ -149,11 +184,23 @@ public TileEntity createNewTileEntity(@Nonnull World world, private final ModConfig.CakeConfig conf = new ModConfig.CakeConfig() { @Override - public String fuel() { return cakeFuel; } + public String fuel(int dim) { + return cache.getPropertyIfPresentOrNull(dim, c -> c.cakeFuel); + } + @Override - public boolean useCustomCoordinates() { return (customX != 0 || customY != 0 || customZ != 0); } + public boolean useCustomCoordinates(int dim) { + return cache.getPropertyIfPresentOrElse(dim, c -> { + ModConfig.CustomCoords cc = c.customCoords; + return (cc.x != 0 || cc.y != 0 || cc.z != 0); + }, () -> false); + } + @Override - public ModConfig.CustomCoords customCoords() { return new ModConfig.CustomCoords(customX, customY, customZ); } + public ModConfig.CustomCoords customCoords(int dim) { + return cache.getPropertyIfPresentOrElse(dim, c -> c.customCoords, () -> new CustomCake(dim).customCoords); + } + @Override public boolean consumesFuel() { return ModConfig.tweaks.customEdible.customCake.consumeFuel; } @Override diff --git a/src/main/java/jackyy/dimensionaledibles/item/ItemBlockCustomCake.java b/src/main/java/jackyy/dimensionaledibles/item/ItemBlockCustomCake.java index 7cfcd75..1d26185 100644 --- a/src/main/java/jackyy/dimensionaledibles/item/ItemBlockCustomCake.java +++ b/src/main/java/jackyy/dimensionaledibles/item/ItemBlockCustomCake.java @@ -2,6 +2,7 @@ import jackyy.dimensionaledibles.block.tile.TileDimensionCake; import jackyy.dimensionaledibles.registry.ModBlocks; +import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumRarity; @@ -13,6 +14,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class ItemBlockCustomCake extends ItemBlock { public ItemBlockCustomCake() { @@ -53,7 +58,7 @@ public String getCakeName(ItemStack stack) { return nbt.getString("cakeName"); } - public int getDimID(ItemStack stack) { + public static int getDimID(ItemStack stack) { NBTTagCompound nbt = stack.getTagCompound(); if (nbt == null || !nbt.hasKey("dimID")) { return 0; diff --git a/src/main/java/jackyy/dimensionaledibles/item/ItemCustomApple.java b/src/main/java/jackyy/dimensionaledibles/item/ItemCustomApple.java index af03199..140bbe8 100644 --- a/src/main/java/jackyy/dimensionaledibles/item/ItemCustomApple.java +++ b/src/main/java/jackyy/dimensionaledibles/item/ItemCustomApple.java @@ -1,25 +1,27 @@ package jackyy.dimensionaledibles.item; -import jackyy.dimensionaledibles.DimensionalEdibles; -import jackyy.dimensionaledibles.registry.ModConfig; -import jackyy.dimensionaledibles.util.TeleporterHandler; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.MobEffects; -import net.minecraft.item.EnumRarity; -import net.minecraft.item.ItemFood; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.PotionEffect; -import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.apache.logging.log4j.Level; +import jackyy.dimensionaledibles.*; +import jackyy.dimensionaledibles.registry.*; +import jackyy.dimensionaledibles.util.*; +import mcp.*; +import net.minecraft.creativetab.*; +import net.minecraft.entity.player.*; +import net.minecraft.init.*; +import net.minecraft.item.*; +import net.minecraft.nbt.*; +import net.minecraft.potion.*; +import net.minecraft.util.*; +import net.minecraft.util.math.*; +import net.minecraft.world.*; +import net.minecraftforge.common.*; +import net.minecraftforge.fml.relauncher.*; +import javax.annotation.*; + +import static jackyy.dimensionaledibles.DimensionalEdibles.*; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class ItemCustomApple extends ItemFood { public ItemCustomApple() { @@ -31,7 +33,9 @@ public ItemCustomApple() { } @Override - public void onFoodEaten(ItemStack stack, World world, EntityPlayer player) { + public void onFoodEaten(ItemStack stack, + World world, + EntityPlayer player) { int dimension; NBTTagCompound nbt = stack.getTagCompound(); if (nbt == null || !nbt.hasKey("dimID")) { @@ -51,7 +55,12 @@ public void onFoodEaten(ItemStack stack, World world, EntityPlayer player) { coords = TeleporterHandler.getDimPos(playerMP, dimension, player.getPosition()); } TeleporterHandler.updateDimPos(playerMP, world.provider.getDimension(), player.getPosition()); - TeleporterHandler.teleport(playerMP, dimension, coords.getX(), coords.getY(), coords.getZ(), playerMP.server.getPlayerList()); + TeleporterHandler.teleport(playerMP, + dimension, + coords.getX(), + coords.getY(), + coords.getZ(), + playerMP.server.getPlayerList()); player.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 200, 200, false, false)); } } @@ -59,55 +68,61 @@ public void onFoodEaten(ItemStack stack, World world, EntityPlayer player) { @Override @SideOnly(Side.CLIENT) - public void getSubItems(CreativeTabs tab, NonNullList list) { + public void getSubItems(CreativeTabs tab, + NonNullList list) { if (isInCreativeTab(tab)) { if (ModConfig.general.customApple) { - ItemStack stack; - for (String s : ModConfig.tweaks.customEdible.dimensions) { + for(String s : ModConfig.tweaks.customEdible.dimensions) { + parseSubItemsString(s, list); + } + } + } + } + + private void parseSubItemsString(String s, + NonNullList list) { + ItemStack stack; + try { + String[] parts = s.split(","); + if (parts.length < 2) { + logger.error("{} is not a valid input line! Format needs to be: , ", s); + return; + } + int dimension = Integer.parseInt(parts[0]); + if (DimensionManager.isDimensionRegistered(dimension)) { + stack = new ItemStack(this); + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt == null) { + nbt = new NBTTagCompound(); + stack.setTagCompound(nbt); + } + nbt.setInteger("dimID", dimension); + nbt.setString("appleName", parts[1].trim()); + nbt.setInteger("x", 0); + nbt.setInteger("y", 0); + nbt.setInteger("z", 0); + for(String c : ModConfig.tweaks.customEdible.customCoords) { try { - String[] parts = s.split(","); - if (parts.length < 2) { - DimensionalEdibles.logger.log(Level.ERROR, s + " is not a valid input line! Format needs to be: , "); + String[] coords = c.split(","); + if (coords.length < 4) { + logger.error("{} is not a valid input line! Format needs to be: , , , ", c); continue; } - int dimension = Integer.parseInt(parts[0]); - if (DimensionManager.isDimensionRegistered(dimension)) { - stack = new ItemStack(this); - NBTTagCompound nbt = stack.getTagCompound(); - if (nbt == null) { - nbt = new NBTTagCompound(); - stack.setTagCompound(nbt); - } - nbt.setInteger("dimID", dimension); - nbt.setString("appleName", parts[1].trim()); - nbt.setInteger("x", 0); - nbt.setInteger("y", 0); - nbt.setInteger("z", 0); - for (String c : ModConfig.tweaks.customEdible.customCoords) { - try { - String[] coords = c.split(","); - if (coords.length < 4) { - DimensionalEdibles.logger.log(Level.ERROR, c + " is not a valid input line! Format needs to be: , , , "); - continue; - } - if (Integer.parseInt(coords[0].trim()) == dimension) { - nbt.setInteger("x", Integer.parseInt(coords[1].trim())); - nbt.setInteger("y", Integer.parseInt(coords[2].trim())); - nbt.setInteger("z", Integer.parseInt(coords[3].trim())); - } - } catch (NumberFormatException e) { - DimensionalEdibles.logger.log(Level.ERROR, c + " is not a valid line input! The dimension ID needs to be a number!"); - } - } - list.add(stack); - } else { - DimensionalEdibles.logger.log(Level.ERROR, parts[0] + " is not a valid dimension ID! (Needs to be a number)"); + if (Integer.parseInt(coords[0].trim()) == dimension) { + nbt.setInteger("x", Integer.parseInt(coords[1].trim())); + nbt.setInteger("y", Integer.parseInt(coords[2].trim())); + nbt.setInteger("z", Integer.parseInt(coords[3].trim())); } - } catch (NumberFormatException e) { - DimensionalEdibles.logger.log(Level.ERROR, s + " is not a valid line input! The dimension ID needs to be a number!"); + } catch(NumberFormatException e) { + logger.error("{} is not a valid line input! The dimension ID needs to be a number!", c, e); } } + list.add(stack); + } else { + logger.error("{} is not a valid dimension ID! (Needs to be a number)", parts[0]); } + } catch(NumberFormatException e) { + logger.error("{} is not a valid line input! The dimension ID needs to be a number!", s, e); } } diff --git a/src/main/java/jackyy/dimensionaledibles/registry/ModConfig.java b/src/main/java/jackyy/dimensionaledibles/registry/ModConfig.java index a750d7a..8e863d2 100644 --- a/src/main/java/jackyy/dimensionaledibles/registry/ModConfig.java +++ b/src/main/java/jackyy/dimensionaledibles/registry/ModConfig.java @@ -1,12 +1,12 @@ package jackyy.dimensionaledibles.registry; -import jackyy.dimensionaledibles.DimensionalEdibles; -import net.minecraft.util.math.BlockPos; -import net.minecraftforge.common.config.Config; -import net.minecraftforge.common.config.ConfigManager; -import net.minecraftforge.fml.client.event.ConfigChangedEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import jackyy.dimensionaledibles.*; +import jackyy.dimensionaledibles.block.*; +import net.minecraft.util.math.*; +import net.minecraftforge.common.config.*; +import net.minecraftforge.fml.client.event.*; +import net.minecraftforge.fml.common.*; +import net.minecraftforge.fml.common.eventhandler.*; @Config(modid = DimensionalEdibles.MODID, name = "DimensionalEdibles", category = DimensionalEdibles.MODID) public class ModConfig { @@ -17,8 +17,11 @@ public class ModConfig { public static Tweaks tweaks = new Tweaks(); public interface CakeConfig { - /** Resource name of the fuel item for this cake. */ - String fuel(); + /** + * Resource name of the fuel item for this cake. + * @param dim target dimension (ignored except for CustomEdible) + */ + String fuel(int dim); /** Whether this cake comes pre-fueled (true) or starts empty (false) */ boolean preFueled(); @@ -26,11 +29,17 @@ public interface CakeConfig { /** Whether this cake should consume fuel. */ boolean consumesFuel(); - /** Whether to use custom coordinates */ - boolean useCustomCoordinates(); - - /** Custom Coordinates defined for this cake */ - CustomCoords customCoords(); + /** + * Whether to use custom coordinates + * @param dim target dimension (ignored except for CustomEdible) + */ + boolean useCustomCoordinates(int dim); + + /** + * Custom Coordinates defined for this cake + * @param dim target dimension (ignored except for CustomEdible) + */ + CustomCoords customCoords(int dim); } public static class General { @@ -77,6 +86,11 @@ public CustomCoords(double x, double y, double z) { public BlockPos toBlockPos() { return new BlockPos(x, y, z); } + + @Override + public String toString() { + return String.format("<%.2f,%.2f,%.2f>",x,y,z); + } } public static class Tweaks { @@ -111,11 +125,11 @@ public static class EndCake implements CakeConfig { public CustomCoords customCoords = new CustomCoords(); // boilerplate - public String fuel() { return fuel; } + public String fuel(int dim) { return fuel; } public boolean preFueled() { return preFueled; } public boolean consumesFuel() { return consumeFuel; } - public boolean useCustomCoordinates() { return useCustomCoords; } - public CustomCoords customCoords() { return customCoords; } + public boolean useCustomCoordinates(int dim) { return useCustomCoords; } + public CustomCoords customCoords(int dim) { return customCoords; } } public static class EnderApple { @@ -138,11 +152,11 @@ public static class NetherCake implements CakeConfig { public CustomCoords customCoords = new CustomCoords(); // boilerplate - public String fuel() { return fuel; } + public String fuel(int dim) { return fuel; } public boolean preFueled() { return preFueled; } public boolean consumesFuel() { return consumeFuel; } - public boolean useCustomCoordinates() { return useCustomCoords; } - public CustomCoords customCoords() { return customCoords; } + public boolean useCustomCoordinates(int dim) { return useCustomCoords; } + public CustomCoords customCoords(int dim) { return customCoords; } } public static class NetherApple { @@ -170,11 +184,11 @@ public static class OverworldCake implements CakeConfig { public CustomCoords customCoords = new CustomCoords(); // boilerplate - public String fuel() { return fuel; } + public String fuel(int dim) { return fuel; } public boolean preFueled() { return preFueled; } public boolean consumesFuel() { return consumeFuel; } - public boolean useCustomCoordinates() { return useCustomCoords; } - public CustomCoords customCoords() { return customCoords; } + public boolean useCustomCoordinates(int dim) { return useCustomCoords; } + public CustomCoords customCoords(int dim) { return customCoords; } } public static class OverworldApple { @@ -226,9 +240,11 @@ public static class CustomCake { @Mod.EventBusSubscriber public static class ConfigHolder { @SubscribeEvent + @SuppressWarnings("unused") public static void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event) { if (event.getModID().equals(DimensionalEdibles.MODID)) { ConfigManager.sync(DimensionalEdibles.MODID, Config.Type.INSTANCE); + BlockCustomCake.rebuildCache(); } } } diff --git a/src/main/java/jackyy/dimensionaledibles/util/Cache.java b/src/main/java/jackyy/dimensionaledibles/util/Cache.java new file mode 100644 index 0000000..33e3512 --- /dev/null +++ b/src/main/java/jackyy/dimensionaledibles/util/Cache.java @@ -0,0 +1,48 @@ +package jackyy.dimensionaledibles.util; + +import mcp.*; + +import javax.annotation.*; +import java.util.*; +import java.util.function.*; + +/** + * Specialization of HashMap which adds the ability to interact with fields of a potentially nonexistent key, + * using a lazily-evaluated fallback if the key does not exist. + * + * @param Class of the map keys + * @param Class of the map values + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class Cache extends HashMap { + /** + * @param key the key of the map entry + * @param ifFunction produces data from the value of the map entry if the key exists + * @param elseFunction produces the alternative result if the map contains no such key + * @param the type of value returned + * @return the value produced by {@code ifFunction} if the map contains an entry with the specified key, otherwise the + * result of {@code elseFunction.get()}. + */ + public T getPropertyIfPresentOrElse(K key, + Function ifFunction, + Supplier elseFunction) { + if (!this.containsKey(key)) + return elseFunction.get(); + return ifFunction.apply(this.get(key)); + } + + /** + * @param key the key of the map entry + * @param ifFunction produces data from the value of the map entry if the key exists + * @param the type of value returned + * @return the value produced by {@code ifFunction} if the map contains an entry with the specified key, + * otherwise {@code null}. + * @see Cache#getPropertyIfPresentOrElse(Object, Function, Supplier) + */ + @Nullable + public T getPropertyIfPresentOrNull(K key, + Function ifFunction) { + return this.getPropertyIfPresentOrElse(key, ifFunction, () -> null); + } +} diff --git a/src/main/resources/assets/dimensionaledibles/lang/en_US.lang b/src/main/resources/assets/dimensionaledibles/lang/en_US.lang index f83ad9d..14d908e 100644 --- a/src/main/resources/assets/dimensionaledibles/lang/en_US.lang +++ b/src/main/resources/assets/dimensionaledibles/lang/en_US.lang @@ -13,6 +13,10 @@ tile.dimensionaledibles.nether_cake.name=Nether Cake tile.dimensionaledibles.overworld_cake.name=Overworld Cake tile.dimensionaledibles.custom_cake.name=Custom Cake +#Tooltip +tooltip.dimensionaledibles.cake=§3§oRefill using %s. +tooltip.dimensionaledibles.custom_cake.bad_config=§4Could not get Custom Cake fuel! + #JEI Compat dimensionaledibles.end_cake.jeidesc=Place the cake down and fill it with %d, then right click on the cake and you'll be teleported to The End. The cake has infinite uses as long as it is fueled. dimensionaledibles.nether_cake.jeidesc=Place the cake down and fill it with %d, then right click on the cake and you'll be teleported to the Nether. The cake has infinite uses as long as it is fueled.