mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
- Fixed #8067. Included weirddan455 fixes to Kardur Doomscourge as well. Added support for "remove from combat" to the 2 cards. Note that attacking creatures put into the graveyard is a special case. Test will follow.
This commit is contained in:
parent
9baa36c2e3
commit
43dbaf405b
5 changed files with 137 additions and 24 deletions
|
@ -2,7 +2,6 @@ package mage.cards.k;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.effects.RestrictionEffect;
|
import mage.abilities.effects.RestrictionEffect;
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
|
@ -10,30 +9,21 @@ import mage.abilities.effects.common.LoseLifeOpponentsEffect;
|
||||||
import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect;
|
import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.*;
|
||||||
import mage.constants.Duration;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.SuperType;
|
|
||||||
import mage.filter.FilterPermanent;
|
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
|
||||||
import mage.filter.predicate.permanent.AttackingPredicate;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.watchers.common.AttackedThisTurnWatcher;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.abilities.common.AttackingCreaturePutIntoGraveyardTriggeredAbility;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class KardurDoomscourge extends CardImpl {
|
public final class KardurDoomscourge extends CardImpl {
|
||||||
|
|
||||||
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("an attacking creature");
|
|
||||||
|
|
||||||
static {
|
|
||||||
filter.add(AttackingPredicate.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public KardurDoomscourge(UUID ownerId, CardSetInfo setInfo) {
|
public KardurDoomscourge(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
|
||||||
|
|
||||||
|
@ -48,12 +38,13 @@ public final class KardurDoomscourge extends CardImpl {
|
||||||
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE, Duration.UntilYourNextTurn
|
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE, Duration.UntilYourNextTurn
|
||||||
).setText("until your next turn, creatures your opponents control attack each combat if able"));
|
).setText("until your next turn, creatures your opponents control attack each combat if able"));
|
||||||
ability.addEffect(new KardurDoomscourgeEffect());
|
ability.addEffect(new KardurDoomscourgeEffect());
|
||||||
|
ability.addWatcher(new AttackedThisTurnWatcher());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// Whenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.
|
// Whenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.
|
||||||
ability = new DiesCreatureTriggeredAbility(new LoseLifeOpponentsEffect(1), false, filter);
|
Ability ability2 = new AttackingCreaturePutIntoGraveyardTriggeredAbility(new LoseLifeOpponentsEffect(1), new FilterCreaturePermanent("an attacking creature"), false, true, false);
|
||||||
ability.addEffect(new GainLifeEffect(1).concatBy("and"));
|
ability2.addEffect(new GainLifeEffect(1).concatBy("and"));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private KardurDoomscourge(final KardurDoomscourge card) {
|
private KardurDoomscourge(final KardurDoomscourge card) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package mage.cards.k;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
|
import mage.abilities.common.AttackingCreaturePutIntoGraveyardTriggeredAbility;
|
||||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
@ -32,8 +32,7 @@ public final class KithkinMourncaller extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// Whenever an attacking Kithkin or Elf is put into your graveyard from the battlefield, you may draw a card.
|
// Whenever an attacking Kithkin or Elf is put into your graveyard from the battlefield, you may draw a card.
|
||||||
this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new DrawCardSourceControllerEffect(1),
|
this.addAbility(new AttackingCreaturePutIntoGraveyardTriggeredAbility(new DrawCardSourceControllerEffect(1), filter, true, false, true));
|
||||||
true, filter, false, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private KithkinMourncaller(final KithkinMourncaller card) {
|
private KithkinMourncaller(final KithkinMourncaller card) {
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package mage.abilities.common;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import static mage.game.events.GameEvent.EventType.DECLARE_ATTACKERS_STEP;
|
||||||
|
import static mage.game.events.GameEvent.EventType.END_COMBAT_STEP_POST;
|
||||||
|
import static mage.game.events.GameEvent.EventType.REMOVED_FROM_COMBAT;
|
||||||
|
import static mage.game.events.GameEvent.EventType.ZONE_CHANGE;
|
||||||
|
import mage.game.events.ZoneChangeEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author weirddan455 and jeffwadsworth
|
||||||
|
*/
|
||||||
|
public class AttackingCreaturePutIntoGraveyardTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
protected FilterPermanent filterPermanent;
|
||||||
|
private final boolean onlyToControllerGraveyard;
|
||||||
|
private final boolean itDies;
|
||||||
|
|
||||||
|
public AttackingCreaturePutIntoGraveyardTriggeredAbility(Effect effect, FilterPermanent filterPermanent, Boolean onlyToControllerGraveyard, Boolean itDies, Boolean optional) {
|
||||||
|
super(Zone.BATTLEFIELD, effect, optional);
|
||||||
|
this.filterPermanent = filterPermanent;
|
||||||
|
this.onlyToControllerGraveyard = onlyToControllerGraveyard;
|
||||||
|
this.itDies = itDies;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttackingCreaturePutIntoGraveyardTriggeredAbility(final AttackingCreaturePutIntoGraveyardTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
this.filterPermanent = ability.filterPermanent;
|
||||||
|
this.onlyToControllerGraveyard = ability.onlyToControllerGraveyard;
|
||||||
|
this.itDies = ability.itDies;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttackingCreaturePutIntoGraveyardTriggeredAbility copy() {
|
||||||
|
return new AttackingCreaturePutIntoGraveyardTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
switch (event.getType()) {
|
||||||
|
case DECLARE_ATTACKERS_STEP:
|
||||||
|
case END_COMBAT_STEP_POST:
|
||||||
|
case ZONE_CHANGE:
|
||||||
|
case REMOVED_FROM_COMBAT:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
switch (event.getType()) {
|
||||||
|
case DECLARE_ATTACKERS_STEP:
|
||||||
|
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||||
|
if (permanent != null
|
||||||
|
&& !filterPermanent.match(permanent, game)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
game.getState().setValue(this.getSourceId() + "Attackers", game.getCombat().getAttackers());
|
||||||
|
return false;
|
||||||
|
case END_COMBAT_STEP_POST:
|
||||||
|
game.getState().setValue(this.getSourceId() + "Attackers", null);
|
||||||
|
return false;
|
||||||
|
case ZONE_CHANGE:
|
||||||
|
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||||
|
if (zEvent.getFromZone() == Zone.BATTLEFIELD
|
||||||
|
&& zEvent.getToZone() == Zone.GRAVEYARD) {
|
||||||
|
if (onlyToControllerGraveyard
|
||||||
|
&& !this.isControlledBy(game.getOwnerId(zEvent.getTargetId()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (itDies
|
||||||
|
&& !zEvent.isDiesEvent()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<UUID> attackers = (List<UUID>) game.getState().getValue(this.getSourceId() + "Attackers");
|
||||||
|
return attackers != null
|
||||||
|
&& attackers.contains(zEvent.getTargetId());
|
||||||
|
}
|
||||||
|
case REMOVED_FROM_COMBAT:
|
||||||
|
// a card removed from combat is no longer an attacker or blocker so remove it from the list
|
||||||
|
if (game.isSimulation()) { // a simulated game will always choose to apply any triggered effect IE: Gustcloak Savior
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<UUID> attackersList = (List<UUID>) game.getState().getValue(this.getSourceId() + "Attackers");
|
||||||
|
if (attackersList != null
|
||||||
|
&& attackersList.contains(event.getTargetId())) {
|
||||||
|
attackersList.remove(event.getTargetId());
|
||||||
|
game.getState().setValue(this.getSourceId() + "Attackers", attackersList);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTriggerPhrase() {
|
||||||
|
if (itDies) {
|
||||||
|
return "Whenever " + filterPermanent.getMessage() + " dies, ";
|
||||||
|
}
|
||||||
|
return "Whenever " + filterPermanent.getMessage() + " is put into " + (onlyToControllerGraveyard ? "your" : "a")
|
||||||
|
+ " graveyard from the battlefield, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -354,8 +354,8 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
if (game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId))
|
if (game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId))
|
||||||
|| (!canBand && !canBandWithOther)
|
|| (!canBand && !canBandWithOther)
|
||||||
|| !player.chooseUse(Outcome.Benefit,
|
|| !player.chooseUse(Outcome.Benefit,
|
||||||
(isBanded ? "Band " + attacker.getLogName()
|
(isBanded ? "Band " + attacker.getLogName()
|
||||||
+ " with another " : "Form a band with " + attacker.getLogName() + " and an ")
|
+ " with another " : "Form a band with " + attacker.getLogName() + " and an ")
|
||||||
+ "attacking creature?", null, game)) {
|
+ "attacking creature?", null, game)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +573,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
* Handle the blocker selection process
|
* Handle the blocker selection process
|
||||||
*
|
*
|
||||||
* @param blockController player that controls how to block, if null the
|
* @param blockController player that controls how to block, if null the
|
||||||
* defender is the controller
|
* defender is the controller
|
||||||
* @param game
|
* @param game
|
||||||
*/
|
*/
|
||||||
public void selectBlockers(Player blockController, Ability source, Game game) {
|
public void selectBlockers(Player blockController, Ability source, Game game) {
|
||||||
|
@ -1390,7 +1390,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
* @param playerId
|
* @param playerId
|
||||||
* @param game
|
* @param game
|
||||||
* @param solveBanding check whether also add creatures banded with
|
* @param solveBanding check whether also add creatures banded with
|
||||||
* attackerId
|
* attackerId
|
||||||
*/
|
*/
|
||||||
public void addBlockingGroup(UUID blockerId, UUID attackerId, UUID playerId, Game game, boolean solveBanding) {
|
public void addBlockingGroup(UUID blockerId, UUID attackerId, UUID playerId, Game game, boolean solveBanding) {
|
||||||
Permanent blocker = game.getPermanent(blockerId);
|
Permanent blocker = game.getPermanent(blockerId);
|
||||||
|
@ -1463,6 +1463,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
creature.clearBandedCards();
|
creature.clearBandedCards();
|
||||||
blockingGroups.remove(creatureId);
|
blockingGroups.remove(creatureId);
|
||||||
if (result && withInfo) {
|
if (result && withInfo) {
|
||||||
|
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.REMOVED_FROM_COMBAT, creatureId, null, null));
|
||||||
game.informPlayers(creature.getLogName() + " removed from combat");
|
game.informPlayers(creature.getLogName() + " removed from combat");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -457,6 +457,7 @@ public class GameEvent implements Serializable {
|
||||||
ROOM_ENTERED,
|
ROOM_ENTERED,
|
||||||
VENTURE, VENTURED,
|
VENTURE, VENTURED,
|
||||||
DUNGEON_COMPLETED,
|
DUNGEON_COMPLETED,
|
||||||
|
REMOVED_FROM_COMBAT, // targetId id of permanent removed from combat
|
||||||
//custom events
|
//custom events
|
||||||
CUSTOM_EVENT
|
CUSTOM_EVENT
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue