diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index b3335d35ea9..f68164f7335 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -75,11 +75,13 @@ public class Game { private List activePlanes = null; - public final Phase cleanup; - public final Phase endOfCombat; - public final Phase endOfTurn; public final Untap untap; public final Phase upkeep; + public final Phase beginOfCombat; + public final Phase endOfCombat; + public final Phase endOfTurn; + public final Phase cleanup; + // to execute commands for "current" phase each time state based action is checked public final List sbaCheckedCommandList; public final MagicStack stack; @@ -363,9 +365,10 @@ public class Game { untap = new Untap(this); upkeep = new Phase(PhaseType.UPKEEP); - cleanup = new Phase(PhaseType.CLEANUP); + beginOfCombat = new Phase(PhaseType.COMBAT_BEGIN); endOfCombat = new Phase(PhaseType.COMBAT_END); endOfTurn = new Phase(PhaseType.END_OF_TURN); + cleanup = new Phase(PhaseType.CLEANUP); sbaCheckedCommandList = new ArrayList<>(); @@ -428,6 +431,9 @@ public class Game { public final Phase getUpkeep() { return upkeep; } + public final Phase getBeginOfCombat() { + return beginOfCombat; + } public final Phase getEndOfCombat() { return endOfCombat; } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlPlayerEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlPlayerEffect.java index 790568d7f94..56ef3240554 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlPlayerEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlPlayerEffect.java @@ -2,7 +2,6 @@ package forge.game.ability.effects; import java.util.List; -import forge.GameCommand; import forge.game.Game; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; @@ -28,10 +27,11 @@ public class ControlPlayerEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Player controller = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Controller"), sa).get(0); final Game game = controller.getGame(); + final boolean combat = sa.hasParam("Combat"); for (final Player pTarget: getTargetPlayers(sa)) { // before next untap gain control - game.getCleanup().addUntil(pTarget, (GameCommand) () -> { + (combat ? game.getBeginOfCombat() : game.getCleanup()).addUntil(pTarget, () -> { // CR 800.4b if (!controller.isInGame()) { return; @@ -41,7 +41,7 @@ public class ControlPlayerEffect extends SpellAbilityEffect { pTarget.addController(ts, controller); // after following cleanup release control - game.getCleanup().addUntil((GameCommand) () -> pTarget.removeController(ts)); + (combat ? game.getEndOfCombat() : game.getCleanup()).addUntil(() -> pTarget.removeController(ts)); }); } } diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index 8678a8a635b..f6e7ae1a67a 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -297,6 +297,7 @@ public class PhaseHandler implements java.io.Serializable { case COMBAT_BEGIN: nCombatsThisTurn++; combat = new Combat(playerTurn); + game.getBeginOfCombat().executeUntil(playerTurn); //PhaseUtil.verifyCombat(); break; @@ -756,7 +757,6 @@ public class PhaseHandler implements java.io.Serializable { } } } - // fire blockers declared trigger final Map bdRunParams = AbilityKey.newMap(); bdRunParams.put(AbilityKey.Blockers, declaredBlockers); bdRunParams.put(AbilityKey.Attackers, blockedAttackers); @@ -768,7 +768,6 @@ public class PhaseHandler implements java.io.Serializable { continue; } - // Run triggers final Map runParams = AbilityKey.newMap(); runParams.put(AbilityKey.Blocker, c1); runParams.put(AbilityKey.Attackers, combat.getAttackersBlockedBy(c1)); diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index c4010f3521b..e055aef9991 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -428,7 +428,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable | Description$ As an additional cost to cast this spell, you may waterbend {10}. +A:SP$ ControlPlayer | ValidTgts$ Opponent | Condition$ OptionalCost | ConditionOptionalPaid$ False | Combat$ True | SubAbility$ ControlTurn | SpellDescription$ You control target opponent during their next combat phase. If this spell’s additional cost was paid, you control that player during their next turn instead. Exile CARDNAME. +SVar:ControlTurn:DB$ ControlPlayer | Defined$ Targeted | Condition$ OptionalCost | ConditionOptionalPaid$ True | SubAbility$ DBExile +SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Stack | Destination$ Exile +SVar:X:Count$xPaid +Oracle:As an additional cost to cast this spell, you may waterbend {10}.\nYou control target opponent during their next combat phase. If this spell’s additional cost was paid, you control that player during their next turn instead. (You see all cards that player could see and make all decisions for them.)\nExile Secret of Bloodbending. diff --git a/forge-gui/res/cardsfolder/upcoming/teo_spirited_glider.txt b/forge-gui/res/cardsfolder/upcoming/teo_spirited_glider.txt index ec39bb63949..960cce1ebc5 100644 --- a/forge-gui/res/cardsfolder/upcoming/teo_spirited_glider.txt +++ b/forge-gui/res/cardsfolder/upcoming/teo_spirited_glider.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Human Pilot Ally PT:1/4 K:Flying T:Mode$ AttackersDeclared | AttackingPlayer$ You | ValidAttackers$ Creature.withFlying | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever one or more creatures you control with flying attack, draw a card, then discard a card. When you discard a nonland card this way, put a +1/+1 counter on target creature you control. -SVar:DBDraw:DB$ Draw | SubAbility$ DBDiscard | SpellDescription$ Draw a card, then discard a card. +SVar:TrigDraw:DB$ Draw | SubAbility$ DBDiscard SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBImmediateTrig SVar:DBImmediateTrig:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | ConditionCompare$ GE1 | Execute$ TrigPutCounter | SubAbility$ DBCleanup | SpellDescription$ When you discard a nonland card this way, put a +1/+1 counter on target creature you control. SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 1