mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
- Temporarily reverted 30117:30118 (related to Echo update) because the current new implementation misbehaves (please see the related forum post) and I could not fix the rule interaction bug in a timely manner.
- Feel free to revert this commit and continue working on the new Echo implementation.
This commit is contained in:
@@ -165,7 +165,7 @@ public class CreatureEvaluator implements Function<Card, Integer> {
|
||||
value -= subValue(30, "cupkeep");
|
||||
} else if (c.hasStartOfKeyword("At the beginning of your upkeep, sacrifice CARDNAME unless you pay")) {
|
||||
value -= subValue(20, "sac-unless");
|
||||
} else if (c.hasStartOfKeyword("Echo") && c.cameUnderControlSinceLastUpkeep()) {
|
||||
} else if (c.hasStartOfKeyword("(Echo unpaid)")) {
|
||||
value -= subValue(10, "echo-unpaid");
|
||||
}
|
||||
|
||||
|
||||
@@ -471,6 +471,9 @@ public class GameAction {
|
||||
oldBattlefield.remove(c);
|
||||
newBattlefield.add(c);
|
||||
c.setSickness(true);
|
||||
if (c.hasStartOfKeyword("Echo")) {
|
||||
c.addExtrinsicKeyword("(Echo unpaid)");
|
||||
}
|
||||
if (game.getPhaseHandler().inCombat()) {
|
||||
game.getCombat().removeFromCombat(c);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private boolean drawnThisTurn = false;
|
||||
private boolean becameTargetThisTurn = false;
|
||||
private boolean startedTheTurnUntapped = false;
|
||||
private boolean underControlSinceLastUpkeep = true; // for Echo
|
||||
private boolean tapped = false;
|
||||
private boolean sickness = true; // summoning sickness
|
||||
private boolean token = false;
|
||||
@@ -207,6 +206,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private NavigableMap<Long, Player> tempControllers = new TreeMap<>();
|
||||
|
||||
private String originalText = "", text = "";
|
||||
private String echoCost = "";
|
||||
private Cost miracleCost = null;
|
||||
private String chosenType = "";
|
||||
private List<String> chosenColors;
|
||||
@@ -1101,6 +1101,14 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
turnInZone = turn;
|
||||
}
|
||||
|
||||
public final void setEchoCost(final String s) {
|
||||
echoCost = s;
|
||||
}
|
||||
|
||||
public final String getEchoCost() {
|
||||
return echoCost;
|
||||
}
|
||||
|
||||
public final void setManaCost(final ManaCost s) {
|
||||
currentState.setManaCost(s);
|
||||
}
|
||||
@@ -2150,14 +2158,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public void setStartedTheTurnUntapped(boolean untapped) {
|
||||
startedTheTurnUntapped = untapped;
|
||||
}
|
||||
|
||||
public boolean cameUnderControlSinceLastUpkeep() {
|
||||
return underControlSinceLastUpkeep;
|
||||
}
|
||||
|
||||
public void setUnderControlSinceLastUpkeep(boolean underControlSinceLastUpkeep) {
|
||||
this.underControlSinceLastUpkeep = underControlSinceLastUpkeep;
|
||||
}
|
||||
|
||||
public final Player getOwner() {
|
||||
return owner;
|
||||
@@ -4616,10 +4616,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
if (!hasStartedTheTurnUntapped()) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("cameUnderControlSinceLastUpkeep")) {
|
||||
if (!cameUnderControlSinceLastUpkeep()) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("attackedOrBlockedSinceYourLastUpkeep")) {
|
||||
if (!getDamageHistory().hasAttackedSinceLastUpkeepOf(sourceController)
|
||||
&& !getDamageHistory().hasBlockedSinceLastUpkeepOf(sourceController)) {
|
||||
|
||||
@@ -2306,18 +2306,19 @@ public class CardFactoryUtil {
|
||||
else if (keyword.startsWith("Echo")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String manacost = k[1];
|
||||
|
||||
String upkeepTrig = "Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield " +
|
||||
" | Execute$ TrigUpkeepEcho | IsPresent$ Card.Self+cameUnderControlSinceLastUpkeep | Secondary$ True | " +
|
||||
"TriggerDescription$ Echo: At the beginning of your upkeep, if CARDNAME came under your control since the " +
|
||||
"beginning of your last upkeep, sacrifice it unless you pay the Echo cost";
|
||||
|
||||
String ref = "X".equals(manacost) ? " | References$ X" : "";
|
||||
card.setSVar("TrigUpkeepEcho", "AB$ Sacrifice | Cost$ 0 | SacValid$ Self | "
|
||||
+ "Echo$ " + manacost + ref);
|
||||
card.setEchoCost(manacost);
|
||||
|
||||
final Trigger parsedUpkeepTrig = TriggerHandler.parseTrigger(upkeepTrig, card, true);
|
||||
card.addTrigger(parsedUpkeepTrig);
|
||||
final GameCommand intoPlay = new GameCommand() {
|
||||
|
||||
private static final long serialVersionUID = -7913835645603984242L;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
card.addExtrinsicKeyword("(Echo unpaid)");
|
||||
}
|
||||
};
|
||||
card.addComesIntoPlayCommand(intoPlay);
|
||||
}
|
||||
else if (keyword.startsWith("Suspend")) {
|
||||
card.removeIntrinsicKeyword(keyword);
|
||||
|
||||
@@ -419,7 +419,6 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
c.getDamageHistory().setNotAttackedSinceLastUpkeepOf(playerTurn);
|
||||
c.getDamageHistory().setNotBlockedSinceLastUpkeepOf(playerTurn);
|
||||
c.getDamageHistory().setNotBeenBlockedSinceLastUpkeepOf(playerTurn);
|
||||
c.setUnderControlSinceLastUpkeep(true);
|
||||
}
|
||||
game.getUpkeep().executeUntilEndOfPhase(playerTurn);
|
||||
game.getUpkeep().registerUntilEndCommand(playerTurn);
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
*/
|
||||
package forge.game.phase;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.player.Player;
|
||||
@@ -69,10 +72,42 @@ public class Upkeep extends Phase {
|
||||
game.getStack().freezeStack();
|
||||
|
||||
Upkeep.upkeepUpkeepCost(game); // sacrifice unless upkeep cost is paid
|
||||
Upkeep.upkeepEcho(game);
|
||||
|
||||
game.getStack().unfreezeStack();
|
||||
}
|
||||
|
||||
private static void upkeepEcho(final Game game) {
|
||||
CardCollectionView list = game.getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.hasStartOfKeyword("(Echo unpaid)");
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
final Card c = list.get(i);
|
||||
if (c.hasStartOfKeyword("(Echo unpaid)")) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Echo for ").append(c).append("\n");
|
||||
String ref = "X".equals(c.getEchoCost()) ? " | References$ X" : "";
|
||||
String effect = "AB$ Sacrifice | Cost$ 0 | SacValid$ Self | "
|
||||
+ "Echo$ " + c.getEchoCost() + ref;
|
||||
|
||||
SpellAbility sacAbility = AbilityFactory.getAbility(effect, c);
|
||||
sacAbility.setTrigger(true);
|
||||
sacAbility.setActivatingPlayer(c.getController());
|
||||
sacAbility.setStackDescription(sb.toString());
|
||||
sacAbility.setDescription(sb.toString());
|
||||
|
||||
game.getStack().addSimultaneousStackEntry(sacAbility);
|
||||
|
||||
c.removeAllExtrinsicKeyword("(Echo unpaid)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void upkeepUpkeepCost(final Game game) {
|
||||
final CardCollectionView list = game.getPhaseHandler().getPlayerTurn().getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
|
||||
@@ -242,6 +242,30 @@ public class GameSimulatorTest extends TestCase {
|
||||
assertEquals(16, simGame.getPlayers().get(0).getLife());
|
||||
}
|
||||
|
||||
public void testEchoCostState() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
String c1Name = "Acridian";
|
||||
String c2Name = "Goblin Patrol";
|
||||
Card c1 = addCard(c1Name, p);
|
||||
Card c2 = addCard(c2Name, p);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
|
||||
assertTrue(c1.hasStartOfKeyword("(Echo unpaid)"));
|
||||
assertTrue(c2.hasStartOfKeyword("(Echo unpaid)"));
|
||||
c2.removeAllExtrinsicKeyword("(Echo unpaid)");
|
||||
|
||||
GameSimulator sim = createSimulator(game, p);
|
||||
Game simGame = sim.getSimulatedGameState();
|
||||
Card c1Copy = findCardWithName(simGame, c1Name);
|
||||
assertTrue(c1Copy.hasStartOfKeyword("(Echo unpaid)"));
|
||||
Card c2Copy = findCardWithName(simGame, c2Name);
|
||||
assertFalse(c2Copy.hasStartOfKeyword("(Echo unpaid)"));
|
||||
}
|
||||
|
||||
public void testSimulateUnmorph() {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
|
||||
Reference in New Issue
Block a user