mirror of
https://github.com/magefree/mage.git
synced 2026-01-22 19:29:59 -08:00
* Until end of your turn - fixed that effects discarded too early in multiplayer games (#5759, #5676);
Tests: added dozen tests for end of turn effects and related cards.
This commit is contained in:
parent
4288e45c23
commit
534037e095
22 changed files with 758 additions and 137 deletions
|
|
@ -130,7 +130,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect {
|
|||
if (targetPermanent == null) {
|
||||
return true;
|
||||
}
|
||||
return game.getPhase().getType() == TurnPhase.END && game.getTurnNum() > getNextStartingControllerTurnNum();
|
||||
return game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game); // discard on end of their next turn
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -114,20 +114,21 @@ class GideonJuraEffect extends RequirementEffect {
|
|||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
creatingPermanent = new MageObjectReference(source.getSourceId(), game);
|
||||
setStartingControllerAndTurnNum(game, source.getFirstTarget(), game.getActivePlayerId()); // setup startingController to calc isYourTurn calls
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
return permanent.isControlledBy(source.getFirstTarget());
|
||||
return permanent.isControlledBy(source.getFirstTarget()) && this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
return (getStartingTurnNum() != game.getTurnNum()
|
||||
&& (game.getPhase().getType() == TurnPhase.END
|
||||
&& game.isActivePlayer(source.getFirstTarget())))
|
||||
|| // 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura (because he's no longer on the battlefield, for example), that player may have it attack you, another one of your planeswalkers, or nothing at all.
|
||||
creatingPermanent.getPermanent(game) == null;
|
||||
return (game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game))
|
||||
// 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura
|
||||
// (because he's no longer on the battlefield, for example), that player may have it attack you,
|
||||
// another one of your planeswalkers, or nothing at all.
|
||||
|| creatingPermanent.getPermanent(game) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ public final class OracleEnVec extends CardImpl {
|
|||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// {tap}: Target opponent chooses any number of creatures he or she controls. During that player's next turn, the chosen creatures attack if able, and other creatures can't attack. At the beginning of that turn's end step, destroy each of the chosen creatures that didn't attack. Activate this ability only during your turn.
|
||||
// {T}: Target opponent chooses any number of creatures they control. During that player’s next turn, the chosen
|
||||
// creatures attack if able, and other creatures can’t attack. At the beginning of that turn’s end step,
|
||||
// destroy each of the chosen creatures that didn’t attack this turn. Activate this ability only during your turn.
|
||||
Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new OracleEnVecEffect(), new TapSourceCost(), MyTurnCondition.instance);
|
||||
ability.addTarget(new TargetOpponent());
|
||||
this.addAbility(ability, new AttackedThisTurnWatcher());
|
||||
|
|
@ -62,7 +64,9 @@ class OracleEnVecEffect extends OneShotEffect {
|
|||
|
||||
OracleEnVecEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Target opponent chooses any number of creatures he or she controls. During that player's next turn, the chosen creatures attack if able, and other creatures can't attack. At the beginning of that turn's end step, destroy each of the chosen creatures that didn't attack";
|
||||
this.staticText = "Target opponent chooses any number of creatures he or she controls. During that player's next turn, " +
|
||||
"the chosen creatures attack if able, and other creatures can't attack. At the beginning of that turn's end step, " +
|
||||
"destroy each of the chosen creatures that didn't attack";
|
||||
}
|
||||
|
||||
OracleEnVecEffect(final OracleEnVecEffect effect) {
|
||||
|
|
@ -102,7 +106,7 @@ class OracleEnVecEffect extends OneShotEffect {
|
|||
class OracleEnVecMustAttackRequirementEffect extends RequirementEffect {
|
||||
|
||||
OracleEnVecMustAttackRequirementEffect() {
|
||||
super(Duration.Custom);
|
||||
super(Duration.UntilEndOfYourNextTurn);
|
||||
}
|
||||
|
||||
OracleEnVecMustAttackRequirementEffect(final OracleEnVecMustAttackRequirementEffect effect) {
|
||||
|
|
@ -117,7 +121,8 @@ class OracleEnVecMustAttackRequirementEffect extends RequirementEffect {
|
|||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
return this.getTargetPointer().getFirst(game, source) != null
|
||||
&& this.getTargetPointer().getFirst(game, source).equals(permanent.getId());
|
||||
&& this.getTargetPointer().getFirst(game, source).equals(permanent.getId())
|
||||
&& this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -130,11 +135,20 @@ class OracleEnVecMustAttackRequirementEffect extends RequirementEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
Permanent perm = game.getPermanent(this.getTargetPointer().getFirst(game, source));
|
||||
if (perm != null) {
|
||||
setStartingControllerAndTurnNum(game, perm.getControllerId(), game.getActivePlayerId()); // setup startingController to calc isYourTurn calls
|
||||
} else {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
return getStartingTurnNum() != game.getTurnNum()
|
||||
&& (game.getPhase().getType() == TurnPhase.END
|
||||
&& game.isActivePlayer(this.getTargetPointer().getFirst(game, source)));
|
||||
return game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -169,11 +183,20 @@ class OracleEnVecCantAttackRestrictionEffect extends RestrictionEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
Permanent perm = game.getPermanent(this.getTargetPointer().getFirst(game, source));
|
||||
if (perm != null) {
|
||||
setStartingControllerAndTurnNum(game, perm.getControllerId(), game.getActivePlayerId()); // setup startingController to calc isYourTurn calls
|
||||
} else {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
return getStartingTurnNum() != game.getTurnNum()
|
||||
&& (game.getPhase().getType() == TurnPhase.END
|
||||
&& game.isActivePlayer(this.getTargetPointer().getFirst(game, source)));
|
||||
return game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -71,13 +71,22 @@ class PeaceTalksEffect extends OneShotEffect {
|
|||
|
||||
class PeaceTalksCantAttackEffect extends RestrictionEffect {
|
||||
|
||||
int startedTurnNum = 0;
|
||||
|
||||
public PeaceTalksCantAttackEffect() {
|
||||
super(Duration.Custom);
|
||||
staticText = "Creatures can't attack this turn and next turn";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
startedTurnNum = game.getTurnNum();
|
||||
}
|
||||
|
||||
public PeaceTalksCantAttackEffect(final PeaceTalksCantAttackEffect effect) {
|
||||
super(effect);
|
||||
this.startedTurnNum = effect.startedTurnNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -97,7 +106,7 @@ class PeaceTalksCantAttackEffect extends RestrictionEffect {
|
|||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (getStartingTurnNum() + 2 <= game.getTurnNum()) {
|
||||
if (game.getTurnNum() > (startedTurnNum + 1)) {
|
||||
this.discard();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -107,6 +116,8 @@ class PeaceTalksCantAttackEffect extends RestrictionEffect {
|
|||
|
||||
class PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities extends ContinuousRuleModifyingEffectImpl {
|
||||
|
||||
int startedTurnNum = 0;
|
||||
|
||||
public PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities() {
|
||||
super(Duration.Custom, Outcome.Neutral);
|
||||
staticText = "players and permanents can't be the targets of spells or activated abilities";
|
||||
|
|
@ -114,6 +125,13 @@ class PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities ex
|
|||
|
||||
public PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities(final PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities effect) {
|
||||
super(effect);
|
||||
this.startedTurnNum = effect.startedTurnNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
startedTurnNum = game.getTurnNum();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -149,7 +167,7 @@ class PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities ex
|
|||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (getStartingTurnNum() + 2 <= game.getTurnNum()) {
|
||||
if (game.getTurnNum() > (startedTurnNum + 1)) {
|
||||
this.discard();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,20 +92,21 @@ class RowanKenrithAttackEffect extends RequirementEffect {
|
|||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
creatingPermanent = new MageObjectReference(source.getSourceId(), game);
|
||||
setStartingControllerAndTurnNum(game, source.getFirstTarget(), game.getActivePlayerId()); // setup startingController to calc isYourTurn calls
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
return permanent.isControlledBy(source.getFirstTarget());
|
||||
return permanent.isControlledBy(source.getFirstTarget()) && this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
return (getStartingTurnNum() != game.getTurnNum()
|
||||
&& (game.getPhase().getType() == TurnPhase.END
|
||||
&& game.isActivePlayer(source.getFirstTarget())))
|
||||
|| // 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura (because he's no longer on the battlefield, for example), that player may have it attack you, another one of your planeswalkers, or nothing at all.
|
||||
creatingPermanent.getPermanent(game) == null;
|
||||
return (game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game))
|
||||
// 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura
|
||||
// (because he's no longer on the battlefield, for example), that player may have it attack you,
|
||||
// another one of your planeswalkers, or nothing at all.
|
||||
|| creatingPermanent.getPermanent(game) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -59,9 +59,7 @@ class TauntEffect extends RequirementEffect {
|
|||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
return getStartingTurnNum() != game.getTurnNum() &&
|
||||
(game.getPhase().getType() == TurnPhase.END &&
|
||||
game.isActivePlayer(this.getTargetPointer().getFirst(game, source)));
|
||||
return game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -94,10 +94,7 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (getStartingTurnNum() != 0 && game.getTurnNum() != getStartingTurnNum()) {
|
||||
return game.isActivePlayer(source.getControllerId());
|
||||
}
|
||||
return false;
|
||||
return game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ public final class WallOfDust extends CardImpl {
|
|||
|
||||
class WallOfDustRestrictionEffect extends RestrictionEffect {
|
||||
|
||||
int nextTurnTargetController = 0;
|
||||
protected MageObjectReference targetPermanentReference;
|
||||
|
||||
public WallOfDustRestrictionEffect() {
|
||||
|
|
@ -57,7 +56,6 @@ class WallOfDustRestrictionEffect extends RestrictionEffect {
|
|||
|
||||
public WallOfDustRestrictionEffect(final WallOfDustRestrictionEffect effect) {
|
||||
super(effect);
|
||||
this.nextTurnTargetController = effect.nextTurnTargetController;
|
||||
this.targetPermanentReference = effect.targetPermanentReference;
|
||||
}
|
||||
|
||||
|
|
@ -68,26 +66,22 @@ class WallOfDustRestrictionEffect extends RestrictionEffect {
|
|||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (targetPermanentReference == null) {
|
||||
if (targetPermanentReference == null || targetPermanentReference.getPermanent(game) == null) {
|
||||
return true;
|
||||
}
|
||||
Permanent targetPermanent = targetPermanentReference.getPermanent(game);
|
||||
if (targetPermanent == null) {
|
||||
return true;
|
||||
}
|
||||
if (nextTurnTargetController == 0 && getStartingTurnNum() != game.getTurnNum() && game.isActivePlayer(targetPermanent.getControllerId())) {
|
||||
nextTurnTargetController = game.getTurnNum();
|
||||
}
|
||||
return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController;
|
||||
|
||||
return game.getPhase().getType() == TurnPhase.END && this.isYourNextTurn(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
if (getTargetPointer().getFirst(game, source) == null) {
|
||||
discard();
|
||||
Permanent perm = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (perm != null) {
|
||||
targetPermanentReference = new MageObjectReference(perm, game);
|
||||
setStartingControllerAndTurnNum(game, perm.getControllerId(), game.getActivePlayerId());
|
||||
} else {
|
||||
targetPermanentReference = new MageObjectReference(getTargetPointer().getFirst(game, source), game);
|
||||
discard();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue