Fixed various potential null pointer exceptions

This commit is contained in:
Evan Kranzler 2018-05-31 21:03:40 -04:00
parent 86f7a663b4
commit ab3cd76d3e
44 changed files with 438 additions and 439 deletions

View file

@ -155,7 +155,7 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
return true; return true;
} }
Permanent chosenPermanent = game.getPermanent(target.getFirstTarget()); Permanent chosenPermanent = game.getPermanent(target.getFirstTarget());
if (chosenPermanent != null && permanent != null && chosenPermanent.isCreature() && controller != null) { if (chosenPermanent != null && chosenPermanent.isCreature()) {
CombatGroup chosenGroup = game.getCombat().findGroup(chosenPermanent.getId()); CombatGroup chosenGroup = game.getCombat().findGroup(chosenPermanent.getId());
if (chosenGroup != null) { if (chosenGroup != null) {
// Relevant ruling for Balduvian Warlord: // Relevant ruling for Balduvian Warlord:

View file

@ -152,11 +152,13 @@ class BaronVonCountTriggeredAbility extends TriggeredAbilityImpl {
Permanent sourcePermanent = game.getPermanent(getSourceId()); Permanent sourcePermanent = game.getPermanent(getSourceId());
MageObject mageObject = game.getObject(getSourceId()); MageObject mageObject = game.getObject(getSourceId());
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (game.getState().getValue(mageObject.getId() + "_doom") == null) { if (spell == null || sourcePermanent == null || mageObject == null) {
return false; return false;
} }
Integer doomNumber = (Integer) game.getState().getValue(mageObject.getId() + "_doom"); Integer doomNumber = (Integer) game.getState().getValue(mageObject.getId() + "_doom");
if (spell != null && sourcePermanent != null && mageObject != null && doomNumber > 0) { if (doomNumber == null || doomNumber == 0) {
return false;
}
if (!spell.isFaceDown(game)) { if (!spell.isFaceDown(game)) {
String doomString = doomNumber.toString(); String doomString = doomNumber.toString();
if (spell.getCard().getManaCost().getText().contains(doomString) if (spell.getCard().getManaCost().getText().contains(doomString)
@ -172,7 +174,6 @@ class BaronVonCountTriggeredAbility extends TriggeredAbilityImpl {
} }
} }
} }
}
return false; return false;
} }

View file

@ -90,10 +90,11 @@ class AttachedPermanentPowerCount implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
Permanent attachment = game.getPermanentOrLKIBattlefield(sourceAbility.getSourceId()); Permanent attachment = game.getPermanentOrLKIBattlefield(sourceAbility.getSourceId());
if (attachment == null) {
return 0;
}
Permanent permanent = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo()); Permanent permanent = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo());
if (attachment != null if (permanent != null && (permanent.getPower().getValue() >= 0)) {
&& permanent != null
&& (permanent.getPower().getValue() >= 0)) {
return permanent.getPower().getValue(); return permanent.getPower().getValue();
} }
return 0; return 0;

View file

@ -86,11 +86,13 @@ class NumberOfCapitalsInTextOfTargetCreatureCount implements DynamicValue {
if (cards != null) { if (cards != null) {
for (CardInfo cardInfo : cards) { for (CardInfo cardInfo : cards) {
Card dummy = cardInfo != null ? cardInfo.getCard() : null; Card dummy = cardInfo != null ? cardInfo.getCard() : null;
if (dummy != null) {
for (String line : dummy.getRules()) { for (String line : dummy.getRules()) {
line = line.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic line = line.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
line = line.replaceAll("\\{this\\}", permanent.getName()); line = line.replaceAll("\\{this\\}", permanent.getName());
capitals += line.length() - line.replaceAll("[A-Z]", "").length(); capitals += line.length() - line.replaceAll("[A-Z]", "").length();
} }
}
return -1 * capitals; return -1 * capitals;
} }
} }

View file

@ -92,7 +92,7 @@ class CloneShellEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller == null) {
return false; return false;
} }
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4)); Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));

View file

@ -103,11 +103,15 @@ class CrownOfTheAgesEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
UUID auraId = getTargetPointer().getFirst(game, source); Permanent aura = game.getPermanent(source.getFirstTarget());
Permanent aura = game.getPermanent(auraId); if (aura == null) {
return false;
}
Permanent fromPermanent = game.getPermanent(aura.getAttachedTo()); Permanent fromPermanent = game.getPermanent(aura.getAttachedTo());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (fromPermanent != null && controller != null) { if (fromPermanent == null || controller == null) {
return false;
}
boolean passed = true; boolean passed = true;
FilterCreaturePermanent filterChoice = new FilterCreaturePermanent("another creature"); FilterCreaturePermanent filterChoice = new FilterCreaturePermanent("another creature");
filterChoice.add(Predicates.not(new PermanentIdPredicate(fromPermanent.getId()))); filterChoice.add(Predicates.not(new PermanentIdPredicate(fromPermanent.getId())));
@ -119,7 +123,7 @@ class CrownOfTheAgesEffect extends OneShotEffect {
&& controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source.getSourceId(), game)) { && controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source.getSourceId(), game)) {
Permanent creatureToAttachAura = game.getPermanent(chosenCreatureToAttachAura.getFirstTarget()); Permanent creatureToAttachAura = game.getPermanent(chosenCreatureToAttachAura.getFirstTarget());
if (creatureToAttachAura != null) { if (creatureToAttachAura != null) {
if (aura != null && passed) { if (passed) {
// Check the target filter // Check the target filter
Target target = aura.getSpellAbility().getTargets().get(0); Target target = aura.getSpellAbility().getTargets().get(0);
if (target instanceof TargetPermanent) { if (target instanceof TargetPermanent) {
@ -128,7 +132,7 @@ class CrownOfTheAgesEffect extends OneShotEffect {
} }
} }
// Check for protection // Check for protection
MageObject auraObject = game.getObject(auraId); MageObject auraObject = game.getObject(aura.getId());
if (creatureToAttachAura.cantBeAttachedBy(auraObject, game)) { if (creatureToAttachAura.cantBeAttachedBy(auraObject, game)) {
passed = false; passed = false;
} }
@ -142,7 +146,4 @@ class CrownOfTheAgesEffect extends OneShotEffect {
} }
return true; return true;
} }
return false;
}
} }

View file

@ -173,7 +173,7 @@ class CrypticGatewayEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (source == null || source.getCosts() == null) { if (source.getCosts() == null) {
return false; return false;
} }

View file

@ -112,7 +112,7 @@ class DrainPowerEffect extends OneShotEffect {
for (Ability ability : permanent.getAbilities()) { for (Ability ability : permanent.getAbilities()) {
if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) { if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) {
ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability; ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability;
if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game).canActivate()) { if (manaAbility.canActivate(targetPlayer.getId(), game).canActivate()) {
// canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc) // canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc)
// so it's necessary to filter them out manually - might be buggy in some fringe cases // so it's necessary to filter them out manually - might be buggy in some fringe cases
for (ManaCost manaCost : manaAbility.getManaCosts()) { for (ManaCost manaCost : manaAbility.getManaCosts()) {

View file

@ -98,10 +98,15 @@ class BecomesColorOrColorsEnchantedEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (enchantment == null) {
return false;
}
Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (controller != null && enchantment != null && permanent != null) { if (controller == null || permanent == null) {
return false;
}
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
if (i > 0) { if (i > 0) {
if (!controller.chooseUse(Outcome.Neutral, "Do you wish to choose another color?", source, game)) { if (!controller.chooseUse(Outcome.Neutral, "Do you wish to choose another color?", source, game)) {
@ -135,8 +140,6 @@ class BecomesColorOrColorsEnchantedEffect extends OneShotEffect {
return true; return true;
} }
return false;
}
@Override @Override
public BecomesColorOrColorsEnchantedEffect copy() { public BecomesColorOrColorsEnchantedEffect copy() {

View file

@ -121,7 +121,9 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getTargets().getFirstTarget()); Permanent permanent = game.getPermanent(source.getTargets().getFirstTarget());
if (controller != null && permanent != null) { if (controller == null || permanent == null) {
return false;
}
// Remove target creature from combat // Remove target creature from combat
Effect effect = new RemoveFromCombatTargetEffect(); Effect effect = new RemoveFromCombatTargetEffect();
@ -140,13 +142,15 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
} }
} }
if (!permanent.isCreature()
|| !controller.chooseUse(Outcome.Benefit, "Do you want " + permanent.getLogName() + " to block an attacking creature?", source, game)) {
return false;
}
// Choose new creature to block // Choose new creature to block
if (permanent.isCreature()) {
if (controller.chooseUse(Outcome.Benefit, "Do you want " + permanent.getLogName() + " to block an attacking creature?", source, game)) {
// according to the following mail response from MTG Rules Management about False Orders: // according to the following mail response from MTG Rules Management about False Orders:
// "if Player A attacks Players B and C, Player B's creatures cannot block creatures attacking Player C" // "if Player A attacks Players B and C, Player B's creatures cannot block creatures attacking Player C"
// therefore we need to single out creatures attacking the target blocker's controller (disappointing, I know) // therefore we need to single out creatures attacking the target blocker's controller (disappointing, I know)
List<Permanent> list = new ArrayList<>(); List<Permanent> list = new ArrayList<>();
for (CombatGroup combatGroup : game.getCombat().getGroups()) { for (CombatGroup combatGroup : game.getCombat().getGroups()) {
if (combatGroup.getDefendingPlayerId().equals(permanent.getControllerId())) { if (combatGroup.getDefendingPlayerId().equals(permanent.getControllerId())) {
@ -157,7 +161,9 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
} }
} }
Player targetsController = game.getPlayer(permanent.getControllerId()); Player targetsController = game.getPlayer(permanent.getControllerId());
if (targetsController != null) { if (targetsController == null) {
return false;
}
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName()); FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
filter.add(new PermanentInListPredicate(list)); filter.add(new PermanentInListPredicate(list));
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true); TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
@ -169,7 +175,9 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
return true; return true;
} }
Permanent chosenPermanent = game.getPermanent(target.getFirstTarget()); Permanent chosenPermanent = game.getPermanent(target.getFirstTarget());
if (chosenPermanent != null && permanent != null && chosenPermanent.isCreature() && controller != null) { if (chosenPermanent == null || !chosenPermanent.isCreature()) {
return false;
}
CombatGroup chosenGroup = game.getCombat().findGroup(chosenPermanent.getId()); CombatGroup chosenGroup = game.getCombat().findGroup(chosenPermanent.getId());
if (chosenGroup != null) { if (chosenGroup != null) {
// Relevant ruling for Balduvian Warlord: // Relevant ruling for Balduvian Warlord:
@ -193,14 +201,8 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
if (blockGroup != null) { if (blockGroup != null) {
blockGroup.pickAttackerOrder(permanent.getControllerId(), game); blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
} }
}
}
}
return true; return true;
} }
}
return false;
}
private CombatGroup findBlockingGroup(Permanent blocker, Game game) { private CombatGroup findBlockingGroup(Permanent blocker, Game game) {
if (game.getCombat().blockingGroupsContains(blocker.getId())) { // if (blocker.getBlocking() > 1) { if (game.getCombat().blockingGroupsContains(blocker.getId())) { // if (blocker.getBlocking() > 1) {

View file

@ -93,8 +93,8 @@ class GildedCerodonCondition implements Condition {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null if (controller != null
&& !game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).isEmpty() && (!game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).isEmpty()
|| controller.getGraveyard().count(filter2, game) > 0) { || controller.getGraveyard().count(filter2, game) > 0)) {
return true; return true;
} }
return false; return false;

View file

@ -98,6 +98,10 @@ class GlissaSunseekerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller == null || permanent == null) {
return false;
}
ManaPool pool = controller.getManaPool(); ManaPool pool = controller.getManaPool();
int blackMana = pool.getBlack(); int blackMana = pool.getBlack();
int whiteMana = pool.getWhite(); int whiteMana = pool.getWhite();
@ -106,12 +110,9 @@ class GlissaSunseekerEffect extends OneShotEffect {
int redMana = pool.getRed(); int redMana = pool.getRed();
int colorlessMana = pool.getColorless(); int colorlessMana = pool.getColorless();
int manaPoolTotal = blackMana + whiteMana + blueMana + greenMana + redMana + colorlessMana; int manaPoolTotal = blackMana + whiteMana + blueMana + greenMana + redMana + colorlessMana;
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller != null && permanent != null) {
if (permanent.getConvertedManaCost() == manaPoolTotal) { if (permanent.getConvertedManaCost() == manaPoolTotal) {
return permanent.destroy(source.getSourceId(), game, false); return permanent.destroy(source.getSourceId(), game, false);
} }
}
return false; return false;
} }
} }

View file

@ -97,9 +97,9 @@ class GoblinPsychopathEffect extends ReplacementEffectImpl {
@Override @Override
public boolean checksEventType(GameEvent event, Game game) { public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGE_CREATURE || return event.getType() == GameEvent.EventType.DAMAGE_CREATURE
event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER || || event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER
event.getType() == GameEvent.EventType.DAMAGE_PLAYER; || event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
} }
@Override @Override
@ -116,21 +116,19 @@ class GoblinPsychopathEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null && object != null) { if (controller == null || object == null
if (this.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) { || !(this.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0)) {
return false;
}
DamageEvent damageEvent = (DamageEvent) event; DamageEvent damageEvent = (DamageEvent) event;
if (damageEvent.isCombatDamage()) { if (!damageEvent.isCombatDamage() || wonFlip) {
if (!wonFlip) { return false;
}
// TODO: make this redirect damage from all blockers // TODO: make this redirect damage from all blockers
controller.damage(event.getAmount(), source.getSourceId(), game, false, true); controller.damage(event.getAmount(), source.getSourceId(), game, false, true);
String sourceLogName = source != null ? game.getObject(source.getSourceId()).getLogName() + ": " : ""; String sourceLogName = game.getObject(source.getSourceId()).getLogName() + ": ";
game.informPlayers(sourceLogName + "Redirected " + event.getAmount() + " damage to " + controller.getLogName()); game.informPlayers(sourceLogName + "Redirected " + event.getAmount() + " damage to " + controller.getLogName());
this.discard(); this.discard();
return true; return true;
} }
} }
}
}
return false;
}
}

View file

@ -96,13 +96,12 @@ class HelldozerEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent helldozer = game.getPermanent(source.getSourceId()); Permanent helldozer = game.getPermanent(source.getSourceId());
Permanent landTarget = game.getPermanent(source.getFirstTarget()); Permanent landTarget = game.getPermanent(source.getFirstTarget());
if (landTarget != null) { if (landTarget == null) {
landTarget.destroy(id, game, false); return false;
} }
Permanent landPermanent = (Permanent) game.getLastKnownInformation(landTarget.getId(), Zone.BATTLEFIELD); boolean wasNonBasic = !landTarget.isBasic();
if (landPermanent != null landTarget.destroy(id, game, false);
&& !landPermanent.isBasic() if (wasNonBasic && helldozer != null) {
&& helldozer != null) {
return helldozer.untap(game); return helldozer.untap(game);
} }
return false; return false;

View file

@ -61,6 +61,7 @@ import mage.target.targetpointer.FixedTarget;
public final class Heroism extends CardImpl { public final class Heroism extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a white creature"); private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a white creature");
static { static {
filter.add(new ColorPredicate(ObjectColor.WHITE)); filter.add(new ColorPredicate(ObjectColor.WHITE));
} }
@ -85,6 +86,7 @@ public final class Heroism extends CardImpl {
class HeroismEffect extends OneShotEffect { class HeroismEffect extends OneShotEffect {
private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking red creature"); private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking red creature");
static { static {
filter.add(new ColorPredicate(ObjectColor.RED)); filter.add(new ColorPredicate(ObjectColor.RED));
} }
@ -111,7 +113,7 @@ class HeroismEffect extends OneShotEffect {
Player player = game.getPlayer(game.getActivePlayerId()); Player player = game.getPlayer(game.getActivePlayerId());
Cost cost = new ManaCostsImpl("{2}{R}"); Cost cost = new ManaCostsImpl("{2}{R}");
List<Permanent> permanentsToPrevent = new ArrayList<>(); List<Permanent> permanentsToPrevent = new ArrayList<>();
for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) { for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, game.getActivePlayerId(), game)) {
cost.clearPaid(); cost.clearPaid();
String message = "Pay " + cost.getText() + "? If you don't, " + permanent.getLogName() + "'s combat damage will be prevented this turn."; String message = "Pay " + cost.getText() + "? If you don't, " + permanent.getLogName() + "'s combat damage will be prevented this turn.";
if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) { if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) {

View file

@ -50,10 +50,8 @@ public final class ImmortalServitude extends CardImpl {
public ImmortalServitude(UUID ownerId, CardSetInfo setInfo) { public ImmortalServitude(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{W/B}{W/B}{W/B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{W/B}{W/B}{W/B}");
// Return each creature card with converted mana cost X from your graveyard to the battlefield. // Return each creature card with converted mana cost X from your graveyard to the battlefield.
this.getSpellAbility().addEffect(new ImmortalServitudeEffect()); this.getSpellAbility().addEffect(new ImmortalServitudeEffect());
} }
public ImmortalServitude(final ImmortalServitude card) { public ImmortalServitude(final ImmortalServitude card) {
@ -88,8 +86,7 @@ class ImmortalServitudeEffect extends OneShotEffect {
int count = source.getManaCostsToPay().getX(); int count = source.getManaCostsToPay().getX();
Set<Card> cards = you.getGraveyard().getCards(new FilterCreatureCard(), game); Set<Card> cards = you.getGraveyard().getCards(new FilterCreatureCard(), game);
for (Card card : cards) { for (Card card : cards) {
if (card.getConvertedManaCost() == count if (card != null && card.getConvertedManaCost() == count) {
&& card != null) {
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
} }
} }

View file

@ -63,10 +63,8 @@ public final class IronMaiden extends CardImpl {
return new IronMaiden(this); return new IronMaiden(this);
} }
} }
class IronMaidenEffect extends OneShotEffect { class IronMaidenEffect extends OneShotEffect {
private IronMaidenEffect(final IronMaidenEffect effect) { private IronMaidenEffect(final IronMaidenEffect effect) {
@ -80,17 +78,12 @@ class IronMaidenEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
if(player != null)
{
int amount = player.getHand().size() - 4;
if(amount > 0)
{
if (player != null) { if (player != null) {
int amount = player.getHand().size() - 4;
if (amount > 0) {
player.damage(amount, source.getSourceId(), game, false, true); player.damage(amount, source.getSourceId(), game, false, true);
return true; return true;
} }
}
} }
return false; return false;
} }

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.cards.i; package mage.cards.i;
import java.util.UUID; import java.util.UUID;
@ -101,8 +100,11 @@ class IronclawCurseEffect extends CantBlockAttachedEffect {
@Override @Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (enchantment == null) {
return false;
}
Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo());
if (enchantment != null && enchantment.getAttachedTo() != null) { if (enchantment.getAttachedTo() != null) {
return !(attacker.getPower().getValue() >= enchantedCreature.getToughness().getValue()); return !(attacker.getPower().getValue() >= enchantedCreature.getToughness().getValue());
} }
return true; return true;

View file

@ -265,16 +265,15 @@ class KarnPlayerExileEffect extends OneShotEffect {
if (sourceObject == null) { if (sourceObject == null) {
return false; return false;
} }
if (player != null) { if (player == null) {
return false;
}
TargetCardInHand target = new TargetCardInHand(); TargetCardInHand target = new TargetCardInHand();
if (target != null if (target.canChoose(source.getSourceId(), player.getId(), game)
&& target.canChoose(source.getSourceId(), player.getId(), game)) { && target.chooseTarget(Outcome.Exile, player.getId(), source, game)) {
if (target.chooseTarget(Outcome.Exile, player.getId(), source, game)) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
return player.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game), source, game, true, exileId, sourceObject.getIdName()); return player.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game), source, game, true, exileId, sourceObject.getIdName());
} }
}
}
return false; return false;
} }

View file

@ -50,7 +50,6 @@ public final class KillingWave extends CardImpl {
public KillingWave(UUID ownerId, CardSetInfo setInfo) { public KillingWave(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}");
// For each creature, its controller sacrifices it unless he or she pays X life. // For each creature, its controller sacrifices it unless he or she pays X life.
this.getSpellAbility().addEffect(new KillingWaveEffect()); this.getSpellAbility().addEffect(new KillingWaveEffect());
} }
@ -96,13 +95,14 @@ class KillingWaveEffect extends OneShotEffect {
FilterCreaturePermanent filter = new FilterCreaturePermanent(); FilterCreaturePermanent filter = new FilterCreaturePermanent();
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) {
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(filter, playerId, game); List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(filter, playerId, game);
int lifePaid = 0; int lifePaid = 0;
int playerLife = player.getLife(); int playerLife = player.getLife();
for (Permanent creature : creatures) { for (Permanent creature : creatures) {
String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed."; String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed.";
if (playerLife - amount - lifePaid >= 0 && player != null && player.chooseUse(Outcome.Neutral, message, source, game)) { if (playerLife - amount - lifePaid >= 0 && player.chooseUse(Outcome.Neutral, message, source, game)) {
game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName()); game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName());
lifePaid += amount; lifePaid += amount;
} else { } else {
@ -112,6 +112,7 @@ class KillingWaveEffect extends OneShotEffect {
} }
lifePaidAmounts.put(playerId, lifePaid); lifePaidAmounts.put(playerId, lifePaid);
} }
}
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
int lifePaid = lifePaidAmounts.get(playerId); int lifePaid = lifePaidAmounts.get(playerId);

View file

@ -107,16 +107,12 @@ class LastRitesEffect extends OneShotEffect {
controller.discard(card, source, game); controller.discard(card, source, game);
} }
} }
if (targetPlayer != null) {
FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") + " nonland card" + (discardCount > 1 ? "s" : "")); FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") + " nonland card" + (discardCount > 1 ? "s" : ""));
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
StaticValue discardValue = new StaticValue(discardCount); StaticValue discardValue = new StaticValue(discardCount);
Effect effect = new DiscardCardYouChooseTargetEffect(discardValue, filter, TargetController.ANY); Effect effect = new DiscardCardYouChooseTargetEffect(discardValue, filter, TargetController.ANY);
effect.setTargetPointer(new FixedTarget(targetPlayer.getId())); effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
effect.apply(game, source); effect.apply(game, source);
} else {
return false;
}
} }
return true; return true;
} }

View file

@ -85,13 +85,14 @@ class LudevicNecroAlchemistCondition implements Condition {
Player currentPlayer = null; Player currentPlayer = null;
UUID sourcePlayerId = source.getControllerId(); UUID sourcePlayerId = source.getControllerId();
Player firstPlayer = null; Player firstPlayer = null;
if (playerList != null) { if (playerList == null) {
return false;
}
firstPlayer = playerList.getCurrent(game); firstPlayer = playerList.getCurrent(game);
currentPlayer = playerList.getNext(game); currentPlayer = playerList.getNext(game);
}
while (watcher != null && currentPlayer != null) { while (watcher != null && currentPlayer != null) {
if (currentPlayer != null && !Objects.equals(currentPlayer.getId(), sourcePlayerId) && watcher.getLiveLost(currentPlayer.getId()) > 0) { if (!Objects.equals(currentPlayer.getId(), sourcePlayerId) && watcher.getLiveLost(currentPlayer.getId()) > 0) {
return true; return true;
} }
if (Objects.equals(currentPlayer, firstPlayer)) { if (Objects.equals(currentPlayer, firstPlayer)) {

View file

@ -103,7 +103,6 @@ class MammothHarnessTriggeredAbility extends BlocksOrBecomesBlockedTriggeredAbil
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId());
if (sourcePermanent != null) { if (sourcePermanent != null) {
Permanent attachedTo = game.getPermanentOrLKIBattlefield(sourcePermanent.getAttachedTo()); Permanent attachedTo = game.getPermanentOrLKIBattlefield(sourcePermanent.getAttachedTo());
if (sourcePermanent != null) {
if (event.getSourceId().equals(attachedTo.getId())) { if (event.getSourceId().equals(attachedTo.getId())) {
Permanent blocked = game.getPermanent(event.getTargetId()); Permanent blocked = game.getPermanent(event.getTargetId());
if (blocked != null && filter.match(blocked, game)) { if (blocked != null && filter.match(blocked, game)) {
@ -119,7 +118,6 @@ class MammothHarnessTriggeredAbility extends BlocksOrBecomesBlockedTriggeredAbil
} }
} }
} }
}
return false; return false;
} }

View file

@ -125,7 +125,6 @@ class MaralenOfTheMornsongEffect2 extends OneShotEffect {
Player player = game.getPlayer(activePlayerId); Player player = game.getPlayer(activePlayerId);
if (player != null) { if (player != null) {
player.loseLife(3, game, false); player.loseLife(3, game, false);
if (player != null) {
TargetCardInLibrary target = new TargetCardInLibrary(); TargetCardInLibrary target = new TargetCardInLibrary();
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {
player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game); player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
@ -133,7 +132,6 @@ class MaralenOfTheMornsongEffect2 extends OneShotEffect {
player.shuffleLibrary(source, game); player.shuffleLibrary(source, game);
return true; return true;
} }
}
return false; return false;
} }

View file

@ -97,12 +97,10 @@ class PerishTheThoughtEffect extends OneShotEffect {
if (you.choose(Outcome.Neutral, targetOpponent.getHand(), target, game)) { if (you.choose(Outcome.Neutral, targetOpponent.getHand(), target, game)) {
Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game); Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game);
if (chosenCard != null) { if (chosenCard != null) {
if (targetOpponent != null) {
chosenCard.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); chosenCard.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
targetOpponent.shuffleLibrary(source, game); targetOpponent.shuffleLibrary(source, game);
} }
} }
}
return true; return true;
} }
} }

View file

@ -103,11 +103,13 @@ class PowerLeakEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(game.getActivePlayerId()); Player player = game.getPlayer(game.getActivePlayerId());
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (player != null && permanent != null) { if (player == null || permanent == null) {
return false;
}
ManaCosts<ManaCost> cost = new ManaCostsImpl<>("{X}"); ManaCosts<ManaCost> cost = new ManaCostsImpl<>("{X}");
String message = "Pay {X} to prevent X damage from " + permanent.getLogName() + "?"; String message = "Pay {X} to prevent X damage from " + permanent.getLogName() + "?";
int xValue = 0; int xValue = 0;
if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) { if (player.chooseUse(Outcome.Neutral, message, source, game)) {
xValue = player.announceXMana(0, Integer.MAX_VALUE, "Choose the amount of mana to pay", game, source); xValue = player.announceXMana(0, Integer.MAX_VALUE, "Choose the amount of mana to pay", game, source);
cost.add(new GenericManaCost(xValue)); cost.add(new GenericManaCost(xValue));
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) { if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
@ -128,6 +130,4 @@ class PowerLeakEffect extends OneShotEffect {
effect.discard(); effect.discard();
return true; return true;
} }
return false;
}
} }

