mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Prevent NPEs caused by the AI when testing for the new style AI hints from within AI methods on Card objects, which is dangerous because Card.getRules() is not guaranteed to be non-null, and may indeed be null for objects such as tokens (especially noticeable in Momir Basic and MoJhoSto).
- Currently relegated 99% of AI calls to those getAIHints tests to a wrapper method which checks for a non-null getRules. - The card predicate has to test for non-null directly to avoid adding an unnecessary dependency on the AI module (the alternative would be to add the wrapper methods to the Card object, but that'll clutter it even more and the AI hints belong to the AI side of things, not the card itself).
This commit is contained in:
@@ -1705,7 +1705,7 @@ public class AiController {
|
||||
if (!useSimulation) {
|
||||
for (Entry<DeckSection, CardPool> ds : myDeck) {
|
||||
for (Entry<PaperCard, Integer> cp : ds.getValue()) {
|
||||
if (cp.getKey().getRules().getAiHints().getRemAIDecks())
|
||||
if (cp.getKey().getRules().getAiHints().getRemAIDecks())
|
||||
result.add(cp.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1844,4 +1844,13 @@ public class ComputerUtilCard {
|
||||
|
||||
return AiPlayDecision.WillPlay;
|
||||
}
|
||||
|
||||
// Determine if the AI has an AI:RemoveDeck:All or an AI:RemoveDeck:Random hint specified.
|
||||
// Includes a NPE guard on getRules() which might otherwise be tripped on some cards (e.g. tokens).
|
||||
public static boolean isCardRemAIDeck(final Card card) {
|
||||
return card.getRules() != null && card.getRules().getAiHints().getRemAIDecks();
|
||||
}
|
||||
public static boolean isCardRemRandomDeck(final Card card) {
|
||||
return card.getRules() != null && card.getRules().getAiHints().getRemRandomDecks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1463,7 +1463,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
if (c.getRules().getAiHints().getRemAIDecks() || c.getRules().getAiHints().getRemRandomDecks()) {
|
||||
if (ComputerUtilCard.isCardRemAIDeck(c) || ComputerUtilCard.isCardRemRandomDeck(c)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -171,7 +171,7 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
// do not take control on something it doesn't know how to use
|
||||
return !c.getRules().getAiHints().getRemAIDecks();
|
||||
return !ComputerUtilCard.isCardRemAIDeck(c);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public class PowerExchangeAi extends SpellAbilityAi {
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return !c.getRules().getAiHints().getRemAIDecks() && c.canBeTargetedBy(sa);
|
||||
return !ComputerUtilCard.isCardRemAIDeck(c) && c.canBeTargetedBy(sa);
|
||||
}
|
||||
});
|
||||
CardLists.sortByPowerAsc(list);
|
||||
|
||||
Reference in New Issue
Block a user