2014-07-07 21:31:10 +02:00
package com.pahimar.ee3.exchange ;
2014-06-14 21:40:45 +02:00
2014-07-14 18:04:20 +02:00
import com.google.common.collect.ImmutableSortedMap ;
2015-02-16 03:13:35 +01:00
import com.google.gson.* ;
2015-05-07 19:45:06 +02:00
import com.pahimar.ee3.api.exchange.EnergyValue ;
import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy ;
import com.pahimar.ee3.api.exchange.IEnergyValueProvider ;
2014-07-07 21:31:10 +02:00
import com.pahimar.ee3.recipe.RecipeRegistry ;
2014-09-15 22:06:20 +02:00
import com.pahimar.ee3.reference.Files ;
2015-01-27 05:17:32 +01:00
import com.pahimar.ee3.reference.Reference ;
2015-03-23 13:12:44 +01:00
import com.pahimar.ee3.reference.Settings ;
2015-05-02 20:07:01 +02:00
import com.pahimar.ee3.util.EnergyValueHelper ;
2015-05-07 20:47:54 +02:00
import com.pahimar.ee3.util.LoaderHelper ;
2015-05-02 20:07:01 +02:00
import com.pahimar.ee3.util.LogHelper ;
import com.pahimar.ee3.util.SerializationHelper ;
2015-01-27 05:17:32 +01:00
import cpw.mods.fml.common.FMLCommonHandler ;
2015-05-07 20:47:54 +02:00
import cpw.mods.fml.common.Loader ;
2014-06-14 21:40:45 +02:00
import net.minecraft.item.Item ;
import net.minecraft.item.ItemStack ;
2014-07-15 00:37:50 +02:00
import net.minecraftforge.fluids.FluidStack ;
2014-06-14 21:40:45 +02:00
import net.minecraftforge.oredict.OreDictionary ;
2015-01-27 05:17:32 +01:00
import java.io.File ;
2015-02-16 03:13:35 +01:00
import java.lang.reflect.Type ;
2014-06-14 21:40:45 +02:00
import java.util.* ;
2015-05-02 20:07:01 +02:00
public class EnergyValueRegistry implements JsonSerializer < EnergyValueRegistry > , JsonDeserializer < EnergyValueRegistry >
2014-06-14 21:40:45 +02:00
{
2015-02-16 03:13:35 +01:00
private static final Gson jsonSerializer = ( new GsonBuilder ( ) ) . registerTypeAdapter ( EnergyValueRegistry . class , new EnergyValueRegistry ( ) ) . registerTypeAdapter ( EnergyValueStackMapping . class , new EnergyValueStackMapping ( ) ) . create ( ) ;
private static final Gson prettyJsonSerializer = ( new GsonBuilder ( ) ) . setPrettyPrinting ( ) . registerTypeAdapter ( EnergyValueRegistry . class , new EnergyValueRegistry ( ) ) . registerTypeAdapter ( EnergyValueStackMapping . class , new EnergyValueStackMapping ( ) ) . create ( ) ;
2014-09-16 18:08:16 +02:00
private boolean shouldRegenNextRestart = false ;
2014-06-20 21:57:27 +02:00
private static EnergyValueRegistry energyValueRegistry = null ;
2014-07-14 04:05:27 +02:00
private static Map < WrappedStack , EnergyValue > preAssignedMappings ;
2015-04-17 00:18:49 +02:00
private static Map < WrappedStack , EnergyValue > postAssignedMappings ;
2014-07-14 18:04:20 +02:00
private ImmutableSortedMap < WrappedStack , EnergyValue > stackMappings ;
private ImmutableSortedMap < EnergyValue , List < WrappedStack > > valueMappings ;
2014-06-14 21:40:45 +02:00
2014-06-20 21:57:27 +02:00
private EnergyValueRegistry ( )
2014-06-14 21:40:45 +02:00
{
}
2014-06-20 21:57:27 +02:00
public static EnergyValueRegistry getInstance ( )
2014-06-14 21:40:45 +02:00
{
2014-06-20 21:57:27 +02:00
if ( energyValueRegistry = = null )
2014-06-14 21:40:45 +02:00
{
2014-06-20 21:57:27 +02:00
energyValueRegistry = new EnergyValueRegistry ( ) ;
2014-06-14 21:40:45 +02:00
}
2014-06-20 21:57:27 +02:00
return energyValueRegistry ;
2014-06-14 21:40:45 +02:00
}
2015-05-04 14:18:15 +02:00
public void addPreAssignedEnergyValue ( Object object , float energyValue )
2014-06-14 21:40:45 +02:00
{
2014-07-14 04:05:27 +02:00
addPreAssignedEnergyValue ( object , new EnergyValue ( energyValue ) ) ;
}
2014-06-14 21:40:45 +02:00
2014-07-22 21:56:39 +02:00
public void addPreAssignedEnergyValue ( Object object , EnergyValue energyValue )
2014-07-14 04:05:27 +02:00
{
if ( preAssignedMappings = = null )
{
2015-04-09 18:40:19 +02:00
preAssignedMappings = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-06-14 21:40:45 +02:00
}
2015-04-19 21:01:35 +02:00
if ( WrappedStack . canBeWrapped ( object ) & & energyValue ! = null & & Float . compare ( energyValue . getValue ( ) , 0f ) > 0 )
2014-06-14 21:40:45 +02:00
{
2015-04-19 21:01:35 +02:00
WrappedStack wrappedStack = WrappedStack . wrap ( object ) ;
2014-06-14 21:40:45 +02:00
2014-07-14 04:05:27 +02:00
if ( wrappedStack . getStackSize ( ) > 0 )
2014-06-14 21:40:45 +02:00
{
2015-04-19 21:01:35 +02:00
WrappedStack factoredWrappedStack = WrappedStack . wrap ( wrappedStack , 1 ) ;
2014-07-14 04:05:27 +02:00
EnergyValue factoredEnergyValue = EnergyValueHelper . factorEnergyValue ( energyValue , wrappedStack . getStackSize ( ) ) ;
2014-06-14 21:40:45 +02:00
2014-07-14 04:05:27 +02:00
if ( preAssignedMappings . containsKey ( factoredWrappedStack ) )
2014-06-14 21:40:45 +02:00
{
2014-07-14 04:05:27 +02:00
if ( factoredEnergyValue . compareTo ( preAssignedMappings . get ( factoredWrappedStack ) ) < 0 )
2014-06-14 21:40:45 +02:00
{
2015-05-07 21:11:23 +02:00
LogHelper . trace ( String . format ( " EnergyValueRegistry[%s]: Mod with ID '%s' added a pre-assignment energy value of %s for object %s " , LoaderHelper . getLoaderState ( ) , Loader . instance ( ) . activeModContainer ( ) . getModId ( ) , energyValue , wrappedStack ) ) ;
2014-07-14 04:05:27 +02:00
preAssignedMappings . put ( factoredWrappedStack , factoredEnergyValue ) ;
2014-06-14 21:40:45 +02:00
}
}
2014-07-14 04:05:27 +02:00
else
2014-06-14 21:40:45 +02:00
{
2015-05-07 21:11:23 +02:00
LogHelper . trace ( String . format ( " EnergyValueRegistry[%s]: Mod with ID '%s' added a pre-assignment energy value of %s for object %s " , LoaderHelper . getLoaderState ( ) , Loader . instance ( ) . activeModContainer ( ) . getModId ( ) , energyValue , wrappedStack ) ) ;
2014-07-14 04:05:27 +02:00
preAssignedMappings . put ( factoredWrappedStack , factoredEnergyValue ) ;
2014-06-14 21:40:45 +02:00
}
}
}
2014-07-14 04:05:27 +02:00
}
2014-06-14 21:40:45 +02:00
2015-05-04 14:18:15 +02:00
public void addPostAssignedExactEnergyValue ( Object object , float energyValue )
2014-07-14 04:05:27 +02:00
{
2015-03-05 05:31:43 +01:00
addPostAssignedExactEnergyValue ( object , new EnergyValue ( energyValue ) ) ;
2014-06-14 21:40:45 +02:00
}
2015-03-05 05:31:43 +01:00
public void addPostAssignedExactEnergyValue ( Object object , EnergyValue energyValue )
2014-06-14 21:40:45 +02:00
{
2015-04-17 00:18:49 +02:00
if ( postAssignedMappings = = null )
2014-06-14 21:40:45 +02:00
{
2015-04-17 00:18:49 +02:00
postAssignedMappings = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-07-14 04:05:27 +02:00
}
2014-06-14 21:40:45 +02:00
2015-04-19 21:01:35 +02:00
if ( WrappedStack . canBeWrapped ( object ) & & energyValue ! = null & & Float . compare ( energyValue . getValue ( ) , 0f ) > 0 )
2014-07-14 04:05:27 +02:00
{
2015-04-19 21:01:35 +02:00
WrappedStack wrappedStack = WrappedStack . wrap ( object ) ;
2014-06-14 21:40:45 +02:00
2014-07-14 04:05:27 +02:00
if ( wrappedStack . getStackSize ( ) > 0 )
{
2015-04-19 21:01:35 +02:00
WrappedStack factoredWrappedStack = WrappedStack . wrap ( wrappedStack , 1 ) ;
2014-07-14 04:05:27 +02:00
EnergyValue factoredEnergyValue = EnergyValueHelper . factorEnergyValue ( energyValue , wrappedStack . getStackSize ( ) ) ;
2014-06-14 21:40:45 +02:00
2015-05-07 21:11:23 +02:00
LogHelper . trace ( String . format ( " EnergyValueRegistry[%s]: Mod with ID '%s' added a post-assignment energy value of %s for object %s " , LoaderHelper . getLoaderState ( ) , Loader . instance ( ) . activeModContainer ( ) . getModId ( ) , energyValue , wrappedStack ) ) ;
postAssignedMappings . put ( factoredWrappedStack , factoredEnergyValue ) ;
2014-06-14 21:40:45 +02:00
}
}
}
public boolean hasEnergyValue ( Object object )
{
return hasEnergyValue ( object , false ) ;
}
2015-03-05 05:31:43 +01:00
public boolean hasEnergyValue ( Object object , boolean strict )
{
return getEnergyValue ( object , strict ) ! = null ;
}
2015-04-14 04:27:11 +02:00
public EnergyValue getEnergyValue ( Object object )
2015-03-05 05:31:43 +01:00
{
2015-05-22 00:41:44 +02:00
return getEnergyValue ( EnergyValueRegistryProxy . Phase . ALL , object , false ) ;
2015-03-05 05:31:43 +01:00
}
2015-04-14 04:27:11 +02:00
public EnergyValue getEnergyValue ( Object object , boolean strict )
2014-07-07 17:22:21 +02:00
{
2015-05-22 00:41:44 +02:00
return getEnergyValue ( EnergyValueRegistryProxy . Phase . ALL , object , strict ) ;
2014-07-07 17:22:21 +02:00
}
2015-05-22 00:41:44 +02:00
public EnergyValue getEnergyValue ( EnergyValueRegistryProxy . Phase phase , Object object , boolean strict )
2015-04-19 21:01:35 +02:00
{
2015-05-22 00:41:44 +02:00
if ( phase = = EnergyValueRegistryProxy . Phase . PRE_ASSIGNMENT )
{
return getEnergyValueFromMap ( preAssignedMappings , object , strict ) ;
}
else if ( phase = = EnergyValueRegistryProxy . Phase . POST_ASSIGNMENT )
{
return getEnergyValueFromMap ( postAssignedMappings , object , strict ) ;
}
else
{
return getEnergyValueFromMap ( energyValueRegistry . stackMappings , object , strict ) ;
}
2015-04-19 21:01:35 +02:00
}
public EnergyValue getEnergyValueForStack ( Object object , boolean strict )
{
WrappedStack wrappedObject = WrappedStack . wrap ( object ) ;
if ( wrappedObject ! = null & & getEnergyValue ( object , strict ) ! = null )
{
return new EnergyValue ( getEnergyValue ( object , strict ) . getValue ( ) * wrappedObject . getStackSize ( ) ) ;
}
return null ;
}
2015-04-14 04:27:11 +02:00
public EnergyValue getEnergyValueFromMap ( Map < WrappedStack , EnergyValue > stackEnergyValueMap , Object object )
{
return getEnergyValueFromMap ( stackEnergyValueMap , object , false ) ;
}
public EnergyValue getEnergyValueFromMap ( Map < WrappedStack , EnergyValue > stackEnergyValueMap , Object object , boolean strict )
2014-06-14 21:40:45 +02:00
{
if ( WrappedStack . canBeWrapped ( object ) )
{
2015-04-19 21:01:35 +02:00
WrappedStack wrappedStackObject = WrappedStack . wrap ( object ) ;
WrappedStack unitWrappedStackObject = WrappedStack . wrap ( object ) ;
2015-04-14 04:27:11 +02:00
unitWrappedStackObject . setStackSize ( 1 ) ;
Object wrappedObject = wrappedStackObject . getWrappedObject ( ) ;
/ * *
* In the event that an Item has an IEnergyValueProvider implementation , route the call to the implementation
* /
if ( wrappedObject instanceof ItemStack & & ( ( ItemStack ) wrappedObject ) . getItem ( ) instanceof IEnergyValueProvider & & ! strict )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
ItemStack itemStack = ( ItemStack ) wrappedObject ;
2015-02-20 04:09:10 +01:00
IEnergyValueProvider iEnergyValueProvider = ( IEnergyValueProvider ) itemStack . getItem ( ) ;
EnergyValue energyValue = iEnergyValueProvider . getEnergyValue ( itemStack ) ;
2014-07-14 20:30:50 +02:00
2015-04-19 21:01:35 +02:00
if ( energyValue ! = null & & energyValue . getValue ( ) > 0f )
2014-07-14 20:30:50 +02:00
{
return energyValue ;
}
2014-06-14 21:40:45 +02:00
}
2015-04-14 04:27:11 +02:00
else if ( stackEnergyValueMap ! = null )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
/ * *
* Check for a direct value mapping for the object
* /
if ( stackEnergyValueMap . containsKey ( unitWrappedStackObject ) )
2014-07-14 20:30:50 +02:00
{
2015-04-14 04:27:11 +02:00
return stackEnergyValueMap . get ( unitWrappedStackObject ) ;
}
else if ( ! strict )
{
if ( wrappedObject instanceof ItemStack )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
EnergyValue lowestValue = null ;
ItemStack wrappedItemStack = ( ItemStack ) wrappedObject ;
/ * *
2015-04-17 00:18:49 +02:00
* The ItemStack does not have a direct mapping , so check if it is a member of an OreDictionary
2015-04-19 21:01:35 +02:00
* entry . If it is a member of an OreDictionary entry , check if every ore name it is associated
* with has 1 ) a direct mapping , and 2 ) the same mapping value
2015-04-14 04:27:11 +02:00
* /
2015-04-19 21:01:35 +02:00
if ( OreDictionary . getOreIDs ( wrappedItemStack ) . length > = 1 )
2014-06-14 21:40:45 +02:00
{
2015-04-19 21:01:35 +02:00
EnergyValue energyValue = null ;
boolean allHaveSameValueFlag = true ;
2014-07-14 20:30:50 +02:00
2015-04-19 21:01:35 +02:00
// Scan all valid ore dictionary values, if they ALL have the same value, then return it
for ( int oreID : OreDictionary . getOreIDs ( wrappedItemStack ) )
2015-04-14 04:27:11 +02:00
{
2015-04-19 21:01:35 +02:00
String oreName = OreDictionary . getOreName ( oreID ) ;
if ( ! oreName . equals ( " Unknown " ) )
{
WrappedStack oreStack = WrappedStack . wrap ( new OreStack ( oreName ) ) ;
if ( oreStack ! = null & & stackEnergyValueMap . containsKey ( oreStack ) )
{
if ( energyValue = = null )
{
energyValue = stackEnergyValueMap . get ( oreStack ) ;
}
else if ( ! energyValue . equals ( stackEnergyValueMap . get ( oreStack ) ) )
{
allHaveSameValueFlag = false ;
}
}
else
{
allHaveSameValueFlag = false ;
}
}
else
{
allHaveSameValueFlag = false ;
}
}
if ( energyValue ! = null & & allHaveSameValueFlag )
{
return energyValue ;
2015-04-14 04:27:11 +02:00
}
}
else
{
/ * *
* Scan the stack value map for ItemStacks that have the same Item . If one is found , check
* if it has a wildcard meta value ( and therefore is considered the same ) . Otherwise , check
* if the ItemStack is " damageable " and calculate the value for the damaged stack .
* /
for ( WrappedStack valuedStack : stackEnergyValueMap . keySet ( ) )
{
if ( valuedStack . getWrappedObject ( ) instanceof ItemStack )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
ItemStack valuedItemStack = ( ItemStack ) valuedStack . getWrappedObject ( ) ;
2015-02-21 14:07:17 +01:00
2015-04-14 04:27:11 +02:00
if ( Item . getIdFromItem ( valuedItemStack . getItem ( ) ) = = Item . getIdFromItem ( wrappedItemStack . getItem ( ) ) )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
if ( valuedItemStack . getItemDamage ( ) = = OreDictionary . WILDCARD_VALUE | | wrappedItemStack . getItemDamage ( ) = = OreDictionary . WILDCARD_VALUE )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
EnergyValue stackValue = stackEnergyValueMap . get ( valuedStack ) ;
if ( stackValue . compareTo ( lowestValue ) < 0 )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
lowestValue = stackValue ;
2014-06-14 21:40:45 +02:00
}
}
2015-04-14 04:27:11 +02:00
else if ( wrappedItemStack . getItem ( ) . isDamageable ( ) & & wrappedItemStack . isItemDamaged ( ) )
2014-06-14 21:40:45 +02:00
{
2015-04-19 21:01:35 +02:00
EnergyValue stackValue = new EnergyValue ( stackEnergyValueMap . get ( valuedStack ) . getValue ( ) * ( 1 - ( wrappedItemStack . getItemDamage ( ) * 1 . 0F / wrappedItemStack . getMaxDamage ( ) ) ) ) ;
2014-06-14 21:40:45 +02:00
2015-04-14 04:27:11 +02:00
if ( stackValue . compareTo ( lowestValue ) < 0 )
2014-06-14 21:40:45 +02:00
{
2015-04-14 04:27:11 +02:00
lowestValue = stackValue ;
2014-06-14 21:40:45 +02:00
}
}
}
2014-07-14 20:30:50 +02:00
}
2014-06-14 21:40:45 +02:00
}
2015-04-14 04:27:11 +02:00
return lowestValue ;
2014-06-14 21:40:45 +02:00
}
}
2015-04-19 21:01:35 +02:00
else if ( wrappedObject instanceof OreStack )
{
OreStack oreStack = ( OreStack ) wrappedObject ;
if ( CachedOreDictionary . getInstance ( ) . getItemStacksForOreName ( oreStack . oreName ) . size ( ) > = 1 )
{
EnergyValue energyValue = null ;
boolean allHaveSameValueFlag = true ;
// Scan all valid ore dictionary values, if they ALL have the same value, then return it
for ( ItemStack itemStack : CachedOreDictionary . getInstance ( ) . getItemStacksForOreName ( oreStack . oreName ) )
{
WrappedStack wrappedItemStack = WrappedStack . wrap ( itemStack ) ;
if ( wrappedItemStack ! = null & & stackEnergyValueMap . containsKey ( wrappedItemStack ) )
{
if ( energyValue = = null )
{
energyValue = stackEnergyValueMap . get ( wrappedItemStack ) ;
}
else if ( ! energyValue . equals ( stackEnergyValueMap . get ( wrappedItemStack ) ) )
{
allHaveSameValueFlag = false ;
}
}
else
{
allHaveSameValueFlag = false ;
}
}
if ( energyValue ! = null & & allHaveSameValueFlag )
{
return energyValue ;
}
}
}
2014-06-14 21:40:45 +02:00
}
}
}
return null ;
}
2014-07-14 18:04:20 +02:00
protected final void init ( )
2014-08-29 22:25:31 +02:00
{
2015-02-12 06:15:45 +01:00
if ( ! loadEnergyValueRegistryFromFile ( ) )
2014-08-29 22:25:31 +02:00
{
runDynamicEnergyValueResolution ( ) ;
}
2014-09-16 18:08:16 +02:00
this . shouldRegenNextRestart = false ;
2014-08-29 22:25:31 +02:00
}
private void runDynamicEnergyValueResolution ( )
2014-07-14 04:05:27 +02:00
{
2015-04-09 18:40:19 +02:00
TreeMap < WrappedStack , EnergyValue > stackValueMap = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-07-14 18:04:20 +02:00
/ *
* Pre - assigned values
* /
stackValueMap . putAll ( preAssignedMappings ) ;
2014-07-14 04:05:27 +02:00
2014-09-12 22:11:18 +02:00
// Grab custom pre-assigned values from file
2014-09-15 22:06:20 +02:00
Map < WrappedStack , EnergyValue > preAssignedValueMap = SerializationHelper . readEnergyValueStackMapFromJsonFile ( Files . PRE_ASSIGNED_ENERGY_VALUES ) ;
2015-04-14 04:27:11 +02:00
for ( WrappedStack wrappedStack : preAssignedValueMap . keySet ( ) )
{
if ( preAssignedValueMap . get ( wrappedStack ) ! = null )
{
stackValueMap . put ( wrappedStack , preAssignedValueMap . get ( wrappedStack ) ) ;
}
}
2014-09-12 22:11:18 +02:00
2014-07-14 04:05:27 +02:00
/ *
* Auto - assignment
* /
// Initialize the maps for the first pass to happen
2014-07-14 18:04:20 +02:00
ImmutableSortedMap . Builder < WrappedStack , EnergyValue > stackMappingsBuilder = ImmutableSortedMap . naturalOrder ( ) ;
stackMappingsBuilder . putAll ( stackValueMap ) ;
stackMappings = stackMappingsBuilder . build ( ) ;
2015-04-09 18:40:19 +02:00
Map < WrappedStack , EnergyValue > computedStackValues = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-07-14 04:05:27 +02:00
// Initialize the pass counter
int passNumber = 0 ;
2015-02-12 06:15:45 +01:00
long computationStartTime = System . currentTimeMillis ( ) ;
long passStartTime ;
2015-04-14 04:27:11 +02:00
int computedValueCount = 0 ;
2015-02-14 04:42:28 +01:00
int totalComputedValueCount = 0 ;
LogHelper . info ( " Beginning dynamic value computation " ) ;
2015-03-05 05:31:43 +01:00
boolean isFirstPass = true ;
2015-04-14 04:27:11 +02:00
while ( ( isFirstPass | | computedValueCount > 0 ) & & ( passNumber < 16 ) )
2014-07-14 04:05:27 +02:00
{
2015-03-05 05:31:43 +01:00
if ( isFirstPass )
{
isFirstPass = false ;
}
2015-02-14 04:42:28 +01:00
computedValueCount = 0 ;
2015-02-12 06:15:45 +01:00
passStartTime = System . currentTimeMillis ( ) ;
2014-07-14 04:05:27 +02:00
// Increment the pass counter
passNumber + + ;
// Compute stack mappings from existing stack mappings
2015-04-14 04:27:11 +02:00
computedStackValues = computeStackMappings ( stackValueMap ) ;
2014-07-22 03:43:04 +02:00
2014-07-14 04:05:27 +02:00
for ( WrappedStack keyStack : computedStackValues . keySet ( ) )
{
EnergyValue factoredExchangeEnergyValue = null ;
WrappedStack factoredKeyStack = null ;
2015-04-14 04:27:11 +02:00
if ( keyStack ! = null & & keyStack . getWrappedObject ( ) ! = null & & keyStack . getStackSize ( ) > 0 )
2014-07-14 04:05:27 +02:00
{
2015-04-19 21:01:35 +02:00
if ( computedStackValues . get ( keyStack ) ! = null & & Float . compare ( computedStackValues . get ( keyStack ) . getValue ( ) , 0f ) > 0 )
2014-07-14 04:05:27 +02:00
{
factoredExchangeEnergyValue = EnergyValueHelper . factorEnergyValue ( computedStackValues . get ( keyStack ) , keyStack . getStackSize ( ) ) ;
2015-04-19 21:01:35 +02:00
factoredKeyStack = WrappedStack . wrap ( keyStack , 1 ) ;
2014-07-14 04:05:27 +02:00
}
}
if ( factoredExchangeEnergyValue ! = null )
{
2014-07-14 18:04:20 +02:00
if ( stackValueMap . containsKey ( factoredKeyStack ) )
2014-07-14 04:05:27 +02:00
{
2014-07-14 18:04:20 +02:00
if ( factoredExchangeEnergyValue . compareTo ( stackValueMap . get ( factoredKeyStack ) ) = = - 1 )
2014-07-14 04:05:27 +02:00
{
2014-07-14 18:04:20 +02:00
stackValueMap . put ( factoredKeyStack , factoredExchangeEnergyValue ) ;
2014-07-14 04:05:27 +02:00
}
}
else
{
2014-07-14 18:04:20 +02:00
stackValueMap . put ( factoredKeyStack , factoredExchangeEnergyValue ) ;
2015-02-14 04:42:28 +01:00
computedValueCount + + ;
totalComputedValueCount + + ;
2014-07-14 04:05:27 +02:00
}
}
}
2015-02-19 06:06:18 +01:00
LogHelper . info ( String . format ( " Pass %s: Computed %s values for objects in %s ms " , passNumber , computedValueCount , System . currentTimeMillis ( ) - passStartTime ) ) ;
2014-07-14 04:05:27 +02:00
}
2015-02-14 04:42:28 +01:00
LogHelper . info ( String . format ( " Finished dynamic value computation (computed %s values for objects in %s ms) " , totalComputedValueCount , System . currentTimeMillis ( ) - computationStartTime ) ) ;
2014-07-14 04:05:27 +02:00
2015-04-17 00:18:49 +02:00
if ( postAssignedMappings ! = null )
2014-07-14 04:05:27 +02:00
{
2015-04-17 00:18:49 +02:00
for ( WrappedStack wrappedStack : postAssignedMappings . keySet ( ) )
2014-07-14 04:05:27 +02:00
{
2015-04-17 00:18:49 +02:00
if ( postAssignedMappings . get ( wrappedStack ) ! = null )
2015-04-14 04:27:11 +02:00
{
2015-04-17 00:18:49 +02:00
stackValueMap . put ( wrappedStack , postAssignedMappings . get ( wrappedStack ) ) ;
2015-04-14 04:27:11 +02:00
}
2014-07-14 04:05:27 +02:00
}
}
2014-07-25 04:03:36 +02:00
else
{
2015-04-17 00:18:49 +02:00
postAssignedMappings = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-07-25 04:03:36 +02:00
}
2014-07-14 04:05:27 +02:00
2014-09-12 22:11:18 +02:00
// Grab custom post-assigned values from file
2014-09-15 22:06:20 +02:00
Map < WrappedStack , EnergyValue > postAssignedValueMap = SerializationHelper . readEnergyValueStackMapFromJsonFile ( Files . POST_ASSIGNED_ENERGY_VALUES ) ;
2015-04-14 04:27:11 +02:00
for ( WrappedStack wrappedStack : postAssignedValueMap . keySet ( ) )
{
if ( postAssignedValueMap . get ( wrappedStack ) ! = null )
{
stackValueMap . put ( wrappedStack , postAssignedValueMap . get ( wrappedStack ) ) ;
}
}
2014-09-12 22:11:18 +02:00
2014-07-14 18:04:20 +02:00
/ * *
* Finalize the stack to value map
* /
stackMappingsBuilder = ImmutableSortedMap . naturalOrder ( ) ;
stackMappingsBuilder . putAll ( stackValueMap ) ;
stackMappings = stackMappingsBuilder . build ( ) ;
/ * *
2014-07-14 04:05:27 +02:00
* Value map resolution
* /
2015-02-16 03:13:35 +01:00
generateValueStackMappings ( ) ;
// Serialize values to disk
LogHelper . info ( " Saving energy values to disk " ) ;
2015-04-21 03:16:48 +02:00
save ( ) ;
2015-02-16 03:13:35 +01:00
}
private void generateValueStackMappings ( )
{
2014-07-14 18:04:20 +02:00
SortedMap < EnergyValue , List < WrappedStack > > tempValueMappings = new TreeMap < EnergyValue , List < WrappedStack > > ( ) ;
2014-07-14 04:05:27 +02:00
for ( WrappedStack stack : stackMappings . keySet ( ) )
{
if ( stack ! = null )
{
EnergyValue value = stackMappings . get ( stack ) ;
if ( value ! = null )
{
2014-07-14 18:04:20 +02:00
if ( tempValueMappings . containsKey ( value ) )
2014-07-14 04:05:27 +02:00
{
2014-07-14 18:04:20 +02:00
if ( ! ( tempValueMappings . get ( value ) . contains ( stack ) ) )
2014-07-14 04:05:27 +02:00
{
2014-07-14 18:04:20 +02:00
tempValueMappings . get ( value ) . add ( stack ) ;
2014-07-14 04:05:27 +02:00
}
}
else
{
2014-07-14 18:04:20 +02:00
tempValueMappings . put ( value , new ArrayList < WrappedStack > ( Arrays . asList ( stack ) ) ) ;
2014-07-14 04:05:27 +02:00
}
}
}
}
2014-07-14 18:04:20 +02:00
valueMappings = ImmutableSortedMap . copyOf ( tempValueMappings ) ;
2014-07-14 04:05:27 +02:00
}
2015-04-14 04:27:11 +02:00
private Map < WrappedStack , EnergyValue > computeStackMappings ( Map < WrappedStack , EnergyValue > stackValueMappings )
2014-07-14 04:05:27 +02:00
{
2015-04-09 18:40:19 +02:00
Map < WrappedStack , EnergyValue > computedStackMap = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-07-14 04:05:27 +02:00
for ( WrappedStack recipeOutput : RecipeRegistry . getInstance ( ) . getRecipeMappings ( ) . keySet ( ) )
{
2015-04-14 04:27:11 +02:00
if ( ! hasEnergyValue ( recipeOutput . getWrappedObject ( ) , false ) & & ! computedStackMap . containsKey ( recipeOutput ) )
2014-07-14 04:05:27 +02:00
{
EnergyValue lowestValue = null ;
for ( List < WrappedStack > recipeInputs : RecipeRegistry . getInstance ( ) . getRecipeMappings ( ) . get ( recipeOutput ) )
{
2015-04-14 04:27:11 +02:00
EnergyValue computedValue = EnergyValueHelper . computeEnergyValueFromRecipe ( stackValueMappings , recipeOutput , recipeInputs ) ;
2014-07-14 04:05:27 +02:00
if ( computedValue ! = null )
{
if ( computedValue . compareTo ( lowestValue ) < 0 )
{
lowestValue = computedValue ;
}
}
}
2015-04-19 21:01:35 +02:00
if ( ( lowestValue ! = null ) & & ( lowestValue . getValue ( ) > 0f ) )
2014-07-14 04:05:27 +02:00
{
2015-04-19 21:01:35 +02:00
computedStackMap . put ( WrappedStack . wrap ( recipeOutput . getWrappedObject ( ) ) , lowestValue ) ;
2014-07-14 04:05:27 +02:00
}
}
}
return computedStackMap ;
}
2014-07-15 00:37:50 +02:00
public List getStacksInRange ( int start , int finish )
2014-06-14 21:40:45 +02:00
{
return getStacksInRange ( new EnergyValue ( start ) , new EnergyValue ( finish ) ) ;
}
2014-07-15 00:37:50 +02:00
public List getStacksInRange ( float start , float finish )
2014-07-14 04:05:27 +02:00
{
return getStacksInRange ( new EnergyValue ( start ) , new EnergyValue ( finish ) ) ;
}
2014-07-15 00:37:50 +02:00
public List getStacksInRange ( EnergyValue start , EnergyValue finish )
2014-06-14 21:40:45 +02:00
{
2014-07-15 00:37:50 +02:00
List stacksInRange = new ArrayList < WrappedStack > ( ) ;
2014-06-14 21:40:45 +02:00
2015-03-23 12:36:32 +01:00
if ( valueMappings ! = null )
2014-06-14 21:40:45 +02:00
{
2015-03-23 12:36:32 +01:00
SortedMap < EnergyValue , List < WrappedStack > > tailMap = energyValueRegistry . valueMappings . tailMap ( start ) ;
SortedMap < EnergyValue , List < WrappedStack > > headMap = energyValueRegistry . valueMappings . headMap ( finish ) ;
2014-06-14 21:40:45 +02:00
2015-03-23 12:36:32 +01:00
SortedMap < EnergyValue , List < WrappedStack > > smallerMap ;
SortedMap < EnergyValue , List < WrappedStack > > biggerMap ;
2014-06-14 21:40:45 +02:00
2015-03-23 12:36:32 +01:00
if ( ! tailMap . isEmpty ( ) & & ! headMap . isEmpty ( ) )
2014-06-14 21:40:45 +02:00
{
2015-03-23 12:36:32 +01:00
if ( tailMap . size ( ) < = headMap . size ( ) )
{
smallerMap = tailMap ;
biggerMap = headMap ;
}
else
2014-06-14 21:40:45 +02:00
{
2015-03-23 12:36:32 +01:00
smallerMap = headMap ;
biggerMap = tailMap ;
}
for ( EnergyValue value : smallerMap . keySet ( ) )
{
if ( biggerMap . containsKey ( value ) )
2014-07-15 00:37:50 +02:00
{
2015-03-23 12:36:32 +01:00
for ( WrappedStack wrappedStack : energyValueRegistry . valueMappings . get ( value ) )
2014-07-15 00:37:50 +02:00
{
2015-04-14 04:27:11 +02:00
if ( wrappedStack . getWrappedObject ( ) instanceof ItemStack | | wrappedStack . getWrappedObject ( ) instanceof FluidStack )
2015-03-23 12:36:32 +01:00
{
2015-04-14 04:27:11 +02:00
stacksInRange . add ( wrappedStack . getWrappedObject ( ) ) ;
2015-03-23 12:36:32 +01:00
}
2015-04-14 04:27:11 +02:00
else if ( wrappedStack . getWrappedObject ( ) instanceof OreStack )
2014-07-15 00:37:50 +02:00
{
2015-04-14 04:27:11 +02:00
for ( ItemStack itemStack : OreDictionary . getOres ( ( ( OreStack ) wrappedStack . getWrappedObject ( ) ) . oreName ) )
2015-03-23 12:36:32 +01:00
{
stacksInRange . add ( itemStack ) ;
}
2014-07-15 00:37:50 +02:00
}
}
}
2014-06-14 21:40:45 +02:00
}
}
}
return stacksInRange ;
}
2014-07-25 04:03:36 +02:00
2015-05-03 01:23:35 +02:00
public void loadFromMap ( Map < WrappedStack , EnergyValue > stackValueMap )
2014-08-29 22:25:31 +02:00
{
2015-05-03 01:23:35 +02:00
if ( stackValueMap ! = null )
2014-08-29 22:25:31 +02:00
{
ImmutableSortedMap . Builder < WrappedStack , EnergyValue > stackMappingsBuilder = ImmutableSortedMap . naturalOrder ( ) ;
stackMappingsBuilder . putAll ( stackValueMap ) ;
stackMappings = stackMappingsBuilder . build ( ) ;
/ * *
* Resolve value stack mappings from the newly loaded stack mappings
* /
2015-02-16 03:13:35 +01:00
generateValueStackMappings ( ) ;
2014-08-29 22:25:31 +02:00
}
}
2014-09-10 04:52:46 +02:00
public void setEnergyValue ( WrappedStack wrappedStack , EnergyValue energyValue )
{
2015-04-19 21:01:35 +02:00
if ( wrappedStack ! = null & & energyValue ! = null & & Float . compare ( energyValue . getValue ( ) , 0f ) > 0 )
2014-09-11 22:13:39 +02:00
{
2015-04-09 18:40:19 +02:00
TreeMap < WrappedStack , EnergyValue > stackValueMap = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2014-09-10 04:52:46 +02:00
2014-09-11 22:13:39 +02:00
/ * *
* Read stack value mappings from NBTTagCompound
* /
stackValueMap . putAll ( stackMappings ) ;
stackValueMap . put ( wrappedStack , energyValue ) ;
2014-09-10 04:52:46 +02:00
2014-09-11 22:13:39 +02:00
ImmutableSortedMap . Builder < WrappedStack , EnergyValue > stackMappingsBuilder = ImmutableSortedMap . naturalOrder ( ) ;
stackMappingsBuilder . putAll ( stackValueMap ) ;
stackMappings = stackMappingsBuilder . build ( ) ;
2014-09-10 04:52:46 +02:00
2014-09-11 22:13:39 +02:00
/ * *
* Resolve value stack mappings from the newly loaded stack mappings
* /
SortedMap < EnergyValue , List < WrappedStack > > tempValueMappings = new TreeMap < EnergyValue , List < WrappedStack > > ( ) ;
2014-09-10 04:52:46 +02:00
2014-09-11 22:13:39 +02:00
for ( WrappedStack stack : stackMappings . keySet ( ) )
2014-09-10 04:52:46 +02:00
{
2014-09-11 22:13:39 +02:00
if ( stack ! = null )
2014-09-10 04:52:46 +02:00
{
2014-09-11 22:13:39 +02:00
EnergyValue value = stackMappings . get ( stack ) ;
if ( value ! = null )
2014-09-10 04:52:46 +02:00
{
2014-09-11 22:13:39 +02:00
if ( tempValueMappings . containsKey ( value ) )
2014-09-10 04:52:46 +02:00
{
2014-09-11 22:13:39 +02:00
if ( ! ( tempValueMappings . get ( value ) . contains ( stack ) ) )
{
tempValueMappings . get ( value ) . add ( stack ) ;
}
}
else
{
tempValueMappings . put ( value , new ArrayList < WrappedStack > ( Arrays . asList ( stack ) ) ) ;
2014-09-10 04:52:46 +02:00
}
}
}
}
2014-09-11 22:13:39 +02:00
valueMappings = ImmutableSortedMap . copyOf ( tempValueMappings ) ;
}
2014-09-10 04:52:46 +02:00
}
2014-09-16 18:08:16 +02:00
public boolean getShouldRegenNextRestart ( )
{
return shouldRegenNextRestart ;
}
public void setShouldRegenNextRestart ( boolean shouldRegenNextRestart )
{
this . shouldRegenNextRestart = shouldRegenNextRestart ;
}
2015-02-11 05:38:05 +01:00
2015-02-20 04:09:10 +01:00
public ImmutableSortedMap < WrappedStack , EnergyValue > getStackValueMap ( )
{
return stackMappings ;
}
public ImmutableSortedMap < EnergyValue , List < WrappedStack > > getValueStackMap ( )
{
return valueMappings ;
}
2015-04-21 03:16:48 +02:00
public void save ( )
2015-02-11 05:38:05 +01:00
{
2015-02-12 06:15:45 +01:00
File energyValuesDataDirectory = new File ( FMLCommonHandler . instance ( ) . getMinecraftServerInstance ( ) . getEntityWorld ( ) . getSaveHandler ( ) . getWorldDirectory ( ) , " data " + File . separator + Reference . LOWERCASE_MOD_ID + File . separator + " energyvalues " ) ;
energyValuesDataDirectory . mkdirs ( ) ;
if ( shouldRegenNextRestart )
{
2015-04-21 03:16:48 +02:00
File staticEnergyValuesJsonFile = new File ( energyValuesDataDirectory , Files . STATIC_ENERGY_VALUES_JSON ) ;
File md5EnergyValuesJsonFile = new File ( energyValuesDataDirectory , SerializationHelper . getModListMD5 ( ) + " .json " ) ;
2015-02-12 06:15:45 +01:00
2015-04-21 03:16:48 +02:00
// JSON
if ( staticEnergyValuesJsonFile . exists ( ) )
{
staticEnergyValuesJsonFile . delete ( ) ;
}
if ( md5EnergyValuesJsonFile . exists ( ) )
{
md5EnergyValuesJsonFile . delete ( ) ;
}
2015-02-13 06:23:35 +01:00
shouldRegenNextRestart = false ;
2015-02-12 06:15:45 +01:00
}
else
{
2015-05-02 20:07:01 +02:00
SerializationHelper . compressEnergyValueStackMapToFile ( new File ( energyValuesDataDirectory , Files . STATIC_ENERGY_VALUES_JSON ) , energyValueRegistry . stackMappings ) ;
SerializationHelper . compressEnergyValueStackMapToFile ( new File ( energyValuesDataDirectory , SerializationHelper . getModListMD5 ( ) + " .json.gz " ) , energyValueRegistry . stackMappings ) ;
2015-02-12 06:15:45 +01:00
}
2015-02-11 05:38:05 +01:00
}
2015-02-12 06:15:45 +01:00
public boolean loadEnergyValueRegistryFromFile ( )
2015-02-11 05:38:05 +01:00
{
2015-02-12 06:15:45 +01:00
File energyValuesDataDirectory = new File ( FMLCommonHandler . instance ( ) . getMinecraftServerInstance ( ) . getEntityWorld ( ) . getSaveHandler ( ) . getWorldDirectory ( ) , " data " + File . separator + Reference . LOWERCASE_MOD_ID + File . separator + " energyvalues " ) ;
energyValuesDataDirectory . mkdirs ( ) ;
2015-05-02 20:07:01 +02:00
File staticEnergyValuesFile = new File ( energyValuesDataDirectory , Files . STATIC_ENERGY_VALUES_JSON ) ;
File md5EnergyValuesFile = new File ( energyValuesDataDirectory , SerializationHelper . getModListMD5 ( ) + " .json.gz " ) ;
Map < WrappedStack , EnergyValue > stackValueMap = null ;
2015-03-23 13:12:44 +01:00
if ( ! Settings . DynamicEnergyValueGeneration . regenerateEnergyValuesWhen . equalsIgnoreCase ( " Always " ) )
2015-02-12 06:15:45 +01:00
{
2015-05-03 01:23:35 +02:00
if ( Settings . DynamicEnergyValueGeneration . regenerateEnergyValuesWhen . equalsIgnoreCase ( " When Mods Change " ) )
2015-03-23 13:12:44 +01:00
{
2015-05-03 01:23:35 +02:00
if ( md5EnergyValuesFile . exists ( ) )
{
LogHelper . info ( " Attempting to load energy values from file: " + md5EnergyValuesFile . getAbsolutePath ( ) ) ;
stackValueMap = SerializationHelper . decompressEnergyValueStackMapFromFile ( md5EnergyValuesFile ) ;
}
2015-05-02 20:07:01 +02:00
}
2015-05-03 01:23:35 +02:00
else if ( Settings . DynamicEnergyValueGeneration . regenerateEnergyValuesWhen . equalsIgnoreCase ( " Never " ) )
2015-05-02 20:07:01 +02:00
{
2015-05-03 01:23:35 +02:00
if ( staticEnergyValuesFile . exists ( ) )
{
LogHelper . info ( " Attempting to load energy values from file: " + staticEnergyValuesFile . getAbsolutePath ( ) ) ;
stackValueMap = SerializationHelper . decompressEnergyValueStackMapFromFile ( staticEnergyValuesFile ) ;
}
else if ( md5EnergyValuesFile . exists ( ) )
{
LogHelper . info ( " Attempting to load energy values from file: " + md5EnergyValuesFile . getAbsolutePath ( ) ) ;
stackValueMap = SerializationHelper . decompressEnergyValueStackMapFromFile ( md5EnergyValuesFile ) ;
}
2015-03-23 13:12:44 +01:00
}
2015-02-12 06:15:45 +01:00
2015-05-02 20:07:01 +02:00
if ( stackValueMap ! = null )
2015-03-23 13:12:44 +01:00
{
2015-05-03 01:23:35 +02:00
loadFromMap ( stackValueMap ) ;
2015-03-23 13:12:44 +01:00
LogHelper . info ( " Successfully loaded energy values from file " ) ;
2015-05-03 01:23:35 +02:00
return true ;
2015-03-23 13:12:44 +01:00
}
else
{
LogHelper . info ( " No energy value file to load values from, generating new values " ) ;
return false ;
}
2015-02-12 06:15:45 +01:00
}
else
{
return false ;
}
2015-02-11 05:38:05 +01:00
}
2015-02-16 03:13:35 +01:00
public String toJson ( )
{
2015-03-05 05:31:43 +01:00
return prettyJsonSerializer . toJson ( this ) ;
2015-02-16 03:13:35 +01:00
}
@Override
public EnergyValueRegistry deserialize ( JsonElement json , Type typeOfT , JsonDeserializationContext context ) throws JsonParseException
{
if ( json . isJsonArray ( ) )
{
JsonArray jsonArray = ( JsonArray ) json ;
2015-04-09 18:40:19 +02:00
Map < WrappedStack , EnergyValue > stackValueMap = new TreeMap < WrappedStack , EnergyValue > ( ) ;
2015-02-16 03:13:35 +01:00
Iterator < JsonElement > iterator = jsonArray . iterator ( ) ;
while ( iterator . hasNext ( ) )
{
JsonElement jsonElement = iterator . next ( ) ;
EnergyValueStackMapping energyValueStackMapping = new EnergyValueStackMapping ( ) . deserialize ( jsonElement , typeOfT , context ) ;
if ( energyValueStackMapping ! = null )
{
stackValueMap . put ( energyValueStackMapping . wrappedStack , energyValueStackMapping . energyValue ) ;
}
}
ImmutableSortedMap . Builder < WrappedStack , EnergyValue > stackMappingsBuilder = ImmutableSortedMap . naturalOrder ( ) ;
stackMappingsBuilder . putAll ( stackValueMap ) ;
stackMappings = stackMappingsBuilder . build ( ) ;
generateValueStackMappings ( ) ;
}
return null ;
}
@Override
public JsonElement serialize ( EnergyValueRegistry energyValueRegistry , Type typeOfSrc , JsonSerializationContext context )
{
JsonArray jsonEnergyValueRegistry = new JsonArray ( ) ;
for ( WrappedStack wrappedStack : energyValueRegistry . stackMappings . keySet ( ) )
{
jsonEnergyValueRegistry . add ( EnergyValueStackMapping . jsonSerializer . toJsonTree ( new EnergyValueStackMapping ( wrappedStack , energyValueRegistry . stackMappings . get ( wrappedStack ) ) ) ) ;
}
return jsonEnergyValueRegistry ;
}
2015-04-09 18:40:19 +02:00
public void dumpEnergyValueRegistryToLog ( )
{
dumpEnergyValueRegistryToLog ( EnergyValueRegistryProxy . Phase . ALL ) ;
}
public void dumpEnergyValueRegistryToLog ( EnergyValueRegistryProxy . Phase phase )
{
LogHelper . info ( String . format ( " BEGIN DUMPING %s ENERGY VALUE MAPPINGS " , phase ) ) ;
if ( phase = = EnergyValueRegistryProxy . Phase . PRE_ASSIGNMENT )
{
for ( WrappedStack wrappedStack : this . preAssignedMappings . keySet ( ) )
{
LogHelper . info ( String . format ( " - Object: %s, Value: %s " , wrappedStack , EnergyValueRegistry . getInstance ( ) . getStackValueMap ( ) . get ( wrappedStack ) ) ) ;
}
}
else if ( phase = = EnergyValueRegistryProxy . Phase . POST_ASSIGNMENT )
{
2015-04-17 00:18:49 +02:00
if ( this . postAssignedMappings ! = null )
2015-04-09 18:40:19 +02:00
{
2015-04-17 00:18:49 +02:00
for ( WrappedStack wrappedStack : this . postAssignedMappings . keySet ( ) )
2015-04-09 18:40:19 +02:00
{
LogHelper . info ( String . format ( " - Object: %s, Value: %s " , wrappedStack , EnergyValueRegistry . getInstance ( ) . getStackValueMap ( ) . get ( wrappedStack ) ) ) ;
}
}
}
else if ( phase = = EnergyValueRegistryProxy . Phase . ALL )
{
for ( WrappedStack wrappedStack : EnergyValueRegistry . getInstance ( ) . getStackValueMap ( ) . keySet ( ) )
{
LogHelper . info ( String . format ( " - Object: %s, Value: %s " , wrappedStack , EnergyValueRegistry . getInstance ( ) . getStackValueMap ( ) . get ( wrappedStack ) ) ) ;
}
}
LogHelper . info ( String . format ( " END DUMPING %s ENERGY VALUE MAPPINGS " , phase ) ) ;
}
2014-06-14 21:40:45 +02:00
}