Merge pull request #5865 from tool4ever/uphill

Fix Uphill Battle
This commit is contained in:
tool4ever
2024-08-11 20:26:46 +02:00
committed by GitHub
13 changed files with 15 additions and 47 deletions

View File

@@ -1315,7 +1315,7 @@ public abstract class GameState {
c.setBackSide(true);
}
else if (info.startsWith("OnAdventure")) {
String abAdventure = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell";
String abAdventure = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.!copiedSpell";
SpellAbility saAdventure = AbilityFactory.getAbility(abAdventure, c);
StringBuilder sbPlay = new StringBuilder();
sbPlay.append("Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonAdventure");

View File

@@ -842,7 +842,6 @@ public class GameAction {
}
if (zoneTo.is(ZoneType.Stack)) {
// zoneFrom maybe null if the spell is cast from "Ouside the game", ex. ability of Garth One-Eye
c.setCastFrom(zoneFrom);
if (cause != null && cause.isSpell() && c.equals(cause.getHostCard())) {
c.setCastSA(cause);

View File

@@ -854,7 +854,7 @@ public final class GameActionUtil {
return;
}
if (fromZone != null) { // and not a copy
if (fromZone != null && !fromZone.is(ZoneType.None)) { // and not a copy
// might have been an alternative lki host
oldCard = ability.getCardState().getCard();

View File

@@ -21,12 +21,6 @@ import forge.util.Localizer;
public class PhasesEffect extends SpellAbilityEffect {
// ******************************************
// ************** Phases ********************
// ******************************************
// Phases generally Phase Out. Time and Tide is the only card that can force
// Phased Out cards in.
/* (non-Javadoc)
* @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility)
*/
@@ -56,10 +50,8 @@ public class PhasesEffect extends SpellAbilityEffect {
tgtCards = game.getCardsIn(ZoneType.Battlefield);
}
tgtCards = AbilityUtils.filterListByType(tgtCards, sa.getParam("AllValid"), sa);
} else if (sa.hasParam("Defined")) {
tgtCards = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
} else {
tgtCards = getTargetCards(sa);
tgtCards = getDefinedCardsOrTargeted(sa);
}
if (sa.hasParam("AnyNumber")) {
tgtCards = activator.getController().chooseCardsForEffect(tgtCards, sa,

View File

@@ -169,6 +169,7 @@ public class PlayEffect extends SpellAbilityEffect {
// so it gets added to stack
card.setCopiedPermanent(card);
card.setToken(true);
card.setZone(controller.getZone(ZoneType.None));
tgtCards = new CardCollection(card);
} else {
tgtCards = new CardCollection();

View File

@@ -1700,7 +1700,7 @@ public class CardFactoryUtil {
final String[] k = keyword.split(":");
String renownTrig = "Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player"
+ " | IsPresent$ Card.Self+IsNotRenowned | CombatDamage$ True | Secondary$ True"
+ " | IsPresent$ Card.Self+!IsRenowned | CombatDamage$ True | Secondary$ True"
+ " | TriggerDescription$ Renown " + k[1] +" (" + inst.getReminderText() + ")";
final String effect = "DB$ PutCounter | Defined$ Self | "
@@ -3229,7 +3229,7 @@ public class CardFactoryUtil {
String desc = "Monstrosity " + magnitude;
String effect = "AB$ PutCounter | Cost$ " + manacost + " | ConditionPresent$ "
+ "Card.Self+IsNotMonstrous | Monstrosity$ True | CounterNum$ " + magnitude
+ "Card.Self+!IsMonstrous | Monstrosity$ True | CounterNum$ " + magnitude
+ " | CounterType$ P1P1 | StackDescription$ SpellDescription";
if (reduceCost != null) {
effect += "| ReduceCost$ " + reduceCost;
@@ -4149,7 +4149,7 @@ public class CardFactoryUtil {
SpellAbility saExile = AbilityFactory.getAbility(abExile, card);
String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell+nonToken";
String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.!copiedSpell+nonToken";
AbilitySub saEffect = (AbilitySub)AbilityFactory.getAbility(abEffect, card);
StringBuilder sbPlay = new StringBuilder();

View File

@@ -1456,10 +1456,6 @@ public class CardProperty {
if (!card.isCopiedSpell()) {
return false;
}
} else if (property.startsWith("nonCopiedSpell")) {
if (card.isCopiedSpell()) {
return false;
}
} else if (property.startsWith("hasXCost")) {
ManaCost cost = card.getManaCost();
if (cost == null || cost.countX() <= 0) {
@@ -1481,10 +1477,6 @@ public class CardProperty {
if (!source.getExploited().contains(card)) {
return false;
}
} else if (property.startsWith("unequalPT")) {
if (card.getNetPower() == card.getNetToughness()) {
return false;
}
} else if (property.startsWith("equalPT")) {
if (card.getNetPower() != card.getNetToughness()) {
return false;
@@ -1899,18 +1891,10 @@ public class CardProperty {
if (card.getDevouredCards().isEmpty()) {
return false;
}
} else if (property.equals("HasNotDevoured")) {
if (!card.getDevouredCards().isEmpty()) {
return false;
}
} else if (property.equals("IsMonstrous")) {
if (!card.isMonstrous()) {
return false;
}
} else if (property.equals("IsNotMonstrous")) {
if (card.isMonstrous()) {
return false;
}
} else if (property.equals("IsUnearthed")) {
if (!card.isUnearthed()) {
return false;
@@ -1919,10 +1903,6 @@ public class CardProperty {
if (!card.isRenowned()) {
return false;
}
} else if (property.equals("IsNotRenowned")) {
if (card.isRenowned()) {
return false;
}
} else if (property.equals("IsSolved")) {
if (!card.isSolved()) {
return false;
@@ -1945,10 +1925,6 @@ public class CardProperty {
if (!card.isSuspected()) {
return false;
}
} else if (property.equals("IsUnsuspected")) {
if (card.isSuspected()) {
return false;
}
} else if (property.equals("IsRemembered")) {
if (!source.isRemembered(card)) {
return false;

View File

@@ -2,7 +2,7 @@ Name:Clay Golem
ManaCost:4
Types:Artifact Creature Golem
PT:4/4
A:AB$ PutCounter | Cost$ 6 RollDice<1/8/X> | ConditionPresent$ Card.Self+IsNotMonstrous | Monstrosity$ True | CounterNum$ X | CounterType$ P1P1 | AILogic$ FromDiceRoll | StackDescription$ SpellDescription | SpellDescription$ Monstrosity X, where X is the result. (If this creature isn't monstrous, put X +1/+1 counters on it and it becomes monstrous.)
A:AB$ PutCounter | Cost$ 6 RollDice<1/8/X> | ConditionPresent$ Card.Self+!IsMonstrous | Monstrosity$ True | CounterNum$ X | CounterType$ P1P1 | AILogic$ FromDiceRoll | StackDescription$ SpellDescription | SpellDescription$ Monstrosity X, where X is the result. (If this creature isn't monstrous, put X +1/+1 counters on it and it becomes monstrous.)
T:Mode$ BecomeMonstrous | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Berserk — When CARDNAME becomes monstrous, destroy target permanent.
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Permanent
DeckHas:Ability$Counters

View File

@@ -4,5 +4,5 @@ Types:Creature Elf Warrior
PT:4/3
K:Menace
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDestroy | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters, you may destroy target non-Elf creature whose power and toughness aren't equal.
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.nonElf+unequalPT | TgtPrompt$ Select target non-Elf creature whose power and toughness aren't equal.
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.nonElf+!equalPT | TgtPrompt$ Select target non-Elf creature whose power and toughness aren't equal.
Oracle:Menace (This creature can't be blocked except by two or more creatures.)\nWhen Gilt-Leaf Winnower enters, you may destroy target non-Elf creature whose power and toughness aren't equal.

View File

@@ -2,7 +2,7 @@ Name:Stonebinder's Familiar
ManaCost:W
Types:Creature Spirit Dog
PT:1/1
T:Mode$ ChangesZoneAll | ValidCards$ Card.nonToken+nonCopiedSpell | Destination$ Exile | TriggerZones$ Battlefield | Execute$ TrigPutcounter | PlayerTurn$ True | ActivationLimit$ 1 | TriggerDescription$ Whenever one or more cards are put into exile during your turn, put a +1/+1 counter on CARDNAME. This ability triggers only once each turn.
T:Mode$ ChangesZoneAll | ValidCards$ Card.nonToken+!copiedSpell | Destination$ Exile | TriggerZones$ Battlefield | Execute$ TrigPutcounter | PlayerTurn$ True | ActivationLimit$ 1 | TriggerDescription$ Whenever one or more cards are put into exile during your turn, put a +1/+1 counter on CARDNAME. This ability triggers only once each turn.
SVar:TrigPutcounter:DB$ PutCounter | CounterType$ P1P1 | Defined$ Self | CounterNum$ 1
DeckHas:Ability$Counters
Oracle:Whenever one or more cards are put into exile during your turn, put a +1/+1 counter on Stonebinder's Familiar. This ability triggers only once each turn.

View File

@@ -3,7 +3,7 @@ ManaCost:2 R W
Types:Legendary Creature Time Lord Doctor
PT:3/5
T:Mode$ PhaseOutAll | ValidCards$ Permanent.phasedOutOther | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more other permanents phase out and whenever one or more other cards are put into exile from anywhere, put a time counter on CARDNAME.
T:Mode$ ChangesZoneAll | ValidCards$ Card.Other+nonToken+nonCopiedSpell | Origin$ Any | Destination$ Exile | TriggerZones$ Battlefield | Execute$ TrigPutCounter | Secondary$ True | TriggerDescription$ Whenever one or more other permanents phase out and whenever one or more other cards are put into exile from anywhere, put a time counter on CARDNAME.
T:Mode$ ChangesZoneAll | ValidCards$ Card.Other+nonToken+!copiedSpell | Origin$ Any | Destination$ Exile | TriggerZones$ Battlefield | Execute$ TrigPutCounter | Secondary$ True | TriggerDescription$ Whenever one or more other permanents phase out and whenever one or more other cards are put into exile from anywhere, put a time counter on CARDNAME.
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ TIME
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDamage | TriggerDescription$ Whenever CARDNAME attacks, it deals damage equal to the number of time counters on it to any target. If a creature dealt damage this way would die this turn, exile it instead.
SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | DamageSource$ TriggeredAttackerLKICopy | NumDmg$ Count$CardCounters.TIME | ReplaceDyingDefined$ Targeted.Creature

View File

@@ -1,6 +1,6 @@
Name:Uphill Battle
ManaCost:2 R
Types:Enchantment
R:Event$ Moved | ValidCard$ Creature.OppCtrl | Destination$ Battlefield | ReplaceWith$ ETBTapped | ReplacementResult$ Updated | ActiveZones$ Battlefield | Description$ Creatures played by your opponents enter tapped.
R:Event$ Moved | ValidCard$ Creature | ValidCause$ LandAbility.OppCtrl,Spell.wasCast+Permanent+CastSa Spell.OppCtrl | Destination$ Battlefield | ReplaceWith$ ETBTapped | ReplacementResult$ Updated | ActiveZones$ Battlefield | Description$ Creatures played by your opponents enter tapped.
SVar:ETBTapped:DB$ Tap | ETB$ True | Defined$ ReplacedCard
Oracle:Creatures played by your opponents enter tapped.

View File

@@ -486,13 +486,13 @@ public final class CardScriptParser {
"blockedBySourceThisTurn", "isBlockedByRemembered", "blockedRemembered",
"blockedByRemembered", "unblocked", "attackersBandedWith",
"kicked", "kicked1", "kicked2", "evoked",
"HasDevoured", "HasNotDevoured", "IsMonstrous", "IsNotMonstrous",
"HasDevoured", "IsMonstrous",
"CostsPhyrexianMana", "IsRemembered", "IsNotRemembered",
"IsImprinted", "IsNotImprinted", "hasActivatedAbilityWithTapCost",
"hasActivatedAbility", "hasManaAbility",
"hasNonManaActivatedAbility", "NoAbilities", "HasCounters",
"wasNotCast", "ChosenType", "IsNotChosenType", "IsCommander",
"IsNotCommander","IsRenowned", "IsNotRenowned");
"IsNotCommander", "IsRenowned");
private static final Set<String> VALID_EXCLUSIVE_STARTSWITH = ImmutableSortedSet
.of("named", "notnamed", "OwnedBy", "ControlledBy",
"ControllerControls", "AttachedTo", "EnchantedBy",
@@ -504,7 +504,7 @@ public final class CardScriptParser {
"ThisTurnEntered", "sharesTypeWith", "hasKeyword", "with",
"greatestPowerControlledBy", "greatestCMCControlledBy",
"power", "toughness", "cmc", "totalPT", "counters", "non",
"RememberMap", "wasCastFrom", "wasNotCastFrom", "set",
"RememberMap", "wasCastFrom", "set",
"inZone", "HasSVar");
private static boolean isValidExclusive(String valid) {