Enums & Constants
TeamEnum (Target types for addSpell)
| Value | Name | Description |
|---|---|---|
0 | Enemy | Any enemy |
1 | Ally | Any ally |
2 | Self | Self only |
3 | EnemyAdjacent | Adjacent enemy |
4 | AllyAdjacent | Adjacent ally |
5 | SelfAdjacent | Self if adjacent |
6 | EnemySummon | Enemy summons only |
7 | EnemyNotSummon | Enemy non-summons |
8 | AllySummon | Ally summons |
9 | AllyNotSummon | Ally non-summons |
10 | EnemySummonAdjacent | Adjacent enemy summon |
11 | EnemyNotSummonAdjacent | Adjacent enemy non-summon |
12 | AllySummonAdjacent | Adjacent ally summon |
13 | AllyNotSummonAdjacent | Adjacent ally non-summon |
-- Pass the integer value
-- Example: fightBasic:addSpell(8139, 0, 1, 2, false, 100)
-- ^--- 0 = Enemy
TacticEnum (playTurn tactic)
| Value | Name | Description |
|---|---|---|
0 | Imobile | Stay in place, cast from current cell |
1 | HandToHand | Move to melee range, then cast |
2 | Distance | Stay at range, cast from afar |
3 | NoAction | Skip all turns |
4 | Advanced | Built-in advanced AI |
5 | AdvancedInScript | Lua script handles fight via callbacks |
fightBasic:playTurn(1) -- HandToHand
fightBasic:playTurn(2) -- Distance
BreedEnum (Character class IDs)
| Value | Name |
|---|---|
1 | Feca |
2 | Osamodas |
3 | Enutrof |
4 | Sram |
5 | Xelor |
6 | Ecaflip |
7 | Eniripsa |
8 | Iop |
9 | Cra |
10 | Sadida |
11 | Sacrieur |
12 | Pandawa |
13 | Rogue |
14 | Masqueraider |
15 | Steamer (Foggernaut) |
local breed = fightCharacter:getBreed() -- returns int 1-15
Default Attack Spells by Breed
ATTACK_SPELLS = {
["1"] = 3, -- Feca
["2"] = 4714, -- Osamodas
["3"] = 43, -- Enutrof
["4"] = 61, -- Sram
["5"] = 7359, -- Xelor
["6"] = 7467, -- Ecaflip
["7"] = 4947, -- Eniripsa
["8"] = 8139, -- Iop (Pression)
["9"] = 5813, -- Cra (Fleche de Transfusion)
["10"] = 183, -- Sadida
["11"] = 5885, -- Sacrieur
["12"] = 0, -- Pandawa (0 = no spell, use raw melee)
["13"] = 2794, -- Rogue
["14"] = 6131, -- Masqueraider
["15"] = 3210, -- Steamer
}
DirectionEnum
| Value | Name |
|---|---|
0 | RIGHT |
1 | DOWN_RIGHT |
2 | DOWN |
3 | DOWN_LEFT |
4 | LEFT |
5 | UP_LEFT |
6 | UP |
7 | UP_RIGHT |
StatEnum
| Value | Name | Description |
|---|---|---|
-1 | NONE | No stat |
10 | STRENGHT | Earth / Strength |
11 | VITALITY | Vitality |
12 | WISDOM | Wisdom |
13 | CHANCE | Water |
14 | AGILITY | Air |
15 | INTEL | Fire / Intelligence |
Entity Model (Fight Entity Object)
Returned byfightAction:getAllEntities() and fightSlave:entity().
| Field | Type | Description |
|---|---|---|
Team | boolean | true = ally, false = enemy |
LifePoints | int | Current HP |
MaxLifePoints | int | Max HP |
CellId | int | Current cell position |
CreatureGenericId | int | Monster/creature template ID |
AP | int | Current Action Points |
MP | int | Current Movement Points |
Level | int | Entity level |
PercentTerre | int | Earth resistance % |
PercentFeu | int | Fire resistance % |
PercentEau | int | Water resistance % |
PercentAir | int | Air resistance % |
PercentNeutre | int | Neutral resistance % |
Mycharacter | boolean | true = this is our bot character |
Id | double | Contextual entity ID |
lancesortcellid | int | Cell from which last spell was cast |
grade | int | Entity grade/rank |
local entities = fightAction:getAllEntities()
for _, entity in ipairs(entities) do
fightDebug:print("Name: " .. (entity["name"] or "?"))
fightDebug:print("Cell: " .. entity["CellId"])
fightDebug:print("HP: " .. entity["LifePoints"] .. "/" .. entity["MaxLifePoints"])
fightDebug:print("Team: " .. tostring(entity["Team"])) -- true=ally
fightDebug:print("AP: " .. entity["AP"] .. " MP: " .. entity["MP"])
fightDebug:print("Resistances: T=" .. entity["PercentTerre"]
.. " F=" .. entity["PercentFeu"]
.. " E=" .. entity["PercentEau"]
.. " A=" .. entity["PercentAir"]
.. " N=" .. entity["PercentNeutre"])
end
Error Codes (canCastSpellOnCell / canCastSpellOnCellAfterMove)
| Code | Meaning |
|---|---|
0 | NONE (Success — can cast) |
1-16 | Various spell restrictions (range, AP cost, cooldown, line of sight, occupied cell, etc.) |
Specific error code meanings are not documented in the binary. Test with
canCastSpellOnCell and check the return value.Lua Callbacks
WhenTactic is set to AdvancedInScript, the bot calls these Lua functions:
fightManagementPosition(challengers, defenders)
Called once at fight start during the placement phase.| Parameter | Type | Description |
|---|---|---|
challengers | table | {[cellId] = entityId} — Your team’s placement cells. -1 = empty cell |
defenders | table | {[cellId] = entityId} — Enemy team’s placement cells |
function fightManagementPosition(challengers, defenders)
-- Pick the first free challenger cell
for cell, id in pairs(challengers) do
if id == -1 then
fightAction:chooseCell(cell)
break
end
end
end
function fightManagementPosition(challengers, defenders)
global:delay(global:random(500, 1000))
local bestCell = nil
local bestDist = 999
-- Find nearest enemy cell
local enemyCell = nil
for cell, _ in pairs(defenders) do
enemyCell = cell
break
end
-- Pick closest free challenger cell to enemy
for cell, id in pairs(challengers) do
if id == -1 and enemyCell then
local dist = fightAction:getDistance(cell, enemyCell)
if dist < bestDist then
bestDist = dist
bestCell = cell
end
end
end
if bestCell then
fightAction:chooseCell(bestCell)
end
end
fightManagement()
Called each turn when it’s any entity’s turn (including enemies/summons). You must checkisItMyTurn().
function fightManagement()
if fightCharacter:isItMyTurn() == true then
-- Your turn logic here
end
end
Complete Examples
Example 1: Generic Melee Fighter (any breed)
ATTACK_SPELLS = {
["1"] = 3, ["2"] = 4714, ["3"] = 43,
["4"] = 61, ["5"] = 7359, ["6"] = 7467,
["7"] = 4947, ["8"] = 8139, ["9"] = 5813,
["10"] = 183, ["11"] = 5885, ["12"] = 7041,
["13"] = 2794, ["14"] = 6131, ["15"] = 3210,
}
function fightManagementPosition(challengers, defenders)
global:delay(global:random(500, 1000))
for cell, id in pairs(challengers) do
if id == -1 then
fightAction:chooseCell(cell)
break
end
end
end
function fightManagement()
if fightCharacter:isItMyTurn() == true then
local myCell = fightCharacter:getCellId()
local enemyCell = fightAction:getNearestEnemy()
local spellId = ATTACK_SPELLS[tostring(character:breed())]
-- Move toward enemy if not in range
if fightAction:getDistance(myCell, enemyCell) > 1 then
fightAction:moveTowardCell(enemyCell)
fightDebug:delay(global:random(300, 600))
end
-- Cast spell up to 3 times (refresh enemy position each time)
for i = 1, 3 do
enemyCell = fightAction:getNearestEnemy()
myCell = fightCharacter:getCellId()
if spellId ~= 0 and fightAction:canCastSpellOnCell(myCell, spellId, enemyCell) == 0 then
fightAction:castSpellOnCell(spellId, enemyCell)
fightDebug:delay(global:random(200, 500))
end
end
end
end
Example 2: Ranged Cra with Kiting
function fightManagement()
if fightCharacter:isItMyTurn() ~= true then return end
local myCell = fightCharacter:getCellId()
local enemyCell = fightAction:getNearestEnemy()
local dist = fightAction:getDistance(myCell, enemyCell)
fightDebug:print("Turn " .. fightAction:getCurrentTurn()
.. " | Dist=" .. dist
.. " | AP=" .. fightCharacter:getAP()
.. " | MP=" .. fightCharacter:getMP())
-- Cast ranged spells first (Fleche de Transfusion)
for i = 1, 2 do
enemyCell = fightAction:getNearestEnemy()
myCell = fightCharacter:getCellId()
if fightAction:canCastSpellOnCell(myCell, 5813, enemyCell) == 0 then
fightAction:castSpellOnCell(5813, enemyCell)
fightDebug:delay(global:random(300, 600))
end
end
-- Kite: if enemy is too close, move away
if dist <= 2 and fightCharacter:getMP() > 0 then
local cells = fightAction:getRealReachableCells()
local bestCell = nil
local bestDist = 0
for _, cell in ipairs(cells) do
local d = fightAction:getDistance(cell, enemyCell)
if d > bestDist then
bestDist = d
bestCell = cell
end
end
if bestCell and bestDist > dist then
fightAction:moveTowardCell(bestCell)
fightDebug:delay(global:random(200, 400))
end
end
end
Example 3: Eniripsa Healer + Summon Control
function fightManagement()
if fightCharacter:isItMyTurn() ~= true then return end
local myCell = fightCharacter:getCellId()
-- Priority 1: Self-heal if HP < 60%
if fightCharacter:getLifePointsP() < 60 then
if fightAction:canCastSpellOnCell(myCell, 4947, myCell) == 0 then
fightAction:castSpellOnCell(4947, myCell)
fightDebug:delay(global:random(400, 700))
end
end
-- Priority 2: Heal low-HP allies
local entities = fightAction:getAllEntities()
for _, e in ipairs(entities) do
if e["Team"] == true and e["Mycharacter"] == false then
local hpPercent = (e["LifePoints"] / e["MaxLifePoints"]) * 100
if hpPercent < 50 then
if fightAction:canCastSpellOnCell(myCell, 4947, e["CellId"]) == 0 then
fightAction:castSpellOnCell(4947, e["CellId"])
fightDebug:delay(global:random(300, 600))
end
end
end
end
-- Priority 3: Attack nearest enemy with remaining AP
local enemyCell = fightAction:getNearestEnemy()
if fightAction:canCastSpellOnCell(myCell, 4947, enemyCell) == 0 then
fightAction:castSpellOnCell(4947, enemyCell)
end
end
Example 4: Using fightBasic for Simple AI
-- Setup spell rotation once (outside fight callback)
fightBasic:clearSpells()
fightBasic:addSpell(8131, 0, 1, 1, false, 100) -- Epee Divine, Enemy, every turn, 1x
fightBasic:addSpell(8139, 0, 1, 2, false, 100) -- Pression, Enemy, every turn, 2x
fightBasic:setFightSpeed(1) -- Ultra-Safe delays
fightBasic:setApproachDistance(0) -- No min distance (melee)
function fightManagement()
if fightCharacter:isItMyTurn() == true then
fightBasic:playTurn(1) -- Let basic AI handle it (HandToHand)
end
end
Example 5: Anti-Ban Delays Pattern
function fightManagement()
if fightCharacter:isItMyTurn() ~= true then return end
-- Human-like delay before starting turn
fightDebug:delay(global:random(800, 1500))
local myCell = fightCharacter:getCellId()
local enemyCell = fightAction:getNearestEnemy()
-- Move with delay
if fightAction:getDistance(myCell, enemyCell) > 1 then
fightAction:moveTowardCell(enemyCell)
fightDebug:delay(global:random(400, 900)) -- wait after move
end
-- Cast with delay between each spell
for i = 1, 3 do
enemyCell = fightAction:getNearestEnemy()
myCell = fightCharacter:getCellId()
if fightAction:canCastSpellOnCell(myCell, 8139, enemyCell) == 0 then
fightAction:castSpellOnCell(8139, enemyCell)
fightDebug:delay(global:random(300, 700)) -- delay between casts
end
end
-- End-of-turn delay (simulates thinking)
fightDebug:delay(global:random(200, 500))
end
function fightManagementPosition(challengers, defenders)
-- Delay before placing (humans don't instant-place)
global:delay(global:random(1000, 2000))
for cell, id in pairs(challengers) do
if id == -1 then
fightAction:chooseCell(cell)
break
end
end
end
Sous-pages
Combat basique
Méthodes de combat basiques : playTurn, setFightSpeed et fonctions principales.
Actions de combat
Lancement de sorts, déplacement, pathfinding et gestion des entités.
Personnage de combat
Stats et informations du personnage en combat.
Debug de combat
Débogage et journalisation des informations de combat.
Défis de combat
Gestion des défis de combat.