View file

@ -96,7 +96,10 @@ class SearchLibraryPutInGraveEffect extends SearchEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
UUID targetPlayerID = source.getFirstTarget(); UUID targetPlayerID = source.getFirstTarget();
if (controller != null && targetPlayerID != null && controller.searchLibrary(target, game, targetPlayerID)) { if (controller == null) {
return false;
}
if (targetPlayerID != null && controller.searchLibrary(target, game, targetPlayerID)) {
if (!target.getTargets().isEmpty()) { if (!target.getTargets().isEmpty()) {
Cards cards = new CardsImpl(target.getTargets()); Cards cards = new CardsImpl(target.getTargets());
controller.revealCards("Quiet Speculation", cards, game); controller.revealCards("Quiet Speculation", cards, game);
@ -108,5 +111,4 @@ class SearchLibraryPutInGraveEffect extends SearchEffect {
controller.shuffleLibrary(source, game); controller.shuffleLibrary(source, game);
return false; return false;
} }
} }

View file

@ -84,8 +84,11 @@ class RecoilEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(source.getFirstTarget()); Permanent target = game.getPermanent(source.getFirstTarget());
if (target == null) {
return false;
}
Player controller = game.getPlayer(target.getControllerId()); Player controller = game.getPlayer(target.getControllerId());
if (target != null && controller != null) { if (controller != null) {
controller.moveCards(target, Zone.HAND, source, game); controller.moveCards(target, Zone.HAND, source, game);
controller.discard(1, false, source, game); controller.discard(1, false, source, game);
return true; return true;

View file

@ -157,11 +157,9 @@ class SavingGraceReplacementEffect extends ReplacementEffectImpl {
} }
game.informPlayers(message.toString()); game.informPlayers(message.toString());
// Redirect damage // Redirect damage
if (creature != null) {
creature.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects()); creature.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
return true; return true;
} }
}
return false; return false;
} }

View file

@ -121,8 +121,13 @@ class SerraBestiaryRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (enchantment == null) {
return false;
}
Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo());
if (enchantment != null && enchantment.getAttachedTo() != null) { if (enchantedCreature == null) {
return false;
}
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId()); Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
if (ability.isPresent() if (ability.isPresent()
@ -134,7 +139,6 @@ class SerraBestiaryRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl
return true; return true;
} }
} }
}
return false; return false;
} }

View file

@ -127,7 +127,7 @@ class ShadesBreathSetSubtypeEffect extends ContinuousEffectImpl {
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (permanent != null) { if (permanent != null) {
SubTypeList subtype = permanent.getSubtype(game); SubTypeList subtype = permanent.getSubtype(game);
if (subtype != null && subtype.size() != 1 || !subtype.contains(SubType.SHADE)) { if (subtype != null && (subtype.size() != 1 || !subtype.contains(SubType.SHADE))) {
subtype.removeAll(SubType.getCreatureTypes(false)); subtype.removeAll(SubType.getCreatureTypes(false));
subtype.add(SubType.SHADE); subtype.add(SubType.SHADE);
} }

View file

@ -59,7 +59,6 @@ public final class SlowMotion extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
this.subtype.add(SubType.AURA); this.subtype.add(SubType.AURA);
// Enchant creature // Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent(); TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
@ -85,6 +84,7 @@ public final class SlowMotion extends CardImpl {
} }
class SacrificeEquipedUnlessPaysEffect extends OneShotEffect { class SacrificeEquipedUnlessPaysEffect extends OneShotEffect {
protected Cost cost; protected Cost cost;
public SacrificeEquipedUnlessPaysEffect(Cost cost) { public SacrificeEquipedUnlessPaysEffect(Cost cost) {
@ -101,10 +101,17 @@ class SacrificeEquipedUnlessPaysEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent equipment = game.getPermanent(source.getSourceId()); Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) { if (equipment == null) {
return false;
}
Permanent equipped = game.getPermanent(equipment.getAttachedTo()); Permanent equipped = game.getPermanent(equipment.getAttachedTo());
if (equipped == null) {
return false;
}
Player player = game.getPlayer(equipped.getControllerId()); Player player = game.getPlayer(equipped.getControllerId());
if (player != null && equipped != null) { if (player == null) {
return false;
}
if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? (Or " + equipped.getName() + " will be sacrificed.)", source, game)) { if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? (Or " + equipped.getName() + " will be sacrificed.)", source, game)) {
cost.clearPaid(); cost.clearPaid();
if (cost.pay(source, game, source.getSourceId(), equipped.getControllerId(), false, null)) { if (cost.pay(source, game, source.getSourceId(), equipped.getControllerId(), false, null)) {
@ -114,9 +121,6 @@ class SacrificeEquipedUnlessPaysEffect extends OneShotEffect {
equipped.sacrifice(source.getSourceId(), game); equipped.sacrifice(source.getSourceId(), game);
return true; return true;
} }
}
return false;
}
@Override @Override
public SacrificeEquipedUnlessPaysEffect copy() { public SacrificeEquipedUnlessPaysEffect copy() {

View file

@ -114,12 +114,10 @@ class SpikeCannibalEffect extends OneShotEffect {
} }
if (countersRemoved > 0) { if (countersRemoved > 0) {
if (sourcePermanent != null) {
sourcePermanent.addCounters(CounterType.P1P1.createInstance(countersRemoved), source, game); sourcePermanent.addCounters(CounterType.P1P1.createInstance(countersRemoved), source, game);
return true; return true;
} }
} }
}
return false; return false;
} }

View file

@ -133,7 +133,7 @@ class SpyNetworkFaceDownEffect extends OneShotEffect {
filter.add(new ControllerIdPredicate(player.getId())); filter.add(new ControllerIdPredicate(player.getId()));
TargetCreaturePermanent target = new TargetCreaturePermanent(1, 1, filter, true); TargetCreaturePermanent target = new TargetCreaturePermanent(1, 1, filter, true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)) { if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
while (player != null && controller.chooseUse(outcome, "Look at a face down creature controlled by " + player.getLogName() + "?", source, game)) { while (controller.chooseUse(outcome, "Look at a face down creature controlled by " + player.getLogName() + "?", source, game)) {
target.clearChosen(); target.clearChosen();
while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) { while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) {
controller.chooseTarget(outcome, target, source, game); controller.chooseTarget(outcome, target, source, game);
@ -145,12 +145,10 @@ class SpyNetworkFaceDownEffect extends OneShotEffect {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
cards.add(copyFaceDown); cards.add(copyFaceDown);
controller.lookAtCards("face down card - " + mageObject.getName(), cards, game); controller.lookAtCards("face down card - " + mageObject.getName(), cards, game);
if (player != null) {
game.informPlayers(controller.getLogName() + " looks at a face down creature controlled by " + player.getLogName()); game.informPlayers(controller.getLogName() + " looks at a face down creature controlled by " + player.getLogName());
} }
} }
} }
}
return true; return true;
} }
return false; return false;

