Fixed spell levels not being saved, fixed shields, fixed the drake gem

This commit is contained in:
Sollace 2019-02-05 14:44:35 +02:00
parent 765d647018
commit 4e59f141b6
15 changed files with 254 additions and 121 deletions

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.entity; package com.minelittlepony.unicopia.entity;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.minelittlepony.unicopia.Predicates; import com.minelittlepony.unicopia.Predicates;
@ -79,12 +81,15 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
} }
@Override @Override
public void setEffect(IMagicEffect effect) { public void setEffect(@Nullable IMagicEffect effect) {
effectDelegate.set(effect); effectDelegate.set(effect);
effect.onPlaced(this); if (effect != null) {
effect.onPlaced(this);
}
} }
@Nullable
@Override @Override
public IMagicEffect getEffect() { public IMagicEffect getEffect() {
return effectDelegate.get(); return effectDelegate.get();
@ -174,7 +179,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
displayTick(); displayTick();
} }
if (getEffect() == null) { if (!hasEffect()) {
setDead(); setDead();
} else { } else {
if (getEffect().getDead()) { if (getEffect().getDead()) {
@ -274,8 +279,8 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
} }
public boolean tryLevelUp(ItemStack stack) { public boolean tryLevelUp(ItemStack stack) {
if (SpellRegistry.stackHasEnchantment(stack)) { if (hasEffect() && SpellRegistry.stackHasEnchantment(stack)) {
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) { if (!getEffect().getName().contentEquals(SpellRegistry.getKeyFromStack(stack))) {
return false; return false;
} }

View file

@ -1,48 +1,142 @@
package com.minelittlepony.unicopia.entity.ai; package com.minelittlepony.unicopia.entity.ai;
import java.lang.reflect.Field;
import com.google.common.base.Predicate;
import com.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner;
import com.minelittlepony.unicopia.spell.ICaster; import com.minelittlepony.unicopia.spell.ICaster;
import net.minecraft.entity.Entity; import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.EntityAIFollow; import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.pathfinding.PathNavigate;
import net.minecraft.pathfinding.PathNavigateFlying;
import net.minecraft.pathfinding.PathNavigateGround;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class EntityAIFollowCaster extends EntityAIFollow { public class EntityAIFollowCaster<T extends EntityLivingBase> extends EntityAIBase {
protected final ICaster<?> entity; protected final ICaster<?> casted;
private static Field __followPredicate; protected final EntityLiving entity;
static { protected EntityLivingBase owner;
try {
Field f = EntityAIFollow.class.getDeclaredFields()[1]; protected final World world;
f.setAccessible(true);
__followPredicate = RegistryLockSpinner.makeNonFinal(f); public final double followSpeed;
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace(); private final PathNavigate petPathfinder;
__followPredicate = null;
private int timeout;
public float maxDist;
public float minDist;
private float oldWaterCost;
public EntityAIFollowCaster(ICaster<T> casted, double followSpeed, float minDist, float maxDist) {
this.casted = casted;
this.entity = (EntityLiving)casted.getEntity();
this.world = casted.getWorld();
this.followSpeed = followSpeed;
this.petPathfinder = entity.getNavigator();
this.minDist = minDist;
this.maxDist = maxDist;
this.setMutexBits(3);
if (!(petPathfinder instanceof PathNavigateGround || petPathfinder instanceof PathNavigateFlying)) {
throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
} }
} }
public EntityAIFollowCaster(ICaster<?> caster, double walkSpeed, float maxDistance, float area) { /**
super((EntityLiving)caster.getEntity(), walkSpeed, maxDistance, area); * Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute() {
EntityLivingBase owner = casted.getOwner();
entity = caster; if (owner == null
|| (owner instanceof EntityPlayer && ((EntityPlayer)owner).isSpectator())
|| entity.getDistanceSq(owner) < (minDist * minDist)) {
return false;
}
if (__followPredicate != null) { this.owner = owner;
try {
__followPredicate.set(this, (Predicate<EntityLivingBase>)(e -> { return true;
Entity owner = caster.getOwner(); }
return e != null && (e == owner || (owner != null && owner.getUniqueID().equals(e.getUniqueID())));
})); @Override
} catch (IllegalArgumentException | IllegalAccessException e) { public boolean shouldContinueExecuting() {
e.printStackTrace(); return !petPathfinder.noPath()
&& entity.getDistanceSq(owner) > (maxDist * maxDist);
}
@Override
public void startExecuting() {
timeout = 0;
oldWaterCost = entity.getPathPriority(PathNodeType.WATER);
entity.setPathPriority(PathNodeType.WATER, 0);
}
@Override
public void resetTask() {
owner = null;
petPathfinder.clearPath();
entity.setPathPriority(PathNodeType.WATER, oldWaterCost);
}
@Override
public void updateTask() {
entity.getLookHelper().setLookPositionWithEntity(owner, 10, entity.getVerticalFaceSpeed());
if (--timeout > 0) {
return;
}
timeout = 10;
if (petPathfinder.tryMoveToEntityLiving(owner, followSpeed)
|| entity.getLeashed()
|| entity.isRiding()
|| entity.getDistanceSq(owner) < 144) {
return;
}
int x = MathHelper.floor(owner.posX) - 2;
int y = MathHelper.floor(owner.getEntityBoundingBox().minY);
int z = MathHelper.floor(owner.posZ) - 2;
for (int offX = 0; offX <= 4; offX++) {
for (int offZ = 0; offZ <= 4; offZ++) {
if (canTeleport(x, y, z, offX, offZ)) {
entity.setLocationAndAngles((x + offX) + 0.5F, y, (z + offZ) + 0.5F, entity.rotationYaw, entity.rotationPitch);
petPathfinder.clearPath();
return;
}
} }
} }
} }
}
protected boolean canTeleport(int x, int y, int z, int xOffset, int zOffset) {
if (xOffset < 1 || zOffset < 1 || xOffset > 3 || zOffset > 3) {
return true;
}
BlockPos pos = new BlockPos(x + xOffset, y - 1, z + zOffset);
IBlockState state = world.getBlockState(pos);
return state.getBlockFaceShape(world, pos, EnumFacing.DOWN) == BlockFaceShape.SOLID
&& state.canEntitySpawn(entity)
&& world.isAirBlock(pos.up())
&& world.isAirBlock(pos.up(2));
}
}

View file

@ -104,7 +104,9 @@ public class ModelGem extends ModelBase {
setLightingConditionsBrightness(0xF0F0); setLightingConditionsBrightness(0xF0F0);
Color.glColor(spell.getEffect().getTint(), 1); if (spell.hasEffect()) {
Color.glColor(spell.getEffect().getTint(), 1);
}
int tiers = Math.min(spell.getCurrentLevel(), 5); int tiers = Math.min(spell.getCurrentLevel(), 5);
@ -144,10 +146,7 @@ public class ModelGem extends ModelBase {
} }
protected void renderOverlay(float grow, float scale) { protected void renderOverlay(float grow, float scale) {
body.render(scale); body.render(scale);
} }
private void setLightingConditionsBrightness(int brightness) { private void setLightingConditionsBrightness(int brightness) {

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.spell.ICaster; import com.minelittlepony.unicopia.spell.ICaster;
import com.minelittlepony.unicopia.spell.IMagicEffect; import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellRegistry; import com.minelittlepony.unicopia.spell.SpellRegistry;
@ -9,6 +11,8 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataParameter;
public class EffectSync<T extends EntityLivingBase> { public class EffectSync<T extends EntityLivingBase> {
@Nullable
private IMagicEffect effect; private IMagicEffect effect;
private final ICaster<T> owned; private final ICaster<T> owned;
@ -49,7 +53,7 @@ public class EffectSync<T extends EntityLivingBase> {
return effect; return effect;
} }
public void set(IMagicEffect effect) { public void set(@Nullable IMagicEffect effect) {
if (this.effect != null && this.effect != effect) { if (this.effect != null && this.effect != effect) {
this.effect.setDead(); this.effect.setDead();
} }

View file

@ -327,12 +327,13 @@ class PlayerCapabilities implements IPlayer {
} }
@Override @Override
public void setEffect(IMagicEffect effect) { public void setEffect(@Nullable IMagicEffect effect) {
effectDelegate.set(effect); effectDelegate.set(effect);
sendCapabilities(true); sendCapabilities(true);
} }
@Nullable
@Override @Override
public IMagicEffect getEffect() { public IMagicEffect getEffect() {
return effectDelegate.get(); return effectDelegate.get();

View file

@ -1,17 +1,21 @@
package com.minelittlepony.unicopia.spell; package com.minelittlepony.unicopia.spell;
import net.minecraft.nbt.NBTTagCompound;
public abstract class AbstractSpell implements IMagicEffect { public abstract class AbstractSpell implements IMagicEffect {
protected boolean isDead = false; protected boolean isDead = false;
private int strength = 0;
@Override @Override
public int getCurrentLevel() { public int getCurrentLevel() {
return 0; return strength;
} }
@Override @Override
public void setCurrentLevel(int level) { public void setCurrentLevel(int level) {
strength = level;
} }
@Override @Override
@ -28,4 +32,16 @@ public abstract class AbstractSpell implements IMagicEffect {
public boolean getDead() { public boolean getDead() {
return isDead; return isDead;
} }
@Override
public void writeToNBT(NBTTagCompound compound) {
compound.setBoolean("dead", isDead);
compound.setInteger("spell_strength", strength);
}
@Override
public void readFromNBT(NBTTagCompound compound) {
isDead = compound.getBoolean("dead");
strength = compound.getInteger("spell_strength");
}
} }

View file

@ -5,6 +5,8 @@ import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.player.IOwned; import com.minelittlepony.unicopia.player.IOwned;
import com.minelittlepony.util.shape.IShape; import com.minelittlepony.util.shape.IShape;
import com.minelittlepony.util.vector.VecHelper; import com.minelittlepony.util.vector.VecHelper;
@ -17,8 +19,9 @@ import net.minecraft.world.World;
public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled, IAligned { public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled, IAligned {
void setEffect(IMagicEffect effect); void setEffect(@Nullable IMagicEffect effect);
@Nullable
IMagicEffect getEffect(); IMagicEffect getEffect();
default boolean hasEffect() { default boolean hasEffect() {

View file

@ -83,4 +83,8 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned {
default boolean allowAI() { default boolean allowAI() {
return false; return false;
} }
default IMagicEffect copy() {
return SpellRegistry.instance().copyInstance(this);
}
} }

View file

@ -18,8 +18,6 @@ import net.minecraft.util.math.Vec3d;
public class SpellCharge extends AbstractSpell { public class SpellCharge extends AbstractSpell {
private int desiredLevel = 0;
boolean searching = true; boolean searching = true;
private UUID targettedEntityId; private UUID targettedEntityId;
@ -115,30 +113,21 @@ public class SpellCharge extends AbstractSpell {
return 2; return 2;
} }
@Override
public int getCurrentLevel() {
return desiredLevel;
}
@Override
public void setCurrentLevel(int level) {
desiredLevel = level;
}
@Override @Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
if (targettedEntityId != null) { if (targettedEntityId != null) {
compound.setUniqueId("target", targettedEntityId); compound.setUniqueId("target", targettedEntityId);
} }
compound.setInteger("level", desiredLevel);
} }
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
if (compound.hasKey("target")) { if (compound.hasKey("target")) {
targettedEntityId = compound.getUniqueId("target"); targettedEntityId = compound.getUniqueId("target");
} }
desiredLevel = compound.getInteger("level");
} }
} }

View file

@ -208,6 +208,7 @@ public class SpellDisguise extends AbstractSpell {
@Override @Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
compound.setString("entityId", entityId); compound.setString("entityId", entityId);
compound.setBoolean("dead", getDead()); compound.setBoolean("dead", getDead());
@ -225,6 +226,8 @@ public class SpellDisguise extends AbstractSpell {
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
String newId = compound.getString("entityId"); String newId = compound.getString("entityId");
if (!newId.contentEquals(entityId)) { if (!newId.contentEquals(entityId)) {

View file

@ -49,7 +49,7 @@ public class SpellDrake extends AbstractSpell {
} }
public boolean getDead() { public boolean getDead() {
return super.getDead() || (piggyBackSpell != null && piggyBackSpell.getDead()); return super.getDead();
} }
@Override @Override
@ -58,28 +58,36 @@ public class SpellDrake extends AbstractSpell {
if (firstUpdate) { if (firstUpdate) {
firstUpdate = false; firstUpdate = false;
if (source.getOwner() instanceof EntitySpell) { if (source.getEntity() instanceof EntitySpell) {
EntitySpell living = (EntitySpell)source.getOwner(); EntitySpell living = (EntitySpell)source.getEntity();
((PathNavigateGround)living.getNavigator()).setCanSwim(false); ((PathNavigateGround)living.getNavigator()).setCanSwim(false);
living.tasks.addTask(1, new EntityAISwimming(living)); living.tasks.addTask(1, new EntityAISwimming(living));
living.tasks.addTask(2, new EntityAIFollowCaster(source, 1, 4, 6)); living.tasks.addTask(2, new EntityAIFollowCaster<>(source, 1, 4, 70));
} }
} }
if (piggyBackSpell == null) { if (!source.getWorld().isRemote) {
AxisAlignedBB bb = EFFECT_BOUNDS.offset(source.getOriginVector());
source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e -> e instanceof EntitySpell).stream() if (piggyBackSpell == null) {
.map(i -> (EntitySpell)i) AxisAlignedBB bb = EFFECT_BOUNDS.offset(source.getOriginVector());
.filter(i -> i.getEffect() != null && !(i.getEffect() instanceof SpellDrake))
.findFirst().ifPresent(i -> { source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e -> e instanceof EntitySpell).stream()
piggyBackSpell = i.getEffect(); .map(i -> (EntitySpell)i)
i.setEffect(null); .filter(i -> i.hasEffect() && !(i.getEffect() instanceof SpellDrake))
}); .findFirst().ifPresent(i -> {
piggyBackSpell = i.getEffect().copy();
piggyBackSpell.onPlaced(source);
i.setEffect(null);
});
}
} }
return piggyBackSpell != null && piggyBackSpell.update(source, level); if (piggyBackSpell != null) {
piggyBackSpell.update(source, level);
}
return true;
} }
@Override @Override
@ -89,7 +97,10 @@ public class SpellDrake extends AbstractSpell {
} }
} }
@Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
if (piggyBackSpell != null) { if (piggyBackSpell != null) {
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(piggyBackSpell)); compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(piggyBackSpell));
} }
@ -97,6 +108,8 @@ public class SpellDrake extends AbstractSpell {
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
if (compound.hasKey("effect")) { if (compound.hasKey("effect")) {
piggyBackSpell = SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")); piggyBackSpell = SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect"));
} }

View file

@ -290,6 +290,8 @@ public class SpellPortal extends AbstractSpell implements IUseAction {
@Override @Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
if (destinationPos != null) { if (destinationPos != null) {
compound.setTag("destination", InbtSerialisable.writeBlockPos(destinationPos)); compound.setTag("destination", InbtSerialisable.writeBlockPos(destinationPos));
} }
@ -307,6 +309,8 @@ public class SpellPortal extends AbstractSpell implements IUseAction {
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
if (compound.hasKey("destination")) { if (compound.hasKey("destination")) {
destinationPos = InbtSerialisable.readBlockPos(compound.getCompoundTag("destination")); destinationPos = InbtSerialisable.readBlockPos(compound.getCompoundTag("destination"));
} }

View file

@ -53,6 +53,11 @@ public class SpellRegistry {
return null; return null;
} }
@SuppressWarnings("unchecked")
public <T extends IMagicEffect> T copyInstance(T effect) {
return (T)createEffectFromNBT(serializeEffectToNBT(effect));
}
public IMagicEffect createEffectFromNBT(NBTTagCompound compound) { public IMagicEffect createEffectFromNBT(NBTTagCompound compound) {
if (compound.hasKey("effect_id")) { if (compound.hasKey("effect_id")) {
IMagicEffect effect = getSpellFromName(compound.getString("effect_id")); IMagicEffect effect = getSpellFromName(compound.getString("effect_id"));

View file

@ -13,23 +13,10 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents; import net.minecraft.init.SoundEvents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class SpellShield extends AbstractSpell { public class SpellShield extends AbstractSpell {
private int strength = 0;
@Override
public int getCurrentLevel() {
return strength;
}
@Override
public void setCurrentLevel(int level) {
strength = level;
}
@Override @Override
public String getName() { public String getName() {
return "shield"; return "shield";
@ -52,43 +39,51 @@ public class SpellShield extends AbstractSpell {
@Override @Override
public void render(ICaster<?> source, int level) { public void render(ICaster<?> source, int level) {
spawnParticles(source, 4 + (level * 2)); level = 4 + (level * 2);
}
protected void spawnParticles(ICaster<?> source, int strength) { source.spawnParticles(new Sphere(true, level), level * 6, pos -> {
source.spawnParticles(new Sphere(true, strength), strength * 6, pos -> { Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0);
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0); });
});
} }
@Override @Override
public boolean updateOnPerson(ICaster<?> source) { public boolean updateOnPerson(ICaster<?> source) {
update(source, strength); if (super.updateOnPerson(source)) {
if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) {
if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) { double radius = 4 + (getCurrentLevel() * 2);
double radius = 4 + (strength * 2); if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) {
if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) { setDead();
setDead(); }
} }
} }
return !getDead(); return !getDead();
} }
protected double getDrawDropOffRange(int level) {
return 4 + (level * 2);
}
@Override @Override
public boolean update(ICaster<?> source, int level) { public boolean update(ICaster<?> source, int level) {
double radius = 4 + (level * 2); double radius = getDrawDropOffRange(level);
Entity owner = source.getOwner(); Entity owner = source.getOwner();
boolean ownerIsValid = source.getAffinity() != SpellAffinity.BAD && Predicates.MAGI.test(owner); boolean ownerIsValid = source.getAffinity() != SpellAffinity.BAD && Predicates.MAGI.test(owner);
Vec3d origin = source.getOriginVector();
source.findAllEntitiesInRange(radius) source.findAllEntitiesInRange(radius)
.filter(entity -> !(ownerIsValid && entity.equals(owner))) .filter(entity -> !(ownerIsValid && entity.equals(owner)))
.forEach(i -> { .forEach(i -> {
double dist = Math.sqrt(i.getDistanceSq(source.getOrigin())); try {
double dist = i.getPositionVector().distanceTo(origin);
applyRadialEffect(source, i, dist, radius); applyRadialEffect(source, i, dist, radius);
} catch (Throwable e) {
e.printStackTrace();
}
}); });
return true; return true;
@ -107,10 +102,12 @@ public class SpellShield extends AbstractSpell {
} }
} }
} else if (target instanceof EntityLivingBase) { } else if (target instanceof EntityLivingBase) {
double force = Math.min(0.25F, distance); double force = Math.max(0.1, radius / 4);
if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) { if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) {
force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target)); force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target));
} else {
force *= 0.75;
} }
applyForce(pos, target, force, distance); applyForce(pos, target, force, distance);
@ -121,12 +118,12 @@ public class SpellShield extends AbstractSpell {
* Applies a force to the given entity based on distance from the source. * Applies a force to the given entity based on distance from the source.
*/ */
protected void applyForce(Vec3d pos, Entity target, double force, double distance) { protected void applyForce(Vec3d pos, Entity target, double force, double distance) {
pos = target.getPositionVector().subtract(pos); pos = target.getPositionVector().subtract(pos).normalize().scale(force);
target.addVelocity( target.addVelocity(
force / pos.x, pos.x,
force / pos.y + (distance < 1 ? distance : 0), pos.y + (distance < 1 ? distance : 0),
force / pos.z pos.z
); );
} }
@ -163,14 +160,4 @@ public class SpellShield extends AbstractSpell {
ProjectileUtil.setThrowableHeading(projectile, normal, (float)motion.length(), 0); ProjectileUtil.setThrowableHeading(projectile, normal, (float)motion.length(), 0);
} }
} }
@Override
public void writeToNBT(NBTTagCompound compound) {
compound.setInteger("spell_strength", strength);
}
@Override
public void readFromNBT(NBTTagCompound compound) {
strength = compound.getInteger("spell_strength");
}
} }

View file

@ -23,19 +23,25 @@ public class SpellVortex extends SpellShield {
} }
@Override @Override
protected void spawnParticles(ICaster<?> source, int strength) { public void render(ICaster<?> source, int level) {
level = 4 + (level * 2);
Vec3d pos = source.getOriginVector(); Vec3d pos = source.getOriginVector();
source.spawnParticles(new Sphere(false, strength), strength * 9, p -> { source.spawnParticles(new Sphere(false, level), level * 9, p -> {
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, p, p.subtract(pos)); Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, p, p.subtract(pos));
}); });
} }
@Override
protected double getDrawDropOffRange(int level) {
return 10 + (level * 2);
}
@Override @Override
protected void applyRadialEffect(ICaster<?> source, Entity target, double distance, double radius) { protected void applyRadialEffect(ICaster<?> source, Entity target, double distance, double radius) {
Vec3d pos = source.getOriginVector(); Vec3d pos = source.getOriginVector();
double force = 4 / distance; double force = 2.5F / distance;
if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) { if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) {
force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target)); force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target));