Skip to content

Commit a3d19cb

Browse files
authored
Fix Waterbend-testing humans Invasion Submersible (Card-Forge#9198)
1 parent bd0d5d5 commit a3d19cb

File tree

8 files changed

+18
-34
lines changed

8 files changed

+18
-34
lines changed

docs/Card-scripting-API/Card-scripting-API.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ There are a few other properties that will appear in many cards. These are
2626
| Property | Description
2727
| - | -
2828
|`A`|[Ability effect](Card-scripting-API/AbilityFactory.md)
29-
|`AI`|RemoveDeck:<br />* `All`<br />This will prevent the card from appearing in random AI decks. It is applicable for cards the AI can't use at all like Dark Ritual and also for cards that the AI could use, but only ineffectively like Tortoise Formation. The AI won't draft these cards.<br />* `Random`<br /> This will prevent the card from appearing in random decks. It is only applicable for cards that are too narrow for random decks like Root Cage or Into the North. The AI won't draft these cards.<br />* `NonCommander`<br />
30-
|`Colors`|Color(s) of the card<br /><br />When a card's color is determined by a color indicator rather than shards in a mana cost, this property must be defined. If no identifier is needed, this property should be omitted.<br /><br />* `Colors:red` - This is used on Kobolds of Kher Keep, which has a casting cost of {0} and requires a red indicator to make it red.<br /><br />* `Colors:red,green` - Since Arlinn, Embraced by the Moon has no casting cost (it's the back of a double-faced card), the red and green indicator must be included.
31-
|`DeckHints`|AI-related hints for a deck including this card<br /><br />To improve synergy this will increase the rank of of all other cards that share some of its DeckHints types. This helps with smoothing the selection so cards without these Entries won't be at an unfair disadvantage.<br /><br />The relevant code can be found in the [CardRanker](https://github.com/Card-Forge/forge/blob/master/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java) class.
29+
|`AI`|RemoveDeck:<br />* `All`<br />This will prevent the card from appearing in random AI decks. It is applicable for cards the AI can't use at all and also for cards that the AI could use, but only ineffectively. The AI won't draft these cards.<br />* `Random`<br /> This will prevent the card from appearing in random decks. It is only applicable for cards that are too narrow for random decks like *Root Cage* or *Into the North*. The AI won't draft these cards.<br />* `NonCommander`<br />
30+
|`Colors`|Color(s) of the card<br /><br />When a card's color is determined by a color indicator rather than shards in a mana cost, this property must be defined. If no identifier is needed, this property should be omitted.<br /><br />Example:<br />`Colors:red,green` - Since *Arlinn, Embraced by the Moon* has no mana cost (it's the back of a double-faced card), the red and green indicator must be included.
31+
|`DeckHints`|AI-related hints for a deck including this card<br /><br />To improve synergy this will increase the rank of of all other cards that share some of its DeckHints types. The following types are supported:<br />* Color<br />* Keyword<br />* Name<br />* Type<br /><br />This helps with smoothing the selection so cards without these Entries won't be at an unfair disadvantage.<br /><br />The relevant code can be found in the [CardRanker](https://github.com/Card-Forge/forge/blob/master/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java) class.
3232
|`DeckNeeds`|This can be considered a stronger variant when the AI should not put this card into its deck unless it has whatever other type is specified. The way this works is "inverted": it will directly decrease the rank of the card unless other cards are able to satisfy its types.<br />If a card demands more than one kind of type you can reuse it:<br />`DeckNeeds:Type$Human & Type$Warrior` will only find Human Warrior compared to `DeckNeeds:Type$Human\|Warrior` which is either
33-
|`DeckHas`|specifies that the deck now has a certain ability (like, token generation or counters) so that the drafting/deckbuilding AI knows that it now meets requirements for DeckHints/DeckNeeds. This is actually very useful since many of these (such as `Ability$Graveyard, Ability$Token, Ability$Counters`) are not deduced by parsing the abilities, so an explicit hint is necessary. Using the other types is also supported in case the implicit parsing wouldn't find it (TokenScript$ is also included).<br />It doesn't require exact matching to have an effect but cards that care about multiple entries for a given type will be judged higher if a card seems to provide even "more" synergy for it.<br />Example:<br />Chishiro has two abilities so `DeckHas:Ability$Token & Ability$Counters` is used, therefore score for `DeckNeeds:Ability$Token\|Counters` is increased
33+
|`DeckHas`|Specifies that the deck now has a certain ability (like, token generation) so that the drafting/deckbuilding AI knows that it now meets requirements for DeckHints/DeckNeeds. This is useful since many of these are not deduced by parsing the abilities, so an explicit hint is necessary. If you want to create a new archetype make sure to tag at least roughly 50 cards to start with and balacing the Has/Needs ratio. Currently used values are:<br />* Counters<br />* Graveyard<br />* Token<br /><br />Using the generic types is also supported in case the implicit parsing wouldn't find it (TokenScript$ is also included).<br />It doesn't require exact matching to have an effect but cards that care about multiple entries for a given type will be judged higher if a card seems to provide even "more" synergy for it.<br /><br />Example:<br />*Chishiro* has two abilities so `DeckHas:Ability$Token & Ability$Counters` is used, therefore score for `DeckNeeds:Ability$Token\|Counters` is increased
3434
|`K`|Keyword (see below)
3535
|`Loyalty`|Number of starting loyalty counters
3636
|`ManaCost`|Cost to cast the card shown in mana shards<br /><br />This property is required. It has a single parameter that is a mana cost.<br /><br />* `ManaCost:no cost` for cards that cannot be cast<br />* `ManaCost:1 W W` sets the casting cost to {1}{W}{W}
@@ -41,7 +41,7 @@ There are a few other properties that will appear in many cards. These are
4141
|`S`|[Static ability](Card-scripting-API/Statics.md)
4242
|`SVar`|String variable. Used throughout scripting in a handful of different ways.
4343
|`T`|[Triggered ability](Card-scripting-API/Triggers.md)
44-
|`Text`|Additional text that needs to be displayed on the CardDetailPanel that doesn't have any spell/ability that generates a description for it, for example "CARDNAME can be your commander." or "X can't be 0.".
44+
|`Text`|Additional text that needs to be displayed on the CardDetailPanel that doesn't have any spell/ability that generates a description for it, e.g. "CARDNAME can be your commander." or "X can't be 0.".
4545
|`Types`|Card types and subtypes<br /><br />Include all card types and subtypes, separated by spaces.<br /><br />Example:<br />* `Types:Enchantment Artifact Creature Golem` for a card that reads Enchantment Artifact Creature -- Golem
4646

