Bunch of fixes (#2706)

* Fix Tawnos's Coffin not using ETB counters

* Cost fix

* Saga tweaks

---------

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59>
This commit is contained in:
tool4ever
2023-03-19 20:07:03 +01:00
committed by GitHub
parent 7b78a2052d
commit 25d2aa82b6
14 changed files with 67 additions and 39 deletions

View File

@@ -355,6 +355,31 @@ public class AiController {
return false;
}
}
for (final Trigger tr : card.getTriggers()) {
if (!card.hasStartOfKeyword("Saga") && !card.hasStartOfKeyword("Read ahead")) {
break;
}
if (tr.getMode() != TriggerType.CounterAdded) {
continue;
}
SpellAbility exSA = tr.ensureAbility().copy(activator);
if (api != null && exSA.getApi() == api) {
rightapi = true;
}
if (exSA instanceof AbilitySub && !doTrigger(exSA, false)) {
// AI would not run this chapter if given the chance
// TODO eventually we'll want to consider playing it anyway, especially if Read ahead would still allow an immediate benefit
return false;
}
break;
}
if (api != null && !rightapi) {
return false;
}

View File

@@ -177,7 +177,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
// TODO Determine exile from same zone for AI
return null;
} else {
CardCollectionView chosen = ComputerUtil.chooseExileFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c, ability);
CardCollectionView chosen = ComputerUtil.chooseExileFrom(player, cost, source, c, ability);
return null == chosen ? null : PaymentDecision.card(chosen);
}
}

View File

@@ -66,6 +66,7 @@ import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.cost.Cost;
import forge.game.cost.CostDiscard;
import forge.game.cost.CostExile;
import forge.game.cost.CostPart;
import forge.game.cost.CostPayment;
import forge.game.cost.CostPutCounter;
@@ -641,9 +642,14 @@ public class ComputerUtil {
return sacList;
}
public static CardCollection chooseExileFrom(final Player ai, final ZoneType zone, final String type, final Card activate,
final Card target, final int amount, SpellAbility sa) {
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
public static CardCollection chooseExileFrom(final Player ai, CostExile cost, final Card activate, final int amount, SpellAbility sa) {
CardCollection typeList;
if (cost.zoneRestriction != 1) {
typeList = new CardCollection(ai.getGame().getCardsIn(cost.from));
} else {
typeList = new CardCollection(ai.getCardsIn(cost.from));
}
typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), activate.getController(), activate, sa);
// don't exile the card we're pumping
typeList = ComputerUtilCost.paymentChoicesWithoutTargets(typeList, sa, ai);

View File

@@ -2410,7 +2410,6 @@ public class ComputerUtilCombat {
// (currently looks for the creature with maximum raw power since that's what the AI usually judges by when
// deciding whether the creature is worth blocking).
// If the creature doesn't change into anything, returns the original creature.
if (attacker == null) { return null; }
Card attackerAfterTrigs = attacker;
// Test for some special triggers that can change the creature in combat

View File

@@ -1412,7 +1412,7 @@ public class AttachAi extends SpellAbilityAi {
}
// avoid randomly moving the equipment back and forth between several creatures in one turn
if (AiCardMemory.isRememberedCard(aiPlayer, sa.getHostCard(), AiCardMemory.MemorySet.ATTACHED_THIS_TURN) && !mandatory) {
if (AiCardMemory.isRememberedCard(aiPlayer, attachSource, AiCardMemory.MemorySet.ATTACHED_THIS_TURN) && !mandatory) {
return null;
}
@@ -1423,7 +1423,7 @@ public class AttachAi extends SpellAbilityAi {
}
}
AiCardMemory.rememberCard(aiPlayer, sa.getHostCard(), AiCardMemory.MemorySet.ATTACHED_THIS_TURN);
AiCardMemory.rememberCard(aiPlayer, attachSource, AiCardMemory.MemorySet.ATTACHED_THIS_TURN);
if (c == null && mandatory) {
CardLists.shuffle(list);
@@ -1674,12 +1674,6 @@ public class AttachAi extends SpellAbilityAi {
if (c == null) {
return false;
}
if (sa.getHostCard() == null) {
// FIXME: Not sure what should the resolution be if a SpellAbility has no host card. This should
// not happen normally. Possibly remove this block altogether? (if it's an impossible condition).
System.out.println("AttachAi: isUsefulAttachAction unexpectedly called with SpellAbility with no host card. Assuming it's a determined useful action.");
return true;
}
// useless to equip a creature that can't attack or block.
return !sa.getHostCard().isEquipment() || !ComputerUtilCard.isUselessCreature(ai, c);

View File

@@ -69,7 +69,6 @@ public class CloneAi extends SpellAbilityAi {
bFlag = true;
}
}
}
if (!bFlag) { // All of the defined stuff is cloned, not very useful

View File

@@ -1221,4 +1221,12 @@ public class CountersPutAi extends CountersAi {
return false;
}
@Override
public int chooseNumber(Player player, SpellAbility sa, int min, int max, Map<String, Object> params) {
if (sa.hasParam("ReadAhead")) {
return 1;
}
return max;
}
}