aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gtPlusPlus/core/entity
diff options
context:
space:
mode:
authorRaven Szewczyk <git@eigenraven.me>2024-05-24 19:50:35 +0100
committerRaven Szewczyk <git@eigenraven.me>2024-05-24 19:50:35 +0100
commit6d1b2216464d4dad449ac6fcfec476832224a55e (patch)
tree526a0c15f7056313c80e6c0386e025e9b3f61781 /src/main/java/gtPlusPlus/core/entity
parentb5d35f40afa606ed1b07061dad82e0521a59c186 (diff)
downloadGT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.gz
GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.bz2
GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.zip
Merge addon sources
Diffstat (limited to 'src/main/java/gtPlusPlus/core/entity')
-rw-r--r--src/main/java/gtPlusPlus/core/entity/EntityPrimedMiningExplosive.java405
-rw-r--r--src/main/java/gtPlusPlus/core/entity/InternalEntityRegistry.java64
-rw-r--r--src/main/java/gtPlusPlus/core/entity/monster/EntitySickBlaze.java224
-rw-r--r--src/main/java/gtPlusPlus/core/entity/monster/EntityStaballoyConstruct.java652
-rw-r--r--src/main/java/gtPlusPlus/core/entity/projectile/EntityLightningAttack.java79
-rw-r--r--src/main/java/gtPlusPlus/core/entity/projectile/EntityToxinball.java334
-rw-r--r--src/main/java/gtPlusPlus/core/entity/projectile/EntityToxinballSmall.java65
7 files changed, 1823 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/core/entity/EntityPrimedMiningExplosive.java b/src/main/java/gtPlusPlus/core/entity/EntityPrimedMiningExplosive.java
new file mode 100644
index 0000000000..99a86c447a
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/entity/EntityPrimedMiningExplosive.java
@@ -0,0 +1,405 @@
+package gtPlusPlus.core.entity;
+
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.item.EntityTNTPrimed;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.world.World;
+
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.world.explosions.ExplosionHandler;
+
+public class EntityPrimedMiningExplosive extends EntityTNTPrimed {
+
+ /** How long the fuse is */
+ private EntityLivingBase tntPlacedBy;
+
+ public EntityPrimedMiningExplosive(final World world) {
+ super(world);
+ this.fuse = 160;
+ this.preventEntitySpawning = true;
+ this.setSize(0.98F, 0.98F);
+ this.yOffset = this.height / 2.0F;
+ }
+
+ public EntityPrimedMiningExplosive(final World world, final double x, final double y, final double z,
+ final EntityLivingBase placingEntity) {
+ this(world);
+ this.setPosition(x, y, z);
+ final float f = (float) (Math.random() * Math.PI * 2.0D);
+ this.motionX = -((float) Math.sin(f)) * 0.02F;
+ this.motionY = 0.20000000298023224D;
+ this.motionZ = -((float) Math.cos(f)) * 0.02F;
+ this.fuse = 160;
+ this.prevPosX = x;
+ this.prevPosY = y;
+ this.prevPosZ = z;
+ this.tntPlacedBy = placingEntity;
+ }
+
+ @Override
+ protected void entityInit() {}
+
+ /**
+ * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
+ * prevent them from trampling crops
+ */
+ @Override
+ protected boolean canTriggerWalking() {
+ return false;
+ }
+
+ /**
+ * Returns true if other Entities should be prevented from moving through this Entity.
+ */
+ @Override
+ public boolean canBeCollidedWith() {
+ return !this.isDead;
+ }
+
+ /**
+ * Called to update the entity's position/logic.
+ */
+ @Override
+ public void onUpdate() {
+ this.prevPosX = this.posX;
+ this.prevPosY = this.posY;
+ this.prevPosZ = this.posZ;
+ this.motionY -= 0.03999999910593033D;
+ this.moveEntity(this.motionX, this.motionY, this.motionZ);
+ this.motionX *= 0.9800000190734863D;
+ this.motionY *= 0.9800000190734863D;
+ this.motionZ *= 0.9800000190734863D;
+
+ if (this.onGround) {
+ this.motionX *= 0.699999988079071D;
+ this.motionZ *= 0.699999988079071D;
+ this.motionY *= -0.5D;
+ }
+
+ if (this.fuse-- <= 0) {
+ this.setDead();
+
+ if (!this.worldObj.isRemote) {
+ this.explode();
+ }
+ } else {
+
+ int t = MathUtils.randInt(0, 15);
+
+ if (t <= 2) {
+ int e = MathUtils.randInt(0, 3);
+ if (e <= 1) {
+ this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
+ this.worldObj.spawnParticle(
+ "largesmoke",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "cloud",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "flame",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ } else if (e == 2) {
+ this.worldObj.spawnParticle(
+ "explode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "largeexplode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "hugeexplosion",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ }
+ } else if (t <= 4) {
+ int e = MathUtils.randInt(0, 5);
+ if (e <= 1) {
+ this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
+ this.worldObj.spawnParticle(
+ "largesmoke",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "cloud",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "flame",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ } else if (e == 2) {
+ this.worldObj.spawnParticle(
+ "explode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "largeexplode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "hugeexplosion",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ }
+ } else if (t <= 6) {
+ int e = MathUtils.randInt(0, 4);
+ if (e <= 1) {
+ this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
+ this.worldObj.spawnParticle(
+ "largesmoke",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "cloud",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "flame",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ } else if (e == 2) {
+ this.worldObj.spawnParticle(
+ "explode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "largeexplode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "hugeexplosion",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ }
+ } else if (t <= 8) {
+ int e = MathUtils.randInt(0, 1);
+ if (e <= 1) {
+ this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
+ this.worldObj.spawnParticle(
+ "largesmoke",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "cloud",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "flame",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ } else if (e == 2) {
+ this.worldObj.spawnParticle(
+ "explode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "largeexplode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "hugeexplosion",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ }
+ } else if (t <= 10) {
+ int e = MathUtils.randInt(0, 6);
+ if (e <= 1) {
+ this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
+ this.worldObj.spawnParticle(
+ "largesmoke",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "cloud",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "flame",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ } else if (e >= 2) {
+ this.worldObj.spawnParticle(
+ "explode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "largeexplode",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ this.worldObj.spawnParticle(
+ "hugeexplosion",
+ this.posX + MathUtils.randDouble(0, 1),
+ this.posY + MathUtils.randDouble(0, 1),
+ this.posZ + MathUtils.randDouble(0, 1),
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ }
+ }
+ }
+ }
+
+ private void explode() {
+ final float f = 100.0F;
+
+ ExplosionHandler explode = new ExplosionHandler();
+ explode.createExplosion(this.worldObj, this, this.posX, this.posY, this.posZ, f, false, true);
+
+ /*
+ * this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, f, true);
+ * this.worldObj.createExplosion(this, this.posX+MathUtils.randDouble(-10, 10), this.posY,
+ * this.posZ+MathUtils.randDouble(-10, 10), f+MathUtils.randFloat(-5F, 5F), true);
+ * this.worldObj.createExplosion(this, this.posX+MathUtils.randDouble(-10, 10), this.posY,
+ * this.posZ+MathUtils.randDouble(-10, 10), f+MathUtils.randFloat(-5F, 5F), true);
+ * this.worldObj.createExplosion(this, this.posX+MathUtils.randDouble(-10, 10), this.posY,
+ * this.posZ+MathUtils.randDouble(-10, 10), f+MathUtils.randFloat(-5F, 5F), true);
+ * this.worldObj.createExplosion(this, this.posX+MathUtils.randDouble(-10, 10), this.posY,
+ * this.posZ+MathUtils.randDouble(-10, 10), f+MathUtils.randFloat(-5F, 5F), true);
+ */
+ }
+
+ /**
+ * (abstract) Protected helper method to write subclass entity data to NBT.
+ */
+ @Override
+ protected void writeEntityToNBT(final NBTTagCompound tag) {
+ tag.setByte("Fuse", (byte) this.fuse);
+ }
+
+ /**
+ * (abstract) Protected helper method to read subclass entity data from NBT.
+ */
+ @Override
+ protected void readEntityFromNBT(final NBTTagCompound tag) {
+ this.fuse = tag.getByte("Fuse");
+ }
+
+ /**
+ * returns null or the entityliving it was placed or ignited by
+ */
+ @Override
+ public EntityLivingBase getTntPlacedBy() {
+ return this.tntPlacedBy;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/core/entity/InternalEntityRegistry.java b/src/main/java/gtPlusPlus/core/entity/InternalEntityRegistry.java
new file mode 100644
index 0000000000..a971541bc2
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/entity/InternalEntityRegistry.java
@@ -0,0 +1,64 @@
+package gtPlusPlus.core.entity;
+
+import cpw.mods.fml.common.registry.EntityRegistry;
+import gtPlusPlus.GTplusplus;
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.entity.monster.EntitySickBlaze;
+import gtPlusPlus.core.entity.monster.EntityStaballoyConstruct;
+import gtPlusPlus.core.entity.projectile.EntityLightningAttack;
+import gtPlusPlus.core.entity.projectile.EntityToxinballSmall;
+import gtPlusPlus.core.item.general.spawn.ItemCustomSpawnEgg;
+import gtPlusPlus.core.util.Utils;
+
+public class InternalEntityRegistry {
+
+ static int mEntityID = 0;
+
+ public static void registerEntities() {
+ Logger.INFO("Registering GT++ Entities.");
+
+ EntityRegistry.registerModEntity(
+ EntityPrimedMiningExplosive.class,
+ "MiningCharge",
+ mEntityID++,
+ GTplusplus.instance,
+ 64,
+ 20,
+ true);
+
+ EntityRegistry
+ .registerModEntity(EntityToxinballSmall.class, "toxinBall", mEntityID++, GTplusplus.instance, 64, 20, true);
+
+ EntityRegistry.registerModEntity(
+ EntityStaballoyConstruct.class,
+ "constructStaballoy",
+ mEntityID++,
+ GTplusplus.instance,
+ 64,
+ 20,
+ true);
+ ItemCustomSpawnEgg.registerEntityForSpawnEgg(
+ 0,
+ "constructStaballoy",
+ Utils.rgbtoHexValue(20, 200, 20),
+ Utils.rgbtoHexValue(20, 20, 20));
+
+ EntityRegistry
+ .registerModEntity(EntitySickBlaze.class, "sickBlaze", mEntityID++, GTplusplus.instance, 64, 20, true);
+ ItemCustomSpawnEgg.registerEntityForSpawnEgg(
+ 1,
+ "sickBlaze",
+ Utils.rgbtoHexValue(40, 180, 40),
+ Utils.rgbtoHexValue(75, 75, 75));
+
+ EntityRegistry.registerModEntity(
+ EntityLightningAttack.class,
+ "EntityLightningAttack",
+ mEntityID++,
+ GTplusplus.instance,
+ 64,
+ 20,
+ true);
+
+ }
+}
diff --git a/src/main/java/gtPlusPlus/core/entity/monster/EntitySickBlaze.java b/src/main/java/gtPlusPlus/core/entity/monster/EntitySickBlaze.java
new file mode 100644
index 0000000000..38940d3ad6
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/entity/monster/EntitySickBlaze.java
@@ -0,0 +1,224 @@
+package gtPlusPlus.core.entity.monster;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.SharedMonsterAttributes;
+import net.minecraft.entity.monster.EntityMob;
+import net.minecraft.init.Items;
+import net.minecraft.item.Item;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gtPlusPlus.core.entity.projectile.EntityToxinballSmall;
+
+public class EntitySickBlaze extends EntityMob {
+
+ /** Random offset used in floating behaviour */
+ private float heightOffset = 0.5F;
+ /** ticks until heightOffset is randomized */
+ private int heightOffsetUpdateTime;
+
+ private int field_70846_g;
+ private final int mDataWatcherID = 30;
+
+ public EntitySickBlaze(World p_i1731_1_) {
+ super(p_i1731_1_);
+ this.isImmuneToFire = true;
+ this.experienceValue = 10;
+ }
+
+ @Override
+ protected void applyEntityAttributes() {
+ super.applyEntityAttributes();
+ this.getEntityAttribute(SharedMonsterAttributes.maxHealth)
+ .setBaseValue(20.0D);
+ this.getEntityAttribute(SharedMonsterAttributes.movementSpeed)
+ .setBaseValue(1.5D);
+ this.getEntityAttribute(SharedMonsterAttributes.attackDamage)
+ .setBaseValue(6.0D);
+ }
+
+ @Override
+ protected void entityInit() {
+ super.entityInit();
+ this.dataWatcher.addObject(mDataWatcherID, 0);
+ }
+
+ /**
+ * Returns the sound this mob makes while it's alive.
+ */
+ @Override
+ protected String getLivingSound() {
+ return "mob.blaze.breathe";
+ }
+
+ /**
+ * Returns the sound this mob makes when it is hurt.
+ */
+ @Override
+ protected String getHurtSound() {
+ return "mob.blaze.hit";
+ }
+
+ /**
+ * Returns the sound this mob makes on death.
+ */
+ @Override
+ protected String getDeathSound() {
+ return "mob.blaze.death";
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public int getBrightnessForRender(float p_70070_1_) {
+ return 15728880;
+ }
+
+ /**
+ * Gets how bright this entity is.
+ */
+ @Override
+ public float getBrightness(float p_70013_1_) {
+ return p_70013_1_;
+ }
+
+ /**
+ * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
+ * use this to react to sunlight and start to burn.
+ */
+ @Override
+ public void onLivingUpdate() {
+ if (!this.worldObj.isRemote) {
+ if (this.isWet()) {
+ this.attackEntityFrom(DamageSource.drown, 1.0F);
+ }
+
+ --this.heightOffsetUpdateTime;
+
+ if (this.heightOffsetUpdateTime <= 0) {
+ this.heightOffsetUpdateTime = 100;
+ this.heightOffset = 0.5F + (float) this.rand.nextGaussian() * 3.0F;
+ }
+
+ if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + this.getEntityToAttack()
+ .getEyeHeight() > this.posY + this.getEyeHeight() + this.heightOffset) {
+ this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D;
+ }
+ }
+
+ if (!this.onGround && this.motionY < 0.0D) {
+ this.motionY *= 0.6D;
+ }
+
+ for (int i = 0; i < 2; ++i) {
+ this.worldObj.spawnParticle(
+ "crit",
+ this.posX + (this.rand.nextDouble() - 0.5D) * this.width,
+ this.posY + this.rand.nextDouble() * this.height,
+ this.posZ + (this.rand.nextDouble() - 0.5D) * this.width,
+ 0.0D,
+ 0.0D,
+ 0.0D);
+ }
+
+ super.onLivingUpdate();
+ }
+
+ /**
+ * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack.
+ */
+ @Override
+ protected void attackEntity(Entity entity, float p_70785_2_) {
+ if (this.attackTime <= 0 && p_70785_2_ < 2.0F
+ && entity.boundingBox.maxY > this.boundingBox.minY
+ && entity.boundingBox.minY < this.boundingBox.maxY) {
+ this.attackTime = 20;
+ this.attackEntityAsMob(entity);
+ } else if (p_70785_2_ < 30.0F) {
+ double d0 = entity.posX - this.posX;
+ double d1 = entity.boundingBox.minY + entity.height / 2.0F - (this.posY + this.height / 2.0F);
+ double d2 = entity.posZ - this.posZ;
+
+ if (this.attackTime == 0) {
+ ++this.field_70846_g;
+
+ if (this.field_70846_g == 1) {
+ this.attackTime = 60;
+ } else if (this.field_70846_g <= 4) {
+ this.attackTime = 6;
+ } else {
+ this.attackTime = 100;
+ this.field_70846_g = 0;
+ }
+
+ if (this.field_70846_g > 1) {
+ float f1 = MathHelper.sqrt_float(p_70785_2_) * 0.5F;
+ this.worldObj.playAuxSFXAtEntity(null, 1009, (int) this.posX, (int) this.posY, (int) this.posZ, 0);
+
+ for (int i = 0; i < 1; ++i) {
+ EntityToxinballSmall entitysmalltoxinball = new EntityToxinballSmall(
+ this.worldObj,
+ this,
+ d0 + this.rand.nextGaussian() * f1,
+ d1,
+ d2 + this.rand.nextGaussian() * f1);
+ entitysmalltoxinball.posY = this.posY + this.height / 2.0F + 0.5D;
+ this.worldObj.spawnEntityInWorld(entitysmalltoxinball);
+ }
+ }
+ }
+
+ this.rotationYaw = (float) (Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
+ this.hasAttacked = true;
+ }
+ }
+
+ /**
+ * Called when the mob is falling. Calculates and applies fall damage.
+ */
+ @Override
+ protected void fall(float p_70069_1_) {}
+
+ @Override
+ protected Item getDropItem() {
+ return Items.slime_ball;
+ }
+
+ /**
+ * Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
+ */
+ @Override
+ public boolean isBurning() {
+ return false;
+ }
+
+ /**
+ * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
+ * par2 - Level of Looting used to kill this mob.
+ */
+ @Override
+ protected void dropFewItems(boolean p_70628_1_, int p_70628_2_) {
+ if (p_70628_1_) {
+ int j = this.rand.nextInt(2 + p_70628_2_);
+
+ for (int k = 0; k < j; ++k) {
+ this.dropItem(getDropItem(), 1);
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure the light is not too bright where the mob is spawning
+ */
+ @Override
+ protected boolean isValidLightLevel() {
+ return true;
+ }
+
+ @Override
+ public int getMaxSpawnedInChunk() {
+ return 8;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/core/entity/monster/EntityStaballoyConstruct.java b/src/main/java/gtPlusPlus/core/entity/monster/EntityStaballoyConstruct.java
new file mode 100644
index 0000000000..c58f5ba9df
--- /dev/null
+++ b/src/main/java/gtPlusPlus/core/entity/monster/EntityStaballoyConstruct.java
@@ -0,0 +1,652 @@
+package gtPlusPlus.core.entity.monster;
+
+import java.lang.reflect.Field;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.SharedMonsterAttributes;
+import net.minecraft.entity.ai.EntityAIAttackOnCollide;
+import net.minecraft.entity.ai.EntityAIHurtByTarget;
+import net.minecraft.entity.ai.EntityAILookIdle;
+import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
+import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
+import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
+import net.minecraft.entity.ai.EntityAIWander;
+import net.minecraft.entity.ai.EntityAIWatchClosest;
+import net.minecraft.entity.effect.EntityLightningBolt;
+import net.minecraft.entity.monster.EntityIronGolem;
+import net.minecraft.entity.monster.IMob;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.MathHelper;
+import net.minecraft.village.Village;
+import net.minecraft.world.World;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gtPlusPlus.core.util.math.MathUtils;
+import gtPlusPlus.core.util.minecraft.ItemUtils;
+import gtPlusPlus.core.util.reflect.ReflectionUtils;
+import gtPlusPlus.core.world.explosions.ExplosionHandler;
+
+public class EntityStaballoyConstruct extends EntityIronGolem {
+
+ /*
+ * Determines whether or not the entity is in a fluid at all.
+ */
+ private boolean inFluid = false;
+ private boolean mReflectFirstUpdate = true;
+ private boolean isReadyToExplode = false;
+ private int fuse = 60;
+ private int attackTimer;
+
+ public EntityStaballoyConstruct(World world) {
+ super(world);
+ this.experienceValue = 250;
+ this.setSize(1.4F, 2.9F);
+ this.getNavigator()
+ .setAvoidsWater(true);
+ this.getNavigator()
+ .setBreakDoors(true);
+ this.getNavigator()
+ .setCanSwim(false);
+ this.getNavigator()
+ .setAvoidSun(false);
+ this.tasks.addTask(1, new EntityAIAttackOnCollide(this, 1.0D, true));
+ this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
+ // this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
+ this.tasks.addTask(3, new EntityAIMoveTowardsRestriction(this, 1.0D));
+ this.tasks.addTask(4, new EntityAIWander(this, 0.6D));
+ this.tasks.addTask(5, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
+ this.tasks.addTask(6, new EntityAILookIdle(this));
+ this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
+ this.targetTasks.addTask(
+ 2,
+ new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector));
+ }
+
+ /**
+ * (abstract) Protected helper method to write subclass entity data to NBT.
+ */
+ @Override
+ public void writeEntityToNBT(NBTTagCompound p_70014_1_) {
+ super.writeEntityToNBT(p_70014_1_);
+ p_70014_1_.setBoolean("inFluid", this.inFluid);
+ p_70014_1_.setBoolean("isReadyToExplode", this.isReadyToExplode);
+ p_70014_1_.setInteger("fuse", this.fuse);
+ }
+
+ /**
+ * (abstract) Protected helper method to read subclass entity data from NBT.
+ */
+ @Override
+ public void readEntityFromNBT(NBTTagCompound p_70037_1_) {
+ super.readEntityFromNBT(p_70037_1_);
+ this.inFluid = p_70037_1_.getBoolean("inFluid");
+ this.isReadyToExplode = p_70037_1_.getBoolean("isReadyToExplode");
+ this.fuse = p_70037_1_.getInteger("fuse");
+ }
+
+ @Override
+ protected void entityInit() {
+ super.entityInit();
+ this.dataWatcher.addObject(17, Byte.valueOf((byte) 0));
+ }
+
+ /**
+ * Returns true if the newer Entity AI code should be run
+ */
+ @Override
+ public boolean isAIEnabled() {
+ return true;
+ }
+
+ /**
+ * main AI tick function, replaces updateEntityActionState
+ */
+ @Override
+ protected void updateAITick() {
+ super.updateAITick();
+ }
+
+ @Override
+ protected void applyEntityAttributes() {
+ super.applyEntityAttributes();
+ this.getEntityAttribute(SharedMonsterAttributes.maxHealth)
+ .setBaseValue(500.0D);
+ this.getEntityAttribute(SharedMonsterAttributes.movementSpeed)
+ .setBaseValue(0.5D);
+ }
+
+ /**
+ * Decrements the entity's air supply when underwater
+ */
+ @Override
+ protected int decreaseAirSupply(int p_70682_1_) {
+ return 0;
+ }
+
+ @Override
+ protected void collideWithEntity(Entity p_82167_1_) {
+ if (p_82167_1_ instanceof IMob && this.getRNG()
+ .nextInt(20) == 0) {
+ this.setAttackTarget((EntityLivingBase) p_82167_1_);
+ }
+
+ super.collideWithEntity(p_82167_1_);
+ }
+
+ /**
+ * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
+ * use this to react to sunlight and start to burn.
+ */
+ @Override
+ public void onLivingUpdate() {
+ super.onLivingUpdate();
+
+ if (this.attackTimer > 0) {
+ --this.attackTimer;
+ }
+
+ if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D
+ && this.rand.nextInt(5) == 0) {
+ int i = MathHelper.floor_double(this.posX);
+ int j = MathHelper.floor_double(this.posY - 0.20000000298023224D - this.yOffset);
+ int k = MathHelper.floor_double(this.posZ);
+ Block block = this.worldObj.getBlock(i, j, k);
+
+ if (block.getMaterial() != Material.air) {
+ this.worldObj.spawnParticle(
+ "blockcrack_" + Block.getIdFromBlock(block) + "_" + this.worldObj.getBlockMetadata(i, j, k),
+ this.posX + (this.rand.nextFloat() - 0.5D) * this.width,
+ this.boundingBox.minY + 0.1D,
+ this.posZ + (this.rand.nextFloat() - 0.5D) * this.width,
+ 4.0D * (this.rand.nextFloat() - 0.5D),
+ 0.5D,
+ (this.rand.nextFloat() - 0.5D) * 4.0D);
+ }
+ }
+