View file

@ -112,8 +112,8 @@ class SummonThePackEffect extends OneShotEffect {
StringBuilder message = new StringBuilder(controller.getLogName()).append(" opened: "); StringBuilder message = new StringBuilder(controller.getLogName()).append(" opened: ");
for (Card c : boosterPack) { for (Card c : boosterPack) {
message.append(c.getName()).append(" ");
if (c != null && c.isCreature()) { if (c != null && c.isCreature()) {
message.append(c.getName()).append(" ");
message.append(" (creature card) "); message.append(" (creature card) ");
ContinuousEffect effect2 = new BecomesBlackZombieAdditionEffect(false); ContinuousEffect effect2 = new BecomesBlackZombieAdditionEffect(false);
effect2.setTargetPointer(new FixedTarget(c.getId())); effect2.setTargetPointer(new FixedTarget(c.getId()));
@ -124,7 +124,7 @@ class SummonThePackEffect extends OneShotEffect {
} }
if (creatureCards.size() > 0) { if (creatureCards.size() > 0) {
Set<Card> ccs = new HashSet<Card>(creatureCards); Set<Card> ccs = new HashSet<>(creatureCards);
game.loadCards(ccs, controller.getId()); game.loadCards(ccs, controller.getId());
controller.moveCards(ccs, Zone.BATTLEFIELD, source, game); controller.moveCards(ccs, Zone.BATTLEFIELD, source, game);
} }

View file

@ -102,7 +102,7 @@ class TheBattleOfYavinEffect extends OneShotEffect {
int playerLife = opponent.getLife(); int playerLife = opponent.getLife();
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
String message = "Pay " + amount + " life? If you don't, " + permanent.getName() + " will be sacrificed."; String message = "Pay " + amount + " life? If you don't, " + permanent.getName() + " will be sacrificed.";
if (playerLife - amount - lifePaid >= 0 && opponent != null && opponent.chooseUse(Outcome.Neutral, message, source, game)) { if (playerLife - amount - lifePaid >= 0 && opponent.chooseUse(Outcome.Neutral, message, source, game)) {
game.informPlayers(opponent.getLogName() + " pays " + amount + " life. He will not sacrifice " + permanent.getName()); game.informPlayers(opponent.getLogName() + " pays " + amount + " life. He will not sacrifice " + permanent.getName());
lifePaid += amount; lifePaid += amount;
} else { } else {

View file

@ -81,6 +81,7 @@ public final class TidalFlats extends CardImpl {
class TidalFlatsEffect extends OneShotEffect { class TidalFlatsEffect extends OneShotEffect {
private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking creature without flying"); private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking creature without flying");
static { static {
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
} }
@ -103,17 +104,21 @@ class TidalFlatsEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
game.getPlayerList(); game.getPlayerList();
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller == null) {
return false;
}
Player player = game.getPlayer(game.getActivePlayerId()); Player player = game.getPlayer(game.getActivePlayerId());
if (player == null) {
return false;
}
Cost cost = new ManaCostsImpl("{1}"); Cost cost = new ManaCostsImpl("{1}");
List<Permanent> affectedPermanents = new ArrayList<>(); List<Permanent> affectedPermanents = new ArrayList<>();
for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) { for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
cost.clearPaid(); cost.clearPaid();
String message = "Pay " + cost.getText() + " for " + permanent.getLogName() + "? If you don't, creatures " + controller.getLogName() + " controls blocking it gain first strike until end of turn."; String message = "Pay " + cost.getText() + " for " + permanent.getLogName() + "? If you don't, creatures " + controller.getLogName() + " controls blocking it gain first strike until end of turn.";
if (player != null && player.chooseUse(Outcome.Benefit, message, source, game)) { if (player.chooseUse(Outcome.Benefit, message, source, game)) {
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) { if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
game.informPlayers(player.getLogName() + " paid " + cost.getText() + " for " + permanent.getLogName()); game.informPlayers(player.getLogName() + " paid " + cost.getText() + " for " + permanent.getLogName());
continue;
} else { } else {
game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName()); game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName());
affectedPermanents.add(permanent); affectedPermanents.add(permanent);
@ -140,6 +145,4 @@ class TidalFlatsEffect extends OneShotEffect {
} }
return true; return true;
} }
return false;
}
} }

View file

@ -122,7 +122,7 @@ class TorrentialGearhulkEffect extends OneShotEffect {
game.addEffect(effect, source); game.addEffect(effect, source);
} }
} }
} else { } else if (card != null) {
Logger.getLogger(TorrentialGearhulkEffect.class).error("Torrential Gearhulk - Instant card without spellAbility : " + card.getName()); Logger.getLogger(TorrentialGearhulkEffect.class).error("Torrential Gearhulk - Instant card without spellAbility : " + card.getName());
return false; return false;
} }

