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.
This commit is contained in:
ipdnaeip
2024-03-27 17:11:29 -04:00
committed by GitHub
parent ca7e9034ed
commit 0cb2165ddf
13 changed files with 88 additions and 40 deletions
@@ -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;
@@ -35,8 +35,8 @@ public class EntityDecay extends EntityMagicConstruct {
0.6F + rand.nextFloat() * 0.15F);
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(1.0d, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> 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
@@ -34,7 +34,7 @@ public class EntityFireRing extends EntityScaledConstruct {
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -34,7 +34,7 @@ public class EntityFireSigil extends EntityScaledConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -36,8 +36,8 @@ public class EntityFrostSigil extends EntityScaledConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(width/2, this.posX, this.posY,
this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -33,30 +33,32 @@ public class EntityHealAura extends EntityScaledConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world);
List<EntityLivingBase> 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){
@@ -39,8 +39,8 @@ public class EntityLightningSigil extends EntityScaledConstruct {
this.setDead();
}
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY,
this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -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())))
@@ -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);
@@ -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
}
@@ -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);
}
@@ -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)){
@@ -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<EntityLivingBase> 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 <T extends Entity> List<T> getEntitiesWithinCylinder(double radius, double x, double y, double z, double height, World world, Class<T> entityType) {
AxisAlignedBB aabb = new AxisAlignedBB(x - radius, y, z - radius, x + radius, y + height, z + radius);
List<T> 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.