From 9fe3f693f1d6d015f45898818b7958b3a57a9f4a Mon Sep 17 00:00:00 2001 From: Alkalus <3060479+draknyte1@users.noreply.github.com> Date: Fri, 26 Jul 2019 04:23:36 +0100 Subject: + Added config option to adjust ingame BGM delays. (Should be working) + Added a Pest Killer for quick removal of Butterflies and Bats. + Added Hydrogen Cyanide. % Replaced existing assets for the Bat King. % Replaced Bat King Logic, it's now an offensive mob. $ Fixed Bat King model scaling. --- .../core/entity/monster/EntityBatKing.java | 540 +++++++++++++-------- 1 file changed, 325 insertions(+), 215 deletions(-) (limited to 'src/Java/gtPlusPlus/core/entity') diff --git a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java index 114ca50b4b..ae8c8f38b8 100644 --- a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java +++ b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java @@ -1,228 +1,338 @@ package gtPlusPlus.core.entity.monster; import java.util.Calendar; + +import gtPlusPlus.api.objects.minecraft.BlockPos; +import gtPlusPlus.core.util.math.MathUtils; +import gtPlusPlus.core.util.minecraft.EntityUtils; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; +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.EntityAIFleeSun; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAIRestrictSun; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class EntityBatKing extends EntityBat -{ - /** Coordinates of where the bat spawned. */ - private ChunkCoordinates spawnPosition; - - public EntityBatKing(World p_i1680_1_) - { - super(p_i1680_1_); - this.setSize(2F, 3.6F); - this.setIsBatHanging(false); - } - - protected void entityInit() - { - super.entityInit(); - } - - /** - * Returns the volume for the sounds this mob makes. - */ - protected float getSoundVolume() - { - return 0.3F; - } - - /** - * Gets the pitch of living sounds in living entities. - */ - protected float getSoundPitch() - { - return super.getSoundPitch() * 0.35F; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - protected String getLivingSound() - { - return this.getIsBatHanging() && this.rand.nextInt(4) != 0 ? null : "mob.bat.idle"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return "mob.bat.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return "mob.bat.death"; - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - protected void collideWithEntity(Entity p_82167_1_) {} - - protected void collideWithNearbyEntities() {} - - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(60.0D); - } - - public boolean getIsBatHanging() - { - return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; - } - - public void setIsBatHanging(boolean p_82236_1_) - { - byte b0 = this.dataWatcher.getWatchableObjectByte(16); - - if (p_82236_1_) - { - this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 1))); - } - else - { - this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -2))); - } - } - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - super.onUpdate(); - } - - protected void updateAITasks() - { - super.updateAITasks(); - - } - - /** - * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to - * prevent them from trampling crops - */ - protected boolean canTriggerWalking() - { - return false; - } - - /** - * Called when the mob is falling. Calculates and applies fall damage. - */ - protected void fall(float p_70069_1_) {} - - /** - * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance - * and deal fall damage if landing on the ground. Args: distanceFallenThisTick, onGround - */ - protected void updateFallState(double p_70064_1_, boolean p_70064_3_) {} - - /** - * Return whether this entity should NOT trigger a pressure plate or a tripwire. - */ - public boolean doesEntityNotTriggerPressurePlate() - { - return true; - } - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource p_70097_1_, float p_70097_2_) - { - if (this.isEntityInvulnerable()) - { - return false; - } - else - { - if (!this.worldObj.isRemote && this.getIsBatHanging()) - { - this.setIsBatHanging(false); - } - - return super.attackEntityFrom(p_70097_1_, p_70097_2_); - } - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ - public void readEntityFromNBT(NBTTagCompound p_70037_1_) - { - super.readEntityFromNBT(p_70037_1_); - } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ - public void writeEntityToNBT(NBTTagCompound p_70014_1_) - { - super.writeEntityToNBT(p_70014_1_); - } - - /** - * Checks if the entity's current position is a valid location to spawn this entity. - */ - public boolean getCanSpawnHere() - { - int i = MathHelper.floor_double(this.boundingBox.minY); - - if (i >= 63) - { - return false; - } - else - { - int j = MathHelper.floor_double(this.posX); - int k = MathHelper.floor_double(this.posZ); - int l = this.worldObj.getBlockLightValue(j, i, k); - byte b0 = 4; - Calendar calendar = this.worldObj.getCurrentDate(); - - if ((calendar.get(2) + 1 != 10 || calendar.get(5) < 20) && (calendar.get(2) + 1 != 11 || calendar.get(5) > 3)) - { - if (this.rand.nextBoolean()) - { - return false; - } - } - else - { - b0 = 7; - } - - return l > this.rand.nextInt(b0) ? false : super.getCanSpawnHere(); - } - } +public class EntityBatKing extends EntityMob implements IRangedAttackMob { + + + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F); + private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false); + + public EntityBatKing(World p_i1680_1_) { + super(p_i1680_1_); + this.setSize(2.5F, 1.5F); + + this.setIsBatHanging(false); + this.isImmuneToFire = true; + this.experienceValue = 1000; + + this.tasks.addTask(3, this.aiArrowAttack); + this.tasks.addTask(4, this.aiAttackOnCollide); + this.tasks.addTask(4, new EntityAIRestrictSun(this)); + this.tasks.addTask(5, new EntityAIFleeSun(this, 1.0D)); + this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); + + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + this.targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityBat.class, 0, false)); + + } + + protected void entityInit() { + super.entityInit(); + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() + { + return EnumCreatureAttribute.UNDEAD; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.45F; + } + + /** + * Gets the pitch of living sounds in living entities. + */ + protected float getSoundPitch() { + return super.getSoundPitch() * 0.15F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + int aRand = MathUtils.randInt(0, 10); + if (aRand < 6) { + return null; + } else if (aRand <= 8) { + return "mob.bat.idle"; + } else { + return "mob.blaze.breathe"; + } + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.bat.death"; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + protected void collideWithEntity(Entity aEntity) { + if (aEntity != null) { + if (aEntity instanceof EntityPlayer) { + EntityUtils.doDamage(aEntity, DamageSource.magic, (int) (((EntityPlayer) aEntity).getHealth() / 20)); + } + } + } + + protected void collideWithNearbyEntities() { + } + + protected void applyEntityAttributes() { + + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.maxHealth); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.knockbackResistance); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.movementSpeed); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.followRange); + + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(60.0D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D); + } + + public boolean getIsBatHanging() { + return false; + } + + public void setIsBatHanging(boolean p_82236_1_) { + + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + for (int i = 0; i < 2; ++i) { + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, + this.posY + this.rand.nextDouble() * (double) this.height, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); + } + + if (!isFlying()) { + this.jump(); + } + /* + * if (!hasAir()) { if (isFlying()) { this.jump(); this.jump(); } } + */ + + if (!this.onGround && this.motionY < 0.0D) + { + this.motionY *= 0.0001D; + } + + } + + protected void updateAITasks() { + super.updateAITasks(); + } + + private boolean isFlying() { + if (this.onGround) { + return false; + } + return true; + } + + private boolean hasAir() { + BlockPos p = EntityUtils.findBlockPosUnderEntity(this); + int y = p.yPos; + int yOriginal = p.yPos; + int breaker = 0; + while (y > 0) { + if (breaker > 50) { + break; + } + if (!this.worldObj.isAirBlock(p.xPos, y, p.zPos)) { + break; + } + y--; + breaker++; + } + if (yOriginal - y < 3) { + for (int i=0;i= 63) { + return false; + } else { + int j = MathHelper.floor_double(this.posX); + int k = MathHelper.floor_double(this.posZ); + int l = this.worldObj.getBlockLightValue(j, i, k); + byte b0 = 4; + Calendar calendar = this.worldObj.getCurrentDate(); + + if ((calendar.get(2) + 1 != 10 || calendar.get(5) < 20) + && (calendar.get(2) + 1 != 11 || calendar.get(5) > 3)) { + if (this.rand.nextBoolean()) { + return false; + } + } else { + b0 = 7; + } + + return l > this.rand.nextInt(b0) ? false : super.getCanSpawnHere(); + } + } + + /** + * Attack the specified entity using a ranged attack. + */ + @Override + public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) + { + EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, 1.6F, (float)(14 - this.worldObj.difficultySetting.getDifficultyId() * 4)); + int i = MathUtils.randInt(0, 4); + int j = MathUtils.randInt(0, 3); + int k = MathUtils.randInt(0, 3); + entityarrow.setDamage((double)(p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.difficultySetting.getDifficultyId() * 0.11F)); + + boolean boostAttack = MathUtils.randInt(0, 100) <= 21; + if (boostAttack) { + if (i > 0) { + entityarrow.setDamage(entityarrow.getDamage() + (double) i * 0.5D + 0.5D); + } + + if (j > 0) { + entityarrow.setKnockbackStrength(j); + } + if (k > 0) { + entityarrow.setFire(50 * k); + } + } + + this.playSound("mob.skeleton.say", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(entityarrow); + } } \ No newline at end of file -- cgit From 77a25b1f5fab73f8354ca842650ff86534804b8b Mon Sep 17 00:00:00 2001 From: Alkalus <3060479+draknyte1@users.noreply.github.com> Date: Fri, 2 Aug 2019 17:36:00 +0100 Subject: % More work on the Bat King. --- .../entity/ai/batking/EntityAIBatKingAttack.java | 384 ++++++++++ .../core/entity/monster/EntityBatKing.java | 820 ++++++++++++++------- 2 files changed, 923 insertions(+), 281 deletions(-) create mode 100644 src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java (limited to 'src/Java/gtPlusPlus/core/entity') diff --git a/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java b/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java new file mode 100644 index 0000000000..bad7030c88 --- /dev/null +++ b/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java @@ -0,0 +1,384 @@ +package gtPlusPlus.core.entity.ai.batking; + +import gtPlusPlus.core.entity.monster.EntityBatKing; +import gtPlusPlus.core.util.minecraft.EntityUtils; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IRangedAttackMob; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.pathfinding.PathEntity; +import net.minecraft.pathfinding.PathPoint; +import net.minecraft.util.MathHelper; + +public class EntityAIBatKingAttack extends EntityAIBase { + + private final Ranged mRangedAI; + private final Melee mMeleeAI; + private boolean mIsMelee = false; + + /** The Bat King in control of this AI. */ + private final EntityBatKing mAttackingEntity; + + /** The PathEntity of our entity. */ + private PathEntity mEntityPathEntity; + + /** The current target of Bat King in control of this AI. */ + private EntityLivingBase mEntityTarget; + + private final Class mClassTarget; + + public EntityAIBatKingAttack(EntityAIBatKingAttack aParent, EntityBatKing aAttacker, Class aClassTarget, + double aMovementSpeed, int someInt, int aMaxRangedAttackTime, float someFloat, boolean aLongMemory) { + mRangedAI = new Ranged(aParent, aMovementSpeed, someInt, aMaxRangedAttackTime, someFloat); + mMeleeAI = new Melee(aParent, aClassTarget, aMovementSpeed, aLongMemory); + mAttackingEntity = aAttacker; + mClassTarget = aClassTarget; + } + + @Override + public boolean shouldExecute() { + EntityLivingBase entitylivingbase = this.mAttackingEntity.getAttackTarget(); + if (entitylivingbase == null) { + this.mEntityTarget = null; + return false; + } else if (!entitylivingbase.isEntityAlive()) { + return false; + } else if (this.mClassTarget != null && !this.mClassTarget.isAssignableFrom(entitylivingbase.getClass())) { + return false; + } else { + if (this.mIsMelee) { + return this.mMeleeAI.shouldExecute(); + } + else { + this.mEntityTarget = entitylivingbase; + this.mEntityPathEntity = this.mAttackingEntity.getNavigator().getPathToEntityLiving(entitylivingbase); + return mRangedAI != null && mMeleeAI != null && hasValidTarget(); + } + } + } + + public EntityBatKing getBatKing() { + return this.mAttackingEntity; + } + + public IRangedAttackMob getBatKingAsIRangedAttackMob() { + return this.mAttackingEntity; + } + + public boolean hasValidTarget() { + return this.mEntityTarget != null; + } + + public EntityLivingBase getTarget() { + return mEntityTarget; + } + + @Override + public boolean continueExecuting() { + if (mIsMelee) { + return mMeleeAI.continueExecuting(); + } else { + return mRangedAI.continueExecuting(); + } + } + + @Override + public boolean isInterruptible() { + if (mIsMelee) { + + } else { + + } + return super.isInterruptible(); + } + + @Override + public void startExecuting() { + if (mIsMelee) { + mMeleeAI.startExecuting(); + } else { + mRangedAI.startExecuting(); + } + } + + @Override + public void resetTask() { + if (mIsMelee) { + mMeleeAI.resetTask(); + } else { + mRangedAI.resetTask(); + } + } + + @Override + public void updateTask() { + determineCombatStyle(); + if (mIsMelee) { + mMeleeAI.updateTask(); + } else { + mRangedAI.updateTask(); + } + } + + + private final void determineCombatStyle() { + if (this.mEntityTarget != null && EntityUtils.getDistance(getBatKing(), mEntityTarget) < 4) { + this.mIsMelee = true; + } + else { + this.mIsMelee = false; + } + } + + private class Ranged { + + private final EntityAIBatKingAttack parentAI; + + /** + * A decrementing tick that spawns a ranged attack once this value reaches 0. It + * is then set back to the maxRangedAttackTime. + */ + private int rangedAttackTime; + private double entityMoveSpeed; + private int mCooldownTime; + private int field_96561_g; + /** + * The maximum time the AI has to wait before performing another ranged attack. + */ + private int maxRangedAttackTime; + private float field_96562_i; + private float field_82642_h; + + public Ranged(EntityAIBatKingAttack aParent, double aMovementSpeed, int someInt, + int aMaxRangedAttackTime, float someFloat) { + this.rangedAttackTime = -1; + this.parentAI = aParent; + this.entityMoveSpeed = aMovementSpeed; + this.field_96561_g = someInt; + this.maxRangedAttackTime = aMaxRangedAttackTime; + this.field_96562_i = someFloat; + this.field_82642_h = someFloat * someFloat; + parentAI.setMutexBits(3); + + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + parentAI.getBatKing().getNavigator().setPath(parentAI.mEntityPathEntity, this.entityMoveSpeed); + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return parentAI.shouldExecute() || !parentAI.getBatKing().getNavigator().noPath(); + } + + /** + * Resets the task + */ + public void resetTask() { + parentAI.mEntityTarget = null; + this.mCooldownTime = 0; + this.rangedAttackTime = -1; + } + + /** + * Updates the task + */ + public void updateTask() { + double d0 = parentAI.getBatKing().getDistanceSq(parentAI.mEntityTarget.posX, parentAI.mEntityTarget.boundingBox.minY, + parentAI.mEntityTarget.posZ); + boolean flag = parentAI.getBatKing().getEntitySenses().canSee(parentAI.mEntityTarget); + + if (flag) { + ++this.mCooldownTime; + } else { + this.mCooldownTime = 0; + } + + if (d0 <= (double) this.field_82642_h && this.mCooldownTime >= 20) { + parentAI.getBatKing().getNavigator().clearPathEntity(); + } else { + parentAI.getBatKing().getNavigator().tryMoveToEntityLiving(parentAI.mEntityTarget, this.entityMoveSpeed); + } + + parentAI.getBatKing().getLookHelper().setLookPositionWithEntity(parentAI.mEntityTarget, 30.0F, 30.0F); + float f; + + if (--this.rangedAttackTime == 0) { + if (d0 > (double) this.field_82642_h || !flag) { + return; + } + + f = MathHelper.sqrt_double(d0) / this.field_96562_i; + float f1 = f; + + if (f < 0.1F) { + f1 = 0.1F; + } + + if (f1 > 1.0F) { + f1 = 1.0F; + } + + parentAI.getBatKingAsIRangedAttackMob().attackEntityWithRangedAttack(parentAI.mEntityTarget, f1); + this.rangedAttackTime = MathHelper.floor_float( + f * (float) (this.maxRangedAttackTime - this.field_96561_g) + (float) this.field_96561_g); + } else if (this.rangedAttackTime < 0) { + f = MathHelper.sqrt_double(d0) / this.field_96562_i; + this.rangedAttackTime = MathHelper.floor_float( + f * (float) (this.maxRangedAttackTime - this.field_96561_g) + (float) this.field_96561_g); + } + } + + } + + private class Melee { + + private final EntityAIBatKingAttack parentAI; + + /** + * An amount of decrementing ticks that allows the entity to attack once the + * tick reaches 0. + */ + int attackTick; + /** The speed with which the mob will approach the target */ + double speedTowardsTarget; + /** + * When true, the mob will continue chasing its target, even if it can't find a + * path to them right now. + */ + boolean longMemory; + Class classTarget; + private int field_75445_i; + private double field_151497_i; + private double field_151495_j; + private double field_151496_k; + + private int failedPathFindingPenalty; + + public Melee(EntityAIBatKingAttack aParent, Class aClassTarget, + double aMoveToTargetSpeed, boolean aLongMemory) { + this.parentAI = aParent; + this.classTarget = aClassTarget; + this.speedTowardsTarget = aMoveToTargetSpeed; + this.longMemory = aLongMemory; + parentAI.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!parentAI.hasValidTarget()) { + return false; + } + EntityLivingBase entitylivingbase = parentAI.getTarget(); + + if (entitylivingbase == null) { + return false; + } else if (!entitylivingbase.isEntityAlive()) { + return false; + } else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entitylivingbase.getClass())) { + return false; + } else { + if (--this.field_75445_i <= 0) { + parentAI.mEntityPathEntity = parentAI.mAttackingEntity.getNavigator().getPathToEntityLiving(entitylivingbase); + this.field_75445_i = 4 + parentAI.mAttackingEntity.getRNG().nextInt(7); + return parentAI.mEntityPathEntity != null; + } else { + return true; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + EntityLivingBase entitylivingbase = parentAI.mAttackingEntity.getAttackTarget(); + return entitylivingbase == null ? false + : (!entitylivingbase.isEntityAlive() ? false + : (!this.longMemory ? !parentAI.mAttackingEntity.getNavigator().noPath() + : parentAI.mAttackingEntity.isWithinHomeDistance(MathHelper.floor_double(entitylivingbase.posX), + MathHelper.floor_double(entitylivingbase.posY), + MathHelper.floor_double(entitylivingbase.posZ)))); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + parentAI.mAttackingEntity.getNavigator().setPath(parentAI.mEntityPathEntity, this.speedTowardsTarget); + this.field_75445_i = 0; + } + + /** + * Resets the task + */ + public void resetTask() { + parentAI.mAttackingEntity.getNavigator().clearPathEntity(); + } + + /** + * Updates the task + */ + public void updateTask() { + EntityLivingBase entitylivingbase = parentAI.mAttackingEntity.getAttackTarget(); + parentAI.mAttackingEntity.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F); + double d0 = parentAI.mAttackingEntity.getDistanceSq(entitylivingbase.posX, entitylivingbase.boundingBox.minY, + entitylivingbase.posZ); + double d1 = (double) (parentAI.mAttackingEntity.width * 2.0F * parentAI.mAttackingEntity.width * 2.0F + entitylivingbase.width); + --this.field_75445_i; + + if ((this.longMemory || parentAI.mAttackingEntity.getEntitySenses().canSee(entitylivingbase)) && this.field_75445_i <= 0 + && (this.field_151497_i == 0.0D && this.field_151495_j == 0.0D && this.field_151496_k == 0.0D + || entitylivingbase.getDistanceSq(this.field_151497_i, this.field_151495_j, + this.field_151496_k) >= 1.0D + || parentAI.mAttackingEntity.getRNG().nextFloat() < 0.05F)) { + this.field_151497_i = entitylivingbase.posX; + this.field_151495_j = entitylivingbase.boundingBox.minY; + this.field_151496_k = entitylivingbase.posZ; + this.field_75445_i = failedPathFindingPenalty + 4 + parentAI.mAttackingEntity.getRNG().nextInt(7); + + if (parentAI.mAttackingEntity.getNavigator().getPath() != null) { + PathPoint finalPathPoint = parentAI.mAttackingEntity.getNavigator().getPath().getFinalPathPoint(); + if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.xCoord, + finalPathPoint.yCoord, finalPathPoint.zCoord) < 1) { + failedPathFindingPenalty = 0; + } else { + failedPathFindingPenalty += 10; + } + } else { + failedPathFindingPenalty += 10; + } + + if (d0 > 1024.0D) { + this.field_75445_i += 10; + } else if (d0 > 256.0D) { + this.field_75445_i += 5; + } + + if (!parentAI.mAttackingEntity.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget)) { + this.field_75445_i += 15; + } + } + + this.attackTick = Math.max(this.attackTick - 1, 0); + + if (d0 <= d1 && this.attackTick <= 20) { + this.attackTick = 20; + + if (parentAI.mAttackingEntity.getHeldItem() != null) { + parentAI.mAttackingEntity.swingItem(); + } + + parentAI.mAttackingEntity.attackEntityAsMob(entitylivingbase); + } + } + + } + +} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java index ae8c8f38b8..d48137e6af 100644 --- a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java +++ b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java @@ -1,7 +1,5 @@ package gtPlusPlus.core.entity.monster; -import java.util.Calendar; - import gtPlusPlus.api.objects.minecraft.BlockPos; import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.EntityUtils; @@ -12,27 +10,41 @@ 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.EntityAIFleeSun; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAIRestrictSun; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.entity.projectile.EntityLargeFireball; +import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; public class EntityBatKing extends EntityMob implements IRangedAttackMob { + public int courseChangeCooldown; + public double waypointX; + public double waypointY; + public double waypointZ; + private Entity targetedEntity; + private int aggroCooldown; + public int prevAttackCounter; + public int attackCounter; + private int explosionStrength = 1; private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F); - private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false); + private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, + false); public EntityBatKing(World p_i1680_1_) { super(p_i1680_1_); @@ -42,10 +54,10 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { this.isImmuneToFire = true; this.experienceValue = 1000; - this.tasks.addTask(3, this.aiArrowAttack); - this.tasks.addTask(4, this.aiAttackOnCollide); - this.tasks.addTask(4, new EntityAIRestrictSun(this)); - this.tasks.addTask(5, new EntityAIFleeSun(this, 1.0D)); + //this.tasks.addTask(3, this.aiArrowAttack); + //this.tasks.addTask(4, this.aiAttackOnCollide); + //this.tasks.addTask(4, new EntityAIRestrictSun(this)); + //this.tasks.addTask(5, new EntityAIFleeSun(this, 1.0D)); this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(6, new EntityAILookIdle(this)); @@ -63,276 +75,522 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { /** * Get this Entity's EnumCreatureAttribute */ - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.UNDEAD; - } - - /** - * Returns the volume for the sounds this mob makes. - */ - protected float getSoundVolume() { - return 0.45F; - } - - /** - * Gets the pitch of living sounds in living entities. - */ - protected float getSoundPitch() { - return super.getSoundPitch() * 0.15F; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - protected String getLivingSound() { - int aRand = MathUtils.randInt(0, 10); - if (aRand < 6) { - return null; - } else if (aRand <= 8) { - return "mob.bat.idle"; - } else { - return "mob.blaze.breathe"; - } - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() { - return "mob.blaze.hit"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() { - return "mob.bat.death"; - } - - /** - * Returns true if this entity should push and be pushed by other entities when - * colliding. - */ - public boolean canBePushed() { - return false; - } - - protected void collideWithEntity(Entity aEntity) { - if (aEntity != null) { - if (aEntity instanceof EntityPlayer) { - EntityUtils.doDamage(aEntity, DamageSource.magic, (int) (((EntityPlayer) aEntity).getHealth() / 20)); - } - } - } - - protected void collideWithNearbyEntities() { - } - - protected void applyEntityAttributes() { - - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.maxHealth); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.knockbackResistance); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.movementSpeed); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.followRange); - - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(60.0D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D); - } - - public boolean getIsBatHanging() { - return false; - } - - public void setIsBatHanging(boolean p_82236_1_) { - - } - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() { - return true; - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() { - super.onUpdate(); - - for (int i = 0; i < 2; ++i) { - this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, - this.posY + this.rand.nextDouble() * (double) this.height, - this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); - } - - if (!isFlying()) { - this.jump(); - } - /* - * if (!hasAir()) { if (isFlying()) { this.jump(); this.jump(); } } - */ - - if (!this.onGround && this.motionY < 0.0D) - { - this.motionY *= 0.0001D; - } - - } - - protected void updateAITasks() { - super.updateAITasks(); - } - - private boolean isFlying() { - if (this.onGround) { - return false; - } - return true; - } - - private boolean hasAir() { - BlockPos p = EntityUtils.findBlockPosUnderEntity(this); - int y = p.yPos; - int yOriginal = p.yPos; - int breaker = 0; - while (y > 0) { - if (breaker > 50) { - break; - } - if (!this.worldObj.isAirBlock(p.xPos, y, p.zPos)) { - break; - } - y--; - breaker++; - } - if (yOriginal - y < 3) { - for (int i=0;i= 63) { - return false; - } else { - int j = MathHelper.floor_double(this.posX); - int k = MathHelper.floor_double(this.posZ); - int l = this.worldObj.getBlockLightValue(j, i, k); - byte b0 = 4; - Calendar calendar = this.worldObj.getCurrentDate(); - - if ((calendar.get(2) + 1 != 10 || calendar.get(5) < 20) - && (calendar.get(2) + 1 != 11 || calendar.get(5) > 3)) { - if (this.rand.nextBoolean()) { - return false; - } - } else { - b0 = 7; - } - - return l > this.rand.nextInt(b0) ? false : super.getCanSpawnHere(); - } - } - - /** - * Attack the specified entity using a ranged attack. - */ - @Override - public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) - { - EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, 1.6F, (float)(14 - this.worldObj.difficultySetting.getDifficultyId() * 4)); - int i = MathUtils.randInt(0, 4); - int j = MathUtils.randInt(0, 3); - int k = MathUtils.randInt(0, 3); - entityarrow.setDamage((double)(p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.difficultySetting.getDifficultyId() * 0.11F)); - - boolean boostAttack = MathUtils.randInt(0, 100) <= 21; - if (boostAttack) { - if (i > 0) { - entityarrow.setDamage(entityarrow.getDamage() + (double) i * 0.5D + 0.5D); - } - - if (j > 0) { - entityarrow.setKnockbackStrength(j); - } - if (k > 0) { - entityarrow.setFire(50 * k); - } - } - - this.playSound("mob.skeleton.say", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); - this.worldObj.spawnEntityInWorld(entityarrow); - } + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + /** + * Gets the pitch of living sounds in living entities. + */ + protected float getSoundPitch() { + return super.getSoundPitch() * 0.15F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + int aRand = MathUtils.randInt(0, 10); + if (aRand < 6) { + return null; + } else if (aRand <= 8) { + return "mob.bat.idle"; + } else { + return "mob.blaze.breathe"; + } + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.bat.death"; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + protected void collideWithEntity(Entity aEntity) { + if (aEntity != null) { + if (aEntity instanceof EntityPlayer) { + EntityUtils.doDamage(aEntity, DamageSource.magic, (int) (((EntityPlayer) aEntity).getHealth() / 20)); + } + } + } + + protected void collideWithNearbyEntities() { + } + + protected void applyEntityAttributes() { + + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.maxHealth); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.knockbackResistance); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.movementSpeed); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.followRange); + + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(60.0D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D); + } + + public boolean getIsBatHanging() { + return false; + } + + public void setIsBatHanging(boolean p_82236_1_) { + + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + generateParticles(this); + } + + private static void generateParticles(EntityBatKing aKing) { + for (int i = 0; i < 20; ++i) { + // + if (MathUtils.randInt(0, 50) <= 1) { + String particleName = "smoke"; + if (MathUtils.randInt(0, 3) <= 2) { + particleName = "largesmoke"; + } + aKing.worldObj.spawnParticle(particleName, + aKing.posX + (aKing.rand.nextDouble() - 0.5D) * (double) aKing.width, + aKing.posY + aKing.rand.nextDouble() * (double) aKing.height, + aKing.posZ + (aKing.rand.nextDouble() - 0.5D) * (double) aKing.width, 0.0D, 0.0D, 0.0D); + } + if (MathUtils.randInt(0, 100) <= 1) { + String particleName = "smoke"; + int test2 = MathUtils.randInt(0, 3); + if (test2 == 2) { + particleName = "dripLava"; + } else if (test2 == 3) { + particleName = "portal"; + } + aKing.worldObj.spawnParticle(particleName, + aKing.posX + (aKing.rand.nextDouble() - 0.5D) * (double) aKing.width, + aKing.posY + aKing.rand.nextDouble() * (double) aKing.height, + aKing.posZ + (aKing.rand.nextDouble() - 0.5D) * (double) aKing.width, 0.0D, 0.0D, 0.0D); + } + } + } + + protected void updateAITasks() { + super.updateAITasks(); + } + + private boolean isFlying() { + if (this.onGround) { + return false; + } + return true; + } + + private boolean hasAir() { + BlockPos p = EntityUtils.findBlockPosUnderEntity(this); + int y = p.yPos; + int yOriginal = p.yPos; + int breaker = 0; + while (y > 0) { + if (breaker > 50) { + break; + } + if (!this.worldObj.isAirBlock(p.xPos, y, p.zPos)) { + break; + } + y--; + breaker++; + } + if (yOriginal - y < 3) { + for (int i = 0; i < y; y++) { + this.jump(); + } + return true; + } + return false; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Return whether this entity should NOT trigger a pressure plate or a tripwire. + */ + public boolean doesEntityNotTriggerPressurePlate() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource p_70097_1_, float p_70097_2_) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.worldObj.isRemote && this.getIsBatHanging()) { + this.setIsBatHanging(false); + } + + return super.attackEntityFrom(p_70097_1_, p_70097_2_); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound p_70037_1_) { + super.readEntityFromNBT(p_70037_1_); + if (p_70037_1_.hasKey("ExplosionPower", 99)) { + this.explosionStrength = p_70037_1_.getInteger("ExplosionPower"); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound p_70014_1_) { + super.writeEntityToNBT(p_70014_1_); + p_70014_1_.setInteger("ExplosionPower", this.explosionStrength); + } + + /** + * Attack the specified entity using a ranged attack. + */ + @Override + public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) { + + double d4 = 64.0D; + if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < d4 * d4) { + double d5 = this.targetedEntity.posX - this.posX; + double d6 = this.targetedEntity.boundingBox.minY + (double) (this.targetedEntity.height / 2.0F) + - (this.posY + (double) (this.height / 2.0F)); + double d7 = this.targetedEntity.posZ - this.posZ; + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(d5, d7)) * 180.0F / (float) Math.PI; + + ++this.attackCounter; + + if (this.canEntityBeSeen(this.targetedEntity)) { + + + if (this.attackCounter == 20) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1008, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(this.worldObj, this, d5, d6, d7); + entitylargefireball.field_92057_e = this.explosionStrength; + double d8 = 4.0D; + Vec3 vec3 = this.getLook(1.0F); + entitylargefireball.posX = this.posX + vec3.xCoord * d8; + entitylargefireball.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + entitylargefireball.posZ = this.posZ + vec3.zCoord * d8; + this.worldObj.spawnEntityInWorld(entitylargefireball); + this.attackCounter = -40; + } + } else if (this.attackCounter > 0) { + --this.attackCounter; + } + } else { + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F + / (float) Math.PI; + + if (this.attackCounter > 0) { + --this.attackCounter; + EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, 1.6F, + (float) (14 - this.worldObj.difficultySetting.getDifficultyId() * 4)); + int i = MathUtils.randInt(0, 4); + int j = MathUtils.randInt(0, 3); + int k = MathUtils.randInt(0, 3); + entityarrow.setDamage((double) (p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + + (double) ((float) this.worldObj.difficultySetting.getDifficultyId() * 0.11F)); + + boolean boostAttack = MathUtils.randInt(0, 100) <= 21; + if (boostAttack) { + if (i > 0) { + entityarrow.setDamage(entityarrow.getDamage() + (double) i * 0.5D + 0.5D); + } + + if (j > 0) { + entityarrow.setKnockbackStrength(j); + } + if (k > 0) { + entityarrow.setFire(50 * k); + } + } + + this.playSound("mob.skeleton.say", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(entityarrow); + } + + } + + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 10.0F; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return super.getCanSpawnHere() && this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL; + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 1; + } + + protected Item getDropItem() { + return Items.gunpowder; + } + + /** + * 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. + */ + protected void dropFewItems(boolean p_70628_1_, int p_70628_2_) { + int j = this.rand.nextInt(2) + this.rand.nextInt(1 + p_70628_2_); + int k; + + for (k = 0; k < j; ++k) { + this.dropItem(Items.ghast_tear, 1); + } + + j = this.rand.nextInt(3) + this.rand.nextInt(1 + p_70628_2_); + + for (k = 0; k < j; ++k) { + this.dropItem(Items.gunpowder, 1); + } + } + + @Override + protected void updateEntityActionState() { + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL) { + this.setDead(); + } + + this.despawnEntity(); + this.prevAttackCounter = this.attackCounter; + double d0 = this.waypointX - this.posX; + double d1 = this.waypointY - this.posY; + double d2 = this.waypointZ - this.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d3 < 1.0D || d3 > 3600.0D) { + this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + } + + if (this.courseChangeCooldown-- <= 0) { + this.courseChangeCooldown += this.rand.nextInt(5) + 2; + d3 = (double) MathHelper.sqrt_double(d3); + + if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, d3)) { + this.motionX += d0 / d3 * 0.1D; + this.motionY += d1 / d3 * 0.1D; + this.motionZ += d2 / d3 * 0.1D; + } else { + this.waypointX = this.posX; + this.waypointY = this.posY; + this.waypointZ = this.posZ; + } + } + + if (this.targetedEntity != null && this.targetedEntity.isDead) { + this.targetedEntity = null; + } + + if (this.targetedEntity == null || this.aggroCooldown-- <= 0) { + this.targetedEntity = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D); + + if (this.targetedEntity != null) { + this.aggroCooldown = 20; + } + } + + double d4 = 64.0D; + + if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < d4 * d4) { + double d5 = this.targetedEntity.posX - this.posX; + double d6 = this.targetedEntity.boundingBox.minY + (double) (this.targetedEntity.height / 2.0F) + - (this.posY + (double) (this.height / 2.0F)); + double d7 = this.targetedEntity.posZ - this.posZ; + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(d5, d7)) * 180.0F / (float) Math.PI; + + if (this.canEntityBeSeen(this.targetedEntity)) { + if (this.attackCounter == 10) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1007, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + } + + ++this.attackCounter; + + if (this.attackCounter == 20) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1008, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(this.worldObj, this, d5, d6, d7); + entitylargefireball.field_92057_e = this.explosionStrength; + double d8 = 4.0D; + Vec3 vec3 = this.getLook(1.0F); + entitylargefireball.posX = this.posX + vec3.xCoord * d8; + entitylargefireball.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + entitylargefireball.posZ = this.posZ + vec3.zCoord * d8; + this.worldObj.spawnEntityInWorld(entitylargefireball); + this.attackCounter = -40; + } + } else if (this.attackCounter > 0) { + --this.attackCounter; + } + } else { + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F + / (float) Math.PI; + + if (this.attackCounter > 0) { + --this.attackCounter; + } + } + + if (!this.worldObj.isRemote) { + byte b1 = this.dataWatcher.getWatchableObjectByte(16); + byte b0 = (byte) (this.attackCounter > 10 ? 1 : 0); + + if (b1 != b0) { + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } + } + } + + /** + * True if the ghast has an unobstructed line of travel to the waypoint. + */ + private boolean isCourseTraversable(double p_70790_1_, double p_70790_3_, double p_70790_5_, double p_70790_7_) { + double d4 = (this.waypointX - this.posX) / p_70790_7_; + double d5 = (this.waypointY - this.posY) / p_70790_7_; + double d6 = (this.waypointZ - this.posZ) / p_70790_7_; + AxisAlignedBB axisalignedbb = this.boundingBox.copy(); + + for (int i = 1; (double) i < p_70790_7_; ++i) { + axisalignedbb.offset(d4, d5, d6); + + /* + * if (!this.worldObj.getCollidingBoundingBoxes(this, axisalignedbb).isEmpty()) + * { return false; } + */ + } + + return true; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float p_70069_1_) { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double p_70064_1_, boolean p_70064_3_) { + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float p_70612_1_, float p_70612_2_) { + if (this.isInWater()) { + this.moveFlying(p_70612_1_, p_70612_2_, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.800000011920929D; + this.motionY *= 0.800000011920929D; + this.motionZ *= 0.800000011920929D; + } else if (this.handleLavaMovement()) { + this.moveFlying(p_70612_1_, p_70612_2_, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } else { + float f2 = 0.91F; + + if (this.onGround) { + f2 = this.worldObj.getBlock(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, + MathHelper.floor_double(this.posZ)).slipperiness * 0.91F; + } + + float f3 = 0.16277136F / (f2 * f2 * f2); + this.moveFlying(p_70612_1_, p_70612_2_, this.onGround ? 0.1F * f3 : 0.02F); + f2 = 0.91F; + + if (this.onGround) { + f2 = this.worldObj.getBlock(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, + MathHelper.floor_double(this.posZ)).slipperiness * 0.91F; + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= (double) f2; + this.motionY *= (double) f2; + this.motionZ *= (double) f2; + } + + this.prevLimbSwingAmount = this.limbSwingAmount; + double d1 = this.posX - this.prevPosX; + double d0 = this.posZ - this.prevPosZ; + float f4 = MathHelper.sqrt_double(d1 * d1 + d0 * d0) * 4.0F; + + if (f4 > 1.0F) { + f4 = 1.0F; + } + + this.limbSwingAmount += (f4 - this.limbSwingAmount) * 0.4F; + this.limbSwing += this.limbSwingAmount; + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + return false; + } + } \ No newline at end of file -- cgit From 36cae46b02a783e2ef4887b614934b4df72bcf5a Mon Sep 17 00:00:00 2001 From: Alkalus <3060479+draknyte1@users.noreply.github.com> Date: Sat, 3 Aug 2019 02:49:48 +0100 Subject: $ Fixed minor recipe derp. % More work on Bat King AI. --- .../entity/ai/batking/EntityAIBatKingAttack.java | 38 ++++-- .../core/entity/monster/EntityBatKing.java | 152 +++++++++++++++++---- .../xmod/railcraft/HANDLER_Railcraft.java | 6 +- 3 files changed, 163 insertions(+), 33 deletions(-) (limited to 'src/Java/gtPlusPlus/core/entity') diff --git a/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java b/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java index bad7030c88..52d1d6100c 100644 --- a/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java +++ b/src/Java/gtPlusPlus/core/entity/ai/batking/EntityAIBatKingAttack.java @@ -1,6 +1,8 @@ package gtPlusPlus.core.entity.ai.batking; +import gtPlusPlus.api.objects.Logger; import gtPlusPlus.core.entity.monster.EntityBatKing; +import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.EntityUtils; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IRangedAttackMob; @@ -26,16 +28,17 @@ public class EntityAIBatKingAttack extends EntityAIBase { private final Class mClassTarget; - public EntityAIBatKingAttack(EntityAIBatKingAttack aParent, EntityBatKing aAttacker, Class aClassTarget, + public EntityAIBatKingAttack(EntityBatKing aAttacker, Class aClassTarget, double aMovementSpeed, int someInt, int aMaxRangedAttackTime, float someFloat, boolean aLongMemory) { - mRangedAI = new Ranged(aParent, aMovementSpeed, someInt, aMaxRangedAttackTime, someFloat); - mMeleeAI = new Melee(aParent, aClassTarget, aMovementSpeed, aLongMemory); + mRangedAI = new Ranged(this, aMovementSpeed, someInt, 5, someFloat); + mMeleeAI = new Melee(this, aClassTarget, aMovementSpeed, aLongMemory); mAttackingEntity = aAttacker; mClassTarget = aClassTarget; } @Override public boolean shouldExecute() { + determineCombatStyle(); EntityLivingBase entitylivingbase = this.mAttackingEntity.getAttackTarget(); if (entitylivingbase == null) { this.mEntityTarget = null; @@ -74,6 +77,7 @@ public class EntityAIBatKingAttack extends EntityAIBase { @Override public boolean continueExecuting() { + determineCombatStyle(); if (mIsMelee) { return mMeleeAI.continueExecuting(); } else { @@ -93,6 +97,7 @@ public class EntityAIBatKingAttack extends EntityAIBase { @Override public void startExecuting() { + determineCombatStyle(); if (mIsMelee) { mMeleeAI.startExecuting(); } else { @@ -102,6 +107,7 @@ public class EntityAIBatKingAttack extends EntityAIBase { @Override public void resetTask() { + determineCombatStyle(); if (mIsMelee) { mMeleeAI.resetTask(); } else { @@ -121,12 +127,16 @@ public class EntityAIBatKingAttack extends EntityAIBase { private final void determineCombatStyle() { + boolean aisMeleeNow = this.mIsMelee; if (this.mEntityTarget != null && EntityUtils.getDistance(getBatKing(), mEntityTarget) < 4) { this.mIsMelee = true; } else { this.mIsMelee = false; } + if (aisMeleeNow != this.mIsMelee) { + Logger.INFO("Bat King changed combat style from "+(aisMeleeNow ? "Melee" : "Ranged")+" to "+(this.mIsMelee ? "Melee" : "Ranged")); + } } private class Ranged { @@ -146,7 +156,7 @@ public class EntityAIBatKingAttack extends EntityAIBase { */ private int maxRangedAttackTime; private float field_96562_i; - private float field_82642_h; + private float field_82642_h; //Max range public Ranged(EntityAIBatKingAttack aParent, double aMovementSpeed, int someInt, int aMaxRangedAttackTime, float someFloat) { @@ -156,7 +166,7 @@ public class EntityAIBatKingAttack extends EntityAIBase { this.field_96561_g = someInt; this.maxRangedAttackTime = aMaxRangedAttackTime; this.field_96562_i = someFloat; - this.field_82642_h = someFloat * someFloat; + this.field_82642_h = someFloat * someFloat * 8; parentAI.setMutexBits(3); } @@ -187,7 +197,12 @@ public class EntityAIBatKingAttack extends EntityAIBase { /** * Updates the task */ - public void updateTask() { + public void updateTask() { + + if (MathUtils.randInt(0, 100) == 0) { + maxRangedAttackTime = MathUtils.balance(maxRangedAttackTime, 20, 40); + } + double d0 = parentAI.getBatKing().getDistanceSq(parentAI.mEntityTarget.posX, parentAI.mEntityTarget.boundingBox.minY, parentAI.mEntityTarget.posZ); boolean flag = parentAI.getBatKing().getEntitySenses().canSee(parentAI.mEntityTarget); @@ -201,14 +216,21 @@ public class EntityAIBatKingAttack extends EntityAIBase { if (d0 <= (double) this.field_82642_h && this.mCooldownTime >= 20) { parentAI.getBatKing().getNavigator().clearPathEntity(); } else { - parentAI.getBatKing().getNavigator().tryMoveToEntityLiving(parentAI.mEntityTarget, this.entityMoveSpeed); + if (parentAI.getBatKing().getNavigator().tryMoveToEntityLiving(parentAI.mEntityTarget, this.entityMoveSpeed)) { + Logger.INFO("Doing Ranged Ai Task."); + } + else { + Logger.INFO("Not Doing Ranged Ai Task."); + } } parentAI.getBatKing().getLookHelper().setLookPositionWithEntity(parentAI.mEntityTarget, 30.0F, 30.0F); float f; + Logger.INFO("Ranged AI - "+rangedAttackTime); if (--this.rangedAttackTime == 0) { if (d0 > (double) this.field_82642_h || !flag) { + Logger.INFO("Stopping ranged attack. "+flag+"|"+(d0 > (double) this.field_82642_h)+"|"+d0+"|"+(double) this.field_82642_h); return; } @@ -222,7 +244,7 @@ public class EntityAIBatKingAttack extends EntityAIBase { if (f1 > 1.0F) { f1 = 1.0F; } - + Logger.INFO("Trying to do a ranged attack."); parentAI.getBatKingAsIRangedAttackMob().attackEntityWithRangedAttack(parentAI.mEntityTarget, f1); this.rangedAttackTime = MathHelper.floor_float( f * (float) (this.maxRangedAttackTime - this.field_96561_g) + (float) this.field_96561_g); diff --git a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java index d48137e6af..7ec418cbb1 100644 --- a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java +++ b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java @@ -1,20 +1,23 @@ package gtPlusPlus.core.entity.monster; +import java.lang.reflect.Field; + +import gtPlusPlus.api.objects.Logger; import gtPlusPlus.api.objects.minecraft.BlockPos; +import gtPlusPlus.core.entity.ai.batking.EntityAIBatKingAttack; +import gtPlusPlus.core.entity.projectile.EntityThrowableBomb; import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.EntityUtils; +import gtPlusPlus.core.util.reflect.ReflectionUtils; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureAttribute; 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.EntityAIHurtByTarget; -import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.player.EntityPlayer; @@ -42,7 +45,7 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { public int attackCounter; private int explosionStrength = 1; - private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F); + private EntityAIBatKingAttack aiAttack = new EntityAIBatKingAttack(this, null, 1.0D, 20, 60, 15.0F, true); private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false); @@ -54,15 +57,16 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { this.isImmuneToFire = true; this.experienceValue = 1000; - //this.tasks.addTask(3, this.aiArrowAttack); + this.tasks.addTask(3, this.aiAttack); //this.tasks.addTask(4, this.aiAttackOnCollide); //this.tasks.addTask(4, new EntityAIRestrictSun(this)); //this.tasks.addTask(5, new EntityAIFleeSun(this, 1.0D)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(6, new EntityAILookIdle(this)); + this.tasks.addTask(4, new EntityAIWander(this, 1.0D)); + //this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + //this.tasks.addTask(6, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, this.aiAttack); this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); this.targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityBat.class, 0, false)); @@ -152,6 +156,20 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { } public void setIsBatHanging(boolean p_82236_1_) { + generateParticles(this); + generateParticles(this); + generateParticles(this); + for (int i = 0; i < 32; ++i) { + // + String particleName = "lava"; + if (MathUtils.randInt(0, 3) <= 2) { + particleName = "crit"; + } + this.worldObj.spawnParticle(particleName, + this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, + this.posY + this.rand.nextDouble() * (double) this.height, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); + } } @@ -168,6 +186,37 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { public void onUpdate() { super.onUpdate(); generateParticles(this); + + if (!this.worldObj.isRemote && (this.targetedEntity == null || this.aggroCooldown-- <= 0)) { + this.targetedEntity = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D); + + if (this.targetedEntity != null) { + this.aggroCooldown = 30; + if (aiAttack.hasValidTarget()) { + this.setAttackTarget(aiAttack.getTarget()); + } + else { + Logger.INFO("No valid target."); + if (ReflectionUtils.doesFieldExist(aiAttack.getClass(), "mEntityTarget")) { + Logger.INFO("Found field."); + } + else { + Logger.INFO("Did not find field."); + } + Field target = ReflectionUtils.getField(EntityAIBatKingAttack.class, "mEntityTarget"); + if (target != null) { + ReflectionUtils.setField(aiAttack, target, this.targetedEntity); + Logger.INFO("Set target."); + } + else { + Logger.INFO("Could not set via reflection."); + } + + + } + } + } + } private static void generateParticles(EntityBatKing aKing) { @@ -213,19 +262,18 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { private boolean hasAir() { BlockPos p = EntityUtils.findBlockPosUnderEntity(this); int y = p.yPos; - int yOriginal = p.yPos; - int breaker = 0; - while (y > 0) { - if (breaker > 50) { + int yOriginal = p.yPos; + + for (int u = 0; u<5;u++) { + if (u > 50 || y <= 0) { break; } if (!this.worldObj.isAirBlock(p.xPos, y, p.zPos)) { break; } y--; - breaker++; } - if (yOriginal - y < 3) { + if (yOriginal != y) { for (int i = 0; i < y; y++) { this.jump(); } @@ -287,9 +335,19 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { */ @Override public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) { - + Logger.INFO("Trying to do ranged attack 1 |"+(this.targetedEntity != null)+"|"); + + if (!this.isFlying() || !this.isAirBorne) { + //this.hasAir(); + /* + * for (int i=0;i<3;i++) { this.jump(); } + */ + } + + double d4 = 64.0D; - if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < d4 * d4) { + if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < d4 * d4 * 8) { + Logger.INFO("Trying to do ranged attack 2"); double d5 = this.targetedEntity.posX - this.posX; double d6 = this.targetedEntity.boundingBox.minY + (double) (this.targetedEntity.height / 2.0F) - (this.posY + (double) (this.height / 2.0F)); @@ -297,31 +355,78 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(d5, d7)) * 180.0F / (float) Math.PI; ++this.attackCounter; - - if (this.canEntityBeSeen(this.targetedEntity)) { + if (this.canEntityBeSeen(this.targetedEntity)) { + Logger.INFO("Trying to do ranged attack 3a | "+attackCounter); + + + if (this.attackCounter >= 2) { + Logger.INFO("Trying to do ranged attack 3a1"); - if (this.attackCounter == 20) { this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1008, (int) this.posX, (int) this.posY, (int) this.posZ, 0); - EntityLargeFireball entitylargefireball = new EntityLargeFireball(this.worldObj, this, d5, d6, d7); - entitylargefireball.field_92057_e = this.explosionStrength; + setIsBatHanging(true); + + EntityThrowableBomb entitylargefireball = new EntityThrowableBomb(this.worldObj, this/*d5, d6, d7*/); + //entitylargefireball.field_92057_e = this.explosionStrength; + //entitylargefireball.accelerationX *= 2; + //entitylargefireball.accelerationY *= 2; + //entitylargefireball.accelerationZ *= 2; double d8 = 4.0D; Vec3 vec3 = this.getLook(1.0F); entitylargefireball.posX = this.posX + vec3.xCoord * d8; entitylargefireball.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; entitylargefireball.posZ = this.posZ + vec3.zCoord * d8; - this.worldObj.spawnEntityInWorld(entitylargefireball); - this.attackCounter = -40; + this.worldObj.spawnEntityInWorld(entitylargefireball); + + for (int u=0; u 0) { + Logger.INFO("Trying to do ranged attack 5a"); + --this.attackCounter; + EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, MathUtils.randFloat(1f, 3f), + (float) (14 - this.worldObj.difficultySetting.getDifficultyId() * 4)); + int i = MathUtils.randInt(0, 4); + int j = MathUtils.randInt(0, 3); + int k = MathUtils.randInt(0, 3); + entityarrow.setDamage((double) (p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + + (double) ((float) this.worldObj.difficultySetting.getDifficultyId() * 0.11F)); + + boolean boostAttack = MathUtils.randInt(0, 100) <= 21; + if (boostAttack) { + if (i > 0) { + entityarrow.setDamage(entityarrow.getDamage() + (double) i * 0.5D + 0.5D); + } + + if (j > 0) { + entityarrow.setKnockbackStrength(j); + } + if (k > 0) { + entityarrow.setFire(50 * k); + } + } + + this.playSound("mob.skeleton.say", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(entityarrow); + Logger.INFO("Trying to do ranged attack 5a done"); + } + } + + + + + this.attackCounter = 0; } } else if (this.attackCounter > 0) { + Logger.INFO("Trying to do ranged attack 3b"); --this.attackCounter; } } else { + Logger.INFO("Trying to do ranged attack 4a"); this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float) Math.PI; if (this.attackCounter > 0) { + Logger.INFO("Trying to do ranged attack 5a"); --this.attackCounter; EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, 1.6F, (float) (14 - this.worldObj.difficultySetting.getDifficultyId() * 4)); @@ -347,6 +452,7 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { this.playSound("mob.skeleton.say", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); this.worldObj.spawnEntityInWorld(entityarrow); + Logger.INFO("Trying to do ranged attack 5a done"); } } diff --git a/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java b/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java index cb64dacbf5..b146e00830 100644 --- a/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java +++ b/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java @@ -10,6 +10,8 @@ import gtPlusPlus.core.recipe.common.CI; import gtPlusPlus.core.util.minecraft.FluidUtils; import gtPlusPlus.core.util.minecraft.ItemUtils; import gtPlusPlus.xmod.railcraft.utils.RailcraftUtils; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; public class HANDLER_Railcraft { @@ -53,8 +55,8 @@ public class HANDLER_Railcraft { private static void generateCokeOvenRecipes() { ItemStack[] aInputs1 = new ItemStack[] { - ItemUtils.getSimpleStack(ModItems.itemCactusCharcoal), - ItemUtils.getSimpleStack(ModItems.itemSugarCharcoal) + ItemUtils.getSimpleStack(Blocks.cactus), + ItemUtils.getSimpleStack(Blocks.reeds) }; ItemStack[] aInputs2 = new ItemStack[] { ItemUtils.getSimpleStack(ModItems.itemCactusCharcoal), -- cgit From 800119d6a1e75ffd0201a9dfc44c53a7604a9f37 Mon Sep 17 00:00:00 2001 From: Alkalus <3060479+draknyte1@users.noreply.github.com> Date: Mon, 12 Aug 2019 20:48:13 +0100 Subject: + Added Reliquary support. $ Fixed #527. $ Fixed Sugar Coke Recipe. --- src/Java/gtPlusPlus/GTplusplus.java | 2 +- .../core/entity/monster/EntityBatKing.java | 20 ++- .../core/handler/COMPAT_IntermodStaging.java | 4 + .../core/item/bauble/FireProtectionBauble.java | 3 +- src/Java/gtPlusPlus/core/lib/LoadedMods.java | 6 + .../core/util/reflect/ReflectionUtils.java | 12 ++ .../xmod/railcraft/HANDLER_Railcraft.java | 2 +- .../xmod/reliquary/HANDLER_Reliquary.java | 26 ++++ .../xmod/reliquary/item/ReliquaryItems.java | 161 +++++++++++++++++++++ .../xmod/reliquary/util/AlkahestRecipeWrapper.java | 47 ++++++ .../reliquary/util/ReliquaryRecipeHandler.java | 57 ++++++++ 11 files changed, 332 insertions(+), 8 deletions(-) create mode 100644 src/Java/gtPlusPlus/xmod/reliquary/HANDLER_Reliquary.java create mode 100644 src/Java/gtPlusPlus/xmod/reliquary/item/ReliquaryItems.java create mode 100644 src/Java/gtPlusPlus/xmod/reliquary/util/AlkahestRecipeWrapper.java create mode 100644 src/Java/gtPlusPlus/xmod/reliquary/util/ReliquaryRecipeHandler.java (limited to 'src/Java/gtPlusPlus/core/entity') diff --git a/src/Java/gtPlusPlus/GTplusplus.java b/src/Java/gtPlusPlus/GTplusplus.java index 9813e550ad..8c8b973dc9 100644 --- a/src/Java/gtPlusPlus/GTplusplus.java +++ b/src/Java/gtPlusPlus/GTplusplus.java @@ -69,7 +69,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; @MCVersion(value = "1.7.10") -@Mod(modid = CORE.MODID, name = CORE.name, version = CORE.VERSION, dependencies = "required-after:Forge; after:TConstruct; after:PlayerAPI; after:dreamcraft; after:IC2; after:ihl; after:psychedelicraft; after:gregtech; after:Forestry; after:MagicBees; after:CoFHCore; after:Growthcraft; after:Railcraft; after:CompactWindmills; after:ForbiddenMagic; after:MorePlanet; after:PneumaticCraft; after:ExtraUtilities; after:Thaumcraft; after:rftools; after:simplyjetpacks; after:BigReactors; after:EnderIO; after:tectech; after:GTRedtech; after:beyondrealitycore; after:OpenBlocks; after:IC2NuclearControl; after:TGregworks; after:StevesCarts;") +@Mod(modid = CORE.MODID, name = CORE.name, version = CORE.VERSION, dependencies = "required-after:Forge; after:TConstruct; after:PlayerAPI; after:dreamcraft; after:IC2; after:ihl; after:psychedelicraft; after:gregtech; after:Forestry; after:MagicBees; after:CoFHCore; after:Growthcraft; after:Railcraft; after:CompactWindmills; after:ForbiddenMagic; after:MorePlanet; after:PneumaticCraft; after:ExtraUtilities; after:Thaumcraft; after:rftools; after:simplyjetpacks; after:BigReactors; after:EnderIO; after:tectech; after:GTRedtech; after:beyondrealitycore; after:OpenBlocks; after:IC2NuclearControl; after:TGregworks; after:StevesCarts; after:xreliquary;") public class GTplusplus implements ActionListener { public static enum INIT_PHASE { diff --git a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java index 7ec418cbb1..55e0f4c571 100644 --- a/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java +++ b/src/Java/gtPlusPlus/core/entity/monster/EntityBatKing.java @@ -18,6 +18,7 @@ import net.minecraft.entity.ai.EntityAIAttackOnCollide; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.RandomPositionGenerator; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.player.EntityPlayer; @@ -66,7 +67,7 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { //this.tasks.addTask(6, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, this.aiAttack); + //this.targetTasks.addTask(2, this.aiAttack); this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); this.targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityBat.class, 0, false)); @@ -123,7 +124,7 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { * colliding. */ public boolean canBePushed() { - return false; + return true; } protected void collideWithEntity(Entity aEntity) { @@ -145,10 +146,10 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { this.getAttributeMap().registerAttribute(SharedMonsterAttributes.movementSpeed); this.getAttributeMap().registerAttribute(SharedMonsterAttributes.followRange); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(60.0D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(250.0D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(120.0D); } public boolean getIsBatHanging() { @@ -215,6 +216,15 @@ public class EntityBatKing extends EntityMob implements IRangedAttackMob { } } + else { + Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this, 32, 20); + if (vec3 != null) { + double xPosition = vec3.xCoord; + double yPosition = vec3.yCoord; + double zPosition = vec3.zCoord; + this.getNavigator().tryMoveToXYZ(xPosition, yPosition, zPosition, 3); + } + } } } diff --git a/src/Java/gtPlusPlus/core/handler/COMPAT_IntermodStaging.java b/src/Java/gtPlusPlus/core/handler/COMPAT_IntermodStaging.java index d6a24d718a..b7efcf08ea 100644 --- a/src/Java/gtPlusPlus/core/handler/COMPAT_IntermodStaging.java +++ b/src/Java/gtPlusPlus/core/handler/COMPAT_IntermodStaging.java @@ -13,6 +13,7 @@ import gtPlusPlus.xmod.gregtech.HANDLER_GT; import gtPlusPlus.xmod.growthcraft.HANDLER_GC; import gtPlusPlus.xmod.ic2.HANDLER_IC2; import gtPlusPlus.xmod.railcraft.HANDLER_Railcraft; +import gtPlusPlus.xmod.reliquary.HANDLER_Reliquary; import gtPlusPlus.xmod.sc2.HANDLER_SC2; import gtPlusPlus.xmod.thaumcraft.HANDLER_Thaumcraft; import gtPlusPlus.xmod.thermalfoundation.HANDLER_TF; @@ -35,6 +36,7 @@ public class COMPAT_IntermodStaging { HANDLER_GalactiCraft.preInit(); HANDLER_CropsPlusPlus.preInit(preinit); HANDLER_Railcraft.preInit(); + HANDLER_Reliquary.preInit(); } public static void init(FMLInitializationEvent init){ @@ -52,6 +54,7 @@ public class COMPAT_IntermodStaging { HANDLER_GalactiCraft.init(); HANDLER_CropsPlusPlus.init(init); HANDLER_Railcraft.init(); + HANDLER_Reliquary.init(); } public static void postInit(FMLPostInitializationEvent postinit){ @@ -69,6 +72,7 @@ public class COMPAT_IntermodStaging { HANDLER_GalactiCraft.postInit(); HANDLER_CropsPlusPlus.postInit(postinit); HANDLER_Railcraft.postInit(); + HANDLER_Reliquary.postInit(); } public static void onLoadComplete(FMLLoadCompleteEvent event) { diff --git a/src/Java/gtPlusPlus/core/item/bauble/FireProtectionBauble.java b/src/Java/gtPlusPlus/core/item/bauble/FireProtectionBauble.java index 04467091c0..3c7ea9d2c9 100644 --- a/src/Java/gtPlusPlus/core/item/bauble/FireProtectionBauble.java +++ b/src/Java/gtPlusPlus/core/item/bauble/FireProtectionBauble.java @@ -11,6 +11,7 @@ import cpw.mods.fml.common.registry.GameRegistry; import gtPlusPlus.core.creative.AddToCreativeTab; import gtPlusPlus.core.lib.CORE; import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.preloader.DevHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -28,7 +29,7 @@ public class FireProtectionBauble extends BaseBauble { private static Field isImmuneToFire; static { - isImmuneToFire = ReflectionUtils.getField(Entity.class, "isImmuneToFire"); + isImmuneToFire = ReflectionUtils.getField(Entity.class, DevHelper.IsObfuscatedEnvironment() ? "func_70045_F" : "isImmuneToFire"); } public static boolean fireImmune(Entity aEntity) { diff --git a/src/Java/gtPlusPlus/core/lib/LoadedMods.java b/src/Java/gtPlusPlus/core/lib/LoadedMods.java index 5a2b75337b..d96875b811 100644 --- a/src/Java/gtPlusPlus/core/lib/LoadedMods.java +++ b/src/Java/gtPlusPlus/core/lib/LoadedMods.java @@ -55,6 +55,7 @@ public class LoadedMods { public static boolean Witchery = false; public static boolean Waila = false; public static boolean CropsPlusPlus = false; //Barts Crop Mod + public static boolean Reliquary = false; @@ -102,6 +103,11 @@ public class LoadedMods { Logger.INFO("Components enabled for: Crops++"); totalMods++; } + if (Loader.isModLoaded("xreliquary")) { + Reliquary = true; + Logger.INFO("Components enabled for: Reliquary"); + totalMods++; + } if (Loader.isModLoaded("TConstruct")){ TiCon = true; Logger.INFO("Components enabled for: Tinkers Construct"); diff --git a/src/Java/gtPlusPlus/core/util/reflect/ReflectionUtils.java b/src/Java/gtPlusPlus/core/util/reflect/ReflectionUtils.java index efc86122e2..19e42735d7 100644 --- a/src/Java/gtPlusPlus/core/util/reflect/ReflectionUtils.java +++ b/src/Java/gtPlusPlus/core/util/reflect/ReflectionUtils.java @@ -813,5 +813,17 @@ public class ReflectionUtils { return false; } + public static Object getFieldValue(Field field) { + return getFieldValue(field, null); + } + + public static Object getFieldValue(Field field, Object instance) { + try { + return field.get(instance); + } catch (IllegalArgumentException | IllegalAccessException e) { + } + return null; + } + } diff --git a/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java b/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java index b146e00830..a21a759a77 100644 --- a/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java +++ b/src/Java/gtPlusPlus/xmod/railcraft/HANDLER_Railcraft.java @@ -56,7 +56,7 @@ public class HANDLER_Railcraft { private static void generateCokeOvenRecipes() { ItemStack[] aInputs1 = new ItemStack[] { ItemUtils.getSimpleStack(Blocks.cactus), - ItemUtils.getSimpleStack(Blocks.reeds) + ItemUtils.getSimpleStack(Items.reeds) }; ItemStack[] aInputs2 = new ItemStack[] { ItemUtils.getSimpleStack(ModItems.itemCactusCharcoal), diff --git a/src/Java/gtPlusPlus/xmod/reliquary/HANDLER_Reliquary.java b/src/Java/gtPlusPlus/xmod/reliquary/HANDLER_Reliquary.java new file mode 100644 index 0000000000..7ebb4c7b1f --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/reliquary/HANDLER_Reliquary.java @@ -0,0 +1,26 @@ +package gtPlusPlus.xmod.reliquary; + +import gtPlusPlus.core.lib.LoadedMods; +import gtPlusPlus.xmod.reliquary.util.ReliquaryRecipeHandler; + +public class HANDLER_Reliquary { + + public static void preInit() { + if (LoadedMods.Reliquary) { + + } + } + + public static void init() { + if (LoadedMods.Reliquary) { + + } + } + + public static void postInit() { + if (LoadedMods.Reliquary) { + ReliquaryRecipeHandler.gregifyDefaultRecipes(); + } + } + +} diff --git a/src/Java/gtPlusPlus/xmod/reliquary/item/ReliquaryItems.java b/src/Java/gtPlusPlus/xmod/reliquary/item/ReliquaryItems.java new file mode 100644 index 0000000000..c0db095346 --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/reliquary/item/ReliquaryItems.java @@ -0,0 +1,161 @@ +package gtPlusPlus.xmod.reliquary.item; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import xreliquary.Reliquary; + +public class ReliquaryItems { + + private static Class CLASS_MAIN = ReflectionUtils.getClass("xreliquary.Reliquary"); + private static Field FIELD_CONTENT = ReflectionUtils.getField(CLASS_MAIN, "CONTENT"); + private static Object OBJECT_CONTENT = ReflectionUtils.getFieldValue(FIELD_CONTENT); + private static Method METHOD_GETITEM = ReflectionUtils.getMethod(OBJECT_CONTENT, "getItem", new Class[] {String.class}); + + public static Item getItem(String name) { + try { + return (Item) METHOD_GETITEM.invoke(OBJECT_CONTENT, name); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + } + return null; + } + + public static ItemStack emptyVoidTear() { + return new ItemStack(getItem("void_tear_empty"), 1, 0); + } + + public static ItemStack glowingWater() { + return new ItemStack(getItem("glowing_water")); + } + + public static ItemStack emptyVial() { + return new ItemStack(Reliquary.CONTENT.getItem("potion"), 1, 0); + } + + public static ItemStack emperorChalice() { + return new ItemStack(getItem("emperor_chalice")); + } + + public static ItemStack infernalChalice() { + return new ItemStack(getItem("infernal_chalice")); + } + + public static ItemStack witherSkull() { + return new ItemStack(Items.skull, 1, 1); + } + + public static ItemStack roseBush() { + return new ItemStack(Blocks.double_plant, 1, 4); + } + + public static ItemStack blackWool() { + return new ItemStack(Blocks.wool, 1, 15); + } + + public static ItemStack lapis() { + return new ItemStack(Items.dye, 1, 4); + } + + public static ItemStack gunPart(int i, int m) { + return new ItemStack(getItem("gun_part"), i, m); + } + + public static ItemStack magazine(int m) { + return magazine(1, m); + } + + public static ItemStack magazine(int i, int m) { + return new ItemStack(getItem("magazine"), i, m); + } + + public static ItemStack bullet(int m) { + return bullet(1, m); + } + + public static ItemStack bullet(int i, int m) { + return new ItemStack(getItem("bullet"), i, m); + } + + public static ItemStack ingredient(int m) { + return new ItemStack(getItem("mob_ingredient"), 1, m); + } + + public static ItemStack enderHeart() { + return ingredient(11); + } + + public static ItemStack creeperGland() { + return ingredient(3); + } + + public static ItemStack slimePearl() { + return ingredient(4); + } + + public static ItemStack batWing() { + return ingredient(5); + } + + public static ItemStack ribBone() { + return ingredient(0); + } + + public static ItemStack witherRib() { + return ingredient(1); + } + + public static ItemStack stormEye() { + return ingredient(8); + } + + public static ItemStack fertileEssence() { + return ingredient(9); + } + + public static ItemStack frozenCore() { + return ingredient(10); + } + + public static ItemStack moltenCore() { + return ingredient(7); + } + + public static ItemStack zombieHeart() { + return ingredient(6); + } + + public static ItemStack infernalClaw() { + return ingredient(13); + } + + public static ItemStack shellFragment() { + return ingredient(14); + } + + public static ItemStack squidBeak() { + return ingredient(12); + } + + public static ItemStack spiderFangs() { + return ingredient(2); + } + + public static ItemStack heartPearl(int m) { + return new ItemStack(getItem("heart_pearl"), 1, m); + } + + public static ItemStack nianZhu(int m) { + return new ItemStack(getItem("heart_zhu"), 1, m); + } + + public static ItemStack emptyVoidSatchel() { + return new ItemStack(getItem("void_tear_empty"), 1, 0); + } + +} diff --git a/src/Java/gtPlusPlus/xmod/reliquary/util/AlkahestRecipeWrapper.java b/src/Java/gtPlusPlus/xmod/reliquary/util/AlkahestRecipeWrapper.java new file mode 100644 index 0000000000..6086b74ec4 --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/reliquary/util/AlkahestRecipeWrapper.java @@ -0,0 +1,47 @@ +package gtPlusPlus.xmod.reliquary.util; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.item.ItemStack; + +public class AlkahestRecipeWrapper { + public ItemStack item = null; + public int yield = 0; + public int cost = 0; + public String dictionaryName = null; + + public AlkahestRecipeWrapper(ItemStack par1, int par2, int par3) { + this.item = par1; + this.yield = par2; + this.cost = par3; + } + + public AlkahestRecipeWrapper(String par1, int par2, int par3) { + this.dictionaryName = par1; + this.yield = par2; + this.cost = par3; + } + + public Object getOriginalRecipe() { + try { + Constructor o; + if (dictionaryName == null) { + o = ReflectionUtils.getClass("xreliquary.util.alkahestry.AlkahestRecipe").getConstructor(ItemStack.class, int.class, int.class); + } + else { + o = ReflectionUtils.getClass("xreliquary.util.alkahestry.AlkahestRecipe").getConstructor(String.class, int.class, int.class); + } + + Object r = o.newInstance(dictionaryName == null ? item : dictionaryName, yield, cost); + if (r != null) { + return r; + } + + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // oops + } + return null; + } +} \ No newline at end of file diff --git a/src/Java/gtPlusPlus/xmod/reliquary/util/ReliquaryRecipeHandler.java b/src/Java/gtPlusPlus/xmod/reliquary/util/ReliquaryRecipeHandler.java new file mode 100644 index 0000000000..b79a4f45a5 --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/reliquary/util/ReliquaryRecipeHandler.java @@ -0,0 +1,57 @@ +package gtPlusPlus.xmod.reliquary.util; + +import static gtPlusPlus.core.lib.CORE.GTNH; + +import gregtech.api.enums.GT_Values; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.util.GT_ModHandler; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.material.ALLOY; +import gtPlusPlus.core.recipe.common.CI; +import gtPlusPlus.core.util.minecraft.FluidUtils; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.xmod.reliquary.item.ReliquaryItems; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +public class ReliquaryRecipeHandler { + + public static boolean removeAlkahestRecipe(ItemStack aOutput) { + return false; + } + + public static boolean addAlkahestRecipe(ItemStack[] aInputs, ItemStack aOutput) { + if (aInputs == null || aInputs.length <= 0 || aInputs.length > 9) { + return false; + } + return false; + } + + public static void gregifyDefaultRecipes() { + Logger.INFO("Gregifying Reliquary recipes."); + if (GT_ModHandler.removeRecipeByOutput(ReliquaryItems.glowingWater())) { + Logger.INFO("Removing recipe for Glowing Water."); + } + if (GT_ModHandler.removeRecipeByOutput(ReliquaryItems.emptyVoidTear())) { + Logger.INFO("Removing recipe for Empty Void Tears."); + } + if (GT_ModHandler.removeRecipeByOutput(ReliquaryItems.emperorChalice())) { + Logger.INFO("Removing recipe for the Emperor Chalice."); + } + if (GT_ModHandler.removeRecipeByOutput(ReliquaryItems.infernalChalice())) { + Logger.INFO("Removing recipe for the Infernal Chalice."); + } + Logger.INFO("Finished removing original recipes."); + + // Add new recipes + if (GT_Values.RA.addChemicalRecipe(ALLOY.ENERGYCRYSTAL.getDust(4), ReliquaryItems.emptyVial(), FluidUtils.getHotWater(2000), null, ReliquaryItems.glowingWater(), 20 * 30, 500)) { + Logger.INFO("Added new recipe for Glowing Water."); + } + if (CORE.RA.addSixSlotAssemblingRecipe(new ItemStack[] {ItemUtils.simpleMetaStack(Items.ender_eye, 0, 32), CI.getFieldGenerator(5, GTNH ? 8 : 4), CI.getTieredComponent(OrePrefixes.plate, 5, GTNH ? 16 : 8), CI.getEmitter(3, 20)}, FluidUtils.getUUM(50), ReliquaryItems.emptyVoidTear(), 20 * 2000, 2000)){ + Logger.INFO("Added new recipe for Empty Void Tears."); + } + Logger.INFO("Finished adding new recipes."); + + } +} -- cgit