mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-12-03 17:37:59 +01:00
Added spell traits and trait groupings, and rewrite spell casting to make combining spells and catering to different situations easier
This commit is contained in:
parent
27f143982e
commit
33476f2ed8
58 changed files with 852 additions and 386 deletions
|
@ -5,7 +5,7 @@ import java.util.function.Predicate;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.data.tree.TreeTypeLoader;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.TraitLoader;
|
||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.command.Commands;
|
||||
|
@ -54,6 +55,7 @@ public class Unicopia implements ModInitializer {
|
|||
});
|
||||
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(TreeTypeLoader.INSTANCE);
|
||||
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(UEnchantments.POISONED_JOKE);
|
||||
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(TraitLoader.INSTANCE);
|
||||
|
||||
UBlocks.bootstrap();
|
||||
UItems.bootstrap();
|
||||
|
|
|
@ -8,7 +8,7 @@ import com.minelittlepony.unicopia.EquinePredicates;
|
|||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||
|
|
|
@ -5,7 +5,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
|
@ -59,7 +60,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
|
|||
player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F);
|
||||
|
||||
iplayer.getSpellSlot().get(SpellType.DISGUISE, true)
|
||||
.orElseGet(() -> SpellType.DISGUISE.apply(iplayer))
|
||||
.orElseGet(() -> SpellType.DISGUISE.apply(iplayer, SpellTraits.EMPTY))
|
||||
.setDisguise(looked);
|
||||
|
||||
if (!player.isCreative()) {
|
||||
|
|
|
@ -4,7 +4,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
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.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||
|
@ -67,7 +68,7 @@ public class PegasusRainboomAbility implements Ability<Hit> {
|
|||
if (player.getPhysics().isFlying() && !player.getSpellSlot().isPresent()) {
|
||||
player.getMagicalReserves().getMana().multiply(0.1F);
|
||||
player.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, player.getPhysics().getMotionAngle()), player.getOriginVector(), Vec3d.ZERO);
|
||||
player.setSpell(SpellType.JOUSTING.create());
|
||||
player.setSpell(SpellType.RAINBOOM.create(SpellTraits.EMPTY));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@ 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;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
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;
|
||||
|
@ -114,7 +115,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
SpellType<?> spell = newSpell.getValue();
|
||||
|
||||
player.subtractEnergyCost(spell.isEmpty() ? 2 : 4);
|
||||
spell.apply(player);
|
||||
spell.apply(player, SpellTraits.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
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, SpellType::mayAttach))
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, null))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<SpellType<?>>pass(current == SpellType.EMPTY_KEY ? SpellType.SHIELD : SpellType.EMPTY_KEY));
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@ 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.Thrown;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileCapable;
|
||||
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;
|
||||
|
@ -73,14 +74,14 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
|||
}
|
||||
|
||||
player.subtractEnergyCost(getCostEstimate(player));
|
||||
((Thrown)spell.create()).toss(player);
|
||||
((ProjectileCapable)spell.create(SpellTraits.EMPTY)).toss(player);
|
||||
}
|
||||
}
|
||||
|
||||
private TypedActionResult<SpellType<?>> getNewSpell(Pony player) {
|
||||
return Streams.stream(player.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, SpellType::mayThrow))
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, null))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<SpellType<?>>pass(null));
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package com.minelittlepony.unicopia.ability.magic;
|
||||
|
||||
/**
|
||||
* A magic effect that does something when attached to an entity.
|
||||
*/
|
||||
public interface Attached extends Spell {
|
||||
/**
|
||||
* Called every tick when attached to a living entity.
|
||||
*
|
||||
* @param source The entity we are currently attached to.
|
||||
* @return true to keep alive
|
||||
*/
|
||||
boolean onBodyTick(Caster<?> source);
|
||||
}
|
|
@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.entity.Physics;
|
||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||
import com.minelittlepony.unicopia.particle.ParticleSource;
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
package com.minelittlepony.unicopia.ability.magic;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
/**
|
||||
* Interface for a magic spells
|
||||
*/
|
||||
public interface Spell extends NbtSerialisable, Affine {
|
||||
|
||||
/**
|
||||
* Returns the registered type of this spell.
|
||||
*/
|
||||
SpellType<?> getType();
|
||||
|
||||
/**
|
||||
* The unique id of this particular spell instance.
|
||||
*/
|
||||
UUID getUuid();
|
||||
|
||||
/**
|
||||
* Sets this effect as dead.
|
||||
*/
|
||||
void setDead();
|
||||
|
||||
/**
|
||||
* Returns true if this spell is dead, and must be cleaned up.
|
||||
*/
|
||||
boolean isDead();
|
||||
|
||||
/**
|
||||
* Returns true if this effect has changes that need to be sent to the client.
|
||||
*/
|
||||
boolean isDirty();
|
||||
|
||||
/**
|
||||
* Applies this spell to the supplied caster.
|
||||
*/
|
||||
boolean apply(Caster<?> caster);
|
||||
|
||||
/**
|
||||
* Marks this effect as dirty.
|
||||
*/
|
||||
void setDirty();
|
||||
|
||||
/**
|
||||
* Called when a gem is destroyed.
|
||||
*/
|
||||
void onDestroyed(Caster<?> caster);
|
||||
}
|
|
@ -4,7 +4,7 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
|
||||
public interface SpellContainer {
|
||||
SpellContainer EMPTY = new SpellContainer() {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
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.Spell;
|
||||
|
||||
public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
|
||||
SpellPredicate<ProjectileCapable> IS_THROWN = s -> s instanceof ProjectileCapable;
|
||||
SpellPredicate<Suppressable> IS_SUPPRESSABLE = s -> s instanceof Suppressable;
|
||||
|
||||
default boolean isOn(Caster<?> caster) {
|
||||
return caster.getSpellSlot().get(this, false).isPresent();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.ability.magic;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
|
||||
/**
|
||||
* Magic effects that can be suppressed by other nearby effects.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
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 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 {
|
||||
|
||||
private boolean isDirty;
|
||||
|
||||
private UUID uuid = UUID.randomUUID();
|
||||
|
||||
private final SpellType<?> type;
|
||||
|
||||
public AbstractDelegatingSpell(SpellType<?> type, SpellTraits traits) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
protected abstract Collection<Spell> getDelegates();
|
||||
|
||||
@Override
|
||||
public Affinity getAffinity() {
|
||||
return Affinity.NEUTRAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellType<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead() {
|
||||
getDelegates().forEach(Spell::setDead);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDead() {
|
||||
return getDelegates().isEmpty() || getDelegates().stream().allMatch(Spell::isDead);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
return isDirty || getDelegates().stream().anyMatch(Spell::isDirty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Caster<?> caster) {
|
||||
caster.setSpell(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty() {
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(Caster<?> caster) {
|
||||
getDelegates().forEach(spell -> spell.onDestroyed(caster));
|
||||
}
|
||||
|
||||
@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);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileCapable).forEach(a -> {
|
||||
((ProjectileCapable)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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
compound.putUuid("uuid", uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
isDirty = false;
|
||||
if (compound.contains("uuid")) {
|
||||
uuid = compound.getUuid("uuid");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public abstract class AbstractPlacedSpell extends AbstractSpell implements Attached {
|
||||
|
||||
@Nullable
|
||||
private Identifier dimension;
|
||||
|
||||
private final ParticleHandle particlEffect = new ParticleHandle();
|
||||
|
||||
private final EntityReference<CastSpellEntity> castEntity = new EntityReference<>();
|
||||
|
||||
protected AbstractPlacedSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead() {
|
||||
super.setDead();
|
||||
particlEffect.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
|
||||
if (!source.isClient()) {
|
||||
|
||||
if (dimension == null) {
|
||||
dimension = source.getWorld().getRegistryKey().getValue();
|
||||
setDirty();
|
||||
} else if (!source.getWorld().getRegistryKey().getValue().equals(dimension)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!castEntity.isPresent(source.getWorld())) {
|
||||
CastSpellEntity entity = UEntities.CAST_SPELL.create(source.getWorld());
|
||||
Vec3d pos = castEntity.getPosition().orElse(source.getOriginVector());
|
||||
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, 0, 0);
|
||||
entity.setSpell(this);
|
||||
entity.setMaster(source.getMaster());
|
||||
entity.world.spawnEntity(entity);
|
||||
|
||||
castEntity.set(entity);
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
return !isDead();
|
||||
}
|
||||
|
||||
public boolean onGroundTick(Caster<?> source) {
|
||||
particlEffect.ifAbsent(source, spawner -> {
|
||||
spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), source.getOriginVector(), Vec3d.ZERO);
|
||||
}).ifPresent(p -> {
|
||||
p.attach(source);
|
||||
p.setAttribute(1, getType().getColor());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
super.toNBT(compound);
|
||||
|
||||
if (dimension != null) {
|
||||
compound.putString("dimension", dimension.toString());
|
||||
}
|
||||
compound.put("castEntity", castEntity.toNBT());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
super.fromNBT(compound);
|
||||
if (compound.contains("dimension")) {
|
||||
dimension = new Identifier(compound.getString("dimension"));
|
||||
}
|
||||
if (compound.contains("castEntity")) {
|
||||
castEntity.fromNBT(compound.getCompound("castEntity"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
|
||||
public class CompoundSpell extends AbstractDelegatingSpell {
|
||||
private final List<Spell> spells = new ArrayList<>();
|
||||
|
||||
public CompoundSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Spell> getDelegates() {
|
||||
return spells;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell combineWith(Spell other) {
|
||||
if (other instanceof CompoundSpell) {
|
||||
spells.addAll(((CompoundSpell)other).spells);
|
||||
} else {
|
||||
spells.add(other);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
super.toNBT(compound);
|
||||
NbtList spells = new NbtList();
|
||||
this.spells.forEach(spell -> {
|
||||
spells.add(spell.toNBT());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
super.fromNBT(compound);
|
||||
spells.clear();
|
||||
if (compound.contains("spells", NbtElement.LIST_TYPE)) {
|
||||
spells.addAll(compound.getList("spells", NbtElement.COMPOUND_TYPE).stream()
|
||||
.map(el -> SpellType.fromNBT((NbtCompound)el))
|
||||
.filter(Objects::nonNull)
|
||||
.toList());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,10 +6,11 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.FlightType;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
||||
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.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
@ -27,14 +28,14 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
||||
public class DisguiseSpell extends AbstractSpell implements Attached, Suppressable, FlightType.Provider, PlayerDimensions.Provider, ProjectileImpactListener {
|
||||
public class DisguiseSpell extends AbstractSpell implements Suppressable, FlightType.Provider, PlayerDimensions.Provider, ProjectileImpactListener {
|
||||
|
||||
private final Disguise disguise = new Disguise();
|
||||
|
||||
private int suppressionCounter;
|
||||
|
||||
protected DisguiseSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
public DisguiseSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -83,8 +84,11 @@ public class DisguiseSpell extends AbstractSpell implements Attached, Suppressab
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
return update(source, true);
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (situation == Situation.BODY) {
|
||||
return update(source, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
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.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
|
@ -20,7 +22,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.GameRules;
|
||||
|
||||
public class JoustingSpell extends AbstractSpell implements Attached {
|
||||
public class JoustingSpell extends AbstractSpell {
|
||||
|
||||
private final int rad = 5;
|
||||
private final Shape effect_range = new Sphere(false, rad);
|
||||
|
@ -29,8 +31,8 @@ public class JoustingSpell extends AbstractSpell implements Attached {
|
|||
|
||||
private int age;
|
||||
|
||||
protected JoustingSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
public JoustingSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,7 +42,12 @@ public class JoustingSpell extends AbstractSpell implements Attached {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
|
||||
if (situation != Situation.BODY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source.isClient()) {
|
||||
particlEffect.ifAbsent(source, spawner -> {
|
||||
spawner.addParticle(UParticles.RAINBOOM_TRAIL, source.getOriginVector(), Vec3d.ZERO);
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.util.Identifier;
|
||||
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.
|
||||
* <p>
|
||||
* 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.
|
||||
*/
|
||||
public class PlaceableSpell extends AbstractDelegatingSpell {
|
||||
@Nullable
|
||||
private Identifier dimension;
|
||||
|
||||
private final ParticleHandle particlEffect = new ParticleHandle();
|
||||
|
||||
private final EntityReference<CastSpellEntity> castEntity = new EntityReference<>();
|
||||
|
||||
private Spell spell;
|
||||
|
||||
public PlaceableSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
public PlaceableSpell setSpell(Spell spell) {
|
||||
this.spell = spell;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Spell> getDelegates() {
|
||||
return List.of(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead() {
|
||||
super.setDead();
|
||||
particlEffect.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (situation == Situation.BODY) {
|
||||
if (!source.isClient()) {
|
||||
if (dimension == null) {
|
||||
dimension = source.getWorld().getRegistryKey().getValue();
|
||||
setDirty();
|
||||
} else if (!source.getWorld().getRegistryKey().getValue().equals(dimension)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!castEntity.isPresent(source.getWorld())) {
|
||||
CastSpellEntity entity = UEntities.CAST_SPELL.create(source.getWorld());
|
||||
Vec3d pos = castEntity.getPosition().orElse(source.getOriginVector());
|
||||
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, 0, 0);
|
||||
entity.setSpell(this);
|
||||
entity.setMaster(source.getMaster());
|
||||
entity.world.spawnEntity(entity);
|
||||
|
||||
castEntity.set(entity);
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
return super.tick(source, Situation.GROUND);
|
||||
} else if (situation == Situation.GROUND_ENTITY) {
|
||||
particlEffect.ifAbsent(source, spawner -> {
|
||||
spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), source.getOriginVector(), Vec3d.ZERO);
|
||||
}).ifPresent(p -> {
|
||||
p.attach(source);
|
||||
p.setAttribute(1, getType().getColor());
|
||||
});
|
||||
}
|
||||
|
||||
return !isDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
super.toNBT(compound);
|
||||
if (dimension != null) {
|
||||
compound.putString("dimension", dimension.toString());
|
||||
}
|
||||
compound.put("castEntity", castEntity.toNBT());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
super.toNBT();
|
||||
if (compound.contains("dimension")) {
|
||||
dimension = new Identifier(compound.getString("dimension"));
|
||||
}
|
||||
if (compound.contains("castEntity")) {
|
||||
castEntity.fromNBT(compound.getCompound("castEntity"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaceableSpell toPlaceable() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package com.minelittlepony.unicopia.ability.magic;
|
||||
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;
|
||||
|
@ -20,20 +21,12 @@ import net.minecraft.world.World;
|
|||
/**
|
||||
* Magic effects that can be thrown.
|
||||
*/
|
||||
public interface Thrown extends Spell, ProjectileDelegate {
|
||||
|
||||
/**
|
||||
* Called every tick when attached to an entity.
|
||||
* Called on both sides.
|
||||
*
|
||||
* @param source The entity we are currently attached to.
|
||||
*/
|
||||
boolean onThrownTick(MagicProjectileEntity projectile);
|
||||
public interface ProjectileCapable extends Spell, ProjectileDelegate {
|
||||
|
||||
@Override
|
||||
default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (!projectile.isClient()) {
|
||||
onThrownTick(projectile);
|
||||
tick(projectile, Situation.PROJECTILE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
public enum Situation {
|
||||
BODY,
|
||||
PROJECTILE,
|
||||
GROUND,
|
||||
GROUND_ENTITY
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
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.util.NbtSerialisable;
|
||||
|
||||
/**
|
||||
* Interface for a magic spells
|
||||
*/
|
||||
public interface Spell extends NbtSerialisable, Affine {
|
||||
|
||||
/**
|
||||
* Returns the registered type of this spell.
|
||||
*/
|
||||
SpellType<?> getType();
|
||||
|
||||
/**
|
||||
* The unique id of this particular spell instance.
|
||||
*/
|
||||
UUID getUuid();
|
||||
|
||||
/**
|
||||
* Sets this effect as dead.
|
||||
*/
|
||||
void setDead();
|
||||
|
||||
/**
|
||||
* Returns true if this spell is dead, and must be cleaned up.
|
||||
*/
|
||||
boolean isDead();
|
||||
|
||||
/**
|
||||
* Returns true if this effect has changes that need to be sent to the client.
|
||||
*/
|
||||
boolean isDirty();
|
||||
|
||||
/**
|
||||
* Applies this spell to the supplied caster.
|
||||
*/
|
||||
boolean apply(Caster<?> caster);
|
||||
|
||||
/**
|
||||
* Called to generate this spell's effects.
|
||||
* @param caster The caster currently fueling this spell
|
||||
* @param situation The situation in which the spell is being applied.
|
||||
*/
|
||||
boolean tick(Caster<?> caster, Situation situation);
|
||||
|
||||
/**
|
||||
* Marks this effect as dirty.
|
||||
*/
|
||||
void setDirty();
|
||||
|
||||
/**
|
||||
* Called when a gem is destroyed.
|
||||
*/
|
||||
void onDestroyed(Caster<?> caster);
|
||||
|
||||
/**
|
||||
* Used by crafting to combine two spells into one.
|
||||
*
|
||||
* Returns a compound spell representing the union of this and the other spell.
|
||||
*/
|
||||
default Spell combineWith(Spell other) {
|
||||
return SpellType.COMPOUND_SPELL.create(SpellTraits.EMPTY).combineWith(this).combineWith(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this spell into a placeable spell.
|
||||
*/
|
||||
default PlaceableSpell toPlaceable() {
|
||||
return SpellType.PLACED_SPELL.create(SpellTraits.EMPTY).setSpell(this);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
|
||||
public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
|
||||
SpellPredicate<Thrown> IS_THROWN = s -> s instanceof Thrown;
|
||||
SpellPredicate<Attached> IS_ATTACHED = s -> s instanceof Attached;
|
||||
SpellPredicate<Suppressable> IS_SUPPRESSABLE = s -> s instanceof Suppressable;
|
||||
|
||||
default boolean isOn(Caster<?> caster) {
|
||||
return caster.getSpellSlot().get(this, false).isPresent();
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
||||
|
@ -15,11 +16,13 @@ public abstract class AbstractSpell implements Spell {
|
|||
|
||||
private final SpellType<?> type;
|
||||
|
||||
private UUID uuid;
|
||||
private SpellTraits traits;
|
||||
|
||||
protected AbstractSpell(SpellType<?> type) {
|
||||
private UUID uuid = UUID.randomUUID();
|
||||
|
||||
protected AbstractSpell(SpellType<?> type, SpellTraits traits) {
|
||||
this.type = type;
|
||||
uuid = UUID.randomUUID();
|
||||
this.traits = traits;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +35,10 @@ public abstract class AbstractSpell implements Spell {
|
|||
return type;
|
||||
}
|
||||
|
||||
protected SpellTraits getTraits() {
|
||||
return traits == null ? SpellTraits.EMPTY : traits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead() {
|
||||
isDead = true;
|
||||
|
@ -59,7 +66,7 @@ public abstract class AbstractSpell implements Spell {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Caster<?> caster) {
|
||||
public final boolean apply(Caster<?> caster) {
|
||||
caster.setSpell(this);
|
||||
return true;
|
||||
}
|
||||
|
@ -72,6 +79,7 @@ public abstract class AbstractSpell implements Spell {
|
|||
public void toNBT(NbtCompound compound) {
|
||||
compound.putBoolean("dead", isDead);
|
||||
compound.putUuid("uuid", uuid);
|
||||
compound.put("traits", getTraits().toNbt());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,5 +89,8 @@ public abstract class AbstractSpell implements Spell {
|
|||
uuid = compound.getUuid("uuid");
|
||||
}
|
||||
isDead = compound.getBoolean("dead");
|
||||
if (compound.contains("traits")) {
|
||||
traits = SpellTraits.readNbt(compound.getCompound("traits")).orElse(SpellTraits.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||
|
@ -20,13 +20,13 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class AttractiveSpell extends ShieldSpell implements Thrown {
|
||||
public class AttractiveSpell extends ShieldSpell {
|
||||
|
||||
@Nullable
|
||||
private BlockPos homingPos;
|
||||
|
||||
protected AttractiveSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected AttractiveSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,10 +1,12 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
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;
|
||||
|
||||
import net.minecraft.particle.ParticleEffect;
|
||||
|
@ -15,14 +17,14 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class AwkwardSpell extends AbstractSpell implements Thrown {
|
||||
public class AwkwardSpell extends AbstractSpell implements ProjectileCapable {
|
||||
|
||||
protected AwkwardSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected AwkwardSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity source) {
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (source.isClient()) {
|
||||
source.spawnParticles(new Sphere(false, (1 + source.getLevel().get()) * 8), 10, pos -> {
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
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;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
@ -34,12 +35,12 @@ 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 Thrown, Attached {
|
||||
public class FireSpell extends AbstractSpell implements ProjectileCapable {
|
||||
|
||||
private static final Shape EFFECT_RANGE = new Sphere(false, 4);
|
||||
|
||||
protected FireSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected FireSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,12 +51,7 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity projectile) {
|
||||
return onBodyTick(projectile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (source.isClient()) {
|
||||
generateParticles(source);
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
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;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||
import com.minelittlepony.unicopia.util.PosHelper;
|
||||
import com.minelittlepony.unicopia.util.VecHelper;
|
||||
|
@ -27,22 +27,17 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class IceSpell extends AbstractSpell implements Thrown, Attached {
|
||||
public class IceSpell extends AbstractSpell implements ProjectileCapable {
|
||||
|
||||
private final int rad = 3;
|
||||
private final Shape effect_range = new Sphere(false, rad);
|
||||
|
||||
protected IceSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected IceSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity projectile) {
|
||||
return onBodyTick(projectile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
LivingEntity owner = source.getMaster();
|
||||
|
||||
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range)
|
|
@ -1,6 +1,8 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
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.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.block.state.BlockStateConverter;
|
||||
import com.minelittlepony.unicopia.block.state.StateMaps;
|
||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||
|
@ -16,12 +18,12 @@ import net.minecraft.world.World;
|
|||
|
||||
public class InfernoSpell extends FireSpell {
|
||||
|
||||
protected InfernoSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected InfernoSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (source.isClient()) {
|
||||
generateParticles(source);
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.util.Weighted;
|
||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||
|
@ -20,7 +22,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.WorldEvents;
|
||||
|
||||
public class NecromancySpell extends AbstractPlacedSpell {
|
||||
public class NecromancySpell extends AbstractSpell {
|
||||
|
||||
private final Weighted<EntityType<? extends LivingEntity>> spawnPool = new Weighted<EntityType<? extends LivingEntity>>()
|
||||
.put(7, EntityType.ZOMBIE)
|
||||
|
@ -31,14 +33,12 @@ public class NecromancySpell extends AbstractPlacedSpell {
|
|||
|
||||
private final List<EntityReference<LivingEntity>> summonedEntities = new ArrayList<>();
|
||||
|
||||
protected NecromancySpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected NecromancySpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onGroundTick(Caster<?> source) {
|
||||
super.onGroundTick(source);
|
||||
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
int radius = (source.getLevel().get() + 1) * 4;
|
||||
|
||||
if (source.isClient()) {
|
|
@ -1,10 +1,11 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
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.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
||||
|
@ -15,21 +16,15 @@ import net.minecraft.util.math.Vec3d;
|
|||
/**
|
||||
* A spell for revealing changelings.
|
||||
*/
|
||||
public class RevealingSpell extends AbstractSpell implements Attached, Thrown {
|
||||
public class RevealingSpell extends AbstractSpell implements ProjectileCapable {
|
||||
private static final Shape AREA = new Sphere(false, 15);
|
||||
|
||||
protected RevealingSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected RevealingSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity projectile) {
|
||||
return onBodyTick(projectile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (source.isClient()) {
|
||||
MagicParticleEffect effect = new MagicParticleEffect(getType().getColor());
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
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;
|
||||
import com.minelittlepony.unicopia.block.state.StateMaps;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
@ -15,13 +17,12 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public class ScorchSpell extends FireSpell {
|
||||
|
||||
protected ScorchSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected ScorchSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
BlockPos pos = PosHelper.findSolidGroundAt(source.getWorld(), source.getOrigin(), source.getPhysics().getGravitySignum());
|
||||
|
||||
if (StateMaps.FIRE_AFFECTED.convert(source.getWorld(), pos)) {
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -8,16 +8,16 @@ import java.util.stream.Collectors;
|
|||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
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.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
||||
|
@ -35,14 +35,14 @@ import net.minecraft.entity.vehicle.BoatEntity;
|
|||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class ShieldSpell extends AbstractSpell implements Attached, Thrown {
|
||||
public class ShieldSpell extends AbstractSpell implements ProjectileCapable {
|
||||
|
||||
private final ParticleHandle particlEffect = new ParticleHandle();
|
||||
|
||||
private final Map<UUID, Target> targets = new TreeMap<>();
|
||||
|
||||
protected ShieldSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected ShieldSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,19 +68,14 @@ public class ShieldSpell extends AbstractSpell implements Attached, Thrown {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity source) {
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
if (source.isClient()) {
|
||||
generateParticles(source);
|
||||
}
|
||||
|
||||
applyEntities(source);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
if (source.isClient()) {
|
||||
generateParticles(source);
|
||||
if (situation == Situation.PROJECTILE) {
|
||||
applyEntities(source);
|
||||
return true;
|
||||
}
|
||||
|
||||
long costMultiplier = applyEntities(source);
|
||||
|
@ -216,8 +211,7 @@ public class ShieldSpell extends AbstractSpell implements Attached, Thrown {
|
|||
|
||||
int cooldown = 20;
|
||||
|
||||
Target(UUID id) {
|
||||
}
|
||||
Target(UUID id) { }
|
||||
|
||||
boolean tick() {
|
||||
return --cooldown < 0;
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -6,6 +6,8 @@ import java.util.stream.Stream;
|
|||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
|
@ -26,17 +28,16 @@ import net.minecraft.util.math.Vec3d;
|
|||
/**
|
||||
* A spell that pulls health from other entities and delivers it to the caster.
|
||||
*/
|
||||
public class SiphoningSpell extends AbstractPlacedSpell {
|
||||
public class SiphoningSpell extends AbstractSpell {
|
||||
|
||||
private int ticksUpset;
|
||||
|
||||
protected SiphoningSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected SiphoningSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onGroundTick(Caster<?> source) {
|
||||
super.onGroundTick(source);
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
|
||||
if (ticksUpset > 0) {
|
||||
ticksUpset--;
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -11,7 +11,13 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.CompoundSpell;
|
||||
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.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.util.Registries;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
@ -24,11 +30,17 @@ import net.minecraft.util.registry.Registry;
|
|||
public final class SpellType<T extends Spell> implements Affine, SpellPredicate<T> {
|
||||
|
||||
public static final Identifier EMPTY_ID = new Identifier("unicopia", "null");
|
||||
public static final SpellType<?> EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, t -> null);
|
||||
public static final SpellType<?> EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, (t, c) -> null);
|
||||
|
||||
private static final Registry<SpellType<?>> REGISTRY = Registries.createSimple(new Identifier("unicopia", "spells"));
|
||||
private static final Map<Affinity, Set<SpellType<?>>> BY_AFFINITY = new EnumMap<>(Affinity.class);
|
||||
|
||||
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<DisguiseSpell> DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new);
|
||||
public static final SpellType<JoustingSpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new);
|
||||
|
||||
public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new);
|
||||
public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0, true, ScorchSpell::new);
|
||||
public static final SpellType<FireSpell> FLAME = register("flame", Affinity.GOOD, 0xFF5D00, true, FireSpell::new);
|
||||
|
@ -40,9 +52,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0x8A3A3A, true, NecromancySpell::new);
|
||||
public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.GOOD, 0xe308ab, true, SiphoningSpell::new);
|
||||
public static final SpellType<SiphoningSpell> DRAINING = register("draining", Affinity.BAD, 0xe308ab, true, SiphoningSpell::new);
|
||||
public static final SpellType<DisguiseSpell> DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new);
|
||||
public static final SpellType<RevealingSpell> REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new);
|
||||
public static final SpellType<JoustingSpell> JOUSTING = register("joust", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new);
|
||||
public static final SpellType<AwkwardSpell> AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new);
|
||||
public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", Affinity.NEUTRAL, 0x3A59AA, true, TransformationSpell::new);
|
||||
|
||||
|
@ -53,9 +63,6 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
|
||||
private final Factory<T> factory;
|
||||
|
||||
private final boolean thrown;
|
||||
private final boolean attached;
|
||||
|
||||
@Nullable
|
||||
private String translationKey;
|
||||
|
||||
|
@ -65,24 +72,12 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
this.color = color;
|
||||
this.obtainable = obtainable;
|
||||
this.factory = factory;
|
||||
|
||||
Spell inst = create();
|
||||
thrown = SpellPredicate.IS_THROWN.test(inst);
|
||||
attached = SpellPredicate.IS_ATTACHED.test(inst);
|
||||
}
|
||||
|
||||
public boolean isObtainable() {
|
||||
return obtainable;
|
||||
}
|
||||
|
||||
public boolean mayThrow() {
|
||||
return thrown;
|
||||
}
|
||||
|
||||
public boolean mayAttach() {
|
||||
return attached;
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -111,9 +106,9 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public T create() {
|
||||
public T create(SpellTraits traits) {
|
||||
try {
|
||||
return factory.create(this);
|
||||
return factory.create(this, traits);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -122,13 +117,13 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public T apply(Caster<?> caster) {
|
||||
public T apply(Caster<?> caster, SpellTraits traits) {
|
||||
if (isEmpty()) {
|
||||
caster.setSpell(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
T spell = create();
|
||||
T spell = create(traits);
|
||||
if (spell.apply(caster)) {
|
||||
return spell;
|
||||
}
|
||||
|
@ -177,7 +172,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
@Nullable
|
||||
public static Spell fromNBT(@Nullable NbtCompound compound) {
|
||||
if (compound != null && compound.contains("effect_id")) {
|
||||
Spell effect = getKey(new Identifier(compound.getString("effect_id"))).create();
|
||||
Spell effect = getKey(new Identifier(compound.getString("effect_id"))).create(SpellTraits.EMPTY);
|
||||
|
||||
if (effect != null) {
|
||||
effect.fromNBT(compound);
|
||||
|
@ -198,6 +193,6 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
}
|
||||
|
||||
public interface Factory<T extends Spell> {
|
||||
T create(SpellType<T> type);
|
||||
T create(SpellType<T> type, SpellTraits traits);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
@ -7,7 +7,10 @@ import java.util.Random;
|
|||
import java.util.Set;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||
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.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
@ -19,15 +22,15 @@ import net.minecraft.particle.ParticleTypes;
|
|||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public class TransformationSpell extends AbstractSpell implements Thrown {
|
||||
public class TransformationSpell extends AbstractSpell implements ProjectileCapable {
|
||||
|
||||
protected TransformationSpell(SpellType<?> type) {
|
||||
super(type);
|
||||
protected TransformationSpell(SpellType<?> type, SpellTraits traits) {
|
||||
super(type, traits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity source) {
|
||||
return true;
|
||||
public boolean tick(Caster<?> caster, Situation situation) {
|
||||
return situation == Situation.PROJECTILE;
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,96 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.trait;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class SpellTraits {
|
||||
public static final SpellTraits EMPTY = new SpellTraits(Map.of());
|
||||
|
||||
private final Map<Trait, Float> traits;
|
||||
|
||||
SpellTraits(Map<Trait, Float> traits) {
|
||||
this.traits = traits;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return traits.isEmpty();
|
||||
}
|
||||
|
||||
public Set<Map.Entry<Trait, Float>> entries() {
|
||||
return traits.entrySet();
|
||||
}
|
||||
|
||||
public float getAmount(Trait trait) {
|
||||
return traits.getOrDefault(trait, 0F);
|
||||
}
|
||||
|
||||
public NbtCompound toNbt() {
|
||||
NbtCompound nbt = new NbtCompound();
|
||||
traits.forEach((key, value) -> nbt.putFloat(key.name(), value));
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public Optional<SpellTraits> of(Collection<ItemStack> stacks) {
|
||||
return fromEntries(stacks.stream().flatMap(a -> of(a).entries().stream()));
|
||||
}
|
||||
|
||||
public SpellTraits of(ItemStack stack) {
|
||||
return getEmbeddedTraits(stack).orElseGet(() -> of(stack.getItem()));
|
||||
}
|
||||
|
||||
public SpellTraits of(Item item) {
|
||||
return TraitLoader.INSTANCE.values.getOrDefault(Registry.ITEM.getId(item), null);
|
||||
}
|
||||
|
||||
public SpellTraits of(Block block) {
|
||||
return of(block.asItem());
|
||||
}
|
||||
|
||||
private static Optional<SpellTraits> getEmbeddedTraits(ItemStack stack) {
|
||||
if (!(stack.hasTag() && stack.getTag().contains("spell_traits", NbtElement.COMPOUND_TYPE))) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return readNbt(stack.getTag().getCompound("spell_traits"));
|
||||
}
|
||||
|
||||
public static Optional<SpellTraits> readNbt(NbtCompound traits) {
|
||||
return fromEntries(streamFromNbt(traits));
|
||||
}
|
||||
|
||||
public static Stream<Map.Entry<Trait, Float>> streamFromNbt(NbtCompound traits) {
|
||||
return traits.getKeys().stream().map(key -> {
|
||||
Trait trait = Trait.REGISTRY.get(key.toUpperCase());
|
||||
if (trait == null && !traits.contains(key, NbtElement.NUMBER_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
return Map.entry(trait, traits.getFloat(key));
|
||||
});
|
||||
}
|
||||
|
||||
public static Optional<SpellTraits> fromEntries(Stream<Map.Entry<Trait, Float>> entries) {
|
||||
var result = collect(entries);
|
||||
|
||||
if (result.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(new SpellTraits(result));
|
||||
}
|
||||
|
||||
static Map<Trait, Float> collect(Stream<Map.Entry<Trait, Float>> entries) {
|
||||
return entries.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a + b, () -> new EnumMap<>(Trait.class)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.trait;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public enum Trait {
|
||||
LIFE(TraitGroup.NATURE),
|
||||
ENERGY(TraitGroup.NATURE),
|
||||
REBIRTH(TraitGroup.NATURE),
|
||||
GROWTH(TraitGroup.NATURE),
|
||||
|
||||
WATER(TraitGroup.ELEMENTAL),
|
||||
EARTH(TraitGroup.ELEMENTAL),
|
||||
FIRE(TraitGroup.ELEMENTAL),
|
||||
AIR(TraitGroup.ELEMENTAL),
|
||||
|
||||
CORRUPTION(TraitGroup.DARKNESS),
|
||||
DEATH(TraitGroup.DARKNESS),
|
||||
FAMINE(TraitGroup.DARKNESS),
|
||||
PESTILENCE(TraitGroup.DARKNESS);
|
||||
|
||||
public static final Map<String, Trait> REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Trait::name, Function.identity()));
|
||||
|
||||
private final Identifier id;
|
||||
private final TraitGroup group;
|
||||
|
||||
Trait(TraitGroup group) {
|
||||
this.id = new Identifier("unicopia", "spell/trait/" + name().toLowerCase());
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public TraitGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.trait;
|
||||
|
||||
public enum TraitGroup {
|
||||
NATURE(-0.2F),
|
||||
DARKNESS(0.4F),
|
||||
ELEMENTAL(-0.02F);
|
||||
|
||||
private final float corruption;
|
||||
|
||||
TraitGroup(float corruption) {
|
||||
this.corruption = corruption;
|
||||
}
|
||||
|
||||
// TODO: implement corruption mechanics
|
||||
public float getCorruption() {
|
||||
return corruption;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.trait;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.util.Resources;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.resource.SinglePreparationResourceReloader;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.InvalidIdentifierException;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
|
||||
public class TraitLoader extends SinglePreparationResourceReloader<Map<Identifier, SpellTraits>> implements IdentifiableResourceReloadListener {
|
||||
private static final Identifier ID = new Identifier("unicopia", "data/traits");
|
||||
|
||||
private static final TypeToken<Map<String, String>> TYPE = new TypeToken<>() {};
|
||||
|
||||
public static final TraitLoader INSTANCE = new TraitLoader();
|
||||
|
||||
Map<Identifier, SpellTraits> values = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Identifier getFabricId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Identifier, SpellTraits> prepare(ResourceManager manager, Profiler profiler) {
|
||||
profiler.startTick();
|
||||
|
||||
Map<Identifier, SpellTraits> prepared = new HashMap<>();
|
||||
|
||||
for (String namespace : manager.getAllNamespaces()) {
|
||||
profiler.push(namespace);
|
||||
try {
|
||||
for (Resource resource : manager.getAllResources(new Identifier(namespace, "items/traits"))) {
|
||||
profiler.push(resource.getResourcePackName());
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
|
||||
Map<String, String> data = JsonHelper.deserialize(Resources.GSON, reader, TYPE);
|
||||
|
||||
data.forEach((name, set) -> {
|
||||
try {
|
||||
Identifier id = new Identifier(name);
|
||||
SpellTraits.fromEntries(Arrays.stream(set.split(" ")).map(a -> a.split(":")).map(pair -> {
|
||||
Trait key = Trait.REGISTRY.get(pair[0].toUpperCase());
|
||||
if (key == null) {
|
||||
Unicopia.LOGGER.warn("Failed to load trait entry for item {} in {}. {} is not a valid trait", id, resource.getResourcePackName(), pair[0]);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Map.entry(key, Float.parseFloat(pair[1]));
|
||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
|
||||
Unicopia.LOGGER.warn("Failed to load trait entry for item {} in {}. {} is not a valid weighting", id, resource.getResourcePackName(), Arrays.toString(pair));
|
||||
return null;
|
||||
}
|
||||
})).ifPresent(value -> prepared.put(id, value));
|
||||
} catch (InvalidIdentifierException e) {
|
||||
Unicopia.LOGGER.warn("Failed to load traits for item {} in {}.", name, resource.getResourcePackName(), e);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
profiler.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return prepared;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(Map<Identifier, SpellTraits> prepared, ResourceManager manager, Profiler profiler) {
|
||||
values = prepared;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.USounds;
|
|||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.client.KeyBindingsHandler;
|
||||
import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.client.render;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
|
|
@ -3,8 +3,9 @@ package com.minelittlepony.unicopia.command;
|
|||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
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.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
@ -83,7 +84,7 @@ public class DisguiseCommand {
|
|||
|
||||
Pony iplayer = Pony.of(player);
|
||||
iplayer.getSpellSlot().get(SpellType.DISGUISE, true)
|
||||
.orElseGet(() -> SpellType.DISGUISE.apply(iplayer))
|
||||
.orElseGet(() -> SpellType.DISGUISE.apply(iplayer, SpellTraits.EMPTY))
|
||||
.setDisguise(entity);
|
||||
|
||||
if (source.getEntity() == player) {
|
||||
|
|
|
@ -6,10 +6,9 @@ import java.util.UUID;
|
|||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.AbstractPlacedSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
|
||||
|
||||
|
@ -32,8 +31,6 @@ public class CastSpellEntity extends Entity implements Caster<LivingEntity> {
|
|||
|
||||
private static final TrackedData<Optional<UUID>> SPELL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID);
|
||||
|
||||
private static final SpellPredicate<AbstractPlacedSpell> SPELL_TYPE = s -> s instanceof AbstractPlacedSpell;
|
||||
|
||||
private static final LevelStore LEVELS = Levelled.fixed(0);
|
||||
|
||||
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this, GRAVITY);
|
||||
|
@ -96,7 +93,7 @@ public class CastSpellEntity extends Entity implements Caster<LivingEntity> {
|
|||
if (!Caster.of(master).filter(c -> {
|
||||
UUID spellId = dataTracker.get(SPELL).orElse(null);
|
||||
|
||||
if (!c.getSpellSlot().get(SPELL_TYPE, true).filter(s -> s.getUuid().equals(spellId) && s.onGroundTick(this)).isPresent()) {
|
||||
if (!c.getSpellSlot().get(true).filter(s -> s.getUuid().equals(spellId) && s.tick(this, Situation.GROUND_ENTITY)).isPresent()) {
|
||||
c.setSpell(null);
|
||||
|
||||
return false;
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.minelittlepony.unicopia.Affinity;
|
|||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.ai.BreakHeartGoal;
|
||||
import com.minelittlepony.unicopia.entity.ai.DynamicTargetGoal;
|
||||
import com.minelittlepony.unicopia.entity.ai.WantItTakeItGoal;
|
||||
|
|
|
@ -7,8 +7,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.network.EffectSync;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
|
||||
|
@ -85,8 +85,8 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
getSpellSlot().get(SpellPredicate.IS_ATTACHED, true).ifPresent(effect -> {
|
||||
if (!effect.onBodyTick(this)) {
|
||||
getSpellSlot().get(true).ifPresent(effect -> {
|
||||
if (!effect.tick(this, Situation.BODY)) {
|
||||
setSpell(null);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Random;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.trade.TradeOfferHelper;
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.entity.behaviour;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||
|
||||
import net.minecraft.entity.passive.AxolotlEntity;
|
||||
import net.minecraft.util.math.Vec3f;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import com.minelittlepony.unicopia.FlightType;
|
|||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.player.PlayerAttributes;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Optional;
|
|||
|
||||
import com.minelittlepony.common.util.animation.MotionCompositor;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.minelittlepony.unicopia.FlightType;
|
|||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||
|
@ -94,7 +94,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
|
||||
@Override
|
||||
public boolean isRainbooming() {
|
||||
return pony.getSpellSlot().get(SpellType.JOUSTING, true).isPresent();
|
||||
return pony.getSpellSlot().get(SpellType.RAINBOOM, true).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,8 +16,8 @@ import com.minelittlepony.unicopia.WorldTribeManager;
|
|||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||
import com.minelittlepony.unicopia.ability.EarthPonyStompAbility;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.advancement.UCriteria;
|
||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
|
|
@ -8,8 +8,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -79,7 +79,7 @@ public class GemstoneItem extends Item {
|
|||
return super.getName();
|
||||
}
|
||||
|
||||
public static TypedActionResult<SpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, Predicate<SpellType<?>> test) {
|
||||
public static TypedActionResult<SpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, @Nullable Predicate<SpellType<?>> test) {
|
||||
|
||||
if (!isEnchanted(stack)) {
|
||||
return TypedActionResult.pass(null);
|
||||
|
@ -91,7 +91,7 @@ public class GemstoneItem extends Item {
|
|||
return TypedActionResult.fail(null);
|
||||
}
|
||||
|
||||
if (key == SpellType.EMPTY_KEY || !test.test(key)) {
|
||||
if (key == SpellType.EMPTY_KEY || (test == null || !test.test(key))) {
|
||||
return TypedActionResult.fail(null);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ import java.util.Optional;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
|
|
@ -6,10 +6,11 @@ import com.minelittlepony.unicopia.Affinity;
|
|||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||
import com.minelittlepony.unicopia.entity.Physics;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
|
@ -162,7 +163,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Li
|
|||
lastBlockPos = getBlockPos();
|
||||
}
|
||||
|
||||
if (!getSpellSlot().get(SpellPredicate.IS_THROWN, true).filter(spell -> spell.onThrownTick(this)).isPresent()) {
|
||||
if (!getSpellSlot().get(true).filter(spell -> spell.tick(this, Situation.PROJECTILE)).isPresent()) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue