diff --git a/.gitattributes b/.gitattributes index ac8d23a4e1d..39381f5881a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10127,6 +10127,7 @@ src/main/java/forge/card/abilityFactory/AbilityFactory_AlterLife.java svneol=nat src/main/java/forge/card/abilityFactory/AbilityFactory_Animate.java svneol=native#text/plain src/main/java/forge/card/abilityFactory/AbilityFactory_Attach.java svneol=native#text/plain src/main/java/forge/card/abilityFactory/AbilityFactory_ChangeZone.java svneol=native#text/plain +src/main/java/forge/card/abilityFactory/AbilityFactory_Charm.java -text src/main/java/forge/card/abilityFactory/AbilityFactory_Choose.java svneol=native#text/plain src/main/java/forge/card/abilityFactory/AbilityFactory_Clash.java svneol=native#text/plain src/main/java/forge/card/abilityFactory/AbilityFactory_Cleanup.java svneol=native#text/plain diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 2b72af6c65f..7c183670dff 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -12,6 +12,7 @@ import forge.card.mana.ManaCost; import forge.card.mana.ManaPool; import forge.card.spellability.Ability; import forge.card.spellability.Ability_Static; +import forge.card.spellability.Ability_Sub; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility_Requirements; import forge.card.spellability.Target; @@ -2112,6 +2113,25 @@ public class GameAction { */ public final void playSpellAbility(final SpellAbility sa) { sa.setActivatingPlayer(AllZone.getHumanPlayer()); + + //make Charm choices + if (sa.isCharm()) { + ArrayList choices = new ArrayList(); + choices.addAll(sa.getCharmChoices()); + for (int i = 0; i < sa.getCharmNumber(); i++) { + Object o = GuiUtils.getChoice("Choose a spell", choices.toArray()); + Ability_Sub chosen = (Ability_Sub) o; + sa.addCharmChoice(chosen); + choices.remove(chosen); + //TODO - to support the commands, thi + /* + * TODO - to support the commands, this will need to arrange Ability_Sub items + * so that the Charm sa doesn't have multiple Ability_Subs, but instead, the + * most recent chosen Ability_Sub will be added to the bottom of the SpellAbility tree + */ + sa.setSubAbility(chosen); + } + } // Need to check PayCosts, and Ability + All SubAbilities for Target boolean newAbility = sa.getPayCosts() != null; diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory.java b/src/main/java/forge/card/abilityFactory/AbilityFactory.java index 837d9588344..50a732a4f6c 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory.java @@ -1049,6 +1049,24 @@ public class AbilityFactory { SA = AbilityFactory_Combat.createDrawbackMustAttack(this); } } + + else if (API.equals("Charm")) { + if (isAb) { + SA = AbilityFactory_Charm.createAbilityCharm(this); + } else if (isSp) { + SA = AbilityFactory_Charm.createSpellCharm(this); + } + SA.setIsCharm(true); + int num = Integer.parseInt(mapParams.containsKey("CharmNum") ? mapParams.get("CharmNum") : "1"); + SA.setCharmNumber(num); + + String[] saChoices = mapParams.get("Choices").split(","); + for(int i = 0; i < saChoices.length; i++) { + String ab = hostC.getSVar(saChoices[i]); + AbilityFactory charmAF = new AbilityFactory(); + SA.addCharmChoice(charmAF.getAbility(ab, hostC)); + } + } if (SA == null) { diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory_Charm.java b/src/main/java/forge/card/abilityFactory/AbilityFactory_Charm.java new file mode 100644 index 00000000000..8e23f9cfe72 --- /dev/null +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory_Charm.java @@ -0,0 +1,117 @@ +package forge.card.abilityFactory; + +import forge.card.spellability.Ability_Activated; +import forge.card.spellability.Ability_Sub; +import forge.card.spellability.Spell; +import forge.card.spellability.SpellAbility; + +// Charm specific params: +// Choices - a ","-delimited list of SVars containing ability choices + +/** + *

AbilityFactory_Charm class.

+ * + * @author Forge + */ +public final class AbilityFactory_Charm { + + private AbilityFactory_Charm() { + throw new AssertionError(); + } + + /** + *

createAbilityCharm.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createAbilityCharm(final AbilityFactory af) { + final SpellAbility abCharm = new Ability_Activated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { + private static final long serialVersionUID = -4038591081733095021L; + + @Override + public boolean canPlayAI() { + return charmCanPlayAI(af, this); + } + + @Override + public void resolve() { + charmResolve(af, this); + } + + @Override + public String getStackDescription() { + return charmStackDescription(af, this); + } + + @Override + public boolean doTrigger(final boolean mandatory) { + return charmCanPlayAI(af, this); + } + }; //Ability_Activated + + return abCharm; + } + + /** + *

createSpellCharm.

+ * + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @return a {@link forge.card.spellability.SpellAbility} object. + */ + public static SpellAbility createSpellCharm(final AbilityFactory af) { + final SpellAbility spCharm = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { + private static final long serialVersionUID = -7297235470289087240L; + + @Override + public boolean canPlayAI() { + return charmCanPlayAI(af, this); + } + + @Override + public void resolve() { + charmResolve(af, this); + } + + @Override + public String getStackDescription() { + return charmStackDescription(af, this); + } + }; + + return spCharm; + } + + private static String charmStackDescription(final AbilityFactory af, final SpellAbility sa) { + StringBuilder sb = new StringBuilder(); + + if (sa instanceof Ability_Sub) { + sb.append(" "); + } + else { + sb.append(sa.getSourceCard()).append(" - "); + } + //end standard begin + + //nothing stack specific for Charm + + //begin standard post + Ability_Sub abSub = sa.getSubAbility(); + if (abSub != null) { + sb.append(abSub.getStackDescription()); + } + + return sb.toString(); + } + + private static boolean charmCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + //TODO - enable Charms for the AI + return false; + } + + private static void charmResolve(final AbilityFactory af, final SpellAbility sa) { + //nothing to do. Ability_Subs are set up in GameAction.playSpellAbility(), + //and that Ability_Sub.resolve() is called from AbilityFactory + } + +} //end class AbilityFactory_Charm diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index bad57155537..45e23ff9094 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -61,6 +61,11 @@ public abstract class SpellAbility { private boolean kickerAbility = false; private boolean kothThirdAbility = false; private boolean cycling = false; + private boolean isCharm = false; + + private int charmNumber; + private ArrayList charmChoices = new ArrayList(); + //private ArrayList charmChoicesMade = new ArrayList(); private Input beforePayMana; private Input afterResolve; @@ -1243,5 +1248,96 @@ public abstract class SpellAbility { public boolean isSuppressed() { return (temporarilySuppressed); } + + /** + *

setIsCharm.

+ * + * @param b a boolean. + */ + public final void setIsCharm(final boolean b) { + isCharm = b; + } + + /** + *

isCharm.

+ * + * @return a boolean. + */ + public final boolean isCharm() { + return isCharm; + } + + /** + *

addCharmChoiceMade.

+ * + * @param sa a SpellAbility + * @since 1.1.6 + */ + /* + public final void addCharmChoiceMade(final SpellAbility sa) { + charmChoicesMade.add(sa); + } + */ + + /** + *

getCharmChoicesMade.

+ * + * @return an ArrayList + * @since 1.1.6 + */ + /* + public final ArrayList getCharmChoicesMade() { + return charmChoicesMade; + } + */ + + /** + *

clearCharmChoices.

+ * + * @since 1.1.6 + */ + /* + public final void clearCharmChoicesMade() { + charmChoicesMade.clear(); + } + */ + + /** + *

setCharmNumber.

+ * + * @param i an int + */ + public final void setCharmNumber(final int i) { + charmNumber = i; + } + + /** + *

getCharmNumber.

+ * + * @return an int + */ + public final int getCharmNumber() { + return charmNumber; + } + + /** + *

addCharmChoice.

+ * + * @param sa a SpellAbility + * @since 1.1.6 + */ + public final void addCharmChoice(final SpellAbility sa) { + charmChoices.add(sa); + } + + /** + *

getCharmChoicesMade.

+ * + * @return an ArrayList + * @since 1.1.6 + */ + public final ArrayList getCharmChoices() { + return charmChoices; + } }