diff --git a/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java b/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java index 7cf6d718..eb308efb 100644 --- a/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java +++ b/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/Unicopia.java b/src/main/java/com/minelittlepony/unicopia/Unicopia.java index 1fd31966..2b5168c6 100644 --- a/src/main/java/com/minelittlepony/unicopia/Unicopia.java +++ b/src/main/java/com/minelittlepony/unicopia/Unicopia.java @@ -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(); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/BatEeeeAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/BatEeeeAbility.java index 994d8e9f..6bd06037 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/BatEeeeAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/BatEeeeAbility.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java index 7d296a7d..b8c27e45 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java @@ -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()) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java index 96fb43b8..77f95fc6 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java @@ -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 { 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)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index 77ccfdbb..4e3b83ce 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -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 { 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 { 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.>pass(current == SpellType.EMPTY_KEY ? SpellType.SHIELD : SpellType.EMPTY_KEY)); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java index 54f6ebac..b29a8852 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java @@ -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 { } player.subtractEnergyCost(getCostEstimate(player)); - ((Thrown)spell.create()).toss(player); + ((ProjectileCapable)spell.create(SpellTraits.EMPTY)).toss(player); } } private TypedActionResult> 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.>pass(null)); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Attached.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Attached.java deleted file mode 100644 index 66650e11..00000000 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Attached.java +++ /dev/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); -} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java index 66358cd6..0a5747b0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java deleted file mode 100644 index fdb1ed93..00000000 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java +++ /dev/null @@ -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); -} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java index 81cc9eeb..a4681482 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java @@ -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() { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java new file mode 100644 index 00000000..0ecd3859 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellPredicate.java @@ -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 extends Predicate { + SpellPredicate IS_THROWN = s -> s instanceof ProjectileCapable; + SpellPredicate IS_SUPPRESSABLE = s -> s instanceof Suppressable; + + default boolean isOn(Caster caster) { + return caster.getSpellSlot().get(this, false).isPresent(); + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Suppressable.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Suppressable.java index 4ebe440e..1f4facb0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Suppressable.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Suppressable.java @@ -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. */ diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java new file mode 100644 index 00000000..a71c83fa --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java @@ -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 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 spells, Function 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"); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java deleted file mode 100644 index 3d08024f..00000000 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractPlacedSpell.java +++ /dev/null @@ -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 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")); - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/CompoundSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/CompoundSpell.java new file mode 100644 index 00000000..d72c02b5 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/CompoundSpell.java @@ -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 spells = new ArrayList<>(); + + public CompoundSpell(SpellType type, SpellTraits traits) { + super(type, traits); + } + + @Override + protected Collection 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()); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java index 91100caa..3626c2e0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java @@ -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") diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java index 0b7334ac..4103dbfe 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java @@ -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); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java new file mode 100644 index 00000000..4b5df60f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java @@ -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. + *

