Fixed Single Combat that it does not prevent cast on next turn;

This commit is contained in:
Oleg Agafonov 2019-04-23 16:05:34 +04:00
parent d1e2fc860d
commit 081ac7ca3c
15 changed files with 94 additions and 127 deletions

View file

@ -1,7 +1,5 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
@ -16,12 +14,7 @@ import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.TurnPhase;
import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
@ -29,8 +22,9 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.token.TokenImpl;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class GideonBattleForged extends CardImpl {
@ -98,6 +92,7 @@ class GideonBattleForgedToken extends TokenImpl {
toughness = new MageInt(4);
this.addAbility(IndestructibleAbility.getInstance());
}
public GideonBattleForgedToken(final GideonBattleForgedToken token) {
super(token);
}
@ -109,7 +104,6 @@ class GideonBattleForgedToken extends TokenImpl {
class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect {
int nextTurnTargetController = 0;
protected MageObjectReference targetPermanentReference;
public GideonBattleForgedAttacksIfAbleTargetEffect(Duration duration) {
@ -119,7 +113,6 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect {
public GideonBattleForgedAttacksIfAbleTargetEffect(final GideonBattleForgedAttacksIfAbleTargetEffect effect) {
super(effect);
this.nextTurnTargetController = effect.nextTurnTargetController;
this.targetPermanentReference = effect.targetPermanentReference;
}
@ -137,10 +130,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect {
if (targetPermanent == null) {
return true;
}
if (nextTurnTargetController == 0 && startingTurn != 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 && game.getTurnNum() > getNextStartingControllerTurnNum();
}
@Override

View file

@ -1,6 +1,5 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
@ -13,11 +12,7 @@ import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TurnPhase;
import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
@ -26,8 +21,9 @@ import mage.game.permanent.token.TokenImpl;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public final class GideonJura extends CardImpl {
@ -127,7 +123,7 @@ class GideonJuraEffect extends RequirementEffect {
@Override
public boolean isInactive(Ability source, Game game) {
return (startingTurn != game.getTurnNum()
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.

View file

@ -132,7 +132,7 @@ class OracleEnVecMustAttackRequirementEffect extends RequirementEffect {
@Override
public boolean isInactive(Ability source, Game game) {
return startingTurn != game.getTurnNum()
return getStartingTurnNum() != game.getTurnNum()
&& (game.getPhase().getType() == TurnPhase.END
&& game.isActivePlayer(this.getTargetPointer().getFirst(game, source)));
}
@ -171,7 +171,7 @@ class OracleEnVecCantAttackRestrictionEffect extends RestrictionEffect {
@Override
public boolean isInactive(Ability source, Game game) {
return startingTurn != game.getTurnNum()
return getStartingTurnNum() != game.getTurnNum()
&& (game.getPhase().getType() == TurnPhase.END
&& game.isActivePlayer(this.getTargetPointer().getFirst(game, source)));
}

View file

@ -97,7 +97,7 @@ class PeaceTalksCantAttackEffect extends RestrictionEffect {
@Override
public boolean isInactive(Ability source, Game game) {
if (startingTurn + 2 == game.getTurnNum()) {
if (getStartingTurnNum() + 2 <= game.getTurnNum()) {
this.discard();
return true;
}
@ -149,7 +149,7 @@ class PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities ex
@Override
public boolean isInactive(Ability source, Game game) {
if (startingTurn + 2 == game.getTurnNum()) {
if (getStartingTurnNum() + 2 <= game.getTurnNum()) {
this.discard();
return true;
}

View file

@ -101,7 +101,7 @@ class RowanKenrithAttackEffect extends RequirementEffect {
@Override
public boolean isInactive(Ability source, Game game) {
return (startingTurn != game.getTurnNum()
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.

View file

@ -97,7 +97,7 @@ class SingleCombatEffect extends OneShotEffect {
class SingleCombatRestrictionEffect extends ContinuousRuleModifyingEffectImpl {
SingleCombatRestrictionEffect() {
super(Duration.UntilYourNextTurn, Outcome.Neutral);
super(Duration.UntilEndOfYourNextTurn, Outcome.Neutral);
staticText = "Players can't cast creature or planeswalker spells until the end of your next turn.";
}

View file

@ -1,7 +1,5 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.RequirementEffect;
import mage.cards.CardImpl;
@ -13,8 +11,9 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
*
* @author emerald000
*/
public final class Taunt extends CardImpl {
@ -60,7 +59,7 @@ class TauntEffect extends RequirementEffect {
@Override
public boolean isInactive(Ability source, Game game) {
return startingTurn != game.getTurnNum() &&
return getStartingTurnNum() != game.getTurnNum() &&
(game.getPhase().getType() == TurnPhase.END &&
game.isActivePlayer(this.getTargetPointer().getFirst(game, source)));
}

View file

@ -1,21 +1,12 @@
package mage.cards.t;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
@ -23,8 +14,10 @@ import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
import mage.target.targetpointer.FixedTargets;
import java.util.List;
import java.util.UUID;
/**
*
* @author spjspj
*/
public final class TreasureNabber extends CardImpl {
@ -94,18 +87,8 @@ class TreasureNabberEffect extends ContinuousEffectImpl {
protected FixedTargets fixedTargets;
TreasureNabberEffect() {
super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
super(Duration.UntilEndOfYourNextTurn, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.staticText = "gain control of that artifact until the end of your next turn";
startingTurn = 0;
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
startingTurn = game.getTurnNum();
if (game.getPhase().getStep().getType() == PhaseStep.END_TURN) {
startingTurn = game.getTurnNum() + 1;
}
}
TreasureNabberEffect(final TreasureNabberEffect effect) {
@ -118,16 +101,6 @@ class TreasureNabberEffect extends ContinuousEffectImpl {
return new TreasureNabberEffect(this);
}
@Override
public boolean isInactive(Ability source, Game game) {
if (startingTurn != 0 && game.getTurnNum() >= startingTurn && game.getPhase().getStep().getType() == PhaseStep.END_TURN) {
if (game.isActivePlayer(source.getControllerId())) {
return true;
}
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));

View file

@ -1,7 +1,5 @@
package mage.cards.v;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.TriggeredAbilityImpl;
@ -12,14 +10,7 @@ import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamagedPlaneswalkerEvent;
import mage.game.events.GameEvent;
@ -29,15 +20,15 @@ import mage.game.permanent.token.AssassinToken;
import mage.target.common.TargetNonlandPermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* If an effect creates a copy of one of the Assassin creature tokens, the copy
* will also have the triggered ability.
*
* <p>
* Each Assassin token's triggered ability will trigger whenever it deals combat
* damage to any player, including you.
*
*
* @author LevelX2
*/
public final class VraskaTheUnseen extends CardImpl {
@ -79,7 +70,6 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.ability = ability;
staticText = "Until your next turn, whenever a creature deals combat damage to {this}, destroy that creature";
startingTurn = 0;
}
public VraskaTheUnseenGainAbilityEffect(final VraskaTheUnseenGainAbilityEffect effect) {
@ -87,12 +77,6 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
this.ability = effect.ability.copy();
}
@Override
public void init(Ability source, Game game) {
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
startingTurn = game.getTurnNum();
}
@Override
public VraskaTheUnseenGainAbilityEffect copy() {
return new VraskaTheUnseenGainAbilityEffect(this);
@ -110,10 +94,8 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl {
@Override
public boolean isInactive(Ability source, Game game) {
if (startingTurn != 0 && game.getTurnNum() != startingTurn) {
if (game.isActivePlayer(source.getControllerId())) {
return true;
}
if (getStartingTurnNum() != 0 && game.getTurnNum() != getStartingTurnNum()) {
return game.isActivePlayer(source.getControllerId());
}
return false;
}

View file

@ -75,7 +75,7 @@ class WallOfDustRestrictionEffect extends RestrictionEffect {
if (targetPermanent == null) {
return true;
}
if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.isActivePlayer(targetPermanent.getControllerId())) {
if (nextTurnTargetController == 0 && getStartingTurnNum() != game.getTurnNum() && game.isActivePlayer(targetPermanent.getControllerId())) {
nextTurnTargetController = game.getTurnNum();
}
return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController;

View file

@ -1,10 +1,5 @@
package mage.abilities.effects;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.constants.DependencyType;
@ -13,8 +8,12 @@ import mage.constants.Layer;
import mage.constants.SubLayer;
import mage.game.Game;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public interface ContinuousEffect extends Effect {
@ -59,6 +58,14 @@ public interface ContinuousEffect extends Effect {
void addDependedToType(DependencyType dependencyType);
void setStartingTurnNum(Game game, UUID startingController);
int getStartingTurnNum();
int getNextStartingControllerTurnNum();
UUID getStartingController();
@Override
void newId();

View file

@ -1,12 +1,5 @@
package mage.abilities.effects;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.MageSingleton;
@ -14,16 +7,12 @@ import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.DomainValue;
import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.constants.AbilityType;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.constants.EffectType;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import java.util.*;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -50,8 +39,9 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
protected boolean characterDefining = false;
// until your next turn
protected int startingTurn;
protected UUID startingControllerId;
private int startingTurnNum;
private int yourNextTurnNum;
private UUID startingControllerId;
public ContinuousEffectImpl(Duration duration, Outcome outcome) {
super(outcome);
@ -79,7 +69,8 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
this.affectedObjectsSet = effect.affectedObjectsSet;
this.affectedObjectList.addAll(effect.affectedObjectList);
this.temporary = effect.temporary;
this.startingTurn = effect.startingTurn;
this.startingTurnNum = effect.startingTurnNum;
this.yourNextTurnNum = effect.yourNextTurnNum;
this.startingControllerId = effect.startingControllerId;
this.dependencyTypes = effect.dependencyTypes;
this.dependendToTypes = effect.dependendToTypes;
@ -170,17 +161,44 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
this.affectedObjectsSet = true;
}
}
startingTurn = game.getTurnNum();
startingControllerId = source.getControllerId();
setStartingTurnNum(game, source.getControllerId());
}
@Override
public void setStartingTurnNum(Game game, UUID startingController) {
this.startingControllerId = startingController;
this.startingTurnNum = game.getTurnNum();
this.yourNextTurnNum = game.isActivePlayer(startingControllerId) ? startingTurnNum + 2 : startingTurnNum + 1;
}
public int getStartingTurnNum() {
return this.startingTurnNum;
}
public int getNextStartingControllerTurnNum() {
return this.yourNextTurnNum;
}
public UUID getStartingController() {
return this.startingControllerId;
}
@Override
public boolean isInactive(Ability source, Game game) {
if (duration == Duration.UntilYourNextTurn) {
if (duration == Duration.UntilYourNextTurn || duration == Duration.UntilEndOfYourNextTurn) {
Player player = game.getPlayer(startingControllerId);
if (player != null) {
if (player.isInGame()) {
return game.isActivePlayer(startingControllerId) && game.getTurnNum() != startingTurn;
boolean canDelete = false;
switch (duration) {
case UntilYourNextTurn:
canDelete = game.getTurnNum() >= yourNextTurnNum;
break;
case UntilEndOfYourNextTurn:
canDelete = (game.getTurnNum() > yourNextTurnNum)
|| (game.getTurnNum() == yourNextTurnNum && game.getStep().getType().isAfter(PhaseStep.END_TURN));
}
return canDelete;
}
return player.hasReachedNextTurnAfterLeaving();
}

View file

@ -1,6 +1,5 @@
package mage.abilities.effects;
import java.util.*;
import mage.abilities.Ability;
import mage.abilities.MageSingleton;
import mage.constants.Duration;
@ -8,6 +7,8 @@ import mage.constants.Zone;
import mage.game.Game;
import org.apache.log4j.Logger;
import java.util.*;
/**
* @param <T>
* @author BetaSteward_at_googlemail.com
@ -102,6 +103,7 @@ public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList
break;
case Custom:
case UntilYourNextTurn:
case UntilEndOfYourNextTurn:
if (effect.isInactive(ability, game)) {
it.remove();
}

View file

@ -33,7 +33,7 @@ public class CantAttackYouAllEffect extends RestrictionEffect {
this.alsoPlaneswalker = alsoPlaneswalker;
staticText = filterAttacker.getMessage() + " can't attack you"
+ (alsoPlaneswalker ? " or a planeswalker you control" : "")
+ (duration == Duration.UntilYourNextTurn ? " until your next turn" : "");
+ (duration == Duration.UntilYourNextTurn || duration == Duration.UntilEndOfYourNextTurn ? " " + duration.toString() : "");
}
CantAttackYouAllEffect(final CantAttackYouAllEffect effect) {

View file

@ -1,7 +1,6 @@
package mage.constants;
/**
*
* @author North
*/
public enum Duration {
@ -12,6 +11,7 @@ public enum Duration {
WhileInGraveyard("", false),
EndOfTurn("until end of turn", true),
UntilYourNextTurn("until your next turn", true),
UntilEndOfYourNextTurn("until the end of your next turn", true),
UntilSourceLeavesBattlefield("until {source} leaves the battlefield", true), // supported for continuous layered effects
EndOfCombat("until end of combat", true),
EndOfStep("until end of phase step", true),