diff --git a/.gitattributes b/.gitattributes index bdc3671daee..7055ffbc1a9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3469,6 +3469,7 @@ res/cardsfolder/f/fastbond.txt svneol=native#text/plain res/cardsfolder/f/fatal_attraction.txt svneol=native#text/plain res/cardsfolder/f/fatal_blow.txt svneol=native#text/plain res/cardsfolder/f/fatal_frenzy.txt svneol=native#text/plain +res/cardsfolder/f/fatal_lore.txt -text res/cardsfolder/f/fatal_mutation.txt svneol=native#text/plain res/cardsfolder/f/fatestitcher.txt svneol=native#text/plain res/cardsfolder/f/fathom_mage.txt -text @@ -5975,6 +5976,7 @@ res/cardsfolder/l/liability.txt svneol=native#text/plain res/cardsfolder/l/liberate.txt svneol=native#text/plain res/cardsfolder/l/liberated_dwarf.txt svneol=native#text/plain res/cardsfolder/l/library_of_alexandria.txt svneol=native#text/plain +res/cardsfolder/l/library_of_lat_nam.txt -text res/cardsfolder/l/library_of_leng.txt -text res/cardsfolder/l/lich.txt svneol=native#text/plain res/cardsfolder/l/lich_lord_of_unx.txt svneol=native#text/plain @@ -6684,6 +6686,7 @@ res/cardsfolder/m/mischievous_poltergeist.txt svneol=native#text/plain res/cardsfolder/m/mischievous_quanar.txt -text res/cardsfolder/m/misers_cage.txt svneol=native#text/plain res/cardsfolder/m/misery_charm.txt svneol=native#text/plain +res/cardsfolder/m/misfortune.txt -text res/cardsfolder/m/misfortunes_gain.txt svneol=native#text/plain res/cardsfolder/m/misguided_rage.txt svneol=native#text/plain res/cardsfolder/m/mishra.txt -text diff --git a/res/cardsfolder/f/fatal_lore.txt b/res/cardsfolder/f/fatal_lore.txt new file mode 100644 index 00000000000..1bd8c60fafb --- /dev/null +++ b/res/cardsfolder/f/fatal_lore.txt @@ -0,0 +1,11 @@ +Name:Fatal Lore +ManaCost:2 B B +Types:Sorcery +A:SP$ Charm | Cost$ 2 B B | Chooser$ Opponent | Choices$ DrawThree,DestroyAndDraw | SpellDescription$ An opponent chooses one - You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated. +SVar:DrawThree:DB$ Draw | NumCards$ 3 | Defined$ You | SpellDescription$ You draw three cards. +SVar:DestroyAndDraw:DB$ Destroy | ValidTgts$ Creature.ChosenCtrl | TgtPrompt$ Select target creature | TargetMin$ 0 | TargetMax$ 2 | NoRegen$ True | SpellDescription$ You destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated. | SubAbility$ ChooserDraws +SVar:ChooserDraws:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/fatal_lore.jpg +SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/7.jpg +Oracle:An opponent chooses one - You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated. diff --git a/res/cardsfolder/l/library_of_lat_nam.txt b/res/cardsfolder/l/library_of_lat_nam.txt new file mode 100644 index 00000000000..42ec77fb039 --- /dev/null +++ b/res/cardsfolder/l/library_of_lat_nam.txt @@ -0,0 +1,11 @@ +Name:Library of Lat-Nam +ManaCost:4 U +Types:Sorcery +A:SP$ Charm | Cost$ 4 U | Chooser$ Opponent | Choices$ SlowDraw,Tutor | SpellDescription$ An opponent chooses one - You draw three cards at the beginning of the next turn's upkeep; or you search your library for a card, put that card into your hand, then shuffle your library. +SVar:SlowDraw:DB$ Draw | NumCards$ 3 | Defined$ You | NextUpkeep$ True | SpellDescription$ You draw three cards at the beginning of the next turn's upkeep +SVar:Tutor:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True | SpellDescription$ You search your library for a card, put that card into your hand, then shuffle your library. +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/library_of_lat_nam.jpg +SetInfo:6ED|Rare|http://magiccards.info/scans/en/6e/78.jpg +SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/47.jpg +Oracle:An opponent chooses one - You draw three cards at the beginning of the next turn's upkeep; or you search your library for a card, put that card into your hand, then shuffle your library. diff --git a/res/cardsfolder/m/misfortune.txt b/res/cardsfolder/m/misfortune.txt new file mode 100644 index 00000000000..1713d479166 --- /dev/null +++ b/res/cardsfolder/m/misfortune.txt @@ -0,0 +1,13 @@ +Name:Misfortune +ManaCost:1 B R G +Types:Sorcery +A:SP$ Charm | Cost$ 1 B R G | Chooser$ Opponent | Choices$ Fortune,Misfortune | SpellDescription$ An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her. +SVar:Fortune:DB$ PutCounterAll | ValidCards$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBGainLife | SpellDescription$ Put a +1/+1 counter on each creature you control. You gain 4 life. | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | LifeAmount$ 4 +SVar:Misfortune:DB$ PutCounterAll | ValidCards$ Creature.ChosenCtrl | CounterType$ M1M1 | CounterNum$ 1 | SubAbility$ DBLoseLife | SpellDescription$ you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her. | SubAbility$ DBDamage +SVar:DBDamage:DB$ DealDamage | Defined$ ChosenPlayer | NumDmg$ 4 +SVar:ChooserDraws:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer +SVar:RemAIDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/misfortune.jpg +SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/194.jpg +Oracle:An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her. diff --git a/src/main/java/forge/card/ability/ai/CharmAi.java b/src/main/java/forge/card/ability/ai/CharmAi.java index fcf44b20ee0..bcdc1f4715d 100644 --- a/src/main/java/forge/card/ability/ai/CharmAi.java +++ b/src/main/java/forge/card/ability/ai/CharmAi.java @@ -4,11 +4,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import forge.card.ability.SpellAbilityAi; -import forge.card.ability.effects.CharmEffect; +import org.apache.commons.lang.math.RandomUtils; +import forge.card.ability.SpellAbilityAi;import forge.card.ability.effects.CharmEffect; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; import forge.game.player.AIPlayer; +import forge.game.player.Player; import forge.util.MyRandom; public class CharmAi extends SpellAbilityAi { @@ -22,7 +23,7 @@ public class CharmAi extends SpellAbilityAi { boolean timingRight = sa.isTrigger(); //is there a reason to play the charm now? List chooseFrom = CharmEffect.makePossibleOptions(sa); - List chosenList = chooseOptionsAi(ai, timingRight, chooseFrom, num, min); + List chosenList = chooseOptionsAi(ai, timingRight, chooseFrom, num, min, false); if (chosenList == null || chosenList.isEmpty()) { return false; @@ -32,9 +33,17 @@ public class CharmAi extends SpellAbilityAi { return r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); } - public static List chooseOptionsAi(final AIPlayer ai, boolean playNow, List choices, int num, int min) { + public static List chooseOptionsAi(final AIPlayer ai, boolean playNow, List choices, int num, int min, boolean opponentChoser) { List chosenList = new ArrayList(); + if (opponentChoser) { + // This branch is for "An Opponent chooses" Charm spells from Alliances + // Current just choose the first available spell, which seem generally less disastrous for the AI. + //return choices.subList(0, 1); + return choices.subList(1, choices.size()); + } + + for (int i = 0; i < num; i++) { AbilitySub thisPick = null; for (SpellAbility sub : choices) { @@ -57,4 +66,9 @@ public class CharmAi extends SpellAbilityAi { } return chosenList.size() >= min ? chosenList : null; } + + public static Player determineOpponentChooser(AIPlayer ai, SpellAbility sa, List opponents) { + return opponents.get(RandomUtils.nextInt(opponents.size())); + } + } diff --git a/src/main/java/forge/card/ability/effects/CharmEffect.java b/src/main/java/forge/card/ability/effects/CharmEffect.java index d1051a7e301..bddf06f663c 100644 --- a/src/main/java/forge/card/ability/effects/CharmEffect.java +++ b/src/main/java/forge/card/ability/effects/CharmEffect.java @@ -50,17 +50,37 @@ public class CharmEffect extends SpellAbilityEffect { final List choices = makePossibleOptions(sa); List chosen = null; - + Card source = sa.getSourceCard(); Player activator = sa.getActivatingPlayer(); - if (activator.isHuman()) { + Player chooser = sa.getActivatingPlayer(); + if (sa.hasParam("Chooser")) { + // Three modal cards require you to choose a player to make the modal choice' + // Two of these also reference the chosen player during the spell effect + String choose = sa.getParam("Chooser"); + List opponents = activator.getOpponents(); + int numOpps = opponents.size(); + if (numOpps == 1) { + chooser = opponents.get(0); + } else { + if (activator.isComputer()) { + chooser = CharmAi.determineOpponentChooser((AIPlayer)activator, sa, opponents); + } else { + chooser = GuiChoose.one("Choose an opponent", opponents); + } + } + source.setChosenPlayer(chooser); + } + + if (chooser.isHuman()) { + String modeTitle = String.format("%s activated %s - Choose a mode", activator, source); chosen = new ArrayList(); for (int i = 0; i < num; i++) { AbilitySub a; if (i < min) { - a = GuiChoose.one("Choose a mode", choices); + a = GuiChoose.one(modeTitle, choices); } else { - a = GuiChoose.oneOrNone("Choose a mode", choices); + a = GuiChoose.oneOrNone(modeTitle, choices); } if (null == a) { break; @@ -70,7 +90,7 @@ public class CharmEffect extends SpellAbilityEffect { chosen.add(a); } } else { - chosen = CharmAi.chooseOptionsAi((AIPlayer)activator, sa.isTrigger(), choices, num, min); + chosen = CharmAi.chooseOptionsAi((AIPlayer)chooser, sa.isTrigger(), choices, num, min, !chooser.equals(activator)); } chainAbilities(sa, chosen);