mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
TLA: Airbend (#8419)
This commit is contained in:
@@ -19,6 +19,7 @@ public enum ApiType {
|
|||||||
AddPhase (AddPhaseEffect.class),
|
AddPhase (AddPhaseEffect.class),
|
||||||
AddTurn (AddTurnEffect.class),
|
AddTurn (AddTurnEffect.class),
|
||||||
AdvanceCrank (AdvanceCrankEffect.class),
|
AdvanceCrank (AdvanceCrankEffect.class),
|
||||||
|
Airbend (AirbendEffect.class),
|
||||||
AlterAttribute (AlterAttributeEffect.class),
|
AlterAttribute (AlterAttributeEffect.class),
|
||||||
Amass (AmassEffect.class),
|
Amass (AmassEffect.class),
|
||||||
Animate (AnimateEffect.class),
|
Animate (AnimateEffect.class),
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardZoneTable;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.util.Lang;
|
||||||
|
|
||||||
|
public class AirbendEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
|
final StringBuilder sb = new StringBuilder("Airbend ");
|
||||||
|
|
||||||
|
Iterable<Card> tgts;
|
||||||
|
if (sa.usesTargeting()) {
|
||||||
|
tgts = getCardsfromTargets(sa);
|
||||||
|
} else { // otherwise add self to list and go from there
|
||||||
|
tgts = sa.knownDetermineDefined(sa.getParam("Defined"));
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(sa.getParamOrDefault("DefinedDesc", Lang.joinHomogenous(tgts)));
|
||||||
|
sb.append(".");
|
||||||
|
if (Iterables.size(tgts) > 1) {
|
||||||
|
sb.append(" (Exile them. While each one is exiled, its owner may cast it for {2} rather than its mana cost.)");
|
||||||
|
} else {
|
||||||
|
sb.append(" (Exile it. While it’s exiled, its owner may cast it for {2} rather than its mana cost.)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolve(SpellAbility sa) {
|
||||||
|
final Card hostCard = sa.getHostCard();
|
||||||
|
final Game game = hostCard.getGame();
|
||||||
|
final Player pl = sa.getActivatingPlayer();
|
||||||
|
|
||||||
|
final CardZoneTable triggerList = CardZoneTable.getSimultaneousInstance(sa);
|
||||||
|
|
||||||
|
for (Card c : getTargetCards(sa)) {
|
||||||
|
final Card gameCard = game.getCardState(c, null);
|
||||||
|
// gameCard is LKI in that case, the card is not in game anymore
|
||||||
|
// or the timestamp did change
|
||||||
|
// this should check Self too
|
||||||
|
if (gameCard == null || !c.equalsWithGameTimestamp(gameCard) || gameCard.isPhasedOut()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gameCard.canExiledBy(sa, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
handleExiledWith(gameCard, sa);
|
||||||
|
|
||||||
|
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
|
||||||
|
AbilityKey.addCardZoneTableParams(moveParams, triggerList);
|
||||||
|
|
||||||
|
Card movedCard = game.getAction().exile(gameCard, sa, moveParams);
|
||||||
|
|
||||||
|
if (movedCard == null || !movedCard.isInZone(ZoneType.Exile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Effect to cast for 2 from exile
|
||||||
|
Card eff = createEffect(sa, movedCard.getOwner(), "Airbend" + movedCard, hostCard.getImageKey());
|
||||||
|
eff.addRemembered(movedCard);
|
||||||
|
|
||||||
|
StringBuilder sbPlay = new StringBuilder();
|
||||||
|
sbPlay.append("Mode$ Continuous | MayPlay$ True | MayPlayAltManaCost$ 2 | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand");
|
||||||
|
sbPlay.append(" | AffectedZone$ Exile | Description$ You may cast the card.");
|
||||||
|
eff.addStaticAbility(sbPlay.toString());
|
||||||
|
|
||||||
|
addForgetOnMovedTrigger(eff, "Exile");
|
||||||
|
addForgetOnCastTrigger(eff, "Card.IsRemembered");
|
||||||
|
|
||||||
|
game.getAction().moveToCommand(eff, sa);
|
||||||
|
}
|
||||||
|
triggerList.triggerChangesZoneAll(game, sa);
|
||||||
|
handleExiledWith(triggerList.allCards(), sa);
|
||||||
|
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Airbend, AbilityKey.mapFromPlayer(pl), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ import forge.game.replacement.ReplacementEffect;
|
|||||||
import forge.game.replacement.ReplacementType;
|
import forge.game.replacement.ReplacementType;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
import forge.game.staticability.StaticAbility;
|
|
||||||
import forge.game.trigger.TriggerType;
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.Zone;
|
import forge.game.zone.Zone;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -765,7 +764,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
StringBuilder sbPlay = new StringBuilder();
|
StringBuilder sbPlay = new StringBuilder();
|
||||||
sbPlay.append("Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand+!ThisTurnEntered");
|
sbPlay.append("Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand+!ThisTurnEntered");
|
||||||
sbPlay.append(" | AffectedZone$ Exile | Description$ You may cast the card.");
|
sbPlay.append(" | AffectedZone$ Exile | Description$ You may cast the card.");
|
||||||
final StaticAbility st = eff.addStaticAbility(sbPlay.toString());
|
eff.addStaticAbility(sbPlay.toString());
|
||||||
eff.addRemembered(movedCard);
|
eff.addRemembered(movedCard);
|
||||||
addForgetOnMovedTrigger(eff, "Exile");
|
addForgetOnMovedTrigger(eff, "Exile");
|
||||||
addForgetOnCastTrigger(eff, "Card.IsRemembered");
|
addForgetOnCastTrigger(eff, "Card.IsRemembered");
|
||||||
|
|||||||
6
forge-gui/res/cardsfolder/upcoming/airbending_lesson.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/airbending_lesson.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Airbending Lesson
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Instant Lesson
|
||||||
|
A:SP$ Airbend | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | SubAbility$ DBDraw | SpellDescription$ Airbend target nonland permanent. (Exile it. While it’s exiled, its owner may cast it for {2} rather than its mana cost.)
|
||||||
|
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||||
|
Oracle:Airbend target nonland permanent. (Exile it. While it’s exiled, its owner may cast it for {2} rather than its mana cost.)\nDraw a card.
|
||||||
Reference in New Issue
Block a user