ONE: The Eternal Wanderer + support + tidy related cards

This commit is contained in:
Northmoc
2023-02-03 13:53:31 -05:00
parent d99e43209a
commit 24e9f6505a
13 changed files with 85 additions and 62 deletions

View File

@@ -26,8 +26,6 @@ public enum GlobalRuleChange {
attackerChoosesBlockers ("The attacking player chooses how each creature blocks each combat."),
manaBurn ("A player losing unspent mana causes that player to lose that much life."),
noNight ("It can't become night."),
/* onlyOneAttackerATurn ("No more than one creature can attack each turn."), */
onlyOneAttackerACombat ("No more than one creature can attack each combat."),
onlyOneBlocker ("No more than one creature can block each combat."),
onlyOneBlockerPerOpponent ("Each opponent can't block with more than one creature."),
onlyTwoBlockers ("No more than two creatures can block each combat."),

View File

@@ -7,10 +7,9 @@ import com.google.common.primitives.Ints;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GlobalRuleChange;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.game.staticability.StaticAbilityAttackRestrict;
import forge.util.collect.FCollectionView;
import forge.util.maps.LinkedHashMapToAmount;
import forge.util.maps.MapToAmount;
@@ -107,33 +106,13 @@ public class GlobalAttackRestrictions {
* @return a {@link GlobalAttackRestrictions} object.
*/
public static GlobalAttackRestrictions getGlobalRestrictions(final Player attackingPlayer, final FCollectionView<GameEntity> possibleDefenders) {
int max = -1;
final MapToAmount<GameEntity> defenderMax = new LinkedHashMapToAmount<>(possibleDefenders.size());
final Game game = attackingPlayer.getGame();
/* if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.onlyOneAttackerATurn)) {
if (!attackingPlayer.getAttackedWithCreatureThisTurn().isEmpty()) {
max = 0;
} else {
max = 1;
}
} */
if (max == -1 && game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.onlyOneAttackerACombat)) {
max = 1;
}
if (max == -1) {
for (final Card card : game.getCardsIn(ZoneType.Battlefield)) {
if (card.hasKeyword("No more than two creatures can attack each combat.")) {
max = 2;
break;
}
}
}
int max = StaticAbilityAttackRestrict.globalAttackRestrict(game);
for (final GameEntity defender : possibleDefenders) {
final int defMax = getMaxAttackTo(defender);
final int defMax = StaticAbilityAttackRestrict.attackRestrictNum(defender);
if (defMax != -1) {
defenderMax.add(defender, defMax);
}
@@ -145,27 +124,4 @@ public class GlobalAttackRestrictions {
return new GlobalAttackRestrictions(max, defenderMax);
}
/**
* <p>
* Get the maximum number of creatures allowed to attack a certain defender.
* </p>
*
* @param defender
* the defending {@link GameEntity}.
* @return the maximum number of creatures, or -1 if it is unlimited.
*/
private static int getMaxAttackTo(final GameEntity defender) {
if (defender instanceof Player) {
for (final Card card : ((Player) defender).getCardsIn(ZoneType.Battlefield)) {
if (card.hasKeyword("No more than one creature can attack you each combat.")) {
return 1;
} else if (card.hasKeyword("No more than two creatures can attack you each combat.")) {
return 2;
}
}
}
return -1;
}
}

View File

@@ -0,0 +1,53 @@
package forge.game.staticability;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
import forge.game.zone.ZoneType;
public class StaticAbilityAttackRestrict {
static String MODE = "AttackRestrict";
static public int globalAttackRestrict(Game game) {
int max = Integer.MAX_VALUE;
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final StaticAbility stAb : ca.getStaticAbilities()) {
if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()
|| stAb.hasParam("ValidDefender")) {
continue;
}
int stMax = AbilityUtils.calculateAmount(stAb.getHostCard(),
stAb.getParamOrDefault("MaxAttackers", "1"), stAb);
if (stMax < max) {
max = stMax;
}
}
}
return max < Integer.MAX_VALUE ? max : -1;
}
static public int attackRestrictNum(GameEntity defender) {
final Game game = defender.getGame();
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final StaticAbility stAb : ca.getStaticAbilities()) {
if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) {
continue;
}
if (attackRestrict(stAb, defender)) {
return AbilityUtils.calculateAmount(stAb.getHostCard(),
stAb.getParamOrDefault("MaxAttackers", "1"), stAb);
}
}
}
return -1;
}
static public boolean attackRestrict(StaticAbility stAb, GameEntity defender) {
if (!stAb.matchesValidParam("ValidDefender", defender)) {
return false;
}
return true;
}
}

View File

