mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- Improved FightAI by considering regeneration shields and Heroic triggers that place +1/+1 counters
This commit is contained in:
@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import forge.ai.*;
|
import forge.ai.*;
|
||||||
|
import forge.game.ability.AbilityFactory;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
@@ -16,6 +17,8 @@ import forge.game.player.PlayerActionConfirmMode;
|
|||||||
import forge.game.spellability.AbilitySub;
|
import forge.game.spellability.AbilitySub;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
|
import forge.game.trigger.Trigger;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
@@ -23,6 +26,7 @@ import forge.util.MyRandom;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class CountersPutAi extends SpellAbilityAi {
|
public class CountersPutAi extends SpellAbilityAi {
|
||||||
@@ -113,6 +117,21 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
for (Card humanCreature : humCreatures) {
|
for (Card humanCreature : humCreatures) {
|
||||||
for (Card aiCreature : aiCreatures) {
|
for (Card aiCreature : aiCreatures) {
|
||||||
|
if (sa.isSpell()) { //heroic triggers adding counters
|
||||||
|
for (Trigger t : aiCreature.getTriggers()) {
|
||||||
|
if (t.getMode() == TriggerType.SpellCast) {
|
||||||
|
final Map<String, String> params = t.getMapParams();
|
||||||
|
if ("Card.Self".equals(params.get("TargetsValid")) && "You".equals(params.get("ValidActivatingPlayer"))) {
|
||||||
|
SpellAbility heroic = AbilityFactory.getAbility(aiCreature.getSVar(params.get("Execute")),aiCreature);
|
||||||
|
if ("Self".equals(heroic.getParam("Defined")) && "P1P1".equals(heroic.getParam("CounterType"))) {
|
||||||
|
int n = AbilityUtils.calculateAmount(aiCreature, heroic.getParam("CounterNum"), heroic);
|
||||||
|
nPump += n;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (FightAi.shouldFight(aiCreature, humanCreature, nPump, nPump)) {
|
if (FightAi.shouldFight(aiCreature, humanCreature, nPump, nPump)) {
|
||||||
sa.getTargets().add(aiCreature);
|
sa.getTargets().add(aiCreature);
|
||||||
tgtFight.getTargets().add(humanCreature);
|
tgtFight.getTargets().add(humanCreature);
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import forge.ai.ComputerUtilCard;
|
|||||||
import forge.ai.ComputerUtilCombat;
|
import forge.ai.ComputerUtilCombat;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityFactory;
|
||||||
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
@@ -19,10 +21,13 @@ import forge.game.spellability.AbilitySub;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
|
import forge.game.trigger.Trigger;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class EffectAi extends SpellAbilityAi {
|
public class EffectAi extends SpellAbilityAi {
|
||||||
@@ -137,9 +142,26 @@ public class EffectAi extends SpellAbilityAi {
|
|||||||
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
|
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int buffedAtk = 0, buffedDef = 0;
|
||||||
for (Card humanCreature : humCreatures) {
|
for (Card humanCreature : humCreatures) {
|
||||||
for (Card aiCreature : aiCreatures) {
|
for (Card aiCreature : aiCreatures) {
|
||||||
if (FightAi.shouldFight(aiCreature, humanCreature, 0, 0)) {
|
if (sa.isSpell()) { //heroic triggers adding counters
|
||||||
|
for (Trigger t : aiCreature.getTriggers()) {
|
||||||
|
if (t.getMode() == TriggerType.SpellCast) {
|
||||||
|
final Map<String, String> params = t.getMapParams();
|
||||||
|
if ("Card.Self".equals(params.get("TargetsValid")) && "You".equals(params.get("ValidActivatingPlayer"))) {
|
||||||
|
SpellAbility heroic = AbilityFactory.getAbility(aiCreature.getSVar(params.get("Execute")),aiCreature);
|
||||||
|
if ("Self".equals(heroic.getParam("Defined")) && "P1P1".equals(heroic.getParam("CounterType"))) {
|
||||||
|
int amount = AbilityUtils.calculateAmount(aiCreature, heroic.getParam("CounterNum"), heroic);
|
||||||
|
buffedAtk += amount;
|
||||||
|
buffedDef += amount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FightAi.shouldFight(aiCreature, humanCreature, buffedAtk, buffedDef)) {
|
||||||
tgtFight.getTargets().add(aiCreature);
|
tgtFight.getTargets().add(aiCreature);
|
||||||
sa.getTargets().add(humanCreature);
|
sa.getTargets().add(humanCreature);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -152,7 +152,8 @@ public class FightAi extends SpellAbilityAi {
|
|||||||
if (opponent.getSVar("Targeting").equals("Dies")) {
|
if (opponent.getSVar("Targeting").equals("Dies")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (opponent.hasProtectionFrom(fighter) || !opponent.canBeDestroyed()) {
|
if (opponent.hasProtectionFrom(fighter) || !opponent.canBeDestroyed()
|
||||||
|
|| !opponent.getShield().isEmpty() || ComputerUtil.canRegenerate(opponent.getController(), opponent)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fighter.hasKeyword("Deathtouch") || ComputerUtilCombat.getDamageToKill(opponent) <= fighter.getNetAttack() + pumpAttack) {
|
if (fighter.hasKeyword("Deathtouch") || ComputerUtilCombat.getDamageToKill(opponent) <= fighter.getNetAttack() + pumpAttack) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.ai.ability;
|
|||||||
|
|
||||||
import forge.ai.*;
|
import forge.ai.*;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityFactory;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
@@ -17,11 +18,14 @@ import forge.game.spellability.AbilitySub;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.SpellAbilityRestriction;
|
import forge.game.spellability.SpellAbilityRestriction;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
|
import forge.game.trigger.Trigger;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class PumpAi extends PumpAiBase {
|
public class PumpAi extends PumpAiBase {
|
||||||
|
|
||||||
@@ -235,6 +239,7 @@ public class PumpAi extends PumpAiBase {
|
|||||||
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
|
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int buffedAtk = attack, buffedDef = defense;
|
||||||
for (Card humanCreature : humCreatures) {
|
for (Card humanCreature : humCreatures) {
|
||||||
for (Card aiCreature : aiCreatures) {
|
for (Card aiCreature : aiCreatures) {
|
||||||
if (sa.getParam("AILogic").equals("PowerDmg")) {
|
if (sa.getParam("AILogic").equals("PowerDmg")) {
|
||||||
@@ -244,7 +249,23 @@ public class PumpAi extends PumpAiBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (FightAi.shouldFight(aiCreature, humanCreature, attack, defense)) {
|
if (sa.isSpell()) { //heroic triggers adding counters
|
||||||
|
for (Trigger t : aiCreature.getTriggers()) {
|
||||||
|
if (t.getMode() == TriggerType.SpellCast) {
|
||||||
|
final Map<String, String> params = t.getMapParams();
|
||||||
|
if ("Card.Self".equals(params.get("TargetsValid")) && "You".equals(params.get("ValidActivatingPlayer"))) {
|
||||||
|
SpellAbility heroic = AbilityFactory.getAbility(aiCreature.getSVar(params.get("Execute")),aiCreature);
|
||||||
|
if ("Self".equals(heroic.getParam("Defined")) && "P1P1".equals(heroic.getParam("CounterType"))) {
|
||||||
|
int amount = AbilityUtils.calculateAmount(aiCreature, heroic.getParam("CounterNum"), heroic);
|
||||||
|
buffedAtk += amount;
|
||||||
|
buffedDef += amount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FightAi.shouldFight(aiCreature, humanCreature, buffedAtk, buffedDef)) {
|
||||||
sa.getTargets().add(aiCreature);
|
sa.getTargets().add(aiCreature);
|
||||||
tgtFight.getTargets().add(humanCreature);
|
tgtFight.getTargets().add(humanCreature);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user