Fixed a bunch of NPE and other possible exceptions.

This commit is contained in:
LevelX2 2015-04-20 23:37:28 +02:00
parent 38b72284da
commit c2fb2de67a
12 changed files with 65 additions and 18 deletions

View file

@ -96,7 +96,7 @@ public class GameView implements Serializable {
for (StackObject stackObject: state.getStack()) { for (StackObject stackObject: state.getStack()) {
if (stackObject instanceof StackAbility) { if (stackObject instanceof StackAbility) {
// Stack Ability // Stack Ability
MageObject object = game.getObject(stackObject.getSourceId()); MageObject object = ((StackAbility)stackObject).getSourceObject(game);
Card card = game.getCard(stackObject.getSourceId()); Card card = game.getCard(stackObject.getSourceId());
if (card != null) { if (card != null) {
if (object != null) { if (object != null) {

View file

@ -558,7 +558,6 @@ public class TableController {
if (!match.getPlayer(entry.getValue()).hasQuit()) { if (!match.getPlayer(entry.getValue()).hasQuit()) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null) { if (user != null) {
Player player = match.getPlayer(entry.getValue()).getPlayer();
user.ccGameStarted(match.getGame().getId(), entry.getValue()); user.ccGameStarted(match.getGame().getId(), entry.getValue());
if (creator == null) { if (creator == null) {

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.RevealTargetFromHandCost; import mage.abilities.costs.common.RevealTargetFromHandCost;
import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
import mage.abilities.effects.ContinuousRuleModifyingEffect; import mage.abilities.effects.ContinuousRuleModifyingEffect;
@ -114,9 +115,11 @@ class DragonlordsPrerogativeCondition implements Condition {
boolean applies = false; boolean applies = false;
Spell spell = game.getStack().getSpell(source.getSourceId()); Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) { if (spell != null) {
RevealTargetFromHandCost cost = (RevealTargetFromHandCost) spell.getSpellAbility().getCosts().get(0); for(Cost cost: spell.getSpellAbility().getCosts()) {
if (cost != null) { if (cost instanceof RevealTargetFromHandCost) {
applies = !cost.getTargets().isEmpty(); applies = !((RevealTargetFromHandCost)cost).getTargets().isEmpty();
break;
}
} }
} }
if (!applies) { if (!applies) {

View file

@ -196,9 +196,11 @@ class LivingLoreSacrificeEffect extends OneShotEffect {
if (exileId != null) { if (exileId != null) {
ExileZone exileZone = game.getExile().getExileZone(exileId); ExileZone exileZone = game.getExile().getExileZone(exileId);
Card exiledCard = null; Card exiledCard = null;
for (Card card :exileZone.getCards(game)) { if (exileZone != null) {
exiledCard = card; for (Card card :exileZone.getCards(game)) {
break; exiledCard = card;
break;
}
} }
if (exiledCard != null) { if (exiledCard != null) {
if (exiledCard.getSpellAbility().canChooseTarget(game)) { if (exiledCard.getSpellAbility().canChooseTarget(game)) {

View file

@ -38,7 +38,6 @@ import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterAbility;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate;

View file

@ -278,4 +278,34 @@ public class BestowTest extends CardTestPlayerBase {
assertPowerToughness(playerA, "Silvercoat Lion", 3,3); assertPowerToughness(playerA, "Silvercoat Lion", 3,3);
} }
/**
*
*
*
*/
@Test
public void bestowMogissWarhound() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// Enchantment Creature Hound
// 2/2
// Bestow 2R (If you cast this card for its bestow cost, it's an Aura spell with enchant creature. It becomes a creature again if it's not attached to a creature.)
// Mogis's Warhound attacks each turn if able.
// Enchanted creature gets +2/+2 and attacks each turn if able.
addCard(Zone.HAND, playerA, "Mogis's Warhound");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mogis's Warhound using bestow", "Silvercoat Lion");
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
//
assertHandCount(playerA, "Mogis's Warhound", 0);
// because cast with bestow, Boon Satyr may not be tapped
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPowerToughness(playerA, "Silvercoat Lion", 4,4);
}
} }

View file

@ -31,6 +31,7 @@ package mage.abilities;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.common.ZoneChangeTriggeredAbility; import mage.abilities.common.ZoneChangeTriggeredAbility;
@ -249,7 +250,8 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
@Override @Override
public boolean contains(T ability) { public boolean contains(T ability) {
for (T test: this) { for (Iterator<T> iterator = this.iterator(); iterator.hasNext();) { // simple loop can cause java.util.ConcurrentModificationException
T test = iterator.next();
// Checking also by getRule() without other restrictions is a problem when a triggered ability will be copied to a permanent that had the same ability // Checking also by getRule() without other restrictions is a problem when a triggered ability will be copied to a permanent that had the same ability
// already before the copy. Because then it keeps the triggered ability twice and it triggers twice. // already before the copy. Because then it keeps the triggered ability twice and it triggers twice.
// e.g. 2 Biovisonary and one enchanted with Infinite Reflection // e.g. 2 Biovisonary and one enchanted with Infinite Reflection

View file

@ -173,7 +173,9 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
public void removeEffects(UUID effectIdToRemove, Set<Ability> abilitiesToRemove) { public void removeEffects(UUID effectIdToRemove, Set<Ability> abilitiesToRemove) {
HashSet<Ability> abilities = effectAbilityMap.get(effectIdToRemove); HashSet<Ability> abilities = effectAbilityMap.get(effectIdToRemove);
abilities.removeAll(abilitiesToRemove); if (abilitiesToRemove != null) {
abilities.removeAll(abilitiesToRemove);
}
if (abilities.isEmpty()) { if (abilities.isEmpty()) {
for (Iterator<T> iterator = this.iterator(); iterator.hasNext();) { for (Iterator<T> iterator = this.iterator(); iterator.hasNext();) {
ContinuousEffect effect = iterator.next(); ContinuousEffect effect = iterator.next();

View file

@ -29,12 +29,12 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -79,7 +79,10 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe
if (fromExileZone) { if (fromExileZone) {
UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exilZoneId != null) { if (exilZoneId != null) {
card = game.getExile().getExileZone(exilZoneId).get(getTargetPointer().getFirst(game, source), game); ExileZone exileZone = game.getExile().getExileZone(exilZoneId);
if (exileZone != null && getTargetPointer().getFirst(game, source) != null) {
card = exileZone.get(getTargetPointer().getFirst(game, source), game);
}
} }
} else { } else {
card = game.getCard(targetPointer.getFirst(game, source)); card = game.getCard(targetPointer.getFirst(game, source));

View file

@ -39,6 +39,7 @@ import mage.constants.Outcome;
import mage.constants.SubLayer; import mage.constants.SubLayer;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import org.apache.log4j.Logger;
/** /**
* *
@ -87,7 +88,11 @@ public class BoostSourceEffect extends ContinuousEffectImpl implements SourceEff
public void init(Ability source, Game game) { public void init(Ability source, Game game) {
super.init(source, game); super.init(source, game);
if (affectedObjectsSet) { if (affectedObjectsSet) {
affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); try {
affectedObjectList.add(new MageObjectReference(source.getSourceId(), game));
} catch (IllegalArgumentException ex) {
Logger.getLogger(BoostSourceEffect.class).error("Could not get sourceId reference: " + source.getRule());
}
} }
if (lockedIn) { if (lockedIn) {
power = new StaticValue(power.calculate(game, source, this)); power = new StaticValue(power.calculate(game, source, this));

View file

@ -709,8 +709,10 @@ public abstract class PlayerImpl implements Player, Serializable {
choose(Outcome.Discard, target, source == null ? null : source.getSourceId(), game); choose(Outcome.Discard, target, source == null ? null : source.getSourceId(), game);
for (UUID cardId : target.getTargets()) { for (UUID cardId : target.getTargets()) {
Card card = this.getHand().get(cardId, game); Card card = this.getHand().get(cardId, game);
discardedCards.add(card); if (card != null) { // can happen if user is removed (session expires)
discard(card, source, game); discardedCards.add(card);
discard(card, source, game);
}
} }
} }
return discardedCards; return discardedCards;

View file

@ -208,7 +208,7 @@ public class CardUtil {
* @param ability * @param ability
* @param reduceCount * @param reduceCount
*/ */
public static void adjustAbilityCost(Ability ability, int reduceCount) { private static void adjustAbilityCost(Ability ability, int reduceCount) {
ManaCosts<ManaCost> adjustedCost = adjustCost(ability.getManaCostsToPay(), reduceCount); ManaCosts<ManaCost> adjustedCost = adjustCost(ability.getManaCostsToPay(), reduceCount);
ability.getManaCostsToPay().clear(); ability.getManaCostsToPay().clear();
ability.getManaCostsToPay().addAll(adjustedCost); ability.getManaCostsToPay().addAll(adjustedCost);