v3.0.0: fixed all Cleric spells using projectile autotarget logic

This commit is contained in:
Evan Debenham
2025-01-02 14:12:06 -05:00
parent b3657f11a0
commit 2ba4495512
12 changed files with 60 additions and 13 deletions
@@ -49,8 +49,8 @@ public class BlessSpell extends TargetedClericSpell {
} }
@Override @Override
public boolean usesTargeting() { public int targetingFlags(){
return false; //targeting behaviour is often wrong return -1; //auto-targeting behaviour is often wrong, so we don't use it
} }
@Override @Override
@@ -63,6 +63,10 @@ public abstract class ClericSpell {
return false; return false;
} }
public int targetingFlags(){
return -1; //-1 for no targeting
}
public int icon(){ public int icon(){
return HeroIcon.NONE; return HeroIcon.NONE;
} }
@@ -54,6 +54,11 @@ public class Flash extends TargetedClericSpell {
return super.canCast(hero) && hero.buff(AscendedForm.AscendBuff.class) != null; return super.canCast(hero) && hero.buff(AscendedForm.AscendBuff.class) != null;
} }
@Override
public int targetingFlags() {
return -1; //targets an empty cell, not an enemy
}
@Override @Override
protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) { protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) {
@@ -58,7 +58,7 @@ public class GuidingLight extends TargetedClericSpell {
return; return;
} }
Ballistica aim = new Ballistica(hero.pos, target, Ballistica.MAGIC_BOLT); Ballistica aim = new Ballistica(hero.pos, target, targetingFlags());
if (Actor.findChar( aim.collisionPos ) == hero){ if (Actor.findChar( aim.collisionPos ) == hero){
GLog.i( Messages.get(Wand.class, "self_target") ); GLog.i( Messages.get(Wand.class, "self_target") );
@@ -43,6 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShaftParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
@@ -67,6 +68,11 @@ public class HallowedGround extends TargetedClericSpell {
return 2; return 2;
} }
@Override
public int targetingFlags() {
return Ballistica.STOP_TARGET;
}
@Override @Override
protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) { protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) {
@@ -73,13 +73,18 @@ public class HolyLance extends TargetedClericSpell {
return 4; return 4;
} }
@Override
public int targetingFlags() {
return Ballistica.PROJECTILE;
}
@Override @Override
protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) { protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) {
if (target == null){ if (target == null){
return; return;
} }
Ballistica aim = new Ballistica(hero.pos, target, Ballistica.PROJECTILE); Ballistica aim = new Ballistica(hero.pos, target, targetingFlags());
if (Actor.findChar( aim.collisionPos ) == hero){ if (Actor.findChar( aim.collisionPos ) == hero){
GLog.i( Messages.get(Wand.class, "self_target") ); GLog.i( Messages.get(Wand.class, "self_target") );
@@ -52,6 +52,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfAquaticRejuvenation; import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfAquaticRejuvenation;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfChallenge; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfChallenge;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Kinetic; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Kinetic;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.Sungrass; import com.shatteredpixel.shatteredpixeldungeon.plants.Sungrass;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
@@ -68,6 +69,11 @@ public class MnemonicPrayer extends TargetedClericSpell {
return HeroIcon.MNEMONIC_PRAYER; return HeroIcon.MNEMONIC_PRAYER;
} }
@Override
public int targetingFlags() {
return Ballistica.STOP_TARGET;
}
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) { protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) {
@@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
@@ -47,6 +48,11 @@ public class ShieldOfLight extends TargetedClericSpell {
return HeroIcon.SHIELD_OF_LIGHT; return HeroIcon.SHIELD_OF_LIGHT;
} }
@Override
public int targetingFlags() {
return Ballistica.STOP_TARGET;
}
@Override @Override
protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) { protected void onTargetSelected(HolyTome tome, Hero hero, Integer target) {
@@ -65,7 +65,7 @@ public class Sunray extends TargetedClericSpell {
return; return;
} }
Ballistica aim = new Ballistica(hero.pos, target, Ballistica.MAGIC_BOLT); Ballistica aim = new Ballistica(hero.pos, target, targetingFlags());
if (Actor.findChar( aim.collisionPos ) == hero){ if (Actor.findChar( aim.collisionPos ) == hero){
GLog.i( Messages.get(Wand.class, "self_target") ); GLog.i( Messages.get(Wand.class, "self_target") );
@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@@ -45,8 +46,8 @@ public abstract class TargetedClericSpell extends ClericSpell {
} }
@Override @Override
public boolean usesTargeting() { public int targetingFlags(){
return true; return Ballistica.MAGIC_BOLT;
} }
protected String targetingPrompt(){ protected String targetingPrompt(){
@@ -32,6 +32,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag; import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog; import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
@@ -95,6 +96,18 @@ public class HolyTome extends Artifact {
} }
} }
//used to ensure tome has variable targeting logic for whatever spell is being case
public ClericSpell targetingSpell = null;
@Override
public int targetingPos(Hero user, int dst) {
if (targetingSpell == null || targetingSpell.targetingFlags() == -1) {
return super.targetingPos(user, dst);
} else {
return new Ballistica( user.pos, dst, targetingSpell.targetingFlags() ).collisionPos;
}
}
@Override @Override
public boolean doUnequip(Hero hero, boolean collect, boolean single) { public boolean doUnequip(Hero hero, boolean collect, boolean single) {
if (super.doUnequip(hero, collect, single)){ if (super.doUnequip(hero, collect, single)){
@@ -328,9 +341,9 @@ public class HolyTome extends Artifact {
return; return;
} }
//TODO this is all pretty akward, might be better to just add autotarget functionality to the indicator
if (QuickSlotButton.targetingSlot != -1 && if (QuickSlotButton.targetingSlot != -1 &&
Dungeon.quickslot.getItem(QuickSlotButton.targetingSlot) == HolyTome.this) { Dungeon.quickslot.getItem(QuickSlotButton.targetingSlot) == HolyTome.this) {
targetingSpell = quickSpell;
int cell = QuickSlotButton.autoAim(QuickSlotButton.lastTarget, HolyTome.this); int cell = QuickSlotButton.autoAim(QuickSlotButton.lastTarget, HolyTome.this);
if (cell != -1){ if (cell != -1){
@@ -342,7 +355,8 @@ public class HolyTome extends Artifact {
} else { } else {
quickSpell.onCast(HolyTome.this, Dungeon.hero); quickSpell.onCast(HolyTome.this, Dungeon.hero);
if (quickSpell.usesTargeting() && Dungeon.quickslot.contains(HolyTome.this)){ if (quickSpell.targetingFlags() != -1 && Dungeon.quickslot.contains(HolyTome.this)){
targetingSpell = quickSpell;
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(HolyTome.this)); QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(HolyTome.this));
} }
} }
@@ -178,8 +178,8 @@ public class WndClericSpells extends Window {
} else { } else {
spell.onCast(tome, Dungeon.hero); spell.onCast(tome, Dungeon.hero);
//TODO, probably need targeting logic here if (spell.targetingFlags() != -1 && Dungeon.quickslot.contains(tome)){
if (spell.usesTargeting() && Dungeon.quickslot.contains(tome)){ tome.targetingSpell = spell;
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome)); QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome));
} }
} }
@@ -215,8 +215,8 @@ public class WndClericSpells extends Window {
} else { } else {
spell.onCast(tome, Dungeon.hero); spell.onCast(tome, Dungeon.hero);
//TODO, probably need targeting logic here if (spell.targetingFlags() != -1 && Dungeon.quickslot.contains(tome)){
if (spell.usesTargeting() && Dungeon.quickslot.contains(tome)){ tome.targetingSpell = spell;
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome)); QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome));
} }
} }