Damage modifier support for vanilla entities (throwables, shulker bullet and fangs)
This commit is contained in:
@@ -88,7 +88,9 @@ public class Fangs extends Spell {
|
||||
Integer y = BlockUtils.getNearestFloor(world, new BlockPos(vec), 5);
|
||||
|
||||
if(y != null){
|
||||
world.spawnEntity(new EntityEvokerFangs(world, vec.x, y, vec.z, yaw, i, caster)); // null is fine here
|
||||
EntityEvokerFangs fangs = new EntityEvokerFangs(world, vec.x, y, vec.z, yaw, i, caster); // null is fine here
|
||||
fangs.getEntityData().setFloat(SpellThrowable.DAMAGE_MODIFIER_NBT_KEY, modifiers.get(SpellModifiers.POTENCY));
|
||||
world.spawnEntity(fangs);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ShulkerBullet extends Spell {
|
||||
if(caster != null){
|
||||
world.spawnEntity(new EntityShulkerBullet(world, caster, target, direction.getAxis()));
|
||||
}else{
|
||||
// Can't use the normal constructor because doesn't accept null for the owner
|
||||
// Can't use the normal constructor because it doesn't accept null for the owner
|
||||
EntityShulkerBullet bullet = new EntityShulkerBullet(world);
|
||||
bullet.setLocationAndAngles(x, y, z, bullet.rotationYaw, bullet.rotationPitch);
|
||||
|
||||
@@ -94,6 +94,8 @@ public class ShulkerBullet extends Spell {
|
||||
NBTExtras.storeTagSafely(nbt, "Target", targetTag);
|
||||
bullet.readFromNBT(nbt); // LOL I just modified private fields without reflection
|
||||
|
||||
bullet.getEntityData().setFloat(SpellThrowable.DAMAGE_MODIFIER_NBT_KEY, modifiers.get(SpellModifiers.POTENCY));
|
||||
|
||||
world.spawnEntity(bullet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.living.ISpellCaster;
|
||||
import electroblob.wizardry.integration.DamageSafetyChecker;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.MagicDamage;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
@@ -12,9 +15,13 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityThrowable;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.tileentity.TileEntityDispenser;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.entity.living.LivingAttackEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@@ -39,8 +46,14 @@ import java.util.function.BiFunction;
|
||||
* @since Wizardry 4.2.8
|
||||
*/
|
||||
// TODO: Use events to make these projectiles seek targets when the caster is wearing a ring of attraction (is this possible?)
|
||||
@EventBusSubscriber
|
||||
public class SpellThrowable<T extends EntityThrowable> extends Spell {
|
||||
|
||||
/** NBT key for storing a damage modifier in an external entity (i.e. from vanilla or another mod). Entities with a
|
||||
* float value stored under this key will have their damage dealt multiplied by that value. This is not just for
|
||||
* projectiles; it will work for any entity that uses a damage source with itself as the immediate source. */
|
||||
public static final String DAMAGE_MODIFIER_NBT_KEY = Wizardry.MODID + "DamageModifier";
|
||||
|
||||
private static final float LAUNCH_Y_OFFSET = 0.1f;
|
||||
|
||||
protected final BiFunction<World, EntityLivingBase, T> projectileFactory;
|
||||
@@ -75,6 +88,7 @@ public class SpellThrowable<T extends EntityThrowable> extends Spell {
|
||||
float velocity = calculateVelocity(modifiers, caster.getEyeHeight() - LAUNCH_Y_OFFSET);
|
||||
T projectile = projectileFactory.apply(world, caster);
|
||||
projectile.shoot(caster, caster.rotationPitch, caster.rotationYaw, 0.0f, velocity, 1.0f);
|
||||
projectile.getEntityData().setFloat(DAMAGE_MODIFIER_NBT_KEY, modifiers.get(SpellModifiers.POTENCY));
|
||||
addProjectileExtras(projectile, caster, modifiers);
|
||||
world.spawnEntity(projectile);
|
||||
}
|
||||
@@ -139,4 +153,35 @@ public class SpellThrowable<T extends EntityThrowable> extends Spell {
|
||||
*/
|
||||
protected void addProjectileExtras(T projectile, EntityLivingBase caster, SpellModifiers modifiers){}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingAttackEvent(LivingAttackEvent event){
|
||||
|
||||
// TODO: Annoyingly, wither skulls apply 'direct' damage from their shooter so they won't be recognised here
|
||||
if(!(event.getSource() instanceof MagicDamage)){ // Prevent infinite looping
|
||||
|
||||
float damageModifier = event.getSource().getImmediateSource().getEntityData().getFloat(DAMAGE_MODIFIER_NBT_KEY);
|
||||
|
||||
// Really, we just want to increase the damage without modifying the source, but that would cause an
|
||||
// infinite loop so we need some way of identifying it - the easiest way is to use MagicDamage, which fits
|
||||
// quite nicely since we can only get here if the entity was from a spell anyway
|
||||
if(damageModifier > 0){
|
||||
|
||||
Entity projectile = event.getSource().getImmediateSource();
|
||||
Entity shooter = event.getSource().getTrueSource();
|
||||
|
||||
DamageSource newSource = shooter == projectile
|
||||
? MagicDamage.causeDirectMagicDamage(projectile, DamageType.MAGIC)
|
||||
: MagicDamage.causeIndirectMagicDamage(projectile, shooter, DamageType.MAGIC);
|
||||
|
||||
// Copy over any relevant 'attributes' the original DamageSource might have had.
|
||||
if(event.getSource().isExplosion()) newSource.setExplosion();
|
||||
if(event.getSource().isFireDamage()) newSource.setFireDamage();
|
||||
if(event.getSource().isProjectile()) newSource.setProjectile();
|
||||
|
||||
DamageSafetyChecker.attackEntitySafely(event.getEntity(), newSource,
|
||||
event.getAmount() * damageModifier, event.getSource(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user