Skip to content

Commit 43bb33b

Browse files
authored
VentureEffect: move Dungeon to Tokens (Card-Forge#9404)
1 parent 844012a commit 43bb33b

File tree

14 files changed

+51
-62
lines changed

14 files changed

+51
-62
lines changed

forge-ai/src/main/java/forge/ai/PlayerControllerAi.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,30 +1540,6 @@ public CardState chooseSingleCardState(SpellAbility sa, List<CardState> states,
15401540
return SpellApiToAi.Converter.get(sa).chooseCardState(player, sa, states, params);
15411541
}
15421542

1543-
@Override
1544-
public Card chooseDungeon(Player ai, List<PaperCard> dungeonCards, String message) {
1545-
// TODO: improve the conditions that define which dungeon is a viable option to choose
1546-
List<String> dungeonNames = Lists.newArrayList();
1547-
for (PaperCard pc : dungeonCards) {
1548-
dungeonNames.add(pc.getName());
1549-
}
1550-
1551-
// Don't choose Tomb of Annihilation when life in danger unless we can win right away or can't lose for 0 life
1552-
int lifeInDanger = AiProfileUtil.getIntProperty(player, AiProps.AI_IN_DANGER_THRESHOLD);
1553-
if ((ai.getLife() <= lifeInDanger && !ai.cantLoseForZeroOrLessLife())
1554-
&& !(ai.getLife() > 1 && ai.getWeakestOpponent().getLife() == 1)) {
1555-
dungeonNames.remove("Tomb of Annihilation");
1556-
}
1557-
1558-
try {
1559-
// if this fail somehow add fallback to get any from dungeonCards
1560-
int i = MyRandom.getRandom().nextInt(dungeonNames.size());
1561-
return Card.fromPaperCard(dungeonCards.get(i), ai);
1562-
} catch (Exception e) {
1563-
return Card.fromPaperCard(Aggregates.random(dungeonCards), ai);
1564-
}
1565-
}
1566-
15671543
@Override
15681544
public List<Card> chooseCardsForSplice(SpellAbility sa, List<Card> cards) {
15691545
// sort from best to worst

forge-ai/src/main/java/forge/ai/ability/VentureAi.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import com.google.common.collect.Lists;
44
import forge.ai.AiAbilityDecision;
55
import forge.ai.AiPlayDecision;
6+
import forge.ai.AiProfileUtil;
7+
import forge.ai.AiProps;
68
import forge.ai.PlayerControllerAi;
79
import forge.ai.SpellAbilityAi;
10+
import forge.card.ICardFace;
811
import forge.game.phase.PhaseHandler;
912
import forge.game.phase.PhaseType;
1013
import forge.game.player.Player;
@@ -74,4 +77,19 @@ public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, Lis
7477
return Aggregates.random(spells);
7578
}
7679

80+
@Override
81+
public ICardFace chooseCardFace(Player ai, SpellAbility sa, List<ICardFace> faces) {
82+
if (faces.size() == 1) {
83+
return faces.get(0);
84+
}
85+
86+
// Don't choose Tomb of Annihilation when life in danger unless we can win right away or can't lose for 0 life
87+
int lifeInDanger = AiProfileUtil.getIntProperty(ai, AiProps.AI_IN_DANGER_THRESHOLD);
88+
if ((ai.getLife() <= lifeInDanger && !ai.cantLoseForZeroOrLessLife())
89+
&& !(ai.getLife() > 1 && ai.getWeakestOpponent().getLife() == 1)) {
90+
faces.removeIf(f -> "Tomb of Annihilation".equals(f.getName()));
91+
}
92+
93+
return Aggregates.random(faces);
94+
}
7795
}

