From f10e5965bd3b7e2c1beff8491e835c5927e080c4 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 10 Sep 2022 14:56:59 +0200 Subject: [PATCH] Refine the attraction spell to give it more uses --- .../ability/UnicornCastingAbility.java | 2 +- .../magic/spell/effect/AttractiveSpell.java | 91 ++++++++++++++++++- .../magic/spell/effect/FireBoltSpell.java | 29 ++++-- .../magic/spell/effect/SiphoningSpell.java | 1 - .../spellbook/chapters/dark_magic.json | 52 +++++++++-- .../spellbook/chapters/fire_magic.json | 3 +- 6 files changed, 154 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index 63c35ab6..861468c3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -108,7 +108,7 @@ public class UnicornCastingAbility implements Ability { } else { player.setAnimation(Animation.ARMS_UP); if (s instanceof HomingSpell) { - RayTraceHelper.doTrace(player.getMaster(), 600, 1, EntityPredicates.CAN_COLLIDE).getEntity().ifPresent(((HomingSpell)s)::setTarget); + RayTraceHelper.doTrace(player.getMaster(), 600, 1, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(EntityPredicates.VALID_ENTITY)).getEntity().ifPresent(((HomingSpell)s)::setTarget); } player.playSound(USounds.SPELL_CAST_SUCCESS, 0.05F, 2.2F); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java index 86bc1edc..848a990e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AttractiveSpell.java @@ -1,23 +1,53 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell; +import com.minelittlepony.unicopia.ability.magic.spell.*; 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.particle.FollowingParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.UParticles; +import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.shape.Sphere; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; +import net.minecraft.nbt.NbtCompound; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -public class AttractiveSpell extends ShieldSpell implements ProjectileSpell { +public class AttractiveSpell extends ShieldSpell implements ProjectileSpell, HomingSpell { + + private final EntityReference target = new EntityReference<>(); + + private int age; + private int duration; + protected AttractiveSpell(SpellType type, SpellTraits traits) { super(type, traits); + duration = 120 + (int)(traits.get(Trait.FOCUS, 0, 160) * 19); + } + + @Override + public boolean tick(Caster caster, Situation situation) { + age++; + + if (age % 20 == 0) { + duration--; + } + + if (duration <= 0) { + return false; + } + + Vec3d pos = caster.getOriginVector(); + if (target.isPresent(caster.getReferenceWorld()) && target.get(caster.getReferenceWorld()).distanceTo(caster.getEntity()) > getDrawDropOffRange(caster)) { + target.get(caster.getReferenceWorld()).requestTeleport(pos.x, pos.y, pos.z); + } + + return super.tick(caster, situation); } @Override @@ -41,7 +71,10 @@ public class AttractiveSpell extends ShieldSpell implements ProjectileSpell { @Override protected boolean isValidTarget(Caster source, Entity entity) { - return getTraits().get(Trait.FOCUS) > 10 ? entity instanceof ItemEntity : super.isValidTarget(source, entity); + if (target.isPresent(entity.world)) { + return target.get(entity.world) == entity; + } + return getTraits().get(Trait.KNOWLEDGE) > 10 ? entity instanceof ItemEntity : super.isValidTarget(source, entity); } @Override @@ -72,7 +105,59 @@ public class AttractiveSpell extends ShieldSpell implements ProjectileSpell { if (distance < 0.5) { z += maxVel * 2; } + if (distance < 2) { + x = 0; + z = 0; + } + if (this.target.get(target.world) == target) { + target.fallDistance = 0; + + if (target.isOnGround()) { + target.setPosition(target.getPos().add(0, 0.3, 0)); + target.setOnGround(false); + } + } target.setVelocity(x, y, z); } + + @Override + public boolean setTarget(Entity target) { + if (getTraits().get(Trait.ORDER) >= 20) { + this.target.set(target); + target.setGlowing(true); + this.onDestroyed(null); + return true; + } + return false; + } + + @Override + public void onDestroyed(Caster caster) { + target.getOrEmpty(caster.getReferenceWorld()).ifPresent(target -> target.setGlowing(false)); + } + + @Override + public void onImpact(MagicProjectileEntity projectile, Entity entity) { + if (!isDead() && getTraits().get(Trait.GENEROSITY) > 0) { + setDead(); + Caster.of(entity).ifPresent(getType().create(getTraits())::apply); + } + } + + @Override + public void toNBT(NbtCompound compound) { + super.toNBT(compound); + compound.put("target", target.toNBT()); + compound.putInt("age", age); + compound.putInt("duration", duration); + } + + @Override + public void fromNBT(NbtCompound compound) { + super.fromNBT(compound); + target.fromNBT(compound.getCompound("target")); + age = compound.getInt("age"); + duration = compound.getInt("duration"); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireBoltSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireBoltSpell.java index e9675cf6..53c0a4b2 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireBoltSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/FireBoltSpell.java @@ -1,7 +1,5 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; -import org.jetbrains.annotations.Nullable; - import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell; @@ -9,9 +7,11 @@ import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell; 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.projectile.MagicProjectileEntity; import net.minecraft.entity.Entity; import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; import net.minecraft.predicate.entity.EntityPredicates; public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, HomingSpell { @@ -28,8 +28,7 @@ public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, Hom .with(Trait.FIRE, 60) .build(); - @Nullable - private Entity target; + private final EntityReference target = new EntityReference<>(); protected FireBoltSpell(SpellType type, SpellTraits traits) { super(type, traits); @@ -55,16 +54,16 @@ public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, Hom return true; } - if (getTraits().get(Trait.FOCUS) >= 50 && target == null) { - target = caster.findAllEntitiesInRange( + if (getTraits().get(Trait.FOCUS) >= 50 && !target.isPresent(caster.getReferenceWorld())) { + target.set(caster.findAllEntitiesInRange( getTraits().get(Trait.FOCUS) - 49, EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.notOwnerOrFriend(this, caster)) - ).findFirst().orElse(null); + ).findFirst().orElse(null)); } for (int i = 0; i < getNumberOfBalls(caster); i++) { getType().create(getTraits()).toThrowable().throwProjectile(caster, 2).ifPresent(c -> { - c.setHomingTarget(target); + target.ifPresent(caster.getReferenceWorld(), c::setHomingTarget); }); caster.playSound(USounds.SPELL_FIRE_BOLT_SHOOT, 0.7F, 0.4F / (caster.getReferenceWorld().random.nextFloat() * 0.4F + 0.8F)); @@ -87,9 +86,21 @@ public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, Hom @Override public boolean setTarget(Entity target) { if (getTraits().get(Trait.FOCUS) >= 50) { - this.target = target; + this.target.set(target); return true; } return false; } + + @Override + public void toNBT(NbtCompound compound) { + super.toNBT(compound); + compound.put("target", target.toNBT()); + } + + @Override + public void fromNBT(NbtCompound compound) { + super.fromNBT(compound); + target.fromNBT(compound.getCompound("target")); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java index 5bc2dd0b..21aa2e8f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SiphoningSpell.java @@ -153,7 +153,6 @@ public class SiphoningSpell extends AbstractAreaEffectSpell { owner.heal(healthGain); } - @Override public void toNBT(NbtCompound compound) { super.toNBT(compound); diff --git a/src/main/resources/assets/unicopia/spellbook/chapters/dark_magic.json b/src/main/resources/assets/unicopia/spellbook/chapters/dark_magic.json index 09c64e3a..b07809db 100644 --- a/src/main/resources/assets/unicopia/spellbook/chapters/dark_magic.json +++ b/src/main/resources/assets/unicopia/spellbook/chapters/dark_magic.json @@ -62,11 +62,45 @@ { "recipe": "unicopia:spells/vortex" }, "Requires:", "- 1 protection gem\n- At least 10x strength trait\n- At least 8x knowledge trait\n- At least 9x air trait", - "+ 10x focus to narrow the effect's range to items specifically" + "+ 10x knowledge to narrow the effect's range to items\n+ Add focus trait to increase duration\n+ add power trait to increase range" ] }, { - "title": "10th Slep '12", + "title": "8th Slep '12", + "level": 6, + "elements": [ + "Additional Notes for the Attraction Spell", + "I caught Luna playing with my spellcrafting grid today, even though I expressly forbid her from entering my study when I'm not there.", + "Apparently it was over some dispute with Celly, I don't really remember, but it culminated in Luna sneaking into the study whilst I was out to get some bread." + ] + }, + { + "title": "Arcane Attraction II", + "level": 6, + "elements": [ + "This isn't really about that, though. She's been scolded and sent back to her room, however as I was cleaning up the mess she'd made I noticed something in the piles of gems.", + "It's hard to describe, really. This is still distincly an attraction gem, but it's different.", + "It has traits I hadn't considered before, and the way it behaves... " + ] + }, + { + "title": "Arcane Attraction II Cont.", + "level": 6, + "elements": [ + "Well I'll leave that up to tomorrow. I'm still tired from everything that's happened this week.", + "- Starswirl the Bearded" + ] + }, + { + "title": "", + "level": 6, + "elements": [ + ">0 generosity --> ??", + ">20 order trait --> ???" + ] + }, + { + "title": "20th Slep '12", "level": 11, "elements": [ "As per their agreement, the council have sent certain...supplimental materials to aid in the new direction my research is taking. I was a little shocked at first.", @@ -76,7 +110,7 @@ ] }, { - "title": "11th Slep '12", + "title": "21st Slep '12", "level": 11, "elements": [ "I've put the... thing. In the basement. Locked the door.", @@ -87,19 +121,19 @@ }, { "title": "", - "level": 0, + "level": -1, "elements": [] }, { "title": "", - "level": 0, + "level": -1, "elements": [] }, { - "title": "15th Slep '12", + "title": "25th Slep '12", "level": 13, "elements": [ - "I'm sorry for the long delays. Things have been...", + "I'm sorry for the long delays. Things have been... Busy.", "I've learned a lot about these creatures. Attached are some illustrations, done best I could so I wouldn't have to look at the thing directly.", { "text": "Its body is black and vaguely", @@ -141,7 +175,7 @@ }, { "title": "Dispell Illusion", - "level": 14, + "level": 15, "elements": [ "Dispell Illusion is the first line of defense against transformation/illusion spells.", "When cast it will force any nearby disguised changelings in its range to reveal their true form.", @@ -151,7 +185,7 @@ }, { "title": "", - "level": 14, + "level": 15, "elements": [ { "recipe": "unicopia:spells/reveal" }, "Requires:", diff --git a/src/main/resources/assets/unicopia/spellbook/chapters/fire_magic.json b/src/main/resources/assets/unicopia/spellbook/chapters/fire_magic.json index d7e955e5..4661d40d 100644 --- a/src/main/resources/assets/unicopia/spellbook/chapters/fire_magic.json +++ b/src/main/resources/assets/unicopia/spellbook/chapters/fire_magic.json @@ -220,7 +220,8 @@ "elements": [ { "recipe": "unicopia:spells/shield" }, "Requires:", - "- 1 gemstone\n- At least 10x strength trait\n- At least 6x focus trait\n- At least 10x power trait" + "- 1 gemstone\n- At least 10x strength trait\n- At least 6x focus trait\n- At least 10x power trait", + "\n+ add power trait to increase effect range" ] }, {