diff --git a/src/main/java/fathertoast/specialmobs/client/ClientRegister.java b/src/main/java/fathertoast/specialmobs/client/ClientRegister.java index d368602..99a5d5d 100644 --- a/src/main/java/fathertoast/specialmobs/client/ClientRegister.java +++ b/src/main/java/fathertoast/specialmobs/client/ClientRegister.java @@ -8,6 +8,7 @@ import fathertoast.specialmobs.client.renderer.entity.species.*; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.config.Config; import fathertoast.specialmobs.common.core.SpecialMobs; +import fathertoast.specialmobs.common.core.register.SMBlocks; import fathertoast.specialmobs.common.core.register.SMEntities; import fathertoast.specialmobs.common.entity.creeper.EnderCreeperEntity; import fathertoast.specialmobs.common.entity.enderman.RunicEndermanEntity; @@ -20,6 +21,8 @@ import fathertoast.specialmobs.common.entity.zombie.MadScientistZombieEntity; import fathertoast.specialmobs.common.entity.zombifiedpiglin.VampireZombifiedPiglinEntity; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.renderer.entity.SpriteRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -43,6 +46,8 @@ public class ClientRegister { @SubscribeEvent public static void onClientSetup( FMLClientSetupEvent event ) { + RenderTypeLookup.setRenderLayer( SMBlocks.MELTING_ICE.get(), RenderType.translucent() ); + if( Config.MAIN.GENERAL.fancyFishingMobs.get() ) { ItemModelsProperties.register( Items.FISHING_ROD, new ResourceLocation( "cast" ), new FishingRodItemPropertyGetter() ); } diff --git a/src/main/java/fathertoast/specialmobs/common/bestiary/BestiaryInfo.java b/src/main/java/fathertoast/specialmobs/common/bestiary/BestiaryInfo.java index b0764f3..b93e98e 100644 --- a/src/main/java/fathertoast/specialmobs/common/bestiary/BestiaryInfo.java +++ b/src/main/java/fathertoast/specialmobs/common/bestiary/BestiaryInfo.java @@ -43,16 +43,31 @@ public class BestiaryInfo { NONE( new EnvironmentList() ), FIRE( new EnvironmentList( EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inUltraWarmDimension().build(), - EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).isRaining().canSeeSky().notInDryBiome().build(), EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).isHot().build(), EnvironmentEntry.builder( DefaultWeight.HIGH.value ).isWarm().build(), - EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).isFreezing().build() + EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).isFreezing().build(), + // Regular frozen ocean is actually freezing, so already covered + EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inBiome( Biomes.WARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inBiome( Biomes.DEEP_WARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.HIGH.value ).inBiome( Biomes.LUKEWARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.HIGH.value ).inBiome( Biomes.DEEP_LUKEWARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOW.value ).inBiome( Biomes.COLD_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOW.value ).inBiome( Biomes.DEEP_COLD_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).inBiome( Biomes.DEEP_FROZEN_OCEAN ).build() ) ), ICE( new EnvironmentList( EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).inUltraWarmDimension().build(), EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).isFreezing().build(), EnvironmentEntry.builder( DefaultWeight.LOW.value ).isWarm().build(), - EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).isHot().build() + EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).isHot().build(), + // Regular frozen ocean is actually freezing, so already covered + EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inBiome( Biomes.DEEP_FROZEN_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.HIGH.value ).inBiome( Biomes.COLD_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.HIGH.value ).inBiome( Biomes.DEEP_COLD_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOW.value ).inBiome( Biomes.LUKEWARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOW.value ).inBiome( Biomes.DEEP_LUKEWARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).inBiome( Biomes.WARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.LOWEST.value ).inBiome( Biomes.DEEP_WARM_OCEAN ).build() ) ), DESERT( new EnvironmentList( EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inUltraWarmDimension().build(), @@ -89,6 +104,13 @@ public class BestiaryInfo { EnvironmentEntry.builder( DefaultWeight.HIGH.value ).isRaining().build(), EnvironmentEntry.builder( DefaultWeight.LOW.value ).cannotSeeSky().build() ) ), + TROPICAL( new EnvironmentList( + // All ocean biomes (except regular frozen ocean) have the same temp of 0.5, so we must call out specific biomes + EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inBiome( Biomes.WARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inBiome( Biomes.DEEP_WARM_OCEAN ).build(), + EnvironmentEntry.builder( DefaultWeight.DISABLED.value ).isFreezing().build(), + EnvironmentEntry.builder( DefaultWeight.DISABLED.value ).inBiome( Biomes.DEEP_FROZEN_OCEAN ).build() + ) ), FISHING( new EnvironmentList( EnvironmentEntry.builder( DefaultWeight.HIGHEST.value ).inWaterBiome().build(), EnvironmentEntry.builder( DefaultWeight.HIGH.value ).atMaxMoonLight().build(), diff --git a/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java b/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java index d4db547..be5c9bf 100644 --- a/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java +++ b/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java @@ -13,6 +13,7 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.monster.*; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraftforge.common.ForgeSpawnEggItem; import net.minecraftforge.fml.RegistryObject; @@ -20,6 +21,7 @@ import net.minecraftforge.fml.RegistryObject; import javax.annotation.Nullable; import java.util.*; import java.util.function.Function; +import java.util.function.Predicate; /** * Special mobs are broken up into distinct 'families', each of which correspond to a type of vanilla mob that can be @@ -42,7 +44,7 @@ public class MobFamily { "Creeper", "creepers", 0x0DA70B, new EntityType[] { EntityType.CREEPER }, "Dark", "Death", "Dirt", "Doom", "Drowning", "Ender", "Fire", "Gravel", "Jumping", "Lightning", "Mini", "Sand", /*"Scope",*/ "Snow", "Skeleton", "Splitting" - );//TODO scope + );//TODO scope - maybe in 1.18 when spyglasses exist public static final MobFamily ZOMBIE = new MobFamily<>( FamilyConfig::newLessSpecial, "Zombie", "zombies", 0x00AFAF, new EntityType[] { EntityType.ZOMBIE, EntityType.HUSK }, @@ -50,12 +52,12 @@ public class MobFamily { ); public static final MobFamily DROWNED = new MobFamily<>( FamilyConfig::new, "Drowned", "drowned", 0x8FF1D7, new EntityType[] { EntityType.DROWNED }, - "Abyssal", "Brute", "Fishing", /*"Frozen",*/ "Giant", "Hungry", "Knight", "Plague"//, "Tropical" - ); //TODO Textures! - brute, hungry, plague, frozen, tropical + "Abyssal", "Brute", "Fishing", "Frozen", "Giant", "Hungry", "Knight", "Plague"//, "Tropical" + ); public static final MobFamily ZOMBIFIED_PIGLIN = new MobFamily<>( FamilyConfig::new, "ZombifiedPiglin", "zombified piglins", 0xEA9393, new EntityType[] { EntityType.ZOMBIFIED_PIGLIN }, "Brute", "Fishing", "Giant", "Hungry", "Knight", "Plague", "Vampire"//TODO figure out crossbows - ); + );//TODO crimson/warped public static final MobFamily SKELETON = new MobFamily<>( SkeletonFamilyConfig::new, "Skeleton", "skeletons", 0xC1C1C1, new EntityType[] { EntityType.SKELETON, EntityType.STRAY }, @@ -64,7 +66,7 @@ public class MobFamily { public static final MobFamily WITHER_SKELETON = new MobFamily<>( SkeletonFamilyConfig::new, "WitherSkeleton", "wither skeletons", 0x141414, new EntityType[] { EntityType.WITHER_SKELETON }, "Brute", "Gatling", "Giant", "Knight", "Ninja", "Sniper", "Spitfire" - ); + );//TODO crimson/warped public static final MobFamily SLIME = new MobFamily<>( SlimeFamilyConfig::new, "Slime", "slimes", 0x51A03E, new EntityType[] { EntityType.SLIME }, @@ -96,8 +98,8 @@ public class MobFamily { public static final MobFamily WITCH = new MobFamily<>( WitchFamilyConfig::new, "Witch", "witches", 0x340000, new EntityType[] { EntityType.WITCH }, - "Domination", "Shadows", "Undead", "Wilds", "Wind" - ); + /*"Burned",*/ "Domination", /*"Drowned", "Ice", "Sands",*/ "Shadows", "Undead", "Wilds", "Wind" + );//TODO burned, drowned, ice, sands public static final MobFamily GHAST = new MobFamily<>( GhastFamilyConfig::new, "Ghast", "ghasts", 0xF9F9F9, new EntityType[] { EntityType.GHAST }, @@ -169,6 +171,9 @@ public class MobFamily { /** This family's config. */ public final V config; + /** True if this family has any giant species. */ + private Boolean hasAnyGiants; + private MobFamily( Function, V> configSupplier, String familyName, String readableName, int eggColor, EntityType[] replaceable, String... variantNames ) { @@ -196,17 +201,34 @@ public class MobFamily { } /** Pick a new species from this family, based on the location. */ - public Species nextVariant( World world, @Nullable BlockPos pos ) { - return nextVariant( world, pos, null, vanillaReplacement ); + public Species nextVariant( World world, @Nullable BlockPos pos, @Nullable Predicate> selector ) { + return nextVariant( world, pos, selector, vanillaReplacement ); } /** Pick a new species from this family, based on the location. */ - public Species nextVariant( World world, @Nullable BlockPos pos, @Nullable Function, Boolean> selector, Species fallback ) { + public Species nextVariant( World world, @Nullable BlockPos pos, @Nullable Predicate> selector, Species fallback ) { final Species species = config.GENERAL.specialVariantList.next( world.random, world, pos, selector ); //noinspection unchecked return species == null ? fallback : (Species) species; } + /** + * @return True if this species is NOT taller (in block height) than the base vanilla entity. + * Used to reduce likelihood of suffocation due to Mob Replacement. + */ + public boolean hasAnyGiants() { + if( hasAnyGiants == null ) { + hasAnyGiants = false; + for( Species species : variants ) { + if( !species.isNotGiant() ) { + hasAnyGiants = true; + break; + } + } + } + return hasAnyGiants; + } + //--------------- Species Instance Implementations ---------------- @@ -250,6 +272,8 @@ public class MobFamily { /** This species's config. */ public final SpeciesConfig config; + /** True if this mob is NOT taller (in block height) than the base vanilla entity. */ + private Boolean isNotGiant; /** The scale of this species's height in relation to the base vanilla entity's height. */ private float heightScale = -1.0F; @@ -331,6 +355,17 @@ public class MobFamily { ConfigUtil.camelCaseToLowerSpace( specialVariantName ) + " ") + ConfigUtil.camelCaseToLowerSpace( family.name ); } + /** + * @return True if this species is NOT taller (in block height) than the base vanilla entity. + * Used to reduce likelihood of suffocation due to Mob Replacement. + */ + public boolean isNotGiant() { + if( isNotGiant == null ) { + isNotGiant = MathHelper.ceil( entityType.get().getHeight() ) <= MathHelper.ceil( family.replaceableTypes[0].getHeight() ); + } + return isNotGiant; + } + /** @return The height scale. Used to calculate eye height for families that are not auto-scaled. */ public float getHeightScale() { if( heightScale < 0.0F ) { diff --git a/src/main/java/fathertoast/specialmobs/common/block/MeltingIceBlock.java b/src/main/java/fathertoast/specialmobs/common/block/MeltingIceBlock.java new file mode 100644 index 0000000..94a8d71 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/block/MeltingIceBlock.java @@ -0,0 +1,178 @@ +package fathertoast.specialmobs.common.block; + +import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.core.register.SMBlocks; +import fathertoast.specialmobs.common.util.References; +import net.minecraft.block.*; +import net.minecraft.block.material.Material; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.state.BooleanProperty; +import net.minecraft.state.IntegerProperty; +import net.minecraft.state.StateContainer; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.stats.Stats; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.LightType; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; + +import javax.annotation.Nullable; +import java.util.Random; + +public class MeltingIceBlock extends IceBlock { + + @SpecialMob.LanguageProvider + public static String[] getTranslations( String langKey ) { + return References.translations( langKey, "Melting Ice", + "", "", "", "", "", "" );//TODO + } + + /** @return The state that should be placed. */ + public static BlockState getState( World world, BlockPos pos ) { + final BlockState currentBlock = world.getBlockState( pos ); + return SMBlocks.MELTING_ICE.get().defaultBlockState().setValue( HAS_WATER, + currentBlock.is( Blocks.FROSTED_ICE ) || + currentBlock.getBlock() == Blocks.WATER && currentBlock.getValue( FlowingFluidBlock.LEVEL ) == 0 ); + } + + /** Call this after placing a melting ice block to trigger its melting logic. */ + public static void scheduleFirstTick( World world, BlockPos pos, Random random ) { + world.getBlockTicks().scheduleTick( pos, SMBlocks.MELTING_ICE.get(), MathHelper.nextInt( random, 60, 120 ) ); + } + + /** Called after each melt logic tick to schedule the next tick. */ + private void scheduleTick( World world, BlockPos pos, Random random ) { + final int darkness = 15 - getLight( world, pos ); + + int solidNeighbors = 0; + final BlockPos.Mutable neighborPos = new BlockPos.Mutable(); + for( Direction direction : Direction.Plane.HORIZONTAL ) { + if( world.getBlockState( neighborPos.setWithOffset( pos, direction ) ).getMaterial().isSolid() ) { + solidNeighbors++; + } + } + + // The 'neutral' state is 0 block light and 0 solid neighbors - this gives the same tick rate as frosted ice (1-2s) + // Max delay is same as the default 'first tick' delay (3-6s) + final int delay = 5 + darkness + 10 * solidNeighbors; + world.getBlockTicks().scheduleTick( pos, this, MathHelper.nextInt( random, delay, delay << 1 ) ); + } + + /** @return The light level touching this block (0-15). We use this method because the block is solid. */ + private static int getLight( World world, BlockPos pos ) { + int highestLight = 0; + final BlockPos.Mutable neighborPos = new BlockPos.Mutable(); + for( Direction direction : Direction.values() ) { + final int neighborLight = world.getBrightness( LightType.BLOCK, neighborPos.setWithOffset( pos, direction ) ); + if( neighborLight > 14 ) return 15; + if( neighborLight > highestLight ) highestLight = neighborLight; + } + return highestLight; + } + + public static final IntegerProperty AGE = BlockStateProperties.AGE_3; + public static final BooleanProperty HAS_WATER = BooleanProperty.create( "has_water" ); + + public MeltingIceBlock() { + super( AbstractBlock.Properties.of( Material.ICE ).sound( SoundType.GLASS ).noOcclusion() + .randomTicks().friction( 0.98F ).strength( 0.5F ) ); + registerDefaultState( stateDefinition.any().setValue( AGE, 0 ).setValue( HAS_WATER, true ) ); + } + + @Override + protected void createBlockStateDefinition( StateContainer.Builder builder ) { + builder.add( AGE ).add( HAS_WATER ); + } + + @SuppressWarnings( "deprecation" ) + @Override + public ItemStack getCloneItemStack( IBlockReader world, BlockPos pos, BlockState state ) { return ItemStack.EMPTY; } + + @Override + public void playerDestroy( World world, PlayerEntity player, BlockPos pos, BlockState state, + @Nullable TileEntity tileEntity, ItemStack tool ) { + player.awardStat( Stats.BLOCK_MINED.get( this ) ); + player.causeFoodExhaustion( 0.005F ); + dropResources( state, world, pos, tileEntity, player, tool ); + + if( EnchantmentHelper.getItemEnchantmentLevel( Enchantments.SILK_TOUCH, tool ) == 0 ) { + melt( state, world, pos ); + } + } + + @Override + public void randomTick( BlockState state, ServerWorld world, BlockPos pos, Random random ) { tick( state, world, pos, random ); } + + @SuppressWarnings( "deprecation" ) + @Override + public void tick( BlockState state, ServerWorld world, BlockPos pos, Random random ) { + if( canMelt( world, pos ) ) { + if( slightlyMelt( state, world, pos, random ) ) { + final BlockPos.Mutable neighborPos = new BlockPos.Mutable(); + trySlightlyMelt( world, neighborPos.setWithOffset( pos, Direction.DOWN ), random ); + for( Direction direction : Direction.Plane.HORIZONTAL ) { + trySlightlyMelt( world, neighborPos.setWithOffset( pos, direction ), random ); + } + } + } + else scheduleTick( world, pos, random ); + } + + /** @return True if the conditions allow melting. */ + private boolean canMelt( World world, BlockPos pos ) { + // If a bright-ish (torch or higher) light source is nearby, always allow melting + if( getLight( world, pos ) > 13 ) return true; + + // Otherwise, we want to prevent melting in two specific cases to get our desired melting pattern: + // * surrounded by other melting ice blocks horizontally (outside-in for ice floors/ceilings) + // * block below is non-air and block above is another melting ice block (top-down for ice walls) + final BlockPos.Mutable neighborPos = new BlockPos.Mutable(); + for( Direction direction : Direction.Plane.HORIZONTAL ) { + if( !world.getBlockState( neighborPos.setWithOffset( pos, direction ) ).is( this ) ) { + //noinspection deprecation + return !world.getBlockState( neighborPos.setWithOffset( pos, Direction.UP ) ).is( this ) || + world.getBlockState( neighborPos.setWithOffset( pos, Direction.DOWN ) ).isAir(); + } + } + return false; + } + + /** Attempts to slightly melt a target block. */ + private void trySlightlyMelt( World world, BlockPos pos, Random random ) { + final BlockState state = world.getBlockState( pos ); + if( state.is( this ) && canMelt( world, pos ) ) slightlyMelt( state, world, pos, random ); + } + + /** @return Increments the block's melting and returns true if the block was completely melted. */ + private boolean slightlyMelt( BlockState state, World world, BlockPos pos, Random random ) { + int age = state.getValue( AGE ); + if( age < 3 ) { + world.setBlock( pos, state.setValue( AGE, age + 1 ), References.SetBlockFlags.UPDATE_CLIENT ); + scheduleTick( world, pos, random ); + return false; + } + else { + melt( state, world, pos ); + return true; + } + } + + /** Melts the ice block. */ + @Override + protected void melt( BlockState state, World world, BlockPos pos ) { + if( world.dimensionType().ultraWarm() || !state.getValue( HAS_WATER ) ) { + world.removeBlock( pos, false ); + } + else { + world.setBlockAndUpdate( pos, Blocks.WATER.defaultBlockState() ); + world.neighborChanged( pos, Blocks.WATER, pos ); + } + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/block/UnderwaterSilverfishBlock.java b/src/main/java/fathertoast/specialmobs/common/block/UnderwaterSilverfishBlock.java new file mode 100644 index 0000000..0b38161 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/block/UnderwaterSilverfishBlock.java @@ -0,0 +1,99 @@ +package fathertoast.specialmobs.common.block; + +import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.core.register.SMBlocks; +import fathertoast.specialmobs.common.entity.silverfish.PufferSilverfishEntity; +import fathertoast.specialmobs.common.util.References; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.block.SilverfishBlock; +import net.minecraft.block.material.Material; +import net.minecraft.entity.monster.SilverfishEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.server.ServerWorld; + +import java.util.Random; +import java.util.function.Function; + +/** + * A variation of the regular silverfish block intended for placement under water. + * Contains a puffer silverfish instead of a vanilla one. + */ +public class UnderwaterSilverfishBlock extends SilverfishBlock { + + public enum Type { + TUBE( "tube", Blocks.TUBE_CORAL_BLOCK, + ( langKey ) -> References.translations( langKey, "Infested Tube Coral Block", + "", "", "", "", "", "" ) ),//TODO + + BRAIN( "brain", Blocks.BRAIN_CORAL_BLOCK, + ( langKey ) -> References.translations( langKey, "Infested Brain Coral Block", + "", "", "", "", "", "" ) ),//TODO + + BUBBLE( "bubble", Blocks.BUBBLE_CORAL_BLOCK, + ( langKey ) -> References.translations( langKey, "Infested Bubble Coral Block", + "", "", "", "", "", "" ) ),//TODO + + FIRE( "fire", Blocks.FIRE_CORAL_BLOCK, + ( langKey ) -> References.translations( langKey, "Infested Fire Coral Block", + "", "", "", "", "", "" ) ),//TODO + + HORN( "horn", Blocks.HORN_CORAL_BLOCK, + ( langKey ) -> References.translations( langKey, "Infested Horn Coral Block", + "", "", "", "", "", "" ) );//TODO + + private final String ID; + private final Block HOST_BLOCK; + private final Function TRANSLATIONS; + + Type( String id, Block hostBlock, Function translations ) { + ID = id; + HOST_BLOCK = hostBlock; + TRANSLATIONS = translations; + } + + /** @return The block id for this underwater silverfish block type. */ + public String blockId() { return "infested_" + ID + "_coral_block"; } + + /** @return A new underwater silverfish block for this type. */ + public Block blockSupplier() { return new UnderwaterSilverfishBlock( HOST_BLOCK ); } + + /** @return The 'host block' of this type; that is, the block this type imitates. */ + public Block hostBlock() { return HOST_BLOCK; } + + /** @return The 'infested block' of this type; that is, the actual silverfish block. */ + public Block block() { return SMBlocks.INFESTED_CORAL.get( ordinal() ).get(); } + + /** @return The translations of this type. */ + private String[] getTranslations( String langKey ) { return TRANSLATIONS.apply( langKey ); } + + /** @return Looks up and returns the translations for the type lang key. */ + private static String[] getTranslationsFor( String langKey ) { + for( Type type : values() ) { + if( langKey.contains( type.ID ) ) return type.getTranslations( langKey ); + } + // This will cause the lang provider to throw an exception for us + return References.translations( langKey, "", "", "", "", "", "", "" ); + } + + /** @return A random underwater silverfish block type. */ + public static Type next( Random random ) { return values()[random.nextInt( values().length )]; } + } + + @SpecialMob.LanguageProvider + public static String[] getTranslations( String langKey ) { return Type.getTranslationsFor( langKey ); } + + public UnderwaterSilverfishBlock( Block block ) { + super( block, Properties.of( Material.CLAY ).strength( 0.0F, 0.75F ) ); + } + + @Override + protected void spawnInfestation( ServerWorld world, BlockPos pos ) { + final SilverfishEntity silverfish = PufferSilverfishEntity.SPECIES.entityType.get().create( world ); + if( silverfish == null ) return; + + silverfish.moveTo( pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0.0F, 0.0F ); + world.addFreshEntity( silverfish ); + silverfish.spawnAnim(); + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/block/package-info.java b/src/main/java/fathertoast/specialmobs/common/block/package-info.java new file mode 100644 index 0000000..2135102 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/block/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package fathertoast.specialmobs.common.block; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/config/field/DoubleField.java b/src/main/java/fathertoast/specialmobs/common/config/field/DoubleField.java index 70e16fd..8d254b3 100644 --- a/src/main/java/fathertoast/specialmobs/common/config/field/DoubleField.java +++ b/src/main/java/fathertoast/specialmobs/common/config/field/DoubleField.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.List; import java.util.Random; import java.util.function.Function; +import java.util.function.Predicate; /** * Represents a config field with a double value. @@ -219,13 +220,13 @@ public class DoubleField extends AbstractConfigField { /** @return Returns a random item from this weighted list. Null if none of the items have a positive weight. */ @Nullable - public T next( Random random, World world, @Nullable BlockPos pos, @Nullable Function selector ) { + public T next( Random random, World world, @Nullable BlockPos pos, @Nullable Predicate selector ) { // Due to the 'nebulous' nature of environment-based weights, we must recalculate weights for EVERY call final double[] weights = new double[UNDERLYING_LIST.size()]; double targetWeight = 0.0; for( int i = 0; i < weights.length; i++ ) { final Entry entry = UNDERLYING_LIST.get( i ); - if( selector == null || selector.apply( entry.VALUE ) ) { + if( selector == null || selector.test( entry.VALUE ) ) { targetWeight += weights[i] = entry.WEIGHT.get( world, pos ); } } diff --git a/src/main/java/fathertoast/specialmobs/common/config/species/CorporealShiftGhastSpeciesConfig.java b/src/main/java/fathertoast/specialmobs/common/config/species/CorporealShiftGhastSpeciesConfig.java new file mode 100644 index 0000000..dcb3dce --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/config/species/CorporealShiftGhastSpeciesConfig.java @@ -0,0 +1,38 @@ +package fathertoast.specialmobs.common.config.species; + +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.config.Config; +import fathertoast.specialmobs.common.config.field.IntField; +import fathertoast.specialmobs.common.config.file.ToastConfigSpec; +import fathertoast.specialmobs.common.config.util.ConfigUtil; + +public class CorporealShiftGhastSpeciesConfig extends SpeciesConfig { + + public final CorporealShift CORPOREAL_SHIFT; + + /** Builds the config spec that should be used for this config. */ + public CorporealShiftGhastSpeciesConfig( MobFamily.Species species, int corporealTime, int incorporealTime ) { + super( species ); + + CORPOREAL_SHIFT = new CorporealShift( SPEC, species, species.getConfigName(), corporealTime, incorporealTime ); + } + + public static class CorporealShift extends Config.AbstractCategory { + + public final IntField corporealTicks; + public final IntField incorporealTicks; + + CorporealShift( ToastConfigSpec parent, MobFamily.Species species, String speciesName, + int corporealTime, int incorporealTime ) { + super( parent, ConfigUtil.camelCaseToLowerUnderscore( species.specialVariantName ), + "Options specific to " + speciesName + "." ); + + corporealTicks = SPEC.define( new IntField( "ticks.corporeal", corporealTime, IntField.Range.NON_NEGATIVE, + "The number of ticks " + speciesName + " stay in 'corporeal' mode before shifting (20 ticks = 1 second).", + "In corporeal mode, " + speciesName + " can be damaged and shoot like normal " + species.family.configName + "." ) ); + incorporealTicks = SPEC.define( new IntField( "ticks.incorporeal", incorporealTime, IntField.Range.NON_NEGATIVE, + "The number of ticks " + speciesName + " stay in 'incorporeal' mode before shifting (20 ticks = 1 second).", + "In incorporeal mode, " + speciesName + " are immune to damage and shoot unique fireballs that punish movement." ) ); + } + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/config/species/DrowningCreeperSpeciesConfig.java b/src/main/java/fathertoast/specialmobs/common/config/species/DrowningCreeperSpeciesConfig.java new file mode 100644 index 0000000..220305d --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/config/species/DrowningCreeperSpeciesConfig.java @@ -0,0 +1,47 @@ +package fathertoast.specialmobs.common.config.species; + +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.config.Config; +import fathertoast.specialmobs.common.config.field.DoubleField; +import fathertoast.specialmobs.common.config.field.IntField; +import fathertoast.specialmobs.common.config.file.ToastConfigSpec; +import fathertoast.specialmobs.common.config.util.ConfigUtil; + +public class DrowningCreeperSpeciesConfig extends CreeperSpeciesConfig { + + public final Drowning DROWNING; + + /** Builds the config spec that should be used for this config. */ + public DrowningCreeperSpeciesConfig( MobFamily.Species species, + boolean cannotExplodeWhileWet, boolean explodeWhileBurning, boolean explodeWhenShot, + double infestedChance, int minPuffPuffs, int maxPuffPuffs ) { + super( species, cannotExplodeWhileWet, explodeWhileBurning, explodeWhenShot ); + + DROWNING = new Drowning( SPEC, species, species.getConfigName(), infestedChance, minPuffPuffs, maxPuffPuffs ); + } + + public static class Drowning extends Config.AbstractCategory { + + public final DoubleField infestedBlockChance; + + public final IntField.RandomRange puffPuffs; + + Drowning( ToastConfigSpec parent, MobFamily.Species species, String speciesName, + double infestedChance, int minPuffPuffs, int maxPuffPuffs ) { + super( parent, ConfigUtil.camelCaseToLowerUnderscore( species.specialVariantName ), + "Options specific to " + speciesName + "." ); + + infestedBlockChance = SPEC.define( new DoubleField( "infested_chance", infestedChance, DoubleField.Range.PERCENT, + "Chance for explosion's coral shell blocks to be infested with aquatic silverfish.", + "Rolled for each coral block generated." ) ); + + SPEC.newLine(); + + puffPuffs = new IntField.RandomRange( + SPEC.define( new IntField( "pufferfish.min", minPuffPuffs, IntField.Range.NON_NEGATIVE, + "The minimum and maximum (inclusive) limit on the number of pufferfish that " + speciesName + " spawn with their explosion." ) ), + SPEC.define( new IntField( "pufferfish.max", maxPuffPuffs, IntField.Range.NON_NEGATIVE ) ) + ); + } + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/config/species/SnowCreeperSpeciesConfig.java b/src/main/java/fathertoast/specialmobs/common/config/species/SnowCreeperSpeciesConfig.java new file mode 100644 index 0000000..8bb4e7d --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/config/species/SnowCreeperSpeciesConfig.java @@ -0,0 +1,35 @@ +package fathertoast.specialmobs.common.config.species; + +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.config.Config; +import fathertoast.specialmobs.common.config.field.DoubleField; +import fathertoast.specialmobs.common.config.file.ToastConfigSpec; +import fathertoast.specialmobs.common.config.util.ConfigUtil; + +public class SnowCreeperSpeciesConfig extends CreeperSpeciesConfig { + + public final Snow SNOW; + + /** Builds the config spec that should be used for this config. */ + public SnowCreeperSpeciesConfig( MobFamily.Species species, + boolean cannotExplodeWhileWet, boolean explodeWhileBurning, boolean explodeWhenShot, + double globeChance ) { + super( species, cannotExplodeWhileWet, explodeWhileBurning, explodeWhenShot ); + + SNOW = new Snow( SPEC, species, species.getConfigName(), globeChance ); + } + + public static class Snow extends Config.AbstractCategory { + + public final DoubleField snowGlobeChance; + + Snow( ToastConfigSpec parent, MobFamily.Species species, String speciesName, double globeChance ) { + super( parent, ConfigUtil.camelCaseToLowerUnderscore( species.specialVariantName ), + "Options specific to " + speciesName + "." ); + + snowGlobeChance = SPEC.define( new DoubleField( "snow_globe_chance", globeChance, DoubleField.Range.PERCENT, + "Chance for " + speciesName + " to create a snow globe instead of regular walls when exploding.", + "The globe is always chosen if the " + species.getConfigNameSingular() + " is underwater for some reason." ) ); + } + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/core/SpecialMobReplacer.java b/src/main/java/fathertoast/specialmobs/common/core/SpecialMobReplacer.java index d0e75b8..7f19c1a 100644 --- a/src/main/java/fathertoast/specialmobs/common/core/SpecialMobReplacer.java +++ b/src/main/java/fathertoast/specialmobs/common/core/SpecialMobReplacer.java @@ -7,7 +7,10 @@ import fathertoast.specialmobs.common.util.References; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IServerWorld; import net.minecraft.world.World; import net.minecraftforge.event.TickEvent; @@ -19,12 +22,20 @@ import net.minecraftforge.fml.common.Mod; import javax.annotation.Nullable; import java.util.ArrayDeque; import java.util.Deque; +import java.util.function.Predicate; @Mod.EventBusSubscriber( modid = SpecialMobs.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE ) public final class SpecialMobReplacer { /** List of data for mobs needing replacement. */ private static final Deque TO_REPLACE = new ArrayDeque<>(); + /** Returns true if the species is not damaged by water. */ + private static final Predicate> WATER_INSENSITIVE_SELECTOR = + ( species ) -> !species.config.GENERAL.isDamagedByWater.get(); + /** Returns true if the species's block height is less than or equal to the base vanilla entity's. */ + private static final Predicate> NO_GIANTS_SELECTOR = MobFamily.Species::isNotGiant; + + /** * Called when any entity is spawned into the world by any means (such as natural/spawner spawns or chunk loading). *

@@ -123,7 +134,9 @@ public final class SpecialMobReplacer { // Don't copy UUID tag.remove( "UUID" ); - final MobFamily.Species species = isSpecial ? mobFamily.nextVariant( world, entityPos ) : mobFamily.vanillaReplacement; + final MobFamily.Species species = isSpecial ? + mobFamily.nextVariant( world, entityPos, getVariantFilter( mobFamily, entityToReplace, world, entityPos ) ) : + mobFamily.vanillaReplacement; final LivingEntity replacement = species.entityType.get().create( world ); if( replacement == null ) { @@ -149,6 +162,32 @@ public final class SpecialMobReplacer { entityToReplace.remove(); } + /** @return A selector that filters out variants that are likely to die a stupid death if chosen. */ + @Nullable + private static Predicate> getVariantFilter( MobFamily mobFamily, Entity entityToReplace, + World world, BlockPos entityPos ) { + Predicate> selector = null; + + // Note that we do not check for any fluids (water/lava) since that is handled by spawn logic + if( !mobFamily.vanillaReplacement.bestiaryInfo.isDamagedByWater && // Skip this check if the base vanilla mob dies in water + world.isRainingAt( entityPos ) ) { + selector = WATER_INSENSITIVE_SELECTOR; + } + + // Does not consider overly wide mobs or extra-tall (>1 block taller) mobs + if( mobFamily.hasAnyGiants() ) { + final AxisAlignedBB bb = entityToReplace.getBoundingBox(); + final int y = MathHelper.ceil( bb.maxY ); + // Only check the FULL block above current collision - not a perfect representation, but keeps things simple + if( !world.isUnobstructed( entityToReplace, VoxelShapes.create( + new AxisAlignedBB( bb.minX, y, bb.minZ, bb.maxX, y + 1, bb.maxZ ) ) ) ) { + selector = selector == null ? NO_GIANTS_SELECTOR : selector.and( NO_GIANTS_SELECTOR ); + } + } + + return selector; + } + /** All data needed for a single mob we want to replace. */ private static class MobReplacementEntry { final MobFamily mobFamily; diff --git a/src/main/java/fathertoast/specialmobs/common/core/SpecialMobs.java b/src/main/java/fathertoast/specialmobs/common/core/SpecialMobs.java index 1a186fe..2eda36c 100644 --- a/src/main/java/fathertoast/specialmobs/common/core/SpecialMobs.java +++ b/src/main/java/fathertoast/specialmobs/common/core/SpecialMobs.java @@ -2,6 +2,7 @@ package fathertoast.specialmobs.common.core; import fathertoast.specialmobs.common.compat.top.SMTheOneProbe; import fathertoast.specialmobs.common.config.Config; +import fathertoast.specialmobs.common.core.register.SMBlocks; import fathertoast.specialmobs.common.core.register.SMEffects; import fathertoast.specialmobs.common.core.register.SMEntities; import fathertoast.specialmobs.common.core.register.SMItems; @@ -26,56 +27,54 @@ import javax.annotation.Nullable; @Mod( SpecialMobs.MOD_ID ) public class SpecialMobs { - - /* TODO List: - * Reimplement all old features (see list below) - * Utility features: - * - Bestiary - */ - - /* Feature List: //TODO; list may not be complete + /* Feature List: * (KEY: - = complete in current version, o = incomplete feature from previous version, * + = incomplete new feature, ? = feature to consider adding) * - general - * - entity replacer + * - mob replacer * - environment-sensitive configs * - natural spawning * - copied spawns - * - spiders -> cave spiders - * - endermen -> ender creepers + * - vanilla spiders -> vanilla cave spiders + * - vanilla endermen -> ender creepers * - ocean/river spawns * - drowning creepers * - blueberry slimes * - nether spawns - * - wither skeletons (outside of fortresses) - * - blazes (outside of fortresses) + * - vanilla wither skeletons (outside of fortresses) + * - vanilla blazes (outside of fortresses) * - fire creepers/zombies/spiders * ? warped/crimson mobs + * + phantom spawns * - potions * - vulnerability (opposite of resistance) * - weight (opposite of levitation) + * - blocks + * - infested coral (spawns puffer silverfish) + * - melting ice (similar to frosted ice) * - entities - * - nbt-driven capabilities (special mob data) - * - fish hook + * + TODO bestiary + * - configurable, nbt-driven stats (bestiary info + special mob data) + * - configurable weapon type chance + * - bone shrapnel * - bug spit - * + bestiary - * - configurable stats + * - fish hook * - monster families (see doc for specifics) * - creepers * - chance to spawn charged during thunderstorms - * + scope - perhaps delay this until 1.18 where spyglasses will be in the game + * - chance to become supercharged when charged + * - explosion stats (while wet, while burning, when shot) * - zombies * - transformations (husk -> any other non-water-sensitive zombie -> analogous drowned) * - ranged attack AI (using bow) * - use shields * - drowned - * - AI functions in shallow water * - use shields + * - bug fixes (can move in shallow water, alert regular zombies) * - zombified piglins * - ranged attack AI (using bow) * + ranged attack AI (using crossbow) * - use shields - * ? warped/crimson mobs * - skeletons * - use shields * - melee chance @@ -84,7 +83,6 @@ public class SpecialMobs { * - use shields * - bow chance * - babies - * ? warped/crimson mobs * - slimes * - smallest size can deal damage * - magma cubes @@ -94,22 +92,24 @@ public class SpecialMobs { * - ranged attack AI (spitter) * - silverfish * - ranged attack AI (spitter) + * - chance to spawn already calling for reinforcements * - endermen * - witches * - ability to equip held items (wonky) - * - uses splash speed instead of regular + * - use splash speed instead of regular * - ghasts * - melee attack AI + * - remove vertical targeting restriction * - blazes * - melee attack AI - * ? hoglins - * ? zoglins + * - configurable fireball attack * + guardians * + vortex - * ? shulkers * + phantoms - * + natural spawning * + the goat + * ? hoglins + * ? zoglins + * ? shulkers */ /** Our mod ID. */ @@ -130,9 +130,10 @@ public class SpecialMobs { final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); - SMEffects.REGISTRY.register( modEventBus ); - SMEntities.REGISTRY.register( modEventBus ); + SMBlocks.REGISTRY.register( modEventBus ); SMItems.REGISTRY.register( modEventBus ); + SMEntities.REGISTRY.register( modEventBus ); + SMEffects.REGISTRY.register( modEventBus ); modEventBus.addListener( SMEntities::createAttributes ); modEventBus.addListener( this::setup ); @@ -150,6 +151,7 @@ public class SpecialMobs { NaturalSpawnManager.registerSpawnPlacements(); } + @SuppressWarnings( "SpellCheckingInspection" ) public void sendIMCMessages( InterModEnqueueEvent event ) { if( ModList.get().isLoaded( "theoneprobe" ) ) { InterModComms.sendTo( "theoneprobe", "getTheOneProbe", SMTheOneProbe::new ); diff --git a/src/main/java/fathertoast/specialmobs/common/core/register/SMBlocks.java b/src/main/java/fathertoast/specialmobs/common/core/register/SMBlocks.java new file mode 100644 index 0000000..f9612e1 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/core/register/SMBlocks.java @@ -0,0 +1,49 @@ +package fathertoast.specialmobs.common.core.register; + +import fathertoast.specialmobs.common.block.MeltingIceBlock; +import fathertoast.specialmobs.common.block.UnderwaterSilverfishBlock; +import fathertoast.specialmobs.common.core.SpecialMobs; +import net.minecraft.block.Block; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + +public class SMBlocks { + /** The deferred register for this mod's blocks. */ + public static final DeferredRegister REGISTRY = DeferredRegister.create( ForgeRegistries.BLOCKS, SpecialMobs.MOD_ID ); + + public static final RegistryObject MELTING_ICE = registerTechnicalBlock( "melting_ice", MeltingIceBlock::new ); + + public static final List> INFESTED_CORAL; + + static { + final ArrayList> infestedCoral = new ArrayList<>(); + for( UnderwaterSilverfishBlock.Type type : UnderwaterSilverfishBlock.Type.values() ) { + infestedCoral.add( registerBlock( type.blockId(), type::blockSupplier, ItemGroup.TAB_DECORATIONS ) ); + } + infestedCoral.trimToSize(); + INFESTED_CORAL = Collections.unmodifiableList( infestedCoral ); + } + + /** Registers a block and a simple BlockItem for it. */ + private static RegistryObject registerBlock( String name, Supplier blockSupplier, ItemGroup itemGroup ) { + final RegistryObject blockRegObject = REGISTRY.register( name, blockSupplier ); + SMItems.REGISTRY.register( name, () -> new BlockItem( blockRegObject.get(), new Item.Properties().tab( itemGroup ) ) ); + return blockRegObject; + } + + /** Registers a technical block (not visible in the creative menu) and a simple BlockItem for it. */ + private static RegistryObject registerTechnicalBlock( String name, Supplier blockSupplier ) { + final RegistryObject blockRegObject = REGISTRY.register( name, blockSupplier ); + SMItems.REGISTRY.register( name, () -> new BlockItem( blockRegObject.get(), new Item.Properties() ) ); + return blockRegObject; + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/entity/MobHelper.java b/src/main/java/fathertoast/specialmobs/common/entity/MobHelper.java index ea18dcb..f6b90de 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/MobHelper.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/MobHelper.java @@ -26,10 +26,7 @@ import net.minecraft.potion.Effects; import net.minecraft.tags.FluidTags; import net.minecraft.tags.ITag; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.DamageSource; -import net.minecraft.util.Hand; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvents; +import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.shapes.ISelectionContext; @@ -38,6 +35,8 @@ import net.minecraft.world.Difficulty; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.IServerWorld; import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.entity.living.LivingKnockBackEvent; import javax.annotation.Nullable; @@ -552,4 +551,41 @@ public final class MobHelper { } } } + + /** @return Attempts to place a block, firing the appropriate Forge event. Returns true if successful. */ + public static boolean placeBlock( Entity entity, BlockPos pos, BlockState block ) { + return placeBlock( entity, pos, block, References.SetBlockFlags.DEFAULTS ); + } + + /** @return Attempts to place a block, firing the appropriate Forge event. Returns true if successful. */ + public static boolean placeBlock( Entity entity, BlockPos pos, Direction direction, BlockState block ) { + return placeBlock( entity, pos, direction, block, References.SetBlockFlags.DEFAULTS ); + } + + /** @return Attempts to place a block, firing the appropriate Forge event. Returns true if successful. */ + public static boolean placeBlock( Entity entity, BlockPos pos, BlockState block, int updateFlags ) { + return placeBlock( entity, pos, Direction.UP, block, updateFlags ); + } + + /** @return Attempts to place a block, firing the appropriate Forge event. Returns true if successful. */ + public static boolean placeBlock( Entity entity, BlockPos pos, Direction direction, BlockState block, int updateFlags ) { + if( canPlaceBlock( entity, pos, direction ) ) { + entity.level.setBlock( pos, block, updateFlags ); + return true; + } + return false; + } + + // Note to future self - I should probably also make 'destroy block' methods for whatever Forge event those should have, + // generally I do fire mob griefing events already for everything, though + + /** @return Fires the Forge event to check if a block can be placed and returns the result. */ + public static boolean canPlaceBlock( Entity entity, BlockPos pos ) { + return canPlaceBlock( entity, pos, Direction.UP ); + } + + /** @return Fires the Forge event to check if a block can be placed and returns the result. */ + public static boolean canPlaceBlock( Entity entity, BlockPos pos, Direction direction ) { + return !ForgeEventFactory.onBlockPlace( entity, BlockSnapshot.create( entity.level.dimension(), entity.level, pos ), direction ); + } } \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/entity/cavespider/FireCaveSpiderEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/cavespider/FireCaveSpiderEntity.java index b87aede..fdbe18b 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/cavespider/FireCaveSpiderEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/cavespider/FireCaveSpiderEntity.java @@ -3,6 +3,7 @@ package fathertoast.specialmobs.common.entity.cavespider; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; import net.minecraft.block.Blocks; @@ -63,7 +64,7 @@ public class FireCaveSpiderEntity extends _SpecialCaveSpiderEntity { if( !level.isClientSide() ) { final BlockPos pos = target.blockPosition(); if( level.getBlockState( pos ).getMaterial().isReplaceable() ) { - level.setBlock( pos, Blocks.FIRE.defaultBlockState(), References.SetBlockFlags.DEFAULTS ); + MobHelper.placeBlock( this, pos, Blocks.FIRE.defaultBlockState() ); } } target.setSecondsOnFire( 5 ); diff --git a/src/main/java/fathertoast/specialmobs/common/entity/cavespider/WebCaveSpiderEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/cavespider/WebCaveSpiderEntity.java index 59872c3..030b439 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/cavespider/WebCaveSpiderEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/cavespider/WebCaveSpiderEntity.java @@ -5,6 +5,7 @@ import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; import fathertoast.specialmobs.common.config.species.SpeciesConfig; import fathertoast.specialmobs.common.config.species.WebSpiderSpeciesConfig; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; import net.minecraft.block.Blocks; @@ -99,8 +100,8 @@ public class WebCaveSpiderEntity extends _SpecialCaveSpiderEntity { /** @return Attempts to place a cobweb at the given position and returns true if successful. */ private boolean tryPlaceWeb( BlockPos pos ) { - if( level.getBlockState( pos ).getMaterial().isReplaceable() ) { - level.setBlock( pos, Blocks.COBWEB.defaultBlockState(), References.SetBlockFlags.DEFAULTS ); + if( level.getBlockState( pos ).getMaterial().isReplaceable() && + MobHelper.placeBlock( this, pos, Blocks.COBWEB.defaultBlockState() ) ) { webCount--; return true; } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/creeper/DirtCreeperEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/creeper/DirtCreeperEntity.java index 0f3d291..291c41a 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/creeper/DirtCreeperEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/creeper/DirtCreeperEntity.java @@ -3,6 +3,7 @@ package fathertoast.specialmobs.common.entity.creeper; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.util.ExplosionHelper; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; @@ -78,7 +79,7 @@ public class DirtCreeperEntity extends _SpecialCreeperEntity { if( x * x + y * y + z * z <= radius * radius ) { final BlockPos pos = center.offset( x, y, z ); if( level.getBlockState( pos ).getMaterial().isReplaceable() ) { - level.setBlock( pos, dirt, References.SetBlockFlags.DEFAULTS ); + MobHelper.placeBlock( this, pos, dirt ); } } } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/creeper/DrowningCreeperEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/creeper/DrowningCreeperEntity.java index 3fb757d..092652d 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/creeper/DrowningCreeperEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/creeper/DrowningCreeperEntity.java @@ -3,10 +3,13 @@ package fathertoast.specialmobs.common.entity.creeper; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.block.UnderwaterSilverfishBlock; +import fathertoast.specialmobs.common.config.species.DrowningCreeperSpeciesConfig; import fathertoast.specialmobs.common.config.species.SpeciesConfig; import fathertoast.specialmobs.common.config.util.EnvironmentEntry; import fathertoast.specialmobs.common.config.util.EnvironmentList; import fathertoast.specialmobs.common.config.util.environment.biome.BiomeCategory; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.entity.ai.AIHelper; import fathertoast.specialmobs.common.entity.ai.AmphibiousMovementController; import fathertoast.specialmobs.common.entity.ai.IAmphibiousMob; @@ -38,6 +41,7 @@ import net.minecraft.world.IServerWorld; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; import java.util.Random; @@ -60,12 +64,19 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp @SpecialMob.ConfigSupplier public static SpeciesConfig createConfig( MobFamily.Species species ) { SpeciesConfig.NEXT_NATURAL_SPAWN_CHANCE_EXCEPTIONS = new EnvironmentList( + EnvironmentEntry.builder( 0.06F ).inBiome( Biomes.WARM_OCEAN ).build(), + EnvironmentEntry.builder( 0.06F ).inBiome( Biomes.DEEP_WARM_OCEAN ).build(), EnvironmentEntry.builder( 0.06F ).inBiomeCategory( BiomeCategory.RIVER ).build(), EnvironmentEntry.builder( 0.02F ).inBiomeCategory( BiomeCategory.OCEAN ).belowSeaDepths().build(), EnvironmentEntry.builder( 0.0F ).inBiomeCategory( BiomeCategory.OCEAN ).build() ); - return _SpecialCreeperEntity.createConfig( species ); + return new DrowningCreeperSpeciesConfig( species, false, false, false, + 0.25, 2, 4 ); } + /** @return This entity's species config. */ + @Override + public DrowningCreeperSpeciesConfig getConfig() { return (DrowningCreeperSpeciesConfig) getSpecies().config; } + @SpecialMob.SpawnPlacementRegistrar public static void registerSpeciesSpawnPlacement( MobFamily.Species species ) { NaturalSpawnManager.registerSpawnPlacement( species, EntitySpawnPlacementRegistry.PlacementType.IN_WATER, @@ -114,6 +125,9 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp //--------------- Variant-Specific Implementations ---------------- + /** The maximum number of pufferfish spawned on explosion. */ + private int pufferfish; + public DrowningCreeperEntity( EntityType entityType, World world ) { super( entityType, world ); moveControl = new AmphibiousMovementController<>( this ); @@ -121,6 +135,8 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp groundNavigation = new GroundPathNavigator( this, world ); maxUpStep = 1.0F; setPathfindingMalus( PathNodeType.WATER, PathNodeType.WALKABLE.getMalus() ); + + pufferfish = getConfig().DROWNING.puffPuffs.next( random ); } /** Override to change this entity's AI goals. */ @@ -147,17 +163,23 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp if( explosionMode == Explosion.Mode.NONE ) return; - final BlockState brainCoral = Blocks.BRAIN_CORAL_BLOCK.defaultBlockState(); - final BlockState hornCoral = Blocks.HORN_CORAL_BLOCK.defaultBlockState(); + final UnderwaterSilverfishBlock.Type mainType = UnderwaterSilverfishBlock.Type.next( random ); + final UnderwaterSilverfishBlock.Type rareType = UnderwaterSilverfishBlock.Type.next( random ); + final BlockState mainCoral = mainType.hostBlock().defaultBlockState(); + final BlockState rareCoral = rareType.hostBlock().defaultBlockState(); + final BlockState mainInfestedCoral = mainType.block().defaultBlockState(); + final BlockState rareInfestedCoral = rareType.block().defaultBlockState(); + final BlockState water = Blocks.WATER.defaultBlockState(); final BlockState seaPickle = Blocks.SEA_PICKLE.defaultBlockState().setValue( BlockStateProperties.WATERLOGGED, true ); final BlockState seaGrass = Blocks.SEAGRASS.defaultBlockState(); final int radius = (int) Math.floor( explosionPower ); + final int radiusSq = radius * radius; final int rMinusOneSq = (radius - 1) * (radius - 1); final BlockPos center = new BlockPos( explosion.getPos() ); // Track how many pufferfish have been spawned so we don't spawn a bunch of them - spawnPufferfish( center.above( 1 ) ); + if( pufferfish > 0 ) spawnPufferfish( center.above( 1 ) ); int pufferCount = 1; for( int y = -radius; y <= radius; y++ ) { @@ -165,34 +187,38 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp for( int z = -radius; z <= radius; z++ ) { final int distSq = x * x + y * y + z * z; - if( distSq <= radius * radius ) { + if( distSq <= radiusSq ) { final BlockPos pos = center.offset( x, y, z ); final BlockState stateAtPos = level.getBlockState( pos ); if( stateAtPos.getMaterial().isReplaceable() || stateAtPos.is( BlockTags.LEAVES ) ) { - if( distSq > rMinusOneSq ) { - // "Coral" casing - level.setBlock( pos, random.nextFloat() < 0.25F ? brainCoral : hornCoral, References.SetBlockFlags.DEFAULTS ); - } - else { + if( distSq <= rMinusOneSq ) { + // Water fill final float fillChoice = random.nextFloat(); if( fillChoice < 0.1F && seaPickle.canSurvive( level, pos ) ) { - level.setBlock( pos, seaPickle, References.SetBlockFlags.DEFAULTS ); + MobHelper.placeBlock( this, pos, seaPickle ); } else if( fillChoice < 0.3F && seaGrass.canSurvive( level, pos ) ) { - level.setBlock( pos, seaGrass, References.SetBlockFlags.DEFAULTS ); + MobHelper.placeBlock( this, pos, seaGrass ); } else { // Water fill - level.setBlock( pos, water, References.SetBlockFlags.DEFAULTS ); + MobHelper.placeBlock( this, pos, water ); - if( random.nextFloat() < 0.0075F && pufferCount < 5 ) { + if( random.nextFloat() < 0.0075F && pufferCount < pufferfish ) { spawnPufferfish( pos ); pufferCount++; } } } + else if( isCoralSafe( rMinusOneSq, x, y, z ) ) { + // Coral casing + final boolean infested = getConfig().DROWNING.infestedBlockChance.rollChance( random ); + MobHelper.placeBlock( this, pos, random.nextFloat() < 0.8F ? + infested ? mainInfestedCoral : mainCoral : + infested ? rareInfestedCoral : rareCoral ); + } } } } @@ -210,6 +236,28 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp } } + /** @return Checks the inner three-ish block distances and returns true if at least one is inside the main radius. */ + @SuppressWarnings( "RedundantIfStatement" ) // The symmetry makes it look better + private boolean isCoralSafe( int rMinusOneSq, int x, int y, int z ) { + int distSq; + if( y != 0 ) { + final int innerY = y < 0 ? y + 1 : y - 1; + distSq = x * x + innerY * innerY + z * z; + if( distSq <= rMinusOneSq ) return true; + } + if( x != 0 ) { + final int innerX = x < 0 ? x + 1 : x - 1; + distSq = innerX * innerX + y * y + z * z; + if( distSq <= rMinusOneSq ) return true; + } + if( z != 0 ) { + final int innerZ = z < 0 ? z + 1 : z - 1; + distSq = x * x + y * y + innerZ * innerZ; + if( distSq <= rMinusOneSq ) return true; + } + return false; + } + // The below two methods are here to effectively override the private Entity#isInRain to always return true (always wet) @Override public boolean isInWaterOrRain() { return true; } @@ -217,9 +265,18 @@ public class DrowningCreeperEntity extends _SpecialCreeperEntity implements IAmp @Override public boolean isInWaterRainOrBubble() { return true; } + /** Override to save data to this entity's NBT data. */ + @Override + public void addVariantSaveData( CompoundNBT saveTag ) { + saveTag.putByte( References.TAG_SUMMONS, (byte) pufferfish ); + } + /** Override to load data from this entity's NBT data. */ @Override public void readVariantSaveData( CompoundNBT saveTag ) { + if( saveTag.contains( References.TAG_SUMMONS, References.NBT_TYPE_NUMERICAL ) ) + pufferfish = saveTag.getByte( References.TAG_SUMMONS ); + setPathfindingMalus( PathNodeType.WATER, PathNodeType.WALKABLE.getMalus() ); } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/creeper/SnowCreeperEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/creeper/SnowCreeperEntity.java index 276ad37..ea1f8f9 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/creeper/SnowCreeperEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/creeper/SnowCreeperEntity.java @@ -3,6 +3,9 @@ package fathertoast.specialmobs.common.entity.creeper; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.block.MeltingIceBlock; +import fathertoast.specialmobs.common.config.species.SnowCreeperSpeciesConfig; +import fathertoast.specialmobs.common.config.species.SpeciesConfig; import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.entity.ai.AIHelper; import fathertoast.specialmobs.common.entity.ai.FluidPathNavigator; @@ -12,6 +15,7 @@ import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.FlowingFluidBlock; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.ai.attributes.Attributes; @@ -45,6 +49,16 @@ public class SnowCreeperEntity extends _SpecialCreeperEntity { .addToAttribute( Attributes.MAX_HEALTH, 10.0 ); } + @SpecialMob.ConfigSupplier + public static SpeciesConfig createConfig( MobFamily.Species species ) { + return new SnowCreeperSpeciesConfig( species, false, false, false, + 0.33 ); + } + + /** @return This entity's species config. */ + @Override + public SnowCreeperSpeciesConfig getConfig() { return (SnowCreeperSpeciesConfig) getSpecies().config; } + @SpecialMob.LanguageProvider public static String[] getTranslations( String langKey ) { return References.translations( langKey, "Snow Creeper", @@ -123,7 +137,9 @@ public class SnowCreeperEntity extends _SpecialCreeperEntity { final BlockPos center = new BlockPos( explosion.getPos() ); if( explosionMode != Explosion.Mode.NONE ) { - final BlockState ice = Blocks.ICE.defaultBlockState(); + final boolean snowGlobe = isUnderWater() || random.nextDouble() < getConfig().SNOW.snowGlobeChance.get(); + + final int radiusSq = radius * radius; final int rMinusOneSq = (radius - 1) * (radius - 1); for( int y = -radius; y <= radius; y++ ) { @@ -131,19 +147,32 @@ public class SnowCreeperEntity extends _SpecialCreeperEntity { for( int z = -radius; z <= radius; z++ ) { final int distSq = x * x + y * y + z * z; - if( distSq <= radius * radius ) { + if( distSq <= radiusSq ) { final BlockPos pos = center.offset( x, y, z ); - // Freeze top layer of water and temporary ice within affected volume + // Freeze top layer of water sources and frosted ice within affected volume final BlockState block = level.getBlockState( pos ); - if( block.is( Blocks.FROSTED_ICE ) || block.getFluidState().is( FluidTags.WATER ) ) { + if( block.is( Blocks.FROSTED_ICE ) || block.getBlock() == Blocks.WATER && block.getValue( FlowingFluidBlock.LEVEL ) == 0 ) { final BlockState blockAbove = level.getBlockState( pos.above() ); - if( !blockAbove.getMaterial().blocksMotion() && !blockAbove.getFluidState().is( FluidTags.WATER ) ) - level.setBlock( pos, ice, References.SetBlockFlags.DEFAULTS ); + if( !blockAbove.getMaterial().blocksMotion() && !blockAbove.getFluidState().is( FluidTags.WATER ) && + MobHelper.placeBlock( this, pos, MeltingIceBlock.getState( level, pos ) ) ) { + MeltingIceBlock.scheduleFirstTick( level, pos, random ); + } } - // Attempt to place pillars along circumference only - if( y == 0 && distSq > rMinusOneSq ) placePillar( pos, radius ); + if( distSq > rMinusOneSq ) { + if( snowGlobe ) { + // Create spherical shell of ice + if( level.getBlockState( pos ).getMaterial().isReplaceable() && + MobHelper.placeBlock( this, pos, MeltingIceBlock.getState( level, pos ) ) ) { + MeltingIceBlock.scheduleFirstTick( level, pos, random ); + } + } + else if( y == 0 ) { + // Create ice wall + placePillar( pos, radius ); + } + } } } } @@ -164,13 +193,14 @@ public class SnowCreeperEntity extends _SpecialCreeperEntity { if( shouldReplace( currentPos ) ) findGroundBelow( currentPos, radius ); else if( findGroundAbove( currentPos, radius ) ) return; - final BlockState ice = Blocks.PACKED_ICE.defaultBlockState(); final int maxY = Math.min( currentPos.getY() + 4, level.getMaxBuildHeight() - 2 ); int height = -2; // This is minimum pillar height if( pos.getY() > currentPos.getY() ) height -= (pos.getY() - currentPos.getY()) / 2; while( currentPos.getY() < maxY && shouldReplace( currentPos ) ) { - level.setBlock( currentPos, ice, References.SetBlockFlags.DEFAULTS ); + if( MobHelper.placeBlock( this, currentPos, MeltingIceBlock.getState( level, currentPos ) ) ) { + MeltingIceBlock.scheduleFirstTick( level, currentPos, random ); + } currentPos.move( 0, 1, 0 ); if( ++height >= 0 && random.nextBoolean() ) break; diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/BruteDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/BruteDrownedEntity.java index 9bdee72..00f09fe 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/drowned/BruteDrownedEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/BruteDrownedEntity.java @@ -23,7 +23,7 @@ public class BruteDrownedEntity extends _SpecialDrownedEntity { @SpecialMob.BestiaryInfoSupplier public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { bestiaryInfo.color( 0xFFF87E ) - .uniqueTextureBaseOnly() + .uniqueTextureWithOverlay() .size( 1.2F, 0.7F, 2.35F ) .addExperience( 2 ) .addToAttribute( Attributes.MAX_HEALTH, 10.0 ).addToAttribute( Attributes.ARMOR, 10.0 ); diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/FishingDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/FishingDrownedEntity.java index 59ada19..384c09f 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/drowned/FishingDrownedEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/FishingDrownedEntity.java @@ -40,7 +40,7 @@ public class FishingDrownedEntity extends _SpecialDrownedEntity implements IAngl @SpecialMob.BestiaryInfoSupplier public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { - bestiaryInfo.color( 0x2D41F4 ).weight( BestiaryInfo.DefaultWeight.LOW ).theme( BestiaryInfo.Theme.FISHING ) + bestiaryInfo.color( 0x2D41F4 ).weight( BestiaryInfo.DefaultWeight.LOW ) .addExperience( 2 ).drownImmune().fluidPushImmune() .convertThrowToFishing().fishingAttack( 1.0, 40, 15.0 ) .multiplyAttribute( Attributes.MOVEMENT_SPEED, 0.8 ); diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/FrozenDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/FrozenDrownedEntity.java new file mode 100644 index 0000000..35f6699 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/FrozenDrownedEntity.java @@ -0,0 +1,163 @@ +package fathertoast.specialmobs.common.entity.drowned; + +import fathertoast.specialmobs.common.bestiary.BestiaryInfo; +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.block.MeltingIceBlock; +import fathertoast.specialmobs.common.entity.MobHelper; +import fathertoast.specialmobs.common.util.ExplosionHelper; +import fathertoast.specialmobs.common.util.References; +import fathertoast.specialmobs.datagen.loot.LootTableBuilder; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.FlowingFluidBlock; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.potion.Effects; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.world.Explosion; +import net.minecraft.world.World; + +import javax.annotation.Nullable; + +@SpecialMob +public class FrozenDrownedEntity extends _SpecialDrownedEntity { + + //--------------- Static Special Mob Hooks ---------------- + + @SpecialMob.SpeciesReference + public static MobFamily.Species SPECIES; + + @SpecialMob.BestiaryInfoSupplier + public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { + bestiaryInfo.color( 0xDDEAEA ).weight( BestiaryInfo.DefaultWeight.LOW ).theme( BestiaryInfo.Theme.ICE ) + .uniqueTextureWithOverlay() + .addExperience( 2 ).effectImmune( Effects.MOVEMENT_SLOWDOWN ) + .addToAttribute( Attributes.ARMOR, 10.0 ) + .multiplyAttribute( Attributes.MOVEMENT_SPEED, 0.8 ); + } + + @SpecialMob.LanguageProvider + public static String[] getTranslations( String langKey ) { + return References.translations( langKey, "Frozen Drowned", + "", "", "", "", "", "" );//TODO + } + + @SpecialMob.LootTableProvider + public static void buildLootTable( LootTableBuilder loot ) { + addBaseLoot( loot ); + loot.addCommonDrop( "common", Blocks.ICE ); + loot.addRareDrop( "rare", Blocks.BLUE_ICE ); + } + + @SpecialMob.Factory + public static EntityType.IFactory getVariantFactory() { return FrozenDrownedEntity::new; } + + /** @return This entity's mob species. */ + @SpecialMob.SpeciesSupplier + @Override + public MobFamily.Species getSpecies() { return SPECIES; } + + + //--------------- Variant-Specific Implementations ---------------- + + private static final int ICE_SEAL_TICKS = 4; + + private int iceSealTimer; + private BlockPos iceSealPos; + + public FrozenDrownedEntity( EntityType entityType, World world ) { super( entityType, world ); } + + /** Override to apply effects when this entity hits a target with a melee attack. */ + @Override + protected void onVariantAttack( LivingEntity target ) { + MobHelper.applyEffect( target, Effects.MOVEMENT_SLOWDOWN, 2 ); + } + + /** Called each tick to update this entity's movement. */ + @Override + public void aiStep() { + if( !level.isClientSide() ) { + if( iceSealPos != null ) { + // Currently creating ice seal + if( iceSealTimer++ % ICE_SEAL_TICKS == 0 ) { + final int radius = iceSealTimer / ICE_SEAL_TICKS; + makeIceSeal( iceSealPos, radius ); + + if( radius >= 7 ) { + iceSealTimer = 100 + random.nextInt( 100 ); + iceSealPos = null; + } + } + } + else if( iceSealTimer-- <= 0 ) { + // Check if a new ice seal should be created + final LivingEntity target = getTarget(); + if( target != null && target.isUnderWater() && distanceToSqr( target ) < 144.0 && random.nextInt( 20 ) == 0 ) { + final BlockPos pos = findIceSealPos( target.blockPosition(), MathHelper.ceil( target.getBbHeight() ) ); + if( pos != null && ExplosionHelper.getMode( this ) != Explosion.Mode.NONE ) { + iceSealTimer = 0; + iceSealPos = pos; + } + } + } + } + super.aiStep(); + } + + /** @return The position to create an ice seal at, or null if the target is invalid. */ + @Nullable + private BlockPos findIceSealPos( BlockPos targetPos, int targetHeight ) { + // Find the water surface + final int maxRange = 6 + targetHeight; + final BlockPos.Mutable pos = targetPos.mutable(); + for( int y = 0; y <= maxRange; y++ ) { + pos.setY( targetPos.getY() + y ); + if( pos.getY() >= level.getMaxBuildHeight() ) break; // Can't build here + + final BlockState block = level.getBlockState( pos ); + if( block.getBlock() != Blocks.WATER || block.getValue( FlowingFluidBlock.LEVEL ) != 0 ) { + if( y - 1 <= targetHeight ) break; // Don't build inside the target entity + return pos.below(); + } + } + return null; + } + + /** Creates an ice seal centered at the position with a certain size. */ + private void makeIceSeal( BlockPos center, int radius ) { + if( !isSilent() ) { + level.playSound( null, center.getX() + 0.5, center.getY() + 0.5, center.getZ() + 0.5, + SoundEvents.GLASS_BREAK, getSoundSource(), 0.4F, 1.0F / (random.nextFloat() * 0.4F + 0.8F) ); + } + + if( radius <= 0 ) { + placeSealBlock( center ); + return; + } + + for( int x = -radius; x <= radius; x++ ) { + for( int z = -radius; z <= radius; z++ ) { + final int distSq = x * x + z * z; + + // Fill circle + if( distSq <= radius * radius ) { + placeSealBlock( center.offset( x, 0, z ) ); + } + } + } + } + + /** Attempts to place a single seal block. */ + private void placeSealBlock( BlockPos pos ) { + final BlockState block = MeltingIceBlock.getState( level, pos ); + if( level.getBlockState( pos ).getMaterial().isReplaceable() && level.isUnobstructed( block, pos, ISelectionContext.empty() ) && + MobHelper.placeBlock( this, pos, block ) ) { + MeltingIceBlock.scheduleFirstTick( level, pos, random ); + } + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/GiantDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/GiantDrownedEntity.java index 85fbded..9f750bd 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/drowned/GiantDrownedEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/GiantDrownedEntity.java @@ -22,7 +22,7 @@ public class GiantDrownedEntity extends _SpecialDrownedEntity { @SpecialMob.BestiaryInfoSupplier public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { - bestiaryInfo.color( 0x799C65 ).theme( BestiaryInfo.Theme.MOUNTAIN ) + bestiaryInfo.color( 0x799C65 ) .size( 1.5F, 0.9F, 2.95F ) .addExperience( 1 ) .addToAttribute( Attributes.MAX_HEALTH, 20.0 ) diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/HungryDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/HungryDrownedEntity.java index 1a561ef..e80fe79 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/drowned/HungryDrownedEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/HungryDrownedEntity.java @@ -34,7 +34,7 @@ public class HungryDrownedEntity extends _SpecialDrownedEntity { @SpecialMob.BestiaryInfoSupplier public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { bestiaryInfo.color( 0xAB1518 ) - .uniqueTextureBaseOnly() + .uniqueTextureWithOverlay() .addExperience( 2 ).regen( 30 ).disableRangedAttack() .addToAttribute( Attributes.MAX_HEALTH, 10.0 ) .multiplyAttribute( Attributes.MOVEMENT_SPEED, 1.3 ); diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/PlagueDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/PlagueDrownedEntity.java index 4ad094c..b0d1021 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/drowned/PlagueDrownedEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/PlagueDrownedEntity.java @@ -23,8 +23,8 @@ public class PlagueDrownedEntity extends _SpecialDrownedEntity { @SpecialMob.BestiaryInfoSupplier public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { - bestiaryInfo.color( 0x8AA838 ).theme( BestiaryInfo.Theme.FOREST ) - .uniqueTextureBaseOnly() + bestiaryInfo.color( 0x8AA838 ) + .uniqueTextureWithOverlay() .addExperience( 1 ) .multiplyAttribute( Attributes.MOVEMENT_SPEED, 1.1 ); } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/drowned/TropicalDrownedEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/drowned/TropicalDrownedEntity.java new file mode 100644 index 0000000..cd4df08 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/entity/drowned/TropicalDrownedEntity.java @@ -0,0 +1,76 @@ +package fathertoast.specialmobs.common.entity.drowned; + +import fathertoast.specialmobs.common.bestiary.BestiaryInfo; +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.config.species.DrownedSpeciesConfig; +import fathertoast.specialmobs.common.config.species.SpeciesConfig; +import fathertoast.specialmobs.common.entity.MobHelper; +import fathertoast.specialmobs.common.util.References; +import fathertoast.specialmobs.datagen.loot.LootTableBuilder; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.potion.Effects; +import net.minecraft.world.World; + +@SpecialMob +public class TropicalDrownedEntity extends _SpecialDrownedEntity { + + //--------------- Static Special Mob Hooks ---------------- + + @SpecialMob.SpeciesReference + public static MobFamily.Species SPECIES; + + @SpecialMob.BestiaryInfoSupplier + public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { + bestiaryInfo.color( 0xD962A3 ).weight( BestiaryInfo.DefaultWeight.LOWEST ).theme( BestiaryInfo.Theme.TROPICAL ) + .uniqueTextureWithOverlay() + .addExperience( 1 ) + .multiplyRangedCooldown( 0.75F ).rangedMaxRange( 15.0 ) + .multiplyAttribute( Attributes.MOVEMENT_SPEED, 1.2 ); + } + + @SpecialMob.ConfigSupplier + public static SpeciesConfig createConfig( MobFamily.Species species ) { + return new DrownedSpeciesConfig( species, 1.0, DEFAULT_SHIELD_CHANCE ); + } + + @SpecialMob.LanguageProvider + public static String[] getTranslations( String langKey ) { + return References.translations( langKey, "Tropical Drowned", + "", "", "", "", "", "" );//TODO + } + + @SpecialMob.LootTableProvider + public static void buildLootTable( LootTableBuilder loot ) { + addBaseLoot( loot ); + loot.addCommonDrop( "common", Blocks.SEA_PICKLE ); + loot.addUncommonDrop( "uncommon", + Blocks.TUBE_CORAL, Blocks.TUBE_CORAL_FAN, Blocks.TUBE_CORAL_BLOCK, + Blocks.BRAIN_CORAL, Blocks.BRAIN_CORAL_FAN, Blocks.BRAIN_CORAL_BLOCK, + Blocks.BUBBLE_CORAL, Blocks.BUBBLE_CORAL_FAN, Blocks.BUBBLE_CORAL_BLOCK, + Blocks.FIRE_CORAL, Blocks.FIRE_CORAL_FAN, Blocks.FIRE_CORAL_BLOCK, + Blocks.HORN_CORAL, Blocks.HORN_CORAL_FAN, Blocks.HORN_CORAL_BLOCK ); + } + + @SpecialMob.Factory + public static EntityType.IFactory getVariantFactory() { return TropicalDrownedEntity::new; } + + /** @return This entity's mob species. */ + @SpecialMob.SpeciesSupplier + @Override + public MobFamily.Species getSpecies() { return SPECIES; } + + + //--------------- Variant-Specific Implementations ---------------- + + public TropicalDrownedEntity( EntityType entityType, World world ) { super( entityType, world ); } + + /** Override to apply effects when this entity hits a target with a melee attack. */ + @Override + protected void onVariantAttack( LivingEntity target ) { + MobHelper.applyEffect( target, Effects.POISON ); + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/entity/enderman/FlameEndermanEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/enderman/FlameEndermanEntity.java index bb47972..acdede0 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/enderman/FlameEndermanEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/enderman/FlameEndermanEntity.java @@ -3,6 +3,7 @@ package fathertoast.specialmobs.common.entity.enderman; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.util.ExplosionHelper; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; @@ -120,8 +121,9 @@ public class FlameEndermanEntity extends _SpecialEndermanEntity { while( currentPos.getY() < maxY ) { currentPos.move( 0, 1, 0 ); - if( shouldSetFire( currentPos ) ) - level.setBlock( currentPos, AbstractFireBlock.getState( level, currentPos ), References.SetBlockFlags.DEFAULTS ); + if( shouldSetFire( currentPos ) ) { + MobHelper.placeBlock( this, currentPos, AbstractFireBlock.getState( level, currentPos ) ); + } } } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/ghast/CorporealShiftGhastEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/ghast/CorporealShiftGhastEntity.java index ef00d75..b3275c1 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/ghast/CorporealShiftGhastEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/ghast/CorporealShiftGhastEntity.java @@ -3,6 +3,8 @@ package fathertoast.specialmobs.common.entity.ghast; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.config.species.CorporealShiftGhastSpeciesConfig; +import fathertoast.specialmobs.common.config.species.SpeciesConfig; import fathertoast.specialmobs.common.core.register.SMItems; import fathertoast.specialmobs.common.entity.projectile.IncorporealFireballEntity; import fathertoast.specialmobs.common.util.References; @@ -39,6 +41,14 @@ public class CorporealShiftGhastEntity extends _SpecialGhastEntity { .multiplyAttribute( Attributes.MOVEMENT_SPEED, 0.8 ); } + @SpecialMob.ConfigSupplier + public static SpeciesConfig createConfig( MobFamily.Species species ) { + return new CorporealShiftGhastSpeciesConfig( species, 300, 200 ); + } + + /** @return This entity's species config. */ + public CorporealShiftGhastSpeciesConfig getConfig() { return (CorporealShiftGhastSpeciesConfig) getSpecies().config; } + @SpecialMob.LanguageProvider public static String[] getTranslations( String langKey ) { return References.translations( langKey, "Corporeal Shift Ghast", @@ -64,8 +74,7 @@ public class CorporealShiftGhastEntity extends _SpecialGhastEntity { public static final DataParameter CORPOREAL = EntityDataManager.defineId( CorporealShiftGhastEntity.class, DataSerializers.BOOLEAN ); - private final int maxShiftTime = 150; - private int shiftTime = maxShiftTime; + private int shiftTime; public CorporealShiftGhastEntity( EntityType entityType, World world ) { super( entityType, world ); } @@ -73,7 +82,7 @@ public class CorporealShiftGhastEntity extends _SpecialGhastEntity { protected void defineSynchedData() { super.defineSynchedData(); entityData.define( CORPOREAL, false ); - if( !level.isClientSide() && random.nextBoolean() ) setCorporeal( true ); + if( !level.isClientSide() ) setCorporeal( random.nextBoolean() ); } @Override @@ -81,8 +90,7 @@ public class CorporealShiftGhastEntity extends _SpecialGhastEntity { super.tick(); if( --shiftTime <= 0 ) { - if( !level.isClientSide ) { - shiftTime = maxShiftTime + random.nextInt( maxShiftTime ); + if( !level.isClientSide() ) { setCorporeal( !isCorporeal() ); spawnShiftSmoke( (ServerWorld) level ); } @@ -106,7 +114,10 @@ public class CorporealShiftGhastEntity extends _SpecialGhastEntity { public boolean isCorporeal() { return entityData.get( CORPOREAL ); } - private void setCorporeal( boolean value ) { entityData.set( CORPOREAL, value ); } + private void setCorporeal( boolean value ) { + entityData.set( CORPOREAL, value ); + shiftTime = value ? getConfig().CORPOREAL_SHIFT.corporealTicks.get() : getConfig().CORPOREAL_SHIFT.incorporealTicks.get(); + } /** Called to attack the target with a ranged attack. */ @Override diff --git a/src/main/java/fathertoast/specialmobs/common/entity/projectile/IncorporealFireballEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/projectile/IncorporealFireballEntity.java index cae32ef..9c31d96 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/projectile/IncorporealFireballEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/projectile/IncorporealFireballEntity.java @@ -1,8 +1,10 @@ package fathertoast.specialmobs.common.entity.projectile; +import fathertoast.specialmobs.common.bestiary.SpecialMob; import fathertoast.specialmobs.common.core.register.SMEntities; import fathertoast.specialmobs.common.core.register.SMItems; import fathertoast.specialmobs.common.entity.ghast.CorporealShiftGhastEntity; +import fathertoast.specialmobs.common.util.References; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; @@ -27,7 +29,7 @@ import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; public class IncorporealFireballEntity extends AbstractFireballEntity { - + public int explosionPower = 1; private boolean shouldExplode = false; @@ -35,20 +37,26 @@ public class IncorporealFireballEntity extends AbstractFireballEntity { private LivingEntity target; - public IncorporealFireballEntity(EntityType entityType, World world ) { + public IncorporealFireballEntity( EntityType entityType, World world ) { super( entityType, world ); } - public IncorporealFireballEntity(World world, CorporealShiftGhastEntity ghast, double x, double y, double z ) { + public IncorporealFireballEntity( World world, CorporealShiftGhastEntity ghast, double x, double y, double z ) { super( SMEntities.INCORPOREAL_FIREBALL.get(), ghast, x, y, z, world ); target = ghast.getTarget(); } - public IncorporealFireballEntity(World world, @Nullable PlayerEntity owner, LivingEntity target, double x, double y, double z ) { + public IncorporealFireballEntity( World world, @Nullable PlayerEntity owner, LivingEntity target, double x, double y, double z ) { super( SMEntities.INCORPOREAL_FIREBALL.get(), owner, x, y, z, world ); this.target = target; } - + + @SpecialMob.LanguageProvider + public static String[] getTranslations( String langKey ) { + return References.translations( langKey, "Incorporeal Fireball", + "", "", "", "", "", "" );//TODO + } + @Override public void tick() { super.tick(); @@ -95,21 +103,21 @@ public class IncorporealFireballEntity extends AbstractFireballEntity { if( !this.level.isClientSide ) { Entity target = traceResult.getEntity(); - + boolean fizzle; - - if ( target instanceof PlayerEntity ) { + + if( target instanceof PlayerEntity ) { // TODO - Implement player-specific checks fizzle = true; } else { - if (target.getX() != target.xo || target.getY() != target.yo || target.getZ() != target.zo) { + if( target.getX() != target.xo || target.getY() != target.yo || target.getZ() != target.zo ) { explode(); return; } fizzle = true; } - if (fizzle) { + if( fizzle ) { playSound( SoundEvents.FIRE_EXTINGUISH, 1.0F, 1.0F ); remove(); } @@ -124,10 +132,10 @@ public class IncorporealFireballEntity extends AbstractFireballEntity { shouldExplode = true; return true; } - - @OnlyIn(Dist.CLIENT) + + @OnlyIn( Dist.CLIENT ) public ItemStack getItem() { - return new ItemStack(SMItems.INCORPOREAL_FIREBALL.get()); + return new ItemStack( SMItems.INCORPOREAL_FIREBALL.get() ); } @Override diff --git a/src/main/java/fathertoast/specialmobs/common/entity/spider/FireSpiderEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/spider/FireSpiderEntity.java index 389ff07..965b7ee 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/spider/FireSpiderEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/spider/FireSpiderEntity.java @@ -3,6 +3,7 @@ package fathertoast.specialmobs.common.entity.spider; import fathertoast.specialmobs.common.bestiary.BestiaryInfo; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; import net.minecraft.block.Blocks; @@ -63,7 +64,7 @@ public class FireSpiderEntity extends _SpecialSpiderEntity { if( !level.isClientSide() ) { final BlockPos pos = target.blockPosition(); if( level.getBlockState( pos ).getMaterial().isReplaceable() ) { - level.setBlock( pos, Blocks.FIRE.defaultBlockState(), References.SetBlockFlags.DEFAULTS ); + MobHelper.placeBlock( this, pos, Blocks.FIRE.defaultBlockState() ); } } target.setSecondsOnFire( 5 ); diff --git a/src/main/java/fathertoast/specialmobs/common/entity/spider/WebSpiderEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/spider/WebSpiderEntity.java index 13d170e..5262588 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/spider/WebSpiderEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/spider/WebSpiderEntity.java @@ -5,6 +5,7 @@ import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; import fathertoast.specialmobs.common.config.species.SpeciesConfig; import fathertoast.specialmobs.common.config.species.WebSpiderSpeciesConfig; +import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; import net.minecraft.block.Blocks; @@ -99,8 +100,8 @@ public class WebSpiderEntity extends _SpecialSpiderEntity { /** @return Attempts to place a cobweb at the given position and returns true if successful. */ private boolean tryPlaceWeb( BlockPos pos ) { - if( level.getBlockState( pos ).getMaterial().isReplaceable() ) { - level.setBlock( pos, Blocks.COBWEB.defaultBlockState(), References.SetBlockFlags.DEFAULTS ); + if( level.getBlockState( pos ).getMaterial().isReplaceable() && + MobHelper.placeBlock( this, pos, Blocks.COBWEB.defaultBlockState() ) ) { webCount--; return true; } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/witch/IceWitchEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/witch/IceWitchEntity.java new file mode 100644 index 0000000..2464aa3 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/entity/witch/IceWitchEntity.java @@ -0,0 +1,89 @@ +package fathertoast.specialmobs.common.entity.witch; + +import fathertoast.specialmobs.common.bestiary.BestiaryInfo; +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.bestiary.SpecialMob; +import fathertoast.specialmobs.common.util.References; +import fathertoast.specialmobs.datagen.loot.LootTableBuilder; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.potion.Effects; +import net.minecraft.potion.Potions; +import net.minecraft.world.World; + +@SpecialMob +public class IceWitchEntity extends _SpecialWitchEntity { + + //--------------- Static Special Mob Hooks ---------------- + + @SpecialMob.SpeciesReference + public static MobFamily.Species SPECIES; + + @SpecialMob.BestiaryInfoSupplier + public static void getBestiaryInfo( BestiaryInfo.Builder bestiaryInfo ) { + bestiaryInfo.color( 0xDDEAEA ).weight( BestiaryInfo.DefaultWeight.LOW ).theme( BestiaryInfo.Theme.ICE ) + .uniqueTextureBaseOnly() + .addExperience( 2 ).effectImmune( Effects.MOVEMENT_SLOWDOWN ) + .addToAttribute( Attributes.ARMOR, 10.0 ) + .multiplyAttribute( Attributes.MOVEMENT_SPEED, 0.8 ); + } + + @SpecialMob.LanguageProvider + public static String[] getTranslations( String langKey ) { + return References.translations( langKey, "Ice Witch", + "", "", "", "", "", "" );//TODO + } + + @SpecialMob.LootTableProvider + public static void buildLootTable( LootTableBuilder loot ) { + addBaseLoot( loot ); + loot.addClusterDrop( "common", Items.SNOWBALL ); + loot.addUncommonDrop( "uncommon", Blocks.BLUE_ICE ); + } + + @SpecialMob.Factory + public static EntityType.IFactory getVariantFactory() { return IceWitchEntity::new; } + + /** @return This entity's mob species. */ + @SpecialMob.SpeciesSupplier + @Override + public MobFamily.Species getSpecies() { return SPECIES; } + + + //--------------- Variant-Specific Implementations ---------------- + + /** Ticks before this witch can use its ice wall ability. */ + private int wallDelay; + + public IceWitchEntity( EntityType entityType, World world ) { super( entityType, world ); } + + /** Override to modify potion attacks. Return an empty item stack to cancel the potion throw. */ + @Override + protected ItemStack pickVariantThrownPotion( ItemStack originalPotion, LivingEntity target, float damageMulti, float distance ) { + if( !target.hasEffect( Effects.MOVEMENT_SLOWDOWN ) ) { + return makeSplashPotion( Potions.STRONG_SLOWNESS ); + } + return originalPotion; + } + + /** Called each tick to update this entity's movement. */ + @Override + public void aiStep() { + final LivingEntity target = getTarget(); + if( !level.isClientSide() && isAlive() && wallDelay-- <= 0 && target != null && random.nextInt( 20 ) == 0 ) { + + // Create an ice wall behind the target if they are vulnerable + final double distanceSq = target.distanceToSqr( this ); + if( distanceSq > 100.0 && distanceSq < 196.0 && target.hasEffect( Effects.MOVEMENT_SLOWDOWN ) && canSee( target ) ) { + wallDelay = 200; + + //TODO + } + } + super.aiStep(); + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/entity/witch/WindWitchEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/witch/WindWitchEntity.java index d73ec6f..6f6fde7 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/witch/WindWitchEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/witch/WindWitchEntity.java @@ -43,7 +43,6 @@ public class WindWitchEntity extends _SpecialWitchEntity { bestiaryInfo.color( 0x6388B2 ).theme( BestiaryInfo.Theme.MOUNTAIN ) .uniqueTextureWithEyes() .addExperience( 2 ).fallImmune() - .addToAttribute( Attributes.ATTACK_DAMAGE, 2.0 ) .multiplyAttribute( Attributes.MOVEMENT_SPEED, 1.2 ); } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/zombie/FrozenZombieEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/zombie/FrozenZombieEntity.java index 03192d5..9036508 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/zombie/FrozenZombieEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/zombie/FrozenZombieEntity.java @@ -5,6 +5,7 @@ import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; import fathertoast.specialmobs.common.entity.MobHelper; import fathertoast.specialmobs.common.entity.ai.AIHelper; +import fathertoast.specialmobs.common.entity.drowned.FrozenDrownedEntity; import fathertoast.specialmobs.common.util.References; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; import net.minecraft.block.Blocks; @@ -16,6 +17,7 @@ import net.minecraft.entity.ai.attributes.ModifiableAttributeInstance; import net.minecraft.entity.ai.goal.LookAtGoal; import net.minecraft.entity.ai.goal.LookRandomlyGoal; import net.minecraft.entity.ai.goal.WaterAvoidingRandomWalkingGoal; +import net.minecraft.entity.monster.ZombieEntity; import net.minecraft.entity.projectile.AbstractArrowEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -92,6 +94,10 @@ public class FrozenZombieEntity extends _SpecialZombieEntity { return MobHelper.tipArrow( arrow, Effects.MOVEMENT_SLOWDOWN ); } + /** Override to change the entity this converts to when drowned. */ + @Override + protected EntityType getVariantConversionType() { return FrozenDrownedEntity.SPECIES.entityType.get(); } + /** Called each tick to update this entity's movement. */ @Override public void aiStep() { diff --git a/src/main/java/fathertoast/specialmobs/common/entity/zombie/HuskZombieEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/zombie/HuskZombieEntity.java index 1b9d7be..bc70a20 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/zombie/HuskZombieEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/zombie/HuskZombieEntity.java @@ -26,7 +26,7 @@ import net.minecraft.world.IServerWorld; import net.minecraft.world.World; import java.util.Random; -import java.util.function.Function; +import java.util.function.Predicate; @SpecialMob public class HuskZombieEntity extends _SpecialZombieEntity { @@ -109,7 +109,7 @@ public class HuskZombieEntity extends _SpecialZombieEntity { } /** Returns true if the species is not a husk and not damaged by water. */ - private static final Function, Boolean> HUSK_CONVERSION_SELECTOR = + private static final Predicate> HUSK_CONVERSION_SELECTOR = ( species ) -> species != SPECIES && !species.config.GENERAL.isDamagedByWater.get(); /** Performs this zombie's drowning conversion. */ diff --git a/src/main/java/fathertoast/specialmobs/common/item/IncorporealFireChargeItem.java b/src/main/java/fathertoast/specialmobs/common/item/IncorporealFireChargeItem.java index 20b5ac2..d45b90b 100644 --- a/src/main/java/fathertoast/specialmobs/common/item/IncorporealFireChargeItem.java +++ b/src/main/java/fathertoast/specialmobs/common/item/IncorporealFireChargeItem.java @@ -1,45 +1,69 @@ package fathertoast.specialmobs.common.item; import fathertoast.specialmobs.common.bestiary.SpecialMob; -import fathertoast.specialmobs.common.network.NetworkHelper; -import fathertoast.specialmobs.common.util.EntityUtil; +import fathertoast.specialmobs.common.entity.projectile.IncorporealFireballEntity; import fathertoast.specialmobs.common.util.References; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileHelper; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; -import net.minecraft.item.Rarity; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.EntityRayTraceResult; +import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; +import javax.annotation.Nullable; + public class IncorporealFireChargeItem extends Item { - - public IncorporealFireChargeItem() { - super(new Item.Properties().stacksTo(1).tab(ItemGroup.TAB_MISC).rarity(Rarity.UNCOMMON)); - } - + @SpecialMob.LanguageProvider public static String[] getTranslations( String langKey ) { return References.translations( langKey, "Incorporeal Fire Charge", "", "", "", "", "", "" );//TODO } - + + public IncorporealFireChargeItem() { super( new Item.Properties().tab( ItemGroup.TAB_MISC ) ); } + @Override - public ActionResult use(World world, PlayerEntity player, Hand hand) { - if (world.isClientSide) { - Entity entity = EntityUtil.getClientPickEntity(player, 340.0D); - - if (entity instanceof LivingEntity) { - NetworkHelper.spawnIncorporealFireball(player, (LivingEntity) entity); - world.playSound(player, player.blockPosition(), SoundEvents.FIRECHARGE_USE, SoundCategory.BLOCKS, 1.0F, (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F); - return ActionResult.consume(player.getItemInHand(hand)); + public ActionResult use( World world, PlayerEntity player, Hand hand ) { + final ItemStack item = player.getItemInHand( hand ); + if( player.getCooldowns().isOnCooldown( item.getItem() ) ) return ActionResult.pass( item ); + + final Entity target = pickEntity( player, 127.0 ); + if( target instanceof LivingEntity ) { + if( !world.isClientSide() ) { + world.addFreshEntity( new IncorporealFireballEntity( world, player, (LivingEntity) target, + player.getX(), player.getEyeY(), player.getZ() ) ); + world.playSound( null, player.blockPosition(), SoundEvents.FIRECHARGE_USE, SoundCategory.BLOCKS, 1.0F, (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F ); + + if( !player.abilities.instabuild ) { + item.shrink( 1 ); + } + player.getCooldowns().addCooldown( item.getItem(), 10 ); + return ActionResult.consume( item ); } + return ActionResult.pass( item ); } - return ActionResult.pass(player.getItemInHand(hand)); + + return ActionResult.fail( item ); } -} + + @Nullable + private static Entity pickEntity( PlayerEntity player, double range ) { + final Vector3d eyePos = player.getEyePosition( 1.0F ); + final Vector3d viewVec = player.getViewVector( 1.0F ).scale( range ); + + final AxisAlignedBB bb = player.getBoundingBox().expandTowards( viewVec ).inflate( 1.0 ); + final EntityRayTraceResult result = ProjectileHelper.getEntityHitResult( player.level, player, eyePos, eyePos.add( viewVec ), bb, + ( entity ) -> !entity.isSpectator() && entity.isAlive() && entity.isPickable() && !player.isPassengerOfSameVehicle( entity ) ); + + return result == null ? null : result.getEntity(); + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/network/NetworkHelper.java b/src/main/java/fathertoast/specialmobs/common/network/NetworkHelper.java index 9c3dfcd..07ac081 100644 --- a/src/main/java/fathertoast/specialmobs/common/network/NetworkHelper.java +++ b/src/main/java/fathertoast/specialmobs/common/network/NetworkHelper.java @@ -1,14 +1,7 @@ package fathertoast.specialmobs.common.network; -import fathertoast.specialmobs.common.network.message.C2SSpawnIncorporealFireball; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; - -import javax.annotation.Nonnull; - public class NetworkHelper { - - public static void spawnIncorporealFireball(@Nonnull PlayerEntity player, @Nonnull LivingEntity livingEntity) { - PacketHandler.CHANNEL.sendToServer(new C2SSpawnIncorporealFireball(player.getUUID(), livingEntity.getId())); - } -} + // public static void spawnIncorporealFireball( @Nonnull PlayerEntity player, @Nonnull LivingEntity livingEntity ) { + // PacketHandler.CHANNEL.sendToServer( new C2SSpawnIncorporealFireball( player.getUUID(), livingEntity.getId() ) ); + // } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/network/PacketHandler.java b/src/main/java/fathertoast/specialmobs/common/network/PacketHandler.java index 69c02db..ca2f705 100644 --- a/src/main/java/fathertoast/specialmobs/common/network/PacketHandler.java +++ b/src/main/java/fathertoast/specialmobs/common/network/PacketHandler.java @@ -1,7 +1,6 @@ package fathertoast.specialmobs.common.network; import fathertoast.specialmobs.common.core.SpecialMobs; -import fathertoast.specialmobs.common.network.message.C2SSpawnIncorporealFireball; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; @@ -33,7 +32,7 @@ public class PacketHandler { } public final void registerMessages() { - registerMessage( C2SSpawnIncorporealFireball.class, C2SSpawnIncorporealFireball::encode, C2SSpawnIncorporealFireball::decode, C2SSpawnIncorporealFireball::handle ); + //registerMessage( C2SSpawnIncorporealFireball.class, C2SSpawnIncorporealFireball::encode, C2SSpawnIncorporealFireball::decode, C2SSpawnIncorporealFireball::handle ); } public void registerMessage( Class messageType, BiConsumer encoder, Function decoder, BiConsumer> handler ) { diff --git a/src/main/java/fathertoast/specialmobs/common/network/message/C2SSpawnIncorporealFireball.java b/src/main/java/fathertoast/specialmobs/common/network/message/C2SSpawnIncorporealFireball.java index c4046a3..7fa95ab 100644 --- a/src/main/java/fathertoast/specialmobs/common/network/message/C2SSpawnIncorporealFireball.java +++ b/src/main/java/fathertoast/specialmobs/common/network/message/C2SSpawnIncorporealFireball.java @@ -1,37 +1,29 @@ package fathertoast.specialmobs.common.network.message; -import fathertoast.specialmobs.common.network.work.ServerWork; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.network.NetworkEvent; - -import java.util.UUID; -import java.util.function.Supplier; - public class C2SSpawnIncorporealFireball { - - public final UUID playerUUID; - public final int targetEntityID; - - public C2SSpawnIncorporealFireball(UUID playerUUID, int targetEntityId) { - this.playerUUID = playerUUID; - this.targetEntityID = targetEntityId; - } - - public static void handle(C2SSpawnIncorporealFireball message, Supplier contextSupplier) { - NetworkEvent.Context context = contextSupplier.get(); - - if (context.getDirection().getReceptionSide().isServer()) { - context.enqueueWork(() -> ServerWork.handleSpawnIncorporealFireball(message)); - } - context.setPacketHandled(true); - } - - public static C2SSpawnIncorporealFireball decode(PacketBuffer buffer) { - return new C2SSpawnIncorporealFireball(buffer.readUUID(), buffer.readInt()); - } - - public static void encode(C2SSpawnIncorporealFireball message, PacketBuffer buffer) { - buffer.writeUUID(message.playerUUID); - buffer.writeInt(message.targetEntityID); - } -} + // public final UUID playerUUID; + // public final int targetEntityID; + // + // public C2SSpawnIncorporealFireball(UUID playerUUID, int targetEntityId) { + // this.playerUUID = playerUUID; + // this.targetEntityID = targetEntityId; + // } + // + // public static void handle(C2SSpawnIncorporealFireball message, Supplier contextSupplier) { + // NetworkEvent.Context context = contextSupplier.get(); + // + // if (context.getDirection().getReceptionSide().isServer()) { + // context.enqueueWork(() -> ServerWork.handleSpawnIncorporealFireball(message)); + // } + // context.setPacketHandled(true); + // } + // + // public static C2SSpawnIncorporealFireball decode(PacketBuffer buffer) { + // return new C2SSpawnIncorporealFireball(buffer.readUUID(), buffer.readInt()); + // } + // + // public static void encode(C2SSpawnIncorporealFireball message, PacketBuffer buffer) { + // buffer.writeUUID(message.playerUUID); + // buffer.writeInt(message.targetEntityID); + // } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/network/work/ServerWork.java b/src/main/java/fathertoast/specialmobs/common/network/work/ServerWork.java index cca5778..a3cfaf0 100644 --- a/src/main/java/fathertoast/specialmobs/common/network/work/ServerWork.java +++ b/src/main/java/fathertoast/specialmobs/common/network/work/ServerWork.java @@ -1,36 +1,25 @@ package fathertoast.specialmobs.common.network.work; -import fathertoast.specialmobs.common.entity.projectile.IncorporealFireballEntity; -import fathertoast.specialmobs.common.network.message.C2SSpawnIncorporealFireball; -import net.minecraft.entity.Entity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.server.MinecraftServer; -import net.minecraft.world.server.ServerWorld; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.LogicalSidedProvider; - public class ServerWork { - - public static void handleSpawnIncorporealFireball(C2SSpawnIncorporealFireball message) { - MinecraftServer server = LogicalSidedProvider.INSTANCE.get(LogicalSide.SERVER); - - if (server == null) - return; - - ServerPlayerEntity player = server.getPlayerList().getPlayer(message.playerUUID); - - if (player == null) - return; - - ServerWorld world = (ServerWorld) player.level; - Entity entity = world.getEntity(message.targetEntityID); - - if (!(entity instanceof LivingEntity)) - return; - - LivingEntity livingEntity = (LivingEntity) entity; - IncorporealFireballEntity fireballEntity = new IncorporealFireballEntity(world, player, livingEntity, player.getX(), player.getEyeY(), player.getZ()); - world.addFreshEntity(fireballEntity); - } - } + // public static void handleSpawnIncorporealFireball(C2SSpawnIncorporealFireball message) { + // MinecraftServer server = LogicalSidedProvider.INSTANCE.get(LogicalSide.SERVER); + // + // if (server == null) + // return; + // + // ServerPlayerEntity player = server.getPlayerList().getPlayer(message.playerUUID); + // + // if (player == null) + // return; + // + // ServerWorld world = (ServerWorld) player.level; + // Entity entity = world.getEntity(message.targetEntityID); + // + // if (!(entity instanceof LivingEntity)) + // return; + // + // LivingEntity livingEntity = (LivingEntity) entity; + // IncorporealFireballEntity fireballEntity = new IncorporealFireballEntity(world, player, livingEntity, player.getX(), player.getEyeY(), player.getZ()); + // world.addFreshEntity(fireballEntity); + // } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java b/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java index eb77e94..f5a32ff 100644 --- a/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java +++ b/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java @@ -5,10 +5,12 @@ import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.bestiary.SpecialMob; import fathertoast.specialmobs.common.config.species.SpeciesConfig; import fathertoast.specialmobs.datagen.loot.LootTableBuilder; +import net.minecraft.block.Block; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.attributes.AttributeModifierMap; import net.minecraft.item.Item; +import net.minecraftforge.registries.ForgeRegistryEntry; import javax.annotation.Nullable; import java.lang.annotation.Annotation; @@ -103,14 +105,20 @@ public final class AnnotationHelper { } } - /** Gets the translations from a mod item. Throws an exception if anything goes wrong. */ - public static String[] getTranslations( Item item ) { + /** Gets the translations from a block. Throws an exception if anything goes wrong. */ + public static String[] getTranslations( Block block ) { return getTranslations( block, block.getDescriptionId() ); } + + /** Gets the translations from an item. Throws an exception if anything goes wrong. */ + public static String[] getTranslations( Item item ) { return getTranslations( item, item.getDescriptionId() ); } + + /** Gets the translations from a registry entry. Throws an exception if anything goes wrong. */ + public static String[] getTranslations( ForgeRegistryEntry entry, String key ) { try { - return (String[]) getMethod( item.getClass(), SpecialMob.LanguageProvider.class ) - .invoke( null, item.getDescriptionId() ); + return (String[]) getMethod( entry.getClass(), SpecialMob.LanguageProvider.class ) + .invoke( null, key ); } catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException ex ) { - throw new RuntimeException( "Item class for " + item.getRegistryName() + " has invalid language provider method", ex ); + throw new RuntimeException( "Class for " + entry.getRegistryName() + " has invalid language provider method", ex ); } } diff --git a/src/main/java/fathertoast/specialmobs/common/util/EntityUtil.java b/src/main/java/fathertoast/specialmobs/common/util/EntityUtil.java deleted file mode 100644 index 621de83..0000000 --- a/src/main/java/fathertoast/specialmobs/common/util/EntityUtil.java +++ /dev/null @@ -1,31 +0,0 @@ -package fathertoast.specialmobs.common.util; - -import fathertoast.specialmobs.common.core.SpecialMobs; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.ProjectileHelper; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.EntityRayTraceResult; -import net.minecraft.util.math.vector.Vector3d; - -import javax.annotation.Nullable; - -public class EntityUtil { - - @Nullable - public static Entity getClientPickEntity( PlayerEntity player, double pickRange ) { - if( !player.level.isClientSide ) { - SpecialMobs.LOG.error( "Tried to fetch player \"mouse-over\" entity from server side. This can't be right?" ); - return null; - } - Vector3d eyePos = player.getEyePosition( 1.0F ); - Vector3d viewVec = player.getViewVector( 1.0F ); - Vector3d targetVec = eyePos.add( viewVec.x * pickRange, viewVec.y * pickRange, viewVec.z * pickRange ); - - AxisAlignedBB AABB = player.getBoundingBox().expandTowards( viewVec.scale( pickRange ) ).inflate( 1.0D, 1.0D, 1.0D ); - EntityRayTraceResult result = ProjectileHelper.getEntityHitResult( player, eyePos, targetVec, AABB, - ( entity ) -> !entity.isSpectator() && entity.isPickable(), pickRange ); - - return result != null ? result.getEntity() : null; - } -} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/common/util/References.java b/src/main/java/fathertoast/specialmobs/common/util/References.java index 9f43b76..8440da1 100644 --- a/src/main/java/fathertoast/specialmobs/common/util/References.java +++ b/src/main/java/fathertoast/specialmobs/common/util/References.java @@ -256,7 +256,7 @@ public final class References { // Spawner mobs public static final String TAG_BABIES = "Babies"; // Mother (Cave) Spider, Wilds Witch, Queen Ghast, Wildfire Blaze public static final String TAG_EXTRA_BABIES = "ExtraBabies"; // Splitting Creeper, Mother (Cave) Spider, Wilds Witch - public static final String TAG_SUMMONS = "Summons"; // Undead Witch, Wilds Witch, Queen Ghast, Wildfire Blaze + public static final String TAG_SUMMONS = "Summons"; // Drowning Creeper, Undead Witch, Wilds Witch, Queen Ghast, Wildfire Blaze // Growing mobs public static final String TAG_GROWTH_LEVEL = "GrowthLevel"; // Hungry Spider, Conflagration Blaze diff --git a/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java b/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java index 16a49eb..587851b 100644 --- a/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java +++ b/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java @@ -16,6 +16,7 @@ public class DataGatherListener { DataGenerator generator = event.getGenerator(); if( event.includeClient() ) { + generator.addProvider( new SMBlockStateAndModelProvider( generator, event.getExistingFileHelper() ) ); generator.addProvider( new SMItemModelProvider( generator, event.getExistingFileHelper() ) ); for( Map.Entry entry : SMLanguageProvider.LANG_CODE_MAP.entrySet() ) { generator.addProvider( new SMLanguageProvider( generator, entry.getKey(), entry.getValue() ) ); diff --git a/src/main/java/fathertoast/specialmobs/datagen/SMBlockStateAndModelProvider.java b/src/main/java/fathertoast/specialmobs/datagen/SMBlockStateAndModelProvider.java new file mode 100644 index 0000000..8adfb72 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/datagen/SMBlockStateAndModelProvider.java @@ -0,0 +1,45 @@ +package fathertoast.specialmobs.datagen; + +import fathertoast.specialmobs.common.block.MeltingIceBlock; +import fathertoast.specialmobs.common.block.UnderwaterSilverfishBlock; +import fathertoast.specialmobs.common.core.SpecialMobs; +import fathertoast.specialmobs.common.core.register.SMBlocks; +import net.minecraft.block.Blocks; +import net.minecraft.data.DataGenerator; +import net.minecraftforge.client.model.generators.BlockStateProvider; +import net.minecraftforge.client.model.generators.ModelProvider; +import net.minecraftforge.client.model.generators.VariantBlockStateBuilder; +import net.minecraftforge.common.data.ExistingFileHelper; + +import java.util.Objects; + +public class SMBlockStateAndModelProvider extends BlockStateProvider { + + public SMBlockStateAndModelProvider( DataGenerator gen, ExistingFileHelper existingFileHelper ) { + super( gen, SpecialMobs.MOD_ID, existingFileHelper ); + } + + @Override + protected void registerStatesAndModels() { + String name; + + // Melting ice + final VariantBlockStateBuilder builder = getVariantBuilder( SMBlocks.MELTING_ICE.get() ); + name = Objects.requireNonNull( Blocks.FROSTED_ICE.getRegistryName() ).getPath(); + for( int age = 0; age <= 3; age++ ) { + builder.partialState().with( MeltingIceBlock.AGE, age ).modelForState().modelFile( models().getExistingFile( + mcLoc( ModelProvider.BLOCK_FOLDER + "/" + name + "_" + age ) ) ).addModel(); + } + itemModels().withExistingParent( SMBlocks.MELTING_ICE.getId().getPath(), + mcLoc( ModelProvider.BLOCK_FOLDER + "/" + name + "_0" ) ); + + // Infested coral + for( UnderwaterSilverfishBlock.Type type : UnderwaterSilverfishBlock.Type.values() ) { + name = Objects.requireNonNull( type.hostBlock().getRegistryName() ).getPath(); + + getVariantBuilder( type.block() ).partialState().modelForState().modelFile( models().getExistingFile( + mcLoc( ModelProvider.BLOCK_FOLDER + "/" + name ) ) ).addModel(); + itemModels().withExistingParent( type.blockId(), mcLoc( ModelProvider.BLOCK_FOLDER + "/" + name ) ); + } + } +} \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/datagen/SMItemModelProvider.java b/src/main/java/fathertoast/specialmobs/datagen/SMItemModelProvider.java index 9828350..33fe00c 100644 --- a/src/main/java/fathertoast/specialmobs/datagen/SMItemModelProvider.java +++ b/src/main/java/fathertoast/specialmobs/datagen/SMItemModelProvider.java @@ -22,15 +22,16 @@ public class SMItemModelProvider extends ItemModelProvider { protected void registerModels() { // Bestiary-generated spawn egg models final ResourceLocation spawnEggParent = modLoc( ITEM_FOLDER + "/template_sm_spawn_egg" ); - for( MobFamily.Species species : MobFamily.getAllSpecies() ) + for( MobFamily.Species species : MobFamily.getAllSpecies() ) { withExistingParent( species.spawnEgg.getId().getPath(), spawnEggParent ); - + } + // Simple items - for(RegistryObject regObject : SMItems.SIMPLE_ITEMS) { - String name = Objects.requireNonNull(regObject.getId()).getPath(); - - withExistingParent(name, mcLoc("item/generated")) - .texture("layer0", modLoc(ITEM_FOLDER + "/" + name)); + for( RegistryObject regObject : SMItems.SIMPLE_ITEMS ) { + final String name = Objects.requireNonNull( regObject.getId() ).getPath(); + + withExistingParent( name, mcLoc( ITEM_FOLDER + "/generated" ) ) + .texture( "layer0", modLoc( ITEM_FOLDER + "/" + name ) ); } } } \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/datagen/SMLanguageProvider.java b/src/main/java/fathertoast/specialmobs/datagen/SMLanguageProvider.java index f773ae7..941b4bf 100644 --- a/src/main/java/fathertoast/specialmobs/datagen/SMLanguageProvider.java +++ b/src/main/java/fathertoast/specialmobs/datagen/SMLanguageProvider.java @@ -2,12 +2,15 @@ package fathertoast.specialmobs.datagen; import fathertoast.specialmobs.common.bestiary.MobFamily; import fathertoast.specialmobs.common.core.SpecialMobs; +import fathertoast.specialmobs.common.core.register.SMBlocks; import fathertoast.specialmobs.common.core.register.SMEffects; 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 net.minecraft.block.Block; import net.minecraft.data.DataGenerator; +import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraftforge.common.ForgeSpawnEggItem; import net.minecraftforge.common.data.LanguageProvider; @@ -71,13 +74,18 @@ public class SMLanguageProvider extends LanguageProvider { translationList.add( References.translations( SMEntities.FISHING_BOBBER.get().getDescriptionId(), "Fishing Bobber", "", "", "", "", "", "" ) ); //TODO + // Blocks + for( RegistryObject regObject : SMBlocks.REGISTRY.getEntries() ) { + translationList.add( AnnotationHelper.getTranslations( regObject.get() ) ); + } + // Items for( RegistryObject regObject : SMItems.REGISTRY.getEntries() ) { // Lazy method of avoiding duplicate entries for now if( regObject.get() instanceof ForgeSpawnEggItem ) continue; + if( regObject.get() instanceof BlockItem ) continue; - final String[] itemTranslations = AnnotationHelper.getTranslations( regObject.get() ); - translationList.add( itemTranslations ); + translationList.add( AnnotationHelper.getTranslations( regObject.get() ) ); } // Misc diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 71af7c8..d95e0bf 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -9,6 +9,9 @@ public net.minecraft.client.renderer.RenderState field_228528_t_ # LIGHTMAP public net.minecraft.client.renderer.RenderState field_228530_v_ # OVERLAY public net.minecraft.client.renderer.RenderState field_228515_g_ # TRANSLUCENT_TRANSPARENCY +# Blocks +protected net.minecraft.block.SilverfishBlock func_235505_a_(Lnet/minecraft/world/server/ServerWorld;Lnet/minecraft/util/math/BlockPos;)V # spawnInfestation(ServerWorld, BlockPos) + # Entity registration public net.minecraft.entity.EntityType field_233593_bg_ # immuneTo public net.minecraft.entity.ai.attributes.AttributeModifierMap$MutableAttribute field_233811_a_ # builder diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/brute.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/brute.png index f1bfe2a..9eda24e 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/brute.png and b/src/main/resources/assets/specialmobs/textures/entity/drowned/brute.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/brute_overlay.png index f1bfe2a..66f601b 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/brute_overlay.png and b/src/main/resources/assets/specialmobs/textures/entity/drowned/brute_overlay.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/frozen.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/frozen.png new file mode 100644 index 0000000..cf7af5a Binary files /dev/null and b/src/main/resources/assets/specialmobs/textures/entity/drowned/frozen.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/frozen_overlay.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/frozen_overlay.png new file mode 100644 index 0000000..8c355a9 Binary files /dev/null and b/src/main/resources/assets/specialmobs/textures/entity/drowned/frozen_overlay.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry.png index faa7404..e8790f2 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry.png and b/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry_overlay.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry_overlay.png index faa7404..e84d3cc 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry_overlay.png and b/src/main/resources/assets/specialmobs/textures/entity/drowned/hungry_overlay.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/plague.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/plague.png index 0140656..a88500d 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/plague.png and b/src/main/resources/assets/specialmobs/textures/entity/drowned/plague.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/plague_overlay.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/plague_overlay.png index 0140656..e20239c 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/plague_overlay.png and b/src/main/resources/assets/specialmobs/textures/entity/drowned/plague_overlay.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/tropical.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/tropical.png new file mode 100644 index 0000000..84f9f74 Binary files /dev/null and b/src/main/resources/assets/specialmobs/textures/entity/drowned/tropical.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/vanilla_overlay.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/tropical_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entity/drowned/vanilla_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity/drowned/tropical_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entity/drowned/vanilla.png b/src/main/resources/assets/specialmobs/textures/entity/drowned/vanilla.png deleted file mode 100644 index f7fff3f..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entity/drowned/vanilla.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen.png b/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen.png index b67b295..eb4bc5b 100644 Binary files a/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen.png and b/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen_old.png b/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen_old.png new file mode 100644 index 0000000..b67b295 Binary files /dev/null and b/src/main/resources/assets/specialmobs/textures/entity/zombie/frozen_old.png differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/conflagration.png b/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/conflagration.png deleted file mode 100644 index c023afb..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/conflagration.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/ember.png b/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/ember.png deleted file mode 100644 index b706d60..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/ember.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/hellfire.png b/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/hellfire.png deleted file mode 100644 index 854b661..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/hellfire.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/inferno.png b/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/inferno.png deleted file mode 100644 index 8b349fe..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/inferno.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/jolt.png b/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/jolt.png deleted file mode 100644 index bdc007d..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/jolt.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/wildfire.png b/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/wildfire.png deleted file mode 100644 index ae427e9..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/blaze/wildfire.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/flying.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/flying.png deleted file mode 100644 index 0276493..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/flying.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/flying_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/flying_eyes.png deleted file mode 100644 index 50ee169..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/flying_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/mother.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/mother.png deleted file mode 100644 index 496e2e8..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/mother.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/mother_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/mother_eyes.png deleted file mode 100644 index 9c73c1d..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/mother_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/web.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/web.png deleted file mode 100644 index 22455d2..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/web.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/web_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/web_eyes.png deleted file mode 100644 index eebc22b..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/web_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/witch.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/witch.png deleted file mode 100644 index f702979..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/witch.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/witch_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/witch_eyes.png deleted file mode 100644 index f351546..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/cave_spider/witch_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dark.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dark.png deleted file mode 100644 index dedf549..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dark.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dark_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dark_eyes.png deleted file mode 100644 index 58b7377..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dark_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/death.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/death.png deleted file mode 100644 index a913856..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/death.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/death_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/death_eyes.png deleted file mode 100644 index f2c37bf..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/death_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dirt.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dirt.png deleted file mode 100644 index 28b237f..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/dirt.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/doom.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/doom.png deleted file mode 100644 index 5f6dff9..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/doom.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/doom_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/doom_overlay.png deleted file mode 100644 index 42aae81..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/doom_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/drowning.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/drowning.png deleted file mode 100644 index 123c698..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/drowning.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/drowning_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/drowning_eyes.png deleted file mode 100644 index 74f1895..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/drowning_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/skeleton.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/skeleton.png deleted file mode 100644 index 09863cc..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/skeleton.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/bouncing.png b/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/bouncing.png deleted file mode 100644 index 6ba470b..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/bouncing.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/hardened.png b/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/hardened.png deleted file mode 100644 index 49bf7be..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/hardened.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/sticky.png b/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/sticky.png deleted file mode 100644 index ed36b0f..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/sticky.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/volatile.png b/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/volatile.png deleted file mode 100644 index 2fa0d36..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/magma_cube/volatile.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/silverfish/fishy.png b/src/main/resources/assets/specialmobs/textures/entityNEW/silverfish/fishy.png deleted file mode 100644 index 2bcd886..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/silverfish/fishy.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/brute.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/brute.png deleted file mode 100644 index c270c27..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/brute.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/brute_overlay.png deleted file mode 100644 index 56d23cf..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/brute_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/fire.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/fire.png deleted file mode 100644 index ce42947..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/fire.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/gatling_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/gatling_overlay.png deleted file mode 100644 index b2f4306..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/gatling_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/ninja_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/ninja_overlay.png deleted file mode 100644 index 9c71a2a..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/ninja_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/poison.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/poison.png deleted file mode 100644 index 366b712..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/poison.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/poison_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/poison_overlay.png deleted file mode 100644 index 1fb05dd..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/poison_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/sniper.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/sniper.png deleted file mode 100644 index 4559ddd..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/sniper.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/sniper_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/sniper_overlay.png deleted file mode 100644 index 3447dd7..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/skeleton/sniper_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/desert.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/desert.png deleted file mode 100644 index 1ac3eab..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/desert.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/desert_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/desert_eyes.png deleted file mode 100644 index bcaa2f0..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/desert_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/flying.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/flying.png deleted file mode 100644 index a73acb6..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/flying.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/flying_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/flying_eyes.png deleted file mode 100644 index 24d6077..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/flying_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/hungry.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/hungry.png deleted file mode 100644 index 9421864..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/hungry.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/hungry_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/hungry_eyes.png deleted file mode 100644 index 88d96bb..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/hungry_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/mother.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/mother.png deleted file mode 100644 index 2557e30..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/mother.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/mother_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/mother_eyes.png deleted file mode 100644 index 9c73c1d..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/mother_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/pale.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/pale.png deleted file mode 100644 index 6797fbd..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/pale.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/pale_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/pale_eyes.png deleted file mode 100644 index f88e644..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/pale_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/web.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/web.png deleted file mode 100644 index e07ec59..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/web.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/web_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/web_eyes.png deleted file mode 100644 index 485c344..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/web_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/witch.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/witch.png deleted file mode 100644 index 55891be..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/witch.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/witch_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/spider/witch_eyes.png deleted file mode 100644 index a7f436c..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/spider/witch_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/brute.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/brute.png deleted file mode 100644 index bf349a1..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/brute.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/brute_overlay.png deleted file mode 100644 index 428890c..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/brute_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/fire.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/fire.png deleted file mode 100644 index 4996804..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/fire.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/gatling_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/gatling_overlay.png deleted file mode 100644 index ac3082e..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/gatling_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/ninja_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/ninja_overlay.png deleted file mode 100644 index aa497ef..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/ninja_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/sniper.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/sniper.png deleted file mode 100644 index c37386c..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/sniper.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/sniper_overlay.png b/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/sniper_overlay.png deleted file mode 100644 index e978274..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/wither_skeleton/sniper_overlay.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/brute.png b/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/brute.png deleted file mode 100644 index 05e9e36..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/brute.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/fire.png b/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/fire.png deleted file mode 100644 index 136907e..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/fire.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/fire_eyes.png b/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/fire_eyes.png deleted file mode 100644 index a2183dc..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/fire_eyes.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/hungry.png b/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/hungry.png deleted file mode 100644 index abcfcc7..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/hungry.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/mad_scientist.png b/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/mad_scientist.png deleted file mode 100644 index aa1ad63..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/mad_scientist.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/plague.png b/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/plague.png deleted file mode 100644 index be48b3b..0000000 Binary files a/src/main/resources/assets/specialmobs/textures/entityNEW/zombie/plague.png and /dev/null differ diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/blaze/conflagration.png b/src/main/resources/assets/specialmobs/textures/entity_old/blaze/conflagration.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/blaze/conflagration.png rename to src/main/resources/assets/specialmobs/textures/entity_old/blaze/conflagration.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/blaze/ember.png b/src/main/resources/assets/specialmobs/textures/entity_old/blaze/ember.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/blaze/ember.png rename to src/main/resources/assets/specialmobs/textures/entity_old/blaze/ember.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/blaze/hellfire.png b/src/main/resources/assets/specialmobs/textures/entity_old/blaze/hellfire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/blaze/hellfire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/blaze/hellfire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/blaze/inferno.png b/src/main/resources/assets/specialmobs/textures/entity_old/blaze/inferno.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/blaze/inferno.png rename to src/main/resources/assets/specialmobs/textures/entity_old/blaze/inferno.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/blaze/jolt.png b/src/main/resources/assets/specialmobs/textures/entity_old/blaze/jolt.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/blaze/jolt.png rename to src/main/resources/assets/specialmobs/textures/entity_old/blaze/jolt.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/blaze/wildfire.png b/src/main/resources/assets/specialmobs/textures/entity_old/blaze/wildfire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/blaze/wildfire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/blaze/wildfire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/flying.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/flying.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/flying.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/flying.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/flying_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/flying_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/flying_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/flying_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/mother.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/mother.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/mother.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/mother.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/mother_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/mother_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/mother_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/mother_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/web.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/web.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/web.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/web.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/web_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/web_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/web_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/web_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/witch.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/witch.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/witch.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/witch.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/witch_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/witch_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/cave_spider/witch_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/cave_spider/witch_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/dark.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/dark.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/dark.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/dark.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/dark_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/dark_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/dark_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/dark_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/death.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/death.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/death.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/death.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/death_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/death_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/death_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/death_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/dirt.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/dirt.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/dirt.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/dirt.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/doom.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/doom.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/doom.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/doom.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/doom_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/doom_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/doom_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/doom_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/drowning.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/drowning.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/drowning.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/drowning.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/drowning_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/drowning_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/drowning_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/drowning_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/ender.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/ender.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/ender.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/ender.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/ender_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/ender_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/ender_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/ender_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/fire.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/fire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/fire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/fire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/gravel.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/gravel.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/gravel.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/gravel.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/jumping.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/jumping.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/jumping.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/jumping.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/lightning.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/lightning.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/lightning.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/lightning.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/splitting.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/splitting.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/splitting.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/splitting.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/creeper/splitting_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/creeper/splitting_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/creeper/splitting_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/creeper/splitting_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/blinding.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/blinding.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/blinding.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/blinding.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/blinding_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/blinding_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/blinding_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/blinding_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/icy.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/icy.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/icy.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/icy.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/icy_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/icy_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/icy_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/icy_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/lightning.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/lightning.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/lightning.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/lightning.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/lightning_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/lightning_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/lightning_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/lightning_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/mirage.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/mirage.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/mirage.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/mirage.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/mirage_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/mirage_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/mirage_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/mirage_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/thief.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/thief.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/thief.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/thief.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/enderman/thief_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/enderman/thief_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/enderman/thief_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/enderman/thief_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/fighter.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/fighter.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/fighter.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/fighter.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/fighter_shooting.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/fighter_shooting.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/fighter_shooting.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/fighter_shooting.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/king.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/king.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/king.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/king.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/king_shooting.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/king_shooting.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/king_shooting.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/king_shooting.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/queen.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/queen.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/queen.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/queen.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/queen_shooting.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/queen_shooting.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/queen_shooting.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/queen_shooting.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/unholy.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/unholy.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/unholy.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/unholy.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/ghast/unholy_shooting.png b/src/main/resources/assets/specialmobs/textures/entity_old/ghast/unholy_shooting.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/ghast/unholy_shooting.png rename to src/main/resources/assets/specialmobs/textures/entity_old/ghast/unholy_shooting.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/bouncing.png b/src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/bouncing.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/bouncing.png rename to src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/bouncing.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/hardened.png b/src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/hardened.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/hardened.png rename to src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/hardened.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/sticky.png b/src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/sticky.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/sticky.png rename to src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/sticky.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/volatile.png b/src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/volatile.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/magma_cube/volatile.png rename to src/main/resources/assets/specialmobs/textures/entity_old/magma_cube/volatile.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/blinding.png b/src/main/resources/assets/specialmobs/textures/entity_old/silverfish/blinding.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/blinding.png rename to src/main/resources/assets/specialmobs/textures/entity_old/silverfish/blinding.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/fishing.png b/src/main/resources/assets/specialmobs/textures/entity_old/silverfish/fishing.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/fishing.png rename to src/main/resources/assets/specialmobs/textures/entity_old/silverfish/fishing.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/flying.png b/src/main/resources/assets/specialmobs/textures/entity_old/silverfish/flying.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/flying.png rename to src/main/resources/assets/specialmobs/textures/entity_old/silverfish/flying.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/poison.png b/src/main/resources/assets/specialmobs/textures/entity_old/silverfish/poison.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/poison.png rename to src/main/resources/assets/specialmobs/textures/entity_old/silverfish/poison.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/tough.png b/src/main/resources/assets/specialmobs/textures/entity_old/silverfish/tough.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/silverfish/tough.png rename to src/main/resources/assets/specialmobs/textures/entity_old/silverfish/tough.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/brute.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/brute.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/brute.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/brute.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/brute_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/brute_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/brute_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/fire.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/fire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/fire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/fire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/gatling_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/gatling_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/gatling_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/gatling_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/ninja_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/ninja_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/ninja_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/ninja_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/poison.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/poison.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/poison.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/poison.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/poison_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/poison_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/poison_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/poison_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/sniper.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/sniper.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/sniper.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/sniper.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/sniper_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/skeleton/sniper_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/skeleton/sniper_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/skeleton/sniper_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/blackberry.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/blackberry.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/blackberry.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/blackberry.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/blueberry.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/blueberry.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/blueberry.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/blueberry.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/caramel.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/caramel.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/caramel.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/caramel.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/grape.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/grape.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/grape.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/grape.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/lemon.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/lemon.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/lemon.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/lemon.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/strawberry.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/strawberry.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/strawberry.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/strawberry.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/slime/watermelon.png b/src/main/resources/assets/specialmobs/textures/entity_old/slime/watermelon.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/slime/watermelon.png rename to src/main/resources/assets/specialmobs/textures/entity_old/slime/watermelon.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/desert.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/desert.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/desert.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/desert.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/desert_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/desert_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/desert_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/desert_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/flying.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/flying.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/flying.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/flying.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/flying_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/flying_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/flying_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/flying_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/hungry.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/hungry.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/hungry.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/hungry.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/hungry_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/hungry_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/hungry_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/hungry_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/mother.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/mother.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/mother.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/mother.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/mother_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/mother_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/mother_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/mother_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/pale.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/pale.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/pale.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/pale.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/pale_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/pale_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/pale_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/pale_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/web.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/web.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/web.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/web.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/web_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/web_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/web_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/web_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/witch.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/witch.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/witch.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/witch.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/spider/witch_eyes.png b/src/main/resources/assets/specialmobs/textures/entity_old/spider/witch_eyes.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/spider/witch_eyes.png rename to src/main/resources/assets/specialmobs/textures/entity_old/spider/witch_eyes.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/witch/domination.png b/src/main/resources/assets/specialmobs/textures/entity_old/witch/domination.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/witch/domination.png rename to src/main/resources/assets/specialmobs/textures/entity_old/witch/domination.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/witch/shadows.png b/src/main/resources/assets/specialmobs/textures/entity_old/witch/shadows.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/witch/shadows.png rename to src/main/resources/assets/specialmobs/textures/entity_old/witch/shadows.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/witch/undead.png b/src/main/resources/assets/specialmobs/textures/entity_old/witch/undead.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/witch/undead.png rename to src/main/resources/assets/specialmobs/textures/entity_old/witch/undead.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/witch/wilds.png b/src/main/resources/assets/specialmobs/textures/entity_old/witch/wilds.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/witch/wilds.png rename to src/main/resources/assets/specialmobs/textures/entity_old/witch/wilds.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/witch/wind.png b/src/main/resources/assets/specialmobs/textures/entity_old/witch/wind.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/witch/wind.png rename to src/main/resources/assets/specialmobs/textures/entity_old/witch/wind.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/brute.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/brute.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/brute.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/brute.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/brute_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/brute_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/brute_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/fire.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/fire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/fire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/fire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/gatling_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/gatling_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/gatling_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/gatling_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/ninja_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/ninja_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/ninja_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/ninja_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/sniper.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/sniper.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/sniper.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/sniper.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/sniper_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/sniper_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/wither_skeleton/sniper_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/wither_skeleton/sniper_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombie/brute.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombie/brute.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombie/brute.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombie/brute.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombie/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombie/brute_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombie/brute_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombie/brute_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombie/fire.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombie/fire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombie/fire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombie/fire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombie/hungry.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombie/hungry.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombie/hungry.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombie/hungry.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombie/husk.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombie/husk.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombie/husk.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombie/husk.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombie/plague.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombie/plague.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombie/plague.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombie/plague.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/brute.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/brute.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/brute.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/brute.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/brute_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/brute_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/brute_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/brute_overlay.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/hungry.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/hungry.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/hungry.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/hungry.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/plague.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/plague.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/plague.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/plague.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/vampire.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/vampire.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/vampire.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/vampire.png diff --git a/src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/vampire_overlay.png b/src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/vampire_overlay.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityOLD/zombified_piglin/vampire_overlay.png rename to src/main/resources/assets/specialmobs/textures/entity_old/zombified_piglin/vampire_overlay.png diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 129efa9..898f3ce 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -6,7 +6,7 @@ - Fixed issue preventing all attribute modifications during mob replacement. Fixes the superspeed ghasts. - Life loss and life steal effects can no longer reduce life below 1 (half a heart). Prevents inventory loss bug. - Witches of the Wilds now spawn 3 baby spiders with their summon spell by default instead of 0. - - No longer copies UUID when replcing mobs. Might mess up some things, but also should prevent odd glitches. + - No longer copies UUID when replacing mobs. Might mess up some things, but also should prevent odd glitches. 1.0.2 - Fixed server crash caused by mirage enderman teleport. 1.0.1