Spells can now be attached to entities other than players

This commit is contained in:
Sollace 2019-03-12 22:12:46 +02:00
parent 1248b93995
commit 779ae10a99
17 changed files with 289 additions and 81 deletions

View file

@ -1,8 +1,10 @@
package com.minelittlepony.unicopia.forgebullshit;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.IMagicals;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
@ -28,9 +30,11 @@ public class FBS {
@SubscribeEvent
public static void attach(AttachCapabilitiesEvent<Entity> event) {
if (event.getObject() instanceof EntityPlayer
|| event.getObject() instanceof EntityItem) {
event.addCapability(new ResourceLocation("unicopia", "race"), new Provider(event.getObject()));
Entity obj = event.getObject();
if ((obj instanceof EntityLivingBase && !(obj instanceof IMagicals))
|| obj instanceof EntityItem) {
event.addCapability(new ResourceLocation("unicopia", "race"), new Provider(obj));
}
}

View file

@ -6,7 +6,8 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.power.IPower;
import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import com.minelittlepony.unicopia.spell.CasterUtils;
import com.minelittlepony.unicopia.spell.IAligned;
import com.minelittlepony.unicopia.spell.ICaster;
@ -82,12 +83,10 @@ public class ItemMagicStaff extends ItemStaff implements IAligned, ITossableItem
if (attacker.isSneaking()) {
stack.damageItem(50, attacker);
if (attacker instanceof EntityPlayer) {
IPower.takeFromPlayer((EntityPlayer)attacker, 4);
}
CasterUtils.toCaster(attacker).ifPresent(c -> c.subtractEnergyCost(4));
onImpact(
CasterUtils.toCaster(target).orElseGet(() -> CasterUtils.near(target)),
CasterUtils.near(target),
target.getPosition(),
target.getEntityWorld().getBlockState(target.getPosition())
);
@ -140,9 +139,10 @@ public class ItemMagicStaff extends ItemStaff implements IAligned, ITossableItem
@Override
public void toss(World world, ItemStack stack, EntityPlayer player) {
CasterUtils.toCaster(player).ifPresent(effect::toss);
IPlayer iplayer = PlayerSpeciesList.instance().getPlayer(player);
IPower.takeFromPlayer(player, 4);
iplayer.subtractEnergyCost(4);
effect.toss(iplayer);
stack.damageItem(1, player);
}

View file

@ -0,0 +1,135 @@
package com.minelittlepony.unicopia.player;
import java.util.Map;
import com.google.common.collect.Maps;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.network.EffectSync;
import com.minelittlepony.unicopia.spell.IAligned;
import com.minelittlepony.unicopia.spell.IAttachedEffect;
import com.minelittlepony.unicopia.spell.ICaster;
import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellAffinity;
import com.minelittlepony.unicopia.spell.SpellRegistry;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
public class EntityCapabilities implements IRaceContainer<EntityLivingBase>, ICaster<EntityLivingBase> {
private static final Map<Class<? extends EntityLivingBase>, DataParameter<NBTTagCompound>> EFFECT_KEYS = Maps.newHashMap();
private final DataParameter<NBTTagCompound> EFFECT;
private final EffectSync<EntityLivingBase> effectDelegate;
private EntityLivingBase entity;
EntityCapabilities(EntityLivingBase entity) {
setOwner(entity);
EFFECT = EFFECT_KEYS.computeIfAbsent(entity.getClass(), c -> {
return EntityDataManager.createKey(c, DataSerializers.COMPOUND_TAG);
});
effectDelegate = new EffectSync<>(this, EFFECT);
entity.getDataManager().register(EFFECT, new NBTTagCompound());
}
@Override
public Race getPlayerSpecies() {
return Race.HUMAN;
}
@Override
public void setPlayerSpecies(Race race) {
}
@Override
public void setEffect(IMagicEffect effect) {
effectDelegate.set(effect);
}
@Override
public <T extends IMagicEffect> T getEffect(Class<T> type, boolean update) {
return effectDelegate.get(type, update);
}
@Override
public boolean hasEffect() {
return effectDelegate.has();
}
@Override
public void beforeUpdate() {
}
@Override
public void onUpdate() {
if (hasEffect()) {
IAttachedEffect effect = getEffect(IAttachedEffect.class, true);
if (effect != null) {
if (entity.getEntityWorld().isRemote) {
effect.renderOnPerson(this);
}
if (!effect.updateOnPerson(this)) {
setEffect(null);
}
}
}
}
@Override
public void onDimensionalTravel(int destinationDimension) {
}
@Override
public void setOwner(EntityLivingBase owner) {
entity = owner;
}
@Override
public EntityLivingBase getOwner() {
return entity;
}
@Override
public int getCurrentLevel() {
return 0;
}
@Override
public void setCurrentLevel(int level) {
}
@Override
public SpellAffinity getAffinity() {
if (getOwner() instanceof IAligned) {
return ((IAligned)getOwner()).getAffinity();
}
return SpellAffinity.NEUTRAL;
}
@Override
public void writeToNBT(NBTTagCompound compound) {
IMagicEffect effect = getEffect();
if (effect != null) {
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(effect));
}
}
@Override
public void readFromNBT(NBTTagCompound compound) {
if (compound.hasKey("effect")) {
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
}
}
}

View file

@ -9,7 +9,7 @@ import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.event.entity.ProjectileImpactEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.event.entity.player.PlayerDropsEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
@ -31,7 +31,12 @@ class Hooks {
}
@SubscribeEvent
public static void onPlayerJump(LivingJumpEvent event) {
public static void onLivingUpdate(LivingEvent.LivingUpdateEvent event) {
PlayerSpeciesList.instance().getEntity(event.getEntityLiving()).onUpdate();
}
@SubscribeEvent
public static void onPlayerJump(LivingEvent.LivingJumpEvent event) {
if (event.getEntityLiving() instanceof EntityPlayer) {
if (PlayerSpeciesList.instance().getPlayer((EntityPlayer)event.getEntityLiving()).getGravity().getGravitationConstant() < 0) {
event.getEntityLiving().motionY = -event.getEntityLiving().motionY;

View file

@ -37,6 +37,7 @@ import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.network.play.server.SPacketSetPassengers;
import net.minecraft.potion.PotionEffect;
import net.minecraft.stats.StatList;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
@ -310,6 +311,22 @@ class PlayerCapabilities implements IPlayer {
return true;
}
@Override
public boolean subtractEnergyCost(double foodSubtract) {
if (!entity.capabilities.isCreativeMode) {
int food = (int)(entity.getFoodStats().getFoodLevel() - foodSubtract);
if (food < 0) {
entity.getFoodStats().addStats(-entity.getFoodStats().getFoodLevel(), 0);
entity.attackEntityFrom(DamageSource.MAGIC, -food/2);
} else {
entity.getFoodStats().addStats((int)-foodSubtract, 0);
}
}
return entity.getHealth() > 0;
}
@Override
public boolean stepOnCloud() {
EntityPlayer player = getOwner();

View file

@ -7,8 +7,10 @@ import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UConfig;
import com.minelittlepony.unicopia.forgebullshit.FBS;
import com.minelittlepony.unicopia.spell.ICaster;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
@ -65,6 +67,10 @@ public class PlayerSpeciesList {
return new ItemCapabilities();
}
if (entity instanceof EntityLivingBase) {
return new EntityCapabilities((EntityLivingBase)entity);
}
throw new IllegalArgumentException("entity");
}
@ -82,6 +88,12 @@ public class PlayerSpeciesList {
return getPlayer(IPlayer.getPlayerFromServer(playerId));
}
@SuppressWarnings("unchecked")
@Nullable
public <T extends EntityLivingBase> ICaster<T> getCaster(T entity) {
return (ICaster<T>)getEntity(entity);
}
public <T extends Entity> IRaceContainer<T> getEntity(T entity) {
return FBS.of(entity).getRaceContainer();
}

View file

@ -10,38 +10,11 @@ import com.minelittlepony.util.shape.IShape;
import com.minelittlepony.util.shape.Sphere;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public interface IPower<T extends IData> extends IKeyBind {
/**
* Subtracts a given food amount from the player.
* Harms the player if there is not enough hunger available.
*/
static boolean takeFromPlayer(EntityPlayer player, double foodSubtract) {
if (!player.capabilities.isCreativeMode) {
int food = (int)(player.getFoodStats().getFoodLevel() - foodSubtract);
if (food < 0) {
player.getFoodStats().addStats(-player.getFoodStats().getFoodLevel(), 0);
player.attackEntityFrom(DamageSource.MAGIC, -food/2);
} else {
player.getFoodStats().addStats((int)-foodSubtract, 0);
}
}
return player.getHealth() > 0;
}
static double getPlayerEyeYPos(EntityPlayer player) {
if (player.getEntityWorld().isRemote) {
return player.posY + player.getEyeHeight() - player.getYOffset();
}
return player.posY + player.getEyeHeight() - 1;
}
static void spawnParticles(int particleId, Entity entity, int count, int...args) {
double halfDist = entity.getEyeHeight() / 1.5;
double middle = entity.getEntityBoundingBox().minY + halfDist;

View file

@ -74,7 +74,7 @@ public class PowerGrow implements IPower<Location> {
}
if (count > 0) {
IPower.takeFromPlayer(player.getOwner(), count * 5);
player.subtractEnergyCost(count * 5);
}
}

View file

@ -166,13 +166,13 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
spawnParticleRing(player, i);
}
IPower.takeFromPlayer(player, rad);
iplayer.subtractEnergyCost(rad);
} else if (data.hitType == 1) {
boolean harmed = player.getHealth() < player.getMaxHealth();
if (harmed && player.world.rand.nextInt(30) == 0) {
IPower.takeFromPlayer(player, 3);
iplayer.subtractEnergyCost(3);
return;
}
@ -182,12 +182,12 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
UWorld.enqueueTask(w -> removeTree(w, data.pos()));
}
IPower.takeFromPlayer(player, 3);
iplayer.subtractEnergyCost(3);
} else {
int cost = dropApples(player.world, data.pos());
if (cost > 0) {
IPower.takeFromPlayer(player, cost * 3);
iplayer.subtractEnergyCost(cost * 3);
}
}
}

View file

@ -128,7 +128,7 @@ public class PowerTeleport implements IPower<Location> {
}
player.setPositionAndUpdate(data.x + (player.posX - Math.floor(player.posX)), data.y, data.z + (player.posZ - Math.floor(player.posZ)));
IPower.takeFromPlayer(player, distance);
iplayer.subtractEnergyCost(distance);
player.fallDistance /= distance;

View file

@ -9,6 +9,7 @@ import javax.annotation.Nullable;
import com.google.common.collect.Streams;
import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.entity.IMagicals;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.entity.Entity;
@ -19,6 +20,9 @@ import net.minecraft.util.math.BlockPos;
public class CasterUtils {
/**
* Finds all surrounding spells withing range from the given caster.
*/
public static Stream<ICaster<?>> findAllSpellsInRange(ICaster<?> source, double radius) {
BlockPos origin = source.getOrigin();
@ -41,6 +45,9 @@ public class CasterUtils {
.map(Optional::get);
}
/**
* Finds all magically capabable entities in the world.
*/
static Stream<ICaster<?>> findAllSpells(ICaster<?> source) {
return source.getWorld().getEntities(EntityLivingBase.class, e -> {
return e instanceof ICaster || e instanceof EntityPlayer;
@ -67,29 +74,50 @@ public class CasterUtils {
.filter(e -> !e.getDead());
}
/**
* Determines if the passed in entity is holding the named effect.
* By holding that meant the effect must be attached to the caster associated with the entity.
*/
public static boolean isHoldingEffect(String effectName, Entity entity) {
return Streams.stream(entity.getEquipmentAndArmor())
.map(SpellRegistry::getKeyFromStack)
.anyMatch(s -> s.equals(effectName));
}
/**
* Creates a new caster at the position of the given entity.
* First attempts to convert the passed entity into a caster.
*/
@Nonnull
public static ICaster<?> near(@Nonnull Entity entity) {
ICaster<?> result = toCasterRaw(entity);
if (result != null) {
return result;
}
EntitySpell caster = new EntitySpell(entity.world);
caster.copyLocationAndAnglesFrom(entity);
return caster;
}
/**
* Attempts to convert the passed entity into a caster using all the known methods.
*/
public static Optional<ICaster<?>> toCaster(@Nullable Entity entity) {
return Optional.ofNullable(toCasterRaw(entity));
}
private static ICaster<?> toCasterRaw(Entity entity) {
if (entity instanceof ICaster<?>) {
return Optional.of((ICaster<?>)entity);
return (ICaster<?>)entity;
}
if (entity instanceof EntityPlayer) {
return Optional.of(PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity));
if (entity instanceof EntityLivingBase && !(entity instanceof IMagicals)) {
return PlayerSpeciesList.instance().getCaster((EntityLivingBase)entity);
}
return Optional.empty();
return null;
}
}

View file

@ -1,7 +1,5 @@
package com.minelittlepony.unicopia.spell;
import com.minelittlepony.unicopia.player.IPlayer;
public interface IAttachedEffect extends IMagicEffect {
/**
* Called every tick when attached to a player.
@ -9,7 +7,7 @@ public interface IAttachedEffect extends IMagicEffect {
* @param source The entity we are currently attached to.
* @return true to keep alive
*/
boolean updateOnPerson(IPlayer caster);
boolean updateOnPerson(ICaster<?> caster);
/**
* Called every tick when attached to a player. Used to apply particle effects.
@ -17,5 +15,5 @@ public interface IAttachedEffect extends IMagicEffect {
*
* @param source The entity we are currently attached to.
*/
default void renderOnPerson(IPlayer source) {}
default void renderOnPerson(ICaster<?> source) {}
}

View file

@ -8,6 +8,7 @@ import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.entity.IMagicals;
import com.minelittlepony.unicopia.player.IOwned;
import com.minelittlepony.unicopia.power.IPower;
import com.minelittlepony.util.shape.IShape;
@ -15,28 +16,45 @@ import com.minelittlepony.util.vector.VecHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled, IAligned {
/**
* Interface for any magically capable entities that can cast and persist spells.
*/
public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled, IAligned, IMagicals {
void setEffect(@Nullable IMagicEffect effect);
/**
* Gets the active effect for this caster.
*/
@Nullable
default IMagicEffect getEffect(boolean update) {
return getEffect(null, update);
}
/**
* Gets the active effect for the matching given type.
* Returns null if no such effect exists for this caster.
*/
@Nullable
<T extends IMagicEffect> T getEffect(@Nullable Class<T> type, boolean update);
/**
* Gets the active effect for this caster updating it if needed.
*/
@Nullable
default IMagicEffect getEffect() {
return getEffect(true);
}
/**
* Returns true if this caster has an active effect attached to it.
*/
boolean hasEffect();
/**
@ -81,6 +99,17 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
return getEntity().getPosition();
}
/**
* Gets the center position where this caster is located.
*/
default Vec3d getOriginVector() {
return getEntity().getPositionVector();
}
/**
* Returns a new caster at the given position.
* This one is not altered, rather the method will return an entirely new caster with the same owner as this one.
*/
default ICaster<?> at(BlockPos newOrigin) {
EntitySpell spell = new EntitySpell(getWorld());
spell.setPosition(newOrigin.getX(), newOrigin.getY(), newOrigin.getZ());
@ -89,10 +118,6 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
return spell;
}
default Vec3d getOriginVector() {
return getEntity().getPositionVector();
}
default void spawnParticles(int particleId, int count, int...args) {
IPower.spawnParticles(particleId, getEntity(), count, args);
}
@ -107,6 +132,12 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
}
}
default boolean subtractEnergyCost(double amount) {
getOwner().attackEntityFrom(DamageSource.MAGIC, (int)amount/2);
return getOwner().getHealth() > 0;
}
default Stream<ICaster<?>> findAllSpells() {
return CasterUtils.findAllSpells(this);
}

View file

@ -6,7 +6,6 @@ import net.minecraft.util.EnumFacing;
/**
* Represents an object with an action to perform when dispensed from a dispenser.
*
*/
public interface IDispenceable extends IMagicEffect {

View file

@ -1,12 +1,13 @@
package com.minelittlepony.unicopia.spell;
import com.minelittlepony.unicopia.entity.IMagicals;
import com.minelittlepony.unicopia.init.UBlocks;
import com.minelittlepony.unicopia.init.USounds;
import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import com.minelittlepony.util.WorldEvent;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
@ -51,9 +52,14 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
return new ItemStack(Items.SLIME_BALL);
}
private boolean checkStruggleCondition(ICaster<?> caster) {
return !caster.getOrigin().equals(previousTrappedPosition)
|| (!(caster.getOwner() instanceof EntityPlayer) && caster.getWorld().rand.nextInt(20) == 0);
}
@Override
public boolean updateOnPerson(IPlayer caster) {
EntityPlayer entity = caster.getOwner();
public boolean updateOnPerson(ICaster<?> caster) {
EntityLivingBase entity = caster.getOwner();
if (entity.motionY > 0) {
entity.playSound(SoundEvents.BLOCK_SLIME_HIT, 1, 1);
@ -67,14 +73,12 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
setDirty(true);
}
if (!caster.getWorld().isRemote) {
if (!origin.equals(previousTrappedPosition)) {
previousTrappedPosition = origin;
struggleCounter--;
WorldEvent.DESTROY_BLOCK.play(caster.getWorld(), origin, Blocks.SLIME_BLOCK.getDefaultState());
if (!caster.getWorld().isRemote && checkStruggleCondition(caster)) {
previousTrappedPosition = origin;
struggleCounter--;
WorldEvent.DESTROY_BLOCK.play(caster.getWorld(), origin, Blocks.SLIME_BLOCK.getDefaultState());
setDirty(true);
}
setDirty(true);
}
if (caster.getWorld().isAirBlock(origin) || caster.getWorld().getBlockState(origin).getBlock().isReplaceable(caster.getWorld(), origin)) {
@ -97,7 +101,10 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
entity.hurtTime = 2;
entity.collidedHorizontally = true;
entity.collided = true;
entity.capabilities.isFlying = false;
if (entity instanceof EntityPlayer) {
((EntityPlayer)entity).capabilities.isFlying = false;
}
PotionEffect SLIME_REGEN = new PotionEffect(MobEffects.REGENERATION, 0);
@ -126,7 +133,7 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
}
@Override
public void renderOnPerson(IPlayer source) {
public void renderOnPerson(ICaster<?> source) {
render(source);
}
@ -140,7 +147,7 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
setDirty(true);
}
protected void entrap(IPlayer e) {
protected void entrap(ICaster<?> e) {
SpellChangelingTrap existing = e.getEffect(SpellChangelingTrap.class, true);
@ -155,8 +162,8 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect,
public void onImpact(ICaster<?> caster, BlockPos pos, IBlockState state) {
if (caster.isLocal()) {
caster.findAllEntitiesInRange(5)
.filter(e -> e instanceof EntityPlayer)
.map(e -> PlayerSpeciesList.instance().getPlayer((EntityPlayer)e))
.filter(e -> !(e instanceof IMagicals) && e instanceof EntityLivingBase)
.map(e -> PlayerSpeciesList.instance().getCaster((EntityLivingBase)e))
.forEach(this::entrap);
}
}

View file

@ -146,8 +146,6 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu
entity.setUniqueId(UUID.randomUUID());
entity.extinguish();
PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity).setEffect(null);
onEntityLoaded(source);
}
@ -179,6 +177,8 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu
return;
}
CasterUtils.toCaster(entity).ifPresent(c -> c.setEffect(null));
if (source.getWorld().isRemote) {
source.getWorld().spawnEntity(entity);
}
@ -289,7 +289,7 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu
}
@Override
public boolean updateOnPerson(IPlayer caster) {
public boolean updateOnPerson(ICaster<?> caster) {
return update(caster);
}

View file

@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.particle.ParticleConnection;
import com.minelittlepony.unicopia.particle.Particles;
import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import com.minelittlepony.unicopia.power.IPower;
import com.minelittlepony.util.ProjectileUtil;
import com.minelittlepony.util.shape.Sphere;
@ -39,7 +38,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell implements IAttac
}
@Override
public void renderOnPerson(IPlayer source) {
public void renderOnPerson(ICaster<?> source) {
render(source);
}
@ -57,7 +56,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell implements IAttac
}
@Override
public boolean updateOnPerson(IPlayer source) {
public boolean updateOnPerson(ICaster<?> source) {
int costMultiplier = applyEntities(source);
if (costMultiplier > 0) {
if (source.getOwner().ticksExisted % 20 == 0) {
@ -66,7 +65,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell implements IAttac
cost *= costMultiplier / 5F;
System.out.println("Taking " + cost);
if (!IPower.takeFromPlayer(source.getOwner(), cost)) {
if (!source.subtractEnergyCost(cost)) {
setDead();
}
}