diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java
index 7233db6cf84..35ca5b84401 100644
--- a/src/main/java/forge/GameAction.java
+++ b/src/main/java/forge/GameAction.java
@@ -30,7 +30,9 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.card.abilityfactory.AbilityFactory;
+import forge.card.abilityfactory.ApiType;
import forge.card.abilityfactory.effects.AttachEffect;
+import forge.card.abilityfactory.effects.CharmEffect;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost;
import forge.card.cost.CostPayment;
@@ -1954,6 +1956,11 @@ public class GameAction {
public final void playSpellAbility(SpellAbility sa) {
sa.setActivatingPlayer(Singletons.getControl().getPlayer());
+ AbilityFactory af = sa.getAbilityFactory();
+ if (af != null && af.getAPI() == ApiType.Charm && !sa.isWrapper()) {
+ CharmEffect.makeChoices(sa);
+ }
+
sa = GameAction.chooseOptionalAdditionalCosts(sa);
if (sa == null) {
diff --git a/src/main/java/forge/card/abilityfactory/ApiType.java b/src/main/java/forge/card/abilityfactory/ApiType.java
index 6f88726b9b4..0abcf96ddcb 100644
--- a/src/main/java/forge/card/abilityfactory/ApiType.java
+++ b/src/main/java/forge/card/abilityfactory/ApiType.java
@@ -17,6 +17,7 @@ public enum ApiType {
Bond ( BondEffect.class, BondAi.class ),
ChangeZone(null, null), // not converted
ChangeZoneAll(ChangeZoneAllEffect.class, ChangeZoneAllAi.class), // classes extracted but not converted
+ /** This is Modal, like 'choose one - ' or 'choose two - '.
Might be great to rename this api and update all scripts.*/
Charm(CharmEffect.class, CharmAi.class),
ChooseCard ( ChooseCardEffect.class, ChooseCardAi.class ),
ChooseColor ( ChooseColorEffect.class, ChooseColorAi.class ),
diff --git a/src/main/java/forge/card/abilityfactory/ai/AttachAi.java b/src/main/java/forge/card/abilityfactory/ai/AttachAi.java
index 5abc94be327..6378d659dab 100644
--- a/src/main/java/forge/card/abilityfactory/ai/AttachAi.java
+++ b/src/main/java/forge/card/abilityfactory/ai/AttachAi.java
@@ -21,7 +21,6 @@ import forge.card.abilityfactory.ApiType;
import forge.card.abilityfactory.SpellAiLogic;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost;
-import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.card.staticability.StaticAbility;
@@ -495,12 +494,6 @@ public class AttachAi extends SpellAiLogic {
}
}
- // check SubAbilities DoTrigger?
- final AbilitySub abSub = sa.getSubAbility();
- if (abSub != null) {
- return abSub.doTrigger(mandatory);
- }
-
return true;
}
diff --git a/src/main/java/forge/card/abilityfactory/effects/CharmEffect.java b/src/main/java/forge/card/abilityfactory/effects/CharmEffect.java
index d4d5e7597ac..a32092bc668 100644
--- a/src/main/java/forge/card/abilityfactory/effects/CharmEffect.java
+++ b/src/main/java/forge/card/abilityfactory/effects/CharmEffect.java
@@ -30,7 +30,25 @@ public class CharmEffect extends SpellEffect {
@Override
public void resolve(java.util.Map params, SpellAbility sa) {
+ // all chosen modes have been chained as subabilities to this sa.
+ // so nothing to do in this resolve
+ }
+
+ @Override
+ protected String getStackDescription(java.util.Map params, SpellAbility sa) {
+ final StringBuilder sb = new StringBuilder();
+ // nothing stack specific for Charm
+
+ return sb.toString();
+ }
+
+ public static void makeChoices(SpellAbility sa) {
+ AbilityFactory af = sa.getAbilityFactory();
+ final Map params = af.getMapParams();
+ //this resets all previous choices
+ sa.setSubAbility(null);
+
final int num = Integer.parseInt(params.containsKey("CharmNum") ? params.get("CharmNum") : "1");
final int min = params.containsKey("MinCharmNum") ? Integer.parseInt(params.get("MinCharmNum")) : num;
final List choices = makePossibleOptions(sa, params);
@@ -59,21 +77,24 @@ public class CharmEffect extends SpellEffect {
else
chosen = CharmAi.chooseOptionsAi(activator, true, choices, num, min);
- // if ( null == chosen) throw Exception! // only AI might return no list at all
- for(AbilitySub as : chosen)
- {
- as.setActivatingPlayer(sa.getActivatingPlayer());
- AbilityFactory.resolve(as, false);
+ chainAbilities(sa, chosen);
+ }
+
+ private static void chainAbilities(SpellAbility sa, List chosen) {
+ SpellAbility saDeepest = sa;
+ while( saDeepest.getSubAbility() != null)
+ saDeepest = saDeepest.getSubAbility();
+
+ for(AbilitySub sub : chosen){
+ saDeepest.setSubAbility(sub);
+ sub.setActivatingPlayer(saDeepest.getActivatingPlayer());
+ sub.setParent(saDeepest);
+
+ // to chain the next one
+ saDeepest = sub;
}
}
-
-
- @Override
- protected String getStackDescription(java.util.Map params, SpellAbility sa) {
- final StringBuilder sb = new StringBuilder();
- // nothing stack specific for Charm
-
- return sb.toString();
- }
+
+
}
\ No newline at end of file
diff --git a/src/main/java/forge/card/abilityfactory/effects/UnattachAllEffect.java b/src/main/java/forge/card/abilityfactory/effects/UnattachAllEffect.java
index 0de52a03c89..1290d53f27d 100644
--- a/src/main/java/forge/card/abilityfactory/effects/UnattachAllEffect.java
+++ b/src/main/java/forge/card/abilityfactory/effects/UnattachAllEffect.java
@@ -11,7 +11,6 @@ import forge.GameEntity;
import forge.Singletons;
import forge.card.abilityfactory.SpellEffect;
import forge.card.spellability.SpellAbility;
-import forge.card.spellability.Target;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
diff --git a/src/main/java/forge/card/trigger/TriggerHandler.java b/src/main/java/forge/card/trigger/TriggerHandler.java
index 39af6459531..9b8a98ca706 100644
--- a/src/main/java/forge/card/trigger/TriggerHandler.java
+++ b/src/main/java/forge/card/trigger/TriggerHandler.java
@@ -30,6 +30,8 @@ import forge.Command;
import forge.GameActionUtil;
import forge.Singletons;
import forge.card.abilityfactory.AbilityFactory;
+import forge.card.abilityfactory.ApiType;
+import forge.card.abilityfactory.effects.CharmEffect;
import forge.card.cost.Cost;
import forge.card.spellability.Ability;
import forge.card.spellability.AbilitySub;
@@ -486,7 +488,13 @@ public class TriggerHandler {
sa[0].setActivatingPlayer(p);
}
sa[0].setStackDescription(sa[0].toString());
- // TODO - for Charms to supports AI, this needs to be removed
+ // ---TODO - for Charms to supports AI, this needs to be removed
+ //if (sa[0].getActivatingPlayer().isHuman()) {
+ final AbilityFactory af = sa[0].getAbilityFactory();
+ if (af != null && af.getAPI() == ApiType.Charm && !sa[0].isWrapper()) {
+ CharmEffect.makeChoices(sa[0]);
+ }
+ //}
boolean mand = false;
if (params.containsKey("OptionalDecider")) {
sa[0].setOptionalTrigger(true);