- AI fix for "fight" keyword. Added "AILogic$ Main2" to Domri Rade's +1 to allow AI to choose -2 ability if available.

This commit is contained in:
excessum
2014-03-20 12:58:04 +00:00
parent 7c3bcda327
commit 9f810d131f
11 changed files with 160 additions and 56 deletions

View File

@@ -2,6 +2,7 @@ package forge.ai.ability;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.ai.*;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
@@ -12,6 +13,7 @@ import forge.game.cost.Cost;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
@@ -92,6 +94,34 @@ public class CountersPutAi extends SpellAbilityAi {
// TODO handle proper calculation of X values based on Cost
int amount = AbilityUtils.calculateAmount(source, amountStr, sa);
if (sa.getParam("AILogic").equals("Fight")) {
int nPump = 0;
if (type.equals("P1P1")) {
nPump = amount;
}
final AbilitySub tgtFight = sa.getSubAbility();
List<Card> aiCreatures = ai.getCreaturesInPlay();
aiCreatures = CardLists.getTargetableCards(aiCreatures, sa);
aiCreatures = ComputerUtil.getSafeTargets(ai, sa, aiCreatures);
CardLists.sortByPowerDesc(aiCreatures);
List<Card> humCreatures = ai.getOpponent().getCreaturesInPlay();
humCreatures = CardLists.getTargetableCards(humCreatures, tgtFight);
CardLists.sortByCmcDesc(humCreatures);
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
return false;
}
for (Card humanCreature : humCreatures) {
for (Card aiCreature : aiCreatures) {
if (FightAi.shouldFight(aiCreature, humanCreature, nPump, nPump)) {
sa.getTargets().add(aiCreature);
tgtFight.getTargets().add(humanCreature);
return true;
}
}
}
}
if (amountStr.equals("X") && source.getSVar(amountStr).equals("Count$xPaid")) {
// Set PayX here to maximum value.
amount = ComputerUtilMana.determineLeftoverMana(sa, ai);

View File

@@ -2,6 +2,8 @@ package forge.ai.ability;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCombat;
import forge.ai.SpellAbilityAi;
@@ -13,6 +15,7 @@ import forge.game.combat.CombatUtil;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetRestrictions;
@@ -120,6 +123,29 @@ public class EffectAi extends SpellAbilityAi {
}
}
randomReturn = threatened;
} else if (logic.equals("Fight")) {
List<Card> humCreatures = ai.getOpponent().getCreaturesInPlay();
humCreatures = CardLists.getTargetableCards(humCreatures, sa);
CardLists.sortByCmcDesc(humCreatures);
final AbilitySub tgtFight = sa.getSubAbility();
List<Card> aiCreatures = ai.getCreaturesInPlay();
aiCreatures = CardLists.getTargetableCards(aiCreatures, tgtFight);
aiCreatures = ComputerUtil.getSafeTargets(ai, tgtFight, aiCreatures);
CardLists.sortByPowerDesc(aiCreatures);
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
return false;
}
for (Card humanCreature : humCreatures) {
for (Card aiCreature : aiCreatures) {
if (FightAi.shouldFight(aiCreature, humanCreature, 0, 0)) {
tgtFight.getTargets().add(aiCreature);
sa.getTargets().add(humanCreature);
return true;
}
}
}
}
} else { //no AILogic
return false;

View File

@@ -53,7 +53,7 @@ public class FightAi extends SpellAbilityAi {
}
if (sa.hasParam("TargetsFromDifferentZone")) {
if (humCreatures.isEmpty() && aiCreatures.isEmpty()) {
if (!(humCreatures.isEmpty() && aiCreatures.isEmpty())) {
for (Card humanCreature : humCreatures) {
for (Card aiCreature : aiCreatures) {
if (ComputerUtilCombat.getDamageToKill(humanCreature) <= aiCreature.getNetAttack()
@@ -135,5 +135,29 @@ public class FightAi extends SpellAbilityAi {
return true;
}
public static boolean shouldFight(Card fighter, Card opponent, int pumpAttack, int pumpDefense) {
if (canKill(fighter, opponent, pumpAttack)) {
if (!canKill(opponent, fighter, -pumpDefense)) {
return true;
} else {
final Random r = MyRandom.getRandom();
if (r.nextInt(20)<(opponent.getCMC() - fighter.getCMC())) {
return true;
}
}
}
return false;
}
public static boolean canKill(Card fighter, Card opponent, int pumpAttack) {
if (opponent.getSVar("Targeting").equals("Dies")) {
return true;
}
if (opponent.hasProtectionFrom(fighter) || !opponent.canBeDestroyed()) {
return false;
}
if (fighter.hasKeyword("Deathtouch") || ComputerUtilCombat.getDamageToKill(opponent) <= fighter.getNetAttack() + pumpAttack) {
return true;
}
return false;
}
}

View File

@@ -2,6 +2,7 @@ package forge.ai.ability;
import forge.ai.SpellAbilityAi;
import forge.ai.SpellApiToAi;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.AbilityStatic;
@@ -22,6 +23,11 @@ public class PeekAndRevealAi extends SpellAbilityAi {
if (sa instanceof AbilityStatic) {
return false;
}
if (sa.getParam("AILogic").equals("Main2")) {
if (aiPlayer.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) {
return false;
}
}
// So far this only appears on Triggers, but will expand
// once things get converted from Dig + NoMove
return true;

View File

@@ -13,6 +13,7 @@ import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityRestriction;
import forge.game.spellability.TargetRestrictions;
@@ -211,9 +212,31 @@ public class PumpAi extends PumpAiBase {
} else {
return false;
}
} else {
}
if (sa.getParam("AILogic").equals("Fight")) {
final AbilitySub tgtFight = sa.getSubAbility();
List<Card> aiCreatures = ai.getCreaturesInPlay();
aiCreatures = CardLists.getTargetableCards(aiCreatures, sa);
aiCreatures = ComputerUtil.getSafeTargets(ai, sa, aiCreatures);
CardLists.sortByPowerDesc(aiCreatures);
List<Card> humCreatures = ai.getOpponent().getCreaturesInPlay();
humCreatures = CardLists.getTargetableCards(humCreatures, tgtFight);
CardLists.sortByCmcDesc(humCreatures);
if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
return false;
}
for (Card humanCreature : humCreatures) {
for (Card aiCreature : aiCreatures) {
if (FightAi.shouldFight(aiCreature, humanCreature, attack, defense)) {
sa.getTargets().add(aiCreature);
tgtFight.getTargets().add(humanCreature);
return true;
}
}
}
}
return false;
} else if (sa.isCurse()) {
if (sa.canTarget(opp)) {
sa.getTargets().add(opp);

View File

@@ -2,10 +2,10 @@ Name:Domri Rade
ManaCost:1 R G
Types:Planeswalker Domri
Loyalty:3
A:AB$ PeekAndReveal | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | PeekAmount$ 1 | RevealValid$ Creature | RevealOptional$ True | RememberRevealed$ True | SubAbility$ DBChangeZone | SpellDescription$ Look at the top card of your library. If it's a creature card, you may reveal it and put it into your hand.
A:AB$ PeekAndReveal | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | AILogic$ Main2 | PeekAmount$ 1 | RevealValid$ Creature | RevealOptional$ True | RememberRevealed$ True | SubAbility$ DBChangeZone | SpellDescription$ Look at the top card of your library. If it's a creature card, you may reveal it and put it into your hand.
SVar:DBChangeZone:DB$ ChangeZone | Defined$ TopOfLibrary | Origin$ Library | Destination$ Hand | ConditionDefined$ Remembered | ConditionPresent$ Creature | ConditionCompare$ EQ1 | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ Pump | Cost$ SubCounter<2/LOYALTY> | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control | Planeswalker$ True | SubAbility$ DomriFight | StackDescription$ None | SpellDescription$ Target creature you control fights another target creature.
A:AB$ Pump | Cost$ SubCounter<2/LOYALTY> | ValidTgts$ Creature.YouCtrl | AILogic$ Fight | TgtPrompt$ Choose target creature you control | Planeswalker$ True | SubAbility$ DomriFight | StackDescription$ None | SpellDescription$ Target creature you control fights another target creature.
SVar:DomriFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature | TargetUnique$ True | TgtPrompt$ Choose another target creature to fight the first target creature
A:AB$ Effect | Cost$ SubCounter<7/LOYALTY> | Name$ Domri Rade emblem | Image$ domri_rade_emblem | StaticAbilities$ STDomri | Planeswalker$ True | Ultimate$ True | Stackable$ False | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "Creatures you control have double strike, trample, hexproof and haste."
SVar:STDomri:Mode$ Continuous | EffectZone$ Command | Affected$ Creature.YouCtrl | AffectedZone$ Battlefield | AddKeyword$ Double Strike & Trample & Hexproof & Haste

View File

@@ -1,9 +1,7 @@
Name:Hunt the Hunter
ManaCost:G
Types:Sorcery
A:SP$ Pump | Cost$ G | ValidTgts$ Creature.YouCtrl+Green | TgtPrompt$ Select target green creature you control | SubAbility$ DBFight | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Target green creature you control gets +2/+2 until end of turn. It fights target green creature an opponent controls.
A:SP$ Pump | Cost$ G | ValidTgts$ Creature.YouCtrl+Green | AILogic$ Fight | TgtPrompt$ Select target green creature you control | SubAbility$ DBFight | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Target green creature you control gets +2/+2 until end of turn. It fights target green creature an opponent controls.
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.OppCtrl+Green | TgtPrompt$ Select target green creature an opponent controls
SVar:RemRandomDeck:True
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/hunt_the_hunter.jpg
Oracle:Target green creature you control gets +2/+2 until end of turn. It fights target green creature an opponent controls.

View File

@@ -1,8 +1,7 @@
Name:Hunt the Weak
ManaCost:3 G
Types:Sorcery
A:SP$ PutCounter | Cost$ 3 G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control to put a +1/+1 counter | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBFight | SpellDescription$ Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.
A:SP$ PutCounter | Cost$ 3 G | AILogic$ Fight | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control to put a +1/+1 counter | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBFight | SpellDescription$ Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/hunt_the_weak.jpg
Oracle:Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control. (Each deals damage equal to its power to the other.)

View File

@@ -1,8 +1,7 @@
Name:Mutant's Prey
ManaCost:G
Types:Instant
A:SP$ Pump | Cost$ G | ValidTgts$ Creature.YouCtrl+counters_GE1_P1P1 | TgtPrompt$ Select target creature you control with a +1/+1 counter | SubAbility$ DBFight | SpellDescription$ Target creature you control with a +1/+1 counter on it fights target creature an opponent controls.
A:SP$ Pump | Cost$ G | AILogic$ Fight | ValidTgts$ Creature.YouCtrl+counters_GE1_P1P1 | TgtPrompt$ Select target creature you control with a +1/+1 counter | SubAbility$ DBFight | SpellDescription$ Target creature you control with a +1/+1 counter on it fights target creature an opponent controls.
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls
SVar:RemRandomDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/mutants_prey.jpg
Oracle:Target creature you control with a +1/+1 counter on it fights target creature an opponent controls. (Each deals damage equal to its power to the other.)

View File

@@ -1,7 +1,7 @@
Name:Pit Fight
ManaCost:1 RG
Types:Instant
A:SP$ Pump | Cost$ 1 RG | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control | SubAbility$ DBPitFight | StackDescription$ None | SpellDescription$ Target creature you control fights another target creature.
A:SP$ Pump | Cost$ 1 RG | AILogic$ Fight | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control | SubAbility$ DBPitFight | StackDescription$ None | SpellDescription$ Target creature you control fights another target creature.
SVar:DBPitFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature | TargetUnique$ True | TgtPrompt$ Choose target creature to fight the first target
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/pit_fight.jpg

View File

@@ -1,10 +1,9 @@
Name:Time to Feed
ManaCost:2 G
Types:Sorcery
A:SP$ Effect | Cost$ 2 G | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an oppoenent controls | RememberObjects$ Targeted | Triggers$ TrigDies | SVars$ TrigGainLife | SubAbility$ DBFight | SpellDescription$ Choose target creature an opponent controls. When that creature dies this turn, you gain 3 life. Target creature you control fights that creature.
A:SP$ Effect | Cost$ 2 G | ValidTgts$ Creature.OppCtrl | AILogic$ Fight | TgtPrompt$ Select target creature an oppoenent controls | RememberObjects$ Targeted | Triggers$ TrigDies | SVars$ TrigGainLife | SubAbility$ DBFight | SpellDescription$ Choose target creature an opponent controls. When that creature dies this turn, you gain 3 life. Target creature you control fights that creature.
SVar:TrigDies:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.IsRemembered | OneOff$ True | Execute$ TrigGainLife | TriggerDescription$ When that creature dies this turn, you gain 3 life.
SVar:TrigGainLife:AB$ GainLife | Cost$ 0 | LifeAmount$ 3
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control to fight the first target
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/time_to_feed.jpg
Oracle:Choose target creature an opponent controls. When that creature dies this turn, you gain 3 life. Target creature you control fights that\ncreature. (Each deals damage equal to its power to the other.)