@@ -1,7 +1,7 @@
Name:Astral Arena
ManaCost:no cost
Types:Plane Kolbahan
S:Mode$ Continuous | EffectZone$ Command | GlobalRule$ No more than one creature can attack each combat. | Description$ No more than one creature can attack each combat.
S:Mode$ AttackRestrict | EffectZone$ Command | MaxAttackers$ 1 | Description$ No more than one creature can attack each combat.
S:Mode$ Continuous | EffectZone$ Command | GlobalRule$ No more than one creature can block each combat. | Description$ No more than one creature can block each combat.
T:Mode$ PlanarDice | Result$ Chaos | TriggerZones$ Command | Execute$ RolledChaos | TriggerDescription$ Whenever you roll {CHAOS}, CARDNAME deals 2 damage to each creature.
SVar:RolledChaos:DB$ DamageAll | NumDmg$ 2 | ValidCards$ Creature | ValidDescription$ each creature.

View File

@@ -1,7 +1,7 @@
Name:Caverns of Despair
ManaCost:2 R R
Types:World Enchantment
K:No more than two creatures can attack each combat.
S:Mode$ AttackRestrict | MaxAttackers$ 2 | Description$ No more than two creatures can attack each combat.
S:Mode$ Continuous | GlobalRule$ No more than two creatures can block each combat. | Description$ No more than two creatures can block each combat.
SVar:NonStackingEffect:True
AI:RemoveDeck:Random

View File

@@ -1,7 +1,6 @@
Name:Crawlspace
ManaCost:3
Types:Artifact
K:No more than two creatures can attack you each combat.
S:Mode$ AttackRestrict | MaxAttackers$ 2 | ValidDefender$ You | Description$ No more than two creatures can attack you each combat.
SVar:NonStackingEffect:True
AI:RemoveDeck:Random
Oracle:No more than two creatures can attack you each combat.

View File

@@ -1,7 +1,7 @@
Name:Dueling Grounds
ManaCost:1 G W
Types:Enchantment
S:Mode$ Continuous | GlobalRule$ No more than one creature can attack each combat. | Description$ No more than one creature can attack each combat.
S:Mode$ AttackRestrict | MaxAttackers$ 1 | Description$ No more than one creature can attack each combat.
S:Mode$ Continuous | GlobalRule$ No more than one creature can block each combat. | Description$ No more than one creature can block each combat.
AI:RemoveDeck:Random
Oracle:No more than one creature can attack each combat.\nNo more than one creature can block each combat.

View File

@@ -5,7 +5,7 @@ PT:5/5
K:Kicker:3
K:etbCounter:P1P1:5:CheckSVar$ WasKicked:If CARDNAME was kicked, it enters the battlefield with five +1/+1 counters on it.
SVar:WasKicked:Count$Kicked.1.0
T:Mode$ Attacks | ValidCard$ Card.Self | Alone$ True | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks alone, double its power and toughness until end of turn.
T:Mode$ Attacks | ValidCard$ Card.Self | Alone$ True | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever NICKNAME attacks alone, double its power and toughness until end of turn.
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ +X | NumDef$ +Y | Double$ True
SVar:X:Count$CardPower
SVar:Y:Count$CardToughness

View File

@@ -3,8 +3,8 @@ ManaCost:1 G W
Types:Legendary Creature Cat Warrior
PT:3/2
K:First Strike
S:Mode$ Continuous | EffectZone$ Battlefield | Affected$ Card.Self+tapped | AddKeyword$ No more than one creature can attack you each combat. | Description$ As long as CARDNAME is tapped, no more than one creature can attack you each combat.
S:Mode$ AttackRestrict | IsPresent$ Card.Self+tapped | MaxAttackers$ 1 | ValidDefender$ You | Description$ As long as CARDNAME is tapped, no more than one creature can attack you each combat.
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigLimitBlock | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, each opponent can't block with more than one creature this combat.
SVar:TrigLimitBlock:DB$ Effect | Name$ Mirri, Weatherlight Duelist Effect | StaticAbilities$ STLimitBlock | Duration$ UntilEndOfCombat
SVar:TrigLimitBlock:DB$ Effect | StaticAbilities$ STLimitBlock | Duration$ UntilEndOfCombat
SVar:STLimitBlock:Mode$ Continuous | EffectZone$ Command | GlobalRule$ Each opponent can't block with more than one creature. | Description$ Each opponent can't block with more than one creature this combat.
Oracle:First strike\nWhenever Mirri, Weatherlight Duelist attacks, each opponent can't block with more than one creature this combat.\nAs long as Mirri, Weatherlight Duelist is tapped, no more than one creature can attack you each combat.

View File

@@ -2,6 +2,6 @@ Name:Silent Arbiter
ManaCost:4
Types:Artifact Creature Construct
PT:1/5
S:Mode$ Continuous | GlobalRule$ No more than one creature can attack each combat. | Description$ No more than one creature can attack each combat.
S:Mode$ AttackRestrict | MaxAttackers$ 1 | Description$ No more than one creature can attack each combat.
S:Mode$ Continuous | GlobalRule$ No more than one creature can block each combat. | Description$ No more than one creature can block each combat.
Oracle:No more than one creature can attack each combat.\nNo more than one creature can block each combat.

View File

