mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Further work on spell traits and clean up how projectile spells are handled
This commit is contained in:
parent
33476f2ed8
commit
2890bc3e07
22 changed files with 204 additions and 150 deletions
|
@ -8,8 +8,8 @@ import com.google.common.collect.Streams;
|
|||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
|
@ -109,13 +109,13 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
TypedActionResult<SpellType<?>> newSpell = getNewSpell(player);
|
||||
TypedActionResult<CustomisedSpellType<?>> newSpell = getNewSpell(player);
|
||||
|
||||
if (newSpell.getResult() != ActionResult.FAIL) {
|
||||
SpellType<?> spell = newSpell.getValue();
|
||||
CustomisedSpellType<?> spell = newSpell.getValue();
|
||||
|
||||
player.subtractEnergyCost(spell.isEmpty() ? 2 : 4);
|
||||
spell.apply(player, SpellTraits.EMPTY);
|
||||
spell.apply(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,13 +135,13 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
return TypedActionResult.pass(stack);
|
||||
}
|
||||
|
||||
private TypedActionResult<SpellType<?>> getNewSpell(Pony player) {
|
||||
private TypedActionResult<CustomisedSpellType<?>> getNewSpell(Pony player) {
|
||||
final SpellType<?> current = player.getSpellSlot().get(true).map(Spell::getType).orElse(SpellType.empty());
|
||||
return Streams.stream(player.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, null))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<SpellType<?>>pass(current == SpellType.EMPTY_KEY ? SpellType.SHIELD : SpellType.EMPTY_KEY));
|
||||
.orElse(TypedActionResult.<CustomisedSpellType<?>>pass((current == SpellType.EMPTY_KEY ? SpellType.SHIELD : SpellType.EMPTY_KEY).withTraits()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,9 +5,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
|
@ -63,27 +62,27 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
|||
|
||||
@Override
|
||||
public void apply(Pony player, Hit data) {
|
||||
TypedActionResult<SpellType<?>> thrown = getNewSpell(player);
|
||||
TypedActionResult<CustomisedSpellType<?>> thrown = getNewSpell(player);
|
||||
|
||||
if (thrown.getResult() != ActionResult.FAIL) {
|
||||
@Nullable
|
||||
SpellType<?> spell = thrown.getValue();
|
||||
CustomisedSpellType<?> spell = thrown.getValue();
|
||||
|
||||
if (spell == null) {
|
||||
spell = SpellType.VORTEX;
|
||||
spell = SpellType.VORTEX.withTraits();
|
||||
}
|
||||
|
||||
player.subtractEnergyCost(getCostEstimate(player));
|
||||
((ProjectileCapable)spell.create(SpellTraits.EMPTY)).toss(player);
|
||||
spell.create().toThrowable().throwProjectile(player);
|
||||
}
|
||||
}
|
||||
|
||||
private TypedActionResult<SpellType<?>> getNewSpell(Pony player) {
|
||||
private TypedActionResult<CustomisedSpellType<?>> getNewSpell(Pony player) {
|
||||
return Streams.stream(player.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, null))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<SpellType<?>>pass(null));
|
||||
.orElse(TypedActionResult.<CustomisedSpellType<?>>pass(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,11 +2,11 @@ package com.minelittlepony.unicopia.ability.magic;
|
|||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
|
||||
public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
|
||||
SpellPredicate<ProjectileCapable> IS_THROWN = s -> s instanceof ProjectileCapable;
|
||||
SpellPredicate<ProjectileSpell> IS_THROWN = s -> s instanceof ProjectileSpell;
|
||||
SpellPredicate<Suppressable> IS_SUPPRESSABLE = s -> s instanceof Suppressable;
|
||||
|
||||
default boolean isOn(Caster<?> caster) {
|
||||
|
|
|
@ -10,13 +10,14 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public abstract class AbstractDelegatingSpell implements Spell, ProjectileCapable {
|
||||
public abstract class AbstractDelegatingSpell implements ProjectileSpell {
|
||||
|
||||
private boolean isDirty;
|
||||
|
||||
|
@ -76,27 +77,30 @@ public abstract class AbstractDelegatingSpell implements Spell, ProjectileCapabl
|
|||
getDelegates().forEach(spell -> spell.onDestroyed(caster));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
return execute(getDelegates().stream(), spell -> spell.tick(source, situation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileCapable).forEach(a -> {
|
||||
((ProjectileCapable)a).onImpact(projectile, pos, state);
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileDelegate).forEach(a -> {
|
||||
((ProjectileDelegate)a).onImpact(projectile, pos, state);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileCapable).forEach(a -> {
|
||||
((ProjectileCapable)a).onImpact(projectile, entity);
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileDelegate).forEach(a -> {
|
||||
((ProjectileDelegate)a).onImpact(projectile, entity);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
return execute(getDelegates().stream(), spell -> spell.tick(source, situation));
|
||||
}
|
||||
|
||||
private boolean execute(Stream<Spell> spells, Function<Spell, Boolean> action) {
|
||||
return spells.reduce(false, (u, a) -> action.apply(a), (a, b) -> a || b);
|
||||
public void configureProjectile(MagicProjectileEntity projectile, Caster<?> caster) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileSpell).forEach(a -> {
|
||||
((ProjectileSpell)a).configureProjectile(projectile, caster);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,4 +115,8 @@ public abstract class AbstractDelegatingSpell implements Spell, ProjectileCapabl
|
|||
uuid = compound.getUuid("uuid");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean execute(Stream<Spell> spells, Function<Spell, Boolean> action) {
|
||||
return spells.reduce(false, (u, a) -> action.apply(a), (a, b) -> a || b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ public class CompoundSpell extends AbstractDelegatingSpell {
|
|||
|
||||
@Override
|
||||
public Spell combineWith(Spell other) {
|
||||
if (other instanceof CompoundSpell) {
|
||||
spells.addAll(((CompoundSpell)other).spells);
|
||||
if (other instanceof AbstractDelegatingSpell) {
|
||||
spells.addAll(((AbstractDelegatingSpell)other).getDelegates());
|
||||
} else {
|
||||
spells.add(other);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell {
|
|||
spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), source.getOriginVector(), Vec3d.ZERO);
|
||||
}).ifPresent(p -> {
|
||||
p.attach(source);
|
||||
p.setAttribute(1, getType().getColor());
|
||||
p.setAttribute(1, spell.getType().getColor());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Magic effects that can be thrown.
|
||||
*/
|
||||
public interface ProjectileCapable extends Spell, ProjectileDelegate {
|
||||
|
||||
@Override
|
||||
default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (!projectile.isClient()) {
|
||||
tick(projectile, Situation.PROJECTILE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of damage to be dealt when the projectile collides with an entity.
|
||||
*/
|
||||
default int getThrowDamage(Caster<?> stack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sound made when thrown.
|
||||
*/
|
||||
default SoundEvent getThrowSound(Caster<?> caster) {
|
||||
return SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the appearance to be used when projecting this spell.
|
||||
*/
|
||||
default ItemStack getCastAppearance(Caster<?> caster) {
|
||||
return GemstoneItem.enchanted(UItems.GEMSTONE.getDefaultStack(), getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects this spell.
|
||||
*
|
||||
* Returns the resulting projectile entity for customization (or null if on the client).
|
||||
*/
|
||||
@Nullable
|
||||
default MagicProjectileEntity toss(Caster<?> caster) {
|
||||
World world = caster.getWorld();
|
||||
|
||||
LivingEntity entity = caster.getMaster();
|
||||
|
||||
world.playSound(null, entity.getX(), entity.getY(), entity.getZ(), getThrowSound(caster), SoundCategory.NEUTRAL, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
if (!caster.isClient()) {
|
||||
MagicProjectileEntity projectile = new MagicProjectileEntity(world, entity);
|
||||
|
||||
projectile.setItem(getCastAppearance(caster));
|
||||
projectile.setThrowDamage(getThrowDamage(caster));
|
||||
projectile.setSpell(this);
|
||||
projectile.setHydrophobic();
|
||||
projectile.setProperties(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, 1);
|
||||
|
||||
world.spawnEntity(projectile);
|
||||
|
||||
return projectile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
* Magic effects that can be thrown.
|
||||
*/
|
||||
public interface ProjectileSpell extends Spell, ProjectileDelegate {
|
||||
|
||||
@Override
|
||||
default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (!projectile.isClient()) {
|
||||
tick(projectile, Situation.PROJECTILE);
|
||||
}
|
||||
}
|
||||
|
||||
default void configureProjectile(MagicProjectileEntity projectile, Caster<?> caster) { }
|
||||
}
|
|
@ -75,4 +75,12 @@ public interface Spell extends NbtSerialisable, Affine {
|
|||
default PlaceableSpell toPlaceable() {
|
||||
return SpellType.PLACED_SPELL.create(SpellTraits.EMPTY).setSpell(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this spell into a throwable spell.
|
||||
* @return
|
||||
*/
|
||||
default ThrowableSpell toThrowable() {
|
||||
return SpellType.THROWN_SPELL.create(SpellTraits.EMPTY).setSpell(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ThrowableSpell extends AbstractDelegatingSpell {
|
||||
|
||||
private Spell spell;
|
||||
|
||||
public ThrowableSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
public ThrowableSpell setSpell(Spell spell) {
|
||||
this.spell = spell;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Spell> getDelegates() {
|
||||
return List.of(spell);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects this spell.
|
||||
*
|
||||
* Returns the resulting projectile entity for customization (or null if on the client).
|
||||
*/
|
||||
public Optional<MagicProjectileEntity> throwProjectile(Caster<?> caster) {
|
||||
World world = caster.getWorld();
|
||||
|
||||
LivingEntity entity = caster.getMaster();
|
||||
|
||||
world.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.NEUTRAL, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
if (!caster.isClient()) {
|
||||
MagicProjectileEntity projectile = new MagicProjectileEntity(world, entity);
|
||||
|
||||
projectile.setItem(GemstoneItem.enchanted(UItems.GEMSTONE.getDefaultStack(), spell.getType()));
|
||||
projectile.setSpell(this);
|
||||
projectile.setProperties(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, 1);
|
||||
projectile.setHydrophobic();
|
||||
configureProjectile(projectile, caster);
|
||||
world.spawnEntity(projectile);
|
||||
|
||||
return Optional.of(projectile);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThrowableSpell toThrowable() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import java.util.List;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
||||
|
@ -17,7 +16,7 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class AwkwardSpell extends AbstractSpell implements ProjectileCapable {
|
||||
public class AwkwardSpell extends AbstractSpell {
|
||||
|
||||
protected AwkwardSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
||||
public class CustomisedSpellType<T extends Spell> {
|
||||
|
||||
private final SpellType<T> type;
|
||||
private final SpellTraits traits;
|
||||
|
||||
public CustomisedSpellType(SpellType<T> type, SpellTraits traits) {
|
||||
this.type = type;
|
||||
this.traits = traits;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return type.isEmpty();
|
||||
}
|
||||
|
||||
public T create() {
|
||||
return type.create(traits);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T apply(Caster<?> caster) {
|
||||
return type.apply(caster, traits);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
|||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.block.state.StateMaps;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
|
@ -35,7 +35,7 @@ import net.minecraft.world.explosion.Explosion.DestructionType;
|
|||
/**
|
||||
* Simple fire spell that triggers an effect when used on a block.
|
||||
*/
|
||||
public class FireSpell extends AbstractSpell implements ProjectileCapable {
|
||||
public class FireSpell extends AbstractSpell implements ProjectileSpell {
|
||||
|
||||
private static final Shape EFFECT_RANGE = new Sphere(false, 4);
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.block.state.StateMaps;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
|
@ -27,7 +26,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class IceSpell extends AbstractSpell implements ProjectileCapable {
|
||||
public class IceSpell extends AbstractSpell {
|
||||
|
||||
private final int rad = 3;
|
||||
private final Shape effect_range = new Sphere(false, rad);
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
|||
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.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||
|
@ -16,7 +15,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
/**
|
||||
* A spell for revealing changelings.
|
||||
*/
|
||||
public class RevealingSpell extends AbstractSpell implements ProjectileCapable {
|
||||
public class RevealingSpell extends AbstractSpell {
|
||||
private static final Shape AREA = new Sphere(false, 15);
|
||||
|
||||
protected RevealingSpell(SpellType<?> type, SpellTraits traits) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
@ -42,14 +40,7 @@ public class ScorchSpell extends FireSpell {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MagicProjectileEntity toss(Caster<?> caster) {
|
||||
MagicProjectileEntity projectile = super.toss(caster);
|
||||
|
||||
if (projectile != null) {
|
||||
projectile.setNoGravity(true);
|
||||
}
|
||||
|
||||
return projectile;
|
||||
public void configureProjectile(MagicProjectileEntity projectile, Caster<?> caster) {
|
||||
projectile.setNoGravity(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.EquinePredicates;
|
|||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
|
@ -35,7 +35,7 @@ import net.minecraft.entity.vehicle.BoatEntity;
|
|||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class ShieldSpell extends AbstractSpell implements ProjectileCapable {
|
||||
public class ShieldSpell extends AbstractSpell implements ProjectileSpell {
|
||||
|
||||
private final ParticleHandle particlEffect = new ParticleHandle();
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.JoustingSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.util.Registries;
|
||||
|
||||
|
@ -37,6 +38,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
|
||||
public static final SpellType<CompoundSpell> COMPOUND_SPELL = register("compound", Affinity.NEUTRAL, 0, false, CompoundSpell::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<DisguiseSpell> DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new);
|
||||
public static final SpellType<JoustingSpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new);
|
||||
|
@ -66,12 +68,15 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
@Nullable
|
||||
private String translationKey;
|
||||
|
||||
private final CustomisedSpellType<T> traited;
|
||||
|
||||
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
|
||||
this.id = id;
|
||||
this.affinity = affinity;
|
||||
this.color = color;
|
||||
this.obtainable = obtainable;
|
||||
this.factory = factory;
|
||||
traited = new CustomisedSpellType<>(this, SpellTraits.EMPTY);
|
||||
}
|
||||
|
||||
public boolean isObtainable() {
|
||||
|
@ -105,6 +110,14 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
return new TranslatableText(getTranslationKey());
|
||||
}
|
||||
|
||||
public CustomisedSpellType<T> withTraits() {
|
||||
return traited;
|
||||
}
|
||||
|
||||
public CustomisedSpellType<T> withTraits(SpellTraits traits) {
|
||||
return traits.isEmpty() ? withTraits() : new CustomisedSpellType<>(this, traits);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T create(SpellTraits traits) {
|
||||
try {
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Set;
|
|||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
|
@ -22,7 +22,7 @@ import net.minecraft.particle.ParticleTypes;
|
|||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public class TransformationSpell extends AbstractSpell implements ProjectileCapable {
|
||||
public class TransformationSpell extends AbstractSpell implements ProjectileSpell {
|
||||
|
||||
protected TransformationSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
|
|
|
@ -43,19 +43,19 @@ public final class SpellTraits {
|
|||
return nbt;
|
||||
}
|
||||
|
||||
public Optional<SpellTraits> of(Collection<ItemStack> stacks) {
|
||||
public static Optional<SpellTraits> of(Collection<ItemStack> stacks) {
|
||||
return fromEntries(stacks.stream().flatMap(a -> of(a).entries().stream()));
|
||||
}
|
||||
|
||||
public SpellTraits of(ItemStack stack) {
|
||||
public static SpellTraits of(ItemStack stack) {
|
||||
return getEmbeddedTraits(stack).orElseGet(() -> of(stack.getItem()));
|
||||
}
|
||||
|
||||
public SpellTraits of(Item item) {
|
||||
public static SpellTraits of(Item item) {
|
||||
return TraitLoader.INSTANCE.values.getOrDefault(Registry.ITEM.getId(item), null);
|
||||
}
|
||||
|
||||
public SpellTraits of(Block block) {
|
||||
public static SpellTraits of(Block block) {
|
||||
return of(block.asItem());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -79,19 +81,20 @@ public class GemstoneItem extends Item {
|
|||
return super.getName();
|
||||
}
|
||||
|
||||
public static TypedActionResult<SpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, @Nullable Predicate<SpellType<?>> test) {
|
||||
public static TypedActionResult<CustomisedSpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, @Nullable Predicate<SpellType<?>> test) {
|
||||
|
||||
if (!isEnchanted(stack)) {
|
||||
return TypedActionResult.pass(null);
|
||||
}
|
||||
|
||||
SpellType<Spell> key = getSpellKey(stack);
|
||||
SpellTraits traits = SpellTraits.of(stack);
|
||||
|
||||
if (Objects.equals(key, exclude)) {
|
||||
return TypedActionResult.fail(null);
|
||||
}
|
||||
|
||||
if (key == SpellType.EMPTY_KEY || (test == null || !test.test(key))) {
|
||||
if (key.isEmpty() || (test == null || !test.test(key))) {
|
||||
return TypedActionResult.fail(null);
|
||||
}
|
||||
|
||||
|
@ -105,7 +108,7 @@ public class GemstoneItem extends Item {
|
|||
}
|
||||
}
|
||||
|
||||
return TypedActionResult.consume(key);
|
||||
return TypedActionResult.consume(key.withTraits(traits));
|
||||
}
|
||||
|
||||
public static boolean isEnchanted(ItemStack stack) {
|
||||
|
|
|
@ -8,10 +8,10 @@ public interface ProjectileDelegate {
|
|||
/**
|
||||
* Called once the projectile lands either hitting the ground or an entity.
|
||||
*/
|
||||
void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state);
|
||||
default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {}
|
||||
|
||||
/**
|
||||
* Called once the projectile lands either hitting the ground or an entity.
|
||||
*/
|
||||
void onImpact(MagicProjectileEntity projectile, Entity entity);
|
||||
default void onImpact(MagicProjectileEntity projectile, Entity entity) {}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue