mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28: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)) {
|
if (handlePlaneswalkerRule(p, noRegCreats)) {
|
||||||
checkAgain = true;
|
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("Battle cry") || keyword.equals("Devoid") || keyword.equals("Riot")
|
||||||
|| keyword.equals("Daybound") || keyword.equals("Nightbound")
|
|| keyword.equals("Daybound") || keyword.equals("Nightbound")
|
||||||
|| keyword.equals("Friends forever") || keyword.equals("Choose a Background")
|
|| 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(")");
|
sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")");
|
||||||
} else if (keyword.startsWith("Partner:")) {
|
} else if (keyword.startsWith("Partner:")) {
|
||||||
final String[] k = keyword.split(":");
|
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("Class") || keyword.startsWith("Blitz")
|
||||||
|| keyword.startsWith("Specialize") || keyword.equals("Ravenous")
|
|| keyword.startsWith("Specialize") || keyword.equals("Ravenous")
|
||||||
|| keyword.equals("For Mirrodin") || keyword.startsWith("Craft")
|
|| keyword.equals("For Mirrodin") || keyword.startsWith("Craft")
|
||||||
|| keyword.startsWith("Landwalk") || keyword.startsWith("Visit")
|
|| keyword.startsWith("Landwalk") || keyword.startsWith("Visit")) {
|
||||||
|| keyword.equals("Start your engines")) {
|
|
||||||
// keyword parsing takes care of adding a proper description
|
// keyword parsing takes care of adding a proper description
|
||||||
} else if (keyword.equals("Read ahead")) {
|
} else if (keyword.equals("Read ahead")) {
|
||||||
sb.append(Localizer.getInstance().getMessage("lblReadAhead")).append(" (").append(Localizer.getInstance().getMessage("lblReadAheadDesc"));
|
sb.append(Localizer.getInstance().getMessage("lblReadAhead")).append(" (").append(Localizer.getInstance().getMessage("lblReadAheadDesc"));
|
||||||
|
|||||||
@@ -1835,15 +1835,6 @@ public class CardFactoryUtil {
|
|||||||
squadTrigger.setOverridingAbility(squadAbility);
|
squadTrigger.setOverridingAbility(squadAbility);
|
||||||
squadTrigger.setSVar("SquadAmount", "Count$OptionalKeywordAmount");
|
squadTrigger.setSVar("SquadAmount", "Count$OptionalKeywordAmount");
|
||||||
inst.addTrigger(squadTrigger);
|
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")) {
|
} else if (keyword.equals("Storm")) {
|
||||||
final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | TriggerZones$ Stack | Secondary$ True"
|
final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | TriggerZones$ Stack | Secondary$ True"
|
||||||
+ "| TriggerDescription$ Storm (" + inst.getReminderText() + ")";
|
+ "| 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(GameEventRollDie event);
|
||||||
T visit(GameEventScry event);
|
T visit(GameEventScry event);
|
||||||
T visit(GameEventShuffle event);
|
T visit(GameEventShuffle event);
|
||||||
T visit(GameEventSpeedUp event);
|
T visit(GameEventSpeedChanged event);
|
||||||
T visit(GameEventSpellAbilityCast event);
|
T visit(GameEventSpellAbilityCast event);
|
||||||
T visit(GameEventSpellResolved event);
|
T visit(GameEventSpellResolved event);
|
||||||
T visit(GameEventSpellRemovedFromStack event);
|
T visit(GameEventSpellRemovedFromStack event);
|
||||||
@@ -101,7 +101,7 @@ public interface IGameEventVisitor<T> {
|
|||||||
public T visit(GameEventRollDie event) { return null; }
|
public T visit(GameEventRollDie event) { return null; }
|
||||||
public T visit(GameEventScry event) { return null; }
|
public T visit(GameEventScry event) { return null; }
|
||||||
public T visit(GameEventShuffle 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(GameEventSpellResolved event) { return null; }
|
||||||
public T visit(GameEventSpellAbilityCast event) { return null; }
|
public T visit(GameEventSpellAbilityCast event) { return null; }
|
||||||
public T visit(GameEventSpellRemovedFromStack 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() {
|
public final void increaseSpeed() {
|
||||||
if (speedEffect == null) createSpeedEffect();
|
if (speedEffect == null) createSpeedEffect();
|
||||||
if (!maxSpeed()) { // can't increase past 4
|
if (!maxSpeed()) { // can't increase past 4
|
||||||
|
int old = speed;
|
||||||
speed++;
|
speed++;
|
||||||
view.updateSpeed(this);
|
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() {
|
public final void decreaseSpeed() {
|
||||||
if (speed > 1) { // can't decrease speed below 1
|
if (speed > 1) { // can't decrease speed below 1
|
||||||
|
int old = speed;
|
||||||
speed--;
|
speed--;
|
||||||
view.updateSpeed(this);
|
view.updateSpeed(this);
|
||||||
getGame().fireEvent(new GameEventPlayerStatsChanged(this, false));
|
game.fireEvent(new GameEventSpeedChanged(this, old, speed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public final boolean noSpeed() {
|
public final boolean noSpeed() {
|
||||||
@@ -1998,9 +2000,11 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
public final void createSpeedEffect() {
|
public final void createSpeedEffect() {
|
||||||
final PlayerZone com = getZone(ZoneType.Command);
|
final PlayerZone com = getZone(ZoneType.Command);
|
||||||
DetachedCardEffect eff = new DetachedCardEffect(this, "Speed Effect");
|
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 | "
|
"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";
|
String speedUp = "DB$ ChangeSpeed";
|
||||||
Trigger lifeLostTrigger = TriggerHandler.parseTrigger(trigger, eff, true);
|
Trigger lifeLostTrigger = TriggerHandler.parseTrigger(trigger, eff, true);
|
||||||
lifeLostTrigger.setOverridingAbility(AbilityFactory.getAbility(speedUp, eff));
|
lifeLostTrigger.setOverridingAbility(AbilityFactory.getAbility(speedUp, eff));
|
||||||
|
|||||||
@@ -451,7 +451,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
|||||||
return processCards(cards, cardsRefreshDetails);
|
return processCards(cards, cardsRefreshDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Void visit(final GameEventSpeedUp event) {
|
public Void visit(final GameEventSpeedChanged event) {
|
||||||
Player p = event.player;
|
Player p = event.player;
|
||||||
processPlayer(p, livesUpdate);
|
processPlayer(p, livesUpdate);
|
||||||
return processEvent();
|
return processEvent();
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ public class EventVisualizer extends IGameEventVisitor.Base<SoundEffectType> imp
|
|||||||
@Override
|
@Override
|
||||||
public SoundEffectType visit(final GameEventShuffle event) { return SoundEffectType.Shuffle; }
|
public SoundEffectType visit(final GameEventShuffle event) { return SoundEffectType.Shuffle; }
|
||||||
@Override
|
@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
|
@Override
|
||||||
public SoundEffectType visit(final GameEventTokenCreated event) { return SoundEffectType.Token; }
|
public SoundEffectType visit(final GameEventTokenCreated event) { return SoundEffectType.Token; }
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user