Support for Midnight Crusader Shuttle (#4478)

This commit is contained in:
tool4ever
2024-01-04 16:47:58 +01:00
committed by GitHub
parent 2933922572
commit 1e135e8d3b
19 changed files with 44 additions and 88 deletions

View File

@@ -344,12 +344,11 @@ public class ChangeZoneAi extends SpellAbilityAi {
Iterable<Player> pDefined = Lists.newArrayList(source.getController()); Iterable<Player> pDefined = Lists.newArrayList(source.getController());
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null && tgt.canTgtPlayer()) { if (tgt != null && tgt.canTgtPlayer()) {
sa.resetTargets();
boolean isCurse = sa.isCurse(); boolean isCurse = sa.isCurse();
if (isCurse && sa.canTarget(opponent)) { if (isCurse && sa.canTarget(opponent)) {
sa.resetTargets();
sa.getTargets().add(opponent); sa.getTargets().add(opponent);
} else if (!isCurse && sa.canTarget(ai)) { } else if (!isCurse && sa.canTarget(ai)) {
sa.resetTargets();
sa.getTargets().add(ai); sa.getTargets().add(ai);
} }
if (!sa.isTargetNumberValid()) { if (!sa.isTargetNumberValid()) {

View File

@@ -611,46 +611,41 @@ public abstract class SpellAbilityEffect {
} }
} }
protected static boolean addToCombat(Card c, Player controller, SpellAbility sa, String attackingParam, String blockingParam) { protected static boolean addToCombat(Card c, SpellAbility sa, String attackingParam, String blockingParam) {
final Card host = sa.getHostCard(); final Card host = sa.getHostCard();
final Game game = controller.getGame(); final Game game = host.getGame();
if (!c.isCreature() || !game.getPhaseHandler().inCombat()) { if (!c.isCreature() || !game.getPhaseHandler().inCombat()) {
return false; return false;
} }
boolean combatChanged = false; boolean combatChanged = false;
final Combat combat = game.getCombat(); final Combat combat = game.getCombat();
if (sa.hasParam(attackingParam) && combat.getAttackingPlayer().equals(controller)) { if (sa.hasParam(attackingParam) && combat.getAttackingPlayer().equals(c.getController())) {
String attacking = sa.getParam(attackingParam); String attacking = sa.getParam(attackingParam);
GameEntity defender = null; GameEntity defender = null;
FCollection<GameEntity> defs = null; FCollection<GameEntity> defs = null;
// important to update defenders here, maybe some PW got removed // important to update defenders here, maybe some PW got removed
combat.initConstraints(); combat.initConstraints();
if (sa.hasParam("ChoosePlayerOrPlaneswalker")) { if ("True".equalsIgnoreCase(attacking)) {
PlayerCollection defendingPlayers = AbilityUtils.getDefinedPlayers(sa.hasParam("ForEach") ? c : host, attacking, sa);
defs = new FCollection<>(defendingPlayers);
defs.addAll(Iterables.filter(combat.getDefendingPlaneswalkers(), CardPredicates.isControlledByAnyOf(defendingPlayers)));
} else if ("True".equalsIgnoreCase(attacking)) {
defs = (FCollection<GameEntity>) combat.getDefenders(); defs = (FCollection<GameEntity>) combat.getDefenders();
} else { } else {
defs = AbilityUtils.getDefinedEntities(host, attacking, sa); defs = AbilityUtils.getDefinedEntities(sa.hasParam("ForEach") ? c : host, attacking.split(","), sa);
} }
if (defs != null) { if (defs != null) {
Map<String, Object> params = Maps.newHashMap(); Map<String, Object> params = Maps.newHashMap();
params.put("Attacker", c); params.put("Attacker", c);
Player chooser; defender = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(defs, sa,
if (sa.hasParam("Chooser")) {
chooser = Iterables.getFirst(AbilityUtils.getDefinedPlayers(host, sa.getParam("Chooser"), sa), null);
} else {
chooser = controller;
}
defender = chooser.getController().chooseSingleEntityForEffect(defs, sa,
Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false, params); Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false, params);
} }
if (defender != null) { final GameEntity originalDefender = combat.getDefenderByAttacker(c);
if (defender != null &&
(originalDefender == null || !originalDefender.equals(defender))) {
// we might be reselecting
combat.removeFromCombat(c);
combat.addAttacker(c, defender); combat.addAttacker(c, defender);
combat.getBandOfAttacker(c).setBlocked(false); combat.getBandOfAttacker(c).setBlocked(false);
combatChanged = true; combatChanged = true;

View File

@@ -1,16 +1,10 @@
package forge.game.ability.effects; package forge.game.ability.effects;
import java.util.Map;
import com.google.common.collect.Maps;
import forge.game.Game; import forge.game.Game;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.ability.AbilityKey; import forge.game.ability.AbilityKey;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.combat.AttackingBand;
import forge.game.combat.Combat;
import forge.game.event.GameEventCombatChanged; import forge.game.event.GameEventCombatChanged;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
@@ -18,7 +12,6 @@ import forge.game.spellability.SpellAbilityStackInstance;
import forge.util.CardTranslation; import forge.util.CardTranslation;
import forge.util.Lang; import forge.util.Lang;
import forge.util.Localizer; import forge.util.Localizer;
import forge.util.collect.FCollection;
public class ChangeCombatantsEffect extends SpellAbilityEffect { public class ChangeCombatantsEffect extends SpellAbilityEffect {
@@ -36,33 +29,24 @@ public class ChangeCombatantsEffect extends SpellAbilityEffect {
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
boolean isCombatChanged = false; boolean isCombatChanged = false;
final boolean isOptional = sa.hasParam("Optional");
final Player activator = sa.getActivatingPlayer(); final Player activator = sa.getActivatingPlayer();
final Game game = activator.getGame(); final Game game = activator.getGame();
// TODO: may expand this effect for defined blocker (False Orders, General Jarkeld, Sorrow's Path, Ydwen Efreet) // TODO: may expand this effect for defined blocker (False Orders, General Jarkeld, Sorrow's Path, Ydwen Efreet)
for (final Card c : getTargetCards(sa)) { for (final Card c : getTargetCards(sa)) {
String cardString = CardTranslation.getTranslatedName(c.getName()) + " (" + c.getId() + ")"; String cardString = CardTranslation.getTranslatedName(c.getName()) + " (" + c.getId() + ")";
boolean isOptional = sa.hasParam("Optional");
if (isOptional && !activator.getController().confirmAction(sa, null, if (isOptional && !activator.getController().confirmAction(sa, null,
Localizer.getInstance().getMessage("lblChangeCombatantOption", cardString), null)) { Localizer.getInstance().getMessage("lblChangeCombatantOption", cardString), null)) {
continue; continue;
} }
final Combat combat = game.getCombat(); final GameEntity originalDefender = game.getCombat().getDefenderByAttacker(c);
final GameEntity originalDefender = combat.getDefenderByAttacker(c);
final FCollection<GameEntity> defs = new FCollection<>(sa.hasParam("PlayerOnly") ? combat.getDefendingPlayers() : combat.getDefenders());
String title = Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", cardString); if (addToCombat(c, sa, "Attacking", "Blocking")) {
Map<String, Object> params = Maps.newHashMap(); isCombatChanged = true;
params.put("Attacker", c); GameEntity defender = game.getCombat().getDefenderByAttacker(c);
final GameEntity defender = activator.getController().chooseSingleEntityForEffect(defs, sa, title, false, params);
if (originalDefender != null && !originalDefender.equals(defender)) {
AttackingBand ab = combat.getBandOfAttacker(c);
if (ab != null) {
combat.unregisterAttacker(c, ab);
ab.removeAttacker(c);
}
combat.addAttacker(c, defender);
// retarget triggers to the new defender (e.g. Ulamog, Ceaseless Hunger + Portal Mage) // retarget triggers to the new defender (e.g. Ulamog, Ceaseless Hunger + Portal Mage)
for (SpellAbilityStackInstance si : game.getStack()) { for (SpellAbilityStackInstance si : game.getStack()) {
if (si.isTrigger() && c.equals(si.getSourceCard()) if (si.isTrigger() && c.equals(si.getSourceCard())
@@ -75,7 +59,6 @@ public class ChangeCombatantsEffect extends SpellAbilityEffect {
} }
} }
} }
isCombatChanged = true;
} }
} }

View File

@@ -673,7 +673,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("LeaveBattlefield")) { if (sa.hasParam("LeaveBattlefield")) {
addLeaveBattlefieldReplacement(movedCard, sa, sa.getParam("LeaveBattlefield")); addLeaveBattlefieldReplacement(movedCard, sa, sa.getParam("LeaveBattlefield"));
} }
if (addToCombat(movedCard, movedCard.getController(), sa, "Attacking", "Blocking")) { if (addToCombat(movedCard, sa, "Attacking", "Blocking")) {
combatChanged = true; combatChanged = true;
} }
if (sa.isNinjutsu()) { if (sa.isNinjutsu()) {
@@ -1369,7 +1369,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} }
} }
if (addToCombat(c, c.getController(), sa, "Attacking", "Blocking")) { if (addToCombat(c, sa, "Attacking", "Blocking")) {
combatChanged = true; combatChanged = true;
} }

View File

@@ -18,7 +18,6 @@ import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView; import forge.game.card.CardCollectionView;
import forge.game.card.CardLists; import forge.game.card.CardLists;
import forge.game.event.GameEventCardStatsChanged; import forge.game.event.GameEventCardStatsChanged;
import forge.game.event.GameEventCombatChanged;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
@@ -149,7 +148,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
return; return;
} }
boolean combatChanged = false;
CardCollection untapped = new CardCollection(); CardCollection untapped = new CardCollection();
for (Card tgtC : tgtCards) { for (Card tgtC : tgtCards) {
if (!tgtC.isInPlay() || !tgtC.canBeControlledBy(newController)) { if (!tgtC.isInPlay() || !tgtC.canBeControlledBy(newController)) {
@@ -176,25 +174,10 @@ public class ControlGainEffect extends SpellAbilityEffect {
if (tgtC.untap(true)) untapped.add(tgtC); if (tgtC.untap(true)) untapped.add(tgtC);
} }
final List<String> kws = Lists.newArrayList(); if (keywords != null) {
final List<String> hiddenKws = Lists.newArrayList(); tgtC.addChangedCardKeywords(keywords, Lists.newArrayList(), false, tStamp, 0);
if (null != keywords) {
for (final String kw : keywords) {
if (kw.startsWith("HIDDEN")) {
hiddenKws.add(kw.substring(7));
} else {
kws.add(kw);
}
}
}
if (!kws.isEmpty()) {
tgtC.addChangedCardKeywords(kws, Lists.newArrayList(), false, tStamp, 0);
game.fireEvent(new GameEventCardStatsChanged(tgtC)); game.fireEvent(new GameEventCardStatsChanged(tgtC));
} }
if (!hiddenKws.isEmpty()) {
tgtC.addHiddenExtrinsicKeywords(tStamp, 0, hiddenKws);
}
if (remember && !source.isRemembered(tgtC)) { if (remember && !source.isRemembered(tgtC)) {
source.addRemembered(tgtC); source.addRemembered(tgtC);
@@ -244,7 +227,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
@Override @Override
public void run() { public void run() {
tgtC.removeHiddenExtrinsicKeywords(tStamp, 0);
tgtC.removeChangedCardKeywords(tStamp, 0); tgtC.removeChangedCardKeywords(tStamp, 0);
} }
}; };
@@ -252,11 +234,8 @@ public class ControlGainEffect extends SpellAbilityEffect {
} }
game.getAction().controllerChangeZoneCorrection(tgtC); game.getAction().controllerChangeZoneCorrection(tgtC);
if (addToCombat(tgtC, tgtC.getController(), sa, "Attacking", "Blocking")) {
combatChanged = true;
}
} // end foreach target } // end foreach target
if (!untapped.isEmpty()) { if (!untapped.isEmpty()) {
final Map<AbilityKey, Object> runParams = AbilityKey.newMap(); final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
final Map<Player, CardCollection> map = Maps.newHashMap(); final Map<Player, CardCollection> map = Maps.newHashMap();
@@ -264,11 +243,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
runParams.put(AbilityKey.Map, map); runParams.put(AbilityKey.Map, map);
game.getTriggerHandler().runTrigger(TriggerType.UntapAll, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.UntapAll, runParams, false);
} }
if (combatChanged) {
game.updateCombatForView();
game.fireEvent(new GameEventCombatChanged());
}
} }
/** /**

View File

@@ -411,7 +411,7 @@ public class DigEffect extends SpellAbilityEffect {
} }
c = game.getAction().moveTo(c.getController().getZone(destZone1), c, sa, moveParams); c = game.getAction().moveTo(c.getController().getZone(destZone1), c, sa, moveParams);
if (destZone1.equals(ZoneType.Battlefield)) { if (destZone1.equals(ZoneType.Battlefield)) {
if (addToCombat(c, c.getController(), sa, "Attacking", "Blocking")) { if (addToCombat(c, sa, "Attacking", "Blocking")) {
combatChanged = true; combatChanged = true;
} }
} else if (destZone1.equals(ZoneType.Exile)) { } else if (destZone1.equals(ZoneType.Exile)) {

View File

@@ -239,7 +239,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
c.setTapped(true); c.setTapped(true);
} }
m = game.getAction().moveTo(c.getController().getZone(foundDest), c, sa, moveParams); m = game.getAction().moveTo(c.getController().getZone(foundDest), c, sa, moveParams);
if (addToCombat(c, c.getController(), sa, "Attacking", "Blocking")) { if (addToCombat(c, sa, "Attacking", "Blocking")) {
combatChanged = true; combatChanged = true;
} }
} else if (sa.hasParam("NoMoveFound")) { } else if (sa.hasParam("NoMoveFound")) {

View File

@@ -65,7 +65,7 @@ public class MeldEffect extends SpellAbilityEffect {
PlayerZoneBattlefield bf = (PlayerZoneBattlefield)controller.getZone(ZoneType.Battlefield); PlayerZoneBattlefield bf = (PlayerZoneBattlefield)controller.getZone(ZoneType.Battlefield);
bf.addToMelded(secondary); bf.addToMelded(secondary);
Card movedCard = game.getAction().changeZone(primary.getZone(), bf, primary, 0, sa); Card movedCard = game.getAction().changeZone(primary.getZone(), bf, primary, 0, sa);
if (addToCombat(movedCard, movedCard.getController(), sa, "Attacking", "Blocking")) { if (addToCombat(movedCard, sa, "Attacking", "Blocking")) {
game.updateCombatForView(); game.updateCombatForView();
game.fireEvent(new GameEventCombatChanged()); game.fireEvent(new GameEventCombatChanged());
} }

View File

@@ -185,7 +185,7 @@ public abstract class TokenEffectBase extends SpellAbilityEffect {
addSelfTrigger(sa, sa.getParam("AtEOTTrig"), moved); addSelfTrigger(sa, sa.getParam("AtEOTTrig"), moved);
} }
if (addToCombat(moved, tok.getController(), sa, "TokenAttacking", "TokenBlocking")) { if (addToCombat(moved, sa, "TokenAttacking", "TokenBlocking")) {
combatChanged.setTrue(); combatChanged.setTrue();
} }

View File

@@ -1566,8 +1566,8 @@ public class CardFactoryUtil {
final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True" final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True"
+ " | TriggerDescription$ Myriad (" + inst.getReminderText() + ")"; + " | TriggerDescription$ Myriad (" + inst.getReminderText() + ")";
final String copyStr = "DB$ CopyPermanent | Defined$ Self | TokenTapped$ True | Optional$ True | TokenAttacking$ Remembered" final String copyStr = "DB$ CopyPermanent | Defined$ Self | TokenTapped$ True | Optional$ True | TokenAttacking$ Player.IsRemembered,Valid Planeswalker.ControlledBy Remembered"
+ "| ForEach$ OppNonDefendingPlayer | ChoosePlayerOrPlaneswalker$ True | AtEOT$ ExileCombat | CleanupForEach$ True"; + "| ForEach$ OppNonDefendingPlayer | AtEOT$ ExileCombat | CleanupForEach$ True";
final SpellAbility copySA = AbilityFactory.getAbility(copyStr, card); final SpellAbility copySA = AbilityFactory.getAbility(copyStr, card);
copySA.setIntrinsic(intrinsic); copySA.setIntrinsic(intrinsic);

View File

@@ -241,6 +241,10 @@ public class CardProperty {
if (!lp.contains(card.getProtectingPlayer())) { if (!lp.contains(card.getProtectingPlayer())) {
return false; return false;
} }
} else if (property.equals("Defending")) {
if (game.getCombat() == null || !game.getCombat().getAttackersAndDefenders().values().contains(card)) {
return false;
}
} else if (property.startsWith("DefendingPlayer")) { } else if (property.startsWith("DefendingPlayer")) {
Player p = property.endsWith("Ctrl") ? controller : card.getOwner(); Player p = property.endsWith("Ctrl") ? controller : card.getOwner();
if (!game.getPhaseHandler().inCombat()) { if (!game.getPhaseHandler().inCombat()) {

View File

@@ -7,6 +7,6 @@ S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$
SVar:X:Count$Valid Creature.YouCtrl SVar:X:Count$Valid Creature.YouCtrl
T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ DBRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control. T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ DBRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control.
SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Opponent | ChangeZoneTable$ True | RepeatSubAbility$ DBToken SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Opponent | ChangeZoneTable$ True | RepeatSubAbility$ DBToken
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenTapped$ True | TokenAttacking$ Remembered | ChoosePlayerOrPlaneswalker$ True | TokenOwner$ You SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenTapped$ True | TokenAttacking$ Player.IsRemembered,Valid Planeswalker.ControlledBy Remembered | TokenOwner$ You
DeckHas:Ability$Token DeckHas:Ability$Token
Oracle:Vigilance\nAdeline, Resplendent Cathar's power is equal to the number of creatures you control.\nWhenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control. Oracle:Vigilance\nAdeline, Resplendent Cathar's power is equal to the number of creatures you control.\nWhenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control.

View File

@@ -5,6 +5,6 @@ PT:0/0
K:etbCounter:P1P1:X K:etbCounter:P1P1:X
SVar:X:Count$xPaid SVar:X:Count$xPaid
A:AB$ PutCounter | Cost$ 2 | Activator$ Player | IsPresent$ Card.Self+attackingYou | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBReselect | ActivationPhases$ Declare Attackers | AILogic$ AlwaysWithNoTgt | SpellDescription$ Put a +1/+1 counter on CARDNAME, then you may reselect which player CARDNAME is attacking. Only the player CARDNAME is attacking may activate this ability and only during the declare attackers step. (It can't attack its controller.) A:AB$ PutCounter | Cost$ 2 | Activator$ Player | IsPresent$ Card.Self+attackingYou | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBReselect | ActivationPhases$ Declare Attackers | AILogic$ AlwaysWithNoTgt | SpellDescription$ Put a +1/+1 counter on CARDNAME, then you may reselect which player CARDNAME is attacking. Only the player CARDNAME is attacking may activate this ability and only during the declare attackers step. (It can't attack its controller.)
SVar:DBReselect:DB$ ChangeCombatants | Defined$ Self | AILogic$ WeakestOppExceptCtrl | PlayerOnly$ True SVar:DBReselect:DB$ ChangeCombatants | Defined$ Self | AILogic$ WeakestOppExceptCtrl | Attacking$ Player.OpponentOf CardController
DeckHas:Ability$Counters DeckHas:Ability$Counters
Oracle:Capricopian enters the battlefield with X +1/+1 counters on it.\n{2}: Put a +1/+1 counter on Capricopian, then you may reselect which player Capricopian is attacking. Only the player Capricopian is attacking may activate this ability and only during the declare attackers step. (It can't attack its controller.) Oracle:Capricopian enters the battlefield with X +1/+1 counters on it.\n{2}: Put a +1/+1 counter on Capricopian, then you may reselect which player Capricopian is attacking. Only the player Capricopian is attacking may activate this ability and only during the declare attackers step. (It can't attack its controller.)

View File

@@ -3,7 +3,7 @@ ManaCost:2 R G
Types:Legendary Creature Human Scout Types:Legendary Creature Human Scout
PT:1/4 PT:1/4
T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME attacks, reveal the top card of your library. If it's a creature card, put it onto the battlefield tapped and attacking defending player or a planeswalker they control. Otherwise, put that card into your hand. When you put a creature card onto the battlefield this way, it fights CARDNAME. T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME attacks, reveal the top card of your library. If it's a creature card, put it onto the battlefield tapped and attacking defending player or a planeswalker they control. Otherwise, put that card into your hand. When you put a creature card onto the battlefield this way, it fights CARDNAME.
SVar:TrigDig:DB$ Dig | DigNum$ 1 | ChangeNum$ All | Optional$ True | Reveal$ True | ChangeValid$ Creature | DestinationZone$ Battlefield | DestinationZone2$ Hand | Tapped$ True | Attacking$ DefendingPlayer | ChoosePlayerOrPlaneswalker$ True | RememberChanged$ True | SubAbility$ DBImmediateTriggerCheck SVar:TrigDig:DB$ Dig | DigNum$ 1 | ChangeNum$ All | Optional$ True | Reveal$ True | ChangeValid$ Creature | DestinationZone$ Battlefield | DestinationZone2$ Hand | Tapped$ True | Attacking$ DefendingPlayer,Valid Planeswalker.ControlledBy DefendingPlayer | RememberChanged$ True | SubAbility$ DBImmediateTriggerCheck
SVar:DBImmediateTriggerCheck:DB$ ImmediateTrigger | Execute$ DBFight | ConditionDefined$ Remembered | ConditionPresent$ Creature | ConditionCompare$ GE1 | TriggerDescription$ When you put a creature card onto the battlefield this way, it fights Hans Eriksson. SVar:DBImmediateTriggerCheck:DB$ ImmediateTrigger | Execute$ DBFight | ConditionDefined$ Remembered | ConditionPresent$ Creature | ConditionCompare$ GE1 | TriggerDescription$ When you put a creature card onto the battlefield this way, it fights Hans Eriksson.
SVar:DBFight:DB$ Fight | Defined$ Remembered | ExtraDefined$ Self | SubAbility$ DBCleanup SVar:DBFight:DB$ Fight | Defined$ Remembered | ExtraDefined$ Self | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -3,7 +3,7 @@ ManaCost:2 U
Types:Artifact Types:Artifact
K:Flash K:Flash
T:Mode$ ChangesZone | Phase$ Declare Attackers | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeAttacker | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.) T:Mode$ ChangesZone | Phase$ Declare Attackers | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeAttacker | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.)
SVar:TrigChangeAttacker:DB$ ChangeCombatants | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature SVar:TrigChangeAttacker:DB$ ChangeCombatants | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | Attacking$ True
AI:RemoveDeck:All AI:RemoveDeck:All
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}. A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}.
Oracle:Flash\nWhen Misleading Signpost enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.)\n{T}: Add {U}. Oracle:Flash\nWhen Misleading Signpost enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.)\n{T}: Add {U}.

View File

@@ -4,6 +4,6 @@ Types:Creature Human Wizard
PT:2/2 PT:2/2
K:Flash K:Flash
T:Mode$ ChangesZone | Phase$ Declare Attackers | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeAttacker | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.) T:Mode$ ChangesZone | Phase$ Declare Attackers | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeAttacker | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.)
SVar:TrigChangeAttacker:DB$ ChangeCombatants | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature SVar:TrigChangeAttacker:DB$ ChangeCombatants | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | Attacking$ True
AI:RemoveDeck:All AI:RemoveDeck:All
Oracle:Flash\nWhen Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.) Oracle:Flash\nWhen Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. (It can't attack its controller or their permanents.)

View File

@@ -4,6 +4,8 @@ Types:Legendary Creature Minotaur Warrior
PT:5/5 PT:5/5
S:Mode$ MinMaxBlocker | ValidCard$ Card.Self | Max$ 1 | Description$ CARDNAME can't be blocked by more than one creature. S:Mode$ MinMaxBlocker | ValidCard$ Card.Self | Max$ 1 | Description$ CARDNAME can't be blocked by more than one creature.
T:Mode$ AttackersDeclared | AttackingPlayer$ Player.Opponent | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | IsPresent$ Card.Self+tapped | TriggerDescription$ Whenever an opponent attacks with one or more creatures, if NICKNAME is tapped, you may have that opponent gain control of NICKNAME until end of combat. If you do, choose a player or planeswalker that opponent is attacking. NICKNAME is attacking that player or planeswalker. T:Mode$ AttackersDeclared | AttackingPlayer$ Player.Opponent | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | IsPresent$ Card.Self+tapped | TriggerDescription$ Whenever an opponent attacks with one or more creatures, if NICKNAME is tapped, you may have that opponent gain control of NICKNAME until end of combat. If you do, choose a player or planeswalker that opponent is attacking. NICKNAME is attacking that player or planeswalker.
SVar:TrigGainControl:DB$ GainControl | Defined$ Self | NewController$ TriggeredAttackingPlayer | LoseControl$ EndOfCombat | Attacking$ Player.Defending | Chooser$ You | ChoosePlayerOrPlaneswalker$ True SVar:TrigGainControl:DB$ GainControl | Defined$ Self | NewController$ TriggeredAttackingPlayer | LoseControl$ EndOfCombat | RememberControlled$ True | SubAbility$ DBAttack
SVar:DBAttack:DB$ ChangeCombatants | Defined$ Remembered | Attacking$ Player.Defending,Valid Planeswalker.Defending | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All AI:RemoveDeck:All
Oracle:Tahngarth, First Mate can't be blocked by more than one creature.\nWhenever an opponent attacks with one or more creatures, if Tahngarth is tapped, you may have that opponent gain control of Tahngarth until end of combat. If you do, choose a player or planeswalker that opponent is attacking. Tahngarth is attacking that player or planeswalker. Oracle:Tahngarth, First Mate can't be blocked by more than one creature.\nWhenever an opponent attacks with one or more creatures, if Tahngarth is tapped, you may have that opponent gain control of Tahngarth until end of combat. If you do, choose a player or planeswalker that opponent is attacking. Tahngarth is attacking that player or planeswalker.

View File

@@ -5,7 +5,6 @@ PT:4/4
K:Flash K:Flash
K:Flying K:Flying
T:Mode$ ChangesZone | Phase$ Declare Attackers | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEachAttacker | TriggerDescription$ When CARDNAME enters the battlefield during the declare attackers step, for each attacking creature, you may reselect which player or permanent that creature is attacking. (It can't attack its controller or their permanents.) T:Mode$ ChangesZone | Phase$ Declare Attackers | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEachAttacker | TriggerDescription$ When CARDNAME enters the battlefield during the declare attackers step, for each attacking creature, you may reselect which player or permanent that creature is attacking. (It can't attack its controller or their permanents.)
SVar:TrigEachAttacker:DB$ RepeatEach | RepeatCards$ Creature.attacking | RepeatSubAbility$ DBChangeAttacker SVar:TrigEachAttacker:DB$ ChangeCombatants | Defined$ Valid Creature.attacking | Optional$ True | Attacking$ True
SVar:DBChangeAttacker:DB$ ChangeCombatants | Defined$ Remembered | Optional$ True
AI:RemoveDeck:All AI:RemoveDeck:All
Oracle:Flash\nFlying\nWhen Windshaper Planetar enters the battlefield during the declare attackers step, for each attacking creature, you may reselect which player or permanent that creature is attacking. (It can't attack its controller or their permanents.) Oracle:Flash\nFlying\nWhen Windshaper Planetar enters the battlefield during the declare attackers step, for each attacking creature, you may reselect which player or permanent that creature is attacking. (It can't attack its controller or their permanents.)

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Human Pirate
PT:4/3 PT:4/3
K:Flying K:Flying
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigBorrow | TriggerDescription$ Whenever CARDNAME attacks, look at defending player's hand. You may put a creature card from it onto the battlefield under your control tapped and attacking that player or a planeswalker they control. Return that creature to its owner's hand at the beginning of the next end step. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigBorrow | TriggerDescription$ Whenever CARDNAME attacks, look at defending player's hand. You may put a creature card from it onto the battlefield under your control tapped and attacking that player or a planeswalker they control. Return that creature to its owner's hand at the beginning of the next end step.
SVar:TrigBorrow:DB$ ChangeZone | ChangeNum$ 1 | DefinedPlayer$ TriggeredDefendingPlayer | Chooser$ You | ChangeType$ Creature | Origin$ Hand | Destination$ Battlefield | GainControl$ True | Tapped$ True | Attacking$ DefendingPlayer | ChoosePlayerOrPlaneswalker$ True | RememberChanged$ True | SubAbility$ DBDelayTrig SVar:TrigBorrow:DB$ ChangeZone | ChangeNum$ 1 | DefinedPlayer$ TriggeredDefendingPlayer | Chooser$ You | ChangeType$ Creature | Origin$ Hand | Destination$ Battlefield | GainControl$ True | Tapped$ True | Attacking$ DefendingPlayer,Valid Planeswalker.ControlledBy DefendingPlayer | RememberChanged$ True | SubAbility$ DBDelayTrig
SVar:DBDelayTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | RememberObjects$ RememberedLKI | Execute$ DBChange | StackDescription$ None | SubAbility$ DBCleanup | TriggerDescription$ Return that creature to its owner's hand at the beginning of the next end step. SVar:DBDelayTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | RememberObjects$ RememberedLKI | Execute$ DBChange | StackDescription$ None | SubAbility$ DBCleanup | TriggerDescription$ Return that creature to its owner's hand at the beginning of the next end step.
SVar:DBChange:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand SVar:DBChange:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True