A little more cleanup and refactoring

This commit is contained in:
Sollace 2021-12-24 19:06:39 +02:00
parent 8ff6514306
commit 668d5bc787
13 changed files with 46 additions and 48 deletions

View file

@ -2,12 +2,8 @@ package com.minelittlepony.unicopia;
import java.util.function.Predicate; import java.util.function.Predicate;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
@ -31,10 +27,6 @@ public interface EquinePredicates {
Predicate<LivingEntity> HAS_WANT_IT_NEED_IT = e -> EnchantmentHelper.getEquipmentLevel(UEnchantments.WANT_IT_NEED_IT, e) > 0; Predicate<LivingEntity> HAS_WANT_IT_NEED_IT = e -> EnchantmentHelper.getEquipmentLevel(UEnchantments.WANT_IT_NEED_IT, e) > 0;
static Predicate<Entity> carryingSpell(@Nullable SpellType<?> type) {
return IS_PLAYER.and(e -> Pony.of((PlayerEntity)e).getSpellSlot().get(type, false).isPresent());
}
static Predicate<Entity> ofRace(Race race) { static Predicate<Entity> ofRace(Race race) {
return raceMatches(race::equals); return raceMatches(race::equals);
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.unicopia.ability; package com.minelittlepony.unicopia.ability;
import java.util.Random; import java.util.Random;
import java.util.function.Predicate;
import com.minelittlepony.unicopia.AwaitTickQueue; import com.minelittlepony.unicopia.AwaitTickQueue;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
@ -13,7 +12,6 @@ import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -24,8 +22,6 @@ import net.minecraft.util.math.Vec3d;
*/ */
public class BatEeeeAbility implements Ability<Hit> { public class BatEeeeAbility implements Ability<Hit> {
private static final Predicate<Entity> HAS_SHIELD = EquinePredicates.carryingSpell(SpellType.SHIELD);
@Override @Override
public int getWarmupTime(Pony player) { public int getWarmupTime(Pony player) {
return 1; return 1;
@ -84,7 +80,7 @@ public class BatEeeeAbility implements Ability<Hit> {
} }
int total = player.findAllEntitiesInRange(5).mapToInt(e -> { int total = player.findAllEntitiesInRange(5).mapToInt(e -> {
if (e instanceof LivingEntity && !HAS_SHIELD.test(e)) { if (e instanceof LivingEntity && !SpellType.SHIELD.isOn(e)) {
boolean isEarthPony = EquinePredicates.PLAYER_EARTH.test(e); boolean isEarthPony = EquinePredicates.PLAYER_EARTH.test(e);
e.damage(MagicalDamageSource.create("eeee", player), isEarthPony ? 0.1F : 0.3F); e.damage(MagicalDamageSource.create("eeee", player), isEarthPony ? 0.1F : 0.3F);

View file

@ -5,7 +5,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.Spell;
/** /**
* Magic effects that can be suppressed by other nearby effects. * Magic effects that can be suppressed by other nearby effects.
*/ */
public interface Suppressable extends Spell { public interface IllusionarySpell extends Spell {
/** /**
* Returns true if this spell is currently still suppressed. * Returns true if this spell is currently still suppressed.
@ -13,7 +13,7 @@ public interface Suppressable extends Spell {
boolean isSuppressed(); boolean isSuppressed();
/** /**
* Returns true if this spell can be suppressed by the given other spell and caster. * Returns true if this illusion can be suppressed by the given other spell and caster.
*/ */
boolean isVulnerable(Caster<?> otherSource, Spell other); boolean isVulnerable(Caster<?> otherSource, Spell other);

View file

@ -5,15 +5,21 @@ import java.util.function.Predicate;
import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell;
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell; import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.Spell;
import com.minelittlepony.unicopia.ability.magic.spell.effect.ShieldSpell;
import net.minecraft.entity.Entity;
public interface SpellPredicate<T extends Spell> extends Predicate<Spell> { public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
SpellPredicate<Suppressable> CAN_SUPPRESS = s -> s instanceof Suppressable; SpellPredicate<IllusionarySpell> CAN_SUPPRESS = s -> s instanceof IllusionarySpell;
SpellPredicate<ProjectileSpell> HAS_PROJECTILE_EVENTS = s -> s instanceof ProjectileSpell; SpellPredicate<ProjectileSpell> HAS_PROJECTILE_EVENTS = s -> s instanceof ProjectileSpell;
SpellPredicate<AbstractDisguiseSpell> IS_DISGUISE = s -> s instanceof AbstractDisguiseSpell; SpellPredicate<AbstractDisguiseSpell> IS_DISGUISE = s -> s instanceof AbstractDisguiseSpell;
SpellPredicate<ShieldSpell> IS_SHIELD_LIKE = spell -> spell instanceof ShieldSpell;
default boolean isOn(Caster<?> caster) { default boolean isOn(Caster<?> caster) {
return caster.getSpellSlot().contains(this); return caster.getSpellSlot().contains(this);
} }
default boolean isOn(Entity entity) {
return Caster.of(entity).filter(this::isOn).isPresent();
}
} }

View file

@ -6,7 +6,6 @@ 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;
public abstract class AbstractAreaEffectSpell extends AbstractSpell { public abstract class AbstractAreaEffectSpell extends AbstractSpell {
protected AbstractAreaEffectSpell(SpellType<?> type, SpellTraits traits) { protected AbstractAreaEffectSpell(SpellType<?> type, SpellTraits traits) {
super(type, traits); super(type, traits);
} }
@ -15,5 +14,4 @@ public abstract class AbstractAreaEffectSpell extends AbstractSpell {
public boolean apply(Caster<?> source) { public boolean apply(Caster<?> source) {
return toPlaceable().apply(source); return toPlaceable().apply(source);
} }
} }

View file

@ -15,8 +15,7 @@ import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
/** /**
* Shapeshifts the player. * Base implementation for a spell that changes the player's appearance.
* <p>
*/ */
public abstract class AbstractDisguiseSpell extends AbstractSpell implements Disguise, ProjectileImpactListener { public abstract class AbstractDisguiseSpell extends AbstractSpell implements Disguise, ProjectileImpactListener {

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell;
import java.util.Optional; import java.util.Optional;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Suppressable; import com.minelittlepony.unicopia.ability.magic.IllusionarySpell;
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.ability.magic.spell.trait.Trait;
@ -20,11 +20,11 @@ import net.minecraft.nbt.NbtCompound;
* <p> * <p>
* Internal. Used by the changeling ability. * Internal. Used by the changeling ability.
*/ */
public class ChangelingDisguiseSpell extends AbstractDisguiseSpell implements Suppressable { public class DispersableDisguiseSpell extends AbstractDisguiseSpell implements IllusionarySpell {
private int suppressionCounter; private int suppressionCounter;
public ChangelingDisguiseSpell(SpellType<?> type, SpellTraits traits) { public DispersableDisguiseSpell(SpellType<?> type, SpellTraits traits) {
super(type, traits); super(type, traits);
} }

View file

@ -19,12 +19,11 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
// TODO: We'll need a recipe to make a spell placeable
/** /**
* A spell that can be attached to a specific location in the world. * A spell that can be attached to a specific location in the world.
* <p> * <p>
* The spell's effects are still powered by the casting player, so if the player dies or leaves the area, their * The spell's effects are still powered by the casting player, so if the player dies or leaves the area, their
* spell loses effect until they return. * spell loses affect until they return.
*/ */
public class PlaceableSpell extends AbstractDelegatingSpell { public class PlaceableSpell extends AbstractDelegatingSpell {
@Nullable @Nullable

View file

@ -27,7 +27,7 @@ import net.minecraft.world.GameRules;
* <p> * <p>
* Used by the Rainboom ability. * Used by the Rainboom ability.
*/ */
public class JoustingSpell extends AbstractSpell { public class RainboomAbilitySpell extends AbstractSpell {
private final int rad = 5; private final int rad = 5;
private final Shape effect_range = new Sphere(false, rad); private final Shape effect_range = new Sphere(false, rad);
@ -36,7 +36,7 @@ public class JoustingSpell extends AbstractSpell {
private int age; private int age;
public JoustingSpell(SpellType<?> type, SpellTraits traits) { public RainboomAbilitySpell(SpellType<?> type, SpellTraits traits) {
super(type, traits); super(type, traits);
} }

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.ability.magic.spell.effect; package com.minelittlepony.unicopia.ability.magic.spell.effect;
import com.minelittlepony.unicopia.USounds;
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;
@ -23,7 +24,7 @@ public class DarkVortexSpell extends AttractiveSpell {
.with(Trait.DARKNESS, 100) .with(Trait.DARKNESS, 100)
.build(); .build();
private int accumulatedMass = 0; private float accumulatedMass = 0;
protected DarkVortexSpell(SpellType<?> type, SpellTraits traits) { protected DarkVortexSpell(SpellType<?> type, SpellTraits traits) {
super(type, traits); super(type, traits);
@ -41,7 +42,11 @@ public class DarkVortexSpell extends AttractiveSpell {
return true; return true;
} }
if (accumulatedMass > 20) { if (!source.isClient()) {
accumulatedMass += 0.001F * (1 + getTraits().get(Trait.STRENGTH, 70, 120) - 70);
}
if (accumulatedMass > 20 * getTraits().get(Trait.POWER, 1, 60) / 10F) {
if (!source.isClient()) { if (!source.isClient()) {
Vec3d pos = source.getOriginVector(); Vec3d pos = source.getOriginVector();
source.getWorld().createExplosion( source.getWorld().createExplosion(
@ -72,6 +77,10 @@ public class DarkVortexSpell extends AttractiveSpell {
}).ifPresent(p -> { }).ifPresent(p -> {
p.setAttribute(0, radius); p.setAttribute(0, radius);
}); });
if (source.getEntity().age % 20 == 0) {
source.playSound(USounds.AMBIENT_WIND_GUST, 1, 1);
}
} }
@Override @Override
@ -83,14 +92,11 @@ public class DarkVortexSpell extends AttractiveSpell {
protected long applyEntities(Caster<?> source) { protected long applyEntities(Caster<?> source) {
if (!source.isClient()) { if (!source.isClient()) {
PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, 1 + ((int)getDrawDropOffRange(source) / 2F))).forEach(i -> { PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, 1 + ((int)getDrawDropOffRange(source) / 2F))).forEach(i -> {
if (!source.getWorld().isAir(i)) { if (!source.getWorld().isAir(i) && source.getWorld().random.nextInt(120) == 0) {
source.getWorld().breakBlock(i, false); source.getWorld().breakBlock(i, false);
if (source.getWorld().random.nextInt(accumulatedMass + 1) == 0) {
accumulatedMass++; accumulatedMass++;
setDirty(); setDirty();
} }
}
}); });
} }
@ -112,12 +118,12 @@ public class DarkVortexSpell extends AttractiveSpell {
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound) {
super.toNBT(compound); super.toNBT(compound);
compound.putInt("accumulatedMass", accumulatedMass); compound.putFloat("accumulatedMass", accumulatedMass);
} }
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound) {
super.fromNBT(compound); super.fromNBT(compound);
accumulatedMass = compound.getInt("accumulatedMass"); accumulatedMass = compound.getFloat("accumulatedMass");
} }
} }

View file

@ -14,10 +14,10 @@ import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
/** /**
* An area-effect spell that suppresses other forms of magic * An area-effect spell that disperses illussions.
*/ */
public class RevealingSpell extends AbstractAreaEffectSpell { public class DisperseIllusionSpell extends AbstractAreaEffectSpell {
protected RevealingSpell(SpellType<?> type, SpellTraits traits) { protected DisperseIllusionSpell(SpellType<?> type, SpellTraits traits) {
super(type, traits); super(type, traits);
} }

View file

@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
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.ability.magic.spell.trait.Trait;
@ -128,6 +129,7 @@ public class ShieldSpell extends AbstractSpell {
return source.findAllEntitiesInRange(radius) return source.findAllEntitiesInRange(radius)
.filter(entity -> { .filter(entity -> {
return !FriendshipBraceletItem.isComrade(source, entity) return !FriendshipBraceletItem.isComrade(source, entity)
&& !SpellPredicate.IS_SHIELD_LIKE.isOn(entity)
&& isValidTarget(entity) && isValidTarget(entity)
&& !(ownerIsValid && (Pony.equal(entity, owner) || owner.isConnectedThroughVehicle(entity))); && !(ownerIsValid && (Pony.equal(entity, owner) || owner.isConnectedThroughVehicle(entity)));
}) })

View file

@ -12,10 +12,10 @@ import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.ability.magic.Caster; 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.CompoundSpell;
import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell;
import com.minelittlepony.unicopia.ability.magic.spell.ChangelingDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.CompoundSpell;
import com.minelittlepony.unicopia.ability.magic.spell.JoustingSpell; import com.minelittlepony.unicopia.ability.magic.spell.DispersableDisguiseSpell;
import com.minelittlepony.unicopia.ability.magic.spell.RainboomAbilitySpell;
import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell; import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell;
import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.Spell;
import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell; import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell;
@ -43,8 +43,8 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
public static final SpellType<PlaceableSpell> PLACED_SPELL = register("placed", Affinity.NEUTRAL, 0, false, PlaceableSpell::new); public static final SpellType<PlaceableSpell> PLACED_SPELL = register("placed", Affinity.NEUTRAL, 0, false, PlaceableSpell::new);
public static final SpellType<ThrowableSpell> THROWN_SPELL = register("thrown", Affinity.NEUTRAL, 0, false, ThrowableSpell::new); public static final SpellType<ThrowableSpell> THROWN_SPELL = register("thrown", Affinity.NEUTRAL, 0, false, ThrowableSpell::new);
public static final SpellType<AbstractDisguiseSpell> CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, ChangelingDisguiseSpell::new); public static final SpellType<AbstractDisguiseSpell> CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DispersableDisguiseSpell::new);
public static final SpellType<JoustingSpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new); public static final SpellType<RainboomAbilitySpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, RainboomAbilitySpell::new);
public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell.DEFAULT_TRAITS, IceSpell::new); public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell.DEFAULT_TRAITS, IceSpell::new);
public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0, true, ScorchSpell.DEFAULT_TRAITS, ScorchSpell::new); public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0, true, ScorchSpell.DEFAULT_TRAITS, ScorchSpell::new);
@ -55,7 +55,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
public static final SpellType<DarkVortexSpell> DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0, true, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new); public static final SpellType<DarkVortexSpell> DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0, true, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new);
public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0x8A3A3A, true, NecromancySpell::new); public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0x8A3A3A, true, NecromancySpell::new);
public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xe308ab, true, SiphoningSpell::new); public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xe308ab, true, SiphoningSpell::new);
public static final SpellType<RevealingSpell> REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new); public static final SpellType<DisperseIllusionSpell> REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, DisperseIllusionSpell::new);
public static final SpellType<AwkwardSpell> AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new); public static final SpellType<AwkwardSpell> AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new);
public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", Affinity.GOOD, 0x3A59AA, true, TransformationSpell::new); public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", Affinity.GOOD, 0x3A59AA, true, TransformationSpell::new);
public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", Affinity.GOOD, 0x00EEFF, true, FeatherFallSpell.DEFAULT_TRAITS, FeatherFallSpell::new); public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", Affinity.GOOD, 0x00EEFF, true, FeatherFallSpell.DEFAULT_TRAITS, FeatherFallSpell::new);