diff --git a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java index 9e3e8f0c..4a6bfdbd 100644 --- a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java +++ b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java @@ -3,10 +3,7 @@ package electroblob.wizardry.client; import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect; import electroblob.wizardry.data.DispenserCastingData; import electroblob.wizardry.data.SpellEmitterData; -import electroblob.wizardry.item.ItemArtefact; -import electroblob.wizardry.item.ItemFlamecatcher; -import electroblob.wizardry.item.ItemSpectralBow; -import electroblob.wizardry.item.ItemWand; +import electroblob.wizardry.item.*; import electroblob.wizardry.potion.PotionSlowTime; import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryPotions; @@ -120,6 +117,7 @@ public final class WizardryClientEventHandler { Minecraft.getMinecraft().player.prevRotationPitch = 0; Minecraft.getMinecraft().player.rotationYaw = 0; Minecraft.getMinecraft().player.rotationPitch = 0; + } } @@ -133,10 +131,10 @@ public final class WizardryClientEventHandler { event.getMovementInput().jump = false; event.getMovementInput().sneak = false; } - + if(ItemArtefact.isArtefactActive(event.getEntityPlayer(), WizardryItems.charm_move_speed) && event.getEntityPlayer().isHandActive() - && event.getEntityPlayer().getActiveItemStack().getItem() instanceof ItemWand){ + && event.getEntityPlayer().getActiveItemStack().getItem() instanceof ISpellCastingItem){ // Normally speed is set to 20% when using items, this makes it 80% event.getMovementInput().moveStrafe *= 4; event.getMovementInput().moveForward *= 4; diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java b/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java index 506276e9..00178bc7 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java @@ -35,8 +35,8 @@ public class EntityDecay extends EntityMagicConstruct { 0.6F + rand.nextFloat() * 0.15F); if(!this.world.isRemote){ - List targets = EntityUtils.getLivingWithinRadius(1.0d, this.posX, this.posY, - this.posZ, this.world); + List targets = EntityUtils.getLivingWithinCylinder(this.width/2f, this.posX, this.posY, + this.posZ, this.height, this.world); for(EntityLivingBase target : targets){ if(target != this.getCaster()){ // If this check wasn't here the potion would be reapplied every tick and hence the entity would be diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java b/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java index ed5b4b84..40f067c4 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java @@ -34,7 +34,7 @@ public class EntityFireRing extends EntityScaledConstruct { if(this.ticksExisted % 5 == 0 && !this.world.isRemote){ - List targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world); + List targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, this.posZ, this.height, this.world); for(EntityLivingBase target : targets){ diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java index de3de2b6..f587cc13 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java @@ -34,7 +34,7 @@ public class EntityFireSigil extends EntityScaledConstruct { if(!this.world.isRemote){ - List targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world); + List targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, this.posZ, this.height, this.world); for(EntityLivingBase target : targets){ diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java index fc08e7d9..2ab1e50f 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java @@ -36,8 +36,8 @@ public class EntityFrostSigil extends EntityScaledConstruct { if(!this.world.isRemote){ - List targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, - this.posZ, this.world); + List targets = EntityUtils.getLivingWithinCylinder(width/2, this.posX, this.posY, + this.posZ, this.height, this.world); for(EntityLivingBase target : targets){ diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java b/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java index d887eabe..3fef3ae6 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java @@ -33,30 +33,32 @@ public class EntityHealAura extends EntityScaledConstruct { if(!this.world.isRemote){ - List targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world); + List targets = EntityUtils.getLivingWithinCylinder(width/2, posX, posY, posZ, this.height, world); for(EntityLivingBase target : targets){ if(this.isValidTarget(target)){ - if(target.isEntityUndead()){ + if(target.isEntityUndead()) { double velX = target.motionX; double velY = target.motionY; double velZ = target.motionZ; - if(this.getCaster() != null){ - target.attackEntityFrom( - MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.RADIANT), - Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier); - }else{ - target.attackEntityFrom(DamageSource.MAGIC, Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier); - } + if (this.ticksExisted % 10 == 1) { + if (this.getCaster() != null) { + target.attackEntityFrom( + MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.RADIANT), + Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier); + } else { + target.attackEntityFrom(DamageSource.MAGIC, Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier); + } - // Removes knockback - target.motionX = velX; - target.motionY = velY; - target.motionZ = velZ; + // Removes knockback + target.motionX = velX; + target.motionY = velY; + target.motionZ = velZ; + } } }else if(target.getHealth() < target.getMaxHealth() && target.ticksExisted % 5 == 0){ diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java index 63cc1325..b9024b9d 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java @@ -39,8 +39,8 @@ public class EntityLightningSigil extends EntityScaledConstruct { this.setDead(); } - List targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, - this.posZ, this.world); + List targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, + this.posZ, this.height, this.world); for(EntityLivingBase target : targets){ diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java index 18f5e1f2..995f6533 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java @@ -130,8 +130,12 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp if(entity != null && !entity.isInvisible() && AllyDesignationSystem.isValidTarget(EntityWizard.this, entity)){ - // ... and is a mob, a summoned creature ... - if((entity instanceof IMob || entity instanceof ISummonedCreature + // ... and is a non summoned creature mob ... + if((entity instanceof IMob && !(entity instanceof ISummonedCreature) + + // or is a summoned creature with a mob owner or an owner who has attacked the wizard ... + || entity instanceof ISummonedCreature && (((ISummonedCreature)entity).getOwner() instanceof IMob || ((ISummonedCreature)entity).getOwner() == this.getRevengeTarget() || ((ISummonedCreature) entity).getOwner() == this.getAttackTarget()) + // ... or in the whitelist ... || Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist) .contains(EntityList.getKey(entity.getClass()))) diff --git a/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java b/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java index d8b57e54..2f79f40b 100644 --- a/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java +++ b/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java @@ -193,14 +193,6 @@ public class ItemFlamecatcher extends ItemBow implements IConjuredItem { charge = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, world, (EntityPlayer)entity, charge, true); if(charge < 0) return; - if(stack.getTagCompound() != null){ - int shotsLeft = stack.getTagCompound().getInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY) - 1; - stack.getTagCompound().setInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY, shotsLeft); - if(shotsLeft == 0 && !world.isRemote){ - stack.setItemDamage(getMaxDamage(stack) - getAnimationFrames()); - } - } - float velocity = (float)charge / DRAW_TIME; velocity = (velocity * velocity + velocity * 2) / 3; @@ -208,6 +200,14 @@ public class ItemFlamecatcher extends ItemBow implements IConjuredItem { if((double)velocity >= 0.1D){ + if(stack.getTagCompound() != null){ + int shotsLeft = stack.getTagCompound().getInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY) - 1; + stack.getTagCompound().setInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY, shotsLeft); + if(shotsLeft == 0 && !world.isRemote){ + stack.setItemDamage(getMaxDamage(stack) - getAnimationFrames()); + } + } + if(!world.isRemote){ EntityFlamecatcherArrow arrow = new EntityFlamecatcherArrow(world); arrow.aim(player, EntityFlamecatcherArrow.SPEED * velocity); diff --git a/src/main/java/electroblob/wizardry/spell/Enrage.java b/src/main/java/electroblob/wizardry/spell/Enrage.java index 45003b49..cdd1d22d 100644 --- a/src/main/java/electroblob/wizardry/spell/Enrage.java +++ b/src/main/java/electroblob/wizardry/spell/Enrage.java @@ -4,7 +4,7 @@ import electroblob.wizardry.item.SpellActions; import electroblob.wizardry.util.ParticleBuilder; import electroblob.wizardry.util.ParticleBuilder.Type; import electroblob.wizardry.util.SpellModifiers; -import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.tileentity.TileEntityDispenser; import net.minecraft.util.math.Vec3d; @@ -29,7 +29,7 @@ public class Enrage extends SpellAreaEffect { @Override protected boolean affectEntity(World world, Vec3d origin, @Nullable EntityLivingBase caster, EntityLivingBase target, int targetCount, int ticksInUse, SpellModifiers modifiers){ - if(caster != null && target instanceof EntityCreature){ + if(caster != null && target instanceof EntityLiving){ target.setRevengeTarget(caster); // Yours truly, angry mobs } diff --git a/src/main/java/electroblob/wizardry/spell/Heal.java b/src/main/java/electroblob/wizardry/spell/Heal.java index 8baf906b..efc87664 100644 --- a/src/main/java/electroblob/wizardry/spell/Heal.java +++ b/src/main/java/electroblob/wizardry/spell/Heal.java @@ -38,7 +38,7 @@ public class Heal extends SpellBuff { entity.heal(health); // If the player is able to heal, they can't possibly have absorption hearts, so no need to check! - if(excessHealth > 0 && entity instanceof EntityPlayer + if(excessHealth > entity.getAbsorptionAmount() && entity instanceof EntityPlayer && ItemArtefact.isArtefactActive((EntityPlayer)entity, WizardryItems.amulet_absorption)){ entity.setAbsorptionAmount(excessHealth); } diff --git a/src/main/java/electroblob/wizardry/util/AllyDesignationSystem.java b/src/main/java/electroblob/wizardry/util/AllyDesignationSystem.java index 9c78abaa..77e8b9f8 100644 --- a/src/main/java/electroblob/wizardry/util/AllyDesignationSystem.java +++ b/src/main/java/electroblob/wizardry/util/AllyDesignationSystem.java @@ -141,6 +141,11 @@ public final class AllyDesignationSystem { return false; } + // Tests whether the target is a creature that was summoned/tamed (or is otherwise owned) by the attacker + if(target instanceof IEntityOwnable && attacker instanceof EntityLiving && !(((EntityLiving)attacker).getRevengeTarget() == ((IEntityOwnable)target).getOwner() || ((EntityLiving)attacker).getAttackTarget() == ((IEntityOwnable)target).getOwner())){ + return false; + } + // Tests whether the target is a creature that was mind controlled by the attacker if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(WizardryPotions.mind_control)){ diff --git a/src/main/java/electroblob/wizardry/util/EntityUtils.java b/src/main/java/electroblob/wizardry/util/EntityUtils.java index 0386188c..e3f0449f 100644 --- a/src/main/java/electroblob/wizardry/util/EntityUtils.java +++ b/src/main/java/electroblob/wizardry/util/EntityUtils.java @@ -117,6 +117,45 @@ public final class EntityUtils { return entityList; } + /** + * Returns all EntityLivingBase within the cylinder radius of the given coordinates. This should + * used by circle effects. + * + * @param radius The search radius + * @param x The x coordinate to search around + * @param y The y coordinate to search around + * @param z The z coordinate to search around + * @param height The height of the cylinder + * @param world The world to search in + */ + public static List getLivingWithinCylinder(double radius, double x, double y, double z, double height, World world) { + return getEntitiesWithinCylinder(radius, x, y, z, height, world, EntityLivingBase.class); + } + + /** + * Returns all entities of the specified type within the cylinder radius of the given coordinates. This should + * used by circle effects. + * + * @param radius The search radius + * @param x The x coordinate to search around + * @param y The y coordinate to search around + * @param z The z coordinate to search around + * @param height The height of the cylinder + * @param world The world to search in + * @param entityType The class of entity to search for; pass in Entity.class for all entities + */ + public static List getEntitiesWithinCylinder(double radius, double x, double y, double z, double height, World world, Class entityType) { + AxisAlignedBB aabb = new AxisAlignedBB(x - radius, y, z - radius, x + radius, y + height, z + radius); + List entityList = world.getEntitiesWithinAABB(entityType, aabb); + for(T entity : entityList) { + if (entity.getDistance(x, entity.posY, z) > radius) { + entityList.remove(entity); + break; + } + } + return entityList; + } + /** * Gets an entity from its UUID. If the UUID is known to belong to an {@code EntityPlayer}, use the more efficient * {@link World#getPlayerEntityByUUID(UUID)} instead.