- 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:
Agetian
2018-10-26 17:16:12 +03:00
parent a001cb78c0
commit f4db360265
6 changed files with 16 additions and 6 deletions

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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);
}
});

View File

@@ -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);