diff --git a/src/main/java/com/hbm/config/MobConfig.java b/src/main/java/com/hbm/config/MobConfig.java new file mode 100644 index 000000000..45b796c48 --- /dev/null +++ b/src/main/java/com/hbm/config/MobConfig.java @@ -0,0 +1,38 @@ +package com.hbm.config; + +import net.minecraftforge.common.config.Configuration; + +public class MobConfig { + + public static boolean enableMaskman = true; + public static int maskmanDelay = 60 * 60 * 60; + public static int maskmanChance = 3; + public static int maskmanMinRad = 50; + public static boolean maskmanUnderground = true; + + public static boolean enableRaids = false; + public static int raidDelay = 30 * 60 * 60; + public static int raidChance = 3; + public static int raidAmount = 15; + public static int raidAttackDelay = 40; + public static int raidAttackReach = 2; + + public static void loadFromConfig(Configuration config) { + + final String CATEGORY = "12_mobs"; + + enableMaskman = CommonConfig.createConfigBool(config, CATEGORY, "12.00_enableMaskman", "Whether mask man should spawn", true); + maskmanDelay = CommonConfig.createConfigInt(config, CATEGORY, "12.01_maskmanDelay", "How many world ticks need to pass for a check to be performed", 60 * 60 * 60); + maskmanChance = CommonConfig.createConfigInt(config, CATEGORY, "12.02_maskmanChance", "1:x chance to spawn mask man, must be at least 1", 3); + maskmanMinRad = CommonConfig.createConfigInt(config, CATEGORY, "12.03_maskmanMinRad", "The amount of radiation needed for mask man to spawn", 50); + maskmanUnderground = CommonConfig.createConfigBool(config, CATEGORY, "12.04_maskmanUnderound", "Whether players need to be underground for mask man to spawn", true); + + enableMaskman = CommonConfig.createConfigBool(config, CATEGORY, "12.05_enableFBIRaids", "Whether there should be FBI raids", false); + raidDelay = CommonConfig.createConfigInt(config, CATEGORY, "12.06_raidDelay", "How many world ticks need to pass for a check to be performed", 30 * 60 * 60); + raidChance = CommonConfig.createConfigInt(config, CATEGORY, "12.07_raidChance", "1:x chance to spawn a raid, must be at least 1", 3); + raidAmount = CommonConfig.createConfigInt(config, CATEGORY, "12.08_raidAmount", "How many FBI agents are spawned each raid", 15); + raidAttackDelay = CommonConfig.createConfigInt(config, CATEGORY, "12.09_raidAttackDelay", "Time between individual attempts to break machines", 40); + raidAttackReach = CommonConfig.createConfigInt(config, CATEGORY, "12.10_raidAttackReach", "How far away machiens can be broken", 2); + + } +} diff --git a/src/main/java/com/hbm/entity/mob/EntityFBI.java b/src/main/java/com/hbm/entity/mob/EntityFBI.java index c1a2a1522..d7f92610e 100644 --- a/src/main/java/com/hbm/entity/mob/EntityFBI.java +++ b/src/main/java/com/hbm/entity/mob/EntityFBI.java @@ -1,19 +1,181 @@ package com.hbm.entity.mob; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.hbm.blocks.ModBlocks; +import com.hbm.config.MobConfig; +import com.hbm.entity.projectile.EntityBullet; import com.hbm.items.ModItems; -import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.IRangedAttackMob; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIArrowAttack; +import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIBreakDoor; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EntityDamageSourceIndirect; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -public class EntityFBI extends EntityZombie { +public class EntityFBI extends EntityMob implements IRangedAttackMob { - public EntityFBI(World p_i1745_1_) { - super(p_i1745_1_); + public EntityFBI(World world) { + super(world); + this.getNavigator().setBreakDoors(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIBreakDoor(this)); + this.tasks.addTask(2, new EntityAIArrowAttack(this, 1D, 20, 25, 15.0F)); + this.tasks.addTask(3, 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(0.6F, 1.8F); } + + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(0.5D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3D); + } + + public boolean attackEntityFrom(DamageSource source, float amount) { + + if(source instanceof EntityDamageSourceIndirect && ((EntityDamageSourceIndirect)source).getEntity() instanceof EntityFBI) { + return false; + } + + return super.attackEntityFrom(source, amount); + } + + protected void entityInit() { + super.entityInit(); + } protected void addRandomArmor() { super.addRandomArmor(); - this.setCurrentItemOrArmor(0, new ItemStack(ModItems.gun_revolver_nopip)); + + int equip = rand.nextInt(2); + + switch(equip) { + case 0: this.setCurrentItemOrArmor(0, new ItemStack(ModItems.gun_revolver_nopip)); break; + case 1: this.setCurrentItemOrArmor(0, new ItemStack(ModItems.gun_ks23)); break; + } + } + + protected boolean isAIEnabled() { + return true; + } + + //combat vest = full diamond set + public int getTotalArmorValue() { + return 20; + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase entity, float f) { + + if(this.getEquipmentInSlot(0) != null) { + if(this.getEquipmentInSlot(0).getItem() == ModItems.gun_revolver_nopip) { + EntityBullet bullet = new EntityBullet(worldObj, this, entity, 3F, 2); + bullet.damage = 10; + this.worldObj.spawnEntityInWorld(bullet); + this.playSound("hbm:weapon.revolverShootAlt", 1.0F, 1.0F); + } + + if(this.getEquipmentInSlot(0).getItem() == ModItems.gun_ks23) { + for(int i = 0; i < 7; i++) { + EntityBullet bullet = new EntityBullet(worldObj, this, entity, 3F, 5); + bullet.damage = 3; + this.worldObj.spawnEntityInWorld(bullet); + } + this.playSound("hbm:weapon.shotgunShoot", 1.0F, 1.0F); + } + } + } + + private static final Set canDestroy = new HashSet(); + + static { + canDestroy.add(Blocks.wooden_door); + canDestroy.add(Blocks.iron_door); + canDestroy.add(Blocks.trapdoor); + canDestroy.add(ModBlocks.machine_press); + canDestroy.add(ModBlocks.machine_epress); + canDestroy.add(ModBlocks.dummy_block_assembler); + canDestroy.add(ModBlocks.dummy_block_chemplant); + canDestroy.add(ModBlocks.dummy_block_centrifuge); + canDestroy.add(ModBlocks.dummy_block_gascent); + canDestroy.add(ModBlocks.machine_crystallizer); + canDestroy.add(ModBlocks.dummy_block_reactor_small); + canDestroy.add(ModBlocks.dummy_port_reactor_small); + canDestroy.add(ModBlocks.machine_turbine); + canDestroy.add(ModBlocks.machine_large_turbine); + canDestroy.add(ModBlocks.crate_iron); + canDestroy.add(ModBlocks.crate_steel); + canDestroy.add(ModBlocks.machine_diesel); + canDestroy.add(ModBlocks.machine_selenium); + canDestroy.add(ModBlocks.machine_rtg_grey); + canDestroy.add(ModBlocks.machine_minirtg); + canDestroy.add(ModBlocks.machine_powerrtg); + canDestroy.add(ModBlocks.machine_cyclotron); + canDestroy.add(Blocks.chest); + canDestroy.add(Blocks.trapped_chest); + } + + public IEntityLivingData onSpawnWithEgg(IEntityLivingData data) { + this.addRandomArmor(); + return super.onSpawnWithEgg(data); + } + + public void onLivingUpdate() { + super.onLivingUpdate(); + + if(worldObj.isRemote) + return; + + if(this.ticksExisted % MobConfig.raidAttackDelay == 0) { + Vec3 vec = Vec3.createVectorHelper(MobConfig.raidAttackReach, 0, 0); + vec.rotateAroundY((float)(Math.PI * 2) * rand.nextFloat()); + + Vec3 vec3 = Vec3.createVectorHelper(this.posX, this.posY + 0.5 + rand.nextFloat(), this.posZ); + Vec3 vec31 = Vec3.createVectorHelper(vec3.xCoord + vec.xCoord, vec3.yCoord + vec.yCoord, vec3.zCoord + vec.zCoord); + MovingObjectPosition mop = this.worldObj.func_147447_a(vec3, vec31, false, true, false); + + if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK) { + + if(canDestroy.contains(worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ))) + worldObj.func_147480_a(mop.blockX, mop.blockY, mop.blockZ, false); + } + } + + double range = 1.5; + + List items = worldObj.getEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX, posY, posZ).expand(range, range, range)); + + for(EntityItem item : items) + item.setFire(10); } } diff --git a/src/main/java/com/hbm/handler/BossSpawnHandler.java b/src/main/java/com/hbm/handler/BossSpawnHandler.java index eea81228e..a00f041e0 100644 --- a/src/main/java/com/hbm/handler/BossSpawnHandler.java +++ b/src/main/java/com/hbm/handler/BossSpawnHandler.java @@ -1,10 +1,15 @@ package com.hbm.handler; +import com.hbm.config.MobConfig; +import com.hbm.entity.mob.EntityFBI; import com.hbm.entity.mob.EntityMaskMan; import com.hbm.util.ContaminationUtil; import cpw.mods.fml.common.eventhandler.Event.Result; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.event.ForgeEventFactory; @@ -12,32 +17,62 @@ public class BossSpawnHandler { public static void rollTheDice(World world) { - int delay = 60 * 60 * 60; //every hour - - if(world.getTotalWorldTime() % delay == 0) { + if(MobConfig.enableMaskman) { - if(world.rand.nextInt(3) == 0 && !world.playerEntities.isEmpty() && world.provider.isSurfaceWorld()) { //33% chance only if there is a player online + if(world.getTotalWorldTime() % MobConfig.maskmanDelay == 0) { - EntityPlayer player = (EntityPlayer) world.playerEntities.get(world.rand.nextInt(world.playerEntities.size())); //choose a random player - - if(ContaminationUtil.getRads(player) >= 50 && world.getHeightValue((int)player.posX, (int)player.posZ) > player.posY + 3) { //if the player has more than 50 RAD and is underground + if(world.rand.nextInt(MobConfig.maskmanChance) == 0 && !world.playerEntities.isEmpty() && world.provider.isSurfaceWorld()) { //33% chance only if there is a player online - double spawnX = player.posX + world.rand.nextGaussian() * 20; - double spawnZ = player.posZ + world.rand.nextGaussian() * 20; - double spawnY = world.getHeightValue((int)player.posX, (int)player.posZ); + EntityPlayer player = (EntityPlayer) world.playerEntities.get(world.rand.nextInt(world.playerEntities.size())); //choose a random player - EntityMaskMan maskman = new EntityMaskMan(world); - maskman.setLocationAndAngles(spawnX, spawnY, spawnZ, world.rand.nextFloat() * 360.0F, 0.0F); - Result canSpawn = ForgeEventFactory.canEntitySpawn(maskman, world, (float)spawnX, (float)spawnY, (float)spawnZ); - - if (canSpawn == Result.ALLOW || canSpawn == Result.DEFAULT) { + if(ContaminationUtil.getRads(player) >= MobConfig.maskmanMinRad && (world.getHeightValue((int)player.posX, (int)player.posZ) > player.posY + 3 || !MobConfig.maskmanUnderground)) { //if the player has more than 50 RAD and is underground - world.spawnEntityInWorld(maskman); - ForgeEventFactory.doSpecialSpawn(maskman, world, (float)spawnX, (float)spawnY, (float)spawnZ); + double spawnX = player.posX + world.rand.nextGaussian() * 20; + double spawnZ = player.posZ + world.rand.nextGaussian() * 20; + double spawnY = world.getHeightValue((int)spawnX, (int)spawnZ); + + trySpawn(world, (float)spawnX, (float)spawnY, (float)spawnZ, new EntityMaskMan(world)); + } + } + } + } + + + + if(MobConfig.enableRaids) { + + if(world.getTotalWorldTime() % MobConfig.raidDelay == 0) { + + if(world.rand.nextInt(MobConfig.raidChance) == 0 && !world.playerEntities.isEmpty() && world.provider.isSurfaceWorld()) { + + EntityPlayer player = (EntityPlayer) world.playerEntities.get(world.rand.nextInt(world.playerEntities.size())); + + Vec3 vec = Vec3.createVectorHelper(32, 0, 0); + vec.rotateAroundY((float)(Math.PI * 2) * world.rand.nextFloat()); + + for(int i = 0; i < MobConfig.raidAmount; i++) { + + double spawnX = player.posX + vec.xCoord + world.rand.nextGaussian() * 5; + double spawnZ = player.posZ + vec.zCoord + world.rand.nextGaussian() * 5; + double spawnY = world.getHeightValue((int)spawnX, (int)spawnZ); + + trySpawn(world, (float)spawnX, (float)spawnY, (float)spawnZ, new EntityFBI(world)); } } } } } + + private static void trySpawn(World world, float x, float y, float z, EntityLiving e) { + + e.setLocationAndAngles(x, y, z, world.rand.nextFloat() * 360.0F, 0.0F); + Result canSpawn = ForgeEventFactory.canEntitySpawn(e, world, x, y, z); + + if (canSpawn == Result.ALLOW || canSpawn == Result.DEFAULT) { + + world.spawnEntityInWorld(e); + ForgeEventFactory.doSpecialSpawn(e, world, x, y, z); + } + } } diff --git a/src/main/java/com/hbm/items/ModItems.java b/src/main/java/com/hbm/items/ModItems.java index 1941baed7..61bf29fa3 100644 --- a/src/main/java/com/hbm/items/ModItems.java +++ b/src/main/java/com/hbm/items/ModItems.java @@ -3667,7 +3667,7 @@ public class ModItems { .addEffect(new PotionEffect(Potion.field_76443_y.id, 20, 0)) .addEffect(new PotionEffect(HbmPotion.radx.id, 20, 0)) .setBlastProtection(0.5F) - .setGravity(0.02D) + //.setGravity(0.02D) .setStep("hbm:step.metal") .setJump("hbm:step.iron_jump") .setFall("hbm:step.iron_land") diff --git a/src/main/java/com/hbm/lib/RefStrings.java b/src/main/java/com/hbm/lib/RefStrings.java index 65bd057e4..811672c03 100644 --- a/src/main/java/com/hbm/lib/RefStrings.java +++ b/src/main/java/com/hbm/lib/RefStrings.java @@ -3,7 +3,7 @@ package com.hbm.lib; public class RefStrings { public static final String MODID = "hbm"; public static final String NAME = "Hbm's Nuclear Tech Mod"; - public static final String VERSION = "1.0.27 BETA (MEMEPACK)"; + public static final String VERSION = "1.0.27 BETA (MEMEPACK 2)"; //HBM's Beta Naming Convention: //V T (X) //V -> next release version