From 00758b0c15324978b7abfb0aa075b50b45fa5123 Mon Sep 17 00:00:00 2001
From: Sollace <sollacea@gmail.com>
Date: Mon, 27 Dec 2021 14:08:21 +0200
Subject: [PATCH] Added a light spell

---
 .../magic/spell/effect/LightSpell.java        | 96 +++++++++++++++++++
 .../ability/magic/spell/effect/SpellType.java |  1 +
 .../resources/assets/unicopia/lang/en_us.json |  4 +-
 3 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java

diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java
new file mode 100644
index 00000000..5ee80336
--- /dev/null
+++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/LightSpell.java
@@ -0,0 +1,96 @@
+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.ability.magic.spell.trait.Trait;
+import com.minelittlepony.unicopia.entity.EntityReference;
+import com.minelittlepony.unicopia.entity.FairyEntity;
+import com.minelittlepony.unicopia.entity.UEntities;
+import com.minelittlepony.unicopia.util.VecHelper;
+
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtElement;
+import net.minecraft.nbt.NbtList;
+
+public class LightSpell extends AbstractSpell {
+    public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder()
+            .with(Trait.LIFE, 10)
+            .with(Trait.AIR, 0.3F)
+            .with(Trait.KINDNESS, 12)
+            .with(Trait.ORDER, 25)
+            .build();
+
+    private int duration;
+
+    private List<EntityReference<FairyEntity>> lights;
+
+    protected LightSpell(SpellType<?> type, SpellTraits traits) {
+        super(type, traits);
+        duration = (int)(traits.get(Trait.FOCUS, 0, 160) * 19);
+    }
+
+    @Override
+    public boolean tick(Caster<?> caster, Situation situation) {
+
+        if (duration-- <= 0) {
+            return false;
+        }
+
+        if (lights == null) {
+            int size = 2 + caster.getWorld().random.nextInt(2) + (int)(getTraits().get(Trait.LIFE, 10, 20) - 10)/10;
+            lights = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                lights.set(i, new EntityReference<FairyEntity>());
+            }
+        }
+
+        if (!caster.isClient()) {
+            lights.forEach(ref -> {
+                if (!ref.isPresent(caster.getWorld())) {
+                    FairyEntity entity = UEntities.TWITTERMITE.create(caster.getWorld());
+                    entity.setPosition(ref.getPosition().orElseGet(() -> {
+                        return caster.getMaster().getPos().add(VecHelper.supply(() -> caster.getWorld().random.nextInt(2) - 1));
+                    }));
+                    entity.setMaster(caster.getMaster());
+                    entity.world.spawnEntity(entity);
+
+                    ref.set(entity);
+                    setDirty();
+                }
+            });
+        }
+
+        return true;
+    }
+
+    @Override
+    public void toNBT(NbtCompound compound) {
+        super.toNBT(compound);
+        if (lights != null) {
+            NbtList list = new NbtList();
+            lights.forEach(light -> {
+                list.add(light.toNBT());
+            });
+            compound.put("lights", list);
+        }
+    }
+
+    @Override
+    public void fromNBT(NbtCompound compound) {
+        super.fromNBT(compound);
+        if (compound.contains("lights", NbtElement.LIST_TYPE)) {
+            lights = new ArrayList<>();
+            compound.getList("lights", NbtElement.COMPOUND_TYPE).forEach(nbt -> {
+                EntityReference<FairyEntity> light = new EntityReference<>();
+                light.fromNBT((NbtCompound)nbt);
+                lights.add(light);
+            });
+        } else {
+            lights = null;
+        }
+    }
+}
diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java
index a0257c4f..fa1c4120 100644
--- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java
+++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java
@@ -61,6 +61,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
     public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", Affinity.GOOD, 0x00EEFF, true, FeatherFallSpell.DEFAULT_TRAITS, FeatherFallSpell::new);
     public static final SpellType<CatapultSpell> CATAPULT = register("catapult", Affinity.GOOD, 0x33FF00, true, CatapultSpell.DEFAULT_TRAITS, CatapultSpell::new);
     public static final SpellType<FireBoltSpell> FIRE_BOLT = register("fire_bolt", Affinity.GOOD, 0x888800, true, FireBoltSpell.DEFAULT_TRAITS, FireBoltSpell::new);
+    public static final SpellType<LightSpell> LIGHT = register("light", Affinity.GOOD, 0x00AA88, true, LightSpell.DEFAULT_TRAITS, LightSpell::new);
 
     private final Identifier id;
     private final Affinity affinity;
diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json
index cf781f38..5d0ead54 100644
--- a/src/main/resources/assets/unicopia/lang/en_us.json
+++ b/src/main/resources/assets/unicopia/lang/en_us.json
@@ -149,9 +149,11 @@
   "spell.unicopia.necromancy": "Necromancy",
   "spell.unicopia.necromancy.lore": "Summons undead minions from beyond the grave",
   "spell.unicopia.siphoning": "Life Sapping",
-  "spell.unicopia.siphoning.lore": "Channels other creature's life force into the user",
+  "spell.unicopia.siphoning.lore": "Channels other creature's life force into the caster",
   "spell.unicopia.reveal": "Dispell Illusion",
   "spell.unicopia.reveal.lore": "Negates shapeshifting magic",
+  "spell.unicopia.light": "Dancing Light",
+  "spell.unicopia.light.lore": "Summons multiple small lights to follow the caster",
   "spell.unicopia.awkward": "Botched",
   "spell.unicopia.awkward.lore": "Unstable magics",
   "spell.unicopia.transformation": "Transmutation",