0cb2165ddf
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.
121 lines
3.9 KiB
Java
121 lines
3.9 KiB
Java
package electroblob.wizardry.entity.construct;
|
|
|
|
import electroblob.wizardry.registry.Spells;
|
|
import electroblob.wizardry.registry.WizardrySounds;
|
|
import electroblob.wizardry.spell.Spell;
|
|
import electroblob.wizardry.util.EntityUtils;
|
|
import electroblob.wizardry.util.MagicDamage;
|
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
|
import electroblob.wizardry.util.ParticleBuilder;
|
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.util.DamageSource;
|
|
import net.minecraft.util.math.MathHelper;
|
|
import net.minecraft.world.World;
|
|
|
|
import java.util.List;
|
|
|
|
public class EntityLightningSigil extends EntityScaledConstruct {
|
|
|
|
public static final String SECONDARY_RANGE = "secondary_range";
|
|
public static final String SECONDARY_MAX_TARGETS = "secondary_max_targets";
|
|
|
|
public EntityLightningSigil(World world){
|
|
super(world);
|
|
setSize(Spells.frost_sigil.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2, 0.2f);
|
|
}
|
|
|
|
@Override
|
|
protected boolean shouldScaleHeight(){
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onUpdate(){
|
|
|
|
super.onUpdate();
|
|
|
|
if(this.ticksExisted > 600 && this.getCaster() == null && !this.world.isRemote){
|
|
this.setDead();
|
|
}
|
|
|
|
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY,
|
|
this.posZ, this.height, this.world);
|
|
|
|
for(EntityLivingBase target : targets){
|
|
|
|
if(this.isValidTarget(target)){
|
|
|
|
double velX = target.motionX;
|
|
double velY = target.motionY;
|
|
double velZ = target.motionZ;
|
|
|
|
// Only works if target is actually damaged to account for hurtResistantTime
|
|
if(target.attackEntityFrom(getCaster() != null ? MagicDamage.causeIndirectMagicDamage(this, getCaster(),
|
|
DamageType.SHOCK) : DamageSource.MAGIC, Spells.lightning_sigil.getProperty(Spell.DIRECT_DAMAGE)
|
|
.floatValue() * damageMultiplier)){
|
|
|
|
// Removes knockback
|
|
target.motionX = velX;
|
|
target.motionY = velY;
|
|
target.motionZ = velZ;
|
|
|
|
this.playSound(WizardrySounds.ENTITY_LIGHTNING_SIGIL_TRIGGER, 1.0f, 1.0f);
|
|
|
|
// Secondary chaining effect
|
|
double seekerRange = Spells.lightning_sigil.getProperty(SECONDARY_RANGE).doubleValue();
|
|
|
|
List<EntityLivingBase> secondaryTargets = EntityUtils.getLivingWithinRadius(seekerRange,
|
|
target.posX, target.posY + target.height / 2, target.posZ, world);
|
|
|
|
for(int j = 0; j < Math.min(secondaryTargets.size(),
|
|
Spells.lightning_sigil.getProperty(SECONDARY_MAX_TARGETS).floatValue()); j++){
|
|
|
|
EntityLivingBase secondaryTarget = secondaryTargets.get(j);
|
|
|
|
if(secondaryTarget != target && this.isValidTarget(secondaryTarget)){
|
|
|
|
if(world.isRemote){
|
|
|
|
ParticleBuilder.create(Type.LIGHTNING).entity(target)
|
|
.pos(0, target.height/2, 0).target(secondaryTarget).spawn(world);
|
|
|
|
ParticleBuilder.spawnShockParticles(world, secondaryTarget.posX,
|
|
secondaryTarget.posY + secondaryTarget.height / 2,
|
|
secondaryTarget.posZ);
|
|
}
|
|
|
|
secondaryTarget.playSound(WizardrySounds.ENTITY_LIGHTNING_SIGIL_TRIGGER, 1.0F,
|
|
world.rand.nextFloat() * 0.4F + 1.5F);
|
|
|
|
secondaryTarget.attackEntityFrom(
|
|
MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.SHOCK),
|
|
Spells.lightning_sigil.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier);
|
|
}
|
|
|
|
}
|
|
// The trap is destroyed once triggered.
|
|
this.setDead();
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.world.isRemote && this.rand.nextInt(15) == 0){
|
|
double radius = (0.5 + rand.nextDouble() * 0.3) * width/2;
|
|
float angle = rand.nextFloat() * (float)Math.PI * 2;
|
|
ParticleBuilder.create(Type.SPARK)
|
|
.pos(this.posX + radius * MathHelper.cos(angle), this.posY + 0.1, this.posZ + radius * MathHelper.sin(angle))
|
|
.spawn(world);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void entityInit(){}
|
|
|
|
@Override
|
|
public boolean canRenderOnFire(){
|
|
return false;
|
|
}
|
|
|
|
}
|