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 f79ef70be24..67373fa9dcb 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -2113,6 +2113,14 @@ public class CardProperty { return false; } return names.contains(card.getName()); + } else if (property.equals("NotedTypes")) { + String types = sourceController.getDraftNotes().get(spellAbility.getHostCard().getName()); + if (types == null || types.isEmpty()) { + return false; + } + List typeList = Lists.newArrayList(types.split(",")); + + return Iterables.any(card.getType().getCreatureTypes(), typeList::contains); } else if (property.startsWith("Triggered")) { if (spellAbility instanceof SpellAbility) { final String key = property.substring(9); diff --git a/forge-gui/res/cardsfolder/p/paliano_vanguard.txt b/forge-gui/res/cardsfolder/p/paliano_vanguard.txt new file mode 100644 index 00000000000..8050b5dc4a9 --- /dev/null +++ b/forge-gui/res/cardsfolder/p/paliano_vanguard.txt @@ -0,0 +1,8 @@ +Name:Paliano Vanguard +ManaCost:1 W +Types:Creature Human Soldier +PT:2/2 +Draft:Draft CARDNAME face up. +Draft:As you draft a creature card, you may reveal it, note its creature types, then turn CARDNAME face down. +S:Mode$ Continuous | Affected$ Creature.Other+NotedTypes+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other creatures you control of a type you noted for cards named Paliano Vanguard get +1/+1. +Oracle:Draft Paliano Vanguard face up.\nAs you draft a creature card, you may reveal it, note its creature types, then turn Paliano Vanguard face down.\nOther creatures you control of a type you noted for cards named Paliano Vanguard get +1/+1. \ No newline at end of file diff --git a/forge-gui/res/editions/Conspiracy Take the Crown.txt b/forge-gui/res/editions/Conspiracy Take the Crown.txt index 55e42a265f4..659f7ddc348 100644 --- a/forge-gui/res/editions/Conspiracy Take the Crown.txt +++ b/forge-gui/res/editions/Conspiracy Take the Crown.txt @@ -249,6 +249,7 @@ Hymn of the Wilds Incendiary Dissent Natural Unity Noble Banneret +Paliano Vanguard Pyretic Hunter Sovereign's Realm Summoner's Bond diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java index 7b23d166a1a..f16ce6b2056 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java @@ -30,9 +30,10 @@ public class LimitedPlayer { private static final int CanTradeAfterDraft = 1 << 4; private static final int AnimusRemoveFromPool = 1 << 5; private static final int NobleBanneretActive = 1 << 6; + private static final int PalianoVanguardActive = 1 << 7; private static final int MAXFLAGS = CantDraftThisRound | ReceiveLastCard | CanRemoveAfterDraft | SpyNextCardDrafted - | CanTradeAfterDraft | AnimusRemoveFromPool | NobleBanneretActive; + | CanTradeAfterDraft | AnimusRemoveFromPool | NobleBanneretActive | PalianoVanguardActive; private int playerFlags = 0; @@ -103,14 +104,15 @@ public class LimitedPlayer { } alreadyRevealed |= handleNobleBanneret(bestPick); + alreadyRevealed |= handlePalianoVanguard(bestPick); - - if (bestPick.getRules().getMainPart().getDraftActions() == null) { + Iterable draftActions = bestPick.getRules().getMainPart().getDraftActions(); + if (draftActions == null || !draftActions.iterator().hasNext()) { return true; } // Draft Actions - Iterable draftActions = bestPick.getRules().getMainPart().getDraftActions(); + if (Iterables.contains(draftActions, "Reveal CARDNAME as you draft it.")) { if (!alreadyRevealed) { revealed.add(bestPick); @@ -165,11 +167,9 @@ public class LimitedPlayer { playerFlags |= AnimusRemoveFromPool; } else if (Iterables.contains(draftActions, "As you draft a creature card, you may reveal it, note its name, then turn CARDNAME face down.")) { playerFlags |= NobleBanneretActive; + } else if (Iterables.contains(draftActions, "As you draft a creature card, you may reveal it, note its creature types, then turn CARDNAME face down.")) { + playerFlags |= PalianoVanguardActive; } - // As you draft a VALID, you may remove it face up. (It's no longer in your draft pool) - // TODO We need a deck section that's not your sideboard but is your cardpool? - // Keyword absorption: If creature is absorbed, it gains all the abilities of the creature it absorbed. This includes - // flying, first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, reach, and vigilance. } // Note who passed it to you. (Either player before you in draft passing order except if you receive the last card @@ -222,13 +222,17 @@ public class LimitedPlayer { } protected boolean removeWithAnimus(PaperCard bestPick) { - return SGuiChoose.one("Remove this " + bestPick + " from the draft for ANnimus of Predation?", Lists.newArrayList("Yes", "No")).equals("Yes"); + return SGuiChoose.one("Remove this " + bestPick + " from the draft for Animus of Predation?", Lists.newArrayList("Yes", "No")).equals("Yes"); } protected boolean revealWithBanneret(PaperCard bestPick) { return SGuiChoose.one("Reveal this " + bestPick + " for Noble Banneret?", Lists.newArrayList("Yes", "No")).equals("Yes"); } + protected boolean revealWithVanguard(PaperCard bestPick) { + return SGuiChoose.one("Reveal this " + bestPick + " for Paliano Vanguard?", Lists.newArrayList("Yes", "No")).equals("Yes"); + } + public String name() { if (this instanceof LimitedPlayerAI) { return "Player[" + order + "]"; @@ -353,6 +357,55 @@ public class LimitedPlayer { return alreadyRevealed; } + public boolean handlePalianoVanguard(PaperCard bestPick) { + boolean alreadyRevealed = false; + if ((playerFlags & PalianoVanguardActive) != PalianoVanguardActive) { + return false; + } + + if (!bestPick.getRules().getType().isCreature()) { + return false; + } + + boolean remaining = false; + PaperCard found = null; + + for(PaperCard c : faceUp) { + if (c.getName().equals("Paliano Vanguard")) { + if (found == null) { + found = c; + } else { + remaining = true; + break; + } + } + } + + if (found == null) { + playerFlags &= ~PalianoVanguardActive; + return false; + } + + if (!revealWithVanguard(bestPick)) { + return false; + } + + // As you draft a creature card, you may reveal it, note its name, then turn CARDNAME face down. + List note = noted.computeIfAbsent(found.getName(), k -> Lists.newArrayList()); + revealed.add(bestPick); + note.addAll(bestPick.getRules().getType().getCreatureTypes()); + addLog(name() + " revealed " + bestPick.getName() + " and noted - " + TextUtil.join(bestPick.getRules().getType().getCreatureTypes(), ",") + " for Paliano Vanguard."); + addLog(name() + " has flipped Paliano Vanguard face down."); + alreadyRevealed = true; + + faceUp.remove(found); + + if (!remaining) { + playerFlags &= ~PalianoVanguardActive; + } + return alreadyRevealed; + } + /* public void addSingleBoosterPack(boolean random) { // TODO Lore Seeker diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayerAI.java b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayerAI.java index 777826332ad..fe12b1c754d 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayerAI.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayerAI.java @@ -9,6 +9,7 @@ import forge.localinstance.properties.ForgePreferences; import java.util.Collections; import java.util.List; +import java.util.Set; public class LimitedPlayerAI extends LimitedPlayer { protected DeckColors deckCols; @@ -91,4 +92,23 @@ public class LimitedPlayerAI extends LimitedPlayer { List nobleBanneret = getDraftNotes().getOrDefault("Noble Banneret", null); return nobleBanneret == null || !nobleBanneret.contains(bestPick.getName()); } + + @Override + protected boolean revealWithVanguard(PaperCard bestPick) { + // Just choose the first creature that we haven't noted types of yet. + // This is a very simple heuristic, but it's good enough for now. + if (!bestPick.getRules().getType().isCreature()) { + return false; + } + + List notedTypes = getDraftNotes().getOrDefault("Paliano Vanguard", null); + + Set types = bestPick.getRules().getType().getCreatureTypes(); + + if (notedTypes == null || types.isEmpty()) { + return false; + } + + return types.containsAll(notedTypes); + } }