MagicWars 1.2.0 - Script your card - Part II
Posted: 14 Dec 2009, 20:51
Here is the next part of the article cycle describing scripting engine in MagicWars that allows you to create your own cards.
As I promised, today we will take a look at setting parameters at just created spells and abilities. Here the base list that is available at the moment:
setTarget(pattern)
setTargetCount(count)
setTargetsAreOptional(isOptional)
setTargetsUnique(isUnique)
setSpecificTarget(String description, String pattern)
setSpecificTarget(String description, Closure closure)
setTrigger(pattern)
setCondition(closure)
setLimit(limit)
setCanPlay(closure)
setDescription(String description)
setStackDescription(String description)
setInvisible(Boolean isInvisible)
addCost(Cost cost)
also we'll take a look at
addKicker(cost)
addFlashback(cost)
addTrap(spell, closure, cost)
addUnearth(cost)
and some specific cases:
@upkeepEachTurn(closure)
@effect(Closure apply, Closure discard)
@entersTheBattlefield(closure)
@leavesTheBattlefield(closure)
Let's start!
setTarget(pattern) - indicates that spellability (let's write it so, instead of long "spell or ability") targets smth in the game
pattern is constant string that represent simple variants of targets, and for this function it can be "Creature", "Creature|Player" or "Player".
note: all targeting spells can access selected target(s) by injected $target and $targets variables
example: //Shock
setTargetsAreOptional(isOptional) - indicates whether you can cancel targeting or not, default is true (usually you can cancel targeting). For default cases, no need to set this parameter. Used for abilities only.
example for setTargetsAreOptional(false) would be Flametongue Kavu that _must_ target any creature when comes into play (even itself if no other creature exists)
setTargetsUnique(isUnique) - if target count is more than 1, then this parameter says whether you can choose one target twice
setSpecificTarget(String description, String pattern) - if target is more complicated just creature in play, use this method to set target type
description - what will be shown to play when he is asked to choose the target
pattern - string that uses "zone=(.*),type=(.*)[,color=(.*)]" pattern
now only zone=Battlefield is available, for types and color you can combine them using & and ^ symbols
examples:
but it's also for simple cases, as you have more universal method for targeting:
setSpecificTarget(String description, Closure closure)
description - what will be shown to play when he is asked to choose the target
closure - that returns true or false for $permanent
few examples:
setTrigger(pattern) - is used for addAbilityTriggered, sets the trigger condition when ability will be triggered. Some of triggers available now:
"@creatureAttacks" - triggers when any create attacks (once for every creature attacking)
"@moveToZone,from=,to=" - when any object moves from one zone to another
is a constant of GameZone type:
setCondition(closure) - filters objects for trigger (in case we don't want to handle all of them)
examples:
setCanPlay(closure) - set the conditions when ability can be played
addCost(Cost cost) - experimental, adds additionaly cost to spellability. at the moment it can be only SacrificeCost() that sacrifices card it self
// from Zektar Shrine Expedition (ZEN): sacrifice and put 7/1 token if there are 3 quest counters
setStackDescription(String description) - add message that will be displayed to opponent in stack
you can specify message as string or reference to text from card description:
setInvisible(Boolean isInvisible) - if true, opponent won't be asked to response, false by default
...
some coffee here
...
addKicker(cost)
addFlashback(cost)
addTrap(spell, closure[, cost]) (closure indicates the case when it will be available for its trap cost)
addUnearth(cost)
- all of them are rather easy and just adds kicker, flashback, trap and unearth.
@upkeepEachTurn(closure) - executed at every your upkeep
first closure will be applyed to existing and new permanents, the second will applyed when effect owner will leave player or change controller
@leavesTheBattlefield(closure) - is called when card leaves the battlefield
That's it for today.
Next time we'll get to know what objects (from the game and engine) we can use in our spells.
See you
As I promised, today we will take a look at setting parameters at just created spells and abilities. Here the base list that is available at the moment:
setTarget(pattern)
setTargetCount(count)
setTargetsAreOptional(isOptional)
setTargetsUnique(isUnique)
setSpecificTarget(String description, String pattern)
setSpecificTarget(String description, Closure closure)
setTrigger(pattern)
setCondition(closure)
setLimit(limit)
setCanPlay(closure)
setDescription(String description)
setStackDescription(String description)
setInvisible(Boolean isInvisible)
addCost(Cost cost)
also we'll take a look at
addKicker(cost)
addFlashback(cost)
addTrap(spell, closure, cost)
addUnearth(cost)
and some specific cases:
@upkeepEachTurn(closure)
@effect(Closure apply, Closure discard)
@entersTheBattlefield(closure)
@leavesTheBattlefield(closure)
Let's start!
setTarget(pattern) - indicates that spellability (let's write it so, instead of long "spell or ability") targets smth in the game
pattern is constant string that represent simple variants of targets, and for this function it can be "Creature", "Creature|Player" or "Player".
note: all targeting spells can access selected target(s) by injected $target and $targets variables
example: //Shock
- Code: Select all
addSpell({
dealDamage($target, 2, $this)
})
setTarget("Creature|Player")
setTargetsAreOptional(isOptional) - indicates whether you can cancel targeting or not, default is true (usually you can cancel targeting). For default cases, no need to set this parameter. Used for abilities only.
example for setTargetsAreOptional(false) would be Flametongue Kavu that _must_ target any creature when comes into play (even itself if no other creature exists)
setTargetsUnique(isUnique) - if target count is more than 1, then this parameter says whether you can choose one target twice
setSpecificTarget(String description, String pattern) - if target is more complicated just creature in play, use this method to set target type
description - what will be shown to play when he is asked to choose the target
pattern - string that uses "zone=(.*),type=(.*)[,color=(.*)]" pattern
now only zone=Battlefield is available, for types and color you can combine them using & and ^ symbols
examples:
- Code: Select all
//Doom Blade
setSpecificTarget("Select nonblack creature to destroy.", "zone=Battlefield,type=Creature,color=^Black")
- Code: Select all
//Terror
setSpecificTarget("Select nonartifact, nonblack creature to destroy.", "zone=Battlefield,type=Creature&^Artifact,color=^Black")
- Code: Select all
//Creeping Mold
setSpecificTarget("Select artifact, enchantment, or land to destroy.", "zone=Battlefield,type=Land&Artifact&Enchantment") // <-- short pattern without color
but it's also for simple cases, as you have more universal method for targeting:
setSpecificTarget(String description, Closure closure)
description - what will be shown to play when he is asked to choose the target
closure - that returns true or false for $permanent
few examples:
- Code: Select all
// royal assasin
setSpecificTarget("Select target tapped creature to destroy.", {
return $permanent.isCreature() && $permanent.isTapped()
})
- Code: Select all
// royal assasin
setSpecificTarget("Select target tapped creature to destroy.", {
return $permanent.creature && $permanent.tapped
})
- Code: Select all
abilityTriggered.setSpecificTarget("Select nonbasic land to destroy.", {
return $permanent.isLand() && !$permanent.isBasicLand()
})
- Code: Select all
setSpecificTarget("Select target creature without flying.", {
return $permanent.creature && !$permanent.hasKeyword(KEYWORD_FLYING_SA)
})
setTrigger(pattern) - is used for addAbilityTriggered, sets the trigger condition when ability will be triggered. Some of triggers available now:
"@creatureAttacks" - triggers when any create attacks (once for every creature attacking)
"@moveToZone,from=,to=" - when any object moves from one zone to another
is a constant of GameZone type:
- Code: Select all
GameZone {
Library,
Hand,
Battlefield,
Stack,
Graveyard,
Exile,
Any
}
setCondition(closure) - filters objects for trigger (in case we don't want to handle all of them)
examples:
- Code: Select all
//Hagra Crocodile (ZEN) and Landfall
addAbilityTriggered(text[1], {
pumpUntilEOT($this, 2, 2)
})
setCondition({
return $card.isLand() && $card.controller == $this.controller
})
setTrigger("@moveToZone,from=Any,to=Battlefield")
- Code: Select all
//Deathgreeter (M10)
addAbilityTriggered(text[0], {
gainLife($this.controller, 1, $this)
}, "gain 1 life?")
setCondition({
return $card.creature && !$card.equals($this)
})
setTrigger("@moveToZone,from=Battlefield,to=Graveyard")
setCanPlay(closure) - set the conditions when ability can be played
addCost(Cost cost) - experimental, adds additionaly cost to spellability. at the moment it can be only SacrificeCost() that sacrifices card it self
// from Zektar Shrine Expedition (ZEN): sacrifice and put 7/1 token if there are 3 quest counters
- Code: Select all
addCost(SacrificeCost())
setCanPlay({
$this.getCounters(CounterType.QUEST) >= 3
})
setStackDescription(String description) - add message that will be displayed to opponent in stack
you can specify message as string or reference to text from card description:
- Code: Select all
text = [ "Flying", "Other Faerie creatures you control get +1/+1."]
setInvisible(Boolean isInvisible) - if true, opponent won't be asked to response, false by default
...
some coffee here
...
addKicker(cost)
addFlashback(cost)
addTrap(spell, closure[, cost]) (closure indicates the case when it will be available for its trap cost)
addUnearth(cost)
- all of them are rather easy and just adds kicker, flashback, trap and unearth.
- Code: Select all
def spell = spells($this)
addTrap(spell[0], {
return $opponent.getGameStatistics().hasSearchedLibraryForACardThisTurn();
}) // <-- cost is "0" here
@upkeepEachTurn(closure) - executed at every your upkeep
- Code: Select all
//Vampire Lacerator (ZEN)
@upkeepEachTurn({
if ($oppLife > 10) {
loseLife($this.controller, 1, $this)
mwprint("Upkeep, {Vampire Lacerator}: " + nickname($this.controller) + " loses 1 life.");
}
})
first closure will be applyed to existing and new permanents, the second will applyed when effect owner will leave player or change controller
- Code: Select all
// Scion of Oona
@effect({
if ($permanent.isCreature() && $permanent.type('Faerie')
&& $permanent.controller == $this.controller && !$permanent.equals($this)) {
$permanent.addAttack(1);
$permanent.addDefense(1);
$permanent.addKeyword(KEYWORD_SHROUD_SA);
}
},{
if ($permanent.isCreature() && $permanent.type('Faerie')
&& $permanent.controller == $this.controller && !$permanent.equals($this)) {
$permanent.subAttack(1);
$permanent.subDefense(1);
$permanent.removeKeyword(KEYWORD_SHROUD_SA);
}
})
@leavesTheBattlefield(closure) - is called when card leaves the battlefield
- Code: Select all
// Flametongue Kavu
@entersTheBattlefield({
def abilityTriggered = TriggeredAbility($this, {
dealDamage($target, 4, $this);
})
abilityTriggered.setNeedsTargetCreature(true)
abilityTriggered.setTargetsAreOptional(false)
stack.add(abilityTriggered)
})
That's it for today.
Next time we'll get to know what objects (from the game and engine) we can use in our spells.
See you