• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.x Series Interface Explanations

Codex NG

Recurrent Flamer
Joined
Jul 24, 2015
Messages
2,994
Solutions
12
Reaction score
1,657
I will be using 1.0, 1.1 & 1.2 for this tutorial/explanation.

Since there is no proper documentation for this anywhere, this will be it.

First let me say this so its out of the way, an interface is not a function in the sense that
we know of like add(2, 2) = 4, no it is a mechanism which allows us to interact with the server.

The parameters of the interface are actually arguments which are sent from the server based on our
actions in the game, whether it is logging in, stepping on a tile, equipping or using an item etc..
this information is sent to the interface's parameters, which we then use in our scripts.

List of interfaces

Actions
Code:
onUse

Chat Channel Events
Code:
canJoin
onJoin
onLeave
onSpeak

Creature Events
Code:
onAdvance
onDeath
onExtendedOpcode
onHealthChange
onKill
onLogin
onLogout
onManaChange
onModalWindow
onPrepareDeath
onTextEdit
onThink

Global Events
Code:
onRecord
onShutdown
onStartup
onTime

Monster Events
Code:
onCreatureAppear
onCreatureDisappear
onCreatureMove
onCreatureSay
onThink

Movements
Code:
onAddItem
onDeEquip
onEquip
onRemoveItem
onStepIn
onStepOut

NPCs
Code:
onCreatureAppear
onCreatureDisappear
onCreatureMove
onCreatureSay
onPlayerCloseChannel
onPlayerEndTrade
onThink

Raids
Code:
onRaid

Talkactions
Code:
onSay

Spells
Code:
onCastSpell

Weapons
Code:
onUseWeapon
--------------------------------------------
cid, player, creature, npc, monster

1.0
The parameter cid is the id of the player, creature, npc or monster
1.1 - 1.2
The parameter player, creature, npc, monster is userdata, it is a pointer to a metatable of the
respected argument, however the argument can be creature and be refering to a player or monster etc..
this is why we use
Code:
if isPlayer(cid) then
    -- do something
end

or

if creature:isPlayer() then
    -- do something
end
To determine if the value passed is the intended target.

Please note, this information might not be 100% correct, but it is better than nothing.

This code is lifted from the sources.

--------------------------------------------
Actions
onUse
1.0
Code:
onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)

1.1 / 1.2
Code:
onUse(player, item, fromPosition, target, toPosition, isHotkey)
item is userdata it contains the itemid and unique id of the item, however it also
contains other things like the name, description etc and is accessable via its metamethods.

fromPosition is a metatable which contains x, y, z & stackpos of the item, fromPosition
returns the position of where the item you are using came from.. e.g. your backpack, the ground etc..

itemEx or target is userdata it contains the itemid and unique id of the item you use the item on,
however it also contains other things like the name, description etc and is accessable via its metamethods.

toPosition is a metatable which contains x, y, z & stackpos of the itemEx or target, toPosition returns
the position of itemEx or target.. e.g. your backpack, the ground etc..

isHotkey is a boolean value, the return value of this is true if a hotkey was pressed and false if it wasn't.

--------------------------------------------

Movements
onStepIn & onStepOut
1.0
Code:
onStepIn(cid, item, pos, fromPosition)
onStepOut(cid, item, pos, fromPosition)

1.1 / 1.2
Code:
onStepIn(creature, item, pos, fromPosition)
onStepOut(creature, item, pos, fromPosition)

We've already discussed cid and creature,

item see actions for indepth explanation, however it is not an item you use, it is an item you walk on or off, this doesn't
have to be a stationary item such a ground tile this can be a moveable item aswell.

pos is the position of the item you are walking on or off.

fromPosition is the position of where you came from.

onEquip & onDeEquip

1.0
Code:
onEquip(cid, item, slot)
onDeEquip(cid, item, slot)

1.1 / 1.2
Code:
onEquip(player, item, slot)
onDeEquip(player, item, slot)


