@@ -1324,6 +1324,10 @@ public void declareAttackers(Player attacker, Combat combat) {
13241324 // Check if we can reinforce with Banding creatures
13251325 aiAtk .reinforceWithBanding (combat );
13261326
1327+ // Per CR 508.1d, the decision to pay attack costs (e.g. Propaganda)
1328+ // is made at declaration time. Remove attackers the AI can't pay for.
1329+ removeUnpayableAttackers (combat );
1330+
13271331 // if invalid: just try an attack declaration that we know to be legal
13281332 if (!CombatUtil .validateAttackers (combat )) {
13291333 combat .clearAttackers ();
@@ -1343,6 +1347,22 @@ public void declareAttackers(Player attacker, Combat combat) {
13431347 }
13441348 }
13451349
1350+ private void removeUnpayableAttackers (Combat combat ) {
1351+ for (Card attacker : new ArrayList <>(combat .getAttackers ())) {
1352+ Cost attackCost = CombatUtil .getAttackCost (game , attacker , combat .getDefenderByAttacker (attacker ));
1353+ if (attackCost == null ) {
1354+ continue ;
1355+ }
1356+ SpellAbility fakeSA = new SpellAbility .EmptySa (attacker , attacker .getController ());
1357+ fakeSA .setCardState (attacker .getCurrentState ());
1358+ fakeSA .setPayCosts (attackCost );
1359+ fakeSA .setSVar ("X" , "0" );
1360+ if (!ComputerUtilCost .canPayCost (attackCost , fakeSA , player , true )) {
1361+ combat .removeFromCombat (attacker );
1362+ }
1363+ }
1364+ }
1365+
13461366 private List <SpellAbility > singleSpellAbilityList (SpellAbility sa ) {
13471367 if (sa == null ) {
13481368 return null ;
0 commit comments