[LTC] Implement Gandalf, Westward Voyager (#10727)

* refactor and cleanup SpellCastControllerTriggeredAbility

* [LTC] Implement Gandalf, Westward Voyager

* throw on unexpected setTargetPointer
This commit is contained in:
Susucre 2023-08-05 04:26:25 +02:00 committed by GitHub
parent 4ac9293821
commit 0e5069ccc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
82 changed files with 567 additions and 361 deletions

View file

@ -2,6 +2,7 @@ package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.SetTargetPointer;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
@ -11,61 +12,62 @@ import mage.game.stack.Spell;
import mage.target.targetpointer.FixedTarget;
/**
* @author North
* @author North, Susucr
*/
public class SpellCastControllerTriggeredAbility extends TriggeredAbilityImpl {
protected final FilterSpell filter;
protected String rule; // TODO: This sould be final, but is not because of the telescoping contructors
protected final String rule;
// If either the cast spell or the card must be set as TargetPointer of effects.
protected final SetTargetPointer setTargetPointer;
// The source SPELL that triggered the ability will be set as target to effect
protected boolean rememberSource;
// Use it if you want to remember CARD instead spell
protected boolean rememberSourceAsCard;
// Trigger only for spells cast from this zone. Default is from any zone.
private Zone fromZone = Zone.ALL;
private final Zone fromZone;
public SpellCastControllerTriggeredAbility(Effect effect, boolean optional) {
this(Zone.BATTLEFIELD, effect, StaticFilters.FILTER_SPELL_A, optional, false);
this(effect, null, optional);
}
public SpellCastControllerTriggeredAbility(Effect effect, FilterSpell filter, boolean optional) {
this(effect, filter, optional, false);
this(effect, filter, optional, SetTargetPointer.NONE);
}
public SpellCastControllerTriggeredAbility(Effect effect, FilterSpell filter, boolean optional, Zone fromZone) {
this(effect, filter, optional, false);
this.fromZone = fromZone;
makeTriggerPhrase();
public SpellCastControllerTriggeredAbility(Effect effect, FilterSpell filter,
boolean optional, SetTargetPointer setTargetPointer) {
this(Zone.BATTLEFIELD, effect, filter, optional, setTargetPointer);
}
public SpellCastControllerTriggeredAbility(Effect effect, FilterSpell filter, boolean optional, String rule) {
this(effect, filter, optional, false);
this.rule = rule;
public SpellCastControllerTriggeredAbility(Zone zone, Effect effect, FilterSpell filter,
boolean optional, SetTargetPointer setTargetPointer) {
this(zone, effect, filter, optional, setTargetPointer, null, null);
}
public SpellCastControllerTriggeredAbility(Effect effect, FilterSpell filter, boolean optional, boolean rememberSource) {
this(Zone.BATTLEFIELD, effect, filter, optional, rememberSource);
}
public SpellCastControllerTriggeredAbility(Zone zone, Effect effect, FilterSpell filter, boolean optional, boolean rememberSource) {
this(zone, effect, filter, optional, rememberSource, false);
}
public SpellCastControllerTriggeredAbility(Zone zone, Effect effect, FilterSpell filter, boolean optional, boolean rememberSource, boolean rememberSourceAsCard) {
public SpellCastControllerTriggeredAbility(Zone zone, Effect effect, FilterSpell filter,
boolean optional, SetTargetPointer setTargetPointer,
String rule, Zone fromZone) {
super(zone, effect, optional);
this.filter = filter;
this.rememberSource = rememberSource;
this.rememberSourceAsCard = rememberSourceAsCard;
this.filter = filter == null ? StaticFilters.FILTER_SPELL_A : filter;
this.setTargetPointer = setTargetPointer;
this.rule = rule;
this.fromZone = fromZone == null ? Zone.ALL : fromZone;
makeTriggerPhrase();
}
public static SpellCastControllerTriggeredAbility createWithFromZone(Effect effect, FilterSpell filter, boolean optional, Zone fromZone) {
return new SpellCastControllerTriggeredAbility(Zone.BATTLEFIELD, effect, filter, optional, null, null, fromZone);
}
public static SpellCastControllerTriggeredAbility createWithRule(Effect effect, FilterSpell filter, boolean optional, String rule) {
return new SpellCastControllerTriggeredAbility(Zone.BATTLEFIELD, effect, filter, optional, null, rule, null);
}
protected SpellCastControllerTriggeredAbility(final SpellCastControllerTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.rule = ability.rule;
this.rememberSource = ability.rememberSource;
this.rememberSourceAsCard = ability.rememberSourceAsCard;
this.setTargetPointer = ability.setTargetPointer;
this.fromZone = ability.fromZone;
}
@ -86,8 +88,17 @@ public class SpellCastControllerTriggeredAbility extends TriggeredAbilityImpl {
return false;
}
this.getEffects().setValue("spellCast", spell);
if (rememberSource) {
this.getEffects().setTargetPointer(new FixedTarget(rememberSourceAsCard ? spell.getCard().getId() : spell.getId(), game));
switch (setTargetPointer) {
case NONE:
break;
case SPELL:
getEffects().setTargetPointer(new FixedTarget(spell.getId(), game));
break;
case CARD:
getEffects().setTargetPointer(new FixedTarget(spell.getCard().getId()));
break;
default:
throw new UnsupportedOperationException("Unexpected setTargetPointer " + setTargetPointer);
}
return true;
}
@ -103,6 +114,19 @@ public class SpellCastControllerTriggeredAbility extends TriggeredAbilityImpl {
}
private void makeTriggerPhrase() {
setTriggerPhrase("Whenever you cast " + filter.getMessage() + (fromZone != Zone.ALL ? " from your " + fromZone.toString().toLowerCase() : "") + ", ");
String text = "Whenever you cast " + filter.getMessage();
switch (fromZone) {
case ALL:
break;
case EXILED:
text += " from exile";
break;
default:
text += " from your " + fromZone.toString().toLowerCase();
break;
}
setTriggerPhrase(text + ", ");
}
}