mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
Merge branch 'goadai' into 'master'
GoadAi: improve targeting for triggers See merge request core-developers/forge!6010
This commit is contained in:
@@ -1318,7 +1318,6 @@ public class AiBlockController {
|
||||
}
|
||||
|
||||
int evalAtk = ComputerUtilCard.evaluateCreature(attacker, true, false);
|
||||
int evalBlk = ComputerUtilCard.evaluateCreature(blocker, true, false);
|
||||
boolean atkEmbalm = (attacker.hasStartOfKeyword("Embalm") || attacker.hasStartOfKeyword("Eternalize")) && !attacker.isToken();
|
||||
boolean blkEmbalm = (blocker.hasStartOfKeyword("Embalm") || blocker.hasStartOfKeyword("Eternalize")) && !blocker.isToken();
|
||||
|
||||
@@ -1327,10 +1326,13 @@ public class AiBlockController {
|
||||
chance = Math.max(0, chance - chanceModForEmbalm);
|
||||
}
|
||||
|
||||
if (blocker.isFaceDown() && !checkingOther && blocker.getState(CardStateName.Original).getType().isCreature()) {
|
||||
int evalBlk;
|
||||
if (blocker.isFaceDown() && blocker.getView().canFaceDownBeShownTo(ai.getView(), false) && blocker.getState(CardStateName.Original).getType().isCreature()) {
|
||||
// if the blocker is a face-down creature (e.g. cast via Morph, Manifest), evaluate it
|
||||
// in relation to the original state, not to the Morph state
|
||||
evalBlk = ComputerUtilCard.evaluateCreature(Card.fromPaperCard(blocker.getPaperCard(), ai), false, true);
|
||||
} else {
|
||||
evalBlk = ComputerUtilCard.evaluateCreature(blocker, true, false);
|
||||
}
|
||||
int chanceToSavePW = chanceToTradeDownToSaveWalker > 0 && evalAtk + 1 < evalBlk ? chanceToTradeDownToSaveWalker : chanceToTradeToSaveWalker;
|
||||
boolean powerParityOrHigher = blocker.getNetPower() <= attacker.getNetPower();
|
||||
|
||||
@@ -30,7 +30,7 @@ public class GoadAi extends SpellAbilityAi {
|
||||
if (list.isEmpty())
|
||||
return false;
|
||||
|
||||
if (game.getPlayers().size() >= 2) {
|
||||
if (game.getPlayers().size() > 2) {
|
||||
// use this part only in multiplayer
|
||||
CardCollection betterList = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -79,10 +79,43 @@ public class GoadAi extends SpellAbilityAi {
|
||||
|
||||
// AI does not find a good creature to goad.
|
||||
// because if it would goad a creature it would attack AI.
|
||||
// AI might not have enough infomation to block it
|
||||
// AI might not have enough information to block it
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||
if (checkApiLogic(ai, sa)) {
|
||||
return true;
|
||||
}
|
||||
if (!mandatory) {
|
||||
return false;
|
||||
}
|
||||
if (sa.usesTargeting()) {
|
||||
if (sa.getTargetRestrictions().canTgtPlayer()) {
|
||||
for (Player opp : ai.getOpponents()) {
|
||||
if (sa.canTarget(opp)) {
|
||||
sa.getTargets().add(opp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (sa.canTarget(ai)) {
|
||||
sa.getTargets().add(ai);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
List<Card> list = CardLists.getTargetableCards(ai.getGame().getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
if (list.isEmpty())
|
||||
return false;
|
||||
|
||||
sa.getTargets().add(ComputerUtilCard.getWorstCreatureAI(list));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ReplaceDamageAi extends SpellAbilityAi {
|
||||
if (c.hasSVar("MustBeBlocked")) {
|
||||
return c;
|
||||
}
|
||||
// TODO check if target can receive counters
|
||||
// TODO check if target can receive counters + sort these to the front if that can prevent loss
|
||||
if (c.hasKeyword(Keyword.INFECT)) {
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class RevealAi extends RevealAiBase {
|
||||
@Override
|
||||
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
||||
// we can reuse this function here...
|
||||
final boolean bFlag = revealHandTargetAI(ai, sa/* , true, false */);
|
||||
final boolean bFlag = revealHandTargetAI(ai, sa, false);
|
||||
|
||||
if (!bFlag) {
|
||||
return false;
|
||||
@@ -80,7 +80,7 @@ public class RevealAi extends RevealAiBase {
|
||||
|
||||
}
|
||||
|
||||
if (!revealHandTargetAI(ai, sa/*, false, mandatory*/)) {
|
||||
if (!revealHandTargetAI(ai, sa, mandatory)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import forge.game.zone.ZoneType;
|
||||
|
||||
public abstract class RevealAiBase extends SpellAbilityAi {
|
||||
|
||||
protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa) {
|
||||
protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa, boolean mandatory) {
|
||||
if (sa.usesTargeting()) {
|
||||
// ability is targeted
|
||||
sa.resetTargets();
|
||||
@@ -29,7 +29,7 @@ public abstract class RevealAiBase extends SpellAbilityAi {
|
||||
|
||||
Player p = Collections.max(opps, PlayerPredicates.compareByZoneSize(ZoneType.Hand));
|
||||
|
||||
if (p.getCardsIn(ZoneType.Hand).isEmpty()) {
|
||||
if (!mandatory && p.getCardsIn(ZoneType.Hand).isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
sa.getTargets().add(p);
|
||||
@@ -45,7 +45,7 @@ public abstract class RevealAiBase extends SpellAbilityAi {
|
||||
*/
|
||||
@Override
|
||||
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
|
||||
revealHandTargetAI(ai, sa);
|
||||
revealHandTargetAI(ai, sa, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class RevealHandAi extends RevealAiBase {
|
||||
*/
|
||||
@Override
|
||||
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
||||
final boolean bFlag = revealHandTargetAI(ai, sa/*, true, false*/);
|
||||
final boolean bFlag = revealHandTargetAI(ai, sa, false);
|
||||
|
||||
if (!bFlag) {
|
||||
return false;
|
||||
@@ -29,8 +29,7 @@ public class RevealHandAi extends RevealAiBase {
|
||||
|
||||
@Override
|
||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||
|
||||
return revealHandTargetAI(ai, sa/*, false, mandatory*/);
|
||||
return revealHandTargetAI(ai, sa, mandatory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user