Both onEquip and onDeEquip are only used by the player, see the cid and player
explanation above, item see the indepth explanation above, however it is not an
item you step on or off, or even an item you use, it is as the name of the interfaces imply it is
an item in which you equip to or remove from the player.

slot is a number, the slot id of where item is equipped to or de-equipped from.

onAddItem & onRemoveItem

1.0 - 1.2
Code:
onAddItem(moveitem, tileitem, pos)
onRemoveItem(moveitem, tileitem, pos)

Both moveitem & tileitem are userdata, moveitem is the item you move on to tileitem, pos is a table with the position of tileitem.

For instance if tileitem is a dustbin (itemid 1777), and you took your backpack off and tossed it in the dustbin, moveitem would be your backpack.

This rule applies to both onAddItem & onRemoveItem and can be used in conjunction with onStepIn or onStepOut or both.

--------------------------------------------

Talkactions

onSay

1.0
Code:
onSay(cid, words, param, type)
1.1 - 1.2
Code:
onSay(player, words, param, type)
See cid and player above for an in-depth explanation.

words is a string, it contains the command used when executing the talkaction.

param is also a string it contains the argument you pass to the command.

type is a number it is the speak class used when executing the talkaction.

If you run a print(type(type)) over it will return 1, which is TALKTYPE_SAY

--------------------------------------------

Raids

onRaid

1.0 - 1.2
Code:
onRaid()

onRaid has no parameters, its parameters are read from the xml which is beyond the scope of this tutorial.
--------------------------------------------
 
Last edited:
Creature Events

onKill

1.0
Code:
onKill(cid, target)
1.1 - 1.2
Code:
onKill(creature, target)

cid, creature and target are userdata, both cid and creature are the monster, npc or player which did the killing, target is the npc, player or monster which got killed.

onLogin & onLogout

1.0
Code:
onLogin(cid)
onLogout(cid)
1.1 - 1.2
Code:
onLogin(player)
onLogout(player)

See both player and cid above for an in-depth explanation.

onAdvance

1.0
Code:
onAdvance(cid, skill, oldLevel, newLevel)
1.1 - 1.2
Code:
onAdvance(player, skill, oldLevel, newLevel)

See both player and cid above for an in-depth explanation.

skill is a number and is referring to the 9 different skills associated with the player and can be referenced either by name or number this includes all the melee skills, magic level, experience level and fishing.

List of skills for this parameter
Code:
    SKILL_FIST = 0
    SKILL_CLUB = 1
    SKILL_SWORD = 2
    SKILL_AXE = 3
    SKILL_DISTANCE = 4
    SKILL_SHIELD = 5
    SKILL_FISHING = 6
    SKILL_MAGLEVEL = 7
    SKILL_LEVEL = 8

oldLevel is a number and is referring to the previous level they had before they leveled up.

newLevel is a number and is referring to the current level they have now as a result of leveling up.

onDeath

1.0
Code:
onDeath(cid, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified)
1.1 - 1.2
Code:
onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified)

Both cid, and creature are userdata and can be either a monster, npc or player which has died.

corpse is the body or container of the thing that died.

lasthitkiller is userdata, this is an npc, monster, player or field which hit the npc, monster or player last before it died

mostdamagekiller is userdata, this is an npc, monster, player or field which did the most damage to the npc, monster or player before it died.

lasthitunjustified is a boolean value, this is open for debate might just be player related I honestly don't know, when i think unjustified i think pker, however this could also possibly be a player experience stealer.

mostdamageunjustified is a boolean value, this is open for debate might just be player related I honestly don't know, when i think unjustified i think pker, however this could also possibly be a player experience stealer.

onPrepareDeath

1.0
Code:
onPrepareDeath(cid, killer)
1.1 - 1.2
Code:
onPrepareDeath(creature, killer)

Both cid, and creature are userdata and can be either a monster, npc or player which is about to die.

killer is also userdata this is can be an npc, monster, player or field which is about to kill the player, monster or npc.

onThink

