Merge branch 'master' into 'master'

Fix a variety of Roll Dice card- and AI-related issues, improve AI for AF RollDice

See merge request core-developers/forge!4138
This commit is contained in:
Michael Kamensky
2021-03-07 17:08:33 +00:00
14 changed files with 31 additions and 15 deletions

View File

@@ -375,7 +375,9 @@ public class AiController {
@Override
public boolean apply(final Card c) {
CardCollectionView battlefield = player.getCardsIn(ZoneType.Battlefield);
canPlaySpellBasic(c, null);
if (canPlaySpellBasic(c, null) != AiPlayDecision.WillPlay) {
return false;
}
String name = c.getName();
if (c.getType().isLegendary() && !name.equals("Flagstones of Trokair")) {
if (Iterables.any(battlefield, CardPredicates.nameEquals(name))) {

View File

@@ -2,6 +2,8 @@ package forge.ai.ability;
import forge.ai.SpellAbilityAi;
import forge.game.Game;
import forge.game.card.Card;
import forge.game.cost.Cost;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
@@ -12,8 +14,19 @@ import forge.game.spellability.SpellAbility;
public class RollDiceAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
PhaseHandler ph = aiPlayer.getGame().getPhaseHandler();
Card source = sa.getHostCard();
Game game = aiPlayer.getGame();
PhaseHandler ph = game.getPhaseHandler();
Cost cost = sa.getPayCosts();
String logic = sa.getParamOrDefault("AILogic", "");
if (logic.equals("Combat")) {
return game.getCombat() != null && ((game.getCombat().isAttacking(source) && game.getCombat().isUnblocked(source)) || game.getCombat().isBlocking(source));
} else if (logic.equals("CombatEarly")) {
return game.getCombat() != null && (game.getCombat().isAttacking(source) || game.getCombat().isBlocking(source));
} else if (logic.equals("Main2")) {
return ph.is(PhaseType.MAIN2, aiPlayer);
}
if (cost != null && (sa.getPayCosts().hasManaCost() || sa.getPayCosts().hasTapCost())) {
return ph.getNextTurn() == aiPlayer && ph.is(PhaseType.END_OF_TURN);

View File

@@ -2,7 +2,7 @@ Name:As Luck Would Have It
ManaCost:G
Types:Enchantment
K:Hexproof
T:Mode$ RolledDie | Execute$ TrigCounters | ValidPlayer$ You | TriggerDescription$ Whenever you roll a die, put a number of luck counters on As Luck Would Have It equal to the result. Then if there are 100 or more luck counters on As Luck Would Have It, you win the game.
T:Mode$ RolledDie | Execute$ TrigCounters | ValidPlayer$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you roll a die, put a number of luck counters on As Luck Would Have It equal to the result. Then if there are 100 or more luck counters on As Luck Would Have It, you win the game.
SVar:TrigCounters:DB$ PutCounter | Defined$ Self | CounterType$ LUCK | CounterNum$ X | SubAbility$ DBWin
SVar:DBWin:DB$ WinsGame | Defined$ You | ConditionPresent$ Card.Self+counters_GE100_LUCK
SVar:X:TriggerCount$Result

View File

@@ -2,7 +2,7 @@ Name:Chicken à la King
ManaCost:1 U U
Types:Creature Bird Noble
PT:2/2
T:Mode$ RolledDie | Execute$ TrigCounters | ValidResult$ 6 | TriggerDescription$ Whenever a 6 is rolled on a six-sided die, put a +1/+1 counter on each Bird.
T:Mode$ RolledDie | TriggerZones$ Battlefield | Execute$ TrigCounters | ValidResult$ 6 | TriggerDescription$ Whenever a 6 is rolled on a six-sided die, put a +1/+1 counter on each Bird.
SVar:TrigCounters:DB$ PutCounterAll | ValidCards$ Bird | CounterType$ P1P1 | CounterNum$ 1
A:AB$ RollDice | Cost$ tapXType<1/Bird> | SpellDescription$ Roll a six-sided die.
DeckHas:Ability$Counters

View File

@@ -1,7 +1,7 @@
Name:Chittering Doom
ManaCost:3 G
Types:Enchantment
T:Mode$ RolledDie | Execute$ TrigToken | ValidPlayer$ You | ValidResult$ GE4 | TriggerDescription$ Whenever you roll a 4 or higher on a die, create a 1/1 green Squirrel creature token.
T:Mode$ RolledDie | TriggerZones$ Battlefield | Execute$ TrigToken | ValidPlayer$ You | ValidResult$ GE4 | TriggerDescription$ Whenever you roll a 4 or higher on a die, create a 1/1 green Squirrel creature token.
SVar:TrigToken:DB$ Token | TokenScript$ g_1_1_squirrel
DeckHas:Ability$Token
Oracle:Whenever you roll a 4 or higher on a die, create a 1/1 green Squirrel creature token.

View File

@@ -6,10 +6,10 @@ K:ETBReplacement:Other:RollLoyal
SVar:RollLoyal:DB$ RollDice | Sides$ 4 | ResultSVar$ Result | SubAbility$ DBLoyalty | SpellDescription$ Add 1d4 loyalty counters to CARDNAME
SVar:DBLoyalty:DB$ PutCounter | Defined$ Self | CounterType$ LOYALTY | CounterNum$ Result | ETB$ True
A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | ValidTgts$ Opponent | TokenOwner$ Targeted | TokenScript$ b_1_1_skeleton_opp_life | Planeswalker$ True | SpellDescription$ Target opponent creates a 1/1 black Skeleton creature token with "When this creature dies, each opponent gains 2 life.""
A:AB$ RollDice | Cost$ AddCounter<1/LOYALTY> | Sides$ 2 | On1$ DBSkipTurn | ResultSVar$ Result | SubAbility$ DBDraw | SpellDescription$ Roll a d20. If you roll a 1, skip your next turn. If you roll a 12 or higher, draw a card.
A:AB$ RollDice | Cost$ AddCounter<1/LOYALTY> | Sides$ 2 | On1$ DBSkipTurn | ResultSVar$ Result | Planeswalker$ True | SubAbility$ DBDraw | SpellDescription$ Roll a d20. If you roll a 1, skip your next turn. If you roll a 12 or higher, draw a card.
SVar:DBSkipTurn:DB$ SkipTurn | Defined$ You | NumTurns$ 1
SVar:DBDraw:DB$ Draw | ConditionCheckSVar$ Result | ConditionSVarCompare$ GE12
A:AB$ Token | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | TokenScript$ r_3_3_fighter_first_strike | SubAbility$ DBCleric | SpellDescription$ You get an adventuring party. (Your party is a 3/3 red Fighter with first strike, a 1/1 white Cleric with lifelink, a 2/2 black Rogue with hexproof, and a 1/1 blue Wizard with flying.)
A:AB$ Token | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | TokenScript$ r_3_3_fighter_first_strike | SubAbility$ DBCleric | SpellDescription$ You get an adventuring party. (Your party is a 3/3 red Fighter with first strike, a 1/1 white Cleric with lifelink, a 2/2 black Rogue with hexproof, and a 1/1 blue Wizard with flying.)
SVar:DBCleric:DB$ Token | TokenScript$ w_1_1_cleric_lifelink | SubAbility$ DBRogue
SVar:DBRogue:DB$ Token | TokenScript$ b_2_2_rogue_hexproof | SubAbility$ DBWizard
SVar:DBWizard:DB$ Token | TokenScript$ u_1_1_wizard_flying

View File

@@ -2,7 +2,7 @@ Name:Ground Pounder
ManaCost:1 G
Types:Creature Goblin Warrior
PT:2/2
A:AB$ RollDice | Cost$ 3 G | ResultSVar$ X | SubAbility$ DBPump | SpellDescription$ Roll a six-sided die.
A:AB$ RollDice | Cost$ 3 G | ResultSVar$ X | SubAbility$ DBPump | AILogic$ Combat | SpellDescription$ Roll a six-sided die.
SVar:DBPump:DB$ Pump | Defined$ Self | NumAtt$ X | NumDef$ X | SpellDescription$ CARDNAME gets +X/+X until end of turn, where X is the result.
T:Mode$ RolledDie | Execute$ TrigTrample | ValidPlayer$ You | ValidResult$ GE5 | TriggerDescription$ Whenever you roll a 5 or higher on a die, CARDNAME gains trample until end of turn.
SVar:TrigTrample:DB$ Pump | Defined$ Self | KW$ Trample

View File

@@ -1,6 +1,6 @@
Name:Growth Spurt
ManaCost:1 G
Types:Instant
A:SP$ RollDice | Cost$ 1 G | ResultSVar$ X | SubAbility$ DBPump
A:SP$ RollDice | Cost$ 1 G | ResultSVar$ X | AILogic$ Combat | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | ValidTgts$ Creature | NumAtt$ X | NumDef$ X | SpellDescription$ Target creature gets +X/+X until end of turn, where X is the result.
Oracle:Roll a six-sided die. Target creature gets +X/+X until end of turn, where X is the result.

View File

@@ -5,7 +5,7 @@ PT:0/0
K:ETBReplacement:Other:RollCounters
SVar:RollCounters:DB$ RollDice | ResultSVar$ Result | SubAbility$ DBCounters | SpellDescription$ As CARDNAME enters the battlefield, roll a six-sided die. CARDNAME enters the battlefield with a number of +1/+1 counters on it equal to the total of those results.
SVar:DBCounters:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ Result | ETB$ True
T:Mode$ RolledDie | Execute$ TrigRemove | ValidPlayer$ You | TriggerDescription$ Whenever you roll a die, remove all +1/+1 counters from CARDNAME, then put a number of +1/+1 counters on it equal to the result.
T:Mode$ RolledDie | Execute$ TrigRemove | ValidPlayer$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you roll a die, remove all +1/+1 counters from CARDNAME, then put a number of +1/+1 counters on it equal to the result.
SVar:TrigRemove:DB$ RemoveCounterAll | ValidCards$ Card.Self | CounterType$ P1P1 | AllCounters$ True | SubAbility$ TrigCounters
SVar:X:TriggerCount$Result
SVar:TrigCounters:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ X

View File

@@ -2,7 +2,7 @@ Name:Mad Science Fair Project
ManaCost:3
Types:Artifact
A:AB$ Pump | Cost$ T | ValidTgts$ Player | SubAbility$ DBRoll
SVar:DBRoll:DB$ RollDice | On1$ AddC | On2$ AddC | On3$ AddC | Else$ AddAny | SpellDescription$ {T}: Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color they choose.
SVar:DBRoll:DB$ RollDice | On1$ AddC | On2$ AddC | On3$ AddC | Else$ AddAny | AILogic$ Main2 | SpellDescription$ {T}: Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color they choose.
SVar:AddC:DB$ Mana | Produced$ C | Defined$ Targeted
SVar:AddAny:DB$ Mana | Produced$ Any | Defined$ Targeted
SVar:PlayMain1:TRUE

View File

@@ -5,5 +5,5 @@ PT:1/1
T:Mode$ RolledDie | Execute$ TrigPump | ValidPlayer$ You | ValidResult$ GE5 | TriggerDescription$ Whenever you roll a 5 or higher on a die, CARDNAME gets +X/+X until end of turn, where X is the result.
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ X | NumDef$ X
SVar:X:TriggerCount$Result
A:AB$ RollDice | Cost$ 6 | SpellDescription$ Roll a six-sided die.
Oracle:{3}{G}: Roll a six-sided die. Ground Pounder gets +X/+X until end of turn, where X is the result.\nWhenever you roll a 5 or higher on a die, Ground Pounder gains trample until end of turn.
A:AB$ RollDice | Cost$ 6 | AILogic$ Combat | SpellDescription$ Roll a six-sided die.
Oracle:Whenever you roll a 5 or higher on a die, Steel Squirrel gets +X/+X until end of turn, where X is the result.\n{6}: Roll a six-sided die.

View File

@@ -2,7 +2,7 @@ Name:Urza's Science Fair Project
ManaCost:6
Types:Artifact Creature Construct
PT:4/4
A:AB$ RollDice | Cost$ 2 | On1$ M2 | On2$ Fog | On3$ Vig | On4$ FS | On5$ Fly | On6$ P2 | SpellDescription$ Roll a six-sided die. CARDNAME gets the indicated result: 1-It gets -2/-2 until end of turn. 2-Prevent all combat damage it would deal this turn. 3-It gains vigilance until end of turn. 4-It gains first strike until end of turn. 5-It gains flying until end of turn. 6-It gets +2/+2 until end of turn.
A:AB$ RollDice | Cost$ 2 | On1$ M2 | On2$ Fog | On3$ Vig | On4$ FS | On5$ Fly | On6$ P2 | AILogic$ CombatEarly | SpellDescription$ Roll a six-sided die. CARDNAME gets the indicated result: 1-It gets -2/-2 until end of turn. 2-Prevent all combat damage it would deal this turn. 3-It gains vigilance until end of turn. 4-It gains first strike until end of turn. 5-It gains flying until end of turn. 6-It gets +2/+2 until end of turn.
SVar:M2:DB$ Pump | Defined$ Self | NumAtt$ -2 | NumDef$ -2
SVar:Fog:DB$ Pump | Defined$ Self | KW$ Prevent all combat damage that would be dealt by CARDNAME.
SVar:Vig:DB$ Pump | Defined$ Self | KW$ Vigilance

View File

@@ -3,7 +3,7 @@ ManaCost:2 G
Types:Creature Spider Monkey Scientist
PT:2/2
K:Reach
T:Mode$ RolledDie | Execute$ TrigCounter | ValidPlayer$ You | ValidResult$ GE4 | TriggerDescription$ Whenever you roll a 4 or higher on a die, put a +1/+1 counter on CARDNAME.
T:Mode$ RolledDie | TriggerZones$ Battlefield | Execute$ TrigCounter | ValidPlayer$ You | ValidResult$ GE4 | TriggerDescription$ Whenever you roll a 4 or higher on a die, put a +1/+1 counter on CARDNAME.
SVar:TrigCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
A:AB$ RollDice | Cost$ 6 | SpellDescription$ Roll a six-sided die.
DeckHas:Ability$Counters

View File

@@ -42,6 +42,7 @@ Domri, City Smasher|Domri's Overrun|You may feel a slight sensation of burning r
Dovin Baan|Dovin's Static|Have you tried to turn it off and on again?
Dovin, Architect of Law|Dovin's Freeze|With one gear out of place, the whole machine grinds to halt.
Dovin, Grand Arbiter|Dovin's Modern Recall|The best solutions for the worst problems.
Dungeon Master|Dungeons and Dragons|A fighter, a wizard, a rogue, and a cleric walk into a dungeon...
Elspeth Tirel|Elspeth's Solitude|Tokens are my only friends...
Elspeth, Knight-Errant|Elspeth's Endurance|Bant will prevail!
Elspeth, Sun's Champion|Elspeth's Crusade|With Heliod on my side, I'm invincible!