From bd7da33e779cbc1c35939bb7368e302b10a4918c Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 22 Jun 2018 12:04:08 +0300 Subject: [PATCH 1/5] - Fix logic in DamageDealAi, update logic for Chandra, Fire of Kaladesh. --- forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java | 7 ++++++- forge-gui/res/cardsfolder/c/chandra_fire_of_kaladesh.txt | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index 1e78c806dda..92f40adaad3 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -491,6 +491,10 @@ public class DamageDealAi extends DamageAiBase { sa.getTargets().add(enemy); } return true; + } else if ("PingAfterCombat".equals(sa.getParam("AILogic"))) { + if (this.shouldTgtP(ai, sa, dmg, noPrevention)) { + + } } if (tgt.getMaxTargets(source, sa) <= 0) { @@ -657,7 +661,7 @@ public class DamageDealAi extends DamageAiBase { } } - } else if (tgt.canTgtCreature() || tgt.canTgtPlaneswalker()) { + } else if (tgt.canTgtCreature()) { final Card c = this.dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, mandatory); if (c != null) { //option to hold removal instead only applies for single targeted removal @@ -693,6 +697,7 @@ public class DamageDealAi extends DamageAiBase { else if (sa.canTarget(enemy)) { if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) || (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2)) + || ("PingAfterAttack".equals(sa.getParam("AILogic")) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) || sa.getPayCosts() == null || immediately || this.shouldTgtP(ai, sa, dmg, noPrevention)) && (!avoidTargetP(ai, sa))) { diff --git a/forge-gui/res/cardsfolder/c/chandra_fire_of_kaladesh.txt b/forge-gui/res/cardsfolder/c/chandra_fire_of_kaladesh.txt index 8833de984e7..4fcad74d274 100644 --- a/forge-gui/res/cardsfolder/c/chandra_fire_of_kaladesh.txt +++ b/forge-gui/res/cardsfolder/c/chandra_fire_of_kaladesh.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Human Shaman PT:2/2 T:Mode$ SpellCast | ValidCard$ Card.Red | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a red spell, untap CARDNAME. SVar:TrigUntap:DB$ Untap | Defined$ Self -A:AB$ DealDamage | Cost$ T | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 1 | References$ X | SubAbility$ DBTransform | SpellDescription$ CARDNAME deals 1 damage to target player or planeswalker. If CARDNAME has dealt 3 or more damage this turn, exile her, then return her to the battlefield transformed under her owner's control. +A:AB$ DealDamage | Cost$ T | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 1 | References$ X | SubAbility$ DBTransform | AILogic$ PingAfterAttack | SpellDescription$ CARDNAME deals 1 damage to target player or planeswalker. If CARDNAME has dealt 3 or more damage this turn, exile her, then return her to the battlefield transformed under her owner's control. SVar:DBTransform:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | SubAbility$ DBReturn | ConditionCheckSVar$ X | ConditionSVarCompare$ GE3 | References$ X | StackDescription$ If CARDNAME has dealt 3 or more damage this turn, exile her, then return her to the battlefield transformed under her owner's control. SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield | Transformed$ True | WithCounters$ LOYALTY_4 | SubAbility$ DBCleanup | StackDescription$ SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True From 44985478241aba13f02a19a41d0c57f5e0035c38 Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 22 Jun 2018 12:06:17 +0300 Subject: [PATCH 2/5] - Remove unused code. --- forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index 92f40adaad3..3c712d1bd6a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -491,10 +491,6 @@ public class DamageDealAi extends DamageAiBase { sa.getTargets().add(enemy); } return true; - } else if ("PingAfterCombat".equals(sa.getParam("AILogic"))) { - if (this.shouldTgtP(ai, sa, dmg, noPrevention)) { - - } } if (tgt.getMaxTargets(source, sa) <= 0) { From 07383f7c4cd6a4f25fce33d1b6360a4c4b1301b7 Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 22 Jun 2018 12:07:20 +0300 Subject: [PATCH 3/5] - Minor code tweak. --- forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index 3c712d1bd6a..be160bf03c0 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -693,7 +693,7 @@ public class DamageDealAi extends DamageAiBase { else if (sa.canTarget(enemy)) { if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) || (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2)) - || ("PingAfterAttack".equals(sa.getParam("AILogic")) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) + || ("PingAfterAttack".equals(sa.getParam("AILogic")) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai)) || sa.getPayCosts() == null || immediately || this.shouldTgtP(ai, sa, dmg, noPrevention)) && (!avoidTargetP(ai, sa))) { From f192e1cf2758e4c4cea472d300e8ad4a9bb0990c Mon Sep 17 00:00:00 2001 From: Agetian Date: Fri, 22 Jun 2018 13:26:34 +0300 Subject: [PATCH 4/5] - Different logic update, seems more appropriate. --- forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index be160bf03c0..67d821d5bfe 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -657,7 +657,7 @@ public class DamageDealAi extends DamageAiBase { } } - } else if (tgt.canTgtCreature()) { + } else if (tgt.canTgtCreature() || tgt.canTgtPlaneswalker()) { final Card c = this.dealDamageChooseTgtC(ai, sa, dmg, noPrevention, enemy, mandatory); if (c != null) { //option to hold removal instead only applies for single targeted removal @@ -690,7 +690,7 @@ public class DamageDealAi extends DamageAiBase { } // TODO: Improve Damage, we shouldn't just target the player just // because we can - else if (sa.canTarget(enemy)) { + if (sa.canTarget(enemy) && tcs.getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) || (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2)) || ("PingAfterAttack".equals(sa.getParam("AILogic")) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai)) From efe493d179530291174777ed22868c362469e89b Mon Sep 17 00:00:00 2001 From: Agetian Date: Sun, 24 Jun 2018 09:17:01 +0300 Subject: [PATCH 5/5] - Unify AI logic checks. --- .../main/java/forge/ai/ability/DamageDealAi.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index 67d821d5bfe..d55ad8aa463 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -481,10 +481,11 @@ public class DamageDealAi extends DamageAiBase { final PhaseHandler phase = game.getPhaseHandler(); final boolean divided = sa.hasParam("DividedAsYouChoose"); final boolean oppTargetsChoice = sa.hasParam("TargetingPlayer"); + final String logic = sa.getParamOrDefault("AILogic", ""); Player enemy = ComputerUtil.getOpponentFor(ai); - if ("PowerDmg".equals(sa.getParam("AILogic"))) { + if ("PowerDmg".equals(logic)) { // check if it is better to target the player instead, the original target is already set in PumpAi.pumpTgtAI() if (tgt.canTgtCreatureAndPlayer() && this.shouldTgtP(ai, sa, dmg, noPrevention)){ sa.resetTargets(); @@ -504,11 +505,11 @@ public class DamageDealAi extends DamageAiBase { TargetChoices tcs = sa.getTargets(); // Do not use if would kill self - if (("SelfDamage".equals(sa.getParam("AILogic"))) && (ai.getLife() <= Integer.parseInt(source.getSVar("SelfDamageAmount")))) { + if (("SelfDamage".equals(logic)) && (ai.getLife() <= Integer.parseInt(source.getSVar("SelfDamageAmount")))) { return false; } - if ("ChoiceBurn".equals(sa.getParam("AILogic"))) { + if ("ChoiceBurn".equals(logic)) { // do not waste burns on player if other choices are present if (this.shouldTgtP(ai, sa, dmg, noPrevention)) { tcs.add(enemy); @@ -517,7 +518,7 @@ public class DamageDealAi extends DamageAiBase { return false; } } - if ("Polukranos".equals(sa.getParam("AILogic"))) { + if ("Polukranos".equals(logic)) { int dmgTaken = 0; CardCollection humCreatures = enemy.getCreaturesInPlay(); Card lastTgt = null; @@ -681,7 +682,7 @@ public class DamageDealAi extends DamageAiBase { } continue; } - } else if ("OppAtTenLife".equals(sa.getParam("AILogic"))) { + } else if ("OppAtTenLife".equals(logic)) { for (final Player p : ai.getOpponents()) { if (sa.canTarget(p) && p.getLife() == 10 && tcs.getNumTargeted() < tgt.getMaxTargets(source, sa)) { tcs.add(p); @@ -693,7 +694,7 @@ public class DamageDealAi extends DamageAiBase { if (sa.canTarget(enemy) && tcs.getNumTargeted() < tgt.getMaxTargets(source, sa)) { if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) || (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2)) - || ("PingAfterAttack".equals(sa.getParam("AILogic")) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai)) + || ("PingAfterAttack".equals(logic) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai)) || sa.getPayCosts() == null || immediately || this.shouldTgtP(ai, sa, dmg, noPrevention)) && (!avoidTargetP(ai, sa))) {