diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index 563a11d75ad..2739f2bf4e0 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -404,7 +404,6 @@ public abstract class GameState { if (c.isForetoldThisTurn()) { newText.append("|ForetoldThisTurn"); } - } if (zoneType == ZoneType.Battlefield || zoneType == ZoneType.Exile) { @@ -1377,7 +1376,7 @@ public abstract class GameState { c.turnFaceDown(true); c.addMayLookTemp(c.getOwner()); } else if (info.equals("ForetoldThisTurn")) { - c.setForetoldThisTurn(true); + c.setTurnInZone(turn); } else if (info.equals("IsToken")) { c.setToken(true); } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 66a5a6881ff..11ba5524015 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -76,11 +76,8 @@ public class GameAction { } public final void resetActivationsPerTurn() { - // Reset Activations per Turn for (final Card card : game.getCardsInGame()) { card.resetActivationsPerTurn(); - // need to reset this in exile - card.resetForetoldThisTurn(); } } diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 261f59cf419..941ed5d1cac 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -686,7 +686,7 @@ public abstract class SpellAbilityEffect { if ("True".equalsIgnoreCase(attacking)) { defs.addAll(combat.getDefenders()); } else { - defs.addAll(AbilityUtils.getDefinedEntities(sa.hasParam("ForEach") ? c : host, attacking.split("&"), sa)); + defs.addAll(AbilityUtils.getDefinedEntities(sa.hasParam("ForEach") ? c : host, attacking.split(" & "), sa)); } Map params = Maps.newHashMap(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 2dcdf6b053c..7a769769343 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -737,7 +737,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } if (sa.hasParam("Foretold")) { movedCard.setForetold(true); - movedCard.setForetoldThisTurn(true); if (sa.hasParam("ForetoldCost")) { movedCard.setForetoldCostByEffect(true); } @@ -1401,7 +1400,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("Foretold")) { movedCard.setForetold(true); - movedCard.setForetoldThisTurn(true); if (sa.hasParam("ForetoldCost")) { movedCard.setForetoldCostByEffect(true); } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index c532edc0c6d..6e585649092 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -220,7 +220,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private boolean manifested; private boolean foretold; - private boolean foretoldThisTurn; private boolean foretoldCostByEffect; private boolean specialized; @@ -6257,13 +6256,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public boolean isForetoldThisTurn() { - return foretoldThisTurn; - } - public final void setForetoldThisTurn(final boolean foretoldThisTurn) { - this.foretoldThisTurn = foretoldThisTurn; - } - public void resetForetoldThisTurn() { - foretoldThisTurn = false; + return getTurnInZone() == game.getPhaseHandler().getTurn(); } public boolean isSpecialized() { diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index a7478f74eb4..d20a7812668 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -31,7 +31,6 @@ import forge.GameCommand; import forge.game.cost.CostExile; import forge.game.cost.CostPart; import forge.game.event.GameEventCardForetold; -import forge.game.trigger.TriggerType; import forge.util.Localizer; import org.apache.commons.lang3.StringUtils; @@ -1566,7 +1565,7 @@ public class CardFactoryUtil { final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True" + " | TriggerDescription$ Myriad (" + inst.getReminderText() + ")"; - final String copyStr = "DB$ CopyPermanent | Defined$ Self | TokenTapped$ True | Optional$ True | TokenAttacking$ Player.IsRemembered,Valid Planeswalker.ControlledBy Remembered" + final String copyStr = "DB$ CopyPermanent | Defined$ Self | TokenTapped$ True | Optional$ True | TokenAttacking$ RememberedPlayer & Valid Planeswalker.ControlledBy Remembered" + "| ForEach$ OppNonDefendingPlayer | AtEOT$ ExileCombat | CleanupForEach$ True"; final SpellAbility copySA = AbilityFactory.getAbility(copyStr, card); @@ -3018,8 +3017,6 @@ public class CardFactoryUtil { final Game game = getHostCard().getGame(); final Card c = game.getAction().exile(new CardCollection(getHostCard()), this, null).get(0); c.setForetold(true); - game.getTriggerHandler().runTrigger(TriggerType.IsForetold, AbilityKey.mapFromCard(c), false); - c.setForetoldThisTurn(true); c.turnFaceDown(true); // look at the exiled card c.addMayLookTemp(getActivatingPlayer()); diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index f6bfd2897d2..c1f43a06d5f 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -329,7 +329,7 @@ public final class CardUtil { newCopy.setBestowTimestamp(in.getBestowTimestamp()); newCopy.setForetold(in.isForetold()); - newCopy.setForetoldThisTurn(in.isForetoldThisTurn()); + newCopy.setTurnInZone(in.getTurnInZone()); newCopy.setForetoldCostByEffect(in.isForetoldCostByEffect()); newCopy.setMeldedWith(getLKICopy(in.getMeldedWith(), cachedMap)); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerIsForetold.java b/forge-game/src/main/java/forge/game/trigger/TriggerIsForetold.java deleted file mode 100644 index 80067244ab0..00000000000 --- a/forge-game/src/main/java/forge/game/trigger/TriggerIsForetold.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2021 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.game.trigger; - -import forge.game.ability.AbilityKey; -import forge.game.card.Card; -import forge.game.spellability.SpellAbility; - -import java.util.Map; - -/** - *

- * Trigger_IsForetold class. - *

- * (Mainly copied from TriggerBecomeMonstrous) - */ -public class TriggerIsForetold extends Trigger { - - /** - *

- * Constructor for Trigger_IsForetold. - *

- * - * @param params - * a {@link java.util.HashMap} object. - * @param host - * a {@link forge.game.card.Card} object. - * @param intrinsic - * the intrinsic - */ - public TriggerIsForetold(Map params, final Card host, final boolean intrinsic) { - super(params, host, intrinsic); - } - - /** {@inheritDoc} - * @param runParams*/ - @Override - public final boolean performTest(Map runParams) { - if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) { - return false; - } - - return true; - } - - /** {@inheritDoc} */ - @Override - public final void setTriggeringObjects(final SpellAbility sa, Map runParams) { - sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card); - } - - @Override - public String getImportantStackObjects(SpellAbility sa) { - //nothing here because foretelling is secretive - generally will be Static anyway - return ""; - } -} diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerType.java b/forge-game/src/main/java/forge/game/trigger/TriggerType.java index 8507d5710f2..27529e8bea6 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerType.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerType.java @@ -81,7 +81,6 @@ public enum TriggerType { Foretell(TriggerForetell.class), Immediate(TriggerImmediate.class), Investigated(TriggerInvestigated.class), - IsForetold(TriggerIsForetold.class), LandPlayed(TriggerLandPlayed.class), LifeGained(TriggerLifeGained.class), LifeLost(TriggerLifeLost.class), diff --git a/forge-gui/res/cardsfolder/a/adeline_resplendent_cathar.txt b/forge-gui/res/cardsfolder/a/adeline_resplendent_cathar.txt index e05adab9bee..b9db933a45a 100644 --- a/forge-gui/res/cardsfolder/a/adeline_resplendent_cathar.txt +++ b/forge-gui/res/cardsfolder/a/adeline_resplendent_cathar.txt @@ -7,6 +7,6 @@ S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ SVar:X:Count$Valid Creature.YouCtrl T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ DBRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control. SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Opponent | ChangeZoneTable$ True | RepeatSubAbility$ DBToken -SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenTapped$ True | TokenAttacking$ Player.IsRemembered & Valid Planeswalker.ControlledBy Remembered | TokenOwner$ You +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenTapped$ True | TokenAttacking$ RememberedPlayer & Valid Planeswalker.ControlledBy Remembered | TokenOwner$ You DeckHas:Ability$Token Oracle:Vigilance\nAdeline, Resplendent Cathar's power is equal to the number of creatures you control.\nWhenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control. diff --git a/forge-gui/res/cardsfolder/l/lupine_harbingers.txt b/forge-gui/res/cardsfolder/l/lupine_harbingers.txt index 74b191669e1..58f431186b9 100644 --- a/forge-gui/res/cardsfolder/l/lupine_harbingers.txt +++ b/forge-gui/res/cardsfolder/l/lupine_harbingers.txt @@ -4,7 +4,7 @@ Types:Creature Wolf PT:4/4 K:Trample K:Haste -T:Mode$ IsForetold | ValidCard$ Card.Self | TriggerZones$ Exile | Execute$ TrigNoteNum | Static$ True +T:Mode$ ChangesZone | ValidCard$ Card.Self | Destination$ Exile | Execute$ TrigNoteNum | Static$ True SVar:TrigNoteNum:DB$ Pump | NoteNumber$ X SVar:X:Count$YourTurns K:etbCounter:P1P1:Z:CheckSVar$ WasForetold:CARDNAME enters the battlefield with X +1/+1 counters on it, where X is the number of turns you've begun since it was foretold. diff --git a/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt b/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt index 45d0b68645a..a4ff4a48fd2 100644 --- a/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt +++ b/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt @@ -5,7 +5,7 @@ PT:5/5 S:Mode$ MinMaxBlocker | ValidCard$ Card.Self | Max$ 1 | Description$ CARDNAME can't be blocked by more than one creature. T:Mode$ AttackersDeclared | AttackingPlayer$ Player.Opponent | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | IsPresent$ Card.Self+tapped | TriggerDescription$ Whenever an opponent attacks with one or more creatures, if NICKNAME is tapped, you may have that opponent gain control of NICKNAME until end of combat. If you do, choose a player or planeswalker that opponent is attacking. NICKNAME is attacking that player or planeswalker. SVar:TrigGainControl:DB$ GainControl | Defined$ Self | NewController$ TriggeredAttackingPlayer | LoseControl$ EndOfCombat | RememberControlled$ True | SubAbility$ DBAttack -SVar:DBAttack:DB$ ChangeCombatants | Defined$ Remembered | Attacking$ Player.Defending & Valid Planeswalker.Defending | SubAbility$ DBCleanup +SVar:DBAttack:DB$ ChangeCombatants | Defined$ Remembered | Attacking$ .Defending & Valid Planeswalker.Defending | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True AI:RemoveDeck:All Oracle:Tahngarth, First Mate can't be blocked by more than one creature.\nWhenever an opponent attacks with one or more creatures, if Tahngarth is tapped, you may have that opponent gain control of Tahngarth until end of combat. If you do, choose a player or planeswalker that opponent is attacking. Tahngarth is attacking that player or planeswalker. diff --git a/forge-gui/res/cardsfolder/upcoming/kylox_visionary_inventor.txt b/forge-gui/res/cardsfolder/upcoming/kylox_visionary_inventor.txt new file mode 100644 index 00000000000..109ad80bc0b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/kylox_visionary_inventor.txt @@ -0,0 +1,18 @@ +Name:Kylox, Visionary Inventor +ManaCost:5 U R +Types:Legendary Creature Viashino Artificer +PT:4/4 +K:Menace +K:Ward:2 +K:Haste +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, sacrifice any number of other creatures, then exile the top X cards of your library, where X is their total power. You may cast any number of instant and/or sorcery spells from among the exiled cards without paying their mana costs. +SVar:TrigSac:DB$ Sacrifice | Defined$ You | Amount$ SacX | SacValid$ Creature.Other | RememberSacrificed$ True | Optional$ True | SubAbility$ DBDig +SVar:DBDig:DB$ Dig | Defined$ You | DigNum$ X | ChangeNum$ All | DestinationZone$ Exile | Imprint$ True | SubAbility$ DBPlay +SVar:DBPlay:DB$ Play | Valid$ Card.IsImprinted+YouOwn | ValidZone$ Exile | ValidSA$ Instant,Sorcery | Controller$ You | WithoutManaCost$ True | Optional$ True | Amount$ All | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True +SVar:X:RememberedLKI$CardPower +SVar:SacX:Count$Valid Creature.Other +DeckHas:Ability$Sacrifice +DeckHints:Type$Instant|Sorcery +AI:RemoveDeck:All +Oracle:Menace, ward {2}, haste\nWhenever Kylox, Visionary Inventor attacks, sacrifice any number of other creatures, then exile the top X cards of your library, where X is their total power. You may cast any number of instant and/or sorcery spells from among the exiled cards without paying their mana costs.