View file

@ -109,13 +109,16 @@ class TreacherousLinkEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent) event; DamageEvent damageEvent = (DamageEvent) event;
Permanent enchantedCreature = game.getPermanentOrLKIBattlefield(damageEvent.getTargetId()); Permanent enchantedCreature = game.getPermanentOrLKIBattlefield(damageEvent.getTargetId());
if (enchantedCreature == null) {
return false;
}
Player controller = game.getPlayer(enchantedCreature.getControllerId()); Player controller = game.getPlayer(enchantedCreature.getControllerId());
if (enchantedCreature != null && controller != null) { if (controller == null) {
return false;
}
controller.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects()); controller.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
return true; return true;
} }
return false;
}
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {

View file

@ -100,7 +100,7 @@ class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSource
} }
public boolean isEnchantedCreature(MageObject input, Game game) { public boolean isEnchantedCreature(MageObject input, Game game) {
if (input != null && !input.isCreature()) { if (input == null || input.isCreature()) {
return false; return false;
} }
for (UUID attachmentId : ((Permanent) input).getAttachments()) { for (UUID attachmentId : ((Permanent) input).getAttachments()) {

View file

@ -64,7 +64,6 @@ public final class WheelOfTorture extends CardImpl {
} }
} }
class WheelOfTortureEffect extends OneShotEffect { class WheelOfTortureEffect extends OneShotEffect {
private WheelOfTortureEffect(final WheelOfTortureEffect effect) { private WheelOfTortureEffect(final WheelOfTortureEffect effect) {
@ -78,17 +77,12 @@ class WheelOfTortureEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player player = game.getPlayer(targetPointer.getFirst(game, source));
if(player != null)
{
int amount = 3 - player.getHand().size();
if(amount > 0)
{
if (player != null) { if (player != null) {
int amount = 3 - player.getHand().size();
if (amount > 0) {
player.damage(amount, source.getSourceId(), game, false, true); player.damage(amount, source.getSourceId(), game, false, true);
return true; return true;
} }
}
} }
return false; return false;
} }
@ -103,5 +97,4 @@ class WheelOfTortureEffect extends OneShotEffect {
return "Wheel of Torture deals X damage to that player, where X is 3 minus the number of cards in their hand"; return "Wheel of Torture deals X damage to that player, where X is 3 minus the number of cards in their hand";
} }
} }

View file

@ -83,6 +83,9 @@ class WretchedBanquetEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent targetCreature = game.getPermanent(source.getFirstTarget()); Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (targetCreature == null) {
return false;
}
List<Permanent> creatures = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game); List<Permanent> creatures = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game);
int minPower = targetCreature.getPower().getValue() + 1; int minPower = targetCreature.getPower().getValue() + 1;
@ -92,7 +95,7 @@ class WretchedBanquetEffect extends OneShotEffect {
} }
} }
if (targetCreature != null && targetCreature.getPower().getValue() <= minPower) { if (targetCreature.getPower().getValue() <= minPower) {
targetCreature.destroy(source.getSourceId(), game, false); targetCreature.destroy(source.getSourceId(), game, false);
return true; return true;
} }

View file

@ -1,6 +1,5 @@
package mage.verify; package mage.verify;
import javassist.bytecode.SignatureAttribute;
import mage.ObjectColor; import mage.ObjectColor;
import mage.cards.*; import mage.cards.*;
import mage.cards.basiclands.BasicLand; import mage.cards.basiclands.BasicLand;
@ -352,9 +351,7 @@ public class VerifyCardDataTest {
//Assert.assertNotNull("Can't create token by default constructor", token); //Assert.assertNotNull("Can't create token by default constructor", token);
if (token == null) { if (token == null) {
Assert.fail("Can't create token by default constructor: " + className); Assert.fail("Can't create token by default constructor: " + className);
} } else if (tokDataNamesIndex.getOrDefault(token.getName(), "").isEmpty()) {
if (tokDataNamesIndex.getOrDefault(token.getName(), "").isEmpty()) {
errorsList.add("error, can't find data in card-pictures-tok.txt for token: " + tokenClass.getName() + " -> " + token.getName()); errorsList.add("error, can't find data in card-pictures-tok.txt for token: " + tokenClass.getName() + " -> " + token.getName());
} }
} }

View file

@ -103,7 +103,7 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf
} }
if (targetController != null) { if (targetController != null) {
MageObject sourceObject = game.getObject(source.getSourceId()); MageObject sourceObject = game.getObject(source.getSourceId());
if (targetController != null && sourceObject != null) { if (sourceObject != null) {
Cost costToPay; Cost costToPay;
if (cost != null) { if (cost != null) {
costToPay = cost.copy(); costToPay = cost.copy();