From 545bd3a34b0a2a3744f1c4112e96cd58cb04023e Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Feb 2019 10:31:31 +0200 Subject: [PATCH] Rewrote spell levelling --- .../unicopia/entity/EntitySpell.java | 53 ++++++++--------- .../unicopia/spell/AbstractSpell.java | 58 ++++++++++++++----- .../unicopia/spell/IMagicEffect.java | 26 ++++++--- .../unicopia/spell/SpellAwkward.java | 6 +- .../unicopia/spell/SpellCharge.java | 13 ++--- .../unicopia/spell/SpellDisguise.java | 4 +- .../unicopia/spell/SpellDrake.java | 8 +-- .../unicopia/spell/SpellFire.java | 8 +-- .../unicopia/spell/SpellIce.java | 6 +- .../unicopia/spell/SpellInferno.java | 4 +- .../unicopia/spell/SpellNecromancy.java | 14 ++--- .../unicopia/spell/SpellPortal.java | 6 +- .../unicopia/spell/SpellShield.java | 21 +++---- .../unicopia/spell/SpellVortex.java | 10 ++-- 14 files changed, 133 insertions(+), 104 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntitySpell.java b/src/main/java/com/minelittlepony/unicopia/entity/EntitySpell.java index 33a75785..3053a808 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/EntitySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntitySpell.java @@ -169,7 +169,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster 0 && !world.isRemote && world.rand.nextInt(200) == 0) { - addLevels(-1); - if (getCurrentLevel() <= 0) { - setDead(); - } - } - if (overLevelCap()) { if (world.rand.nextInt(10) == 0) { spawnExplosionParticle(); } + + if (!world.isRemote && hasEffect()) { + float exhaustionChance = getEffect().getExhaustion(this); + + if (exhaustionChance == 0 || world.rand.nextInt((int)(exhaustionChance / 500)) == 0) { + addLevels(-1); + } else if (world.rand.nextInt((int)(exhaustionChance * 500)) == 0) { + setEffect(null); + } else if (world.rand.nextInt((int)(exhaustionChance * 3500)) == 0) { + world.createExplosion(this, posX, posY, posZ, getCurrentLevel()/2, true); + setDead(); + } + } } + + if (getCurrentLevel() < 0) { + setDead(); + } } @Override @@ -213,6 +223,10 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster getMaxLevel(); + } + @Override protected void updateFallState(double y, boolean onGround, IBlockState state, BlockPos pos) { this.onGround = true; @@ -286,14 +300,6 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster 10) { - world.createExplosion(this, posX, posY, posZ, getCurrentLevel()/2, true); - setDead(); - return false; - } - } - playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1); return true; @@ -304,7 +310,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster 0 && getCurrentLevel() >= (max * 1.1); - } - @Override public Entity getEntity() { return this; diff --git a/src/main/java/com/minelittlepony/unicopia/spell/AbstractSpell.java b/src/main/java/com/minelittlepony/unicopia/spell/AbstractSpell.java index 7d55e010..c98ddf1d 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/AbstractSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/AbstractSpell.java @@ -7,18 +7,6 @@ public abstract class AbstractSpell implements IMagicEffect { protected boolean isDead; protected boolean isDirty; - private int strength = 0; - - @Override - public int getCurrentLevel() { - return strength; - } - - @Override - public void setCurrentLevel(int level) { - strength = level; - } - @Override public boolean isCraftable() { return true; @@ -44,16 +32,58 @@ public abstract class AbstractSpell implements IMagicEffect { isDirty = dirty; } + @Override + public int getMaxLevelCutOff(ICaster source) { + return 1; + } + + public float getMaxExhaustion(ICaster caster) { + return 1; + } + + public float getExhaustion(ICaster caster) { + return 0; + } + @Override public void writeToNBT(NBTTagCompound compound) { compound.setBoolean("dead", isDead); - compound.setInteger("spell_strength", strength); } @Override public void readFromNBT(NBTTagCompound compound) { setDirty(false); isDead = compound.getBoolean("dead"); - strength = compound.getInteger("spell_strength"); + } + + public static abstract class RangedAreaSpell extends AbstractSpell { + + @Override + public int getMaxLevelCutOff(ICaster source) { + return 17; + } + + @Override + public float getMaxExhaustion(ICaster caster) { + return 1000; + } + + @Override + public float getExhaustion(ICaster caster) { + float max = getMaxLevelCutOff(caster); + float current = caster.getCurrentLevel(); + + if (current > max) { + float maxEc = getMaxExhaustion(caster); + + current -= max; + current /= max; + current /= maxEc; + + return maxEc - current; + } + + return super.getExhaustion(caster); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/IMagicEffect.java b/src/main/java/com/minelittlepony/unicopia/spell/IMagicEffect.java index 63ba9e5d..04259ac2 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/IMagicEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/IMagicEffect.java @@ -5,7 +5,7 @@ import com.minelittlepony.unicopia.util.serialisation.InbtSerialisable; /** * Interface for a magic spells */ -public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned { +public interface IMagicEffect extends InbtSerialisable, IAligned { /** * Gets the name used to identify this effect. @@ -42,6 +42,20 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned { */ boolean isCraftable(); + + /** + * Gets the highest level this spell can be safely operated at. + * Gems may go higher, however chance of explosion/exhaustion increases with every level. + */ + int getMaxLevelCutOff(ICaster caster); + + float getMaxExhaustion(ICaster caster); + + /** + * Gets the chances of this effect turning into an innert gem or exploding. + */ + float getExhaustion(ICaster caster); + /** * Called when first attached to a gem. */ @@ -56,7 +70,7 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned { * @return true to keep alive */ default boolean updateOnPerson(ICaster caster) { - return update(caster, getCurrentLevel()); + return update(caster); } /** @@ -64,9 +78,8 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned { * Called on both sides. * * @param source The entity we are currently attached to. - * @param level Current active spell level */ - boolean update(ICaster source, int level); + boolean update(ICaster source); /** * Called every tick when attached to a player. Used to apply particle effects. @@ -75,7 +88,7 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned { * @param source The entity we are currently attached to. */ default void renderOnPerson(ICaster source) { - render(source, getCurrentLevel()); + render(source); } /** @@ -83,9 +96,8 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned { * Is only called on the client side. * * @param source The entity we are attached to. - * @param level Current spell level */ - void render(ICaster source, int level); + void render(ICaster source); /** * Return true to allow the gem update and move. diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellAwkward.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellAwkward.java index 98c5a557..e40432c1 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellAwkward.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellAwkward.java @@ -30,13 +30,13 @@ public class SpellAwkward extends AbstractSpell { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { return true; } @Override - public void render(ICaster source, int level) { - source.spawnParticles(new Sphere(false, (1 + level) * 8), 10, pos -> { + public void render(ICaster source) { + source.spawnParticles(new Sphere(false, (1 + source.getCurrentLevel()) * 8), 10, pos -> { int index = (int)MathHelper.nextDouble(source.getWorld().rand, 0, max); EnumParticleTypes type = EnumParticleTypes.getByName(names.get(index)); diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellCharge.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellCharge.java index d3c77daf..f9782a78 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellCharge.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellCharge.java @@ -41,8 +41,8 @@ public class SpellCharge extends AbstractSpell { } @Override - public void render(ICaster source, int level) { - if (source.getWorld().rand.nextInt(4 + level * 4) == 0) { + public void render(ICaster source) { + if (source.getWorld().rand.nextInt(4 + source.getCurrentLevel() * 4) == 0) { EntitySpell target = getTarget(source); if (target != null) { @@ -83,7 +83,7 @@ public class SpellCharge extends AbstractSpell { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { if (searching) { BlockPos origin = source.getOrigin(); @@ -99,7 +99,7 @@ public class SpellCharge extends AbstractSpell { } else { EntitySpell target = getTarget(source); - if (target != null && !target.overLevelCap() && level > 0) { + if (target != null && !target.overLevelCap() && source.getCurrentLevel() > 0) { source.addLevels(-1); target.addLevels(1); } @@ -108,11 +108,6 @@ public class SpellCharge extends AbstractSpell { return !getDead(); } - @Override - public int getMaxLevel() { - return 2; - } - @Override public void writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java index 03d66c4c..4f02b662 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java @@ -70,7 +70,7 @@ public class SpellDisguise extends AbstractSpell { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { if (entity == null && entityNbt != null) { entity = EntityList.createEntityFromNBT(entityNbt, source.getWorld()); @@ -202,7 +202,7 @@ public class SpellDisguise extends AbstractSpell { } @Override - public void render(ICaster source, int level) { + public void render(ICaster source) { } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellDrake.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellDrake.java index e484dc18..7a4049a2 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellDrake.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellDrake.java @@ -53,7 +53,7 @@ public class SpellDrake extends AbstractSpell { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { if (firstUpdate) { firstUpdate = false; @@ -85,16 +85,16 @@ public class SpellDrake extends AbstractSpell { } if (piggyBackSpell != null) { - piggyBackSpell.update(source, level); + piggyBackSpell.update(source); } return true; } @Override - public void render(ICaster source, int level) { + public void render(ICaster source) { if (piggyBackSpell != null) { - piggyBackSpell.render(source, level); + piggyBackSpell.render(source); } } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java index dc730fc1..f7b167cf 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java @@ -38,7 +38,7 @@ import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.SoundCategory; import net.minecraft.world.World; -public class SpellFire extends AbstractSpell implements IUseAction, IDispenceable { +public class SpellFire extends AbstractSpell.RangedAreaSpell implements IUseAction, IDispenceable { public final StateMapList affected = new StateMapList(); @@ -84,13 +84,13 @@ public class SpellFire extends AbstractSpell implements IUseAction, IDispenceabl } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { return false; } @Override - public void render(ICaster source, int level) { - source.spawnParticles(visual_effect_region, level * 6, pos -> { + public void render(ICaster source) { + source.spawnParticles(visual_effect_region, source.getCurrentLevel() * 6, pos -> { source.getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, pos.x, pos.y, pos.z, 0, 0, 0); }); } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java index d2f8bfec..45fc21ef 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java @@ -28,7 +28,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; -public class SpellIce extends AbstractSpell implements IUseAction, IDispenceable { +public class SpellIce extends AbstractSpell.RangedAreaSpell implements IUseAction, IDispenceable { public final StateMapList affected = new StateMapList(); @@ -72,12 +72,12 @@ public class SpellIce extends AbstractSpell implements IUseAction, IDispenceable } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { return false; } @Override - public void render(ICaster source, int level) { + public void render(ICaster source) { } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java index bcbcf590..2d927ae6 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java @@ -67,11 +67,11 @@ public class SpellInferno extends SpellFire { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { World w = source.getWorld(); if (!w.isRemote) { - int radius = 4 + (level * 4); + int radius = 4 + (source.getCurrentLevel() * 4); IShape shape = new Sphere(false, radius); Vec3d origin = source.getOriginVector(); diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java index 70b277ff..78074e08 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java @@ -20,7 +20,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -public class SpellNecromancy extends AbstractSpell { +public class SpellNecromancy extends AbstractSpell.RangedAreaSpell { private final List> spawns = Lists.newArrayList( EntityZombie::new, @@ -44,7 +44,7 @@ public class SpellNecromancy extends AbstractSpell { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { if (source.getWorld().isRemote || source.getWorld().getDifficulty() == EnumDifficulty.PEACEFUL) { return true; @@ -53,9 +53,9 @@ public class SpellNecromancy extends AbstractSpell { float additional = source.getWorld().getDifficultyForLocation(source.getOrigin()).getAdditionalDifficulty(); - level++; + int radius = source.getCurrentLevel() + 1; - IShape affectRegion = new Sphere(false, level * 4); + IShape affectRegion = new Sphere(false, radius * 4); if (source.getWorld().rand.nextInt(100) != 0) { return true; @@ -63,7 +63,7 @@ public class SpellNecromancy extends AbstractSpell { Vec3d origin = source.getOriginVector(); - if (VecHelper.findAllEntitiesInRange(source.getEntity(), source.getWorld(), source.getOrigin(), level * 4) + if (VecHelper.findAllEntitiesInRange(source.getEntity(), source.getWorld(), source.getOrigin(), radius * 4) .filter(e -> e instanceof EntityZombie) .count() >= 10 * (1 + additional)) { return true; @@ -102,8 +102,8 @@ public class SpellNecromancy extends AbstractSpell { } @Override - public void render(ICaster source, int level) { - IShape affectRegion = new Sphere(false, (1 + level) * 4); + public void render(ICaster source) { + IShape affectRegion = new Sphere(false, (1 + source.getCurrentLevel()) * 4); source.spawnParticles(affectRegion, 5, pos -> { if (!source.getWorld().isAirBlock(new BlockPos(pos).down())) { diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellPortal.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellPortal.java index 3fefa21f..e5113f1f 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellPortal.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellPortal.java @@ -29,7 +29,7 @@ import net.minecraft.util.SoundCategory; import net.minecraft.world.World; import net.minecraft.world.WorldServer; -public class SpellPortal extends AbstractSpell implements IUseAction { +public class SpellPortal extends AbstractSpell.RangedAreaSpell implements IUseAction { private static final IShape portalZone_X = new Sphere(true, 1, 0, 2, 1); private static final IShape portalZone_Y = new Sphere(true, 1, 2, 0, 2); @@ -142,7 +142,7 @@ public class SpellPortal extends AbstractSpell implements IUseAction { } @Override - public boolean update(ICaster source, int level) { + public boolean update(ICaster source) { if (!source.getWorld().isRemote) { getDestinationPortal().ifPresent(dest -> source.getWorld().getEntitiesWithinAABB(Entity.class, getTeleportBounds().offset(source.getOrigin())).stream() @@ -159,7 +159,7 @@ public class SpellPortal extends AbstractSpell implements IUseAction { } @Override - public void render(ICaster source, int level) { + public void render(ICaster source) { source.spawnParticles(getPortalZone(), 10, pos -> { Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0); }); diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java index 4b8cbf73..e333fb76 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java @@ -18,7 +18,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; import net.minecraft.util.math.Vec3d; -public class SpellShield extends AbstractSpell { +public class SpellShield extends AbstractSpell.RangedAreaSpell { private Optional particleEffect = Optional.empty(); @@ -38,13 +38,8 @@ public class SpellShield extends AbstractSpell { } @Override - public int getMaxLevel() { - return 17; - } - - @Override - public void render(ICaster source, int level) { - int radius = 4 + (level * 2); + public void render(ICaster source) { + int radius = 4 + (source.getCurrentLevel() * 2); source.spawnParticles(new Sphere(true, radius), radius * 6, pos -> { Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0); @@ -63,7 +58,7 @@ public class SpellShield extends AbstractSpell { public boolean updateOnPerson(ICaster source) { if (super.updateOnPerson(source)) { if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) { - double radius = 4 + (getCurrentLevel() * 2); + double radius = 4 + (source.getCurrentLevel() * 2); if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) { setDead(); } @@ -73,13 +68,13 @@ public class SpellShield extends AbstractSpell { return !getDead(); } - protected double getDrawDropOffRange(int level) { - return 4 + (level * 2); + protected double getDrawDropOffRange(ICaster source) { + return 4 + (source.getCurrentLevel() * 2); } @Override - public boolean update(ICaster source, int level) { - double radius = getDrawDropOffRange(level); + public boolean update(ICaster source) { + double radius = getDrawDropOffRange(source); Entity owner = source.getOwner(); diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellVortex.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellVortex.java index ef689573..aa1f6d5a 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellVortex.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellVortex.java @@ -23,18 +23,18 @@ public class SpellVortex extends SpellShield { } @Override - public void render(ICaster source, int level) { - level = 4 + (level * 2); + public void render(ICaster source) { + int range = 4 + (source.getCurrentLevel() * 2); Vec3d pos = source.getOriginVector(); - source.spawnParticles(new Sphere(false, level), level * 9, p -> { + source.spawnParticles(new Sphere(false, range), range * 9, p -> { Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, p, p.subtract(pos)); }); } @Override - protected double getDrawDropOffRange(int level) { - return 10 + (level * 2); + protected double getDrawDropOffRange(ICaster caster) { + return 10 + (caster.getCurrentLevel() * 2); } @Override