mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Start your Engines as StaticAction (#6987)
* Start your Engines as StaticAction * ~ fix trigger desc * ~ moved keyword to better place
This commit is contained in:
@@ -1560,6 +1560,12 @@ public class GameAction {
|
||||
}
|
||||
}
|
||||
|
||||
// 704.5z If a player controls a permanent with start your engines! and that player has no speed, that player’s speed becomes 1. See rule 702.179, “Start Your Engines!”
|
||||
if (p.getSpeed() == 0 && p.getCardsIn(ZoneType.Battlefield).anyMatch(c -> c.hasKeyword(Keyword.START_YOUR_ENGINES))) {
|
||||
p.increaseSpeed();
|
||||
checkAgain = true;
|
||||
}
|
||||
|
||||
if (handlePlaneswalkerRule(p, noRegCreats)) {
|
||||
checkAgain = true;
|
||||
}
|
||||
|
||||
@@ -2550,7 +2550,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
|| keyword.equals("Battle cry") || keyword.equals("Devoid") || keyword.equals("Riot")
|
||||
|| keyword.equals("Daybound") || keyword.equals("Nightbound")
|
||||
|| keyword.equals("Friends forever") || keyword.equals("Choose a Background")
|
||||
|| keyword.equals("Space sculptor") || keyword.equals("Doctor's companion")) {
|
||||
|| keyword.equals("Space sculptor") || keyword.equals("Doctor's companion")
|
||||
|| keyword.equals("Start your engines")) {
|
||||
sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")");
|
||||
} else if (keyword.startsWith("Partner:")) {
|
||||
final String[] k = keyword.split(":");
|
||||
@@ -2706,8 +2707,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
|| keyword.startsWith("Class") || keyword.startsWith("Blitz")
|
||||
|| keyword.startsWith("Specialize") || keyword.equals("Ravenous")
|
||||
|| keyword.equals("For Mirrodin") || keyword.startsWith("Craft")
|
||||
|| keyword.startsWith("Landwalk") || keyword.startsWith("Visit")
|
||||
|| keyword.equals("Start your engines")) {
|
||||
|| keyword.startsWith("Landwalk") || keyword.startsWith("Visit")) {
|
||||
// keyword parsing takes care of adding a proper description
|
||||
} else if (keyword.equals("Read ahead")) {
|
||||
sb.append(Localizer.getInstance().getMessage("lblReadAhead")).append(" (").append(Localizer.getInstance().getMessage("lblReadAheadDesc"));
|
||||
|
||||
@@ -1835,15 +1835,6 @@ public class CardFactoryUtil {
|
||||
squadTrigger.setOverridingAbility(squadAbility);
|
||||
squadTrigger.setSVar("SquadAmount", "Count$OptionalKeywordAmount");
|
||||
inst.addTrigger(squadTrigger);
|
||||
} else if (keyword.equals("Start your engines")) {
|
||||
final String trig = "Mode$ Always | TriggerZones$ Battlefield | Static$ True | CheckDefinedPlayer$ " +
|
||||
"You.NoSpeed | TriggerDescription$ Start your engines! (" + inst.getReminderText() + ")";
|
||||
final String effect = "DB$ ChangeSpeed";
|
||||
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trig, card, intrinsic);
|
||||
trigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
||||
|
||||
inst.addTrigger(trigger);
|
||||
} else if (keyword.equals("Storm")) {
|
||||
final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | TriggerZones$ Stack | Secondary$ True"
|
||||
+ "| TriggerDescription$ Storm (" + inst.getReminderText() + ")";
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package forge.game.event;
|
||||
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class GameEventSpeedChanged extends GameEvent {
|
||||
|
||||
public final Player player;
|
||||
public final int oldValue;
|
||||
public final int newValue;
|
||||
|
||||
public GameEventSpeedChanged(Player affected, int oldValue, int newValue) {
|
||||
player = affected;
|
||||
this.oldValue = oldValue;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package forge.game.event;
|
||||
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class GameEventSpeedUp extends GameEvent {
|
||||
|
||||
public final Player player;
|
||||
|
||||
public GameEventSpeedUp(Player affected) {
|
||||
player = affected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public interface IGameEventVisitor<T> {
|
||||
T visit(GameEventRollDie event);
|
||||
T visit(GameEventScry event);
|
||||
T visit(GameEventShuffle event);
|
||||
T visit(GameEventSpeedUp event);
|
||||
T visit(GameEventSpeedChanged event);
|
||||
T visit(GameEventSpellAbilityCast event);
|
||||
T visit(GameEventSpellResolved event);
|
||||
T visit(GameEventSpellRemovedFromStack event);
|
||||
@@ -101,7 +101,7 @@ public interface IGameEventVisitor<T> {
|
||||
public T visit(GameEventRollDie event) { return null; }
|
||||
public T visit(GameEventScry event) { return null; }
|
||||
public T visit(GameEventShuffle event) { return null; }
|
||||
public T visit(GameEventSpeedUp event) { return null; }
|
||||
public T visit(GameEventSpeedChanged event) { return null; }
|
||||
public T visit(GameEventSpellResolved event) { return null; }
|
||||
public T visit(GameEventSpellAbilityCast event) { return null; }
|
||||
public T visit(GameEventSpellRemovedFromStack event) { return null; }
|
||||
|
||||
@@ -1973,16 +1973,18 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
public final void increaseSpeed() {
|
||||
if (speedEffect == null) createSpeedEffect();
|
||||
if (!maxSpeed()) { // can't increase past 4
|
||||
int old = speed;
|
||||
speed++;
|
||||
view.updateSpeed(this);
|
||||
game.fireEvent(new GameEventSpeedUp(this)); //play sound effect
|
||||
getGame().fireEvent(new GameEventSpeedChanged(this, old, speed)); //play sound effect
|
||||
}
|
||||
}
|
||||
public final void decreaseSpeed() {
|
||||
if (speed > 1) { // can't decrease speed below 1
|
||||
int old = speed;
|
||||
speed--;
|
||||
view.updateSpeed(this);
|
||||
getGame().fireEvent(new GameEventPlayerStatsChanged(this, false));
|
||||
game.fireEvent(new GameEventSpeedChanged(this, old, speed));
|
||||
}
|
||||
}
|
||||
public final boolean noSpeed() {
|
||||
@@ -1998,9 +2000,11 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
public final void createSpeedEffect() {
|
||||
final PlayerZone com = getZone(ZoneType.Command);
|
||||
DetachedCardEffect eff = new DetachedCardEffect(this, "Speed Effect");
|
||||
String trigger = "Mode$ LifeLost | ValidPlayer$ Opponent | TriggerZones$ Command | ActivationLimit$ 1 | " +
|
||||
// 702.179d There is an inherent triggered ability associated with a player having 1 or more speed. This ability has no source and is controlled by that player.
|
||||
// That ability is “Whenever one or more opponents lose life during your turn, if your speed is less than 4, your speed increases by 1. This ability triggers only once each turn.”
|
||||
String trigger = "Mode$ LifeLostAll | ValidPlayer$ Opponent | TriggerZones$ Command | ActivationLimit$ 1 | " +
|
||||
"PlayerTurn$ True | CheckSVar$ Count$YourSpeed | SVarCompare$ LT4 | "
|
||||
+ "TriggerDescription$ Your speed increases once on each of your turns when an opponent loses life.";
|
||||
+ "TriggerDescription$ Whenever one or more opponents lose life during your turn, if your speed is less than 4, your speed increases by 1. This ability triggers only once each turn.";
|
||||
String speedUp = "DB$ ChangeSpeed";
|
||||
Trigger lifeLostTrigger = TriggerHandler.parseTrigger(trigger, eff, true);
|
||||
lifeLostTrigger.setOverridingAbility(AbilityFactory.getAbility(speedUp, eff));
|
||||
|
||||
@@ -451,7 +451,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return processCards(cards, cardsRefreshDetails);
|
||||
}
|
||||
|
||||
public Void visit(final GameEventSpeedUp event) {
|
||||
public Void visit(final GameEventSpeedChanged event) {
|
||||
Player p = event.player;
|
||||
processPlayer(p, livesUpdate);
|
||||
return processEvent();
|
||||
|
||||
@@ -80,7 +80,7 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventShuffle event) { return SoundEffectType.Shuffle; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventSpeedUp event) { return SoundEffectType.SpeedUp; }
|
||||
public SoundEffectType visit(final GameEventSpeedChanged event) { return event.newValue > event.oldValue ? SoundEffectType.SpeedUp : null; }
|
||||
@Override
|
||||
public SoundEffectType visit(final GameEventTokenCreated event) { return SoundEffectType.Token; }
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user