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);
|
Integer y = BlockUtils.getNearestFloor(world, new BlockPos(vec), 5);
|
||||||
|
|
||||||
if(y != null){
|
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;
|
flag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class ShulkerBullet extends Spell {
|
|||||||
if(caster != null){
|
if(caster != null){
|
||||||
world.spawnEntity(new EntityShulkerBullet(world, caster, target, direction.getAxis()));
|
world.spawnEntity(new EntityShulkerBullet(world, caster, target, direction.getAxis()));
|
||||||
}else{
|
}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);
|
EntityShulkerBullet bullet = new EntityShulkerBullet(world);
|
||||||
bullet.setLocationAndAngles(x, y, z, bullet.rotationYaw, bullet.rotationPitch);
|
bullet.setLocationAndAngles(x, y, z, bullet.rotationYaw, bullet.rotationPitch);
|
||||||
|
|
||||||
@@ -94,6 +94,8 @@ public class ShulkerBullet extends Spell {
|
|||||||
NBTExtras.storeTagSafely(nbt, "Target", targetTag);
|
NBTExtras.storeTagSafely(nbt, "Target", targetTag);
|
||||||
bullet.readFromNBT(nbt); // LOL I just modified private fields without reflection
|
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);
|
world.spawnEntity(bullet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ package electroblob.wizardry.spell;
|
|||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.living.ISpellCaster;
|
import electroblob.wizardry.entity.living.ISpellCaster;
|
||||||
|
import electroblob.wizardry.integration.DamageSafetyChecker;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
@@ -12,9 +15,13 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||||||
import net.minecraft.entity.projectile.EntityThrowable;
|
import net.minecraft.entity.projectile.EntityThrowable;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.tileentity.TileEntityDispenser;
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.world.World;
|
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;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
@@ -39,8 +46,14 @@ import java.util.function.BiFunction;
|
|||||||
* @since Wizardry 4.2.8
|
* @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?)
|
// 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 {
|
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;
|
private static final float LAUNCH_Y_OFFSET = 0.1f;
|
||||||
|
|
||||||
protected final BiFunction<World, EntityLivingBase, T> projectileFactory;
|
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);
|
float velocity = calculateVelocity(modifiers, caster.getEyeHeight() - LAUNCH_Y_OFFSET);
|
||||||
T projectile = projectileFactory.apply(world, caster);
|
T projectile = projectileFactory.apply(world, caster);
|
||||||
projectile.shoot(caster, caster.rotationPitch, caster.rotationYaw, 0.0f, velocity, 1.0f);
|
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);
|
addProjectileExtras(projectile, caster, modifiers);
|
||||||
world.spawnEntity(projectile);
|
world.spawnEntity(projectile);
|
||||||
}
|
}
|
||||||
@@ -139,4 +153,35 @@ public class SpellThrowable<T extends EntityThrowable> extends Spell {
|
|||||||
*/
|
*/
|
||||||
protected void addProjectileExtras(T projectile, EntityLivingBase caster, SpellModifiers modifiers){}
|
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