• 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!

Action Teleport System Kinto, 4 version: ModalWindow and version: no modalwindow

Michcol94

Member
Joined
Sep 2, 2021
Messages
105
Reaction score
18
I thought I'd give something back to the community, it's nothing complicated, but there's always something useful for someone, these are different versions of the teleportation script.
Libraries necessary for modal window scripts:
At the beginning, you will need the library that I used to create the following teleportation scripts and slightly modified by adding the ability to add five buttons - the original version allowed adding four buttons from this topic:
[TFS 1.2] Modal Window Helper Lib (https://otland.net/threads/tfs-1-2-modal-window-helper-lib.238773/)

ok, first of all, we add the ready library to the /data/lib folder called modalwindow.lua with the code from the spoiler:
Lua:
if not modalWindows then
    modalWindows = {
        modalWindowConstructor = ModalWindow,
        nextFreeId = 500,

        windows = {}
    }
end

local MT = {}
MT.__index = MT

function ModalWindow(...)
    local args = {...}
    if type(args[1]) == 'table' then
        local self = setmetatable(args[1], MT)
        local id = modalWindows.nextFreeId     
        self.id = id
        self.buttons = {}
        self.choices = {}
        self.players = {}
        self.created = false

        modalWindows.nextFreeId = id + 1
        table.insert(modalWindows.windows, self)
        return self
    end

    return modalWindows.modalWindowConstructor(...)
end

function MT:setDefaultCallback(callback)
    self.defaultCallback = callback
end

function MT:addButton(text, callback)
    local button = {text = tostring(text), callback = callback}
    table.insert(self.buttons, button)
    return button
end

function MT:addButtons(...)
    for _, text in ipairs({...}) do
        table.insert(self.buttons, {text = tostring(text)})
    end
end

function MT:addChoice(text)
    local choice = {text = tostring(text)}
    table.insert(self.choices, choice)
    return choice
end

function MT:addChoices(...)
    for _, text in ipairs({...}) do
        table.insert(self.choices, {text = tostring(text)})
    end
end

function MT:setDefaultEnterButton(text)
    self.defaultEnterButton = text
end

function MT:setDefaultEscapeButton(text)
    self.defaultEscapeButton = text
end

function MT:setTitle(title)
    self.title = tostring(title)
end

function MT:setMessage(message)
    self.message = tostring(message)
end

local buttonOrder = {
    [5] = {1, 2, 3, 4, 5},
    [4] = {3, 4, 2, 1},
    [3] = {2, 3, 1},
    [2] = {1, 2},
    [1] = {1}
}
function MT:create()
    local modalWindow = modalWindows.modalWindowConstructor(self.id, self.title, self.message)
    local order = buttonOrder[math.min(#self.buttons, 5)]

    if order then
        for _, i in ipairs(order) do
            local button = self.buttons[i]
            modalWindow:addButton(i, button.text)
            button.id = i

            if button.text == self.defaultEnterButton then
                modalWindow:setDefaultEnterButton(i)
            elseif button.text == self.defaultEscapeButton then
                modalWindow:setDefaultEscapeButton(i)
            end
        end
    end

    for _, choice in ipairs(self.choices) do
        modalWindow:addChoice(_, choice.text)
        choice.id = _
    end

    self.modalWindow = modalWindow
end

function MT:sendToPlayer(player)
    if not self.modalWindow then
        self:create()
    end

    player:registerEvent('ModalWindowHelper')
    self.players[player:getId()] = true
    return self.modalWindow:sendToPlayer(player)
end
And in the /data/lib/lib.lua file we add the following lines of code:
Lua:
dofile('data/lib/modalwindow.lua')

Now the second file in data/cretaurescripts/scripts we add a file called modalwindowhelper.lua with the contents, i.e. the code from the spoiler below:
Lua:
function onModalWindow(player, modalWindowId, buttonId, choiceId)
    local modalWindow
    for _, window in ipairs(modalWindows.windows) do
        if window.id == modalWindowId then
            modalWindow = window
            break
        end
    end

    if not modalWindow then
        return true
    end

    local playerId = player:getId()
    if not modalWindow.players[playerId] then
        return true
    end
    modalWindow.players[playerId] = nil

    local choice = modalWindow.choices[choiceId]

    for _, button in ipairs(modalWindow.buttons) do
        if button.id == buttonId then
            local callback = button.callback or modalWindow.defaultCallback
            if callback then
                callback(button, choice)
                break
            end
        end
    end

    return true
end
Now we edit the /data/creaturescripts.xml file and add lines of code:
Lua:
<event type="modalwindow" name="ModalWindowHelper" script="modalwindowhelper.lua" />


Modal Window:
- So let's start with the first version with a modal window, this is the version with teleporting to the selected city by the player:

You need to edit the item ID and the x,y,z positions and optionally the city name!
I add a file called kinto.lua to the /data/actions/sripts folder with the code:
Lua:
print("kinto.lua script loaded.") -- Debug
local teleportItemID = 12722
local cities = {
    { name = "Center City", pos = Position(1036, 964, 7) }, -- Edit the name of the city, i.e. the button and coordinates, example { name = "button name", pos = Position(x coordinates, y coordinates, z coordinates) },
    { name = "West City", pos = Position(1044, 959, 7) },  --Edit the name of the city, i.e. the button and coordinates, example { name = "button name", pos = Position(x coordinates, y coordinates, z coordinates) },
    { name = "North City", pos = Position(1044, 959, 7) }, --Edit the name of the city, i.e. the button and coordinates, example { name = "button name", pos = Position(x coordinates, y coordinates, z coordinates) },
    { name = "East City", pos = Position(1044, 959, 7) }, --Edit the name of the city, i.e. the button and coordinates, example { name = "button name", pos = Position(x coordinates, y coordinates, z coordinates) },
    { name = "South City", pos = Position(1044, 959, 7) }, --Edit the name of the city, i.e. the button and coordinates, example { name = "button name", pos = Position(x coordinates, y coordinates, z coordinates) },
}
print("Cities loaded") -- Debug

local playerPositions = {}
local function teleportPlayer(player, destination)
    if player:getMana() < player:getMaxMana() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You need full mana to teleport and fly to the city.")
        return
    end
    player:teleportTo(destination)
    local mana = player:getMana()
            player:addMana(-mana) --   
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getId() == teleportItemID then
        local window = ModalWindow {
            id =20,
            title = "Kinto",
            message = "Select the city you are flying to:"
        }
        for i, city in ipairs(cities) do       
            window:addButton(city.name, function() teleportPlayer(player, city.pos) end)
        end
        if not playerPositions[player:getId()] then
            playerPositions[player:getId()] = {}
        end
        window:sendToPlayer(player)
        return true
    end
end
In the /data/actions.xml file we add the lines of code:
Code:
<action itemid="12722" script="kinto.lua" /> <!-- itemid="item id number"  script="file path kinto.lua" />-->
This is the effect of our code and how it works in practice:
-click first use item:

Zrzut ekranu 2023-12-13 183827.png

Zrzut ekranu 2023-12-13 184558.png

Version 2:
Now it's time for the second version which saves our current position to which we can later teleport:
You need to edit the item ID!
-I add a file called kinto2.lua to the /data/actions/scripts folder with the code:
Lua:
print("kinto2.lua script loaded.") -- Debug
local teleportItemID = 12722 -- <<<===== NUMBER ID ITEMS EDIT --
local playerPositions = {}
local function savePlayerPosition(player)
    local playerID = player:getId()
    playerPositions[playerID] = player:getPosition()
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Your position has been saved.")
end
local function teleportToSavedPosition(player)
    local playerID = player:getId()
    if not playerPositions[playerID] then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "No saved position found.")
        return
    end
    if player:getMana() < player:getMaxMana() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You need full mana to teleport.")
        return
    end
    player:teleportTo(playerPositions[playerID])
    player:addMana(-player:getMana())
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Teleported to your saved position.")
end
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getId() == teleportItemID then
        local window = ModalWindow {
            id = 20,
            title = "Kinto", -- <<<<<===========  Name title Window in the game
            message = "Select your action:"
        }
        window:addButton("Save My Position", function() savePlayerPosition(player) end)
        window:addButton("Teleport to Saved Position", function() teleportToSavedPosition(player) end)
        window:setDefaultEscapeButton("Close")
        window:sendToPlayer(player)
        return true
    end
end
In the /data/actions.xml file we add the lines of code:
Code:
<action itemid="12722" script="kinto2.lua" /> <!-- itemid="item id number"  script="file path kinto.lua" />-->
This is the effect of our code and how it works in practice:
-click first use item:
Zrzut ekranu 2023-12-13 183827.png
Effect open window:
Zrzut ekranu 2023-12-13 193945.png


No Modal Window version:

Version 1:

Now it's time for a version that saves our current position, to which we can later teleport if we have all the mana. after telportation we lose all mana.
You need to edit the item ID!
-I add a file called kinto3.lua to the /data/actions/scripts folder with the code:
Lua:
print("kinto3.lua script loaded.") -- Debug

local teleportItemID = 12721 -- EDIT NUMBER ID YUOR ITEM
local playerPositions = {}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local playerID = player:getId()

    if item:getId() == teleportItemID then
        -- Jeśli gracz kliknął na swoją pozycję, zapisz ją
        if toPosition == player:getPosition() then
            playerPositions[playerID] = toPosition
            player:sendTextMessage(MESSAGE_INFO_DESCR, "Your position has been saved.")
            return true
        end

        -- Jeśli gracz używa przedmiotu i ma zapisaną pozycję, teleportuj go
        if playerPositions[playerID] then
            if player:getMana() < player:getMaxMana() then
                player:sendTextMessage(MESSAGE_INFO_DESCR, "You need full mana to teleport.")
                return true
            end

            player:teleportTo(playerPositions[playerID])
            player:addMana(-player:getMana()) -- Odejmuje całą manę
            player:sendTextMessage(MESSAGE_INFO_DESCR, "Teleported to your saved position.")
            return true
        else
            player:sendTextMessage(MESSAGE_INFO_DESCR, "No saved position found.")
            return true
        end
    end

    return false
end
In the /data/actions/actions.xml file we add the lines of code:
Lua:
<action itemid="12721" script="kinto3.lua" /> <!-- itemid="item id number"  script="file path kinto.lua" />-->

Version2:
After entering the command !teleport, the name of the city from the table, for example: !teleport Center City
It teleports us to the selected city and its coordinates if we have full mana and the necessary teleportation item. After teleportation, we lose all mana.
You need to edit the item ID and the x,y,z positions and optionally the city name!
Lua:
local cities = {

-- EDIT TOWN NAME AND POSITION X,Y,Z

    ["Center City"] = Position(1036, 964, 7),
    ["West City"] = Position(1044, 959, 7),
    ["North City"] = Position(1044, 959, 7),
    ["East City"] = Position(1044, 959, 7),
    ["South City"] = Position(1044, 959, 7)
}

local requiredItemID = 12721 --

function onSay(player, words, param)
    local city = cities[param]
    if not city then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "City not found.")
        return false
    end

    if player:getMana() < player:getMaxMana() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You need full mana to teleport.")
        return false
    end

    if player:getItemCount(requiredItemID) == 0 then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You do not have the teleport item to teleport.")
        return false
    end

    player:teleportTo(city)
    player:addMana(-player:getMana())
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Teleported to " .. param .. ".")
    return true
end
In the /data/talkactions/talkactions.xml file we add the lines of code:
Lua:
<talkaction words="!teleport" separator=" " script="teleportcity.lua" />
Post automatically merged:

No modal window version 1.
This is the effect of our code and how it works in practice:
Zrzut ekranu 2023-12-13 204748.png
Click use witch in you character in the game:

Zrzut ekranu 2023-12-13 204833.png
Now use witch in the item teleport:

Zrzut ekranu 2023-12-13 204748.png

Zrzut ekranu 2023-12-13 204955.png
Post automatically merged:

This version requires editing the Tibia.dat and items.otb files
Zrzut ekranu 2023-12-13 195521.png
Zrzut ekranu 2023-12-13 195156.png
 
Last edited:
Back
Top