mirror of
https://github.com/FatherToast/SpecialMobs.git
synced 2025-05-29 15:26:38 +00:00
okie I will use these tomorrow
This commit is contained in:
parent
c16dd2c61e
commit
ab7002c22c
71 changed files with 2256 additions and 107 deletions
|
@ -13,6 +13,7 @@ import net.minecraft.potion.Effects;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -280,13 +281,13 @@ public class BestiaryInfo {
|
|||
public Builder vanillaTextureBaseOnly( String tex ) { return vanillaBaseTexture( tex ).noEyesTexture().noOverlayTexture(); }
|
||||
|
||||
/** Sets the species default base texture. */
|
||||
private Builder vanillaBaseTexture( String tex ) { return baseTexture( tex == null ? null : new ResourceLocation( tex ) ); }
|
||||
private Builder vanillaBaseTexture( String tex ) { return baseTexture( new ResourceLocation( tex ) ); }
|
||||
|
||||
/** Sets the species default glowing eyes texture. */
|
||||
private Builder vanillaEyesTexture( String eyeTex ) { return eyesTexture( eyeTex == null ? null : new ResourceLocation( eyeTex ) ); }
|
||||
private Builder vanillaEyesTexture( String eyeTex ) { return eyesTexture( new ResourceLocation( eyeTex ) ); }
|
||||
|
||||
/** Sets the species default overlay texture. */
|
||||
private Builder vanillaOverlayTexture( String ovrTex ) { return overlayTexture( ovrTex == null ? null : new ResourceLocation( ovrTex ) ); }
|
||||
private Builder vanillaOverlayTexture( String ovrTex ) { return overlayTexture( new ResourceLocation( ovrTex ) ); }
|
||||
|
||||
|
||||
//--------------- Textures (Auto-selected) ----------------
|
||||
|
@ -351,19 +352,19 @@ public class BestiaryInfo {
|
|||
public Builder noAnimationTexture() { return noOverlayTexture(); }
|
||||
|
||||
/** Sets the species default base texture. */
|
||||
private Builder baseTexture( ResourceLocation tex ) {
|
||||
private Builder baseTexture( @Nullable ResourceLocation tex ) {
|
||||
texture = tex;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the species default glowing eyes texture. */
|
||||
private Builder eyesTexture( ResourceLocation eyeTex ) {
|
||||
private Builder eyesTexture( @Nullable ResourceLocation eyeTex ) {
|
||||
eyesTexture = eyeTex;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the species default overlay texture. */
|
||||
private Builder overlayTexture( ResourceLocation ovrTex ) {
|
||||
private Builder overlayTexture( @Nullable ResourceLocation ovrTex ) {
|
||||
overlayTexture = ovrTex;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import fathertoast.specialmobs.common.core.register.SMEntities;
|
|||
import fathertoast.specialmobs.common.core.register.SMItems;
|
||||
import fathertoast.specialmobs.common.util.AnnotationHelper;
|
||||
import fathertoast.specialmobs.common.util.References;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
@ -18,7 +17,6 @@ import net.minecraftforge.common.ForgeSpawnEggItem;
|
|||
import net.minecraftforge.fml.RegistryObject;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -28,8 +26,6 @@ import java.util.function.Function;
|
|||
*
|
||||
* @see MobFamily.Species
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
public class MobFamily<T extends LivingEntity, V extends FamilyConfig> {
|
||||
/** List of all families, generated to make iteration possible. */
|
||||
private static final ArrayList<MobFamily<?, ?>> FAMILY_LIST = new ArrayList<>();
|
||||
|
@ -238,8 +234,6 @@ public class MobFamily<T extends LivingEntity, V extends FamilyConfig> {
|
|||
*
|
||||
* @see MobFamily
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
public static class Species<T extends LivingEntity> {
|
||||
/** The special mob family this species belongs to. */
|
||||
public final MobFamily<? super T, ?> family;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.bestiary;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.family;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -25,7 +25,7 @@ public abstract class AbstractConfigField {
|
|||
* Creates a new field with the supplied key and description.
|
||||
* If the description is null, it will cancel the entire comment, including the automatic field info text.
|
||||
*/
|
||||
protected AbstractConfigField( String key, String... description ) {
|
||||
protected AbstractConfigField( String key, @Nullable String... description ) {
|
||||
this( loadingCategory + key, description == null ? null : TomlHelper.newComment( description ) );
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public abstract class AbstractConfigField {
|
|||
* Creates a new field with the supplied key and comment. This method is only used for very special circumstances.
|
||||
* If the comment is null, it will cancel the entire comment, including the automatic field info text.
|
||||
*/
|
||||
AbstractConfigField( String key, List<String> comment ) {
|
||||
AbstractConfigField( String key, @Nullable List<String> comment ) {
|
||||
KEY = key;
|
||||
COMMENT = comment;
|
||||
}
|
||||
|
|
|
@ -42,16 +42,10 @@ public class AttributeListField extends GenericField<AttributeList> {
|
|||
public ConfigDrivenAttributeModifierMap linkedAttributeMap;
|
||||
|
||||
/** Creates a new field. */
|
||||
public AttributeListField( String key, AttributeList defaultValue, String... description ) {
|
||||
public AttributeListField( String key, AttributeList defaultValue, @Nullable String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
}
|
||||
|
||||
/** Applies all attribute changes in this list to the entity attribute builder. */
|
||||
public void apply( AttributeModifierMap.MutableAttribute builder ) { get().apply( builder ); }
|
||||
|
||||
/** Applies all attribute changes in this list to the entity. */
|
||||
public void apply( LivingEntity entity ) { get().apply( entity ); }
|
||||
|
||||
/** Adds info about the field type, format, and bounds to the end of a field's description. */
|
||||
public void appendFieldInfo( List<String> comment ) {
|
||||
comment.add( TomlHelper.fieldInfoFormat( "Attribute List", valueDefault,
|
||||
|
@ -81,7 +75,7 @@ public class AttributeListField extends GenericField<AttributeList> {
|
|||
if( linkedAttributeMap != null ) linkedAttributeMap.invalidate();
|
||||
}
|
||||
|
||||
/** Parses a single entry line and returns a valid result if possible, or null if the entry is completely invalid. */
|
||||
/** Parses a single entry line and returns a valid result. */
|
||||
private AttributeEntry parseEntry( final String line ) {
|
||||
// Parse the attribute-operation-value array
|
||||
final String[] args = line.split( " ", 4 );
|
||||
|
@ -148,4 +142,13 @@ public class AttributeListField extends GenericField<AttributeList> {
|
|||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Convenience methods
|
||||
|
||||
/** Applies all attribute changes in this list to the entity attribute builder. */
|
||||
public void apply( AttributeModifierMap.MutableAttribute builder ) { get().apply( builder ); }
|
||||
|
||||
/** Applies all attribute changes in this list to the entity. */
|
||||
public void apply( LivingEntity entity ) { get().apply( entity ); }
|
||||
}
|
|
@ -28,7 +28,7 @@ public class BlockListField extends GenericField<BlockList> {
|
|||
}
|
||||
|
||||
/** Creates a new field. */
|
||||
public BlockListField( String key, BlockList defaultValue, String... description ) {
|
||||
public BlockListField( String key, BlockList defaultValue, @Nullable String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,15 @@ public class BlockListField extends GenericField<BlockList> {
|
|||
value = new BlockList( this, TomlHelper.parseStringList( raw ) );
|
||||
}
|
||||
|
||||
|
||||
// Convenience methods
|
||||
|
||||
/** @return Returns true if there are no entries in this block list. */
|
||||
public boolean isEmpty() { return get().isEmpty(); }
|
||||
|
||||
/** @return Returns true if the block is contained in this list. */
|
||||
public boolean matches( BlockState blockState ) { return get().matches( blockState ); }
|
||||
|
||||
/**
|
||||
* Represents two block list fields, a blacklist and a whitelist, combined into one.
|
||||
*/
|
||||
|
@ -73,7 +82,7 @@ public class BlockListField extends GenericField<BlockList> {
|
|||
|
||||
/** @return Returns true if the block is contained in this list. */
|
||||
public boolean matches( BlockState blockState ) {
|
||||
return blockState != null && !BLACKLIST.get().matches( blockState ) && WHITELIST.get().matches( blockState );
|
||||
return !BLACKLIST.get().matches( blockState ) && WHITELIST.get().matches( blockState );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ public class BooleanField extends AbstractConfigField {
|
|||
private boolean value;
|
||||
|
||||
/** Creates a new field. */
|
||||
public BooleanField( String key, boolean defaultValue, String... description ) {
|
||||
public BooleanField( String key, boolean defaultValue, @Nullable String... description ) {
|
||||
super( key, description );
|
||||
valueDefault = defaultValue;
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ public class DoubleField extends AbstractConfigField {
|
|||
private double value;
|
||||
|
||||
/** Creates a new field that accepts a common range of values. */
|
||||
public DoubleField( String key, double defaultValue, Range range, String... description ) {
|
||||
public DoubleField( String key, double defaultValue, Range range, @Nullable String... description ) {
|
||||
this( key, defaultValue, range.MIN, range.MAX, description );
|
||||
}
|
||||
|
||||
/** Creates a new field that accepts a specialized range of values. */
|
||||
public DoubleField( String key, double defaultValue, double min, double max, String... description ) {
|
||||
public DoubleField( String key, double defaultValue, double min, double max, @Nullable String... description ) {
|
||||
super( key, description );
|
||||
valueDefault = defaultValue;
|
||||
valueMin = min;
|
||||
|
|
|
@ -33,7 +33,7 @@ public class EntityListField extends GenericField<EntityList> {
|
|||
}
|
||||
|
||||
/** Creates a new field. */
|
||||
public EntityListField( String key, EntityList defaultValue, String... description ) {
|
||||
public EntityListField( String key, EntityList defaultValue, @Nullable String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
}
|
||||
|
||||
|
@ -191,6 +191,36 @@ public class EntityListField extends GenericField<EntityList> {
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Convenience methods
|
||||
|
||||
/** @return True if the entity is contained in this list. */
|
||||
public boolean contains( @Nullable Entity entity ) { return get().contains( entity ); }
|
||||
|
||||
/**
|
||||
* @param entity The entity to retrieve values for.
|
||||
* @return The array of values of the best-match entry. Returns null if the entity is not contained in this entity list.
|
||||
*/
|
||||
@Nullable
|
||||
public double[] getValues( @Nullable Entity entity ) { return get().getValues( entity ); }
|
||||
|
||||
/**
|
||||
* @param entity The entity to retrieve a value for.
|
||||
* @return The first value in the best-match entry's value array. Returns 0 if the entity is not contained in this
|
||||
* entity list or has no values specified. This should only be used for 'single value' lists.
|
||||
* @see EntityList#setSingleValue()
|
||||
* @see EntityList#setSinglePercent()
|
||||
*/
|
||||
public double getValue( @Nullable Entity entity ) { return get().getValue( entity ); }
|
||||
|
||||
/**
|
||||
* @param entity The entity to roll a value for.
|
||||
* @return Randomly rolls the first percentage value in the best-match entry's value array. Returns false if the entity
|
||||
* is not contained in this entity list or has no values specified. This should only be used for 'single percent' lists.
|
||||
* @see EntityList#setSinglePercent()
|
||||
*/
|
||||
public boolean rollChance( @Nullable LivingEntity entity ) { return get().rollChance( entity ); }
|
||||
|
||||
/**
|
||||
* Represents two entity list fields, a blacklist and a whitelist, combined into one.
|
||||
* The blacklist cannot contain values, but the whitelist can have any settings.
|
||||
|
@ -210,17 +240,21 @@ public class EntityListField extends GenericField<EntityList> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Convenience methods
|
||||
|
||||
/** @return True if the entity is contained in this list. */
|
||||
public boolean contains( Entity entity ) {
|
||||
return entity != null && !BLACKLIST.get().contains( entity ) && WHITELIST.get().contains( entity );
|
||||
public boolean contains( @Nullable Entity entity ) {
|
||||
return entity != null && !BLACKLIST.contains( entity ) && WHITELIST.contains( entity );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entity The entity to retrieve values for.
|
||||
* @return The array of values of the best-match entry. Returns null if the entity is not contained in this entity list.
|
||||
*/
|
||||
public double[] getValues( Entity entity ) {
|
||||
return entity != null && !BLACKLIST.get().contains( entity ) ? WHITELIST.get().getValues( entity ) : null;
|
||||
@Nullable
|
||||
public double[] getValues( @Nullable Entity entity ) {
|
||||
return entity != null && !BLACKLIST.contains( entity ) ? WHITELIST.getValues( entity ) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,8 +264,8 @@ public class EntityListField extends GenericField<EntityList> {
|
|||
* @see EntityList#setSingleValue()
|
||||
* @see EntityList#setSinglePercent()
|
||||
*/
|
||||
public double getValue( Entity entity ) {
|
||||
return entity != null && !BLACKLIST.get().contains( entity ) ? WHITELIST.get().getValue( entity ) : 0.0;
|
||||
public double getValue( @Nullable Entity entity ) {
|
||||
return entity != null && !BLACKLIST.contains( entity ) ? WHITELIST.getValue( entity ) : 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,8 +274,8 @@ public class EntityListField extends GenericField<EntityList> {
|
|||
* is not contained in this entity list or has no values specified. This should only be used for 'single percent' lists.
|
||||
* @see EntityList#setSinglePercent()
|
||||
*/
|
||||
public boolean rollChance( LivingEntity entity ) {
|
||||
return entity != null && !BLACKLIST.get().contains( entity ) && WHITELIST.get().rollChance( entity );
|
||||
public boolean rollChance( @Nullable LivingEntity entity ) {
|
||||
return entity != null && !BLACKLIST.contains( entity ) && WHITELIST.rollChance( entity );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,13 +14,13 @@ public class EnumField<T extends Enum<T>> extends GenericField<T> {
|
|||
private final T[] valuesValid;
|
||||
|
||||
/** Creates a new field that accepts any enum value. */
|
||||
public EnumField( String key, T defaultValue, String... description ) {
|
||||
public EnumField( String key, T defaultValue, @Nullable String... description ) {
|
||||
//noinspection unchecked
|
||||
this( key, defaultValue, (T[]) defaultValue.getClass().getEnumConstants(), description );
|
||||
}
|
||||
|
||||
/** Creates a new field that accepts the specified set of enum values. */
|
||||
public EnumField( String key, T defaultValue, T[] validValues, String... description ) {
|
||||
public EnumField( String key, T defaultValue, T[] validValues, @Nullable String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
valuesValid = validValues;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public class EnumField<T extends Enum<T>> extends GenericField<T> {
|
|||
}
|
||||
|
||||
/** @return Attempts to parse the string literal as one of the valid values for this field and returns it, or null if invalid. */
|
||||
@Nullable
|
||||
private T parseValue( String name ) {
|
||||
for( T val : valuesValid ) {
|
||||
if( val.name().equalsIgnoreCase( name ) ) return val;
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
package fathertoast.specialmobs.common.config.field;
|
||||
|
||||
import fathertoast.specialmobs.common.config.file.TomlHelper;
|
||||
import fathertoast.specialmobs.common.config.util.EnvironmentEntry;
|
||||
import fathertoast.specialmobs.common.config.util.EnvironmentList;
|
||||
import fathertoast.specialmobs.common.config.util.environment.*;
|
||||
import fathertoast.specialmobs.common.config.util.environment.biome.*;
|
||||
import fathertoast.specialmobs.common.config.util.environment.dimension.DimensionPropertyEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.dimension.DimensionTypeEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.dimension.DimensionTypeGroupEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.StructureEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.StructureGroupEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.YEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.YFromSeaEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.time.*;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a config field with an environment list value.
|
||||
*/
|
||||
public class EnvironmentListField extends GenericField<EnvironmentList> {
|
||||
|
||||
/* When adding new environment conditions, you must:
|
||||
* - Add a new constant for its name here
|
||||
* - Create the environment class and ensure #name() returns the new name constant
|
||||
* - Link the name to construction in #parseCondition(String,String) below
|
||||
* - Add any applicable builder methods in EnvironmentEntry.Builder
|
||||
* - Describe the new environment condition's usage/format in #environmentDescriptions() below
|
||||
*/
|
||||
// Dimension-based
|
||||
public static final String ENV_DIMENSION_PROPERTY = "dimension_property";
|
||||
public static final String ENV_DIMENSION_TYPE = "dimension_type";
|
||||
// Biome-based
|
||||
public static final String ENV_RAINFALL = "rainfall";
|
||||
public static final String ENV_BIOME_TEMPERATURE = "biome_temp";
|
||||
public static final String ENV_TEMPERATURE = "temp";
|
||||
public static final String ENV_BIOME_CATEGORY = "biome_category";
|
||||
public static final String ENV_BIOME = "biome";
|
||||
// Position-based TODO can_see_sky
|
||||
public static final String ENV_STRUCTURE = "structure";
|
||||
public static final String ENV_Y = "y";
|
||||
public static final String ENV_Y_FROM_SEA = "y_from_sea";
|
||||
// Time-based
|
||||
public static final String ENV_DIFFICULTY = "difficulty";
|
||||
public static final String ENV_SPECIAL_DIFFICULTY = "special_difficulty";
|
||||
public static final String ENV_WEATHER = "weather";
|
||||
public static final String ENV_MOON_BRIGHTNESS = "moon_brightness";
|
||||
public static final String ENV_MOON_PHASE = "moon_phase";
|
||||
public static final String ENV_DAY_TIME = "day_time";
|
||||
public static final String ENV_TIME_FROM_MIDNIGHT = "time_from_midnight";
|
||||
public static final String ENV_WORLD_TIME = "world_time";
|
||||
|
||||
/**
|
||||
* Provides a description of how to use environment lists. Recommended to put at the top of any file using environment lists.
|
||||
* Always use put the environment condition descriptions at the bottom of the file if this is used!
|
||||
*/
|
||||
public static List<String> verboseDescription() {
|
||||
List<String> comment = new ArrayList<>();
|
||||
comment.add( "Environment List fields: General format = [ \"value environment1 condition1 & environment2 condition2 & ...\", ... ]" );
|
||||
comment.add( " Environment lists are arrays of environment entries. Each entry is a value followed by the environment conditions that must be" );
|
||||
comment.add( " satisfied for the value to be chosen. The environments are tested in the order listed, and the first matching entry is chosen." );
|
||||
comment.add( " See the bottom of this file for an explanation on each environment condition available." );
|
||||
return comment;
|
||||
}
|
||||
|
||||
/** Provides a detailed description of how to use each environment condition. Recommended to put at the bottom of any file using environment lists. */
|
||||
public static List<String> environmentDescriptions() {
|
||||
List<String> comment = new ArrayList<>();
|
||||
comment.add( "Environment conditions (for Environment List entries):" );
|
||||
comment.add( " Many environment conditions can be inverted by using \"!\"; these are shown with (!) in the appropriate location." );
|
||||
comment.add( " Other environment conditions are numerical comparisons; these use the operators (shown as op) <, >, =, <=, >=, or != to compare value." );
|
||||
comment.add( "Valid environment conditions are:" );
|
||||
// Dimension-based
|
||||
comment.add( " \"" + ENV_DIMENSION_PROPERTY + " (!)property\":" );
|
||||
comment.add( " Valid property values: " + TomlHelper.literalList( (Object[]) DimensionPropertyEnvironment.Value.values() ) );
|
||||
comment.add( " Dimension properties are the true/false values available to dimension types in data packs." );
|
||||
comment.add( " See the wiki for more info: [https://minecraft.fandom.com/wiki/Custom_dimension#Syntax]." );
|
||||
comment.add( " \"" + ENV_DIMENSION_TYPE + " (!)namespace:dimension_type_name\":" );
|
||||
comment.add( " The world's dimension type. In vanilla, these are only \"minecraft:overworld\", \"minecraft:the_nether\", or \"minecraft:the_end\"." );
|
||||
// Biome-based
|
||||
comment.add( " \"" + ENV_RAINFALL + " op value\":" );
|
||||
comment.add( " Biome's rainfall parameter. If this is \"= 0\", it checks that rain is disabled. For reference, rainfall > 0.85 suppresses fire." );
|
||||
comment.add( " \"" + ENV_BIOME_TEMPERATURE + " op value\" or \"" + ENV_BIOME_TEMPERATURE + " (!)" + TemperatureEnvironment.FREEZING + "\":" );
|
||||
comment.add( " Biome's temperature parameter. For reference, freezing is < 0.15 and hot is generally considered > 0.95." );
|
||||
comment.add( " \"" + ENV_TEMPERATURE + " op value\" or \"" + ENV_TEMPERATURE + " (!)" + TemperatureEnvironment.FREEZING + "\":" );
|
||||
comment.add( " Height-adjusted temperature. For reference, freezing is < 0.15 and hot is generally considered > 0.95." );
|
||||
comment.add( " \"" + ENV_BIOME_CATEGORY + " (!)category\":" );
|
||||
comment.add( " Valid category values: " + TomlHelper.literalList( (Object[]) BiomeCategoryEnvironment.Value.values() ) );
|
||||
comment.add( " \"" + ENV_BIOME + " (!)namespace:biome_name\":" );
|
||||
comment.add( " The biome. See the wiki for vanilla biome names (resource locations) [https://minecraft.fandom.com/wiki/Biome#Biome_IDs]." );
|
||||
// Position-based
|
||||
comment.add( " \"" + ENV_STRUCTURE + " (!)namespace:structure_name\":" );
|
||||
comment.add( " The structure. See the wiki for vanilla structure names [https://minecraft.fandom.com/wiki/Generated_structures#Locating]." );
|
||||
comment.add( " \"" + ENV_Y + " op value\":" );
|
||||
comment.add( " The y-value. For reference, sea level is normally 63 and lava level is normally 10." );//TODO change lava level to -54 for MC 1.18
|
||||
comment.add( " \"" + ENV_Y_FROM_SEA + " op value\":" );
|
||||
comment.add( " The y-value from sea level. Expect the only air <= 0 to be in caves (which may still have direct view of the sky)." );
|
||||
// Time-based
|
||||
comment.add( " \"" + ENV_DIFFICULTY + " op value\":" );
|
||||
comment.add( " The regional difficulty (0 to 6.75). This is based on many factors such as difficulty setting, moon brightness, chunk inhabited time, and world time." );
|
||||
comment.add( " For reference, this scales up to the max after 63 days in the world and 150 days in a particular chunk, and peaks during full moons." );
|
||||
comment.add( " On Peaceful this is always 0, on Easy this is 0.75 to 1.5, on Normal this is 1.5 to 4.0, and on Hard this is 2.25 to 6.75." );
|
||||
comment.add( " \"" + ENV_SPECIAL_DIFFICULTY + " op value\":" );
|
||||
comment.add( " The 'special multiplier' for regional difficulty (0 to 1). For reference, this is 0 when difficulty <= 2 and 1 when difficulty >= 4." );
|
||||
comment.add( " This is always 0 in Easy and below. In Normal, it maxes at absolute peak regional difficulty. In Hard, it starts at 0.125 and maxes out in ~50 days." );
|
||||
comment.add( " \"" + ENV_WEATHER + " (!)type\":" );
|
||||
comment.add( " Valid type values: " + TomlHelper.literalList( (Object[]) WeatherEnvironment.Value.values() ) );
|
||||
comment.add( " \"" + ENV_MOON_BRIGHTNESS + " op value\":" );
|
||||
comment.add( " The moon brightness (0 to 1). New moon has 0 brightness, full moon has 1 brightness. Intermediate phases are 0.25, 0.5, or 0.75." );
|
||||
comment.add( " \"" + ENV_MOON_PHASE + " (!)phase\":" );
|
||||
comment.add( " Valid phase values: " + TomlHelper.literalList( (Object[]) MoonPhaseEnvironment.Value.values() ) );
|
||||
comment.add( " \"" + ENV_DAY_TIME + " (!)time\":" );
|
||||
comment.add( " Valid time values: " + TomlHelper.literalList( (Object[]) DayTimeEnvironment.Value.values() ) );
|
||||
comment.add( " Note that the transition periods, sunset & sunrise, are considered as part of day & night, respectively." );
|
||||
comment.add( " \"" + ENV_TIME_FROM_MIDNIGHT + " op value\":" );
|
||||
comment.add( " The absolute time in ticks away from midnight. Value must be 0 to 12000." );
|
||||
comment.add( " \"" + ENV_MOON_PHASE + " (!)phase\":" );
|
||||
comment.add( " Valid phase values: " + TomlHelper.literalList( (Object[]) MoonPhaseEnvironment.Value.values() ) );
|
||||
comment.add( " \"" + ENV_WORLD_TIME + " op value\":" );
|
||||
comment.add( " The total time the world has existed, in ticks. For reference, each day cycle is 24000 ticks and each lunar cycle is 192000 ticks." );
|
||||
return comment;
|
||||
}
|
||||
|
||||
/** Creates a new field. */
|
||||
public EnvironmentListField( String key, EnvironmentList defaultValue, String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
}
|
||||
|
||||
/** Adds info about the field type, format, and bounds to the end of a field's description. */
|
||||
public void appendFieldInfo( List<String> comment ) {
|
||||
comment.add( TomlHelper.fieldInfoFormat( "Environment List", valueDefault, "[ \"value condition1 state1 & condition2 state2 & ...\", ... ]" ) );
|
||||
comment.add( " Range for Values: " + TomlHelper.fieldRange( valueDefault.getMinValue(), valueDefault.getMaxValue() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads this field's value from the given raw toml value. If anything goes wrong, correct it at the lowest level possible.
|
||||
* <p>
|
||||
* For example, a missing value should be set to the default, while an out-of-range value should be adjusted to the
|
||||
* nearest in-range value
|
||||
*/
|
||||
@Override
|
||||
public void load( @Nullable Object raw ) {
|
||||
if( raw == null ) {
|
||||
value = valueDefault;
|
||||
return;
|
||||
}
|
||||
List<String> list = TomlHelper.parseStringList( raw );
|
||||
List<EnvironmentEntry> entryList = new ArrayList<>();
|
||||
for( String line : list ) {
|
||||
entryList.add( parseEntry( line ) );
|
||||
}
|
||||
value = new EnvironmentList( entryList );
|
||||
}
|
||||
|
||||
/** Parses a single entry line and returns the result. */
|
||||
private EnvironmentEntry parseEntry( final String line ) {
|
||||
// Parse the value out of the conditions
|
||||
final String[] args = line.split( " ", 2 );
|
||||
final double value = parseValue( args[0], line );
|
||||
|
||||
final List<AbstractEnvironment> conditions = new ArrayList<>();
|
||||
if( args.length > 1 ) {
|
||||
final String[] condArgs = args[1].trim().split( "&" );
|
||||
for( String condArg : condArgs ) {
|
||||
conditions.add( parseCondition( condArg.trim(), line ) );
|
||||
}
|
||||
}
|
||||
if( conditions.isEmpty() ) {
|
||||
SpecialMobs.LOG.warn( "No environments defined in entry for {} \"{}\"! Invalid entry: {}",
|
||||
getClass(), getKey(), line );
|
||||
}
|
||||
|
||||
return new EnvironmentEntry( value, conditions );
|
||||
}
|
||||
|
||||
/** Parses a single value argument and returns a valid result. */
|
||||
private double parseValue( final String arg, final String line ) {
|
||||
// Try to parse the value
|
||||
double value;
|
||||
try {
|
||||
value = Double.parseDouble( arg );
|
||||
}
|
||||
catch( NumberFormatException ex ) {
|
||||
// This is thrown if the string is not a parsable number
|
||||
SpecialMobs.LOG.warn( "Invalid value for {} \"{}\"! Falling back to 0. Invalid entry: {}",
|
||||
getClass(), getKey(), line );
|
||||
value = 0.0;
|
||||
}
|
||||
// Verify value is within range
|
||||
if( value < valueDefault.getMinValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is below the minimum ({})! Clamping value. Invalid value: {}",
|
||||
getClass(), getKey(), valueDefault.getMinValue(), value );
|
||||
value = valueDefault.getMinValue();
|
||||
}
|
||||
else if( value > valueDefault.getMaxValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is above the maximum ({})! Clamping value. Invalid value: {}",
|
||||
getClass(), getKey(), valueDefault.getMaxValue(), value );
|
||||
value = valueDefault.getMaxValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Parses a single environment condition argument and returns a valid result. */
|
||||
private AbstractEnvironment parseCondition( final String arg, final String line ) {
|
||||
// First parse the environment name, since it defines the format for the rest
|
||||
final String[] args = arg.split( " ", 2 );
|
||||
|
||||
final String value;
|
||||
if( args.length < 2 ) value = "";
|
||||
else value = args[1].trim();
|
||||
|
||||
switch( args[0] ) {
|
||||
// Dimension-based
|
||||
case ENV_DIMENSION_PROPERTY:
|
||||
return new DimensionPropertyEnvironment( this, value );
|
||||
case ENV_DIMENSION_TYPE:
|
||||
return value.endsWith( "*" ) ? new DimensionTypeGroupEnvironment( this, value ) : new DimensionTypeEnvironment( this, value );
|
||||
// Biome-based
|
||||
case ENV_RAINFALL:
|
||||
return new RainfallEnvironment( this, value );
|
||||
case ENV_BIOME_TEMPERATURE:
|
||||
return new BiomeTemperatureEnvironment( this, value );
|
||||
case ENV_TEMPERATURE:
|
||||
return new TemperatureEnvironment( this, value );
|
||||
case ENV_BIOME_CATEGORY:
|
||||
return new BiomeCategoryEnvironment( this, value );
|
||||
case ENV_BIOME:
|
||||
return value.endsWith( "*" ) ? new BiomeGroupEnvironment( this, value ) : new BiomeEnvironment( this, value );
|
||||
// Position-based
|
||||
case ENV_STRUCTURE:
|
||||
return value.endsWith( "*" ) ? new StructureGroupEnvironment( this, value ) : new StructureEnvironment( this, value );
|
||||
case ENV_Y:
|
||||
return new YEnvironment( this, value );
|
||||
case ENV_Y_FROM_SEA:
|
||||
return new YFromSeaEnvironment( this, value );
|
||||
// Time-based
|
||||
case ENV_DIFFICULTY:
|
||||
return new DifficultyEnvironment( this, value );
|
||||
case ENV_SPECIAL_DIFFICULTY:
|
||||
return new SpecialDifficultyEnvironment( this, value );
|
||||
case ENV_WEATHER:
|
||||
return new WeatherEnvironment( this, value );
|
||||
case ENV_MOON_BRIGHTNESS:
|
||||
return new MoonBrightnessEnvironment( this, value );
|
||||
case ENV_MOON_PHASE:
|
||||
return new MoonPhaseEnvironment( this, value );
|
||||
case ENV_DAY_TIME:
|
||||
return new DayTimeEnvironment( this, value );
|
||||
case ENV_TIME_FROM_MIDNIGHT:
|
||||
return new TimeFromMidnightEnvironment( this, value );
|
||||
case ENV_WORLD_TIME:
|
||||
return new WorldTimeEnvironment( this, value );
|
||||
}
|
||||
|
||||
// The environment name was not recognized; try to provide some good feedback because this field is complicated
|
||||
final String[] environmentNames = {
|
||||
// Dimension-based
|
||||
ENV_DIMENSION_PROPERTY, ENV_DIMENSION_TYPE,
|
||||
// Biome-based
|
||||
ENV_RAINFALL, ENV_BIOME_TEMPERATURE, ENV_TEMPERATURE, ENV_BIOME_CATEGORY, ENV_BIOME,
|
||||
// Position-based
|
||||
ENV_STRUCTURE, ENV_Y, ENV_Y_FROM_SEA,
|
||||
// Time-based
|
||||
ENV_DIFFICULTY, ENV_SPECIAL_DIFFICULTY, ENV_WEATHER, ENV_MOON_BRIGHTNESS, ENV_MOON_PHASE, ENV_DAY_TIME,
|
||||
ENV_TIME_FROM_MIDNIGHT, ENV_WORLD_TIME
|
||||
};
|
||||
final AbstractEnvironment fallback = new YEnvironment( ComparisonOperator.LESS_THAN, 0 );
|
||||
SpecialMobs.LOG.warn( "Invalid environment '{}' for {} \"{}\"! Falling back to \"{}\". Environment name must be in the set [ {} ]. Invalid environment: {}",
|
||||
args[0], getClass(), getKey(), fallback, TomlHelper.literalList( (Object[]) environmentNames ), line );
|
||||
return fallback;
|
||||
}
|
||||
|
||||
|
||||
// Convenience methods
|
||||
|
||||
/** @return The value matching the given environment, or the default value if no matching environment is defined. */
|
||||
public double getOrElse( World world, @Nullable BlockPos pos, DoubleField defaultValue ) { return get().getOrElse( world, pos, defaultValue ); }
|
||||
|
||||
/** @return The value matching the given environment, or the default value if no matching environment is defined. */
|
||||
public double getOrElse( World world, @Nullable BlockPos pos, double defaultValue ) { return get().getOrElse( world, pos, defaultValue ); }
|
||||
|
||||
/** @return The value matching the given environment, or null if no matching environment is defined. */
|
||||
@Nullable
|
||||
public Double get( World world, @Nullable BlockPos pos ) { return get().get( world, pos ); }
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package fathertoast.specialmobs.common.config.field;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a config field with an object value.
|
||||
* <p>
|
||||
|
@ -16,7 +18,7 @@ public abstract class GenericField<T> extends AbstractConfigField {
|
|||
protected T value;
|
||||
|
||||
/** Creates a new field. */
|
||||
public GenericField( String key, T defaultValue, String... description ) {
|
||||
public GenericField( String key, T defaultValue, @Nullable String... description ) {
|
||||
super( key, description );
|
||||
valueDefault = defaultValue;
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ public class IntField extends AbstractConfigField {
|
|||
private int value;
|
||||
|
||||
/** Creates a new field that accepts a common range of values. */
|
||||
public IntField( String key, int defaultValue, Range range, String... description ) {
|
||||
public IntField( String key, int defaultValue, Range range, @Nullable String... description ) {
|
||||
this( key, defaultValue, range.MIN, range.MAX, description );
|
||||
}
|
||||
|
||||
/** Creates a new field that accepts a specialized range of values. */
|
||||
public IntField( String key, int defaultValue, int min, int max, String... description ) {
|
||||
public IntField( String key, int defaultValue, int min, int max, @Nullable String... description ) {
|
||||
super( key, description );
|
||||
valueDefault = defaultValue;
|
||||
valueMin = min;
|
||||
|
|
|
@ -17,7 +17,7 @@ import javax.annotation.Nullable;
|
|||
public class LazyRegistryEntryListField<T extends IForgeRegistryEntry<T>> extends RegistryEntryListField<T> {
|
||||
|
||||
/** Creates a new field. */
|
||||
public LazyRegistryEntryListField( String key, RegistryEntryList<T> defaultValue, String... description ) {
|
||||
public LazyRegistryEntryListField( String key, RegistryEntryList<T> defaultValue, @Nullable String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public class RegistryEntryListField<T extends IForgeRegistryEntry<T>> extends Ge
|
|||
}
|
||||
|
||||
/** Creates a new field. */
|
||||
public RegistryEntryListField( String key, RegistryEntryList<T> defaultValue, String... description ) {
|
||||
public RegistryEntryListField( String key, RegistryEntryList<T> defaultValue, @Nullable String... description ) {
|
||||
super( key, defaultValue, description );
|
||||
}
|
||||
|
||||
|
@ -57,15 +57,18 @@ public class RegistryEntryListField<T extends IForgeRegistryEntry<T>> extends Ge
|
|||
value = new RegistryEntryList<>( this, valueDefault.getRegistry(), TomlHelper.parseStringList( raw ) );
|
||||
}
|
||||
|
||||
|
||||
// Convenience methods
|
||||
|
||||
/** @return The registry this list draws from. */
|
||||
public IForgeRegistry<T> getRegistry() { return value.getRegistry(); }
|
||||
public IForgeRegistry<T> getRegistry() { return get().getRegistry(); }
|
||||
|
||||
/** @return The entries in this list. */
|
||||
public Set<T> getEntries() { return value.getEntries(); }
|
||||
public Set<T> getEntries() { return get().getEntries(); }
|
||||
|
||||
/** @return Returns true if there are no entries in this list. */
|
||||
public boolean isEmpty() { return value.isEmpty(); }
|
||||
public boolean isEmpty() { return get().isEmpty(); }
|
||||
|
||||
/** @return Returns true if the entry is contained in this list. */
|
||||
public boolean contains( T entry ) { return value.contains( entry ); }
|
||||
public boolean contains( @Nullable T entry ) { return get().contains( entry ); }
|
||||
}
|
|
@ -14,13 +14,13 @@ public class ScaledDoubleField extends DoubleField {
|
|||
private double valueScaled;
|
||||
|
||||
/** Creates a new field that accepts a common range of values. */
|
||||
public ScaledDoubleField( String key, double defaultValue, double scale, Range range, String... description ) {
|
||||
public ScaledDoubleField( String key, double defaultValue, double scale, Range range, @Nullable String... description ) {
|
||||
super( key, defaultValue, range, description );
|
||||
SCALE = scale;
|
||||
}
|
||||
|
||||
/** Creates a new field that accepts a specialized range of values. */
|
||||
public ScaledDoubleField( String key, double defaultValue, double scale, double min, double max, String... description ) {
|
||||
public ScaledDoubleField( String key, double defaultValue, double scale, double min, double max, @Nullable String... description ) {
|
||||
super( key, defaultValue, min, max, description );
|
||||
SCALE = scale;
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ public class SqrDoubleField extends DoubleField {
|
|||
private double valueSqr;
|
||||
|
||||
/** Creates a new field that accepts a common range of values. */
|
||||
public SqrDoubleField( String key, double defaultValue, Range range, String... description ) {
|
||||
public SqrDoubleField( String key, double defaultValue, Range range, @Nullable String... description ) {
|
||||
super( key, defaultValue, range, description );
|
||||
}
|
||||
|
||||
/** Creates a new field that accepts a specialized range of values. */
|
||||
public SqrDoubleField( String key, double defaultValue, double min, double max, String... description ) {
|
||||
public SqrDoubleField( String key, double defaultValue, double min, double max, @Nullable String... description ) {
|
||||
super( key, defaultValue, min, max, description );
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.field;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -6,10 +6,12 @@ import fathertoast.specialmobs.common.config.field.DoubleField;
|
|||
import fathertoast.specialmobs.common.config.field.IntField;
|
||||
import fathertoast.specialmobs.common.config.util.ConfigUtil;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
public final class TomlHelper {
|
||||
private TomlHelper() { } // This is a static access only class that cannot be instantiated
|
||||
|
||||
|
@ -32,7 +34,7 @@ public final class TomlHelper {
|
|||
}
|
||||
|
||||
/** Attempts to convert a string value to a raw non-string toml literal. May or may not be accurate. */
|
||||
public static Object parseRaw( String value ) {
|
||||
public static Object parseRaw( @Nullable String value ) {
|
||||
// Note: It is very important here that the returned value is NOT a string
|
||||
|
||||
if( value != null && !"".equals( value ) ) {
|
||||
|
@ -56,9 +58,9 @@ public final class TomlHelper {
|
|||
}
|
||||
|
||||
/** Attempts to convert an object to a toml literal. May or may not be accurate. */
|
||||
public static String toLiteral( Object value ) {
|
||||
public static String toLiteral( @Nullable Object value ) {
|
||||
if( value == null ) {
|
||||
return "null";
|
||||
return "";
|
||||
}
|
||||
else if( value instanceof Enum<?> ) {
|
||||
return "\"" + ((Enum<?>) value).name().toLowerCase() + "\"";
|
||||
|
@ -66,21 +68,22 @@ public final class TomlHelper {
|
|||
else if( value instanceof String ) {
|
||||
return "\"" + value + "\"";
|
||||
}
|
||||
else if( value instanceof Double && ((Double) value).isInfinite() ) {
|
||||
// Toml infinite literals do not match java; these may also be unsupported in the current version
|
||||
return (Double) value > 0.0 ? "Inf" : "-Inf";
|
||||
}
|
||||
// Infinite values not supported
|
||||
//else if( value instanceof Double && ((Double) value).isInfinite() ) {
|
||||
// // Toml infinite literals do not match java
|
||||
// return (Double) value > 0.0 ? "Inf" : "-Inf";
|
||||
//}
|
||||
else {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/** Attempts to convert an object array to a toml literal. May or may not be accurate. */
|
||||
public static String toLiteral( Object... values ) {
|
||||
public static String toLiteral( @Nullable Object... values ) {
|
||||
if( values == null ) {
|
||||
return "null";
|
||||
return "";
|
||||
}
|
||||
else if( values.length < 1 ) {
|
||||
if( values.length < 1 ) {
|
||||
return "[]";
|
||||
}
|
||||
else {
|
||||
|
@ -92,7 +95,7 @@ public final class TomlHelper {
|
|||
public static String literalList( Object... list ) { return literalList( Arrays.asList( list ) ); }
|
||||
|
||||
/** Attempts to convert an object list to a list of toml literals. May or may not be accurate. */
|
||||
public static String literalList( List<Object> list ) {
|
||||
public static String literalList( @Nullable List<Object> list ) {
|
||||
if( list == null || list.isEmpty() ) return "";
|
||||
StringBuilder literals = new StringBuilder();
|
||||
for( Object obj : list ) {
|
||||
|
@ -196,7 +199,7 @@ public final class TomlHelper {
|
|||
public static List<String> splitKey( String key ) { return StringUtils.split( key, '.' ); }
|
||||
|
||||
/** Combines a toml path into a key. */
|
||||
public static String mergePath( List<String> path ) {
|
||||
public static String mergePath( @Nullable List<String> path ) {
|
||||
if( path == null || path.isEmpty() ) return "";
|
||||
StringBuilder key = new StringBuilder();
|
||||
for( String subKey : path ) {
|
||||
|
@ -207,15 +210,13 @@ public final class TomlHelper {
|
|||
}
|
||||
|
||||
/** Convenience method for creating a list of single-line comments (no \n or \r). */
|
||||
public static ArrayList<String> newComment( String... lines ) {
|
||||
return new ArrayList<>( Arrays.asList( lines ) );
|
||||
}
|
||||
public static ArrayList<String> newComment( String... lines ) { return new ArrayList<>( Arrays.asList( lines ) ); }
|
||||
|
||||
/** Combines an array of objects as a comma-separated string. */
|
||||
public static String combineList( Object... list ) { return combineList( Arrays.asList( list ) ); }
|
||||
|
||||
/** Combines a list of objects as a comma-separated string. */
|
||||
public static String combineList( List<Object> list ) {
|
||||
public static String combineList( @Nullable List<Object> list ) {
|
||||
if( list == null || list.isEmpty() ) return "";
|
||||
StringBuilder key = new StringBuilder();
|
||||
for( Object obj : list ) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.file;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.species;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -5,6 +5,7 @@ import fathertoast.specialmobs.common.config.file.TomlHelper;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -33,7 +34,7 @@ public class AttributeList implements IStringArray {
|
|||
|
||||
/** @return Returns true if this object has the same value as another object. */
|
||||
@Override
|
||||
public boolean equals( Object other ) {
|
||||
public boolean equals( @Nullable Object other ) {
|
||||
if( !(other instanceof AttributeList) ) return false;
|
||||
// Compare by the string list view of the object
|
||||
return toStringList().equals( ((AttributeList) other).toStringList() );
|
||||
|
|
|
@ -32,7 +32,7 @@ public class BlockEntry implements Cloneable {
|
|||
this( block.getBlock() );
|
||||
|
||||
// Add all the properties present in the block state
|
||||
StateBuilder state = new StateBuilder();
|
||||
StateBuilder state = new StateBuilder( BLOCK );
|
||||
for( Property<? extends Comparable<?>> property : block.getProperties() ) {
|
||||
state.add( property, block.getValue( property ) );
|
||||
}
|
||||
|
@ -45,13 +45,8 @@ public class BlockEntry implements Cloneable {
|
|||
public BlockEntry( AbstractConfigField field, String line ) {
|
||||
// Parse the base block
|
||||
final String[] pair = line.split( "\\[", 2 );
|
||||
final ResourceLocation regKey = new ResourceLocation( pair[0] );
|
||||
if( !ForgeRegistries.BLOCKS.containsKey( regKey ) ) {
|
||||
BLOCK = Blocks.AIR;
|
||||
}
|
||||
else {
|
||||
BLOCK = ForgeRegistries.BLOCKS.getValue( regKey );
|
||||
}
|
||||
final Block block = ForgeRegistries.BLOCKS.getValue( new ResourceLocation( pair[0] ) );
|
||||
BLOCK = block == null ? Blocks.AIR : block;
|
||||
|
||||
// We are done constructing if the entry is invalid or does not specify block states
|
||||
if( BLOCK == Blocks.AIR || pair.length < 2 ) {
|
||||
|
@ -143,7 +138,7 @@ public class BlockEntry implements Cloneable {
|
|||
final StateContainer<Block, BlockState> stateContainer = block.getStateDefinition();
|
||||
|
||||
// Parse the state and build the matcher
|
||||
final StateBuilder builder = new StateBuilder();
|
||||
final StateBuilder builder = new StateBuilder( block );
|
||||
final String[] properties = stateString.split( "," );
|
||||
for( String combinedEntry : properties ) {
|
||||
// Parse an individual property key-value pair
|
||||
|
@ -271,9 +266,6 @@ public class BlockEntry implements Cloneable {
|
|||
/** Can be used for building default configs to make block entries with target states. */
|
||||
public StateBuilder( Block block ) { BLOCK = block; }
|
||||
|
||||
/** Used by block entries to build target states. Can not be built into a block entry when using this constructor. */
|
||||
private StateBuilder() { BLOCK = null; }
|
||||
|
||||
/** @return Returns true if this state builder has no properties set. */
|
||||
@SuppressWarnings( "BooleanMethodIsAlwaysInverted" )
|
||||
public boolean isEmpty() { return propertiesToMatch.isEmpty(); }
|
||||
|
@ -289,7 +281,7 @@ public class BlockEntry implements Cloneable {
|
|||
|
||||
/** @return Returns a block entry reflecting the current state of this builder. */
|
||||
public BlockEntry toBlockEntry() {
|
||||
BlockEntry target = new BlockEntry( BLOCK );
|
||||
final BlockEntry target = new BlockEntry( BLOCK );
|
||||
if( !isEmpty() ) {
|
||||
target.MATCHERS.add( toTargetState() );
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.block.Blocks;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -61,13 +62,11 @@ public class BlockList implements IStringArray {
|
|||
|
||||
/** @return A string representation of this object. */
|
||||
@Override
|
||||
public String toString() {
|
||||
return TomlHelper.toLiteral( PRINT_LIST.toArray() );
|
||||
}
|
||||
public String toString() { return TomlHelper.toLiteral( PRINT_LIST.toArray() ); }
|
||||
|
||||
/** @return Returns true if this object has the same value as another object. */
|
||||
@Override
|
||||
public boolean equals( Object other ) {
|
||||
public boolean equals( @Nullable Object other ) {
|
||||
if( !(other instanceof BlockList) ) return false;
|
||||
// Compare by the string list view of the object
|
||||
return toStringList().equals( ((BlockList) other).toStringList() );
|
||||
|
@ -109,10 +108,9 @@ public class BlockList implements IStringArray {
|
|||
private void mergeFromNamespace( String namespace ) {
|
||||
for( ResourceLocation regKey : ForgeRegistries.BLOCKS.getKeys() ) {
|
||||
if( regKey.toString().startsWith( namespace ) ) {
|
||||
BlockEntry entry = new BlockEntry( ForgeRegistries.BLOCKS.getValue( regKey ) );
|
||||
if( entry.BLOCK != null && entry.BLOCK != Blocks.AIR ) {
|
||||
mergeFrom( entry );
|
||||
}
|
||||
final Block block = ForgeRegistries.BLOCKS.getValue( regKey );
|
||||
if( block != null && block != Blocks.AIR )
|
||||
mergeFrom( new BlockEntry( block ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package fathertoast.specialmobs.common.config.util;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.FileConfig;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fml.loading.FMLPaths;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public abstract class ConfigUtil {
|
||||
@Mod.EventBusSubscriber( modid = SpecialMobs.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE )
|
||||
public final class ConfigUtil {
|
||||
/** The current "version" of the dynamic registries. This is incremented each time dynamic registries are loaded. */
|
||||
public static byte DYNAMIC_REGISTRY_VERSION;
|
||||
|
||||
/** The plus or minus symbol (+/-). */
|
||||
public static final String PLUS_OR_MINUS = "\u00b1";
|
||||
|
@ -44,4 +52,12 @@ public abstract class ConfigUtil {
|
|||
|
||||
/** @return A string representation of the file from the game directory. */
|
||||
public static String toRelativePath( File gameFile ) { return FMLPaths.GAMEDIR.get().relativize( gameFile.toPath() ).toString(); }
|
||||
|
||||
/**
|
||||
* Called when a server (integrated or dedicated) is about to start.
|
||||
*
|
||||
* @param event The event data.
|
||||
*/
|
||||
@SubscribeEvent( priority = EventPriority.NORMAL )
|
||||
public static void onServerAboutToStart( FMLServerAboutToStartEvent event ) { DYNAMIC_REGISTRY_VERSION++; }
|
||||
}
|
|
@ -5,6 +5,7 @@ import fathertoast.specialmobs.common.config.file.TomlHelper;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -45,7 +46,7 @@ public class EntityList implements IStringArray {
|
|||
|
||||
/** @return Returns true if this object has the same value as another object. */
|
||||
@Override
|
||||
public boolean equals( Object other ) {
|
||||
public boolean equals( @Nullable Object other ) {
|
||||
if( !(other instanceof EntityList) ) return false;
|
||||
// Compare by the string list view of the object
|
||||
return toStringList().equals( ((EntityList) other).toStringList() );
|
||||
|
@ -63,7 +64,8 @@ public class EntityList implements IStringArray {
|
|||
}
|
||||
|
||||
/** @return True if the entity is contained in this list. */
|
||||
public boolean contains( Entity entity ) {
|
||||
public boolean contains( @Nullable Entity entity ) {
|
||||
if( entity == null ) return false;
|
||||
final EntityEntry targetEntry = new EntityEntry( entity );
|
||||
for( EntityEntry currentEntry : ENTRIES ) {
|
||||
currentEntry.checkClass( entity.level );
|
||||
|
@ -77,7 +79,9 @@ public class EntityList implements IStringArray {
|
|||
* @param entity The entity to retrieve values for.
|
||||
* @return The array of values of the best-match entry. Returns null if the entity is not contained in this entity list.
|
||||
*/
|
||||
public double[] getValues( Entity entity ) {
|
||||
@Nullable
|
||||
public double[] getValues( @Nullable Entity entity ) {
|
||||
if( entity == null ) return null;
|
||||
final EntityEntry targetEntry = new EntityEntry( entity );
|
||||
EntityEntry bestMatch = null;
|
||||
for( EntityEntry currentEntry : ENTRIES ) {
|
||||
|
@ -101,7 +105,7 @@ public class EntityList implements IStringArray {
|
|||
* @see #setSingleValue()
|
||||
* @see #setSinglePercent()
|
||||
*/
|
||||
public double getValue( Entity entity ) {
|
||||
public double getValue( @Nullable Entity entity ) {
|
||||
final double[] values = getValues( entity );
|
||||
return values == null || values.length < 1 ? 0.0 : values[0];
|
||||
}
|
||||
|
@ -112,7 +116,7 @@ public class EntityList implements IStringArray {
|
|||
* is not contained in this entity list or has no values specified. This should only be used for 'single percent' lists.
|
||||
* @see #setSinglePercent()
|
||||
*/
|
||||
public boolean rollChance( LivingEntity entity ) {
|
||||
public boolean rollChance( @Nullable LivingEntity entity ) {
|
||||
return ENTRIES.length > 0 && entity != null && entity.getRandom().nextDouble() < getValue( entity );
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package fathertoast.specialmobs.common.config.util;
|
||||
|
||||
import fathertoast.specialmobs.common.config.util.environment.*;
|
||||
import fathertoast.specialmobs.common.config.util.environment.biome.BiomeEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.dimension.DimensionTypeEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.StructureEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.YEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.position.YFromSeaEnvironment;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.structure.Structure;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* One condition-value entry in an environment list. Uses a 'lazy' implementation so any needed registries are
|
||||
* not polled until this entry is actually used.
|
||||
*/
|
||||
@SuppressWarnings( "unused" )
|
||||
public class EnvironmentEntry {
|
||||
/** The value given to this entry. */
|
||||
public final double VALUE;
|
||||
/** The conditions that define this entry's environment. */
|
||||
private final AbstractEnvironment[] CONDITIONS;
|
||||
|
||||
/** Creates an entry with the specified values. */
|
||||
public EnvironmentEntry( double value, List<AbstractEnvironment> conditions ) { this( value, conditions.toArray( new AbstractEnvironment[0] ) ); }
|
||||
|
||||
/** Creates an entry with the specified values. */
|
||||
public EnvironmentEntry( double value, AbstractEnvironment... conditions ) {
|
||||
VALUE = value;
|
||||
CONDITIONS = conditions;
|
||||
}
|
||||
|
||||
/** @return Returns true if all this entry's conditions match the provided environment. */
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
for( AbstractEnvironment condition : CONDITIONS ) {
|
||||
if( !condition.matches( world, pos ) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The string representation of this environment entry, as it would appear in a config file.
|
||||
* <p>
|
||||
* Format is "value condition1 state1 & condition2 state2 & ...".
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
// Start with the value
|
||||
final StringBuilder str = new StringBuilder().append( VALUE ).append( ' ' );
|
||||
// List all conditions
|
||||
boolean first = true;
|
||||
for( AbstractEnvironment condition : CONDITIONS ) {
|
||||
if( first ) first = false;
|
||||
else str.append( " & " );
|
||||
str.append( condition );
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public static Builder builder( double value ) { return new Builder( value ); }
|
||||
|
||||
/**
|
||||
* Builder class used to simplify creation of environment entries, with shortcuts for the most commonly used environments.
|
||||
*/
|
||||
public static class Builder {
|
||||
private final double VALUE;
|
||||
private final ArrayList<AbstractEnvironment> CONDITIONS = new ArrayList<>();
|
||||
|
||||
private Builder( double value ) { VALUE = value; }
|
||||
|
||||
public EnvironmentEntry build() { return new EnvironmentEntry( VALUE, CONDITIONS ); }
|
||||
|
||||
public Builder in( AbstractEnvironment condition ) {
|
||||
CONDITIONS.add( condition );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Dimension-based
|
||||
|
||||
public Builder inDimensionType( RegistryKey<DimensionType> dimType ) { return in( new DimensionTypeEnvironment( dimType ) ); }
|
||||
|
||||
|
||||
// Biome-based
|
||||
|
||||
public Builder inBiome( RegistryKey<Biome> biome ) { return in( new BiomeEnvironment( biome ) ); }
|
||||
|
||||
|
||||
// Position-based
|
||||
|
||||
public Builder inStructure( Structure<?> structure ) { return in( new StructureEnvironment( structure ) ); }
|
||||
|
||||
public Builder belowY( int y ) { return in( new YEnvironment( ComparisonOperator.LESS_THAN, y ) ); }
|
||||
|
||||
public Builder atLeastY( int y ) { return in( new YEnvironment( ComparisonOperator.GREATER_OR_EQUAL, y ) ); }
|
||||
|
||||
public Builder belowSeaLevel() { return in( new YFromSeaEnvironment( ComparisonOperator.LESS_THAN, 0 ) ); }
|
||||
|
||||
public Builder atLeastSeaLevel() { return in( new YFromSeaEnvironment( ComparisonOperator.GREATER_OR_EQUAL, 0 ) ); }
|
||||
|
||||
|
||||
// Time-based
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package fathertoast.specialmobs.common.config.util;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.DoubleField;
|
||||
import fathertoast.specialmobs.common.config.field.IStringArray;
|
||||
import fathertoast.specialmobs.common.config.file.TomlHelper;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A list of condition-value entries used to link one number to specific environments.
|
||||
*/
|
||||
@SuppressWarnings( { "unused", "SameParameterValue" } )
|
||||
public class EnvironmentList implements IStringArray {
|
||||
/** The condition-value entries in this list. */
|
||||
private final EnvironmentEntry[] ENTRIES;
|
||||
|
||||
/** The minimum value accepted for entry values in this list. */
|
||||
private double minValue = Double.NEGATIVE_INFINITY;
|
||||
/** The maximum value accepted for entry values in this list. */
|
||||
private double maxValue = Double.POSITIVE_INFINITY;
|
||||
|
||||
/**
|
||||
* Create a new environment list from a list of entries.
|
||||
* <p>
|
||||
* By default, environment list value(s) can be any numerical double.
|
||||
* This can be changed with helper methods that alter values' bounds and return 'this'.
|
||||
*/
|
||||
public EnvironmentList( List<EnvironmentEntry> entries ) { this( entries.toArray( new EnvironmentEntry[0] ) ); }
|
||||
|
||||
/**
|
||||
* Create a new environment list from an array of entries. Used for creating default configs.
|
||||
* <p>
|
||||
* By default, environment list value(s) can be any numerical double.
|
||||
* This can be changed with helper methods that alter values' bounds and return 'this'.
|
||||
*/
|
||||
public EnvironmentList( EnvironmentEntry... entries ) { ENTRIES = entries; }
|
||||
|
||||
/** @return A string representation of this object. */
|
||||
@Override
|
||||
public String toString() { return TomlHelper.toLiteral( toStringList().toArray() ); }
|
||||
|
||||
/** @return Returns true if this object has the same value as another object. */
|
||||
@Override
|
||||
public boolean equals( @Nullable Object other ) {
|
||||
if( !(other instanceof EnvironmentList) ) return false;
|
||||
// Compare by the string list view of the object
|
||||
return toStringList().equals( ((EnvironmentList) other).toStringList() );
|
||||
}
|
||||
|
||||
/** @return A list of strings that will represent this object when written to a toml file. */
|
||||
@Override
|
||||
public List<String> toStringList() {
|
||||
// Create a list of the entries in string format
|
||||
final List<String> list = new ArrayList<>( ENTRIES.length );
|
||||
for( EnvironmentEntry entry : ENTRIES ) {
|
||||
list.add( entry.toString() );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/** @return The value matching the given environment, or the default value if no matching environment is defined. */
|
||||
public double getOrElse( World world, @Nullable BlockPos pos, DoubleField defaultValue ) {
|
||||
return getOrElse( world, pos, defaultValue.get() );
|
||||
}
|
||||
|
||||
/** @return The value matching the given environment, or the default value if no matching environment is defined. */
|
||||
public double getOrElse( World world, @Nullable BlockPos pos, double defaultValue ) {
|
||||
final Double value = get( world, pos );
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
/** @return The value matching the given environment, or null if no matching environment is defined. */
|
||||
@Nullable
|
||||
public Double get( World world, @Nullable BlockPos pos ) {
|
||||
for( EnvironmentEntry entry : ENTRIES ) {
|
||||
if( entry.matches( world, pos ) ) return entry.VALUE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Bounds entry values in this list to the specified range. */
|
||||
public EnvironmentList setRange( DoubleField.Range range ) { return setRange( range.MIN, range.MAX ); }
|
||||
|
||||
/** Bounds entry values in this list to the specified limits, inclusive. */
|
||||
public EnvironmentList setRange( double min, double max ) {
|
||||
minValue = min;
|
||||
maxValue = max;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @return The minimum value that can be given to entry values. */
|
||||
public double getMinValue() { return minValue; }
|
||||
|
||||
/** @return The maximum value that can be given to entry values. */
|
||||
public double getMaxValue() { return maxValue; }
|
||||
}
|
|
@ -8,6 +8,7 @@ import net.minecraft.util.ResourceLocation;
|
|||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -25,9 +26,7 @@ public class RegistryEntryList<T extends IForgeRegistryEntry<T>> implements IStr
|
|||
/** The list used to write back to file. */
|
||||
protected final List<String> PRINT_LIST = new ArrayList<>();
|
||||
|
||||
protected RegistryEntryList( IForgeRegistry<T> registry ) {
|
||||
REGISTRY = registry;
|
||||
}
|
||||
protected RegistryEntryList( IForgeRegistry<T> registry ) { REGISTRY = registry; }
|
||||
|
||||
/**
|
||||
* Create a new registry entry list from an array of entries. Used for creating default configs.
|
||||
|
@ -79,13 +78,11 @@ public class RegistryEntryList<T extends IForgeRegistryEntry<T>> implements IStr
|
|||
|
||||
/** @return A string representation of this object. */
|
||||
@Override
|
||||
public String toString() {
|
||||
return TomlHelper.toLiteral( PRINT_LIST.toArray() );
|
||||
}
|
||||
public String toString() { return TomlHelper.toLiteral( PRINT_LIST.toArray() ); }
|
||||
|
||||
/** @return Returns true if this object has the same value as another object. */
|
||||
@Override
|
||||
public boolean equals( Object other ) {
|
||||
public boolean equals( @Nullable Object other ) {
|
||||
if( !(other instanceof RegistryEntryList) ) return false;
|
||||
// Compare by the registries used and string list view of the object
|
||||
return getRegistry() == ((RegistryEntryList<?>) other).getRegistry() &&
|
||||
|
@ -100,7 +97,7 @@ public class RegistryEntryList<T extends IForgeRegistryEntry<T>> implements IStr
|
|||
public boolean isEmpty() { return UNDERLYING_SET.isEmpty(); }
|
||||
|
||||
/** @return Returns true if the entry is contained in this list. */
|
||||
public boolean contains( T entry ) { return UNDERLYING_SET.contains( entry ); }
|
||||
public boolean contains( @Nullable T entry ) { return UNDERLYING_SET.contains( entry ); }
|
||||
|
||||
/** @return Adds the registry entry if it exists and isn't already present, returns true if successful. */
|
||||
protected boolean mergeFrom( ResourceLocation regKey ) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.*;
|
|||
* <p>
|
||||
* Creates a config field for each item so weights can be defined by the user.
|
||||
*/
|
||||
@SuppressWarnings( "unused" )
|
||||
public class WeightedList<T extends WeightedList.Value> {
|
||||
/** The spec used by this config that defines the file's format. */
|
||||
protected final ToastConfigSpec SPEC;
|
||||
|
@ -110,6 +111,7 @@ public class WeightedList<T extends WeightedList.Value> {
|
|||
default int getDefaultWeight() { return 1; }
|
||||
|
||||
/** @return Returns the comment for this object. */
|
||||
@Nullable
|
||||
default String[] getComment() { return null; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class AbstractEnvironment {
|
||||
/** @return The string representation of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public final String toString() { return name() + " " + value(); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
public abstract String name();
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
public abstract String value();
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
public abstract boolean matches( World world, @Nullable BlockPos pos );
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.file.TomlHelper;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class CompareFloatEnvironment extends AbstractEnvironment {
|
||||
/** How the actual value is compared to this environment's value. */
|
||||
public final ComparisonOperator COMPARATOR;
|
||||
/** The value for this environment. */
|
||||
public final float VALUE;
|
||||
|
||||
public CompareFloatEnvironment( ComparisonOperator op, float value ) {
|
||||
COMPARATOR = op;
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public CompareFloatEnvironment( AbstractConfigField field, String line ) {
|
||||
if( line.isEmpty() ) {
|
||||
COMPARATOR = ComparisonOperator.LESS_THAN;
|
||||
VALUE = 0.0F;
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Not defined. Defaulting to \"{}\". Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), value(), line );
|
||||
}
|
||||
else {
|
||||
final ComparisonOperator op = ComparisonOperator.parse( line );
|
||||
if( op == null ) {
|
||||
COMPARATOR = ComparisonOperator.LESS_THAN;
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Comparison not defined (must be in the set [ {} ]). Defaulting to \"{}\". Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), TomlHelper.literalList( (Object[]) ComparisonOperator.values() ), COMPARATOR, line );
|
||||
}
|
||||
else COMPARATOR = op;
|
||||
VALUE = parseValue( field, line, line.substring( COMPARATOR.toString().length() ).trim() );
|
||||
}
|
||||
}
|
||||
|
||||
/** @return Parses the value and returns a valid result. */
|
||||
private float parseValue( AbstractConfigField field, String line, String arg ) {
|
||||
// Try to parse the value
|
||||
float value;
|
||||
try {
|
||||
value = Float.parseFloat( arg );
|
||||
}
|
||||
catch( NumberFormatException ex ) {
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Value not defined (must be a float). Defaulting to '0'. Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), line );
|
||||
value = 0.0F;
|
||||
}
|
||||
// Verify value is within range
|
||||
if( value < getMinValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is below the minimum ({})! Clamping value. Invalid value: {}",
|
||||
field.getClass(), field.getKey(), getMinValue(), value );
|
||||
value = getMinValue();
|
||||
}
|
||||
else if( value > getMaxValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is above the maximum ({})! Clamping value. Invalid value: {}",
|
||||
field.getClass(), field.getKey(), getMaxValue(), value );
|
||||
value = getMaxValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
protected float getMinValue() { return Float.NEGATIVE_INFINITY; }
|
||||
|
||||
/** @return The maximum value that can be given to the value. */
|
||||
protected float getMaxValue() { return Float.POSITIVE_INFINITY; }
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String value() { return COMPARATOR + " " + VALUE; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
final float actual = getActual( world, pos );
|
||||
return !Float.isNaN( actual ) && COMPARATOR.apply( actual, VALUE );
|
||||
}
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
public abstract float getActual( World world, @Nullable BlockPos pos );
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.file.TomlHelper;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class CompareIntEnvironment extends AbstractEnvironment {
|
||||
/** How the actual value is compared to this environment's value. */
|
||||
public final ComparisonOperator COMPARATOR;
|
||||
/** The value for this environment. */
|
||||
public final int VALUE;
|
||||
|
||||
public CompareIntEnvironment( ComparisonOperator op, int value ) {
|
||||
COMPARATOR = op;
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public CompareIntEnvironment( AbstractConfigField field, String line ) {
|
||||
if( line.isEmpty() ) {
|
||||
COMPARATOR = ComparisonOperator.LESS_THAN;
|
||||
VALUE = 0;
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Not defined. Defaulting to \"{}\". Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), value(), line );
|
||||
}
|
||||
else {
|
||||
final ComparisonOperator op = ComparisonOperator.parse( line );
|
||||
if( op == null ) {
|
||||
COMPARATOR = ComparisonOperator.LESS_THAN;
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Comparison not defined (must be in the set [ {} ]). Defaulting to \"{}\". Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), TomlHelper.literalList( (Object[]) ComparisonOperator.values() ), COMPARATOR, line );
|
||||
}
|
||||
else COMPARATOR = op;
|
||||
VALUE = parseValue( field, line, line.substring( COMPARATOR.toString().length() ).trim() );
|
||||
}
|
||||
}
|
||||
|
||||
/** @return Parses the value and returns a valid result. */
|
||||
private int parseValue( AbstractConfigField field, String line, String arg ) {
|
||||
// Try to parse the value
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt( arg );
|
||||
}
|
||||
catch( NumberFormatException ex ) {
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Value not defined (must be an integer). Defaulting to '0'. Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), line );
|
||||
value = 0;
|
||||
}
|
||||
// Verify value is within range
|
||||
if( value < getMinValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is below the minimum ({})! Clamping value. Invalid value: {}",
|
||||
field.getClass(), field.getKey(), getMinValue(), value );
|
||||
value = getMinValue();
|
||||
}
|
||||
else if( value > getMaxValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is above the maximum ({})! Clamping value. Invalid value: {}",
|
||||
field.getClass(), field.getKey(), getMaxValue(), value );
|
||||
value = getMaxValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
protected int getMinValue() { return Integer.MIN_VALUE; }
|
||||
|
||||
/** @return The maximum value that can be given to the value. */
|
||||
protected int getMaxValue() { return Integer.MAX_VALUE; }
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String value() { return COMPARATOR + " " + VALUE; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
final Integer actual = getActual( world, pos );
|
||||
return actual != null && COMPARATOR.apply( actual, VALUE );
|
||||
}
|
||||
|
||||
/** @return Returns the actual value to compare, or null if there isn't enough information. */
|
||||
@Nullable
|
||||
public abstract Integer getActual( World world, @Nullable BlockPos pos );
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.file.TomlHelper;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class CompareLongEnvironment extends AbstractEnvironment {
|
||||
/** How the actual value is compared to this environment's value. */
|
||||
public final ComparisonOperator COMPARATOR;
|
||||
/** The value for this environment. */
|
||||
public final long VALUE;
|
||||
|
||||
public CompareLongEnvironment( ComparisonOperator op, long value ) {
|
||||
COMPARATOR = op;
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public CompareLongEnvironment( AbstractConfigField field, String line ) {
|
||||
if( line.isEmpty() ) {
|
||||
COMPARATOR = ComparisonOperator.LESS_THAN;
|
||||
VALUE = 0L;
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Not defined. Defaulting to \"{}\". Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), value(), line );
|
||||
}
|
||||
else {
|
||||
final ComparisonOperator op = ComparisonOperator.parse( line );
|
||||
if( op == null ) {
|
||||
COMPARATOR = ComparisonOperator.LESS_THAN;
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Comparison not defined (must be in the set [ {} ]). Defaulting to \"{}\". Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), TomlHelper.literalList( (Object[]) ComparisonOperator.values() ), COMPARATOR, line );
|
||||
}
|
||||
else COMPARATOR = op;
|
||||
VALUE = parseValue( field, line, line.substring( COMPARATOR.toString().length() ).trim() );
|
||||
}
|
||||
}
|
||||
|
||||
/** @return Parses the value and returns a valid result. */
|
||||
private long parseValue( AbstractConfigField field, String line, String arg ) {
|
||||
// Try to parse the value
|
||||
long value;
|
||||
try {
|
||||
value = Long.parseLong( arg );
|
||||
}
|
||||
catch( NumberFormatException ex ) {
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Value not defined (must be a long). Defaulting to '0'. Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), line );
|
||||
value = 0;
|
||||
}
|
||||
// Verify value is within range
|
||||
if( value < getMinValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is below the minimum ({})! Clamping value. Invalid value: {}",
|
||||
field.getClass(), field.getKey(), getMinValue(), value );
|
||||
value = getMinValue();
|
||||
}
|
||||
else if( value > getMaxValue() ) {
|
||||
SpecialMobs.LOG.warn( "Value for {} \"{}\" is above the maximum ({})! Clamping value. Invalid value: {}",
|
||||
field.getClass(), field.getKey(), getMaxValue(), value );
|
||||
value = getMaxValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
protected long getMinValue() { return Long.MIN_VALUE; }
|
||||
|
||||
/** @return The maximum value that can be given to the value. */
|
||||
protected long getMaxValue() { return Long.MAX_VALUE; }
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String value() { return COMPARATOR + " " + VALUE; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
final Long actual = getActual( world, pos );
|
||||
return actual != null && COMPARATOR.apply( actual, VALUE );
|
||||
}
|
||||
|
||||
/** @return Returns the actual value to compare, or null if there isn't enough information. */
|
||||
@Nullable
|
||||
public abstract Long getActual( World world, @Nullable BlockPos pos );
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public enum ComparisonOperator {
|
||||
NOT_EQUAL_TO( "!=" ), LESS_OR_EQUAL( "<=" ), GREATER_OR_EQUAL( ">=" ),
|
||||
EQUAL_TO( "=" ), LESS_THAN( "<" ), GREATER_THAN( ">" );
|
||||
|
||||
private final String LITERAL;
|
||||
|
||||
ComparisonOperator( String str ) { LITERAL = str; }
|
||||
|
||||
@Override
|
||||
public String toString() { return LITERAL; }
|
||||
|
||||
public boolean apply( float first, float second ) {
|
||||
switch( this ) {
|
||||
case LESS_THAN:
|
||||
return first < second;
|
||||
case LESS_OR_EQUAL:
|
||||
return first <= second;
|
||||
case GREATER_THAN:
|
||||
return first > second;
|
||||
case GREATER_OR_EQUAL:
|
||||
return first >= second;
|
||||
case EQUAL_TO:
|
||||
return first == second;
|
||||
case NOT_EQUAL_TO:
|
||||
return first != second;
|
||||
}
|
||||
throw new IllegalStateException( "Float comparison implementation is invalid! :(" );
|
||||
}
|
||||
|
||||
public boolean apply( int first, int second ) {
|
||||
switch( this ) {
|
||||
case LESS_THAN:
|
||||
return first < second;
|
||||
case LESS_OR_EQUAL:
|
||||
return first <= second;
|
||||
case GREATER_THAN:
|
||||
return first > second;
|
||||
case GREATER_OR_EQUAL:
|
||||
return first >= second;
|
||||
case EQUAL_TO:
|
||||
return first == second;
|
||||
case NOT_EQUAL_TO:
|
||||
return first != second;
|
||||
}
|
||||
throw new IllegalStateException( "Integer comparison implementation is invalid! :(" );
|
||||
}
|
||||
|
||||
public boolean apply( long first, long second ) {
|
||||
switch( this ) {
|
||||
case LESS_THAN:
|
||||
return first < second;
|
||||
case LESS_OR_EQUAL:
|
||||
return first <= second;
|
||||
case GREATER_THAN:
|
||||
return first > second;
|
||||
case GREATER_OR_EQUAL:
|
||||
return first >= second;
|
||||
case EQUAL_TO:
|
||||
return first == second;
|
||||
case NOT_EQUAL_TO:
|
||||
return first != second;
|
||||
}
|
||||
throw new IllegalStateException( "Long comparison implementation is invalid! :(" );
|
||||
}
|
||||
|
||||
/** @return The operator described by a given string, or null if invalid. */
|
||||
@Nullable
|
||||
public static ComparisonOperator parse( String op ) {
|
||||
for( ComparisonOperator operator : values() ) {
|
||||
if( op.startsWith( operator.LITERAL ) ) return operator;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.util.ConfigUtil;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Dynamic registries are contained in {@link net.minecraft.util.registry.DynamicRegistries}
|
||||
*/
|
||||
public abstract class DynamicRegistryEnvironment<T> extends AbstractEnvironment {
|
||||
/** The field containing this entry. We save a reference to help improve error/warning reports. */
|
||||
private final AbstractConfigField FIELD;
|
||||
|
||||
/** If true, the condition is inverted. */
|
||||
protected final boolean INVERT;
|
||||
/** The registry key for this environment. */
|
||||
private final ResourceLocation REGISTRY_KEY;
|
||||
|
||||
private T registryEntry;
|
||||
/** The value of ConfigUtil#DYNAMIC_REGISTRY_VERSION at the time of last poll. */
|
||||
private byte version = -1;
|
||||
|
||||
public DynamicRegistryEnvironment( ResourceLocation regKey ) { this( regKey, false ); }
|
||||
|
||||
public DynamicRegistryEnvironment( ResourceLocation regKey, boolean invert ) {
|
||||
FIELD = null;
|
||||
INVERT = invert;
|
||||
REGISTRY_KEY = regKey;
|
||||
}
|
||||
|
||||
public DynamicRegistryEnvironment( AbstractConfigField field, String line ) {
|
||||
FIELD = field;
|
||||
INVERT = line.startsWith( "!" );
|
||||
REGISTRY_KEY = new ResourceLocation( INVERT ? line.substring( 1 ) : line );
|
||||
}
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public final String value() { return (INVERT ? "!" : "") + REGISTRY_KEY.toString(); }
|
||||
|
||||
/** @return The registry used. */
|
||||
public abstract RegistryKey<Registry<T>> getRegistry();
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public final boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
if( world instanceof ServerWorld )
|
||||
return matches( (ServerWorld) world, pos ); // These don't work on the client :(
|
||||
return INVERT;
|
||||
}
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
public abstract boolean matches( ServerWorld world, @Nullable BlockPos pos );
|
||||
|
||||
/** @return The target registry object. */
|
||||
@Nullable
|
||||
public final T getRegistryEntry( ServerWorld world ) {
|
||||
if( version != ConfigUtil.DYNAMIC_REGISTRY_VERSION ) {
|
||||
version = ConfigUtil.DYNAMIC_REGISTRY_VERSION;
|
||||
|
||||
final Registry<T> registry = world.getServer().registryAccess().registryOrThrow( getRegistry() );
|
||||
registryEntry = registry.get( REGISTRY_KEY );
|
||||
if( registryEntry == null ) {
|
||||
SpecialMobs.LOG.info( "Missing entry for {} \"{}\"! Not present in registry \"{}\". Missing entry: {}",
|
||||
FIELD.getClass(), FIELD.getKey(), getRegistry().getRegistryName(), REGISTRY_KEY );
|
||||
}
|
||||
}
|
||||
return registryEntry;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.util.ConfigUtil;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dynamic registries are contained in {@link net.minecraft.util.registry.DynamicRegistries}
|
||||
*/
|
||||
public abstract class DynamicRegistryGroupEnvironment<T> extends AbstractEnvironment {
|
||||
/** The field containing this entry. We save a reference to help improve error/warning reports. */
|
||||
private final AbstractConfigField FIELD;
|
||||
|
||||
/** If true, the condition is inverted. */
|
||||
protected final boolean INVERT;
|
||||
/** The namespace for this environment. */
|
||||
private final String NAMESPACE;
|
||||
|
||||
private List<T> registryEntries;
|
||||
/** The value of ConfigUtil#DYNAMIC_REGISTRY_VERSION at the time of last poll. */
|
||||
private byte version = -1;
|
||||
|
||||
public DynamicRegistryGroupEnvironment( ResourceLocation regKey ) { this( regKey, false ); }
|
||||
|
||||
public DynamicRegistryGroupEnvironment( ResourceLocation regKey, boolean invert ) {
|
||||
FIELD = null;
|
||||
INVERT = invert;
|
||||
NAMESPACE = regKey.toString();
|
||||
}
|
||||
|
||||
public DynamicRegistryGroupEnvironment( AbstractConfigField field, String line ) {
|
||||
FIELD = field;
|
||||
INVERT = line.startsWith( "!" );
|
||||
NAMESPACE = line.substring( INVERT ? 1 : 0, line.length() - 1 );
|
||||
}
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public final String value() { return (INVERT ? "!" : "") + NAMESPACE + "*"; }
|
||||
|
||||
/** @return The registry used. */
|
||||
public abstract RegistryKey<Registry<T>> getRegistry();
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public final boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
if( world instanceof ServerWorld )
|
||||
return matches( (ServerWorld) world, pos ); // These don't work on the client :(
|
||||
return INVERT;
|
||||
}
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
public abstract boolean matches( ServerWorld world, @Nullable BlockPos pos );
|
||||
|
||||
/** @return The target registry object. */
|
||||
protected final List<T> getRegistryEntries( ServerWorld world ) {
|
||||
if( version != ConfigUtil.DYNAMIC_REGISTRY_VERSION ) {
|
||||
version = ConfigUtil.DYNAMIC_REGISTRY_VERSION;
|
||||
|
||||
registryEntries = new ArrayList<>();
|
||||
final Registry<T> registry = world.getServer().registryAccess().registryOrThrow( getRegistry() );
|
||||
for( ResourceLocation regKey : registry.keySet() ) {
|
||||
if( regKey.toString().startsWith( NAMESPACE ) ) {
|
||||
final T entry = registry.get( regKey );
|
||||
if( entry != null ) registryEntries.add( entry );
|
||||
}
|
||||
}
|
||||
if( registryEntries.isEmpty() ) {
|
||||
SpecialMobs.LOG.info( "Namespace entry for {} \"{}\" did not match anything in registry \"{}\"! Questionable entry: {}",
|
||||
FIELD == null ? "DEFAULT" : FIELD.getClass(), FIELD == null ? "DEFAULT" : FIELD.getKey(), getRegistry().getRegistryName(), NAMESPACE );
|
||||
}
|
||||
registryEntries = Collections.unmodifiableList( registryEntries );
|
||||
}
|
||||
return registryEntries;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.file.TomlHelper;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class EnumEnvironment<T extends Enum<T>> extends AbstractEnvironment {
|
||||
/** If true, the condition is inverted. */
|
||||
protected final boolean INVERT;
|
||||
/** The enum value for this environment. */
|
||||
protected final T VALUE;
|
||||
|
||||
public EnumEnvironment( T value ) { this( value, false ); }
|
||||
|
||||
public EnumEnvironment( T value, boolean invert ) {
|
||||
INVERT = invert;
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public EnumEnvironment( AbstractConfigField field, String line, T[] validValues ) {
|
||||
INVERT = line.startsWith( "!" );
|
||||
VALUE = parseValue( field, line, validValues, INVERT ? line.substring( 1 ) : line );
|
||||
}
|
||||
|
||||
/** @return Attempts to parse the string literal as one of the valid values and returns it, or null if invalid. */
|
||||
private T parseValue( AbstractConfigField field, String line, T[] validValues, String name ) {
|
||||
for( T value : validValues ) {
|
||||
if( value.name().equalsIgnoreCase( name ) ) return value;
|
||||
}
|
||||
// Value cannot be parsed
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Value not defined (must be in the set [ {} ]). Defaulting to {}. Invalid entry: {}",
|
||||
field.getClass(), field.getKey(), TomlHelper.literalList( (Object[]) validValues ), TomlHelper.toLiteral(), line );
|
||||
return validValues[0];
|
||||
}
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public final String value() { return (INVERT ? "!" : "") + VALUE.name().toLowerCase( Locale.ROOT ); }
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Registries are contained in {@link net.minecraftforge.registries.ForgeRegistries}
|
||||
*/
|
||||
public abstract class RegistryEnvironment<T extends IForgeRegistryEntry<T>> extends AbstractEnvironment {
|
||||
/** The field containing this entry. We save a reference to help improve error/warning reports. */
|
||||
private final AbstractConfigField FIELD;
|
||||
|
||||
/** If true, the condition is inverted. */
|
||||
protected final boolean INVERT;
|
||||
/** The registry key for this environment. */
|
||||
private final ResourceLocation REGISTRY_KEY;
|
||||
|
||||
private T registryEntry;
|
||||
|
||||
public RegistryEnvironment( T regEntry ) { this( regEntry, false ); }
|
||||
|
||||
public RegistryEnvironment( T regEntry, boolean invert ) {
|
||||
FIELD = null;
|
||||
INVERT = invert;
|
||||
REGISTRY_KEY = regEntry.getRegistryName();
|
||||
registryEntry = regEntry;
|
||||
}
|
||||
|
||||
public RegistryEnvironment( AbstractConfigField field, String line ) {
|
||||
FIELD = field;
|
||||
INVERT = line.startsWith( "!" );
|
||||
REGISTRY_KEY = new ResourceLocation( INVERT ? line.substring( 1 ) : line );
|
||||
}
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public final String value() { return (INVERT ? "!" : "") + REGISTRY_KEY.toString(); }
|
||||
|
||||
/** @return The registry used. */
|
||||
public abstract IForgeRegistry<T> getRegistry();
|
||||
|
||||
/** @return The registry entry. */
|
||||
@Nullable
|
||||
protected final T getRegistryEntry() {
|
||||
if( registryEntry == null ) {
|
||||
if( !getRegistry().containsKey( REGISTRY_KEY ) ) {
|
||||
SpecialMobs.LOG.warn( "Invalid entry for {} \"{}\"! Not present in registry \"{}\". Invalid entry: {}",
|
||||
FIELD.getClass(), FIELD.getKey(), getRegistry().getRegistryName(), REGISTRY_KEY );
|
||||
}
|
||||
registryEntry = getRegistry().getValue( REGISTRY_KEY );
|
||||
}
|
||||
return registryEntry;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Registries are contained in {@link net.minecraftforge.registries.ForgeRegistries}
|
||||
*/
|
||||
public abstract class RegistryGroupEnvironment<T extends IForgeRegistryEntry<T>> extends AbstractEnvironment {
|
||||
/** The field containing this entry. We save a reference to help improve error/warning reports. */
|
||||
private final AbstractConfigField FIELD;
|
||||
|
||||
/** If true, the condition is inverted. */
|
||||
protected final boolean INVERT;
|
||||
/** The namespace for this environment. */
|
||||
private final String NAMESPACE;
|
||||
|
||||
private List<T> registryEntries;
|
||||
|
||||
public RegistryGroupEnvironment( T regEntry ) { this( regEntry, false ); }
|
||||
|
||||
public RegistryGroupEnvironment( T regEntry, boolean invert ) {
|
||||
FIELD = null;
|
||||
INVERT = invert;
|
||||
//noinspection ConstantConditions
|
||||
NAMESPACE = regEntry.getRegistryName().toString();
|
||||
}
|
||||
|
||||
public RegistryGroupEnvironment( AbstractConfigField field, String line ) {
|
||||
FIELD = field;
|
||||
INVERT = line.startsWith( "!" );
|
||||
NAMESPACE = line.substring( INVERT ? 1 : 0, line.length() - 1 );
|
||||
}
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public final String value() { return (INVERT ? "!" : "") + NAMESPACE + "*"; }
|
||||
|
||||
/** @return The registry used. */
|
||||
public abstract IForgeRegistry<T> getRegistry();
|
||||
|
||||
/** @return The registry entries. */
|
||||
protected final List<T> getRegistryEntries() {
|
||||
if( registryEntries == null ) {
|
||||
registryEntries = new ArrayList<>();
|
||||
for( ResourceLocation regKey : getRegistry().getKeys() ) {
|
||||
if( regKey.toString().startsWith( NAMESPACE ) ) {
|
||||
final T entry = getRegistry().getValue( regKey );
|
||||
if( entry != null ) registryEntries.add( entry );
|
||||
}
|
||||
}
|
||||
if( registryEntries.isEmpty() ) {
|
||||
SpecialMobs.LOG.warn( "Namespace entry for {} \"{}\" did not match anything in registry \"{}\"! Questionable entry: {}",
|
||||
FIELD == null ? "DEFAULT" : FIELD.getClass(), FIELD == null ? "DEFAULT" : FIELD.getKey(), getRegistry().getRegistryName(), NAMESPACE );
|
||||
}
|
||||
registryEntries = Collections.unmodifiableList( registryEntries );
|
||||
}
|
||||
return registryEntries;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.EnumEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BiomeCategoryEnvironment extends EnumEnvironment<BiomeCategoryEnvironment.Value> {
|
||||
public enum Value {
|
||||
NONE( Biome.Category.NONE ),
|
||||
TAIGA( Biome.Category.TAIGA ),
|
||||
EXTREME_HILLS( Biome.Category.EXTREME_HILLS ),
|
||||
JUNGLE( Biome.Category.JUNGLE ),
|
||||
MESA( Biome.Category.MESA ),
|
||||
PLAINS( Biome.Category.PLAINS ),
|
||||
SAVANNA( Biome.Category.SAVANNA ),
|
||||
ICY( Biome.Category.ICY ),
|
||||
THE_END( Biome.Category.THEEND ),
|
||||
BEACH( Biome.Category.BEACH ),
|
||||
FOREST( Biome.Category.FOREST ),
|
||||
OCEAN( Biome.Category.OCEAN ),
|
||||
DESERT( Biome.Category.DESERT ),
|
||||
RIVER( Biome.Category.RIVER ),
|
||||
SWAMP( Biome.Category.SWAMP ),
|
||||
MUSHROOM( Biome.Category.MUSHROOM ),
|
||||
NETHER( Biome.Category.NETHER );
|
||||
|
||||
public final Biome.Category BASE;
|
||||
|
||||
Value( Biome.Category vanillaCat ) { BASE = vanillaCat; }
|
||||
}
|
||||
|
||||
public BiomeCategoryEnvironment( Value value ) { super( value ); }
|
||||
|
||||
public BiomeCategoryEnvironment( Value value, boolean invert ) { super( value, invert ); }
|
||||
|
||||
public BiomeCategoryEnvironment( AbstractConfigField field, String line ) { super( field, line, Value.values() ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_BIOME_CATEGORY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
return (pos != null && VALUE.BASE.equals( world.getBiome( pos ).getBiomeCategory() )) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.DynamicRegistryEnvironment;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BiomeEnvironment extends DynamicRegistryEnvironment<Biome> {
|
||||
|
||||
public BiomeEnvironment( RegistryKey<Biome> biome ) { super( biome.getRegistryName() ); }
|
||||
|
||||
public BiomeEnvironment( RegistryKey<Biome> biome, boolean invert ) { super( biome.getRegistryName(), invert ); }
|
||||
|
||||
public BiomeEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_BIOME; }
|
||||
|
||||
/** @return The registry used. */
|
||||
@Override
|
||||
public RegistryKey<Registry<Biome>> getRegistry() { return Registry.BIOME_REGISTRY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( ServerWorld world, @Nullable BlockPos pos ) {
|
||||
final Biome entry = getRegistryEntry( world );
|
||||
return (entry != null && pos != null && entry.equals( world.getBiome( pos ) )) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.DynamicRegistryGroupEnvironment;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class BiomeGroupEnvironment extends DynamicRegistryGroupEnvironment<Biome> {
|
||||
|
||||
public BiomeGroupEnvironment( RegistryKey<Biome> biome ) { super( biome.getRegistryName() ); }
|
||||
|
||||
public BiomeGroupEnvironment( RegistryKey<Biome> biome, boolean invert ) { super( biome.getRegistryName(), invert ); }
|
||||
|
||||
public BiomeGroupEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_BIOME; }
|
||||
|
||||
/** @return The registry used. */
|
||||
@Override
|
||||
public RegistryKey<Registry<Biome>> getRegistry() { return Registry.BIOME_REGISTRY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public final boolean matches( ServerWorld world, @Nullable BlockPos pos ) {
|
||||
final Biome target = pos == null ? null : world.getBiome( pos );
|
||||
if( target != null ) {
|
||||
final List<Biome> entries = getRegistryEntries( world );
|
||||
for( Biome entry : entries ) {
|
||||
if( entry.equals( target ) ) return !INVERT;
|
||||
}
|
||||
}
|
||||
return INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareFloatEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BiomeTemperatureEnvironment extends CompareFloatEnvironment {
|
||||
|
||||
public BiomeTemperatureEnvironment( ComparisonOperator op, float value ) { super( op, value ); }
|
||||
|
||||
public BiomeTemperatureEnvironment( AbstractConfigField field, String line ) { super( field, TemperatureEnvironment.handleTempInput( line ) ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_BIOME_TEMPERATURE; }
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String value() {
|
||||
if( COMPARATOR == ComparisonOperator.LESS_THAN && VALUE == 0.15F )
|
||||
return TemperatureEnvironment.FREEZING;
|
||||
if( COMPARATOR == ComparisonOperator.GREATER_THAN && VALUE == Math.nextDown( 0.15F ) )
|
||||
return "!" + TemperatureEnvironment.FREEZING;
|
||||
return super.value();
|
||||
}
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
@Override
|
||||
public float getActual( World world, @Nullable BlockPos pos ) {
|
||||
return pos == null ? Float.NaN : world.getBiome( pos ).getBaseTemperature();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareFloatEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class RainfallEnvironment extends CompareFloatEnvironment {
|
||||
|
||||
public RainfallEnvironment( ComparisonOperator op, float value ) { super( op, value ); }
|
||||
|
||||
public RainfallEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_RAINFALL; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
// Handle the special case of no rainfall
|
||||
if( COMPARATOR == ComparisonOperator.EQUAL_TO && VALUE == 0.0F )
|
||||
return pos != null && world.getBiome( pos ).getPrecipitation() == Biome.RainType.NONE;
|
||||
return super.matches( world, pos );
|
||||
}
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
@Override
|
||||
public float getActual( World world, @Nullable BlockPos pos ) {
|
||||
return pos == null ? Float.NaN : world.getBiome( pos ).getDownfall();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareFloatEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class TemperatureEnvironment extends CompareFloatEnvironment {
|
||||
|
||||
public static final String FREEZING = "freezing";
|
||||
|
||||
public static String handleTempInput( String line ) {
|
||||
if( line.equalsIgnoreCase( FREEZING ) )
|
||||
return ComparisonOperator.LESS_THAN + " " + 0.15F;
|
||||
if( line.equalsIgnoreCase( "!" + FREEZING ) )
|
||||
return ComparisonOperator.GREATER_THAN + " " + Math.nextDown( 0.15F );
|
||||
return line;
|
||||
}
|
||||
|
||||
public TemperatureEnvironment( ComparisonOperator op, float value ) { super( op, value ); }
|
||||
|
||||
public TemperatureEnvironment( AbstractConfigField field, String line ) { super( field, handleTempInput( line ) ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_TEMPERATURE; }
|
||||
|
||||
/** @return The string value of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String value() {
|
||||
if( COMPARATOR == ComparisonOperator.LESS_THAN && VALUE == 0.15F )
|
||||
return FREEZING;
|
||||
if( COMPARATOR == ComparisonOperator.GREATER_THAN && VALUE == Math.nextDown( 0.15F ) )
|
||||
return "!" + FREEZING;
|
||||
return super.value();
|
||||
}
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
@Override
|
||||
public float getActual( World world, @Nullable BlockPos pos ) {
|
||||
return pos == null ? Float.NaN : world.getBiome( pos ).getTemperature( pos );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.util.environment.biome;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,51 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.dimension;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.EnumEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class DimensionPropertyEnvironment extends EnumEnvironment<DimensionPropertyEnvironment.Value> {
|
||||
/**
|
||||
* Represents all boolean values defined by dimension type, named to match data pack format.
|
||||
*
|
||||
* @see <a href="https://minecraft.fandom.com/wiki/Custom_dimension#Syntax">Data pack format (Minecraft Wiki)</a>
|
||||
*/
|
||||
public enum Value {
|
||||
@SuppressWarnings( "SpellCheckingInspection" )
|
||||
ULTRAWARM( DimensionType::ultraWarm ),
|
||||
NATURAL( DimensionType::natural ),
|
||||
HAS_SKYLIGHT( DimensionType::hasSkyLight ),
|
||||
HAS_CEILING( DimensionType::hasCeiling ),
|
||||
FIXED_TIME( DimensionType::hasFixedTime ),
|
||||
PIGLIN_SAFE( DimensionType::piglinSafe ),
|
||||
BED_WORKS( DimensionType::bedWorks ),
|
||||
RESPAWN_ANCHOR_WORKS( DimensionType::respawnAnchorWorks ),
|
||||
HAS_RAIDS( DimensionType::hasRaids );
|
||||
|
||||
private final Function<DimensionType, Boolean> SUPPLIER;
|
||||
|
||||
Value( Function<DimensionType, Boolean> supplier ) { SUPPLIER = supplier; }
|
||||
|
||||
public boolean of( DimensionType dimType ) { return SUPPLIER.apply( dimType ); }
|
||||
}
|
||||
|
||||
public DimensionPropertyEnvironment( Value value ) { super( value ); }
|
||||
|
||||
public DimensionPropertyEnvironment( Value value, boolean invert ) { super( value, invert ); }
|
||||
|
||||
public DimensionPropertyEnvironment( AbstractConfigField field, String line ) { super( field, line, Value.values() ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_DIMENSION_PROPERTY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) { return VALUE.of( world.dimensionType() ) != INVERT; }
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.dimension;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.DynamicRegistryEnvironment;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DimensionTypeEnvironment extends DynamicRegistryEnvironment<DimensionType> {
|
||||
|
||||
public DimensionTypeEnvironment( RegistryKey<DimensionType> dimType ) { super( dimType.getRegistryName() ); }
|
||||
|
||||
public DimensionTypeEnvironment( RegistryKey<DimensionType> dimType, boolean invert ) { super( dimType.getRegistryName(), invert ); }
|
||||
|
||||
public DimensionTypeEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_DIMENSION_TYPE; }
|
||||
|
||||
/** @return The registry used. */
|
||||
@Override
|
||||
public RegistryKey<Registry<DimensionType>> getRegistry() { return Registry.DIMENSION_TYPE_REGISTRY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( ServerWorld world, @Nullable BlockPos pos ) {
|
||||
final DimensionType entry = getRegistryEntry( world );
|
||||
return (entry != null && entry.equals( world.dimensionType() )) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.dimension;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.DynamicRegistryGroupEnvironment;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class DimensionTypeGroupEnvironment extends DynamicRegistryGroupEnvironment<DimensionType> {
|
||||
|
||||
public DimensionTypeGroupEnvironment( RegistryKey<DimensionType> dimType ) { super( dimType.getRegistryName() ); }
|
||||
|
||||
public DimensionTypeGroupEnvironment( RegistryKey<DimensionType> dimType, boolean invert ) { super( dimType.getRegistryName(), invert ); }
|
||||
|
||||
public DimensionTypeGroupEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_DIMENSION_TYPE; }
|
||||
|
||||
/** @return The registry used. */
|
||||
@Override
|
||||
public RegistryKey<Registry<DimensionType>> getRegistry() { return Registry.DIMENSION_TYPE_REGISTRY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public final boolean matches( ServerWorld world, @Nullable BlockPos pos ) {
|
||||
final DimensionType target = world.dimensionType();
|
||||
final List<DimensionType> entries = getRegistryEntries( world );
|
||||
for( DimensionType entry : entries ) {
|
||||
if( entry.equals( target ) ) return !INVERT;
|
||||
}
|
||||
return INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.util.environment.dimension;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.util.environment;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,38 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.position;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.RegistryEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.structure.Structure;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class StructureEnvironment extends RegistryEnvironment<Structure<?>> {
|
||||
|
||||
public StructureEnvironment( Structure<?> structure ) { super( structure ); }
|
||||
|
||||
public StructureEnvironment( Structure<?> structure, boolean invert ) { super( structure, invert ); }
|
||||
|
||||
public StructureEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_STRUCTURE; }
|
||||
|
||||
/** @return The registry used. */
|
||||
@Override
|
||||
public IForgeRegistry<Structure<?>> getRegistry() { return ForgeRegistries.STRUCTURE_FEATURES; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
final Structure<?> entry = getRegistryEntry();
|
||||
return (entry != null && pos != null && world instanceof ServerWorld &&
|
||||
((ServerWorld) world).structureFeatureManager().getStructureAt( pos, false, entry ).isValid()) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.position;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.RegistryGroupEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.structure.Structure;
|
||||
import net.minecraft.world.gen.feature.structure.StructureManager;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class StructureGroupEnvironment extends RegistryGroupEnvironment<Structure<?>> {
|
||||
|
||||
public StructureGroupEnvironment( Structure<?> biome ) { super( biome ); }
|
||||
|
||||
public StructureGroupEnvironment( Structure<?> biome, boolean invert ) { super( biome, invert ); }
|
||||
|
||||
public StructureGroupEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_STRUCTURE; }
|
||||
|
||||
/** @return The registry used. */
|
||||
@Override
|
||||
public IForgeRegistry<Structure<?>> getRegistry() { return ForgeRegistries.STRUCTURE_FEATURES; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public final boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
final StructureManager structureManager = pos != null && world instanceof ServerWorld ?
|
||||
((ServerWorld) world).structureFeatureManager() : null;
|
||||
if( structureManager != null ) {
|
||||
final List<Structure<?>> entries = getRegistryEntries();
|
||||
for( Structure<?> entry : entries ) {
|
||||
if( structureManager.getStructureAt( pos, false, entry ).isValid() ) return !INVERT;
|
||||
}
|
||||
}
|
||||
return INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.position;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareIntEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class YEnvironment extends CompareIntEnvironment {
|
||||
|
||||
public YEnvironment( ComparisonOperator op, int value ) { super( op, value ); }
|
||||
|
||||
public YEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_Y; }
|
||||
|
||||
/** @return Returns the actual value to compare, or null if there isn't enough information. */
|
||||
@Override
|
||||
public Integer getActual( World world, @Nullable BlockPos pos ) { return pos == null ? null : pos.getY(); }
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.position;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareIntEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class YFromSeaEnvironment extends CompareIntEnvironment {
|
||||
|
||||
public YFromSeaEnvironment( ComparisonOperator op, int value ) { super( op, value ); }
|
||||
|
||||
public YFromSeaEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_Y_FROM_SEA; }
|
||||
|
||||
/** @return Returns the actual value to compare, or null if there isn't enough information. */
|
||||
@Override
|
||||
public Integer getActual( World world, @Nullable BlockPos pos ) { return pos == null ? null : pos.getY() - world.getSeaLevel(); }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.util.environment.position;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,45 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.EnumEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DayTimeEnvironment extends EnumEnvironment<DayTimeEnvironment.Value> {
|
||||
/** Values match up to the vanilla set time command. */
|
||||
public enum Value {
|
||||
DAY( 1_000, 13_000 ), SUNSET( 12_000, 13_000 ),
|
||||
NIGHT( 13_000, 1_000 ), SUNRISE( 23_000, 1_000 );
|
||||
|
||||
private final int START, END;
|
||||
|
||||
Value( int start, int end ) {
|
||||
START = start;
|
||||
END = end;
|
||||
}
|
||||
|
||||
public boolean matches( int dayTime ) {
|
||||
if( START < END ) return START <= dayTime && dayTime < END;
|
||||
return START <= dayTime || dayTime < END; // Handle day wrapping
|
||||
}
|
||||
}
|
||||
|
||||
public DayTimeEnvironment( Value value ) { super( value ); }
|
||||
|
||||
public DayTimeEnvironment( Value value, boolean invert ) { super( value, invert ); }
|
||||
|
||||
public DayTimeEnvironment( AbstractConfigField field, String line ) { super( field, line, Value.values() ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_DAY_TIME; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
return (VALUE.matches( (int) (world.dayTime() / 24_000L) )) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareFloatEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Notes on regional difficulty:
|
||||
* Maxes out over 63 days in the world and 150 days the in the chunk (effectively, time the chunk has been loaded).
|
||||
* Peaks during the full moon and dramatically scaled by difficulty setting.
|
||||
* <p>
|
||||
* Peaceful: 0
|
||||
* Easy: 0.75 to 1.5 (0.25 from world time, 0.375 from chunk time, and 0.125 from moon brightness)
|
||||
* Normal: 1.5 to 4.0 (0.5 from world time, 1.5 from chunk time, and 0.5 from moon brightness)
|
||||
* Hard: 2.25 to 6.75 (0.75 from world time, 3.0 from chunk time, and 0.75 from moon brightness)
|
||||
*/
|
||||
public class DifficultyEnvironment extends CompareFloatEnvironment {
|
||||
|
||||
public DifficultyEnvironment( ComparisonOperator op, float value ) { super( op, value ); }
|
||||
|
||||
public DifficultyEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
protected float getMinValue() { return 0.0F; }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_DIFFICULTY; }
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
@Override
|
||||
public float getActual( World world, @Nullable BlockPos pos ) {
|
||||
return pos == null ? Float.NaN : world.getCurrentDifficultyAt( pos ).getEffectiveDifficulty();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareFloatEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class MoonBrightnessEnvironment extends CompareFloatEnvironment {
|
||||
|
||||
public MoonBrightnessEnvironment( ComparisonOperator op, float value ) { super( op, value ); }
|
||||
|
||||
public MoonBrightnessEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
protected float getMinValue() { return 0.0F; }
|
||||
|
||||
/** @return The maximum value that can be given to the value. */
|
||||
protected float getMaxValue() { return 1.0F; }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_MOON_BRIGHTNESS; }
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
@Override
|
||||
public float getActual( World world, @Nullable BlockPos pos ) {
|
||||
return pos == null ? Float.NaN : DimensionType.MOON_BRIGHTNESS_PER_PHASE[world.dimensionType().moonPhase( world.dayTime() )];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.EnumEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class MoonPhaseEnvironment extends EnumEnvironment<MoonPhaseEnvironment.Value> {
|
||||
/** Values match up to the vanilla weather command. */
|
||||
public enum Value {
|
||||
FULL( 0 ), WANING_GIBBOUS( 1 ), LAST_QUARTER( 2 ), WANING_CRESCENT( 3 ),
|
||||
NEW( 4 ), WAXING_CRESCENT( 5 ), FIRST_QUARTER( 6 ), WAXING_GIBBOUS( 7 );
|
||||
|
||||
public final int INDEX;
|
||||
|
||||
Value( int i ) { INDEX = i; }
|
||||
}
|
||||
|
||||
public MoonPhaseEnvironment( Value value ) { super( value ); }
|
||||
|
||||
public MoonPhaseEnvironment( Value value, boolean invert ) { super( value, invert ); }
|
||||
|
||||
public MoonPhaseEnvironment( AbstractConfigField field, String line ) { super( field, line, Value.values() ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_MOON_PHASE; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
final int phase = world.dimensionType().moonPhase( world.dayTime() );
|
||||
return (VALUE.INDEX == phase) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareFloatEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Notes on special multiplier difficulty:
|
||||
* This is 0 while regional difficulty is <= 2 and this is 1 while regional difficulty is >= 4 (linearly scales between).
|
||||
* <p>
|
||||
* In Peaceful and Easy, this is always 0. In Normal, this only maxes out at the absolute peak regional difficulty.
|
||||
* In Hard, this starts out as 0.125 and reaches 1 during new moons with only ~50 days in the area.
|
||||
*/
|
||||
public class SpecialDifficultyEnvironment extends CompareFloatEnvironment {
|
||||
|
||||
public SpecialDifficultyEnvironment( ComparisonOperator op, float value ) { super( op, value ); }
|
||||
|
||||
public SpecialDifficultyEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
protected float getMinValue() { return 0.0F; }
|
||||
|
||||
/** @return The maximum value that can be given to the value. */
|
||||
protected float getMaxValue() { return 1.0F; }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_SPECIAL_DIFFICULTY; }
|
||||
|
||||
/** @return Returns the actual value to compare, or Float.NaN if there isn't enough information. */
|
||||
@Override
|
||||
public float getActual( World world, @Nullable BlockPos pos ) {
|
||||
return pos == null ? Float.NaN : world.getCurrentDifficultyAt( pos ).getSpecialMultiplier();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareIntEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class TimeFromMidnightEnvironment extends CompareIntEnvironment {
|
||||
|
||||
public TimeFromMidnightEnvironment( ComparisonOperator op, int value ) { super( op, value ); }
|
||||
|
||||
public TimeFromMidnightEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_TIME_FROM_MIDNIGHT; }
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
@Override
|
||||
protected int getMinValue() { return 0; }
|
||||
|
||||
/** @return The maximum value that can be given to the value. */
|
||||
@Override
|
||||
protected int getMaxValue() { return 12_000; }
|
||||
|
||||
/** @return Returns the actual value to compare, or null if there isn't enough information. */
|
||||
@Override
|
||||
public Integer getActual( World world, @Nullable BlockPos pos ) {
|
||||
int dayTime = (int) (world.dayTime() / 24_000L);
|
||||
if( dayTime < 18_000 ) dayTime += 24_000;
|
||||
return dayTime - 18_000;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.EnumEnvironment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class WeatherEnvironment extends EnumEnvironment<WeatherEnvironment.Value> {
|
||||
/** Values match up to the vanilla weather command. */
|
||||
public enum Value { CLEAR, RAIN, THUNDER }
|
||||
|
||||
public WeatherEnvironment( Value value ) { super( value ); }
|
||||
|
||||
public WeatherEnvironment( Value value, boolean invert ) { super( value, invert ); }
|
||||
|
||||
public WeatherEnvironment( AbstractConfigField field, String line ) { super( field, line, Value.values() ); }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_BIOME_CATEGORY; }
|
||||
|
||||
/** @return Returns true if this environment matches the provided environment. */
|
||||
@Override
|
||||
public boolean matches( World world, @Nullable BlockPos pos ) {
|
||||
if( world.getLevelData().isThundering() ) return (VALUE == Value.CLEAR) == INVERT; // Thunder implies rain
|
||||
if( world.getLevelData().isRaining() ) return (VALUE == Value.RAIN) != INVERT;
|
||||
return (VALUE == Value.CLEAR) != INVERT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import fathertoast.specialmobs.common.config.field.AbstractConfigField;
|
||||
import fathertoast.specialmobs.common.config.field.EnvironmentListField;
|
||||
import fathertoast.specialmobs.common.config.util.environment.CompareLongEnvironment;
|
||||
import fathertoast.specialmobs.common.config.util.environment.ComparisonOperator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class WorldTimeEnvironment extends CompareLongEnvironment {
|
||||
|
||||
public WorldTimeEnvironment( ComparisonOperator op, long value ) { super( op, value ); }
|
||||
|
||||
public WorldTimeEnvironment( AbstractConfigField field, String line ) { super( field, line ); }
|
||||
|
||||
/** @return The minimum value that can be given to the value. */
|
||||
@Override
|
||||
protected long getMinValue() { return 0L; }
|
||||
|
||||
/** @return The string name of this environment, as it would appear in a config file. */
|
||||
@Override
|
||||
public String name() { return EnvironmentListField.ENV_MOON_BRIGHTNESS; }
|
||||
|
||||
/** @return Returns the actual value to compare, or null if there isn't enough information. */
|
||||
@Override
|
||||
public Long getActual( World world, @Nullable BlockPos pos ) { return world.dayTime(); }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.util.environment.time;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.config.util;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -4,7 +4,6 @@ import fathertoast.specialmobs.common.bestiary.MobFamily;
|
|||
import fathertoast.specialmobs.common.config.Config;
|
||||
import fathertoast.specialmobs.common.entity.MobHelper;
|
||||
import fathertoast.specialmobs.common.util.References;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -18,12 +17,9 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@Mod.EventBusSubscriber( modid = SpecialMobs.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE )
|
||||
public final class SpecialMobReplacer {
|
||||
/** List of data for mobs needing replacement. */
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.core;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,7 @@
|
|||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
package fathertoast.specialmobs.common.core.register;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
Loading…
Add table
Reference in a new issue