2016-06-23 03:49:47 +00:00
/ *
* Minecraft Forge
* Copyright ( c ) 2016 .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2 . 1
* of the License .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
* /
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 ;
2016-01-02 13:38:18 +00:00
import net.minecraftforge.fml.common.LoaderState ;
2015-04-11 21:18:53 +00:00
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 ;
2015-06-18 11:14:46 +00:00
import net.minecraft.util.ResourceLocation ;
2016-03-07 00:54:47 +00:00
import net.minecraft.util.text.translation.I18n ;
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 ;
2016-01-02 13:38:18 +00:00
import com.google.common.collect.ImmutableSet ;
2014-01-30 02:34: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-06-01 20:29:34 +00:00
import net.minecraftforge.fml.common.FMLLog ;
import net.minecraftforge.fml.common.Loader ;
import net.minecraftforge.fml.common.ModContainer ;
Initial update to 1.8, Super beta. Most rendering related hooks are out due to major changes in 1.8.
Some notes:
Almost all int x, int y, int z parameters have been changed to BlockPos class
ForgeDirection has been removed, replaced by net.minecraft.util.EnumFacing.
All FML classes have moved from packet cpw.mods.fml to net.minecraftforge.fml
Fluid Rendering has been disabled for the time being, to be re-evaulated and a test mod created for it.
Minecraft now uses a Model based system for rendering blocks and Items. The intention is to expand the model format to better suit modder's needed once it is evaulated.
As such, The model loaders from Forge have been removed, to be replaced by expanding vanilla's model format.
Metadata has been extracted out in Minecraft to IBlockState, which holds a list of properties instead of magic number metadata. DO NOT listen to the fearmongering, you can do EVERYTHING with block states you could previously with metadata.
Stencil Bits are disabled entirely by for the main Display, Modders must enable and recreate the FrameBuffer if they wish to use Stencil Bits.
2014-11-26 03:56:35 +00:00
import net.minecraftforge.fml.common.eventhandler.Event ;
2017-06-19 22:02:18 +00:00
import net.minecraftforge.registries.IRegistryDelegate ;
2013-12-17 01:18:48 +00:00
2017-01-11 23:17:56 +00:00
import javax.annotation.Nullable ;
2013-05-23 05:01:19 +00:00
/ * *
* Handles Fluid registrations . Fluids MUST be registered in order to function .
* /
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 ( ) ;
2015-04-20 13:26:27 +00:00
static Map < Fluid , FluidDelegate > delegates = Maps . newHashMap ( ) ;
2015-04-11 21:18:53 +00:00
2016-01-02 13:38:18 +00:00
static boolean universalBucketEnabled = false ;
static Set < Fluid > bucketFluids = Sets . newHashSet ( ) ;
2015-06-18 11:14:46 +00:00
public static final Fluid WATER = new Fluid ( " water " , new ResourceLocation ( " blocks/water_still " ) , new ResourceLocation ( " blocks/water_flow " ) ) {
2013-11-12 09:05:13 +00:00
@Override
2015-11-24 15:05:35 +00:00
public String getLocalizedName ( FluidStack fs ) {
2016-03-07 00:54:47 +00:00
return I18n . translateToLocal ( " tile.water.name " ) ;
2013-11-12 09:05:13 +00:00
}
2016-05-18 12:11:56 +00:00
} . setBlock ( Blocks . WATER ) . setUnlocalizedName ( Blocks . WATER . getUnlocalizedName ( ) ) ;
2015-04-05 20:13:17 +00:00
2015-06-18 11:14:46 +00:00
public static final Fluid LAVA = new Fluid ( " lava " , new ResourceLocation ( " blocks/lava_still " ) , new ResourceLocation ( " blocks/lava_flow " ) ) {
2013-11-12 09:05:13 +00:00
@Override
2015-11-24 15:05:35 +00:00
public String getLocalizedName ( FluidStack fs ) {
2016-03-07 00:54:47 +00:00
return I18n . translateToLocal ( " tile.lava.name " ) ;
2013-11-12 09:05:13 +00:00
}
2016-05-18 12:11:56 +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
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 ( ) ;
2015-06-03 23:26:53 +00:00
loadFluidDefaults ( newfluidIDs , defaultNames ) ;
2013-05-23 05:01:19 +00:00
}
/ * *
2015-04-11 21:18:53 +00:00
* 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 .
2015-11-24 15:05:35 +00:00
* @param localFluidIDs
* @param defaultNames
2015-04-11 21:18:53 +00:00
* /
2015-06-03 23:26:53 +00:00
private static void loadFluidDefaults ( BiMap < Fluid , Integer > localFluidIDs , Set < String > defaultNames )
2015-04-11 21:18:53 +00:00
{
// If there's an empty set of default names, use the defaults as defined locally
if ( defaultNames . isEmpty ( ) ) {
defaultNames . addAll ( defaultFluidName . values ( ) ) ;
}
2015-06-03 23:26:53 +00:00
BiMap < String , Fluid > localFluids = HashBiMap . create ( fluids ) ;
2015-04-11 21:18:53 +00:00
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 ) {
2017-06-23 05:33:11 +00:00
FMLLog . log . error ( " The fluid {} (specified as {}) is missing from this instance - it will be removed " , derivedName , defaultName ) ;
2015-04-11 21:18:53 +00:00
continue ;
}
fluid = masterFluidReference . get ( localDefault ) ;
2017-06-23 05:33:11 +00:00
FMLLog . log . error ( " The fluid {} specified as default is not present - it will be reverted to default {} " , defaultName , localDefault ) ;
2015-04-11 21:18:53 +00:00
}
2017-06-23 05:33:11 +00:00
FMLLog . log . debug ( " The fluid {} has been selected as the default fluid for {} " , defaultName , fluid . getName ( ) ) ;
2015-06-03 23:26:53 +00:00
Fluid oldFluid = localFluids . put ( fluid . getName ( ) , fluid ) ;
Integer id = localFluidIDs . remove ( oldFluid ) ;
localFluidIDs . put ( fluid , id ) ;
}
2015-07-09 20:40:51 +00:00
BiMap < Integer , String > localFluidNames = HashBiMap . create ( ) ;
2015-06-03 23:26:53 +00:00
for ( Entry < Fluid , Integer > e : localFluidIDs . entrySet ( ) ) {
localFluidNames . put ( e . getValue ( ) , e . getKey ( ) . getName ( ) ) ;
2015-04-11 21:18:53 +00:00
}
2015-06-03 23:26:53 +00:00
fluidIDs = localFluidIDs ;
fluids = localFluids ;
fluidNames = localFluidNames ;
2015-04-11 21:18:53 +00:00
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 ) ;
}
2015-03-25 05:27:15 +00:00
public static String getFluidName ( Fluid fluid )
2013-07-17 04:40:49 +00:00
{
2015-03-25 05:27:15 +00:00
return fluids . inverse ( ) . get ( fluid ) ;
2013-05-23 05:01:19 +00:00
}
2015-03-25 05:27:15 +00:00
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
}
2017-01-11 23:17:56 +00:00
@Nullable
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 ) ;
}
/ * *
* Returns a read - only map containing Fluid Names and their associated IDs .
2015-12-10 10:54:00 +00:00
* Modders should never actually use this , use the String names .
2014-01-30 02:34:23 +00:00
* /
2015-12-10 10:54:00 +00:00
@Deprecated
2015-11-24 15:05:35 +00:00
public static Map < Fluid , Integer > getRegisteredFluidIDs ( )
2015-04-08 03:06:55 +00:00
{
2015-11-24 15:05:35 +00:00
return ImmutableMap . copyOf ( fluidIDs ) ;
2015-04-08 03:06:55 +00:00
}
2016-01-02 13:38:18 +00:00
/ * *
* Enables the universal bucket in forge .
* Has to be called before pre - initialization .
* Actually just call it statically in your mod class .
* /
public static void enableUniversalBucket ( )
{
if ( Loader . instance ( ) . hasReachedState ( LoaderState . PREINITIALIZATION ) )
{
2017-01-11 23:17:56 +00:00
ModContainer modContainer = Loader . instance ( ) . activeModContainer ( ) ;
String modContainerName = modContainer = = null ? null : modContainer . getName ( ) ;
2017-06-23 05:33:11 +00:00
FMLLog . log . error ( " Trying to activate the universal filled bucket too late. Call it statically in your Mods class. Mod: {} " , modContainerName ) ;
2016-01-02 13:38:18 +00:00
}
else
{
universalBucketEnabled = true ;
}
}
public static boolean isUniversalBucketEnabled ( )
{
return universalBucketEnabled ;
}
/ * *
* Registers a fluid with the universal bucket .
* This only has an effect if the universal bucket is enabled .
* @param fluid The fluid that the bucket shall be able to hold
* @return True if the fluid was added successfully , false if it already was registered or couldn ' t be registered with the bucket .
* /
public static boolean addBucketForFluid ( Fluid fluid )
{
if ( fluid = = null ) {
return false ;
}
// register unregistered fluids
if ( ! isFluidRegistered ( fluid ) )
{
registerFluid ( fluid ) ;
}
return bucketFluids . add ( fluid ) ;
}
/ * *
* All fluids registered with the universal bucket
* @return An immutable set containing the fluids
* /
public static Set < Fluid > getBucketFluids ( )
{
return ImmutableSet . copyOf ( bucketFluids ) ;
}
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
{
2016-03-24 08:44:52 +00:00
private final String fluidName ;
private final int fluidID ;
2013-05-23 05:01:19 +00:00
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 ;
}
2016-03-24 08:44:52 +00:00
public String getFluidName ( )
{
return fluidName ;
}
public int getFluidID ( )
{
return fluidID ;
}
2013-05-23 05:01:19 +00:00
}
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 ) ) {
2017-06-23 05:33:11 +00:00
FMLLog . log . error ( " The fluid registry is corrupted. A fluid {} {} is not properly registered. The mod that registered this is broken " , key . getClass ( ) . getName ( ) , key . getName ( ) ) ;
2015-04-19 01:37:45 +00:00
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 ) )
{
2017-06-23 05:33:11 +00:00
FMLLog . log . debug ( " Loading persistent fluid defaults from world " ) ;
2015-04-11 21:18:53 +00:00
NBTTagList tl = tag . getTagList ( " DefaultFluidList " , 8 ) ;
for ( int i = 0 ; i < tl . tagCount ( ) ; i + + )
{
defaults . add ( tl . getStringTagAt ( i ) ) ;
}
}
else
{
2017-06-23 05:33:11 +00:00
FMLLog . log . debug ( " World is missing persistent fluid defaults - using local defaults " ) ;
2015-04-11 21:18:53 +00:00
}
2015-06-03 23:26:53 +00:00
loadFluidDefaults ( HashBiMap . create ( fluidIDs ) , defaults ) ;
2015-04-11 21:18:53 +00:00
}
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 ( ) )
{
2017-06-23 05:33:11 +00:00
FMLLog . log . fatal ( " The fluid registry is corrupted. Something has inserted a fluid without registering it " ) ;
FMLLog . log . fatal ( " There is {} unregistered fluids " , illegalFluids . size ( ) ) ;
2015-04-19 01:37:45 +00:00
for ( Fluid f : illegalFluids )
{
2017-06-23 05:33:11 +00:00
FMLLog . log . fatal ( " Fluid name : {}, type: {} " , f . getName ( ) , f . getClass ( ) . getName ( ) ) ;
2015-04-19 01:37:45 +00:00
}
2017-06-23 05:33:11 +00:00
FMLLog . log . fatal ( " The mods that own these fluids need to register them properly " ) ;
2015-04-19 01:37:45 +00:00
throw new IllegalStateException ( " The fluid map contains fluids unknown to the master fluid registry " ) ;
}
}
2015-04-20 13:06:23 +00:00
2017-06-19 22:02:18 +00:00
static IRegistryDelegate < Fluid > makeDelegate ( Fluid fl )
2015-04-20 13:06:23 +00:00
{
return delegates . get ( fl ) ;
}
2017-06-19 22:02:18 +00:00
private static class FluidDelegate implements IRegistryDelegate < Fluid >
2015-04-20 13:06:23 +00:00
{
private String name ;
private Fluid fluid ;
FluidDelegate ( Fluid fluid , String name )
{
this . fluid = fluid ;
this . name = name ;
}
@Override
public Fluid get ( )
{
return fluid ;
}
@Override
2016-04-01 21:13:06 +00:00
public ResourceLocation name ( ) {
2015-11-28 08:01:31 +00:00
return new ResourceLocation ( name ) ;
}
2015-04-20 13:06:23 +00:00
@Override
public Class < Fluid > type ( )
{
return Fluid . class ;
}
void rebind ( )
{
fluid = fluids . get ( name ) ;
}
}
2016-03-07 00:54:47 +00:00
}