Refine the attraction spell to give it more uses

This commit is contained in:
Sollace 2022-09-10 14:56:59 +02:00
parent aba1337774
commit f10e5965bd
6 changed files with 154 additions and 24 deletions

View file

@ -108,7 +108,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
} else { } else {
player.setAnimation(Animation.ARMS_UP); player.setAnimation(Animation.ARMS_UP);
if (s instanceof HomingSpell) { 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); player.playSound(USounds.SPELL_CAST_SUCCESS, 0.05F, 2.2F);
} }

View file

@ -1,23 +1,53 @@
package com.minelittlepony.unicopia.ability.magic.spell.effect; package com.minelittlepony.unicopia.ability.magic.spell.effect;
import com.minelittlepony.unicopia.ability.magic.Caster; 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.SpellTraits;
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; 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.FollowingParticleEffect;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.particle.UParticles;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity; import net.minecraft.entity.ItemEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class AttractiveSpell extends ShieldSpell implements ProjectileSpell { public class AttractiveSpell extends ShieldSpell implements ProjectileSpell, HomingSpell {
private final EntityReference<Entity> target = new EntityReference<>();
private int age;
private int duration;
protected AttractiveSpell(SpellType<?> type, SpellTraits traits) { protected AttractiveSpell(SpellType<?> type, SpellTraits traits) {
super(type, 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 @Override
@ -41,7 +71,10 @@ public class AttractiveSpell extends ShieldSpell implements ProjectileSpell {
@Override @Override
protected boolean isValidTarget(Caster<?> source, Entity entity) { 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 @Override
@ -72,7 +105,59 @@ public class AttractiveSpell extends ShieldSpell implements ProjectileSpell {
if (distance < 0.5) { if (distance < 0.5) {
z += maxVel * 2; 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); 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");
}
} }

View file

@ -1,7 +1,5 @@
package com.minelittlepony.unicopia.ability.magic.spell.effect; package com.minelittlepony.unicopia.ability.magic.spell.effect;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell; 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.Situation;
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
import com.minelittlepony.unicopia.entity.EntityReference;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, HomingSpell { public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, HomingSpell {
@ -28,8 +28,7 @@ public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, Hom
.with(Trait.FIRE, 60) .with(Trait.FIRE, 60)
.build(); .build();
@Nullable private final EntityReference<Entity> target = new EntityReference<>();
private Entity target;
protected FireBoltSpell(SpellType<?> type, SpellTraits traits) { protected FireBoltSpell(SpellType<?> type, SpellTraits traits) {
super(type, traits); super(type, traits);
@ -55,16 +54,16 @@ public class FireBoltSpell extends AbstractSpell implements ProjectileSpell, Hom
return true; return true;
} }
if (getTraits().get(Trait.FOCUS) >= 50 && target == null) { if (getTraits().get(Trait.FOCUS) >= 50 && !target.isPresent(caster.getReferenceWorld())) {
target = caster.findAllEntitiesInRange( target.set(caster.findAllEntitiesInRange(
getTraits().get(Trait.FOCUS) - 49, getTraits().get(Trait.FOCUS) - 49,
EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.notOwnerOrFriend(this, caster)) EntityPredicates.VALID_LIVING_ENTITY.and(TargetSelecter.notOwnerOrFriend(this, caster))
).findFirst().orElse(null); ).findFirst().orElse(null));
} }
for (int i = 0; i < getNumberOfBalls(caster); i++) { for (int i = 0; i < getNumberOfBalls(caster); i++) {
getType().create(getTraits()).toThrowable().throwProjectile(caster, 2).ifPresent(c -> { 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)); 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 @Override
public boolean setTarget(Entity target) { public boolean setTarget(Entity target) {
if (getTraits().get(Trait.FOCUS) >= 50) { if (getTraits().get(Trait.FOCUS) >= 50) {
this.target = target; this.target.set(target);
return true; return true;
} }
return false; 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"));
}
} }

View file

@ -153,7 +153,6 @@ public class SiphoningSpell extends AbstractAreaEffectSpell {
owner.heal(healthGain); owner.heal(healthGain);
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound) {
super.toNBT(compound); super.toNBT(compound);

View file

@ -62,11 +62,45 @@
{ "recipe": "unicopia:spells/vortex" }, { "recipe": "unicopia:spells/vortex" },
"Requires:", "Requires:",
"- 1 protection gem\n- At least 10x strength trait\n- At least 8x knowledge trait\n- At least 9x air trait", "- 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, "level": 11,
"elements": [ "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.", "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, "level": 11,
"elements": [ "elements": [
"I've put the... thing. In the basement. Locked the door.", "I've put the... thing. In the basement. Locked the door.",
@ -87,19 +121,19 @@
}, },
{ {
"title": "", "title": "",
"level": 0, "level": -1,
"elements": [] "elements": []
}, },
{ {
"title": "", "title": "",
"level": 0, "level": -1,
"elements": [] "elements": []
}, },
{ {
"title": "15th Slep '12", "title": "25th Slep '12",
"level": 13, "level": 13,
"elements": [ "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.", "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", "text": "Its body is black and vaguely",
@ -141,7 +175,7 @@
}, },
{ {
"title": "Dispell Illusion", "title": "Dispell Illusion",
"level": 14, "level": 15,
"elements": [ "elements": [
"Dispell Illusion is the first line of defense against transformation/illusion spells.", "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.", "When cast it will force any nearby disguised changelings in its range to reveal their true form.",
@ -151,7 +185,7 @@
}, },
{ {
"title": "", "title": "",
"level": 14, "level": 15,
"elements": [ "elements": [
{ "recipe": "unicopia:spells/reveal" }, { "recipe": "unicopia:spells/reveal" },
"Requires:", "Requires:",

View file

@ -220,7 +220,8 @@
"elements": [ "elements": [
{ "recipe": "unicopia:spells/shield" }, { "recipe": "unicopia:spells/shield" },
"Requires:", "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"
] ]
}, },
{ {