4747
Rarity and Set info are now defined in edition definition files. These can be found at /res/reditions path.
@@ -198,8 +198,6 @@ equipped already (Kor Duelist).
198198

199199
`SVar:EndOfTurnLeavePlay:True`
200200

201-
`SVar:maxLevel:`
202-
203201
`SVar:HasCombatEffect:True`
204202

205203
`SVar:HasAttackEffect:True`

docs/Development/ownership.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The "Ancestors" column is basically there to list currently inactive developers
3434
## Forge Script DSL
3535
| Concept | Owners | Ancestors | Example tasks |
3636
| - | - | - | - |
37-
| [Card Scripting](cardscripting) | TRT, Northmoc, Simisays, Fulgur14, Dracontes | a lot | - implement new Sets<br>- clean up outdated elements<br>- apply Oracle updates |
37+
| [Card Scripting](cardscripting) | TRT, Northmoc, Simisays, Fulgur14, Dracontes | a lot | - implement new Sets<br>- review script PR<br>- clean up outdated elements<br>- apply Oracle updates |
3838
| ForgeScribe | | Austinino | |
3939

4040
## Modes

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,7 @@ else if (!sa.getHostCard().isPermanent() && sa.canCastTiming(player)
17261726
return future.get(game.getAITimeout(), TimeUnit.SECONDS);
17271727
} catch (InterruptedException | ExecutionException | TimeoutException e) {
17281728
try {
1729+
e.printStackTrace();
17291730
t.stop();
17301731
} catch (UnsupportedOperationException ex) {
17311732
// Android and Java 20 dropped support to stop so sadly thread will keep running

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

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,20 +1285,6 @@ public static boolean castPermanentInMain1(final Player ai, final SpellAbility s
12851285
}
12861286
} // AntiBuffedBy
12871287

1288-
// Plane cards that give Haste (e.g. Sokenzan)
1289-
if (ai.getGame().getRules().hasAppliedVariant(GameType.Planechase)) {
1290-
for (Card c : ai.getGame().getActivePlanes()) {
1291-
for (StaticAbility s : c.getStaticAbilities()) {
1292-
if (s.hasParam("AddKeyword")
1293-
&& s.getParam("AddKeyword").contains("Haste")
1294-
&& "Creature".equals(s.getParam("Affected"))
1295-
&& card.isCreature()) {
1296-
return true;
1297-
}
1298-
}
1299-
}
1300-
}
1301-
13021288
final CardCollectionView vengevines = ai.getCardsIn(ZoneType.Graveyard, "Vengevine");
13031289
if (!vengevines.isEmpty()) {
13041290
final CardCollectionView creatures = ai.getCardsIn(ZoneType.Hand);
@@ -1458,16 +1444,15 @@ public static boolean hasACardGivingHaste(final Player ai, final boolean checkOp
14581444
for (StaticAbility stAb : c.getStaticAbilities()) {
14591445
if (stAb.checkMode(StaticAbilityMode.Continuous) && stAb.hasParam("AddKeyword")
14601446
&& stAb.getParam("AddKeyword").contains("Haste")) {
1461-
14621447
if (c.isEquipment() && c.getEquipping() == null) {
14631448
return true;
14641449
}
14651450

14661451
final String affected = stAb.getParam("Affected");
1467-
if (affected.contains("Creature.YouCtrl")
1468-
|| affected.contains("Other+YouCtrl")) {
1452+
if (affected.startsWith("Creature") && (affected.contains("YouCtrl") || !affected.contains("."))) {
14691453
return true;
1470-
} else if (affected.contains("Creature.PairedWith") && !c.isPaired()) {
1454+
}
1455+
if (affected.contains("Creature.PairedWith") && !c.isPaired()) {
14711456
return true;
14721457
}
14731458
}
@@ -1482,8 +1467,7 @@ public static boolean hasACardGivingHaste(final Player ai, final boolean checkOp
14821467
}
14831468

14841469
final String valid = params.get("ValidCard");
1485-
if (valid.contains("Creature.YouCtrl")
1486-
|| valid.contains("Other+YouCtrl") ) {
1470+
if (valid.contains("Creature.YouCtrl") || valid.contains("Other+YouCtrl") ) {
14871471

14881472
final SpellAbility sa = t.getOverridingAbility();
14891473
if (sa != null && sa.getApi() == ApiType.Pump && sa.hasParam("KW")

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,10 @@ public static ManaCostBeingPaid calculateManaCost(final Cost cost, final SpellAb
13021302
Cost payCosts;
13031303
if (test) {
13041304
payCosts = CostAdjustment.adjust(cost, sa, effect);
1305+
// prevent asking Human when only predicting
1306+
if (!payer.getController().isAI()) {
1307+
sa.setMaxWaterbend(null);
1308+
}
13051309
} else {
13061310
// when not testing CostPayment already handled raise
13071311
payCosts = cost;

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,10 +1066,8 @@ public Collection<PaperCard> getAllNonPromosNonReprintsNoAlt() {
10661066
}
10671067

10681068
public String getNormalizedName(final String cardName) {
1069-
String cardName1 = cardName;
10701069
// normalize Names first
1071-
cardName1 = normalizedNames.getOrDefault(cardName1, cardName1);
1072-
return cardName1;
1070+
return normalizedNames.getOrDefault(cardName, cardName);
10731071
}
10741072

10751073
@Override

forge-game/src/main/java/forge/game/spellability/SpellAbility.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,6 +2699,7 @@ public Integer getMaxWaterbend() {
26992699
}
27002700
public void setMaxWaterbend(Cost cost) {
27012701
if (cost == null || cost.getMaxWaterbend() == null) {
2702+
maxWaterbend = 0;
27022703
return;
27032704
}
27042705
maxWaterbend = AbilityUtils.calculateAmount(getHostCard(), cost.getMaxWaterbend(), this);

forge-gui/src/main/java/forge/player/PlayerControllerHuman.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,13 +2942,11 @@ private void addCardToZone(ZoneType zone, final boolean repeatLast, final boolea
29422942
}
29432943
final Player p = pOld;
29442944

2945-
29462945
final CardDb carddb = FModel.getMagicDb().getCommonCards();
2947-
final List<ICardFace> faces = Lists.newArrayList(carddb.getAllFaces());
29482946

29492947
List<CardFaceView> choices = new ArrayList<>();
29502948
CardFaceView cardFaceView;
2951-
for (ICardFace cardFace : faces) {
2949+
for (ICardFace cardFace : carddb.getAllFaces()) {
29522950
cardFaceView = new CardFaceView(CardTranslation.getTranslatedName(cardFace.getDisplayName()), cardFace.getName());
29532951
choices.add(cardFaceView);
29542952
}

0 commit comments

Comments
 (0)