Support duplicate objects per effect (#4518)

* Fix Serrated Biskelion

* Fix Angel of Destiny

* Fix Diviner Spirit
This commit is contained in:
tool4ever
2024-01-17 11:02:04 +01:00
committed by GitHub
parent 1d92e7f915
commit 96b3d07051
26 changed files with 134 additions and 69 deletions

View File

@@ -738,12 +738,11 @@ public class SpecialCardAi {
// Grothama, All-Devouring
public static class GrothamaAllDevouring {
public static boolean consider(final Player ai, final SpellAbility sa) {
final Card source = sa.getHostCard();
final Card devourer = AbilityUtils.getDefinedCards(source, sa.getParam("ExtraDefined"), sa).getFirst(); // maybe just getOriginalHost()?
final Card fighter = sa.getHostCard();
final Card devourer = sa.getOriginalHost();
if (ai.getTeamMates(true).contains(devourer.getController())) {
return false; // TODO: Currently, the AI doesn't ever fight its own (or allied) Grothama for card draw. This can be improved.
}
final Card fighter = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa).getFirst();
boolean goodTradeOrNoTrade = devourer.canBeDestroyed() && (devourer.getNetPower() < fighter.getNetToughness() || !fighter.canBeDestroyed()
|| ComputerUtilCard.evaluateCreature(devourer) > ComputerUtilCard.evaluateCreature(fighter));
return goodTradeOrNoTrade && fighter.getNetPower() >= devourer.getNetToughness();

View File

@@ -825,8 +825,8 @@ public class AbilityUtils {
return objects;
}
public static FCollection<GameEntity> getDefinedEntities(final Card card, final String[] def, final CardTraitBase sa) {
final FCollection<GameEntity> objects = new FCollection<>();
public static List<GameEntity> getDefinedEntities(final Card card, final String[] def, final CardTraitBase sa) {
final List<GameEntity> objects = new ArrayList<>();
for (String d : def) {
objects.addAll(AbilityUtils.getDefinedEntities(card, d, sa));
}

View File

@@ -206,16 +206,44 @@ public abstract class SpellAbilityEffect {
protected final static CardCollection getDefinedCardsOrTargeted(final SpellAbility sa) { return getCards(true, "Defined", sa); }
protected final static CardCollection getDefinedCardsOrTargeted(final SpellAbility sa, final String definedParam) { return getCards(true, definedParam, sa); }
protected static List<Card> getTargetCardsWithDuplicates(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
List<Card> result = Lists.newArrayList();
getCards(definedFirst, definedParam, sa, result);
return result;
}
// overloaded variant that returns the unique objects instead of filling a result list
private static CardCollection getCards(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
return getCards(definedFirst, definedParam, sa, null);
}
private static CardCollection getCards(final boolean definedFirst, final String definedParam, final SpellAbility sa, List<Card> resultDuplicate) {
if (sa.hasParam("ThisDefinedAndTgts")) {
CardCollection cards =
AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("ThisDefinedAndTgts"), sa);
CardCollection cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("ThisDefinedAndTgts"), sa);
cards.addAll(sa.getTargets().getTargetCards());
return cards;
}
CardCollection resultUnique = null;
final boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam));
return useTargets ? new CardCollection(sa.getTargets().getTargetCards())
: AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam(definedParam), sa);
if (useTargets) {
if (resultDuplicate == null) {
resultUnique = new CardCollection();
resultDuplicate = resultUnique;
}
Iterables.addAll(resultDuplicate, sa.getTargets().getTargetCards());
} else {
String[] def = sa.getParamOrDefault(definedParam, "Self").split(" & ");
for (String d : def) {
CardCollection defResult = AbilityUtils.getDefinedCards(sa.getHostCard(), d, sa);
if (resultDuplicate == null) {
resultUnique = defResult;
resultDuplicate = resultUnique;
} else {
resultDuplicate.addAll(defResult);
}
}
}
return resultUnique;
}
// Players
@@ -224,16 +252,44 @@ public abstract class SpellAbilityEffect {
protected final static PlayerCollection getDefinedPlayersOrTargeted(final SpellAbility sa) { return getPlayers(true, "Defined", sa); }
protected final static PlayerCollection getDefinedPlayersOrTargeted(final SpellAbility sa, final String definedParam) { return getPlayers(true, definedParam, sa); }
protected static List<Player> getTargetPlayersWithDuplicates(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
List<Player> result = Lists.newArrayList();
getPlayers(definedFirst, definedParam, sa, result);
return result;
}
// overloaded variant that returns the unique objects instead of filling a result list
private static PlayerCollection getPlayers(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
return getPlayers(definedFirst, definedParam, sa, null);
}
private static PlayerCollection getPlayers(final boolean definedFirst, final String definedParam, final SpellAbility sa, List<Player> resultDuplicate) {
PlayerCollection resultUnique = null;
final boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam));
PlayerCollection players = useTargets ? new PlayerCollection(sa.getTargets().getTargetPlayers())
: AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam(definedParam), sa);
// try sort in APNAP order
int indexAP = players.indexOf(sa.getHostCard().getGame().getPhaseHandler().getPlayerTurn());
if (indexAP != -1) {
Collections.rotate(players, - indexAP);
if (useTargets) {
if (resultDuplicate == null) {
resultUnique = new PlayerCollection();
resultDuplicate = resultUnique;
}
Iterables.addAll(resultDuplicate, sa.getTargets().getTargetPlayers());
} else {
String[] def = sa.getParamOrDefault(definedParam, "You").split(" & ");
for (String d : def) {
PlayerCollection defResult = AbilityUtils.getDefinedPlayers(sa.getHostCard(), d, sa);
if (resultDuplicate == null) {
resultUnique = defResult;
resultDuplicate = resultUnique;
} else {
resultDuplicate.addAll(defResult);
}
}
}
return players;
// try sort in APNAP order
int indexAP = resultDuplicate.indexOf(sa.getHostCard().getGame().getPhaseHandler().getPlayerTurn());
if (indexAP != -1) {
Collections.rotate(resultDuplicate, - indexAP);
}
return resultUnique;
}
// Spells
@@ -624,21 +680,19 @@ public abstract class SpellAbilityEffect {
String attacking = sa.getParam(attackingParam);
GameEntity defender = null;
FCollection<GameEntity> defs = null;
FCollection<GameEntity> defs = new FCollection<>();
// important to update defenders here, maybe some PW got removed
combat.initConstraints();
if ("True".equalsIgnoreCase(attacking)) {
defs = (FCollection<GameEntity>) combat.getDefenders();
defs.addAll(combat.getDefenders());
} else {
defs = AbilityUtils.getDefinedEntities(sa.hasParam("ForEach") ? c : host, attacking.split(","), sa);
defs.addAll(AbilityUtils.getDefinedEntities(sa.hasParam("ForEach") ? c : host, attacking.split("&"), sa));
}
if (defs != null) {
Map<String, Object> params = Maps.newHashMap();
params.put("Attacker", c);
defender = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(defs, sa,
Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false, params);
}
Map<String, Object> params = Maps.newHashMap();
params.put("Attacker", c);
defender = sa.getActivatingPlayer().getController().chooseSingleEntityForEffect(defs, sa,
Localizer.getInstance().getMessage("lblChooseDefenderToAttackWithCard", CardTranslation.getTranslatedName(c.getName())), false, params);
final GameEntity originalDefender = combat.getDefenderByAttacker(c);
if (defender != null &&

View File

@@ -1,8 +1,11 @@
package forge.game.ability.effects;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Sets;
import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
@@ -53,7 +56,6 @@ public class DrawEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
final Card source = sa.getHostCard();
final int numCards = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumCards"), sa) : 1;
final boolean upto = sa.hasParam("Upto");
final boolean optional = sa.hasParam("OptionalDecider") || upto;
@@ -61,11 +63,16 @@ public class DrawEffect extends SpellAbilityEffect {
moveParams.put(AbilityKey.LastStateBattlefield, sa.getLastStateBattlefield());
moveParams.put(AbilityKey.LastStateGraveyard, sa.getLastStateGraveyard());
for (final Player p : getDefinedPlayersOrTargeted(sa)) {
final List<Player> tgts = getTargetPlayersWithDuplicates(true, "Defined", sa);
for (final Player p : Sets.newHashSet(tgts)) {
if (!p.isInGame()) {
continue;
}
int numCards = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumCards"), sa) : 1;
numCards *= Collections.frequency(tgts, p);
// it is optional, not upto and player can't choose to draw that many cards
if (optional && !upto && !p.canDrawAmount(numCards)) {
continue;

View File

@@ -98,11 +98,8 @@ public class FightEffect extends DamageBaseEffect {
}
}
if (sa.hasParam("Defined")) {
List<Card> defined = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa);
List<Card> defined = getTargetCardsWithDuplicates(true, "Defined", sa);
// Allow both fighters to come from defined list if first fighter not already found
if (sa.hasParam("ExtraDefined")) {
defined.addAll(AbilityUtils.getDefinedCards(host, sa.getParam("ExtraDefined"), sa));
}
List<Card> newDefined = Lists.newArrayList();
for (final Card d : defined) {

View File

@@ -5,8 +5,14 @@ import forge.game.ability.SpellAbilityEffect;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.util.Lang;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Sets;
public class LifeGainEffect extends SpellAbilityEffect {
/* (non-Javadoc)
@@ -44,21 +50,20 @@ public class LifeGainEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) {
String amount = sa.getParam("LifeAmount");
boolean variableAmount = amount.equals("AFNotDrawnNum");
int lifeAmount = 0;
if (variableAmount) {
amount = "X";
} else {
lifeAmount = AbilityUtils.calculateAmount(sa.getHostCard(), amount, sa);
}
final List<Player> tgts = getTargetPlayersWithDuplicates(false, "Defined", sa);
for (final Player p : getDefinedPlayersOrTargeted(sa)) {
for (final Player p : Sets.newHashSet(tgts)) {
if (!p.isInGame()) {
continue;
}
if (variableAmount) {
sa.setSVar("AFNotDrawnNum", sa.getSVar("AFNotDrawnNum_" + p.getId()));
lifeAmount = AbilityUtils.calculateAmount(sa.getHostCard(), amount, sa);
}
int lifeAmount = AbilityUtils.calculateAmount(sa.getHostCard(), amount, sa);
lifeAmount *= Collections.frequency(tgts, p);
p.gainLife(lifeAmount, sa.getHostCard(), sa);
}
}

View File

@@ -7,6 +7,6 @@ S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$
SVar:X:Count$Valid Creature.YouCtrl
T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ DBRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control.
SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ Opponent | ChangeZoneTable$ True | RepeatSubAbility$ DBToken
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenTapped$ True | TokenAttacking$ Player.IsRemembered,Valid Planeswalker.ControlledBy Remembered | TokenOwner$ You
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenTapped$ True | TokenAttacking$ Player.IsRemembered & Valid Planeswalker.ControlledBy Remembered | TokenOwner$ You
DeckHas:Ability$Token
Oracle:Vigilance\nAdeline, Resplendent Cathar's power is equal to the number of creatures you control.\nWhenever you attack, for each opponent, create a 1/1 white Human creature token that's tapped and attacking that player or a planeswalker they control.

View File

@@ -5,8 +5,7 @@ PT:2/6
K:Flying
K:Double Strike
T:Mode$ DamageDone | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigGain | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature you control deals combat damage to a player, you and that player each gain that much life.
SVar:TrigGain:DB$ GainLife | Defined$ You | LifeAmount$ X | SubAbility$ DBGain
SVar:DBGain:DB$ GainLife | Defined$ TriggeredTarget | LifeAmount$ X
SVar:TrigGain:DB$ GainLife | Defined$ You & TriggeredTarget | LifeAmount$ X
SVar:X:TriggerCount$DamageAmount
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ Z | SVarCompare$ GEY | Execute$ TrigLose | TriggerDescription$ At the beginning of your end step, if you have at least 15 life more than your starting life total, each player CARDNAME attacked this turn loses the game.
SVar:TrigLose:DB$ LosesGame | Defined$ Player.attackedBySourceThisTurn

View File

@@ -2,6 +2,6 @@ Name:Conjured Currency
ManaCost:5 U
Types:Enchantment
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ ExchangeCards | OptionalDecider$ You | TriggerDescription$ At the beginning of your upkeep, you may exchange control of CARDNAME and target permanent you neither own nor control.
SVar:ExchangeCards:DB$ ExchangeControl | Defined$ Self | ValidTgts$ Permanent.YouDontCtrl+YouDontOwn | TgtPrompt$ Select target permanent you neither own nor control | SpellDescription$ Exchange control of CARDNAME and target permanent you neither own nor control.
SVar:ExchangeCards:DB$ ExchangeControl | Defined$ Self | ValidTgts$ Permanent.YouDontCtrl+YouDontOwn | TgtPrompt$ Select target permanent you neither own nor control
AI:RemoveDeck:All
Oracle:At the beginning of your upkeep, you may exchange control of Conjured Currency and target permanent you neither own nor control.

View File

@@ -1,7 +1,8 @@
Name:Cunning Strike
ManaCost:3 U R
Types:Instant
A:SP$ DealDamage | Cost$ 3 U R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 2 | SubAbility$ DB1 | SpellDescription$ CARDNAME deals 2 damage to target creature and 2 damage to target player or planeswalker. Draw a card.
SVar:DB1:DB$ DealDamage | NumDmg$ 2 | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | SubAbility$ DBDraw
A:SP$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 2 | DamageMap$ True | SubAbility$ DB1 | SpellDescription$ CARDNAME deals 2 damage to target creature and 2 damage to target player or planeswalker. Draw a card.
SVar:DB1:DB$ DealDamage | NumDmg$ 2 | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | SubAbility$ DBDamageResolve
SVar:DBDamageResolve:DB$ DamageResolve | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | NumCards$ 1
Oracle:Cunning Strike deals 2 damage to target creature and 2 damage to target player or planeswalker.\nDraw a card.

View File

@@ -3,7 +3,6 @@ ManaCost:4 U
Types:Creature Spirit
PT:2/4
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you and that player each draw that many cards.
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | Defined$ TriggeredTarget | NumCards$ X
SVar:TrigDraw:DB$ Draw | Defined$ You & TriggeredTarget | NumCards$ X
SVar:X:TriggerCount$DamageAmount
Oracle:Whenever Diviner Spirit deals combat damage to a player, you and that player each draw that many cards.

View File

@@ -1,9 +1,9 @@
Name:Ezuri's Predation
ManaCost:5 G G G
Types:Sorcery
A:SP$ RepeatEach | Cost$ 5 G G G | RepeatCards$ Creature.OppCtrl | ChooseOrder$ True | UseImprinted$ True | RepeatSubAbility$ DBToken | ChangeZoneTable$ True | SpellDescription$ For each creature your opponents control, create a 4/4 green Phyrexian Beast creature token. Each of those Beasts fights a different one of those creatures.
A:SP$ RepeatEach | RepeatCards$ Creature.OppCtrl | ChooseOrder$ True | UseImprinted$ True | RepeatSubAbility$ DBToken | ChangeZoneTable$ True | SpellDescription$ For each creature your opponents control, create a 4/4 green Phyrexian Beast creature token. Each of those Beasts fights a different one of those creatures.
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_4_4_phyrexian_beast | TokenOwner$ You | RememberTokens$ True | SubAbility$ DBFight
SVar:DBFight:DB$ Fight | Defined$ Imprinted | ExtraDefined$ Remembered | SubAbility$ DBCleanup
SVar:DBFight:DB$ Fight | Defined$ Imprinted & Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:NeedsToPlay:Creature.OppCtrl+powerLE3
Oracle:For each creature your opponents control, create a 4/4 green Phyrexian Beast creature token. Each of those Beasts fights a different one of those creatures.

View File

@@ -1,6 +1,7 @@
Name:First Volley
ManaCost:1 R
Types:Instant Arcane
A:SP$ DealDamage | Cost$ 1 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 1 damage to target creature and 1 damage to that creature's controller.
SVar:DBDealDamage:DB$ DealDamage | NumDmg$ 1 | Defined$ TargetedController
A:SP$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | DamageMap$ True | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 1 damage to target creature and 1 damage to that creature's controller.
SVar:DBDealDamage:DB$ DealDamage | NumDmg$ 1 | Defined$ TargetedController | SubAbility$ DBDamageResolve
SVar:DBDamageResolve:DB$ DamageResolve
Oracle:First Volley deals 1 damage to target creature and 1 damage to that creature's controller.

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Wurm
PT:10/8
S:Mode$ Continuous | Affected$ Creature.Other | AddTrigger$ GrothamaAttack | AddSVar$ HasAttackEffect | Description$ Other creatures have "Whenever this creature attacks, you may have it fight CARDNAME."
SVar:GrothamaAttack:Mode$ Attacks | ValidCard$ Card.Self | Execute$ GrothamaFight | OptionalDecider$ You | TriggerDescription$ Whenever this creature attacks, ABILITY.
SVar:GrothamaFight:DB$ Fight | Defined$ TriggeredAttackerLKICopy | ExtraDefined$ OriginalHost | AILogic$ Grothama | SpellDescription$ You may have it fight ORIGINALHOST
SVar:GrothamaFight:DB$ Fight | Defined$ TriggeredAttackerLKICopy & OriginalHost | AILogic$ Grothama | SpellDescription$ You may have it fight ORIGINALHOST
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigRepeat | TriggerDescription$ When NICKNAME leaves the battlefield, each player draws cards equal to the amount of damage dealt to NICKNAME this turn by sources they controlled.
SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ TrigDraw
SVar:TrigDraw:DB$ Draw | Defined$ Remembered | NumCards$ X

View File

@@ -3,9 +3,9 @@ ManaCost:2 R G
Types:Legendary Creature Human Scout
PT:1/4
T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME attacks, reveal the top card of your library. If it's a creature card, put it onto the battlefield tapped and attacking defending player or a planeswalker they control. Otherwise, put that card into your hand. When you put a creature card onto the battlefield this way, it fights CARDNAME.
SVar:TrigDig:DB$ Dig | DigNum$ 1 | ChangeNum$ All | Optional$ True | Reveal$ True | ChangeValid$ Creature | DestinationZone$ Battlefield | DestinationZone2$ Hand | Tapped$ True | Attacking$ DefendingPlayer,Valid Planeswalker.ControlledBy DefendingPlayer | RememberChanged$ True | SubAbility$ DBImmediateTriggerCheck
SVar:TrigDig:DB$ Dig | DigNum$ 1 | ChangeNum$ All | Optional$ True | Reveal$ True | ChangeValid$ Creature | DestinationZone$ Battlefield | DestinationZone2$ Hand | Tapped$ True | Attacking$ DefendingPlayer & Valid Planeswalker.ControlledBy DefendingPlayer | RememberChanged$ True | SubAbility$ DBImmediateTriggerCheck
SVar:DBImmediateTriggerCheck:DB$ ImmediateTrigger | Execute$ DBFight | ConditionDefined$ Remembered | ConditionPresent$ Creature | ConditionCompare$ GE1 | TriggerDescription$ When you put a creature card onto the battlefield this way, it fights Hans Eriksson.
SVar:DBFight:DB$ Fight | Defined$ Remembered | ExtraDefined$ Self | SubAbility$ DBCleanup
SVar:DBFight:DB$ Fight | Defined$ Remembered & Self | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:HasAttackEffect:TRUE
Oracle:Whenever Hans Eriksson attacks, reveal the top card of your library. If it's a creature card, put it onto the battlefield tapped and attacking defending player or a planeswalker they control. Otherwise, put that card into your hand. When you put a creature card onto the battlefield this way, it fights Hans Eriksson.

View File

@@ -1,6 +1,7 @@
Name:Hungry Flames
ManaCost:2 R
Types:Instant
A:SP$ DealDamage | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 3 | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 3 damage to target creature and 2 damage to target player or planeswalker.
SVar:DBDealDamage:DB$ DealDamage | NumDmg$ 2 | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker
A:SP$ DealDamage | ValidTgts$ Creature | NumDmg$ 3 | DamageMap$ True | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 3 damage to target creature and 2 damage to target player or planeswalker.
SVar:DBDealDamage:DB$ DealDamage | NumDmg$ 2 | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | SubAbility$ DBDamageResolve
SVar:DBDamageResolve:DB$ DamageResolve
Oracle:Hungry Flames deals 3 damage to target creature and 2 damage to target player or planeswalker.

View File

@@ -1,6 +1,7 @@
Name:Lunge
ManaCost:2 R
Types:Instant
A:SP$ DealDamage | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 2 | SubAbility$ DB1 | SpellDescription$ CARDNAME deals 2 damage to target creature and 2 damage to target player or planeswalker.
SVar:DB1:DB$ DealDamage | NumDmg$ 2 | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker
A:SP$ DealDamage | ValidTgts$ Creature | NumDmg$ 2 | DamageMap$ True | SubAbility$ DB1 | SpellDescription$ CARDNAME deals 2 damage to target creature and 2 damage to target player or planeswalker.
SVar:DB1:DB$ DealDamage | NumDmg$ 2 | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | SubAbility$ DBDamageResolve
SVar:DBDamageResolve:DB$ DamageResolve
Oracle:Lunge deals 2 damage to target creature and 2 damage to target player or planeswalker.

View File

@@ -2,8 +2,9 @@ Name:Neonate's Rush
ManaCost:2 R
Types:Instant
S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | IsPresent$ Vampire.YouCtrl | Description$ This spell costs {1} less to cast if you control a Vampire.
A:SP$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 1 damage to target creature and 1 damage to its controller. Draw a card.
SVar:DBDealDamage:DB$ DealDamage | Defined$ TargetedController | NumDmg$ 1 | SubAbility$ DBDraw
A:SP$ DealDamage | ValidTgts$ Creature | NumDmg$ 1 | DamageMap$ True | SubAbility$ DBDealDamage | SpellDescription$ CARDNAME deals 1 damage to target creature and 1 damage to its controller. Draw a card.
SVar:DBDealDamage:DB$ DealDamage | Defined$ TargetedController | NumDmg$ 1 | SubAbility$ DBDamageResolve
SVar:DBDamageResolve:DB$ DamageResolve | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | NumCards$ 1
SVar:BuffedBy:Vampire
DeckHints:Type$Vampire

View File

@@ -2,7 +2,8 @@ Name:Psionic Entity
ManaCost:4 U
Types:Creature Illusion
PT:2/2
A:AB$ DealDamage | Cost$ T | ValidTgts$ Any | NumDmg$ 2 | SubAbility$ DB1 | SpellDescription$ CARDNAME deals 2 damage to any target and 3 damage to itself.
SVar:DB1:DB$ DealDamage | NumDmg$ 3 | Defined$ Self
A:AB$ DealDamage | Cost$ T | ValidTgts$ Any | NumDmg$ 2 | DamageMap$ True | SubAbility$ DB1 | SpellDescription$ CARDNAME deals 2 damage to any target and 3 damage to itself.
SVar:DB1:DB$ DealDamage | NumDmg$ 3 | Defined$ Self | SubAbility$ DBDamageResolve
SVar:DBDamageResolve:DB$ DamageResolve
AI:RemoveDeck:All
Oracle:{T}: Psionic Entity deals 2 damage to any target and 3 damage to itself.

View File

@@ -5,7 +5,6 @@ PT:2/4
K:Trample
K:Haste
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDraw | CombatDamage$ True | TriggerDescription$ Share Intelligence — Whenever CARDNAME deals combat damage to a player, you and that player each draw that many cards.
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | Defined$ TriggeredTarget | NumCards$ X
SVar:TrigDraw:DB$ Draw | Defined$ You & TriggeredTarget | NumCards$ X
SVar:X:TriggerCount$DamageAmount
Oracle:Trample, haste\nShare Intelligence — Whenever Sergeant John Benton deals combat damage to a player, you and that player each draw that many cards.

View File

@@ -5,7 +5,7 @@ PT:5/5
K:Flying
S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME can't attack. | IsPresent$ Creature | PresentCompare$ GT1 | Description$ CARDNAME can't attack if another creature is on the battlefield.
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ At the beginning of your upkeep, you lose 3 life.
A:AB$ ChangeZone | Cost$ T | ValidTgts$ Creature | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select target creature | SubAbility$ DBCounter | SpellDescription$ Exile target creature and put a +1/+1 counter on CARDNAME.
A:AB$ ChangeZone | Cost$ T | ValidTgts$ Creature | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select target creature | SubAbility$ DBCounter | SpellDescription$ Exile target creature and put a +1/+1 counter on NICKNAME.
SVar:TrigLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 3
SVar:DBCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 | Defined$ Self
#TODO: This creature seems almost AI playable, except the AI won't play around it and will cast other creatures, which may not even be a necessarily bad thing. Maybe RemRandomDeck would suffice here.

View File

@@ -1,6 +1,7 @@
Name:Shower of Sparks
ManaCost:R
Types:Instant
A:SP$ DealDamage | Cost$ R | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | SubAbility$ DBDamage | SpellDescription$ CARDNAME deals 1 damage to target creature
SVar:DBDamage:DB$ DealDamage | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 1 | SpellDescription$ and 1 damage to target player or planeswalker.
A:SP$ DealDamage | ValidTgts$ Creature | NumDmg$ 1 | DamageMap$ True | SubAbility$ DBDamage | SpellDescription$ CARDNAME deals 1 damage to target creature
SVar:DBDamage:DB$ DealDamage | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 1 | SubAbility$ DBDamageResolve | SpellDescription$ and 1 damage to target player or planeswalker.
SVar:DBDamageResolve:DB$ DamageResolve
Oracle:Shower of Sparks deals 1 damage to target creature and 1 damage to target player or planeswalker.

View File

@@ -4,6 +4,6 @@ Types:Creature Minotaur Warrior
PT:3/4
A:AB$ Pump | Cost$ 1 | NumAtt$ +1 | NumDef$ -1 | SpellDescription$ CARDNAME gets +1/-1 until end of turn.
T:Mode$ BecomesTarget | ValidSource$ Ability.Land+namedLabyrinth of Skophos+YouCtrl | ValidTarget$ Creature.Other | TriggerZones$ Battlefield | Execute$ TrigFight | OptionalDecider$ You | TriggerDescription$ Whenever another creature becomes the target of an ability of a land you control named Labyrinth of Skophos, you may have CARDNAME fight that creature. (Each deals damage equal to its power to the other.)
SVar:TrigFight:DB$ Fight | Defined$ Self | ExtraDefined$ TriggeredTarget
SVar:TrigFight:DB$ Fight | Defined$ Self & TriggeredTarget
DeckNeeds:Name$Labyrinth of Skophos
Oracle:{1}: Skophos Maze-Warden gets +1/-1 until end of turn.\nWhenever another creature becomes the target of an ability of a land you control named Labyrinth of Skophos, you may have Skophos Maze-Warden fight that creature. (Each deals damage equal to its power to the other.)

View File

@@ -5,7 +5,7 @@ PT:5/5
S:Mode$ MinMaxBlocker | ValidCard$ Card.Self | Max$ 1 | Description$ CARDNAME can't be blocked by more than one creature.
T:Mode$ AttackersDeclared | AttackingPlayer$ Player.Opponent | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | IsPresent$ Card.Self+tapped | TriggerDescription$ Whenever an opponent attacks with one or more creatures, if NICKNAME is tapped, you may have that opponent gain control of NICKNAME until end of combat. If you do, choose a player or planeswalker that opponent is attacking. NICKNAME is attacking that player or planeswalker.
SVar:TrigGainControl:DB$ GainControl | Defined$ Self | NewController$ TriggeredAttackingPlayer | LoseControl$ EndOfCombat | RememberControlled$ True | SubAbility$ DBAttack
SVar:DBAttack:DB$ ChangeCombatants | Defined$ Remembered | Attacking$ Player.Defending,Valid Planeswalker.Defending | SubAbility$ DBCleanup
SVar:DBAttack:DB$ ChangeCombatants | Defined$ Remembered | Attacking$ Player.Defending & Valid Planeswalker.Defending | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All
Oracle:Tahngarth, First Mate can't be blocked by more than one creature.\nWhenever an opponent attacks with one or more creatures, if Tahngarth is tapped, you may have that opponent gain control of Tahngarth until end of combat. If you do, choose a player or planeswalker that opponent is attacking. Tahngarth is attacking that player or planeswalker.

View File

@@ -6,8 +6,7 @@ K:Flying
T:Mode$ Drawn | ValidCard$ Card.OppOwn | FirstCardInDrawStep$ False | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever an opponent draws a card except the first one they draw in each of their draw steps, create a 1/1 green Snake creature token.
SVar:TrigToken:DB$ Token | TokenScript$ g_1_1_snake
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you and that player each draw that many cards.
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | Defined$ TriggeredTarget | NumCards$ X
SVar:TrigDraw:DB$ Draw | Defined$ You & TriggeredTarget | NumCards$ X
SVar:X:TriggerCount$DamageAmount
DeckHas:Ability$Token
Oracle:Flying\nWhenever an opponent draws a card except the first one they draw in each of their draw steps, create a 1/1 green Snake creature token.\nWhenever Xyris, the Writhing Storm deals combat damage to a player, you and that player each draw that many cards.

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Human Pirate
PT:4/3
K:Flying
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigBorrow | TriggerDescription$ Whenever CARDNAME attacks, look at defending player's hand. You may put a creature card from it onto the battlefield under your control tapped and attacking that player or a planeswalker they control. Return that creature to its owner's hand at the beginning of the next end step.
SVar:TrigBorrow:DB$ ChangeZone | ChangeNum$ 1 | DefinedPlayer$ TriggeredDefendingPlayer | Chooser$ You | ChangeType$ Creature | Origin$ Hand | Destination$ Battlefield | GainControl$ True | Tapped$ True | Attacking$ DefendingPlayer,Valid Planeswalker.ControlledBy DefendingPlayer | RememberChanged$ True | SubAbility$ DBDelayTrig
SVar:TrigBorrow:DB$ ChangeZone | ChangeNum$ 1 | DefinedPlayer$ TriggeredDefendingPlayer | Chooser$ You | ChangeType$ Creature | Origin$ Hand | Destination$ Battlefield | GainControl$ True | Tapped$ True | Attacking$ DefendingPlayer & Valid Planeswalker.ControlledBy DefendingPlayer | RememberChanged$ True | SubAbility$ DBDelayTrig
SVar:DBDelayTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | RememberObjects$ RememberedLKI | Execute$ DBChange | StackDescription$ None | SubAbility$ DBCleanup | TriggerDescription$ Return that creature to its owner's hand at the beginning of the next end step.
SVar:DBChange:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True