Kylox, Visionary Inventor + Alchemy cleanup (#4562)

* Remove fake trigger

* Remove redundancy

* Adapt script from OtDxRaichunite
This commit is contained in:
tool4ever
2024-01-21 10:41:51 +01:00
committed by GitHub
parent 260218a40d
commit 742252191a
13 changed files with 26 additions and 97 deletions

View File

@@ -404,7 +404,6 @@ public abstract class GameState {
if (c.isForetoldThisTurn()) { if (c.isForetoldThisTurn()) {
newText.append("|ForetoldThisTurn"); newText.append("|ForetoldThisTurn");
} }
} }
if (zoneType == ZoneType.Battlefield || zoneType == ZoneType.Exile) { if (zoneType == ZoneType.Battlefield || zoneType == ZoneType.Exile) {
@@ -1377,7 +1376,7 @@ public abstract class GameState {
c.turnFaceDown(true); c.turnFaceDown(true);
c.addMayLookTemp(c.getOwner()); c.addMayLookTemp(c.getOwner());
} else if (info.equals("ForetoldThisTurn")) { } else if (info.equals("ForetoldThisTurn")) {
c.setForetoldThisTurn(true); c.setTurnInZone(turn);
} else if (info.equals("IsToken")) { } else if (info.equals("IsToken")) {
c.setToken(true); c.setToken(true);
} }

View File

@@ -76,11 +76,8 @@ public class GameAction {
} }
public final void resetActivationsPerTurn() { public final void resetActivationsPerTurn() {
// Reset Activations per Turn
for (final Card card : game.getCardsInGame()) { for (final Card card : game.getCardsInGame()) {
card.resetActivationsPerTurn(); card.resetActivationsPerTurn();
// need to reset this in exile
card.resetForetoldThisTurn();
} }
} }

View File

@@ -686,7 +686,7 @@ public abstract class SpellAbilityEffect {
if ("True".equalsIgnoreCase(attacking)) { if ("True".equalsIgnoreCase(attacking)) {
defs.addAll(combat.getDefenders()); defs.addAll(combat.getDefenders());
} else { } 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<String, Object> params = Maps.newHashMap(); Map<String, Object> params = Maps.newHashMap();

View File

@@ -737,7 +737,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} }
if (sa.hasParam("Foretold")) { if (sa.hasParam("Foretold")) {
movedCard.setForetold(true); movedCard.setForetold(true);
movedCard.setForetoldThisTurn(true);
if (sa.hasParam("ForetoldCost")) { if (sa.hasParam("ForetoldCost")) {
movedCard.setForetoldCostByEffect(true); movedCard.setForetoldCostByEffect(true);
} }
@@ -1401,7 +1400,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (sa.hasParam("Foretold")) { if (sa.hasParam("Foretold")) {
movedCard.setForetold(true); movedCard.setForetold(true);
movedCard.setForetoldThisTurn(true);
if (sa.hasParam("ForetoldCost")) { if (sa.hasParam("ForetoldCost")) {
movedCard.setForetoldCostByEffect(true); movedCard.setForetoldCostByEffect(true);
} }

View File

@@ -220,7 +220,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private boolean manifested; private boolean manifested;
private boolean foretold; private boolean foretold;
private boolean foretoldThisTurn;
private boolean foretoldCostByEffect; private boolean foretoldCostByEffect;
private boolean specialized; private boolean specialized;
@@ -6257,13 +6256,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
public boolean isForetoldThisTurn() { public boolean isForetoldThisTurn() {
return foretoldThisTurn; return getTurnInZone() == game.getPhaseHandler().getTurn();
}
public final void setForetoldThisTurn(final boolean foretoldThisTurn) {
this.foretoldThisTurn = foretoldThisTurn;
}
public void resetForetoldThisTurn() {
foretoldThisTurn = false;
} }
public boolean isSpecialized() { public boolean isSpecialized() {

View File

@@ -31,7 +31,6 @@ import forge.GameCommand;
import forge.game.cost.CostExile; import forge.game.cost.CostExile;
import forge.game.cost.CostPart; import forge.game.cost.CostPart;
import forge.game.event.GameEventCardForetold; import forge.game.event.GameEventCardForetold;
import forge.game.trigger.TriggerType;
import forge.util.Localizer; import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -1566,7 +1565,7 @@ public class CardFactoryUtil {
final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True" final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True"
+ " | TriggerDescription$ Myriad (" + inst.getReminderText() + ")"; + " | 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"; + "| ForEach$ OppNonDefendingPlayer | AtEOT$ ExileCombat | CleanupForEach$ True";
final SpellAbility copySA = AbilityFactory.getAbility(copyStr, card); final SpellAbility copySA = AbilityFactory.getAbility(copyStr, card);
@@ -3018,8 +3017,6 @@ public class CardFactoryUtil {
final Game game = getHostCard().getGame(); final Game game = getHostCard().getGame();
final Card c = game.getAction().exile(new CardCollection(getHostCard()), this, null).get(0); final Card c = game.getAction().exile(new CardCollection(getHostCard()), this, null).get(0);
c.setForetold(true); c.setForetold(true);
game.getTriggerHandler().runTrigger(TriggerType.IsForetold, AbilityKey.mapFromCard(c), false);
c.setForetoldThisTurn(true);
c.turnFaceDown(true); c.turnFaceDown(true);
// look at the exiled card // look at the exiled card
c.addMayLookTemp(getActivatingPlayer()); c.addMayLookTemp(getActivatingPlayer());

View File

@@ -329,7 +329,7 @@ public final class CardUtil {
newCopy.setBestowTimestamp(in.getBestowTimestamp()); newCopy.setBestowTimestamp(in.getBestowTimestamp());
newCopy.setForetold(in.isForetold()); newCopy.setForetold(in.isForetold());
newCopy.setForetoldThisTurn(in.isForetoldThisTurn()); newCopy.setTurnInZone(in.getTurnInZone());
newCopy.setForetoldCostByEffect(in.isForetoldCostByEffect()); newCopy.setForetoldCostByEffect(in.isForetoldCostByEffect());
newCopy.setMeldedWith(getLKICopy(in.getMeldedWith(), cachedMap)); newCopy.setMeldedWith(getLKICopy(in.getMeldedWith(), cachedMap));

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package forge.game.trigger;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import java.util.Map;
/**
* <p>
* Trigger_IsForetold class.
* </p>
* (Mainly copied from TriggerBecomeMonstrous)
*/
public class TriggerIsForetold extends Trigger {
/**
* <p>
* Constructor for Trigger_IsForetold.
* </p>
*
* @param params
* a {@link java.util.HashMap} object.
* @param host
* a {@link forge.game.card.Card} object.
* @param intrinsic
* the intrinsic
*/
public TriggerIsForetold(Map<String, String> params, final Card host, final boolean intrinsic) {
super(params, host, intrinsic);
}
/** {@inheritDoc}
* @param runParams*/
@Override
public final boolean performTest(Map<AbilityKey, Object> runParams) {
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
return false;
}
return true;
}
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card);
}
@Override
public String getImportantStackObjects(SpellAbility sa) {
//nothing here because foretelling is secretive - generally will be Static anyway
return "";
}
}

View File

@@ -81,7 +81,6 @@ public enum TriggerType {
Foretell(TriggerForetell.class), Foretell(TriggerForetell.class),
Immediate(TriggerImmediate.class), Immediate(TriggerImmediate.class),
Investigated(TriggerInvestigated.class), Investigated(TriggerInvestigated.class),
IsForetold(TriggerIsForetold.class),
LandPlayed(TriggerLandPlayed.class), LandPlayed(TriggerLandPlayed.class),
LifeGained(TriggerLifeGained.class), LifeGained(TriggerLifeGained.class),
LifeLost(TriggerLifeLost.class), LifeLost(TriggerLifeLost.class),

View File

@@ -7,6 +7,6 @@ S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$
SVar:X:Count$Valid Creature.YouCtrl 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. 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: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 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. 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.

View File

@@ -4,7 +4,7 @@ Types:Creature Wolf
PT:4/4 PT:4/4
K:Trample K:Trample
K:Haste 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:TrigNoteNum:DB$ Pump | NoteNumber$ X
SVar:X:Count$YourTurns 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. 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.

View File

@@ -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. 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. 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: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 SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All 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. 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.

View File

@@ -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.