...
 
Commits (32)
......@@ -460,6 +460,10 @@ public class GameAction {
unattachCardLeavingBattlefield(copied);
// Remove all changed keywords
copied.removeAllChangedText(game.getNextTimestamp());
// reset activations
for (SpellAbility ab : copied.getSpellAbilities()) {
ab.getRestrictions().resetTurnActivations();
}
} else if (toBattlefield) {
// reset timestamp in changezone effects so they have same timestamp if ETB simutaneously
copied.setTimestamp(game.getNextTimestamp());
......
......@@ -168,7 +168,7 @@ public enum ApiType {
static {
for(ApiType t : ApiType.values()) {
allValues.put(t.name(), t);
allValues.put(t.name().toLowerCase(), t);
}
}
......@@ -179,7 +179,7 @@ public enum ApiType {
}
public static ApiType smartValueOf(String value) {
ApiType v = allValues.get(value);
ApiType v = allValues.get(value.toLowerCase());
if ( v == null )
throw new RuntimeException("Element " + value + " not found in ApiType enum");
return v;
......
......@@ -43,10 +43,10 @@ public class CountersMultiplyEffect extends SpellAbilityEffect {
for (final Card tgtCard : getTargetCards(sa)) {
if (counterType != null) {
tgtCard.addCounter(counterType, tgtCard.getCounters(counterType) * n, host, false);
tgtCard.addCounter(counterType, tgtCard.getCounters(counterType) * n, host, true);
} else {
for (Map.Entry<CounterType, Integer> e : tgtCard.getCounters().entrySet()) {
tgtCard.addCounter(e.getKey(), e.getValue() * n, host, false);
tgtCard.addCounter(e.getKey(), e.getValue() * n, host, true);
}
}
game.updateLastStateForCard(tgtCard);
......
......@@ -348,12 +348,7 @@ public class TriggerHandler {
// Static triggers
for (final Trigger t : Lists.newArrayList(activeTriggers)) {
if (t.isStatic() && canRunTrigger(t, mode, runParams)) {
int x = 1;
int p = t.getHostCard().getController().getAmountOfKeyword("Panharmonicon");
if (p > 0 && handlePanharmonicon(t, runParams)) {
x += p;
}
int x = 1 + handlePanharmonicon(t, runParams);
for (int i = 0; i < x; ++i) {
runSingleTrigger(t, runParams);
......@@ -425,12 +420,7 @@ public class TriggerHandler {
}
}
int x = 1;
int p = t.getHostCard().getController().getAmountOfKeyword("Panharmonicon");
if (p > 0 && handlePanharmonicon(t, runParams)) {
x += p;
}
int x = 1 + handlePanharmonicon(t, runParams);;
for (int i = 0; i < x; ++i) {
runSingleTrigger(t, runParams);
......@@ -674,28 +664,36 @@ public class TriggerHandler {
}
}
private boolean handlePanharmonicon(final Trigger t, final Map<String, Object> runParams) {
private int handlePanharmonicon(final Trigger t, final Map<String, Object> runParams) {
final Card host = t.getHostCard();
final Player p = host.getController();
// not a changesZone trigger
if (t.getMode() != TriggerType.ChangesZone) {
return false;
return 0;
}
// not a Permanent you control
if (!t.getHostCard().isPermanent() || !t.getHostCard().isInZone(ZoneType.Battlefield)) {
return false;
}
// its not an ETB trigger or the card is not a Artifact or Creature
if (runParams.get("Destination") instanceof String) {
final String dest = (String) runParams.get("Destination");
if (dest.equals("Battlefield") && runParams.get("Card") instanceof Card) {
final Card card = (Card) runParams.get("Card");
if (card.isCreature() || card.isArtifact()) {
return true;
if (!host.isPermanent() || !host.isInZone(ZoneType.Battlefield)) {
return 0;
}
int n = 0;
for (final String kw : p.getKeywords()) {
if (kw.startsWith("Panharmonicon")) {
if (runParams.get("Destination") instanceof String) {
final String dest = (String) runParams.get("Destination");
if (dest.equals("Battlefield") && runParams.get("Card") instanceof Card) {
final Card card = (Card) runParams.get("Card");
final String valid = kw.split(":")[1];
if (card.isValid(valid.split(","), p, host, null)) {
n++;
}
}
}
}
}
return false;
return n;
}
}
......@@ -990,7 +990,7 @@ public class FSkin {
//format mana symbols to display as icons
pattern = "\\{([A-Z0-9]+)\\}|\\{([A-Z0-9]+)/([A-Z0-9]+)\\}"; //fancy pattern needed so "/" can be omitted from replacement
try {
replacement = "<img src='" + new File(ForgeConstants.CACHE_SYMBOLS_DIR + "/$1$2$3.png").toURI().toURL().toString() + "'>";
replacement = "<img src=\"" + new File(ForgeConstants.CACHE_SYMBOLS_DIR + "/$1$2$3.png").toURI().toURL().toString() + "\">";
str = str.replaceAll(pattern, replacement);
} catch (final MalformedURLException e) {
e.printStackTrace();
......
......@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:ETBReplacement:Other:LandTapped
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Mountain.YouCtrl,Plains.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Mountain or a Plains.
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}.
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/clifftop_retreat.jpg
Oracle:Clifftop Retreat enters the battlefield tapped unless you control a Mountain or a Plains.\n{T}: Add {R} or {W} to your mana pool.
Oracle:Clifftop Retreat enters the battlefield tapped unless you control a Mountain or a Plains.\n{T}: Add {R} or {W}.
......@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:ETBReplacement:Other:LandTapped
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Forest.YouCtrl,Island.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Forest or an Island.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}.
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/hinterland_harbor.jpg
Oracle:Hinterland Harbor enters the battlefield tapped unless you control a Forest or an Island.\n{T}: Add {G} or {U} to your mana pool.
Oracle:Hinterland Harbor enters the battlefield tapped unless you control a Forest or an Island.\n{T}: Add {G} or {U}.
......@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:ETBReplacement:Other:LandTapped
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Plains.YouCtrl,Swamp.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Plains or a Swamp.
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W}.
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/isolated_chapel.jpg
Oracle:Isolated Chapel enters the battlefield tapped unless you control a Plains or a Swamp.\n{T}: Add {W} or {B} to your mana pool.
Oracle:Isolated Chapel enters the battlefield tapped unless you control a Plains or a Swamp.\n{T}: Add {W} or {B}.
......@@ -2,7 +2,7 @@ Name:Meandering River
ManaCost:no cost
Types:Land
K:CARDNAME enters the battlefield tapped.
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W}.
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/meandering_river.jpg
Oracle:Meandering River enters the battlefield tapped.\n{T}: Add {W} or {U} to your mana pool.
Oracle:Meandering River enters the battlefield tapped.\n{T}: Add {W} or {U}.
Name:Naban, Dean of Iteration
ManaCost:1 U
Types:Legendary Creature Human Wizard
PT:2/1
S:Mode$ Continuous | Affected$ You | AddKeyword$ Panharmonicon:Wizard.YouCtrl | Description$ If a Wizard entering the battlefield under your control causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
SVar:Picture:http://www.wizards.com/global/images/magic/general/naban_dean_of_iteration.jpg
Oracle:If a Wizard entering the battlefield under your control causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
Name:Panharmonicon
ManaCost:4
Types:Artifact
S:Mode$ Continuous | Affected$ You | AddKeyword$ Panharmonicon | Description$ If an artifact or creature entering the battlefield causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
S:Mode$ Continuous | Affected$ You | AddKeyword$ Panharmonicon:Creature,Artifact | Description$ If an artifact or creature entering the battlefield causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
SVar:Picture:http://www.wizards.com/global/images/magic/general/panharmonicon.jpg
Oracle:If an artifact or creature entering the battlefield causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
......@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:ETBReplacement:Other:LandTapped
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Island.YouCtrl,Mountain.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control an Island or a Mountain.
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}.
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/sulfur_falls.jpg
Oracle:Sulfur Falls enters the battlefield tapped unless you control an Island or a Mountain.\n{T}: Add {U} or {R} to your mana pool.
Oracle:Sulfur Falls enters the battlefield tapped unless you control an Island or a Mountain.\n{T}: Add {U} or {R}.
\ No newline at end of file
......@@ -2,7 +2,7 @@ Name:Timber Gorge
ManaCost:no cost
Types:Land
K:CARDNAME enters the battlefield tapped.
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/timber_gorge.jpg
Oracle:Timber Gorge enters the battlefield tapped.\n{T}: Add {R} or {G} to your mana pool.
Oracle:Timber Gorge enters the battlefield tapped.\n{T}: Add {R} or {G}.
Name:Bloodstone Goblin
ManaCost:1 R
Types:Creature Goblin Warrior
PT:2/2
T:Mode$ SpellCast | ValidCard$ Card.kicked | ValidActivatingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, if that spell was kicked, CARDNAME gets +1/+1 and gains menace until end of turn. (It can't be blocked except by two or more creatures.)
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 1 | NumDef$ 1 | KW$ Menace
SVar:Picture:http://www.wizards.com/global/images/magic/general/bloodstone_goblin.jpg
Oracle:Whenever you cast a spell, if that spell was kicked, Bloodstone Goblin gets +1/+1 and gains menace until end of turn. (It can't be blocked except by two or more creatures.)
Name:Chandra's Outburst
ManaCost:3 R R
Types:Sorcery
A:SP$ DealDamage | Cost$ 3 R R | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 4 | SubAbility$ DBSearch | SpellDescription$ CARDNAME deals 4 damage to target player or planeswalker.
SVar:DBSearch:DB$ ChangeZone | Origin$ Library,Graveyard | Destination$ Hand | ChangeType$ Card.namedChandra; Bold Pyromancer | ChangeNum$ 1
DeckNeeds:Name$Chandra, Bold Pyromancer
Oracle:Chandra's Outburst deals 4 damage to target player or planeswalker.\nSearch your library and/or graveyard for a card named Chandra, Bold Pyromancer, reveal it, and put it into your hand. If you search your library this way, shuffle it.
Name:Danitha Capashen, Paragon
ManaCost:2 W
Types:Legendary Creature Human Knight
PT:2/2
K:First Strike
K:Vigilance
K:Lifelink
S:Mode$ ReduceCost | ValidCard$ Aura,Equipment | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Aura and Equipment spells you cast cost {1} less to cast.
Oracle:First strike, vigilance, lifelink\nAura and Equipment spells you cast cost {1} less to cast.
Name:Karplusan Hound
ManaCost:3 R
Types:Creature Hound
PT:3/3
T:Mode$ Attacks | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ GE1 | Execute$ DBDealDamage | TriggerDescription$ Whenever CARDNAME attacks, if you control a Chandra planeswalker, this creature deals 2 damage to any target.
SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | NumDmg$ 2 | TgtPrompt$ Select target player or planeswalker
SVar:X:Count$Valid Planeswalker.Chandra+YouCtrl
SVar:BuffedBy:Chandra
Oracle:Whenever Karplusan Hound attacks, if you control a Chandra planeswalker, this creature deals 2 damage to any target.
Name:Niambi, Faithful Healer
ManaCost:1 W U
Types:Legendary Creature Human Cleric
PT:2/2
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSearch | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library and/or graveyard for a card named Teferi, Timebender, reveal it, then put it into your hand. If you searched your library this way, shuffle it.
SVar:TrigSearch:DB$ ChangeZone | Origin$ Library,Graveyard | Destination$ Hand | ChangeType$ Card.namedTeferi; Timebender | ChangeNum$ 1 | Optional$ True
DeckHints:Name$Teferi, Timebender
Oracle:When Niambi, Faithful Healer enters the battlefield, you may search your library and/or graveyard for a card named Teferi, Timebender, reveal it, then put it into your hand. If you searched your library this way, shuffle it.
Name:Pyromantic Pilgrim
ManaCost:2 R
Types:Creature Human Wizard
PT:3/1
K:Haste
Oracle:Haste
Name:Teferi, Timebender
ManaCost:4 W U
Types:Legendary Planeswalker Teferi
Loyalty:5
A:AB$ Untap | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Artifact,Creature | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose target artifact or creature | SpellDescription$ Untap up to one target artifact or creature.
A:AB$ GainLife | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | Defined$ You | LifeAmount$ 2 | SubAbility$ DBDraw | SpellDescription$ You gain 2 life and draw two cards.
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 2
A:AB$ AddTurn | Cost$ SubCounter<9/LOYALTY> | Planeswalker$ True | Ultimate$ True | NumTurns$ 1 | SpellDescription$ Take an extra turn after this one.
Oracle:[+2]: Untap up to one target artifact or creature.\n[−3]: You gain 2 life and draw two cards.\n[−9]: Take an extra turn after this one.
\ No newline at end of file
Name:Teferi’s Sentinel
ManaCost:5
Types:Artifact Creature Golem
PT:2/6
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 4 | IsPresent$ Planeswalker.Teferi+YouCtrl | Description$ As long as you control a Teferi planeswalker, CARDNAME gets +4/+0.
SVar:BuffedBy:Teferi
Oracle:As long as you control a Teferi planeswalker, Teferi’s Sentinel gets +4/+0.
......@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:ETBReplacement:Other:LandTapped
SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionPresent$ Swamp.YouCtrl,Forest.YouCtrl | ConditionCompare$ EQ0 | SpellDescription$ CARDNAME enters the battlefield tapped unless you control a Swamp or a Forest.
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G} to your mana pool.
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}.
SVar:Picture:http://www.wizards.com/global/images/magic/general/woodland_cemetery.jpg
Oracle:Woodland Cemetery enters the battlefield tapped unless you control a Swamp or a Forest.\n{T}: Add {B} or {G} to your mana pool.
Oracle:Woodland Cemetery enters the battlefield tapped unless you control a Swamp or a Forest.\n{T}: Add {B} or {G}.