mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
implement [EOE] Kav Landseeker; fix & test Meandering Towershell along the way
This commit is contained in:
parent
2b7f8869dd
commit
0dceeb78bd
8 changed files with 298 additions and 53 deletions
82
Mage.Sets/src/mage/cards/k/KavLandseeker.java
Normal file
82
Mage.Sets/src/mage/cards/k/KavLandseeker.java
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
package mage.cards.k;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.common.delayed.AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.SacrificeTargetEffect;
|
||||||
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.token.LanderToken;
|
||||||
|
import mage.game.permanent.token.Token;
|
||||||
|
import mage.target.targetpointer.FixedTargets;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public final class KavLandseeker extends CardImpl {
|
||||||
|
|
||||||
|
public KavLandseeker(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.KAVU);
|
||||||
|
this.subtype.add(SubType.SOLDIER);
|
||||||
|
this.power = new MageInt(4);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Menace
|
||||||
|
this.addAbility(new MenaceAbility());
|
||||||
|
|
||||||
|
// When this creature enters, create a Lander token. At the beginning of the end step on your next turn, sacrifice that token.
|
||||||
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new KavLandseekerEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private KavLandseeker(final KavLandseeker card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KavLandseeker copy() {
|
||||||
|
return new KavLandseeker(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KavLandseekerEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
KavLandseekerEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "create a Lander token. "
|
||||||
|
+ "At the beginning of the end step on your next turn, sacrifice that token";
|
||||||
|
}
|
||||||
|
|
||||||
|
private KavLandseekerEffect(final KavLandseekerEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KavLandseekerEffect copy() {
|
||||||
|
return new KavLandseekerEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Token token = new LanderToken();
|
||||||
|
token.putOntoBattlefield(1, game, source, source.getControllerId());
|
||||||
|
game.addDelayedTriggeredAbility(new AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility(
|
||||||
|
new SacrificeTargetEffect()
|
||||||
|
.setTargetPointer(new FixedTargets(token, game))
|
||||||
|
.setText("sacrifice that token"),
|
||||||
|
GameEvent.EventType.END_TURN_STEP_PRE
|
||||||
|
), source);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,39 +1,40 @@
|
||||||
|
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
|
import mage.abilities.common.delayed.AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.keyword.IslandwalkAbility;
|
import mage.abilities.keyword.IslandwalkAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As Meandering Towershell returns to the battlefield because of the delayed
|
* As Meandering Towershell returns to the battlefield because of the delayed
|
||||||
* triggered ability, you choose which opponent or opposing planeswalker it's
|
* triggered ability, you choose which opponent or opposing planeswalker it's
|
||||||
* attacking. It doesn't have to attack the same opponent or opposing
|
* attacking. It doesn't have to attack the same opponent or opposing
|
||||||
* planeswalker that it was when it was exiled.
|
* planeswalker that it was when it was exiled.
|
||||||
*
|
* --
|
||||||
* If Meandering Towershell enters the battlefield attacking, it wasn't declared
|
* If Meandering Towershell enters the battlefield attacking, it wasn't declared
|
||||||
* as an attacking creature that turn. Abilities that trigger when a creature
|
* as an attacking creature that turn. Abilities that trigger when a creature
|
||||||
* attacks, including its own triggered ability, won't trigger.
|
* attacks, including its own triggered ability, won't trigger.
|
||||||
*
|
* --
|
||||||
* On the turn Meandering Towershell attacks and is exiled, raid abilities will
|
* On the turn Meandering Towershell attacks and is exiled, raid abilities will
|
||||||
* see it as a creature that attacked. Conversely, on the turn Meandering
|
* see it as a creature that attacked. Conversely, on the turn Meandering
|
||||||
* Towershell enters the battlefield attacking, raid abilities will not.
|
* Towershell enters the battlefield attacking, raid abilities will not.
|
||||||
*
|
* --
|
||||||
* If you attack with a Meandering Towershell that you don't own, you'll control
|
* If you attack with a Meandering Towershell that you don't own, you'll control
|
||||||
* it when it returns to the battlefield.
|
* it when it returns to the battlefield.
|
||||||
*
|
*
|
||||||
|
|
@ -90,58 +91,13 @@ class MeanderingTowershellEffect extends OneShotEffect {
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||||
if (controller != null && sourcePermanent != null) {
|
if (controller != null && sourcePermanent != null) {
|
||||||
controller.moveCardToExileWithInfo(sourcePermanent, null, "", source, game, Zone.BATTLEFIELD, true);
|
controller.moveCardToExileWithInfo(sourcePermanent, null, "", source, game, Zone.BATTLEFIELD, true);
|
||||||
game.addDelayedTriggeredAbility(new AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility(), source);
|
game.addDelayedTriggeredAbility(new AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility(new MeanderingTowershellReturnEffect(), GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE), source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
|
||||||
|
|
||||||
private int startingTurn;
|
|
||||||
|
|
||||||
public AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility() {
|
|
||||||
super(new MeanderingTowershellReturnEffect());
|
|
||||||
}
|
|
||||||
|
|
||||||
private AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility(final AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility ability) {
|
|
||||||
super(ability);
|
|
||||||
this.startingTurn = ability.startingTurn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Game game) {
|
|
||||||
startingTurn = game.getTurnNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
|
||||||
if (event.getPlayerId().equals(this.controllerId)) {
|
|
||||||
if (game.getTurnNum() != startingTurn) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRule() {
|
|
||||||
return "Return it to the battlefield under your control tapped and attacking at the beginning of the next declare attackers step on your next turn.";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility copy() {
|
|
||||||
return new AtBeginningNextDeclareAttackersStepNextTurnDelayedTriggeredAbility(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MeanderingTowershellReturnEffect extends OneShotEffect {
|
class MeanderingTowershellReturnEffect extends OneShotEffect {
|
||||||
|
|
||||||
MeanderingTowershellReturnEffect() {
|
MeanderingTowershellReturnEffect() {
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ public final class EdgeOfEternities extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Island", 269, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Island", 269, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Island", 270, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Island", 270, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Island", 368, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Island", 368, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Kav Landseeker", 138, Rarity.COMMON, mage.cards.k.KavLandseeker.class));
|
||||||
cards.add(new SetCardInfo("Kavaron Harrier", 139, Rarity.UNCOMMON, mage.cards.k.KavaronHarrier.class));
|
cards.add(new SetCardInfo("Kavaron Harrier", 139, Rarity.UNCOMMON, mage.cards.k.KavaronHarrier.class));
|
||||||
cards.add(new SetCardInfo("Kavaron, Memorial World", 255, Rarity.MYTHIC, mage.cards.k.KavaronMemorialWorld.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Kavaron, Memorial World", 255, Rarity.MYTHIC, mage.cards.k.KavaronMemorialWorld.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Kavaron, Memorial World", 281, Rarity.MYTHIC, mage.cards.k.KavaronMemorialWorld.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Kavaron, Memorial World", 281, Rarity.MYTHIC, mage.cards.k.KavaronMemorialWorld.class, NON_FULL_USE_VARIOUS));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package org.mage.test.cards.single.eoe;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public class KavLandseekerTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.k.KavLandseeker Kav Landseeker} {3}{R}
|
||||||
|
* Creature — Kavu Soldier
|
||||||
|
* Menace (This creature can’t be blocked except by two or more creatures.)
|
||||||
|
* When this creature enters, create a Lander token. At the beginning of the end step on your next turn, sacrifice that token. (It’s an artifact with “{2}, {T}, Sacrifice this token: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.”)
|
||||||
|
* 4/3
|
||||||
|
*/
|
||||||
|
private static final String kav = "Kav Landseeker";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Simple() {
|
||||||
|
addCard(Zone.HAND, playerA, kav);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, kav);
|
||||||
|
|
||||||
|
checkPermanentCount("T3: playerA has a Lander Token", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, playerA, "Lander Token", 1);
|
||||||
|
|
||||||
|
setStopAt(4, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, "Lander Token", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_TimeStop() {
|
||||||
|
addCard(Zone.HAND, playerA, kav);
|
||||||
|
addCard(Zone.HAND, playerA, "Time Stop"); // end the turn
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 6);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, kav);
|
||||||
|
|
||||||
|
checkPermanentCount("T3: playerA has a Lander Token", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, playerA, "Lander Token", 1);
|
||||||
|
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Time Stop");
|
||||||
|
|
||||||
|
setStopAt(6, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
// the delayed trigger has been cleaned up since the "next turn" had no end step.
|
||||||
|
assertPermanentCount(playerA, "Lander Token", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.mage.test.cards.single.ktk;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public class MeanderingTowershellTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link mage.cards.m.MeanderingTowershell Meandering Towershell} {3}{G}{G}
|
||||||
|
* Creature — Turtle
|
||||||
|
* Islandwalk (This creature can’t be blocked as long as defending player controls an Island.)
|
||||||
|
* Whenever this creature attacks, exile it. Return it to the battlefield under your control tapped and attacking at the beginning of the declare attackers step on your next turn.
|
||||||
|
* 5/9
|
||||||
|
*/
|
||||||
|
private static final String towershell = "Meandering Towershell";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Simple() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, towershell);
|
||||||
|
|
||||||
|
attack(1, playerA, towershell, playerB);
|
||||||
|
|
||||||
|
checkPermanentCount("T3 First Main: no Towershell", 3, PhaseStep.PRECOMBAT_MAIN, playerA, playerA, "Meandering Powershell", 0);
|
||||||
|
checkLife("T3 First Main: playerB at 20 life", 3, PhaseStep.PRECOMBAT_MAIN, playerB, 20);
|
||||||
|
|
||||||
|
// Meandering Towershell comes back attacking.
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, towershell, 1);
|
||||||
|
assertLife(playerB, 20 - 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_TimeStop() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, towershell);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
|
||||||
|
addCard(Zone.HAND, playerA, "Time Stop");
|
||||||
|
|
||||||
|
attack(1, playerA, towershell, playerB);
|
||||||
|
|
||||||
|
checkPermanentCount("T3 First Main: no Towershell", 3, PhaseStep.PRECOMBAT_MAIN, playerA, playerA, "Meandering Powershell", 0);
|
||||||
|
checkLife("T3 First Main: playerB at 20 life", 3, PhaseStep.PRECOMBAT_MAIN, playerB, 20);
|
||||||
|
|
||||||
|
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Time Stop");
|
||||||
|
|
||||||
|
// Meandering Towershell never comes back on future turns.
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(6, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertExileCount(playerA, towershell, 1);
|
||||||
|
assertPermanentCount(playerA, towershell, 0);
|
||||||
|
assertLife(playerB, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
package mage.abilities.common.delayed;
|
||||||
|
|
||||||
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Susucr
|
||||||
|
*/
|
||||||
|
public class AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||||
|
|
||||||
|
private GameEvent.EventType stepEvent;
|
||||||
|
private int nextTurn = -1; // once the controller starts a new turn, register it to trigger that turn.
|
||||||
|
private boolean isActive = true;
|
||||||
|
|
||||||
|
public AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility(Effect effect, GameEvent.EventType stepEvent) {
|
||||||
|
this(effect, stepEvent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility(Effect effect, GameEvent.EventType stepEvent, boolean optional) {
|
||||||
|
super(effect, Duration.Custom, true, optional);
|
||||||
|
this.stepEvent = stepEvent;
|
||||||
|
this.setTriggerPhrase(generateTriggerPhrase());
|
||||||
|
}
|
||||||
|
|
||||||
|
private AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility(final AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
this.nextTurn = ability.nextTurn;
|
||||||
|
this.isActive = ability.isActive;
|
||||||
|
this.stepEvent = ability.stepEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility copy() {
|
||||||
|
return new AtTheBeginOfStepOfYourNextTurnDelayedTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == stepEvent
|
||||||
|
|| event.getType() == GameEvent.EventType.BEGIN_TURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
if (!isControlledBy(event.getPlayerId())) {
|
||||||
|
// not your turn.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int turn = game.getTurnNum();
|
||||||
|
switch (event.getType()) {
|
||||||
|
case BEGIN_TURN:
|
||||||
|
// We register the turn number at the start of your next turn.
|
||||||
|
// This is in order to not trigger if that turn ends without an end step.
|
||||||
|
if (this.nextTurn == -1) {
|
||||||
|
this.nextTurn = turn;
|
||||||
|
} else if (turn > this.nextTurn) {
|
||||||
|
this.isActive = false; // to have the delayed trigger being cleaned up
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return turn == this.nextTurn && event.getType() == stepEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInactive(Game game) {
|
||||||
|
return super.isInactive(game) || !isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateTriggerPhrase() {
|
||||||
|
switch (stepEvent) {
|
||||||
|
case END_TURN_STEP_PRE:
|
||||||
|
return "At the beginning of the end step on your next turn, ";
|
||||||
|
case DECLARE_ATTACKERS_STEP_PRE:
|
||||||
|
return "At the beginning of the declare attackers step on your next turn, ";
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("stepEvent only supports steps events");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -40,6 +40,7 @@ public class GameEvent implements Serializable {
|
||||||
PREVENT_DAMAGE, PREVENTED_DAMAGE,
|
PREVENT_DAMAGE, PREVENTED_DAMAGE,
|
||||||
//Turn-based events
|
//Turn-based events
|
||||||
PLAY_TURN, EXTRA_TURN,
|
PLAY_TURN, EXTRA_TURN,
|
||||||
|
BEGIN_TURN, // event fired on actual begin of turn.
|
||||||
CHANGE_PHASE, PHASE_CHANGED,
|
CHANGE_PHASE, PHASE_CHANGED,
|
||||||
CHANGE_STEP, STEP_CHANGED,
|
CHANGE_STEP, STEP_CHANGED,
|
||||||
BEGINNING_PHASE, BEGINNING_PHASE_PRE, BEGINNING_PHASE_POST, // The normal beginning phase -- at the beginning of turn
|
BEGINNING_PHASE, BEGINNING_PHASE_PRE, BEGINNING_PHASE_POST, // The normal beginning phase -- at the beginning of turn
|
||||||
|
|
|
||||||
|
|
@ -547,6 +547,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
resetLandsPlayed();
|
resetLandsPlayed();
|
||||||
updateRange(game);
|
updateRange(game);
|
||||||
game.getState().removeTurnStartEffect(game);
|
game.getState().removeTurnStartEffect(game);
|
||||||
|
GameEvent event = new GameEvent(GameEvent.EventType.BEGIN_TURN, null, null, getId());
|
||||||
|
game.fireEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue