mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
Fixed some possible null pointer exceptions (found in server log). Market Festival, Kindred Summons, Profane Processions, New Blood, Kindred Charge , Bishop of Binding, Metzal Tower of Triumph, Chrome Mox
This commit is contained in:
parent
a38ec84581
commit
2685d9f8b4
10 changed files with 62 additions and 38 deletions
|
@ -132,10 +132,12 @@ class BishopOfBindingExiledCardsPowerCount implements DynamicValue {
|
||||||
@Override
|
@Override
|
||||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, sourceAbility.getSourceId(), sourceAbility.getSourceObjectZoneChangeCounter()));
|
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, sourceAbility.getSourceId(), sourceAbility.getSourceObjectZoneChangeCounter()));
|
||||||
|
if (exileZone != null) {
|
||||||
Card exiledCard = exileZone.getRandom(game);
|
Card exiledCard = exileZone.getRandom(game);
|
||||||
if (exiledCard != null) {
|
if (exiledCard != null) {
|
||||||
return exiledCard.getPower().getValue();
|
return exiledCard.getPower().getValue();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,14 @@ class ChromeMoxManaEffect extends ManaEffect {
|
||||||
if (choice.getChoices().size() == 1) {
|
if (choice.getChoices().size() == 1) {
|
||||||
choice.setChoice(choice.getChoices().iterator().next());
|
choice.setChoice(choice.getChoices().iterator().next());
|
||||||
} else {
|
} else {
|
||||||
player.choose(outcome, choice, game);
|
while (!player.choose(outcome, choice, game)) {
|
||||||
|
if (!player.canRespond()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (choice.getChoice() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch (choice.getChoice()) {
|
switch (choice.getChoice()) {
|
||||||
case "Black":
|
case "Black":
|
||||||
|
|
|
@ -34,10 +34,10 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
||||||
|
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||||
|
import mage.abilities.effects.common.ExileTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.abilities.effects.common.ExileTargetEffect;
|
|
||||||
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
|
@ -95,7 +95,11 @@ class KindredChargeEffect extends OneShotEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||||
if (controller != null && sourceObject != null) {
|
if (controller != null && sourceObject != null) {
|
||||||
String creatureType = game.getState().getValue(sourceObject.getId() + "_type").toString();
|
Object object = game.getState().getValue(sourceObject.getId() + "_type");
|
||||||
|
if (object == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String creatureType = object.toString();
|
||||||
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature you control of the chosen type");
|
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature you control of the chosen type");
|
||||||
filter.add(new SubtypePredicate(SubType.byDescription(creatureType)));
|
filter.add(new SubtypePredicate(SubType.byDescription(creatureType)));
|
||||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
|
||||||
|
|
|
@ -34,9 +34,9 @@ import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.Card;
|
|
||||||
import mage.cards.Cards;
|
import mage.cards.Cards;
|
||||||
import mage.cards.CardsImpl;
|
import mage.cards.CardsImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
@ -48,6 +48,7 @@ import mage.filter.common.FilterCreatureCard;
|
||||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Saga
|
* @author Saga
|
||||||
|
@ -55,7 +56,7 @@ import mage.players.Player;
|
||||||
public class KindredSummons extends CardImpl {
|
public class KindredSummons extends CardImpl {
|
||||||
|
|
||||||
public KindredSummons(UUID ownerId, CardSetInfo setInfo) {
|
public KindredSummons(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{5}{G}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{G}{G}");
|
||||||
|
|
||||||
// Choose a creature type. Reveal cards from the top of your library until you reveal X creature cards of the chosen type,
|
// Choose a creature type. Reveal cards from the top of your library until you reveal X creature cards of the chosen type,
|
||||||
// where X is the number of creatures you control of that type. Put those cards onto the battlefield,
|
// where X is the number of creatures you control of that type. Put those cards onto the battlefield,
|
||||||
|
@ -78,8 +79,8 @@ class KindredSummonsEffect extends OneShotEffect {
|
||||||
|
|
||||||
public KindredSummonsEffect() {
|
public KindredSummonsEffect() {
|
||||||
super(Outcome.PutCreatureInPlay);
|
super(Outcome.PutCreatureInPlay);
|
||||||
this.staticText = "Reveal cards from the top of your library until you reveal X creature cards of the chosen type, " +
|
this.staticText = "Reveal cards from the top of your library until you reveal X creature cards of the chosen type, "
|
||||||
"where X is the number of creatures you control of that type. Put those cards onto the battlefield, "
|
+ "where X is the number of creatures you control of that type. Put those cards onto the battlefield, "
|
||||||
+ "then shuffle the rest of the revealed cards into your library";
|
+ "then shuffle the rest of the revealed cards into your library";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +98,11 @@ class KindredSummonsEffect extends OneShotEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = source.getSourceObject(game);
|
MageObject sourceObject = source.getSourceObject(game);
|
||||||
if (controller != null && sourceObject != null) {
|
if (controller != null && sourceObject != null) {
|
||||||
String creatureType = game.getState().getValue(sourceObject.getId() + "_type").toString();
|
Object object = game.getState().getValue(sourceObject.getId() + "_type");
|
||||||
|
if (object == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String creatureType = object.toString();
|
||||||
FilterControlledCreaturePermanent filterPermanent = new FilterControlledCreaturePermanent("creature you control of the chosen type");
|
FilterControlledCreaturePermanent filterPermanent = new FilterControlledCreaturePermanent("creature you control of the chosen type");
|
||||||
filterPermanent.add(new SubtypePredicate(SubType.byDescription(creatureType)));
|
filterPermanent.add(new SubtypePredicate(SubType.byDescription(creatureType)));
|
||||||
int numberOfCards = game.getBattlefield().countAll(filterPermanent, source.getControllerId(), game);
|
int numberOfCards = game.getBattlefield().countAll(filterPermanent, source.getControllerId(), game);
|
||||||
|
|
|
@ -39,8 +39,8 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.choices.ChoiceColor;
|
import mage.choices.ChoiceColor;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
@ -57,10 +57,9 @@ import mage.target.common.TargetLandPermanent;
|
||||||
public class MarketFestival extends CardImpl {
|
public class MarketFestival extends CardImpl {
|
||||||
|
|
||||||
public MarketFestival(UUID ownerId, CardSetInfo setInfo) {
|
public MarketFestival(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}");
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
|
||||||
this.subtype.add(SubType.AURA);
|
this.subtype.add(SubType.AURA);
|
||||||
|
|
||||||
|
|
||||||
// Enchant land
|
// Enchant land
|
||||||
TargetPermanent auraTarget = new TargetLandPermanent();
|
TargetPermanent auraTarget = new TargetLandPermanent();
|
||||||
this.getSpellAbility().addTarget(auraTarget);
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
@ -108,14 +107,12 @@ class MarketFestivalTriggeredAbility extends TriggeredManaAbility {
|
||||||
return enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo());
|
return enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to his or her mana pool <i>(in addition to the mana the land produces)</i>.";
|
return "Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to his or her mana pool <i>(in addition to the mana the land produces)</i>.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class MarketFestivalManaEffect extends ManaEffect {
|
class MarketFestivalManaEffect extends ManaEffect {
|
||||||
|
|
||||||
public MarketFestivalManaEffect() {
|
public MarketFestivalManaEffect() {
|
||||||
|
@ -152,7 +149,9 @@ class MarketFestivalManaEffect extends ManaEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (choiceColor.getChoice() == null) { // Possible after reconnect?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
choiceColor.increaseMana(mana);
|
choiceColor.increaseMana(mana);
|
||||||
}
|
}
|
||||||
checkToFirePossibleEvents(mana, game, source);
|
checkToFirePossibleEvents(mana, game, source);
|
||||||
|
|
|
@ -126,10 +126,12 @@ class MetzaliTowerOfTriumphEffect extends OneShotEffect {
|
||||||
available.add(permanent);
|
available.add(permanent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!available.isEmpty()) {
|
||||||
Permanent permanent = available.get(RandomUtil.nextInt(available.size()));
|
Permanent permanent = available.get(RandomUtil.nextInt(available.size()));
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.destroy(source.getSourceId(), game, false);
|
permanent.destroy(source.getSourceId(), game, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
*/
|
*/
|
||||||
package mage.cards.n;
|
package mage.cards.n;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.Mode;
|
import mage.abilities.Mode;
|
||||||
|
@ -52,10 +53,6 @@ import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
|
@ -124,7 +121,7 @@ class NewBloodEffect extends OneShotEffect {
|
||||||
class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl {
|
class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
private SubType fromSubType;
|
private SubType fromSubType;
|
||||||
private SubType toSubType;
|
private final SubType toSubType;
|
||||||
|
|
||||||
public ChangeCreatureTypeTargetEffect(SubType fromSubType, SubType toSubType, Duration duration) {
|
public ChangeCreatureTypeTargetEffect(SubType fromSubType, SubType toSubType, Duration duration) {
|
||||||
super(duration, Layer.TextChangingEffects_3, SubLayer.NA, Outcome.Benefit);
|
super(duration, Layer.TextChangingEffects_3, SubLayer.NA, Outcome.Benefit);
|
||||||
|
@ -153,6 +150,7 @@ class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeChoice.getChoice() == null) {
|
if (typeChoice.getChoice() == null) {
|
||||||
|
discard();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fromSubType = SubType.byDescription(typeChoice.getChoice());
|
fromSubType = SubType.byDescription(typeChoice.getChoice());
|
||||||
|
|
|
@ -105,7 +105,7 @@ class ProfaneProcessionEffect extends OneShotEffect {
|
||||||
new ExileTargetEffect(exileId, sourceObject.getIdName()).setTargetPointer(targetPointer).apply(game, source);
|
new ExileTargetEffect(exileId, sourceObject.getIdName()).setTargetPointer(targetPointer).apply(game, source);
|
||||||
game.applyEffects();
|
game.applyEffects();
|
||||||
ExileZone exileZone = game.getExile().getExileZone(exileId);
|
ExileZone exileZone = game.getExile().getExileZone(exileId);
|
||||||
if (exileZone.size() > 2) {
|
if (exileZone != null && exileZone.size() > 2) {
|
||||||
new TransformSourceEffect(true).apply(game, source);
|
new TransformSourceEffect(true).apply(game, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -27,11 +27,12 @@
|
||||||
*/
|
*/
|
||||||
package mage.abilities.common;
|
package mage.abilities.common;
|
||||||
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.events.EntersTheBattlefieldEvent;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.GameEvent.EventType;
|
import mage.game.events.GameEvent.EventType;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
@ -104,7 +105,6 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CreatureEntersBattlefieldTriggeredAbility(CreatureEntersBattlefieldTriggeredAbility ability) {
|
public CreatureEntersBattlefieldTriggeredAbility(CreatureEntersBattlefieldTriggeredAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
this.opponentController = ability.opponentController;
|
this.opponentController = ability.opponentController;
|
||||||
|
@ -118,7 +118,7 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||||
if (filter.match(permanent, sourceId, controllerId, game)
|
if (filter.match(permanent, sourceId, controllerId, game)
|
||||||
&& (permanent.getControllerId().equals(this.controllerId) ^ opponentController)) {
|
&& (permanent.getControllerId().equals(this.controllerId) ^ opponentController)) {
|
||||||
if (!this.getTargets().isEmpty()) {
|
if (!this.getTargets().isEmpty()) {
|
||||||
|
@ -137,7 +137,7 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever a " + filter.getMessage() +" enters the battlefield under "
|
return "Whenever a " + filter.getMessage() + " enters the battlefield under "
|
||||||
+ (opponentController ? "an opponent's control, " : "your control, ")
|
+ (opponentController ? "an opponent's control, " : "your control, ")
|
||||||
+ super.getRule();
|
+ super.getRule();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,12 +60,15 @@ import mage.target.TargetCard;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
import mage.util.GameLog;
|
import mage.util.GameLog;
|
||||||
import mage.util.ThreadLocalStringBuilder;
|
import mage.util.ThreadLocalStringBuilder;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public abstract class PermanentImpl extends CardImpl implements Permanent {
|
public abstract class PermanentImpl extends CardImpl implements Permanent {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(PermanentImpl.class);
|
||||||
|
|
||||||
public class MarkedDamageInfo {
|
public class MarkedDamageInfo {
|
||||||
|
|
||||||
public MarkedDamageInfo(Counter counter, MageObject sourceObject) {
|
public MarkedDamageInfo(Counter counter, MageObject sourceObject) {
|
||||||
|
@ -699,6 +702,10 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (getSpellAbility() == null) {
|
||||||
|
logger.info("FATAL : no spell ability for attach to permanent: " + getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!getSpellAbility().getTargets().isEmpty() && (getSpellAbility().getTargets().get(0) instanceof TargetCard)) {
|
if (!getSpellAbility().getTargets().isEmpty() && (getSpellAbility().getTargets().get(0) instanceof TargetCard)) {
|
||||||
Card attachedToCard = game.getCard(this.getAttachedTo());
|
Card attachedToCard = game.getCard(this.getAttachedTo());
|
||||||
if (attachedToCard != null) {
|
if (attachedToCard != null) {
|
||||||
|
|
Loading…
Reference in a new issue