Fix up spells slightly

This commit is contained in:
Sollace 2018-09-24 21:37:16 +02:00
parent c9e912a378
commit 38e7b8bc36
11 changed files with 200 additions and 169 deletions

View file

@ -12,12 +12,12 @@ public final class Predicates {
return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds(); return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds();
}; };
public static final Predicate<EntityPlayer> MAGI = player -> { public static final Predicate<Entity> MAGI = entity -> {
return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canCast(); return entity instanceof EntityPlayer && PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity).getPlayerSpecies().canCast();
}; };
public static final Predicate<Entity> ITEMS = entity -> { public static final Predicate<Entity> ITEMS = entity -> {
return entity.isEntityAlive() && entity instanceof EntityItem; return entity instanceof EntityItem && entity.isEntityAlive();
}; };
public static final Predicate<EntityItem> ITEM_INTERACT_WITH_CLOUDS = item -> { public static final Predicate<EntityItem> ITEM_INTERACT_WITH_CLOUDS = item -> {

View file

@ -1,10 +1,13 @@
package com.minelittlepony.unicopia.entity; package com.minelittlepony.unicopia.entity;
import org.apache.commons.lang3.StringUtils;
import com.minelittlepony.unicopia.Predicates; import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.UItems; import com.minelittlepony.unicopia.UItems;
import com.minelittlepony.unicopia.item.ItemSpell; import com.minelittlepony.unicopia.item.ICastable;
import com.minelittlepony.unicopia.network.EffectSync; import com.minelittlepony.unicopia.network.EffectSync;
import com.minelittlepony.unicopia.spell.ICaster; import com.minelittlepony.unicopia.spell.ICaster;
import com.minelittlepony.unicopia.spell.ILevelled;
import com.minelittlepony.unicopia.spell.IMagicEffect; import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellRegistry; import com.minelittlepony.unicopia.spell.SpellRegistry;
@ -28,7 +31,7 @@ import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase> { public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase>, ILevelled {
private EntityLivingBase owner = null; private EntityLivingBase owner = null;
@ -102,7 +105,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
} }
protected void setOwner(String ownerName) { protected void setOwner(String ownerName) {
if (ownerName != null && ownerName.length() != 0) { if (!StringUtils.isEmpty(ownerName)) {
dataManager.set(OWNER, ownerName); dataManager.set(OWNER, ownerName);
} }
} }
@ -110,7 +113,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
protected String getOwnerName() { protected String getOwnerName() {
String ownerName = dataManager.get(OWNER); String ownerName = dataManager.get(OWNER);
if (ownerName == null || ownerName.length() == 0) { if (!StringUtils.isEmpty(ownerName)) {
if (owner instanceof EntityPlayer) { if (owner instanceof EntityPlayer) {
return owner.getName(); return owner.getName();
} }
@ -135,7 +138,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
protected void displayTick() { protected void displayTick() {
if (hasEffect()) { if (hasEffect()) {
getEffect().renderAt(this, world, posX, posY, posZ, getLevel()); getEffect().render(this, getCurrentLevel());
} }
} }
@ -152,7 +155,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
setDead(); setDead();
onDeath(); onDeath();
} else { } else {
getEffect().updateAt(this, world, posX, posY, posZ, getLevel()); getEffect().update(this, getCurrentLevel());
} }
if (getEffect().allowAI()) { if (getEffect().allowAI()) {
@ -186,7 +189,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.NEUTRAL, sound.getVolume(), sound.getPitch(), true); world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.NEUTRAL, sound.getVolume(), sound.getPitch(), true);
if (world.getGameRules().getBoolean("doTileDrops")) { if (world.getGameRules().getBoolean("doTileDrops")) {
int level = getLevel(); int level = getCurrentLevel();
ItemStack stack = new ItemStack(UItems.spell, level + 1); ItemStack stack = new ItemStack(UItems.spell, level + 1);
if (hasEffect()) { if (hasEffect()) {
@ -204,44 +207,14 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
super.setDead(); super.setDead();
} }
public int getLevel() {
return dataManager.get(LEVEL);
}
public void setLevel(int radius) {
dataManager.set(LEVEL, radius);
}
public boolean tryLevelUp(ItemStack stack) {
if (SpellRegistry.stackHasEnchantment(stack)) {
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) {
return false;
}
increaseLevel();
if (!world.isRemote) {
if ((rand.nextFloat() * getLevel()) > 10 || overLevelCap()) {
world.createExplosion(this, posX, posY, posZ, getLevel()/2, true);
setDead();
return false;
}
}
playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1);
return true;
}
return false;
}
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) { public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) {
if (Predicates.MAGI.test(player)) { if (Predicates.MAGI.test(player)) {
ItemStack currentItem = player.getHeldItem(EnumHand.MAIN_HAND); ItemStack currentItem = player.getHeldItem(EnumHand.MAIN_HAND);
if (currentItem != null && currentItem.getItem() instanceof ItemSpell) { if (currentItem != null
tryLevelUp(currentItem); && currentItem.getItem() instanceof ICastable
&& ((ICastable)currentItem.getItem()).canFeed(this, currentItem)
&& tryLevelUp(currentItem)) {
if (!player.capabilities.isCreativeMode) { if (!player.capabilities.isCreativeMode) {
currentItem.shrink(1); currentItem.shrink(1);
@ -258,24 +231,48 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
return EnumActionResult.FAIL; return EnumActionResult.FAIL;
} }
public void increaseLevel() { public boolean tryLevelUp(ItemStack stack) {
setLevel(getLevel() + 1); if (SpellRegistry.stackHasEnchantment(stack)) {
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) {
return false;
} }
public boolean canLevelUp() { addLevels(1);
int max = getEffect().getMaxLevel();
return max < 0 || getLevel() < max; if (!world.isRemote) {
if ((rand.nextFloat() * getCurrentLevel()) > 10 || overLevelCap()) {
world.createExplosion(this, posX, posY, posZ, getCurrentLevel()/2, true);
setDead();
return false;
}
}
playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1);
return true;
}
return false;
}
@Override
public int getMaxLevel() {
return getEffect().getMaxLevel();
}
@Override
public int getCurrentLevel() {
return dataManager.get(LEVEL);
}
@Override
public void setCurrentLevel(int level) {
dataManager.set(LEVEL, Math.min(level, 0));
} }
public boolean overLevelCap() { public boolean overLevelCap() {
int max = getEffect().getMaxLevel(); int max = getMaxLevel();
return max > 0 && getLevel() >= (max * 1.1); return max > 0 && getCurrentLevel() >= (max * 1.1);
}
public void decreaseLevel() {
int level = getLevel() - 1;
if (level < 0) level = 0;
setLevel(level);
} }
@Override @Override
@ -287,7 +284,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
public void readEntityFromNBT(NBTTagCompound compound) { public void readEntityFromNBT(NBTTagCompound compound) {
super.readEntityFromNBT(compound); super.readEntityFromNBT(compound);
setOwner(compound.getString("ownerName")); setOwner(compound.getString("ownerName"));
setLevel(compound.getInteger("level")); setCurrentLevel(compound.getInteger("level"));
if (compound.hasKey("effect")) { if (compound.hasKey("effect")) {
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect"))); setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
@ -299,7 +296,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
super.writeEntityToNBT(compound); super.writeEntityToNBT(compound);
compound.setString("ownerName", getOwnerName()); compound.setString("ownerName", getOwnerName());
compound.setInteger("level", getLevel()); compound.setInteger("level", getCurrentLevel());
if (hasEffect()) { if (hasEffect()) {
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(getEffect())); compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(getEffect()));

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.spell.IDispenceable; import com.minelittlepony.unicopia.spell.IDispenceable;
import com.minelittlepony.unicopia.spell.IMagicEffect; import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellCastResult; import com.minelittlepony.unicopia.spell.SpellCastResult;
@ -16,4 +17,7 @@ public interface ICastable extends IMagicalItem {
SpellCastResult onDispenseSpell(IBlockSource source, ItemStack stack, IDispenceable effect); SpellCastResult onDispenseSpell(IBlockSource source, ItemStack stack, IDispenceable effect);
SpellCastResult onCastSpell(EntityPlayer player, World world, BlockPos pos, ItemStack stack, IMagicEffect effect, EnumFacing side, float hitX, float hitY, float hitZ); SpellCastResult onCastSpell(EntityPlayer player, World world, BlockPos pos, ItemStack stack, IMagicEffect effect, EnumFacing side, float hitX, float hitY, float hitZ);
boolean canFeed(EntitySpell spell, ItemStack stack);
} }

View file

@ -180,4 +180,12 @@ public class ItemSpell extends Item implements ICastable {
return spell; return spell;
} }
@Override
public boolean canFeed(EntitySpell entity, ItemStack stack) {
IMagicEffect effect = entity.getEffect();
return effect != null && effect.getName().equals(SpellRegistry.getKeyFromStack(stack));
}
} }

View file

@ -80,8 +80,8 @@ public class ModelGem extends ModelBase {
GlStateManager.translate(0, floatOffset, 0); GlStateManager.translate(0, floatOffset, 0);
floatOffset = (spell.ticksExisted + stutter) / 20; floatOffset = (spell.ticksExisted + stutter) / 20;
if (spell.getLevel() > 0) { if (spell.getCurrentLevel() > 0) {
floatOffset *= spell.getLevel() + 1; floatOffset *= spell.getCurrentLevel() + 1;
} }
floatOffset += spell.hoverStart; floatOffset += spell.hoverStart;

View file

@ -139,10 +139,10 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
setEffect(null); setEffect(null);
} else { } else {
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0 if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
getEffect().render(entity); getEffect().render(this);
} }
if (!getEffect().update(entity)) { if (!getEffect().update(this)) {
setEffect(null); setEffect(null);
} }
} }

View file

@ -1,8 +1,5 @@
package com.minelittlepony.unicopia.spell; package com.minelittlepony.unicopia.spell;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
public abstract class AbstractSpell implements IMagicEffect { public abstract class AbstractSpell implements IMagicEffect {
protected boolean isDead = false; protected boolean isDead = false;
@ -16,14 +13,4 @@ public abstract class AbstractSpell implements IMagicEffect {
public boolean getDead() { public boolean getDead() {
return isDead; return isDead;
} }
@Override
public boolean update(Entity source) {
return false;
}
@Override
public boolean updateAt(ICaster<?> source, World w, double x, double y, double z, int level) {
return false;
}
} }

View file

@ -4,6 +4,8 @@ import com.minelittlepony.unicopia.player.IOwned;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface ICaster<E extends EntityLivingBase> extends IOwned<E> { public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
void setEffect(IMagicEffect effect); void setEffect(IMagicEffect effect);
@ -20,4 +22,12 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
default Entity getEntity() { default Entity getEntity() {
return getOwner(); return getOwner();
} }
default World getWorld() {
return getEntity().getEntityWorld();
}
default BlockPos getOrigin() {
return getEntity().getPosition();
}
} }

View file

@ -0,0 +1,26 @@
package com.minelittlepony.unicopia.spell;
public interface ILevelled {
/**
* Maximum level this spell can reach or -1 for unlimited.
* <br>
* If a gem goes past this level it is more likely to explode.
*/
default int getMaxLevel() {
return 0;
}
default boolean canLevelUp() {
int max = getMaxLevel();
return max < 0 || getCurrentLevel() < max;
}
int getCurrentLevel();
void setCurrentLevel(int level);
default void addLevels(int levels) {
setCurrentLevel(getCurrentLevel() + levels);
}
}

View file

@ -2,24 +2,10 @@ package com.minelittlepony.unicopia.spell;
import com.minelittlepony.unicopia.InbtSerialisable; import com.minelittlepony.unicopia.InbtSerialisable;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
/** /**
* * Interface for a magic spells
* Interface for a magic spell
*
*/ */
public interface IMagicEffect extends InbtSerialisable { public interface IMagicEffect extends InbtSerialisable, ILevelled {
/**
* Maximum level this spell can reach or -1 for unlimited.
* <br>
* If a gem goes past this level it is more likely to explode.
*/
default int getMaxLevel() {
return 0;
}
String getName(); String getName();
@ -39,7 +25,15 @@ public interface IMagicEffect extends InbtSerialisable {
* @param source The entity we are currently attached to. * @param source The entity we are currently attached to.
* @return true to keep alive * @return true to keep alive
*/ */
boolean update(Entity source); boolean update(ICaster<?> caster);
/**
* Called every tick when attached to a gem.
*
* @param source The entity we are currently attached to.
* @param level Current active spell level
*/
boolean update(ICaster<?> source, int level);
/** /**
* Called every tick when attached to a player. Used to apply particle effects. * Called every tick when attached to a player. Used to apply particle effects.
@ -47,34 +41,18 @@ public interface IMagicEffect extends InbtSerialisable {
* *
* @param source The entity we are currently attached to. * @param source The entity we are currently attached to.
*/ */
default void render(Entity source) { default void render(ICaster<?> source) {
} }
/**
* Called every tick when attached to a gem.
*
* @param source The entity we are attached to.
* @param w The world
* @param x Entity position x
* @param y Entity position y
* @param z Entity position z
* @param level Current spell level
*/
boolean updateAt(ICaster<?> source, World w, double x, double y, double z, int level);
/** /**
* Called every tick when attached to an entity to produce particle effects. * Called every tick when attached to an entity to produce particle effects.
* Is only called on the client side. * Is only called on the client side.
* *
* @param source The entity we are attached to. * @param source The entity we are attached to.
* @param w The world
* @param x Entity position x
* @param y Entity position y
* @param z Entity position z
* @param level Current spell level * @param level Current spell level
*/ */
default void renderAt(ICaster<?> source, World w, double x, double y, double z, int level) { default void render(ICaster<?> source, int level) {
} }

View file

@ -1,5 +1,8 @@
package com.minelittlepony.unicopia.spell; package com.minelittlepony.unicopia.spell;
import java.util.Random;
import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.client.particle.Particles; import com.minelittlepony.unicopia.client.particle.Particles;
@ -15,8 +18,8 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents; import net.minecraft.init.SoundEvents;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class SpellShield extends AbstractSpell { public class SpellShield extends AbstractSpell {
@ -26,10 +29,16 @@ public class SpellShield extends AbstractSpell {
} }
public SpellShield(int type) { public SpellShield(int type) {
setStrength(type); setCurrentLevel(type);
} }
public void setStrength(int level) { @Override
public int getCurrentLevel() {
return strength;
}
@Override
public void setCurrentLevel(int level) {
strength = level; strength = level;
} }
@ -44,21 +53,28 @@ public class SpellShield extends AbstractSpell {
} }
@Override @Override
public void render(Entity source) { public void render(ICaster<?> source) {
spawnParticles(source.getEntityWorld(), source.posX, source.posY, source.posZ, 4 + (strength * 2)); spawnParticles(source, 4 + (strength * 2));
} }
public void renderAt(ICaster<?> source, World w, double x, double y, double z, int level) { @Override
if (w.rand.nextInt(4 + level * 4) == 0) { public void render(ICaster<?> source, int level) {
spawnParticles(w, x, y, z, 4 + (level * 2)); if (source.getWorld().rand.nextInt(4 + level * 4) == 0) {
spawnParticles(source, 4 + (level * 2));
} }
} }
protected void spawnParticles(World w, double x, double y, double z, int strength) { protected void spawnParticles(ICaster<?> source, int strength) {
IShape sphere = new Sphere(true, strength); IShape sphere = new Sphere(true, strength);
Random rand = source.getWorld().rand;
int x = source.getOrigin().getX();
int y = source.getOrigin().getY();
int z = source.getOrigin().getZ();
for (int i = 0; i < strength * 6; i++) { for (int i = 0; i < strength * 6; i++) {
Vec3d pos = sphere.computePoint(w.rand); Vec3d pos = sphere.computePoint(rand);
Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false, Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false,
pos.x + x, pos.y + y, pos.z + z, pos.x + x, pos.y + y, pos.z + z,
0, 0, 0); 0, 0, 0);
@ -66,12 +82,12 @@ public class SpellShield extends AbstractSpell {
} }
@Override @Override
public boolean update(Entity source) { public boolean update(ICaster<?> source) {
applyEntities(null, source, source.getEntityWorld(), source.posX, source.posY, source.posZ, strength); update(source, strength);
if (source.getEntityWorld().getWorldTime() % 50 == 0) { if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) {
double radius = 4 + (strength * 2); double radius = 4 + (strength * 2);
if (!IPower.takeFromPlayer((EntityPlayer)source, radius/4)) { if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) {
setDead(); setDead();
} }
} }
@ -80,37 +96,41 @@ public class SpellShield extends AbstractSpell {
} }
@Override @Override
public boolean updateAt(ICaster<?> source, World w, double x, double y, double z, int level) { public boolean update(ICaster<?> source, int level) {
return applyEntities(source, source.getOwner(), w, x, y, z, level);
}
private boolean applyEntities(ICaster<?> source, Entity owner, World w, double x, double y, double z, int level) {
double radius = 4 + (level * 2); double radius = 4 + (level * 2);
AxisAlignedBB bb = new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); Entity owner = source.getOwner();
BlockPos pos = source.getOrigin();
for (Entity i : w.getEntitiesWithinAABBExcludingEntity(source == null ? null : source.getEntity(), bb)) { int x = pos.getX(), y = pos.getY(), z = pos.getZ();
if ((!i.equals(owner)
|| (owner instanceof EntityPlayer
&& !PlayerSpeciesList.instance().getPlayer((EntityPlayer)owner).getPlayerSpecies().canCast()))) {
BlockPos begin = pos.add(-radius, -radius, -radius);
BlockPos end = pos.add(radius, radius, radius);
AxisAlignedBB bb = new AxisAlignedBB(begin, end);
boolean ownerIsValid = Predicates.MAGI.test(owner);
for (Entity i : source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, entity -> !(ownerIsValid && entity.equals(owner)))) {
double dist = i.getDistance(x, y, z); double dist = i.getDistance(x, y, z);
double dist2 = i.getDistance(x, y - i.getEyeHeight(), z); double dist2 = i.getDistance(x, y - i.getEyeHeight(), z);
boolean projectile = ProjectileUtil.isProjectile(i); if (dist > radius && dist2 > radius) {
continue;
}
if (dist <= radius || dist2 <= radius) { if (ProjectileUtil.isProjectile(i)) {
if (projectile) {
if (!ProjectileUtil.isProjectileThrownBy(i, owner)) { if (!ProjectileUtil.isProjectileThrownBy(i, owner)) {
if (dist < radius/2) { if (dist < radius/2) {
i.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1); i.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1);
i.setDead(); i.setDead();
} else { } else {
ricochet(i, x, y, z); ricochet(i, pos);
} }
} }
} else if (i instanceof EntityLivingBase) { } else if (i instanceof EntityLivingBase) {
double force = dist; double force = Math.min(0.25F, dist);
if (i instanceof EntityPlayer) { if (i instanceof EntityPlayer) {
force = calculateForce((EntityPlayer)i); force = calculateForce((EntityPlayer)i);
} }
@ -121,8 +141,7 @@ public class SpellShield extends AbstractSpell {
-(z - i.posZ) / force); -(z - i.posZ) / force);
} }
} }
}
}
return true; return true;
} }
@ -142,11 +161,11 @@ public class SpellShield extends AbstractSpell {
return force; return force;
} }
private void ricochet(Entity projectile, double x, double y, double z) { private void ricochet(Entity projectile, BlockPos pos) {
Vec3d position = new Vec3d(projectile.posX, projectile.posY, projectile.posZ); Vec3d position = new Vec3d(projectile.posX, projectile.posY, projectile.posZ);
Vec3d motion = new Vec3d(projectile.motionX, projectile.motionY, projectile.motionZ); Vec3d motion = new Vec3d(projectile.motionX, projectile.motionY, projectile.motionZ);
Vec3d normal = position.subtract(x, y, z).normalize(); Vec3d normal = position.subtract(pos.getX(), pos.getY(), pos.getZ()).normalize();
Vec3d approach = motion.subtract(normal); Vec3d approach = motion.subtract(normal);
if (approach.length() >= motion.length()) { if (approach.length() >= motion.length()) {
@ -154,10 +173,12 @@ public class SpellShield extends AbstractSpell {
} }
} }
@Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
compound.setInteger("spell_strength", strength); compound.setInteger("spell_strength", strength);
} }
@Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
strength = compound.getInteger("spell_strength"); strength = compound.getInteger("spell_strength");
} }