diff --git a/.gitattributes b/.gitattributes index c2e3dc86cfb..39f541d42f1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1811,6 +1811,7 @@ res/cardsfolder/c/choking_fumes.txt svneol=native#text/plain res/cardsfolder/c/choking_sands.txt svneol=native#text/plain res/cardsfolder/c/choking_tethers.txt svneol=native#text/plain res/cardsfolder/c/choking_vines.txt -text +res/cardsfolder/c/choose_your_champion.txt -text res/cardsfolder/c/chord_of_calling.txt -text res/cardsfolder/c/chorus_of_might.txt -text res/cardsfolder/c/chorus_of_woe.txt svneol=native#text/plain diff --git a/res/cardsfolder/c/choose_your_champion.txt b/res/cardsfolder/c/choose_your_champion.txt new file mode 100644 index 00000000000..9925c47b63b --- /dev/null +++ b/res/cardsfolder/c/choose_your_champion.txt @@ -0,0 +1,10 @@ +Name:Choose Your Champion +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ ChooseChampion | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, target opponent chooses a player. Until your next turn, only you and the chosen player can cast spells and attack with creatures. +SVar:ChooseChampion:AB$ ChoosePlayer | Cost$ 0 | ValidTgts$ Opponent | Choices$ Player | AILogic$ BestAllyBoardPosition | SubAbility$ PrepChamps +SVar:PrepChamps:DB$ Effect | RememberObjects$ ChosenPlayer,You | Name$ Choose Your Champion Scheme | Duration$ UntilYourNextTurn | StaticAbilities$ RestrictAttackers,RestrictCasting +SVar:RestrictAttackers:Mode$ Continuous | Affected$ Creature.nonRememberedPlayerCtrl | AddHiddenKeyword$ CARDNAME can't attack. | EffectZone$ Command | Description$ Until your next turn, only you and the chosen player can attack with creatures. +SVar:RestrictCasting:Mode$ CantBeCast | ValidCard$ Card | Caster$ Player.IsNotRemembered | EffectZone$ Command | Description$ Until your next turn, only you and the chosen player can cast spells. +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/choose_your_champion.jpg +Oracle:When you set this scheme in motion, target opponent chooses a player. Until your next turn, only you and the chosen player can cast spells and attack with creatures. diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index d4c2b21b0a7..e6bdb0f91c2 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -5386,6 +5386,17 @@ public class Card extends GameEntity implements Comparable { } } } + } else if (property.startsWith("nonRememberedPlayerCtrl")) { + if (source.getRemembered().isEmpty()) { + final Card newCard = game.getCardState(source); + if (newCard.getRemembered().contains(this.getController())) { + return false; + } + } + + if (source.getRemembered().contains(this.getController())) { + return false; + } } else if (property.equals("TargetedPlayerCtrl")) { for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) { final SpellAbility saTargeting = sa.getSATargetingPlayer(); diff --git a/src/main/java/forge/card/ability/ai/ChoosePlayerAi.java b/src/main/java/forge/card/ability/ai/ChoosePlayerAi.java index e587b7c1ca6..69be6489c1b 100644 --- a/src/main/java/forge/card/ability/ai/ChoosePlayerAi.java +++ b/src/main/java/forge/card/ability/ai/ChoosePlayerAi.java @@ -4,6 +4,7 @@ import java.util.List; import forge.card.ability.SpellAbilityAi; import forge.card.spellability.SpellAbility; +import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; public class ChoosePlayerAi extends SpellAbilityAi { @@ -45,6 +46,16 @@ public class ChoosePlayerAi extends SpellAbilityAi { } } else if ("Pump".equals(sa.getParam("AILogic"))) { chosen = choices.contains(ai) ? ai : choices.get(0); + } else if ("BestAllyBoardPosition".equals(sa.getParam("AILogic"))) { + List prefChoices = choices; + prefChoices.removeAll(ai.getOpponents()); + if (!prefChoices.isEmpty()) { + chosen = ComputerUtilCard.evaluateBoardPosition(prefChoices); + } + if (chosen == null) { + System.out.println("No good curse choices. Picking first available: " + choices.get(0)); + chosen = choices.get(0); + } } else { System.out.println("Default player choice logic."); chosen = choices.contains(ai) ? ai : choices.get(0); diff --git a/src/main/java/forge/card/ability/effects/EffectEffect.java b/src/main/java/forge/card/ability/effects/EffectEffect.java index b8189353a02..52aa89dbd29 100644 --- a/src/main/java/forge/card/ability/effects/EffectEffect.java +++ b/src/main/java/forge/card/ability/effects/EffectEffect.java @@ -169,8 +169,10 @@ public class EffectEffect extends SpellAbilityEffect { // Set Remembered if (effectRemembered != null) { - for (final Object o : AbilityUtils.getDefinedObjects(hostCard, effectRemembered, sa)) { - eff.addRemembered(o); + for (final String rem : effectRemembered.split(",")) { + for (final Object o : AbilityUtils.getDefinedObjects(hostCard, rem, sa)) { + eff.addRemembered(o); + } } } diff --git a/src/main/java/forge/game/ai/ComputerUtilCard.java b/src/main/java/forge/game/ai/ComputerUtilCard.java index 638df9b4b81..f05930c5f76 100644 --- a/src/main/java/forge/game/ai/ComputerUtilCard.java +++ b/src/main/java/forge/game/ai/ComputerUtilCard.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; + import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -31,6 +32,7 @@ import forge.deck.Deck; import forge.deck.DeckSection; import forge.game.combat.Combat; import forge.game.player.Player; +import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; @@ -820,4 +822,40 @@ public class ComputerUtilCard { } }; + /** + *

+ * evaluateBoardPosition. + *

+ * + * @param listToEvaluate + * a list of players to evaluate. + * @return a Player. + */ + public static Player evaluateBoardPosition(final List listToEvaluate) { + Player bestBoardPosition = listToEvaluate.get(0); + int bestBoardRating = 0; + + for (final Player p : listToEvaluate) { + int pRating = p.getLife() * 3; + pRating += p.getLandsInPlay().size() * 2; + + for (final Card c : p.getCardsIn(ZoneType.Battlefield)) { + pRating += ComputerUtilCard.evaluateCreature(c) / 3; + } + + if (p.getCardsIn(ZoneType.Library).size() < 3) { + pRating /= 5; + } + + System.out.println("Board position evaluation for " + p + ": " + pRating); + + if (pRating > bestBoardRating) { + bestBoardRating = pRating; + bestBoardPosition = p; + } + } + + return bestBoardPosition; + } + }