equivalent-exchange-3/src/main/java/com/pahimar/ee3/util/EnergyValueHelper.java

294 lines
14 KiB
Java

package com.pahimar.ee3.util;
import com.pahimar.ee3.api.exchange.EnergyValue;
import com.pahimar.ee3.api.exchange.IEnergyValueProvider;
import com.pahimar.ee3.exchange.EnergyValueRegistry;
import com.pahimar.ee3.exchange.OreStack;
import com.pahimar.ee3.exchange.WrappedStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.oredict.OreDictionary;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
public class EnergyValueHelper {
/**
* Returns an {@link EnergyValue} for a {@link Object} in the provided {@link Map>} of {@link WrappedStack}s mapped
* to EnergyValues
*
* <p>The order of checking is as follows;</p>
* <ol>
* <li>{@link ItemStack}s whose {@link Item}s implement {@link IEnergyValueProvider}</li>
* <li>Direct EnergyValue mapping of the provided Object in the provided Map</li>
* <li>The following criteria are only checked (in order) in the event that this is a non-strict query;
* <ol>
* <li>
* ItemStacks that are part of an {@link OreDictionary} entry are checked to see if
* <strong>all</strong> Ores they are registered to have the same non-null EnergyValue assigned to
* it
* <ul>
* <li>
* 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
* </li>
* </ul>
* </li>
* <li>
* ItemStacks are checked to see if there exist {@link OreDictionary#WILDCARD_VALUE} equivalents
* </li>
* <li>
* {@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)
* </li>
* </ol>
* </li>
* </ol>
*
* @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<WrappedStack, EnergyValue> valueMap, Object object, boolean strict) {
if (WrappedStack.canBeWrapped(object)) {
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;
}
}
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) {
if (wrappedObject instanceof ItemStack) {
ItemStack unValuedItemStack = ItemStack.copyItemStack((ItemStack) wrappedObject);
EnergyValue minEnergyValue = null;
int[] oreIds = OreDictionary.getOreIDs(unValuedItemStack);
if (oreIds.length > 0) {
EnergyValue energyValue = null;
boolean allHaveSameValue = true;
for (int oreId : oreIds) {
String oreName = OreDictionary.getOreName(oreId);
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 (wrappedObject instanceof OreStack) {
OreStack oreStack = (OreStack) wrappedObject;
List<ItemStack> 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;
}
}
}
}
}
}
return null;
}
// FIXME PRIORITY NUMBER 1 (Implement new method)
public static EnergyValue computeFromInputs(Map<WrappedStack, EnergyValue> valueMap, WrappedStack wrappedOutput, List<WrappedStack> wrappedInputs) {
EnergyValue computedEnergyValue = null;
return computedEnergyValue;
}
public static EnergyValue computeEnergyValueFromRecipe(Map<WrappedStack, EnergyValue> valueMap, WrappedStack wrappedOutput, List<WrappedStack> wrappedInputs) {
float computedValue = 0f;
// TODO We should do some verification that every input has an energy value - if not there is no point doing the calculation
/**
* Basic algorithm:
* Set sumOfInputValues to 0
* For every input, add (input's Unit Value) * (input's stackSize) to sumOfInputs
* return new EnergyValue(sumOfInputs / output's stackSize)
*
* Caveats are for ItemStacks that act as containers. You only want to catch the difference in values between
* pre-crafting and post-crafting
*
* e.g., A recipe that uses up the water in a bucket (empty bucket left) vs uses up the entire water bucket (nothing left)
*/
for (WrappedStack wrappedInput : wrappedInputs) {
EnergyValue wrappedInputValue;
int stackSize = -1;
if (wrappedInput.getWrappedObject() instanceof ItemStack) {
ItemStack itemStack = (ItemStack) wrappedInput.getWrappedObject();
// Check if we are dealing with a potential fluid
if (FluidContainerRegistry.getFluidForFilledItem(itemStack) != null) {
if (itemStack.getItem().getContainerItem(itemStack) != null) {
stackSize = FluidContainerRegistry.getFluidForFilledItem(itemStack).amount * wrappedInput.getStackSize();
wrappedInputValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, FluidContainerRegistry.getFluidForFilledItem(itemStack));
}
else {
wrappedInputValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, wrappedInput);
}
}
else if (itemStack.getItem().getContainerItem(itemStack) != null) {
ItemStack containerItemStack = itemStack.getItem().getContainerItem(itemStack);
if (EnergyValueRegistry.getInstance().hasEnergyValue(itemStack) && EnergyValueRegistry.getInstance().hasEnergyValue(containerItemStack)) {
float itemStackValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, itemStack).getValue();
float containerStackValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, containerItemStack).getValue();
wrappedInputValue = new EnergyValue(itemStackValue - containerStackValue);
}
else {
wrappedInputValue = new EnergyValue(0);
}
}
else if (!itemStack.getItem().doesContainerItemLeaveCraftingGrid(itemStack)) {
wrappedInputValue = new EnergyValue(0);
}
else if (OreDictionary.getOreIDs(itemStack).length > 0) {
wrappedInputValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, wrappedInput, true);
}
else {
wrappedInputValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, wrappedInput);
}
}
else if (wrappedInput.getWrappedObject() instanceof OreStack) {
OreStack oreStack = (OreStack) wrappedInput.getWrappedObject();
wrappedInputValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, wrappedInput);
for (ItemStack itemStack : OreDictionary.getOres(oreStack.oreName))
{
if (!itemStack.getItem().doesContainerItemLeaveCraftingGrid(itemStack))
{
wrappedInputValue = new EnergyValue(0);
}
}
}
else {
wrappedInputValue = EnergyValueRegistry.getInstance().getEnergyValueFromMap(valueMap, wrappedInput);
}
if (wrappedInputValue != null) {
if (stackSize == -1) {
stackSize = wrappedInput.getStackSize();
}
computedValue += wrappedInputValue.getValue() * stackSize;
}
else {
return null;
}
}
return factor(new EnergyValue(computedValue), wrappedOutput.getStackSize());
}
public static EnergyValue factor(EnergyValue energyValue, int factor) {
return factor(energyValue, (float) factor);
}
public static EnergyValue factor(EnergyValue energyValue, float factor) {
if ((Float.compare(factor, 0f) != 0) && (energyValue != null)) {
return new EnergyValue(new BigDecimal(energyValue.getValue() * 1f / factor).setScale(3, BigDecimal.ROUND_HALF_EVEN).floatValue());
}
else {
return null;
}
}
}