From 0cb2165ddf6942ce3ed702451e28464f415e17e3 Mon Sep 17 00:00:00 2001 From: ipdnaeip <89097082+ipdnaeip@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:11:29 -0400 Subject: [PATCH] Added methods for retrieving entities within a cylinder, replaced radius-based methods, implemented DPS check for heal aura, adjusted targeting criteria for summoned creatures, tweaked heal method, fixed flamecatcher ammo loss, updated Enrage target and expanded spellcasting item compatibility for movement speed charm. - by ipdnaeip (#864) Added getEntitiesWithinCylinder and getLivingWithinCylinder methods to return all entities within a cylinder. Replaced getLivingWithinRadius for spells that should use a cylinder instead. The height of the cylinder is determined by the height of the entities. Added a DPS checker on the heal aura damage just in case someone has damage immunity disabled. Modified the AllyDesignationSystem and Wizard classes to no longer target summoned creatures automatically. They will still target hostile summoned creatures or creatures from players that have aggressed on them. Modified the heal method in the Heal class to not reduce absorption amount. It should never really happen, but just in case. Modified the flamecatcher to no longer lose ammo if it was used but no arrow was fired. Enrage now targets EntityLiving instead of EntityCreature. The movement speed charm now works with any spellcasting item as opposed to just wands. --- .../client/WizardryClientEventHandler.java | 10 ++--- .../entity/construct/EntityDecay.java | 4 +- .../entity/construct/EntityFireRing.java | 2 +- .../entity/construct/EntityFireSigil.java | 2 +- .../entity/construct/EntityFrostSigil.java | 4 +- .../entity/construct/EntityHealAura.java | 28 ++++++------- .../construct/EntityLightningSigil.java | 4 +- .../wizardry/entity/living/EntityWizard.java | 8 +++- .../wizardry/item/ItemFlamecatcher.java | 16 ++++---- .../electroblob/wizardry/spell/Enrage.java | 4 +- .../java/electroblob/wizardry/spell/Heal.java | 2 +- .../wizardry/util/AllyDesignationSystem.java | 5 +++ .../wizardry/util/EntityUtils.java | 39 +++++++++++++++++++ 13 files changed, 88 insertions(+), 40 deletions(-) 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.