1.0
Code:
onThink(cid, interval)
1.1 - 1.2
Code:
onThink(creature, interval)

Both cid and creature are userdata and can refer to being a monster, npc or player.

interval is a number which is based in miliseconds

onTextEdit

1.0 - 1.2
Code:
onTextEdit(player, item, text)

See above for the in-depth explanation of player.

item is userdata and can be any item you can write text to.

text is a string the text to write

I'll use an example found in this thread but convert it to 1.2
CreatureEvent - Deathnote! (onTextEdit example)

Code:
function onTextEdit(player, item, text)
    if item.actionid == 9202 then
        local name = Player(text)
        if name then
            name:addHealth(-name:getMaxHealth())
        end
    end
    return true
end

onHealthChange

1.0 - 1.2
Code:
onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)

creature and attacker are userdata and can be a monster, npc or player.

primaryType and secondaryType are a combat type, please see below.
Code:
    COMBAT_NONE
    COMBAT_PHYSICALDAMAGE
    COMBAT_ENERGYDAMAGE
    COMBAT_EARTHDAMAGE
    COMBAT_FIREDAMAGE
    COMBAT_UNDEFINEDDAMAGE
    COMBAT_LIFEDRAIN
    COMBAT_MANADRAIN
    COMBAT_HEALING
    COMBAT_DROWNDAMAGE
    COMBAT_ICEDAMAGE
    COMBAT_HOLYDAMAGE
    COMBAT_DEATHDAMAGE

primaryDamage and secondaryDamage are a number which corresponds to the damage type the creature, npc or player receives.

origin - please refer to the origin list below

Origin list
Code:
    ORIGIN_NONE,
    ORIGIN_CONDITION,
    ORIGIN_SPELL,
    ORIGIN_MELEE,
    ORIGIN_RANGED,

onManaChange

1.0 - 1.2
Code:
onManaChange(creature, attacker, manaChange, origin)

creature and attacker are userdata and can be a monster, npc or player.

manaChange is a number and corresponds to how much mana which was lost or gained.

origin - please refer to the origin list above

onExtendedOpcode

1.0 - 1.2
Code:
onExtendedOpcode(player, opcode, buffer)

opcode is a number (only information i could find on this was CREATURE_EVENT_EXTENDED_OPCODE)

buffer is a string, will have to skip this til i know more

onModalWindow

1.0 - 1.2
Code:
onModalWindow(player, modalWindowId, buttonId, choiceId)

player is userdata and only refers to a player.

modalWindowId is the id number of the window.

buttonId this is a number of the button to press which either exits the window or executes the selection.

choiceId this is a number which corresponds to the id of the selection

We will use a shorter version of this example to save space
Lua - Problems with a TP script.

