Card Abilities
You can find a list of card abilities your version supports by finding the file cardabilites.md
in the persistent directory described in the getting started guide.
Using card abilities
Creating a new card ability
You can use Lua scripts to add new card abilities.
To do so, you must create a new mod folder and add the following folder: GameData/CardAbilities/
For example, let's make a new ability called DestroyCardAbility
:
First, create a file called DestroyCardAbility.lua
, then write the following contents:
export = {
name = "Destroy card", --The name of the ability
parameters = { -- The parameters the ability uses
CardParameter.MakeStringParameter("TAGS", ""), -- Card tags (used to filter targets)
CardParameter.MakeBoolParameter("SELF", false), -- Whether to allow us to target ourselves
CardParameter.MakeBoolParameter("ALLY", false), -- Whether to allow us to target our allies
CardParameter.MakeBoolParameter("ENEMY", false), -- Whether to allow us to target our enemies
},
activeGameZones = { "ZONE_HAND" }, -- Which game zones this ability does something in
availableTargets = function(game, self, selectedTargets) --Get a list of all available targets
return HelperScripts.SearchTagInZones(game, -- Search for all zones
self.GetParameter("TAGS").stringValue, -- With the tags we want
self.card.playerID, -- Our player ID
self.GetParameter("SELF").boolValue, -- Ourselves
self.GetParameter("ALLY").boolValue, -- Allies
self.GetParameter("ENEMY").boolValue, -- Enemies
true, -- Whether to check for protection (Untargetable)
{ "ZONE_FIELD", "ZONE_SET" }); -- In the field and set zones
end,
hasAvailableTargets = function(game, self, selectedTargets) --Checks if we have any available targets
return HelperScripts.IsTagInZones(game, -- Search for all zones
self.GetParameter("TAGS").stringValue, -- With the tags we want
self.card.playerID, -- Our player ID
self.GetParameter("SELF").boolValue, -- Ourselves
self.GetParameter("ALLY").boolValue, -- Allies
self.GetParameter("ENEMY").boolValue, -- Enemies
true, -- Whether to check for protection (Untargetable)
{ "ZONE_FIELD", "ZONE_SET" }); -- In the field and set zones
end,
canPlay = function(game, self) -- Checks if we can play
return HelperScripts.CanPlayCard(game, self.card) and self.HasAvailableTargets(game, nil) -- We check if we can play the card and if we have targets
end,
onPlay = function(game, self, gameEvent) -- Called when we're playing the card
return HelperScripts.SpellOnPlay(game, self, gameEvent) -- We let the spell logic do its thing
end,
onPerformPlay = function(game, self, parameters)
local target = game.GetCard(parameters.GetParameter("TARGET").cardValue) -- Get our target
if target == nil then -- If it's invalid, stop
return
end
HelperScripts.EmitDeaths(game, -- Emit a death event to destroy the card
self.card, -- The source card (ourselves)
{ target } -- The target
)
end
}
Then, copy one of the cards you want to modify by copying the game data sources (for example, the Fireball card)
Make sure to make the copy in a similar path to the other cards (for example, GameData/Sets/AOF/CARD_DESTROY_CARD.json
).
You can then modify the card data to suit your needs, and finally add the ability to it.
You want to find the field abilities
and replace with your own:
{
"name": "Destroy target",
"abilityName": "DestroyCardAbility",
"description": "",
"parameters": [
{
"n": "TAGS",
"t": null,
"dt": 3,
"sv": "FOLLOWER HERO"
},
{
"n": "SELF",
"t": null,
"dt": 0,
"bv": true
},
{
"n": "ALLY",
"t": null,
"dt": 0,
"bv": true
},
{
"n": "ENEMY",
"t": null,
"dt": 0,
"bv": true
}
]
}
Then you can enable the mod and test if your card works!
Card ability structure reference
Fields
name
(String
)
The name of the ability (required)
Example:
...
name = "My ability name",
...
parameters
(Table
)
List of parameters the ability uses. The default values of each parameter are ignored.
Example:
...
parameters = {
CardParameter.MakeBoolParameter("My bool parameter", -- parameter name
false), -- default value
CardParameter.MakeIntParameter("My int parameter", 0),
CardParameter.MakeStringParameter("My string parameter", ""),
},
...
flags
(Table
)
List of state flags the ability uses.
Example:
...
flags = {
CardParameter.MakeBoolParameter("My bool parameter", -- parameter name
false), -- default value
CardParameter.MakeIntParameter("My int parameter", 0),
CardParameter.MakeStringParameter("My string parameter", ""),
},
...
handledCharacteristics
(Table
)
List of characteristics the ability modifies. Please note that you must implement onGetCharacteristic
if you use this!
Example:
...
handledCharacteristics = {
{
name = "ATTACK", -- Characteristic name
priority = GameCharacteristicLayer.Modifier, -- Type of change (Normal, Set, Modifier)
selfOnly = true, -- Whether it applies to the ability's card only
}
},
...
handledPlayerCharacteristics
(Table
)
List of player characteristics the ability modifies. Please note that you must implement onGetPlayerCharacteristic
if you use this!
Example:
...
handledPlayerCharacteristics = {
{
name = "MAXIMUM_MANA", -- Characteristic name
priority = GameCharacteristicLayer.Modifier, -- Type of change (Normal, Set, Modifier)
selfOnly = true, -- Whether it applies to the ability's card only
}
},
...
handledEvents
(Table
)
List of events the ability handles. Please note you must implement handlesEvent
and onEvent
if you use this, and optionally expectedResultForEvent
!
Example:
...
handledEvents = {
name = "EVENT_PARTY", -- Event name
phase = EventPhase.After -- Phase of the event (CheckReplacements, Before, During, After)
},
...
activeGameZones
(Table
)
List of game zones the ability is active.
Name | Description |
---|---|
ZONE_HERO | Hero Zone |
ZONE_DECK | Deck Zone |
ZONE_SET | Support Zone |
ZONE_FIELD | Field Zone |
ZONE_DISCARD | Discard zone |
ZONE_EXILE | Exile Zone |
Example:
...
activeGameZones = { "ZONE_FIELD" },
...
activeWhenAttached
(Bool
)
Whether this ability is active while attached to something.
Example:
...
activeWhenAttached = true,
...
canActivate
(function(game, self) -> Bool
)
Returns whether this ability can be activated.
Example:
...
canActivate = function(game, self)
return HelperScripts.CanRest(game, self)
end,
...
onActivate
(function(game, self) -> CardAbilityActivationPhase
)
Called when this ability is activated.
Example:
...
onActivate = function(game, self)
if game.GetPlayer(self.card.playerID).GetState("MANA").intValue < 3 then
return CardAbilityActivationPhase.Cancelled -- Tells the system to cancel the activation
end
return CardAbilityActivationPhase.Continue -- Tells the system to continue (Cancelled, Continue, Finished). You may Finish instead of Continue.
end,
...
onPerformActivation
(function(game, self)
)
Called to perform this ability's activation. This only gets called if onActivate
returns Continue
.
Example:
...
onPerformActivation = function(game, self)
game.MoveCard(self.card.playerID, self.card.GameZoneName, self.card.playerID, "ZONE_DECK", self.card.IndexInZone, -1)
end,
...