mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Implement traits to modify spell behaviours
This commit is contained in:
parent
78a33deb72
commit
2f1d473262
8 changed files with 51 additions and 23 deletions
|
@ -20,5 +20,5 @@ public interface Suppressable extends Spell {
|
||||||
/**
|
/**
|
||||||
* Event triggered when this effect is suppressed.
|
* Event triggered when this effect is suppressed.
|
||||||
*/
|
*/
|
||||||
void onSuppressed(Caster<?> otherSource);
|
void onSuppressed(Caster<?> otherSource, float suppressTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
||||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
@ -59,8 +60,9 @@ public class DisguiseSpell extends AbstractSpell implements Suppressable, Flight
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuppressed(Caster<?> otherSource) {
|
public void onSuppressed(Caster<?> otherSource, float time) {
|
||||||
suppressionCounter = 100;
|
time /= getTraits().getOrDefault(Trait.STRENGTH, 1);
|
||||||
|
suppressionCounter = (int)(100 * time);
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.block.state.StateMaps;
|
import com.minelittlepony.unicopia.block.state.StateMaps;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||||
import com.minelittlepony.unicopia.util.PosHelper;
|
import com.minelittlepony.unicopia.util.PosHelper;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
import com.minelittlepony.unicopia.util.VecHelper;
|
||||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
@ -36,9 +36,6 @@ import net.minecraft.world.explosion.Explosion.DestructionType;
|
||||||
* Simple fire spell that triggers an effect when used on a block.
|
* Simple fire spell that triggers an effect when used on a block.
|
||||||
*/
|
*/
|
||||||
public class FireSpell extends AbstractSpell implements ProjectileSpell {
|
public class FireSpell extends AbstractSpell implements ProjectileSpell {
|
||||||
|
|
||||||
private static final Shape EFFECT_RANGE = new Sphere(false, 4);
|
|
||||||
|
|
||||||
protected FireSpell(SpellType<?> type, SpellTraits traits) {
|
protected FireSpell(SpellType<?> type, SpellTraits traits) {
|
||||||
super(type, traits);
|
super(type, traits);
|
||||||
}
|
}
|
||||||
|
@ -56,14 +53,14 @@ public class FireSpell extends AbstractSpell implements ProjectileSpell {
|
||||||
generateParticles(source);
|
generateParticles(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PosHelper.getAllInRegionMutable(source.getOrigin(), EFFECT_RANGE).reduce(false,
|
return PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, Math.max(0, 4 + getTraits().get(Trait.POWER)))).reduce(false,
|
||||||
(r, i) -> applyBlocks(source.getWorld(), i),
|
(r, i) -> applyBlocks(source.getWorld(), i),
|
||||||
(a, b) -> a || b)
|
(a, b) -> a || b)
|
||||||
|| applyEntities(null, source.getWorld(), source.getOriginVector());
|
|| applyEntities(null, source.getWorld(), source.getOriginVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateParticles(Caster<?> source) {
|
protected void generateParticles(Caster<?> source) {
|
||||||
source.spawnParticles(EFFECT_RANGE, (1 + source.getLevel().get()) * 6, pos -> {
|
source.spawnParticles(new Sphere(false, Math.max(0, 4 + getTraits().get(Trait.POWER))), (1 + source.getLevel().get()) * 6, pos -> {
|
||||||
source.addParticle(ParticleTypes.LARGE_SMOKE, pos, Vec3d.ZERO);
|
source.addParticle(ParticleTypes.LARGE_SMOKE, pos, Vec3d.ZERO);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -111,7 +108,7 @@ public class FireSpell extends AbstractSpell implements ProjectileSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean applyEntities(Entity owner, World world, Vec3d pos) {
|
protected boolean applyEntities(Entity owner, World world, Vec3d pos) {
|
||||||
return !VecHelper.findInRange(owner, world, pos, 3, i -> applyEntitySingle(owner, world, i)).isEmpty();
|
return !VecHelper.findInRange(owner, world, pos, Math.max(0, 3 + getTraits().get(Trait.POWER)), i -> applyEntitySingle(owner, world, i)).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean applyEntitySingle(Entity owner, World world, Entity e) {
|
protected boolean applyEntitySingle(Entity owner, World world, Entity e) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||||
import com.minelittlepony.unicopia.util.Weighted;
|
import com.minelittlepony.unicopia.util.Weighted;
|
||||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||||
|
@ -39,7 +40,11 @@ public class NecromancySpell extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tick(Caster<?> source, Situation situation) {
|
public boolean tick(Caster<?> source, Situation situation) {
|
||||||
int radius = (source.getLevel().get() + 1) * 4;
|
float radius = (source.getLevel().get() + 1) * 4 + getTraits().get(Trait.POWER);
|
||||||
|
|
||||||
|
if (radius <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (source.isClient()) {
|
if (source.isClient()) {
|
||||||
source.spawnParticles(new Sphere(false, radius), 5, pos -> {
|
source.spawnParticles(new Sphere(false, radius), 5, pos -> {
|
||||||
|
@ -56,7 +61,7 @@ public class NecromancySpell extends AbstractSpell {
|
||||||
|
|
||||||
summonedEntities.removeIf(ref -> !ref.isPresent(source.getWorld()));
|
summonedEntities.removeIf(ref -> !ref.isPresent(source.getWorld()));
|
||||||
|
|
||||||
float additional = source.getWorld().getLocalDifficulty(source.getOrigin()).getLocalDifficulty();
|
float additional = source.getWorld().getLocalDifficulty(source.getOrigin()).getLocalDifficulty() + getTraits().get(Trait.CHAOS, 0, 10);
|
||||||
|
|
||||||
Shape affectRegion = new Sphere(false, radius);
|
Shape affectRegion = new Sphere(false, radius);
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
@ -16,28 +16,33 @@ import net.minecraft.util.math.Vec3d;
|
||||||
* A spell for revealing changelings.
|
* A spell for revealing changelings.
|
||||||
*/
|
*/
|
||||||
public class RevealingSpell extends AbstractSpell {
|
public class RevealingSpell extends AbstractSpell {
|
||||||
private static final Shape AREA = new Sphere(false, 15);
|
|
||||||
|
|
||||||
protected RevealingSpell(SpellType<?> type, SpellTraits traits) {
|
protected RevealingSpell(SpellType<?> type, SpellTraits traits) {
|
||||||
super(type, traits);
|
super(type, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tick(Caster<?> source, Situation situation) {
|
public boolean tick(Caster<?> source, Situation situation) {
|
||||||
|
|
||||||
|
float range = Math.max(0, 15 + getTraits().get(Trait.POWER));
|
||||||
|
|
||||||
|
if (range == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (source.isClient()) {
|
if (source.isClient()) {
|
||||||
MagicParticleEffect effect = new MagicParticleEffect(getType().getColor());
|
MagicParticleEffect effect = new MagicParticleEffect(getType().getColor());
|
||||||
|
|
||||||
source.spawnParticles(AREA, 5, pos -> {
|
source.spawnParticles(new Sphere(false, range), 5, pos -> {
|
||||||
source.addParticle(effect, pos, Vec3d.ZERO);
|
source.addParticle(effect, pos, Vec3d.ZERO);
|
||||||
});
|
});
|
||||||
source.spawnParticles(effect, 5);
|
source.spawnParticles(effect, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
source.findAllSpellsInRange(15).forEach(e -> {
|
source.findAllSpellsInRange(range).forEach(e -> {
|
||||||
e.getSpellSlot().get(SpellPredicate.CAN_SUPPRESS, false)
|
e.getSpellSlot().get(SpellPredicate.CAN_SUPPRESS, false)
|
||||||
.filter(spell -> spell.isVulnerable(source, this))
|
.filter(spell -> spell.isVulnerable(source, this))
|
||||||
.ifPresent(spell -> {
|
.ifPresent(spell -> {
|
||||||
spell.onSuppressed(source);
|
spell.onSuppressed(source, 1 + getTraits().get(Trait.STRENGTH));
|
||||||
source.getWorld().playSound(null, e.getOrigin(), SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, SoundCategory.PLAYERS, 0.2F, 0.5F);
|
source.getWorld().playSound(null, e.getOrigin(), SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, SoundCategory.PLAYERS, 0.2F, 0.5F);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.block.state.StateMaps;
|
import com.minelittlepony.unicopia.block.state.StateMaps;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||||
|
@ -24,7 +25,7 @@ public class ScorchSpell extends FireSpell {
|
||||||
BlockPos pos = PosHelper.findSolidGroundAt(source.getWorld(), source.getOrigin(), source.getPhysics().getGravitySignum());
|
BlockPos pos = PosHelper.findSolidGroundAt(source.getWorld(), source.getOrigin(), source.getPhysics().getGravitySignum());
|
||||||
|
|
||||||
if (StateMaps.FIRE_AFFECTED.convert(source.getWorld(), pos)) {
|
if (StateMaps.FIRE_AFFECTED.convert(source.getWorld(), pos)) {
|
||||||
source.spawnParticles(new Sphere(false, 1), 5, p -> {
|
source.spawnParticles(new Sphere(false, Math.max(1, getTraits().get(Trait.POWER))), 5, p -> {
|
||||||
source.addParticle(ParticleTypes.SMOKE, PosHelper.offset(p, pos), Vec3d.ZERO);
|
source.addParticle(ParticleTypes.SMOKE, PosHelper.offset(p, pos), Vec3d.ZERO);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||||
|
@ -78,12 +79,18 @@ public class ShieldSpell extends AbstractSpell implements ProjectileSpell {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float knowledge = getTraits().get(Trait.KNOWLEDGE, -6, 6);
|
||||||
|
if (knowledge == 0) {
|
||||||
|
knowledge = 1;
|
||||||
|
}
|
||||||
|
|
||||||
long costMultiplier = applyEntities(source);
|
long costMultiplier = applyEntities(source);
|
||||||
if (costMultiplier > 0) {
|
if (costMultiplier > 0) {
|
||||||
double cost = 2 + source.getLevel().get();
|
double cost = 2 + source.getLevel().get();
|
||||||
|
|
||||||
cost *= costMultiplier / ((1 + source.getLevel().get()) * 3F);
|
cost *= costMultiplier / ((1 + source.getLevel().get()) * 3F);
|
||||||
cost /= 2.725D;
|
cost /= 2.725D;
|
||||||
|
cost /= knowledge;
|
||||||
|
|
||||||
if (!source.subtractEnergyCost(cost)) {
|
if (!source.subtractEnergyCost(cost)) {
|
||||||
setDead();
|
setDead();
|
||||||
|
@ -98,7 +105,8 @@ public class ShieldSpell extends AbstractSpell implements ProjectileSpell {
|
||||||
*/
|
*/
|
||||||
public double getDrawDropOffRange(Caster<?> source) {
|
public double getDrawDropOffRange(Caster<?> source) {
|
||||||
float multiplier = source.getMaster().isSneaking() ? 1 : 2;
|
float multiplier = source.getMaster().isSneaking() ? 1 : 2;
|
||||||
return (4 + (source.getLevel().get() * 2)) / multiplier;
|
float min = 4 + getTraits().get(Trait.POWER);
|
||||||
|
return (min + (source.getLevel().get() * 2)) / multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Entity> getTargets(Caster<?> source, double radius) {
|
protected List<Entity> getTargets(Caster<?> source, double radius) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import net.minecraft.nbt.NbtElement;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
|
@ -62,7 +63,7 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
|
|
||||||
public boolean includes(SpellTraits other) {
|
public boolean includes(SpellTraits other) {
|
||||||
return other.stream().allMatch(pair -> {
|
return other.stream().allMatch(pair -> {
|
||||||
return getAmount(pair.getKey()) >= pair.getValue();
|
return get(pair.getKey()) >= pair.getValue();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +80,17 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
return entries().stream();
|
return entries().stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAmount(Trait trait) {
|
public float getOrDefault(Trait trait, float def) {
|
||||||
return traits.getOrDefault(trait, 0F);
|
float i = traits.getOrDefault(trait, def);
|
||||||
|
return i == 0 ? def : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float get(Trait trait) {
|
||||||
|
return getOrDefault(trait, 0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float get(Trait trait, float min, float max) {
|
||||||
|
return MathHelper.clamp(get(trait), min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void appendTooltip(List<Text> tooltip) {
|
public void appendTooltip(List<Text> tooltip) {
|
||||||
|
|
Loading…
Reference in a new issue