diff --git a/src/main/java/com/pahimar/ee3/EquivalentExchange3.java b/src/main/java/com/pahimar/ee3/EquivalentExchange3.java index fbd0832a..a2972681 100644 --- a/src/main/java/com/pahimar/ee3/EquivalentExchange3.java +++ b/src/main/java/com/pahimar/ee3/EquivalentExchange3.java @@ -16,7 +16,6 @@ import com.pahimar.ee3.recipe.RecipeRegistry; import com.pahimar.ee3.reference.Files; import com.pahimar.ee3.reference.Messages; import com.pahimar.ee3.reference.Reference; -import com.pahimar.ee3.reference.Settings; import com.pahimar.ee3.test.EnergyValueMappingsTestSuite; import com.pahimar.ee3.util.FluidHelper; import com.pahimar.ee3.util.LogHelper; @@ -61,7 +60,7 @@ public class EquivalentExchange3 TransmutationKnowledgeRegistry.getInstance(); - AbilityRegistry.getInstance().loadAbilityRegistryFromFile(Settings.Abilities.onlyLoadFile); + AbilityRegistry.getInstance().loadAbilityRegistryFromFile(ConfigurationHandler.Settings.onlyLoadFile); event.registerServerCommand(new CommandEE()); } diff --git a/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java b/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java index 5feee502..b61b04ff 100644 --- a/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java +++ b/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java @@ -1,11 +1,11 @@ package com.pahimar.ee3.command; import com.pahimar.ee3.exchange.EnergyValueRegistry; +import com.pahimar.ee3.handler.ConfigurationHandler; import com.pahimar.ee3.network.PacketHandler; import com.pahimar.ee3.network.message.MessageSyncEnergyValues; import com.pahimar.ee3.reference.Messages; import com.pahimar.ee3.reference.Names; -import com.pahimar.ee3.reference.Settings; import com.pahimar.ee3.util.LogHelper; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; @@ -50,13 +50,13 @@ public class CommandSyncEnergyValues extends CommandBase if (requesterMap.containsKey(commandSenderUUID)) { long timeDifference = System.currentTimeMillis() - requesterMap.get(commandSenderUUID).longValue(); - if (timeDifference >= (Settings.General.syncThreshold * 1000)) + if (timeDifference >= (ConfigurationHandler.Settings.serverSyncThreshold * 1000)) { requesterMap.remove(commandSenderUUID); } else { - coolDown = (Settings.General.syncThreshold * 1000) - timeDifference; + coolDown = (ConfigurationHandler.Settings.serverSyncThreshold * 1000) - timeDifference; shouldSync = false; } } diff --git a/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java b/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java index 289b2aa9..95f3f6da 100644 --- a/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java +++ b/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java @@ -5,10 +5,10 @@ import com.google.gson.*; import com.pahimar.ee3.api.exchange.EnergyValue; import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; import com.pahimar.ee3.api.exchange.IEnergyValueProvider; +import com.pahimar.ee3.handler.ConfigurationHandler; import com.pahimar.ee3.recipe.RecipeRegistry; import com.pahimar.ee3.reference.Files; import com.pahimar.ee3.reference.Reference; -import com.pahimar.ee3.reference.Settings; import com.pahimar.ee3.util.EnergyValueHelper; import com.pahimar.ee3.util.LoaderHelper; import com.pahimar.ee3.util.LogHelper; @@ -730,13 +730,13 @@ public class EnergyValueRegistry implements JsonSerializer, loadFromFile(new File(Files.Global.dataDirectory, Files.ENERGY_VALUES_JSON)); - if (!Settings.DynamicEnergyValueGeneration.regenerateEnergyValuesWhen.equalsIgnoreCase("Always")) { - if (Settings.DynamicEnergyValueGeneration.regenerateEnergyValuesWhen.equalsIgnoreCase("When Mods Change")) { + if (!ConfigurationHandler.Settings.regenerateEnergyValuesWhen.equalsIgnoreCase("Always")) { + if (ConfigurationHandler.Settings.regenerateEnergyValuesWhen.equalsIgnoreCase("When Mods Change")) { if (md5EnergyValuesFile.exists()) { LogHelper.info(ENERGY_VALUE_MARKER, "Attempting to load energy values from file: {}", md5EnergyValuesFile.getAbsolutePath()); stackValueMap = SerializationHelper.decompressEnergyValueStackMapFromFile(md5EnergyValuesFile); } - } else if (Settings.DynamicEnergyValueGeneration.regenerateEnergyValuesWhen.equalsIgnoreCase("Never")) { + } else if (ConfigurationHandler.Settings.regenerateEnergyValuesWhen.equalsIgnoreCase("Never")) { if (staticEnergyValuesFile.exists()) { LogHelper.info(ENERGY_VALUE_MARKER, "Attempting to load energy values from file: {}", staticEnergyValuesFile.getAbsolutePath()); stackValueMap = SerializationHelper.decompressEnergyValueStackMapFromFile(staticEnergyValuesFile); diff --git a/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java b/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java index f3075b14..88c926a4 100644 --- a/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java +++ b/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java @@ -78,28 +78,54 @@ public class NewEnergyValueRegistry { /** * Returns a {@link Map} containing the post-calculation energy value mappings * - * @return a {link Map} containing the post-calculation energy value mappings + * @return a {@link Map} containing the post-calculation energy value mappings */ public Map getPostCalculationValueMap() { return postCalculationValueMap; } + /** + * Checks if there exists an {@link EnergyValue} associated with the provided {@link Object}. + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @return true if the provided object has an energy value, false otherwise + */ public boolean hasEnergyValue(Object object) { return hasEnergyValue(object, false); } + /** + * Checks if there exists an {@link EnergyValue} associated with the provided {@link Object} + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * assignments) query or not + * @return true if the provided object has an energy value, false otherwise + */ public boolean hasEnergyValue(Object object, boolean strict) { - // TODO This - return false; + return getEnergyValue(object, strict) != null; } + /** + * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @return an {@link EnergyValue} if there is one to be found, null otherwise + */ public EnergyValue getEnergyValue(Object object) { return getEnergyValue(object, false); } + /** + * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * assignments) query or not + * @return an {@link EnergyValue} if there is one to be found, null otherwise + */ public EnergyValue getEnergyValue(Object object, boolean strict) { - // TODO This - return null; + return EnergyValueHelper.getEnergyValue(energyValueMap, object, strict); } /** diff --git a/src/main/java/com/pahimar/ee3/handler/ConfigurationHandler.java b/src/main/java/com/pahimar/ee3/handler/ConfigurationHandler.java index 4f145fa5..ea4dd2ee 100644 --- a/src/main/java/com/pahimar/ee3/handler/ConfigurationHandler.java +++ b/src/main/java/com/pahimar/ee3/handler/ConfigurationHandler.java @@ -1,8 +1,6 @@ package com.pahimar.ee3.handler; -import com.pahimar.ee3.reference.Messages; import com.pahimar.ee3.reference.Reference; -import com.pahimar.ee3.reference.Settings; import com.pahimar.ee3.util.ConfigurationHelper; import cpw.mods.fml.client.event.ConfigChangedEvent; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -15,6 +13,9 @@ public class ConfigurationHandler { public static Configuration configuration; + private static final String CATEGORY_SOUND = "general.sound"; + private static final String CATEGORY_ENERGY_VALUE = "general.energy_value"; + public static void init(File configFile) { if (configuration == null) { @@ -25,11 +26,44 @@ public class ConfigurationHandler { private static void loadConfiguration() { - // TODO Come back and do these constants in logical locations and names - Settings.General.syncThreshold = configuration.getInt(Messages.Configuration.GENERAL_SYNC_THRESHOLD, Configuration.CATEGORY_GENERAL, 5, 0, Short.MAX_VALUE, StatCollector.translateToLocal(Messages.Configuration.GENERAL_SYNC_THRESHOLD_COMMENT), Messages.Configuration.GENERAL_SYNC_THRESHOLD_LABEL); - Settings.Sounds.soundMode = ConfigurationHelper.getString(configuration, Messages.Configuration.SOUND_MODE, Configuration.CATEGORY_GENERAL, "All", StatCollector.translateToLocal(Messages.Configuration.SOUND_MODE_COMMENT), new String[]{"All", "Self", "None"}, Messages.Configuration.SOUND_MODE_LABEL); - Settings.Abilities.onlyLoadFile = configuration.getBoolean(Messages.Configuration.ABILITIES_ONLY_LOAD_FILE, Configuration.CATEGORY_GENERAL, false, StatCollector.translateToLocal(Messages.Configuration.ABILITIES_ONLY_LOAD_FILE_COMMENT), Messages.Configuration.ABILITIES_ONLY_LOAD_FILE_LABEL); - Settings.DynamicEnergyValueGeneration.regenerateEnergyValuesWhen = ConfigurationHelper.getString(configuration, Messages.Configuration.REGENERATE_ENERGYVALUES_WHEN, Configuration.CATEGORY_GENERAL, "Always", StatCollector.translateToLocal(Messages.Configuration.REGENERATE_ENERGYVALUES_WHEN_COMMENT), new String[]{"Never", "When Mods Change", "Always"}, Messages.Configuration.REGENERATE_ENERGYVALUES_WHEN_LABEL); + Settings.serverSyncThreshold = configuration.getInt( + Settings.ENERGY_VALUE_SYNC_THRESHOLD_NAME, + CATEGORY_ENERGY_VALUE, + Settings.ENERGY_VALUE_SYNC_THRESHOLD_DEFAULT, + Settings.ENERGY_VALUE_SYNC_THRESHOLD_MIN, + Settings.ENERGY_VALUE_SYNC_THRESHOLD_MAX, + StatCollector.translateToLocal(Settings.ENERGY_VALUE_SYNC_THRESHOLD_COMMENT), + Settings.ENERGY_VALUE_SYNC_THRESHOLD_LABEL); + + Settings.regenerateEnergyValuesWhen = ConfigurationHelper.getString(configuration, + Settings.ENERGY_VALUE_REGENERATE_WHEN_NAME, + CATEGORY_ENERGY_VALUE, + Settings.ENERGY_VALUE_REGENERATE_WHEN_DEFAULT, + StatCollector.translateToLocal(Settings.ENERGY_VALUE_REGENERATE_WHEN_COMMENT), + Settings.ENERGY_VALUE_REGENERATE_WHEN_OPTIONS, + Settings.ENERGY_VALUE_REGENERATE_WHEN_LABEL); + + Settings.energyValueDebugLoggingEnabled = configuration.getBoolean( + Settings.ENERGY_VALUE_DEBUG_LOGGING_ENABLED_NAME, + CATEGORY_ENERGY_VALUE, + Settings.ENERGY_VALUE_DEBUG_LOGGING_ENABLED_DEFAULT, + StatCollector.translateToLocal(Settings.ENERGY_VALUE_DEBUG_LOGGING_ENABLED_COMMENT), + Settings.ENERGY_VALUE_DEBUG_LOGGING_ENABLED_LABEL); + + Settings.soundMode = ConfigurationHelper.getString(configuration, + Settings.SOUND_MODE_NAME, + CATEGORY_SOUND, + Settings.SOUND_MODE_DEFAULT, + StatCollector.translateToLocal(Settings.SOUND_MODE_COMMENT), + Settings.SOUND_MODE_OPTIONS, + Settings.SOUND_MODE_LABEL); + + Settings.onlyLoadFile = configuration.getBoolean( + Settings.ABILITIES_ONLY_LOAD_FILE_NAME, + Configuration.CATEGORY_GENERAL, + false, + StatCollector.translateToLocal(Settings.ABILITIES_ONLY_LOAD_FILE_COMMENT), + Settings.ABILITIES_ONLY_LOAD_FILE_LABEL); if (configuration.hasChanged()) { configuration.save(); @@ -43,4 +77,40 @@ public class ConfigurationHandler { loadConfiguration(); } } + + public static class Settings { + + public static int serverSyncThreshold; + private static final String ENERGY_VALUE_SYNC_THRESHOLD_NAME = "sync_threshold"; + private static final String ENERGY_VALUE_SYNC_THRESHOLD_LABEL = "energy_value.sync_threshold.label"; + private static final String ENERGY_VALUE_SYNC_THRESHOLD_COMMENT = "energy_value.sync_threshold.comment"; + private static final int ENERGY_VALUE_SYNC_THRESHOLD_DEFAULT = 5; + private static final int ENERGY_VALUE_SYNC_THRESHOLD_MIN = 0; + private static final int ENERGY_VALUE_SYNC_THRESHOLD_MAX = Short.MAX_VALUE; + + public static String regenerateEnergyValuesWhen; + private static final String ENERGY_VALUE_REGENERATE_WHEN_NAME = "regenerate_when"; + private static final String ENERGY_VALUE_REGENERATE_WHEN_LABEL = "energy_value.regenerate_when.label"; + private static final String ENERGY_VALUE_REGENERATE_WHEN_COMMENT = "energy_value.regenerate_when.comment"; + private static final String ENERGY_VALUE_REGENERATE_WHEN_DEFAULT = "Always"; // TODO This is set for during mod dev, set to As Needed for release + private static final String[] ENERGY_VALUE_REGENERATE_WHEN_OPTIONS = new String[]{"As Needed", "Always"}; + + public static boolean energyValueDebugLoggingEnabled; + private static final String ENERGY_VALUE_DEBUG_LOGGING_ENABLED_NAME = "debug_logging_enabled"; + private static final String ENERGY_VALUE_DEBUG_LOGGING_ENABLED_LABEL = "energy_value.debug_logging_enabled.label"; + private static final String ENERGY_VALUE_DEBUG_LOGGING_ENABLED_COMMENT = "energy_value.debug_logging_enabled.comment"; + private static final boolean ENERGY_VALUE_DEBUG_LOGGING_ENABLED_DEFAULT = true; // TODO This is set for during mod dev, set to false for release + + public static String soundMode; + private static final String SOUND_MODE_NAME = "mode"; + private static final String SOUND_MODE_LABEL = "sound.mode.label"; + private static final String SOUND_MODE_COMMENT = "sound.mode.comment"; + private static final String SOUND_MODE_DEFAULT = "All"; + private static final String[] SOUND_MODE_OPTIONS = new String[]{"All", "Self", "None"}; + + public static boolean onlyLoadFile; + private static final String ABILITIES_ONLY_LOAD_FILE_NAME = "abilities.onlyLoadFile"; + private static final String ABILITIES_ONLY_LOAD_FILE_LABEL = "general.abilities.onlyLoadFile.label"; + private static final String ABILITIES_ONLY_LOAD_FILE_COMMENT = "general.abilities.onlyLoadFile.comment"; + } } diff --git a/src/main/java/com/pahimar/ee3/network/message/MessageSoundEvent.java b/src/main/java/com/pahimar/ee3/network/message/MessageSoundEvent.java index ff6ca135..2ebff831 100644 --- a/src/main/java/com/pahimar/ee3/network/message/MessageSoundEvent.java +++ b/src/main/java/com/pahimar/ee3/network/message/MessageSoundEvent.java @@ -1,7 +1,7 @@ package com.pahimar.ee3.network.message; import com.pahimar.ee3.EquivalentExchange3; -import com.pahimar.ee3.reference.Settings; +import com.pahimar.ee3.handler.ConfigurationHandler; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; @@ -80,11 +80,11 @@ public class MessageSoundEvent implements IMessage, IMessageHandler} of {@link WrappedStack}s mapped + * to EnergyValues + * + *

The order of checking is as follows;

+ *
    + *
  1. {@link ItemStack}s whose {@link Item}s implement {@link IEnergyValueProvider}
  2. + *
  3. Direct EnergyValue mapping of the provided Object in the provided Map
  4. + *
  5. The following criteria are only checked (in order) in the event that this is a non-strict query; + *
      + *
    1. + * ItemStacks that are part of an {@link OreDictionary} entry are checked to see if + * all Ores they are registered to have the same non-null EnergyValue assigned to + * it + *
        + *
      • + * e.g., ItemStack X is associated with OreDictionary entries A, B and C. An EnergyValue + * would be returned for X only if A, B and C all had the same non-null EnergyValue + *
      • + *
      + *
    2. + *
    3. + * ItemStacks are checked to see if there exist {@link OreDictionary#WILDCARD_VALUE} equivalents + *
    4. + *
    5. + * {@link OreStack}s are checked to see if all members of the OreDictionary entry represented by the + * OreStack have the same non-null EnergyValue (similar to the case for ItemStacks above) + *
    6. + *
    + *
  6. + *
+ * + * @param valueMap a {@link Map} of {@link EnergyValue}'s mapped to {@link WrappedStack}'s + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * assignments) query or not + * @return an {@link EnergyValue} if there is one to be found for the provided {@link Object} in the provided Map, null otherwise + */ public static EnergyValue getEnergyValue(Map valueMap, Object object, boolean strict) { - /** - * Priority of checking goes - * 1 - IEnergyValueProvider implementation - * 2 - Exact match - * 3 - If the object is an ItemStack, various checks in the OreDictionary - * THINK ON THIS BECAUSE THIS LOGIC COULD BE FAULTY FOR COMPUTATION PURPOSES - * 1 - Does the parent OreStack have a non-null value - * 2 - Do all sibling members have the same non-null value - * 3 - Does there exist a wildcard value mapping with a value - * 4 - If the object is an OreStack, check all child ItemStacks to see if they have the same (not null) value - */ if (WrappedStack.canBeWrapped(object)) { - if (object instanceof ItemStack && ((ItemStack) object).getItem() instanceof IEnergyValueProvider && !strict) { + WrappedStack wrappedStack = WrappedStack.wrap(object, 1); + Object wrappedObject = wrappedStack.getWrappedObject(); + if (wrappedObject instanceof ItemStack && ((ItemStack) wrappedObject).getItem() instanceof IEnergyValueProvider && !strict) { + + EnergyValue energyValue = ((IEnergyValueProvider) ((ItemStack) wrappedObject).getItem()).getEnergyValue(((ItemStack) wrappedObject)); + + if (energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) { + return energyValue; + } } - else if (valueMap != null) { - WrappedStack wrappedObject = WrappedStack.wrap(object, 1); - if (valueMap.containsKey(wrappedObject)) { - return valueMap.get(wrappedObject); + if (valueMap != null && !valueMap.isEmpty()) { + + // First check for a direct energy value mapping to the wrapped object + if (valueMap.containsKey(wrappedStack)) { + return valueMap.get(wrappedStack); } else if (!strict) { - // Search for wildcard entries first - // Then search for possible OreStack value - // Then search for possible sibling OreStack values - if (object instanceof ItemStack) { - ItemStack unValuedItemStack = ItemStack.copyItemStack((ItemStack) object); + if (wrappedObject instanceof ItemStack) { + + ItemStack unValuedItemStack = ItemStack.copyItemStack((ItemStack) wrappedObject); EnergyValue minEnergyValue = null; - for (WrappedStack valuedWrappedStack : valueMap.keySet()) { - if (valuedWrappedStack.getWrappedObject() instanceof ItemStack) { - if (Item.getIdFromItem(((ItemStack) valuedWrappedStack.getWrappedObject()).getItem()) == Item.getIdFromItem(unValuedItemStack.getItem())) { + int[] oreIds = OreDictionary.getOreIDs(unValuedItemStack); + if (oreIds.length > 0) { - ItemStack valuedItemStack = (ItemStack) valuedWrappedStack.getWrappedObject(); - if (valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || unValuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) { + EnergyValue energyValue = null; + boolean allHaveSameValue = true; - EnergyValue energyValue = valueMap.get(valuedWrappedStack); + for (int oreId : oreIds) { + String oreName = OreDictionary.getOreName(oreId); - if (energyValue.compareTo(minEnergyValue) < 0) { - minEnergyValue = energyValue; + if (!"Unknown".equalsIgnoreCase(oreName)) { + + WrappedStack oreStack = WrappedStack.wrap(new OreStack(oreName)); + + if (oreStack != null && valueMap.containsKey(oreStack)) { + + if (energyValue == null) { + energyValue = valueMap.get(oreStack); + } + else if (!energyValue.equals(valueMap.get(oreStack))) { + allHaveSameValue = false; + } + } + else { + allHaveSameValue = false; + } + } + else { + allHaveSameValue = false; + } + } + + if (allHaveSameValue) { + return energyValue; + } + } + else { + for (WrappedStack valuedWrappedStack : valueMap.keySet()) { + if (valuedWrappedStack.getWrappedObject() instanceof ItemStack) { + if (Item.getIdFromItem(((ItemStack) valuedWrappedStack.getWrappedObject()).getItem()) == Item.getIdFromItem(unValuedItemStack.getItem())) { + + ItemStack valuedItemStack = (ItemStack) valuedWrappedStack.getWrappedObject(); + if (valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || unValuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) { + + EnergyValue energyValue = valueMap.get(valuedWrappedStack); + + if (energyValue.compareTo(minEnergyValue) < 0) { + minEnergyValue = energyValue; + } } } } } } } - else if (object instanceof OreStack) { + else if (wrappedObject instanceof OreStack) { + OreStack oreStack = (OreStack) wrappedObject; + List itemStacks = OreDictionary.getOres(oreStack.oreName); + + if (!itemStacks.isEmpty()) { + + EnergyValue energyValue = null; + boolean allHaveSameValue = true; + + for (ItemStack itemStack : itemStacks) { + WrappedStack wrappedItemStack = WrappedStack.wrap(itemStack, 1); + + if (wrappedItemStack != null && valueMap.containsKey(wrappedItemStack)) { + if (energyValue == null) { + energyValue = valueMap.get(wrappedItemStack); + } + else if (!energyValue.equals(valueMap.get(wrappedItemStack))) { + allHaveSameValue = false; + } + } + else { + allHaveSameValue = false; + } + } + + if (allHaveSameValue) { + return energyValue; + } + } } } } diff --git a/src/main/resources/assets/ee3/lang/en_US.lang b/src/main/resources/assets/ee3/lang/en_US.lang index 4ab11adf..a826199a 100644 --- a/src/main/resources/assets/ee3/lang/en_US.lang +++ b/src/main/resources/assets/ee3/lang/en_US.lang @@ -1,16 +1,20 @@ -# Configuration -general.sync.threshold.label=Sync Threshold -general.sync.threshold.comment=The number of seconds a player must wait before they can sync their Energy Values with the server again +# Configuration (Energy Value Options) +energy_value=Energy Value Options +energy_value.sync_threshold.label=Sync Threshold +energy_value.sync_threshold.comment=The number of seconds a player must wait before they can sync their energy values for objects with the server again +energy_value.regenerate_when.label=Regenerate EnergyValues +energy_value.regenerate_when.comment=When to regenerate energy values for objects. Options are "Always" (every time Minecraft starts) or "As Needed" (whenever the mod cannot the calculated energy values file). +energy_value.debug_logging_enabled.label=Enable Debug Logging +energy_value.debug_logging_enabled.comment=Additional debug logging for when energy values are calculated for objects -general.sound.soundMode.label=Sounds -general.sound.soundMode.comment='All' plays mod sounds from all players, 'Self' only plays mod sounds from you, and 'None' plays no mod sounds +# Configuration (Sound Options) +sound=Sound Options +sound.mode.label=Play Sounds Only From +sound.mode.comment='All' plays mod sounds from all players, 'Self' only plays mod sounds from you, and 'None' does not play any mod sounds general.abilities.onlyLoadFile.label=Only load Abilities file general.abilities.onlyLoadFile.comment=Setting this to true means that Abilities are initially only loaded from file, rather than from both file and from other mods -general.energyvalues.regenerateEnergyValuesWhen.label=Regenerate EnergyValues -general.energyvalues.regenerateEnergyValuesWhen.comment=When to regenerate EnergyValues. Options are "Always" (every time Minecraft starts), "When Mods Change" (when mods are added, removed, or updated) or "Never" (only generate the first time). - # Keys key.categories.ee3=Equivalent Exchange 3 key.charge=Charge