@@ -1,9 +1,9 @@
Name:Suppress
ManaCost:2 B
Types:Sorcery
A:SP$ ChangeZoneAll | Cost$ 2 B | ValidTgts$ Player | TgtPrompt$ Select target player | ChangeType$ Card | Origin$ Hand | Destination$ Exile | Hidden$ True | ExileFaceDown$ True | RememberTargets$ True | RememberChanged$ True | Reveal$ False | SubAbility$ DelTrig | SpellDescription$ Target player exiles all cards from their hand face down. At the beginning of the end step of that player's next turn, that player returns those cards to their hand.
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player.IsRemembered | Execute$ TrigReturn | Secondary$ True | TriggerDescription$ Return exiled cards to targeted player's hand.
SVar:TrigReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Hand | SubAbility$ DBCleanup
A:SP$ ChangeZoneAll | ValidTgts$ Player | ChangeType$ Card | Origin$ Hand | Destination$ Exile | Hidden$ True | ExileFaceDown$ True | RememberChanged$ True | Reveal$ False | SubAbility$ DelTrig | StackDescription$ {p:Targeted} exiles all cards from their hand face down. | SpellDescription$ Target player exiles all cards from their hand face down. At the beginning of the end step of that player's next turn, that player returns those cards to their hand.
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | DelayedTriggerDefinedPlayer$ Targeted | ThisTurn$ True | RememberObjects$ Remembered | Execute$ TrigReturn | Secondary$ True | SubAbility$ DBCleanup | TriggerDescription$ At the beginning of the end step of that player's next turn, that player returns those cards to their hand. | StackDescription$ At the beginning of the end step of that player's next turn, that player returns those cards to their hand.
SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Exile | Destination$ Hand
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All
Oracle:Target player exiles all cards from their hand face down. At the beginning of the end step of that player's next turn, that player returns those cards to their hand.

View File

@@ -2,7 +2,7 @@ Name:Teleportation Circle
ManaCost:3 W
Types:Enchantment
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigExile | TriggerDescription$ At the beginning of your end step, exile up to one target artifact or creature you control, then return that card to the battlefield under its owner's control.
SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | ValidTgts$ Artifact.YouCtrl,Creature.YouCtrl | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target artifact or creature | SubAbility$ DBReturn
SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | ValidTgts$ Artifact.YouCtrl,Creature.YouCtrl | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target artifact or creature you control | SubAbility$ DBReturn
SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ All | Destination$ Battlefield | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
Oracle:At the beginning of your end step, exile up to one target artifact or creature you control, then return that card to the battlefield under its owner's control.

View File

@@ -0,0 +1,17 @@
Name:The Eternal Wanderer
ManaCost:4 W W
Types:Legendary Planeswalker
Loyalty:5
S:Mode$ AttackRestrict | MaxAttackers$ 1 | ValidDefender$ Card.Self | Description$ No more than one creature can attack CARDNAME each combat.
A:AB$ ChangeZone | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Artifact,Creature | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target artifact or creature | RememberChanged$ True | SubAbility$ DBDelTrig | SpellDescription$ Exile up to one target artifact or creature. Return that card to the battlefield under its owner's control at the beginning of that player's next end step.
SVar:DBDelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player.IsTriggerRemembered | Execute$ TrigReturn | RememberObjects$ TargetedOwner,RememberedLKI | SubAbility$ DBCleanup | TriggerDescription$ Return that card to the battlefield under its owner's control at the beginning of that player's next end step. | StackDescription$ Return that card to the battlefield under its owner's control at the beginning of that player's next end step.
SVar:TrigReturn:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ Token | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | TokenScript$ w_2_2_samurai_double_strike | SpellDescription$ Create a 2/2 white Samurai creature token with double strike.
A:AB$ RepeatEach | Cost$ SubCounter<4/LOYALTY> | Planeswalker$ True | RepeatPlayers$ Player | RepeatSubAbility$ DBChoose | SubAbility$ DBSacAll | StackDescription$ SpellDescription | SpellDescription$ For each player, choose a creature that player controls. Each player sacrifices all creatures they control not chosen this way.
SVar:DBChoose:DB$ ChooseCard | Defined$ You | Choices$ Creature.RememberedPlayerCtrl | Mandatory$ True | Amount$ 1 | ChoiceTitle$ Choose a creature this player controls | ImprintChosen$ True
SVar:DBSacAll:DB$ SacrificeAll | ValidCards$ Creature.IsNotImprinted | SubAbility$ DBCleanup2 | StackDescription$ None
SVar:DBCleanup2:DB$ Cleanup | ClearChosenCard$ True | ClearImprinted$ True
DeckHas:Ability$Token|Sacrifice & Type$Samurai
DeckHints:Keyword$Exalted
Oracle:No more than one creature can attack The Eternal Wanderer each combat.\n[+1]: Exile up to one target artifact or creature. Return that card to the battlefield under its owner's control at the beginning of that player's next end step.\n[0]: Create a 2/2 white Samurai creature token with double strike.\n[4]: For each player, choose a creature that player controls. Each player sacrifices all creatures they control not chosen this way.