From 144156c497699ef67159307048f2e64fd48d30c9 Mon Sep 17 00:00:00 2001 From: Sol Date: Sun, 5 Mar 2017 02:53:42 +0000 Subject: [PATCH] Add Ballot Broker, Borderland Explorer, Custodi Soulcaller, Illusion of Choice (CN2) --- .gitattributes | 4 ++ .../src/main/java/forge/ai/AiController.java | 2 +- .../main/java/forge/ai/ability/VoteAi.java | 10 +++++ .../game/ability/effects/EffectEffect.java | 1 + .../game/ability/effects/VoteEffect.java | 41 ++++++++++++++++++- forge-gui/res/cardsfolder/b/ballot_broker.txt | 6 +++ .../res/cardsfolder/b/borderland_explorer.txt | 8 ++++ .../res/cardsfolder/c/custodi_soulcaller.txt | 9 ++++ .../res/cardsfolder/i/illusion_of_choice.txt | 7 ++++ 9 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/b/ballot_broker.txt create mode 100644 forge-gui/res/cardsfolder/b/borderland_explorer.txt create mode 100644 forge-gui/res/cardsfolder/c/custodi_soulcaller.txt create mode 100644 forge-gui/res/cardsfolder/i/illusion_of_choice.txt diff --git a/.gitattributes b/.gitattributes index 75350821293..72df2350bd2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2457,6 +2457,7 @@ forge-gui/res/cardsfolder/b/ball_lightning.txt svneol=native#text/plain forge-gui/res/cardsfolder/b/ballista_charger.txt -text forge-gui/res/cardsfolder/b/ballista_squad.txt svneol=native#text/plain forge-gui/res/cardsfolder/b/balloon_peddler.txt svneol=native#text/plain +forge-gui/res/cardsfolder/b/ballot_broker.txt -text forge-gui/res/cardsfolder/b/ballynock_cohort.txt svneol=native#text/plain forge-gui/res/cardsfolder/b/ballynock_trapper.txt svneol=native#text/plain forge-gui/res/cardsfolder/b/ballyrush_banneret.txt svneol=native#text/plain @@ -3053,6 +3054,7 @@ forge-gui/res/cardsfolder/b/borborygmos_enraged.txt -text forge-gui/res/cardsfolder/b/border_guard.txt svneol=native#text/plain forge-gui/res/cardsfolder/b/border_patrol.txt svneol=native#text/plain forge-gui/res/cardsfolder/b/borderland_behemoth.txt svneol=native#text/plain +forge-gui/res/cardsfolder/b/borderland_explorer.txt -text forge-gui/res/cardsfolder/b/borderland_marauder.txt -text forge-gui/res/cardsfolder/b/borderland_minotaur.txt -text forge-gui/res/cardsfolder/b/borderland_ranger.txt svneol=native#text/plain @@ -4442,6 +4444,7 @@ forge-gui/res/cardsfolder/c/curtain_of_light.txt -text forge-gui/res/cardsfolder/c/curtains_call.txt -text forge-gui/res/cardsfolder/c/custodi_lich.txt -text svneol=unset#text/plain forge-gui/res/cardsfolder/c/custodi_soulbinders.txt -text +forge-gui/res/cardsfolder/c/custodi_soulcaller.txt -text forge-gui/res/cardsfolder/c/custodi_squire.txt -text forge-gui/res/cardsfolder/c/custodian_of_the_trove.txt -text forge-gui/res/cardsfolder/c/custody_battle.txt -text svneol=unset#text/plain @@ -8267,6 +8270,7 @@ forge-gui/res/cardsfolder/i/illuminate.txt -text forge-gui/res/cardsfolder/i/illuminated_folio.txt -text forge-gui/res/cardsfolder/i/illuminated_wings.txt svneol=native#text/plain forge-gui/res/cardsfolder/i/illumination.txt svneol=native#text/plain +forge-gui/res/cardsfolder/i/illusion_of_choice.txt -text forge-gui/res/cardsfolder/i/illusion_reality.txt -text forge-gui/res/cardsfolder/i/illusionary_armor.txt -text forge-gui/res/cardsfolder/i/illusionary_forces.txt svneol=native#text/plain diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 37bdad2e9b8..e11ba26938f 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -1268,7 +1268,7 @@ public class AiController { public int chooseNumber(SpellAbility sa, String title, int min, int max) { final Card source = sa.getHostCard(); - final String logic = sa.getParam("AILogic"); + final String logic = sa.getParamOrDefault("AILogic", "Max"); if ("GainLife".equals(logic)) { if (player.getLife() < 5 || player.getCardsIn(ZoneType.Hand).size() >= player.getMaxHandSize()) { return min; diff --git a/forge-ai/src/main/java/forge/ai/ability/VoteAi.java b/forge-ai/src/main/java/forge/ai/ability/VoteAi.java index 8e01ad56625..2e6906463bf 100644 --- a/forge-ai/src/main/java/forge/ai/ability/VoteAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/VoteAi.java @@ -9,6 +9,8 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; +import java.util.Map; + public class VoteAi extends SpellAbilityAi { /* (non-Javadoc) * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility) @@ -41,4 +43,12 @@ public class VoteAi extends SpellAbilityAi { protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { return true; } + + @Override + public int chooseNumber(Player player, SpellAbility sa, int min, int max, Map params) { + if (sa.getActivatingPlayer().isOpponentOf(player)) { + return min; + } + return max; + } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java index bc168f6cc72..1901110a469 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java @@ -102,6 +102,7 @@ public class EffectEffect extends SpellAbilityEffect { final Player controller = sa.hasParam("EffectOwner") ? ownerEff : sa.getActivatingPlayer(); final Card eff = new Card(game.nextCardId(), game); + eff.setTimestamp(game.getNextTimestamp()); eff.setName(name); // if name includes emplem then it should be one eff.addType(name.endsWith("emblem") ? "Emblem" : "Effect"); diff --git a/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java b/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java index 5ea44eb6f5b..dc01adcbc12 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import com.google.common.base.Predicate; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.ArrayListMultimap; @@ -70,10 +71,48 @@ public class VoteEffect extends SpellAbilityEffect { } ListMultimap votes = ArrayListMultimap.create(); + Player voter = null; + + List voters = game.getPlayers().filter(new Predicate() { + @Override + public boolean apply(Player input) { + return input.hasKeyword("You choose how each player votes this turn."); + } + }); + + if (voters.size() > 1) { + long latestTimestamp = -1; + for(Player p : voters) { + List illusions = CardLists.filter(p.getCardsIn(ZoneType.Command), new Predicate() { + @Override + public boolean apply(Card input) { + return input.getName().equals("Illusion of Choice Effect"); + } + }); + for(Card illusion : illusions) { + if (illusion.getTimestamp() > latestTimestamp) { + latestTimestamp = illusion.getTimestamp(); + voter = p; + } + } + } + } else if (voters.size() == 1) { + voter = voters.get(0); + } + for (final Player p : tgtPlayers) { int voteAmount = p.getKeywords().getAmount("You get an additional vote.") + 1; + int optionalVotes = p.getKeywords().getAmount("You may vote an additional time."); + voteAmount += p.getController().chooseNumber(sa, "How many additional votes do you want?", 0, optionalVotes); + for (int i = 0; i < voteAmount; i++) { - final Object result = p.getController().vote(sa, host + "Vote:", voteType, votes); + Object result; + if (voter == null) { + result = p.getController().vote(sa, host + "Vote:", voteType, votes); + } else { + result = voter.getController().vote(sa, host + "Vote:", voteType, votes); + } + votes.put(result, p); host.getGame().getAction().nofityOfValue(sa, p, result + "\r\nCurrent Votes:" + votes, p); } diff --git a/forge-gui/res/cardsfolder/b/ballot_broker.txt b/forge-gui/res/cardsfolder/b/ballot_broker.txt new file mode 100644 index 00000000000..3e92c6240a0 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/ballot_broker.txt @@ -0,0 +1,6 @@ +Name:Ballot Broker +ManaCost:2 W +Types:Creature Human Advisor +PT:2/3 +S:Mode$ Continuous | Affected$ You | AddKeyword$ You may vote an additional time. | Description$ While voting, you may vote an additional time. (The votes can be for different choices or for the same choice.) +Oracle:While voting, you may vote an additional time. (The votes can be for different choices or for the same choice.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/b/borderland_explorer.txt b/forge-gui/res/cardsfolder/b/borderland_explorer.txt new file mode 100644 index 00000000000..ddd3030ce47 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/borderland_explorer.txt @@ -0,0 +1,8 @@ +Name:Borderland Explorer +ManaCost:1 G +Types:Creature Elf Scout +PT:3/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExploration | TriggerDescription$ When CARDNAME enters the battlefield, each player may discard a card. Each player who discarded a card this way may search his or her library for a basic land card, reveal it, put it into his or her hand, then shuffle his or her library. +SVar:TrigExploration:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBDiscardToFetch +SVar:DBDiscardToFetch:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Land.Basic | DefinedPlayer$ Player.IsRemembered | UnlessCost$ Discard<1/Card> | UnlessPayer$ Player.IsRemembered | UnlessSwitched$ True +Oracle:When Borderland Explorer enters the battlefield, each player may discard a card. Each player who discarded a card this way may search his or her library for a basic land card, reveal it, put it into his or her hand, then shuffle his or her library. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/c/custodi_soulcaller.txt b/forge-gui/res/cardsfolder/c/custodi_soulcaller.txt new file mode 100644 index 00000000000..d5512768280 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/custodi_soulcaller.txt @@ -0,0 +1,9 @@ +Name:Custodi Soulcaller +ManaCost:1 W W +Types:Creature Human Cleric +PT:1/2 +K:Melee +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSoulcall | TriggerDescription$ Whenever CARDNAME attacks, return target creature card with converted mana cost X or less from your graveyard to the battlefield, where X is the number of players you attacked with a creature this combat +SVar:TrigSoulcall:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.YouCtrl+cmcLEX +SVar:X:TriggeredPlayersDefenders$Amount +Oracle:Whenever Custodi Soulcaller attacks, return target creature card with converted mana cost X or less from your graveyard to the battlefield, where X is the number of players you attacked with a creature this combat \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/i/illusion_of_choice.txt b/forge-gui/res/cardsfolder/i/illusion_of_choice.txt new file mode 100644 index 00000000000..9e9def45de5 --- /dev/null +++ b/forge-gui/res/cardsfolder/i/illusion_of_choice.txt @@ -0,0 +1,7 @@ +Name:Illusion of Choice +ManaCost:U +Types:Instant +A:SP$ Effect | Cost$ U | Name$ Illusion of Choice Effect | StaticAbilities$ STVoter | SubAbilities$ DBDraw | SpellDescription$ You choose how each player votes this turn. Draw a card. +SVar:DBDraw:DB$ Draw | NumCards$ 1 +SVar:STVoter:Mode$ Continuous | EffectZone$ Command | Affected$ You | AddKeyword$ You choose how each player votes this turn. +SVar:RemAIDeck:True \ No newline at end of file