Code:
local towns = {
    "Thais",
    "Carlin",
    "Venore"
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if player:getCondition(CONDITION_INFIGHT, CONDITIONID_DEFAULT) then
        player:sendCancelMessage("PZ locked!")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local modalWindow = ModalWindow(2, "Destination", "Make your choice:")
    for i = 1, #towns do
        modalWindow:addChoice(i, i .. ". " .. towns[i])
    end

    modalWindow:addButton(1, 'Go')
    modalWindow:setDefaultEnterButton(1)
    modalWindow:addButton(2, 'Exit')
    modalWindow:setDefaultEscapeButton(2)

    modalWindow:sendToPlayer(player)
    player:registerEvent("eventName")
    return true
end

local destinations = {
    Position(32369, 32241, 7),
    Position(32360, 31782, 7),
    Position(32957, 32076, 7)
}

function onModalWindow(player, modalWindowId, buttonId, choiceId)
    player:unregisterEvent("eventName")
    if modalWindowId ~= 2 or buttonId ~= 1 then
        return false
    end

    local destination = destinations[choiceId]
    if not destination then
        return true
    end

    player:teleportTo(destination)
    destination:sendMagicEffect(CONST_ME_TELEPORT)
    return true
end

reserved

reserved
 
Last edited by a moderator:
Good job.
Little correction: Item is an userdata not a metatable.

Only positions are metatables. The other stuff is all userdata. In fact it's a table with Position metatable but that's not that relevant.
 
Well done so far.
I just have a little suggestions, you could list all the available events first and then go into detail.
I know first hand that a lot of people look into this threads and search for an overview, so instead of going through everything and searching it, they can find it easily in a list.

Probably even add the parameters already to it, easy to copy paste for people who aren't familiar with them then.
 
Last edited by a moderator:
Probably even add the parameters already to it, easy to copy paste for people who aren't familiar with them then.
Text is limited per post :(

I am going to re-arrange the explanation so its in the listing order, I have to get ready for work soon, should of thought about this over the weekend.
 
Last edited:
reminds me why I didn't update my old tutorial, I cannot even edit the posts cause they're to long, even reporting them didn't really cause any attention to get them changed by a mod
 
Hi, how I get Experience (like monsterType:getExperience()) inside of onHealthChange ?
 
Hi, how I get Experience (like monsterType:getExperience()) inside of onHealthChange ?
creature or attacker could possibly be a monster but you'll need to check for it being a monster because both Player & MonsterType have the method getExperience.

Code:
https://github.com/otland/forgottenserver/search?l=C%2B%2B&q=getexperience&type=
 
creature or attacker could possibly be a monster but you'll need to check for it being a monster because both Player & MonsterType have the method getExperience.

Code:
https://github.com/otland/forgottenserver/search?l=C%2B%2B&q=getexperience&type=

Can you help me formulate within the onHealthChange the ability to print the monster experience? I need to make a critical calculation based on the monster's experience
 
Can you help me formulate within the onHealthChange the ability to print the monster experience? I need to make a critical calculation based on the monster's experience
Always check the sources, particularly luascript.cpp this source file will let you know if a specific method exists.
Here is your example.
Lua:
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if creature:isMonster() then
        -- do something
    elseif attacker:isMonster() then
        -- or do something else
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end
Code:
https://github.com/otland/forgottenserver/search?q=isMonster&unscoped_q=isMonster

Remember both Player & MonsterType have the same method getExperience. Unfortunately I will not complete the script for you.. don't be afraid to code even if it crashes the server.. its not made out of glass.
 
Ar those interfaces or callbacks?
They are arguments, All of these parameters (creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) are really arguments, they are sent from the server but only primaryDamage, primaryType, secondaryDamage, secondaryType are returned. However you can manipulate these values prior to returning them. As an example by setting the values primaryDamage & secondaryDamage to 0 you can emulate invincibility from an attack that affects the player's health, hence the name onHealthChange.

onHealthChange is the interface.
 
They are arguments, All of these parameters (creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) are really arguments, they are sent from the server but only primaryDamage, primaryType, secondaryDamage, secondaryType are returned. However you can manipulate these values prior to returning them. As an example by setting the values primaryDamage & secondaryDamage to 0 you can emulate invincibility from an attack that affects the player's health, hence the name onHealthChange.

onHealthChange is the interface.
Sorry for the missunderstanding, i meant all the time "onHealthChange". As your first post you say those are interfaces. I would not call them interfaces.

Good post anyway.
 
Sorry for the missunderstanding, i meant all the time "onHealthChange". As your first post you say those are interfaces. I would not call them interfaces.

Good post anyway.
But they are interface's otland/forgottenserver
Google definition of an interface in regards to programming
Code:
Interfaces in Object Oriented Programming Languages. An interface is a programming structure/syntax that allows the computer to enforce certain properties on an object (class). For example, say we have a car class and a scooter class and a truck class. Each of these three classes should have a start_engine() action.
 
The interface in the example you provided is Creature And all creture has those methods
This is correct. The Creature Event class is the interface, and things like onHealthChange are events (methods) of that class. Technically, C++ doesn’t have interfaces, just abstract classes, but that’s beside the point.
 
Last edited:
Back
Top