mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Fixed various potential null pointer exceptions
This commit is contained in:
parent
86f7a663b4
commit
ab3cd76d3e
44 changed files with 438 additions and 439 deletions
|
@ -155,7 +155,7 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
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());
|
||||
if (chosenGroup != null) {
|
||||
// Relevant ruling for Balduvian Warlord:
|
||||
|
|
|
@ -59,7 +59,7 @@ import mage.util.CardUtil;
|
|||
public final class BaronVonCount extends CardImpl {
|
||||
|
||||
public BaronVonCount(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.VILLAIN);
|
||||
|
@ -152,22 +152,23 @@ class BaronVonCountTriggeredAbility extends TriggeredAbilityImpl {
|
|||
Permanent sourcePermanent = game.getPermanent(getSourceId());
|
||||
MageObject mageObject = game.getObject(getSourceId());
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
||||
if (spell == null || sourcePermanent == null || mageObject == null) {
|
||||
return false;
|
||||
}
|
||||
Integer doomNumber = (Integer) game.getState().getValue(mageObject.getId() + "_doom");
|
||||
if (spell != null && sourcePermanent != null && mageObject != null && doomNumber > 0) {
|
||||
if (!spell.isFaceDown(game)) {
|
||||
String doomString = doomNumber.toString();
|
||||
if (spell.getCard().getManaCost().getText().contains(doomString)
|
||||
|| String.valueOf(spell.getPower().getBaseValue()).contains(doomString)
|
||||
|| String.valueOf(spell.getToughness().getBaseValue()).contains(doomString)) {
|
||||
return true;
|
||||
} else {
|
||||
for (String string : spell.getCard().getRules()) {
|
||||
if (string.contains(doomString)) {
|
||||
return true;
|
||||
}
|
||||
if (doomNumber == null || doomNumber == 0) {
|
||||
return false;
|
||||
}
|
||||
if (!spell.isFaceDown(game)) {
|
||||
String doomString = doomNumber.toString();
|
||||
if (spell.getCard().getManaCost().getText().contains(doomString)
|
||||
|| String.valueOf(spell.getPower().getBaseValue()).contains(doomString)
|
||||
|| String.valueOf(spell.getToughness().getBaseValue()).contains(doomString)) {
|
||||
return true;
|
||||
} else {
|
||||
for (String string : spell.getCard().getRules()) {
|
||||
if (string.contains(doomString)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
|
|||
public final class BloodfireInfusion extends CardImpl {
|
||||
|
||||
public BloodfireInfusion(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant creature you control
|
||||
|
@ -90,10 +90,11 @@ class AttachedPermanentPowerCount implements DynamicValue {
|
|||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
Permanent attachment = game.getPermanentOrLKIBattlefield(sourceAbility.getSourceId());
|
||||
if (attachment == null) {
|
||||
return 0;
|
||||
}
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo());
|
||||
if (attachment != null
|
||||
&& permanent != null
|
||||
&& (permanent.getPower().getValue() >= 0)) {
|
||||
if (permanent != null && (permanent.getPower().getValue() >= 0)) {
|
||||
return permanent.getPower().getValue();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -86,10 +86,12 @@ class NumberOfCapitalsInTextOfTargetCreatureCount implements DynamicValue {
|
|||
if (cards != null) {
|
||||
for (CardInfo cardInfo : cards) {
|
||||
Card dummy = cardInfo != null ? cardInfo.getCard() : null;
|
||||
for (String line : dummy.getRules()) {
|
||||
line = line.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
|
||||
line = line.replaceAll("\\{this\\}", permanent.getName());
|
||||
capitals += line.length() - line.replaceAll("[A-Z]", "").length();
|
||||
if (dummy != null) {
|
||||
for (String line : dummy.getRules()) {
|
||||
line = line.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
|
||||
line = line.replaceAll("\\{this\\}", permanent.getName());
|
||||
capitals += line.length() - line.replaceAll("[A-Z]", "").length();
|
||||
}
|
||||
}
|
||||
return -1 * capitals;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ class CloneShellEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
|
||||
|
|
|
@ -103,46 +103,47 @@ class CrownOfTheAgesEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID auraId = getTargetPointer().getFirst(game, source);
|
||||
Permanent aura = game.getPermanent(auraId);
|
||||
Permanent aura = game.getPermanent(source.getFirstTarget());
|
||||
if (aura == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent fromPermanent = game.getPermanent(aura.getAttachedTo());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (fromPermanent != null && controller != null) {
|
||||
boolean passed = true;
|
||||
FilterCreaturePermanent filterChoice = new FilterCreaturePermanent("another creature");
|
||||
filterChoice.add(Predicates.not(new PermanentIdPredicate(fromPermanent.getId())));
|
||||
if (fromPermanent == null || controller == null) {
|
||||
return false;
|
||||
}
|
||||
boolean passed = true;
|
||||
FilterCreaturePermanent filterChoice = new FilterCreaturePermanent("another creature");
|
||||
filterChoice.add(Predicates.not(new PermanentIdPredicate(fromPermanent.getId())));
|
||||
|
||||
Target chosenCreatureToAttachAura = new TargetPermanent(filterChoice);
|
||||
chosenCreatureToAttachAura.setNotTarget(true);
|
||||
Target chosenCreatureToAttachAura = new TargetPermanent(filterChoice);
|
||||
chosenCreatureToAttachAura.setNotTarget(true);
|
||||
|
||||
if (chosenCreatureToAttachAura.canChoose(source.getSourceId(), source.getControllerId(), game)
|
||||
&& controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source.getSourceId(), game)) {
|
||||
Permanent creatureToAttachAura = game.getPermanent(chosenCreatureToAttachAura.getFirstTarget());
|
||||
if (creatureToAttachAura != null) {
|
||||
if (aura != null && passed) {
|
||||
// Check the target filter
|
||||
Target target = aura.getSpellAbility().getTargets().get(0);
|
||||
if (target instanceof TargetPermanent) {
|
||||
if (!target.getFilter().match(creatureToAttachAura, game)) {
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
// Check for protection
|
||||
MageObject auraObject = game.getObject(auraId);
|
||||
if (creatureToAttachAura.cantBeAttachedBy(auraObject, game)) {
|
||||
if (chosenCreatureToAttachAura.canChoose(source.getSourceId(), source.getControllerId(), game)
|
||||
&& controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source.getSourceId(), game)) {
|
||||
Permanent creatureToAttachAura = game.getPermanent(chosenCreatureToAttachAura.getFirstTarget());
|
||||
if (creatureToAttachAura != null) {
|
||||
if (passed) {
|
||||
// Check the target filter
|
||||
Target target = aura.getSpellAbility().getTargets().get(0);
|
||||
if (target instanceof TargetPermanent) {
|
||||
if (!target.getFilter().match(creatureToAttachAura, game)) {
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
if (passed) {
|
||||
fromPermanent.removeAttachment(aura.getId(), game);
|
||||
creatureToAttachAura.addAttachment(aura.getId(), game);
|
||||
return true;
|
||||
// Check for protection
|
||||
MageObject auraObject = game.getObject(aura.getId());
|
||||
if (creatureToAttachAura.cantBeAttachedBy(auraObject, game)) {
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
if (passed) {
|
||||
fromPermanent.removeAttachment(aura.getId(), game);
|
||||
creatureToAttachAura.addAttachment(aura.getId(), game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public final class CrypticGateway extends CardImpl {
|
|||
TargetControlledPermanent target;
|
||||
|
||||
public CrypticGateway(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||
|
||||
// Tap two untapped creatures you control: You may put a creature card from your hand that shares a creature type with each creature tapped this way onto the battlefield.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CrypticGatewayEffect(), new CrypticGatewayCost(new TargetControlledPermanent(filter))));
|
||||
|
@ -173,7 +173,7 @@ class CrypticGatewayEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (source == null || source.getCosts() == null) {
|
||||
if (source.getCosts() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ class DrainPowerEffect extends OneShotEffect {
|
|||
for (Ability ability : permanent.getAbilities()) {
|
||||
if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) {
|
||||
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)
|
||||
// so it's necessary to filter them out manually - might be buggy in some fringe cases
|
||||
for (ManaCost manaCost : manaAbility.getManaCosts()) {
|
||||
|
|
|
@ -98,44 +98,47 @@ class BecomesColorOrColorsEnchantedEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (enchantment == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (controller != null && enchantment != null && permanent != null) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i > 0) {
|
||||
if (!controller.chooseUse(Outcome.Neutral, "Do you wish to choose another color?", source, game)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ChoiceColor choiceColor = new ChoiceColor();
|
||||
if (!controller.choose(Outcome.Benefit, choiceColor, game)) {
|
||||
return false;
|
||||
}
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(permanent.getName() + ": " + controller.getLogName() + " has chosen " + choiceColor.getChoice());
|
||||
}
|
||||
if (choiceColor.getColor().isBlack()) {
|
||||
sb.append('B');
|
||||
} else if (choiceColor.getColor().isBlue()) {
|
||||
sb.append('U');
|
||||
} else if (choiceColor.getColor().isRed()) {
|
||||
sb.append('R');
|
||||
} else if (choiceColor.getColor().isGreen()) {
|
||||
sb.append('G');
|
||||
} else if (choiceColor.getColor().isWhite()) {
|
||||
sb.append('W');
|
||||
if (controller == null || permanent == null) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i > 0) {
|
||||
if (!controller.chooseUse(Outcome.Neutral, "Do you wish to choose another color?", source, game)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
String colors = new String(sb);
|
||||
ObjectColor chosenColors = new ObjectColor(colors);
|
||||
ContinuousEffect effect = new BecomesColorTargetEffect(chosenColors, Duration.Custom);
|
||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
||||
game.addEffect(effect, source);
|
||||
|
||||
return true;
|
||||
ChoiceColor choiceColor = new ChoiceColor();
|
||||
if (!controller.choose(Outcome.Benefit, choiceColor, game)) {
|
||||
return false;
|
||||
}
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(permanent.getName() + ": " + controller.getLogName() + " has chosen " + choiceColor.getChoice());
|
||||
}
|
||||
if (choiceColor.getColor().isBlack()) {
|
||||
sb.append('B');
|
||||
} else if (choiceColor.getColor().isBlue()) {
|
||||
sb.append('U');
|
||||
} else if (choiceColor.getColor().isRed()) {
|
||||
sb.append('R');
|
||||
} else if (choiceColor.getColor().isGreen()) {
|
||||
sb.append('G');
|
||||
} else if (choiceColor.getColor().isWhite()) {
|
||||
sb.append('W');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
String colors = new String(sb);
|
||||
ObjectColor chosenColors = new ObjectColor(colors);
|
||||
ContinuousEffect effect = new BecomesColorTargetEffect(chosenColors, Duration.Custom);
|
||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
||||
game.addEffect(effect, source);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -121,85 +121,87 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = game.getPermanent(source.getTargets().getFirstTarget());
|
||||
if (controller != null && permanent != null) {
|
||||
if (controller == null || permanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove target creature from combat
|
||||
Effect effect = new RemoveFromCombatTargetEffect();
|
||||
effect.apply(game, source);
|
||||
// Remove target creature from combat
|
||||
Effect effect = new RemoveFromCombatTargetEffect();
|
||||
effect.apply(game, source);
|
||||
|
||||
// Make blocked creatures unblocked
|
||||
BlockedByOnlyOneCreatureThisCombatWatcher watcher = (BlockedByOnlyOneCreatureThisCombatWatcher) game.getState().getWatchers().get(BlockedByOnlyOneCreatureThisCombatWatcher.class.getSimpleName());
|
||||
if (watcher != null) {
|
||||
Set<CombatGroup> combatGroups = watcher.getBlockedOnlyByCreature(permanent.getId());
|
||||
if (combatGroups != null) {
|
||||
for (CombatGroup combatGroup : combatGroups) {
|
||||
if (combatGroup != null) {
|
||||
combatGroup.setBlocked(false, game);
|
||||
}
|
||||
// Make blocked creatures unblocked
|
||||
BlockedByOnlyOneCreatureThisCombatWatcher watcher = (BlockedByOnlyOneCreatureThisCombatWatcher) game.getState().getWatchers().get(BlockedByOnlyOneCreatureThisCombatWatcher.class.getSimpleName());
|
||||
if (watcher != null) {
|
||||
Set<CombatGroup> combatGroups = watcher.getBlockedOnlyByCreature(permanent.getId());
|
||||
if (combatGroups != null) {
|
||||
for (CombatGroup combatGroup : combatGroups) {
|
||||
if (combatGroup != null) {
|
||||
combatGroup.setBlocked(false, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
// "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)
|
||||
|
||||
List<Permanent> list = new ArrayList<>();
|
||||
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
||||
if (combatGroup.getDefendingPlayerId().equals(permanent.getControllerId())) {
|
||||
for (UUID attackingCreatureId : combatGroup.getAttackers()) {
|
||||
Permanent targetsControllerAttacker = game.getPermanent(attackingCreatureId);
|
||||
list.add(targetsControllerAttacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
Player targetsController = game.getPlayer(permanent.getControllerId());
|
||||
if (targetsController != null) {
|
||||
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
|
||||
filter.add(new PermanentInListPredicate(list));
|
||||
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
|
||||
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
Permanent chosenPermanent = game.getPermanent(target.getFirstTarget());
|
||||
if (chosenPermanent != null && permanent != null && chosenPermanent.isCreature() && controller != null) {
|
||||
CombatGroup chosenGroup = game.getCombat().findGroup(chosenPermanent.getId());
|
||||
if (chosenGroup != null) {
|
||||
// Relevant ruling for Balduvian Warlord:
|
||||
// 7/15/2006 If an attacking creature has an ability that triggers “When this creature becomes blocked,”
|
||||
// it triggers when a creature blocks it due to the Warlord’s ability only if it was unblocked at that point.
|
||||
boolean notYetBlocked = chosenGroup.getBlockers().isEmpty();
|
||||
chosenGroup.addBlockerToGroup(permanent.getId(), controller.getId(), game);
|
||||
game.getCombat().addBlockingGroup(permanent.getId(), chosenPermanent.getId(), controller.getId(), game); // 702.21h
|
||||
if (notYetBlocked) {
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, chosenPermanent.getId(), null));
|
||||
for (UUID bandedId : chosenPermanent.getBandedCards()) {
|
||||
CombatGroup bandedGroup = game.getCombat().findGroup(bandedId);
|
||||
if (bandedGroup != null && chosenGroup.getBlockers().size() == 1) {
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, bandedId, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BLOCKER_DECLARED, chosenPermanent.getId(), permanent.getId(), permanent.getControllerId()));
|
||||
}
|
||||
CombatGroup blockGroup = findBlockingGroup(permanent, game); // a new blockingGroup is formed, so it's necessary to find it again
|
||||
if (blockGroup != null) {
|
||||
blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
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
|
||||
|
||||
// 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"
|
||||
// therefore we need to single out creatures attacking the target blocker's controller (disappointing, I know)
|
||||
List<Permanent> list = new ArrayList<>();
|
||||
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
||||
if (combatGroup.getDefendingPlayerId().equals(permanent.getControllerId())) {
|
||||
for (UUID attackingCreatureId : combatGroup.getAttackers()) {
|
||||
Permanent targetsControllerAttacker = game.getPermanent(attackingCreatureId);
|
||||
list.add(targetsControllerAttacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
Player targetsController = game.getPlayer(permanent.getControllerId());
|
||||
if (targetsController == null) {
|
||||
return false;
|
||||
}
|
||||
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
|
||||
filter.add(new PermanentInListPredicate(list));
|
||||
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
|
||||
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
Permanent chosenPermanent = game.getPermanent(target.getFirstTarget());
|
||||
if (chosenPermanent == null || !chosenPermanent.isCreature()) {
|
||||
return false;
|
||||
}
|
||||
CombatGroup chosenGroup = game.getCombat().findGroup(chosenPermanent.getId());
|
||||
if (chosenGroup != null) {
|
||||
// Relevant ruling for Balduvian Warlord:
|
||||
// 7/15/2006 If an attacking creature has an ability that triggers “When this creature becomes blocked,”
|
||||
// it triggers when a creature blocks it due to the Warlord’s ability only if it was unblocked at that point.
|
||||
boolean notYetBlocked = chosenGroup.getBlockers().isEmpty();
|
||||
chosenGroup.addBlockerToGroup(permanent.getId(), controller.getId(), game);
|
||||
game.getCombat().addBlockingGroup(permanent.getId(), chosenPermanent.getId(), controller.getId(), game); // 702.21h
|
||||
if (notYetBlocked) {
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, chosenPermanent.getId(), null));
|
||||
for (UUID bandedId : chosenPermanent.getBandedCards()) {
|
||||
CombatGroup bandedGroup = game.getCombat().findGroup(bandedId);
|
||||
if (bandedGroup != null && chosenGroup.getBlockers().size() == 1) {
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, bandedId, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BLOCKER_DECLARED, chosenPermanent.getId(), permanent.getId(), permanent.getControllerId()));
|
||||
}
|
||||
CombatGroup blockGroup = findBlockingGroup(permanent, game); // a new blockingGroup is formed, so it's necessary to find it again
|
||||
if (blockGroup != null) {
|
||||
blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private CombatGroup findBlockingGroup(Permanent blocker, Game game) {
|
||||
|
|
|
@ -93,8 +93,8 @@ class GildedCerodonCondition implements Condition {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null
|
||||
&& !game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).isEmpty()
|
||||
|| controller.getGraveyard().count(filter2, game) > 0) {
|
||||
&& (!game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).isEmpty()
|
||||
|| controller.getGraveyard().count(filter2, game) > 0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -98,6 +98,10 @@ class GlissaSunseekerEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
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();
|
||||
int blackMana = pool.getBlack();
|
||||
int whiteMana = pool.getWhite();
|
||||
|
@ -106,11 +110,8 @@ class GlissaSunseekerEffect extends OneShotEffect {
|
|||
int redMana = pool.getRed();
|
||||
int colorlessMana = pool.getColorless();
|
||||
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) {
|
||||
return permanent.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
if (permanent.getConvertedManaCost() == manaPoolTotal) {
|
||||
return permanent.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import mage.players.Player;
|
|||
public final class GoblinPsychopath extends CardImpl {
|
||||
|
||||
public GoblinPsychopath(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
|
||||
this.subtype.add(SubType.GOBLIN);
|
||||
this.subtype.add(SubType.MUTANT);
|
||||
this.power = new MageInt(5);
|
||||
|
@ -97,9 +97,9 @@ class GoblinPsychopathEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DAMAGE_CREATURE ||
|
||||
event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER ||
|
||||
event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
|
||||
return event.getType() == GameEvent.EventType.DAMAGE_CREATURE
|
||||
|| event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER
|
||||
|| event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -116,21 +116,19 @@ class GoblinPsychopathEffect extends ReplacementEffectImpl {
|
|||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
MageObject object = game.getObject(event.getSourceId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null && object != null) {
|
||||
if (this.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
|
||||
DamageEvent damageEvent = (DamageEvent) event;
|
||||
if (damageEvent.isCombatDamage()) {
|
||||
if (!wonFlip) {
|
||||
// TODO: make this redirect damage from all blockers
|
||||
controller.damage(event.getAmount(), source.getSourceId(), game, false, true);
|
||||
String sourceLogName = source != null ? game.getObject(source.getSourceId()).getLogName() + ": " : "";
|
||||
game.informPlayers(sourceLogName + "Redirected " + event.getAmount() + " damage to " + controller.getLogName());
|
||||
this.discard();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (controller == null || object == null
|
||||
|| !(this.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
DamageEvent damageEvent = (DamageEvent) event;
|
||||
if (!damageEvent.isCombatDamage() || wonFlip) {
|
||||
return false;
|
||||
}
|
||||
// TODO: make this redirect damage from all blockers
|
||||
controller.damage(event.getAmount(), source.getSourceId(), game, false, true);
|
||||
String sourceLogName = game.getObject(source.getSourceId()).getLogName() + ": ";
|
||||
game.informPlayers(sourceLogName + "Redirected " + event.getAmount() + " damage to " + controller.getLogName());
|
||||
this.discard();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import mage.target.common.TargetLandPermanent;
|
|||
public final class Helldozer extends CardImpl {
|
||||
|
||||
public Helldozer(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}");
|
||||
this.subtype.add(SubType.ZOMBIE);
|
||||
this.subtype.add(SubType.GIANT);
|
||||
|
||||
|
@ -96,13 +96,12 @@ class HelldozerEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Permanent helldozer = game.getPermanent(source.getSourceId());
|
||||
Permanent landTarget = game.getPermanent(source.getFirstTarget());
|
||||
if (landTarget != null) {
|
||||
landTarget.destroy(id, game, false);
|
||||
if (landTarget == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent landPermanent = (Permanent) game.getLastKnownInformation(landTarget.getId(), Zone.BATTLEFIELD);
|
||||
if (landPermanent != null
|
||||
&& !landPermanent.isBasic()
|
||||
&& helldozer != null) {
|
||||
boolean wasNonBasic = !landTarget.isBasic();
|
||||
landTarget.destroy(id, game, false);
|
||||
if (wasNonBasic && helldozer != null) {
|
||||
return helldozer.untap(game);
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -61,15 +61,16 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public final class Heroism extends CardImpl {
|
||||
|
||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a white creature");
|
||||
|
||||
static {
|
||||
filter.add(new ColorPredicate(ObjectColor.WHITE));
|
||||
}
|
||||
|
||||
public Heroism(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
|
||||
|
||||
// Sacrifice a white creature: For each attacking red creature, prevent all combat damage that would be dealt by that creature this turn unless its controller pays {2}{R}.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new HeroismEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, true))));
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new HeroismEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))));
|
||||
}
|
||||
|
||||
public Heroism(final Heroism card) {
|
||||
|
@ -85,6 +86,7 @@ public final class Heroism extends CardImpl {
|
|||
class HeroismEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking red creature");
|
||||
|
||||
static {
|
||||
filter.add(new ColorPredicate(ObjectColor.RED));
|
||||
}
|
||||
|
@ -111,7 +113,7 @@ class HeroismEffect extends OneShotEffect {
|
|||
Player player = game.getPlayer(game.getActivePlayerId());
|
||||
Cost cost = new ManaCostsImpl("{2}{R}");
|
||||
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();
|
||||
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)) {
|
||||
|
|
|
@ -48,12 +48,10 @@ import mage.players.Player;
|
|||
public final class ImmortalServitude extends CardImpl {
|
||||
|
||||
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.
|
||||
this.getSpellAbility().addEffect(new ImmortalServitudeEffect());
|
||||
|
||||
}
|
||||
|
||||
public ImmortalServitude(final ImmortalServitude card) {
|
||||
|
@ -88,8 +86,7 @@ class ImmortalServitudeEffect extends OneShotEffect {
|
|||
int count = source.getManaCostsToPay().getX();
|
||||
Set<Card> cards = you.getGraveyard().getCards(new FilterCreatureCard(), game);
|
||||
for (Card card : cards) {
|
||||
if (card.getConvertedManaCost() == count
|
||||
&& card != null) {
|
||||
if (card != null && card.getConvertedManaCost() == count) {
|
||||
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import mage.players.Player;
|
|||
public final class IronMaiden extends CardImpl {
|
||||
|
||||
public IronMaiden(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in their hand minus 4.
|
||||
Ability ability = new BeginningOfUpkeepTriggeredAbility(new IronMaidenEffect(), TargetController.OPPONENT, false);
|
||||
|
@ -63,10 +63,8 @@ public final class IronMaiden extends CardImpl {
|
|||
return new IronMaiden(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class IronMaidenEffect extends OneShotEffect {
|
||||
|
||||
private IronMaidenEffect(final IronMaidenEffect effect) {
|
||||
|
@ -80,16 +78,11 @@ class IronMaidenEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if(player != null)
|
||||
{
|
||||
if (player != null) {
|
||||
int amount = player.getHand().size() - 4;
|
||||
if(amount > 0)
|
||||
{
|
||||
if (player != null) {
|
||||
player.damage(amount, source.getSourceId(), game, false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
player.damage(amount, source.getSourceId(), game, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.cards.i;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -55,7 +54,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public final class IronclawCurse extends CardImpl {
|
||||
|
||||
public IronclawCurse(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant creature
|
||||
|
@ -101,8 +100,11 @@ class IronclawCurseEffect extends CantBlockAttachedEffect {
|
|||
@Override
|
||||
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
|
||||
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (enchantment == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null) {
|
||||
if (enchantment.getAttachedTo() != null) {
|
||||
return !(attacker.getPower().getValue() >= enchantedCreature.getToughness().getValue());
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -265,15 +265,14 @@ class KarnPlayerExileEffect extends OneShotEffect {
|
|||
if (sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
if (player != null) {
|
||||
TargetCardInHand target = new TargetCardInHand();
|
||||
if (target != null
|
||||
&& target.canChoose(source.getSourceId(), player.getId(), game)) {
|
||||
if (target.chooseTarget(Outcome.Exile, player.getId(), source, game)) {
|
||||
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
return player.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game), source, game, true, exileId, sourceObject.getIdName());
|
||||
}
|
||||
}
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
TargetCardInHand target = new TargetCardInHand();
|
||||
if (target.canChoose(source.getSourceId(), player.getId(), game)
|
||||
&& target.chooseTarget(Outcome.Exile, player.getId(), source, game)) {
|
||||
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 false;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,7 @@ import java.util.*;
|
|||
public final class KillingWave extends CardImpl {
|
||||
|
||||
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.
|
||||
this.getSpellAbility().addEffect(new KillingWaveEffect());
|
||||
|
@ -96,21 +95,23 @@ class KillingWaveEffect extends OneShotEffect {
|
|||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(filter, playerId, game);
|
||||
if (player != null) {
|
||||
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(filter, playerId, game);
|
||||
|
||||
int lifePaid = 0;
|
||||
int playerLife = player.getLife();
|
||||
for (Permanent creature : creatures) {
|
||||
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)) {
|
||||
game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName());
|
||||
lifePaid += amount;
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " will sacrifice " + creature.getName());
|
||||
sacrifices.add(creature);
|
||||
int lifePaid = 0;
|
||||
int playerLife = player.getLife();
|
||||
for (Permanent creature : creatures) {
|
||||
String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed.";
|
||||
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());
|
||||
lifePaid += amount;
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " will sacrifice " + creature.getName());
|
||||
sacrifices.add(creature);
|
||||
}
|
||||
}
|
||||
lifePaidAmounts.put(playerId, lifePaid);
|
||||
}
|
||||
lifePaidAmounts.put(playerId, lifePaid);
|
||||
}
|
||||
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
|
|
|
@ -57,7 +57,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public final class LastRites extends CardImpl {
|
||||
|
||||
public LastRites(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
|
||||
|
||||
// Discard any number of cards. Target player reveals their hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards.
|
||||
this.getSpellAbility().addEffect(new LastRitesEffect());
|
||||
|
@ -107,16 +107,12 @@ class LastRitesEffect extends OneShotEffect {
|
|||
controller.discard(card, source, game);
|
||||
}
|
||||
}
|
||||
if (targetPlayer != null) {
|
||||
FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") + " nonland card" + (discardCount > 1 ? "s" : ""));
|
||||
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
|
||||
StaticValue discardValue = new StaticValue(discardCount);
|
||||
Effect effect = new DiscardCardYouChooseTargetEffect(discardValue, filter, TargetController.ANY);
|
||||
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
|
||||
effect.apply(game, source);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") + " nonland card" + (discardCount > 1 ? "s" : ""));
|
||||
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
|
||||
StaticValue discardValue = new StaticValue(discardCount);
|
||||
Effect effect = new DiscardCardYouChooseTargetEffect(discardValue, filter, TargetController.ANY);
|
||||
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
|
||||
effect.apply(game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -85,13 +85,14 @@ class LudevicNecroAlchemistCondition implements Condition {
|
|||
Player currentPlayer = null;
|
||||
UUID sourcePlayerId = source.getControllerId();
|
||||
Player firstPlayer = null;
|
||||
if (playerList != null) {
|
||||
firstPlayer = playerList.getCurrent(game);
|
||||
currentPlayer = playerList.getNext(game);
|
||||
if (playerList == null) {
|
||||
return false;
|
||||
}
|
||||
firstPlayer = playerList.getCurrent(game);
|
||||
currentPlayer = playerList.getNext(game);
|
||||
|
||||
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;
|
||||
}
|
||||
if (Objects.equals(currentPlayer, firstPlayer)) {
|
||||
|
|
|
@ -60,7 +60,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public final class MammothHarness extends CardImpl {
|
||||
|
||||
public MammothHarness(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);
|
||||
|
||||
// Enchant creature
|
||||
|
@ -103,20 +103,18 @@ class MammothHarnessTriggeredAbility extends BlocksOrBecomesBlockedTriggeredAbil
|
|||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
Permanent attachedTo = game.getPermanentOrLKIBattlefield(sourcePermanent.getAttachedTo());
|
||||
if (sourcePermanent != null) {
|
||||
if (event.getSourceId().equals(attachedTo.getId())) {
|
||||
Permanent blocked = game.getPermanent(event.getTargetId());
|
||||
if (blocked != null && filter.match(blocked, game)) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
return true;
|
||||
}
|
||||
if (event.getSourceId().equals(attachedTo.getId())) {
|
||||
Permanent blocked = game.getPermanent(event.getTargetId());
|
||||
if (blocked != null && filter.match(blocked, game)) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
return true;
|
||||
}
|
||||
if (event.getTargetId().equals(attachedTo.getId())) {
|
||||
Permanent blocker = game.getPermanent(event.getSourceId());
|
||||
if (blocker != null) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event.getTargetId().equals(attachedTo.getId())) {
|
||||
Permanent blocker = game.getPermanent(event.getSourceId());
|
||||
if (blocker != null) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,14 +125,12 @@ class MaralenOfTheMornsongEffect2 extends OneShotEffect {
|
|||
Player player = game.getPlayer(activePlayerId);
|
||||
if (player != null) {
|
||||
player.loseLife(3, game, false);
|
||||
if (player != null) {
|
||||
TargetCardInLibrary target = new TargetCardInLibrary();
|
||||
if (player.searchLibrary(target, game)) {
|
||||
player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
|
||||
}
|
||||
player.shuffleLibrary(source, game);
|
||||
return true;
|
||||
TargetCardInLibrary target = new TargetCardInLibrary();
|
||||
if (player.searchLibrary(target, game)) {
|
||||
player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
|
||||
}
|
||||
player.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -97,10 +97,8 @@ class PerishTheThoughtEffect extends OneShotEffect {
|
|||
if (you.choose(Outcome.Neutral, targetOpponent.getHand(), target, game)) {
|
||||
Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game);
|
||||
if (chosenCard != null) {
|
||||
if (targetOpponent != null) {
|
||||
chosenCard.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
|
||||
targetOpponent.shuffleLibrary(source, game);
|
||||
}
|
||||
chosenCard.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
|
||||
targetOpponent.shuffleLibrary(source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -60,7 +60,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public final class PowerLeak extends CardImpl {
|
||||
|
||||
public PowerLeak(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant enchantment
|
||||
|
@ -103,31 +103,31 @@ class PowerLeakEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(game.getActivePlayerId());
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (player != null && permanent != null) {
|
||||
ManaCosts<ManaCost> cost = new ManaCostsImpl<>("{X}");
|
||||
String message = "Pay {X} to prevent X damage from " + permanent.getLogName() + "?";
|
||||
int xValue = 0;
|
||||
if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) {
|
||||
xValue = player.announceXMana(0, Integer.MAX_VALUE, "Choose the amount of mana to pay", game, source);
|
||||
cost.add(new GenericManaCost(xValue));
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
|
||||
game.informPlayers(player.getLogName() + " paid {" + xValue + "} for " + permanent.getLogName());
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay {X} for " + permanent.getLogName());
|
||||
}
|
||||
if (player == null || permanent == null) {
|
||||
return false;
|
||||
}
|
||||
ManaCosts<ManaCost> cost = new ManaCostsImpl<>("{X}");
|
||||
String message = "Pay {X} to prevent X damage from " + permanent.getLogName() + "?";
|
||||
int xValue = 0;
|
||||
if (player.chooseUse(Outcome.Neutral, message, source, game)) {
|
||||
xValue = player.announceXMana(0, Integer.MAX_VALUE, "Choose the amount of mana to pay", game, source);
|
||||
cost.add(new GenericManaCost(xValue));
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
|
||||
game.informPlayers(player.getLogName() + " paid {" + xValue + "} for " + permanent.getLogName());
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay {X} for " + permanent.getLogName());
|
||||
}
|
||||
|
||||
PreventDamageByTargetEffect effect = new PreventDamageByTargetEffect(Duration.OneUse, xValue, false);
|
||||
if (xValue != 0 && cost.isPaid()) {
|
||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
player.damage(2, source.getSourceId(), game, false, true);
|
||||
effect.discard();
|
||||
return true;
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay {X} for " + permanent.getLogName());
|
||||
}
|
||||
return false;
|
||||
|
||||
PreventDamageByTargetEffect effect = new PreventDamageByTargetEffect(Duration.OneUse, xValue, false);
|
||||
if (xValue != 0 && cost.isPaid()) {
|
||||
effect.setTargetPointer(new FixedTarget(permanent.getId()));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
player.damage(2, source.getSourceId(), game, false, true);
|
||||
effect.discard();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public final class QuietSpeculation extends CardImpl {
|
|||
}
|
||||
|
||||
public QuietSpeculation(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}");
|
||||
|
||||
// Search target player's library for up to three cards with flashback and put them into that player's graveyard. Then the player shuffles their library.
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(0, 3, filterCard);
|
||||
|
@ -96,7 +96,10 @@ class SearchLibraryPutInGraveEffect extends SearchEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
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()) {
|
||||
Cards cards = new CardsImpl(target.getTargets());
|
||||
controller.revealCards("Quiet Speculation", cards, game);
|
||||
|
@ -108,5 +111,4 @@ class SearchLibraryPutInGraveEffect extends SearchEffect {
|
|||
controller.shuffleLibrary(source, game);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import mage.target.TargetPermanent;
|
|||
public final class Recoil extends CardImpl {
|
||||
|
||||
public Recoil(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{B}");
|
||||
|
||||
// Return target permanent to its owner's hand. Then that player discards a card.
|
||||
this.getSpellAbility().addEffect(new RecoilEffect());
|
||||
|
@ -84,8 +84,11 @@ class RecoilEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent target = game.getPermanent(source.getFirstTarget());
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
Player controller = game.getPlayer(target.getControllerId());
|
||||
if (target != null && controller != null) {
|
||||
if (controller != null) {
|
||||
controller.moveCards(target, Zone.HAND, source, game);
|
||||
controller.discard(1, false, source, game);
|
||||
return true;
|
||||
|
|
|
@ -157,10 +157,8 @@ class SavingGraceReplacementEffect extends ReplacementEffectImpl {
|
|||
}
|
||||
game.informPlayers(message.toString());
|
||||
// Redirect damage
|
||||
if (creature != null) {
|
||||
creature.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
|
||||
return true;
|
||||
}
|
||||
creature.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -121,18 +121,22 @@ class SerraBestiaryRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (enchantment == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null) {
|
||||
MageObject object = game.getObject(event.getSourceId());
|
||||
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
|
||||
if (ability.isPresent()
|
||||
&& object != null
|
||||
&& object.isCreature()
|
||||
&& object.getId().equals(enchantedCreature.getId())
|
||||
&& game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId())) {
|
||||
if (ability.get().getCosts().stream().anyMatch((cost) -> (cost instanceof TapSourceCost))) {
|
||||
return true;
|
||||
}
|
||||
if (enchantedCreature == null) {
|
||||
return false;
|
||||
}
|
||||
MageObject object = game.getObject(event.getSourceId());
|
||||
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
|
||||
if (ability.isPresent()
|
||||
&& object != null
|
||||
&& object.isCreature()
|
||||
&& object.getId().equals(enchantedCreature.getId())
|
||||
&& game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId())) {
|
||||
if (ability.get().getCosts().stream().anyMatch((cost) -> (cost instanceof TapSourceCost))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -127,7 +127,7 @@ class ShadesBreathSetSubtypeEffect extends ContinuousEffectImpl {
|
|||
for (Permanent permanent : permanents) {
|
||||
if (permanent != null) {
|
||||
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.add(SubType.SHADE);
|
||||
}
|
||||
|
|
|
@ -56,10 +56,9 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public final class SlowMotion extends CardImpl {
|
||||
|
||||
public SlowMotion(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
|
||||
// Enchant creature
|
||||
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||
this.getSpellAbility().addTarget(auraTarget);
|
||||
|
@ -68,7 +67,7 @@ public final class SlowMotion extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
|
||||
// At the beginning of the upkeep of enchanted creature's controller, that player sacrifices that creature unless he or she pays {2}.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeEquipedUnlessPaysEffect(new GenericManaCost(2)), TargetController.CONTROLLER_ATTACHED_TO, false ));
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeEquipedUnlessPaysEffect(new GenericManaCost(2)), TargetController.CONTROLLER_ATTACHED_TO, false));
|
||||
|
||||
// When Slow Motion is put into a graveyard from the battlefield, return Slow Motion to its owner's hand.
|
||||
this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new ReturnToHandSourceEffect()));
|
||||
|
@ -85,13 +84,14 @@ public final class SlowMotion extends CardImpl {
|
|||
}
|
||||
|
||||
class SacrificeEquipedUnlessPaysEffect extends OneShotEffect {
|
||||
|
||||
protected Cost cost;
|
||||
|
||||
public SacrificeEquipedUnlessPaysEffect(Cost cost) {
|
||||
super(Outcome.Sacrifice);
|
||||
this.cost = cost;
|
||||
staticText = "that player sacrifices that creature unless he or she pays {2}";
|
||||
}
|
||||
}
|
||||
|
||||
public SacrificeEquipedUnlessPaysEffect(final SacrificeEquipedUnlessPaysEffect effect) {
|
||||
super(effect);
|
||||
|
@ -101,25 +101,29 @@ class SacrificeEquipedUnlessPaysEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent equipment = game.getPermanent(source.getSourceId());
|
||||
if (equipment != null && equipment.getAttachedTo() != null) {
|
||||
Permanent equipped = game.getPermanent(equipment.getAttachedTo());
|
||||
Player player = game.getPlayer(equipped.getControllerId());
|
||||
if (player != null && equipped != null) {
|
||||
if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? (Or " + equipped.getName() + " will be sacrificed.)", source, game)) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(source, game, source.getSourceId(), equipped.getControllerId(), false, null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
equipped.sacrifice(source.getSourceId(), game);
|
||||
if (equipment == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent equipped = game.getPermanent(equipment.getAttachedTo());
|
||||
if (equipped == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(equipped.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? (Or " + equipped.getName() + " will be sacrificed.)", source, game)) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(source, game, source.getSourceId(), equipped.getControllerId(), false, null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
equipped.sacrifice(source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SacrificeEquipedUnlessPaysEffect copy() {
|
||||
return new SacrificeEquipedUnlessPaysEffect(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,10 +114,8 @@ class SpikeCannibalEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (countersRemoved > 0) {
|
||||
if (sourcePermanent != null) {
|
||||
sourcePermanent.addCounters(CounterType.P1P1.createInstance(countersRemoved), source, game);
|
||||
return true;
|
||||
}
|
||||
sourcePermanent.addCounters(CounterType.P1P1.createInstance(countersRemoved), source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public final class SpyNetwork extends CardImpl {
|
||||
|
||||
public SpyNetwork(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
|
||||
|
||||
// Look at target player's hand, the top card of that player's library, and any face-down creatures he or she controls. Look at the top four cards of your library, then put them back in any order.
|
||||
this.getSpellAbility().addEffect(new SpyNetworkLookAtTargetPlayerHandEffect());
|
||||
|
@ -133,7 +133,7 @@ class SpyNetworkFaceDownEffect extends OneShotEffect {
|
|||
filter.add(new ControllerIdPredicate(player.getId()));
|
||||
TargetCreaturePermanent target = new TargetCreaturePermanent(1, 1, filter, true);
|
||||
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();
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
|
@ -145,9 +145,7 @@ class SpyNetworkFaceDownEffect extends OneShotEffect {
|
|||
Cards cards = new CardsImpl();
|
||||
cards.add(copyFaceDown);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,8 +112,8 @@ class SummonThePackEffect extends OneShotEffect {
|
|||
StringBuilder message = new StringBuilder(controller.getLogName()).append(" opened: ");
|
||||
|
||||
for (Card c : boosterPack) {
|
||||
message.append(c.getName()).append(" ");
|
||||
if (c != null && c.isCreature()) {
|
||||
message.append(c.getName()).append(" ");
|
||||
message.append(" (creature card) ");
|
||||
ContinuousEffect effect2 = new BecomesBlackZombieAdditionEffect(false);
|
||||
effect2.setTargetPointer(new FixedTarget(c.getId()));
|
||||
|
@ -124,7 +124,7 @@ class SummonThePackEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (creatureCards.size() > 0) {
|
||||
Set<Card> ccs = new HashSet<Card>(creatureCards);
|
||||
Set<Card> ccs = new HashSet<>(creatureCards);
|
||||
game.loadCards(ccs, controller.getId());
|
||||
controller.moveCards(ccs, Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ import mage.target.common.TargetOpponent;
|
|||
public final class TheBattleOfYavin extends CardImpl {
|
||||
|
||||
public TheBattleOfYavin(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{B}");
|
||||
|
||||
// For each nonland permanent target opponent controls, that player sacrificies it unless he or she pays X life.
|
||||
this.getSpellAbility().addEffect(new TheBattleOfYavinEffect());
|
||||
|
@ -102,7 +102,7 @@ class TheBattleOfYavinEffect extends OneShotEffect {
|
|||
int playerLife = opponent.getLife();
|
||||
for (Permanent permanent : permanents) {
|
||||
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());
|
||||
lifePaid += amount;
|
||||
} else {
|
||||
|
|
|
@ -62,7 +62,7 @@ import mage.target.targetpointer.FixedTarget;
|
|||
public final class TidalFlats extends CardImpl {
|
||||
|
||||
public TidalFlats(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
|
||||
|
||||
// {U}{U}: For each attacking creature without flying, its controller may pay {1}. If he or she doesn't, creatures you control blocking that creature gain first strike until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TidalFlatsEffect(), new ManaCostsImpl("{U}{U}")));
|
||||
|
@ -81,6 +81,7 @@ public final class TidalFlats extends CardImpl {
|
|||
class TidalFlatsEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking creature without flying");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
|
||||
}
|
||||
|
@ -103,43 +104,45 @@ class TidalFlatsEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
game.getPlayerList();
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Player player = game.getPlayer(game.getActivePlayerId());
|
||||
Cost cost = new ManaCostsImpl("{1}");
|
||||
List<Permanent> affectedPermanents = new ArrayList<>();
|
||||
for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
|
||||
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.";
|
||||
if (player != null && player.chooseUse(Outcome.Benefit, message, source, game)) {
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
|
||||
game.informPlayers(player.getLogName() + " paid " + cost.getText() + " for " + permanent.getLogName());
|
||||
continue;
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName());
|
||||
affectedPermanents.add(permanent);
|
||||
}
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(game.getActivePlayerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Cost cost = new ManaCostsImpl("{1}");
|
||||
List<Permanent> affectedPermanents = new ArrayList<>();
|
||||
for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
|
||||
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.";
|
||||
if (player.chooseUse(Outcome.Benefit, message, source, game)) {
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
|
||||
game.informPlayers(player.getLogName() + " paid " + cost.getText() + " for " + permanent.getLogName());
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName());
|
||||
affectedPermanents.add(permanent);
|
||||
}
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName());
|
||||
affectedPermanents.add(permanent);
|
||||
}
|
||||
}
|
||||
|
||||
for (Permanent permanent : affectedPermanents) {
|
||||
CombatGroup group = game.getCombat().findGroup(permanent.getId());
|
||||
if (group != null) {
|
||||
for (UUID blockerId : group.getBlockers()) {
|
||||
Permanent blocker = game.getPermanent(blockerId);
|
||||
if (blocker != null && Objects.equals(blocker.getControllerId(), controller.getId())) {
|
||||
ContinuousEffect effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(blocker.getId()));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
for (Permanent permanent : affectedPermanents) {
|
||||
CombatGroup group = game.getCombat().findGroup(permanent.getId());
|
||||
if (group != null) {
|
||||
for (UUID blockerId : group.getBlockers()) {
|
||||
Permanent blocker = game.getPermanent(blockerId);
|
||||
if (blocker != null && Objects.equals(blocker.getControllerId(), controller.getId())) {
|
||||
ContinuousEffect effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(blocker.getId()));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ class TorrentialGearhulkEffect extends OneShotEffect {
|
|||
game.addEffect(effect, source);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (card != null) {
|
||||
Logger.getLogger(TorrentialGearhulkEffect.class).error("Torrential Gearhulk - Instant card without spellAbility : " + card.getName());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
public final class TreacherousLink extends CardImpl {
|
||||
|
||||
public TreacherousLink(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant creature
|
||||
|
@ -109,12 +109,15 @@ class TreacherousLinkEffect extends ReplacementEffectImpl {
|
|||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
DamageEvent damageEvent = (DamageEvent) event;
|
||||
Permanent enchantedCreature = game.getPermanentOrLKIBattlefield(damageEvent.getTargetId());
|
||||
Player controller = game.getPlayer(enchantedCreature.getControllerId());
|
||||
if (enchantedCreature != null && controller != null) {
|
||||
controller.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
|
||||
return true;
|
||||
if (enchantedCreature == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
Player controller = game.getPlayer(enchantedCreature.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
controller.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -83,7 +83,7 @@ public final class WallOfPutridFlesh extends CardImpl {
|
|||
|
||||
class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSourceEffect {
|
||||
|
||||
public PreventDamageToSourceByEnchantedCreatures(){
|
||||
public PreventDamageToSourceByEnchantedCreatures() {
|
||||
super(Duration.WhileOnBattlefield);
|
||||
}
|
||||
|
||||
|
@ -100,10 +100,10 @@ class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSource
|
|||
}
|
||||
|
||||
public boolean isEnchantedCreature(MageObject input, Game game) {
|
||||
if (input != null && !input.isCreature()) {
|
||||
if (input == null || input.isCreature()) {
|
||||
return false;
|
||||
}
|
||||
for (UUID attachmentId : ((Permanent)input).getAttachments()) {
|
||||
for (UUID attachmentId : ((Permanent) input).getAttachments()) {
|
||||
Permanent attachment = game.getPermanent(attachmentId);
|
||||
if (attachment != null && attachment.isEnchantment()) {
|
||||
return true;
|
||||
|
|
|
@ -47,7 +47,7 @@ import mage.players.Player;
|
|||
public final class WheelOfTorture extends CardImpl {
|
||||
|
||||
public WheelOfTorture(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// At the beginning of each opponent's upkeep, Wheel of Torture deals X damage to that player, where X is 3 minus the number of cards in their hand.
|
||||
Ability ability = new BeginningOfUpkeepTriggeredAbility(new WheelOfTortureEffect(), TargetController.OPPONENT, false);
|
||||
|
@ -64,7 +64,6 @@ public final class WheelOfTorture extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
class WheelOfTortureEffect extends OneShotEffect {
|
||||
|
||||
private WheelOfTortureEffect(final WheelOfTortureEffect effect) {
|
||||
|
@ -78,16 +77,11 @@ class WheelOfTortureEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if(player != null)
|
||||
{
|
||||
if (player != null) {
|
||||
int amount = 3 - player.getHand().size();
|
||||
if(amount > 0)
|
||||
{
|
||||
if (player != null) {
|
||||
player.damage(amount, source.getSourceId(), game, false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
player.damage(amount, source.getSourceId(), game, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -83,6 +83,9 @@ class WretchedBanquetEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
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);
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.verify;
|
||||
|
||||
import javassist.bytecode.SignatureAttribute;
|
||||
import mage.ObjectColor;
|
||||
import mage.cards.*;
|
||||
import mage.cards.basiclands.BasicLand;
|
||||
|
@ -352,9 +351,7 @@ public class VerifyCardDataTest {
|
|||
//Assert.assertNotNull("Can't create token by default constructor", token);
|
||||
if (token == null) {
|
||||
Assert.fail("Can't create token by default constructor: " + className);
|
||||
}
|
||||
|
||||
if (tokDataNamesIndex.getOrDefault(token.getName(), "").isEmpty()) {
|
||||
} else if (tokDataNamesIndex.getOrDefault(token.getName(), "").isEmpty()) {
|
||||
errorsList.add("error, can't find data in card-pictures-tok.txt for token: " + tokenClass.getName() + " -> " + token.getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ public class DoUnlessTargetPlayerOrTargetsControllerPaysEffect extends OneShotEf
|
|||
}
|
||||
if (targetController != null) {
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (targetController != null && sourceObject != null) {
|
||||
if (sourceObject != null) {
|
||||
Cost costToPay;
|
||||
if (cost != null) {
|
||||
costToPay = cost.copy();
|
||||
|
|
Loading…
Reference in a new issue