forge-core/src/main/java/forge/card/CardEdition.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ public enum EditionSectionWithCollectorNumbers {
142142
PRERELEASE_PROMO("prerelease promo"),
143143
BUNDLE("bundle"),
144144
BOX_TOPPER("box topper"),
145-
DUNGEONS("dungeons"),
146145
JUMPSTART("jumpstart"),
147146
REBALANCED("rebalanced"),
148147
ETERNAL("eternal"),

forge-core/src/main/java/forge/token/TokenDb.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,4 +202,6 @@ public Predicate<? super PaperToken> wasPrintedInSets(List<String> allowedSetCod
202202
public Iterator<PaperToken> iterator() {
203203
return allTokenByName.values().iterator();
204204
}
205+
206+
public Map<String, CardRules> getRules() { return this.rulesByName;}
205207
}

forge-game/src/main/java/forge/game/ability/effects/VentureEffect.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
import java.util.List;
55
import java.util.Map;
66
import java.util.function.Predicate;
7+
import java.util.stream.Collectors;
8+
9+
import org.apache.commons.lang3.ObjectUtils;
10+
11+
import com.google.common.collect.Lists;
712

813
import forge.StaticData;
914
import forge.card.CardRules;
10-
import forge.card.CardRulesPredicates;
15+
import forge.card.GamePieceType;
16+
import forge.card.ICardFace;
1117
import forge.game.Game;
1218
import forge.game.ability.AbilityKey;
1319
import forge.game.ability.SpellAbilityEffect;
1420
import forge.game.card.Card;
1521
import forge.game.card.CardCollectionView;
22+
import forge.game.card.CardFactory;
1623
import forge.game.card.CounterType;
1724
import forge.game.event.GameEventCardCounters;
1825
import forge.game.player.Player;
@@ -22,10 +29,7 @@
2229
import forge.game.trigger.TriggerType;
2330
import forge.game.trigger.WrappedAbility;
2431
import forge.game.zone.ZoneType;
25-
import forge.item.PaperCard;
26-
import forge.item.PaperCardPredicates;
2732
import forge.util.Localizer;
28-
import forge.util.PredicateString.StringOp;
2933

3034
public class VentureEffect extends SpellAbilityEffect {
3135

@@ -44,20 +48,30 @@ private Card getDungeonCard(SpellAbility sa, Player player, Map<AbilityKey, Obje
4448
}
4549
}
4650

47-
List<PaperCard> dungeonCards;
51+
Predicate<Map.Entry<String, CardRules>> filter;
4852
if (sa.hasParam("Dungeon")) {
4953
String dungeonType = sa.getParam("Dungeon");
50-
Predicate<CardRules> rulesPredicate = CardRulesPredicates.IS_DUNGEON.and(CardRulesPredicates.subType(StringOp.EQUALS, dungeonType));
51-
dungeonCards = StaticData.instance().getVariantCards().getAllCards(
52-
PaperCardPredicates.fromRules(rulesPredicate));
54+
filter = e -> e.getValue().getType().hasSubtype(dungeonType);
5355
} else {
5456
// Create a new dungeon card chosen by player in command zone.
55-
dungeonCards = StaticData.instance().getVariantCards().getAllCards(
56-
PaperCardPredicates.fromRules(CardRulesPredicates.IS_DUNGEON));
57-
dungeonCards.removeIf(c -> !c.getRules().isEnterableDungeon());
57+
filter = e -> e.getValue().isEnterableDungeon();
5858
}
59+
Map<ICardFace, String> mapping = StaticData.instance().getAllTokens().getRules().entrySet()
60+
.stream().filter(filter).collect(Collectors.toMap(e -> e.getValue().getMainPart(), Map.Entry::getKey));
5961
String message = Localizer.getInstance().getMessage("lblChooseDungeon");
60-
Card dungeon = player.getController().chooseDungeon(player, dungeonCards, message);
62+
ICardFace chosen = player.getController().chooseSingleCardFace(sa, Lists.newArrayList(mapping.keySet()), message);
63+
if (chosen == null) {
64+
return null;
65+
}
66+
String script = mapping.get(chosen);
67+
final Card host = sa.getHostCard();
68+
Card editionHost = sa.getOriginalHost();
69+
70+
String edition = ObjectUtils.firstNonNull(editionHost, host).getSetCode();
71+
edition = ObjectUtils.firstNonNull(StaticData.instance().getCardEdition(edition).getTokenSet(script), edition);
72+
73+
final Card dungeon = CardFactory.getCard(StaticData.instance().getAllTokens().getToken(script, edition), player, game);
74+
dungeon.setGamePieceType(GamePieceType.DUNGEON);
6175

6276
game.getAction().moveToCommand(dungeon, sa, moveParams);
6377

forge-game/src/main/java/forge/game/player/PlayerController.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,6 @@ public final boolean payManaCost(CostPartMana costPartMana, SpellAbility sa, Str
318318
public abstract String chooseCardName(SpellAbility sa, Predicate<ICardFace> cpp, String valid, String message);
319319
public abstract String chooseCardName(SpellAbility sa, List<ICardFace> faces, String message);
320320

321-
public abstract Card chooseDungeon(Player player, List<PaperCard> dungeonCards, String message);
322321
// better to have this odd method than those if playerType comparison in ChangeZone
323322
public abstract Card chooseSingleCardForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, boolean isOptional, Player decider);
324323
public abstract List<Card> chooseCardsForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, int min, int max, DelayedReveal delayedReveal, String selectPrompt, Player decider);

forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -767,12 +767,6 @@ public CardState chooseSingleCardState(SpellAbility sa, List<CardState> states,
767767
return null;
768768
}
769769

770-
@Override
771-
public Card chooseDungeon(Player player, List<PaperCard> dungeonCards, String message) {
772-
// TODO Auto-generated method stub
773-
return null;
774-
}
775-
776770
@Override
777771
public List<Card> chooseCardsForSplice(SpellAbility sa, List<Card> cards) {
778772
return Lists.newArrayList();

forge-gui/res/editions/Commander Legends Battle for Baldur's Gate.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -960,9 +960,6 @@ ScryfallCode=CLB
960960
[buy a box]
961961
936 R Elder Brain @Nino Is
962962

963-
[dungeons]
964-
20 Undercity
965-
966963
[foils]
967964
Abdel Adrian, Gorion's Ward+|CLB
968965
Ellyn Harbreeze, Busybody+|CLB
@@ -1165,6 +1162,7 @@ Zevlor, Elturel Exile|CLB
11651162
16 c_1_1_a_construct @Jakub Kasper
11661163
17 c_a_treasure_sac @Dan Murayama Scott
11671164
18 volos_journal @Zoltan Boros
1165+
20 undercity
11681166
21 c_3_2_eldrazi_horror @Jason Felix
11691167
22 c_1_1_shapeshifter_changeling @Steve Prescott
11701168
23 c_2_2_shapeshifter_changeling @Johann Bodin
@@ -1195,4 +1193,4 @@ Zevlor, Elturel Exile|CLB
11951193
48 c_a_gold_sac @Yeong-Hao Han
11961194

11971195
[other]
1198-
20☇ initiative @Ioannis Fiore
1196+
20☇ initiative @Ioannis Fiore

forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms.txt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,6 @@ A-233 R A-Sorcerer Class @Alexander Mokhov
447447
A-237 R A-Triumphant Adventurer @Alexander Mokhov
448448
A-255 R A-Dungeon Descent @Kasia 'Kafis' Zielińska
449449

450-
[dungeons]
451-
20 Dungeon of the Mad Mage
452-
21 Lost Mine of Phandelver
453-
22 Tomb of Annihilation
454-
455450
[tokens]
456451
1 w_3_3_angel_flying @Irina Nordsol
457452
2 icingdeath_frost_tongue @Kieran Yanner
@@ -468,12 +463,12 @@ A-255 R A-Dungeon Descent @Kasia 'Kafis' Zielińska
468463
13 guenhwyvar @Brian Valeza
469464
14 g_2_2_wolf @Daren Bader
470465
15 c_a_treasure_sac @Dan Murayama Scott
466+
20 dungeon_of_the_mad_mage
467+
21 lost_mine_of_phandelver
468+
22 tomb_of_annihilation
471469

472470
[other]
473471
16 emblem_ellywick_tumblestrum @Anna Steinbauer
474472
17 emblem_lolth_spider_queen @Tyler Jacobson
475473
18 emblem_mordenkainen @Ryan Pancoast
476474
19 emblem_zariel_archduke_of_avernus @Heonhwa Choe
477-
20 Dungeon of the Mad Mage
478-
21 Lost Mine of Phandelver
479-
22 Tomb of Annihilation

forge-gui/res/cardsfolder/d/dungeon_of_the_mad_mage.txt renamed to forge-gui/res/tokenscripts/dungeon_of_the_mad_mage.txt

File renamed without changes.

0 commit comments

Comments
 (0)