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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user