mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
Update Skyshroud Ambush implementation
This commit is contained in:
@@ -39,6 +39,7 @@ import com.google.common.collect.Multimap;
|
|||||||
import com.google.common.collect.Table;
|
import com.google.common.collect.Table;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
|
import forge.GameCommand;
|
||||||
import forge.card.CardRarity;
|
import forge.card.CardRarity;
|
||||||
import forge.card.CardStateName;
|
import forge.card.CardStateName;
|
||||||
import forge.card.CardType.Supertype;
|
import forge.card.CardType.Supertype;
|
||||||
@@ -99,6 +100,8 @@ public class Game {
|
|||||||
public final Phase endOfTurn;
|
public final Phase endOfTurn;
|
||||||
public final Untap untap;
|
public final Untap untap;
|
||||||
public final Phase upkeep;
|
public final Phase upkeep;
|
||||||
|
// to execute commands for "current" phase each time state based action is checked
|
||||||
|
public final List<GameCommand> sbaCheckedCommandList;
|
||||||
public final MagicStack stack;
|
public final MagicStack stack;
|
||||||
public final CostPaymentStack costPaymentStack = new CostPaymentStack();
|
public final CostPaymentStack costPaymentStack = new CostPaymentStack();
|
||||||
private final PhaseHandler phaseHandler;
|
private final PhaseHandler phaseHandler;
|
||||||
@@ -308,6 +311,8 @@ public class Game {
|
|||||||
endOfCombat = new Phase(PhaseType.COMBAT_END);
|
endOfCombat = new Phase(PhaseType.COMBAT_END);
|
||||||
endOfTurn = new Phase(PhaseType.END_OF_TURN);
|
endOfTurn = new Phase(PhaseType.END_OF_TURN);
|
||||||
|
|
||||||
|
sbaCheckedCommandList = new ArrayList<>();
|
||||||
|
|
||||||
// update players
|
// update players
|
||||||
view.updatePlayers(this);
|
view.updatePlayers(this);
|
||||||
|
|
||||||
@@ -382,6 +387,17 @@ public class Game {
|
|||||||
return cleanup;
|
return cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSBACheckedCommand(final GameCommand c) {
|
||||||
|
sbaCheckedCommandList.add(c);
|
||||||
|
}
|
||||||
|
public final void runSBACheckedCommands() {
|
||||||
|
for (final GameCommand c : sbaCheckedCommandList) {
|
||||||
|
c.run();
|
||||||
|
}
|
||||||
|
sbaCheckedCommandList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public final PhaseHandler getPhaseHandler() {
|
public final PhaseHandler getPhaseHandler() {
|
||||||
return phaseHandler;
|
return phaseHandler;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
|
||||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
@@ -1158,11 +1157,7 @@ public class GameAction {
|
|||||||
// sol(10/29) added for Phase updates, state effects shouldn't be
|
// sol(10/29) added for Phase updates, state effects shouldn't be
|
||||||
// checked during Spell Resolution (except when persist-returning
|
// checked during Spell Resolution (except when persist-returning
|
||||||
if (game.getStack().isResolving()) {
|
if (game.getStack().isResolving()) {
|
||||||
Iterator<SpellAbilityStackInstance> it = game.getStack().iterator();
|
return;
|
||||||
SpellAbility top = it.next().getSpellAbility(true);
|
|
||||||
if (!top.hasParam("CheckStates") && !top.getSubAbility().hasParam("CheckStates")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.isGameOver()) {
|
if (game.isGameOver()) {
|
||||||
@@ -1376,6 +1371,9 @@ public class GameAction {
|
|||||||
if (!refreeze) {
|
if (!refreeze) {
|
||||||
game.getStack().unfreezeStack();
|
game.getStack().unfreezeStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run all commands that are queued to run after state based actions are checked
|
||||||
|
game.runSBACheckedCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean stateBasedAction_Saga(Card c, CardZoneTable table) {
|
private boolean stateBasedAction_Saga(Card c, CardZoneTable table) {
|
||||||
|
|||||||
@@ -283,31 +283,24 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
if ((duration == null) || duration.equals("EndOfTurn")) {
|
if ((duration == null) || duration.equals("EndOfTurn")) {
|
||||||
game.getEndOfTurn().addUntil(endEffect);
|
game.getEndOfTurn().addUntil(endEffect);
|
||||||
}
|
} else if (duration.equals("UntilHostLeavesPlay")) {
|
||||||
else if (duration.equals("UntilHostLeavesPlay")) {
|
|
||||||
hostCard.addLeavesPlayCommand(endEffect);
|
hostCard.addLeavesPlayCommand(endEffect);
|
||||||
}
|
} else if (duration.equals("UntilHostLeavesPlayOrEOT")) {
|
||||||
else if (duration.equals("UntilHostLeavesPlayOrEOT")) {
|
|
||||||
game.getEndOfTurn().addUntil(endEffect);
|
game.getEndOfTurn().addUntil(endEffect);
|
||||||
hostCard.addLeavesPlayCommand(endEffect);
|
hostCard.addLeavesPlayCommand(endEffect);
|
||||||
}
|
} else if (duration.equals("UntilYourNextTurn")) {
|
||||||
else if (duration.equals("UntilYourNextTurn")) {
|
|
||||||
game.getCleanup().addUntil(controller, endEffect);
|
game.getCleanup().addUntil(controller, endEffect);
|
||||||
}
|
} else if (duration.equals("UntilYourNextUpkeep")) {
|
||||||
else if (duration.equals("UntilYourNextUpkeep")) {
|
|
||||||
game.getUpkeep().addUntil(controller, endEffect);
|
game.getUpkeep().addUntil(controller, endEffect);
|
||||||
}
|
} else if (duration.equals("UntilEndOfCombat")) {
|
||||||
else if (duration.equals("UntilEndOfCombat")) {
|
|
||||||
game.getEndOfCombat().addUntil(endEffect);
|
game.getEndOfCombat().addUntil(endEffect);
|
||||||
}
|
} else if (duration.equals("UntilTheEndOfYourNextTurn")) {
|
||||||
else if (duration.equals("UntilTheEndOfYourNextTurn")) {
|
|
||||||
if (game.getPhaseHandler().isPlayerTurn(controller)) {
|
if (game.getPhaseHandler().isPlayerTurn(controller)) {
|
||||||
game.getEndOfTurn().registerUntilEnd(controller, endEffect);
|
game.getEndOfTurn().registerUntilEnd(controller, endEffect);
|
||||||
} else {
|
} else {
|
||||||
game.getEndOfTurn().addUntilEnd(controller, endEffect);
|
game.getEndOfTurn().addUntilEnd(controller, endEffect);
|
||||||
}
|
}
|
||||||
}
|
} else if (duration.equals("ThisTurnAndNextTurn")) {
|
||||||
else if (duration.equals("ThisTurnAndNextTurn")) {
|
|
||||||
game.getUntap().addAt(new GameCommand() {
|
game.getUntap().addAt(new GameCommand() {
|
||||||
private static final long serialVersionUID = -5054153666503075717L;
|
private static final long serialVersionUID = -5054153666503075717L;
|
||||||
|
|
||||||
@@ -316,6 +309,8 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
game.getEndOfTurn().addUntil(endEffect);
|
game.getEndOfTurn().addUntil(endEffect);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (duration.equals("UntilStateBasedActionChecked")) {
|
||||||
|
game.addSBACheckedCommand(endEffect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import forge.game.player.Player;
|
|||||||
import forge.game.replacement.ReplacementType;
|
import forge.game.replacement.ReplacementType;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.trigger.TriggerType;
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
|
||||||
import forge.util.CardTranslation;
|
import forge.util.CardTranslation;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
@@ -78,24 +77,6 @@ public class FightEffect extends DamageBaseEffect {
|
|||||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
runParams.put(AbilityKey.Fighters, fighters);
|
runParams.put(AbilityKey.Fighters, fighters);
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.FightOnce, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.FightOnce, runParams, false);
|
||||||
|
|
||||||
if (sa.hasParam("ConditionWinnerDefined")) {
|
|
||||||
Card mustWin = AbilityUtils.getDefinedCards(host, sa.getParam("ConditionWinnerDefined"), sa).get(0);
|
|
||||||
Card mustLose = null;
|
|
||||||
for (Card l : fighters) {
|
|
||||||
if (l != mustWin) {
|
|
||||||
mustLose = l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
game.getAction().checkStateEffects(true);
|
|
||||||
SpellAbility sub = sa.getAdditionalAbility("WinSubAbility");
|
|
||||||
if (mustWin.getZone().getZoneType().equals(ZoneType.Battlefield) && mustLose != null &&
|
|
||||||
!mustLose.getZone().getZoneType().equals(ZoneType.Battlefield)) {
|
|
||||||
if (sub != null) {
|
|
||||||
AbilityUtils.resolve(sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Card> getFighters(SpellAbility sa) {
|
private static List<Card> getFighters(SpellAbility sa) {
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ Name:Skyshroud Ambush
|
|||||||
ManaCost:1 G
|
ManaCost:1 G
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Pump | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control | ImprintCards$ ThisTargetedCard | SubAbility$ DBFight | StackDescription$ Target creature you control [{c:ThisTargetedCard}] | SpellDescription$ Target creature you control fights target creature you don't control. When the creature you control wins the fight, draw a card.
|
A:SP$ Pump | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Choose target creature you control | ImprintCards$ ThisTargetedCard | SubAbility$ DBFight | StackDescription$ Target creature you control [{c:ThisTargetedCard}] | SpellDescription$ Target creature you control fights target creature you don't control. When the creature you control wins the fight, draw a card.
|
||||||
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Choose target creature you don't control | RememberObjects$ ThisTargetedCard | ConditionWinnerDefined$ Imprinted | WinSubAbility$ DBImmediateTrigger | CheckStates$ True | SubAbility$ DBCleanup | StackDescription$ fights target creature you don't control [{c:ThisTargetedCard}]. When the creature you control wins the fight, draw a card.
|
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Choose target creature you don't control | RememberObjects$ ThisTargetedCard | SubAbility$ DBEffect | StackDescription$ fights target creature you don't control [{c:ThisTargetedCard}]. When the creature you control wins the fight, draw a card.
|
||||||
SVar:DBImmediateTrigger:DB$ ImmediateTrigger | Execute$ TrigDraw | Secondary$ True | StackDescription$ None | TriggerDescription$ When the creature you control wins the fight, draw a card.
|
SVar:DBEffect:DB$ Effect | Triggers$ TrigWin | RememberObjects$ Remembered | ImprintCards$ Imprinted | Duration$ UntilStateBasedActionChecked | SubAbility$ DBCleanup
|
||||||
|
SVar:TrigWin:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Creature.IsRemembered | IsPresent$ Creature.IsImprinted | NoResolvingCheck$ True | Execute$ TrigDraw | TriggerDescription$ When the creature you control wins the fight, draw a card.
|
||||||
SVar:TrigDraw:DB$ Draw | NumCards$ 1
|
SVar:TrigDraw:DB$ Draw | NumCards$ 1
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
|
||||||
Oracle:Target creature you control fights target creature you don't control. When the creature you control wins the fight, draw a card.
|
Oracle:Target creature you control fights target creature you don't control. When the creature you control wins the fight, draw a card.
|
||||||
|
|||||||
Reference in New Issue
Block a user