From dd759352de3161c7f73d893148b38b6e81deec8f Mon Sep 17 00:00:00 2001 From: Hanmac Date: Sat, 22 Dec 2018 09:04:05 +0100 Subject: [PATCH] Keyword: add Adapt --- .../java/forge/ai/ComputerUtilCombat.java | 40 +++++++++++++------ .../java/forge/ai/ability/CountersPutAi.java | 4 ++ .../src/main/java/forge/game/card/Card.java | 2 +- .../java/forge/game/card/CardFactoryUtil.java | 18 +++++++++ .../main/java/forge/game/keyword/Keyword.java | 1 + .../res/cardsfolder/upcoming/aeromunculus.txt | 8 ++++ 6 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/aeromunculus.txt diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 9fbd2ab58bc..481cab38688 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -1052,11 +1052,15 @@ public class ComputerUtilCombat { if (!ability.hasParam("CounterType") || !ability.getParam("CounterType").equals("P1P1")) { continue; } - + if (ability.hasParam("Monstrosity") && blocker.isMonstrous()) { - continue; + continue; } - + + if (ability.hasParam("Adapt") && blocker.getCounters(CounterType.P1P1) > 0) { + continue; + } + if (ComputerUtilCost.canPayCost(ability, blocker.getController())) { int pBonus = AbilityUtils.calculateAmount(ability.getHostCard(), ability.getParam("CounterNum"), ability); if (pBonus > 0) { @@ -1224,11 +1228,15 @@ public class ComputerUtilCombat { if (!ability.hasParam("CounterType") || !ability.getParam("CounterType").equals("P1P1")) { continue; } - + if (ability.hasParam("Monstrosity") && blocker.isMonstrous()) { - continue; + continue; } - + + if (ability.hasParam("Adapt") && blocker.getCounters(CounterType.P1P1) > 0) { + continue; + } + if (ComputerUtilCost.canPayCost(ability, blocker.getController())) { int tBonus = AbilityUtils.calculateAmount(ability.getHostCard(), ability.getParam("CounterNum"), ability); if (tBonus > 0) { @@ -1442,11 +1450,15 @@ public class ComputerUtilCombat { if (!ability.hasParam("CounterType") || !ability.getParam("CounterType").equals("P1P1")) { continue; } - + if (ability.hasParam("Monstrosity") && attacker.isMonstrous()) { - continue; + continue; } - + + if (ability.hasParam("Adapt") && blocker.getCounters(CounterType.P1P1) > 0) { + continue; + } + if (!ability.getPayCosts().hasTapCost() && ComputerUtilCost.canPayCost(ability, attacker.getController())) { int pBonus = AbilityUtils.calculateAmount(ability.getHostCard(), ability.getParam("CounterNum"), ability); if (pBonus > 0) { @@ -1675,11 +1687,15 @@ public class ComputerUtilCombat { if (!ability.hasParam("CounterType") || !ability.getParam("CounterType").equals("P1P1")) { continue; } - + if (ability.hasParam("Monstrosity") && attacker.isMonstrous()) { - continue; + continue; } - + + if (ability.hasParam("Adapt") && blocker.getCounters(CounterType.P1P1) > 0) { + continue; + } + if (!ability.getPayCosts().hasTapCost() && ComputerUtilCost.canPayCost(ability, attacker.getController())) { int tBonus = AbilityUtils.calculateAmount(ability.getHostCard(), ability.getParam("CounterNum"), ability); if (tBonus > 0) { diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java index cb7d60ce4e5..8499e2921de 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -311,6 +311,10 @@ public class CountersPutAi extends SpellAbilityAi { return false; } + if (sa.hasParam("Adapt") && source.getCounters(CounterType.P1P1) > 0) { + return false; + } + // TODO handle proper calculation of X values based on Cost int amount = AbilityUtils.calculateAmount(source, amountStr, sa); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 4463c639640..205b82422ae 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1662,7 +1662,7 @@ public class Card extends GameEntity implements Comparable { || keyword.equals("Undaunted") || keyword.startsWith("Monstrosity") || keyword.startsWith("Embalm") || keyword.startsWith("Level up") || keyword.equals("Prowess") || keyword.startsWith("Eternalize") || keyword.startsWith("Reinforce") || keyword.startsWith("Champion") || keyword.startsWith("Prowl") - || keyword.startsWith("Amplify") || keyword.startsWith("Ninjutsu") + || keyword.startsWith("Amplify") || keyword.startsWith("Ninjutsu") || keyword.startsWith("Adapt") || keyword.startsWith("Cycling") || keyword.startsWith("TypeCycling")) { // keyword parsing takes care of adding a proper description } else if (keyword.startsWith("CantBeBlockedByAmount")) { diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 2fba1dfd121..7c94bf77427 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3676,6 +3676,24 @@ public class CardFactoryUtil { inst.addSpellAbility(newSA); } + } else if (keyword.startsWith("Adapt")) { + final String[] k = keyword.split(":"); + final String magnitude = k[1]; + final String manacost = k[2]; + + String desc = "Adapt " + magnitude; + + String effect = "AB$ PutCounter | Cost$ " + manacost + " | ConditionPresent$ " + + "Card.Self+counters_EQ0_P1P1 | Adapt$ True | CounterNum$ " + magnitude + + " | CounterType$ P1P1 | StackDescription$ SpellDescription"; + + effect += "| SpellDescription$ " + desc + " (" + inst.getReminderText() + ")"; + + final SpellAbility sa = AbilityFactory.getAbility(effect, card); + sa.setIntrinsic(intrinsic); + + sa.setTemporary(!intrinsic); + inst.addSpellAbility(sa); } else if (keyword.equals("Aftermath") && card.getCurrentStateName().equals(CardStateName.RightSplit)) { // Aftermath does modify existing SA, and does not add new one diff --git a/forge-game/src/main/java/forge/game/keyword/Keyword.java b/forge-game/src/main/java/forge/game/keyword/Keyword.java index b5272d5199d..d4f02e84311 100644 --- a/forge-game/src/main/java/forge/game/keyword/Keyword.java +++ b/forge-game/src/main/java/forge/game/keyword/Keyword.java @@ -13,6 +13,7 @@ import forge.util.TextUtil; public enum Keyword { UNDEFINED(SimpleKeyword.class, false, ""), ABSORB(KeywordWithAmount.class, false, "If a source would deal damage to this creature, prevent %d of that damage."), + ADAPT(KeywordWithCostAndAmount.class, false, "If this creature has no +1/+1 counters on it, put {%2$d:+1/+1 counter} on it."), AFFINITY(KeywordWithType.class, false, "This spell costs you {1} less to cast for each %s you control."), AFFLICT(KeywordWithAmount.class, false, "Whenever this creature becomes blocked, defending player loses %d life."), AFTERLIFE(KeywordWithAmount.class, false, "When this creature dies, create {%1$d:1/1 white and black Spirit creature token} with flying."), diff --git a/forge-gui/res/cardsfolder/upcoming/aeromunculus.txt b/forge-gui/res/cardsfolder/upcoming/aeromunculus.txt new file mode 100644 index 00000000000..a0028624591 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/aeromunculus.txt @@ -0,0 +1,8 @@ +Name:Aeromunculus +ManaCost:1 G U +Types:Creature Homunculus Mutant +PT:2/3 +K:Flying +K:Adapt:1:2 G U +DeckHas:Ability$Counters +Oracle:Flying\n{2}{G}{U}: Adapt 1. (If this creature has no +1/+1 counters on it, put a +1/+1 counter on it.)