+ * 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 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 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; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Thrown.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileCapable.java similarity index 87% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/Thrown.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileCapable.java index 521494a2..328d1edc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Thrown.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileCapable.java @@ -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); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Situation.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Situation.java new file mode 100644 index 00000000..96ff9f4d --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Situation.java @@ -0,0 +1,8 @@ +package com.minelittlepony.unicopia.ability.magic.spell; + +public enum Situation { + BODY, + PROJECTILE, + GROUND, + GROUND_ENTITY +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java new file mode 100644 index 00000000..260d27a0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/Spell.java @@ -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); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellPredicate.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellPredicate.java deleted file mode 100644 index a84cbec5..00000000 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellPredicate.java +++ /dev/null @@ -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 extends Predicate { - SpellPredicate IS_THROWN = s -> s instanceof Thrown; - SpellPredicate IS_ATTACHED = s -> s instanceof Attached; - SpellPredicate IS_SUPPRESSABLE = s -> s instanceof Suppressable; - - default boolean isOn(Caster caster) { - return caster.getSpellSlot().get(this, false).isPresent(); - } -} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java similarity index 66% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java index 8d027613..36c775a7 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AbstractSpell.java @@ -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); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java similarity index 91% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java index 5d2f70e8..a3c947fc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java @@ -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 diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AwkwardSpell.java similarity index 71% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AwkwardSpell.java index 8741cb1a..802efe76 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AwkwardSpell.java @@ -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 -> { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireSpell.java similarity index 92% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireSpell.java index ff1fc34d..35fe7c91 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireSpell.java @@ -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); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/IceSpell.java similarity index 86% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/IceSpell.java index ba665d10..2e3385a4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/IceSpell.java @@ -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) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java similarity index 85% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java index 857bc824..5eca5cc6 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java @@ -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); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java similarity index 91% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java index e5a74b99..b40f56d3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/NecromancySpell.java @@ -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> spawnPool = new Weighted>() .put(7, EntityType.ZOMBIE) @@ -31,14 +33,12 @@ public class NecromancySpell extends AbstractPlacedSpell { private final List> 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()) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/RevealingSpell.java similarity index 68% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/RevealingSpell.java index cce2ca37..b6c3fff3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/RevealingSpell.java @@ -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()); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ScorchSpell.java similarity index 81% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ScorchSpell.java index facf318e..33f2d40f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ScorchSpell.java @@ -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)) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java similarity index 91% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java index 54631731..abe22e6e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java @@ -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 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; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java similarity index 92% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java index acb41241..e8d75945 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java @@ -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--; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java similarity index 83% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java index f43107e0..d97f44e8 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java @@ -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 implements Affine, SpellPredicate { 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> REGISTRY = Registries.createSimple(new Identifier("unicopia", "spells")); private static final Map>> BY_AFFINITY = new EnumMap<>(Affinity.class); + public static final SpellType COMPOUND_SPELL = register("compound", Affinity.NEUTRAL, 0, false, CompoundSpell::new); + public static final SpellType PLACED_SPELL = register("placed", Affinity.NEUTRAL, 0, false, PlaceableSpell::new); + + public static final SpellType DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new); + public static final SpellType RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new); + public static final SpellType FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new); public static final SpellType SCORCH = register("scorch", Affinity.BAD, 0, true, ScorchSpell::new); public static final SpellType FLAME = register("flame", Affinity.GOOD, 0xFF5D00, true, FireSpell::new); @@ -40,9 +52,7 @@ public final class SpellType implements Affine, SpellPredicate< public static final SpellType NECROMANCY = register("necromancy", Affinity.BAD, 0x8A3A3A, true, NecromancySpell::new); public static final SpellType SIPHONING = register("siphoning", Affinity.GOOD, 0xe308ab, true, SiphoningSpell::new); public static final SpellType DRAINING = register("draining", Affinity.BAD, 0xe308ab, true, SiphoningSpell::new); - public static final SpellType DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new); public static final SpellType REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new); - public static final SpellType JOUSTING = register("joust", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new); public static final SpellType AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new); public static final SpellType TRANSFORMATION = register("transformation", Affinity.NEUTRAL, 0x3A59AA, true, TransformationSpell::new); @@ -53,9 +63,6 @@ public final class SpellType implements Affine, SpellPredicate< private final Factory factory; - private final boolean thrown; - private final boolean attached; - @Nullable private String translationKey; @@ -65,24 +72,12 @@ public final class SpellType 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 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 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 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 implements Affine, SpellPredicate< } public interface Factory { - T create(SpellType type); + T create(SpellType type, SpellTraits traits); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java similarity index 80% rename from src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java rename to src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java index aa83e939..446f0abc 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java @@ -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 diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java new file mode 100644 index 00000000..3c7408c4 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java @@ -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 traits; + + SpellTraits(Map traits) { + this.traits = traits; + } + + public boolean isEmpty() { + return traits.isEmpty(); + } + + public Set> 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 of(Collection 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 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 readNbt(NbtCompound traits) { + return fromEntries(streamFromNbt(traits)); + } + + public static Stream> 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 fromEntries(Stream> entries) { + var result = collect(entries); + + if (result.isEmpty()) { + return Optional.empty(); + } + return Optional.of(new SpellTraits(result)); + } + + static Map collect(Stream> entries) { + return entries.filter(Objects::nonNull) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a + b, () -> new EnumMap<>(Trait.class))); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java new file mode 100644 index 00000000..5f46354b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java @@ -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 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; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitGroup.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitGroup.java new file mode 100644 index 00000000..79ac55ff --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitGroup.java @@ -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; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitLoader.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitLoader.java new file mode 100644 index 00000000..d9cbda2b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitLoader.java @@ -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> implements IdentifiableResourceReloadListener { + private static final Identifier ID = new Identifier("unicopia", "data/traits"); + + private static final TypeToken> TYPE = new TypeToken<>() {}; + + public static final TraitLoader INSTANCE = new TraitLoader(); + + Map values = new HashMap<>(); + + @Override + public Identifier getFabricId() { + return ID; + } + + @Override + protected Map prepare(ResourceManager manager, Profiler profiler) { + profiler.startTick(); + + Map 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 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 prepared, ResourceManager manager, Profiler profiler) { + values = prepared; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java index 33a25915..8682d8fe 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java index 632c565a..bee52af5 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java b/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java index 844650b8..0cbec6aa 100644 --- a/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java +++ b/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java @@ -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) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java index e141a2b8..63e43759 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/CastSpellEntity.java @@ -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 { private static final TrackedData> SPELL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID); - private static final SpellPredicate SPELL_TYPE = s -> s instanceof AbstractPlacedSpell; - private static final LevelStore LEVELS = Levelled.fixed(0); private final EntityPhysics physics = new EntityPhysics<>(this, GRAVITY); @@ -96,7 +93,7 @@ public class CastSpellEntity extends Entity implements Caster { 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; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java index 7995e5f1..330d6f04 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index ed1ec8d3..70b817e1 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -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 implements Equine, 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); } }); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/UTradeOffers.java b/src/main/java/com/minelittlepony/unicopia/entity/UTradeOffers.java index ad3bf08a..fd614461 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/UTradeOffers.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/UTradeOffers.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java index e9738a87..270a4312 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/AxolotlBehaviour.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java index f52eaa84..13666eea 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java index c0a1770d..233e572e 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 748cc791..d168d525 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -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 implements Tickab @Override public boolean isRainbooming() { - return pony.getSpellSlot().get(SpellType.JOUSTING, true).isPresent(); + return pony.getSpellSlot().get(SpellType.RAINBOOM, true).isPresent(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index 88141e2e..f5e4a29d 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java index d6860dc4..1d710569 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java @@ -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> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType exclude, Predicate> test) { + public static TypedActionResult> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType exclude, @Nullable Predicate> 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); } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index 858bd485..54d72ebc 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java index b0a32c98..9b77c98b 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinTargetPredicate.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java b/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java index 3a377a87..f91fec06 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java +++ b/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java b/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java index 151ee4c2..d5d16871 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java @@ -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; diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java index 40b4dd84..2790b67d 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java @@ -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

  • spell.onThrownTick(this)).isPresent()) { + if (!getSpellSlot().get(true).filter(spell -> spell.tick(this, Situation.PROJECTILE)).isPresent()) { discard(); } }