From ad067b7444f87e75b976c1cf1e94b8c856f8af27 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Mon, 16 Sep 2019 23:07:53 -0600 Subject: [PATCH 01/37] push `toStringMap` down into `Trigger` eliminating the need for the conversion. Also add helper method `setTriggeringObjectsFrom` and change `getRunParams` into similar but not identical `getFromRunParams` --- .../forge/game/spellability/SpellAbility.java | 9 +++++++++ .../src/main/java/forge/game/trigger/Trigger.java | 10 +++++----- .../java/forge/game/trigger/TriggerAbandoned.java | 2 +- .../java/forge/game/trigger/TriggerAttached.java | 3 +-- .../trigger/TriggerAttackerBlockedByCreature.java | 3 +-- .../game/trigger/TriggerAttackerUnblocked.java | 4 +--- .../trigger/TriggerAttackerUnblockedOnce.java | 3 +-- .../game/trigger/TriggerAttackersDeclared.java | 3 +-- .../java/forge/game/trigger/TriggerAttacks.java | 11 +++++++---- .../game/trigger/TriggerBlockersDeclared.java | 3 +-- .../java/forge/game/trigger/TriggerBlocks.java | 3 +-- .../forge/game/trigger/TriggerChampioned.java | 3 +-- .../game/trigger/TriggerCounterRemovedOnce.java | 3 +-- .../java/forge/game/trigger/TriggerCountered.java | 11 +++++++---- .../java/forge/game/trigger/TriggerCrewed.java | 3 +-- .../game/trigger/TriggerDamageDealtOnce.java | 4 +--- .../java/forge/game/trigger/TriggerHandler.java | 15 +++++++-------- .../forge/game/trigger/TriggerTapsForMana.java | 4 +--- 18 files changed, 48 insertions(+), 49 deletions(-) diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index fb7c64c7d80..58d74c8d84b 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -565,6 +565,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public void setTriggeringObject(final AbilityKey type, final Object o) { triggeringObjects.put(type, o); } + public void setTriggeringObjectsFrom(final Trigger trigger, final AbilityKey... types) { + int typesLength = types.length; + for (int i = 0; i < typesLength; i += 1) { + AbilityKey type = types[i]; + triggeringObjects.put(type, trigger.getFromRunParams(type)); + } + } + + public boolean hasTriggeringObject(final AbilityKey type) { return triggeringObjects.containsKey(type); } diff --git a/forge-game/src/main/java/forge/game/trigger/Trigger.java b/forge-game/src/main/java/forge/game/trigger/Trigger.java index 18b0e3c6f50..7d1c0b5fe36 100644 --- a/forge-game/src/main/java/forge/game/trigger/Trigger.java +++ b/forge-game/src/main/java/forge/game/trigger/Trigger.java @@ -66,7 +66,7 @@ public abstract class Trigger extends TriggerReplacementBase { /** The run params. */ - private Map runParams; + private Map runParams; private TriggerType mode; @@ -122,7 +122,7 @@ public abstract class Trigger extends TriggerReplacementBase { this.id = nextId(); this.intrinsic = intrinsic; - this.setRunParams(new HashMap<>()); // TODO: Consider whether this can be null instead, for performance reasons. + this.setRunParams(AbilityKey.newMap()); // TODO: Consider whether this can be null instead, for performance reasons. this.originalMapParams.putAll(params); this.mapParams.putAll(params); this.setHostCard(host); @@ -460,8 +460,8 @@ public abstract class Trigger extends TriggerReplacementBase { * * @return the runParams */ - public Map getRunParams() { - return this.runParams; + public Object getFromRunParams(AbilityKey key) { + return this.runParams.get(key); } /** @@ -470,7 +470,7 @@ public abstract class Trigger extends TriggerReplacementBase { * @param runParams0 * the runParams to set */ - public void setRunParams(final Map runParams0) { + public void setRunParams(final Map runParams0) { this.runParams = runParams0; } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAbandoned.java b/forge-game/src/main/java/forge/game/trigger/TriggerAbandoned.java index dcb65899236..42e0e0af649 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAbandoned.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAbandoned.java @@ -63,7 +63,7 @@ public class TriggerAbandoned extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Scheme, this.getRunParams().get("Scheme")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Scheme); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java index 96fdfd28ae6..82f6c081ae7 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java @@ -73,8 +73,7 @@ public class TriggerAttached extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Source, this.getRunParams().get("AttachSource")); - sa.setTriggeringObject(AbilityKey.Target, this.getRunParams().get("AttachTarget")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Source, AbilityKey.Target); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlockedByCreature.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlockedByCreature.java index 7ddb60acdef..f4b01752327 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlockedByCreature.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlockedByCreature.java @@ -88,8 +88,7 @@ public class TriggerAttackerBlockedByCreature extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Attacker, this.getRunParams().get("Attacker")); - sa.setTriggeringObject(AbilityKey.Blocker, this.getRunParams().get("Blocker")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Attacker, AbilityKey.Blocker); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblocked.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblocked.java index a8e9d41209a..decaca22f1d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblocked.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblocked.java @@ -70,9 +70,7 @@ public class TriggerAttackerUnblocked extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Attacker, this.getRunParams().get("Attacker")); - sa.setTriggeringObject(AbilityKey.Defender, this.getRunParams().get("Defender")); - sa.setTriggeringObject(AbilityKey.DefendingPlayer, this.getRunParams().get("DefendingPlayer")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Attacker, AbilityKey.Defender, AbilityKey.DefendingPlayer); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblockedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblockedOnce.java index 23567718e5c..11220460602 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblockedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerUnblockedOnce.java @@ -85,8 +85,7 @@ public class TriggerAttackerUnblockedOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.AttackingPlayer, this.getRunParams().get("AttackingPlayer")); - sa.setTriggeringObject(AbilityKey.Defenders, this.getRunParams().get("Defenders")); + sa.setTriggeringObjectsFrom(this, AbilityKey.AttackingPlayer, AbilityKey.Defenders); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttackersDeclared.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttackersDeclared.java index f9be4cacdd6..f26bcaa7293 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttackersDeclared.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttackersDeclared.java @@ -87,8 +87,7 @@ public class TriggerAttackersDeclared extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Attackers, this.getRunParams().get("Attackers")); - sa.setTriggeringObject(AbilityKey.AttackingPlayer, this.getRunParams().get("AttackingPlayer")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Attackers, AbilityKey.AttackingPlayer); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java index cc35af51e0c..551ff2826bb 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java @@ -125,10 +125,13 @@ public class TriggerAttacks extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Attacker, this.getRunParams().get("Attacker")); - sa.setTriggeringObject(AbilityKey.Defender, this.getRunParams().get("Attacked")); - sa.setTriggeringObject(AbilityKey.Defenders, this.getRunParams().get("Defenders")); - sa.setTriggeringObject(AbilityKey.DefendingPlayer, this.getRunParams().get("DefendingPlayer")); + sa.setTriggeringObjectsFrom( + this, + AbilityKey.Attacker, + AbilityKey.Defender, + AbilityKey.Defenders, + AbilityKey.DefendingPlayer + ); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBlockersDeclared.java b/forge-game/src/main/java/forge/game/trigger/TriggerBlockersDeclared.java index c7ec35ae012..57a0947072e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBlockersDeclared.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBlockersDeclared.java @@ -52,8 +52,7 @@ public class TriggerBlockersDeclared extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Blockers, this.getRunParams().get("Blockers")); - sa.setTriggeringObject(AbilityKey.Attackers, this.getRunParams().get("Attackers")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Blockers, AbilityKey.Attackers); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBlocks.java b/forge-game/src/main/java/forge/game/trigger/TriggerBlocks.java index 6388a1ed6a2..7f537edea16 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBlocks.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBlocks.java @@ -89,8 +89,7 @@ public class TriggerBlocks extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Blocker, this.getRunParams().get("Blocker")); - sa.setTriggeringObject(AbilityKey.Attackers, this.getRunParams().get("Attackers")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Blocker, AbilityKey.Attackers); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerChampioned.java b/forge-game/src/main/java/forge/game/trigger/TriggerChampioned.java index d95e92662ad..e0b27efee0f 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerChampioned.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerChampioned.java @@ -72,8 +72,7 @@ public class TriggerChampioned extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Championed, this.getRunParams().get("Championed")); - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Championed, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java index a96eb1df4c9..591e6df967e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java @@ -74,8 +74,7 @@ public class TriggerCounterRemovedOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Amount, this.getRunParams().get("CounterAmount")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Amount); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCountered.java b/forge-game/src/main/java/forge/game/trigger/TriggerCountered.java index ae5087b29e2..0afa88d020c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCountered.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCountered.java @@ -93,10 +93,13 @@ public class TriggerCountered extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Cause, this.getRunParams().get("Cause")); - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); - sa.setTriggeringObject(AbilityKey.CounteredSA, this.getRunParams().get("CounteredSA")); + sa.setTriggeringObjectsFrom( + this, + AbilityKey.Card, + AbilityKey.Cause, + AbilityKey.Player, + AbilityKey.CounteredSA + ); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCrewed.java b/forge-game/src/main/java/forge/game/trigger/TriggerCrewed.java index 655fa1d591a..624b97e1d24 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCrewed.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCrewed.java @@ -39,8 +39,7 @@ public class TriggerCrewed extends Trigger { @Override public void setTriggeringObjects(SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Vehicle, this.getRunParams().get("Vehicle")); - sa.setTriggeringObject(AbilityKey.Crew, this.getRunParams().get("Crew")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Vehicle, AbilityKey.Crew); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java index 7a8dee7acec..20e744c5755 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java @@ -106,9 +106,7 @@ public class TriggerDamageDealtOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Source, this.getRunParams().get("DamageSource")); - sa.setTriggeringObject(AbilityKey.Targets, this.getRunParams().get("DamageTargets")); - sa.setTriggeringObject(AbilityKey.DamageAmount, this.getRunParams().get("DamageAmount")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Source, AbilityKey.Targets, AbilityKey.DamageAmount); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index 87d51dc130d..8db3e275531 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -338,7 +338,7 @@ public class TriggerHandler { private void runStateTrigger(final Map runParams) { for (final Trigger t: activeTriggers) { if (canRunTrigger(t, TriggerType.Always, runParams)) { - runSingleTrigger(t, toStringMap(runParams)); + runSingleTrigger(t, runParams); } } } @@ -376,7 +376,7 @@ public class TriggerHandler { // Static triggers for (final Trigger t : Lists.newArrayList(activeTriggers)) { if (t.isStatic() && canRunTrigger(t, mode, runParams)) { - runSingleTrigger(t, toStringMap(runParams)); + runSingleTrigger(t, runParams); checkStatics = true; } @@ -420,7 +420,6 @@ public class TriggerHandler { final TriggerType mode = wt.getMode(); final Map runParams = wt.getParams(); - final Map stringRunParams = toStringMap(runParams); final List triggers = wt.getTriggers() != null ? wt.getTriggers() : activeTriggers; Card card = null; @@ -450,7 +449,7 @@ public class TriggerHandler { int x = 1 + handlePanharmonicon(t, runParams, player); for (int i = 0; i < x; ++i) { - runSingleTrigger(t, stringRunParams); + runSingleTrigger(t, runParams); } checkStatics = true; } @@ -459,7 +458,7 @@ public class TriggerHandler { for (final Trigger deltrig : delayedTriggersWorkingCopy) { if (deltrig.getHostCard().getController().equals(player)) { if (isTriggerActive(deltrig) && canRunTrigger(deltrig, mode, runParams)) { - runSingleTrigger(deltrig, stringRunParams); + runSingleTrigger(deltrig, runParams); delayedTriggers.remove(deltrig); } } @@ -547,14 +546,14 @@ public class TriggerHandler { // Checks if the conditions are right for a single trigger to go off, and // runs it if so. // Return true if the trigger went off, false otherwise. - private void runSingleTrigger(final Trigger regtrig, final Map runParams) { + private void runSingleTrigger(final Trigger regtrig, final Map runParams) { final Map triggerParams = regtrig.getMapParams(); regtrig.setRunParams(runParams); // All tests passed, execute ability. if (regtrig instanceof TriggerTapsForMana) { - final SpellAbility abMana = (SpellAbility) runParams.get("AbilityMana"); + final SpellAbility abMana = (SpellAbility) runParams.get(AbilityKey.AbilityMana); if (null != abMana && null != abMana.getManaPart()) { abMana.setUndoable(false); } @@ -562,7 +561,7 @@ public class TriggerHandler { SpellAbility sa = null; Card host = regtrig.getHostCard(); - final Card trigCard = regtrig.getRunParams().containsKey("Card") ? (Card)regtrig.getRunParams().get("Card") : null; + final Card trigCard = (Card) regtrig.getFromRunParams(AbilityKey.Card); if (trigCard != null && (host.getId() == trigCard.getId())) { host = trigCard; diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerTapsForMana.java b/forge-game/src/main/java/forge/game/trigger/TriggerTapsForMana.java index 5474f5fc6b8..4763c543f04 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerTapsForMana.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerTapsForMana.java @@ -105,9 +105,7 @@ public class TriggerTapsForMana extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); - sa.setTriggeringObject(AbilityKey.Produced, this.getRunParams().get("Produced")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Player, AbilityKey.Produced); } @Override From 350756435fc2272ed47f99ecda0cbeeba62e609c Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Mon, 16 Sep 2019 23:16:24 -0600 Subject: [PATCH 02/37] add incorrectly not staged changes --- .../java/forge/game/trigger/TriggerAdapt.java | 2 +- .../game/trigger/TriggerAttackerBlocked.java | 13 ++++++++----- .../forge/game/trigger/TriggerBecomeMonarch.java | 2 +- .../game/trigger/TriggerBecomeMonstrous.java | 3 +-- .../forge/game/trigger/TriggerBecomeRenowned.java | 2 +- .../forge/game/trigger/TriggerBecomesTarget.java | 5 ++--- .../game/trigger/TriggerBecomesTargetOnce.java | 5 ++--- .../game/trigger/TriggerChangesController.java | 2 +- .../forge/game/trigger/TriggerChangesZone.java | 2 +- .../forge/game/trigger/TriggerChangesZoneAll.java | 2 +- .../forge/game/trigger/TriggerCounterAdded.java | 5 +---- .../game/trigger/TriggerCounterAddedAll.java | 2 +- .../game/trigger/TriggerCounterAddedOnce.java | 7 ++----- .../forge/game/trigger/TriggerCounterRemoved.java | 2 +- .../java/forge/game/trigger/TriggerCycled.java | 2 +- .../forge/game/trigger/TriggerDamageDone.java | 13 ++++++++----- .../forge/game/trigger/TriggerDamageDoneOnce.java | 12 +++--------- .../game/trigger/TriggerDamagePrevented.java | 6 +++--- .../game/trigger/TriggerDamagePreventedOnce.java | 4 ++-- .../java/forge/game/trigger/TriggerDestroyed.java | 3 +-- .../java/forge/game/trigger/TriggerDevoured.java | 2 +- .../java/forge/game/trigger/TriggerDiscarded.java | 3 +-- .../java/forge/game/trigger/TriggerDrawn.java | 3 +-- .../java/forge/game/trigger/TriggerEvolved.java | 2 +- .../java/forge/game/trigger/TriggerExerted.java | 3 +-- .../java/forge/game/trigger/TriggerExiled.java | 2 +- .../java/forge/game/trigger/TriggerExploited.java | 3 +-- .../java/forge/game/trigger/TriggerExplores.java | 2 +- .../java/forge/game/trigger/TriggerFight.java | 2 +- .../forge/game/trigger/TriggerFlippedCoin.java | 2 +- .../forge/game/trigger/TriggerInvestigated.java | 2 +- .../forge/game/trigger/TriggerLandPlayed.java | 2 +- .../forge/game/trigger/TriggerLifeGained.java | 3 +-- .../java/forge/game/trigger/TriggerLifeLost.java | 3 +-- .../java/forge/game/trigger/TriggerLosesGame.java | 2 +- .../game/trigger/TriggerPayCumulativeUpkeep.java | 3 +-- .../java/forge/game/trigger/TriggerPayEcho.java | 2 +- .../java/forge/game/trigger/TriggerPayLife.java | 3 +-- .../java/forge/game/trigger/TriggerPhase.java | 2 +- .../java/forge/game/trigger/TriggerPhaseIn.java | 2 +- .../java/forge/game/trigger/TriggerPhaseOut.java | 2 +- .../forge/game/trigger/TriggerPlanarDice.java | 2 +- .../game/trigger/TriggerPlaneswalkedFrom.java | 2 +- .../forge/game/trigger/TriggerPlaneswalkedTo.java | 2 +- .../forge/game/trigger/TriggerRegenerated.java | 3 +-- .../java/forge/game/trigger/TriggerRevealed.java | 2 +- .../forge/game/trigger/TriggerSacrificed.java | 2 +- .../main/java/forge/game/trigger/TriggerScry.java | 2 +- .../game/trigger/TriggerSearchedLibrary.java | 2 +- .../forge/game/trigger/TriggerSetInMotion.java | 2 +- .../java/forge/game/trigger/TriggerShuffled.java | 2 +- .../game/trigger/TriggerSpellAbilityCast.java | 15 +++++++++------ .../game/trigger/TriggerSpellAbilityCopy.java | 2 +- .../java/forge/game/trigger/TriggerSurveil.java | 2 +- .../main/java/forge/game/trigger/TriggerTaps.java | 2 +- .../forge/game/trigger/TriggerTransformed.java | 2 +- .../java/forge/game/trigger/TriggerTurnBegin.java | 2 +- .../forge/game/trigger/TriggerTurnFaceUp.java | 2 +- .../java/forge/game/trigger/TriggerUnattach.java | 3 +-- .../java/forge/game/trigger/TriggerUntaps.java | 2 +- .../main/java/forge/game/trigger/TriggerVote.java | 9 +++++++-- 61 files changed, 97 insertions(+), 109 deletions(-) diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAdapt.java b/forge-game/src/main/java/forge/game/trigger/TriggerAdapt.java index ab2f92ccba2..a5345b69a63 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAdapt.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAdapt.java @@ -64,7 +64,7 @@ public class TriggerAdapt extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java index 20fef05e093..2e09e604ca9 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttackerBlocked.java @@ -85,11 +85,14 @@ public class TriggerAttackerBlocked extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Attacker, getRunParams().get("Attacker")); - sa.setTriggeringObject(AbilityKey.Blockers, getRunParams().get("Blockers")); - sa.setTriggeringObject(AbilityKey.Defender, getRunParams().get("Defender")); - sa.setTriggeringObject(AbilityKey.DefendingPlayer, getRunParams().get("DefendingPlayer")); - sa.setTriggeringObject(AbilityKey.NumBlockers, getRunParams().get("NumBlockers")); + sa.setTriggeringObjectsFrom( + this, + AbilityKey.Attacker, + AbilityKey.Blockers, + AbilityKey.Defender, + AbilityKey.DefendingPlayer, + AbilityKey.NumBlockers + ); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonarch.java b/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonarch.java index d52c072f825..c53165cce66 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonarch.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonarch.java @@ -36,7 +36,7 @@ public class TriggerBecomeMonarch extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonstrous.java b/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonstrous.java index 1e6643e767f..1dba122cb98 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonstrous.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBecomeMonstrous.java @@ -65,8 +65,7 @@ public class TriggerBecomeMonstrous extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.MonstrosityAmount, getRunParams().get("MonstrosityAmount")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.MonstrosityAmount); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBecomeRenowned.java b/forge-game/src/main/java/forge/game/trigger/TriggerBecomeRenowned.java index d6086fc7133..23117108cc7 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBecomeRenowned.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBecomeRenowned.java @@ -63,7 +63,7 @@ public class TriggerBecomeRenowned extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTarget.java b/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTarget.java index 4e87946af5f..d27f3903b9d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTarget.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTarget.java @@ -89,9 +89,8 @@ public class TriggerBecomesTarget extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.SourceSA, this.getRunParams().get("SourceSA")); - sa.setTriggeringObject(AbilityKey.Source, ((SpellAbility) this.getRunParams().get("SourceSA")).getHostCard()); - sa.setTriggeringObject(AbilityKey.Target, this.getRunParams().get("Target")); + sa.setTriggeringObject(AbilityKey.Source, ((SpellAbility) getFromRunParams(AbilityKey.SourceSA)).getHostCard()); + sa.setTriggeringObjectsFrom(this, AbilityKey.SourceSA, AbilityKey.Target); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java index 368a1bc2281..eba4a98f119 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java @@ -81,9 +81,8 @@ public class TriggerBecomesTargetOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.SourceSA, this.getRunParams().get("SourceSA")); - sa.setTriggeringObject(AbilityKey.Source, ((SpellAbility) this.getRunParams().get("SourceSA")).getHostCard()); - sa.setTriggeringObject(AbilityKey.Targets, this.getRunParams().get("Targets")); + sa.setTriggeringObjectsFrom(this, AbilityKey.SourceSA, AbilityKey.Targets); + sa.setTriggeringObject(AbilityKey.Source, ((SpellAbility) getFromRunParams(AbilityKey.SourceSA)).getHostCard()); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerChangesController.java b/forge-game/src/main/java/forge/game/trigger/TriggerChangesController.java index 0648a26418d..9c47284385e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerChangesController.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerChangesController.java @@ -71,7 +71,7 @@ public class TriggerChangesController extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java b/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java index 1cd778b509b..a2574e1c897 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java @@ -218,7 +218,7 @@ public class TriggerChangesZone extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerChangesZoneAll.java b/forge-game/src/main/java/forge/game/trigger/TriggerChangesZoneAll.java index f2a36fa0f45..6c0b3b7c259 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerChangesZoneAll.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerChangesZoneAll.java @@ -23,7 +23,7 @@ public class TriggerChangesZoneAll extends Trigger { @Override public void setTriggeringObjects(SpellAbility sa) { - final CardZoneTable table = (CardZoneTable) getRunParams().get("Cards"); + final CardZoneTable table = (CardZoneTable) getFromRunParams(AbilityKey.Cards); CardCollection allCards = this.filterCards(table); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java index 7b87470996a..f6b282ee52a 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java @@ -121,10 +121,7 @@ public class TriggerCounterAdded extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - if (this.getRunParams().containsKey("Card")) - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - if (this.getRunParams().containsKey("Player")) - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedAll.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedAll.java index 859fd6b8787..02c97d93d8b 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedAll.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedAll.java @@ -25,7 +25,7 @@ public class TriggerCounterAddedAll extends Trigger { @Override public void setTriggeringObjects(SpellAbility sa) { - final GameEntityCounterTable table = (GameEntityCounterTable) getRunParams().get("Objects"); + final GameEntityCounterTable table = (GameEntityCounterTable) getFromRunParams(AbilityKey.Objects); Map all = this.filterTable(table); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java index 4baeaff29c5..29cc7db445d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java @@ -106,11 +106,8 @@ public class TriggerCounterAddedOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - if (this.getRunParams().containsKey("Card")) - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - if (this.getRunParams().containsKey("Player")) - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); - sa.setTriggeringObject(AbilityKey.Amount, this.getRunParams().get("CounterAmount")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Player); + sa.setTriggeringObject(AbilityKey.Amount, getFromRunParams(AbilityKey.CounterAmount)); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemoved.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemoved.java index 1f344bfad12..dc3327f1509 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemoved.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemoved.java @@ -83,7 +83,7 @@ public class TriggerCounterRemoved extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCycled.java b/forge-game/src/main/java/forge/game/trigger/TriggerCycled.java index 82359ed0c66..2df0732a3a5 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCycled.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCycled.java @@ -50,7 +50,7 @@ public class TriggerCycled extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java index 1c9751d0321..65651dd674e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java @@ -119,11 +119,14 @@ public class TriggerDamageDone extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Source, CardUtil.getLKICopy((Card)this.getRunParams().get("DamageSource"))); - sa.setTriggeringObject(AbilityKey.Target, this.getRunParams().get("DamageTarget")); - sa.setTriggeringObject(AbilityKey.DamageAmount, this.getRunParams().get("DamageAmount")); - // This parameter is here because LKI information related to combat doesn't work properly - sa.setTriggeringObject(AbilityKey.DefendingPlayer, this.getRunParams().get("DefendingPlayer")); + sa.setTriggeringObject(AbilityKey.Source, CardUtil.getLKICopy((Card)getFromRunParams(AbilityKey.DamageSource))); + sa.setTriggeringObject(AbilityKey.Target, getFromRunParams(AbilityKey.DamageTarget)); + sa.setTriggeringObjectsFrom( + this, + AbilityKey.DamageAmount, + // This parameter is here because LKI information related to combat doesn't work properly + AbilityKey.DefendingPlayer + ); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDoneOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDoneOnce.java index f80a9c9e3c6..20078a32bbf 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDoneOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDoneOnce.java @@ -58,15 +58,9 @@ public class TriggerDamageDoneOnce extends Trigger { @Override public void setTriggeringObjects(SpellAbility sa) { - if (this.getRunParams().containsKey("DamageTarget")) { - sa.setTriggeringObject(AbilityKey.Target, this.getRunParams().get("DamageTarget")); - } - if (this.getRunParams().containsKey("DamageSources")) { - sa.setTriggeringObject(AbilityKey.Sources, this.getRunParams().get("DamageSources")); - } - sa.setTriggeringObject(AbilityKey.DamageAmount, this.getRunParams().get("DamageAmount")); - - + sa.setTriggeringObject(AbilityKey.Target, getFromRunParams(AbilityKey.DamageTarget)); + sa.setTriggeringObject(AbilityKey.Sources, getFromRunParams(AbilityKey.DamageSources)); + sa.setTriggeringObjectsFrom(this, AbilityKey.DamageAmount); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamagePrevented.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamagePrevented.java index 5807e02e70a..8736ba600ee 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamagePrevented.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamagePrevented.java @@ -103,9 +103,9 @@ public class TriggerDamagePrevented extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Source, CardUtil.getLKICopy((Card)this.getRunParams().get("DamageSource"))); - sa.setTriggeringObject(AbilityKey.Target, this.getRunParams().get("DamageTarget")); - sa.setTriggeringObject(AbilityKey.DamageAmount, this.getRunParams().get("DamageAmount")); + sa.setTriggeringObject(AbilityKey.Source, CardUtil.getLKICopy((Card)getFromRunParams(AbilityKey.DamageSource))); + sa.setTriggeringObject(AbilityKey.Target, getFromRunParams(AbilityKey.DamageTarget)); + sa.setTriggeringObjectsFrom(this, AbilityKey.DamageAmount); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamagePreventedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamagePreventedOnce.java index b2cbf8ce369..9f6839167e7 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamagePreventedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamagePreventedOnce.java @@ -94,8 +94,8 @@ public class TriggerDamagePreventedOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Target, this.getRunParams().get("DamageTarget")); - sa.setTriggeringObject(AbilityKey.DamageAmount, this.getRunParams().get("DamageAmount")); + sa.setTriggeringObject(AbilityKey.Target, getFromRunParams(AbilityKey.DamageTarget)); + sa.setTriggeringObjectsFrom(this, AbilityKey.DamageAmount); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDestroyed.java b/forge-game/src/main/java/forge/game/trigger/TriggerDestroyed.java index 22a39539d54..a91c5f78802 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDestroyed.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDestroyed.java @@ -68,8 +68,7 @@ public class TriggerDestroyed extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Causer, this.getRunParams().get("Causer")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Causer); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDevoured.java b/forge-game/src/main/java/forge/game/trigger/TriggerDevoured.java index 9d2ab4a1d8e..6f87272938c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDevoured.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDevoured.java @@ -61,7 +61,7 @@ public class TriggerDevoured extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Devoured, this.getRunParams().get("Devoured")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Devoured); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDiscarded.java b/forge-game/src/main/java/forge/game/trigger/TriggerDiscarded.java index 5b046239a43..10acd4010df 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDiscarded.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDiscarded.java @@ -86,8 +86,7 @@ public class TriggerDiscarded extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Cause, this.getRunParams().get("Cause")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Cause); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDrawn.java b/forge-game/src/main/java/forge/game/trigger/TriggerDrawn.java index 30fae66a797..d8a88321e8f 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDrawn.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDrawn.java @@ -81,8 +81,7 @@ public class TriggerDrawn extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Player, getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerEvolved.java b/forge-game/src/main/java/forge/game/trigger/TriggerEvolved.java index 615c5e94f10..80bce94215c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerEvolved.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerEvolved.java @@ -62,7 +62,7 @@ public class TriggerEvolved extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerExerted.java b/forge-game/src/main/java/forge/game/trigger/TriggerExerted.java index b70e1fd4894..221bbcfd0a7 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerExerted.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerExerted.java @@ -33,8 +33,7 @@ public class TriggerExerted extends Trigger { @Override public void setTriggeringObjects(SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerExiled.java b/forge-game/src/main/java/forge/game/trigger/TriggerExiled.java index 0842e0732ae..bed1269155b 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerExiled.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerExiled.java @@ -97,7 +97,7 @@ public class TriggerExiled extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerExploited.java b/forge-game/src/main/java/forge/game/trigger/TriggerExploited.java index 49437a4b948..fbab5694a5e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerExploited.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerExploited.java @@ -72,8 +72,7 @@ public class TriggerExploited extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Exploited, this.getRunParams().get("Exploited")); - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Exploited, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerExplores.java b/forge-game/src/main/java/forge/game/trigger/TriggerExplores.java index 54f1ff15f54..93b9b14cae7 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerExplores.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerExplores.java @@ -62,7 +62,7 @@ public class TriggerExplores extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Explorer, this.getRunParams().get("Card")); + sa.setTriggeringObject(AbilityKey.Explorer, getFromRunParams(AbilityKey.Card)); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerFight.java b/forge-game/src/main/java/forge/game/trigger/TriggerFight.java index aecf04ca0db..414e42e698a 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerFight.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerFight.java @@ -63,7 +63,7 @@ public class TriggerFight extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Fighter, this.getRunParams().get("Fighter")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Fighter); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerFlippedCoin.java b/forge-game/src/main/java/forge/game/trigger/TriggerFlippedCoin.java index 45dbc6a8346..22ebf4ffd9a 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerFlippedCoin.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerFlippedCoin.java @@ -70,7 +70,7 @@ public class TriggerFlippedCoin extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerInvestigated.java b/forge-game/src/main/java/forge/game/trigger/TriggerInvestigated.java index 4673c43daaf..46ef04bdf7c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerInvestigated.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerInvestigated.java @@ -60,7 +60,7 @@ public class TriggerInvestigated extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } /** {@inheritDoc} */ diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerLandPlayed.java b/forge-game/src/main/java/forge/game/trigger/TriggerLandPlayed.java index 42facf2e807..9e06d86062a 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerLandPlayed.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerLandPlayed.java @@ -52,7 +52,7 @@ public class TriggerLandPlayed extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerLifeGained.java b/forge-game/src/main/java/forge/game/trigger/TriggerLifeGained.java index 9b13cc0d680..ab27b458c5c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerLifeGained.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerLifeGained.java @@ -74,8 +74,7 @@ public class TriggerLifeGained extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.LifeAmount, getRunParams().get("LifeAmount")); - sa.setTriggeringObject(AbilityKey.Player, getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.LifeAmount, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerLifeLost.java b/forge-game/src/main/java/forge/game/trigger/TriggerLifeLost.java index a592a376217..bd747b33932 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerLifeLost.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerLifeLost.java @@ -71,8 +71,7 @@ public class TriggerLifeLost extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.LifeAmount, this.getRunParams().get("LifeAmount")); - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.LifeAmount, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerLosesGame.java b/forge-game/src/main/java/forge/game/trigger/TriggerLosesGame.java index e55850fa631..1b1ad8f2389 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerLosesGame.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerLosesGame.java @@ -39,7 +39,7 @@ public class TriggerLosesGame extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPayCumulativeUpkeep.java b/forge-game/src/main/java/forge/game/trigger/TriggerPayCumulativeUpkeep.java index 51a74fa139e..c567c311cd6 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPayCumulativeUpkeep.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPayCumulativeUpkeep.java @@ -70,8 +70,7 @@ public class TriggerPayCumulativeUpkeep extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.PayingMana, this.getRunParams().get("PayingMana")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.PayingMana); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPayEcho.java b/forge-game/src/main/java/forge/game/trigger/TriggerPayEcho.java index d6f94a2ea0f..9eb5571b930 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPayEcho.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPayEcho.java @@ -70,7 +70,7 @@ public class TriggerPayEcho extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPayLife.java b/forge-game/src/main/java/forge/game/trigger/TriggerPayLife.java index 9ff7bd8f4a8..89cf4d10920 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPayLife.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPayLife.java @@ -61,8 +61,7 @@ public class TriggerPayLife extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.LifeAmount, getRunParams().get("LifeAmount")); - sa.setTriggeringObject(AbilityKey.Player, getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.LifeAmount, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPhase.java b/forge-game/src/main/java/forge/game/trigger/TriggerPhase.java index 974d40259e7..19bf36a0dda 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPhase.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPhase.java @@ -60,7 +60,7 @@ public class TriggerPhase extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPhaseIn.java b/forge-game/src/main/java/forge/game/trigger/TriggerPhaseIn.java index d519d56959e..c250dbe097d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPhaseIn.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPhaseIn.java @@ -28,7 +28,7 @@ public class TriggerPhaseIn extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPhaseOut.java b/forge-game/src/main/java/forge/game/trigger/TriggerPhaseOut.java index 7adcb00cc8b..9583ff22d6f 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPhaseOut.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPhaseOut.java @@ -36,7 +36,7 @@ public class TriggerPhaseOut extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPlanarDice.java b/forge-game/src/main/java/forge/game/trigger/TriggerPlanarDice.java index 4e1ccdf0a7e..e3b3ddd78ff 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPlanarDice.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPlanarDice.java @@ -56,7 +56,7 @@ public class TriggerPlanarDice extends Trigger { */ @Override public void setTriggeringObjects(SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedFrom.java b/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedFrom.java index 9cee000a7fe..3d9b36d339e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedFrom.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedFrom.java @@ -53,7 +53,7 @@ public class TriggerPlaneswalkedFrom extends Trigger { */ @Override public void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Cards, this.getRunParams().get("Cards")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Cards); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedTo.java b/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedTo.java index 5644c090053..efc3f2079dd 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedTo.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerPlaneswalkedTo.java @@ -53,7 +53,7 @@ public class TriggerPlaneswalkedTo extends Trigger { */ @Override public void setTriggeringObjects(SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Cards, this.getRunParams().get("Cards")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Cards); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerRegenerated.java b/forge-game/src/main/java/forge/game/trigger/TriggerRegenerated.java index 8eea96379ef..b1358375fa9 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerRegenerated.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerRegenerated.java @@ -68,8 +68,7 @@ public class TriggerRegenerated extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); - sa.setTriggeringObject(AbilityKey.Cause, this.getRunParams().get("Cause")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Cause); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerRevealed.java b/forge-game/src/main/java/forge/game/trigger/TriggerRevealed.java index b86e7b10439..096aff377a7 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerRevealed.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerRevealed.java @@ -32,7 +32,7 @@ public class TriggerRevealed extends Trigger { @Override public void setTriggeringObjects(SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSacrificed.java b/forge-game/src/main/java/forge/game/trigger/TriggerSacrificed.java index aac417535ef..4c4a05f110a 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSacrificed.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSacrificed.java @@ -126,7 +126,7 @@ public class TriggerSacrificed extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerScry.java b/forge-game/src/main/java/forge/game/trigger/TriggerScry.java index bd0f3cadac5..5202cec9429 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerScry.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerScry.java @@ -62,7 +62,7 @@ public class TriggerScry extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSearchedLibrary.java b/forge-game/src/main/java/forge/game/trigger/TriggerSearchedLibrary.java index 05fd3e062dc..da568d1437a 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSearchedLibrary.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSearchedLibrary.java @@ -74,7 +74,7 @@ public class TriggerSearchedLibrary extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSetInMotion.java b/forge-game/src/main/java/forge/game/trigger/TriggerSetInMotion.java index 1811c949573..92e1ccd981c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSetInMotion.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSetInMotion.java @@ -77,7 +77,7 @@ public class TriggerSetInMotion extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Scheme, this.getRunParams().get("Scheme")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Scheme); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerShuffled.java b/forge-game/src/main/java/forge/game/trigger/TriggerShuffled.java index ed801458055..4052524770e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerShuffled.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerShuffled.java @@ -74,7 +74,7 @@ public class TriggerShuffled extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCast.java b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCast.java index db43216f341..11085cc424e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCast.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCast.java @@ -264,17 +264,20 @@ public class TriggerSpellAbilityCast extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - final SpellAbility castSA = (SpellAbility) getRunParams().get("CastSA"); + final SpellAbility castSA = (SpellAbility) getFromRunParams(AbilityKey.CastSA); final SpellAbilityStackInstance si = sa.getHostCard().getGame().getStack().getInstanceFromSpellAbility(castSA); sa.setTriggeringObject(AbilityKey.Card, castSA.getHostCard()); sa.setTriggeringObject(AbilityKey.SpellAbility, castSA); sa.setTriggeringObject(AbilityKey.StackInstance, si); sa.setTriggeringObject(AbilityKey.SpellAbilityTargetingCards, (si != null ? si.getSpellAbility(true) : castSA).getTargets().getTargetCards()); - sa.setTriggeringObject(AbilityKey.Player, getRunParams().get("Player")); - sa.setTriggeringObject(AbilityKey.Activator, getRunParams().get("Activator")); - sa.setTriggeringObject(AbilityKey.CurrentStormCount, getRunParams().get("CurrentStormCount")); - sa.setTriggeringObject(AbilityKey.CurrentCastSpells, getRunParams().get("CurrentCastSpells")); - sa.setTriggeringObject(AbilityKey.CastSACMC, getRunParams().get("CastSACMC")); + sa.setTriggeringObjectsFrom( + this, + AbilityKey.Player, + AbilityKey.Activator, + AbilityKey.CurrentStormCount, + AbilityKey.CurrentCastSpells, + AbilityKey.CastSACMC + ); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCopy.java b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCopy.java index 4dc044312ac..f6b553e016f 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCopy.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSpellAbilityCopy.java @@ -91,7 +91,7 @@ public class TriggerSpellAbilityCopy extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - final SpellAbility copySA = (SpellAbility) getRunParams().get("CopySA"); + final SpellAbility copySA = (SpellAbility) getFromRunParams(AbilityKey.CopySA); final SpellAbilityStackInstance si = sa.getHostCard().getGame().getStack().getInstanceFromSpellAbility(copySA); sa.setTriggeringObject(AbilityKey.Card, copySA.getHostCard()); sa.setTriggeringObject(AbilityKey.SpellAbility, copySA); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSurveil.java b/forge-game/src/main/java/forge/game/trigger/TriggerSurveil.java index 374e97aa73a..740d7f5fd05 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerSurveil.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSurveil.java @@ -56,7 +56,7 @@ public class TriggerSurveil extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } /** {@inheritDoc} */ diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerTaps.java b/forge-game/src/main/java/forge/game/trigger/TriggerTaps.java index 421a34d71ac..fb3ef851185 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerTaps.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerTaps.java @@ -78,7 +78,7 @@ public class TriggerTaps extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerTransformed.java b/forge-game/src/main/java/forge/game/trigger/TriggerTransformed.java index ab5944ab9b0..a7d75887819 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerTransformed.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerTransformed.java @@ -59,7 +59,7 @@ public class TriggerTransformed extends Trigger { */ @Override public void setTriggeringObjects(SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Transformer, this.getRunParams().get("Transformer")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Transformer); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerTurnBegin.java b/forge-game/src/main/java/forge/game/trigger/TriggerTurnBegin.java index 0c6c879c4b9..eed574ed726 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerTurnBegin.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerTurnBegin.java @@ -21,7 +21,7 @@ public class TriggerTurnBegin extends Trigger { @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Player, this.getRunParams().get("Player")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Player); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java b/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java index 8aa74bb14d3..f5f70484e6d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java @@ -61,7 +61,7 @@ public class TriggerTurnFaceUp extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerUnattach.java b/forge-game/src/main/java/forge/game/trigger/TriggerUnattach.java index f68eb51c482..c7dc5511b0e 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerUnattach.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerUnattach.java @@ -73,8 +73,7 @@ public class TriggerUnattach extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Object, getRunParams().get("Object")); - sa.setTriggeringObject(AbilityKey.Attach, getRunParams().get("Attach")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Object, AbilityKey.Attach); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerUntaps.java b/forge-game/src/main/java/forge/game/trigger/TriggerUntaps.java index f06243482c8..f2f4443f329 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerUntaps.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerUntaps.java @@ -67,7 +67,7 @@ public class TriggerUntaps extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObject(AbilityKey.Card, this.getRunParams().get("Card")); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerVote.java b/forge-game/src/main/java/forge/game/trigger/TriggerVote.java index 07481b9571a..621e4df81a3 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerVote.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerVote.java @@ -65,8 +65,13 @@ public class TriggerVote extends Trigger { @Override public final void setTriggeringObjects(final SpellAbility sa) { @SuppressWarnings("unchecked") - final ListMultimap votes = (ArrayListMultimap) this.getRunParams().get("AllVotes"); - sa.setTriggeringObject(AbilityKey.OtherVoters, getVoters(this.getHostCard().getController(), votes, true, true)); + FCollection voters = getVoters( + this.getHostCard().getController(), + (ListMultimap) getFromRunParams(AbilityKey.AllVotes), + true, + true + ); + sa.setTriggeringObject(AbilityKey.OtherVoters, voters); } @Override From 30d37c11b07f61b998cb260758418bd9a76a003a Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Tue, 17 Sep 2019 19:40:45 -0600 Subject: [PATCH 03/37] remove import --- forge-game/src/main/java/forge/game/trigger/TriggerVote.java | 1 - 1 file changed, 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerVote.java b/forge-game/src/main/java/forge/game/trigger/TriggerVote.java index 621e4df81a3..abe296995c3 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerVote.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerVote.java @@ -20,7 +20,6 @@ package forge.game.trigger; import java.util.List; import java.util.Map; -import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import forge.game.ability.AbilityKey; From bafbe73bd65866eb8f86a77e6471e506d6ccb363 Mon Sep 17 00:00:00 2001 From: Ryan1729 Date: Wed, 18 Sep 2019 21:12:13 -0600 Subject: [PATCH 04/37] convert missed keys to enum --- forge-game/src/main/java/forge/game/zone/MagicStack.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index a70ed6c30cb..d0040eb9745 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -659,7 +659,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable Date: Fri, 20 Sep 2019 05:37:35 +0000 Subject: [PATCH 05/37] german translation update & fix some typos --- forge-gui/res/languages/de-DE.properties | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 994f8550aed..4a84d50e47a 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -179,8 +179,8 @@ KeyboardShortcuts=Tastenkombinationen lblAchievements=Errungenschaften # VSubmenuDownloaders.java btnDownloadSetPics=Bilder(LQ) Sets herunterladen -btnDownloadPicsHQ=Bilder(HQ Karten herunterladen (Sehr langsam!) btnDownloadPics=Bilder(LQ) Karten herunterladen +btnDownloadPicsHQ=Bilder(HQ) Karten herunterladen (Sehr langsam!) btnDownloadQuestImages=Bilder für Quests herunterladen btnDownloadAchievementImages=Bilder für Erfolge herunterladen btnReportBug=Einen Fehler melden @@ -389,7 +389,7 @@ lblVanguardDesc=Jeder Spieler hat eine eigene spielbeeinflussende \"Avatar\"-Kar lblCommander=Commander lblCommanderDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast) jederzeit gespielt werden kann und die Farben des Decks bestimmt. lblOathbreaker=Eidbrecher -lblOathbreakerDesc=Jeder Spieler hat eine Plainswalker-Karte als seinen "Eidbrecher", welche jederzeit gespielt werdeb kann und die Farben des Decks festlegt. Jeder Spieler hat außerdem noch einnen "Signatur"-Spruch, welcher gespielt werden kann, solange der Eidbrecher im Spiel ist. +lblOathbreakerDesc=Jeder Spieler hat eine Planeswalker-Karte als seinen "Eidbrecher", welche jederzeit gespielt werden kann und die Farben des Decks festlegt. Jeder Spieler hat außerdem noch einen "Signatur"-Spruch, welcher gespielt werden kann, solange der Eidbrecher im Spiel ist. lblTinyLeaders=Kleine Anführer lblTinyLeadersDesc=Jeder Spieler hat eine legendäre \"General\"-Karte, welche (fast) jederzeit gespielt werden kann und die Farben des Decks bestimmt. Alle Karten haben umgewandelte Manakosten von max. 3. lblBrawl=Brawl @@ -528,7 +528,7 @@ lblConstructedDecks=Konstruierte Decks lblCommanderDecks=Commander Decks lblRandomCommanderDecks=Zufälliges Commander Deck lblRandomCommanderCard-basedDecks=Zufälliges Commander Deck (kartenbasiert) -lblOathbreakerDecks=Oathbreaker-Decks +lblOathbreakerDecks=Eidbrecher-Decks lblTinyLeadersDecks=Kleine-Anführer-Decks lblBrawlDecks=Brawl Decks lblSchemeDecks=Komplott-Decks @@ -796,7 +796,7 @@ lbltoplanardeck=zum Weltendeck lbltoconspiracydeck=zum Verschwörungsdeck lblMove=Verschieben #VDock.java -lblDock=Anhängen +lblDock=Symbolleiste lblViewDeckList=Zeige Deckliste lblRevertLayout=Layout zurücksetzen lblOpenLayout=Lade Layout @@ -849,8 +849,8 @@ ttbtnRandDeck5=Erzeugt konstuiertes Deck in fünf Farben lblCurrentDeck2=aktuelles Deck lblUntitled=Unbenannt #VPrompt.java -lblPrompt=Abfrage -lblGameSetup=Spielaufbau +lblPrompt=Meldungen +lblGameSetup=Spielvorbereitung #ColumnDef.java lblAIStatus=KI-Status lblCMC=UMK @@ -891,13 +891,13 @@ lblSettings=Einstellungen #SettingsPage.java lblAutomaticBugReports=Automatischer Fehlerbericht lblBattlefieldTextureFiltering=Texturenfilter Spielfeld -lblCompactListItems=kompakte Liste -lblCompactTabs=kompakte Tabs +lblCompactListItems=Kompakte Liste +lblCompactTabs=Kompakte Tabs lblCardOverlays=Karten-Overlays lblDisableCardEffect=Karten-"Effekt"-Anzeige abschalten lblDynamicBackgroundPlanechase=Weltenjagd dynamischer Hintergrund lblGameplayOptions=Spiel-Optionen -lblGeneralSettings=allgem. Einstellungen +lblGeneralSettings=Allgem. Einstellungen lblHotSeatMode=Hot-Seat-Modus lblLandscapeMode=Querformat lblLater=Später @@ -912,7 +912,7 @@ lblShowCardManaCostOverlays=Blende die Manakosten der Karten ein lblShowCardNameOverlays=Blende den Namen der Karten ein lblShowCardOverlays=Zeige Karten-Einblendungen an lblShowCardPTOverlays=Blende Stärke und Widerstand ein -lblShowMatchBackground=Zeige Duell hintergund an +lblShowMatchBackground=Zeige Duell-Hintergund an lblVibrateAfterLongPress=Vibieren nach langem Tastendruck lblVibrateWhenLosingLife=Vibrieren nach Lebenspunktverlust lblVibrationOptions=Vibrationsoptionen @@ -971,6 +971,6 @@ lblCatalog=Katalog lblCommanders=Komandeure lblOathbreakers=Eidbrecher #Forge.java -lblLoadingFonts=Loading fonts... -lblLoadingCardTranslations=Loading card translations... -lblFinishingStartup=Finishing startup... \ No newline at end of file +lblLoadingFonts=Lade Schriften... +lblLoadingCardTranslations=Lade Kartenübersetzungen... +lblFinishingStartup=Abschliessen... From dfeeff6e3b713f11ab62db5e5451ffea963af6cd Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 20 Sep 2019 20:29:41 +0800 Subject: [PATCH 06/37] More ELD cards --- .../res/cardsfolder/upcoming/bloodhaze_wolverine.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/fabled_passage.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/festive_funeral.txt | 6 ++++++ forge-gui/res/cardsfolder/upcoming/foreboding_fruit.txt | 8 ++++++++ .../res/cardsfolder/upcoming/improbable_alliance.txt | 9 +++++++++ .../res/cardsfolder/upcoming/irencrag_pyromancer.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/locthwain_paladin.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/mad_ratter.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/mantle_of_tides.txt | 9 +++++++++ forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt | 9 +++++++++ forge-gui/res/tokenscripts/r_1_1_dwarf.txt | 6 ++++++ 11 files changed, 84 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/bloodhaze_wolverine.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/fabled_passage.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/festive_funeral.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/foreboding_fruit.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/improbable_alliance.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/irencrag_pyromancer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/locthwain_paladin.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/mad_ratter.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/mantle_of_tides.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt create mode 100644 forge-gui/res/tokenscripts/r_1_1_dwarf.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bloodhaze_wolverine.txt b/forge-gui/res/cardsfolder/upcoming/bloodhaze_wolverine.txt new file mode 100644 index 00000000000..9acbdf89503 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bloodhaze_wolverine.txt @@ -0,0 +1,7 @@ +Name:Bloodhaze Wolverine +ManaCost:1 R +Types:Creature Wolverine +PT:2/1 +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you draw your second card each turn, CARDNAME gets +1/+1 and gains first strike until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 1 | NumDef$ 1 | KW$ First Strike +Oracle:Whenever you draw your second card each turn, Bloodhaze Wolverine gets +1/+1 and gains first strike until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/fabled_passage.txt b/forge-gui/res/cardsfolder/upcoming/fabled_passage.txt new file mode 100644 index 00000000000..0dd3dd1dba4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fabled_passage.txt @@ -0,0 +1,7 @@ +Name:Fabled Passage +ManaCost:no cost +Types:Land +A:AB$ ChangeZone | Cost$ T Sac<1/CARDNAME> | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Basic | ChangeNum$ 1 | RememerChanged$ True | SubAbility$ DBUntap | SpellDescription$ Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. Then if you control four or more lands, untap that land. +SVar:DBUntap:DB$ Untap | Defined$ Remembered | ConditionPresent$ Land.YouCtrl | ConditionCompare$ GE4 | ConditionDescription$ If you control four or more lands, untap that land. | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:{T}, Sacrifice Fabled Passage: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. Then if you control four or more lands, untap that land. diff --git a/forge-gui/res/cardsfolder/upcoming/festive_funeral.txt b/forge-gui/res/cardsfolder/upcoming/festive_funeral.txt new file mode 100644 index 00000000000..cbf1ae394d0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/festive_funeral.txt @@ -0,0 +1,6 @@ +Name:Festive Funeral +ManaCost:4 B +Types:Instant +A:SP$ Pump | Cost$ 4 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -X | NumDef$ -X | IsCurse$ True | References$ X | SpellDescription$ Target creature gets -X/-X until end of turn, where X is the number of cards in your graveyard. +SVar:X:Count$InYourYard +Oracle:Target creature gets -X/-X until end of turn, where X is the number of cards in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/foreboding_fruit.txt b/forge-gui/res/cardsfolder/upcoming/foreboding_fruit.txt new file mode 100644 index 00000000000..b0137c2de2b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/foreboding_fruit.txt @@ -0,0 +1,8 @@ +Name:Foreboding Fruit +ManaCost:2 B +Types:Sorcery +A:SP$ Draw | Cost$ 2 B | NumCards$ 2 | ValidTgts$ Player | TgtPrompt$ Choose a player | SubAbility$ DBLoseLife | SpellDescription$ Target player draws two cards and loses 2 life. Adamant — If at least three black mana was spent to cast this spell, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 2 life.") +SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 2 | Defined$ Targeted | SubAbility$ DBToken +SVar:DBToken:DB$ Token | TokenAmount$ X | TokenScript$ c_a_food_sac | TokenOwner$ You | LegacyImage$ c a food sac eld | References$ X +SVar:X:Count$Adamant.Black.1.0 +Oracle:Target player draws two cards and loses 2 life.\nAdamant — If at least three black mana was spent to cast this spell, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 2 life.") diff --git a/forge-gui/res/cardsfolder/upcoming/improbable_alliance.txt b/forge-gui/res/cardsfolder/upcoming/improbable_alliance.txt new file mode 100644 index 00000000000..d202d4c64dc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/improbable_alliance.txt @@ -0,0 +1,9 @@ +Name:Improbable Alliance +ManaCost:U R +Types:Enchantment +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you draw your second card each turn, create a 1/1 blue Faerie creature token with flying. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ u_1_1_faerie_flying | TokenOwner$ You | LegacyImage$ u 1 1 faerie flying eld +A:AB$ Draw | Cost$ 4 U R | NumCards$ 1 | SpellDescription$ Draw a card, then discard a card. | SubAbility$ DBDiscard +SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose +AI:RemoveDeck:All +Oracle:Whenever you draw your second card each turn, create a 1/1 blue Faerie creature token with flying.\n{4}{U}{R}: Draw a card, then discard a card. diff --git a/forge-gui/res/cardsfolder/upcoming/irencrag_pyromancer.txt b/forge-gui/res/cardsfolder/upcoming/irencrag_pyromancer.txt new file mode 100644 index 00000000000..6559ba57551 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/irencrag_pyromancer.txt @@ -0,0 +1,8 @@ +Name:Irencrag Pyromancer +ManaCost:2 R +Types:Creature Human Wizard +PT:0/4 +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever you draw your second card each turn, CARDNAME deals 3 damage to any target. +SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 3 +AI:RemoveDeck:Random +Oracle:Whenever you draw your second card each turn, Irencrag Pyromancer deals 3 damage to any target. diff --git a/forge-gui/res/cardsfolder/upcoming/locthwain_paladin.txt b/forge-gui/res/cardsfolder/upcoming/locthwain_paladin.txt new file mode 100644 index 00000000000..e9e5f59d791 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/locthwain_paladin.txt @@ -0,0 +1,7 @@ +Name:Locthwain Paladin +ManaCost:3 B +Types:Creature Human Knight +PT:3/2 +K:Menace +K:etbCounter:P1P1:1:Adamant$ Black:Adamant — If at least three black mana was spent to cast this spell, CARDNAME enters the battlefield with a +1/+1 counter on it. +Oracle:Menace (This creature can't be blocked except by two or more creatures.)\nAdamant — If at least three black mana was spent to cast this spell, Locthwain Paladin enters the battlefield with a +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/upcoming/mad_ratter.txt b/forge-gui/res/cardsfolder/upcoming/mad_ratter.txt new file mode 100644 index 00000000000..dc66876f36f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mad_ratter.txt @@ -0,0 +1,8 @@ +Name:Mad Ratter +ManaCost:3 R +Types:Creature Goblin +PT:1/2 +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you draw your second card each turn, create two 1/1 black Rat creature tokens. +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ b_1_1_rat | TokenOwner$ You | LegacyImage$ b 1 1 rat eld +SVar:PlayMain1:TRUE +Oracle:Whenever you draw your second card each turn, create two 1/1 black Rat creature tokens. diff --git a/forge-gui/res/cardsfolder/upcoming/mantle_of_tides.txt b/forge-gui/res/cardsfolder/upcoming/mantle_of_tides.txt new file mode 100644 index 00000000000..28670bc5792 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mantle_of_tides.txt @@ -0,0 +1,9 @@ +Name:Mantle of Tides +ManaCost:U +Types:Artifact Equipment +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 2 | Description$ Equipped creature gets +1/+2. +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigAttach | TriggerDescription$ Whenever you draw your second card each turn, attach CARDNAME to target creature you control. +SVar:TrigAttach:DB$ Attach | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control +SVar:PlayMain1:TRUE +K:Equip:3 +Oracle:Equipped creature gets +1/+2.\nWhenever you draw your second card each turn, attach Mantle of Tides to target creature you control.\nEquip {3} ({3}: Attach to target creature you control. Equip only as a sorcery.) diff --git a/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt b/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt new file mode 100644 index 00000000000..f4f7e149b61 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt @@ -0,0 +1,9 @@ +Name:Mystic Sanctuary +ManaCost:no cost +Types:Land Island +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control three or more other Islands. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Island.YouCtrl+Other | ConditionCompare$ LT3 | SubAbility$ MoveToPlay +SVar:MoveToPlay:DB$ ChangeZone | Defined$ Self | Origin$ All | Destination$ Battlefield +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may put target instant or sorcery card from your graveyard on top of your library. +SVar:TrigChange:DB$ ChangeZone | TgtPrompt$ Choose target instant or sorcery card in your graveyard | ValidTgts$ Instant.YouOwn,Sorcery.YouOwn | Origin$ Graveyard | Destination$ Library +Oracle:({T}: Add {U}.)\nMystic Sanctuary enters the battlefield tapped unless you control three or more other Islands.\nWhen Mystic Sanctuary enters the battlefield untapped, you may put target instant or sorcery card from your graveyard on top of your library. diff --git a/forge-gui/res/tokenscripts/r_1_1_dwarf.txt b/forge-gui/res/tokenscripts/r_1_1_dwarf.txt new file mode 100644 index 00000000000..f6ff5776ddf --- /dev/null +++ b/forge-gui/res/tokenscripts/r_1_1_dwarf.txt @@ -0,0 +1,6 @@ +Name:Dwarf +ManaCost:no cost +Types:Creature Dwarf +Colors:red +PT:1/1 +Oracle: From e07504a55e5ba6ab1eb172550db01af47b84c3b8 Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 20 Sep 2019 20:37:06 +0800 Subject: [PATCH 07/37] Update 3 scripts --- forge-gui/res/cardsfolder/upcoming/idyllic_grange.txt | 3 +-- forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt | 2 +- forge-gui/res/cardsfolder/upcoming/witchs_cottage.txt | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/idyllic_grange.txt b/forge-gui/res/cardsfolder/upcoming/idyllic_grange.txt index bb0830870b0..41d7e14ea13 100644 --- a/forge-gui/res/cardsfolder/upcoming/idyllic_grange.txt +++ b/forge-gui/res/cardsfolder/upcoming/idyllic_grange.txt @@ -2,9 +2,8 @@ Name:Idyllic Grange ManaCost:no cost Types:Land Plains R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control three or more other Plains. -SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ LT3 | References$ ETBCheckSVar | SubAbility$ MoveToPlay +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Plains.YouCtrl+Other | ConditionCompare$ LT3 | SubAbility$ MoveToPlay SVar:MoveToPlay:DB$ ChangeZone | Defined$ Self | Origin$ All | Destination$ Battlefield -SVar:ETBCheckSVar:Count$Valid Plains.YouCtrl+Other T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+untapped | Execute$ TrigPutCounter | TriggerDescription$ When CARDNAME enters the battlefield untapped, put a +1/+1 counter on target creature you control. SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 1 Oracle:({T}: Add {W}.)\nIdyllic Grange enters the battlefield tapped unless you control three or more other Plains.\nWhen Idyllic Grange enters the battlefield untapped, put a +1/+1 counter on target creature you control. diff --git a/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt b/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt index f4f7e149b61..ceb98944205 100644 --- a/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt +++ b/forge-gui/res/cardsfolder/upcoming/mystic_sanctuary.txt @@ -4,6 +4,6 @@ Types:Land Island R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control three or more other Islands. SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Island.YouCtrl+Other | ConditionCompare$ LT3 | SubAbility$ MoveToPlay SVar:MoveToPlay:DB$ ChangeZone | Defined$ Self | Origin$ All | Destination$ Battlefield -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may put target instant or sorcery card from your graveyard on top of your library. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+untapped | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may put target instant or sorcery card from your graveyard on top of your library. SVar:TrigChange:DB$ ChangeZone | TgtPrompt$ Choose target instant or sorcery card in your graveyard | ValidTgts$ Instant.YouOwn,Sorcery.YouOwn | Origin$ Graveyard | Destination$ Library Oracle:({T}: Add {U}.)\nMystic Sanctuary enters the battlefield tapped unless you control three or more other Islands.\nWhen Mystic Sanctuary enters the battlefield untapped, you may put target instant or sorcery card from your graveyard on top of your library. diff --git a/forge-gui/res/cardsfolder/upcoming/witchs_cottage.txt b/forge-gui/res/cardsfolder/upcoming/witchs_cottage.txt index f961ea09bbd..4fd8616f7a5 100644 --- a/forge-gui/res/cardsfolder/upcoming/witchs_cottage.txt +++ b/forge-gui/res/cardsfolder/upcoming/witchs_cottage.txt @@ -2,9 +2,8 @@ Name:Witch's Cottage ManaCost:no cost Types:Land Swamp R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control three or more other Swamps. -SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ ETBCheckSVar | ConditionSVarCompare$ LT3 | References$ ETBCheckSVar | SubAbility$ MoveToPlay +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Swamp.YouCtrl+Other | ConditionCompare$ LT3 | SubAbility$ MoveToPlay SVar:MoveToPlay:DB$ ChangeZone | Defined$ Self | Origin$ All | Destination$ Battlefield -SVar:ETBCheckSVar:Count$Valid Swamp.YouCtrl+Other T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+untapped | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield untapped, you may put target creature card from your graveyard on top of your library. SVar:TrigChange:DB$ ChangeZone | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouOwn | Origin$ Graveyard | Destination$ Library Oracle:({T}: Add {B}.)\nWitch's Cottage enters the battlefield tapped unless you control three or more other Swamps.\nWhen Witch's Cottage enters the battlefield untapped, you may put target creature card from your graveyard on top of your library. From 96c840eebeee35efe9051e3dd67b002d3ef48490 Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 20 Sep 2019 20:54:16 +0800 Subject: [PATCH 08/37] More ELD cards --- .../cardsfolder/upcoming/return_of_the_wildspeaker.txt | 8 ++++++++ .../res/cardsfolder/upcoming/rosethorn_halberd.txt | 8 ++++++++ .../res/cardsfolder/upcoming/sage_of_the_falls.txt | 9 +++++++++ forge-gui/res/cardsfolder/upcoming/so_tiny.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/steelgaze_griffin.txt | 9 +++++++++ .../res/cardsfolder/upcoming/thrill_of_possibility.txt | 7 +++++++ 6 files changed, 51 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/return_of_the_wildspeaker.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/rosethorn_halberd.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/sage_of_the_falls.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/so_tiny.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/steelgaze_griffin.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/thrill_of_possibility.txt diff --git a/forge-gui/res/cardsfolder/upcoming/return_of_the_wildspeaker.txt b/forge-gui/res/cardsfolder/upcoming/return_of_the_wildspeaker.txt new file mode 100644 index 00000000000..25e67135c63 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/return_of_the_wildspeaker.txt @@ -0,0 +1,8 @@ +Name:Return of the Wildspeaker +ManaCost:4 G +Types:Instant +A:SP$ Charm | Cost$ 4 G | Choices$ DBDraw,DBPumpAll +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ X | References$ X | SpellDescription$ Draw cards equal to the greatest power among non-Human creatures you control. +SVar:X:Count$GreatestPower_Creature.YouCtrl+nonHuman +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl+nonHuman | NumAtt$ 3 | NumDef$ 3 | SpellDescription$ Non-Human creatures you control get +3/+3 until end of turn. +Oracle:Choose one —\n• Draw cards equal to the greatest power among non-Human creatures you control.\n• Non-Human creatures you control get +3/+3 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/rosethorn_halberd.txt b/forge-gui/res/cardsfolder/upcoming/rosethorn_halberd.txt new file mode 100644 index 00000000000..9d5682f0fb4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rosethorn_halberd.txt @@ -0,0 +1,8 @@ +Name:Rosethorn Halberd +ManaCost:G +Types:Artifact Equipment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAttach | TriggerDescription$ When CARDNAME enters the battlefield, attach it to target non-Human creature you control. +SVar:TrigAttach:DB$ Attach | ValidTgts$ Creature.nonHuman+YouCtrl | TgtPrompt$ Select target non-Human creature you control +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 1 | Description$ Equipped creature gets +2/+1. +K:Equip:5 +Oracle:When Rosethorn Halberd enters the battlefield, attach it to target non-Human creature you control.\nEquipped creature gets +2/+1.\nEquip {5} ({5}: Attach to target creature you control. Equip only as a sorcery.) diff --git a/forge-gui/res/cardsfolder/upcoming/sage_of_the_falls.txt b/forge-gui/res/cardsfolder/upcoming/sage_of_the_falls.txt new file mode 100644 index 00000000000..ab70f78266d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sage_of_the_falls.txt @@ -0,0 +1,9 @@ +Name:Sage of the Falls +ManaCost:4 U +Types:Creature Merfolk Wizard +PT:2/5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigLoot | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME or another non-Human creature enters the battlefield under you control, you may draw a card. If you do, discard a card. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonHuman+Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigLoot | OptionalDecider$ You | Secondary$ True | TriggerDescription$ Whenever CARDNAME or another non-Human creature enters the battlefield under you control, you may draw a card. If you do, discard a card. +SVar:TrigLoot:DB$ Draw | NumCards$ 1 | SubAbility$ DBDiscard +SVar:DBDiscard:DB$ Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1 +Oracle:Whenever Sage of the Falls or another non-Human creature enters the battlefield under you control, you may draw a card. If you do, discard a card. diff --git a/forge-gui/res/cardsfolder/upcoming/so_tiny.txt b/forge-gui/res/cardsfolder/upcoming/so_tiny.txt new file mode 100644 index 00000000000..8c4560df64b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/so_tiny.txt @@ -0,0 +1,10 @@ +Name:So Tiny +ManaCost:U +Types:Enchantment Aura +K:Flash +K:Enchant creature +A:SP$ Attach | Cost$ U | ValidTgts$ Creature | AILogic$ Curse +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ -X | References$ X,Y | Description$ Enchanted creature gets -2/-0. It gets -6/-0 instead as long as its controller has seven or more cards in their graveyard. +SVar:X:Count$Compare Y GE7.6.2 +SVar:Y:Count$ValidGraveyard Card.EnchantedControllerCtrl +Oracle:Flash\nEnchant creature\nEnchanted creature gets -2/-0. It gets -6/-0 instead as long as its controller has seven or more cards in their graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/steelgaze_griffin.txt b/forge-gui/res/cardsfolder/upcoming/steelgaze_griffin.txt new file mode 100644 index 00000000000..0b46be76958 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/steelgaze_griffin.txt @@ -0,0 +1,9 @@ +Name:Steelgaze Griffin +ManaCost:4 U +Types:Creature Griffin +PT:2/4 +K:Flying +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ When you draw your second card each turn, CARDNAME gets +2/+0 until end of turn. +SVar:TrigPump:DB$ Pump | NumAtt$ +2 | NumDef$ +0 | Defined$ Self +SVar:PlayMain1:TRUE +Oracle:Flying\nWhen you draw your second card each turn, Steelgaze Griffin gets +2/+0 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/thrill_of_possibility.txt b/forge-gui/res/cardsfolder/upcoming/thrill_of_possibility.txt new file mode 100644 index 00000000000..3536b7d3689 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/thrill_of_possibility.txt @@ -0,0 +1,7 @@ +Name:Thrill of Possibility +ManaCost:1 R +Types:Instant +A:SP$ Draw | Cost$ 1 R Discard<1/Card> | Defined$ You | NumCards$ 2 | SpellDescription$ Draw two cards. +DeckHas:Ability$Discard +DeckHints:Keyword$Madness & Ability$Delirium +Oracle:As an additional cost to cast this spell, discard a card.\nDraw two cards. From cb18c226496c177870357e694f7251f1e412a809 Mon Sep 17 00:00:00 2001 From: swordshine Date: Fri, 20 Sep 2019 21:29:36 +0800 Subject: [PATCH 09/37] Add Hushbringer --- .../src/main/java/forge/game/GlobalRuleChange.java | 1 + .../java/forge/game/trigger/TriggerHandler.java | 14 ++++++++++++++ forge-gui/res/cardsfolder/upcoming/hushbringer.txt | 10 ++++++++++ 3 files changed, 25 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/hushbringer.txt diff --git a/forge-game/src/main/java/forge/game/GlobalRuleChange.java b/forge-game/src/main/java/forge/game/GlobalRuleChange.java index 2e7fc2ca2ab..3eb37542dcf 100644 --- a/forge-game/src/main/java/forge/game/GlobalRuleChange.java +++ b/forge-game/src/main/java/forge/game/GlobalRuleChange.java @@ -27,6 +27,7 @@ public enum GlobalRuleChange { manapoolsDontEmpty ("Mana pools don't empty as steps and phases end."), noCycling ("Players can't cycle cards."), noCreatureETBTriggers ("Creatures entering the battlefield don't cause abilities to trigger."), + noCreatureDyingTriggers ("Creatures dying don't cause abilities to trigger."), noLegendRule ("The legend rule doesn't apply."), noPrevention ("Damage can't be prevented."), /* onlyOneAttackerATurn ("No more than one creature can attack each turn."), */ diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index cf2f159ae65..39bb51ff6af 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -541,6 +541,20 @@ public class TriggerHandler { } } } // Torpor Orb check + + if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noCreatureDyingTriggers) + && !regtrig.isStatic() && mode.equals(TriggerType.ChangesZone)) { + if (runParams.get(AbilityKey.Destination) instanceof String && runParams.get(AbilityKey.Origin) instanceof String) { + final String dest = (String) runParams.get(AbilityKey.Destination); + final String origin = (String) runParams.get(AbilityKey.Origin); + if (dest.equals("Graveyard") && origin.equals("Battlefield") && runParams.get(AbilityKey.Card) instanceof Card) { + final Card card = (Card) runParams.get(AbilityKey.Card); + if (card.isCreature()) { + return false; + } + } + } + } return true; } diff --git a/forge-gui/res/cardsfolder/upcoming/hushbringer.txt b/forge-gui/res/cardsfolder/upcoming/hushbringer.txt new file mode 100644 index 00000000000..3fc0204661c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hushbringer.txt @@ -0,0 +1,10 @@ +Name:Hushbringer +ManaCost:1 W +Types:Creature Faerie +PT:1/2 +K:Flying +K:Lifelink +S:Mode$ Continuous | GlobalRule$ Creatures entering the battlefield don't cause abilities to trigger. | Description$ Creatures entering the battlefield or dying don't cause abilities to trigger. +S:Mode$ Continuous | GlobalRule$ Creatures dying don't cause abilities to trigger. | Secondary$ True | Description$ Creatures entering the battlefield or dying don't cause abilities to trigger. +AI:RemoveDeck:Random +Oracle:Flying, lifelink\nCreatures entering the battlefield or dying don't cause abilities to trigger. From 0c354e8a704a09461988923ebeff6e0541ad2aaa Mon Sep 17 00:00:00 2001 From: Hanmac Date: Sun, 8 Sep 2019 09:30:48 +0200 Subject: [PATCH 10/37] Adventure: add Logic to cast as Spell --- .../main/java/forge/card/CardSplitType.java | 3 +- .../main/java/forge/card/CardStateName.java | 1 + .../src/main/java/forge/game/GameAction.java | 4 ++ .../main/java/forge/game/GameActionUtil.java | 14 ++++++ .../src/main/java/forge/game/card/Card.java | 48 ++++++++++++++++--- .../java/forge/game/card/CardFactory.java | 9 +++- .../java/forge/game/card/CardFactoryUtil.java | 26 ++++++++++ .../forge/game/spellability/SpellAbility.java | 7 +++ .../foulmire_knight_profane_insight.txt | 16 +++++++ 9 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/foulmire_knight_profane_insight.txt diff --git a/forge-core/src/main/java/forge/card/CardSplitType.java b/forge-core/src/main/java/forge/card/CardSplitType.java index a949ec8b975..f1e53ed0898 100644 --- a/forge-core/src/main/java/forge/card/CardSplitType.java +++ b/forge-core/src/main/java/forge/card/CardSplitType.java @@ -8,7 +8,8 @@ public enum CardSplitType Transform(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Transformed), Meld(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Meld), Split(FaceSelectionMethod.COMBINE, CardStateName.RightSplit), - Flip(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Flipped); + Flip(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Flipped), + Adventure(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Adventure); CardSplitType(FaceSelectionMethod calcMode, CardStateName stateName) { method = calcMode; diff --git a/forge-core/src/main/java/forge/card/CardStateName.java b/forge-core/src/main/java/forge/card/CardStateName.java index b7333a7de23..70b857dc5c8 100644 --- a/forge-core/src/main/java/forge/card/CardStateName.java +++ b/forge-core/src/main/java/forge/card/CardStateName.java @@ -9,6 +9,7 @@ public enum CardStateName { Meld, LeftSplit, RightSplit, + Adventure, ; diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 908f2bc678e..d45c5794e99 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -146,6 +146,10 @@ public class GameAction { } } + // if an adventureCard is put from Stack somewhere else, need to reset to Original State + if (c.isAdventureCard() && (zoneFrom.is(ZoneType.Stack) || !zoneTo.is(ZoneType.Stack))) { + c.setState(CardStateName.Original, true); + } // Clean up the temporary Dash SVar when the Dashed card leaves the battlefield // Clean up the temporary AtEOT SVar diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index e425d2fff6e..5db2ff403e6 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -22,6 +22,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import forge.card.CardStateName; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostParser; import forge.game.ability.AbilityUtils; @@ -101,6 +102,19 @@ public final class GameActionUtil { } source.turnFaceDownNoUpdate(); lkicheck = true; + } else if (sa.isAdventure() && !source.isInZone(ZoneType.Battlefield)) { + if (!source.isLKI()) { + source = CardUtil.getLKICopy(source); + } + // need way to copy adventure state + if (!source.hasState(CardStateName.Adventure)) { + source.addAlternateState(CardStateName.Adventure, false); + source.getState(CardStateName.Adventure).copyFrom( + sa.getHostCard().getState(CardStateName.Adventure), true); + } + + source.setState(CardStateName.Adventure, false); + lkicheck = true; } if (lkicheck) { 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 99ecc3df0ea..3e16bf717b3 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -351,9 +351,12 @@ public class Card extends GameEntity implements Comparable { else if (isDoubleFaced() && currentStateName != CardStateName.Transformed) { return CardStateName.Transformed; } - else if (this.isMeldable() && currentStateName != CardStateName.Meld) { + else if (isMeldable() && currentStateName != CardStateName.Meld) { return CardStateName.Meld; } + else if (this.isAdventureCard() && currentStateName != CardStateName.Adventure) { + return CardStateName.Adventure; + } else { return CardStateName.Original; } @@ -803,6 +806,10 @@ public class Card extends GameEntity implements Comparable { return getRules() != null && getRules().getSplitType() == CardSplitType.Split; } + public final boolean isAdventureCard() { + return getRules() != null && getRules().getSplitType() == CardSplitType.Adventure; + } + public final boolean isBackSide() { return backside; } @@ -1989,7 +1996,19 @@ public class Card extends GameEntity implements Comparable { continue; } - final String sAbility = formatSpellAbility(sa); + String sAbility = formatSpellAbility(sa); + + // add Adventure to AbilityText + if (sa.isAdventure() && state.getView().getState().equals(CardStateName.Original)) { + StringBuilder sbSA = new StringBuilder(); + sbSA.append("Adventure ").append(getState(CardStateName.Adventure).getName()); + if (sa.getPayCosts() != null) { + sbSA.append(" ").append(sa.getPayCosts().toSimpleString()); + } + sbSA.append(": "); + sbSA.append(sAbility); + sAbility = sbSA.toString(); + } if (sa.getManaPart() != null) { if (addedManaStrings.contains(sAbility)) { @@ -2397,10 +2416,21 @@ public class Card extends GameEntity implements Comparable { // add Facedown abilities from Original state but only if this state is face down // need CardStateView#getState or might crash in StackOverflow - if ((mana == null || mana == false) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) { - for (SpellAbility sa : getState(CardStateName.Original).getNonManaAbilities()) { - if (sa.isManifestUp() || sa.isMorphUp()) { - list.add(sa); + if (isInZone(ZoneType.Battlefield)) { + if ((mana == null || mana == false) && isFaceDown() && state.getView().getState() == CardStateName.FaceDown) { + for (SpellAbility sa : getState(CardStateName.Original).getNonManaAbilities()) { + if (sa.isManifestUp() || sa.isMorphUp()) { + list.add(sa); + } + } + } + } else { + // Adenture may only be cast not from Battlefield + if (isAdventureCard() && state.getView().getState() == CardStateName.Original) { + for (SpellAbility sa : getState(CardStateName.Adventure).getSpellAbilities()) { + if (mana == null || mana == sa.isManaAbility()) { + list.add(sa); + } } } } @@ -5731,6 +5761,12 @@ public class Card extends GameEntity implements Comparable { } public void setSplitStateToPlayAbility(final SpellAbility sa) { + if (isAdventureCard()) { + if (sa.isAdventure()) { + setState(CardStateName.Adventure, true); + } + return; + } if (!isSplitCard()) { return; // just in case } diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 98dab46962d..115f53982e2 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -305,6 +305,11 @@ public class CardFactory { } else if (c.isMeldable() && cp instanceof PaperCard) { c.setState(CardStateName.Meld, false); c.setImageKey(cp.getImageKey(true)); + } else if (c.isAdventureCard()) { + c.setState(CardStateName.Adventure, false); + c.setImageKey(originalPicture); + c.setSetCode(cp.getEdition()); + c.setRarity(cp.getRarity()); } c.setSetCode(cp.getEdition()); @@ -325,7 +330,6 @@ public class CardFactory { // ****************************************************************** // ************** Link to different CardFactories ******************* - if (state == CardStateName.LeftSplit || state == CardStateName.RightSplit) { for (final SpellAbility sa : card.getSpellAbilities()) { if (state == CardStateName.LeftSplit) { @@ -342,6 +346,9 @@ public class CardFactory { } else if (state != CardStateName.Original){ CardFactoryUtil.setupKeywordedAbilities(card); } + if (state == CardStateName.Adventure) { + CardFactoryUtil.setupAdventureAbility(card); + } } card.setState(CardStateName.Original, false); 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 829f0979785..4ef2afa3fee 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -4738,4 +4738,30 @@ public class CardFactoryUtil { } return byClause + StringUtils.join(orClauses, " or ") + "."; } + + public static void setupAdventureAbility(Card card) { + if (card.getCurrentStateName() != CardStateName.Adventure) { + return; + } + SpellAbility sa = card.getFirstSpellAbility(); + if (sa == null) { + return; + } + sa.setAdventure(true); + + String abExile = "DB$ ChangeZone | Defined$ Self | Origin$ Stack | Destination$ Exile | StackDescription$ None"; + + AbilitySub saExile = (AbilitySub)AbilityFactory.getAbility(abExile, card); + + String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile"; + AbilitySub saEffect = (AbilitySub)AbilityFactory.getAbility(abEffect, card); + + StringBuilder sb = new StringBuilder(); + sb.append("Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonAdventure"); + sb.append(" | AffectedZone$ Exile | Description$ You may cast the card."); + saEffect.setSVar("Play", sb.toString()); + + saExile.setSubAbility(saEffect); + sa.appendSubAbility(saExile); + } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index fb7c64c7d80..65a653a4e66 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -118,6 +118,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private boolean basicLandAbility = false; + private boolean adventure = false; private SplitSide splitSide = null; enum SplitSide { LEFT, RIGHT } @@ -852,6 +853,12 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public void setRightSplit() { splitSide = SplitSide.RIGHT; } + public boolean isAdventure() { + return this.adventure; + } + public void setAdventure(boolean adventure) { + this.adventure = adventure; + } public SpellAbility copy() { return copy(hostCard, false); diff --git a/forge-gui/res/cardsfolder/upcoming/foulmire_knight_profane_insight.txt b/forge-gui/res/cardsfolder/upcoming/foulmire_knight_profane_insight.txt new file mode 100644 index 00000000000..7965754d32f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/foulmire_knight_profane_insight.txt @@ -0,0 +1,16 @@ +Name:Foulmire Knight +ManaCost:B +Types:Creature Zombie Knight +PT:1/1 +K:Deathtouch +Oracle:Deathtouch +AlternateMode:Adventure + +ALTERNATE + +Name:Profane Insight +ManaCost:2 B +Types:Instant Adventure +A:SP$ Draw | Cost$ 2 B | Defined$ You | NumCards$ 1 | SubAbility$ DBLoseLife | SpellDescription$ You draw a card and you lose 1 life. +SVar:DBLoseLife:DB$LoseLife | Defined$ You | LifeAmount$ 1 +Oracle:You draw a card and you lose 1 life. From 378d0e26ab0616d9f147fdf1a85dd5f8b37d5a12 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Sun, 8 Sep 2019 23:40:56 +0200 Subject: [PATCH 11/37] Adventure: add - separator --- forge-game/src/main/java/forge/game/card/Card.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3e16bf717b3..a2d5ef9ff22 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2001,7 +2001,7 @@ public class Card extends GameEntity implements Comparable { // add Adventure to AbilityText if (sa.isAdventure() && state.getView().getState().equals(CardStateName.Original)) { StringBuilder sbSA = new StringBuilder(); - sbSA.append("Adventure ").append(getState(CardStateName.Adventure).getName()); + sbSA.append("Adventure — ").append(getState(CardStateName.Adventure).getName()); if (sa.getPayCosts() != null) { sbSA.append(" ").append(sa.getPayCosts().toSimpleString()); } From 94805103da02d55bce61eb8dfd7bfa3c6cff8e32 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Thu, 12 Sep 2019 08:15:00 +0000 Subject: [PATCH 12/37] Spell: add extra check for Adventure cards --- .../java/forge/game/spellability/Spell.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/forge-game/src/main/java/forge/game/spellability/Spell.java b/forge-game/src/main/java/forge/game/spellability/Spell.java index b3761737538..0c41a3fc6b3 100644 --- a/forge-game/src/main/java/forge/game/spellability/Spell.java +++ b/forge-game/src/main/java/forge/game/spellability/Spell.java @@ -100,6 +100,10 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable if (card.isSplitCard()) { CardStateName name = isLeftSplit() ? CardStateName.LeftSplit : CardStateName.RightSplit; isInstant = card.getState(name).getType().isInstant(); + } else if (isAdventure()) { + if (card.hasState(CardStateName.Adventure)) { + isInstant = card.getState(CardStateName.Adventure).getType().isInstant(); + } } boolean lkicheck = false; @@ -130,6 +134,19 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable } card.turnFaceDownNoUpdate(); lkicheck = true; + } else if (isAdventure()) { + if (!card.isLKI()) { + card = CardUtil.getLKICopy(card); + } + // need way to copy adventure state + if (!card.hasState(CardStateName.Adventure)) { + card.addAlternateState(CardStateName.Adventure, false); + card.getState(CardStateName.Adventure).copyFrom( + getHostCard().getState(CardStateName.Adventure), true); + } + + card.setState(CardStateName.Adventure, false); + lkicheck = true; } From d9dd31b263126c9ab4b99a8658d89b55d2aa3662 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Fri, 13 Sep 2019 10:31:40 +0000 Subject: [PATCH 13/37] ELD: Animating Faerie --- .../upcoming/animating_faerie_bring_to_life.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/animating_faerie_bring_to_life.txt diff --git a/forge-gui/res/cardsfolder/upcoming/animating_faerie_bring_to_life.txt b/forge-gui/res/cardsfolder/upcoming/animating_faerie_bring_to_life.txt new file mode 100644 index 00000000000..c499d5251d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/animating_faerie_bring_to_life.txt @@ -0,0 +1,16 @@ +Name:Animating Faerie +ManaCost:2 U +Types:Creature Faerie +PT:2/2 +K:Flying +Oracle:Flying +AlternateMode:Adventure + +ALTERNATE + +Name:Bring to Life +ManaCost:2 U +Types:Sorcery Adventure +A:SP$ Animate | Cost$ 2 U | ValidTgts$ Artifact.nonCreature+YouCtrl | TgtPrompt$ Select noncreature artifact | Power$ 0 | Toughness$ 0 | Types$ Artifact,Creature | RemoveCardTypes$ True | Permanent$ True | SubAbility$ DBPutCounter | SpellDescription$ Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on it. +SVar:DBPutCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ P1P1 | CounterNum$ 4 +Oracle:Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on it. \ No newline at end of file From 7a504bf3c851c6b22c94ac309b2b7704385ddcc4 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Fri, 13 Sep 2019 10:49:53 +0000 Subject: [PATCH 14/37] Update CardFactoryUtil.java --- forge-game/src/main/java/forge/game/card/CardFactoryUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4ef2afa3fee..a4598259209 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -4753,7 +4753,7 @@ public class CardFactoryUtil { AbilitySub saExile = (AbilitySub)AbilityFactory.getAbility(abExile, card); - String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile"; + String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile | Duration$ Permanent"; AbilitySub saEffect = (AbilitySub)AbilityFactory.getAbility(abEffect, card); StringBuilder sb = new StringBuilder(); From feaa01f70cff338f31709e5ef3eee4badb3a7b13 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Fri, 13 Sep 2019 12:50:54 +0000 Subject: [PATCH 15/37] ELD: Merchant of the Vale --- .../upcoming/merchant_of_the_vale_haggle.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/merchant_of_the_vale_haggle.txt diff --git a/forge-gui/res/cardsfolder/upcoming/merchant_of_the_vale_haggle.txt b/forge-gui/res/cardsfolder/upcoming/merchant_of_the_vale_haggle.txt new file mode 100644 index 00000000000..e88a20025ec --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/merchant_of_the_vale_haggle.txt @@ -0,0 +1,17 @@ +Name:Merchant of the Vale +ManaCost:2 R +Types:Creature Human Peasant +PT:2/3 +A:AB$ Draw | Cost$ 2 R Discard<1/Card> | NumCards$ 1 | Defined$ You | SpellDescription$ Draw a card. +Oracle:{2}{R}, Discard a card: Draw a card. +AlternateMode:Adventure + +ALTERNATE + +Name:Haggle +ManaCost:R +Types:Instant Adventure +A:SP$ Discard | Cost$ R | NumCards$ 1 | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBDraw | SpellDescription$ You may discard a card. If you do, draw a card. +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:You may discard a card. If you do, draw a card. (Then exile this card. You may cast the creature later from exile.) \ No newline at end of file From 1e7ed8452214c001abaaeb51bc8ecc52e7ce566a Mon Sep 17 00:00:00 2001 From: Hanmac Date: Sun, 15 Sep 2019 17:55:05 +0200 Subject: [PATCH 16/37] CardProperty: add AdventureCard for Creature with adventure --- .../src/main/java/forge/game/card/CardProperty.java | 4 ++++ forge-gui/res/cardsfolder/upcoming/edgewall_innkeeper.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/wandermare.txt | 8 ++++++++ 3 files changed, 19 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/edgewall_innkeeper.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/wandermare.txt diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 3a2969c98eb..73cccee915e 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -107,6 +107,10 @@ public class CardProperty { if (card.isSplitCard()) { return false; } + } else if (property.equals("AdventureCard")) { + if (!card.isAdventureCard()) { + return false; + } } else if (property.startsWith("leftcmc") || property.startsWith("rightcmc")) { int x; int y = 0; diff --git a/forge-gui/res/cardsfolder/upcoming/edgewall_innkeeper.txt b/forge-gui/res/cardsfolder/upcoming/edgewall_innkeeper.txt new file mode 100644 index 00000000000..db027f357e7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/edgewall_innkeeper.txt @@ -0,0 +1,7 @@ +Name:Edgewall Innkeeper +ManaCost:G +Types:Creature Human Peasant +PT:1/1 +T:Mode$ SpellCast | ValidCard$ Creature.AdventureCard | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell that has an Adventure, draw a card. +SVar:TrigDraw:DB$Draw | Defined$ You | NumCards$ 1 +Oracle:Whenever you cast a creature spell that has an Adventure, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/wandermare.txt b/forge-gui/res/cardsfolder/upcoming/wandermare.txt new file mode 100644 index 00000000000..75c4b295306 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wandermare.txt @@ -0,0 +1,8 @@ +Name:Wandermare +ManaCost:1 G W +Types:Creature Horse +PT:3/3 +T:Mode$ SpellCast | ValidCard$ Creature.AdventureCard | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell that has an Adventure, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters +Oracle:Whenever you cast a creature spell that has an Adventure, put a +1/+1 counter on Wandermare. (It doesn’t need to have gone on the adventure first.) From b7b1c3a4370433cd5ae2af9ac7e56d59ebed9e65 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Fri, 20 Sep 2019 16:20:35 +0200 Subject: [PATCH 17/37] As Foretold: fix the cmc check --- .../main/java/forge/game/GameActionUtil.java | 46 +++++++++++++------ .../java/forge/game/card/CardProperty.java | 22 --------- forge-gui/res/cardsfolder/a/as_foretold.txt | 4 +- 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index 5db2ff403e6..be395f2f6d2 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -114,6 +114,38 @@ public final class GameActionUtil { } source.setState(CardStateName.Adventure, false); + + // need to reset CMC + source.setLKICMC(-1); + source.setLKICMC(source.getCMC()); + lkicheck = true; + } else if (source.isSplitCard() && (sa.isLeftSplit() || sa.isRightSplit())) { + if (!source.isLKI()) { + source = CardUtil.getLKICopy(source); + } + if (sa.isLeftSplit()) { + if (!source.hasState(CardStateName.LeftSplit)) { + source.addAlternateState(CardStateName.LeftSplit, false); + source.getState(CardStateName.LeftSplit).copyFrom( + sa.getHostCard().getState(CardStateName.LeftSplit), true); + } + + source.setState(CardStateName.LeftSplit, false); + } + + if (sa.isRightSplit()) { + if (!source.hasState(CardStateName.RightSplit)) { + source.addAlternateState(CardStateName.RightSplit, false); + source.getState(CardStateName.RightSplit).copyFrom( + sa.getHostCard().getState(CardStateName.RightSplit), true); + } + + source.setState(CardStateName.RightSplit, false); + } + + // need to reset CMC + source.setLKICMC(-1); + source.setLKICMC(source.getCMC()); lkicheck = true; } @@ -146,20 +178,6 @@ public final class GameActionUtil { newSA = sa.copyWithManaCostReplaced(activator, o.getAltManaCost()); newSA.setBasicSpell(false); changedManaCost = true; - if (host.hasSVar("AsForetoldSplitCMCHack")) { - // TODO: This is a temporary workaround for As Foretold interaction with split cards, better solution needed. - if (sa.isLeftSplit()) { - int leftCMC = sa.getHostCard().getCMC(Card.SplitCMCMode.LeftSplitCMC); - if (leftCMC > host.getCounters(CounterType.TIME)) { - continue; - } - } else if (sa.isRightSplit()) { - int rightCMC = sa.getHostCard().getCMC(Card.SplitCMCMode.RightSplitCMC); - if (rightCMC > host.getCounters(CounterType.TIME)) { - continue; - } - } - } } else { newSA = sa.copy(activator); } diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 73cccee915e..34674f9c52f 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -111,28 +111,6 @@ public class CardProperty { if (!card.isAdventureCard()) { return false; } - } else if (property.startsWith("leftcmc") || property.startsWith("rightcmc")) { - int x; - int y = 0; - String rhs = ""; - - if (property.startsWith("leftcmc")) { - rhs = property.substring(9); - y = card.getCMC(Card.SplitCMCMode.LeftSplitCMC); - } else if (property.startsWith("rightcmc")) { - rhs = property.substring(10); - y = card.getCMC(Card.SplitCMCMode.RightSplitCMC); - } - - try { - x = Integer.parseInt(rhs); - } catch (final NumberFormatException e) { - x = AbilityUtils.calculateAmount(source, rhs, spellAbility); - } - - if (!Expressions.compare(y, property, x)) { - return false; - } } else if (property.startsWith("YouCtrl")) { if (!controller.equals(sourceController)) { return false; diff --git a/forge-gui/res/cardsfolder/a/as_foretold.txt b/forge-gui/res/cardsfolder/a/as_foretold.txt index cfc3e86bd67..b282a3d18af 100644 --- a/forge-gui/res/cardsfolder/a/as_foretold.txt +++ b/forge-gui/res/cardsfolder/a/as_foretold.txt @@ -3,9 +3,7 @@ ManaCost:2 U Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your upkeep, put a time counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ TIME | CounterNum$ 1 -S:Mode$ Continuous | MayPlay$ True | MayPlayAltManaCost$ 0 | MayPlayLimit$ 1 | MayPlayDontGrantZonePermissions$ True | Affected$ Card.YouCtrl+NotSplit+nonLand+cmcLEX | AffectedZone$ Hand,Graveyard,Library,Exile,Command | Description$ Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast with converted mana cost X or less, where X is the number of time counters on CARDNAME. -S:Mode$ Continuous | MayPlay$ True | MayPlayAltManaCost$ 0 | MayPlayLimit$ 1 | MayPlayDontGrantZonePermissions$ True | Affected$ Card.YouCtrl+Split+nonLand+leftcmcLEX,Card.YouCtrl+Split+nonLand+rightcmcLEX | AffectedZone$ Hand,Graveyard,Library,Exile,Command | Secondary$ True +S:Mode$ Continuous | MayPlay$ True | MayPlayAltManaCost$ 0 | MayPlayLimit$ 1 | MayPlayDontGrantZonePermissions$ True | Affected$ Card.YouCtrl+nonLand+cmcLEX | AffectedZone$ Hand,Graveyard,Library,Exile,Command | Description$ Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast with converted mana cost X or less, where X is the number of time counters on CARDNAME. SVar:X:Count$CardCounters.TIME -SVar:AsForetoldSplitCMCHack:TRUE SVar:Picture:http://www.wizards.com/global/images/magic/general/as_foretold.jpg Oracle:At the beginning of your upkeep, put a time counter on As Foretold.\nOnce each turn, you may pay {0} rather than pay the mana cost for a spell you cast with converted mana cost X or less, where X is the number of time counters on As Foretold. From 9b3fa50deefe011281670e799d1410c08558ef1d Mon Sep 17 00:00:00 2001 From: Hanmac Date: Fri, 20 Sep 2019 18:03:06 +0200 Subject: [PATCH 18/37] Adventure: If an object becomes a copy of an object that has an Adventure, the copy also has an Adventure. --- forge-game/src/main/java/forge/game/GameActionUtil.java | 6 ------ forge-game/src/main/java/forge/game/card/Card.java | 2 +- forge-game/src/main/java/forge/game/card/CardFactory.java | 8 ++++++++ .../src/main/java/forge/game/card/CardFactoryUtil.java | 2 +- .../src/main/java/forge/game/card/CardProperty.java | 8 ++++++++ forge-game/src/main/java/forge/game/card/CardUtil.java | 5 +++++ .../src/main/java/forge/game/spellability/Spell.java | 6 ------ .../res/cardsfolder/upcoming/mysterious_pathlighter.txt | 8 ++++++++ 8 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/mysterious_pathlighter.txt diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index be395f2f6d2..b0575c15420 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -106,12 +106,6 @@ public final class GameActionUtil { if (!source.isLKI()) { source = CardUtil.getLKICopy(source); } - // need way to copy adventure state - if (!source.hasState(CardStateName.Adventure)) { - source.addAlternateState(CardStateName.Adventure, false); - source.getState(CardStateName.Adventure).copyFrom( - sa.getHostCard().getState(CardStateName.Adventure), true); - } source.setState(CardStateName.Adventure, false); 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 a2d5ef9ff22..7044c836f46 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -807,7 +807,7 @@ public class Card extends GameEntity implements Comparable { } public final boolean isAdventureCard() { - return getRules() != null && getRules().getSplitType() == CardSplitType.Adventure; + return hasState(CardStateName.Adventure); } public final boolean isBackSide() { diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 115f53982e2..ecbfaeae056 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -735,6 +735,14 @@ public class CardFactory { final CardState ret2 = new CardState(out, CardStateName.Flipped); ret2.copyFrom(in.getState(CardStateName.Flipped, true), false); result.put(CardStateName.Flipped, ret2); + } else if (in.isAdventureCard()) { + final CardState ret1 = new CardState(out, CardStateName.Original); + ret1.copyFrom(in.getState(CardStateName.Original, true), false); + result.put(CardStateName.Original, ret1); + + final CardState ret2 = new CardState(out, CardStateName.Adventure); + ret2.copyFrom(in.getState(CardStateName.Adventure, true), false); + result.put(CardStateName.Adventure, ret2); } else { // in all other cases just copy the current state to original final CardState ret = new CardState(out, CardStateName.Original); 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 a4598259209..d5176500cef 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -4753,7 +4753,7 @@ public class CardFactoryUtil { AbilitySub saExile = (AbilitySub)AbilityFactory.getAbility(abExile, card); - String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile | Duration$ Permanent"; + String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell"; AbilitySub saEffect = (AbilitySub)AbilityFactory.getAbility(abEffect, card); StringBuilder sb = new StringBuilder(); diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 34674f9c52f..3de4411ab84 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -1340,6 +1340,14 @@ public class CardProperty { if (card.isToken()) { return false; } + } else if (property.startsWith("copiedSpell")) { + if (!card.isCopiedSpell()) { + return false; + } + } else if (property.startsWith("nonCopiedSpell")) { + if (card.isCopiedSpell()) { + return false; + } } else if (property.startsWith("hasXCost")) { SpellAbility sa1 = card.getFirstSpellAbility(); if (sa1 != null && !sa1.isXCost()) { 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 4dcd5e489bf..82a306157e0 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -225,6 +225,11 @@ public final class CardUtil { newCopy.turnFaceDownNoUpdate(); } + if (in.isAdventureCard() && in.getFaceupCardStateName().equals(CardStateName.Original)) { + newCopy.addAlternateState(CardStateName.Adventure, false); + newCopy.getState(CardStateName.Adventure).copyFrom(in.getState(CardStateName.Adventure), true); + } + /* if (in.isCloned()) { newCopy.addAlternateState(CardStateName.Cloner, false); diff --git a/forge-game/src/main/java/forge/game/spellability/Spell.java b/forge-game/src/main/java/forge/game/spellability/Spell.java index 0c41a3fc6b3..51a83100632 100644 --- a/forge-game/src/main/java/forge/game/spellability/Spell.java +++ b/forge-game/src/main/java/forge/game/spellability/Spell.java @@ -138,12 +138,6 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable if (!card.isLKI()) { card = CardUtil.getLKICopy(card); } - // need way to copy adventure state - if (!card.hasState(CardStateName.Adventure)) { - card.addAlternateState(CardStateName.Adventure, false); - card.getState(CardStateName.Adventure).copyFrom( - getHostCard().getState(CardStateName.Adventure), true); - } card.setState(CardStateName.Adventure, false); lkicheck = true; diff --git a/forge-gui/res/cardsfolder/upcoming/mysterious_pathlighter.txt b/forge-gui/res/cardsfolder/upcoming/mysterious_pathlighter.txt new file mode 100644 index 00000000000..251f8db2232 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mysterious_pathlighter.txt @@ -0,0 +1,8 @@ +Name:Mysterious Pathlighter +ManaCost:2 W +Types:Creature Faerie +PT:2/2 +K:Flying +K:ETBReplacement:Other:AddExtraCounter:Mandatory:Battlefield:Creature.YouCtrl+AdventureCard +SVar:AddExtraCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Each creature you control that has an Adventure enters the battlefield with an additional +1/+1 counter on it. +Oracle:Flying\nEach creature you control that has an Adventure enters the battlefield with an additional +1/+1 counter on it. From fc1d5543d86eca41b1482d8b7572ea1e0a56c0d6 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 10:21:52 +0800 Subject: [PATCH 19/37] More ELD cards --- forge-gui/res/cardsfolder/upcoming/barrow_witches.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/charmed_sleep.txt | 9 +++++++++ .../res/cardsfolder/upcoming/crashing_drawbridge.txt | 8 ++++++++ .../res/cardsfolder/upcoming/didnt_say_please.txt | 6 ++++++ forge-gui/res/cardsfolder/upcoming/dwarven_mine.txt | 9 +++++++++ forge-gui/res/cardsfolder/upcoming/flutterfox.txt | 8 ++++++++ .../res/cardsfolder/upcoming/gingerbread_cabin.txt | 9 +++++++++ .../cardsfolder/upcoming/kenriths_transformation.txt | 10 ++++++++++ forge-gui/res/cardsfolder/upcoming/lash_of_thorns.txt | 5 +++++ .../res/cardsfolder/upcoming/locthwain_gargoyle.txt | 6 ++++++ .../res/cardsfolder/upcoming/malevolent_noble.txt | 7 +++++++ .../res/cardsfolder/upcoming/moonlit_scavengers.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/outflank.txt | 6 ++++++ forge-gui/res/cardsfolder/upcoming/prized_griffin.txt | 6 ++++++ .../res/cardsfolder/upcoming/prophet_of_the_peak.txt | 7 +++++++ .../res/cardsfolder/upcoming/scalding_cauldron.txt | 5 +++++ .../res/cardsfolder/upcoming/signpost_scarecrow.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/weapon_rack.txt | 7 +++++++ 18 files changed, 131 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/barrow_witches.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/charmed_sleep.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/crashing_drawbridge.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/didnt_say_please.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/dwarven_mine.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/flutterfox.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/gingerbread_cabin.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/kenriths_transformation.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/lash_of_thorns.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/locthwain_gargoyle.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/malevolent_noble.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/moonlit_scavengers.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/outflank.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/prized_griffin.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/prophet_of_the_peak.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/scalding_cauldron.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/signpost_scarecrow.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/weapon_rack.txt diff --git a/forge-gui/res/cardsfolder/upcoming/barrow_witches.txt b/forge-gui/res/cardsfolder/upcoming/barrow_witches.txt new file mode 100644 index 00000000000..1a1c3481fc6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/barrow_witches.txt @@ -0,0 +1,7 @@ +Name:Barrow Witches +ManaCost:4 B +Types:Creature Human Warlock +PT:3/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, return target Knight card from your graveyard to your hand. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Card.Knight+YouOwn | TgtPrompt$ Select target Knight card in your graveyard +Oracle:When Barrow Witches enters the battlefield, return target Knight card from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/charmed_sleep.txt b/forge-gui/res/cardsfolder/upcoming/charmed_sleep.txt new file mode 100644 index 00000000000..cd6d7905644 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/charmed_sleep.txt @@ -0,0 +1,9 @@ +Name:Charmed Sleep +ManaCost:1 U U +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | Cost$ 1 U U | ValidTgts$ Creature | AILogic$ KeepTapped +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigTap | TriggerDescription$ When CARDNAME enters the battlefield, tap enchanted creature. +SVar:TrigTap:DB$ Tap | Defined$ Enchanted +S:Mode$ Continuous | Affected$ Creature.AttachedBy | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Enchanted creature doesn't untap during its controller's untap step. +Oracle:Enchant creature\nWhen Charmed Sleep enters the battlefield, tap enchanted creature.\nEnchanted creature doesn't untap during its controller's untap step. diff --git a/forge-gui/res/cardsfolder/upcoming/crashing_drawbridge.txt b/forge-gui/res/cardsfolder/upcoming/crashing_drawbridge.txt new file mode 100644 index 00000000000..a151407909c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/crashing_drawbridge.txt @@ -0,0 +1,8 @@ +Name:Crashing Drawbridge +ManaCost:2 +Types:Artifact Creature Wall +PT:0/4 +K:Defender +A:AB$ PumpAll | Cost$ T | ValidCards$ Creature.YouCtrl | KW$ Haste | SpellDescription$ Creatures you control gain haste until end of turn. +SVar:PlayMain1:TRUE +Oracle:Defender\n{T}: Creatures you control gain haste until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/didnt_say_please.txt b/forge-gui/res/cardsfolder/upcoming/didnt_say_please.txt new file mode 100644 index 00000000000..34abf9c05cc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/didnt_say_please.txt @@ -0,0 +1,6 @@ +Name:Didn't Say Please +ManaCost:1 U U +Types:Instant +A:SP$ Counter | Cost$ 1 U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | SubAbility$ DBMill | Destination$ Graveyard | SpellDescription$ Counter target spell. Its controller puts the top three cards of their library into their graveyard. +SVar:DBMill:DB$ Mill | NumCards$ 3 | Defined$ TargetedController +Oracle:Counter target spell. Its controller puts the top three cards of their library into their graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/dwarven_mine.txt b/forge-gui/res/cardsfolder/upcoming/dwarven_mine.txt new file mode 100644 index 00000000000..197f174e6af --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dwarven_mine.txt @@ -0,0 +1,9 @@ +Name:Dwarven Mine +ManaCost:no cost +Types:Land Mountain +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control three or more other Mountains. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Mountain.YouCtrl+Other | ConditionCompare$ LT3 | SubAbility$ MoveToPlay +SVar:MoveToPlay:DB$ ChangeZone | Defined$ Self | Origin$ All | Destination$ Battlefield +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+untapped | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield untapped, create a 1/1 red Dwarf creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_1_1_dwarf | TokenOwner$ You | LegacyImage$ r 1 1 dwarf eld +Oracle:({T}: Add {R}.)\nDwarven Mine enters the battlefield tapped unless you control three or more other Mountains.\nWhen Dwarven Mine enters the battlefield untapped, create a 1/1 red Dwarf creature token. diff --git a/forge-gui/res/cardsfolder/upcoming/flutterfox.txt b/forge-gui/res/cardsfolder/upcoming/flutterfox.txt new file mode 100644 index 00000000000..784eefaefa8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/flutterfox.txt @@ -0,0 +1,8 @@ +Name:Flutterfox +ManaCost:1 W +Types:Creature Fox +PT:2/2 +S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Flying | IsPresent$ Artifact.YouCtrl,Enchantment.YouCtrl | Description$ As long as you control an artifact or enchantment, CARDNAME has flying. +SVar:BuffedBy:Artifact,Enchantment +DeckHints:Type$Artifact | Enchantment +Oracle:As long as you control an artifact or enchantment, Flutterfox has flying. diff --git a/forge-gui/res/cardsfolder/upcoming/gingerbread_cabin.txt b/forge-gui/res/cardsfolder/upcoming/gingerbread_cabin.txt new file mode 100644 index 00000000000..4c04e707f06 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/gingerbread_cabin.txt @@ -0,0 +1,9 @@ +Name:Gingerbread Cabin +ManaCost:no cost +Types:Land Forest +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | Description$ CARDNAME enters the battlefield tapped unless you control three or more other Forests. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Forest.YouCtrl+Other | ConditionCompare$ LT3 | SubAbility$ MoveToPlay +SVar:MoveToPlay:DB$ ChangeZone | Defined$ Self | Origin$ All | Destination$ Battlefield +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+untapped | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield untapped, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life."). +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_food_sac | TokenOwner$ You | LegacyImage$ c a food sac eld +Oracle:({T}: Add {G}.)\nGingerbread Cabin enters the battlefield tapped unless you control three or more other Forests.\nWhen Gingerbread Cabin enters the battlefield untapped, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") diff --git a/forge-gui/res/cardsfolder/upcoming/kenriths_transformation.txt b/forge-gui/res/cardsfolder/upcoming/kenriths_transformation.txt new file mode 100644 index 00000000000..3d67fe04c55 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/kenriths_transformation.txt @@ -0,0 +1,10 @@ +Name:Kenrith's Transformation +ManaCost:1 G +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | Cost$ 1 G | ValidTgts$ Creature | AILogic$ Curse +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, draw a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | SetPower$ 3 | SetToughness$ 3 | SetColor$ Green | RemoveAllAbilities$ True | AddType$ Creature & Elk | RemoveCardTypes$ True | Description$ Enchanted creature loses all abilities and is a green Elk creature with base power and toughness 3/3. (It loses all other card types and creature types.) +AI:RemoveDeck:All +Oracle:Enchant creature\nWhen Kenrith's Transformation enters the battlefield, draw a card.\nEnchanted creature loses all abilities and is a green Elk creature with base power and toughness 3/3. (It loses all other card types and creature types.) diff --git a/forge-gui/res/cardsfolder/upcoming/lash_of_thorns.txt b/forge-gui/res/cardsfolder/upcoming/lash_of_thorns.txt new file mode 100644 index 00000000000..41cdb1bc16f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lash_of_thorns.txt @@ -0,0 +1,5 @@ +Name:Lash of Thorns +ManaCost:B +Types:Instant +A:SP$ Pump | Cost$ B | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +1 | KW$ Deathtouch | SpellDescription$ Target creature gets +2/+1 and gains deathtouch until end of turn. +Oracle:Target creature gets +2/+1 and gains deathtouch until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/locthwain_gargoyle.txt b/forge-gui/res/cardsfolder/upcoming/locthwain_gargoyle.txt new file mode 100644 index 00000000000..04296299e19 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/locthwain_gargoyle.txt @@ -0,0 +1,6 @@ +Name:Locthwain Gargoyle +ManaCost:1 +Types:Artifact Creature Gargoyle +PT:0/3 +A:AB$ Pump | Cost$ 4 | Defined$ Self | NumAtt$ +2 | KW$ Flying | SpellDescription$ CARDNAME gets +2/+0 and gains flying until end of turn. +Oracle:{4}: Locthwain Gargoyle gets +2/+0 and gains flying until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/malevolent_noble.txt b/forge-gui/res/cardsfolder/upcoming/malevolent_noble.txt new file mode 100644 index 00000000000..da201c52c09 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/malevolent_noble.txt @@ -0,0 +1,7 @@ +Name:Malevolent Noble +ManaCost:1 B +Types:Creature Human Noble +PT:2/2 +A:AB$ PutCounter | Cost$ 2 Sac<1/Artifact;Creature.Other/artifact or another creature> | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. +DeckHas:Ability$Counters +Oracle:{2}, Sacrifice an artifact or another creature: Put a +1/+1 counter on Malevolent Noble. diff --git a/forge-gui/res/cardsfolder/upcoming/moonlit_scavengers.txt b/forge-gui/res/cardsfolder/upcoming/moonlit_scavengers.txt new file mode 100644 index 00000000000..cd15aac54b4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/moonlit_scavengers.txt @@ -0,0 +1,8 @@ +Name:Moonlit Scavengers +ManaCost:5 U +Types:Creature Merfolk Rogue +PT:4/5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigBounce | IsPresent$ Artifact.YouCtrl,Enchantment.YouCtrl | TriggerDescription$ When CARDNAME enters the battlefield, if you control an artifact or enchantment, return target creature an opponent controls to its owner's hand. +SVar:TrigBounce:DB$ ChangeZone | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | Origin$ Battlefield | Destination$ Hand +DeckHints:Type$Artifact,Enchantment +Oracle:When Moonlit Scavengers enters the battlefield, if you control an artifact or enchantment, return target creature an opponent controls to its owner's hand. diff --git a/forge-gui/res/cardsfolder/upcoming/outflank.txt b/forge-gui/res/cardsfolder/upcoming/outflank.txt new file mode 100644 index 00000000000..91018e361cc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/outflank.txt @@ -0,0 +1,6 @@ +Name:Outflank +ManaCost:W +Types:Instant +A:SP$ DealDamage | Cost$ W | ValidTgts$ Creature.attacking,Creature.blocking | TgtPrompt$ Select target attacking or blocking creature | NumDmg$ X | References$ X | SpellDescription$ CARDNAME deals damage to target attacking or blocking creature equal to the number of creatures you control. +SVar:X:Count$Valid Creature.YouCtrl +Oracle:Outflank deals damage to target attacking or blocking creature equal to the number of creatures you control. diff --git a/forge-gui/res/cardsfolder/upcoming/prized_griffin.txt b/forge-gui/res/cardsfolder/upcoming/prized_griffin.txt new file mode 100644 index 00000000000..c4962f97200 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/prized_griffin.txt @@ -0,0 +1,6 @@ +Name:Prized Griffin +ManaCost:4 W +Types:Creature Griffin +PT:3/4 +K:Flying +Oracle:Flying diff --git a/forge-gui/res/cardsfolder/upcoming/prophet_of_the_peak.txt b/forge-gui/res/cardsfolder/upcoming/prophet_of_the_peak.txt new file mode 100644 index 00000000000..00fef71ae6f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/prophet_of_the_peak.txt @@ -0,0 +1,7 @@ +Name:Prophet of the Peak +ManaCost:6 +Types:Artifact Creature Cat +PT:5/5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When CARDNAME enters the battlefield, scry 2. +SVar:TrigScry:DB$ Scry | ScryNum$ 2 +Oracle:When Prophet of the Peak enters the battlefield, scry 2. diff --git a/forge-gui/res/cardsfolder/upcoming/scalding_cauldron.txt b/forge-gui/res/cardsfolder/upcoming/scalding_cauldron.txt new file mode 100644 index 00000000000..efd2e3e83ab --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/scalding_cauldron.txt @@ -0,0 +1,5 @@ +Name:Scalding Cauldron +ManaCost:1 +Types:Artifact +A:AB$ DealDamage | Cost$ 3 T Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 3 | SpellDescription$ CARDNAME deals 3 damage to target creature. +Oracle:{3}, {T}, Sacrifice Scalding Cauldron: It deals 3 damage to target creature. diff --git a/forge-gui/res/cardsfolder/upcoming/signpost_scarecrow.txt b/forge-gui/res/cardsfolder/upcoming/signpost_scarecrow.txt new file mode 100644 index 00000000000..43726093f21 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/signpost_scarecrow.txt @@ -0,0 +1,8 @@ +Name:Signpost Scarecrow +ManaCost:4 +Types:Artifact Creature Scarecrow +PT:2/4 +K:Vigilance +A:AB$ Mana | Cost$ 2 | Produced$ Any | SpellDescription$ Add one mana of any color. +AI:RemoveDeck:All +Oracle:Vigilance\n{2}: Add one mana of any color. diff --git a/forge-gui/res/cardsfolder/upcoming/weapon_rack.txt b/forge-gui/res/cardsfolder/upcoming/weapon_rack.txt new file mode 100644 index 00000000000..2b6da1154be --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/weapon_rack.txt @@ -0,0 +1,7 @@ +Name:Weapon Rack +ManaCost:4 +Types:Artifact +K:etbCounter:P1P1:3 +A:AB$ MoveCounter | Cost$ T | Source$ Self | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SorcerySpeed$ True | SpellDescription$ Move a +1/+1 counter from CARDNAME onto target creature. Activate this ability only any time you could cast a sorcery. +AI:RemoveDeck:All +Oracle:Weapon Rack enters the battlefield with three +1/+1 counters on it.\n{T}: Move a +1/+1 counter from Weapon Rack onto target creature. Activate this ability only any time you could cast a sorcery. From f938366d4091d0fe0d5814ee95cc50e2932abc4f Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 10:38:57 +0800 Subject: [PATCH 20/37] Update ELD edition file --- forge-gui/res/editions/Throne of Eldraine.txt | 318 +++++++++++++++++- 1 file changed, 317 insertions(+), 1 deletion(-) diff --git a/forge-gui/res/editions/Throne of Eldraine.txt b/forge-gui/res/editions/Throne of Eldraine.txt index 9c3a37d5ba1..96a50f4671a 100644 --- a/forge-gui/res/editions/Throne of Eldraine.txt +++ b/forge-gui/res/editions/Throne of Eldraine.txt @@ -9,8 +9,324 @@ BoosterCovers=3 Booster=10 Common, 3 Uncommon, 1 RareMythic, 1 BasicLand [cards] +1 R Acclaimed Contender +2 U All That Glitters +3 U Archon of Absolution +4 C Ardenvale Paladin +5 C Ardenvale Tactician // Dizzying Swoop +6 C Bartered Cow +7 C Beloved Princess +8 R Charming Prince +9 M The Circle of Loyalty +10 U Deafening Silence +11 C Faerie Guidemother // Gift of the Fae +12 C Flutterfox +13 C Fortifying Provisions +14 R Giant Killer // Chop Down +15 U Glass Casket +16 R Happily Ever After +17 M Harmonious Archon +18 R Hushbringer +19 C Knight of the Keep +20 R Linden, the Steadfast Queen +21 C Lonesome Unicorn // Rider in Need +22 U Mysterious Pathlighter +23 C Outflank +24 C Prized Griffin +25 U Rally for the Throne +26 M Realm-Cloaked Giant // Cast Off +27 U Righteousness +28 U Shepherd of the Flock // Usher to Safety +29 C Shining Armor +30 C Silverflame Ritual +31 C Silverflame Squire // On Alert +32 U Syr Alin, the Lion's Claw +33 C Trapped in the Tower +34 C True Love's Kiss +35 U Venerable Knight +36 R Worthy Knight +37 C Youthful Knight +38 U Animating Faerie // Bring to Life +39 M Brazen Borrower // Petty Theft +40 C Charmed Sleep +41 C Corridor Monitor +42 C Didn't Say Please +43 R Emry, Lurker of the Loch +44 R Fae of Wishes // Granted +45 U Faerie Vandal +46 R Folio of Fancies +47 U Frogify +48 R Gadwick, the Wizened +49 U Hypnotic Sprite // Mesmeric Glare +50 U Into the Story +51 M The Magic Mirror +52 C Mantle of Tides +53 C Merfolk Secretkeeper // Venture Deeper +54 R Midnight Clock +55 R Mirrormade +56 C Mistford River Turtle +57 C Moonlit Scavengers +58 U Mystical Dispute +59 C Opt +60 U Overwhelmed Apprentice +61 C Queen of Ice // Rage of Winter +62 C Run Away Together +63 U Sage of the Falls +64 C So Tiny +65 C Steelgaze Griffin +66 R Stolen by the Fae +67 U Syr Elenora, the Discerning +68 C Tome Raider +69 U Turn into a Pumpkin +70 C Unexplained Vision +71 R Vantress Gargoyle +72 C Vantress Paladin +73 C Wishful Merfolk +74 C Witching Well +75 R Ayara, First of Locthwain +76 C Bake into a Pie +77 C Barrow Witches +78 U Belle of the Brawl +79 R Blacklance Paragon +80 U Bog Naughty +81 U Cauldron Familiar +82 M The Cauldron of Eternity +83 U Cauldron's Gift +84 R Clackbridge Troll +85 U Epic Downfall +86 C Eye Collector +87 C Festive Funeral +88 C Foreboding Fruit +89 C Forever Young +90 U Foulmire Knight // Profane Insight +91 C Giant's Skewer +92 C Lash of Thorns +93 C Locthwain Paladin +94 C Lost Legion +95 C Malevolent Noble +96 C Memory Theft +97 R Murderous Rider // Swift End +98 R Oathsworn Knight +99 U Order of Midnight // Alter Fate +100 R Piper of the Swarm +101 M Rankle, Master of Pranks +102 C Reaper of Night // Harvest Fear +103 C Reave Soul +104 U Revenge of Ravens +105 C Smitten Swordmaster // Curry Favor +106 U Specter's Shriek +107 U Syr Konrad, the Grim +108 C Tempting Witch +109 C Wicked Guardian +110 R Wishclaw Talisman +111 R Witch's Vengeance +112 C Barge In +113 C Bloodhaze Wolverine +114 C Blow Your House Down +115 R Bonecrusher Giant // Stomp +116 C Brimstone Trebuchet +117 U Burning-Yard Trainer +118 U Claim the Firstborn +119 C Crystal Slipper +120 M Embercleave +121 C Embereth Paladin +122 U Embereth Shieldbreaker // Battle Display +123 U Ferocity of the Wilds +124 R Fervent Champion +125 R Fires of Invention +126 C Fling +127 R Irencrag Feat +128 R Irencrag Pyromancer +129 U Joust +130 U Mad Ratter +131 C Merchant of the Vale // Haggle +132 C Ogre Errant +133 R Opportunistic Dragon +134 C Raging Redcap +135 U Redcap Melee +136 C Redcap Raiders +137 C Rimrock Knight // Boulder Rush +138 M Robber of the Rich +139 C Scorching Dragonfire +140 C Searing Barrage +141 C Seven Dwarves +142 U Skullknocker Ogre +143 U Slaying Fire +144 R Sundering Stroke +145 U Syr Carah, the Bold +146 C Thrill of Possibility +147 R Torbran, Thane of Red Fell +148 C Weaselback Redcap +149 U Beanstalk Giant // Fertile Footsteps +150 C Curious Pair // Treats to Share +151 U Edgewall Innkeeper +152 R Feasting Troll King +153 C Fell the Pheasant +154 C Fierce Witchstalker +155 U Flaxen Intruder // Welcome Home +156 C Garenbrig Carver // Shield's Might +157 C Garenbrig Paladin +158 C Garenbrig Squire +159 U Giant Opportunity +160 R Gilded Goose +161 M The Great Henge +162 C Insatiable Appetite +163 U Keeper of Fables +164 U Kenrith's Transformation +165 R Lovestruck Beast // Heart's Desire +166 C Maraleaf Rider +167 U Oakhame Adversary +168 U Once and Future +169 R Once Upon a Time +170 C Outmuscle +171 M Questing Beast +172 R Return of the Wildspeaker +173 C Return to Nature +174 C Rosethorn Acolyte // Seasonal Ritual +175 C Rosethorn Halberd +176 C Sporecap Spider +177 U Syr Faren, the Hengehammer +178 C Tall as a Beanstalk +179 U Trail of Crumbs +180 C Tuinvale Treefolk // Oaken Boon +181 R Wicked Wolf +182 R Wildborn Preserver +183 C Wildwood Tracker +184 C Wolf's Quarry +185 R Yorvo, Lord of Garenbrig +186 R Dance of the Manse +187 R Doom Foretold +188 U Drown in the Loch +189 R Escape to the Wilds +190 R Faeburrow Elder +191 M Garruk, Cursed Huntsman +192 U Grumgully, the Generous +193 U Improbable Alliance +194 U Inspiring Veteran +195 R Lochmere Serpent +196 U Maraleaf Pixie +197 M Oko, Thief of Crowns +198 M Outlaws' Merriment +199 M The Royal Scions +200 U Savvy Hunter +201 U Shinechaser +202 U Steelclaw Lance +203 R Stormfist Crusader +204 U Wandermare +205 U Wintermoor Commander +206 U Arcanist's Owl +207 U Covetous Urge +208 U Deathless Knight +209 U Elite Headhunter +210 U Fireborn Knight +211 U Loch Dragon +212 U Oakhame Ranger // Bring Back +213 U Rampart Smasher +214 U Resolute Rider +215 U Thunderous Snapper +216 U Clockwork Servant +217 C Crashing Drawbridge +218 U Enchanted Carriage +219 C Gingerbrute +220 C Golden Egg +221 C Henge Walker +222 U Heraldic Banner +223 U Inquisitive Puppet +224 C Jousting Dummy +225 C Locthwain Gargoyle +226 U Lucky Clover +227 C Prophet of the Peak +228 C Roving Keep +229 C Scalding Cauldron +230 U Shambling Suit +231 C Signpost Scarecrow +232 U Sorcerer's Broom +233 R Sorcerous Spyglass +234 U Spinning Wheel +235 R Stonecoil Serpent +236 C Weapon Rack +237 U Witch's Oven +238 R Castle Ardenvale +239 R Castle Embereth +240 R Castle Garenbrig +241 R Castle Locthwain +242 R Castle Vantress +243 C Dwarven Mine +244 R Fabled Passage +245 C Gingerbread Cabin +246 C Idyllic Grange +247 C Mystic Sanctuary +248 U Tournament Grounds +249 C Witch's Cottage +250 C Plains +251 C Plains +252 C Plains +253 C Plains +254 C Island +255 C Island +256 C Island +257 C Island +258 C Swamp +259 C Swamp +260 C Swamp +261 C Swamp +262 C Mountain +263 C Mountain +264 C Mountain +265 C Mountain +266 C Forest +267 C Forest +268 C Forest +269 C Forest +303 M Kenrith, the Returned King +304 M Rowan, Fearless Sparkmage +305 C Garrison Griffin +306 U Rowan's Battleguard +307 R Rowan's Stalwarts +308 C Wind-Scarred Crag +309 M Oko, the Trickster +310 C Oko's Accomplices +311 U Bramblefort Fink +312 R Oko's Hospitality +313 C Thornwood Falls +314 R Mace of the Valiant +315 R Silverwing Squadron +316 R Faerie Formation +317 R Shimmer Dragon +318 R Workshop Elders +319 R Chittering Witch +320 R Taste of Death +321 R Embereth Skyblazer +322 R Steelbane Hydra +323 R Thorn Mammoth +324 M Alela, Artful Provocateur +325 R Banish into Fable 326 M Chulane, Teller of Tales +327 R Gluttonous Troll +328 R Knights' Charge +329 M Korvold, Fae-Cursed King +330 M Syr Gwyn, Hero of Ashvale 331 C Arcane Signet +332 R Tome of Legends +333 C Command Tower [tokens] - +w_0_1_goat +w_1_1_human +w_2_2_knight_vigilance +w_1_1_mouse +u_1_1_faerie_flying +b_1_1_rat +r_1_1_dwarf +g_2_2_bear +g_1_1_boar_food +g_7_7_giant +rw_2_1_human_cleric_lifelink_haste +rw_1_2_human_rogue_haste_damage +rw_3_1_human_warrior_trample_haste +bg_2_2_wolf_garruk +c_a_food_sac +c_a_food_sac +c_a_food_sac +c_a_food_sac +emblem_garruk_cursed_hunstman From 3887dc1440907771c495b05f71b12a05bf8e8b6e Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 11:53:29 +0800 Subject: [PATCH 21/37] Add Beanstalk Giant --- .../beanstalk_giant_fertile_footsteps.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/beanstalk_giant_fertile_footsteps.txt diff --git a/forge-gui/res/cardsfolder/upcoming/beanstalk_giant_fertile_footsteps.txt b/forge-gui/res/cardsfolder/upcoming/beanstalk_giant_fertile_footsteps.txt new file mode 100644 index 00000000000..943f8d1dbfe --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/beanstalk_giant_fertile_footsteps.txt @@ -0,0 +1,16 @@ +Name:Beanstalk Giant +ManaCost:6 G +Types:Creature Giant +PT:*/* +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of lands you control. +SVar:X:Count$Valid Land.YouCtrl +Oracle:Beanstalk Giant's power and toughness are each equal to the number of lands you control. +AlternateMode:Adventure + +ALTERNATE + +Name:Fertile Footsteps +ManaCost:2 G +Types:Sorcery Adventure +A:SP$ ChangeZone | Cost$ 2 G | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ 1 | SpellDescription$ Search your library for a basic land card, put it onto the battlefield, then shuffle your library. +Oracle:Search your library for a basic land card, put it onto the battlefield, then shuffle your library. From 18cd8d68e16979124298a6d9a3eca4927b823419 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 12:47:36 +0800 Subject: [PATCH 22/37] More ELD cards --- forge-gui/res/cardsfolder/n/narrow_escape.txt | 2 +- .../ardenvale_tactician_dizzying_swoop.txt | 15 +++++++++++++++ .../upcoming/brazen_borrower_petty_theft.txt | 17 +++++++++++++++++ .../upcoming/fae_of_wishes_granted.txt | 16 ++++++++++++++++ .../faerie_guidemother_gift_of_the_fae.txt | 15 +++++++++++++++ .../upcoming/giant_killer_chop_down.txt | 15 +++++++++++++++ .../upcoming/lonesome_unicorn_rider_in_need.txt | 15 +++++++++++++++ .../upcoming/realm_cloaked_giant_cast_off.txt | 15 +++++++++++++++ .../shepherd_of_the_flock_usher_to_safety.txt | 14 ++++++++++++++ .../upcoming/silverflame_squire_on_alert.txt | 15 +++++++++++++++ 10 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/ardenvale_tactician_dizzying_swoop.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/brazen_borrower_petty_theft.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/fae_of_wishes_granted.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/faerie_guidemother_gift_of_the_fae.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/giant_killer_chop_down.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/lonesome_unicorn_rider_in_need.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/realm_cloaked_giant_cast_off.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/shepherd_of_the_flock_usher_to_safety.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/silverflame_squire_on_alert.txt diff --git a/forge-gui/res/cardsfolder/n/narrow_escape.txt b/forge-gui/res/cardsfolder/n/narrow_escape.txt index 2a919389355..9c77e681093 100644 --- a/forge-gui/res/cardsfolder/n/narrow_escape.txt +++ b/forge-gui/res/cardsfolder/n/narrow_escape.txt @@ -1,7 +1,7 @@ Name:Narrow Escape ManaCost:2 W Types:Instant -A:SP$ ChangeZone | Cost$ 2 W | Origin$ Battlefield | Destination$ Hand | ValidTgts$ Permanent.YouCtrl | SubAbility$ DBGainLife | Defined$ TargetedController | TgtPrompt$ Select target permanent you control | SpellDescription$ Return target permanent you control to its owner's hand. You gain 4 life. +A:SP$ ChangeZone | Cost$ 2 W | Origin$ Battlefield | Destination$ Hand | ValidTgts$ Permanent.YouCtrl | SubAbility$ DBGainLife | TgtPrompt$ Select target permanent you control | SpellDescription$ Return target permanent you control to its owner's hand. You gain 4 life. SVar:DBGainLife:DB$GainLife | LifeAmount$ 4 SVar:Picture:http://www.wizards.com/global/images/magic/general/Narrow_Escape.jpg Oracle:Return target permanent you control to its owner's hand. You gain 4 life. diff --git a/forge-gui/res/cardsfolder/upcoming/ardenvale_tactician_dizzying_swoop.txt b/forge-gui/res/cardsfolder/upcoming/ardenvale_tactician_dizzying_swoop.txt new file mode 100644 index 00000000000..44079acb237 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ardenvale_tactician_dizzying_swoop.txt @@ -0,0 +1,15 @@ +Name:Ardenvale Tactician +ManaCost:1 W W +Types:Creature Human Knight +PT:2/3 +K:Flying +Oracle:Flying +AlternateMode:Adventure + +ALTERNATE + +Name:Dizzying Swoop +ManaCost:1 W +Types:Instant Adventure +A:SP$ Tap | Cost$ 1 W | TargetMin$ 0 | TargetMax$ 2 | TgtPrompt$ Choose target creature | ValidTgts$ Creature | SpellDescription$ Tap up to two target creatures. +Oracle:Tap up to two target creatures. diff --git a/forge-gui/res/cardsfolder/upcoming/brazen_borrower_petty_theft.txt b/forge-gui/res/cardsfolder/upcoming/brazen_borrower_petty_theft.txt new file mode 100644 index 00000000000..07a5d8b2ba8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/brazen_borrower_petty_theft.txt @@ -0,0 +1,17 @@ +Name:Brazen Borrower +ManaCost:1 U U +Types:Creature Faerie Rogue +PT:3/1 +K:Flash +K:Flying +K:CARDNAME can block only creatures with flying. +Oracle:Flash\nFlying\nBrazen Borrower can block only creatures with flying. +AlternateMode:Adventure + +ALTERNATE + +Name:Petty Theft +ManaCost:1 U +Types:Instant Adventure +A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent an opponent controls | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent an opponent controls to its owner's hand. +Oracle:Return target nonland permanent an opponent controls to its owner's hand. diff --git a/forge-gui/res/cardsfolder/upcoming/fae_of_wishes_granted.txt b/forge-gui/res/cardsfolder/upcoming/fae_of_wishes_granted.txt new file mode 100644 index 00000000000..ab386699477 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fae_of_wishes_granted.txt @@ -0,0 +1,16 @@ +Name:Fae of Wishes +ManaCost:1 U +Types:Creature Faerie Wizard +PT:1/4 +K:Flying +A:AB$ ChangeZone | Cost$ 1 U Discard<2/Card> | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return CARDNAME to its owner's hand. +Oracle:Flying\{1}{U}, Discard two cards: Return Fae of Wishes to its owner's hand. +AlternateMode:Adventure + +ALTERNATE + +Name:Granted +ManaCost:3 U +Types:Sorcery Adventure +A:SP$ ChangeZone | Cost$ 3 U | Origin$ Sideboard | Destination$ Hand | ChangeType$ Card.nonCreature | ChangeNum$ 1 | SpellDescription$ You may choose a noncreature card you own from outside the game, reveal it, and put it into your hand. +Oracle:You may choose a noncreature card you own from outside the game, reveal it, and put it into your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/faerie_guidemother_gift_of_the_fae.txt b/forge-gui/res/cardsfolder/upcoming/faerie_guidemother_gift_of_the_fae.txt new file mode 100644 index 00000000000..273859ccc9a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/faerie_guidemother_gift_of_the_fae.txt @@ -0,0 +1,15 @@ +Name:Faerie Guidemother +ManaCost:W +Types:Creature Faerie +PT:1/1 +K:Flying +Oracle:Flying +AlternateMode:Adventure + +ALTERNATE + +Name:Gift of the Fae +ManaCost:1 W +Types:Sorcery Adventure +A:SP$ Pump | Cost$ 1 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 2 | NumDef$ 1 | KW$ Flying | SpellDescription$ Target creature gets +2/+1 and gains flying until end of turn. +Oracle:Target creature gets +2/+1 and gains flying until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/giant_killer_chop_down.txt b/forge-gui/res/cardsfolder/upcoming/giant_killer_chop_down.txt new file mode 100644 index 00000000000..7389066bc56 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/giant_killer_chop_down.txt @@ -0,0 +1,15 @@ +Name:Giant Killer +ManaCost:W +Types:Creature Human Peasant +PT:1/2 +A:AB$ Tap | Cost$ 1 W T | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Tap target creature. +Oracle:{1}{W}, {T}: Tap target creature. +AlternateMode:Adventure + +ALTERNATE + +Name:Chop Down +ManaCost:2 W +Types:Instant Adventure +A:SP$ Destroy | Cost$ 2 W | ValidTgts$ Creature.powerGE4 | TgtPrompt$ Select target creature with power 4 or greater | SpellDescription$ Destroy target creature with power 4 or greater. +Oracle:Destroy target creature with power 4 or greater. diff --git a/forge-gui/res/cardsfolder/upcoming/lonesome_unicorn_rider_in_need.txt b/forge-gui/res/cardsfolder/upcoming/lonesome_unicorn_rider_in_need.txt new file mode 100644 index 00000000000..f791350d2d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lonesome_unicorn_rider_in_need.txt @@ -0,0 +1,15 @@ +Name:Lonesome Unicorn +ManaCost:4 W +Types:Creature Unicorn +PT:3/3 +K:Vigilance +Oracle:Vigilance +AlternateMode:Adventure + +ALTERNATE + +Name:Rider in Need +ManaCost:2 W +Types:Sorcery Adventure +A:SP$ Token | Cost$ 2 W | TokenAmount$ 1 | TokenScript$ w_2_2_knight_vigilance | TokenOwner$ You | LegacyImage$ w 2 2 knight vigilance eld | SpellDescription$ Create a 2/2 white Knight creature token with vigilance. +Oracle:Create a 2/2 white Knight creature token with vigilance. diff --git a/forge-gui/res/cardsfolder/upcoming/realm_cloaked_giant_cast_off.txt b/forge-gui/res/cardsfolder/upcoming/realm_cloaked_giant_cast_off.txt new file mode 100644 index 00000000000..c1752563e2b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/realm_cloaked_giant_cast_off.txt @@ -0,0 +1,15 @@ +Name:Realm-Cloaked Giant +ManaCost:5 W W +Types:Creature Giant +PT:7/7 +K:Vigilance +Oracle:Vigilance +AlternateMode:Adventure + +ALTERNATE + +Name:Cast Off +ManaCost:3 W W +Types:Sorcery Adventure +A:SP$ DestroyAll | Cost$ 3 W W | ValidCards$ Creature.nonGiant | SpellDescription$ Destroy all non-Giant creatures. +Oracle:Destroy all non-Giant creatures. diff --git a/forge-gui/res/cardsfolder/upcoming/shepherd_of_the_flock_usher_to_safety.txt b/forge-gui/res/cardsfolder/upcoming/shepherd_of_the_flock_usher_to_safety.txt new file mode 100644 index 00000000000..33d0e2c60d1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/shepherd_of_the_flock_usher_to_safety.txt @@ -0,0 +1,14 @@ +Name:Shepherd of the Flock +ManaCost:1 W +Types:Creature Human Peasant +PT:3/1 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:Usher to Safety +ManaCost:W +Types:Instant Adventure +A:SP$ ChangeZone | Cost$ W | Origin$ Battlefield | Destination$ Hand | ValidTgts$ Permanent.YouCtrl | TgtPrompt$ Select target permanent you control | SpellDescription$ Return target permanent you control to its owner's hand. +Oracle:Return target permanent you control to its owner's hand. diff --git a/forge-gui/res/cardsfolder/upcoming/silverflame_squire_on_alert.txt b/forge-gui/res/cardsfolder/upcoming/silverflame_squire_on_alert.txt new file mode 100644 index 00000000000..d74d31de991 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/silverflame_squire_on_alert.txt @@ -0,0 +1,15 @@ +Name:Silverflame Squire +ManaCost:1 W +Types:Creature Human Soldier +PT:2/1 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:On Alert +ManaCost:2 W +Types:Instant Adventure +A:SP$ Pump | Cost$ 2 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SubAbility$ DBUntap | SpellDescription$ Target creature gets +2/+2 until end of turn. Untap it. +SVar:DBUntap:DB$ Untap | Defined$ Targeted +Oracle:Target creature gets +2/+2 until end of turn. Untap it. From 661c3d96aab58b6b134182e1fe1d9a893ebc8b10 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 16:07:28 +0800 Subject: [PATCH 23/37] More ELD cards --- .../upcoming/bonecrusher_giant_stomp.txt | 18 ++++++++++++++++++ .../upcoming/curious_pair_treats_to_share.txt | 14 ++++++++++++++ .../embereth_shieldbreaker_battle_display.txt | 14 ++++++++++++++ .../upcoming/flaxen_intruder_welcome_home.txt | 17 +++++++++++++++++ .../garenbrig_carver_shields_might.txt | 14 ++++++++++++++ .../hypnotic_sprite_mesmeric_glare.txt | 15 +++++++++++++++ .../lovestruck_beast_hearts_desire.txt | 15 +++++++++++++++ .../merfolk_secretkeeper_venture_deeper.txt | 14 ++++++++++++++ .../upcoming/murderous_rider_swift_end.txt | 18 ++++++++++++++++++ .../upcoming/oakhame_ranger_bring_back.txt | 15 +++++++++++++++ .../upcoming/order_of_midnight_alter_fate.txt | 16 ++++++++++++++++ .../upcoming/queen_of_ice_rage_of_winter.txt | 19 +++++++++++++++++++ .../upcoming/reaper_of_night_harvest_fear.txt | 17 +++++++++++++++++ .../upcoming/rimrock_knight_boulder_rush.txt | 15 +++++++++++++++ .../rosethorn_acolyte_seasonal_ritual.txt | 15 +++++++++++++++ .../smitten_swordmaster_curry_favor.txt | 17 +++++++++++++++++ .../upcoming/tuinvale_treefolk_oaken_boon.txt | 14 ++++++++++++++ 17 files changed, 267 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/bonecrusher_giant_stomp.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/curious_pair_treats_to_share.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/embereth_shieldbreaker_battle_display.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/flaxen_intruder_welcome_home.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/garenbrig_carver_shields_might.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hypnotic_sprite_mesmeric_glare.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/merfolk_secretkeeper_venture_deeper.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/murderous_rider_swift_end.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/oakhame_ranger_bring_back.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/order_of_midnight_alter_fate.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/queen_of_ice_rage_of_winter.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/reaper_of_night_harvest_fear.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/rimrock_knight_boulder_rush.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/rosethorn_acolyte_seasonal_ritual.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/smitten_swordmaster_curry_favor.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/tuinvale_treefolk_oaken_boon.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bonecrusher_giant_stomp.txt b/forge-gui/res/cardsfolder/upcoming/bonecrusher_giant_stomp.txt new file mode 100644 index 00000000000..3d3b0a2ddd7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bonecrusher_giant_stomp.txt @@ -0,0 +1,18 @@ +Name:Bonecrusher Giant +ManaCost:2 R +Types:Creature Giant +PT:4/3 +T:Mode$ BecomesTarget | ValidTarget$ Card.Self | SourceType$ Spell | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ When CARDNAME becomes the target of a spell, CARDNAME deals 2 damage to that spell's controller. +SVar:TrigDmg:DB$ DealDamage | Defined$ TriggeredSourceController | NumDmg$ 2 +Oracle:Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell's controller. +AlternateMode:Adventure + +ALTERNATE + +Name:Stomp +ManaCost:1 R +Types:Instant Adventure +A:SP$ Effect | Cost$ 1 R | Name$ Stomp Effect | StaticAbilities$ STCantPrevent | AILogic$ Burn | SubAbility$ DBDamage | SpellDescription$ Damage can't be prevented this turn. CARDNAME deals 2 damage to any target. +SVar:STCantPrevent:Mode$ Continuous | EffectZone$ Command | GlobalRule$ Damage can't be prevented. | Description$ Damage can't be prevented. +SVar:DBDamage:DB$ DealDamage | ValidTgts$ Player,Planeswalker,Creature | TgtPrompt$ Select any target | NumDmg$ 2 | NoPrevention$ True +Oracle:Damage can't be prevented this turn. Stomp deals 2 damage to any target. diff --git a/forge-gui/res/cardsfolder/upcoming/curious_pair_treats_to_share.txt b/forge-gui/res/cardsfolder/upcoming/curious_pair_treats_to_share.txt new file mode 100644 index 00000000000..7ccbfb39c31 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/curious_pair_treats_to_share.txt @@ -0,0 +1,14 @@ +Name:Curious Pair +ManaCost:1 G +Types:Creature Human Peasant +PT:1/3 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:Treats to Share +ManaCost:G +Types:Sorcery Adventure +A:SP$ Token | Cost$ G | TokenAmount$ 1 | TokenScript$ c_a_food_sac | TokenOwner$ You | LegacyImage$ c a food sac eld | SpellDescription$ Create a Food token. (Then exile this card. You may cast the creature later from exile.) +Oracle:Create a Food token. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/upcoming/embereth_shieldbreaker_battle_display.txt b/forge-gui/res/cardsfolder/upcoming/embereth_shieldbreaker_battle_display.txt new file mode 100644 index 00000000000..d06ccf6f67f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/embereth_shieldbreaker_battle_display.txt @@ -0,0 +1,14 @@ +Name:Embereth Shieldbreaker +ManaCost:1 R +Types:Creature Human Knight +PT:2/1 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:Battle Display +ManaCost:R +Types:Sorcery Adventure +A:SP$ Destroy | Cost$ R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact. | SpellDescription$ Destroy target artifact. +Oracle:Destroy target artifact. diff --git a/forge-gui/res/cardsfolder/upcoming/flaxen_intruder_welcome_home.txt b/forge-gui/res/cardsfolder/upcoming/flaxen_intruder_welcome_home.txt new file mode 100644 index 00000000000..d64c8abdf1e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/flaxen_intruder_welcome_home.txt @@ -0,0 +1,17 @@ +Name:Flaxen Intruder +ManaCost:G +Types:Creature Human Berserker +PT:1/2 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ Trigtrig | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may sacrifice it. When you do, destroy target artifact or enchantment. +SVar:Trigtrig:AB$ ImmediateTrigger | Cost$ Sac<1/CARDNAME> | Execute$ TrigDestroy | TriggerDescription$ When you do, destroy target artifact or enchantment. +SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment +Oracle:Whenever Flaxen Intruder deals combat damage to a player, you may sacrifice it. When you do, destroy target artifact or enchantment. +AlternateMode:Adventure + +ALTERNATE + +Name:Welcome Home +ManaCost:5 G G +Types:Sorcery Adventure +A:SP$ Token | Cost$ 5 G G | TokenAmount$ 3 | TokenScript$ g_2_2_bear | TokenOwner$ You | LegacyImage$ g 2 2 bear eld | SpellDescription$ Create three 2/2 green Bear creature tokens. +Oracle:Create three 2/2 green Bear creature tokens. diff --git a/forge-gui/res/cardsfolder/upcoming/garenbrig_carver_shields_might.txt b/forge-gui/res/cardsfolder/upcoming/garenbrig_carver_shields_might.txt new file mode 100644 index 00000000000..7e6e2108ddd --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/garenbrig_carver_shields_might.txt @@ -0,0 +1,14 @@ +Name:Garenbrig Carver +ManaCost:3 G +Types:Creature Human Warrior +PT:3/2 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:Shield's Might +ManaCost:1 G +Types:Sorcery Adventure +A:SP$ Pump | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Target creature gets +2/+2 until end of turn. (Then exile this card. You may cast the creature later from exile.) +Oracle:Target creature gets +2/+2 until end of turn. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/upcoming/hypnotic_sprite_mesmeric_glare.txt b/forge-gui/res/cardsfolder/upcoming/hypnotic_sprite_mesmeric_glare.txt new file mode 100644 index 00000000000..c3d8ca0ee76 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hypnotic_sprite_mesmeric_glare.txt @@ -0,0 +1,15 @@ +Name:Hypnotic Sprite +ManaCost:U U +Types:Creature Faerie +PT:2/1 +K:Flying +Oracle:Flying +AlternateMode:Adventure + +ALTERNATE + +Name:Mesmeric Glare +ManaCost:2 U +Types:Instant Adventure +A:SP$ Counter | Cost$ 2 U | TargetType$ Spell | TgtPrompt$ Select target spell with CMC 3 or less | ValidTgts$ Card.cmcLE3 | SpellDescription$ Counter target spell with converted mana cost 3 or less. +Oracle:Counter target spell with converted mana cost 3 or less. diff --git a/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt b/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt new file mode 100644 index 00000000000..351ad60f884 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt @@ -0,0 +1,15 @@ +Name:Lovestruck Beast +ManaCost:2 G +Types:Creature Beast Noble +PT:5/5 +S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME can't attack. | IsPresent$ Creature.YouCtrl+powerEQ1+toughnessEQ1 | Description$ CARDNAME can't attack unless you control a 1/1 creature. +Oracle:Lovestruck Beast can't attack unless you control a 1/1 creature. +AlternateMode:Adventure + +ALTERNATE + +Name:Heart's Desire +ManaCost:G +Types:Sorcery Adventure +A:SP$ Token | Cost$ G | TokenAmount$ 1 | TokenOwner$ You | TokenScript$ w_1_1_human | LegacyImage$ w 1 1 human eld | SpellDescription$ Create a 1/1 white Human creature token. (Then exile this card. You may cast the creature later from exile.) +Oracle:Create a 1/1 white Human creature token. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/upcoming/merfolk_secretkeeper_venture_deeper.txt b/forge-gui/res/cardsfolder/upcoming/merfolk_secretkeeper_venture_deeper.txt new file mode 100644 index 00000000000..1d2e8a7acd0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/merfolk_secretkeeper_venture_deeper.txt @@ -0,0 +1,14 @@ +Name:Merfolk Secretkeeper +ManaCost:U +Types:Creature Merfolk Wizard +PT:0/4 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:Venture Deeper +ManaCost:U +Types:Sorcery Adventure +A:SP$ Mill | Cost$ U | NumCards$ 4 | ValidTgts$ Player | TgtPrompt$ Choose a player | SpellDescription$ Target player puts the top four cards of their library into their graveyard. +Oracle:Target player puts the top four cards of their library into their graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/murderous_rider_swift_end.txt b/forge-gui/res/cardsfolder/upcoming/murderous_rider_swift_end.txt new file mode 100644 index 00000000000..9a11e27fce9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/murderous_rider_swift_end.txt @@ -0,0 +1,18 @@ +Name:Murderous Rider +ManaCost:1 B B +Types:Creature Zombie Knight +PT:2/3 +K:Lifelink +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | TriggerController$ TriggeredCardController | Execute$ TrigChange | TriggerDescription$ Whenever CARDNAME dies, put it on the bottom of its owner's library. +SVar:TrigChange:DB$ ChangeZone | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Library | LibraryPosition$ -1 +Oracle:Lifelink\nWhen Murderous Rider dies, put it on the bottom of its owner's library. +AlternateMode:Adventure + +ALTERNATE + +Name:Swift End +ManaCost:1 B B +Types:Instant Adventure +A:SP$ Destroy | Cost$ 1 B B | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | SubAbility$ DBLoseLife | SpellDescription$ Destroy target creature or planeswalker. You lose 2 life. +SVar:DBLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 2 +Oracle:Destroy target creature or planeswalker. You lose 2 life. diff --git a/forge-gui/res/cardsfolder/upcoming/oakhame_ranger_bring_back.txt b/forge-gui/res/cardsfolder/upcoming/oakhame_ranger_bring_back.txt new file mode 100644 index 00000000000..c14811c08cb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/oakhame_ranger_bring_back.txt @@ -0,0 +1,15 @@ +Name:Oakhame Ranger +ManaCost::G/W G/W G/W G/W +Types:Creature Elf Knight +PT:2/2 +A:AB$ PumpAll | Cost$ T | ValidCards$ Creature.YouCtrl | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Creatures you control get +1/+1 until end of turn. +Oracle:{T}: Creatures you control get +1/+1 until end of turn. +AlternateMode:Adventure + +ALTERNATE + +Name:Bring Back +ManaCost::G/W G/W G/W G/W +Types:Sorcery Adventure +A:SP$ Token | Cost$ G/W G/W G/W G/W | TokenAmount$ 2 | TokenScript$ w_1_1_human | TokenOwner$ You | LegacyImage$ w 1 1 human eld | SpellDescription$ Create two 1/1 white Human creature tokens. +Oracle:Create two 1/1 white Human creature tokens. diff --git a/forge-gui/res/cardsfolder/upcoming/order_of_midnight_alter_fate.txt b/forge-gui/res/cardsfolder/upcoming/order_of_midnight_alter_fate.txt new file mode 100644 index 00000000000..702fecd3648 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/order_of_midnight_alter_fate.txt @@ -0,0 +1,16 @@ +Name:Order of Midnight +ManaCost:1 B +Types:Creature Human Knight +PT:2/2 +K:Flying +K:CARDNAME can't block. +Oracle:Flying\nOrder of Midnight can't block. +AlternateMode:Adventure + +ALTERNATE + +Name:Alter Fate +ManaCost:1 B +Types:Sorcery Adventure +A:SP$ ChangeZone | Cost$ 1 B | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Select target creature card in your graveyard | ValidTgts$ Creature.YouOwn | SpellDescription$ Return target creature card from your graveyard to your hand. (Then exile this card. You may cast the creature later from exile.) +Oracle:Return target creature card from your graveyard to your hand. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/upcoming/queen_of_ice_rage_of_winter.txt b/forge-gui/res/cardsfolder/upcoming/queen_of_ice_rage_of_winter.txt new file mode 100644 index 00000000000..0778b9c503d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/queen_of_ice_rage_of_winter.txt @@ -0,0 +1,19 @@ +Name:Queen of Ice +ManaCost:2 U +Types:Creature Human Noble Wizard +PT:2/3 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, tap that creature. It doesn't untap during its controller's next upkeep. +SVar:TrigTap:DB$ Tap | Defined$ TriggeredTarget | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ TriggeredTarget | KW$ HIDDEN This card doesn't untap during your next untap step. | Permanent$ True | IsCurse$ True +SVar:HasCombatEffect:TRUE +Oracle:Whenever Queen of Ice deals combat damage to a creature, tap that creature. It doesn't untap during its controller's next upkeep. +AlternateMode:Adventure + +ALTERNATE + +Name:Rage of Winter +ManaCost:1 U +Types:Sorcery Adventure +A:SP$ Tap | Cost$ 1 U | ValidTgts$ Creature | SubAbility$ DBPump | SpellDescription$ Tap target creature. It doesn't untap during its contller's next untap step. +SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ HIDDEN This card doesn't untap during your next untap step. | Permanent$ True | IsCurse$ True +Oracle:Tap target creature. It doesn't untap during its contller's next untap step. diff --git a/forge-gui/res/cardsfolder/upcoming/reaper_of_night_harvest_fear.txt b/forge-gui/res/cardsfolder/upcoming/reaper_of_night_harvest_fear.txt new file mode 100644 index 00000000000..b916452909e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/reaper_of_night_harvest_fear.txt @@ -0,0 +1,17 @@ +Name:Reaper of Night +ManaCost:5 B B +Types:Creature Specter +PT:4/5 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | CheckSVar$ X | SVarCompare$ LE2 | References$ X | TriggerDescription$ Whenever CARDNAME attacks, if defending player has two or fewer cards in hand, it gains flying until end of turn. +SVar:X:Count$ValidHand Card.DefenderCtrl +SVar:TrigPump:DB$ Pump | KW$ Flying +Oracle:Whenever Reaper of Night attacks, if defending player has two or fewer cards in hand, it gains flying until end of turn. +AlternateMode:Adventure + +ALTERNATE + +Name:Harvest Fear +ManaCost:3 B +Types:Sorcery Adventure +A:SP$ Discard | Cost$ 3 B | ValidTgts$ Opponent | NumCards$ 2 | Mode$ TgtChoose | SpellDescription$ Target opponent discards two cards. +Oracle:Target opponent discards two cards. diff --git a/forge-gui/res/cardsfolder/upcoming/rimrock_knight_boulder_rush.txt b/forge-gui/res/cardsfolder/upcoming/rimrock_knight_boulder_rush.txt new file mode 100644 index 00000000000..75e64155970 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rimrock_knight_boulder_rush.txt @@ -0,0 +1,15 @@ +Name:Rimrock Knight +ManaCost:1 R +Types:Creature Dwarf Knight +PT:3/1 +K:CARDNAME can't block. +Oracle:Rimrock Knight can't block. +AlternateMode:Adventure + +ALTERNATE + +Name:Boulder Rush +ManaCost:R +Types:Instant Adventure +A:SP$ Pump | Cost$ R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 2 | SpellDescription$ Target creature gets +2/+0 until end of turn. +Oracle:Target creature gets +2/+0 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/rosethorn_acolyte_seasonal_ritual.txt b/forge-gui/res/cardsfolder/upcoming/rosethorn_acolyte_seasonal_ritual.txt new file mode 100644 index 00000000000..9377e24c137 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rosethorn_acolyte_seasonal_ritual.txt @@ -0,0 +1,15 @@ +Name:Rosethorn Acolyte +ManaCost:2 G +Types:Creature Elf Druid +PT:2/3 +A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color. +Oracle:{T}: Add one mana of any color. +AlternateMode:Adventure + +ALTERNATE + +Name:Seasonal Ritual +ManaCost:G +Types:Sorcery Adventure +A:SP$ Mana | Cost$ G | Produced$ Any | SpellDescription$ Add one mana of any color. +Oracle:Add one mana of any color. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/upcoming/smitten_swordmaster_curry_favor.txt b/forge-gui/res/cardsfolder/upcoming/smitten_swordmaster_curry_favor.txt new file mode 100644 index 00000000000..c9f5b2d4551 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/smitten_swordmaster_curry_favor.txt @@ -0,0 +1,17 @@ +Name:Smitten Swordmaster +ManaCost:1 B +Types:Creature Human Knight +PT:2/1 +K:Lifelink +Oracle:Lifelink +AlternateMode:Adventure + +ALTERNATE + +Name:Curry Favor +ManaCost:B +Types:Sorcery Adventure +A:SP$ GainLife | Cost$ B | Defined$ You | LifeAmount$ X | References$ X | SubAbility$ DBLoseLife | SpellDescription$ You gain X life and each opponent loses X life, where X is the number of Knights you control. +SVar:DBLoseLife:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ X | References$ X +SVar:X:Count$Valid Knight.YouCtrl +Oracle:You gain X life and each opponent loses X life, where X is the number of Knights you control. diff --git a/forge-gui/res/cardsfolder/upcoming/tuinvale_treefolk_oaken_boon.txt b/forge-gui/res/cardsfolder/upcoming/tuinvale_treefolk_oaken_boon.txt new file mode 100644 index 00000000000..c5ed354ec8f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tuinvale_treefolk_oaken_boon.txt @@ -0,0 +1,14 @@ +Name:Tuinvale Treefolk +ManaCost:5 G +Types:Creature Treefolk Druid +PT:6/5 +Oracle: +AlternateMode:Adventure + +ALTERNATE + +Name:Oaken Boon +ManaCost:3 G +Types:Sorcery Adventure +A:SP$ PutCounter | Cost$ 3 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Put two +1/+1 counters on target creature. +Oracle:Put two +1/+1 counters on target creature. From 695d2324ac895819fad85aaef7bd44336d20e52a Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 16:12:32 +0800 Subject: [PATCH 24/37] Fix Lovestruck Beast --- .../res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt b/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt index 351ad60f884..3432d8cf184 100644 --- a/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt +++ b/forge-gui/res/cardsfolder/upcoming/lovestruck_beast_hearts_desire.txt @@ -2,7 +2,7 @@ Name:Lovestruck Beast ManaCost:2 G Types:Creature Beast Noble PT:5/5 -S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME can't attack. | IsPresent$ Creature.YouCtrl+powerEQ1+toughnessEQ1 | Description$ CARDNAME can't attack unless you control a 1/1 creature. +S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME can't attack. | IsPresent$ Creature.YouCtrl+powerEQ1+toughnessEQ1 | PresentCompare$ EQ0 | Description$ CARDNAME can't attack unless you control a 1/1 creature. Oracle:Lovestruck Beast can't attack unless you control a 1/1 creature. AlternateMode:Adventure From 23d72cb59a9fdf6192a1e158d863a86cac9c8f13 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 16:24:34 +0800 Subject: [PATCH 25/37] More ELD cards --- forge-gui/res/cardsfolder/upcoming/garenbrig_squire.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/memory_theft.txt | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/garenbrig_squire.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/memory_theft.txt diff --git a/forge-gui/res/cardsfolder/upcoming/garenbrig_squire.txt b/forge-gui/res/cardsfolder/upcoming/garenbrig_squire.txt new file mode 100644 index 00000000000..853025f7b7f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/garenbrig_squire.txt @@ -0,0 +1,8 @@ +Name:Garenbrig Squire +ManaCost:1 G +Types:Creature Human Soldier +PT:2/2 +T:Mode$ SpellCast | ValidCard$ Creature.AdventureCard | ValidActivatingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell that has an Adventure, CARDNAME gets +1/+1 until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 1 | NumDef$ 1 +SVar:BuffedBy:Creature.AdventureCard +Oracle:Whenever you cast a creature spell that has an Adventure, Garenbrig Squire gets +1/+1 until end of turn. (It doesn't need to have gone on the adventure first.) diff --git a/forge-gui/res/cardsfolder/upcoming/memory_theft.txt b/forge-gui/res/cardsfolder/upcoming/memory_theft.txt new file mode 100644 index 00000000000..a51ef072bd6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/memory_theft.txt @@ -0,0 +1,6 @@ +Name:Memory Theft +ManaCost:2 B +Types:Sorcery +A:SP$ Discard | Cost$ 2 B | ValidTgts$ Opponent | Mode$ RevealYouChoose | NumCards$ 1 | SubAbility$ DBChangeZone | SpellDescription$ Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. You may put a card that has an Adventure that player owns from exile into that player's graveyard. +SVar:DBChangeZone:DB$ ChangeZone | ChangeType$ Card.AdventureCard+TargetedPlayerCtrl | Origin$ Exile | Destination$ Graveyard | Hidden$ True +Oracle:Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. You may put a card that has an Adventure that player owns from exile into that player's graveyard. From 70398d8d151d2171933015fb78f557377d10a474 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 18:12:11 +0800 Subject: [PATCH 26/37] Add two cards --- forge-gui/res/cardsfolder/upcoming/lucky_clover.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/resolute_rider.txt | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/lucky_clover.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/resolute_rider.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lucky_clover.txt b/forge-gui/res/cardsfolder/upcoming/lucky_clover.txt new file mode 100644 index 00000000000..c53cfbfc01e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lucky_clover.txt @@ -0,0 +1,7 @@ +Name:Lucky Clover +ManaCost:2 +Types:Artifact +T:Mode$ SpellCast | ValidCard$ Instant.Adventure,Sorcery.Adventure | ValidActivatingPlayer$ You | Execute$ TrigCopySpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an Adventure instant or sorcery spell, copy it. You may choose new targets for the copy. +SVar:TrigCopySpell:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility +AI:RemoveDeck:Random +Oracle:Whenever you cast an Adventure instant or sorcery spell, copy it. You may choose new targets for the copy. diff --git a/forge-gui/res/cardsfolder/upcoming/resolute_rider.txt b/forge-gui/res/cardsfolder/upcoming/resolute_rider.txt new file mode 100644 index 00000000000..879e9456c38 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/resolute_rider.txt @@ -0,0 +1,7 @@ +Name:Resolute Rider +ManaCost:W/B W/B W/B W/B +Types:Creature Human Knight +PT:4/2 +A:AB$ Pump | Cost$ W/B W/B | KW$ Lifelink | Defined$ Self | SpellDescription$ CARDNAME gains lifelink until end of turn. +A:AB$ Pump | Cost$ W/B W/B W/B W/B | KW$ Indestructible | Defined$ Self | SpellDescription$ CARDNAME gains lifelink until end of turn. +Oracle:{W/B}{W/B}: Resolute Rider gains lifelink until end of turn.\n{W/B}{W/B}{W/B}{W/B}: Resolute Rider gains indestructible until end of turn. From facb93945e4d06229b269063bbd23cd39f2b70f5 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 19:17:28 +0800 Subject: [PATCH 27/37] Add Deathless Knight --- .../src/main/java/forge/game/card/CardFactoryUtil.java | 3 +++ forge-game/src/main/java/forge/game/player/Player.java | 7 +++++++ .../res/cardsfolder/upcoming/deathless_knight.txt | 10 ++++++++++ 3 files changed, 20 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/deathless_knight.txt 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 d5176500cef..35ef4469f01 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -999,6 +999,9 @@ public class CardFactoryUtil { if (sq[0].contains("LifeYourTeamGainedThisTurn")) { return doXMath(cc.getLifeGainedByTeamThisTurn(), m, c); } + if (sq[0].contains("LifeYouGainedTimesThisTurn")) { + return doXMath(cc.getLifeGainedTimesThisTurn(), m, c); + } if (sq[0].contains("LifeOppsLostThisTurn")) { return doXMath(cc.getOpponentLostLifeThisTurn(), m, c); } diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index b7aec94aa23..94ecc6ed017 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -93,6 +93,7 @@ public class Player extends GameEntity implements Comparable { private int lifeLostThisTurn = 0; private int lifeLostLastTurn = 0; private int lifeGainedThisTurn = 0; + private int lifeGainedTimesThisTurn = 0; private int lifeGainedByTeamThisTurn = 0; private int numPowerSurgeLands; private int numLibrarySearchedOwn = 0; //The number of times this player has searched his library @@ -440,6 +441,7 @@ public class Player extends GameEntity implements Comparable { view.updateLife(this); newLifeSet = true; lifeGainedThisTurn += lifeGain; + lifeGainedTimesThisTurn++; // team mates need to be notified about life gained for (final Player p : getTeamMates(true)) { @@ -2242,6 +2244,10 @@ public class Player extends GameEntity implements Comparable { lifeGainedThisTurn = n; } + public final int getLifeGainedTimesThisTurn() { + return lifeGainedTimesThisTurn; + } + public final int getLifeLostThisTurn() { return lifeLostThisTurn; } @@ -2935,6 +2941,7 @@ public class Player extends GameEntity implements Comparable { setLifeLostLastTurn(getLifeLostThisTurn()); setLifeLostThisTurn(0); lifeGainedThisTurn = 0; + lifeGainedTimesThisTurn = 0; lifeGainedByTeamThisTurn = 0; setLibrarySearched(0); setNumManaConversion(0); diff --git a/forge-gui/res/cardsfolder/upcoming/deathless_knight.txt b/forge-gui/res/cardsfolder/upcoming/deathless_knight.txt new file mode 100644 index 00000000000..8996b25fccf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/deathless_knight.txt @@ -0,0 +1,10 @@ +Name:Deathless Knight +ManaCost:B/G B/G B/G B/G +Types:Creature Skeleton Knight +PT:4/2 +K:Haste +T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Graveyard | CheckSVar$ X | SVarCompare$ EQ1 | NoResolvingCheck$ True | Execute$ TrigReturn | TriggerDescription$ Whenever you gain life for the first time each turn, return CARDNAME from your graveyard to your hand. +SVar:TrigReturn:DB$ ChangeZone | Defined$ Self | Origin$ Graveyard | Destination$ Hand +SVar:X:Count$LifeYouGainedTimesThisTurn +DeckHints:Ability$LifeGain +Oracle:Haste\nWhenever you gain life for the first time each turn, return Deathless Knight from your graveyard to your hand. From bcccf726b5407c7b9ab5b7083cef956491e0c500 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 22:10:57 +0800 Subject: [PATCH 28/37] Fix Kaalia of the Vast --- forge-ai/src/main/java/forge/ai/ComputerUtilCost.java | 2 +- forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index bdbf2abf61c..c94a5e7e16d 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -468,7 +468,7 @@ public class ComputerUtilCost { continue; try { - extraManaNeeded += Integer.parseInt(snem); + extraManaNeeded += Integer.parseInt(parts[0]); } catch (final NumberFormatException e) { System.out.println("wrong SpellsNeedExtraMana SVar format on " + c); } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java index 551ff2826bb..a0c651436ab 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttacks.java @@ -125,10 +125,10 @@ public class TriggerAttacks extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { + sa.setTriggeringObject(AbilityKey.Defender, getFromRunParams(AbilityKey.Attacked)); sa.setTriggeringObjectsFrom( this, AbilityKey.Attacker, - AbilityKey.Defender, AbilityKey.Defenders, AbilityKey.DefendingPlayer ); From 0f4c1960d993a06232da7c834a3a5aabfc969443 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 21 Sep 2019 22:27:21 +0800 Subject: [PATCH 29/37] More fixes --- .../src/main/java/forge/game/trigger/TriggerAttached.java | 3 ++- .../java/forge/game/trigger/TriggerCounterRemovedOnce.java | 3 ++- .../main/java/forge/game/trigger/TriggerDamageDealtOnce.java | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java b/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java index 82f6c081ae7..29afd7f7ebe 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAttached.java @@ -73,7 +73,8 @@ public class TriggerAttached extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObjectsFrom(this, AbilityKey.Source, AbilityKey.Target); + sa.setTriggeringObject(AbilityKey.Source, getFromRunParams(AbilityKey.AttachSource)); + sa.setTriggeringObject(AbilityKey.Target, getFromRunParams(AbilityKey.AttachTarget)); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java index 591e6df967e..96e731c4983 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterRemovedOnce.java @@ -74,7 +74,8 @@ public class TriggerCounterRemovedOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObjectsFrom(this, AbilityKey.Card, AbilityKey.Amount); + sa.setTriggeringObjectsFrom(this, AbilityKey.Card); + sa.setTriggeringObject(AbilityKey.Amount, getFromRunParams(AbilityKey.CounterAmount)); } @Override diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java index 20e744c5755..fbc875d93ec 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDealtOnce.java @@ -106,7 +106,9 @@ public class TriggerDamageDealtOnce extends Trigger { /** {@inheritDoc} */ @Override public final void setTriggeringObjects(final SpellAbility sa) { - sa.setTriggeringObjectsFrom(this, AbilityKey.Source, AbilityKey.Targets, AbilityKey.DamageAmount); + sa.setTriggeringObjectsFrom(this, AbilityKey.DamageAmount); + sa.setTriggeringObject(AbilityKey.Source, getFromRunParams(AbilityKey.DamageSource)); + sa.setTriggeringObject(AbilityKey.Targets, getFromRunParams(AbilityKey.DamageTargets)); } @Override From 4988a80cdd1ca6e61d07d76504894fffa9e635a1 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 22 Sep 2019 12:28:10 +0800 Subject: [PATCH 30/37] Add Giant Opportunity --- forge-gui/res/cardsfolder/upcoming/giant_opportunity.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/giant_opportunity.txt diff --git a/forge-gui/res/cardsfolder/upcoming/giant_opportunity.txt b/forge-gui/res/cardsfolder/upcoming/giant_opportunity.txt new file mode 100644 index 00000000000..69b7f90d316 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/giant_opportunity.txt @@ -0,0 +1,8 @@ +Name:Giant Opportunity +ManaCost:2 G +Types:Sorcery +A:SP$ Sacrifice | Cost$ 2 G | SacValid$ Food | Defined$ You | Amount$ 2 | Optional$ True | StrictAmount$ True | RememberSacrificed$ True | SubAbility$ DBToken | SpellDescription$ You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. Otherwise, create three Food tokens. (They're artifacts with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_7_7_giant | TokenOwner$ You | LegacyImage$ g 7 7 giant eld | ConditionDefined$ Remembered | ConditionPresent$ Food | ConditionCompare$ EQ2 | SubAbility$ DBToken2 +SVar:DBToken2:DB$ Token | TokenAmount$ 3 | TokenScript$ c_a_food_sac | TokenOwner$ You | LegacyImage$ c a food sac eld | ConditionDefined$ Remembered | ConditionPresent$ Food | ConditionCompare$ EQ0 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. Otherwise, create three Food tokens. (They're artifacts with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") From 8fdf76a4e521d610494cbf89881ceea75192f3ec Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 22 Sep 2019 13:13:33 +0800 Subject: [PATCH 31/37] Add three cards --- forge-gui/res/cardsfolder/upcoming/forever_young.txt | 7 +++++++ forge-gui/res/cardsfolder/upcoming/redcap_melee.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/specters_shriek.txt | 10 ++++++++++ 3 files changed, 25 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/forever_young.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/redcap_melee.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/specters_shriek.txt diff --git a/forge-gui/res/cardsfolder/upcoming/forever_young.txt b/forge-gui/res/cardsfolder/upcoming/forever_young.txt new file mode 100644 index 00000000000..5b26bbfe95c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/forever_young.txt @@ -0,0 +1,7 @@ +Name:Forever Young +ManaCost:1 B +Types:Sorcery +A:SP$ ChangeZone | Cost$ 1 B | Origin$ Graveyard | Destination$ Library | TargetMin$ 0 | TargetMax$ X | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouOwn | References$ X | SpellDescription$ Put any number of target creature cards from your graveyard on top of your library. Draw a card. | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ 1 | Defined$ You +SVar:X:Count$TypeInYourYard.Creature +Oracle:Put any number of target creature cards from your graveyard on top of your library.\nDraw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/redcap_melee.txt b/forge-gui/res/cardsfolder/upcoming/redcap_melee.txt new file mode 100644 index 00000000000..b81d26ada96 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/redcap_melee.txt @@ -0,0 +1,8 @@ +Name:Redcap Melee +ManaCost:R +Types:Instant +A:SP$ DealDamage | Cost$ R | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | NumDmg$ 4 | RememberDamaged$ True | SubAbility$ DBSac | SpellDescription$ CARDNAME deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land. +SVar:DBSac:DB$ Sacrifice | SacValid$ Land | Defined$ You | ConditionDefined$ Remembered | ConditionPresent$ Card.nonRed | ConditionCompare$ GE1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +AI:RemoveDeck:All +Oracle:Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land. diff --git a/forge-gui/res/cardsfolder/upcoming/specters_shriek.txt b/forge-gui/res/cardsfolder/upcoming/specters_shriek.txt new file mode 100644 index 00000000000..ff829d48093 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/specters_shriek.txt @@ -0,0 +1,10 @@ +Name:Specter's Shriek +ManaCost:B +Types:Sorcery +A:SP$ RevealHand | Cost$ B | ValidTgts$ Opponent | RememberRevealed$ True | SubAbility$ DBChoose | StackDescription$ SpellDescription | SpellDescription$ Target opponent reveals their hand. You may choose a nonland card from it. If you do, that player exiles that card. If a nonblack card is exiled this way, exile a card from your hand. +SVar:DBChoose:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Card.nonLand+IsRemembered | ChoiceTitle$ Select a nonland card | SubAbility$ DBExile | MinAmount$ 0 | StackDescription$ None +SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | Defined$ ChosenCard | Mandatory$ True | SubAbility$ DBExile2 +SVar:DBExile2:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ConditionDefined$ ChosenCard | ConditionPresent$ Card.nonBlack | ConditionCompare$ GE1 | Mandatory$ True | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True +AI:RemoveDeck:All +Oracle:Target opponent reveals their hand. You may choose a nonland card from it. If you do, that player exiles that card. If a nonblack card is exiled this way, exile a card from your hand. From 79d03abe8cc2f8eeaab4d8ec82d2aa7906a6481d Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 22 Sep 2019 20:26:08 +0800 Subject: [PATCH 32/37] Add Drown in the Loch --- .../forge/game/spellability/SpellAbility.java | 16 ++++++++++++++++ .../cardsfolder/upcoming/drown_in_the_loch.txt | 7 +++++++ 2 files changed, 23 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/drown_in_the_loch.txt diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 2a016cc9706..e27af7b79bb 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -45,6 +45,7 @@ import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.trigger.WrappedAbility; +import forge.game.zone.ZoneType; import forge.util.Expressions; import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; @@ -1061,6 +1062,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return false; } } + if (hasParam("TargetsWithControllerProperty") && entity instanceof Card) { + final String prop = getParam("TargetsWithControllerProperty"); + final Card c = (Card) entity; + if (prop.equals("cmcLECardsInGraveyard") + && c.getCMC() > c.getController().getCardsIn(ZoneType.Graveyard).size()) { + return false; + } + } if (hasParam("TargetsWithRelatedProperty") && entity instanceof Card) { final String related = getParam("TargetsWithRelatedProperty"); final Card c = (Card) entity; @@ -1603,6 +1612,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit if (hasParam("TargetType") && !topSA.isValid(getParam("TargetType").split(","), getActivatingPlayer(), getHostCard(), this)) { return false; } + if (hasParam("TargetsWithControllerProperty")) { + final String prop = getParam("TargetsWithControllerProperty"); + if (prop.equals("cmcLECardsInGraveyard") + && topSA.getHostCard().getCMC() > topSA.getActivatingPlayer().getCardsIn(ZoneType.Graveyard).size()) { + return false; + } + } final String splitTargetRestrictions = tgt.getSAValidTargeting(); if (splitTargetRestrictions != null) { diff --git a/forge-gui/res/cardsfolder/upcoming/drown_in_the_loch.txt b/forge-gui/res/cardsfolder/upcoming/drown_in_the_loch.txt new file mode 100644 index 00000000000..9e86e7b6b0d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/drown_in_the_loch.txt @@ -0,0 +1,7 @@ +Name:Drown in the Loch +ManaCost:U B +Types:Instant +A:SP$ Charm | Cost$ U B | Choices$ DBCounter,DBDestroy +SVar:DBCounter:DB$ Counter | TargetType$ Spell | ValidTgts$ Card | TargetsWithControllerProperty$ cmcLECardsInGraveyard | TgtPrompt$ Select target spell with converted mana cost less than or equal to the number of cards in its controller's graveyard. | SpellDescription$ Counter target spell with converted mana cost less than or equal to the number of cards in its controller's graveyard. +SVar:DBDestroy:DB$ Destroy | ValidTgts$ Creature | TargetsWithControllerProperty$ cmcLECardsInGraveyard | TgtPrompt$ Select target creature with converted mana cost less than or equal to the number of cards in its controller's graveyard. | SpellDescription$ Destroy target creature with converted mana cost less than or equal to the number of cards in its controller's graveyard. +Oracle:Choose one —\n• Counter target spell with converted mana cost less than or equal to the number of cards in its controller's graveyard.\n• Destroy target creature with converted mana cost less than or equal to the number of cards in its controller's graveyard. From 9f3316502a6f17283457aa153b4274e20c676ae7 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 22 Sep 2019 20:32:43 +0800 Subject: [PATCH 33/37] Fix The Cauldron of Eternity --- forge-gui/res/cardsfolder/upcoming/the_cauldron_of_eternity.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/upcoming/the_cauldron_of_eternity.txt b/forge-gui/res/cardsfolder/upcoming/the_cauldron_of_eternity.txt index fdd657ee8a5..69765581709 100644 --- a/forge-gui/res/cardsfolder/upcoming/the_cauldron_of_eternity.txt +++ b/forge-gui/res/cardsfolder/upcoming/the_cauldron_of_eternity.txt @@ -2,7 +2,7 @@ Name:The Cauldron of Eternity ManaCost:10 B B Types:Legendary Artifact S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | References$ X | EffectZone$ All | Description$ CARDNAME costs {2} less for each creature card in your graveyard. -SVar:X:Count$TypeInYourYard.Creature +SVar:X:Count$TypeInYourYard.Creature/Twice T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigChange | TriggerDescription$ Whenever a creature you control dies, put it on the bottom of its owner's library. SVar:TrigChange:DB$ ChangeZone | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Library | LibraryPosition$ -1 SVar:BuffedBy:Creature From 3ca2b8c4be1bf33c75b8609d07794343d9c62f66 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 22 Sep 2019 22:17:01 +0800 Subject: [PATCH 34/37] Add Happily Ever After --- .../main/java/forge/game/card/CardFactoryUtil.java | 2 +- .../res/cardsfolder/upcoming/happily_ever_after.txt | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/happily_ever_after.txt 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 35ef4469f01..8fc4114e6bf 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1274,7 +1274,7 @@ public class CardFactoryUtil { } if (sq[0].contains("CardControllerTypes")) { - return doXMath(getCardTypesFromList(cc.getCardsIn(ZoneType.smartValueOf(sq[1]))), m, c); + return doXMath(getCardTypesFromList(cc.getCardsIn(ZoneType.listValueOf(sq[1]))), m, c); } if (sq[0].contains("CardTypes")) { diff --git a/forge-gui/res/cardsfolder/upcoming/happily_ever_after.txt b/forge-gui/res/cardsfolder/upcoming/happily_ever_after.txt new file mode 100644 index 00000000000..d1c2e4c854f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/happily_ever_after.txt @@ -0,0 +1,13 @@ +Name:Happily Ever After +ManaCost:2 W +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, each player gains 5 life and draws a card. +SVar:TrigGainLife:DB$ GainLife | Defined$ Player | LifeAmount$ 5 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ Player | NumCards$ 1 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ Z | SVarCompare$ EQ11 | LifeTotal$ You | LifeAmount$ GEW | References$ X,Y,Z,W | Execute$ TrigWin | TriggerDescription$ At the beginning of your upkeep, if there are five colors among permanents you control, there are six or more card types among permanents you control and/or cards in your graveyard, and your life total is greater than or equal to your starting life total, you win the game. +SVar:TrigWin:DB$ WinsGame | Defined$ You +SVar:X:Count$ColorsCtrl Permanent.YouCtrl+inZoneBattlefield/LimitMax.5 +SVar:Y:Count$CardControllerTypes.Battlefield,Graveyard/LimitMax.6 +SVar:Z:SVar$X/Plus.Y +SVar:W:Count$YourStartingLife +Oracle:When Happily Ever After enters the battlefield, each player gains 5 life and draws a card.\nAt the beginning of your upkeep, if there are five colors among permanents you control, there are six or more card types among permanents you control and/or cards in your graveyard, and your life total is greater than or equal to your starting life total, you win the game. From 9a32e2885a86b022c3c0e2901b5e3c74d4abbfd7 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 22 Sep 2019 22:59:10 +0800 Subject: [PATCH 35/37] Add Fires of Invention --- .../res/cardsfolder/upcoming/fires_of_invention.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/fires_of_invention.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fires_of_invention.txt b/forge-gui/res/cardsfolder/upcoming/fires_of_invention.txt new file mode 100644 index 00000000000..fbaafa0b509 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fires_of_invention.txt @@ -0,0 +1,9 @@ +Name:Fires of Invention +ManaCost:3 R +Types:Enchantment +S:Mode$ CantBeCast | NonCasterTurn$ True | Caster$ You | Description$ You can cast spells only during your turn and you can cast no more than two spells each turn. +S:Mode$ CantBeCast | NumLimitEachTurn$ 2 | Caster$ You | Secondary$ True | Description$ You can cast spells only during your turn and you can cast no more than two spells each turn. +S:Mode$ Continuous | Affected$ Card.nonLand+YouOwn+cmcLEX | References$ X | MayPlay$ True | MayPlayWithoutManaCost$ True | AffectedZone$ Hand,Graveyard,Exile,Command,Library | MayPlayDontGrantZonePermissions$ True | Description$ You may cast spells with converted mana cost less than or equal to the number of lands you control without paying their mana costs. +SVar:X:Count$Valid Land.YouCtrl +AI:RemoveDeck:Random +Oracle:You can cast spells only during your turn and you can cast no more than two spells each turn.\nYou may cast spells with converted mana cost less than or equal to the number of lands you control without paying their mana costs. From 4bf837701f5a4728c25e278b8c891939d75fe038 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 22 Sep 2019 20:49:55 +0200 Subject: [PATCH 36/37] Mobile: Translated more strings and Views Fixed duplicated Catalog label Fixed Stack label not found --- forge-gui-mobile/src/forge/card/CardZoom.java | 5 +- .../src/forge/deck/FDeckChooser.java | 34 +++---- .../src/forge/itemmanager/DeckManager.java | 3 +- .../src/forge/itemmanager/ItemManager.java | 9 +- .../forge/itemmanager/SpellShopManager.java | 3 +- .../filters/AdvancedSearchFilter.java | 7 +- .../forge/itemmanager/views/ImageView.java | 3 +- .../screens/constructed/AvatarSelector.java | 3 +- .../screens/constructed/LobbyScreen.java | 18 ++-- .../screens/constructed/PlayerPanel.java | 96 +++++++++---------- .../forge/screens/match/MatchController.java | 5 +- .../src/forge/screens/match/MatchScreen.java | 2 +- .../forge/screens/match/views/VGameMenu.java | 11 ++- .../src/forge/screens/settings/FilesPage.java | 40 ++++---- .../forge/screens/settings/SettingsPage.java | 2 +- forge-gui/res/languages/de-DE.properties | 71 +++++++++++++- forge-gui/res/languages/en-US.properties | 73 +++++++++++++- forge-gui/res/languages/es-ES.properties | 75 ++++++++++++++- forge-gui/res/languages/zh-CN.properties | 73 +++++++++++++- 19 files changed, 412 insertions(+), 121 deletions(-) diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index b3cdd3a599a..c0f8130e634 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -27,6 +27,7 @@ import forge.screens.match.MatchController; import forge.toolbox.FCardPanel; import forge.toolbox.FDialog; import forge.toolbox.FOverlay; +import forge.util.Localizer; import forge.util.collect.FCollectionView; import forge.util.Utils; @@ -281,10 +282,10 @@ public class CardZoom extends FOverlay { if (currentActivateAction != null) { g.fillRect(FDialog.MSG_BACK_COLOR, 0, 0, w, messageHeight); - g.drawText("Swipe up to " + currentActivateAction, FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, 0, w, messageHeight, false, Align.center, true); + g.drawText(Localizer.getInstance().getMessage("lblSwipeUpTo").replace("%s", currentActivateAction), FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, 0, w, messageHeight, false, Align.center, true); } g.fillRect(FDialog.MSG_BACK_COLOR, 0, h - messageHeight, w, messageHeight); - g.drawText("Swipe down to switch to " + (zoomMode ? "detail" : "picture") + " view", FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, h - messageHeight, w, messageHeight, false, Align.center, true); + g.drawText(zoomMode ? Localizer.getInstance().getMessage("lblSwipeDownDetailView") : Localizer.getInstance().getMessage("lblSwipeDownPictureView"), FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, h - messageHeight, w, messageHeight, false, Align.center, true); } @Override diff --git a/forge-gui-mobile/src/forge/deck/FDeckChooser.java b/forge-gui-mobile/src/forge/deck/FDeckChooser.java index 742c79d40fe..b62ea91d363 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckChooser.java +++ b/forge-gui-mobile/src/forge/deck/FDeckChooser.java @@ -73,6 +73,7 @@ public class FDeckChooser extends FScreen { private boolean isAi; private final ForgePreferences prefs = FModel.getPreferences(); + private final Localizer localizer = Localizer.getInstance(); private FPref stateSetting = null; private FOptionPane optionPane; @@ -98,7 +99,7 @@ public class FDeckChooser extends FScreen { container.add(deckChooser.lstDecks); container.setHeight(FOptionPane.getMaxDisplayObjHeight()); - deckChooser.optionPane = new FOptionPane(null, null, title, null, container, ImmutableList.of("OK", "Cancel"), 0, new Callback() { + deckChooser.optionPane = new FOptionPane(null, null, title, null, container, ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")), 0, new Callback() { @Override public void run(Integer result) { if (result == 0) { @@ -309,7 +310,7 @@ public class FDeckChooser extends FScreen { editor = new FDeckEditor(getEditorType(), generatedDeck, true); } else { - FOptionPane.showErrorDialog("You must select something before you can generate a new deck."); + FOptionPane.showErrorDialog(localizer.getMessage("lblMustSelectGenerateNewDeck")); return; } break; @@ -377,9 +378,10 @@ public class FDeckChooser extends FScreen { return; } + //prompt to duplicate deck if deck doesn't exist already - FOptionPane.showConfirmDialog(selectedDeckType + " cannot be edited directly. Would you like to duplicate " + deck.getName() + " for editing as a custom user deck?", - "Duplicate Deck?", "Duplicate", "Cancel", new Callback() { + FOptionPane.showConfirmDialog(selectedDeckType + " " + localizer.getMessage("lblCannotEditDuplicateCustomDeck").replace("%s", deck.getName()), + localizer.getMessage("lblDuplicateDeck"), localizer.getMessage("lblDuplicate"), localizer.getMessage("lblCancel"), new Callback() { @Override public void run(Boolean result) { if (result) { @@ -770,16 +772,16 @@ public class FDeckChooser extends FScreen { btnViewDeck.setVisible(false); btnRandom.setWidth(btnNewDeck.getWidth()); - btnNewDeck.setText("Generate New Deck"); + btnNewDeck.setText(localizer.getMessage("lblGenerateNewDeck")); switch (deckType) { case COLOR_DECK: - btnRandom.setText("Random Colors"); + btnRandom.setText(localizer.getMessage("lblRandomColors")); break; case THEME_DECK: - btnRandom.setText("Random Theme"); + btnRandom.setText(localizer.getMessage("lblRandomTheme")); break; default: - btnRandom.setText("Random Deck"); + btnRandom.setText(localizer.getMessage("lblRandomDeck")); break; } } @@ -789,11 +791,11 @@ public class FDeckChooser extends FScreen { btnViewDeck.setVisible(true); btnRandom.setWidth(btnNewDeck.getWidth()); - btnNewDeck.setText("New Deck"); + btnNewDeck.setText(localizer.getMessage("lblNewDeck")); if (lstDecks.getGameType() == GameType.DeckManager) { //handle special case of Deck Editor screen where this button will start a game with the deck - btnRandom.setText("Test Deck"); + btnRandom.setText(localizer.getMessage("lblTestDeck")); switch (selectedDeckType) { case SCHEME_DECK: @@ -806,7 +808,7 @@ public class FDeckChooser extends FScreen { } } else { - btnRandom.setText("Random Deck"); + btnRandom.setText(localizer.getMessage("lblRandomDeck")); } } @@ -1063,7 +1065,7 @@ public class FDeckChooser extends FScreen { return; } - GuiChoose.getInteger("How many opponents are you willing to face?", 1, 50, new Callback() { + GuiChoose.getInteger(localizer.getMessage("lblHowManyOpponents"), 1, 50, new Callback() { @Override public void run(final Integer numOpponents) { if (numOpponents == null) { return; } @@ -1089,7 +1091,7 @@ public class FDeckChooser extends FScreen { } ListChooser chooser = new ListChooser<>( - "Choose allowed deck types for opponents", 0, deckTypes.size(), deckTypes, null, new Callback>() { + localizer.getMessage("lblChooseAllowedDeckTypeOpponents"), 0, deckTypes.size(), deckTypes, null, new Callback>() { @Override public void run(final List allowedDeckTypes) { if (allowedDeckTypes == null || allowedDeckTypes.isEmpty()) { @@ -1109,7 +1111,7 @@ public class FDeckChooser extends FScreen { FThreads.invokeInEdtLater(new Runnable() { @Override public void run() { - LoadingOverlay.show("Loading new game...", new Runnable() { + LoadingOverlay.show(localizer.getMessage("lblLoadingNewGame"), new Runnable() { @Override public void run() { GauntletData gauntlet = GauntletUtil.createQuickGauntlet(userDeck, numOpponents, allowedDeckTypes, netCat); @@ -1135,12 +1137,12 @@ public class FDeckChooser extends FScreen { } private void testVariantDeck(final Deck userDeck, final GameType variant) { - promptForDeck("Select Opponent's Deck", variant, true, new Callback() { + promptForDeck(localizer.getMessage("lblSelectOpponentDeck"), variant, true, new Callback() { @Override public void run(final Deck aiDeck) { if (aiDeck == null) { return; } - LoadingOverlay.show("Loading new game...", new Runnable() { + LoadingOverlay.show(localizer.getMessage("lblLoadingNewGame"), new Runnable() { @Override public void run() { Set appliedVariants = new HashSet<>(); diff --git a/forge-gui-mobile/src/forge/itemmanager/DeckManager.java b/forge-gui-mobile/src/forge/itemmanager/DeckManager.java index d48e2a6e067..363a70bf27a 100644 --- a/forge-gui-mobile/src/forge/itemmanager/DeckManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/DeckManager.java @@ -18,6 +18,7 @@ import forge.itemmanager.filters.DeckFormatFilter; import forge.itemmanager.filters.TextSearchFilter; import forge.toolbox.FList; import forge.toolbox.FList.CompactModeHandler; +import forge.util.Localizer; import forge.util.Utils; import com.badlogic.gdx.utils.Align; @@ -39,7 +40,7 @@ public final class DeckManager extends ItemManager implements IHasGam public DeckManager(final GameType gt) { super(DeckProxy.class, true); gameType = gt; - setCaption("Decks"); + setCaption(Localizer.getInstance().getMessage("lblDecks")); } public GameType getGameType() { diff --git a/forge-gui-mobile/src/forge/itemmanager/ItemManager.java b/forge-gui-mobile/src/forge/itemmanager/ItemManager.java index 96c381e1d5b..ecd6f10b0e9 100644 --- a/forge-gui-mobile/src/forge/itemmanager/ItemManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/ItemManager.java @@ -53,6 +53,7 @@ import forge.toolbox.FList; import forge.toolbox.FList.CompactModeHandler; import forge.util.ItemPool; import forge.util.LayoutHelper; +import forge.util.Localizer; import java.util.*; import java.util.Map.Entry; @@ -125,7 +126,7 @@ public abstract class ItemManager extends FContainer im add(btnAdvancedSearchOptions); btnAdvancedSearchOptions.setSelected(!hideFilters); if (allowSortChange()) { - cbxSortOptions = add(new FComboBox<>("Sort: ")); + cbxSortOptions = add(new FComboBox<>(Localizer.getInstance().getMessage("lblSort") + ": ")); cbxSortOptions.setFont(FSkinFont.get(12)); } else { @@ -140,7 +141,7 @@ public abstract class ItemManager extends FContainer im FPopupMenu menu = new FPopupMenu() { @Override protected void buildMenu() { - addItem(new FMenuItem("Advanced Search", FSkinImage.SEARCH, new FEventHandler() { + addItem(new FMenuItem(Localizer.getInstance().getMessage("lblAdvancedSearch"), FSkinImage.SEARCH, new FEventHandler() { @Override public void handleEvent(FEvent e) { if (advancedSearchFilter == null) { @@ -150,7 +151,7 @@ public abstract class ItemManager extends FContainer im advancedSearchFilter.edit(); } })); - addItem(new FMenuItem("Reset Filters", FSkinImage.DELETE, new FEventHandler() { + addItem(new FMenuItem(Localizer.getInstance().getMessage("lblResetFilters"), FSkinImage.DELETE, new FEventHandler() { @Override public void handleEvent(FEvent e) { resetFilters(); @@ -261,7 +262,7 @@ public abstract class ItemManager extends FContainer im } if (cbxSortOptions != null) { - cbxSortOptions.setText("(none)"); + cbxSortOptions.setText("(" + Localizer.getInstance().getMessage("lblNone") + ")"); } model.getCascadeManager().reset(); diff --git a/forge-gui-mobile/src/forge/itemmanager/SpellShopManager.java b/forge-gui-mobile/src/forge/itemmanager/SpellShopManager.java index 66d9bc0c8e8..444db64407e 100644 --- a/forge-gui-mobile/src/forge/itemmanager/SpellShopManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/SpellShopManager.java @@ -19,6 +19,7 @@ import forge.itemmanager.filters.TextSearchFilter; import forge.quest.QuestSpellShop; import forge.toolbox.FList; import forge.toolbox.FList.CompactModeHandler; +import forge.util.Localizer; public class SpellShopManager extends ItemManager { @@ -29,7 +30,7 @@ public class SpellShopManager extends ItemManager { fnGetPrice = isShop0 ? QuestSpellShop.fnPriceGet : QuestSpellShop.fnPriceSellGet; if (!isShop0) { - setCaption("Cards"); + setCaption(Localizer.getInstance().getMessage("lblCards")); } } diff --git a/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java b/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java index 58327e7245c..d028f3812be 100644 --- a/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java +++ b/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java @@ -25,6 +25,7 @@ import forge.toolbox.FTextField; import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FLabel; import forge.util.Callback; +import forge.util.Localizer; public class AdvancedSearchFilter extends ItemFilter { @@ -126,13 +127,13 @@ public class AdvancedSearchFilter extends ItemFilter item.setTextRenderer(new TextRenderer()); //ensure symbols are displayed addItem(item); } - addItem(new FMenuItem("Edit Expression", FSkinImage.EDIT, new FEventHandler() { + addItem(new FMenuItem(Localizer.getInstance().getMessage("lblEditExpression"), FSkinImage.EDIT, new FEventHandler() { @Override public void handleEvent(FEvent e) { edit(); } })); - addItem(new FMenuItem("Remove Filter", FSkinImage.DELETE, new FEventHandler() { + addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRemoveFilter"), FSkinImage.DELETE, new FEventHandler() { @Override public void handleEvent(FEvent e) { reset(); @@ -176,7 +177,7 @@ public class AdvancedSearchFilter extends ItemFilter }); private EditScreen() { - super("Advanced Search"); + super(Localizer.getInstance().getMessage("lblAdvancedSearch")); Filter filter = new Filter(); model.addFilterControl(filter); scroller.add(filter); diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 8261e525f40..1833745ddfc 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -30,6 +30,7 @@ import forge.toolbox.FTextField; import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; +import forge.util.Localizer; import forge.util.Utils; import java.util.*; @@ -358,7 +359,7 @@ public class ImageView extends ItemView { otherItems = groups.get(groups.size() - 1); } else { - otherItems = new Group("Other"); + otherItems = new Group(Localizer.getInstance().getMessage("lblOther")); otherItems.isCollapsed = btnExpandCollapseAll.isAllCollapsed; groups.add(otherItems); } diff --git a/forge-gui-mobile/src/forge/screens/constructed/AvatarSelector.java b/forge-gui-mobile/src/forge/screens/constructed/AvatarSelector.java index 562d9ea1454..5fa5dfac739 100644 --- a/forge-gui-mobile/src/forge/screens/constructed/AvatarSelector.java +++ b/forge-gui-mobile/src/forge/screens/constructed/AvatarSelector.java @@ -12,6 +12,7 @@ import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; import forge.util.Callback; +import forge.util.Localizer; import forge.util.MyRandom; import forge.util.Utils; @@ -63,7 +64,7 @@ public class AvatarSelector extends FScreen { }; private AvatarSelector(final String playerName, final int currentIndex0, final List usedAvatars0, final Callback callback0) { - super("Select Avatar for " + playerName); + super(Localizer.getInstance().getMessage("lblSelectAvatarFor").replace("%s",playerName)); currentIndex = currentIndex0; usedAvatars = usedAvatars0; diff --git a/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java b/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java index b111fa139f4..70e8fafed64 100644 --- a/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java +++ b/forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java @@ -3,6 +3,7 @@ package forge.screens.constructed; import java.util.*; import forge.deck.*; +import forge.util.Localizer; import org.apache.commons.lang3.StringUtils; import com.badlogic.gdx.Gdx; @@ -49,12 +50,13 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { // General variables private GameLobby lobby; private IPlayerChangeListener playerChangeListener = null; - private final FLabel lblPlayers = new FLabel.Builder().text("Players:").font(VARIANTS_FONT).build(); + final Localizer localizer = Localizer.getInstance(); + private final FLabel lblPlayers = new FLabel.Builder().text(localizer.getMessage("lblPlayers") + ":").font(VARIANTS_FONT).build(); private final FComboBox cbPlayerCount; private final Deck[] decks = new Deck[MAX_PLAYERS]; // Variants frame and variables - private final FLabel lblVariants = new FLabel.Builder().text("Variants:").font(VARIANTS_FONT).build(); + private final FLabel lblVariants = new FLabel.Builder().text(localizer.getMessage("lblVariants") + ":").font(VARIANTS_FONT).build(); private final FComboBox cbVariants = new FComboBox<>(); private final List playerPanels = new ArrayList<>(MAX_PLAYERS); @@ -117,7 +119,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { add(lblVariants); add(cbVariants); cbVariants.setFont(VARIANTS_FONT); - cbVariants.addItem("(None)"); + cbVariants.addItem("(" + localizer.getMessage("lblNone") + ")"); cbVariants.addItem(GameType.Vanguard); cbVariants.addItem(GameType.MomirBasic); cbVariants.addItem(GameType.MoJhoSto); @@ -128,7 +130,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { cbVariants.addItem(GameType.Planechase); cbVariants.addItem(GameType.Archenemy); cbVariants.addItem(GameType.ArchenemyRumble); - cbVariants.addItem("More...."); + cbVariants.addItem(localizer.getMessage("lblMore")); cbVariants.setChangedHandler(new FEventHandler() { @Override public void handleEvent(FEvent e) { @@ -282,7 +284,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { FThreads.invokeInEdtLater(new Runnable() { @Override public void run() { - LoadingOverlay.show("Loading new game...", startGame); + LoadingOverlay.show(localizer.getMessage("lblLoadingNewGame"), startGame); } }); } @@ -312,7 +314,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { // Name String prefName = prefs.getPref(FPref.PLAYER_NAME); - playerPanels.get(0).setPlayerName(StringUtils.isBlank(prefName) ? "Human" : prefName); + playerPanels.get(0).setPlayerName(StringUtils.isBlank(prefName) ? Localizer.getInstance().getMessage("lblHuman") : prefName); } List getUsedAvatars() { @@ -347,7 +349,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { private final FList lstVariants = add(new FList<>()); private MultiVariantSelect() { - super("Select Variants"); + super(Localizer.getInstance().getMessage("lblSelectVariants")); lstVariants.setListItemRenderer(new VariantRenderer()); lstVariants.addItem(new Variant(GameType.Vanguard)); @@ -625,7 +627,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView { if (ready) { updateDeck(index); if (decks[index] == null) { - FOptionPane.showErrorDialog("Select a deck before readying!"); + FOptionPane.showErrorDialog(localizer.getMessage("msgSelectAdeckBeforeReadying")); update(false); return; } diff --git a/forge-gui-mobile/src/forge/screens/constructed/PlayerPanel.java b/forge-gui-mobile/src/forge/screens/constructed/PlayerPanel.java index 22a48093b2e..1f2e28ff3ad 100644 --- a/forge-gui-mobile/src/forge/screens/constructed/PlayerPanel.java +++ b/forge-gui-mobile/src/forge/screens/constructed/PlayerPanel.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import forge.util.*; import org.apache.commons.lang3.StringUtils; import com.badlogic.gdx.utils.Align; import com.google.common.collect.ImmutableList; @@ -39,10 +40,6 @@ import forge.toolbox.FOptionPane; import forge.toolbox.FTextField; import forge.toolbox.FToggleSwitch; import forge.toolbox.FEvent.FEventHandler; -import forge.util.Callback; -import forge.util.Lang; -import forge.util.NameGenerator; -import forge.util.Utils; public class PlayerPanel extends FContainer { private static final ForgePreferences prefs = FModel.getPreferences(); @@ -60,21 +57,22 @@ public class PlayerPanel extends FContainer { private final FLabel avatarLabel = new FLabel.Builder().opaque(true).iconScaleFactor(0.99f).alphaComposite(1).iconInBackground(true).build(); private int avatarIndex; - private final FTextField txtPlayerName = new FTextField("Player name"); + final Localizer localizer = Localizer.getInstance(); + private final FTextField txtPlayerName = new FTextField(localizer.getMessage("lblPlayerName")); private final FToggleSwitch humanAiSwitch; private final FToggleSwitch devModeSwitch; private FComboBox cbTeam = new FComboBox<>(); private FComboBox cbArchenemyTeam = new FComboBox<>(); - private final FLabel btnDeck = new FLabel.ButtonBuilder().text("Loading Deck...").build(); - private final FLabel btnSchemeDeck = new FLabel.ButtonBuilder().text("Scheme Deck: Random Generated Deck").build(); - private final FLabel btnCommanderDeck = new FLabel.ButtonBuilder().text("Commander Deck: Random Generated Deck").build(); - private final FLabel btnOathbreakDeck = new FLabel.ButtonBuilder().text("Oathbreaker Deck: Random Generated Deck").build(); - private final FLabel btnTinyLeadersDeck = new FLabel.ButtonBuilder().text("Tiny Leaders Deck: Random Generated Deck").build(); - private final FLabel btnBrawlDeck = new FLabel.ButtonBuilder().text("Brawl Deck: Random Generated Deck").build(); - private final FLabel btnPlanarDeck = new FLabel.ButtonBuilder().text("Planar Deck: Random Generated Deck").build(); - private final FLabel btnVanguardAvatar = new FLabel.ButtonBuilder().text("Vanguard Avatar: Random").build(); + private final FLabel btnDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblLoadingDeck")).build(); + private final FLabel btnSchemeDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblSchemeDeckRandomGenerated")).build(); + private final FLabel btnCommanderDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblCommanderDeckRandomGenerated")).build(); + private final FLabel btnOathbreakDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblOathbreakerDeckRandomGenerated")).build(); + private final FLabel btnTinyLeadersDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblTinyLeadersDeckRandomGenerated")).build(); + private final FLabel btnBrawlDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblBrawlDeckRandomGenerated")).build(); + private final FLabel btnPlanarDeck = new FLabel.ButtonBuilder().text(localizer.getMessage("lblPlanarDeckRandomGenerated")).build(); + private final FLabel btnVanguardAvatar = new FLabel.ButtonBuilder().text(localizer.getMessage("lblVanguardAvatarRandom")).build(); private final FDeckChooser deckChooser, lstSchemeDecks, lstCommanderDecks, lstOathbreakerDecks, lstTinyLeadersDecks, lstBrawlDecks, lstPlanarDecks; private final FVanguardChooser lstVanguardAvatars; @@ -84,10 +82,10 @@ public class PlayerPanel extends FContainer { screen = screen0; allowNetworking = allowNetworking0; if (allowNetworking) { - humanAiSwitch = new FToggleSwitch("Not Ready", "Ready"); + humanAiSwitch = new FToggleSwitch(localizer.getMessage("lblNotReady"), localizer.getMessage("lblReady")); } else { - humanAiSwitch = new FToggleSwitch("Human", "AI"); + humanAiSwitch = new FToggleSwitch(localizer.getMessage("lblHuman"), localizer.getMessage("lblAI")); } index = index0; populateTeamsComboBoxes(); @@ -97,7 +95,7 @@ public class PlayerPanel extends FContainer { setPlayerName(slot.getName()); setAvatarIndex(slot.getAvatarIndex()); - devModeSwitch = new FToggleSwitch("Normal", "Dev Mode"); + devModeSwitch = new FToggleSwitch(localizer.getMessage("lblNormal"), localizer.getMessage("lblDevMode")); devModeSwitch.setVisible(isNetworkHost()); cbTeam.setEnabled(true); @@ -117,10 +115,10 @@ public class PlayerPanel extends FContainer { @Override public void handleEvent(FEvent e) { if( ((DeckManager)e.getSource()).getSelectedItem() != null) { - btnCommanderDeck.setText("Commander Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName()); + btnCommanderDeck.setText(localizer.getMessage("lblCommanderDeck") + ": " + ((DeckManager) e.getSource()).getSelectedItem().getName()); lstCommanderDecks.saveState(); }else{ - btnCommanderDeck.setText("Commander Deck"); + btnCommanderDeck.setText(localizer.getMessage("lblCommanderDeck")); } } }); @@ -128,10 +126,10 @@ public class PlayerPanel extends FContainer { @Override public void handleEvent(FEvent e) { if( ((DeckManager)e.getSource()).getSelectedItem() != null) { - btnOathbreakDeck.setText("Oathbreaker Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName()); + btnOathbreakDeck.setText(localizer.getMessage("lblOathbreakerDeck") + ": " + ((DeckManager) e.getSource()).getSelectedItem().getName()); lstOathbreakerDecks.saveState(); }else{ - btnOathbreakDeck.setText("Oathbreaker Deck"); + btnOathbreakDeck.setText(localizer.getMessage("lblOathbreakerDeck")); } } }); @@ -139,10 +137,10 @@ public class PlayerPanel extends FContainer { @Override public void handleEvent(FEvent e) { if( ((DeckManager)e.getSource()).getSelectedItem() != null) { - btnTinyLeadersDeck.setText("Tiny Leaders Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName()); + btnTinyLeadersDeck.setText(localizer.getMessage("lblTinyLeadersDeck") + ": " + ((DeckManager) e.getSource()).getSelectedItem().getName()); lstTinyLeadersDecks.saveState(); }else{ - btnTinyLeadersDeck.setText("Tiny Leaders Deck"); + btnTinyLeadersDeck.setText(localizer.getMessage("lblTinyLeadersDeck")); } } }); @@ -150,10 +148,10 @@ public class PlayerPanel extends FContainer { @Override public void handleEvent(FEvent e) { if( ((DeckManager)e.getSource()).getSelectedItem() != null) { - btnBrawlDeck.setText("Brawl Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName()); + btnBrawlDeck.setText(localizer.getMessage("lblBrawlDeck") + ": " + ((DeckManager) e.getSource()).getSelectedItem().getName()); lstBrawlDecks.saveState(); }else{ - btnBrawlDeck.setText("Brawl Deck"); + btnBrawlDeck.setText(localizer.getMessage("lblBrawlDeck")); } } }); @@ -161,9 +159,9 @@ public class PlayerPanel extends FContainer { @Override public void handleEvent(FEvent e) { if( ((DeckManager)e.getSource()).getSelectedItem() != null){ - btnSchemeDeck.setText("Scheme Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName()); + btnSchemeDeck.setText(localizer.getMessage("lblSchemeDeck") + ": " + ((DeckManager)e.getSource()).getSelectedItem().getName()); }else{ - btnSchemeDeck.setText("Scheme Deck"); + btnSchemeDeck.setText(localizer.getMessage("lblSchemeDeck")); } } }); @@ -171,16 +169,16 @@ public class PlayerPanel extends FContainer { @Override public void handleEvent(FEvent e) { if( ((DeckManager)e.getSource()).getSelectedItem() != null){ - btnPlanarDeck.setText("Planar Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName()); + btnPlanarDeck.setText(localizer.getMessage("lblPlanarDeck") + ": " + ((DeckManager)e.getSource()).getSelectedItem().getName()); }else{ - btnPlanarDeck.setText("Planar Deck"); + btnPlanarDeck.setText(localizer.getMessage("lblPlanarDeck")); } } }); lstVanguardAvatars = new FVanguardChooser(isAi, new FEventHandler() { @Override public void handleEvent(FEvent e) { - btnVanguardAvatar.setText("Vanguard: " + ((CardManager)e.getSource()).getSelectedItem().getName()); + btnVanguardAvatar.setText(localizer.getMessage("lblVanguard") + ": " + ((CardManager)e.getSource()).getSelectedItem().getName()); } }); @@ -188,7 +186,7 @@ public class PlayerPanel extends FContainer { add(avatarLabel); createNameEditor(); - add(newLabel("Name:")); + add(newLabel(localizer.getMessage("lblName") + ":")); add(txtPlayerName); nameRandomiser = createNameRandomizer(); @@ -197,7 +195,7 @@ public class PlayerPanel extends FContainer { humanAiSwitch.setChangedHandler(humanAiSwitched); add(humanAiSwitch); - add(newLabel("Team:")); + add(newLabel(localizer.getMessage("lblTeam") + ":")); cbTeam.setChangedHandler(teamChangedHandler); cbArchenemyTeam.setChangedHandler(teamChangedHandler); add(cbTeam); @@ -211,7 +209,7 @@ public class PlayerPanel extends FContainer { btnDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - deckChooser.setHeaderCaption("Select Deck for " + txtPlayerName.getText()); + deckChooser.setHeaderCaption(localizer.getMessage("lblSelectDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(deckChooser); } }); @@ -219,7 +217,7 @@ public class PlayerPanel extends FContainer { btnCommanderDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstCommanderDecks.setHeaderCaption("Select Commander Deck for " + txtPlayerName.getText()); + lstCommanderDecks.setHeaderCaption(localizer.getMessage("lblSelectCommanderDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstCommanderDecks); } }); @@ -227,7 +225,7 @@ public class PlayerPanel extends FContainer { btnOathbreakDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstOathbreakerDecks.setHeaderCaption("Select Oathbreaker Deck for " + txtPlayerName.getText()); + lstOathbreakerDecks.setHeaderCaption(localizer.getMessage("lblSelectOathbreakerDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstOathbreakerDecks); } }); @@ -235,7 +233,7 @@ public class PlayerPanel extends FContainer { btnTinyLeadersDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstTinyLeadersDecks.setHeaderCaption("Select Tiny Leaders Deck for " + txtPlayerName.getText()); + lstTinyLeadersDecks.setHeaderCaption(localizer.getMessage("lblSelectTinyLeadersDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstTinyLeadersDecks); } }); @@ -243,7 +241,7 @@ public class PlayerPanel extends FContainer { btnBrawlDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstBrawlDecks.setHeaderCaption("Select Brawl Deck for " + txtPlayerName.getText()); + lstBrawlDecks.setHeaderCaption(localizer.getMessage("lblSelectBrawlDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstBrawlDecks); } }); @@ -251,7 +249,7 @@ public class PlayerPanel extends FContainer { btnSchemeDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstSchemeDecks.setHeaderCaption("Select Scheme Deck for " + txtPlayerName.getText()); + lstSchemeDecks.setHeaderCaption(localizer.getMessage("lblSelectSchemeDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstSchemeDecks); } }); @@ -259,7 +257,7 @@ public class PlayerPanel extends FContainer { btnPlanarDeck.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstPlanarDecks.setHeaderCaption("Select Planar Deck for " + txtPlayerName.getText()); + lstPlanarDecks.setHeaderCaption(localizer.getMessage("lblSelectPlanarDeckFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstPlanarDecks); } }); @@ -267,7 +265,7 @@ public class PlayerPanel extends FContainer { btnVanguardAvatar.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - lstVanguardAvatars.setHeaderCaption("Select Vanguard for " + txtPlayerName.getText()); + lstVanguardAvatars.setHeaderCaption(localizer.getMessage("lblSelectVanguardFor").replace("%s", txtPlayerName.getText())); Forge.openScreen(lstVanguardAvatars); } }); @@ -565,11 +563,11 @@ public class PlayerPanel extends FContainer { } private void populateTeamsComboBoxes() { - cbArchenemyTeam.addItem("Archenemy"); - cbArchenemyTeam.addItem("Heroes"); + cbArchenemyTeam.addItem(localizer.getMessage("lblArchenemy")); + cbArchenemyTeam.addItem(localizer.getMessage("lblHeroes")); for (int i = 1; i <= LobbyScreen.MAX_PLAYERS; i++) { - cbTeam.addItem("Team " + i); + cbTeam.addItem(localizer.getMessage("lblTeam") + " " + i); } cbTeam.setEnabled(mayEdit); } @@ -639,7 +637,7 @@ public class PlayerPanel extends FContainer { if (index == 0) { name = FModel.getPreferences().getPref(FPref.PLAYER_NAME); if (name.isEmpty()) { - name = "Human"; + name = localizer.getMessage("lblHuman"); } } else { @@ -837,11 +835,11 @@ public class PlayerPanel extends FContainer { return new FLabel.Builder().text(title).font(LABEL_FONT).align(Align.right).build(); } - private static final ImmutableList genderOptions = ImmutableList.of("Male", "Female", "Any"); - private static final ImmutableList typeOptions = ImmutableList.of("Fantasy", "Generic", "Any"); + private static final ImmutableList genderOptions = ImmutableList.of(Localizer.getInstance().getMessage("lblMale"), Localizer.getInstance().getMessage("lblFemale"), Localizer.getInstance().getMessage("lblAny")); + private static final ImmutableList typeOptions = ImmutableList.of(Localizer.getInstance().getMessage("lblFantasy"), Localizer.getInstance().getMessage("lblGeneric"), Localizer.getInstance().getMessage("lblAny")); private final void getNewName(final Callback callback) { - final String title = "Get new random name"; - final String message = "What type of name do you want to generate?"; + final String title = localizer.getMessage("lblGetNewRandomName"); + final String message = localizer.getMessage("lbltypeofName"); final FSkinImage icon = FOptionPane.QUESTION_ICON; FOptionPane.showOptionDialog(message, title, icon, genderOptions, 2, new Callback() { @@ -869,8 +867,8 @@ public class PlayerPanel extends FContainer { private void generateRandomName(final String gender, final String type, final List usedNames, final String title, final Callback callback) { final String newName = NameGenerator.getRandomName(gender, type, usedNames); - String confirmMsg = "Would you like to use the name \"" + newName + "\", or try again?"; - FOptionPane.showConfirmDialog(confirmMsg, title, "Use this name", "Try again", true, new Callback() { + String confirmMsg = localizer.getMessage("lblconfirmName").replace("%s", newName); + FOptionPane.showConfirmDialog(confirmMsg, title, localizer.getMessage("lblUseThisName"), localizer.getMessage("lblTryAgain"), true, new Callback() { @Override public void run(Boolean result) { if (result) { diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index 8e3727a03e4..444968e230e 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import forge.util.Localizer; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Function; @@ -244,7 +245,7 @@ public class MatchController extends AbstractGuiGame { if (abilities.size() == 1) { return abilities.get(0); } - return SGuiChoose.oneOrNone("Choose ability to play", abilities); + return SGuiChoose.oneOrNone(Localizer.getInstance().getMessage("lblChooseAbilityToPlay"), abilities); } @Override @@ -519,7 +520,7 @@ public class MatchController extends AbstractGuiGame { public List chooseEntitiesForEffect(String title, List optionList, int min, int max, DelayedReveal delayedReveal) { final int m1 = max >= 0 ? optionList.size() - max : -1; final int m2 = min >= 0 ? optionList.size() - min : -1; - return SGuiChoose.order(title, "Selected", m1, m2, (List) optionList, null); + return SGuiChoose.order(title, Localizer.getInstance().getMessage("lblSelected"), m1, m2, (List) optionList, null); } @Override diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 9a49fbe6873..c516f137e54 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -152,7 +152,7 @@ public class MatchScreen extends FScreen { else { menuBar.addTab("\u2022 \u2022 \u2022", new PlayerSpecificMenu(true)); stack.setRotate90(true); - menuBar.addTab(localizer.getMessage("Stack") + " (0)", stack); + menuBar.addTab(localizer.getMessage("lblStack") + " (0)", stack); menuBar.addTab("\u2022 \u2022 \u2022", new PlayerSpecificMenu(false)); //create fake menu tabs for other drop downs so they can be positioned as needed diff --git a/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java b/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java index fa78bdb428e..cf900c6c192 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java @@ -11,6 +11,7 @@ import forge.screens.settings.SettingsScreen; import forge.toolbox.FEvent; import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FOptionPane; +import forge.util.Localizer; import forge.util.ThreadUtil; public class VGameMenu extends FDropDownMenu { @@ -19,6 +20,8 @@ public class VGameMenu extends FDropDownMenu { @Override protected void buildMenu() { + final Localizer localizer = Localizer.getInstance(); + addItem(new FMenuItem(MatchController.instance.getConcedeCaption(), FSkinImage.CONCEDE, new FEventHandler() { @Override public void handleEvent(FEvent e) { @@ -43,7 +46,7 @@ public class VGameMenu extends FDropDownMenu { GameStateDeserializer.loadGameState(MatchUtil.getGame(), ForgeConstants.USER_GAMES_DIR + "GameSave.txt"); } }));*/ - addItem(new FMenuItem("Deck List", FSkinImage.DECKLIST, new FEventHandler() { + addItem(new FMenuItem(localizer.getMessage("lblDeckList"), FSkinImage.DECKLIST, new FEventHandler() { @Override public void handleEvent(FEvent e) { final Player player = MatchController.getHostedMatch().getGame().getPhaseHandler().getPlayerTurn(); @@ -54,10 +57,10 @@ public class VGameMenu extends FDropDownMenu { return; } } - FOptionPane.showMessageDialog("No player has priority at the moment, so deck list can't be viewed."); + FOptionPane.showMessageDialog(localizer.getMessage("lblNoPlayerPriorityNoDeckListViewed")); } })); - addItem(new FMenuItem("Auto-Yields", FSkinImage.WARNING, new FEventHandler() { + addItem(new FMenuItem(localizer.getMessage("lblAutoYields"), FSkinImage.WARNING, new FEventHandler() { @Override public void handleEvent(FEvent e) { final boolean autoYieldsDisabled = MatchController.instance.getDisableAutoYields(); @@ -82,7 +85,7 @@ public class VGameMenu extends FDropDownMenu { autoYields.show(); } })); - addItem(new FMenuItem("Settings", FSkinImage.SETTINGS, new FEventHandler() { + addItem(new FMenuItem(localizer.getMessage("lblSettings"), FSkinImage.SETTINGS, new FEventHandler() { @Override public void handleEvent(FEvent e) { SettingsScreen.show(false); diff --git a/forge-gui-mobile/src/forge/screens/settings/FilesPage.java b/forge-gui-mobile/src/forge/screens/settings/FilesPage.java index 4f4367b646f..940f9c44ef6 100644 --- a/forge-gui-mobile/src/forge/screens/settings/FilesPage.java +++ b/forge-gui-mobile/src/forge/screens/settings/FilesPage.java @@ -1,6 +1,7 @@ package forge.screens.settings; import forge.download.*; +import forge.util.Localizer; import org.apache.commons.lang3.StringUtils; import com.badlogic.gdx.utils.Align; @@ -20,47 +21,48 @@ import forge.util.Callback; public class FilesPage extends TabPage { private final FGroupList lstItems = add(new FGroupList<>()); + private final Localizer localizer = Localizer.getInstance(); protected FilesPage() { - super("Files", FSkinImage.OPEN); + super(Localizer.getInstance().getMessage("lblFiles"), FSkinImage.OPEN); lstItems.setListItemRenderer(new FilesItemRenderer()); - lstItems.addGroup("Content Downloaders"); - lstItems.addGroup("Storage Locations"); + lstItems.addGroup(localizer.getMessage("ContentDownloaders")); + lstItems.addGroup(localizer.getMessage("lblStorageLocations")); //lstItems.addGroup("Data Import"); //content downloaders - lstItems.addItem(new ContentDownloader("Download LQ Card Pictures", - "Download default card picture for each card.") { + lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadPics"), + localizer.getMessage("lblDownloadPics")) { @Override protected GuiDownloadService createService() { return new GuiDownloadPicturesLQ(); } }, 0); - lstItems.addItem(new ContentDownloader("Download LQ Set Pictures", - "Download all pictures of each card (one for each set the card appeared in)") { + lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadSetPics"), + localizer.getMessage("lblDownloadSetPics")) { @Override protected GuiDownloadService createService() { return new GuiDownloadSetPicturesLQ(); } }, 0); - lstItems.addItem(new ContentDownloader("Download Quest Images", - "Download tokens and icons used in Quest mode.") { + lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadQuestImages"), + localizer.getMessage("lblDownloadQuestImages")) { @Override protected GuiDownloadService createService() { return new GuiDownloadQuestImages(); } }, 0); - lstItems.addItem(new ContentDownloader("Download Achievement Images", - "Download achievement images to really make your trophies stand out.") { + lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadAchievementImages"), + localizer.getMessage("lblDownloadAchievementImages")) { @Override protected GuiDownloadService createService() { return new GuiDownloadAchievementImages(); } }, 0); - lstItems.addItem(new ContentDownloader("Download Card Prices", - "Download up-to-date price list for in-game card shops.") { + lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadPrices"), + localizer.getMessage("lblDownloadPrices")) { @Override protected GuiDownloadService createService() { return new GuiDownloadPrices(); @@ -68,19 +70,19 @@ public class FilesPage extends TabPage { }, 0); //storage locations - final StorageOption cardPicsOption = new StorageOption("Card Pics Location", ForgeProfileProperties.getCardPicsDir()) { + final StorageOption cardPicsOption = new StorageOption(localizer.getMessage("lblCardPicsLocation"), ForgeProfileProperties.getCardPicsDir()) { @Override protected void onDirectoryChanged(String newDir) { ForgeProfileProperties.setCardPicsDir(newDir); } }; - final StorageOption decksOption = new StorageOption("Decks Location", ForgeProfileProperties.getDecksDir()) { + final StorageOption decksOption = new StorageOption(localizer.getMessage("lblDecksLocation"), ForgeProfileProperties.getDecksDir()) { @Override protected void onDirectoryChanged(String newDir) { ForgeProfileProperties.setDecksDir(newDir); } }; - lstItems.addItem(new StorageOption("Data Location (e.g. Settings and Quests)", ForgeProfileProperties.getUserDir()) { + lstItems.addItem(new StorageOption(localizer.getMessage("lblDataLocation"), ForgeProfileProperties.getUserDir()) { @Override protected void onDirectoryChanged(String newDir) { ForgeProfileProperties.setUserDir(newDir); @@ -89,7 +91,7 @@ public class FilesPage extends TabPage { decksOption.updateDir(ForgeProfileProperties.getDecksDir()); } }, 1); - lstItems.addItem(new StorageOption("Image Cache Location", ForgeProfileProperties.getCacheDir()) { + lstItems.addItem(new StorageOption(localizer.getMessage("lblImageCacheLocation"), ForgeProfileProperties.getCacheDir()) { @Override protected void onDirectoryChanged(String newDir) { ForgeProfileProperties.setCacheDir(newDir); @@ -171,13 +173,13 @@ public class FilesPage extends TabPage { @Override public void select() { - FFileChooser.show("Select " + label, ChoiceType.GetDirectory, description, new Callback() { + FFileChooser.show(localizer.getMessage("lblSelect").replace("%s", label), ChoiceType.GetDirectory, description, new Callback() { @Override public void run(String result) { if (StringUtils.isEmpty(result) || description.equals(result)) { return; } updateDir(result); onDirectoryChanged(result); - FOptionPane.showMessageDialog("You'll need to restart Forge for this change to take effect. Be sure to move any necessary files to the new location before you do.", "Restart Required", FOptionPane.INFORMATION_ICON); + FOptionPane.showMessageDialog(localizer.getMessage("lblRestartForgeMoveFilesNewLocation"), localizer.getMessage("lblRestartRequired"), FOptionPane.INFORMATION_ICON); } }); } diff --git a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java index 62bdd7a3844..2c6ae253c5c 100644 --- a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java +++ b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java @@ -37,7 +37,7 @@ public class SettingsPage extends TabPage { private final FGroupList lstSettings = add(new FGroupList<>()); public SettingsPage() { - super("Settings", FSkinImage.SETTINGS); + super(Localizer.getInstance().getMessage("lblSettings"), FSkinImage.SETTINGS); final Localizer localizer = Localizer.getInstance(); diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 4a84d50e47a..3aba248ee9a 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -373,6 +373,17 @@ btnBuildNewSealedDeck=Erstelle neues Sealed Deck lblViewDeck=Zeige Deck lblRandomDeck=Zufälliges Deck lblRandomColors=Zufällige Farben +lblMustSelectGenerateNewDeck=You must select something before you can generate a new deck. +lblOK=OK +lblCannotEditDuplicateCustomDeck=cannot be edited directly. Would you like to duplicate %s for editing as a custom user deck? +lblDuplicateDeck=Duplicate Deck? +lblDuplicate=Duplicate +lblHowManyOpponents=How many opponents are you willing to face? +lblChooseAllowedDeckTypeOpponents=Choose allowed deck types for opponents +lblSelectOpponentDeck=Select Opponent's Deck +lblGenerateNewDeck=Generate New Deck +lblRandomTheme=Random Theme +lblTestDeck=Test Deck #GameType.java lblSealed=Sealed lblDraft=Draft @@ -967,10 +978,68 @@ lblToMainDeck=zum Haupt-Deck lblHowMany=wie viel? lblInventory=Inhaltsverzeichnis lblCollection=Sammlung -lblCatalog=Katalog lblCommanders=Komandeure lblOathbreakers=Eidbrecher #Forge.java lblLoadingFonts=Lade Schriften... lblLoadingCardTranslations=Lade Kartenübersetzungen... lblFinishingStartup=Abschliessen... +#LobbyScreen.java +lblMore=More... +lblLoadingNewGame=Loading new game... +lblSelectVariants=Select Variants +msgSelectAdeckBeforeReadying=Select a deck before readying! +#PlayerPanel +lblLoadingDeck=Loading Deck... +lblSchemeDeckRandomGenerated=Scheme Deck: Random Generated Deck +lblCommanderDeckRandomGenerated=Commander Deck: Random Generated Deck +lblOathbreakerDeckRandomGenerated=Oathbreaker Deck: Random Generated Deck +lblTinyLeadersDeckRandomGenerated=Tiny Leaders Deck: Random Generated Deck +lblBrawlDeckRandomGenerated=Brawl Deck: Random Generated Deck +lblPlanarDeckRandomGenerated=Planar Deck: Random Generated Deck +lblVanguardAvatarRandom=Vanguard Avatar: Random +lblNotReady=Not Ready +lblNormal=Normal +lblDevMode=Dev Mode +lblOathbreakerDeck=Oathbreaker Deck +lblTinyLeadersDeck=Tiny Leaders Deck +lblBrawlDeck=Brawl Deck +lblSelectDeckFor=Select Deck for %s +lblSelectCommanderDeckFor=Select Commander Deck for %s +lblSelectOathbreakerDeckFor=Select Oathbreaker Deck for %s +lblSelectTinyLeadersDeckFor=Select Tiny Leaders Deck for %s +lblSelectBrawlDeckFor=Select Brawl Deck for %s +lblSelectSchemeDeckFor=Select Scheme Deck for %s +lblSelectPlanarDeckFor=Select Planar Deck for %s +lblSelectVanguardFor=Select Vanguard for %s +lblMale=Male +lblFemale=Female +lblAny=Any +lblFantasy=Fantasy +lblGeneric=Generic +#MatchController +lblChooseAbilityToPlay=Choose ability to play +lblSelected=Selected +#ItemManager +lblAdvancedSearch=Advanced Search +lblSort=Sort +lblResetFilters=Reset Filters +#AdvancedSearchFilter +lblEditExpression=Edit Expression +lblRemoveFilter=Remove Filter +#CardZoom +lblSwipeUpTo=Swipe up to %s +lblSwipeDownDetailView=Swipe down to switch to detail view +lblSwipeDownPictureView=Swipe down to switch to picture view +#VGameMenu +lblNoPlayerPriorityNoDeckListViewed=No player has priority at the moment, so deck list can't be viewed. +#FilesPage +lblFiles=Files +lblStorageLocations=Storage Locations +lblCardPicsLocation=Card Pics Location +lblDecksLocation=Decks Location +lblDataLocation=Data Location (e.g. Settings and Quests) +lblImageCacheLocation=Image Cache Location +lblRestartForgeMoveFilesNewLocation=You'll need to restart Forge for this change to take effect. Be sure to move any necessary files to the new location before you do. +lblRestartRequired=Restart Required +lblSelect=Select %s \ No newline at end of file diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 86f39905691..48a902c7dee 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -373,6 +373,17 @@ btnBuildNewSealedDeck=Build New Sealed Deck lblViewDeck=View Deck lblRandomDeck=Random Deck lblRandomColors=Random Colors +lblMustSelectGenerateNewDeck=You must select something before you can generate a new deck. +lblOK=OK +lblCannotEditDuplicateCustomDeck=cannot be edited directly. Would you like to duplicate %s for editing as a custom user deck? +lblDuplicateDeck=Duplicate Deck? +lblDuplicate=Duplicate +lblHowManyOpponents=How many opponents are you willing to face? +lblChooseAllowedDeckTypeOpponents=Choose allowed deck types for opponents +lblSelectOpponentDeck=Select Opponent's Deck +lblGenerateNewDeck=Generate New Deck +lblRandomTheme=Random Theme +lblTestDeck=Test Deck #GameType.java lblSealed=Sealed lblDraft=Draft @@ -967,10 +978,68 @@ lblToMainDeck=to Main Deck lblHowMany=how many? lblInventory=Inventory lblCollection=Collection -lblCatalog=Catalog lblCommanders=Commanders lblOathbreakers=Oathbreakers #Forge.java lblLoadingFonts=Loading fonts... lblLoadingCardTranslations=Loading card translations... -lblFinishingStartup=Finishing startup... \ No newline at end of file +lblFinishingStartup=Finishing startup... +#LobbyScreen.java +lblMore=More... +lblLoadingNewGame=Loading new game... +lblSelectVariants=Select Variants +msgSelectAdeckBeforeReadying=Select a deck before readying! +#PlayerPanel +lblLoadingDeck=Loading Deck... +lblSchemeDeckRandomGenerated=Scheme Deck: Random Generated Deck +lblCommanderDeckRandomGenerated=Commander Deck: Random Generated Deck +lblOathbreakerDeckRandomGenerated=Oathbreaker Deck: Random Generated Deck +lblTinyLeadersDeckRandomGenerated=Tiny Leaders Deck: Random Generated Deck +lblBrawlDeckRandomGenerated=Brawl Deck: Random Generated Deck +lblPlanarDeckRandomGenerated=Planar Deck: Random Generated Deck +lblVanguardAvatarRandom=Vanguard Avatar: Random +lblNotReady=Not Ready +lblNormal=Normal +lblDevMode=Dev Mode +lblOathbreakerDeck=Oathbreaker Deck +lblTinyLeadersDeck=Tiny Leaders Deck +lblBrawlDeck=Brawl Deck +lblSelectDeckFor=Select Deck for %s +lblSelectCommanderDeckFor=Select Commander Deck for %s +lblSelectOathbreakerDeckFor=Select Oathbreaker Deck for %s +lblSelectTinyLeadersDeckFor=Select Tiny Leaders Deck for %s +lblSelectBrawlDeckFor=Select Brawl Deck for %s +lblSelectSchemeDeckFor=Select Scheme Deck for %s +lblSelectPlanarDeckFor=Select Planar Deck for %s +lblSelectVanguardFor=Select Vanguard for %s +lblMale=Male +lblFemale=Female +lblAny=Any +lblFantasy=Fantasy +lblGeneric=Generic +#MatchController +lblChooseAbilityToPlay=Choose ability to play +lblSelected=Selected +#ItemManager +lblAdvancedSearch=Advanced Search +lblSort=Sort +lblResetFilters=Reset Filters +#AdvancedSearchFilter +lblEditExpression=Edit Expression +lblRemoveFilter=Remove Filter +#CardZoom +lblSwipeUpTo=Swipe up to %s +lblSwipeDownDetailView=Swipe down to switch to detail view +lblSwipeDownPictureView=Swipe down to switch to picture view +#VGameMenu +lblNoPlayerPriorityNoDeckListViewed=No player has priority at the moment, so deck list can't be viewed. +#FilesPage +lblFiles=Files +lblStorageLocations=Storage Locations +lblCardPicsLocation=Card Pics Location +lblDecksLocation=Decks Location +lblDataLocation=Data Location (e.g. Settings and Quests) +lblImageCacheLocation=Image Cache Location +lblRestartForgeMoveFilesNewLocation=You'll need to restart Forge for this change to take effect. Be sure to move any necessary files to the new location before you do. +lblRestartRequired=Restart Required +lblSelect=Select %s \ No newline at end of file diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 968fbf9fc48..bb9b5b01f6f 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -231,7 +231,7 @@ lblGameSettings=Configuración lblHeaderConstructedMode=Formato Oficial: Construido lblGetNewRandomName=Obtener nuevo nombre aleatorio lbltypeofName=¿Qué tipo de nombre quieres generar? -lblconfirmName=¿Quieres usar el nombre de %n, o probar de nuevo? +lblconfirmName=¿Quieres usar el nombre de %s, o probar de nuevo? lblUseThisName=Usar este nombre lblTryAgain=Probar de nuevo lblAddAPlayer=Añadir Jugador @@ -373,6 +373,17 @@ btnBuildNewSealedDeck=Nuevo Mazo Sellado lblViewDeck=Ver Mazo lblRandomDeck=Mazo Aleatorio lblRandomColors=Colores Aleatorios +lblMustSelectGenerateNewDeck=Debes seleccionar algo antes de generar un nuevo mazo. +lblOK=OK +lblCannotEditDuplicateCustomDeck= no se puede editar directamente. ¿Quieres duplicar %s para editarlo como un mazo de usuario personalizado? +lblDuplicateDeck=¿Duplicar Mazo? +lblDuplicate=Duplicar +lblHowManyOpponents=¿A cuántos oponentes está dispuesto a enfrentarse? +lblChooseAllowedDeckTypeOpponents=Elige los tipos de mazo permitidos para los oponentes +lblSelectOpponentDeck=Seleccionar Mazo del Oponente +lblGenerateNewDeck=Generar un Nuevo Mazo +lblRandomTheme=Tema Aleatorio +lblTestDeck=Probar Mazo #GameType.java lblSealed=Sellado lblDraft=Draft @@ -967,10 +978,68 @@ lblToMainDeck=al Mazo Principal lblHowMany=¿cuántos? lblInventory=Inventario lblCollection=Colección -lblCatalog=Catálogo lblCommanders=Commanders lblOathbreakers=Oathbreakers #Forge.java lblLoadingFonts=Loading fonts... lblLoadingCardTranslations=Loading card translations... -lblFinishingStartup=Finishing startup... \ No newline at end of file +lblFinishingStartup=Finishing startup... +#LobbyScreen.java +lblMore=Más... +lblLoadingNewGame=Cargando nueva partida... +lblSelectVariants=Selecciona Variants +msgSelectAdeckBeforeReadying=¡Selecciona un mazo antes de estar listo! +#PlayerPanel +lblLoadingDeck=Cargando mazo... +lblSchemeDeckRandomGenerated=Scheme Deck: Random Generated Deck +lblCommanderDeckRandomGenerated=Commander Deck: Random Generated Deck +lblOathbreakerDeckRandomGenerated=Oathbreaker Deck: Random Generated Deck +lblTinyLeadersDeckRandomGenerated=Tiny Leaders Deck: Random Generated Deck +lblBrawlDeckRandomGenerated=Brawl Deck: Random Generated Deck +lblPlanarDeckRandomGenerated=Planar Deck: Random Generated Deck +lblVanguardAvatarRandom=Vanguard Avatar: Random +lblNotReady=No Listo +lblNormal=Normal +lblDevMode=Dev Mode +lblOathbreakerDeck=Mazo Oathbreaker +lblTinyLeadersDeck=Mazo Tiny Leaders +lblBrawlDeck=Mazo Brawl +lblSelectDeckFor=Selecciona Mazo para %s +lblSelectCommanderDeckFor=Selecciona Mazo Commander para %s +lblSelectOathbreakerDeckFor=Selecciona Mazo Oathbreaker para %s +lblSelectTinyLeadersDeckFor=Selecciona Mazo Tiny Leaders para %s +lblSelectBrawlDeckFor=Selecciona Mazo Brawl para %s +lblSelectSchemeDeckFor=Selecciona Mazo Scheme para %s +lblSelectPlanarDeckFor=Seleccionar Mazo Planar para %s +lblSelectVanguardFor=Selecciona Vanguard para %s +lblMale=Hombre +lblFemale=Mujer +lblAny=Cualquiera +lblFantasy=Fantasía +lblGeneric=Genérico +#MatchController +lblChooseAbilityToPlay=Elige la habilidad para jugar +lblSelected=Seleccionado +#ItemManager +lblAdvancedSearch=Búsqueda Avanzada +lblSort=Ordenar +lblResetFilters=Reiniciar Filtros +#AdvancedSearchFilter +lblEditExpression=Editar Expresión +lblRemoveFilter=Eliminar Filtro +#CardZoom +lblSwipeUpTo=Desliza hacia arriba para %s +lblSwipeDownDetailView=Desliza hacia abajo para cambiar a la vista de detalle +lblSwipeDownPictureView=Desliza hacia abajo para cambiar a la vista de imagen +#VGameMenu +lblNoPlayerPriorityNoDeckListViewed=Ningún jugador tiene prioridad en este momento, por lo que la lista de mazos no se puede ver. +#FilesPage +lblFiles=Archivos +lblStorageLocations=Ubicación del almacenamiento +lblCardPicsLocation=Ubicación de las Imágenes de las Cartas +lblDecksLocation=Ubicación de los Mazos +lblDataLocation=Ubicación de los Datos (por ejemplo, Configuración y Aventuras) +lblImageCacheLocation=Ubicación de la Caché de imágenes +lblRestartForgeMoveFilesNewLocation=Necesitarás reiniciar Forge para que este cambio tenga efecto. Asegúrate de mover todos los archivos necesarios a la nueva ubicación antes de hacerlo. +lblRestartRequired=Reinicio Requerido +lblSelect=Seleccionar %s \ No newline at end of file diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index a588789c5db..daa4f85a646 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -373,6 +373,17 @@ btnBuildNewSealedDeck=构建新的现开套牌 lblViewDeck=查看套牌 lblRandomDeck=随机套牌 lblRandomColors=随机颜色 +lblMustSelectGenerateNewDeck=You must select something before you can generate a new deck. +lblOK=OK +lblCannotEditDuplicateCustomDeck=cannot be edited directly. Would you like to duplicate %s for editing as a custom user deck? +lblDuplicateDeck=Duplicate Deck? +lblDuplicate=Duplicate +lblHowManyOpponents=How many opponents are you willing to face? +lblChooseAllowedDeckTypeOpponents=Choose allowed deck types for opponents +lblSelectOpponentDeck=Select Opponent's Deck +lblGenerateNewDeck=Generate New Deck +lblRandomTheme=Random Theme +lblTestDeck=Test Deck #GameType.java lblSealed=现开 lblDraft=轮抓 @@ -967,10 +978,68 @@ lblToMainDeck=到主牌 lblHowMany=多少? lblInventory=库存 lblCollection=珍藏 -lblCatalog=目录 lblCommanders=指挥官 lblOathbreakers=破誓者 #Forge.java lblLoadingFonts=加载字体中 lblLoadingCardTranslations=加载卡牌翻译中 -lblFinishingStartup=完成启动 \ No newline at end of file +lblFinishingStartup=完成启动 +#LobbyScreen.java +lblMore=More... +lblLoadingNewGame=Loading new game... +lblSelectVariants=Select Variants +msgSelectAdeckBeforeReadying=Select a deck before readying! +#PlayerPanel +lblLoadingDeck=Loading Deck... +lblSchemeDeckRandomGenerated=Scheme Deck: Random Generated Deck +lblCommanderDeckRandomGenerated=Commander Deck: Random Generated Deck +lblOathbreakerDeckRandomGenerated=Oathbreaker Deck: Random Generated Deck +lblTinyLeadersDeckRandomGenerated=Tiny Leaders Deck: Random Generated Deck +lblBrawlDeckRandomGenerated=Brawl Deck: Random Generated Deck +lblPlanarDeckRandomGenerated=Planar Deck: Random Generated Deck +lblVanguardAvatarRandom=Vanguard Avatar: Random +lblNotReady=Not Ready +lblNormal=Normal +lblDevMode=Dev Mode +lblOathbreakerDeck=Oathbreaker Deck +lblTinyLeadersDeck=Tiny Leaders Deck +lblBrawlDeck=Brawl Deck +lblSelectDeckFor=Select Deck for %s +lblSelectCommanderDeckFor=Select Commander Deck for %s +lblSelectOathbreakerDeckFor=Select Oathbreaker Deck for %s +lblSelectTinyLeadersDeckFor=Select Tiny Leaders Deck for %s +lblSelectBrawlDeckFor=Select Brawl Deck for %s +lblSelectSchemeDeckFor=Select Scheme Deck for %s +lblSelectPlanarDeckFor=Select Planar Deck for %s +lblSelectVanguardFor=Select Vanguard for %s +lblMale=Male +lblFemale=Female +lblAny=Any +lblFantasy=Fantasy +lblGeneric=Generic +#MatchController +lblChooseAbilityToPlay=Choose ability to play +lblSelected=Selected +#ItemManager +lblAdvancedSearch=Advanced Search +lblSort=Sort +lblResetFilters=Reset Filters +#AdvancedSearchFilter +lblEditExpression=Edit Expression +lblRemoveFilter=Remove Filter +#CardZoom +lblSwipeUpTo=Swipe up to %s +lblSwipeDownDetailView=Swipe down to switch to detail view +lblSwipeDownPictureView=Swipe down to switch to picture view +#VGameMenu +lblNoPlayerPriorityNoDeckListViewed=No player has priority at the moment, so deck list can't be viewed. +#FilesPage +lblFiles=Files +lblStorageLocations=Storage Locations +lblCardPicsLocation=Card Pics Location +lblDecksLocation=Decks Location +lblDataLocation=Data Location (e.g. Settings and Quests) +lblImageCacheLocation=Image Cache Location +lblRestartForgeMoveFilesNewLocation=You'll need to restart Forge for this change to take effect. Be sure to move any necessary files to the new location before you do. +lblRestartRequired=Restart Required +lblSelect=Select %s \ No newline at end of file From 7d5b8d2d5eaf5839402d6a898d6be192daf3003a Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 23 Sep 2019 04:53:14 +0000 Subject: [PATCH 37/37] Fix getController() (Donate -> Illusions of Grandeur -> bounce Illusions of Grandeur, or Path to Exile taken by any player via Act of Treason etc... the effect should be on the controller) --- .../src/main/java/forge/game/card/Card.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) 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 7044c836f46..cf42e514f99 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2722,9 +2722,27 @@ public class Card extends GameEntity implements Comparable { public final Player getController() { if ((currentZone == null) || ((currentZone.getZoneType() != ZoneType.Battlefield) && (currentZone.getZoneType() != ZoneType.Stack))){ - //only permanents and spells have controllers [108.4], - //so a card really only has a controller while it's on the stack or battlefield. - //everywhere else, just use the owner [108.4a]. + /* + * 108.4. A card doesn’t have a controller unless that card represents a permanent or spell; in those cases, + * its controller is determined by the rules for permanents or spells. See rules 110.2 and 112.2. + * 108.4a If anything asks for the controller of a card that doesn’t have one (because it’s not a permanent + * or spell), use its owner instead. + * + * Control, Controller: "Control" is the system that determines who gets to use an object in the game. + * An object's "controller" is the player who currently controls it. See rule 108.4. + * + * 400.6. If an object would move from one zone to another, determine what event is moving the object. + * If the object is moving to a public zone and its owner will be able to look at it in that zone, + * its owner looks at it to see if it has any abilities that would affect the move. + * If the object is moving to the battlefield, each other player who will be able to look at it in that + * zone does so. Then any appropriate replacement effects, whether they come from that object or from + * elsewhere, are applied to that event. If any effects or rules try to do two or more contradictory or + * mutually exclusive things to a particular object, that object’s CONTROLLER—or its OWNER + * IF IT HAS NO CONTROLLER—chooses which effect to apply, and what that effect does. + */ + if (controller != null) { + return controller; // if there's a controller we return this + } if (owner != null) { return owner; }