fixed cases that could lead to NPE

This commit is contained in:
North 2013-01-03 15:09:27 +02:00
parent e4349c8b23
commit c083fae37b
9 changed files with 151 additions and 107 deletions

View file

@ -131,8 +131,10 @@ public class DevourEffect extends ReplacementEffectImpl<DevourEffect> {
int devouredCreatures = target.getTargets().size(); int devouredCreatures = target.getTargets().size();
game.informPlayers(new StringBuilder(creature.getName()).append(" devours ").append(devouredCreatures).append(" creatures").toString()); game.informPlayers(new StringBuilder(creature.getName()).append(" devours ").append(devouredCreatures).append(" creatures").toString());
for (UUID targetId: target.getTargets()) { for (UUID targetId: target.getTargets()) {
Permanent targetCreature = game.getPermanent(targetId); Permanent targetCreature = game.getPermanent(targetId);
cardSubtypes.add((ArrayList<String>) targetCreature.getSubtype()); if (targetCreature != null) {
cardSubtypes.add((ArrayList<String>) targetCreature.getSubtype());
}
if (targetCreature == null || !targetCreature.sacrifice(source.getSourceId(), game)) { if (targetCreature == null || !targetCreature.sacrifice(source.getSourceId(), game)) {
return false; return false;
} }

View file

@ -62,8 +62,11 @@ public class RegenerateAttachedEffect extends ReplacementEffectImpl<RegenerateAt
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
//20110204 - 701.11 //20110204 - 701.11
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
return false;
}
Permanent equipped = game.getPermanent(permanent.getAttachedTo()); Permanent equipped = game.getPermanent(permanent.getAttachedTo());
if (permanent != null && equipped.regenerate(this.getId(), game)) { if (equipped != null && equipped.regenerate(this.getId(), game)) {
this.used = true; this.used = true;
return true; return true;
} }

View file

@ -83,8 +83,6 @@ import mage.util.CardUtil;
* *
* @author LevelX2 * @author LevelX2
*/ */
public class ConvokeAbility extends SimpleStaticAbility implements AdjustingSourceCosts { public class ConvokeAbility extends SimpleStaticAbility implements AdjustingSourceCosts {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
@ -123,47 +121,51 @@ public class ConvokeAbility extends SimpleStaticAbility implements AdjustingSour
int adjCost = 0; int adjCost = 0;
for (UUID creatureId: target.getTargets()) { for (UUID creatureId: target.getTargets()) {
Permanent perm = game.getPermanent(creatureId); Permanent perm = game.getPermanent(creatureId);
if (perm!= null) { if (perm == null) {
Card card = game.getCard(perm.getId()); continue;
ManaCosts manaCostsCreature = card.getSpellAbility().getManaCosts(); }
if (card != null && manaCostsCreature != null && manaCostsCreature.convertedManaCost() > 0) {
if (perm.tap(game)) {
Choice chooseManaType = buildChoice(manaCostsCreature, ability.getManaCostsToPay());
if (chooseManaType.getChoices().size() > 0) {
if (chooseManaType.getChoices().size() > 1) {
chooseManaType.getChoices().add("Colorless");
chooseManaType.setMessage("Choose mana color to reduce from " + perm.getName());
while (!chooseManaType.isChosen()) {
player.choose(Outcome.Benefit, chooseManaType, game);
}
} else {
chooseManaType.setChoice(chooseManaType.getChoices().iterator().next());
}
ManaCosts manaCostsToReduce = new ManaCostsImpl(); Card card = game.getCard(perm.getId());
if (chooseManaType.getChoice().equals("Black")) { if (card == null) {
manaCostsToReduce.load("{B}"); continue;
} }
if (chooseManaType.getChoice().equals("Blue")) {
manaCostsToReduce.load("{U}"); ManaCosts manaCostsCreature = card.getSpellAbility().getManaCosts();
} if (manaCostsCreature != null && manaCostsCreature.convertedManaCost() > 0 && perm.tap(game)) {
if (chooseManaType.getChoice().equals("Green")) { Choice chooseManaType = buildChoice(manaCostsCreature, ability.getManaCostsToPay());
manaCostsToReduce.load("{G}"); if (chooseManaType.getChoices().size() > 0) {
} if (chooseManaType.getChoices().size() > 1) {
if (chooseManaType.getChoice().equals("White")) { chooseManaType.getChoices().add("Colorless");
manaCostsToReduce.load("{W}"); chooseManaType.setMessage("Choose mana color to reduce from " + perm.getName());
} while (!chooseManaType.isChosen()) {
if (chooseManaType.getChoice().equals("Red")) { player.choose(Outcome.Benefit, chooseManaType, game);
manaCostsToReduce.load("{R}");
}
if (chooseManaType.getChoice().equals("Colorless")) {
++adjCost;
}
CardUtil.adjustCost((SpellAbility)ability, manaCostsToReduce);
} else {
++adjCost;
} }
} else {
chooseManaType.setChoice(chooseManaType.getChoices().iterator().next());
} }
ManaCosts manaCostsToReduce = new ManaCostsImpl();
if (chooseManaType.getChoice().equals("Black")) {
manaCostsToReduce.load("{B}");
}
if (chooseManaType.getChoice().equals("Blue")) {
manaCostsToReduce.load("{U}");
}
if (chooseManaType.getChoice().equals("Green")) {
manaCostsToReduce.load("{G}");
}
if (chooseManaType.getChoice().equals("White")) {
manaCostsToReduce.load("{W}");
}
if (chooseManaType.getChoice().equals("Red")) {
manaCostsToReduce.load("{R}");
}
if (chooseManaType.getChoice().equals("Colorless")) {
++adjCost;
}
CardUtil.adjustCost((SpellAbility)ability, manaCostsToReduce);
} else {
++adjCost;
} }
} }
} }
@ -200,4 +202,3 @@ public class ConvokeAbility extends SimpleStaticAbility implements AdjustingSour
return "Convoke <i>(Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.)</i>"; return "Convoke <i>(Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.)</i>";
} }
} }

View file

@ -89,8 +89,9 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
return filter.match(permanent, game); return filter.match(permanent, game);
} }
Player player = game.getPlayer(id); Player player = game.getPlayer(id);
if (player != null) if (player != null) {
return filter.match(player, game); return filter.match(player, game);
}
return false; return false;
} }
@ -101,20 +102,24 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id); Permanent permanent = game.getPermanent(id);
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
if (source != null)
//TODO: check for replacement effects
return permanent.canBeTargetedBy(game.getObject(source.getSourceId()), controllerId, game) && filter.match(permanent, source.getSourceId(), controllerId, game);
else
return filter.match(permanent, source.getSourceId(), controllerId, game);
}
Player player = game.getPlayer(id); Player player = game.getPlayer(id);
if (player != null)
if (source != null) if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
if (player != null) {
return player.canBeTargetedBy(targetSource, game) && filter.match(player, game); return player.canBeTargetedBy(targetSource, game) && filter.match(player, game);
else }
return filter.match(player, game); }
if (permanent != null) {
return filter.match(permanent, game);
}
if (player != null) {
return filter.match(player, game);
}
return false; return false;
} }
@ -135,15 +140,17 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;
@ -164,15 +171,17 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && filter.match(player, game)) { if (player != null && filter.match(player, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
if (filter.match(permanent, null, sourceControllerId, game)) { if (filter.match(permanent, null, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;

View file

@ -75,27 +75,33 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount<TargetCreatureOrP
return filter.match(permanent, game); return filter.match(permanent, game);
} }
Player player = game.getPlayer(id); Player player = game.getPlayer(id);
if (player != null) if (player != null) {
return filter.match(player, game); return filter.match(player, game);
}
return false; return false;
} }
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id); Permanent permanent = game.getPermanent(id);
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
if (source != null)
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
else
return filter.match(permanent, game);
}
Player player = game.getPlayer(id); Player player = game.getPlayer(id);
if (player != null)
if (source != null) if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
if (player != null) {
return player.canBeTargetedBy(targetSource, game) && filter.match(player, game); return player.canBeTargetedBy(targetSource, game) && filter.match(player, game);
else }
return filter.match(player, game); }
if (permanent != null) {
return filter.match(permanent, game);
}
if (player != null) {
return filter.match(player, game);
}
return false; return false;
} }
@ -107,15 +113,17 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount<TargetCreatureOrP
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;
@ -128,15 +136,17 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount<TargetCreatureOrP
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && filter.match(player, game)) { if (player != null && filter.match(player, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
if (filter.match(permanent, null, sourceControllerId, game)) { if (filter.match(permanent, null, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;

View file

@ -82,9 +82,9 @@ public class TargetCreaturePermanentAmount extends TargetAmount<TargetCreaturePe
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id); Permanent permanent = game.getPermanent(id);
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) { if (permanent != null) {
if (source != null) { if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game); return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
} else { } else {
return filter.match(permanent, game); return filter.match(permanent, game);

View file

@ -97,27 +97,33 @@ public class TargetPermanentOrPlayer extends TargetImpl<TargetPermanentOrPlayer>
return filter.match(permanent, game); return filter.match(permanent, game);
} }
Player player = game.getPlayer(id); Player player = game.getPlayer(id);
if (player != null) if (player != null) {
return filter.match(player, game); return filter.match(player, game);
}
return false; return false;
} }
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id); Permanent permanent = game.getPermanent(id);
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
if (source != null)
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
else
return filter.match(permanent, game);
}
Player player = game.getPlayer(id); Player player = game.getPlayer(id);
if (player != null)
if (source != null) if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
if (player != null) {
return player.canBeTargetedBy(targetSource, game) && filter.match(player, game); return player.canBeTargetedBy(targetSource, game) && filter.match(player, game);
else }
return filter.match(player, game); }
if (permanent != null) {
return filter.match(permanent, game);
}
if (player != null) {
return filter.match(player, game);
}
return false; return false;
} }
@ -138,15 +144,17 @@ public class TargetPermanentOrPlayer extends TargetImpl<TargetPermanentOrPlayer>
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) { if (player != null && player.canBeTargetedBy(targetSource, game) && filter.match(player, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;
@ -167,15 +175,17 @@ public class TargetPermanentOrPlayer extends TargetImpl<TargetPermanentOrPlayer>
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && filter.match(player, game)) { if (player != null && filter.match(player, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, game)) {
if (filter.match(permanent, null, sourceControllerId, game) && filter.match(permanent, game)) { if (filter.match(permanent, null, sourceControllerId, game) && filter.match(permanent, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;

View file

@ -104,24 +104,27 @@ public class TargetSpellOrPermanent extends TargetImpl<TargetSpellOrPermanent> {
return filter.match(permanent, game); return filter.match(permanent, game);
} }
Spell spell = game.getStack().getSpell(id); Spell spell = game.getStack().getSpell(id);
if (spell != null) if (spell != null) {
return filter.match(spell, game); return filter.match(spell, game);
}
return false; return false;
} }
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id); Permanent permanent = game.getPermanent(id);
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) { if (permanent != null) {
if (source != null) if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game); return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
else } else {
return filter.match(permanent, game); return filter.match(permanent, game);
}
} }
Spell spell = game.getStack().getSpell(id); Spell spell = game.getStack().getSpell(id);
if (spell != null) if (spell != null) {
return filter.match(spell, game); return filter.match(spell, game);
}
return false; return false;
} }
@ -142,15 +145,17 @@ public class TargetSpellOrPermanent extends TargetImpl<TargetSpellOrPermanent> {
Spell spell = game.getStack().getSpell(stackObject.getId()); Spell spell = game.getStack().getSpell(stackObject.getId());
if (spell != null && filter.match(spell, sourceId, sourceControllerId, game)) { if (spell != null && filter.match(spell, sourceId, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;
@ -171,15 +176,17 @@ public class TargetSpellOrPermanent extends TargetImpl<TargetSpellOrPermanent> {
Spell spell = game.getStack().getSpell(stackObject.getId()); Spell spell = game.getStack().getSpell(stackObject.getId());
if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell, game)) { if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
for (Permanent permanent: game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, game)) {
if (filter.match(permanent, null, sourceControllerId, game) && filter.match(permanent, game)) { if (filter.match(permanent, null, sourceControllerId, game) && filter.match(permanent, game)) {
count++; count++;
if (count >= this.minNumberOfTargets) if (count >= this.minNumberOfTargets) {
return true; return true;
}
} }
} }
return false; return false;

View file

@ -55,8 +55,9 @@ public class CardUtil {
*/ */
public static boolean shareTypes(Card card1, Card card2) { public static boolean shareTypes(Card card1, Card card2) {
if (card1 == null || card2 == null) if (card1 == null || card2 == null) {
throw new IllegalArgumentException("Params can't be null"); throw new IllegalArgumentException("Params can't be null");
}
for (Constants.CardType type : card1.getCardType()) { for (Constants.CardType type : card1.getCardType()) {
if (card2.getCardType().contains(type)) { if (card2.getCardType().contains(type)) {
@ -75,8 +76,9 @@ public class CardUtil {
*/ */
public static boolean shareSubtypes(Card card1, Card card2) { public static boolean shareSubtypes(Card card1, Card card2) {
if (card1 == null || card2 == null) if (card1 == null || card2 == null) {
throw new IllegalArgumentException("Params can't be null"); throw new IllegalArgumentException("Params can't be null");
}
for (String subtype : card1.getSubtype()) { for (String subtype : card1.getSubtype()) {
if (card2.getSubtype().contains(subtype)) { if (card2.getSubtype().contains(subtype)) {
@ -108,8 +110,8 @@ public class CardUtil {
boolean reduced = false; boolean reduced = false;
for (ManaCost manaCost : previousCost) { for (ManaCost manaCost : previousCost) {
Mana mana = manaCost.getOptions().get(0); Mana mana = manaCost.getOptions().get(0);
int colorless = mana.getColorless(); int colorless = mana != null ? mana.getColorless() : 0;
if (!reduced && mana != null && colorless > 0) { if (!reduced && colorless > 0) {
if ((colorless - reduceCount) > 0) { if ((colorless - reduceCount) > 0) {
int newColorless = colorless - reduceCount; int newColorless = colorless - reduceCount;
adjustedCost.add(new GenericManaCost(newColorless)); adjustedCost.add(new GenericManaCost(newColorless));