diff --git a/src/main/java/mod/acgaming/spackenmobs/entities/EntityBakaMitaiCreeper.java b/src/main/java/mod/acgaming/spackenmobs/entities/EntityBakaMitaiCreeper.java index 65c564b..341e0c4 100644 --- a/src/main/java/mod/acgaming/spackenmobs/entities/EntityBakaMitaiCreeper.java +++ b/src/main/java/mod/acgaming/spackenmobs/entities/EntityBakaMitaiCreeper.java @@ -96,7 +96,7 @@ public class EntityBakaMitaiCreeper extends EntityMob { super.writeEntityToNBT(compound); - if ((Boolean) this.dataManager.get(POWERED)) + if (this.dataManager.get(POWERED)) { compound.setBoolean("powered", true); } diff --git a/src/main/java/mod/acgaming/spackenmobs/entities/EntityITbyHF.java b/src/main/java/mod/acgaming/spackenmobs/entities/EntityITbyHF.java new file mode 100644 index 0000000..76a9682 --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/entities/EntityITbyHF.java @@ -0,0 +1,64 @@ +package mod.acgaming.spackenmobs.entities; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.*; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.world.World; +import net.minecraft.world.storage.loot.LootTableList; + +import javax.annotation.Nullable; + +public class EntityITbyHF extends EntityCreature +{ + public EntityITbyHF(World worldIn) + { + super(worldIn); + this.setSize(0.6F, 2.0F); + } + + protected void initEntityAI() + { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAvoidEntity(this, EntityLatinTeacher.class, 12.0F, 0.8D, 0.8D)); + this.tasks.addTask(2, new EntityAIMoveIndoors(this)); + this.tasks.addTask(3, new EntityAIRestrictOpenDoor(this)); + this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 0.6D)); + this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F)); + this.tasks.addTask(9, new EntityAIWanderAvoidWater(this, 0.6D)); + this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.5D); + } + + protected void entityInit() + { + super.entityInit(); + } + + protected SoundEvent getHurtSound(DamageSource damageSourceIn) + { + return SoundEvents.ENTITY_VILLAGER_HURT; + } + + protected SoundEvent getDeathSound() + { + return SoundEvents.ENTITY_VILLAGER_DEATH; + } + + @Nullable + protected ResourceLocation getLootTable() + { + return LootTableList.ENTITIES_VILLAGER; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/entities/EntityJens.java b/src/main/java/mod/acgaming/spackenmobs/entities/EntityJens.java index 67b39d9..d851e34 100644 --- a/src/main/java/mod/acgaming/spackenmobs/entities/EntityJens.java +++ b/src/main/java/mod/acgaming/spackenmobs/entities/EntityJens.java @@ -48,7 +48,7 @@ public class EntityJens extends EntityAnimal public EntityJens(World worldIn) { super(worldIn); - this.setSize(0.6F, 2.0F); + this.setSize(0.6F, 1.8F); } @Override diff --git a/src/main/java/mod/acgaming/spackenmobs/entities/EntityJensWither.java b/src/main/java/mod/acgaming/spackenmobs/entities/EntityJensWither.java new file mode 100644 index 0000000..b1e3c31 --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/entities/EntityJensWither.java @@ -0,0 +1,708 @@ +package mod.acgaming.spackenmobs.entities; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.*; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.entity.projectile.EntityWitherSkull; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.pathfinding.PathNavigateGround; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EntitySelectors; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; + +public class EntityJensWither extends EntityMob implements IRangedAttackMob +{ + private static final DataParameter FIRST_HEAD_TARGET = EntityDataManager.createKey(EntityJensWither.class, DataSerializers.VARINT); + private static final DataParameter SECOND_HEAD_TARGET = EntityDataManager.createKey(EntityJensWither.class, DataSerializers.VARINT); + private static final DataParameter THIRD_HEAD_TARGET = EntityDataManager.createKey(EntityJensWither.class, DataSerializers.VARINT); + private static final DataParameter[] HEAD_TARGETS = new DataParameter[]{FIRST_HEAD_TARGET, SECOND_HEAD_TARGET, THIRD_HEAD_TARGET}; + private static final DataParameter INVULNERABILITY_TIME = EntityDataManager.createKey(EntityJensWither.class, DataSerializers.VARINT); + /** + * Selector used to determine the entities a wither boss should attack. + */ + private static final Predicate NOT_UNDEAD = p_apply_1_ -> p_apply_1_ instanceof EntityLivingBase && ((EntityLivingBase) p_apply_1_).getCreatureAttribute() != EnumCreatureAttribute.UNDEAD && ((EntityLivingBase) p_apply_1_).attackable(); + private final float[] xRotationHeads = new float[2]; + private final float[] yRotationHeads = new float[2]; + private final float[] xRotOHeads = new float[2]; + private final float[] yRotOHeads = new float[2]; + private final int[] nextHeadUpdate = new int[2]; + private final int[] idleHeadUpdates = new int[2]; + private final BossInfoServer bossInfo = (BossInfoServer) (new BossInfoServer(this.getDisplayName(), BossInfo.Color.PURPLE, BossInfo.Overlay.PROGRESS)).setDarkenSky(true); + /** + * Time before the Wither tries to break blocks + */ + private int blockBreakCounter; + + public EntityJensWither(World worldIn) + { + super(worldIn); + this.setHealth(this.getMaxHealth()); + this.setSize(0.9F, 3.5F); + this.isImmuneToFire = true; + ((PathNavigateGround) this.getNavigator()).setCanSwim(true); + this.experienceValue = 50; + } + + public static boolean canDestroyBlock(Block blockIn) + { + return blockIn != Blocks.BEDROCK && blockIn != Blocks.END_PORTAL && blockIn != Blocks.END_PORTAL_FRAME && blockIn != Blocks.COMMAND_BLOCK && blockIn != Blocks.REPEATING_COMMAND_BLOCK && blockIn != Blocks.CHAIN_COMMAND_BLOCK && blockIn != Blocks.BARRIER && blockIn != Blocks.STRUCTURE_BLOCK && blockIn != Blocks.STRUCTURE_VOID && blockIn != Blocks.PISTON_EXTENSION && blockIn != Blocks.END_GATEWAY; + } + + protected void initEntityAI() + { + this.tasks.addTask(0, new EntityJensWither.AIDoNothing()); + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIAttackRanged(this, 1.0D, 40, 20.0F)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, false, NOT_UNDEAD)); + } + + protected void entityInit() + { + super.entityInit(); + this.dataManager.register(FIRST_HEAD_TARGET, 0); + this.dataManager.register(SECOND_HEAD_TARGET, 0); + this.dataManager.register(THIRD_HEAD_TARGET, 0); + this.dataManager.register(INVULNERABILITY_TIME, 0); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound compound) + { + super.writeEntityToNBT(compound); + compound.setInteger("Invul", this.getInvulTime()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound compound) + { + super.readEntityFromNBT(compound); + this.setInvulTime(compound.getInteger("Invul")); + + if (this.hasCustomName()) + { + this.bossInfo.setName(this.getDisplayName()); + } + } + + /** + * Sets the custom name tag for this entity + */ + public void setCustomNameTag(String name) + { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); + } + + protected SoundEvent getAmbientSound() + { + return SoundEvents.ENTITY_WITHER_AMBIENT; + } + + protected SoundEvent getHurtSound(DamageSource damageSourceIn) + { + return SoundEvents.ENTITY_WITHER_HURT; + } + + protected SoundEvent getDeathSound() + { + return SoundEvents.ENTITY_WITHER_DEATH; + } + + /** + * 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. + */ + public void onLivingUpdate() + { + this.motionY *= 0.6000000238418579D; + + if (!this.world.isRemote && this.getWatchedTargetId(0) > 0) + { + Entity entity = this.world.getEntityByID(this.getWatchedTargetId(0)); + + if (entity != null) + { + if (this.posY < entity.posY || !this.isArmored() && this.posY < entity.posY + 5.0D) + { + if (this.motionY < 0.0D) + { + this.motionY = 0.0D; + } + + this.motionY += (0.5D - this.motionY) * 0.6000000238418579D; + } + + double d0 = entity.posX - this.posX; + double d1 = entity.posZ - this.posZ; + double d3 = d0 * d0 + d1 * d1; + + if (d3 > 9.0D) + { + double d5 = MathHelper.sqrt(d3); + this.motionX += (d0 / d5 * 0.5D - this.motionX) * 0.6000000238418579D; + this.motionZ += (d1 / d5 * 0.5D - this.motionZ) * 0.6000000238418579D; + } + } + } + + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 0.05000000074505806D) + { + this.rotationYaw = (float) MathHelper.atan2(this.motionZ, this.motionX) * (180F / (float) Math.PI) - 90.0F; + } + + super.onLivingUpdate(); + + for (int i = 0; i < 2; ++i) + { + this.yRotOHeads[i] = this.yRotationHeads[i]; + this.xRotOHeads[i] = this.xRotationHeads[i]; + } + + for (int j = 0; j < 2; ++j) + { + int k = this.getWatchedTargetId(j + 1); + Entity entity1 = null; + + if (k > 0) + { + entity1 = this.world.getEntityByID(k); + } + + if (entity1 != null) + { + double d11 = this.getHeadX(j + 1); + double d12 = this.getHeadY(j + 1); + double d13 = this.getHeadZ(j + 1); + double d6 = entity1.posX - d11; + double d7 = entity1.posY + (double) entity1.getEyeHeight() - d12; + double d8 = entity1.posZ - d13; + double d9 = MathHelper.sqrt(d6 * d6 + d8 * d8); + float f = (float) (MathHelper.atan2(d8, d6) * (180D / Math.PI)) - 90.0F; + float f1 = (float) (-(MathHelper.atan2(d7, d9) * (180D / Math.PI))); + this.xRotationHeads[j] = this.rotlerp(this.xRotationHeads[j], f1, 40.0F); + this.yRotationHeads[j] = this.rotlerp(this.yRotationHeads[j], f, 10.0F); + } else + { + this.yRotationHeads[j] = this.rotlerp(this.yRotationHeads[j], this.renderYawOffset, 10.0F); + } + } + + boolean flag = this.isArmored(); + + for (int l = 0; l < 3; ++l) + { + double d10 = this.getHeadX(l); + double d2 = this.getHeadY(l); + double d4 = this.getHeadZ(l); + this.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d10 + this.rand.nextGaussian() * 0.30000001192092896D, d2 + this.rand.nextGaussian() * 0.30000001192092896D, d4 + this.rand.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D); + + if (flag && this.world.rand.nextInt(4) == 0) + { + this.world.spawnParticle(EnumParticleTypes.SPELL_MOB, d10 + this.rand.nextGaussian() * 0.30000001192092896D, d2 + this.rand.nextGaussian() * 0.30000001192092896D, d4 + this.rand.nextGaussian() * 0.30000001192092896D, 0.699999988079071D, 0.699999988079071D, 0.5D); + } + } + + if (this.getInvulTime() > 0) + { + for (int i1 = 0; i1 < 3; ++i1) + { + this.world.spawnParticle(EnumParticleTypes.SPELL_MOB, this.posX + this.rand.nextGaussian(), this.posY + (double) (this.rand.nextFloat() * 3.3F), this.posZ + this.rand.nextGaussian(), 0.699999988079071D, 0.699999988079071D, 0.8999999761581421D); + } + } + } + + protected void updateAITasks() + { + if (this.getInvulTime() > 0) + { + int j1 = this.getInvulTime() - 1; + + if (j1 <= 0) + { + this.world.newExplosion(this, this.posX, this.posY + (double) this.getEyeHeight(), this.posZ, 7.0F, false, net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)); + this.world.playBroadcastSound(1023, new BlockPos(this), 0); + } + + this.setInvulTime(j1); + + if (this.ticksExisted % 10 == 0) + { + this.heal(10.0F); + } + } else + { + super.updateAITasks(); + + for (int i = 1; i < 3; ++i) + { + if (this.ticksExisted >= this.nextHeadUpdate[i - 1]) + { + this.nextHeadUpdate[i - 1] = this.ticksExisted + 10 + this.rand.nextInt(10); + + if (this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) + { + int j3 = i - 1; + int k3 = this.idleHeadUpdates[i - 1]; + this.idleHeadUpdates[j3] = this.idleHeadUpdates[i - 1] + 1; + + if (k3 > 15) + { + float f = 10.0F; + float f1 = 5.0F; + double d0 = MathHelper.nextDouble(this.rand, this.posX - 10.0D, this.posX + 10.0D); + double d1 = MathHelper.nextDouble(this.rand, this.posY - 5.0D, this.posY + 5.0D); + double d2 = MathHelper.nextDouble(this.rand, this.posZ - 10.0D, this.posZ + 10.0D); + this.launchWitherSkullToCoords(i + 1, d0, d1, d2, true); + this.idleHeadUpdates[i - 1] = 0; + } + } + + int k1 = this.getWatchedTargetId(i); + + if (k1 > 0) + { + Entity entity = this.world.getEntityByID(k1); + + if (entity != null && entity.isEntityAlive() && this.getDistanceSq(entity) <= 900.0D && this.canEntityBeSeen(entity)) + { + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).capabilities.disableDamage) + { + this.updateWatchedTargetId(i, 0); + } else + { + this.launchWitherSkullToEntity(i + 1, (EntityLivingBase) entity); + this.nextHeadUpdate[i - 1] = this.ticksExisted + 40 + this.rand.nextInt(20); + this.idleHeadUpdates[i - 1] = 0; + } + } else + { + this.updateWatchedTargetId(i, 0); + } + } else + { + List list = this.world.getEntitiesWithinAABB(EntityLivingBase.class, this.getEntityBoundingBox().grow(20.0D, 8.0D, 20.0D), Predicates.and(NOT_UNDEAD, EntitySelectors.NOT_SPECTATING)); + + for (int j2 = 0; j2 < 10 && !list.isEmpty(); ++j2) + { + EntityLivingBase entitylivingbase = list.get(this.rand.nextInt(list.size())); + + if (entitylivingbase != this && entitylivingbase.isEntityAlive() && this.canEntityBeSeen(entitylivingbase)) + { + if (entitylivingbase instanceof EntityPlayer) + { + if (!((EntityPlayer) entitylivingbase).capabilities.disableDamage) + { + this.updateWatchedTargetId(i, entitylivingbase.getEntityId()); + } + } else + { + this.updateWatchedTargetId(i, entitylivingbase.getEntityId()); + } + + break; + } + + list.remove(entitylivingbase); + } + } + } + } + + if (this.getAttackTarget() != null) + { + this.updateWatchedTargetId(0, this.getAttackTarget().getEntityId()); + } else + { + this.updateWatchedTargetId(0, 0); + } + + if (this.blockBreakCounter > 0) + { + --this.blockBreakCounter; + + if (this.blockBreakCounter == 0 && net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) + { + int i1 = MathHelper.floor(this.posY); + int l1 = MathHelper.floor(this.posX); + int i2 = MathHelper.floor(this.posZ); + boolean flag = false; + + for (int k2 = -1; k2 <= 1; ++k2) + { + for (int l2 = -1; l2 <= 1; ++l2) + { + for (int j = 0; j <= 3; ++j) + { + int i3 = l1 + k2; + int k = i1 + j; + int l = i2 + l2; + BlockPos blockpos = new BlockPos(i3, k, l); + IBlockState iblockstate = this.world.getBlockState(blockpos); + Block block = iblockstate.getBlock(); + + if (!block.isAir(iblockstate, this.world, blockpos) && block.canEntityDestroy(iblockstate, world, blockpos, this) && net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this, blockpos, iblockstate)) + { + flag = this.world.destroyBlock(blockpos, true) || flag; + } + } + } + } + + if (flag) + { + this.world.playEvent(null, 1022, new BlockPos(this), 0); + } + } + } + + if (this.ticksExisted % 20 == 0) + { + this.heal(1.0F); + } + + this.bossInfo.setPercent(this.getHealth() / this.getMaxHealth()); + } + } + + /** + * Initializes this Wither's explosion sequence and makes it invulnerable. Called immediately after spawning. + */ + public void ignite() + { + this.setInvulTime(220); + this.setHealth(this.getMaxHealth() / 3.0F); + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() + { + } + + /** + * Add the given player to the list of players tracking this entity. For instance, a player may track a boss in + * order to view its associated boss bar. + */ + public void addTrackingPlayer(EntityPlayerMP player) + { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); + } + + /** + * Removes the given player from the list of players tracking this entity. See {@link Entity#addTrackingPlayer} for + * more information on tracking. + */ + public void removeTrackingPlayer(EntityPlayerMP player) + { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); + } + + private double getHeadX(int p_82214_1_) + { + if (p_82214_1_ <= 0) + { + return this.posX; + } else + { + float f = (this.renderYawOffset + (float) (180 * (p_82214_1_ - 1))) * 0.017453292F; + float f1 = MathHelper.cos(f); + return this.posX + (double) f1 * 1.3D; + } + } + + private double getHeadY(int p_82208_1_) + { + return p_82208_1_ <= 0 ? this.posY + 3.0D : this.posY + 2.2D; + } + + private double getHeadZ(int p_82213_1_) + { + if (p_82213_1_ <= 0) + { + return this.posZ; + } else + { + float f = (this.renderYawOffset + (float) (180 * (p_82213_1_ - 1))) * 0.017453292F; + float f1 = MathHelper.sin(f); + return this.posZ + (double) f1 * 1.3D; + } + } + + private float rotlerp(float p_82204_1_, float p_82204_2_, float p_82204_3_) + { + float f = MathHelper.wrapDegrees(p_82204_2_ - p_82204_1_); + + if (f > p_82204_3_) + { + f = p_82204_3_; + } + + if (f < -p_82204_3_) + { + f = -p_82204_3_; + } + + return p_82204_1_ + f; + } + + private void launchWitherSkullToEntity(int p_82216_1_, EntityLivingBase p_82216_2_) + { + this.launchWitherSkullToCoords(p_82216_1_, p_82216_2_.posX, p_82216_2_.posY + (double) p_82216_2_.getEyeHeight() * 0.5D, p_82216_2_.posZ, p_82216_1_ == 0 && this.rand.nextFloat() < 0.001F); + } + + /** + * Launches a Wither skull toward (par2, par4, par6) + */ + private void launchWitherSkullToCoords(int p_82209_1_, double x, double y, double z, boolean invulnerable) + { + this.world.playEvent(null, 1024, new BlockPos(this), 0); + double d0 = this.getHeadX(p_82209_1_); + double d1 = this.getHeadY(p_82209_1_); + double d2 = this.getHeadZ(p_82209_1_); + double d3 = x - d0; + double d4 = y - d1; + double d5 = z - d2; + EntityWitherSkull EntityWitherskull = new EntityWitherSkull(this.world, this, d3, d4, d5); + + if (invulnerable) + { + EntityWitherskull.setInvulnerable(true); + } + + EntityWitherskull.posY = d1; + EntityWitherskull.posX = d0; + EntityWitherskull.posZ = d2; + this.world.spawnEntity(EntityWitherskull); + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) + { + this.launchWitherSkullToEntity(0, target); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource source, float amount) + { + if (this.isEntityInvulnerable(source)) + { + return false; + } else if (source != DamageSource.DROWN && !(source.getTrueSource() instanceof EntityJensWither)) + { + if (this.getInvulTime() > 0 && source != DamageSource.OUT_OF_WORLD) + { + return false; + } else + { + if (this.isArmored()) + { + Entity entity = source.getImmediateSource(); + + if (entity instanceof EntityArrow) + { + return false; + } + } + + Entity entity1 = source.getTrueSource(); + + if (!(entity1 instanceof EntityPlayer) && entity1 instanceof EntityLivingBase && ((EntityLivingBase) entity1).getCreatureAttribute() == this.getCreatureAttribute()) + { + return false; + } else + { + if (this.blockBreakCounter <= 0) + { + this.blockBreakCounter = 20; + } + + for (int i = 0; i < this.idleHeadUpdates.length; ++i) + { + this.idleHeadUpdates[i] += 3; + } + + return super.attackEntityFrom(source, amount); + } + } + } else + { + return false; + } + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) + { + EntityItem entityitem = this.dropItem(Items.NETHER_STAR, 1); + + if (entityitem != null) + { + entityitem.setNoDespawn(); + } + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() + { + this.idleTime = 0; + } + + @SideOnly(Side.CLIENT) + public int getBrightnessForRender() + { + return 15728880; + } + + public void fall(float distance, float damageMultiplier) + { + } + + /** + * adds a PotionEffect to the entity + */ + public void addPotionEffect(PotionEffect potioneffectIn) + { + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(300.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.6000000238418579D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(4.0D); + } + + @SideOnly(Side.CLIENT) + public float getHeadYRotation(int p_82207_1_) + { + return this.yRotationHeads[p_82207_1_]; + } + + @SideOnly(Side.CLIENT) + public float getHeadXRotation(int p_82210_1_) + { + return this.xRotationHeads[p_82210_1_]; + } + + public int getInvulTime() + { + return this.dataManager.get(INVULNERABILITY_TIME); + } + + public void setInvulTime(int time) + { + this.dataManager.set(INVULNERABILITY_TIME, time); + } + + /** + * Returns the target entity ID if present, or -1 if not @param par1 The target offset, should be from 0-2 + */ + public int getWatchedTargetId(int head) + { + return this.dataManager.get(HEAD_TARGETS[head]); + } + + /** + * Updates the target entity ID + */ + public void updateWatchedTargetId(int targetOffset, int newId) + { + this.dataManager.set(HEAD_TARGETS[targetOffset], newId); + } + + /** + * Returns whether the wither is armored with its boss armor or not by checking whether its health is below half of + * its maximum. + */ + public boolean isArmored() + { + return this.getHealth() <= this.getMaxHealth() / 2.0F; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() + { + return EnumCreatureAttribute.UNDEAD; + } + + protected boolean canBeRidden(Entity entityIn) + { + return false; + } + + /** + * Returns false if this Entity is a boss, true otherwise. + */ + public boolean isNonBoss() + { + return false; + } + + public void setSwingingArms(boolean swingingArms) + { + } + + class AIDoNothing extends EntityAIBase + { + public AIDoNothing() + { + this.setMutexBits(7); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() + { + return EntityJensWither.this.getInvulTime() > 0; + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/entities/EntityLatinTeacher.java b/src/main/java/mod/acgaming/spackenmobs/entities/EntityLatinTeacher.java new file mode 100644 index 0000000..359f046 --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/entities/EntityLatinTeacher.java @@ -0,0 +1,247 @@ +package mod.acgaming.spackenmobs.entities; + +import mod.acgaming.spackenmobs.misc.ModSoundEvents; +import net.minecraft.block.material.Material; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IRangedAttackMob; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.*; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityPotion; +import net.minecraft.init.Items; +import net.minecraft.init.MobEffects; +import net.minecraft.init.PotionTypes; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.potion.PotionEffect; +import net.minecraft.potion.PotionType; +import net.minecraft.potion.PotionUtils; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.storage.loot.LootTableList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.UUID; + +public class EntityLatinTeacher extends EntityMob implements IRangedAttackMob +{ + private static final UUID MODIFIER_UUID = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); + private static final AttributeModifier MODIFIER = (new AttributeModifier(MODIFIER_UUID, "Drinking speed penalty", -0.25D, 0)).setSaved(false); + private static final DataParameter IS_DRINKING = EntityDataManager.createKey(EntityLatinTeacher.class, DataSerializers.BOOLEAN); + + private int potionUseTimer; + + public EntityLatinTeacher(World worldIn) + { + super(worldIn); + this.setSize(0.6F, 1.95F); + } + + protected void initEntityAI() + { + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIAttackRanged(this, 1.0D, 60, 10.0F)); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityITbyHF.class, 8.0F)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityITbyHF.class, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, true)); + } + + protected void entityInit() + { + super.entityInit(); + this.getDataManager().register(IS_DRINKING, Boolean.FALSE); + } + + protected SoundEvent getAmbientSound() + { + return ModSoundEvents.ENTITY_LATINTEACHER_AMBIENT; + } + + protected SoundEvent getHurtSound(DamageSource damageSourceIn) + { + return SoundEvents.ENTITY_WITCH_HURT; + } + + protected SoundEvent getDeathSound() + { + return SoundEvents.ENTITY_WITCH_DEATH; + } + + public boolean isDrinkingPotion() + { + return this.getDataManager().get(IS_DRINKING); + } + + public void setDrinkingPotion(boolean drinkingPotion) + { + this.getDataManager().set(IS_DRINKING, drinkingPotion); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(26.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D); + } + + public void onLivingUpdate() + { + if (!this.world.isRemote) + { + if (this.isDrinkingPotion()) + { + if (this.potionUseTimer-- <= 0) + { + this.setDrinkingPotion(false); + ItemStack itemstack = this.getHeldItemMainhand(); + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, ItemStack.EMPTY); + + if (itemstack.getItem() == Items.POTIONITEM) + { + List list = PotionUtils.getEffectsFromStack(itemstack); + + if (list != null) + { + for (PotionEffect potioneffect : list) + { + this.addPotionEffect(new PotionEffect(potioneffect)); + } + } + } + + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(MODIFIER); + } + } else + { + PotionType potiontype = null; + + if (this.rand.nextFloat() < 0.15F && this.isInsideOfMaterial(Material.WATER) && !this.isPotionActive(MobEffects.WATER_BREATHING)) + { + potiontype = PotionTypes.WATER_BREATHING; + } else if (this.rand.nextFloat() < 0.15F && (this.isBurning() || this.getLastDamageSource() != null && this.getLastDamageSource().isFireDamage()) && !this.isPotionActive(MobEffects.FIRE_RESISTANCE)) + { + potiontype = PotionTypes.FIRE_RESISTANCE; + } else if (this.rand.nextFloat() < 0.05F && this.getHealth() < this.getMaxHealth()) + { + potiontype = PotionTypes.HEALING; + } else if (this.rand.nextFloat() < 0.5F && this.getAttackTarget() != null && !this.isPotionActive(MobEffects.SPEED) && this.getAttackTarget().getDistanceSq(this) > 121.0D) + { + potiontype = PotionTypes.SWIFTNESS; + } + + if (potiontype != null) + { + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, PotionUtils.addPotionToItemStack(new ItemStack(Items.POTIONITEM), potiontype)); + this.potionUseTimer = this.getHeldItemMainhand().getMaxItemUseDuration(); + this.setDrinkingPotion(true); + this.world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.rand.nextFloat() * 0.4F); + IAttributeInstance iattributeinstance = this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); + iattributeinstance.removeModifier(MODIFIER); + iattributeinstance.applyModifier(MODIFIER); + } + } + + if (this.rand.nextFloat() < 7.5E-4F) + { + this.world.setEntityState(this, (byte) 15); + } + } + + super.onLivingUpdate(); + } + + @SideOnly(Side.CLIENT) + public void handleStatusUpdate(byte id) + { + if (id == 15) + { + for (int i = 0; i < this.rand.nextInt(35) + 10; ++i) + { + this.world.spawnParticle(EnumParticleTypes.SPELL_WITCH, this.posX + this.rand.nextGaussian() * 0.12999999523162842D, this.getEntityBoundingBox().maxY + 0.5D + this.rand.nextGaussian() * 0.12999999523162842D, this.posZ + this.rand.nextGaussian() * 0.12999999523162842D, 0.0D, 0.0D, 0.0D); + } + } else + { + super.handleStatusUpdate(id); + } + } + + protected float applyPotionDamageCalculations(DamageSource source, float damage) + { + damage = super.applyPotionDamageCalculations(source, damage); + + if (source.getTrueSource() == this) + { + damage = 0.0F; + } + + if (source.isMagicDamage()) + { + damage = (float) ((double) damage * 0.15D); + } + + return damage; + } + + @Nullable + protected ResourceLocation getLootTable() + { + return LootTableList.ENTITIES_WITCH; + } + + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) + { + if (!this.isDrinkingPotion()) + { + double d0 = target.posY + (double) target.getEyeHeight() - 1.100000023841858D; + double d1 = target.posX + target.motionX - this.posX; + double d2 = d0 - this.posY; + double d3 = target.posZ + target.motionZ - this.posZ; + float f = MathHelper.sqrt(d1 * d1 + d3 * d3); + PotionType potiontype = PotionTypes.HARMING; + + if (f >= 8.0F && !target.isPotionActive(MobEffects.SLOWNESS)) + { + potiontype = PotionTypes.SLOWNESS; + } else if (target.getHealth() >= 8.0F && !target.isPotionActive(MobEffects.POISON)) + { + potiontype = PotionTypes.POISON; + } else if (f <= 3.0F && !target.isPotionActive(MobEffects.WEAKNESS) && this.rand.nextFloat() < 0.25F) + { + potiontype = PotionTypes.WEAKNESS; + } + + EntityPotion entitypotion = new EntityPotion(this.world, this, PotionUtils.addPotionToItemStack(new ItemStack(Items.SPLASH_POTION), potiontype)); + entitypotion.rotationPitch -= -20.0F; + entitypotion.shoot(d1, d2 + (double) (f * 0.2F), d3, 0.75F, 8.0F); + this.world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_WITCH_THROW, this.getSoundCategory(), 1.0F, 0.8F + this.rand.nextFloat() * 0.4F); + this.world.spawnEntity(entitypotion); + } + } + + public float getEyeHeight() + { + return 1.62F; + } + + public void setSwingingArms(boolean swingingArms) + { + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/entities/EntityTileraGhast.java b/src/main/java/mod/acgaming/spackenmobs/entities/EntityTileraGhast.java new file mode 100644 index 0000000..9392228 --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/entities/EntityTileraGhast.java @@ -0,0 +1,374 @@ +package mod.acgaming.spackenmobs.entities; + +import net.minecraft.entity.EntityFlying; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityAIFindEntityNearestPlayer; +import net.minecraft.entity.ai.EntityMoveHelper; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityLargeFireball; +import net.minecraft.init.SoundEvents; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.World; +import net.minecraft.world.storage.loot.LootTableList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; +import java.util.Random; + +public class EntityTileraGhast extends EntityFlying implements IMob +{ + private static final DataParameter ATTACKING = EntityDataManager.createKey(EntityTileraGhast.class, DataSerializers.BOOLEAN); + private int explosionStrength = 1; + + public EntityTileraGhast(World worldIn) + { + super(worldIn); + this.setSize(4.0F, 4.0F); + this.isImmuneToFire = true; + this.experienceValue = 5; + this.moveHelper = new GhastMoveHelper(this); + } + + protected void initEntityAI() + { + this.tasks.addTask(5, new AIRandomFly(this)); + this.tasks.addTask(7, new AILookAround(this)); + this.tasks.addTask(7, new AIFireballAttack(this)); + this.targetTasks.addTask(1, new EntityAIFindEntityNearestPlayer(this)); + } + + @SideOnly(Side.CLIENT) + public boolean isAttacking() + { + return this.dataManager.get(ATTACKING); + } + + public void setAttacking(boolean attacking) + { + this.dataManager.set(ATTACKING, attacking); + } + + public int getFireballStrength() + { + return this.explosionStrength; + } + + public void onUpdate() + { + super.onUpdate(); + + if (!this.world.isRemote && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) + { + this.setDead(); + } + } + + public boolean attackEntityFrom(DamageSource source, float amount) + { + if (this.isEntityInvulnerable(source)) + { + return false; + } else if (source.getImmediateSource() instanceof EntityLargeFireball && source.getTrueSource() instanceof EntityPlayer) + { + super.attackEntityFrom(source, 1000.0F); + return true; + } else + { + return super.attackEntityFrom(source, amount); + } + } + + protected void entityInit() + { + super.entityInit(); + this.dataManager.register(ATTACKING, Boolean.FALSE); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(100.0D); + } + + public SoundCategory getSoundCategory() + { + return SoundCategory.HOSTILE; + } + + protected SoundEvent getAmbientSound() + { + return SoundEvents.ENTITY_GHAST_AMBIENT; + } + + protected SoundEvent getHurtSound(DamageSource damageSourceIn) + { + return SoundEvents.ENTITY_GHAST_HURT; + } + + protected SoundEvent getDeathSound() + { + return SoundEvents.ENTITY_GHAST_DEATH; + } + + @Nullable + protected ResourceLocation getLootTable() + { + return LootTableList.ENTITIES_GHAST; + } + + protected float getSoundVolume() + { + return 10.0F; + } + + public boolean getCanSpawnHere() + { + return this.rand.nextInt(20) == 0 && super.getCanSpawnHere() && this.world.getDifficulty() != EnumDifficulty.PEACEFUL; + } + + public int getMaxSpawnedInChunk() + { + return 1; + } + + public void writeEntityToNBT(NBTTagCompound compound) + { + super.writeEntityToNBT(compound); + compound.setInteger("ExplosionPower", this.explosionStrength); + } + + public void readEntityFromNBT(NBTTagCompound compound) + { + super.readEntityFromNBT(compound); + + if (compound.hasKey("ExplosionPower", 99)) + { + this.explosionStrength = compound.getInteger("ExplosionPower"); + } + } + + public float getEyeHeight() + { + return 2.6F; + } + + static class AIFireballAttack extends EntityAIBase + { + private final EntityTileraGhast parentEntity; + public int attackTimer; + + public AIFireballAttack(EntityTileraGhast ghast) + { + this.parentEntity = ghast; + } + + public boolean shouldExecute() + { + return this.parentEntity.getAttackTarget() != null; + } + + public void startExecuting() + { + this.attackTimer = 0; + } + + public void resetTask() + { + this.parentEntity.setAttacking(false); + } + + public void updateTask() + { + EntityLivingBase entitylivingbase = this.parentEntity.getAttackTarget(); + double d0 = 64.0D; + + if (entitylivingbase.getDistanceSq(this.parentEntity) < 4096.0D && this.parentEntity.canEntityBeSeen(entitylivingbase)) + { + World world = this.parentEntity.world; + ++this.attackTimer; + + if (this.attackTimer == 10) + { + world.playEvent(null, 1015, new BlockPos(this.parentEntity), 0); + } + + if (this.attackTimer == 20) + { + double d1 = 4.0D; + Vec3d vec3d = this.parentEntity.getLook(1.0F); + double d2 = entitylivingbase.posX - (this.parentEntity.posX + vec3d.x * 4.0D); + double d3 = entitylivingbase.getEntityBoundingBox().minY + (double) (entitylivingbase.height / 2.0F) - (0.5D + this.parentEntity.posY + (double) (this.parentEntity.height / 2.0F)); + double d4 = entitylivingbase.posZ - (this.parentEntity.posZ + vec3d.z * 4.0D); + world.playEvent(null, 1016, new BlockPos(this.parentEntity), 0); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(world, this.parentEntity, d2, d3, d4); + entitylargefireball.explosionPower = this.parentEntity.getFireballStrength(); + entitylargefireball.posX = this.parentEntity.posX + vec3d.x * 4.0D; + entitylargefireball.posY = this.parentEntity.posY + (double) (this.parentEntity.height / 2.0F) + 0.5D; + entitylargefireball.posZ = this.parentEntity.posZ + vec3d.z * 4.0D; + world.spawnEntity(entitylargefireball); + this.attackTimer = -40; + } + } else if (this.attackTimer > 0) + { + --this.attackTimer; + } + + this.parentEntity.setAttacking(this.attackTimer > 10); + } + } + + static class AILookAround extends EntityAIBase + { + private final EntityTileraGhast parentEntity; + + public AILookAround(EntityTileraGhast ghast) + { + this.parentEntity = ghast; + this.setMutexBits(2); + } + + public boolean shouldExecute() + { + return true; + } + + public void updateTask() + { + if (this.parentEntity.getAttackTarget() == null) + { + this.parentEntity.rotationYaw = -((float) MathHelper.atan2(this.parentEntity.motionX, this.parentEntity.motionZ)) * (180F / (float) Math.PI); + this.parentEntity.renderYawOffset = this.parentEntity.rotationYaw; + } else + { + EntityLivingBase entitylivingbase = this.parentEntity.getAttackTarget(); + double d0 = 64.0D; + + if (entitylivingbase.getDistanceSq(this.parentEntity) < 4096.0D) + { + double d1 = entitylivingbase.posX - this.parentEntity.posX; + double d2 = entitylivingbase.posZ - this.parentEntity.posZ; + this.parentEntity.rotationYaw = -((float) MathHelper.atan2(d1, d2)) * (180F / (float) Math.PI); + this.parentEntity.renderYawOffset = this.parentEntity.rotationYaw; + } + } + } + } + + static class AIRandomFly extends EntityAIBase + { + private final EntityTileraGhast parentEntity; + + public AIRandomFly(EntityTileraGhast ghast) + { + this.parentEntity = ghast; + this.setMutexBits(1); + } + + public boolean shouldExecute() + { + EntityMoveHelper entitymovehelper = this.parentEntity.getMoveHelper(); + + if (!entitymovehelper.isUpdating()) + { + return true; + } else + { + double d0 = entitymovehelper.getX() - this.parentEntity.posX; + double d1 = entitymovehelper.getY() - this.parentEntity.posY; + double d2 = entitymovehelper.getZ() - this.parentEntity.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + return d3 < 1.0D || d3 > 3600.0D; + } + } + + public boolean shouldContinueExecuting() + { + return false; + } + + public void startExecuting() + { + Random random = this.parentEntity.getRNG(); + double d0 = this.parentEntity.posX + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + double d1 = this.parentEntity.posY + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + double d2 = this.parentEntity.posZ + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.parentEntity.getMoveHelper().setMoveTo(d0, d1, d2, 1.0D); + } + } + + static class GhastMoveHelper extends EntityMoveHelper + { + private final EntityTileraGhast parentEntity; + private int courseChangeCooldown; + + public GhastMoveHelper(EntityTileraGhast ghast) + { + super(ghast); + this.parentEntity = ghast; + } + + public void onUpdateMoveHelper() + { + if (this.action == EntityMoveHelper.Action.MOVE_TO) + { + double d0 = this.posX - this.parentEntity.posX; + double d1 = this.posY - this.parentEntity.posY; + double d2 = this.posZ - this.parentEntity.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (this.courseChangeCooldown-- <= 0) + { + this.courseChangeCooldown += this.parentEntity.getRNG().nextInt(5) + 2; + d3 = MathHelper.sqrt(d3); + + if (this.isNotColliding(this.posX, this.posY, this.posZ, d3)) + { + this.parentEntity.motionX += d0 / d3 * 0.1D; + this.parentEntity.motionY += d1 / d3 * 0.1D; + this.parentEntity.motionZ += d2 / d3 * 0.1D; + } else + { + this.action = EntityMoveHelper.Action.WAIT; + } + } + } + } + + private boolean isNotColliding(double x, double y, double z, double p_179926_7_) + { + double d0 = (x - this.parentEntity.posX) / p_179926_7_; + double d1 = (y - this.parentEntity.posY) / p_179926_7_; + double d2 = (z - this.parentEntity.posZ) / p_179926_7_; + AxisAlignedBB axisalignedbb = this.parentEntity.getEntityBoundingBox(); + + for (int i = 1; (double) i < p_179926_7_; ++i) + { + axisalignedbb = axisalignedbb.offset(d0, d1, d2); + + if (!this.parentEntity.world.getCollisionBoxes(this.parentEntity, axisalignedbb).isEmpty()) + { + return false; + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/misc/ModConfigs.java b/src/main/java/mod/acgaming/spackenmobs/misc/ModConfigs.java index f84ae20..f2dd649 100644 --- a/src/main/java/mod/acgaming/spackenmobs/misc/ModConfigs.java +++ b/src/main/java/mod/acgaming/spackenmobs/misc/ModConfigs.java @@ -36,6 +36,13 @@ public class ModConfigs public static boolean SmavaCreeper_spawn = true; @Name("Allow MZTEWolf to spawn?") public static boolean MZTEWolf_spawn = true; + @Name("Allow Latin Teacher to spawn?") + public static boolean LatinTeacher_spawn = true; + @Name("Allow ITbyHF to spawn?") + public static boolean ITbyHF_spawn = true; + @Name("Allow tilera Ghast to spawn?") + public static boolean tileraGhast_spawn = true; + @Name("ApoRed spawn probability:") public static int ApoRed_weight = 15; @Name("ApoRed min group size:") @@ -108,6 +115,25 @@ public class ModConfigs public static int MZTEWolf_min = 1; @Name("MZTEWolf max group size:") public static int MZTEWolf_max = 2; + @Name("Latin Teacher spawn probability:") + public static int LatinTeacher_weight = 15; + @Name("Latin Teacher min group size:") + public static int LatinTeacher_min = 1; + @Name("Latin Teacher max group size:") + public static int LatinTeacher_max = 2; + @Name("ITbyHF spawn probability:") + public static int ITbyHF_weight = 15; + @Name("ITbyHF min group size:") + public static int ITbyHF_min = 1; + @Name("ITbyHF max group size:") + public static int ITbyHF_max = 2; + @Name("tilera Ghast spawn probability:") + public static int tileraGhast_weight = 15; + @Name("tilera Ghast min group size:") + public static int tileraGhast_min = 1; + @Name("tilera Ghast max group size:") + public static int tileraGhast_max = 2; + @Name("Time in seconds Jens needs to digest:") public static int Jens_digest_time = 120; @Name("Maximum distance in blocks Jens can search:") diff --git a/src/main/java/mod/acgaming/spackenmobs/misc/ModEntities.java b/src/main/java/mod/acgaming/spackenmobs/misc/ModEntities.java index bc9080d..bd412b4 100644 --- a/src/main/java/mod/acgaming/spackenmobs/misc/ModEntities.java +++ b/src/main/java/mod/acgaming/spackenmobs/misc/ModEntities.java @@ -14,11 +14,14 @@ public class ModEntities RenderingRegistry.registerEntityRenderingHandler(EntityFriedrichLiechtenstein.class, RenderFriedrichLiechtenstein.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntityHolzstammhuhn.class, RenderHolzstammhuhn.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntityIslamist.class, RenderIslamist.FACTORY); + RenderingRegistry.registerEntityRenderingHandler(EntityITbyHF.class, RenderITbyHF.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntityJens.class, RenderJens.FACTORY); + RenderingRegistry.registerEntityRenderingHandler(EntityLatinTeacher.class, RenderLatinTeacher.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntityMZTEWolf.class, RenderMZTEWolf.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntityMarcellDAvis.class, RenderMarcellDAvis.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntityMrBean.class, RenderMrBean.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntitySchalker.class, RenderSchalker.FACTORY); RenderingRegistry.registerEntityRenderingHandler(EntitySmavaCreeper.class, RenderSmavaCreeper.FACTORY); + RenderingRegistry.registerEntityRenderingHandler(EntityTileraGhast.class, RenderTileraGhast.FACTORY); } } \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/misc/ModSoundEvents.java b/src/main/java/mod/acgaming/spackenmobs/misc/ModSoundEvents.java index 7f675b3..143676e 100644 --- a/src/main/java/mod/acgaming/spackenmobs/misc/ModSoundEvents.java +++ b/src/main/java/mod/acgaming/spackenmobs/misc/ModSoundEvents.java @@ -52,4 +52,6 @@ public class ModSoundEvents public static final SoundEvent ENTITY_FRIEDRICH_AMBIENT = new SoundEvent(new ResourceLocation("spackenmobs:entities.friedrich.ambient")); public static final SoundEvent ENTITY_FRIEDRICH_HURT = new SoundEvent(new ResourceLocation("spackenmobs:entities.friedrich.hurt")); public static final SoundEvent ENTITY_FRIEDRICH_DEATH = new SoundEvent(new ResourceLocation("spackenmobs:entities.friedrich.death")); + + public static final SoundEvent ENTITY_LATINTEACHER_AMBIENT = new SoundEvent(new ResourceLocation("spackenmobs:entities.latin_teacher.ambient")); } \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/misc/RegHandler.java b/src/main/java/mod/acgaming/spackenmobs/misc/RegHandler.java index 7f35dbe..26d648b 100644 --- a/src/main/java/mod/acgaming/spackenmobs/misc/RegHandler.java +++ b/src/main/java/mod/acgaming/spackenmobs/misc/RegHandler.java @@ -4,10 +4,7 @@ import mod.acgaming.spackenmobs.Spackenmobs; import mod.acgaming.spackenmobs.entities.*; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.monster.*; -import net.minecraft.entity.passive.EntityChicken; -import net.minecraft.entity.passive.EntityCow; -import net.minecraft.entity.passive.EntityPig; -import net.minecraft.entity.passive.EntityWolf; +import net.minecraft.entity.passive.*; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; @@ -120,6 +117,27 @@ public class RegHandler { EntityRegistry.addSpawn(EntityFriedrichLiechtenstein.class, ModConfigs.Friedrich_weight, ModConfigs.Friedrich_min, ModConfigs.Friedrich_max, EnumCreatureType.CREATURE, BiomeHelper.getBiomesWithCreature(EntityCow.class)); } + + // Latin Teacher + EntityRegistry.registerModEntity(new ResourceLocation("spackenmobs:latin_teacher"), EntityLatinTeacher.class, "latin_teacher", id++, Spackenmobs.instance, 64, 1, true, 16447728, 15878595); + if (ModConfigs.LatinTeacher_spawn) + { + EntityRegistry.addSpawn(EntityLatinTeacher.class, ModConfigs.LatinTeacher_weight, ModConfigs.LatinTeacher_min, ModConfigs.LatinTeacher_max, EnumCreatureType.MONSTER, BiomeHelper.getBiomesWithMonster(EntityWitch.class)); + } + + // ITbyHF + EntityRegistry.registerModEntity(new ResourceLocation("spackenmobs:itbyhf"), EntityITbyHF.class, "itbyhf", id++, Spackenmobs.instance, 64, 1, true, 16447728, 15878595); + if (ModConfigs.ITbyHF_spawn) + { + EntityRegistry.addSpawn(EntityITbyHF.class, ModConfigs.ITbyHF_weight, ModConfigs.ITbyHF_min, ModConfigs.ITbyHF_max, EnumCreatureType.CREATURE, BiomeHelper.getBiomesWithCreature(EntitySheep.class)); + } + + // tilera Ghast + EntityRegistry.registerModEntity(new ResourceLocation("spackenmobs:tilera_ghast"), EntityTileraGhast.class, "tilera_ghast", id++, Spackenmobs.instance, 64, 1, true, 16447728, 15878595); + if (ModConfigs.tileraGhast_spawn) + { + EntityRegistry.addSpawn(EntityTileraGhast.class, ModConfigs.tileraGhast_weight, ModConfigs.tileraGhast_min, ModConfigs.tileraGhast_max, EnumCreatureType.MONSTER, BiomeHelper.getBiomesWithMonster(EntityGhast.class)); + } } @SubscribeEvent diff --git a/src/main/java/mod/acgaming/spackenmobs/render/LayerHeldItemLatinTeacher.java b/src/main/java/mod/acgaming/spackenmobs/render/LayerHeldItemLatinTeacher.java new file mode 100644 index 0000000..52ba4cd --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/render/LayerHeldItemLatinTeacher.java @@ -0,0 +1,97 @@ +package mod.acgaming.spackenmobs.render; + +import mod.acgaming.spackenmobs.entities.EntityLatinTeacher; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class LayerHeldItemLatinTeacher implements LayerRenderer +{ + private final RenderLatinTeacher latinTeacherRenderer; + + public LayerHeldItemLatinTeacher(RenderLatinTeacher latinTeacherRendererIn) + { + this.latinTeacherRenderer = latinTeacherRendererIn; + } + + public void doRenderLayer(EntityLatinTeacher entitylivingbaseIn, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) + { + ItemStack itemstack = entitylivingbaseIn.getHeldItemMainhand(); + + if (!itemstack.isEmpty()) + { + GlStateManager.color(1.0F, 1.0F, 1.0F); + GlStateManager.pushMatrix(); + + if (this.latinTeacherRenderer.getMainModel().isChild) + { + GlStateManager.translate(0.0F, 0.625F, 0.0F); + GlStateManager.rotate(-20.0F, -1.0F, 0.0F, 0.0F); + float f = 0.5F; + GlStateManager.scale(0.5F, 0.5F, 0.5F); + } + + this.latinTeacherRenderer.getMainModel().villagerNose.postRender(0.0625F); + GlStateManager.translate(-0.0625F, 0.53125F, 0.21875F); + Item item = itemstack.getItem(); + Minecraft minecraft = Minecraft.getMinecraft(); + + if (Block.getBlockFromItem(item).getDefaultState().getRenderType() == EnumBlockRenderType.ENTITYBLOCK_ANIMATED) + { + GlStateManager.translate(0.0F, 0.0625F, -0.25F); + GlStateManager.rotate(30.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(-5.0F, 0.0F, 1.0F, 0.0F); + float f1 = 0.375F; + GlStateManager.scale(0.375F, -0.375F, 0.375F); + } else if (item instanceof net.minecraft.item.ItemBow) + { + GlStateManager.translate(0.0F, 0.125F, -0.125F); + GlStateManager.rotate(-45.0F, 0.0F, 1.0F, 0.0F); + float f2 = 0.625F; + GlStateManager.scale(0.625F, -0.625F, 0.625F); + GlStateManager.rotate(-100.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(-20.0F, 0.0F, 1.0F, 0.0F); + } else if (item.isFull3D()) + { + if (item.shouldRotateAroundWhenRendering()) + { + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.translate(0.0F, -0.0625F, 0.0F); + } + + this.latinTeacherRenderer.transformHeldFull3DItemLayer(); + GlStateManager.translate(0.0625F, -0.125F, 0.0F); + float f3 = 0.625F; + GlStateManager.scale(0.625F, -0.625F, 0.625F); + GlStateManager.rotate(0.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(0.0F, 0.0F, 1.0F, 0.0F); + } else + { + GlStateManager.translate(0.1875F, 0.1875F, 0.0F); + float f4 = 0.875F; + GlStateManager.scale(0.875F, 0.875F, 0.875F); + GlStateManager.rotate(-20.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.rotate(-60.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(-30.0F, 0.0F, 0.0F, 1.0F); + } + + GlStateManager.rotate(-15.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(40.0F, 0.0F, 0.0F, 1.0F); + minecraft.getItemRenderer().renderItem(entitylivingbaseIn, itemstack, ItemCameraTransforms.TransformType.THIRD_PERSON_RIGHT_HAND); + GlStateManager.popMatrix(); + } + } + + public boolean shouldCombineTextures() + { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/render/LayerJensWitherAura.java b/src/main/java/mod/acgaming/spackenmobs/render/LayerJensWitherAura.java new file mode 100644 index 0000000..8ec9da3 --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/render/LayerJensWitherAura.java @@ -0,0 +1,60 @@ +package mod.acgaming.spackenmobs.render; + +import mod.acgaming.spackenmobs.entities.EntityJensWither; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelWither; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class LayerJensWitherAura implements LayerRenderer +{ + private static final ResourceLocation WITHER_ARMOR = new ResourceLocation("textures/entity/wither/wither_armor.png"); + private final RenderJensWither witherRenderer; + private final ModelWither witherModel = new ModelWither(0.5F); + + public LayerJensWitherAura(RenderJensWither witherRendererIn) + { + this.witherRenderer = witherRendererIn; + } + + public void doRenderLayer(EntityJensWither entitylivingbaseIn, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) + { + if (entitylivingbaseIn.isArmored()) + { + GlStateManager.depthMask(!entitylivingbaseIn.isInvisible()); + this.witherRenderer.bindTexture(WITHER_ARMOR); + GlStateManager.matrixMode(5890); + GlStateManager.loadIdentity(); + float f = (float) entitylivingbaseIn.ticksExisted + partialTicks; + float f1 = MathHelper.cos(f * 0.02F) * 3.0F; + float f2 = f * 0.01F; + GlStateManager.translate(f1, f2, 0.0F); + GlStateManager.matrixMode(5888); + GlStateManager.enableBlend(); + float f3 = 0.5F; + GlStateManager.color(0.5F, 0.5F, 0.5F, 1.0F); + GlStateManager.disableLighting(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); + this.witherModel.setLivingAnimations(entitylivingbaseIn, limbSwing, limbSwingAmount, partialTicks); + this.witherModel.setModelAttributes(this.witherRenderer.getMainModel()); + Minecraft.getMinecraft().entityRenderer.setupFogColor(true); + this.witherModel.render(entitylivingbaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + Minecraft.getMinecraft().entityRenderer.setupFogColor(false); + GlStateManager.matrixMode(5890); + GlStateManager.loadIdentity(); + GlStateManager.matrixMode(5888); + GlStateManager.enableLighting(); + GlStateManager.disableBlend(); + } + } + + public boolean shouldCombineTextures() + { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/render/RenderITbyHF.java b/src/main/java/mod/acgaming/spackenmobs/render/RenderITbyHF.java new file mode 100644 index 0000000..dca87aa --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/render/RenderITbyHF.java @@ -0,0 +1,38 @@ +package mod.acgaming.spackenmobs.render; + +import mod.acgaming.spackenmobs.entities.EntityITbyHF; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderBiped; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RenderITbyHF extends RenderBiped +{ + public static final Factory FACTORY = new Factory(); + private static final ResourceLocation ITBYHF_TEXTURE = new ResourceLocation("spackenmobs:textures/entities/itbyhf.png"); + + public RenderITbyHF(RenderManager renderManagerIn) + { + super(renderManagerIn, new ModelBiped(), 0.25F); + } + + @Override + protected ResourceLocation getEntityTexture(EntityITbyHF entity) + { + return ITBYHF_TEXTURE; + } + + private static class Factory implements IRenderFactory + { + @Override + public Render createRenderFor(RenderManager manager) + { + return new RenderITbyHF(manager); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/render/RenderJensWither.java b/src/main/java/mod/acgaming/spackenmobs/render/RenderJensWither.java new file mode 100644 index 0000000..c2dbf1c --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/render/RenderJensWither.java @@ -0,0 +1,42 @@ +package mod.acgaming.spackenmobs.render; + +import mod.acgaming.spackenmobs.entities.EntityJensWither; +import net.minecraft.client.model.ModelWither; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RenderJensWither extends RenderLiving +{ + private static final ResourceLocation INVULNERABLE_JENS_WITHER_TEXTURE = new ResourceLocation("spackenmobs:textures/entities/jens_wither_inv.png"); + private static final ResourceLocation JENS_WITHER_TEXTURE = new ResourceLocation("spackenmobs:textures/entities/jens_wither.png"); + + public RenderJensWither(RenderManager renderManagerIn) + { + super(renderManagerIn, new ModelWither(0.0F), 1.0F); + this.addLayer(new LayerJensWitherAura(this)); + } + + protected ResourceLocation getEntityTexture(EntityJensWither entity) + { + int i = entity.getInvulTime(); + return i > 0 && (i > 80 || i / 5 % 2 != 1) ? INVULNERABLE_JENS_WITHER_TEXTURE : JENS_WITHER_TEXTURE; + } + + protected void preRenderCallback(EntityJensWither entitylivingbaseIn, float partialTickTime) + { + float f = 2.0F; + int i = entitylivingbaseIn.getInvulTime(); + + if (i > 0) + { + f -= ((float) i - partialTickTime) / 220.0F * 0.5F; + } + + GlStateManager.scale(f, f, f); + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/render/RenderLatinTeacher.java b/src/main/java/mod/acgaming/spackenmobs/render/RenderLatinTeacher.java new file mode 100644 index 0000000..ba19d7c --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/render/RenderLatinTeacher.java @@ -0,0 +1,61 @@ +package mod.acgaming.spackenmobs.render; + +import mod.acgaming.spackenmobs.entities.EntityLatinTeacher; +import net.minecraft.client.model.ModelWitch; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RenderLatinTeacher extends RenderLiving +{ + public static final RenderLatinTeacher.Factory FACTORY = new RenderLatinTeacher.Factory(); + private static final ResourceLocation LATINTEACHER_TEXTURE = new ResourceLocation("spackenmobs:textures/entities/latin_teacher.png"); + + public RenderLatinTeacher(RenderManager renderManagerIn) + { + super(renderManagerIn, new ModelWitch(0.0F), 0.5F); + this.addLayer(new LayerHeldItemLatinTeacher(this)); + } + + public ModelWitch getMainModel() + { + return (ModelWitch) super.getMainModel(); + } + + public void doRender(EntityLatinTeacher entity, double x, double y, double z, float entityYaw, float partialTicks) + { + ((ModelWitch) this.mainModel).holdingItem = !entity.getHeldItemMainhand().isEmpty(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + + protected ResourceLocation getEntityTexture(EntityLatinTeacher entity) + { + return LATINTEACHER_TEXTURE; + } + + public void transformHeldFull3DItemLayer() + { + GlStateManager.translate(0.0F, 0.1875F, 0.0F); + } + + protected void preRenderCallback(EntityLatinTeacher entitylivingbaseIn, float partialTickTime) + { + float f = 0.9375F; + GlStateManager.scale(0.9375F, 0.9375F, 0.9375F); + } + + private static class Factory implements IRenderFactory + { + @Override + public Render createRenderFor(RenderManager manager) + { + return new RenderLatinTeacher(manager); + } + } +} \ No newline at end of file diff --git a/src/main/java/mod/acgaming/spackenmobs/render/RenderTileraGhast.java b/src/main/java/mod/acgaming/spackenmobs/render/RenderTileraGhast.java new file mode 100644 index 0000000..d8dd584 --- /dev/null +++ b/src/main/java/mod/acgaming/spackenmobs/render/RenderTileraGhast.java @@ -0,0 +1,48 @@ +package mod.acgaming.spackenmobs.render; + +import mod.acgaming.spackenmobs.entities.EntityTileraGhast; +import net.minecraft.client.model.ModelGhast; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class RenderTileraGhast extends RenderLiving +{ + public static final RenderTileraGhast.Factory FACTORY = new RenderTileraGhast.Factory(); + private static final ResourceLocation TILERA_GHAST_TEXTURE = new ResourceLocation("spackenmobs:textures/entities/tilera_ghast.png"); + private static final ResourceLocation TILERA_GHAST_SHOOTING_TEXTURE = new ResourceLocation("spackenmobs:textures/entities/tilera_ghast_shooting.png"); + + public RenderTileraGhast(RenderManager renderManagerIn) + { + super(renderManagerIn, new ModelGhast(), 0.5F); + } + + protected ResourceLocation getEntityTexture(EntityTileraGhast entity) + { + return entity.isAttacking() ? TILERA_GHAST_SHOOTING_TEXTURE : TILERA_GHAST_TEXTURE; + } + + protected void preRenderCallback(EntityTileraGhast entitylivingbaseIn, float partialTickTime) + { + float f = 1.0F; + float f1 = 4.5F; + float f2 = 4.5F; + GlStateManager.scale(4.5F, 4.5F, 4.5F); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + } + + private static class Factory implements IRenderFactory + { + @Override + public Render createRenderFor(RenderManager manager) + { + return new RenderTileraGhast(manager); + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/spackenmobs/lang/de_de.lang b/src/main/resources/assets/spackenmobs/lang/de_de.lang index 57f583a..6d51d23 100644 --- a/src/main/resources/assets/spackenmobs/lang/de_de.lang +++ b/src/main/resources/assets/spackenmobs/lang/de_de.lang @@ -16,12 +16,16 @@ entity.drachenlord.name=Drachenlord entity.friedrich.name=Friedrich Liechtenstein entity.holzstammhuhn.name=Holzstammhuhn entity.islamist.name=Islamist +entity.itbyhf.name=ITbyHF entity.jens.name=Jens +entity.jens_wither.name=Jens-Wither +entity.latin_teacher.name=Lateinlehrerin entity.marcell_davis.name=Marcell D'Avis entity.mr_bean.name=Mr. Bean entity.mztewolf.name=MZTEWolf entity.schalker.name=Schalker entity.smava_creeper.name=Smava-Creeper +entity.tilera_ghast.name=tilera-Ghast item.ahoj_brause.name=Ahoj-Brause Brausepulver item.ahoj_brause_drink.name=Ahoj-Brause Brause item.ram.name=RAM diff --git a/src/main/resources/assets/spackenmobs/lang/en_us.lang b/src/main/resources/assets/spackenmobs/lang/en_us.lang index bad057b..6749eb5 100644 --- a/src/main/resources/assets/spackenmobs/lang/en_us.lang +++ b/src/main/resources/assets/spackenmobs/lang/en_us.lang @@ -16,12 +16,16 @@ entity.drachenlord.name=Drachenlord entity.friedrich.name=Friedrich Liechtenstein entity.holzstammhuhn.name=Holzstammhuhn entity.islamist.name=Islamist +entity.itbyhf.name=ITbyHF entity.jens.name=Jens +entity.jens_wither.name=Jens Wither +entity.latin_teacher.name=Latin Teacher entity.marcell_davis.name=Marcell D'Avis entity.mr_bean.name=Mr. Bean entity.mztewolf.name=MZTEWolf entity.schalker.name=Schalker entity.smava_creeper.name=Smava Creeper +entity.tilera_ghast.name=tilera Ghast item.ahoj_brause.name=Ahoj-Brause Soda Powder item.ahoj_brause_drink.name=Ahoj-Brause Soda item.ram.name=RAM diff --git a/src/main/resources/assets/spackenmobs/textures/entities/itbyhf.png b/src/main/resources/assets/spackenmobs/textures/entities/itbyhf.png new file mode 100644 index 0000000..2d43813 Binary files /dev/null and b/src/main/resources/assets/spackenmobs/textures/entities/itbyhf.png differ diff --git a/src/main/resources/assets/spackenmobs/textures/entities/latin_teacher.png b/src/main/resources/assets/spackenmobs/textures/entities/latin_teacher.png new file mode 100644 index 0000000..0e6075f Binary files /dev/null and b/src/main/resources/assets/spackenmobs/textures/entities/latin_teacher.png differ diff --git a/src/main/resources/assets/spackenmobs/textures/entities/tilera_ghast.png b/src/main/resources/assets/spackenmobs/textures/entities/tilera_ghast.png new file mode 100644 index 0000000..662c76b Binary files /dev/null and b/src/main/resources/assets/spackenmobs/textures/entities/tilera_ghast.png differ diff --git a/src/main/resources/assets/spackenmobs/textures/entities/tilera_ghast_shooting.png b/src/main/resources/assets/spackenmobs/textures/entities/tilera_ghast_shooting.png new file mode 100644 index 0000000..a226b25 Binary files /dev/null and b/src/main/resources/assets/spackenmobs/textures/entities/tilera_ghast_shooting.png differ