mirror of
https://github.com/magefree/mage.git
synced 2025-12-30 07:22:03 -08:00
Implementing "Start your engines!" mechanic (#13259)
* add initial speed handling * finish speed implementation * remove skip list * add initial test * add some more tests * change speed initialization to state-based action * add opponent speed check * add control change test * add check for speed 5
This commit is contained in:
parent
655af10b2e
commit
ef213b1bef
11 changed files with 393 additions and 15 deletions
|
|
@ -4,15 +4,11 @@ import mage.cards.ExpansionSet;
|
|||
import mage.constants.Rarity;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class Aetherdrift extends ExpansionSet {
|
||||
|
||||
private static final List<String> unfinished = Arrays.asList("Aether Syphon", "Amonkhet Raceway", "Avishkar Raceway", "Burnout Bashtronaut", "Embalmed Ascendant", "Endrider Catalyzer", "Endrider Spikespitter", "Far Fortune, End Boss", "Gas Guzzler", "Gastal Raider", "Gastal Thrillseeker", "Glitch Ghost Surveyor", "Goblin Surveyor", "Hazoret, Godseeker", "Hour of Victory", "Howlsquad Heavy", "Kickoff Celebrations", "Leonin Surveyor", "Lightwheel Enhancements", "Loxodon Surveyor", "Mendicant Core, Guidelight", "Momentum Breaker", "Muraganda Raceway", "Mutant Surveyor", "Nesting Bot", "Outpace Oblivion", "Perilous Snare", "Point the Way", "Pride of the Road", "Racers' Scoreboard", "Risen Necroregent", "Samut, the Driving Force", "Slick Imitator", "Starting Column", "Streaking Oilgorger", "Swiftwing Assailant", "The Speed Demon", "Vnwxt, Verbose Host", "Walking Sarcophagus", "Zahur, Glory's Past");
|
||||
private static final Aetherdrift instance = new Aetherdrift();
|
||||
|
||||
public static Aetherdrift getInstance() {
|
||||
|
|
@ -211,7 +207,5 @@ public final class Aetherdrift extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Wreck Remover", 247, Rarity.COMMON, mage.cards.w.WreckRemover.class));
|
||||
cards.add(new SetCardInfo("Wreckage Wickerfolk", 110, Rarity.COMMON, mage.cards.w.WreckageWickerfolk.class));
|
||||
cards.add(new SetCardInfo("Wretched Doll", 111, Rarity.UNCOMMON, mage.cards.w.WretchedDoll.class));
|
||||
|
||||
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
package org.mage.test.cards.designations;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.players.Player;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class StartYourEnginesTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String sarcophagus = "Walking Sarcophagus";
|
||||
|
||||
private void assertSpeed(Player player, int speed) {
|
||||
Assert.assertEquals(player.getName() + " speed should be " + speed, speed, player.getSpeed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegular() {
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 0);
|
||||
assertSpeed(playerB, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpeed1() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 1);
|
||||
assertSpeed(playerB, 0);
|
||||
assertPowerToughness(playerA, sarcophagus, 2, 1);
|
||||
}
|
||||
|
||||
private static final String goblet = "Onyx Goblet";
|
||||
|
||||
@Test
|
||||
public void testSpeed2() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, goblet);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 2);
|
||||
assertSpeed(playerB, 0);
|
||||
assertPowerToughness(playerA, sarcophagus, 2, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpeed1OppTurn() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, goblet);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 1);
|
||||
assertSpeed(playerB, 0);
|
||||
assertPowerToughness(playerA, sarcophagus, 2, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpeed3() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, goblet);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 3);
|
||||
assertSpeed(playerB, 0);
|
||||
assertPowerToughness(playerA, sarcophagus, 2, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpeed4() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, goblet);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
activateAbility(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(5, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 4);
|
||||
assertSpeed(playerB, 0);
|
||||
assertPowerToughness(playerA, sarcophagus, 2 + 1, 1 + 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpeed5() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, goblet);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
activateAbility(5, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
activateAbility(7, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(7, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 4);
|
||||
assertSpeed(playerB, 0);
|
||||
assertPowerToughness(playerA, sarcophagus, 2 + 1, 1 + 2);
|
||||
}
|
||||
|
||||
private static final String surveyor = "Loxodon Surveyor";
|
||||
|
||||
@Test
|
||||
public void testSpeed4Graveyard() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 3);
|
||||
addCard(Zone.GRAVEYARD, playerA, surveyor);
|
||||
|
||||
runCode("Increase player speed", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
player.initSpeed(game);
|
||||
player.increaseSpeed(game);
|
||||
player.increaseSpeed(game);
|
||||
player.increaseSpeed(game);
|
||||
});
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 4);
|
||||
assertSpeed(playerB, 0);
|
||||
assertGraveyardCount(playerA, surveyor, 0);
|
||||
assertExileCount(playerA, surveyor, 1);
|
||||
}
|
||||
|
||||
private static final String mindControl = "Mind Control";
|
||||
|
||||
@Test
|
||||
public void testSpeedChangeControl() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 5);
|
||||
addCard(Zone.HAND, playerA, sarcophagus);
|
||||
addCard(Zone.HAND, playerB, mindControl);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sarcophagus);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, mindControl, sarcophagus);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSpeed(playerA, 1);
|
||||
assertSpeed(playerB, 1);
|
||||
assertPowerToughness(playerB, sarcophagus, 2, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -3977,6 +3977,21 @@ public class TestPlayer implements Player {
|
|||
return computerPlayer.isDrawsOnOpponentsTurn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpeed() {
|
||||
return computerPlayer.getSpeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSpeed(Game game) {
|
||||
computerPlayer.initSpeed(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseSpeed(Game game) {
|
||||
computerPlayer.increaseSpeed(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPayManaMode(boolean payManaMode) {
|
||||
computerPlayer.setPayManaMode(payManaMode);
|
||||
|
|
|
|||
|
|
@ -38,9 +38,21 @@ class MaxSpeedAbilityEffect extends ContinuousEffectImpl {
|
|||
|
||||
private final Ability ability;
|
||||
|
||||
private static Duration getDuration(Ability ability) {
|
||||
switch (ability.getZone()) {
|
||||
case BATTLEFIELD:
|
||||
return Duration.WhileOnBattlefield;
|
||||
case GRAVEYARD:
|
||||
return Duration.WhileInGraveyard;
|
||||
default:
|
||||
return Duration.Custom;
|
||||
}
|
||||
}
|
||||
|
||||
MaxSpeedAbilityEffect(Ability ability) {
|
||||
super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||
super(getDuration(ability), Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||
this.ability = ability;
|
||||
this.ability.setRuleVisible(false);
|
||||
}
|
||||
|
||||
private MaxSpeedAbilityEffect(final MaxSpeedAbilityEffect effect) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
|
|
@ -13,8 +16,10 @@ public enum ControllerSpeedCount implements DynamicValue {
|
|||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
// TODO: Implement this
|
||||
return 0;
|
||||
return Optional
|
||||
.ofNullable(game.getPlayer(sourceAbility.getControllerId()))
|
||||
.map(Player::getSpeed)
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.dynamicvalue.common.ControllerSpeedCount;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
* TODO: Implement this
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class StartYourEnginesAbility extends StaticAbility {
|
||||
|
||||
private static final Hint hint = new ValueHint("Your current speed", ControllerSpeedCount.instance);
|
||||
|
||||
public StartYourEnginesAbility() {
|
||||
super(Zone.BATTLEFIELD, null);
|
||||
this.addHint(hint);
|
||||
}
|
||||
|
||||
private StartYourEnginesAbility(final StartYourEnginesAbility ability) {
|
||||
|
|
@ -25,6 +29,6 @@ public class StartYourEnginesAbility extends StaticAbility {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Start your engines!";
|
||||
return "start your engines!";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ package mage.designations;
|
|||
public enum DesignationType {
|
||||
THE_MONARCH("The Monarch"), // global
|
||||
CITYS_BLESSING("City's Blessing"), // per player
|
||||
THE_INITIATIVE("The Initiative"); // global
|
||||
|
||||
THE_INITIATIVE("The Initiative"), // global
|
||||
SPEED("Speed"); // per player
|
||||
private final String text;
|
||||
|
||||
DesignationType(String text) {
|
||||
|
|
@ -18,5 +18,4 @@ public enum DesignationType {
|
|||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
108
Mage/src/main/java/mage/designations/Speed.java
Normal file
108
Mage/src/main/java/mage/designations/Speed.java
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
package mage.designations;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class Speed extends Designation {
|
||||
|
||||
public Speed() {
|
||||
super(DesignationType.SPEED);
|
||||
addAbility(new SpeedTriggeredAbility());
|
||||
}
|
||||
|
||||
private Speed(final Speed card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed copy() {
|
||||
return new Speed(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SpeedTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
SpeedTriggeredAbility() {
|
||||
super(Zone.ALL, new SpeedEffect());
|
||||
setTriggersLimitEachTurn(1);
|
||||
}
|
||||
|
||||
private SpeedTriggeredAbility(final SpeedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedTriggeredAbility copy() {
|
||||
return new SpeedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.LOST_LIFE_BATCH_FOR_ONE_PLAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return game.isActivePlayer(getControllerId())
|
||||
&& game
|
||||
.getOpponents(getControllerId())
|
||||
.contains(event.getTargetId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkInterveningIfClause(Game game) {
|
||||
return Optional
|
||||
.ofNullable(getControllerId())
|
||||
.map(game::getPlayer)
|
||||
.map(Player::getSpeed)
|
||||
.map(x -> x < 4)
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever one or more opponents lose life during your turn, if your speed is less than 4, " +
|
||||
"increase your speed by 1. This ability triggers only once each turn.";
|
||||
}
|
||||
}
|
||||
|
||||
class SpeedEffect extends OneShotEffect {
|
||||
|
||||
SpeedEffect() {
|
||||
super(Outcome.Benefit);
|
||||
}
|
||||
|
||||
private SpeedEffect(final SpeedEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedEffect copy() {
|
||||
return new SpeedEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Optional.ofNullable(source.getControllerId())
|
||||
.map(game::getPlayer)
|
||||
.ifPresent(player -> player.increaseSpeed(game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -2862,6 +2862,11 @@ public abstract class GameImpl implements Game {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (perm.getAbilities(this).containsClass(StartYourEnginesAbility.class)) {
|
||||
Optional.ofNullable(perm.getControllerId())
|
||||
.map(this::getPlayer)
|
||||
.ifPresent(player -> player.initSpeed(this));
|
||||
}
|
||||
}
|
||||
//201300713 - 704.5k
|
||||
// If a player controls two or more legendary permanents with the same name, that player
|
||||
|
|
|
|||
|
|
@ -216,6 +216,12 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
|
||||
boolean isDrawsOnOpponentsTurn();
|
||||
|
||||
int getSpeed();
|
||||
|
||||
void initSpeed(Game game);
|
||||
|
||||
void increaseSpeed(Game game);
|
||||
|
||||
/**
|
||||
* Returns alternative casting costs a player can cast spells for
|
||||
*
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import mage.counters.CounterType;
|
|||
import mage.counters.Counters;
|
||||
import mage.designations.Designation;
|
||||
import mage.designations.DesignationType;
|
||||
import mage.designations.Speed;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.filter.FilterPermanent;
|
||||
|
|
@ -153,6 +154,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
protected boolean canPlotFromTopOfLibrary = false;
|
||||
protected boolean drawsFromBottom = false;
|
||||
protected boolean drawsOnOpponentsTurn = false;
|
||||
protected int speed = 0;
|
||||
|
||||
protected FilterPermanent sacrificeCostFilter;
|
||||
protected List<AlternativeSourceCosts> alternativeSourceCosts = new ArrayList<>();
|
||||
|
|
@ -252,6 +254,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.canPlotFromTopOfLibrary = player.canPlotFromTopOfLibrary;
|
||||
this.drawsFromBottom = player.drawsFromBottom;
|
||||
this.drawsOnOpponentsTurn = player.drawsOnOpponentsTurn;
|
||||
this.speed = player.speed;
|
||||
|
||||
this.attachments.addAll(player.attachments);
|
||||
|
||||
|
|
@ -367,6 +370,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.drawsFromBottom = player.isDrawsFromBottom();
|
||||
this.drawsOnOpponentsTurn = player.isDrawsOnOpponentsTurn();
|
||||
this.alternativeSourceCosts = CardUtil.deepCopyObject(((PlayerImpl) player).alternativeSourceCosts);
|
||||
this.speed = player.getSpeed();
|
||||
|
||||
this.topCardRevealed = player.isTopCardRevealed();
|
||||
|
||||
|
|
@ -480,6 +484,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.canPlotFromTopOfLibrary = false;
|
||||
this.drawsFromBottom = false;
|
||||
this.drawsOnOpponentsTurn = false;
|
||||
this.speed = 0;
|
||||
|
||||
this.sacrificeCostFilter = null;
|
||||
this.alternativeSourceCosts.clear();
|
||||
|
|
@ -4674,6 +4679,29 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return drawsOnOpponentsTurn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSpeed(Game game) {
|
||||
if (speed > 0) {
|
||||
return;
|
||||
}
|
||||
speed = 1;
|
||||
game.getState().addDesignation(new Speed(), game, getId());
|
||||
game.informPlayers(this.getLogName() + "'s speed is now 1.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseSpeed(Game game) {
|
||||
if (speed < 4) {
|
||||
speed++;
|
||||
game.informPlayers(this.getLogName() + "'s speed has increased to " + speed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoLoseGame() {
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue