diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index 7196b59c5..91476fd94 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -2935,8 +2935,8 @@ public class ModBlocks { GameRegistry.registerBlock(mush, mush.getUnlocalizedName()); GameRegistry.registerBlock(mush_block, mush_block.getUnlocalizedName()); GameRegistry.registerBlock(mush_block_stem, mush_block_stem.getUnlocalizedName()); - GameRegistry.registerBlock(glyphid_base, glyphid_base.getUnlocalizedName()); - GameRegistry.registerBlock(glyphid_spawner, glyphid_spawner.getUnlocalizedName()); + register(glyphid_base); + register(glyphid_spawner); GameRegistry.registerBlock(moon_turf, moon_turf.getUnlocalizedName()); //Waste diff --git a/src/main/java/com/hbm/blocks/generic/BlockGlyphid.java b/src/main/java/com/hbm/blocks/generic/BlockGlyphid.java index 267624e28..e94c67f14 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockGlyphid.java +++ b/src/main/java/com/hbm/blocks/generic/BlockGlyphid.java @@ -1,21 +1,36 @@ package com.hbm.blocks.generic; +import java.util.List; +import java.util.Random; + +import com.hbm.blocks.IBlockMulti; import com.hbm.lib.RefStrings; +import com.hbm.main.MainRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; -public class BlockGlyphid extends Block { - - public IIcon[] icons = new IIcon[2]; +public class BlockGlyphid extends Block implements IBlockMulti { + + public IIcon[] iconsStandard = new IIcon[2]; + public IIcon[] iconsInfested = new IIcon[2]; public BlockGlyphid(Material mat) { super(mat); + this.setCreativeTab(MainRegistry.blockTab); + } + + @Override + public Item getItemDropped(int meta, Random rand, int fortune) { + return null; } @Override @@ -24,20 +39,39 @@ public class BlockGlyphid extends Block { long l = (long) (x * 3129871) ^ (long)y * 116129781L ^ (long)z; l = l * l * 42317861L + l * 11L; int i = (int)(l >> 16 & 3L); - return icons[(int)(Math.abs(i) % this.icons.length)]; + IIcon[] icons = this.getIconArray(world.getBlockMetadata(x, y, z)); + return icons[(int)(Math.abs(i) % icons.length)]; } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int meta) { - return icons[meta % this.icons.length]; + IIcon[] icons = this.getIconArray(meta); + return icons[meta % icons.length]; } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister reg) { - icons[0] = reg.registerIcon(RefStrings.MODID + ":glyphid_base"); - icons[1] = reg.registerIcon(RefStrings.MODID + ":glyphid_base_alt"); + iconsStandard[0] = reg.registerIcon(RefStrings.MODID + ":glyphid_base"); + iconsStandard[1] = reg.registerIcon(RefStrings.MODID + ":glyphid_base_alt"); + iconsInfested[0] = reg.registerIcon(RefStrings.MODID + ":glyphid_base_infested"); + iconsInfested[1] = reg.registerIcon(RefStrings.MODID + ":glyphid_base_infested_alt"); } + protected IIcon[] getIconArray(int meta) { + if(meta == 1) return this.iconsInfested; + return this.iconsStandard; + } + + @Override + public int getSubCount() { + return 2; + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for(int i = 0; i < getSubCount(); ++i) list.add(new ItemStack(item, 1, i)); + } } diff --git a/src/main/java/com/hbm/blocks/generic/BlockGlyphidSpawner.java b/src/main/java/com/hbm/blocks/generic/BlockGlyphidSpawner.java index f02a8efba..e4d07db08 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockGlyphidSpawner.java +++ b/src/main/java/com/hbm/blocks/generic/BlockGlyphidSpawner.java @@ -1,33 +1,40 @@ package com.hbm.blocks.generic; -import java.util.List; -import java.util.Random; +import java.util.*; +import java.util.function.Function; +import com.hbm.blocks.IBlockMulti; import com.hbm.config.MobConfig; -import com.hbm.entity.mob.EntityGlyphid; -import com.hbm.entity.mob.EntityGlyphidBehemoth; -import com.hbm.entity.mob.EntityGlyphidBlaster; -import com.hbm.entity.mob.EntityGlyphidBombardier; -import com.hbm.entity.mob.EntityGlyphidBrawler; -import com.hbm.entity.mob.EntityGlyphidBrenda; -import com.hbm.entity.mob.EntityGlyphidNuclear; -import com.hbm.entity.mob.EntityGlyphidScout; +import com.hbm.entity.mob.*; import com.hbm.handler.pollution.PollutionHandler; import com.hbm.handler.pollution.PollutionHandler.PollutionType; import com.hbm.items.ModItems; +import com.hbm.lib.RefStrings; +import com.hbm.main.MainRegistry; +import com.hbm.util.Tuple.Pair; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.IIcon; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -public class BlockGlyphidSpawner extends BlockContainer { +public class BlockGlyphidSpawner extends BlockContainer implements IBlockMulti { + + public IIcon[] icons = new IIcon[2]; - public BlockGlyphidSpawner(Material p_i45386_1_) { - super(p_i45386_1_); + public BlockGlyphidSpawner(Material mat) { + super(mat); + this.setCreativeTab(MainRegistry.blockTab); } @Override @@ -35,6 +42,44 @@ public class BlockGlyphidSpawner extends BlockContainer { return ModItems.egg_glyphid; } + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + return icons[meta % icons.length]; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister reg) { + icons[0] = reg.registerIcon(RefStrings.MODID + ":glyphid_eggs_alt"); + icons[1] = reg.registerIcon(RefStrings.MODID + ":glyphid_eggs_infested"); + } + + @Override + public int getSubCount() { + return 2; + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for(int i = 0; i < getSubCount(); ++i) list.add(new ItemStack(item, 1, i)); + } + + private static final ArrayList, int[]>> spawnMap = new ArrayList<>(); + + static { + // big thanks to martin for the suggestion of using functions + spawnMap.add(new Pair<>(EntityGlyphid::new, MobConfig.glyphidChance)); + spawnMap.add(new Pair<>(EntityGlyphidBombardier::new, MobConfig.bombardierChance)); + spawnMap.add(new Pair<>(EntityGlyphidBrawler::new, MobConfig.brawlerChance)); + spawnMap.add(new Pair<>(EntityGlyphidDigger::new, MobConfig.diggerChance)); + spawnMap.add(new Pair<>(EntityGlyphidBlaster::new, MobConfig.blasterChance)); + spawnMap.add(new Pair<>(EntityGlyphidBehemoth::new, MobConfig.behemothChance)); + spawnMap.add(new Pair<>(EntityGlyphidBrenda::new, MobConfig.brendaChance)); + spawnMap.add(new Pair<>(EntityGlyphidNuclear::new, MobConfig.johnsonChance)); + } + @Override public int quantityDropped(int meta, int fortune, Random rand) { return 1 + rand.nextInt(3) + fortune; @@ -46,47 +91,95 @@ public class BlockGlyphidSpawner extends BlockContainer { } public static class TileEntityGlpyhidSpawner extends TileEntity { - + + boolean initialSpawn = true; + @Override public void updateEntity() { - - if(!worldObj.isRemote && worldObj.getTotalWorldTime() % 60 == 0 && this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL) { - - int count = 0; - - for(Object e : worldObj.loadedEntityList) { - if(e instanceof EntityGlyphid) { - count++; - if(count >= MobConfig.spawnMax) return; - } - } - float soot = PollutionHandler.getPollution(worldObj, xCoord, yCoord, zCoord, PollutionType.SOOT); - List list = worldObj.getEntitiesWithinAABB(EntityGlyphid.class, AxisAlignedBB.getBoundingBox(xCoord - 6, yCoord + 1, zCoord - 6, xCoord + 7, yCoord + 9, zCoord + 7)); - - if(list.size() < 3) { - EntityGlyphid glyphid = createGlyphid(soot); - glyphid.setLocationAndAngles(xCoord + 0.5, yCoord + 1, zCoord + 0.5, worldObj.rand.nextFloat() * 360.0F, 0.0F); - this.worldObj.spawnEntityInWorld(glyphid); - } - - if(worldObj.rand.nextInt(20) == 0 && soot >= MobConfig.scoutThreshold) { - EntityGlyphidScout scout = new EntityGlyphidScout(worldObj); - scout.setLocationAndAngles(xCoord + 0.5, yCoord + 1, zCoord + 0.5, worldObj.rand.nextFloat() * 360.0F, 0.0F); - this.worldObj.spawnEntityInWorld(scout); + if(!worldObj.isRemote && this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL) { + + if(initialSpawn || worldObj.getTotalWorldTime() % MobConfig.swarmCooldown == 0) { + + int count = 0; + + for(Object e : worldObj.loadedEntityList) { + if(e instanceof EntityGlyphid) { + count++; + if(count >= MobConfig.spawnMax) return; + } + } + + List list = worldObj.getEntitiesWithinAABB(EntityGlyphid.class, AxisAlignedBB.getBoundingBox(xCoord - 5, yCoord + 1, zCoord - 5, xCoord + 6, yCoord + 7, zCoord + 6)); + float soot = PollutionHandler.getPollution(worldObj, xCoord, yCoord, zCoord, PollutionType.SOOT); + + if(list.size() <= 3) { + + ArrayList currentSwarm = createSwarm(soot, this.getBlockMetadata()); + + for(EntityGlyphid glyphid : currentSwarm) { + trySpawnEntity(glyphid); + } + + if(!initialSpawn && worldObj.rand.nextInt(MobConfig.scoutSwarmSpawnChance + 1) == 0 && soot >= MobConfig.scoutThreshold) { + EntityGlyphidScout scout = new EntityGlyphidScout(worldObj); + if(this.getBlockMetadata() == 1) scout.getDataWatcher().updateObject(EntityGlyphid.DW_SUBTYPE, (byte) EntityGlyphid.TYPE_INFECTED); + trySpawnEntity(scout); + } + + initialSpawn = false; + } } } } - public EntityGlyphid createGlyphid(float soot) { - Random rand = new Random(); - - if(soot < MobConfig.tier2Threshold) return rand.nextInt(5) == 0 ? new EntityGlyphidBombardier(worldObj) : new EntityGlyphid(worldObj); - if(soot < MobConfig.tier3Threshold) return rand.nextInt(5) == 0 ? new EntityGlyphidBombardier(worldObj) : new EntityGlyphidBrawler(worldObj); - if(soot < MobConfig.tier4Threshold) return rand.nextInt(5) == 0 ? new EntityGlyphidBlaster(worldObj) : new EntityGlyphidBehemoth(worldObj); - if(soot < MobConfig.tier5Threshold) return rand.nextInt(5) == 0 ? new EntityGlyphidBlaster(worldObj) : new EntityGlyphidBrenda(worldObj); + public void trySpawnEntity(EntityGlyphid glyphid) { + double offsetX = glyphid.getRNG().nextGaussian() * 3; + double offsetZ = glyphid.getRNG().nextGaussian() * 3; - return rand.nextInt(3) == 0 ? new EntityGlyphidBlaster(worldObj) : new EntityGlyphidNuclear(worldObj); + for(int i = 0; i < 7; i++) { + glyphid.setLocationAndAngles(xCoord + 0.5 + offsetX, yCoord - 2 + i, zCoord + 0.5 + offsetZ, worldObj.rand.nextFloat() * 360.0F, 0.0F); + if(glyphid.getCanSpawnHere()) { + worldObj.spawnEntityInWorld(glyphid); + return; + } + } + } + + public ArrayList createSwarm(float soot, int meta) { + + Random rand = new Random(); + ArrayList currentSpawns = new ArrayList<>(); + int swarmAmount = (int) Math.min(MobConfig.baseSwarmSize * Math.max(MobConfig.swarmScalingMult * (soot / MobConfig.sootStep), 1), 10); + int cap = 100; + + while(currentSpawns.size() <= swarmAmount && cap >= 0) { + // (dys)functional programing + for(Pair, int[]> glyphid : spawnMap) { + int[] chance = glyphid.getValue(); + int adjustedChance = (int) (chance[0] + (chance[1] - chance[1] / Math.max(((soot + 1) / 3), 1))); + if(soot >= chance[2] && rand.nextInt(100) <= adjustedChance) { + EntityGlyphid entity = glyphid.getKey().apply(worldObj); + if(meta == 1) entity.getDataWatcher().updateObject(EntityGlyphid.DW_SUBTYPE, (byte) EntityGlyphid.TYPE_INFECTED); + currentSpawns.add(entity); + } + } + + cap--; + } + return currentSpawns; + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setBoolean("initialSpawn", initialSpawn); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.initialSpawn = nbt.getBoolean("initialSpawn"); } } } diff --git a/src/main/java/com/hbm/blocks/generic/BlockLoot.java b/src/main/java/com/hbm/blocks/generic/BlockLoot.java index db0a966f7..cf949e161 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockLoot.java +++ b/src/main/java/com/hbm/blocks/generic/BlockLoot.java @@ -51,14 +51,6 @@ public class BlockLoot extends BlockContainer { @Override public void onBlockAdded(World world, int x, int y, int z) { super.onBlockAdded(world, x, y, z); - - /*TileEntityLoot loot = (TileEntityLoot) world.getTileEntity(x, y, z); - - if(loot != null && loot.items.isEmpty()) { - loot.addItem(new ItemStack(ModItems.gun_lever_action), 0, 0, 0); - }*/ - - //LootGenerator.lootCapStash(world, x, y, z); } @Override diff --git a/src/main/java/com/hbm/config/CommonConfig.java b/src/main/java/com/hbm/config/CommonConfig.java index 7e121b26e..578f98bef 100644 --- a/src/main/java/com/hbm/config/CommonConfig.java +++ b/src/main/java/com/hbm/config/CommonConfig.java @@ -74,7 +74,11 @@ public class CommonConfig { prop.comment = comment; return prop.getString(); } - + public static int[] createConfigIntList(Configuration config, String category, String name, String comment, int[] def){ + Property prop = config.get(category, name, def); + prop.comment = comment; + return prop.getIntList(); + } public static String[] createConfigStringList(Configuration config, String category, String name, String comment) { Property prop = config.get(category, name, new String[] { "PLACEHOLDER" }); prop.comment = comment; diff --git a/src/main/java/com/hbm/config/MobConfig.java b/src/main/java/com/hbm/config/MobConfig.java index 8ce250f40..7f9d45c9d 100644 --- a/src/main/java/com/hbm/config/MobConfig.java +++ b/src/main/java/com/hbm/config/MobConfig.java @@ -30,14 +30,42 @@ public class MobConfig { public static boolean enableHives = true; public static int hiveSpawn = 256; - public static double scoutThreshold = 0.1; - public static double tier2Threshold = 1; - public static double tier3Threshold = 10; - public static double tier4Threshold = 50; - public static double tier5Threshold = 100; + public static double scoutThreshold = 5; + public static int scoutSwarmSpawnChance = 2; + public static boolean waypointDebug = false; + public static int largeHiveChance = 5; + public static int largeHiveThreshold = 30; + + public static int swarmCooldown = 120 * 20; + + public static int baseSwarmSize = 5; + public static double swarmScalingMult = 1.2; + public static int sootStep = 50; + + public static int[] glyphidChance = {50, -40, 0}; + public static int[] brawlerChance = {5, 35, 1}; + public static int[] bombardierChance = {20, -15, 1}; + public static int[] blasterChance = {-15, 40, 5}; + public static int[] diggerChance = {-15, 25, 5}; + public static int[] behemothChance = {-30, 45, 10}; + public static int[] brendaChance = {-50, 60, 20}; + public static int[] johnsonChance = {-50, 60, 50}; + public static double spawnMax = 50; + public static boolean enableInfestation = true; + public static double baseInfestChance = 5; public static double targetingThreshold = 1; - + + public static boolean rampantMode = false; + public static boolean rampantNaturalScoutSpawn = false; + public static double rampantScoutSpawnThresh = 20; + public static int rampantScoutSpawnChance = 1000; + public static boolean scoutInitialSpawn = false; + public static boolean rampantExtendedTargetting = false; + public static boolean rampantDig = false; + public static boolean rampantGlyphidGuidance = false; + public static double rampantSmokeStackOverride = 0.4; + public static double pollutionMult = 3; public static void loadFromConfig(Configuration config) { @@ -69,12 +97,83 @@ public class MobConfig { enableHives = CommonConfig.createConfigBool(config, CATEGORY, "12.G00_enableHives", "Whether glyphid hives should spawn", true); hiveSpawn = CommonConfig.createConfigInt(config, CATEGORY, "12.G01_hiveSpawn", "The average amount of chunks per hive", 256); - scoutThreshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G02_scoutThreshold", "Minimum amount of soot for scouts to spawn", 0.1); - tier2Threshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G03_tier2Threshold", "Minimum amount of soot for tier 2 glyphids to spawn", 1); - tier3Threshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G04_tier3Threshold", "Minimum amount of soot for tier 3 glyphids to spawn", 10); - tier4Threshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G05_tier4Threshold", "Minimum amount of soot for tier 4 glyphids to spawn", 50); - tier5Threshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G06_tier5Threshold", "Minimum amount of soot for tier 5 glyphids to spawn", 100); + scoutThreshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G02_scoutThreshold", "Minimum amount of soot for scouts to spawn", 1); spawnMax = CommonConfig.createConfigDouble(config, CATEGORY, "12.G07_spawnMax", "Maximum amount of glyphids being able to exist at once through natural spawning", 50); targetingThreshold = CommonConfig.createConfigDouble(config, CATEGORY, "12.G08_targetingThreshold", "Minimum amount of soot required for glyphids' extended targeting range to activate", 1D); + + scoutSwarmSpawnChance = CommonConfig.createConfigInt(config, CATEGORY,"12.G10_scoutSwarmSpawn", "How likely are scouts to spawn in swarms, 1 in x chance format", 2); + + largeHiveChance = CommonConfig.createConfigInt(config, CATEGORY,"12.G11_largeHiveChance", "The chance for a large hive to spawn, formula: 1/x", 5); + largeHiveThreshold = CommonConfig.createConfigInt(config, CATEGORY,"12.G12_largeHiveThreshold", "The soot threshold for a large hive to spawn", 20); + + waypointDebug = CommonConfig.createConfigBool(config, CATEGORY,"12.G13_waypointDebug", "Allows glyphid waypoints to be seen, mainly used for debugging, also useful as an aid against them", false); + + //Infested structures + enableInfestation= CommonConfig.createConfigBool(config, CATEGORY, "12.I01_enableInfestation", "Whether structures infested with glyphids should spawn", true); + baseInfestChance = CommonConfig.createConfigDouble(config, CATEGORY, "12.I02_baseInfestChance", "The chance for infested structures to spawn", 5); + + //Glyphid spawn stuff + config.addCustomCategoryComment(CATEGORY, + "General Glyphid spawn logic configuration\n" + + "\n" + + "The first number is the base chance which applies at 0 soot,\n" + + "the second number is the modifier that applies with soot based on the formular below,\n" + + "the third number is a hard minimum of soot for this type to spawn.\n" + + "Negative base chances mean that glyphids won't spawn outright, negative modifiers mean that the type becomes less likely with higher soot.\n" + + "The formula for glyphid spawning chance is: (base chance + (modifier - modifier / max( (soot + 1)/3, 3 )))\n" + + "The formula for glyphid swarm scaling is: (baseSwarmSize * Math.max(swarmScalingMult * soot/sootStep, 1))"); + + + baseSwarmSize = CommonConfig.createConfigInt(config, CATEGORY, "12.GS01_baseSwarmSize", "The basic, soot-less swarm size", 5); + swarmScalingMult = CommonConfig.createConfigDouble(config, CATEGORY, "12.GS02_swarmScalingMult", "By how much should swarm size scale by per soot amount determined below", 1.2); + sootStep = CommonConfig.createConfigInt(config, CATEGORY, "12.GS03_sootStep", "The soot amount the above multiplier applies to the swarm size", 50); + swarmCooldown = CommonConfig.createConfigInt(config, CATEGORY, "12.GS04_swarmCooldown", "How often do glyphid swarms spawn, in seconds", 120) * 20; + + glyphidChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC01_glyphidChance", "Base Spawn chance and soot modifier for a glyphid grunt", new int[]{50, -45, 0}); + brawlerChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC02_brawlerChance", "Base Spawn chance and soot modifier for a glyphid brawler", new int[]{10, 30, 1}); + bombardierChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC03_bombardierChance", "Base Spawn chance and soot modifier for a glyphid bombardier", new int[]{20, -15, 1}); + blasterChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC04_blasterChance", "Base Spawn chance and soot modifier for a glyphid blaster", new int[]{-5, 40, 5}); + diggerChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC05_diggerChance", "Base Spawn chance and soot modifier for a glyphid digger", new int[]{-15, 25, 5}); + behemothChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC06_behemothChance", "Base Spawn chance and soot modifier for a glyphid behemoth", new int[]{-30, 45, 10}); + brendaChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC07_brendaChance", "Base Spawn chance and soot modifier for a glyphid brenda", new int[]{-50, 60, 20}); + johnsonChance = CommonConfig.createConfigIntList(config, CATEGORY, "12.GC08_johnsonChance", "Base Spawn chance and soot modifier for Big Man Johnson", new int[]{-50, 60, 50}); + + String rampantDesc = "Rampant Mode changes glyphid behavior and spawning to be more aggressive, changes include:\n" + + "\n" + + "Glyphid Scouts will naturally spawn alongside normal mobs if soot levels are above a certain threshold\n" + + "Glyphids will always have the extended targetting enabled\n" + + "Glyphids can dig to waypoints\n" + + "The Glyphids will expand always toward your base\n" + + "Scouts will spawn from the start, making glyphids start expanding off the bat\n" + + "Smokestacks have reduced efficiency, only reducing soot by 40%\n"; + + config.addCustomCategoryComment(CATEGORY,rampantDesc); + + rampantMode = CommonConfig.createConfigBool(config, CATEGORY, "12.R01_rampantMode", "The main rampant mode toggle, enables all other features associated with it", false); + + config.addCustomCategoryComment(CATEGORY, "The individual features of rampant can be used regardless of whether the main rampant toggle is enabled or not"); + + rampantNaturalScoutSpawn = CommonConfig.createConfigBool(config, CATEGORY,"12.R02_rampantScoutSpawn", "Whether scouts should spawn natually in highly polluted chunks", false); + rampantScoutSpawnChance = CommonConfig.createConfigInt(config, CATEGORY, "12.R02.1_rampantScoutSpawnChance", "How much soot is needed for scouts to naturally spawn", 20); + rampantScoutSpawnThresh = CommonConfig.createConfigDouble(config, CATEGORY, "12.R02.2_rampantScoutSpawnThresh", "How often scouts naturally spawn per mob population, 1/x format, the bigger the number, the more uncommon the scouts", 600); + rampantExtendedTargetting = CommonConfig.createConfigBool(config, CATEGORY,"12.R03_rampantExtendedTargeting", "Whether Glyphids should have the extended targetting always enabled", false); + rampantDig = CommonConfig.createConfigBool(config, CATEGORY,"12.R04_rampantDig", "Whether Glyphids should be able to dig to waypoints", false); + rampantGlyphidGuidance = CommonConfig.createConfigBool(config, CATEGORY,"12.R05_rampantGlyphidGuidance", "Whether Glyphids should always expand toward a player's spawnpoint", false); + rampantSmokeStackOverride = CommonConfig.createConfigDouble(config, CATEGORY, "12.R06_rampantSmokeStackOverride", "How much should the smokestack multiply soot by when on rampant mode", 0.4); + scoutInitialSpawn = CommonConfig.createConfigBool(config, CATEGORY,"12.R07_scoutInitialSpawn", "Whether glyphid scouts should be able to spawn on the first swarm of a hive, causes glyphids to expand significantly faster", false); + pollutionMult = CommonConfig.createConfigDouble(config, CATEGORY, "12.R08_pollutionMult", "A multiplier for soot emitted, whether you want to increase or decrease it", 1); + + if(rampantMode){ + rampantNaturalScoutSpawn = true; + rampantExtendedTargetting = true; + rampantDig = true; + rampantGlyphidGuidance = true; + scoutSwarmSpawnChance = 1; + scoutThreshold = 0.1; + if(pollutionMult == 1) { + pollutionMult = 2; + } + RadiationConfig.sootFogThreshold *= pollutionMult; + } } } diff --git a/src/main/java/com/hbm/config/RadiationConfig.java b/src/main/java/com/hbm/config/RadiationConfig.java index 25be90304..83cf7a10d 100644 --- a/src/main/java/com/hbm/config/RadiationConfig.java +++ b/src/main/java/com/hbm/config/RadiationConfig.java @@ -31,6 +31,7 @@ public class RadiationConfig { public static double buffMobThreshold = 15D; public static double sootFogThreshold = 35D; public static double sootFogDivisor = 120D; + public static double smokeStackSootMult = 0.8; public static void loadFromConfig(Configuration config) { @@ -68,5 +69,6 @@ public class RadiationConfig { buffMobThreshold = CommonConfig.createConfigDouble(config, CATEGORY_POL, "POL_05_buffMobThreshold", "The amount of soot required to buff naturally spawning mobs", 15D); sootFogThreshold = CommonConfig.createConfigDouble(config, CATEGORY_POL, "POL_06_sootFogThreshold", "How much soot is required for smog to become visible", 35D); sootFogDivisor = CommonConfig.createConfigDouble(config, CATEGORY_POL, "POL_07_sootFogDivisor", "The divisor for smog, higher numbers will require more soot for the same smog density", 120D); + smokeStackSootMult = CommonConfig.createConfigDouble(config, CATEGORY_POL, "POL_08_smokeStackSootMult", "How much does smokestack multiply soot by, with decimal values reducing the soot", 0.8); } } diff --git a/src/main/java/com/hbm/entity/EntityMappings.java b/src/main/java/com/hbm/entity/EntityMappings.java index 16a452ba5..6e25d2040 100644 --- a/src/main/java/com/hbm/entity/EntityMappings.java +++ b/src/main/java/com/hbm/entity/EntityMappings.java @@ -233,7 +233,10 @@ public class EntityMappings { addEntity(TrainCargoTram.class, "entity_ntm_cargo_tram", 250, false); addEntity(TrainCargoTramTrailer.class, "entity_ntm_cargo_tram_trailer", 250, false); addEntity(TrainTunnelBore.class, "entity_ntm_tunnel_bore", 250, false); - + + addEntity(EntityDisperserCanister.class, "entity_disperser", 250); + addEntity(EntityWaypoint.class, "entity_waypoint", 250, false); + addMob(EntityCreeperNuclear.class, "entity_mob_nuclear_creeper", 0x204131, 0x75CE00); addMob(EntityCreeperTainted.class, "entity_mob_tainted_creeper", 0x813b9b, 0xd71fdd); addMob(EntityCreeperPhosgene.class, "entity_mob_phosgene_creeper", 0xE3D398, 0xB8A06B); @@ -262,7 +265,9 @@ public class EntityMappings { addMob(EntityGlyphidBlaster.class, "entity_glyphid_blaster", 0xD83737, 0xDBB79D); addMob(EntityGlyphidScout.class, "entity_glyphid_scout", 0x273038, 0xB9E36B); addMob(EntityGlyphidNuclear.class, "entity_glyphid_nuclear", 0x267F00, 0xA0A0A0); + addMob(EntityGlyphidDigger.class, "entity_glyphid_digger", 0x273038, 0x724A21); addMob(EntityPlasticBag.class, "entity_plastic_bag", 0xd0d0d0, 0x808080); + addMob(EntityParasiteMaggot.class, "entity_parasite_maggot", 0xd0d0d0, 0x808080); addSpawn(EntityCreeperPhosgene.class, 5, 1, 1, EnumCreatureType.monster, BiomeGenBase.getBiomeGenArray()); addSpawn(EntityCreeperVolatile.class, 10, 1, 1, EnumCreatureType.monster, BiomeGenBase.getBiomeGenArray()); diff --git a/src/main/java/com/hbm/entity/effect/EntityMist.java b/src/main/java/com/hbm/entity/effect/EntityMist.java index ceb2dc014..713ebf06e 100644 --- a/src/main/java/com/hbm/entity/effect/EntityMist.java +++ b/src/main/java/com/hbm/entity/effect/EntityMist.java @@ -2,15 +2,13 @@ package com.hbm.entity.effect; import java.util.List; +import com.hbm.entity.mob.EntityGlyphid; +import com.hbm.entity.projectile.EntityChemical; import com.hbm.extprop.HbmLivingProps; import com.hbm.handler.radiation.ChunkRadiationManager; import com.hbm.inventory.fluid.FluidType; import com.hbm.inventory.fluid.Fluids; -import com.hbm.inventory.fluid.trait.FT_Corrosive; -import com.hbm.inventory.fluid.trait.FT_Flammable; -import com.hbm.inventory.fluid.trait.FT_Poison; -import com.hbm.inventory.fluid.trait.FT_Toxin; -import com.hbm.inventory.fluid.trait.FT_VentRadiation; +import com.hbm.inventory.fluid.trait.*; import com.hbm.inventory.fluid.trait.FluidTraitSimple.FT_Gaseous; import com.hbm.inventory.fluid.trait.FluidTraitSimple.FT_Gaseous_ART; import com.hbm.inventory.fluid.trait.FluidTraitSimple.FT_Liquid; @@ -25,13 +23,16 @@ import com.hbm.util.ContaminationUtil.HazardType; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; public class EntityMist extends Entity { @@ -40,12 +41,16 @@ public class EntityMist extends Entity { super(world); this.noClip = true; } - + public int maxAge = 150; public EntityMist setArea(float width, float height) { this.dataWatcher.updateObject(11, width); this.dataWatcher.updateObject(12, height); return this; } + public EntityMist setDuration(int duration){ + this.maxAge = duration; + return this; + } @Override protected void entityInit() { @@ -74,7 +79,7 @@ public class EntityMist extends Entity { if(!worldObj.isRemote) { - if(this.ticksExisted > this.getMaxAge()) { + if(this.ticksExisted >= this.getMaxAge()) { this.setDead(); } @@ -128,7 +133,7 @@ public class EntityMist extends Entity { EntityLivingBase living = e instanceof EntityLivingBase ? (EntityLivingBase) e : null; if(type.temperature >= 100) { - EntityDamageUtil.attackEntityFromIgnoreIFrame(e, new DamageSource(ModDamageSource.s_boil), 5F + (type.temperature - 100) * 0.02F); + EntityDamageUtil.attackEntityFromIgnoreIFrame(e, new DamageSource(ModDamageSource.s_boil), 0.2F + (type.temperature - 100) * 0.02F); if(type.temperature >= 500) { e.setFire(10); //afterburn for 10 seconds @@ -136,7 +141,7 @@ public class EntityMist extends Entity { } if(type.temperature < -20) { if(living != null) { //only living things are affected - EntityDamageUtil.attackEntityFromIgnoreIFrame(e, new DamageSource(ModDamageSource.s_cryolator), 5F + (type.temperature + 20) * -0.05F); //5 damage at -20°C with one extra damage every -20°C + EntityDamageUtil.attackEntityFromIgnoreIFrame(e, new DamageSource(ModDamageSource.s_cryolator), 0.2F + (type.temperature + 20) * -0.05F); //5 damage at -20°C with one extra damage every -20°C living.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 2)); living.addPotionEffect(new PotionEffect(Potion.digSlowdown.id, 100, 4)); } @@ -160,11 +165,11 @@ public class EntityMist extends Entity { if(type.hasTrait(FT_Corrosive.class)) { FT_Corrosive trait = type.getTrait(FT_Corrosive.class); - EntityDamageUtil.attackEntityFromIgnoreIFrame(e, new DamageSource(ModDamageSource.s_acid), trait.getRating() / 20F); if(living != null) { + EntityDamageUtil.attackEntityFromIgnoreIFrame(living, ModDamageSource.acid, trait.getRating() / 60F); for(int i = 0; i < 4; i++) { - ArmorUtil.damageSuit(living, i, trait.getRating() / 5); + ArmorUtil.damageSuit(living, i, trait.getRating() / 50); } } } @@ -191,14 +196,37 @@ public class EntityMist extends Entity { trait.affect(living, intensity); } } + + if(type == Fluids.ENDERJUICE && living != null){ + teleportRandomly(living); + } + + if(type.hasTrait(FT_Pheromone.class)){ + + FT_Pheromone pheromone = type.getTrait(FT_Pheromone.class); + + if(living != null) { + if ((living instanceof EntityGlyphid && pheromone.getType() == 1) || (living instanceof EntityPlayer && pheromone.getType() == 2)) { + int mult = pheromone.getType(); + + living.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, mult * 60 * 20, 1)); + living.addPotionEffect(new PotionEffect(Potion.digSpeed.id, mult * 60 * 20, 1)); + living.addPotionEffect(new PotionEffect(Potion.regeneration.id, mult * 2 * 20, 0)); + living.addPotionEffect(new PotionEffect(Potion.resistance.id, mult * 60 * 20, 0)); + living.addPotionEffect(new PotionEffect(Potion.damageBoost.id, mult * 60 * 20, 1)); + living.addPotionEffect(new PotionEffect(Potion.fireResistance.id, mult * 60 * 20, 0)); + + } + } + } } protected boolean isExtinguishing(FluidType type) { - return this.getStyleFromType(type) == SprayStyle.MIST && this.getType().temperature < 50 && !type.hasTrait(FT_Flammable.class); + return this.getType().temperature < 50 && !type.hasTrait(FT_Flammable.class); } public int getMaxAge() { - return getStyleFromType(this.getType()) == SprayStyle.GAS ? 600 : 150; + return maxAge; } @Override @@ -242,10 +270,76 @@ public class EntityMist extends Entity { return SprayStyle.NULL; } - + public static enum SprayStyle { MIST, //liquids that have been sprayed into a mist GAS, //things that were already gaseous NULL } + + //terribly copy-pasted from EntityChemical.class, whose method was terribly copy-pasted from EntityEnderman.class + //the fun never ends + public void teleportRandomly(Entity e) { + double x = this.posX + (this.rand.nextDouble() - 0.5D) * 64.0D; + double y = this.posY + (double) (this.rand.nextInt(64) - 32); + double z = this.posZ + (this.rand.nextDouble() - 0.5D) * 64.0D; + this.teleportTo(e, x, y, z); + } + + public void teleportTo(Entity e, double x, double y, double z) { + + double targetX = e.posX; + double targetY = e.posY; + double targetZ = e.posZ; + e.posX = x; + e.posY = y; + e.posZ = z; + boolean flag = false; + int i = MathHelper.floor_double(e.posX); + int j = MathHelper.floor_double(e.posY); + int k = MathHelper.floor_double(e.posZ); + + if(e.worldObj.blockExists(i, j, k)) { + boolean flag1 = false; + + while(!flag1 && j > 0) { + Block block = e.worldObj.getBlock(i, j - 1, k); + + if(block.getMaterial().blocksMovement()) { + flag1 = true; + } else { + --e.posY; + --j; + } + } + + if(flag1) { + e.setPosition(e.posX, e.posY, e.posZ); + + if(e.worldObj.getCollidingBoundingBoxes(e, e.boundingBox).isEmpty() && !e.worldObj.isAnyLiquid(e.boundingBox)) { + flag = true; + } + } + } + + if(!flag) { + e.setPosition(targetX, targetY, targetZ); + } else { + short short1 = 128; + + for(int l = 0; l < short1; ++l) { + double d6 = (double) l / ((double) short1 - 1.0D); + float f = (this.rand.nextFloat() - 0.5F) * 0.2F; + float f1 = (this.rand.nextFloat() - 0.5F) * 0.2F; + float f2 = (this.rand.nextFloat() - 0.5F) * 0.2F; + double d7 = targetX + (e.posX - targetX) * d6 + (this.rand.nextDouble() - 0.5D) * (double) e.width * 2.0D; + double d8 = targetY + (e.posY - targetY) * d6 + this.rand.nextDouble() * (double) e.height; + double d9 = targetZ + (e.posZ - targetZ) * d6 + (this.rand.nextDouble() - 0.5D) * (double) e.width * 2.0D; + e.worldObj.spawnParticle("portal", d7, d8, d9, (double) f, (double) f1, (double) f2); + } + + e.worldObj.playSoundEffect(targetX, targetY, targetZ, "mob.endermen.portal", 1.0F, 1.0F); + e.playSound("mob.endermen.portal", 1.0F, 1.0F); + } + } } diff --git a/src/main/java/com/hbm/entity/grenade/EntityDisperserCanister.java b/src/main/java/com/hbm/entity/grenade/EntityDisperserCanister.java new file mode 100644 index 000000000..3316c8015 --- /dev/null +++ b/src/main/java/com/hbm/entity/grenade/EntityDisperserCanister.java @@ -0,0 +1,75 @@ +package com.hbm.entity.grenade; + +import com.hbm.entity.effect.EntityMist; +import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.fluid.Fluids; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.Item; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +public class EntityDisperserCanister extends EntityGrenadeBase { + + public EntityDisperserCanister(World p_i1773_1_) { + super(p_i1773_1_); + } + + public EntityDisperserCanister(World p_i1774_1_, EntityLivingBase p_i1774_2_) { + super(p_i1774_1_, p_i1774_2_); + } + + public EntityDisperserCanister(World p_i1775_1_, double p_i1775_2_, double p_i1775_4_, double p_i1775_6_) { + super(p_i1775_1_, p_i1775_2_, p_i1775_4_, p_i1775_6_); + } + + public EntityDisperserCanister setFluid(int id) { + this.dataWatcher.updateObject(12, id); + return this; + } + + @Override + protected void entityInit() { + this.dataWatcher.addObject(12, 0); + this.dataWatcher.addObject(13, 0); + } + + public EntityDisperserCanister setType(int id) { + this.dataWatcher.updateObject(13, id); + return this; + } + + public FluidType getFluid() { + return Fluids.fromID(this.dataWatcher.getWatchableObjectInt(12)); + } + + public Item getType() { + return Item.getItemById(this.dataWatcher.getWatchableObjectInt(13)); + } + + @Override + public void explode() { + if(!worldObj.isRemote) { + EntityMist mist = new EntityMist(worldObj); + mist.setType(getFluid()); + mist.setPosition(posX, posY, posZ); + mist.setArea(10, 5); + mist.setDuration(80); + worldObj.spawnEntityInWorld(mist); + } + } + + @Override + public void writeEntityToNBT(NBTTagCompound nbt) { + super.writeEntityToNBT(nbt); + nbt.setInteger("fluid", this.dataWatcher.getWatchableObjectInt(12)); + nbt.setInteger("item", this.dataWatcher.getWatchableObjectInt(13)); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbt) { + super.readEntityFromNBT(nbt); + this.dataWatcher.updateObject(12, nbt.getInteger("fluid")); + this.dataWatcher.updateObject(13, nbt.getInteger("item")); + + } +} diff --git a/src/main/java/com/hbm/entity/grenade/EntityGrenadeBase.java b/src/main/java/com/hbm/entity/grenade/EntityGrenadeBase.java index 9b0062987..03b16f48c 100644 --- a/src/main/java/com/hbm/entity/grenade/EntityGrenadeBase.java +++ b/src/main/java/com/hbm/entity/grenade/EntityGrenadeBase.java @@ -13,6 +13,7 @@ import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.World; +@Deprecated public abstract class EntityGrenadeBase extends EntityThrowable { public EntityGrenadeBase(World p_i1773_1_) { @@ -31,24 +32,20 @@ public abstract class EntityGrenadeBase extends EntityThrowable { public void onUpdate() { super.onUpdate(); - - this.prevRotationPitch = this.rotationPitch; - - this.rotationPitch -= Vec3.createVectorHelper(motionX, motionY, motionZ).lengthVector() * 25; - - this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); - while (this.rotationYaw - this.prevRotationYaw < -180.0F) - { - this.prevRotationYaw -= 360.0F; - } + this.prevRotationPitch = this.rotationPitch; + this.rotationPitch -= Vec3.createVectorHelper(motionX, motionY, motionZ).lengthVector() * 25; + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); - while (this.rotationYaw - this.prevRotationYaw >= 180.0F) - { - this.prevRotationYaw += 360.0F; - } + while(this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } - this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + while(this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; } @Override diff --git a/src/main/java/com/hbm/entity/logic/EntityWaypoint.java b/src/main/java/com/hbm/entity/logic/EntityWaypoint.java new file mode 100644 index 000000000..33712524e --- /dev/null +++ b/src/main/java/com/hbm/entity/logic/EntityWaypoint.java @@ -0,0 +1,134 @@ +package com.hbm.entity.logic; + +import com.hbm.config.MobConfig; +import com.hbm.entity.mob.EntityGlyphid; +import static com.hbm.entity.mob.EntityGlyphid.*; +import com.hbm.entity.mob.EntityGlyphidNuclear; +import com.hbm.entity.mob.EntityGlyphidScout; +import com.hbm.main.MainRegistry; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +import java.util.List; + +public class EntityWaypoint extends Entity { + public EntityWaypoint(World world) { + super(world); + this.isImmuneToFire = true; + this.noClip = true; + } + + @Override + protected void entityInit() { + this.dataWatcher.addObject(10, 0); + // this.dataWatcher.addObject(11, 0); + + } + + public int maxAge = 2400; + public int radius = 3; + public boolean highPriority = false; + protected EntityWaypoint additional; + + public void setHighPriority() { + highPriority = true; + } + + public int getWaypointType() { + return this.dataWatcher.getWatchableObjectInt(10); + } + + public void setAdditionalWaypoint(EntityWaypoint waypoint) { + additional = waypoint; + } + + public void setWaypointType(int waypointType) { + this.dataWatcher.updateObject(10, waypointType); + } + + boolean hasSpawned = false; + + public int getColor() { + switch(getWaypointType()) { + + case TASK_RETREAT_FOR_REINFORCEMENTS: return 0x5FA6E8; + case TASK_BUILD_HIVE: + case TASK_INITIATE_RETREAT: return 0x127766; + default: return 0x566573; + } + } + + AxisAlignedBB bb; + + @Override + public void onEntityUpdate() { + if(ticksExisted >= maxAge) { + this.setDead(); + } + + bb = AxisAlignedBB.getBoundingBox(this.posX, this.posY, this.posZ, this.posX, this.posY, this.posZ).expand(radius, radius, radius); + + if(!worldObj.isRemote) { + + if(ticksExisted % 40 == 0) { + + List targets = worldObj.getEntitiesWithinAABBExcludingEntity(this, bb); + + for(Entity e : targets) { + if(e instanceof EntityGlyphid) { + + EntityGlyphid bug = ((EntityGlyphid) e); + + if(additional != null && !hasSpawned) { + worldObj.spawnEntityInWorld(additional); + hasSpawned = true; + } + + boolean exceptions = bug.getWaypoint() != this || e instanceof EntityGlyphidScout || e instanceof EntityGlyphidNuclear; + + if(!exceptions) + bug.setCurrentTask(getWaypointType(), additional); + + if(getWaypointType() == TASK_BUILD_HIVE) { + if(e instanceof EntityGlyphidScout) + setDead(); + } else { + setDead(); + } + + } + } + } + } else if(MobConfig.waypointDebug) { + + double x = bb.minX + (rand.nextDouble() - 0.5) * (bb.maxX - bb.minX); + double y = bb.minY + rand.nextDouble() * (bb.maxY - bb.minY); + double z = bb.minZ + (rand.nextDouble() - 0.5) * (bb.maxZ - bb.minZ); + + NBTTagCompound fx = new NBTTagCompound(); + fx.setString("type", "tower"); + fx.setFloat("lift", 0.5F); + fx.setFloat("base", 0.75F); + fx.setFloat("max", 2F); + fx.setInteger("life", 50 + worldObj.rand.nextInt(10)); + fx.setInteger("color", getColor()); + fx.setDouble("posX", x); + fx.setDouble("posY", y); + fx.setDouble("posZ", z); + MainRegistry.proxy.effectNT(fx); + } + + } + + @Override + protected void readEntityFromNBT(NBTTagCompound nbt) { + this.setWaypointType(nbt.getInteger("type")); + } + + @Override + protected void writeEntityToNBT(NBTTagCompound nbt) { + nbt.setInteger("type", getWaypointType()); + } +} diff --git a/src/main/java/com/hbm/entity/mob/EntityCreeperPhosgene.java b/src/main/java/com/hbm/entity/mob/EntityCreeperPhosgene.java index dc6015870..c3636fa8d 100644 --- a/src/main/java/com/hbm/entity/mob/EntityCreeperPhosgene.java +++ b/src/main/java/com/hbm/entity/mob/EntityCreeperPhosgene.java @@ -37,6 +37,7 @@ public class EntityCreeperPhosgene extends EntityCreeper { mist.setType(Fluids.PHOSGENE); mist.setPosition(posX, posY, posZ); mist.setArea(10, 5); + mist.setDuration(150); worldObj.spawnEntityInWorld(mist); } } diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphid.java b/src/main/java/com/hbm/entity/mob/EntityGlyphid.java index 599b66f6a..ba5d41f5e 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphid.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphid.java @@ -4,45 +4,102 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import com.hbm.blocks.ModBlocks; import com.hbm.config.MobConfig; +import com.hbm.entity.logic.EntityWaypoint; import com.hbm.entity.pathfinder.PathFinderUtils; +import com.hbm.explosion.vanillant.ExplosionVNT; +import com.hbm.explosion.vanillant.standard.*; import com.hbm.handler.pollution.PollutionHandler; import com.hbm.handler.pollution.PollutionHandler.PollutionType; import com.hbm.items.ModItems; import com.hbm.lib.ModDamageSource; import com.hbm.main.ResourceManager; +import com.hbm.potion.HbmPotion; +import net.minecraft.block.Block; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; + +import net.minecraft.util.*; + import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; +import javax.annotation.Nullable; + public class EntityGlyphid extends EntityMob { + //I might have overdone it a little bit + + public boolean hasHome = false; + public int homeX; + public int homeY; + public int homeZ; + protected int currentTask = 0; + + //both of those below are used for digging, so the glyphid remembers what it was doing + protected int previousTask; + protected EntityWaypoint previousWaypoint; + public int taskX; + public int taskY; + public int taskZ; + + //used for digging, bigger glyphids have a longer reach + public int blastSize = Math.min((int) (3 * (getScale())) / 2, 5); + public int blastResToDig = Math.min((int) (50 * (getScale() * 2)), 150); + public boolean shouldDig; + + // Tasks + + /** Idle state, only makes glpyhids wander around randomly */ + public static final int TASK_IDLE = 0; + /** Causes the glyphid to walk to the waypoint, then communicate the FOLLOW task to nearby glyphids */ + public static final int TASK_RETREAT_FOR_REINFORCEMENTS = 1; + /** Task used by scouts, if the waypoint is reached it will construct a new hive */ + public static final int TASK_BUILD_HIVE = 2; + /** Creates a waypoint at the home position and then immediately initiates the RETREAT_FOR_REINFORCEMENTS task */ + public static final int TASK_INITIATE_RETREAT = 3; + /** Will simply walk to the waypoint and enter IDLE once it is reached */ + public static final int TASK_FOLLOW = 4; + /** Causes nuclear glyphids to immediately self-destruct, also signaling nearby scouts to retreat */ + public static final int TASK_TERRAFORM = 5; + /** If any task other than IDLE is interrupted by an obstacle, initiates digging behavior which is also communicated to nearby glyohids */ + public static final int TASK_DIG = 6; + + protected boolean hasWaypoint = false; + /** Yeah, fuck, whatever, anything goes now */ + protected EntityWaypoint taskWaypoint = null; + + //subtypes + public static final int TYPE_NORMAL = 0; + public static final int TYPE_INFECTED = 1; + + //data watcher keys + public static final int DW_WALL = 16; + public static final int DW_ARMOR = 17; + public static final int DW_SUBTYPE = 18; + public EntityGlyphid(World world) { super(world); - /*this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D)); - this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));*/ this.setSize(1.75F, 1F); } - + public ResourceLocation getSkin() { return ResourceManager.glyphid_tex; } - + public double getScale() { return 1.0D; } @@ -50,8 +107,9 @@ public class EntityGlyphid extends EntityMob { @Override protected void entityInit() { super.entityInit(); - this.dataWatcher.addObject(16, new Byte((byte) 0)); //wall climbing - this.dataWatcher.addObject(17, new Byte((byte) 0b11111)); //armor + this.dataWatcher.addObject(DW_WALL, new Byte((byte) 0)); //wall climbing + this.dataWatcher.addObject(DW_ARMOR, new Byte((byte) 0b11111)); //armor + this.dataWatcher.addObject(DW_SUBTYPE, new Byte((byte) 0)); //subtype (i.e. normal, infected, etc) } @Override @@ -61,134 +119,283 @@ public class EntityGlyphid extends EntityMob { this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5D); } - - @Override - protected void dropFewItems(boolean byPlayer, int looting) { - if(rand.nextInt(3) == 0) this.entityDropItem(new ItemStack(ModItems.glyphid_meat, 1 + rand.nextInt(2) + looting), 0F); - } - - @Override - protected Entity findPlayerToAttack() { - if(this.isPotionActive(Potion.blindness)) return null; - EntityPlayer entityplayer = this.worldObj.getClosestVulnerablePlayerToEntity(this, useExtendedTargeting() ? 128D : 16D); - return entityplayer != null && this.canEntityBeSeen(entityplayer) ? entityplayer : null; - } - - @Override - protected void updateEntityActionState() { - super.updateEntityActionState(); - - if(this.isPotionActive(Potion.blindness)) { - this.entityToAttack = null; - this.setPathToEntity(null); - } else { - - // hell yeah!! - if(useExtendedTargeting() && this.entityToAttack != null && !this.hasPath()) { - this.setPathToEntity(PathFinderUtils.getPathEntityToEntityPartial(worldObj, this, this.entityToAttack, 16F, true, false, false, true)); - } - } - - } - - public boolean useExtendedTargeting() { - return PollutionHandler.getPollution(worldObj, (int) Math.floor(posX), (int) Math.floor(posY), (int) Math.floor(posZ), PollutionType.SOOT) >= MobConfig.targetingThreshold; - } - - @Override - protected boolean canDespawn() { - return entityToAttack == null; - } - - @Override - public boolean attackEntityFrom(DamageSource source, float amount) { - - if(!source.isDamageAbsolute() && !source.isUnblockable() && !worldObj.isRemote && !source.isFireDamage() && !source.getDamageType().equals(ModDamageSource.s_cryolator)) { - byte armor = this.dataWatcher.getWatchableObjectByte(17); - - if(armor != 0) { //if at least one bit of armor is present - - if(amount < getDamageThreshold()) return false; - - int chance = getArmorBreakChance(amount); //chances of armor being broken off - if(this.rand.nextInt(chance) == 0 && amount > 1) { - breakOffArmor(); - amount *= 0.25F; - } - - amount -= getDamageThreshold(); - if(amount < 0) return true; - } - - amount = this.calculateDamage(amount); - } - - if(source.isFireDamage()) amount *= 4F; - - return super.attackEntityFrom(source, amount); - } - - public int getArmorBreakChance(float amount) { - return amount < 10 ? 5 : amount < 20 ? 3 : 2; - } - - public float calculateDamage(float amount) { - - byte armor = this.dataWatcher.getWatchableObjectByte(17); - int divisor = 1; - - for(int i = 0; i < 5; i++) { - if((armor & (1 << i)) > 0) { - divisor++; - } - } - - amount /= divisor; - - return amount; - } - - public float getDamageThreshold() { - return 0.5F; - } - - public void breakOffArmor() { - byte armor = this.dataWatcher.getWatchableObjectByte(17); - List indices = Arrays.asList(0, 1, 2, 3, 4); - Collections.shuffle(indices); - - for(Integer i : indices) { - byte bit = (byte) (1 << i); - if((armor & bit) > 0) { - armor &= ~bit; - armor = (byte) (armor & 0b11111); - this.dataWatcher.updateObject(17, armor); - worldObj.playSoundAtEntity(this, "mob.zombie.woodbreak", 1.0F, 1.25F); - break; - } - } - } - - @Override - public boolean attackEntityAsMob(Entity victum) { - if(this.isSwingInProgress) return false; - this.swingItem(); - return super.attackEntityAsMob(victum); - } @Override public void onUpdate() { super.onUpdate(); - if(!this.worldObj.isRemote) { - this.setBesideClimbableBlock(this.isCollidedHorizontally); - - if(worldObj.getTotalWorldTime() % 200 == 0) { + if(!worldObj.isRemote) { + if(!hasHome) { + homeX = (int) posX; + homeY = (int) posY; + homeZ = (int) posZ; + hasHome = true; + } + + if(this.isPotionActive(Potion.blindness)) { + onBlinded(); + } + + if(getCurrentTask() == TASK_FOLLOW){ + + //incase the waypoint somehow doesn't exist and it got this task anyway + if(isAtDestination() && !hasWaypoint) { + setCurrentTask(TASK_IDLE, null); + } + //the task cannot be 6 outside of rampant, so this is a non issue p much + } else if (getCurrentTask() == TASK_DIG && ticksExisted % 20 == 0 && isAtDestination()) { + swingItem(); + + ExplosionVNT vnt = new ExplosionVNT(worldObj, taskX, taskY + 2, taskZ, blastSize, this); + vnt.setBlockAllocator(new BlockAllocatorGlyphidDig(blastResToDig)); + vnt.setBlockProcessor(new BlockProcessorStandard().setNoDrop()); + vnt.setEntityProcessor(null); + vnt.setPlayerProcessor(null); + vnt.explode(); + + this.setCurrentTask(previousTask, previousWaypoint); + } + + this.setBesideClimbableBlock(isCollidedHorizontally); + + if(ticksExisted % 100 == 0) { this.swingItem(); } } } + + @Override + protected void dropFewItems(boolean byPlayer, int looting) { + super.dropFewItems(byPlayer, looting); + Item drop = isBurning() ? ModItems.glyphid_meat_grilled : ModItems.glyphid_meat; + if(rand.nextInt(2) == 0) this.entityDropItem(new ItemStack(drop, ((int) getScale() * 2) + looting), 0F); + } + + @Override + protected Entity findPlayerToAttack() { + if(this.isPotionActive(Potion.blindness)) return null; + + EntityPlayer entityplayer = this.worldObj.getClosestVulnerablePlayerToEntity(this, useExtendedTargeting() ? 128D : 16D); + return entityplayer; + } + + @Override + protected void updateWanderPath() { + if(getCurrentTask() == TASK_IDLE) { + super.updateWanderPath(); + } + } + + @Override + protected void updateEntityActionState() { + super.updateEntityActionState(); + + if(!this.isPotionActive(Potion.blindness)) { + if (!this.hasPath()) { + + // hell yeah!! + if(useExtendedTargeting() && this.entityToAttack != null) { + this.setPathToEntity(PathFinderUtils.getPathEntityToEntityPartial(worldObj, this, this.entityToAttack, 16F, true, false, true, true)); + } else if (getCurrentTask() != TASK_IDLE) { + + this.worldObj.theProfiler.startSection("stroll"); + + if (!isAtDestination()) { + + if (taskWaypoint != null) { + + taskX = (int) taskWaypoint.posX; + taskY = (int) taskWaypoint.posY; + taskZ = (int) taskWaypoint.posZ; + + if (taskWaypoint.highPriority) { + setTarget(taskWaypoint); + } + + } + + if(hasWaypoint) { + + if(canDig()) { + + MovingObjectPosition obstacle = findWaypointObstruction(); + if (getScale() >= 1 && getCurrentTask() != TASK_DIG && obstacle != null) { + digToWaypoint(obstacle); + } else { + Vec3 vec = Vec3.createVectorHelper(posX, posY, posZ); + int maxDist = (int) (Math.sqrt(vec.squareDistanceTo(taskX, taskY, taskZ)) * 1.2); + this.setPathToEntity(PathFinderUtils.getPathEntityToCoordPartial(worldObj, this, taskX, taskY, taskZ, maxDist, true, false, true, true)); + } + + } else { + Vec3 vec = Vec3.createVectorHelper(posX, posY, posZ); + int maxDist = (int) (Math.sqrt(vec.squareDistanceTo(taskX, taskY, taskZ)) * 1.2); + this.setPathToEntity(PathFinderUtils.getPathEntityToCoordPartial(worldObj, this, taskX, taskY, taskZ, maxDist, true, false, true, true)); + } + } + } + + this.worldObj.theProfiler.endSection(); + } + } + } + } + + protected boolean canDig() { + return MobConfig.rampantDig; + } + + public void onBlinded(){ + this.entityToAttack = null; + this.setPathToEntity(null); + this.fleeingTick = 80; + + if(getScale() >= 1.25){ + if(ticksExisted % 20 == 0) { + for (int i = 0; i < 16; i++) { + float angle = (float) Math.toRadians(360D / 16 * i); + Vec3 rot = Vec3.createVectorHelper(0, 0, 4); + rot.rotateAroundY(angle); + Vec3 pos = Vec3.createVectorHelper(this.posX, this.posY + 1, this.posZ); + Vec3 nextPos = Vec3.createVectorHelper(this.posX + rot.xCoord, this.posY + 1, this.posZ + rot.zCoord); + MovingObjectPosition mop = this.worldObj.rayTraceBlocks(pos, nextPos); + + if (mop != null && mop.typeOfHit == mop.typeOfHit.BLOCK) { + + Block block = worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ); + + if (block == ModBlocks.lantern) { + rotationYaw = 360F / 16 * i; + swingItem(); + worldObj.func_147480_a(mop.blockX, mop.blockY, mop.blockZ, false); + } + + } + } + } + } + } + + public boolean useExtendedTargeting() { + return MobConfig.rampantExtendedTargetting || PollutionHandler.getPollution(worldObj, (int) Math.floor(posX), (int) Math.floor(posY), (int) Math.floor(posZ), PollutionType.SOOT) >= MobConfig.targetingThreshold; + } + + @Override + protected boolean canDespawn() { + return entityToAttack == null && getCurrentTask() == TASK_IDLE && this.ticksExisted > 100; + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + + if(source.getEntity() instanceof EntityGlyphid) { + return false; + } + + if(!source.isDamageAbsolute() && !source.isUnblockable() && !worldObj.isRemote && !source.isFireDamage() && !source.getDamageType().equals(ModDamageSource.s_cryolator)) { + byte armor = this.dataWatcher.getWatchableObjectByte(DW_ARMOR); + + if(armor != 0) { //if at least one bit of armor is present + + if(amount < getDamageThreshold()) return false; + + //chances of armor being broken off + if(amount > 1 && isArmorBroken(amount)) { + breakOffArmor(); + amount *= 0.25F; + } + + amount -= getDamageThreshold(); + if(amount < 0) return true; + } + + amount = this.calculateDamage(amount); + } + + if(source.isFireDamage()) { + amount *= 0.7F; + } else if(source.getDamageType().equals("player")) { + amount *= 1.5F; + } else if(source == ModDamageSource.acid || source.equals(new DamageSource(ModDamageSource.s_acid))){ + amount = 0; + } else if(source == DamageSource.inWall) { + amount *= 15F; + } + + if(this.isPotionActive(HbmPotion.phosphorus.getId())){ + amount *= 1.5F; + } + + boolean alive = this.getHealth() > 0; + boolean wasAttacked = super.attackEntityFrom(source, amount); + + if(alive && this.getHealth() <= 0) { + if(doesInfectedSpawnMaggots() && this.dataWatcher.getWatchableObjectByte(DW_SUBTYPE) == TYPE_INFECTED) { + + int j = 2 + this.rand.nextInt(3); + + for(int k = 0; k < j; ++k) { + float f = ((float) (k % 2) - 0.5F) * 0.5F; + float f1 = ((float) (k / 2) - 0.5F) * 0.5F; + EntityParasiteMaggot maggot = new EntityParasiteMaggot(worldObj); + maggot.setLocationAndAngles(this.posX + (double) f, this.posY + 0.5D, this.posZ + (double) f1, this.rand.nextFloat() * 360.0F, 0.0F); + maggot.motionX = f; + maggot.motionZ = f1; + maggot.velocityChanged = true; + this.worldObj.spawnEntityInWorld(maggot); + } + } + } + + return wasAttacked; + } + + public boolean doesInfectedSpawnMaggots() { + return true; + } + + public boolean isArmorBroken(float amount) { + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.6, 2), 100); + } + + public float calculateDamage(float amount) { + + byte armor = this.dataWatcher.getWatchableObjectByte(DW_ARMOR); + int divisor = 1; + + for(int i = 0; i < 5; i++) { + if((armor & (1 << i)) > 0) { + divisor++; + } + } + + amount /= divisor; + + return amount; + } + + public float getDamageThreshold() { + return 0.5F; + } + + public void breakOffArmor() { + byte armor = this.dataWatcher.getWatchableObjectByte(DW_ARMOR); + List indices = Arrays.asList(0, 1, 2, 3, 4); + Collections.shuffle(indices); + + for(Integer i : indices) { + byte bit = (byte) (1 << i); + if((armor & bit) > 0) { + armor &= ~bit; + armor = (byte) (armor & 0b11111); + this.dataWatcher.updateObject(DW_ARMOR, armor); + worldObj.playSoundAtEntity(this, "mob.zombie.woodbreak", 1.0F, 1.25F); + break; + } + } + } + @Override protected void updateArmSwingProgress() { int i = this.swingDuration(); @@ -206,25 +413,25 @@ public class EntityGlyphid extends EntityMob { this.swingProgress = (float) this.swingProgressInt / (float) i; } - + public int swingDuration() { return 15; } @Override public void setInWeb() { } - + @Override public boolean isOnLadder() { return this.isBesideClimbableBlock(); } - + public boolean isBesideClimbableBlock() { - return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + return (this.dataWatcher.getWatchableObjectByte(DW_WALL) & 1) != 0; } public void setBesideClimbableBlock(boolean climbable) { - byte watchable = this.dataWatcher.getWatchableObjectByte(16); + byte watchable = this.dataWatcher.getWatchableObjectByte(DW_WALL); if(climbable) { watchable = (byte) (watchable | 1); @@ -232,23 +439,218 @@ public class EntityGlyphid extends EntityMob { watchable &= -2; } - this.dataWatcher.updateObject(16, Byte.valueOf(watchable)); + this.dataWatcher.updateObject(DW_WALL, Byte.valueOf(watchable)); } - + + @Override + public boolean attackEntityAsMob(Entity victim) { + if(this.isSwingInProgress) return false; + this.swingItem(); + + if(this.dataWatcher.getWatchableObjectByte(DW_SUBTYPE) == TYPE_INFECTED && victim instanceof EntityLivingBase) { + ((EntityLivingBase) victim).addPotionEffect(new PotionEffect(Potion.poison.id, 100, 2)); + ((EntityLivingBase) victim).addPotionEffect(new PotionEffect(Potion.confusion.id, 100, 0)); + } + + return super.attackEntityAsMob(victim); + } + + @Override public EnumCreatureAttribute getCreatureAttribute() { return EnumCreatureAttribute.ARTHROPOD; } + /// TASK SYSTEM START /// + public int getCurrentTask(){ + return currentTask; + } + + public EntityWaypoint getWaypoint(){ + return taskWaypoint; + } + + /** + * Sets a new task for the glyphid to do, a waypoint alongside with that task, and refreshes their waypoint coordinates + * @param task The task the glyphid is to do, refer to carryOutTask() + * @param waypoint The waypoint for the task, can be null + */ + public void setCurrentTask(int task, @Nullable EntityWaypoint waypoint){ + this.currentTask = task; + this.taskWaypoint = waypoint; + this.hasWaypoint = waypoint != null; + if(taskWaypoint != null) { + + taskX = (int) taskWaypoint.posX; + taskY = (int) taskWaypoint.posY; + taskZ = (int) taskWaypoint.posZ; + + if(taskWaypoint.highPriority) { + this.entityToAttack = null; + this.setPathToEntity(null); + } + + } + carryOutTask(); + } + + /** + * Handles the task system, used mainly for things that only need to be done once, such as setting targets + */ + public void carryOutTask(){ + int task = getCurrentTask(); + + switch(task){ + + case TASK_RETREAT_FOR_REINFORCEMENTS: + if(taskWaypoint != null) { + communicate(TASK_FOLLOW, taskWaypoint); + setCurrentTask(TASK_FOLLOW, taskWaypoint); + } + break; + + case TASK_INITIATE_RETREAT: + + if(!worldObj.isRemote && taskWaypoint == null) { + + // Then, Come back later + EntityWaypoint additional = new EntityWaypoint(worldObj); + additional.setLocationAndAngles(posX, posY, posZ, 0, 0); + + // First, go home and get reinforcements + EntityWaypoint home = new EntityWaypoint(worldObj); + home.setWaypointType(TASK_RETREAT_FOR_REINFORCEMENTS); + home.setAdditionalWaypoint(additional); + home.setHighPriority(); + home.setLocationAndAngles(homeX, homeY, homeZ, 0, 0); + worldObj.spawnEntityInWorld(home); + + this.taskWaypoint = home; + communicate(TASK_FOLLOW, home); + setCurrentTask(TASK_FOLLOW, taskWaypoint); + + break; + } + + break; + + case TASK_DIG: + shouldDig = true; + break; + + default: + break; + + } + + } + + /** Copies tasks and waypoint to nearby glyphids. Does not work on glyphid scouts */ + public void communicate(int task, @Nullable EntityWaypoint waypoint) { + int radius = waypoint != null ? waypoint.radius : 4; + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(this.posX, this.posY, this.posZ, this.posX, this.posY, this.posZ).expand(radius, radius, radius); + + List bugs = worldObj.getEntitiesWithinAABBExcludingEntity(this, bb); + for(Entity e : bugs) { + if(e instanceof EntityGlyphid && !(e instanceof EntityGlyphidScout)) { + if(((EntityGlyphid) e).getCurrentTask() != task) { + ((EntityGlyphid) e).setCurrentTask(task, waypoint); + } + } + } + } + + /** What each type of glyphid does when it is time to expand the hive. + * @return Whether it has expanded successfully or not + * **/ + public boolean expandHive(){ + return false; + } + + public boolean isAtDestination() { + int destinationRadius = taskWaypoint != null ? (int) Math.pow(taskWaypoint.radius, 2) : 25; + return this.getDistanceSq(taskX, taskY, taskZ) <= destinationRadius; + } + ///TASK SYSTEM END + + ///DIGGING SYSTEM START + + /** Handles the special digging system, used in Rampant mode due to high potential for destroyed bases**/ + public MovingObjectPosition findWaypointObstruction(){ + Vec3 bugVec = Vec3.createVectorHelper(posX, posY + getEyeHeight(), posZ); + Vec3 waypointVec = Vec3.createVectorHelper(taskX, taskY, taskZ); + //incomplete forge docs my beloved + MovingObjectPosition obstruction = worldObj.func_147447_a(bugVec, waypointVec, false, true, false); + if(obstruction != null){ + Block blockHit = worldObj.getBlock(obstruction.blockX, obstruction.blockY, obstruction.blockZ); + if(blockHit.getExplosionResistance(null) <= blastResToDig){ + return obstruction; + } + } + return null; + } + + public void digToWaypoint(MovingObjectPosition obstacle){ + + EntityWaypoint target = new EntityWaypoint(worldObj); + target.setLocationAndAngles(obstacle.blockX, obstacle.blockY, obstacle.blockZ, 0 , 0); + target.radius = 5; + worldObj.spawnEntityInWorld(target); + + previousTask = getCurrentTask(); + previousWaypoint = getWaypoint(); + + setCurrentTask(TASK_DIG, target); + + Vec3 vec = Vec3.createVectorHelper(posX, posY, posZ); + int maxDist = (int) (Math.sqrt(vec.squareDistanceTo(taskX, taskY, taskZ)) * 1.2); + this.setPathToEntity(PathFinderUtils.getPathEntityToCoordPartial(worldObj, this, taskX, taskY, taskZ, maxDist, true, false, true, true)); + + communicate(TASK_DIG, target); + + } + ///DIGGING END + @Override public void writeEntityToNBT(NBTTagCompound nbt) { super.writeEntityToNBT(nbt); - nbt.setByte("armor", this.dataWatcher.getWatchableObjectByte(17)); + nbt.setByte("armor", this.dataWatcher.getWatchableObjectByte(DW_ARMOR)); + nbt.setByte("subtype", this.dataWatcher.getWatchableObjectByte(DW_SUBTYPE)); + + nbt.setBoolean("hasHome", hasHome); + nbt.setInteger("homeX", homeX); + nbt.setInteger("homeY", homeY); + nbt.setInteger("homeZ", homeZ); + + nbt.setBoolean("hasWaypoint", hasWaypoint); + nbt.setInteger("taskX", taskX); + nbt.setInteger("taskY", taskY); + nbt.setInteger("taskZ", taskZ); + + nbt.setInteger("task", currentTask); } @Override public void readEntityFromNBT(NBTTagCompound nbt) { super.readEntityFromNBT(nbt); - this.dataWatcher.updateObject(17, nbt.getByte("armor")); + this.dataWatcher.updateObject(DW_ARMOR, nbt.getByte("armor")); + this.dataWatcher.updateObject(DW_SUBTYPE, nbt.getByte("subtype")); + + this.hasHome = nbt.getBoolean("hasHome"); + this.homeX = nbt.getInteger("homeX"); + this.homeY = nbt.getInteger("homeY"); + this.homeZ = nbt.getInteger("homeZ"); + + this.hasWaypoint = nbt.getBoolean("hasWaypoint"); + this.taskX = nbt.getInteger("taskX"); + this.taskY = nbt.getInteger("taskY"); + this.taskZ = nbt.getInteger("taskZ"); + + this.currentTask = nbt.getInteger("task"); + } + + @Override + public boolean getCanSpawnHere() { + return this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL && this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox); } } diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidBehemoth.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidBehemoth.java index bf3215059..27f2595d9 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidBehemoth.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidBehemoth.java @@ -1,8 +1,18 @@ package com.hbm.entity.mob; +import com.hbm.entity.effect.EntityMist; +import com.hbm.entity.projectile.EntityChemical; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.items.ModItems; import com.hbm.main.ResourceManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -10,7 +20,7 @@ public class EntityGlyphidBehemoth extends EntityGlyphid { public EntityGlyphidBehemoth(World world) { super(world); - this.setSize(2.25F, 1.25F); + this.setSize(2.5F, 1.5F); } @Override @@ -26,16 +36,78 @@ public class EntityGlyphidBehemoth extends EntityGlyphid { @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(100D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(130D); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.8D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(25D); } + public int timer = 120; + int breathTime = 0; @Override - public int getArmorBreakChance(float amount) { - return amount < 20 ? 10 : amount < 100 ? 5 : amount > 200 ? 1 : 3; + public void onUpdate(){ + super.onUpdate(); + Entity e = this.getEntityToAttack(); + if (e == null) { + timer = 120; + breathTime = 0; + } else { + if (breathTime > 0) { + if(!isSwingInProgress){ + this.swingItem(); + } + acidAttack(); + rotationYaw = prevRotationYaw; + breathTime--; + } else if (--timer <= 0) { + breathTime = 120; + timer = 120; + } + } + + } + @Override + public boolean attackEntityAsMob(Entity victum) { + return super.attackEntityAsMob(victum); } + @Override + public void onDeath(DamageSource source) { + super.onDeath(source); + if (!worldObj.isRemote) { + EntityMist mist = new EntityMist(worldObj); + mist.setType(Fluids.ACID); + mist.setPosition(posX, posY, posZ); + mist.setArea(10, 4); + mist.setDuration(120); + worldObj.spawnEntityInWorld(mist); + } + } + + + public void acidAttack(){ + if(!worldObj.isRemote && entityToAttack instanceof EntityLivingBase && this.getDistanceToEntity(entityToAttack) < 20) { + this.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 2 * 20, 6)); + EntityChemical chem = new EntityChemical(worldObj, this); + + chem.setFluid(Fluids.ACID); + worldObj.spawnEntityInWorld(chem); + } + } + + @Override + protected void dropFewItems(boolean byPlayer, int looting) { + this.entityDropItem(new ItemStack(ModItems.glyphid_gland, 1, Fluids.SULFURIC_ACID.getID()), 1); + super.dropFewItems(byPlayer, looting); + } + @Override + public boolean isArmorBroken(float amount) { + // amount < 5 ? 5 : amount < 10 ? 3 : 2; + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.15, 2), 100); + } + @Override + public int swingDuration() { + return 100; + } @Override public float calculateDamage(float amount) { @@ -44,7 +116,7 @@ public class EntityGlyphidBehemoth extends EntityGlyphid { for(int i = 0; i < 5; i++) { if((armor & (1 << i)) > 0) { - divisor += 3; + divisor += 4; } } diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidBlaster.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidBlaster.java index 5e922ab49..ef2ccde88 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidBlaster.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidBlaster.java @@ -32,8 +32,8 @@ public class EntityGlyphidBlaster extends EntityGlyphidBombardier { } @Override - public int getArmorBreakChance(float amount) { - return amount < 10 ? 10 : amount < 25 ? 5 : amount > 100 ? 1 : 3; + public boolean isArmorBroken(float amount) { + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.25, 2), 100); } @Override @@ -65,12 +65,12 @@ public class EntityGlyphidBlaster extends EntityGlyphidBombardier { @Override public int getBombCount() { - return 20; + return 10; } @Override public float getSpreadMult() { - return 0.75F; + return 0.5F; } @Override diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidBombardier.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidBombardier.java index 61750f0ee..7fda8206d 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidBombardier.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidBombardier.java @@ -4,6 +4,8 @@ import com.hbm.entity.projectile.EntityAcidBomb; import com.hbm.main.ResourceManager; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Vec3; import net.minecraft.world.World; @@ -23,22 +25,26 @@ public class EntityGlyphidBombardier extends EntityGlyphid { protected double lastY; protected double lastZ; + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20D); + + } @Override public void onUpdate() { super.onUpdate(); + Entity e = this.getEntityToAttack(); + if(!this.worldObj.isRemote && e instanceof EntityLivingBase) { - if(!this.worldObj.isRemote) { - - Entity e = this.getEntityToAttack(); - - if(this.ticksExisted % 20 == 0 && e != null) { + if(this.ticksExisted % 20 == 0) { this.lastTarget = e; this.lastX = e.posX; this.lastY = e.posY; this.lastZ = e.posZ; } - if(this.ticksExisted % 20 == 1 && e != null) { + if(this.ticksExisted % 60 == 1) { boolean topAttack = rand.nextBoolean(); @@ -72,6 +78,7 @@ public class EntityGlyphidBombardier extends EntityGlyphid { for(int i = 0; i < getBombCount(); i++) { EntityAcidBomb bomb = new EntityAcidBomb(worldObj, posX, posY + 1, posZ); + bomb.setThrower(this); bomb.setThrowableHeading(fireVec.xCoord, fireVec.yCoord, fireVec.zCoord, (float) v0, i * getSpreadMult()); bomb.damage = getBombDamage(); worldObj.spawnEntityInWorld(bomb); @@ -88,7 +95,7 @@ public class EntityGlyphidBombardier extends EntityGlyphid { } public int getBombCount() { - return 10; + return 5; } public float getSpreadMult() { diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidBrawler.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidBrawler.java index 749230a42..48d274667 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidBrawler.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidBrawler.java @@ -32,19 +32,19 @@ public class EntityGlyphidBrawler extends EntityGlyphid { } @Override - public int getArmorBreakChance(float amount) { - return amount < 10 ? 10 : amount < 25 ? 5 : amount > 100 ? 1 : 3; + public boolean isArmorBroken(float amount) { + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.25, 2), 100); } @Override public float calculateDamage(float amount) { byte armor = this.dataWatcher.getWatchableObjectByte(17); - int divisor = 1; + float divisor = 1; for(int i = 0; i < 5; i++) { if((armor & (1 << i)) > 0) { - divisor += 2; + divisor += 3; } } diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidBrenda.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidBrenda.java index bdce3e7bc..33926bbde 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidBrenda.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidBrenda.java @@ -1,10 +1,13 @@ package com.hbm.entity.mob; +import com.hbm.entity.effect.EntityMist; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.items.ModItems; import com.hbm.main.ResourceManager; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; +import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -30,13 +33,14 @@ public class EntityGlyphidBrenda extends EntityGlyphid { protected void applyEntityAttributes() { super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(250D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.8D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1.2D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(50D); } @Override - public int getArmorBreakChance(float amount) { - return amount < 25 ? 100 : amount > 1000 ? 1 : 10; + public boolean isArmorBroken(float amount) { + // amount < 5 ? 5 : amount < 10 ? 3 : 2; + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.12, 2), 100); } @Override @@ -62,20 +66,27 @@ public class EntityGlyphidBrenda extends EntityGlyphid { } @Override - public void setDead() { + public void onDeath(DamageSource source) { + super.onDeath(source); if(!this.worldObj.isRemote && this.getHealth() <= 0.0F) { + EntityMist mist = new EntityMist(worldObj); + mist.setType(Fluids.PHEROMONE); + mist.setPosition(posX, posY, posZ); + mist.setArea(14, 6); + mist.setDuration(80); + worldObj.spawnEntityInWorld(mist); for(int i = 0; i < 12; ++i) { EntityGlyphid glyphid = new EntityGlyphid(worldObj); glyphid.setLocationAndAngles(this.posX, this.posY + 0.5D, this.posZ, rand.nextFloat() * 360.0F, 0.0F); - glyphid.addPotionEffect(new PotionEffect(Potion.resistance.id, 5 * 60 * 20, 2)); - glyphid.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 5 * 60 * 20, 0)); - glyphid.addPotionEffect(new PotionEffect(Potion.damageBoost.id, 5 * 60 * 20, 4)); - glyphid.addPotionEffect(new PotionEffect(Potion.field_76444_x.id, 5 * 60 * 20, 19)); this.worldObj.spawnEntityInWorld(glyphid); glyphid.moveEntity(rand.nextGaussian(), 0, rand.nextGaussian()); } } - - super.setDead(); } + @Override + protected void dropFewItems(boolean byPlayer, int looting) { + super.dropFewItems(byPlayer, looting); + if(rand.nextInt(3) == 0) this.entityDropItem(new ItemStack(ModItems.glyphid_gland, 1, Fluids.PHEROMONE.getID()), 1); + } + } diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidDigger.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidDigger.java new file mode 100644 index 000000000..09801fe4b --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidDigger.java @@ -0,0 +1,41 @@ +package com.hbm.entity.mob; + +import com.hbm.main.ResourceManager; + +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class EntityGlyphidDigger extends EntityGlyphid { + + public EntityGlyphidDigger(World world) { + super(world); + } + + public ResourceLocation getSkin() { + return ResourceManager.glyphid_digger_tex; + } + + @Override + public double getScale() { + return 1.25D; + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(35D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5D); + } + + @Override + public boolean isArmorBroken(float amount) { + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.25, 2), 100); + } + + @Override + protected boolean canDig() { + return true; + } +} diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidNuclear.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidNuclear.java index 62a3ae9a6..b8342bf6f 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidNuclear.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidNuclear.java @@ -1,6 +1,7 @@ package com.hbm.entity.mob; import com.hbm.blocks.ModBlocks; +import com.hbm.entity.logic.EntityWaypoint; import com.hbm.explosion.vanillant.ExplosionVNT; import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard; import com.hbm.explosion.vanillant.standard.BlockMutatorDebris; @@ -13,15 +14,21 @@ import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; +import net.minecraft.entity.Entity; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import javax.annotation.Nullable; +import java.util.List; + public class EntityGlyphidNuclear extends EntityGlyphid { public int deathTicks; - public EntityGlyphidNuclear(World world) { super(world); this.setSize(2.5F, 1.75F); @@ -38,17 +45,59 @@ public class EntityGlyphidNuclear extends EntityGlyphid { return 2D; } + @Override + public void onUpdate() { + super.onUpdate(); + if(ticksExisted % 20 == 0) { + if(isAtDestination() && getCurrentTask() == TASK_FOLLOW) { + setCurrentTask(TASK_IDLE, null); + } + + if(getCurrentTask() == TASK_BUILD_HIVE && getAITarget() == null) { + this.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, 10 * 20, 3)); + } + + if(getCurrentTask() == TASK_TERRAFORM) { + this.setHealth(0); + } + } + } + + /** Communicates only with glyphid scouts, unlike the super implementation which does the opposite */ + @Override + public void communicate(int task, @Nullable EntityWaypoint waypoint) { + int radius = waypoint != null ? waypoint.radius : 4; + + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox( + this.posX - radius, + this.posY - radius, + this.posZ - radius, + this.posX + radius, + this.posY + radius, + this.posZ + radius); + + List bugs = worldObj.getEntitiesWithinAABBExcludingEntity(this, bb); + for (Entity e: bugs){ + if(e instanceof EntityGlyphidScout){ + if(((EntityGlyphid) e).getCurrentTask() != task){ + ((EntityGlyphid) e).setCurrentTask(task, waypoint); + } + } + } + } + + @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(100D); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.8D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(50D); } @Override - public int getArmorBreakChance(float amount) { - return amount < 25 ? 100 : amount > 1000 ? 1 : 10; + public boolean isArmorBroken(float amount) { + return this.rand.nextInt(100) <= Math.min(Math.pow(amount * 0.12, 2), 100); } @Override @@ -73,20 +122,60 @@ public class EntityGlyphidNuclear extends EntityGlyphid { return 10F; } + @Override + public boolean doesInfectedSpawnMaggots() { + return false; + } + + public boolean hasWaypoint = false; @Override protected void onDeathUpdate() { ++this.deathTicks; + if(!hasWaypoint) { + // effectively causes neighboring EntityGlyphidScout to retreat + communicate(TASK_INITIATE_RETREAT, null); + hasWaypoint = true; + } + + if(deathTicks == 90){ + int radius = 8; + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(this.posX, this.posY, this.posZ, this.posX, this.posY, this.posZ).expand(radius, radius, radius); + + List bugs = worldObj.getEntitiesWithinAABBExcludingEntity(this, bb); + for (Entity e: bugs){ + if(e instanceof EntityGlyphid){ + addPotionEffect(new PotionEffect(Potion.field_76434_w.id, 20, 6)); + addPotionEffect(new PotionEffect(Potion.fireResistance.id, 15 * 20, 1)); + } + } + } if(this.deathTicks == 100) { if(!worldObj.isRemote) { ExplosionVNT vnt = new ExplosionVNT(worldObj, posX, posY, posZ, 25, this); - vnt.setBlockAllocator(new BlockAllocatorStandard(24)); - vnt.setBlockProcessor(new BlockProcessorStandard().withBlockEffect(new BlockMutatorDebris(ModBlocks.volcanic_lava_block, 0)).setNoDrop()); - vnt.setEntityProcessor(new EntityProcessorStandard().withRangeMod(1.5F)); + + if(this.dataWatcher.getWatchableObjectByte(DW_SUBTYPE) == TYPE_INFECTED) { + int j = 15 + this.rand.nextInt(6); + for(int k = 0; k < j; ++k) { + float f = ((float) (k % 2) - 0.5F) * 0.5F; + float f1 = ((float) (k / 2) - 0.5F) * 0.5F; + EntityParasiteMaggot maggot = new EntityParasiteMaggot(worldObj); + maggot.setLocationAndAngles(this.posX + (double) f, this.posY + 0.5D, this.posZ + (double) f1, this.rand.nextFloat() * 360.0F, 0.0F); + maggot.motionX = f; + maggot.motionZ = f1; + maggot.velocityChanged = true; + this.worldObj.spawnEntityInWorld(maggot); + } + } else { + vnt.setBlockAllocator(new BlockAllocatorStandard(24)); + vnt.setBlockProcessor(new BlockProcessorStandard().withBlockEffect(new BlockMutatorDebris(ModBlocks.volcanic_lava_block, 0)).setNoDrop()); + } + + vnt.setEntityProcessor(new EntityProcessorStandard()); vnt.setPlayerProcessor(new PlayerProcessorStandard()); vnt.explode(); - + worldObj.playSoundEffect(posX, posY, posZ, "hbm:weapon.mukeExplosion", 15.0F, 1.0F); NBTTagCompound data = new NBTTagCompound(); diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphidScout.java b/src/main/java/com/hbm/entity/mob/EntityGlyphidScout.java index 181156e09..7e0378bbd 100644 --- a/src/main/java/com/hbm/entity/mob/EntityGlyphidScout.java +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphidScout.java @@ -1,36 +1,49 @@ package com.hbm.entity.mob; import com.hbm.blocks.ModBlocks; +import com.hbm.config.MobConfig; +import com.hbm.entity.logic.EntityWaypoint; +import com.hbm.handler.pollution.PollutionHandler; import com.hbm.main.ResourceManager; import com.hbm.world.feature.GlyphidHive; import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.Vec3; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.*; import net.minecraft.world.World; -public class EntityGlyphidScout extends EntityGlyphid { - - public boolean hasHome = false; - public double homeX; - public double homeY; - public double homeZ; +import java.util.List; +public class EntityGlyphidScout extends EntityGlyphid { + + boolean hasTarget = false; + int timer; + int scoutingRange = 45; + int minDistanceToHive = 8; + boolean useLargeHive = false; + float largeHiveChance = MobConfig.largeHiveChance; + public EntityGlyphidScout(World world) { super(world); this.setSize(1.25F, 0.75F); } - - @Override - public float getDamageThreshold() { - return 0.0F; - } + //extreme measures for anti-scout bullying + @Override + public boolean attackEntityAsMob(Entity victum) { + if(super.attackEntityAsMob(victum) && victum instanceof EntityLivingBase){ + ((EntityLivingBase)victum).addPotionEffect(new PotionEffect(Potion.poison.id, 10 * 20, 3)); + return true; + } + return false; + } + @Override public ResourceLocation getSkin() { return ResourceManager.glyphid_scout_tex; @@ -42,116 +55,261 @@ public class EntityGlyphidScout extends EntityGlyphid { } @Override - public int getArmorBreakChance(float amount) { - return 1; + public boolean isArmorBroken(float amount) { + return this.rand.nextInt(100) <= Math.min(Math.pow(amount, 2), 100); } @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(16D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20D); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1.5D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(2D); } - + @Override - protected boolean canDespawn() { + public void onUpdate() { + super.onUpdate(); + + if((getCurrentTask() != TASK_BUILD_HIVE || getCurrentTask() != TASK_TERRAFORM) && taskWaypoint == null) { + + if(MobConfig.rampantGlyphidGuidance && PollutionHandler.targetCoords != null){ + if(!hasTarget) { + Vec3 dirVec = playerBaseDirFinder(Vec3.createVectorHelper(posX, posY, posZ), getPlayerTargetDirection()); + + EntityWaypoint target = new EntityWaypoint(worldObj); + target.setLocationAndAngles(dirVec.xCoord, dirVec.yCoord, dirVec.zCoord, 0, 0); + target.maxAge = 300; + target.radius = 6; + worldObj.spawnEntityInWorld(target); + hasTarget = true; + + setCurrentTask(TASK_RETREAT_FOR_REINFORCEMENTS, target); + } + + if(super.isAtDestination()) { + setCurrentTask(TASK_BUILD_HIVE, null) ; + hasTarget = false; + } + + } else { + setCurrentTask(TASK_BUILD_HIVE, null); + } + + } + + if(getCurrentTask() == TASK_BUILD_HIVE || getCurrentTask() == TASK_TERRAFORM) { + + if(!worldObj.isRemote && !hasTarget) { + //Check for whether a big man johnson is nearby, this makes the scout switch into its terraforming task + if(scoutingRange != 60 && hasNuclearGlyphidNearby()){ + setCurrentTask(TASK_TERRAFORM, null); + } + + if(expandHive()) { + this.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 180 * 20, 1)); + hasTarget = true; + } + } + + if (getCurrentTask() == TASK_TERRAFORM && super.isAtDestination() && canBuildHiveHere()) { + communicate(TASK_TERRAFORM, taskWaypoint); + } + + if (ticksExisted % 10 == 0 && isAtDestination()) { + timer++; + + if (!worldObj.isRemote && canBuildHiveHere()) { + if(timer == 1) { + + EntityWaypoint additional = new EntityWaypoint(worldObj); + additional.setLocationAndAngles(posX, posY, posZ, 0, 0); + additional.setWaypointType(TASK_IDLE); + + // First, go home and get reinforcements + EntityWaypoint home = new EntityWaypoint(worldObj); + home.setWaypointType(TASK_RETREAT_FOR_REINFORCEMENTS); + home.setAdditionalWaypoint(additional); + home.setLocationAndAngles(homeX, homeY, homeZ, 0, 0); + home.maxAge = 1200; + home.radius = 6; + + worldObj.spawnEntityInWorld(home); + + this.taskWaypoint = home; + this.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 40 * 20, 10)); + communicate(TASK_RETREAT_FOR_REINFORCEMENTS, taskWaypoint); + + } else if(timer >= 5) { + + worldObj.newExplosion(this, posX, posY, posZ, 5F, false, false); + GlyphidHive.generateSmall(worldObj, (int) Math.floor(posX), (int) Math.floor(posY), (int) Math.floor(posZ), rand, this.dataWatcher.getWatchableObjectByte(DW_SUBTYPE) != TYPE_NORMAL, false); + this.setDead(); + + } else { + communicate(TASK_FOLLOW, taskWaypoint); + } + } + } + } + } + + /** Returns true if the position is far enough away from other hives. Also resets the task if unsuccessful. */ + public boolean canBuildHiveHere() { + int length = useLargeHive ? 16 : 8; + + for(int i = 0; i < 8; i++) { + + float angle = (float) Math.toRadians(360D / 16 * i); + Vec3 rot = Vec3.createVectorHelper(0, 0, length); + rot.rotateAroundY(angle); + Vec3 pos = Vec3.createVectorHelper(this.posX, this.posY + 1, this.posZ); + Vec3 nextPos = Vec3.createVectorHelper(this.posX + rot.xCoord, this.posY + 1, this.posZ + rot.zCoord); + MovingObjectPosition mop = this.worldObj.rayTraceBlocks(pos, nextPos); + + if(mop != null && mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { + + Block block = worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ); + + if(block == ModBlocks.glyphid_base) { + setCurrentTask(TASK_IDLE, null); + hasTarget = false; + return false; + } + + } + } return true; } @Override - public void onUpdate() { - super.onUpdate(); + public boolean isAtDestination() { + return this.getCurrentTask() == TASK_BUILD_HIVE && super.isAtDestination(); + } + + public boolean hasNuclearGlyphidNearby(){ + int radius = 8; + + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox( + this.posX - radius, + this.posY - radius, + this.posZ - radius, + this.posX + radius, + this.posY + radius, + this.posZ + radius); + + List bugs = worldObj.getEntitiesWithinAABBExcludingEntity(this, bb); - if(!worldObj.isRemote) { - - if(!this.hasHome) { - this.homeX = posX; - this.homeY = posY; - this.homeZ = posZ; - this.hasHome = true; + for (Entity e: bugs){ + if(e instanceof EntityGlyphidNuclear){ + return true; + } + } + return false; + } + + @Override + public boolean expandHive() { + + int nestX = rand.nextInt((homeX + scoutingRange) - (homeX - scoutingRange)) + (homeX - scoutingRange); + int nestZ = rand.nextInt((homeZ + scoutingRange) - (homeZ - scoutingRange)) + (homeZ - scoutingRange); + int nestY = worldObj.getHeightValue(nestX, nestZ); + Block b = worldObj.getBlock(nestX, nestY - 1, nestZ); + + boolean distanceCheck = Vec3.createVectorHelper(nestX - homeX, nestY - homeY, nestZ - homeZ).lengthVector() > minDistanceToHive; + + if(distanceCheck && b.getMaterial() != Material.air && b.isNormalCube() && b != ModBlocks.glyphid_base) { + + if(b == ModBlocks.basalt) { + useLargeHive = true; + largeHiveChance /= 2; + this.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, 60 * 20, 3)); } - if(rand.nextInt(20) == 0) fleeingTick = 2; + if(!worldObj.isRemote) { + EntityWaypoint nest = new EntityWaypoint(worldObj); + nest.setWaypointType(getCurrentTask()); + nest.radius = 5; - if(this.ticksExisted > 0 && this.ticksExisted % 1200 == 0 && Vec3.createVectorHelper(posX - homeX, posY - homeY, posZ - homeZ).lengthVector() > 8) { - - Block b = worldObj.getBlock((int) Math.floor(posX), (int) Math.floor(posY - 1), (int) Math.floor(posZ)); - - int accuracy = 16; - for(int i = 0; i < accuracy; i++) { - float angle = (float) Math.toRadians(360D / accuracy * i); - Vec3 rot = Vec3.createVectorHelper(0, 0, 16); - rot.rotateAroundY(angle); - Vec3 pos = Vec3.createVectorHelper(this.posX, this.posY + 1, this.posZ); - Vec3 nextPos = Vec3.createVectorHelper(this.posX + rot.xCoord, this.posY + 1, this.posZ + rot.zCoord); - MovingObjectPosition mop = this.worldObj.rayTraceBlocks(pos, nextPos); + if(useLargeHive) + nest.setHighPriority(); + + nest.setLocationAndAngles(nestX, nestY, nestZ, 0, 0); + worldObj.spawnEntityInWorld(nest); + + taskWaypoint = nest; + + // updates the task coordinates + setCurrentTask(getCurrentTask(), taskWaypoint); + communicate(TASK_BUILD_HIVE, taskWaypoint); + } + + return true; + } + + return false; + } + + @Override + public void carryOutTask() { + if (!worldObj.isRemote && taskWaypoint == null) { + switch(getCurrentTask()){ + case TASK_INITIATE_RETREAT: + this.removePotionEffect(Potion.moveSlowdown.id); + this.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, 20 * 20, 4)); + + //then, come back later + EntityWaypoint additional = new EntityWaypoint(worldObj); + additional.setLocationAndAngles(posX, posY, posZ, 0, 0); + additional.setWaypointType(0); - if(mop != null && mop.typeOfHit == mop.typeOfHit.BLOCK) { - - Block block = worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ); - - if(block == ModBlocks.glyphid_base) { - return; - } - } - } - - if(b.getMaterial() != Material.air && b.isNormalCube() && b != ModBlocks.glyphid_base) { - this.setDead(); - worldObj.newExplosion(this, posX, posY, posZ, 5F, false, false); - GlyphidHive.generate(worldObj, (int) Math.floor(posX), (int) Math.floor(posY), (int) Math.floor(posZ), rand); - } + //First, go home and get reinforcements + EntityWaypoint home = new EntityWaypoint(worldObj); + home.setWaypointType(2); + home.setAdditionalWaypoint(additional); + home.setHighPriority(); + home.radius = 6; + home.setLocationAndAngles(homeX, homeY, homeZ, 0, 0); + worldObj.spawnEntityInWorld(home); + + communicate(4, home); + break; + + //terraforming task, only used if a big man johnson is near the scout + case TASK_TERRAFORM: + scoutingRange = 60; + minDistanceToHive = 20; + break; } } + super.carryOutTask(); + + } + + @Override + public boolean useExtendedTargeting() { + return false; } - @Override - protected void updateWanderPath() { - this.worldObj.theProfiler.startSection("stroll"); - boolean flag = false; - int pathX = -1; - int pathY = -1; - int pathZ = -1; - float maxWeight = -99999.0F; + ///RAMPANT MODE STUFFS - for(int l = 0; l < 5; ++l) { - int x = MathHelper.floor_double(this.posX + (double) this.rand.nextInt(25) - 12.0D); - int y = MathHelper.floor_double(this.posY + (double) this.rand.nextInt(11) - 5.0D); - int z = MathHelper.floor_double(this.posZ + (double) this.rand.nextInt(25) - 12.0D); - float weight = this.getBlockPathWeight(x, y, z); - - if(weight > maxWeight) { - maxWeight = weight; - pathX = x; - pathY = y; - pathZ = z; - flag = true; - } + /** Finds the direction from the bug's location to the target and adds it to their current coord + * Used as a performant way to make scouts expand toward the player's spawn point + * @return An adjusted direction vector, to be added into the bug's current position for it to path in the required direction**/ + public static Vec3 playerBaseDirFinder(Vec3 currentLocation, Vec3 target){ + Vec3 dirVec = currentLocation.subtract(target).normalize(); + return Vec3.createVectorHelper( + currentLocation.xCoord + dirVec.xCoord * 10, + currentLocation.yCoord + dirVec.yCoord * 10, + currentLocation.zCoord + dirVec.zCoord * 10 + ); + } + + protected Vec3 getPlayerTargetDirection() { + EntityPlayer player = worldObj.getClosestPlayerToEntity(this, 300); + if(player != null) { + return Vec3.createVectorHelper(player.posX, player.posY, player.posZ); } - - if(flag) { - this.setPathToEntity(this.worldObj.getEntityPathToXYZ(this, pathX, pathY, pathZ, 10.0F, true, false, false, true)); - } - - this.worldObj.theProfiler.endSection(); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbt) { - super.writeEntityToNBT(nbt); - nbt.setBoolean("hasHome", hasHome); - nbt.setDouble("homeX", homeX); - nbt.setDouble("homeY", homeY); - nbt.setDouble("homeZ", homeZ); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbt) { - super.readEntityFromNBT(nbt); - this.hasHome = nbt.getBoolean("hasHome"); - this.homeX = nbt.getDouble("homeX"); - this.homeY = nbt.getDouble("homeY"); - this.homeZ = nbt.getDouble("homeZ"); + return PollutionHandler.targetCoords; } } diff --git a/src/main/java/com/hbm/entity/mob/EntityParasiteMaggot.java b/src/main/java/com/hbm/entity/mob/EntityParasiteMaggot.java new file mode 100644 index 000000000..40cc3b003 --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/EntityParasiteMaggot.java @@ -0,0 +1,49 @@ +package com.hbm.entity.mob; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.world.World; + +public class EntityParasiteMaggot extends EntityMob { + + public EntityParasiteMaggot(World world) { + super(world); + this.setSize(0.3F, 0.7F); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1.0D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(2.0D); + } + + @Override + protected boolean canTriggerWalking() { + return false; + } + + @Override + protected Entity findPlayerToAttack() { + return this.worldObj.getClosestVulnerablePlayerToEntity(this, 16); + } + + @Override + public void onUpdate() { + this.renderYawOffset = this.rotationYaw; + super.onUpdate(); + } + + @Override + protected boolean isValidLightLevel() { + return true; + } + + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } +} diff --git a/src/main/java/com/hbm/entity/pathfinder/PathFinderUtils.java b/src/main/java/com/hbm/entity/pathfinder/PathFinderUtils.java index 9d5b2f36c..fc4064646 100644 --- a/src/main/java/com/hbm/entity/pathfinder/PathFinderUtils.java +++ b/src/main/java/com/hbm/entity/pathfinder/PathFinderUtils.java @@ -59,4 +59,54 @@ public class PathFinderUtils { world.theProfiler.endSection(); return pathentity; } + + public static PathEntity getPathEntityToCoordPartial(World world, Entity fromEntity, int posX, int posY, int posZ, float maxDist, boolean allowDoors, boolean allowBlocked, boolean allowWater, boolean canDrown) { + world.theProfiler.startSection("pathfind"); + int startX = MathHelper.floor_double(fromEntity.posX); + int startY = MathHelper.floor_double(fromEntity.posY + 1.0D); + int startZ = MathHelper.floor_double(fromEntity.posZ); + int maxDistEff = (int) (maxDist + 16.0F); + int minX = startX - maxDistEff; + int minY = startY - maxDistEff; + int minZ = startZ - maxDistEff; + int maxX = startX + maxDistEff; + int maxY = startY + maxDistEff; + int maxZ = startZ + maxDistEff; + ChunkCache chunkcache = new ChunkCache(world, minX, minY, minZ, maxX, maxY, maxZ, 0); + + Vec3 vec = Vec3.createVectorHelper(posX - fromEntity.posX, posY - fromEntity.posY, posZ - fromEntity.posZ); + vec = vec.normalize(); + vec.xCoord *= maxDist; + vec.yCoord *= maxDist; + vec.zCoord *= maxDist; + + int x = (int) Math.floor(fromEntity.posX + vec.xCoord); + int y = (int) Math.floor(fromEntity.posY + vec.yCoord); + int z = (int) Math.floor(fromEntity.posZ + vec.zCoord); + + //this part will adjust the end of the path so it's actually on the ground, it being unreachable causes mobs to slow down + boolean solid = false; + + for(int i = y; i > y - 10; i--) { + if(!world.getBlock(x, i, z).getMaterial().blocksMovement() && world.getBlock(x, i - 1, z).isNormalCube()) { + solid = true; + y = i; + break; + } + + } + + if(!solid) for(int i = y + 10; i > y; i--) { + if(!world.getBlock(x, i, z).getMaterial().blocksMovement() && world.getBlock(x, i - 1, z).isNormalCube()) { + solid = true; + y = i; + break; + } + } + + //PathEntity pathentity = (new PathFinder(chunkcache, allowDoors, allowBlocked, allowWater, canDrown)).createEntityPathTo(fromEntity, toEntity, maxDist); + PathEntity pathentity = (new PathFinder(chunkcache, allowDoors, allowBlocked, allowWater, canDrown)).createEntityPathTo(fromEntity, x, y, z, maxDist); + world.theProfiler.endSection(); + return pathentity; + } } diff --git a/src/main/java/com/hbm/entity/projectile/EntityAcidBomb.java b/src/main/java/com/hbm/entity/projectile/EntityAcidBomb.java index 8a688df2d..dd928b885 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityAcidBomb.java +++ b/src/main/java/com/hbm/entity/projectile/EntityAcidBomb.java @@ -4,6 +4,7 @@ import com.hbm.entity.mob.EntityGlyphid; import com.hbm.lib.ModDamageSource; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EntityDamageSourceIndirect; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; @@ -27,7 +28,7 @@ public class EntityAcidBomb extends EntityThrowableInterp { if(mop.typeOfHit == mop.typeOfHit.ENTITY) { if(!(mop.entityHit instanceof EntityGlyphid)) { - mop.entityHit.attackEntityFrom(ModDamageSource.acid, damage); + mop.entityHit.attackEntityFrom(new EntityDamageSourceIndirect(ModDamageSource.s_acid, this, thrower), damage); this.setDead(); } } diff --git a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java index d8ee0f4f3..bfaaf8b31 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java +++ b/src/main/java/com/hbm/entity/projectile/EntityBulletBaseNT.java @@ -378,8 +378,8 @@ public class EntityBulletBaseNT extends EntityThrowableInterp implements IBullet data.setInteger("block", Block.getIdFromBlock(Blocks.redstone_block)); PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, living.posX, living.posY + living.height - head, living.posZ), new TargetPoint(living.dimension, living.posX, living.posY, living.posZ, 50)); worldObj.playSoundEffect(victim.posX, victim.posY, victim.posZ, "mob.zombie.woodbreak", 1.0F, 0.95F + rand.nextFloat() * 0.2F); - } - } + } + } } } diff --git a/src/main/java/com/hbm/entity/projectile/EntityChemical.java b/src/main/java/com/hbm/entity/projectile/EntityChemical.java index 3eb72cddc..b6119b8c8 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityChemical.java +++ b/src/main/java/com/hbm/entity/projectile/EntityChemical.java @@ -4,16 +4,13 @@ import java.awt.Color; import java.util.List; import com.hbm.blocks.ModBlocks; +import com.hbm.entity.mob.EntityGlyphid; +import com.hbm.entity.mob.EntityGlyphidBehemoth; import com.hbm.extprop.HbmLivingProps; import com.hbm.handler.radiation.ChunkRadiationManager; import com.hbm.inventory.fluid.FluidType; import com.hbm.inventory.fluid.Fluids; -import com.hbm.inventory.fluid.trait.FT_Combustible; -import com.hbm.inventory.fluid.trait.FT_Corrosive; -import com.hbm.inventory.fluid.trait.FT_Flammable; -import com.hbm.inventory.fluid.trait.FT_Poison; -import com.hbm.inventory.fluid.trait.FT_Toxin; -import com.hbm.inventory.fluid.trait.FT_VentRadiation; +import com.hbm.inventory.fluid.trait.*; import com.hbm.lib.ModDamageSource; import com.hbm.main.MainRegistry; import com.hbm.tileentity.IRepairable; @@ -43,6 +40,7 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; + public class EntityChemical extends EntityThrowableNT { /* @@ -211,6 +209,12 @@ public class EntityChemical extends EntityThrowableNT { HbmLivingProps.setOil(living, 300); //doused in oil for 15 seconds } } + if(type.hasTrait(Fluids.DELICIOUS.getClass())) { + if(living != null && living.isEntityAlive()) { + living.heal(2F * (float) intensity); + } + } + } if(this.isExtinguishing()) { @@ -219,7 +223,7 @@ public class EntityChemical extends EntityThrowableNT { if(style == ChemicalStyle.BURNING) { FT_Combustible trait = type.getTrait(FT_Combustible.class); - EntityDamageUtil.attackEntityFromIgnoreIFrame(e, getDamage(ModDamageSource.s_flamethrower), 2F + (trait != null ? (trait.getCombustionEnergy() / 100_000F) : 0)); + EntityDamageUtil.attackEntityFromIgnoreIFrame(e, getDamage(ModDamageSource.s_flamethrower), 0.2F + (trait != null ? (trait.getCombustionEnergy() / 100_000F) : 0)); e.setFire(5); } @@ -229,17 +233,17 @@ public class EntityChemical extends EntityThrowableNT { float heat = Math.max(flammable != null ? flammable.getHeatEnergy() / 50_000F : 0, combustible != null ? combustible.getCombustionEnergy() / 100_000F : 0); heat *= intensity; - EntityDamageUtil.attackEntityFromIgnoreIFrame(e, getDamage(ModDamageSource.s_flamethrower), (2F + heat) * (float) intensity); + EntityDamageUtil.attackEntityFromIgnoreIFrame(e, getDamage(ModDamageSource.s_flamethrower), (0.2F + heat) * (float) intensity); e.setFire((int) Math.ceil(5 * intensity)); } if(type.hasTrait(FT_Corrosive.class)) { FT_Corrosive trait = type.getTrait(FT_Corrosive.class); - EntityDamageUtil.attackEntityFromIgnoreIFrame(e, getDamage(ModDamageSource.s_acid), trait.getRating() / 50F); - + if(living != null) { + EntityDamageUtil.attackEntityFromIgnoreIFrame(living, getDamage(ModDamageSource.s_acid), trait.getRating() / 50F); for(int i = 0; i < 4; i++) { - ArmorUtil.damageSuit(living, i, (int) Math.ceil(trait.getRating() / 50)); + ArmorUtil.damageSuit(living, i, trait.getRating() / 40); } } } @@ -267,6 +271,26 @@ public class EntityChemical extends EntityThrowableNT { trait.affect(living, intensity); } } + + if(type.hasTrait(FT_Pheromone.class)){ + + FT_Pheromone pheromone = type.getTrait(FT_Pheromone.class); + + if(living != null) { + living.addPotionEffect(new PotionEffect(Potion.resistance.id, 2 * 60 * 20, 2)); + living.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, 5 * 60 * 20, 1)); + living.addPotionEffect(new PotionEffect(Potion.digSpeed.id, 2 * 60 * 20, 4)); + + if (living instanceof EntityGlyphid && pheromone.getType() == 1) { + living.addPotionEffect(new PotionEffect(Potion.damageBoost.id, 5 * 60 * 20, 4)); + living.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 60 * 20, 0)); + living.addPotionEffect(new PotionEffect(Potion.field_76444_x.id, 60 * 20, 19)); + + } else if (living instanceof EntityPlayer && pheromone.getType() == 2) { + living.addPotionEffect(new PotionEffect(Potion.damageBoost.id, 2 * 60 * 20, 2)); + } + } + } if(type == Fluids.XPJUICE) { @@ -301,14 +325,14 @@ public class EntityChemical extends EntityThrowableNT { } //terribly copy-pasted from EntityEnderman.class - protected boolean teleportRandomly(Entity e) { + public boolean teleportRandomly(Entity e) { double x = this.posX + (this.rand.nextDouble() - 0.5D) * 64.0D; double y = this.posY + (double) (this.rand.nextInt(64) - 32); double z = this.posZ + (this.rand.nextDouble() - 0.5D) * 64.0D; return this.teleportTo(e, x, y, z); } - protected boolean teleportTo(Entity e, double x, double y, double z) { + public boolean teleportTo(Entity e, double x, double y, double z) { double targetX = e.posX; double targetY = e.posY; @@ -387,7 +411,7 @@ public class EntityChemical extends EntityThrowableNT { FT_VentRadiation trait = type.getTrait(FT_VentRadiation.class); ChunkRadiationManager.proxy.incrementRad(worldObj, mop.blockX, mop.blockY, mop.blockZ, trait.getRadPerMB() * 5); } - + ChemicalStyle style = getStyle(); if(style == ChemicalStyle.BURNING || style == ChemicalStyle.GASFLAME) { @@ -401,6 +425,18 @@ public class EntityChemical extends EntityThrowableNT { } } } + + if(style == ChemicalStyle.BURNING || style == ChemicalStyle.GASFLAME) { + + for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { + + Block fire = type == Fluids.BALEFIRE ? ModBlocks.balefire : Blocks.fire; + + if(worldObj.getBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ).isAir(worldObj, x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ)) { + worldObj.setBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, fire); + } + } + } if(this.isExtinguishing()) { diff --git a/src/main/java/com/hbm/explosion/vanillant/standard/BlockAllocatorGlyphidDig.java b/src/main/java/com/hbm/explosion/vanillant/standard/BlockAllocatorGlyphidDig.java new file mode 100644 index 000000000..7837c81f2 --- /dev/null +++ b/src/main/java/com/hbm/explosion/vanillant/standard/BlockAllocatorGlyphidDig.java @@ -0,0 +1,90 @@ +package com.hbm.explosion.vanillant.standard; + +import com.hbm.blocks.ModBlocks; +import com.hbm.blocks.generic.BlockGlyphidSpawner; +import com.hbm.explosion.vanillant.ExplosionVNT; +import com.hbm.explosion.vanillant.interfaces.IBlockAllocator; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.util.MathHelper; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.World; + +import java.util.HashSet; + +public class BlockAllocatorGlyphidDig implements IBlockAllocator { + + protected double maximum; + protected int resolution; + + public BlockAllocatorGlyphidDig(double maximum) { + this(maximum, 16); + } + + public BlockAllocatorGlyphidDig(double maximum, int resolution) { + this.resolution = resolution; + this.maximum = maximum; + } + + @Override + public HashSet allocate(ExplosionVNT explosion, World world, double x, double y, double z, float size) { + + HashSet affectedBlocks = new HashSet(); + + for(int i = 0; i < this.resolution; ++i) { + for(int j = 0; j < this.resolution; ++j) { + for(int k = 0; k < this.resolution; ++k) { + + if(i == 0 || i == this.resolution - 1 || j == 0 || j == this.resolution - 1 || k == 0 || k == this.resolution - 1) { + + double d0 = (double) ((float) i / ((float) this.resolution - 1.0F) * 2.0F - 1.0F); + double d1 = (double) ((float) j / ((float) this.resolution - 1.0F) * 2.0F - 1.0F); + double d2 = (double) ((float) k / ((float) this.resolution - 1.0F) * 2.0F - 1.0F); + double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + d0 /= d3; + d1 /= d3; + d2 /= d3; + + double currentX = x; + double currentY = y; + double currentZ = z; + + double dist = 0; + + for(float stepSize = 0.3F; dist <= explosion.size;) { + + double deltaX = currentX - x; + double deltaY = currentY - y; + double deltaZ = currentZ - z; + dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ); + + int blockX = MathHelper.floor_double(currentX); + int blockY = MathHelper.floor_double(currentY); + int blockZ = MathHelper.floor_double(currentZ); + + Block block = world.getBlock(blockX, blockY, blockZ); + + if(block.getMaterial() != Material.air) { + float blockResistance = explosion.exploder != null ? explosion.exploder.func_145772_a(explosion.compat, world, blockX, blockY, blockZ, block) : block.getExplosionResistance(explosion.exploder, world, blockX, blockY, blockZ, x, y, z); + if(this.maximum < blockResistance || block == ModBlocks.glyphid_spawner) { + break; + } + } + + if(explosion.exploder == null || explosion.exploder.func_145774_a(explosion.compat, world, blockX, blockY, blockZ, block, explosion.size)) { + affectedBlocks.add(new ChunkPosition(blockX, blockY, blockZ)); + } + + currentX += d0 * (double) stepSize; + currentY += d1 * (double) stepSize; + currentZ += d2 * (double) stepSize; + } + } + } + } + } + + return affectedBlocks; + } +} diff --git a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java index 424deacfc..0a31c1634 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java @@ -107,7 +107,7 @@ public class Gun12GaugeFactory { config.comment.add("\"Here, I have a more suitable gun for you. You'll need it - Catch!\""); config.comment.add("Alt-fire with Mouse 2 (Right-click) to fire 2 shells at once"); - config.config = HbmCollection.g12; + config.config = HbmCollection.g12hs; config.animations.put(AnimType.CYCLE, new BusAnimation() .addBus("SPAS_RECOIL_TRANSLATE", new BusAnimationSequence() diff --git a/src/main/java/com/hbm/handler/pollution/PollutionHandler.java b/src/main/java/com/hbm/handler/pollution/PollutionHandler.java index 4ff3b70c1..28cd279c4 100644 --- a/src/main/java/com/hbm/handler/pollution/PollutionHandler.java +++ b/src/main/java/com/hbm/handler/pollution/PollutionHandler.java @@ -8,13 +8,16 @@ import java.util.Locale; import java.util.Map.Entry; import java.util.UUID; +import com.hbm.config.MobConfig; import com.hbm.config.RadiationConfig; +import com.hbm.entity.mob.EntityGlyphidScout; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.gameevent.TickEvent.Phase; import cpw.mods.fml.relauncher.Side; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.IMob; @@ -22,10 +25,12 @@ import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.event.entity.living.LivingSpawnEvent; +import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; import net.minecraftforge.event.world.WorldEvent; public class PollutionHandler { @@ -37,7 +42,8 @@ public class PollutionHandler { public static final float SOOT_PER_SECOND = 1F / 25F; /** Baserate of heavy metal generation, balanced around the soot values of combustion engines */ public static final float HEAVY_METAL_PER_SECOND = 1F / 50F; - + public static Vec3 targetCoords; + /////////////////////// /// UTILITY METHODS /// /////////////////////// @@ -53,7 +59,7 @@ public class PollutionHandler { data = new PollutionData(); ppw.pollution.put(pos, data); } - data.pollution[type.ordinal()] = MathHelper.clamp_float(data.pollution[type.ordinal()] + amount, 0F, 10_000F); + data.pollution[type.ordinal()] = MathHelper.clamp_float((float) (data.pollution[type.ordinal()] + amount * MobConfig.pollutionMult), 0F, 10_000F); } public static void decrementPollution(World world, int x, int y, int z, PollutionType type, float amount) { @@ -173,7 +179,7 @@ public class PollutionHandler { public void updateSystem(TickEvent.ServerTickEvent event) { if(event.side == Side.SERVER && event.phase == Phase.END) { - + eggTimer++; if(eggTimer < 60) return; eggTimer = 0; @@ -193,7 +199,7 @@ public class PollutionHandler { /* CALCULATION */ if(data.pollution[S] > 15) { - pollutionForNeightbors[S] = data.pollution[S] * 0.05F; + pollutionForNeightbors[S] = (float) (data.pollution[S] * 0.05F); data.pollution[S] *= 0.8F; } else { data.pollution[S] *= 0.99F; @@ -334,4 +340,34 @@ public class PollutionHandler { } } } + ///RAMPANT MODE STUFFS/// + + @SubscribeEvent + public void rampantTargetSetter(PlayerSleepInBedEvent event){ + if (MobConfig.rampantGlyphidGuidance) targetCoords = Vec3.createVectorHelper(event.x, event.y, event.z); + } + + @SubscribeEvent + public void rampantScoutPopulator(WorldEvent.PotentialSpawns event){ + //yell at me if this vertical formatting hurts your brain + if(MobConfig.rampantNaturalScoutSpawn + && !event.world.isRemote + && event.world.provider.dimensionId == 0 + && event.type == EnumCreatureType.monster + && event.world.canBlockSeeTheSky(event.x, event.y, event.z)) { + + if (event.world.rand.nextInt(MobConfig.rampantScoutSpawnChance) == 0) { + + float soot = PollutionHandler.getPollution(event.world, event.x, event.y, event.z, PollutionType.SOOT); + + if (soot >= MobConfig.rampantScoutSpawnThresh) { + EntityGlyphidScout scout = new EntityGlyphidScout(event.world); + scout.setLocationAndAngles(event.x, event.y, event.z, event.world.rand.nextFloat() * 360.0F, 0.0F); + event.world.spawnEntityInWorld(scout); + } + } + } + + } + } diff --git a/src/main/java/com/hbm/inventory/FluidContainerRegistry.java b/src/main/java/com/hbm/inventory/FluidContainerRegistry.java index f6f3d2971..5033ee2a4 100644 --- a/src/main/java/com/hbm/inventory/FluidContainerRegistry.java +++ b/src/main/java/com/hbm/inventory/FluidContainerRegistry.java @@ -68,9 +68,14 @@ public class FluidContainerRegistry { if(type.getContainer(CD_Gastank.class) != null) FluidContainerRegistry.registerContainer(new FluidContainer(new ItemStack(ModItems.gas_full, 1, id), new ItemStack(ModItems.gas_empty), type, 1000)); if(type.hasNoContainer()) continue; + + if(type.isDispersable()){ + FluidContainerRegistry.registerContainer(new FluidContainer(new ItemStack(ModItems.disperser_canister, 1 , i), new ItemStack(ModItems.disperser_canister_empty), Fluids.fromID(i), 2000)); + FluidContainerRegistry.registerContainer(new FluidContainer(new ItemStack(ModItems.glyphid_gland, 1 , i), new ItemStack(ModItems.glyphid_gland_empty), Fluids.fromID(i), 4000)); + } FluidContainerRegistry.registerContainer(new FluidContainer(new ItemStack(ModItems.fluid_tank_lead_full, 1, id), new ItemStack(ModItems.fluid_tank_lead_empty), type, 1000)); - + if(type.needsLeadContainer()) continue; FluidContainerRegistry.registerContainer(new FluidContainer(new ItemStack(ModItems.fluid_tank_full, 1, id), new ItemStack(ModItems.fluid_tank_empty), type, 1000)); diff --git a/src/main/java/com/hbm/inventory/OreDictManager.java b/src/main/java/com/hbm/inventory/OreDictManager.java index a64fdb6eb..348f1704c 100644 --- a/src/main/java/com/hbm/inventory/OreDictManager.java +++ b/src/main/java/com/hbm/inventory/OreDictManager.java @@ -98,6 +98,8 @@ public class OreDictManager { public static final String KEY_CIRCUIT_BISMUTH = "circuitVersatile"; + public static final String KEY_GLYPHID_MEAT = "glyphidMeat"; + /* * MATERIALS */ @@ -300,6 +302,7 @@ public class OreDictManager { /** Any special post-RBMK gating material, namely bismuth and arsenic */ public static final DictFrame ANY_BISMOID = new DictFrame("AnyBismoid"); public static final DictFrame ANY_ASH = new DictFrame("Ash"); + public static void registerOres() { @@ -504,7 +507,13 @@ public class OreDictManager { */ OreDictionary.registerOre(KEY_CIRCUIT_BISMUTH, circuit_bismuth); OreDictionary.registerOre(KEY_CIRCUIT_BISMUTH, circuit_arsenic); - + + /* + * GLYPHID M E A T + */ + OreDictionary.registerOre(KEY_GLYPHID_MEAT, new ItemStack(glyphid_meat)); + OreDictionary.registerOre(KEY_GLYPHID_MEAT, new ItemStack(glyphid_meat_grilled)); + for(NTMMaterial mat : Mats.orderedList) { if(mat.smeltable == SmeltingBehavior.SMELTABLE) { if(mat.shapes.contains(MaterialShapes.CASTPLATE)) for(String name : mat.names) OreDictionary.registerOre(MaterialShapes.CASTPLATE.name() + name, new ItemStack(ModItems.plate_cast, 1, mat.id)); diff --git a/src/main/java/com/hbm/inventory/fluid/FluidType.java b/src/main/java/com/hbm/inventory/fluid/FluidType.java index d6fa4d759..728c0bad2 100644 --- a/src/main/java/com/hbm/inventory/fluid/FluidType.java +++ b/src/main/java/com/hbm/inventory/fluid/FluidType.java @@ -171,6 +171,9 @@ public class FluidType { public boolean needsLeadContainer() { return this.traits.containsKey(FT_LeadContainer.class); } + public boolean isDispersable() { + return !(this.traits.containsKey(FT_Amat.class) || this.traits.containsKey(FT_NoContainer.class) || this.traits.containsKey(FT_Viscous.class)); + } /** * Called when the tile entity is broken, effectively voiding the fluids. diff --git a/src/main/java/com/hbm/inventory/fluid/Fluids.java b/src/main/java/com/hbm/inventory/fluid/Fluids.java index 5ca1341f6..d4dd8544b 100644 --- a/src/main/java/com/hbm/inventory/fluid/Fluids.java +++ b/src/main/java/com/hbm/inventory/fluid/Fluids.java @@ -118,6 +118,9 @@ public class Fluids { public static FluidType SOLVENT; //oranic solvent in fact public static FluidType BLOOD; //BLOOD ORB! BLOOD ORB! BLOOD ORB! public static FluidType BLOOD_HOT; + + public static FluidType PHEROMONE; + public static FluidType PHEROMONE_M; public static FluidType SYNGAS; public static FluidType OXYHYDROGEN; public static FluidType RADIOSOLVENT; //DCM-ish made by wacky radio cracking @@ -182,7 +185,7 @@ public class Fluids { public static final FT_NoID NOID = new FT_NoID(); public static final FT_Delicious DELICIOUS = new FT_Delicious(); public static final FT_Leaded LEADED = new FT_Leaded(); - + public static void init() { // ##### ##### ##### ##### ## # ##### # # ##### ## # ##### @@ -282,7 +285,7 @@ public class Fluids { SEEDSLURRY = new FluidType("SEEDSLURRY", 0x7CC35E, 0, 0, 0, EnumSymbol.NONE).addContainers(new CD_Canister(0x7CC35E)).addTraits(LIQUID, VISCOUS); NITRIC_ACID = new FluidType("NITRIC_ACID", 0xBB7A1E, 3, 0, 2, EnumSymbol.OXIDIZER).addTraits(LIQUID, new FT_Corrosive(60)); SOLVENT = new FluidType("SOLVENT", 0xE4E3EF, 2, 3, 0, EnumSymbol.NONE).addContainers(new CD_Canister(0xE4E3EF)).addTraits(LIQUID, new FT_Corrosive(30)); - BLOOD = new FluidType("BLOOD", 0xB22424, 0, 0, 0, EnumSymbol.NONE).addTraits(LIQUID, VISCOUS); + BLOOD = new FluidType("BLOOD", 0xB22424, 0, 0, 0, EnumSymbol.NONE).addTraits(LIQUID, VISCOUS, DELICIOUS); BLOOD_HOT = new FluidType("BLOOD_HOT", 0xF22419, 3, 0, 0, EnumSymbol.NONE).addTraits(LIQUID, VISCOUS).setTemp(666); //it's funny because it's the satan number SYNGAS = new FluidType("SYNGAS", 0x131313, 1, 4, 2, EnumSymbol.NONE).addContainers(new CD_Gastank(0xFFFFFF, 0x131313)).addTraits(GASEOUS); OXYHYDROGEN = new FluidType("OXYHYDROGEN", 0x483FC1, 0, 4, 2, EnumSymbol.NONE).addTraits(GASEOUS); @@ -322,14 +325,15 @@ public class Fluids { SMOKE_LEADED = new FluidType("SMOKE_LEADED", 0x808080, 0, 0, 0, EnumSymbol.NONE).addTraits(GASEOUS, NOID, NOCON); SMOKE_POISON = new FluidType("SMOKE_POISON", 0x808080, 0, 0, 0, EnumSymbol.NONE).addTraits(GASEOUS, NOID, NOCON); HELIUM4 = new FluidType("HELIUM4", 0xE54B0A, 0, 0, 0, EnumSymbol.ASPHYXIANT).addTraits(GASEOUS); - HEAVYWATER_HOT = new FluidType("HEAVYWATER_HOT", 0x4D007B, 1, 0, 0, EnumSymbol.NONE).setTemp(600).addTraits(LIQUID); - SODIUM = new FluidType("SODIUM", 0xCCD4D5, 1, 2, 3, EnumSymbol.NONE).setTemp(400).addTraits(LIQUID); - SODIUM_HOT = new FluidType("SODIUM_HOT", 0xE2ADC1, 1, 2, 3, EnumSymbol.NONE).setTemp(1200).addTraits(LIQUID); - THORIUM_SALT = new FluidType("THORIUM_SALT", 0x7A5542, 2, 0, 3, EnumSymbol.NONE).setTemp(800).addTraits(LIQUID, new FT_Corrosive(65)); - THORIUM_SALT_HOT = new FluidType("THORIUM_SALT_HOT", 0x3E3627, 2, 0, 3, EnumSymbol.NONE).setTemp(1600).addTraits(LIQUID, new FT_Corrosive(65)); - THORIUM_SALT_DEPLETED = new FluidType("THORIUM_SALT_DEPLETED", 0x302D1C, 2, 0, 3, EnumSymbol.NONE).setTemp(800).addTraits(LIQUID, new FT_Corrosive(65)); - FULLERENE = new FluidType(130, "FULLERENE", 0xFF7FED, 3, 3, 3, EnumSymbol.NONE).addTraits(LIQUID, new FT_Corrosive(65)); - + HEAVYWATER_HOT = new FluidType("HEAVYWATER_HOT", 0x4D007B, 1, 0, 0, EnumSymbol.NONE).setTemp(600).addTraits(LIQUID, VISCOUS); + SODIUM = new FluidType("SODIUM", 0xCCD4D5, 1, 2, 3, EnumSymbol.NONE).setTemp(400).addTraits(LIQUID, VISCOUS); + SODIUM_HOT = new FluidType("SODIUM_HOT", 0xE2ADC1, 1, 2, 3, EnumSymbol.NONE).setTemp(1200).addTraits(LIQUID, VISCOUS); + THORIUM_SALT = new FluidType("THORIUM_SALT", 0x7A5542, 2, 0, 3, EnumSymbol.NONE).setTemp(800).addTraits(LIQUID, VISCOUS, new FT_Corrosive(65)); + THORIUM_SALT_HOT = new FluidType("THORIUM_SALT_HOT", 0x3E3627, 2, 0, 3, EnumSymbol.NONE).setTemp(1600).addTraits(LIQUID, VISCOUS, new FT_Corrosive(65)); + THORIUM_SALT_DEPLETED = new FluidType("THORIUM_SALT_DEPLETED", 0x302D1C, 2, 0, 3, EnumSymbol.NONE).setTemp(800).addTraits(LIQUID, VISCOUS, new FT_Corrosive(65)); + FULLERENE = new FluidType("FULLERENE", 0xFF7FED, 3, 3, 3, EnumSymbol.NONE).addTraits(LIQUID, new FT_Corrosive(65)); + PHEROMONE = new FluidType("PHEROMONE", 0x5FA6E8, 0, 0, 0, EnumSymbol.NONE).addTraits(LIQUID, VISCOUS, new FT_Pheromone(1)); + PHEROMONE_M = new FluidType(132, "PHEROMONE_M", 0x48C9B0 , 0, 0, 0, EnumSymbol.NONE).addTraits(LIQUID, VISCOUS, new FT_Pheromone(2)); // ^ ^ ^ ^ ^ ^ ^ ^ //ADD NEW FLUIDS HERE @@ -486,7 +490,10 @@ public class Fluids { metaOrder.add(SMOKE); metaOrder.add(SMOKE_LEADED); metaOrder.add(SMOKE_POISON); - + + //bug meth + metaOrder.add(PHEROMONE); + metaOrder.add(PHEROMONE_M); for(FluidType custom : customFluids) metaOrder.add(custom); CHLORINE.addTraits(new FT_Toxin().addEntry(new ToxinDirectDamage(ModDamageSource.cloud, 2F, 20, HazardClass.GAS_CHLORINE, false))); diff --git a/src/main/java/com/hbm/inventory/fluid/trait/FT_Pheromone.java b/src/main/java/com/hbm/inventory/fluid/trait/FT_Pheromone.java new file mode 100644 index 000000000..4ebfc8e5c --- /dev/null +++ b/src/main/java/com/hbm/inventory/fluid/trait/FT_Pheromone.java @@ -0,0 +1,43 @@ +package com.hbm.inventory.fluid.trait; + +import com.google.gson.JsonObject; +import com.google.gson.stream.JsonWriter; +import net.minecraft.util.EnumChatFormatting; + + +import java.io.IOException; +import java.util.List; + +public class FT_Pheromone extends FluidTrait{ + + public int type; + + public FT_Pheromone(int type){ + this.type = type; + } + + public int getType() { + return type; + } + + @Override + public void addInfo(List info) { + + if (type == 1) { + info.add(EnumChatFormatting.AQUA + "[Glyphid Pheromones]"); + } else { + info.add(EnumChatFormatting.BLUE + "[Modified Pheromones]"); + } + + } + @Override + public void serializeJSON(JsonWriter writer) throws IOException { + writer.name("type").value(type); + } + + @Override + public void deserializeJSON(JsonObject obj) { + this.type = obj.get("type").getAsInt(); + } + +} diff --git a/src/main/java/com/hbm/inventory/fluid/trait/FluidTrait.java b/src/main/java/com/hbm/inventory/fluid/trait/FluidTrait.java index ff2522d09..de7ddc591 100644 --- a/src/main/java/com/hbm/inventory/fluid/trait/FluidTrait.java +++ b/src/main/java/com/hbm/inventory/fluid/trait/FluidTrait.java @@ -35,6 +35,7 @@ public abstract class FluidTrait { traitNameMap.put("leadcontainer", FT_LeadContainer.class); traitNameMap.put("delicious", FT_Delicious.class); traitNameMap.put("leaded", FT_Leaded.class); + traitNameMap.put("pheromone", FT_Pheromone.class); traitNameMap.put("noid", FT_NoID.class); traitNameMap.put("nocontainer", FT_NoContainer.class); } diff --git a/src/main/java/com/hbm/inventory/fluid/trait/FluidTraitSimple.java b/src/main/java/com/hbm/inventory/fluid/trait/FluidTraitSimple.java index d282cea42..f62cd456e 100644 --- a/src/main/java/com/hbm/inventory/fluid/trait/FluidTraitSimple.java +++ b/src/main/java/com/hbm/inventory/fluid/trait/FluidTraitSimple.java @@ -49,7 +49,7 @@ public class FluidTraitSimple { info.add(EnumChatFormatting.DARK_RED + "[Requires hazardous material tank to hold]"); } } - + public static class FT_Delicious extends FluidTrait { @Override public void addInfoHidden(List info) { info.add(EnumChatFormatting.DARK_GREEN + "[Delicious]"); diff --git a/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java b/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java index f3639536b..f14b4bd10 100644 --- a/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java @@ -21,6 +21,7 @@ import com.hbm.inventory.recipes.loader.SerializableRecipe; import com.hbm.items.ModItems; import com.hbm.main.MainRegistry; +import cpw.mods.fml.common.Mod; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; @@ -401,6 +402,7 @@ public class ChemplantRecipes extends SerializableRecipe { recipes.add(new ChemRecipe(101, "CC_CENTRIFUGE", 200) .inputFluids(new FluidStack(Fluids.CHLOROCALCITE_CLEANED, 500), new FluidStack(Fluids.SULFURIC_ACID, 8_000)) .outputFluids(new FluidStack(Fluids.POTASSIUM_CHLORIDE, 250), new FluidStack(Fluids.CALCIUM_CHLORIDE, 250))); + recipes.add(new ChemRecipe(102, "THORIUM_SALT", 60) .inputFluids(new FluidStack(Fluids.THORIUM_SALT_DEPLETED, 16_000)) .inputItems(new OreDictStack(TH232.nugget(), 2)) @@ -408,6 +410,14 @@ public class ChemplantRecipes extends SerializableRecipe { .outputItems( new ItemStack(ModItems.nugget_u233, 1), new ItemStack(ModItems.nuclear_waste_tiny, 1))); + + recipes.add(new ChemRecipe(103, "MEAT_PROCESSING", 200) + .inputItems(new OreDictStack(KEY_GLYPHID_MEAT, 3)) + .inputFluids(new FluidStack(Fluids.SULFURIC_ACID, 1000)) + .outputItems(new ItemStack(ModItems.sulfur, 4), + new ItemStack(ModItems.niter, 3)) + .outputFluids(new FluidStack(Fluids.SALIENT, 250))); + } public static void registerFuelProcessing() { diff --git a/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java b/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java index ee093f541..3af3808a7 100644 --- a/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java @@ -59,6 +59,7 @@ public class LiquefactionRecipes extends SerializableRecipe { recipes.put(new ComparableStack(ModBlocks.plant_flower, 1, 3), new FluidStack(150, Fluids.ETHANOL)); recipes.put(new ComparableStack(ModBlocks.plant_flower, 1, 4), new FluidStack(50, Fluids.ETHANOL)); recipes.put(new ComparableStack(ModItems.biomass), new FluidStack(125, Fluids.BIOGAS)); + recipes.put(new ComparableStack(ModItems.glyphid_gland_empty), new FluidStack(2000, Fluids.BIOGAS)); recipes.put(new ComparableStack(Items.fish, 1, OreDictionary.WILDCARD_VALUE), new FluidStack(100, Fluids.FISHOIL)); recipes.put(new ComparableStack(Blocks.double_plant, 1, 0), new FluidStack(100, Fluids.SUNFLOWEROIL)); diff --git a/src/main/java/com/hbm/inventory/recipes/MixerRecipes.java b/src/main/java/com/hbm/inventory/recipes/MixerRecipes.java index 15bf9a25e..fe7b40217 100644 --- a/src/main/java/com/hbm/inventory/recipes/MixerRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/MixerRecipes.java @@ -83,6 +83,8 @@ public class MixerRecipes extends SerializableRecipe { register(Fluids.CHLOROCALCITE_SOLUTION, new MixerRecipe(500, 50).setStack1(new FluidStack(Fluids.WATER, 250)).setStack2(new FluidStack(Fluids.NITRIC_ACID, 250)).setSolid(new OreDictStack(CHLOROCALCITE.dust()))); register(Fluids.CHLOROCALCITE_MIX, new MixerRecipe(1000, 50).setStack1(new FluidStack(Fluids.CHLOROCALCITE_SOLUTION, 500)).setStack2(new FluidStack(Fluids.SULFURIC_ACID, 500)).setSolid(new ComparableStack(ModItems.powder_flux))); + register(Fluids.PHEROMONE_M, new MixerRecipe(2000, 10).setStack1(new FluidStack(Fluids.PHEROMONE, 1500)).setStack2(new FluidStack(Fluids.BLOOD, 500)).setSolid(new ComparableStack(ModItems.pill_herbal))); + } public static void register(FluidType type, MixerRecipe... rec) { diff --git a/src/main/java/com/hbm/items/ModItems.java b/src/main/java/com/hbm/items/ModItems.java index 211768119..72651c636 100644 --- a/src/main/java/com/hbm/items/ModItems.java +++ b/src/main/java/com/hbm/items/ModItems.java @@ -936,6 +936,11 @@ public class ModItems { public static Item fluid_barrel_empty; public static Item fluid_barrel_infinite; + public static Item disperser_canister_empty; + public static Item disperser_canister; + public static Item glyphid_gland; + public static Item glyphid_gland_empty; + public static Item syringe_empty; public static Item syringe_antidote; public static Item syringe_poison; @@ -4644,6 +4649,13 @@ public class ModItems { fluid_barrel_full = new ItemFluidTank().setUnlocalizedName("fluid_barrel_full").setContainerItem(ModItems.fluid_barrel_empty).setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":fluid_barrel"); fluid_barrel_empty = new Item().setUnlocalizedName("fluid_barrel_empty").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":fluid_barrel"); fluid_barrel_infinite = new ItemInfiniteFluid(null, 1_000_000_000).setUnlocalizedName("fluid_barrel_infinite").setMaxStackSize(1).setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":fluid_barrel_infinite"); + + disperser_canister_empty = new Item().setUnlocalizedName("disperser_canister_empty").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":disperser_canister"); + disperser_canister = new ItemDisperser().setUnlocalizedName("disperser_canister").setContainerItem(ModItems.disperser_canister_empty).setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":disperser_canister"); + + glyphid_gland = new ItemDisperser().setUnlocalizedName("glyphid_gland").setContainerItem(ModItems.glyphid_gland_empty).setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":glyphid_gland"); + glyphid_gland_empty = new Item().setUnlocalizedName("glyphid_gland_empty").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":glyphid_gland"); + siren_track = new ItemCassette().setUnlocalizedName("siren_track").setMaxStackSize(1).setCreativeTab(MainRegistry.templateTab).setTextureName(RefStrings.MODID + ":cassette"); fluid_duct = new ItemFluidDuct().setUnlocalizedName("fluid_duct").setCreativeTab(MainRegistry.templateTab).setTextureName(RefStrings.MODID + ":duct"); @@ -6365,7 +6377,14 @@ public class ModItems { GameRegistry.registerItem(fluid_barrel_empty, fluid_barrel_empty.getUnlocalizedName()); GameRegistry.registerItem(fluid_barrel_full, fluid_barrel_full.getUnlocalizedName()); GameRegistry.registerItem(fluid_barrel_infinite, fluid_barrel_infinite.getUnlocalizedName()); - + + //Disperser Canister + GameRegistry.registerItem(disperser_canister_empty, disperser_canister_empty.getUnlocalizedName()); + GameRegistry.registerItem(disperser_canister, disperser_canister.getUnlocalizedName()); + + GameRegistry.registerItem(glyphid_gland_empty, glyphid_gland_empty.getUnlocalizedName()); + GameRegistry.registerItem(glyphid_gland, glyphid_gland.getUnlocalizedName()); + //Batteries GameRegistry.registerItem(battery_generic, battery_generic.getUnlocalizedName()); GameRegistry.registerItem(battery_red_cell, battery_red_cell.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/items/machine/ItemFluidTank.java b/src/main/java/com/hbm/items/machine/ItemFluidTank.java index f4c0a3551..ce7a2cd0d 100644 --- a/src/main/java/com/hbm/items/machine/ItemFluidTank.java +++ b/src/main/java/com/hbm/items/machine/ItemFluidTank.java @@ -15,7 +15,7 @@ import net.minecraft.util.StatCollector; public class ItemFluidTank extends Item { - IIcon overlayIcon; + protected IIcon overlayIcon; public ItemFluidTank() { this.setHasSubtypes(true); diff --git a/src/main/java/com/hbm/items/weapon/ItemDisperser.java b/src/main/java/com/hbm/items/weapon/ItemDisperser.java new file mode 100644 index 000000000..7f06f07e1 --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/ItemDisperser.java @@ -0,0 +1,75 @@ +package com.hbm.items.weapon; + +import com.hbm.entity.grenade.EntityDisperserCanister; +import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemFluidTank; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +import java.util.List; + +public class ItemDisperser extends ItemFluidTank { + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + + if(!player.capabilities.isCreativeMode) { + --stack.stackSize; + } + + world.playSoundAtEntity(player, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if(!world.isRemote) { + + EntityDisperserCanister canister = new EntityDisperserCanister(world, player); + canister.setType(Item.getIdFromItem(this)); + canister.setFluid(stack.getItemDamage()); + world.spawnEntityInWorld(canister); + } + return stack; + } + + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item item, CreativeTabs tabs, List list) { + + FluidType[] order = Fluids.getInNiceOrder(); + + for(int i = 1; i < order.length; ++i) { + FluidType type = order[i]; + int id = type.getID(); + if(type.isDispersable() && this == ModItems.disperser_canister) { + list.add(new ItemStack(item, 1, id)); + } else if(type == Fluids.PHEROMONE || type == Fluids.SULFURIC_ACID && this == ModItems.glyphid_gland) { + list.add(new ItemStack(item, 1, id)); + } + + } + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + + String s = ("" + StatCollector.translateToLocal(this.getUnlocalizedName() + ".name")).trim(); + String s1 = ("" + StatCollector.translateToLocal(Fluids.fromID(stack.getItemDamage()).getConditionalName())).trim(); + + s = this == ModItems.glyphid_gland ? s1 + " " + s : s + " " + s1; + return s; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister p_94581_1_) { + super.registerIcons(p_94581_1_); + this.overlayIcon = this == ModItems.disperser_canister ? p_94581_1_.registerIcon("hbm:disperser_canister_overlay") : p_94581_1_.registerIcon("hbm:fluid_identifier_overlay"); + } +} diff --git a/src/main/java/com/hbm/lib/HbmWorldGen.java b/src/main/java/com/hbm/lib/HbmWorldGen.java index d8019a7ea..d4bb78bc6 100644 --- a/src/main/java/com/hbm/lib/HbmWorldGen.java +++ b/src/main/java/com/hbm/lib/HbmWorldGen.java @@ -18,20 +18,7 @@ import com.hbm.tileentity.machine.storage.TileEntitySafe; import com.hbm.tileentity.machine.storage.TileEntitySoyuzCapsule; import com.hbm.util.LootGenerator; import com.hbm.util.WeightedRandomGeneric; -import com.hbm.world.dungeon.AncientTomb; -import com.hbm.world.dungeon.Antenna; -import com.hbm.world.dungeon.ArcticVault; -import com.hbm.world.dungeon.Barrel; -import com.hbm.world.dungeon.CrashedVertibird; -import com.hbm.world.dungeon.DesertAtom001; -import com.hbm.world.dungeon.Factory; -import com.hbm.world.dungeon.LibraryDungeon; -import com.hbm.world.dungeon.Radio01; -import com.hbm.world.dungeon.Relay; -import com.hbm.world.dungeon.Satellite; -import com.hbm.world.dungeon.Silo; -import com.hbm.world.dungeon.Spaceship; -import com.hbm.world.dungeon.Vertibird; +import com.hbm.world.dungeon.*; import com.hbm.world.feature.BedrockOre; import com.hbm.world.feature.BedrockOre.BedrockOreDefinition; import com.hbm.world.feature.DepthDeposit; @@ -242,7 +229,13 @@ public class HbmWorldGen implements IWorldGenerator { int x = i + rand.nextInt(16) + 8; int z = j + rand.nextInt(16) + 8; int y = world.getHeightValue(x, z); - if(world.getBlock(x, y - 1, z).isNormalCube()) GlyphidHive.generate(world, x, y, z, rand); + + for(int k = 3; k >= -1; k--) { + if(world.getBlock(x, y - 1 + k, z).isNormalCube()) { + GlyphidHive.generateSmall(world, x, y + k, z, rand, rand.nextInt(10) == 0, true); + break; + } + } } if(biome == BiomeGenBase.plains || biome == BiomeGenBase.desert) { @@ -365,6 +358,7 @@ public class HbmWorldGen implements IWorldGenerator { new Dud().generate(world, rand, x, y, z); } + if(WorldConfig.spaceshipStructure > 0 && rand.nextInt(WorldConfig.spaceshipStructure) == 0) { int x = i + rand.nextInt(16); int z = j + rand.nextInt(16); @@ -372,7 +366,6 @@ public class HbmWorldGen implements IWorldGenerator { new Spaceship().generate(world, rand, x, y, z); } - if(WorldConfig.barrelStructure > 0 && biome.temperature >= 1.5F && !biome.canSpawnLightningBolt() && rand.nextInt(WorldConfig.barrelStructure) == 0) { int x = i + rand.nextInt(16); int z = j + rand.nextInt(16); diff --git a/src/main/java/com/hbm/lib/ModDamageSource.java b/src/main/java/com/hbm/lib/ModDamageSource.java index a477d929c..1fe20cf1c 100644 --- a/src/main/java/com/hbm/lib/ModDamageSource.java +++ b/src/main/java/com/hbm/lib/ModDamageSource.java @@ -16,7 +16,7 @@ public class ModDamageSource extends DamageSource { public static DamageSource nuclearBlast = (new DamageSource("nuclearBlast")).setExplosion(); public static DamageSource mudPoisoning = (new DamageSource("mudPoisoning")).setDamageBypassesArmor(); - public static DamageSource acid = (new DamageSource("acid")).setDamageBypassesArmor(); + public static DamageSource acid = (new DamageSource("acid")); //.setDamageBypassesArmor(); public static DamageSource euthanizedSelf = (new DamageSource("euthanizedSelf")).setDamageBypassesArmor(); public static DamageSource euthanizedSelf2 = (new DamageSource("euthanizedSelf2")).setDamageBypassesArmor(); public static DamageSource tauBlast = (new DamageSource("tauBlast")).setDamageBypassesArmor(); @@ -53,6 +53,7 @@ public class ModDamageSource extends DamageSource { public static DamageSource vacuum = (new DamageSource("vacuum")).setDamageIsAbsolute().setDamageBypassesArmor(); public static DamageSource overdose = (new DamageSource("overdose")).setDamageIsAbsolute().setDamageBypassesArmor(); public static DamageSource microwave = (new DamageSource("microwave")).setDamageIsAbsolute().setDamageBypassesArmor(); + public static DamageSource nitan = (new DamageSource("nitan")).setDamageIsAbsolute().setDamageBypassesArmor().setDamageAllowedInCreativeMode();; public static final String s_bullet = "revolverBullet"; public static final String s_emplacer = "chopperBullet"; diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 2a8e88ddb..dcb6e842c 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -613,6 +613,7 @@ public class ClientProxy extends ServerProxy { RenderingRegistry.registerEntityRenderingHandler(EntitySawblade.class, new RenderSawblade()); RenderingRegistry.registerEntityRenderingHandler(EntityChemical.class, new RenderChemical()); RenderingRegistry.registerEntityRenderingHandler(EntityMist.class, new RenderMist()); + RenderingRegistry.registerEntityRenderingHandler(EntityWaypoint.class, new RenderMist()); RenderingRegistry.registerEntityRenderingHandler(EntityAcidBomb.class, new RenderSnowball(Items.slime_ball)); //grenades RenderingRegistry.registerEntityRenderingHandler(EntityGrenadeGeneric.class, new RenderSnowball(ModItems.grenade_generic)); @@ -660,6 +661,7 @@ public class ClientProxy extends ServerProxy { RenderingRegistry.registerEntityRenderingHandler(EntityGrenadeDynamite.class, new RenderSnowball(ModItems.stick_dynamite)); RenderingRegistry.registerEntityRenderingHandler(EntityGrenadeBouncyGeneric.class, new RenderGenericGrenade()); RenderingRegistry.registerEntityRenderingHandler(EntityGrenadeImpactGeneric.class, new RenderGenericGrenade()); + RenderingRegistry.registerEntityRenderingHandler(EntityDisperserCanister.class, new RenderGenericGrenade()); //missiles RenderingRegistry.registerEntityRenderingHandler(EntityTestMissile.class, new RenderTestMissile()); RenderingRegistry.registerEntityRenderingHandler(EntityMissileCustom.class, new RenderMissileCustom()); @@ -762,6 +764,7 @@ public class ClientProxy extends ServerProxy { RenderingRegistry.registerEntityRenderingHandler(EntityGlyphidBlaster.class, new RenderGlyphid()); RenderingRegistry.registerEntityRenderingHandler(EntityGlyphidScout.class, new RenderGlyphid()); RenderingRegistry.registerEntityRenderingHandler(EntityGlyphidNuclear.class, new RenderGlyphidNuclear()); + RenderingRegistry.registerEntityRenderingHandler(EntityParasiteMaggot.class, new RenderMaggot()); RenderingRegistry.registerEntityRenderingHandler(EntityFBIDrone.class, new RenderDrone()); RenderingRegistry.registerEntityRenderingHandler(EntityPlasticBag.class, new RenderPlasticBag()); RenderingRegistry.registerEntityRenderingHandler(EntityPigeon.class, new RenderPigeon(new ModelPigeon(), 0.3F)); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 9816aee87..0d1a613df 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -750,6 +750,7 @@ public class ResourceManager { public static final ResourceLocation glyphid_blaster_tex = new ResourceLocation(RefStrings.MODID, "textures/entity/glyphid_blaster.png"); public static final ResourceLocation glyphid_scout_tex = new ResourceLocation(RefStrings.MODID, "textures/entity/glyphid_scout.png"); public static final ResourceLocation glyphid_nuclear_tex = new ResourceLocation(RefStrings.MODID, "textures/entity/glyphid_nuclear.png"); + public static final ResourceLocation glyphid_digger_tex = new ResourceLocation(RefStrings.MODID, "textures/entity/glyphid_digger.png"); //ZIRNOX public static final ResourceLocation zirnox_tex = new ResourceLocation(RefStrings.MODID, "textures/models/zirnox.png"); diff --git a/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java b/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java index 49b0ea4f8..6ad109605 100644 --- a/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java +++ b/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java @@ -3,6 +3,7 @@ package com.hbm.render.entity.mob; import org.lwjgl.opengl.GL11; import com.hbm.entity.mob.EntityGlyphid; +import com.hbm.lib.RefStrings; import com.hbm.main.ResourceManager; import net.minecraft.client.model.ModelBase; @@ -13,10 +14,13 @@ import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; public class RenderGlyphid extends RenderLiving { + + public static final ResourceLocation glyphid_infested_tex = new ResourceLocation(RefStrings.MODID, "textures/entity/glyphid_infestation.png"); public RenderGlyphid() { super(new ModelGlyphid(), 1.0F); this.shadowOpaque = 0.0F; + this.setRenderPassModel(this.mainModel); } @Override @@ -24,6 +28,21 @@ public class RenderGlyphid extends RenderLiving { EntityGlyphid glyphid = (EntityGlyphid) entity; return glyphid.getSkin(); } + + @Override + protected int shouldRenderPass(EntityLivingBase entity, int pass, float interp) { + if(pass != 0) { + return -1; + } else { + if(entity.getDataWatcher().getWatchableObjectByte(EntityGlyphid.DW_SUBTYPE) == EntityGlyphid.TYPE_INFECTED) { + this.bindTexture(glyphid_infested_tex); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_ALPHA_TEST); + return 1; + } + return -1; + } + } public static class ModelGlyphid extends ModelBase { @@ -43,11 +62,20 @@ public class RenderGlyphid extends RenderLiving { GL11.glEnable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_CULL_FACE); + this.renderModel(entity, limbSwing); + + GL11.glPopMatrix(); + } + + public void renderModel(Entity entity, float limbSwing) { + + GL11.glPushMatrix(); + double s = ((EntityGlyphid) entity).getScale(); GL11.glScaled(s, s, s); EntityLivingBase living = (EntityLivingBase) entity; - byte armor = living.getDataWatcher().getWatchableObjectByte(17); + byte armor = living.getDataWatcher().getWatchableObjectByte(EntityGlyphid.DW_ARMOR); double walkCycle = limbSwing; diff --git a/src/main/java/com/hbm/render/entity/mob/RenderMaggot.java b/src/main/java/com/hbm/render/entity/mob/RenderMaggot.java new file mode 100644 index 000000000..6fa0184cc --- /dev/null +++ b/src/main/java/com/hbm/render/entity/mob/RenderMaggot.java @@ -0,0 +1,28 @@ +package com.hbm.render.entity.mob; + +import com.hbm.lib.RefStrings; + +import net.minecraft.client.model.ModelSilverfish; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ResourceLocation; + +public class RenderMaggot extends RenderLiving { + + public static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID, "textures/entity/parasite_maggot.png"); + + public RenderMaggot() { + super(new ModelSilverfish(), 0.3F); + } + + @Override + protected float getDeathMaxRotation(EntityLivingBase entity) { + return 180.0F; + } + + @Override + protected ResourceLocation getEntityTexture(Entity entity) { + return texture; + } +} diff --git a/src/main/java/com/hbm/render/entity/projectile/RenderGenericGrenade.java b/src/main/java/com/hbm/render/entity/projectile/RenderGenericGrenade.java index cca75e72d..06ecc70fa 100644 --- a/src/main/java/com/hbm/render/entity/projectile/RenderGenericGrenade.java +++ b/src/main/java/com/hbm/render/entity/projectile/RenderGenericGrenade.java @@ -1,9 +1,11 @@ package com.hbm.render.entity.projectile; +import com.hbm.entity.grenade.EntityDisperserCanister; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import com.hbm.entity.grenade.IGenericGrenade; +import com.hbm.inventory.fluid.FluidType; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; @@ -17,21 +19,43 @@ public class RenderGenericGrenade extends Render { @Override public void doRender(Entity entity, double x, double y, double z, float f0, float f1) { - IGenericGrenade grenade = (IGenericGrenade) entity; + boolean disperser = entity instanceof EntityDisperserCanister; - IIcon iicon = grenade.getGrenade().getIconFromDamage(0); - - if(iicon != null) { - GL11.glPushMatrix(); - GL11.glTranslatef((float) x, (float) y, (float) z); - GL11.glEnable(GL12.GL_RESCALE_NORMAL); - GL11.glScalef(0.5F, 0.5F, 0.5F); - this.bindEntityTexture(entity); - Tessellator tessellator = Tessellator.instance; - - this.renderItem(tessellator, iicon); - GL11.glDisable(GL12.GL_RESCALE_NORMAL); - GL11.glPopMatrix(); + for(int i = 0; i < (disperser ? 2 : 1); i++) { + + IIcon iicon; + if(disperser){ + EntityDisperserCanister canister = (EntityDisperserCanister) entity; + FluidType fluid = canister.getFluid(); + iicon = canister.getType().getIconFromDamageForRenderPass(fluid.getID(), i); + + if(i == 1) { + int hex = fluid.getColor(); + int r = (hex & 0xFF0000) >> 16; + int g = (hex & 0xFF00) >> 8; + int b = (hex & 0xFF); + GL11.glColor3b((byte) (r / 2), (byte) (g / 2), (byte) (b / 2)); + } + + } else { + IGenericGrenade grenade = (IGenericGrenade) entity; + iicon = grenade.getGrenade().getIconFromDamage(i); + } + + if(iicon != null) { + GL11.glPushMatrix(); + GL11.glTranslatef((float) x, (float) y, (float) z); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glScalef(0.5F, 0.5F, 0.5F); + this.bindEntityTexture(entity); + Tessellator tessellator = Tessellator.instance; + + this.renderItem(tessellator, iicon); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); + } + + GL11.glColor3f(1F, 1F, 1F); } } diff --git a/src/main/java/com/hbm/render/tileentity/RenderLoot.java b/src/main/java/com/hbm/render/tileentity/RenderLoot.java index 1813bb7d7..125ebb617 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderLoot.java +++ b/src/main/java/com/hbm/render/tileentity/RenderLoot.java @@ -1,6 +1,7 @@ package com.hbm.render.tileentity; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; import com.hbm.blocks.generic.BlockLoot.TileEntityLoot; import com.hbm.items.ModItems; @@ -82,16 +83,20 @@ public class RenderLoot extends TileEntitySpecialRenderer { protected ModelLeverAction shotgun; private void renderShotgun() { - - if(shotgun == null) - shotgun = new ModelLeverAction(); - GL11.glScaled(0.25, 0.25, 0.25); - GL11.glTranslated(3, 0.0625, 2); - GL11.glRotated(-25, 0, 1, 0); + GL11.glScaled(0.5, 0.5, 0.5); + GL11.glTranslated(1, 0, 0); + GL11.glRotated(25, 0, 1, 0); GL11.glRotated(90, 1, 0, 0); - bindTexture(new ResourceLocation(RefStrings.MODID +":textures/models/ModelLeverAction.png")); - shotgun.render(null, 0F, 0F, 0F, 0F, 0F, 0.0625F); + GL11.glRotated(90, 0, 1, 0); + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + bindTexture(ResourceManager.ff_wood); + ResourceManager.ff_maresleg.renderPart("Grip"); + bindTexture(ResourceManager.ff_gun_bright); + ResourceManager.ff_maresleg.renderPart("Gun"); + ResourceManager.ff_maresleg.renderPart("Lever"); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); } private void renderStandardItem(ItemStack stack) { diff --git a/src/main/java/com/hbm/render/util/RenderInfoSystem.java b/src/main/java/com/hbm/render/util/RenderInfoSystem.java index da618d194..94f7760d2 100644 --- a/src/main/java/com/hbm/render/util/RenderInfoSystem.java +++ b/src/main/java/com/hbm/render/util/RenderInfoSystem.java @@ -44,7 +44,7 @@ public class RenderInfoSystem { } } - @SubscribeEvent + @SubscribeEvent(receiveCanceled = true) public void onOverlayRender(RenderGameOverlayEvent.Pre event) { if(event.type != ElementType.CROSSHAIRS) @@ -80,7 +80,7 @@ public class RenderInfoSystem { int side = pX + 5 + longest; int height = messages.size() * 10 + pZ + 2; int z = 0; - + GL11.glDisable(GL11.GL_TEXTURE_2D); Tessellator tess = Tessellator.instance; tess.startDrawingQuads(); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyBrick.java b/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyBrick.java index 5a95b31ac..c237c9be9 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyBrick.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyBrick.java @@ -1,5 +1,7 @@ package com.hbm.tileentity.machine; + +import com.hbm.config.MobConfig; import com.hbm.main.MainRegistry; import cpw.mods.fml.relauncher.Side; @@ -29,7 +31,7 @@ public class TileEntityChimneyBrick extends TileEntityChimneyBase { @Override public double getPollutionMod() { - return 0.25D; + return MobConfig.rampantMode ? MobConfig.rampantSmokeStackOverride : 0.25D; } AxisAlignedBB bb = null; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyIndustrial.java b/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyIndustrial.java index f5a79dce4..80006caf3 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyIndustrial.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityChimneyIndustrial.java @@ -1,5 +1,6 @@ package com.hbm.tileentity.machine; +import com.hbm.config.MobConfig; import com.hbm.main.MainRegistry; import cpw.mods.fml.relauncher.Side; @@ -29,7 +30,7 @@ public class TileEntityChimneyIndustrial extends TileEntityChimneyBase { @Override public double getPollutionMod() { - return 0.1D; + return MobConfig.rampantMode ? MobConfig.rampantSmokeStackOverride/2 : 0.1D; } @Override diff --git a/src/main/java/com/hbm/util/LootGenerator.java b/src/main/java/com/hbm/util/LootGenerator.java index 69b0af7f5..537796427 100644 --- a/src/main/java/com/hbm/util/LootGenerator.java +++ b/src/main/java/com/hbm/util/LootGenerator.java @@ -8,6 +8,7 @@ import com.hbm.items.ModItems; import com.hbm.items.special.ItemBookLore; import com.hbm.items.ItemAmmoEnums.AmmoFatman; +import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.world.World; @@ -140,4 +141,46 @@ public class LootGenerator { } } } + + public static void lootBones(World world, int x, int y, int z) { + + TileEntityLoot loot = (TileEntityLoot) world.getTileEntity(x, y, z); + + if(loot != null && loot.items.isEmpty()) { + + int limit = world.rand.nextInt(3) + 3; + for(int i = 0; i < limit; i++) { + addItemWithDeviation(loot, world.rand, new ItemStack(Items.bone), world.rand.nextDouble() - 0.5, i * 0.03125, world.rand.nextDouble() - 0.5); + } + } + } + + public static void lootGlyphidHive(World world, int x, int y, int z) { + + TileEntityLoot loot = (TileEntityLoot) world.getTileEntity(x, y, z); + + if(loot != null && loot.items.isEmpty()) { + + int limit = world.rand.nextInt(3) + 3; + for(int i = 0; i < limit; i++) { + + ItemStack stack = new ItemStack(ModItems.ammo_12gauge, 4); + + switch(world.rand.nextInt(11)) { + case 0: stack = new ItemStack(ModItems.steel_plate); break; + case 1: stack = new ItemStack(ModItems.gun_lever_action); break; + case 2: stack = new ItemStack(ModItems.grenade_if_generic); break; + case 3: + case 4: stack = new ItemStack(ModItems.bottle_nuka, 1 + world.rand.nextInt(2)); break; + case 5: + case 6: stack = new ItemStack(ModItems.ingot_steel, 3 + world.rand.nextInt(10)); break; + case 7: stack = new ItemStack(ModItems.steel_pickaxe); break; + case 8: stack = new ItemStack(ModItems.gas_mask_m65); break; + case 9: stack = new ItemStack(ModItems.ammo_20gauge, 8); break; + } + + addItemWithDeviation(loot, world.rand, stack, world.rand.nextDouble() - 0.5, i * 0.03125, world.rand.nextDouble() - 0.5); + } + } + } } diff --git a/src/main/java/com/hbm/world/feature/GlyphidHive.java b/src/main/java/com/hbm/world/feature/GlyphidHive.java index 5c60e3ff2..f615b6519 100644 --- a/src/main/java/com/hbm/world/feature/GlyphidHive.java +++ b/src/main/java/com/hbm/world/feature/GlyphidHive.java @@ -3,126 +3,117 @@ package com.hbm.world.feature; import java.util.Random; import com.hbm.blocks.ModBlocks; +import com.hbm.util.LootGenerator; import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntitySkull; import net.minecraft.world.World; public class GlyphidHive { - public static final int[][][] schematic = new int[][][] { + public static final int[][][] schematicSmall = new int[][][] { { {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,1,1,0,0,0,0}, {0,0,0,0,1,1,1,0,0,0,0}, - {0,0,0,1,1,1,1,1,0,0,0}, - {0,0,0,1,1,1,1,1,0,0,0}, - {0,0,0,1,1,1,1,1,0,0,0}, {0,0,0,0,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, - }, - { - {0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,1,1,1,0,0,0,0}, - {0,0,0,1,1,9,1,1,0,0,0}, - {0,0,1,1,9,9,9,1,1,0,0}, - {0,0,1,9,9,9,9,9,1,0,0}, - {0,0,1,1,9,9,9,1,1,0,0}, - {0,0,0,1,1,9,1,1,0,0,0}, - {0,0,0,0,1,1,1,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, }, { {0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,4,4,4,0,0,0,0}, - {0,0,0,1,1,9,1,1,0,0,0}, - {0,0,1,1,9,9,9,1,1,0,0}, - {0,3,1,9,9,9,9,9,1,5,0}, - {0,3,9,9,9,9,9,9,9,5,0}, - {0,3,1,9,9,9,9,9,1,5,0}, - {0,0,1,1,9,9,9,1,1,0,0}, - {0,0,0,1,1,9,1,1,0,0,0}, - {0,0,0,0,2,2,2,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, - }, - { - {0,0,0,0,0,4,0,0,0,0,0}, - {0,0,0,0,4,4,4,0,0,0,0}, - {0,0,0,1,4,9,4,1,0,0,0}, - {0,0,1,1,9,9,9,1,1,0,0}, - {0,3,3,9,9,9,9,9,5,5,0}, - {3,3,9,9,9,9,9,9,9,5,5}, - {0,3,3,9,9,9,9,9,5,5,0}, - {0,0,1,1,9,9,9,1,1,0,0}, - {0,0,0,1,2,9,2,1,0,0,0}, - {0,0,0,0,2,2,2,0,0,0,0}, - {0,0,0,0,0,2,0,0,0,0,0}, - }, - { - {0,0,0,0,4,4,4,0,0,0,0}, - {0,0,0,1,4,4,4,1,0,0,0}, - {0,0,1,1,4,9,4,1,1,0,0}, - {0,1,1,1,9,9,0,1,1,1,0}, - {3,3,3,9,9,9,9,9,5,5,5}, - {3,3,9,9,9,9,9,9,9,5,5}, - {3,3,3,9,9,9,9,9,5,5,5}, - {0,1,1,1,9,9,9,1,1,1,0}, - {0,0,1,1,2,9,2,1,1,0,0}, - {0,0,0,1,2,2,2,1,0,0,0}, - {0,0,0,0,2,2,2,0,0,0,0}, - }, - { {0,0,0,0,1,1,1,0,0,0,0}, {0,0,0,1,1,1,1,1,0,0,0}, {0,0,1,1,1,1,1,1,1,0,0}, - {0,1,1,1,1,1,1,1,1,1,0}, - {1,1,1,1,1,1,1,1,1,1,1}, - {1,1,1,1,1,1,1,1,1,1,1}, - {1,1,1,1,1,1,1,1,1,1,1}, - {0,1,1,1,1,1,1,1,1,1,0}, + {0,0,1,1,1,1,1,1,1,0,0}, {0,0,1,1,1,1,1,1,1,0,0}, {0,0,0,1,1,1,1,1,0,0,0}, {0,0,0,0,1,1,1,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0}, }, { {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,1,1,1,0,0,0,0}, - {0,0,0,1,1,1,1,1,0,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, + {0,1,1,1,3,3,3,1,1,1,0}, + {0,1,1,1,3,3,3,1,1,1,0}, + {0,1,1,1,3,3,3,1,1,1,0}, + {0,0,1,1,1,1,1,1,1,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, + {0,0,0,0,1,1,1,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0}, + }, + { + {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,1,1,0,0,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, + {0,0,1,1,2,2,2,1,1,0,0}, + {0,1,1,2,2,2,2,2,1,1,0}, + {0,1,1,2,2,2,2,2,1,1,0}, + {0,1,1,2,2,2,2,2,1,1,0}, + {0,0,1,1,2,2,2,1,1,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, + {0,0,0,0,1,1,1,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0}, + }, + { + {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,1,1,0,0,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, {0,0,1,1,1,1,1,1,1,0,0}, {0,1,1,1,1,1,1,1,1,1,0}, {0,1,1,1,1,1,1,1,1,1,0}, {0,1,1,1,1,1,1,1,1,1,0}, {0,0,1,1,1,1,1,1,1,0,0}, - {0,0,0,1,1,1,1,1,0,0,0}, + {0,0,1,1,1,1,1,1,1,0,0}, {0,0,0,0,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, } }; - - public static void generate(World world, int x, int y, int z, Random rand) { - - int orientation = rand.nextInt(4) + 2; + public static void generateSmall(World world, int x, int y, int z, Random rand, boolean infected, boolean loot) { + int overrideMeta = infected ? 1 : 0; for(int i = 0; i < 11; i++) { - for(int j = 0; j < 7; j++) { + for(int j = 0; j < 5; j++) { for(int k = 0; k < 11; k++) { - int block = schematic[6 - j][i][k]; + int block = schematicSmall[4 - j][i][k]; + int iX = x + i - 5; + int iY = y + j - 2; + int iZ = z + k - 5; - if(block == 1 || (block != orientation && block > 1 && block < 6)) { - world.setBlock(x + i - 5, y + j - 2, z + k - 5, ModBlocks.glyphid_base); - } - if(block == 9) { - world.setBlock(x + i - 5, y + j - 2, z + k - 5, Blocks.air); + switch(block) { + case 1: world.setBlock(iX, iY, iZ, ModBlocks.glyphid_base, overrideMeta, 2); break; + case 2: world.setBlock(iX, iY, iZ, rand.nextInt(3) == 0 ? ModBlocks.glyphid_spawner : ModBlocks.glyphid_base, overrideMeta, 2); break; + case 3: + int r = rand.nextInt(3); + if(r == 0) { + world.setBlock(iX, iY, iZ, Blocks.skull, 1, 3); + TileEntitySkull skull = (TileEntitySkull) world.getTileEntity(iX, iY, iZ); + if(skull != null) skull.func_145903_a(rand.nextInt(16)); + } else if(r == 1) { + world.setBlock(iX, iY, z + k - 5, ModBlocks.deco_loot, 0, 2); + LootGenerator.lootBones(world, iX, iY, iZ); + } else if(r == 2) { + if(loot) { + world.setBlock(iX, iY, iZ, ModBlocks.deco_loot, 0, 2); + LootGenerator.lootGlyphidHive(world, iX, iY, iZ); + } else { + world.setBlock(iX, iY, iZ, ModBlocks.glyphid_base, overrideMeta, 2); + } + } + break; } } } } - - world.setBlock(x, y - 1, z, ModBlocks.glyphid_spawner); } } diff --git a/src/main/resources/assets/hbm/lang/de_DE.lang b/src/main/resources/assets/hbm/lang/de_DE.lang index 34cd14145..24112073e 100644 --- a/src/main/resources/assets/hbm/lang/de_DE.lang +++ b/src/main/resources/assets/hbm/lang/de_DE.lang @@ -508,7 +508,7 @@ death.attack.tauBlast=%1$s lud die XVL1456 zu lange auf und wurde in Stücke ger death.attack.teleporter=%1$s wurde ins Nichts teleportiert. desc.item.rtgHeat=Hitzelevel: %s -desc.gui.rtgBFurnace.desc=Bönitigt mindestens 15 Hitze um zu starten$Je mehr Hitze, desto schneller der Vorgang$Hitze über dem maximalen Level hat keinen Effekt$Gold-198 kann zu Quecksilber zerfallen +desc.gui.rtgBFurnace.desc=Benötigt mindestens 15 Hitze um zu starten$Je mehr Hitze, desto schneller der Vorgang$Hitze über dem maximalen Level hat keinen Effekt$Gold-198 kann zu Quecksilber zerfallen desc.gui.rtgBFurnace.heat=§eHitzelevel: %s desc.gui.rtgBFurnace.pellets=Akzeptierte Pellets: desc.gui.rtgBFurnace.pellet=%s (%s Hitze) @@ -527,6 +527,7 @@ entity.entity_glyphid_blaster.name=Glyphid-Blaster entity.entity_glyphid_bombardier.name=Glyphid-Bombardierer entity.entity_glyphid_brawler.name=Glyphid-Schläger entity.entity_glyphid_brenda.name=Brenda +entity.entity_glyphid_digger.name=Glyphid-Gräber entity.entity_glyphid_nuclear.name=Der dicke Johnson entity.entity_glyphid_scout.name=Glyphid-Späher entity.entity_ntm_fbi.name=FBI Agent @@ -540,6 +541,7 @@ entity.entity_mob_nuclear_creeper.name=Nuklearer Creeper entity.entity_mob_phosgene_creeper.name=Phosgen-Creeper entity.entity_mob_tainted_creeper.name=Verseuchter Creeper entity.entity_mob_volatile_creeper.name=Instabiler Creeper +entity.entity_parasite_maggot.name=Parasitische Made entity.entity_pigeon.name=Taube entity.entity_plastic_bag.name=Plastiktüte entity.entity_taint_crab.name=Verseuchte Krabbe diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index db2b9677f..088d36302 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -577,6 +577,7 @@ chem.KEVLAR=Kevlar Compound Production chem.LPG=Petroleum Gas Liquefaction chem.LUBRICANT=Lubricant Mixing chem.METH=Methamphetamine Synthesis +chem.MEAT_PROCESSING=Glyphid Meat Mineral Extraction chem.NITAN=NITAN Super Fuel Mixing chem.NITRIC_ACID=Nitric Acid Production chem.OIL_SAND=Tar Sand Extraction @@ -1035,6 +1036,7 @@ entity.entity_glyphid_blaster.name=Glyphid Blaster entity.entity_glyphid_bombardier.name=Glyphid Bombardier entity.entity_glyphid_brawler.name=Glyphid Brawler entity.entity_glyphid_brenda.name=Brenda +entity.entity_glyphid_digger.name=Glyphid Digger entity.entity_glyphid_nuclear.name=Big Man Johnson entity.entity_glyphid_scout.name=Glyphid Scout entity.entity_ntm_fbi.name=FBI Agent @@ -1048,6 +1050,7 @@ entity.entity_mob_nuclear_creeper.name=Nuclear Creeper entity.entity_mob_phosgene_creeper.name=Phosgene Creeper entity.entity_mob_tainted_creeper.name=Tainted Creeper entity.entity_mob_volatile_creeper.name=Volatile Creeper +entity.entity_parasite_maggot.name=Parasitic Maggot entity.entity_pigeon.name=Pigeon entity.entity_plastic_bag.name=Plastic Bag entity.entity_taint_crab.name=Taint Crab @@ -1353,6 +1356,8 @@ hbmfluid.pain=Pandemonium(III)tantalite Solution hbmfluid.petroil=Petroil hbmfluid.petroil_leaded=Leaded Petroil hbmfluid.petroleum=Petroleum Gas +hbmfluid.pheromone=Booster Pheromone +hbmfluid.pheromone_m=Modified Booster Pheromone hbmfluid.phosgene=Phosgene hbmfluid.plasma_bf=Balefire Plasma hbmfluid.plasma_dh3=Deuterium-Helium-3 Plasma @@ -1400,6 +1405,9 @@ hbmfluid.woodoil=Wood Oil hbmfluid.xenon=Xenon Gas hbmfluid.xpjuice=Experience Juice hbmfluid.xylene=BTX + + + hbmpseudofluid.none=Empty hbmpseudofluid.heuf6=Highly Enriched UF6 hbmpseudofluid.meuf6=Medium Enriched UF6 @@ -2384,6 +2392,8 @@ item.dieselsuit_helmet.name=Diesel-Powered Head-Mounted Environmental Sensor item.dieselsuit_legs.name=Diesel-Powered Leg Servos item.dieselsuit_plate.name=Diesel-Powered Cybernetics item.digamma_diagnostic.name=Digamma Diagnostic +item.disperser_canister.name= Disperser Canister: +item.disperser_canister_empty.name= Disperser Canister item.dns_boots.name=DNT Nano Suit Boots item.dns_legs.name=DNT Nano Suit Leggings item.dns_helmet.name=DNT Nano Suit Helmet @@ -2610,6 +2620,8 @@ item.grenade_smart.name=Smart Grenade item.grenade_strong.name=Enhanced Grenade item.grenade_tau.name=Tau Grenade item.grenade_zomg.name=Negative Energy Pair Annihilation Grenade +item.glyphid_gland.name= Gland +item.glyphid_gland_empty.name= Glyphid's Fluid Gland item.gun_ar15.name=Josh item.gun_avenger.name=CZ57 Avenger Minigun item.gun_b92.name=§9B92 Energy Pistol§r diff --git a/src/main/resources/assets/hbm/textures/blocks/glyphid_base_2.png b/src/main/resources/assets/hbm/textures/blocks/glyphid_base_2.png deleted file mode 100644 index 541a53c5f..000000000 Binary files a/src/main/resources/assets/hbm/textures/blocks/glyphid_base_2.png and /dev/null differ diff --git a/src/main/resources/assets/hbm/textures/blocks/glyphid_base_infested.png b/src/main/resources/assets/hbm/textures/blocks/glyphid_base_infested.png new file mode 100644 index 000000000..50c058246 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/glyphid_base_infested.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/glyphid_base_infested_alt.png b/src/main/resources/assets/hbm/textures/blocks/glyphid_base_infested_alt.png new file mode 100644 index 000000000..7cfa0d2da Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/glyphid_base_infested_alt.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/glyphid_eggs_base_infested.png b/src/main/resources/assets/hbm/textures/blocks/glyphid_eggs_base_infested.png new file mode 100644 index 000000000..c4308d58a Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/glyphid_eggs_base_infested.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/glyphid_eggs_infested.png b/src/main/resources/assets/hbm/textures/blocks/glyphid_eggs_infested.png new file mode 100644 index 000000000..93786bc31 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/glyphid_eggs_infested.png differ diff --git a/src/main/resources/assets/hbm/textures/entity/glyphid_digger.png b/src/main/resources/assets/hbm/textures/entity/glyphid_digger.png new file mode 100644 index 000000000..524358e73 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/entity/glyphid_digger.png differ diff --git a/src/main/resources/assets/hbm/textures/entity/glyphid_infestation.png b/src/main/resources/assets/hbm/textures/entity/glyphid_infestation.png new file mode 100644 index 000000000..4362c8e90 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/entity/glyphid_infestation.png differ diff --git a/src/main/resources/assets/hbm/textures/entity/parasite_maggot.png b/src/main/resources/assets/hbm/textures/entity/parasite_maggot.png new file mode 100644 index 000000000..9bc94381b Binary files /dev/null and b/src/main/resources/assets/hbm/textures/entity/parasite_maggot.png differ diff --git a/src/main/resources/assets/hbm/textures/gui/fluids/pheromone.png b/src/main/resources/assets/hbm/textures/gui/fluids/pheromone.png new file mode 100644 index 000000000..8517917d8 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/gui/fluids/pheromone.png differ diff --git a/src/main/resources/assets/hbm/textures/gui/fluids/pheromone_m.png b/src/main/resources/assets/hbm/textures/gui/fluids/pheromone_m.png new file mode 100644 index 000000000..b82a63ab3 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/gui/fluids/pheromone_m.png differ diff --git a/src/main/resources/assets/hbm/textures/items/chem_icon_MEAT_PROCESSING.png b/src/main/resources/assets/hbm/textures/items/chem_icon_MEAT_PROCESSING.png new file mode 100644 index 000000000..44f694ed7 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/items/chem_icon_MEAT_PROCESSING.png differ diff --git a/src/main/resources/assets/hbm/textures/items/disperser_canister.png b/src/main/resources/assets/hbm/textures/items/disperser_canister.png new file mode 100644 index 000000000..4a5653488 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/items/disperser_canister.png differ diff --git a/src/main/resources/assets/hbm/textures/items/disperser_canister_overlay.png b/src/main/resources/assets/hbm/textures/items/disperser_canister_overlay.png new file mode 100644 index 000000000..1dcba8865 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/items/disperser_canister_overlay.png differ diff --git a/src/main/resources/assets/hbm/textures/items/glyphid_gland.png b/src/main/resources/assets/hbm/textures/items/glyphid_gland.png new file mode 100644 index 000000000..0b1a48e6f Binary files /dev/null and b/src/main/resources/assets/hbm/textures/items/glyphid_gland.png differ