mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 18:50:06 -08:00
Fixed potential NPE errors in getPhase usage (fixed Berserker's Frenzy, etc)
This commit is contained in:
parent
cfd7464b49
commit
a15a0daa04
81 changed files with 162 additions and 130 deletions
|
|
@ -23,13 +23,13 @@ public class DealsDamageToOneOrMoreCreaturesTriggeredAbility extends DealsDamage
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (super.checkTrigger(event, game)) {
|
||||
// check that combat damage does only once trigger also if multiple creatures were damaged because they block or were blocked by source
|
||||
if (game.getTurn().getStepType() == PhaseStep.COMBAT_DAMAGE
|
||||
|| game.getTurn().getStepType() == PhaseStep.FIRST_COMBAT_DAMAGE) {
|
||||
if (game.getTurnStepType() == PhaseStep.COMBAT_DAMAGE
|
||||
|| game.getTurnStepType() == PhaseStep.FIRST_COMBAT_DAMAGE) {
|
||||
String stepHash = (String) game.getState().getValue("damageStep" + getOriginalId());
|
||||
String newStepHash = game.getStep().getType().toString() + game.getTurnNum();
|
||||
String newStepHash = game.getTurnStepType().toString() + game.getTurnNum();
|
||||
if (!newStepHash.equals(stepHash)) {
|
||||
// this ability did not trigger during this damage step
|
||||
game.getState().setValue("damageStep" + getOriginalId(), game.getStep().getType().toString() + game.getTurnNum());
|
||||
game.getState().setValue("damageStep" + getOriginalId(), game.getTurnStepType().toString() + game.getTurnNum());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public enum AddendumCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
if (!game.isActivePlayer(source.getControllerId()) ||
|
||||
!game.getPhase().getType().isMain()) {
|
||||
!game.getTurnPhaseType().isMain()) {
|
||||
return false;
|
||||
}
|
||||
if (CastFromEverywhereSourceCondition.instance.apply(game, source)) {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ public enum AfterBlockersAreDeclaredCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
|
||||
return !(game.getStep().getType() == PhaseStep.BEGIN_COMBAT
|
||||
|| game.getStep().getType() == PhaseStep.DECLARE_ATTACKERS);
|
||||
return !(game.getTurnStepType() == PhaseStep.BEGIN_COMBAT
|
||||
|| game.getTurnStepType() == PhaseStep.DECLARE_ATTACKERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public enum AfterCombatCondition implements Condition {
|
|||
@Override
|
||||
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getStep().getType().isAfter(PhaseStep.END_COMBAT);
|
||||
return game.getTurnStepType().isAfter(PhaseStep.END_COMBAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public enum AfterUpkeepStepCondtion implements Condition {
|
|||
@Override
|
||||
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getStep().getType().isAfter(PhaseStep.UPKEEP);
|
||||
return game.getTurnStepType().isAfter(PhaseStep.UPKEEP);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public enum BeforeBlockersAreDeclaredCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getStep().getType().isBefore(PhaseStep.DECLARE_BLOCKERS);
|
||||
return game.getTurnStepType().isBefore(PhaseStep.DECLARE_BLOCKERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class IsPhaseCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return turnPhase == game.getTurn().getPhaseType() && (!yourTurn || game.getActivePlayerId().equals(source.getControllerId()));
|
||||
return turnPhase == game.getTurnPhaseType() && (!yourTurn || game.getActivePlayerId().equals(source.getControllerId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class IsStepCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return phaseStep == game.getStep().getType() && (!onlyDuringYourSteps || game.isActivePlayer(source.getControllerId()));
|
||||
return phaseStep == game.getTurnStepType() && (!onlyDuringYourSteps || game.isActivePlayer(source.getControllerId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ public class ContinuousEffects implements Serializable {
|
|||
updateTimestamps(timestampGroupName, layerEffects);
|
||||
layerEffects.sort(Comparator.comparingLong(ContinuousEffect::getOrder));
|
||||
/* debug effects apply order:
|
||||
if (game.getStep() != null) System.out.println("layr - " + game.getTurnNum() + "." + game.getStep().getType() + ": layers " + layerEffects.size()
|
||||
if (game.getStep() != null) System.out.println("layr - " + game.getTurnNum() + "." + game.getTurnStepType() + ": layers " + layerEffects.size()
|
||||
+ " - " + layerEffects.stream().map(l -> l.getClass().getSimpleName()).collect(Collectors.joining(", "))
|
||||
+ " - " + callName);
|
||||
//*/
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ public class AddCombatAndMainPhaseEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
// 15.07.2006 If it's somehow not a main phase when Fury of the Horde resolves, all it does is untap all creatures that attacked that turn. No new phases are created.
|
||||
if (game.getTurn().getPhaseType() == TurnPhase.PRECOMBAT_MAIN
|
||||
|| game.getTurn().getPhaseType() == TurnPhase.POSTCOMBAT_MAIN) {
|
||||
if (game.getTurnPhaseType() == TurnPhase.PRECOMBAT_MAIN
|
||||
|| game.getTurnPhaseType() == TurnPhase.POSTCOMBAT_MAIN) {
|
||||
// we can't add two turn modes at once, will add additional post combat on delayed trigger resolution
|
||||
TurnMod combat = new TurnMod(source.getControllerId(), TurnPhase.COMBAT, TurnPhase.POSTCOMBAT_MAIN, false);
|
||||
game.getState().getTurnMods().add(combat);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class DontUntapInControllersNextUntapStepSourceEffect extends ContinuousR
|
|||
validForTurnNum = game.getTurnNum();
|
||||
}
|
||||
// skip untap action
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP
|
||||
&& event.getType() == GameEvent.EventType.UNTAP
|
||||
&& game.isActivePlayer(source.getControllerId())
|
||||
&& event.getTargetId().equals(source.getSourceId())) {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
|
|||
}
|
||||
}
|
||||
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
||||
if (handledTargetsDuringTurn.containsKey(event.getTargetId())
|
||||
&& !handledTargetsDuringTurn.get(event.getTargetId())
|
||||
&& getTargetPointer().getTargets(game, source).contains(event.getTargetId())) {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class DontUntapInControllersUntapStepAllEffect extends ContinuousRuleModi
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP) {
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null) {
|
||||
switch(targetController) {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class DontUntapInControllersUntapStepEnchantedEffect extends ContinuousRu
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP) {
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP) {
|
||||
Permanent enchantment = game.getPermanent(source.getSourceId());
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) {
|
||||
Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class DontUntapInControllersUntapStepSourceEffect extends ContinuousRuleM
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP
|
||||
&& event.getTargetId().equals(source.getSourceId())) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getTurn().getStepType() != PhaseStep.UNTAP) {
|
||||
if (game.getTurnStepType() != PhaseStep.UNTAP) {
|
||||
return false;
|
||||
}
|
||||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public class DontUntapInPlayersNextUntapStepAllEffect extends ContinuousRuleModi
|
|||
}
|
||||
}
|
||||
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class UntapAllDuringEachOtherPlayersUntapStepEffect extends ContinuousEff
|
|||
|
||||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
if (layer == Layer.RulesEffects && game.getStep().getType() == PhaseStep.UNTAP && !source.isControlledBy(game.getActivePlayerId())) {
|
||||
if (layer == Layer.RulesEffects && game.getTurnStepType() == PhaseStep.UNTAP && !source.isControlledBy(game.getActivePlayerId())) {
|
||||
Integer appliedTurn = (Integer) game.getState().getValue(source.getSourceId() + "appliedTurn");
|
||||
if (appliedTurn == null) {
|
||||
appliedTurn = 0;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class UntapSourceDuringEachOtherPlayersUntapStepEffect extends Continuous
|
|||
if (!applied && layer == Layer.RulesEffects) {
|
||||
if (!source.isControlledBy(game.getActivePlayerId())
|
||||
&& game.getStep() != null
|
||||
&& game.getStep().getType() == PhaseStep.UNTAP) {
|
||||
&& game.getTurnStepType() == PhaseStep.UNTAP) {
|
||||
game.getState().setValue(source.getSourceId() + "applied", true);
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
|
|
@ -46,7 +46,7 @@ public class UntapSourceDuringEachOtherPlayersUntapStepEffect extends Continuous
|
|||
}
|
||||
}
|
||||
} else if (applied && layer == Layer.RulesEffects) {
|
||||
if (game.getStep() != null && game.getStep().getType() == PhaseStep.END_TURN) {
|
||||
if (game.getStep() != null && game.getTurnStepType() == PhaseStep.END_TURN) {
|
||||
game.getState().setValue(source.getSourceId() + "applied", false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ public class CastOnlyDuringPhaseStepSourceEffect extends ContinuousRuleModifying
|
|||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
// has to return true, if the spell cannot be cast in the current phase / step
|
||||
if (event.getSourceId().equals(source.getSourceId())) {
|
||||
if ((turnPhase != null && game.getPhase().getType() != turnPhase)
|
||||
|| (phaseStep != null && (game.getTurn().getStepType() != phaseStep))
|
||||
if ((turnPhase != null && game.getTurnPhaseType() != turnPhase)
|
||||
|| (phaseStep != null && (game.getTurnStepType() != phaseStep))
|
||||
|| (condition != null && !condition.apply(game, source))) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class ArtificialScoringSystem implements ScoringSystem {
|
|||
if (game.getStep() == null) {
|
||||
return 0;
|
||||
}
|
||||
return ScoringConstants.LOSE_GAME_SCORE + game.getTurnNum() * 2500 + game.getStep().getType().getIndex() * 200;
|
||||
return ScoringConstants.LOSE_GAME_SCORE + game.getTurnNum() * 2500 + game.getTurnStepType().getIndex() * 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -180,6 +180,19 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
|
|||
|
||||
Turn getTurn();
|
||||
|
||||
/**
|
||||
* @return can return null in non started games
|
||||
*/
|
||||
PhaseStep getTurnStepType();
|
||||
|
||||
/**
|
||||
* @return can return null in non started games
|
||||
*/
|
||||
TurnPhase getTurnPhaseType();
|
||||
|
||||
/**
|
||||
* @return can return null in non started games
|
||||
*/
|
||||
Phase getPhase();
|
||||
|
||||
Step getStep();
|
||||
|
|
|
|||
|
|
@ -2882,6 +2882,16 @@ public abstract class GameImpl implements Game {
|
|||
return state.getTurn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhaseStep getTurnStepType() {
|
||||
return state.getTurnStepType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TurnPhase getTurnPhaseType() {
|
||||
return state.getTurnPhaseType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Phase getPhase() {
|
||||
return state.getTurn().getPhase();
|
||||
|
|
@ -2919,7 +2929,7 @@ public abstract class GameImpl implements Game {
|
|||
|
||||
@Override
|
||||
public boolean isMainPhase() {
|
||||
return state.getTurn().getStepType() == PhaseStep.PRECOMBAT_MAIN || state.getTurn().getStepType() == PhaseStep.POSTCOMBAT_MAIN;
|
||||
return state.getTurnStepType() == PhaseStep.PRECOMBAT_MAIN || state.getTurnStepType() == PhaseStep.POSTCOMBAT_MAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import mage.abilities.effects.ContinuousEffect;
|
|||
import mage.abilities.effects.ContinuousEffects;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.TurnPhase;
|
||||
import mage.constants.Zone;
|
||||
import mage.designations.Designation;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
|
|
@ -22,6 +24,8 @@ import mage.game.permanent.PermanentCard;
|
|||
import mage.game.permanent.PermanentToken;
|
||||
import mage.game.stack.SpellStack;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.game.turn.Phase;
|
||||
import mage.game.turn.Step;
|
||||
import mage.game.turn.Turn;
|
||||
import mage.game.turn.TurnMods;
|
||||
import mage.players.Player;
|
||||
|
|
@ -572,6 +576,19 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
return turn;
|
||||
}
|
||||
|
||||
public PhaseStep getTurnStepType() {
|
||||
Turn turn = this.getTurn();
|
||||
Phase phase = turn != null ? turn.getPhase() : null;
|
||||
Step step = phase != null ? phase.getStep() : null;
|
||||
return step != null ? step.getType() : null;
|
||||
}
|
||||
|
||||
public TurnPhase getTurnPhaseType() {
|
||||
Turn turn = this.getTurn();
|
||||
Phase phase = turn != null ? turn.getPhase() : null;
|
||||
return phase != null ? phase.getType() : null;
|
||||
}
|
||||
|
||||
public Combat getCombat() {
|
||||
return combat;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class LukeSkywalkerEmblemEffect extends PreventionEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getPhase().getType() == TurnPhase.COMBAT
|
||||
if (game.getTurnPhaseType() == TurnPhase.COMBAT
|
||||
&& super.applies(event, source, game)
|
||||
&& event.getType() == GameEvent.EventType.DAMAGE_PLAYER) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class EdgeOfMalacolEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
// Prevent untap event of creatures of target player
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP) {
|
||||
if (game.getTurnStepType() == PhaseStep.UNTAP) {
|
||||
Plane cPlane = game.getState().getCurrentPlane();
|
||||
if (cPlane == null) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -84,13 +84,6 @@ public class Turn implements Serializable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public PhaseStep getStepType() {
|
||||
if (currentPhase != null && currentPhase.getStep() != null) {
|
||||
return currentPhase.getStep().getType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param game
|
||||
* @param activePlayer
|
||||
|
|
@ -148,8 +141,8 @@ public class Turn implements Serializable {
|
|||
public void resumePlay(Game game, boolean wasPaused) {
|
||||
activePlayerId = game.getActivePlayerId();
|
||||
UUID priorityPlayerId = game.getPriorityPlayerId();
|
||||
TurnPhase phaseType = game.getPhase().getType();
|
||||
PhaseStep stepType = game.getStep().getType();
|
||||
TurnPhase phaseType = game.getTurnPhaseType();
|
||||
PhaseStep stepType = game.getTurnStepType();
|
||||
|
||||
Iterator<Phase> it = phases.iterator();
|
||||
Phase phase;
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ public class ManaPool implements Serializable {
|
|||
|
||||
private int emptyItem(ManaPoolItem item, Emptiable toEmpty, Game game, ManaType manaType) {
|
||||
if (item.getDuration() == Duration.EndOfTurn
|
||||
&& game.getPhase().getType() != TurnPhase.END) {
|
||||
&& game.getTurnPhaseType() != TurnPhase.END) {
|
||||
return 0;
|
||||
}
|
||||
if (!manaBecomesColorless) {
|
||||
|
|
|
|||
|
|
@ -2407,7 +2407,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
case PASS_PRIORITY_UNTIL_TURN_END_STEP: // F5
|
||||
resetPlayerPassedActions();
|
||||
passedUntilEndOfTurn = true;
|
||||
skippedAtLeastOnce = PhaseStep.END_TURN != game.getTurn().getStepType();
|
||||
skippedAtLeastOnce = PhaseStep.END_TURN != game.getTurnStepType();
|
||||
this.skip();
|
||||
break;
|
||||
case PASS_PRIORITY_UNTIL_NEXT_TURN: // F4
|
||||
|
|
@ -2423,8 +2423,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
case PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE: //F7
|
||||
resetPlayerPassedActions();
|
||||
passedUntilNextMain = true;
|
||||
skippedAtLeastOnce = !(game.getTurn().getStepType() == PhaseStep.POSTCOMBAT_MAIN
|
||||
|| game.getTurn().getStepType() == PhaseStep.PRECOMBAT_MAIN);
|
||||
skippedAtLeastOnce = !(game.getTurnStepType() == PhaseStep.POSTCOMBAT_MAIN
|
||||
|| game.getTurnStepType() == PhaseStep.PRECOMBAT_MAIN);
|
||||
this.skip();
|
||||
break;
|
||||
case PASS_PRIORITY_UNTIL_STACK_RESOLVED: // Default F10 - Skips until the current stack is resolved
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue