From 8abb8e784d441050327caefb5fb4698dfc06a8b4 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 27 Nov 2020 15:47:27 -0500 Subject: [PATCH] Double agenda - Summoner's Bond! --- forge-ai/src/main/java/forge/ai/GameState.java | 12 ++++++++++++ .../main/java/forge/ai/simulation/GameCopier.java | 4 +++- .../forge/game/ability/effects/SetStateEffect.java | 10 ++++++++-- forge-game/src/main/java/forge/game/card/Card.java | 13 +++++++++++++ .../main/java/forge/game/card/CardFactoryUtil.java | 11 ++++++++++- .../src/main/java/forge/game/card/CardProperty.java | 4 ++++ .../src/main/java/forge/game/card/CardView.java | 6 ++++++ .../src/main/java/forge/game/player/Player.java | 7 ++++++- .../java/forge/trackable/TrackableProperty.java | 1 + forge-gui/res/blockdata/printsheets.txt | 4 ++-- forge-gui/res/cardsfolder/s/summoners_bond.txt | 9 +++++++++ .../src/main/java/forge/card/CardDetailUtil.java | 3 +++ 12 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 forge-gui/res/cardsfolder/s/summoners_bond.txt diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index dfb054f81ec..6dd774ab0c8 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -79,6 +79,7 @@ public abstract class GameState { private final Map> cardToRememberedId = new HashMap<>(); private final Map> cardToImprintedId = new HashMap<>(); private final Map cardToNamedCard = new HashMap<>(); + private final Map cardToNamedCard2 = new HashMap<>(); private final Map cardToExiledWithId = new HashMap<>(); private final Map cardAttackMap = new HashMap<>(); @@ -325,6 +326,9 @@ public abstract class GameState { if (!c.getNamedCard().isEmpty()) { newText.append("|NamedCard:").append(c.getNamedCard()); } + if (!c.getNamedCard2().isEmpty()) { + newText.append("|NamedCard2:").append(c.getNamedCard2()); + } List chosenCardIds = Lists.newArrayList(); for (Object obj : c.getChosenCards()) { @@ -1057,6 +1061,12 @@ public abstract class GameState { c.setNamedCard(entry.getValue()); } + // Named card 2 + for (Entry entry : cardToNamedCard2.entrySet()) { + Card c = entry.getKey(); + c.setNamedCard2(entry.getValue()); + } + // Chosen cards for (Entry entry : cardToChosenCards.entrySet()) { Card c = entry.getKey(); @@ -1285,6 +1295,8 @@ public abstract class GameState { cardToChosenCards.put(c, chosen); } else if (info.startsWith("NamedCard:")) { cardToNamedCard.put(c, info.substring(info.indexOf(':') + 1)); + } else if (info.startsWith("NamedCard2:")) { + cardToNamedCard2.put(c, info.substring(info.indexOf(':') + 1)); } else if (info.startsWith("ExecuteScript:")) { cardToScript.put(c, info.substring(info.indexOf(':') + 1)); } else if (info.startsWith("RememberedCards:")) { diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java index e67711c42ee..671dc4f40b9 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java @@ -342,7 +342,9 @@ public class GameCopier { if (!c.getNamedCard().isEmpty()) { newCard.setNamedCard(c.getNamedCard()); } - + if (!c.getNamedCard2().isEmpty()) { + newCard.setNamedCard2(c.getNamedCard()); + } newCard.setSVars(c.getSVars()); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 31fa50157a9..ee23c3d0dd5 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -121,8 +121,14 @@ public class SetStateEffect extends SpellAbilityEffect { String sb = p + " has unmanifested " + tgt.getName(); game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb); } else if (hiddenAgenda) { - String sb = p + " has revealed " + tgt.getName() + " with the chosen name " + tgt.getNamedCard(); - game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb); + if (tgt.hasKeyword("Double agenda")) { + String sb = p + " has revealed " + tgt.getName() + " with the chosen names " + + tgt.getNamedCard() + " and " + tgt.getNamedCard2(); + game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb); + } else { + String sb = p + " has revealed " + tgt.getName() + " with the chosen name " + tgt.getNamedCard(); game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb); + game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb); + } } game.fireEvent(new GameEventCardStatsChanged(tgt)); if (sa.hasParam("Mega")) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 6f2dfea20dd..bd2a7131d34 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -232,6 +232,7 @@ public class Card extends GameEntity implements Comparable { private String chosenType = ""; private List chosenColors; private String chosenName = ""; + private String chosenName2 = ""; private Integer chosenNumber; private Player chosenPlayer; private EvenOdd chosenEvenOdd = null; @@ -1542,6 +1543,7 @@ public class Card extends GameEntity implements Comparable { public boolean hasChosenName() { return chosenName != null; } + public boolean hasChosenName2() { return chosenName2 != null; } public String getChosenName() { return chosenName; @@ -1550,6 +1552,13 @@ public class Card extends GameEntity implements Comparable { chosenName = s; view.updateNamedCard(this); } + public String getChosenName2() { + return chosenName2; + } + public final void setChosenName2(final String s) { + chosenName2 = s; + view.updateNamedCard2(this); + } public boolean hasChosenEvenOdd() { return chosenEvenOdd != null; @@ -1571,6 +1580,10 @@ public class Card extends GameEntity implements Comparable { public final void setNamedCard(final String s) { setChosenName(s); } + public final String getNamedCard2() { return getChosenName2(); } + public final void setNamedCard2(final String s) { + setChosenName2(s); + } public final boolean getDrawnThisTurn() { return drawnThisTurn; diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 62dd67f34a0..c76a02b86cc 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -198,10 +198,19 @@ public class CardFactoryUtil { Predicate cpp = Predicates.alwaysTrue(); //Predicate pc = Predicates.in(player.getAllCards()); // TODO This would be better to send in the player's deck, not all cards - String name = player.getController().chooseCardName(sa, cpp, "Card", "Name a card for " + card.getName()); + String name = player.getController().chooseCardName(sa, cpp, "Card", + "Name a card for " + card.getName()); if (name == null || name.isEmpty()) { return false; } + if (card.hasKeyword("Double agenda")) { + String name2 = player.getController().chooseCardName(sa, cpp, "Card", + "Name a second card for " + card.getName()); + if (name2 == null || name2.isEmpty()) { + return false; + } + card.setNamedCard2(name2); + } card.setNamedCard(name); card.turnFaceDown(); diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 6b952216b37..613a518ff5b 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -54,6 +54,10 @@ public class CardProperty { if (!card.sharesNameWith(source.getNamedCard())) { return false; } + } else if (property.equals("NamedCard2")) { + if (!card.sharesNameWith(source.getNamedCard2())) { + return false; + } } else if (property.equals("NamedByRememberedPlayer")) { if (!source.hasRemembered()) { final Card newCard = game.getCardState(source); diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index a2cd74fe17c..4132509142a 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -369,6 +369,12 @@ public class CardView extends GameEntityView { void updateNamedCard(Card c) { set(TrackableProperty.NamedCard, c.getNamedCard()); } + public String getNamedCard2() { + return get(TrackableProperty.NamedCard2); + } + void updateNamedCard2(Card c) { + set(TrackableProperty.NamedCard2, c.getNamedCard2()); + } public boolean mayPlayerLook(PlayerView pv) { TrackableCollection col = get(TrackableProperty.PlayerMayLook); diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index a8d7d7aad00..2fb3783d30d 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -104,6 +104,7 @@ public class Player extends GameEntity implements Comparable { private boolean unlimitedHandSize = false; private Card lastDrawnCard = null; private String namedCard = ""; + private String namedCard2 = ""; private int numDrawnThisTurn = 0; private int numDrawnThisDrawStep = 0; private int numDiscardedThisTurn = 0; @@ -1905,6 +1906,10 @@ public class Player extends GameEntity implements Comparable { public final void setNamedCard(final String s) { namedCard = s; } + public final String getNamedCard2() { return namedCard2; } + public final void setNamedCard2(final String s) { + namedCard2 = s; + } public final int getTurn() { return stats.getTurnsPlayed(); @@ -2898,7 +2903,7 @@ public class Player extends GameEntity implements Comparable { // Conspiracies for (IPaperCard cp : registeredPlayer.getConspiracies()) { Card conspire = Card.fromPaperCard(cp, this); - if (conspire.hasKeyword("Hidden agenda")) { + if (conspire.hasKeyword("Hidden agenda") || conspire.hasKeyword("Double agenda")) { if (!CardFactoryUtil.handleHiddenAgenda(this, conspire)) { continue; } diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 223e48c22a2..c1c1c09f676 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -56,6 +56,7 @@ public enum TrackableProperty { ChosenMode(TrackableTypes.StringType), Remembered(TrackableTypes.StringType), NamedCard(TrackableTypes.StringType), + NamedCard2(TrackableTypes.StringType), PlayerMayLook(TrackableTypes.PlayerViewCollectionType, FreezeMode.IgnoresFreeze), EntityAttachedTo(TrackableTypes.GameEntityViewType), EncodedCards(TrackableTypes.CardViewCollectionType), diff --git a/forge-gui/res/blockdata/printsheets.txt b/forge-gui/res/blockdata/printsheets.txt index 9dc780e4cfd..49c9d388543 100644 --- a/forge-gui/res/blockdata/printsheets.txt +++ b/forge-gui/res/blockdata/printsheets.txt @@ -1029,7 +1029,7 @@ Hymn of the Wilds Incendiary Dissent Natural Unity #Sovereign's Realm -#Summoner's Bond +Summoner's Bond Weight Advantage [KLD Planeswalker Decks] @@ -3579,7 +3579,7 @@ Hymn of the Wilds Incendiary Dissent Natural Unity #Sovereign's Realm -#Summoner's Bond +Summoner's Bond Weight Advantage Kaya, Ghost Assassin|CN2|2 diff --git a/forge-gui/res/cardsfolder/s/summoners_bond.txt b/forge-gui/res/cardsfolder/s/summoners_bond.txt new file mode 100644 index 00000000000..4c5226b3182 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/summoners_bond.txt @@ -0,0 +1,9 @@ +Name:Summoner's Bond +ManaCost:no cost +Types:Conspiracy +K:Double agenda +T:Mode$ SpellCast | ValidCard$ Creature.NamedCard | ValidActivatingPlayer$ You | Execute$ TrigSearch | OptionalDecider$ You | TriggerDescription$ Whenever you cast a creature spell with one of the chosen names, you may search your library for a creature card with the other chosen name, reveal it, put it into your hand, then shuffle your library. +T:Mode$ SpellCast | ValidCard$ Creature.NamedCard2 | ValidActivatingPlayer$ You | Execute$ TrigSearch2 | OptionalDecider$ You | Secondary$ True | TriggerDescription$ Whenever you cast a creature spell with one of the chosen names, you may search your library for a creature card with the other chosen name, reveal it, put it into your hand, then shuffle your library. +SVar:TrigSearch:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Creature.NamedCard2 +SVar:TrigSearch2:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Creature.NamedCard +Oracle:Double agenda (Start the game with this conspiracy face down in the command zone and secretly choose two different card names. You may turn this conspiracy face up any time and reveal those names.)\nWhenever you cast a creature spell with one of the chosen names, you may search your library for a creature card with the other chosen name, reveal it, put it into your hand, then shuffle your library. diff --git a/forge-gui/src/main/java/forge/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/card/CardDetailUtil.java index 8694427ce53..af141b97c6e 100644 --- a/forge-gui/src/main/java/forge/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/card/CardDetailUtil.java @@ -442,6 +442,9 @@ public class CardDetailUtil { area.append("Hidden"); } else { area.append(card.getNamedCard()); + if (!card.getNamedCard2().isEmpty()) { + area.append(", ").append(card.getNamedCard2()); + } } area.append(")"); }