2013-05-23 05:01:19 +00:00
package net.minecraftforge.fluids ;
import java.util.Map ;
2015-04-08 03:06:55 +00:00
import java.util.Map.Entry ;
2015-04-11 21:18:53 +00:00
import java.util.Set ;
import org.apache.logging.log4j.Level ;
2013-05-23 05:01:19 +00:00
import net.minecraft.block.Block ;
2014-01-30 02:34:23 +00:00
import net.minecraft.init.Blocks ;
2015-04-11 21:18:53 +00:00
import net.minecraft.nbt.NBTTagCompound ;
import net.minecraft.nbt.NBTTagList ;
import net.minecraft.nbt.NBTTagString ;
2013-11-12 09:05:13 +00:00
import net.minecraft.util.StatCollector ;
2013-05-23 05:01:19 +00:00
import net.minecraftforge.common.MinecraftForge ;
2015-04-19 01:37:45 +00:00
import com.google.common.base.Strings ;
2013-05-23 05:01:19 +00:00
import com.google.common.collect.BiMap ;
import com.google.common.collect.HashBiMap ;
import com.google.common.collect.ImmutableMap ;
2015-04-20 13:06:23 +00:00
import com.google.common.collect.Maps ;
2015-04-11 21:18:53 +00:00
import com.google.common.collect.Sets ;
2013-05-23 05:01:19 +00:00
2015-04-06 02:37:40 +00:00
import cpw.mods.fml.common.FMLLog ;
2015-04-11 21:18:53 +00:00
import cpw.mods.fml.common.Loader ;
import cpw.mods.fml.common.ModContainer ;
2013-12-17 01:18:48 +00:00
import cpw.mods.fml.common.eventhandler.Event ;
2015-04-11 21:18:53 +00:00
import cpw.mods.fml.common.network.ByteBufUtils ;
2015-04-20 13:06:23 +00:00
import cpw.mods.fml.common.registry.RegistryDelegate ;
2013-12-17 01:18:48 +00:00
2013-05-23 05:01:19 +00:00
/ * *
* Handles Fluid registrations . Fluids MUST be registered in order to function .
2013-07-27 21:36:27 +00:00
*
2013-05-23 05:01:19 +00:00
* @author King Lemming , CovertJaguar ( LiquidDictionary )
2013-07-27 21:36:27 +00:00
*
2013-05-23 05:01:19 +00:00
* /
2013-07-17 04:40:49 +00:00
public abstract class FluidRegistry
{
2013-05-23 05:01:19 +00:00
static int maxID = 0 ;
2015-03-25 05:27:15 +00:00
static BiMap < String , Fluid > fluids = HashBiMap . create ( ) ;
static BiMap < Fluid , Integer > fluidIDs = HashBiMap . create ( ) ;
2015-04-08 03:06:55 +00:00
static BiMap < Integer , String > fluidNames = HashBiMap . create ( ) ; //Caching this just makes some other calls faster
2013-09-05 16:08:16 +00:00
static BiMap < Block , Fluid > fluidBlocks ;
2015-04-05 20:13:17 +00:00
2015-04-11 21:18:53 +00:00
// the globally unique fluid map - only used to associate non-defaults during world/server loading
static BiMap < String , Fluid > masterFluidReference = HashBiMap . create ( ) ;
static BiMap < String , String > defaultFluidName = HashBiMap . create ( ) ;
2013-11-12 09:05:13 +00:00
public static final Fluid WATER = new Fluid ( " water " ) {
@Override
public String getLocalizedName ( ) {
return StatCollector . translateToLocal ( " tile.water.name " ) ;
}
2014-02-05 08:05:37 +00:00
} . setBlock ( Blocks . water ) . setUnlocalizedName ( Blocks . water . getUnlocalizedName ( ) ) ;
2015-04-05 20:13:17 +00:00
2013-11-12 09:05:13 +00:00
public static final Fluid LAVA = new Fluid ( " lava " ) {
@Override
public String getLocalizedName ( ) {
return StatCollector . translateToLocal ( " tile.lava.name " ) ;
}
2014-02-05 08:05:37 +00:00
} . setBlock ( Blocks . lava ) . setLuminosity ( 15 ) . setDensity ( 3000 ) . setViscosity ( 6000 ) . setTemperature ( 1300 ) . setUnlocalizedName ( Blocks . lava . getUnlocalizedName ( ) ) ;
2013-05-23 05:01:19 +00:00
public static int renderIdFluid = - 1 ;
2013-07-17 04:40:49 +00:00
static
{
2013-05-23 05:01:19 +00:00
registerFluid ( WATER ) ;
registerFluid ( LAVA ) ;
}
2013-07-17 04:40:49 +00:00
private FluidRegistry ( ) { }
2013-05-23 05:01:19 +00:00
/ * *
* Called by Forge to prepare the ID map for server - > client sync .
2014-01-30 02:34:23 +00:00
* Modders , DO NOT call this .
* /
2015-04-11 21:18:53 +00:00
public static void initFluidIDs ( BiMap < Fluid , Integer > newfluidIDs , Set < String > defaultNames )
2013-07-17 04:40:49 +00:00
{
2013-05-23 05:01:19 +00:00
maxID = newfluidIDs . size ( ) ;
fluidIDs . clear ( ) ;
fluidIDs . putAll ( newfluidIDs ) ;
2015-04-08 03:06:55 +00:00
fluidNames . clear ( ) ;
2015-04-11 21:18:53 +00:00
for ( Entry < Fluid , Integer > e : fluidIDs . entrySet ( ) ) {
2015-04-08 03:06:55 +00:00
fluidNames . put ( e . getValue ( ) , e . getKey ( ) . getName ( ) ) ;
2015-04-11 21:18:53 +00:00
}
loadFluidDefaults ( defaultNames ) ;
}
/ * *
* Called by forge to load default fluid IDs from the world or from server - > client for syncing
* DO NOT call this and expect useful behaviour .
* /
private static void loadFluidDefaults ( Set < String > defaultNames )
{
// If there's an empty set of default names, use the defaults as defined locally
if ( defaultNames . isEmpty ( ) ) {
defaultNames . addAll ( defaultFluidName . values ( ) ) ;
}
for ( String defaultName : defaultNames )
{
Fluid fluid = masterFluidReference . get ( defaultName ) ;
if ( fluid = = null ) {
String derivedName = defaultName . split ( " : " , 2 ) [ 1 ] ;
String localDefault = defaultFluidName . get ( derivedName ) ;
if ( localDefault = = null ) {
FMLLog . getLogger ( ) . log ( Level . ERROR , " The fluid {} (specified as {}) is missing from this instance - it will be removed " , derivedName , defaultName ) ;
continue ;
}
fluid = masterFluidReference . get ( localDefault ) ;
FMLLog . getLogger ( ) . log ( Level . ERROR , " The fluid {} specified as default is not present - it will be reverted to default {} " , defaultName , localDefault ) ;
}
FMLLog . getLogger ( ) . log ( Level . DEBUG , " The fluid {} has been selected as the default fluid for {} " , defaultName , fluid . getName ( ) ) ;
fluids . put ( fluid . getName ( ) , fluid ) ;
Integer id = fluidIDs . remove ( fluid ) ;
fluidIDs . put ( fluid , id ) ;
}
fluidBlocks = null ;
2015-04-20 13:06:23 +00:00
for ( FluidDelegate fd : delegates . values ( ) )
{
fd . rebind ( ) ;
}
2013-05-23 05:01:19 +00:00
}
/ * *
2015-04-11 21:18:53 +00:00
* Register a new Fluid . If a fluid with the same name already exists , registration the alternative fluid is tracked
* in case it is the default in another place
2013-07-27 21:36:27 +00:00
*
2013-05-23 05:01:19 +00:00
* @param fluid
* The fluid to register .
2015-04-11 21:18:53 +00:00
* @return True if the fluid was registered as the current default fluid , false if it was only registered as an alternative
2014-01-30 02:34:23 +00:00
* /
2013-07-17 04:40:49 +00:00
public static boolean registerFluid ( Fluid fluid )
{
2015-04-11 21:18:53 +00:00
masterFluidReference . put ( uniqueName ( fluid ) , fluid ) ;
2015-04-20 13:06:23 +00:00
delegates . put ( fluid , new FluidDelegate ( fluid , fluid . getName ( ) ) ) ;
2015-04-08 11:26:40 +00:00
if ( fluids . containsKey ( fluid . getName ( ) ) )
2013-07-17 04:40:49 +00:00
{
2013-05-23 05:01:19 +00:00
return false ;
}
fluids . put ( fluid . getName ( ) , fluid ) ;
2015-04-10 20:38:45 +00:00
maxID + + ;
fluidIDs . put ( fluid , maxID ) ;
2015-04-08 03:06:55 +00:00
fluidNames . put ( maxID , fluid . getName ( ) ) ;
2015-04-11 21:18:53 +00:00
defaultFluidName . put ( fluid . getName ( ) , uniqueName ( fluid ) ) ;
2013-05-23 05:01:19 +00:00
MinecraftForge . EVENT_BUS . post ( new FluidRegisterEvent ( fluid . getName ( ) , maxID ) ) ;
return true ;
}
2015-04-11 21:18:53 +00:00
private static String uniqueName ( Fluid fluid )
{
ModContainer activeModContainer = Loader . instance ( ) . activeModContainer ( ) ;
String activeModContainerName = activeModContainer = = null ? " minecraft " : activeModContainer . getModId ( ) ;
return activeModContainerName + " : " + fluid . getName ( ) ;
}
/ * *
* Is the supplied fluid the current default fluid for it ' s name
* @param fluid the fluid we ' re testing
* @return if the fluid is default
* /
public static boolean isFluidDefault ( Fluid fluid )
{
return fluids . containsValue ( fluid ) ;
}
/ * *
* Does the supplied fluid have an entry for it ' s name ( whether or not the fluid itself is default )
* @param fluid the fluid we ' re testing
* @return if the fluid ' s name has a registration entry
* /
2013-07-17 04:40:49 +00:00
public static boolean isFluidRegistered ( Fluid fluid )
{
2015-04-11 21:27:14 +00:00
return fluid ! = null & & fluids . containsKey ( fluid . getName ( ) ) ;
2013-05-23 05:01:19 +00:00
}
2013-07-17 04:40:49 +00:00
public static boolean isFluidRegistered ( String fluidName )
{
2015-03-25 05:27:15 +00:00
return fluids . containsKey ( fluidName ) ;
2013-05-23 05:01:19 +00:00
}
2013-07-17 04:40:49 +00:00
public static Fluid getFluid ( String fluidName )
{
2013-05-23 05:01:19 +00:00
return fluids . get ( fluidName ) ;
}
2013-07-17 04:40:49 +00:00
public static Fluid getFluid ( int fluidID )
{
2015-03-25 05:27:15 +00:00
return fluidIDs . inverse ( ) . get ( fluidID ) ;
2013-05-23 05:01:19 +00:00
}
2015-03-25 05:27:15 +00:00
public static int getFluidID ( Fluid fluid )
2013-07-17 04:40:49 +00:00
{
2015-03-25 05:27:15 +00:00
return fluidIDs . get ( fluid ) ;
2013-05-23 05:01:19 +00:00
}
2015-03-25 05:27:15 +00:00
public static int getFluidID ( String fluidName )
2013-07-17 04:40:49 +00:00
{
2015-03-25 05:27:15 +00:00
return fluidIDs . get ( getFluid ( fluidName ) ) ;
2013-05-23 05:01:19 +00:00
}
2015-04-08 03:06:55 +00:00
@Deprecated //Remove in 1.8.3
public static String getFluidName ( int fluidID )
{
return fluidNames . get ( fluidID ) ;
}
2015-03-25 05:27:15 +00:00
public static String getFluidName ( Fluid fluid )
{
return fluids . inverse ( ) . get ( fluid ) ;
}
public static String getFluidName ( FluidStack stack )
2013-07-17 04:40:49 +00:00
{
2015-04-20 13:06:23 +00:00
return getFluidName ( stack . getFluid ( ) ) ;
2013-05-23 05:01:19 +00:00
}
2013-07-17 04:40:49 +00:00
public static FluidStack getFluidStack ( String fluidName , int amount )
{
2015-03-25 05:27:15 +00:00
if ( ! fluids . containsKey ( fluidName ) )
2013-07-17 04:40:49 +00:00
{
2013-05-23 05:01:19 +00:00
return null ;
}
2015-03-25 05:27:15 +00:00
return new FluidStack ( getFluid ( fluidName ) , amount ) ;
2013-05-23 05:01:19 +00:00
}
/ * *
* Returns a read - only map containing Fluid Names and their associated Fluids .
2014-01-30 02:34:23 +00:00
* /
2013-07-17 04:40:49 +00:00
public static Map < String , Fluid > getRegisteredFluids ( )
{
2013-05-23 05:01:19 +00:00
return ImmutableMap . copyOf ( fluids ) ;
}
2015-04-08 03:06:55 +00:00
/ * *
* Returns a read - only map containing Fluid Names and their associated IDs .
* /
@Deprecated //Change return type to <Fluid, Integer> in 1.8.3
public static Map < String , Integer > getRegisteredFluidIDs ( )
{
return ImmutableMap . copyOf ( fluidNames . inverse ( ) ) ;
}
2013-05-23 05:01:19 +00:00
/ * *
2015-03-25 05:27:15 +00:00
* Returns a read - only map containing Fluid IDs and their associated Fluids .
2015-04-08 03:06:55 +00:00
* In 1 . 8 . 3 , this will change to just ' getRegisteredFluidIDs '
2014-01-30 02:34:23 +00:00
* /
2015-04-08 03:06:55 +00:00
public static Map < Fluid , Integer > getRegisteredFluidIDsByFluid ( )
2013-07-17 04:40:49 +00:00
{
2013-05-23 05:01:19 +00:00
return ImmutableMap . copyOf ( fluidIDs ) ;
}
2013-09-05 16:08:16 +00:00
public static Fluid lookupFluidForBlock ( Block block )
{
if ( fluidBlocks = = null )
{
2014-04-03 06:53:05 +00:00
BiMap < Block , Fluid > tmp = HashBiMap . create ( ) ;
2013-09-05 16:08:16 +00:00
for ( Fluid fluid : fluids . values ( ) )
{
2014-01-30 02:34:23 +00:00
if ( fluid . canBePlacedInWorld ( ) & & fluid . getBlock ( ) ! = null )
2013-09-05 16:08:16 +00:00
{
2014-04-03 06:53:05 +00:00
tmp . put ( fluid . getBlock ( ) , fluid ) ;
2013-09-05 16:08:16 +00:00
}
}
2014-04-03 06:53:05 +00:00
fluidBlocks = tmp ;
2013-09-05 16:08:16 +00:00
}
return fluidBlocks . get ( block ) ;
}
2015-04-05 20:13:17 +00:00
2013-07-17 04:40:49 +00:00
public static class FluidRegisterEvent extends Event
{
2013-05-23 05:01:19 +00:00
public final String fluidName ;
public final int fluidID ;
2013-07-17 04:40:49 +00:00
public FluidRegisterEvent ( String fluidName , int fluidID )
{
2013-05-23 05:01:19 +00:00
this . fluidName = fluidName ;
this . fluidID = fluidID ;
}
}
2014-01-30 02:34:23 +00:00
public static int getMaxID ( )
{
return maxID ;
}
2015-04-11 21:18:53 +00:00
public static String getDefaultFluidName ( Fluid key )
{
2015-04-19 01:37:45 +00:00
String name = masterFluidReference . inverse ( ) . get ( key ) ;
if ( Strings . isNullOrEmpty ( name ) ) {
FMLLog . getLogger ( ) . log ( Level . ERROR , " The fluid registry is corrupted. A fluid {} {} is not properly registered. The mod that registered this is broken " , key . getClass ( ) . getName ( ) , key . getName ( ) ) ;
throw new IllegalStateException ( " The fluid registry is corrupted " ) ;
}
return name ;
2015-04-11 21:18:53 +00:00
}
public static void loadFluidDefaults ( NBTTagCompound tag )
{
Set < String > defaults = Sets . newHashSet ( ) ;
if ( tag . hasKey ( " DefaultFluidList " , 9 ) )
{
FMLLog . getLogger ( ) . log ( Level . DEBUG , " Loading persistent fluid defaults from world " ) ;
NBTTagList tl = tag . getTagList ( " DefaultFluidList " , 8 ) ;
for ( int i = 0 ; i < tl . tagCount ( ) ; i + + )
{
defaults . add ( tl . getStringTagAt ( i ) ) ;
}
}
else
{
FMLLog . getLogger ( ) . log ( Level . DEBUG , " World is missing persistent fluid defaults - using local defaults " ) ;
}
loadFluidDefaults ( defaults ) ;
}
public static void writeDefaultFluidList ( NBTTagCompound forgeData )
{
NBTTagList tagList = new NBTTagList ( ) ;
for ( Entry < String , Fluid > def : fluids . entrySet ( ) )
{
tagList . appendTag ( new NBTTagString ( getDefaultFluidName ( def . getValue ( ) ) ) ) ;
}
forgeData . setTag ( " DefaultFluidList " , tagList ) ;
}
2015-04-19 01:37:45 +00:00
public static void validateFluidRegistry ( )
{
Set < Fluid > illegalFluids = Sets . newHashSet ( ) ;
for ( Fluid f : fluids . values ( ) )
{
if ( ! masterFluidReference . containsValue ( f ) )
{
illegalFluids . add ( f ) ;
}
}
if ( ! illegalFluids . isEmpty ( ) )
{
FMLLog . getLogger ( ) . log ( Level . FATAL , " The fluid registry is corrupted. Something has inserted a fluid without registering it " ) ;
FMLLog . getLogger ( ) . log ( Level . FATAL , " There is {} unregistered fluids " , illegalFluids . size ( ) ) ;
for ( Fluid f : illegalFluids )
{
FMLLog . getLogger ( ) . log ( Level . FATAL , " Fluid name : {}, type: {} " , f . getName ( ) , f . getClass ( ) . getName ( ) ) ;
}
FMLLog . getLogger ( ) . log ( Level . FATAL , " The mods that own these fluids need to register them properly " ) ;
throw new IllegalStateException ( " The fluid map contains fluids unknown to the master fluid registry " ) ;
}
}
2015-04-20 13:06:23 +00:00
private static Map < Fluid , FluidDelegate > delegates = Maps . newHashMap ( ) ;
static RegistryDelegate < Fluid > makeDelegate ( Fluid fl )
{
return delegates . get ( fl ) ;
}
private static class FluidDelegate implements RegistryDelegate < Fluid >
{
private String name ;
private Fluid fluid ;
FluidDelegate ( Fluid fluid , String name )
{
this . fluid = fluid ;
this . name = name ;
}
@Override
public Fluid get ( )
{
return fluid ;
}
@Override
public String name ( )
{
return name ;
}
@Override
public Class < Fluid > type ( )
{
return Fluid . class ;
}
void rebind ( )
{
fluid = fluids . get ( name ) ;
}
}
}