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

Help with modal window code

Nostalgian

Member
Joined
Mar 17, 2018
Messages
66
Reaction score
15
Ok, so I've been trying to get modal windows to work for a crafting system I've been working on. For some reason I just can't seem to wrap my head around it and figure out why its not working properly.

I've tried two approaches. I'm extremely confused, but I'll try not to confuse you.

My first approach was with this lib: [TFS 1.2] Modal Window Helper Lib (https://otland.net/threads/tfs-1-2-modal-window-helper-lib.238773/)

here is the code for this approach(keep in mind i'm just trying to make it work, i'll make it neater later):

My action script:
Code:
local config = {
-- Window Config
    mainTitleMsg = "Fletching", -- Main window title
    mainMsg = "Do you want arrows or bolts?", -- Main window message
 }

 
 
-- Crafting Config
 fletchChoice = {
            [1] = {fletch = "Arrow Shaft(5)", itemID = 3219, amount = 5},
            [2] = {fletch = "Bolt(3)", itemID = 3229, amount = 3},
            }
    
    
function onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)

local STORAGE_SKILL_LEVEL = 20032
local STORAGE_SKILL_TRY = 20033
local STORAGE_fletchMASTERY = 20034


local logsIds = {3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148}
local yesLogs = {3141}
local noLogs = {3142, 3143, 3144, 3145, 3146, 3147, 3148}
local target = Item(itemEx.uid)


--This will make sure the players storage value is correct so we can read it in the experience table--
    if player:getStorageValue(STORAGE_SKILL_LEVEL) < 0 then
        player:setStorageValue(STORAGE_SKILL_LEVEL, 1)
        player:setStorageValue(STORAGE_SKILL_TRY, 0)
    end

    if player:getStorageValue(STORAGE_fletchMASTERY) < 0 then
       player:setStorageValue(STORAGE_fletchMASTERY, 0)
    end
    
    local skillLevel = player:getStorageValue(STORAGE_SKILL_LEVEL)
    local skillTry = player:getStorageValue(STORAGE_SKILL_TRY)
    local fletchMastery = player:getStorageValue(STORAGE_fletchMASTERY)
 
    --Its always good to make sure locals we set are read--
    if not target then return false end
      --Check if the itemid is in the logIds table first so the script wont read much before stopping here (optimization)--
    if not isInArray(logsIds, itemEx.itemid) then return false end
    
    -----can't fish in pz---------
    if getTilePzInfo(player:getPosition()) then
    return player:sendCancelMessage("You cannot fletch in a protection zone.")
    end
    
    

    if isInArray(yesLogs, itemEx.itemid) then
    player:sendFletchWindow(config)
    return true
end
end

and my lib script:
Code:
-- Main Crafting Window -- This is the modal window that is displayed first
local player = Player(cid)
 
local STORAGE_SKILL_LEVEL = 20032
local STORAGE_SKILL_TRY = 20033
local STORAGE_fletchMASTERY = 20034


local skillLevel = player:getStorageValue(STORAGE_SKILL_LEVEL)
local skillTry = player:getStorageValue(STORAGE_SKILL_TRY)
local fletchMastery = player:getStorageValue(STORAGE_fletchMASTERY)

local quant = configs.experience[skillLevel][1]
 
    if not quant then return false end

function Player:sendFletchWindow(config)
    local function buttonCallback(button, choice)
 




    -- Modal Window Functionallity
        if button.text == "Select" then
            if fletchChoice[i].fletch == 1 then
            self:addItem(3219,5)
            end
        end
    end

  
    -- Modal window design
    local window = ModalWindow {
        title = config.mainTitleMsg, -- Title of the main craft modal window
        message = config.mainMsg.."\n\n" -- Message of the main craft modal window
    }
 
    -- Add buttons to the window (Note: if you change the names of these you must change the functions in the modal window functionallity!)
    window:addButton("Select", buttonCallback)
    window:addButton("Exit", buttonCallback)
  
    -- Add choices from the action script
    for i = 1, #fletchChoice do
        local o = fletchChoice[i].fletch
        local choice = window:addChoice(o)
        choice.id = i
    end
 
    -- Set what button is pressed when the player presses enter or escape.
    window:setDefaultEnterButton("Select")
    window:setDefaultEscapeButton("Exit")
  
    -- Send the window to player
    window:sendToPlayer(self)
end

With this setup, it sends me the modal window correctly, but when i try to select a choice I keep getting the error "attempt to index 'player' a nil value

Why? I've declared player to be Player(cid)..... does this not work in the lib folder or something?





Here is my Second approach, without that helper lib:

Actions:
Code:
local player = Player(cid)

function onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)

local STORAGE_SKILL_LEVEL = 20032
local STORAGE_SKILL_TRY = 20033
local STORAGE_fletchMASTERY = 20034


local logsIds = {3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148}
local yesLogs = {3141}
local noLogs = {3142, 3143, 3144, 3145, 3146, 3147, 3148}

--These locals require the script to be ran so they are here.--

    local target = Item(itemEx.uid)


--This will make sure the players storage value is correct so we can read it in the experience table--
    if player:getStorageValue(STORAGE_SKILL_LEVEL) < 0 then
        player:setStorageValue(STORAGE_SKILL_LEVEL, 1)
        player:setStorageValue(STORAGE_SKILL_TRY, 0)
    end

    if player:getStorageValue(STORAGE_fletchMASTERY) < 0 then
       player:setStorageValue(STORAGE_fletchMASTERY, 0)
    end
    
    local skillLevel = player:getStorageValue(STORAGE_SKILL_LEVEL)
    local skillTry = player:getStorageValue(STORAGE_SKILL_TRY)
    local fletchMastery = player:getStorageValue(STORAGE_fletchMASTERY)
 
    --Its always good to make sure locals we set are read--
    if not target then return false end
      --Check if the itemid is in the logIds table first so the script wont read much before stopping here (optimization)--
    if not isInArray(logsIds, itemEx.itemid) then return false end
    
    -----can't fish in pz---------
    if getTilePzInfo(player:getPosition()) then
    return player:sendCancelMessage("You cannot fletch in a protection zone.")
    end
    

    
    
    local modalWindow = ModalWindow(1, "Fletching", "Do you want to make arrow shafts or bolts?")
    
    modalWindow:addChoice(1, "Arrow Shaft(5)")
    modalWindow:addChoice(2, "Bolt(3)")
    

    modalWindow:addButton(1, "Select")
    modalWindow:setDefaultEnterButton(1)

    modalWindow:addButton(2, "Cancel")
    modalWindow:setDefaultEscapeButton(2)
        
    modalWindow:sendToPlayer(player)

    return true
    end

and creature script:

Code:
local player = Player(cid)

function onModalWindow(cid, modalWindowId, buttonId, choiceId)

    if modalWindowId ~= 1 or buttonId == 2 then
        return false
    end


 
local STORAGE_SKILL_LEVEL = 20032
local STORAGE_SKILL_TRY = 20033
local STORAGE_fletchMASTERY = 20034


local skillLevel = player:getStorageValue(STORAGE_SKILL_LEVEL)
local skillTry = player:getStorageValue(STORAGE_SKILL_TRY)
local fletchMastery = player:getStorageValue(STORAGE_fletchMASTERY)

local quant = configs.experience[skillLevel][1]
 
    if not quant then return false end
    
    
    
    if choiceId == 1 then
        player:addItem(3219, 5)
        return true
    end
    
    
    if choiceId == 2 then
        doPlayerAddItem(cid,3229,3)
        return true
    end
        
        
    
        
end

With this approach, it sends me the window correctly, but it does nothing when I select an option... no errors in console, no nothing. Its like it just exits when I make a selection. I have tried with this second approach to register the event in login.lua, as well as in the script itself. Makes no difference.

For some reason this is incredibly complicated to me. I am sure I am overthinking it.

Any help is greatly appreciated.
 
Yea, the second approach was an adaptation of that link. I also tried copy pasting the method of that link and just changing item ids to match what I've got. Still nothing.

It sends me the modal window, but does not execute any functionality
 
Just install that Helper Lib and use functions it contains in your action script.
Also declaring player outside a function does nothing.
Just try the example the author gave you and start from there.

Lua:
function onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)

-- The helper lib is used by passing a table value to the ModalWindow function
local window = ModalWindow {
    title = 'Title',
    message = 'Please, choose the lowest number and press [Ok]'
}

local lowestChoice
for i = 1, 5 do
    local value = math.random(1, 100)
    -- modalWindow:addChoice() returns the choice object that will be passed to the callbacks
    local choice = window:addChoice(value)
    -- This way we can pass extra information to the callback
    choice.value = value
    if not lowestChoice or lowestChoice.value > value then
        lowestChoice = choice
    end
end

lowestChoice.correct = true

-- Add a button with a specific callback
window:addButton('Ok',
    function(button, choice)
        if choice.correct then
            print('Player selected the correct option.')
        else
            print('Player selected the incorrect option.')
        end
    end
)
-- Set this button as the default enter button
window:setDefaultEnterButton('Ok')

-- Add a button without a specific callback
window:addButton('Close')
window:setDefaultEscapeButton('Close')

-- If a button without a specific callback is pressed, this fucntion will be called
window:setDefaultCallback(
    function(button, choice)
        print('Default callback, button pressed: ' .. button.text .. ' player choice: ' .. choice.text)
    end
)

window:sendToPlayer(player)

return true
end
 
not tested

Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
local player = Player(cid)

local STORAGE_SKILL_LEVEL = 20032
local STORAGE_SKILL_TRY = 20033
local STORAGE_fletchMASTERY = 20034

local logsIds = {3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148}
local yesLogs = {3141}
local noLogs = {3142, 3143, 3144, 3145, 3146, 3147, 3148}

--These locals require the script to be ran so they are here.--

    local target = Item(itemEx.uid)

--This will make sure the players storage value is correct so we can read it in the experience table--
    if player:getStorageValue(STORAGE_SKILL_LEVEL) < 0 then
        player:setStorageValue(STORAGE_SKILL_LEVEL, 1)
        player:setStorageValue(STORAGE_SKILL_TRY, 0)
    end

    if player:getStorageValue(STORAGE_fletchMASTERY) < 0 then
       player:setStorageValue(STORAGE_fletchMASTERY, 0)
    end
    
    local skillLevel = player:getStorageValue(STORAGE_SKILL_LEVEL)
    local skillTry = player:getStorageValue(STORAGE_SKILL_TRY)
    local fletchMastery = player:getStorageValue(STORAGE_fletchMASTERY)
 
    --Its always good to make sure locals we set are read--
    if not target then return false end
      --Check if the itemid is in the logIds table first so the script wont read much before stopping here (optimization)--
    if not isInArray(logsIds, itemEx.itemid) then return false end
    
    -----can't fish in pz---------
    if getTilePzInfo(player:getPosition()) then
    return player:sendCancelMessage("You cannot fletch in a protection zone.")
    end
    
    local modalWindow = ModalWindow(1000, "Fletching", "Do you want to make arrow shafts or bolts?")
    
    modalWindow:addButton(1, "Select")
    modalWindow:addButton(2, "Cancel")
        
    modalWindow:addChoice(1, "Arrow Shaft(5)")
    modalWindow:addChoice(2, "Bolt(3)")
    
    modalWindow:setDefaultEnterButton(1)
    modalWindow:setDefaultEscapeButton(2)
        
    modalWindow:sendToPlayer(cid)

    return true
    end


Lua:
function onModalWindow(cid, modalWindowId, buttonId, choiceId)
local player = Player(cid)
if buttonId == 2 then
    return false
end

local STORAGE_SKILL_LEVEL = 20032
local STORAGE_SKILL_TRY = 20033
local STORAGE_fletchMASTERY = 20034

local skillLevel = player:getStorageValue(STORAGE_SKILL_LEVEL)
local skillTry = player:getStorageValue(STORAGE_SKILL_TRY)
local fletchMastery = player:getStorageValue(STORAGE_fletchMASTERY)

local quant = configs.experience[skillLevel][1]
 
    if not quant then return false end

    if choiceId == 1 then
        player:addItem(3219, 5)
    elseif choiceId == 2 then
        doPlayerAddItem(cid,3229,3)
    end
    
    return true
end


Make sure to register event for the player (onUse function)
and unregister it as well (onModalWindow function)

that's something you are missing in the script that is stated in the tutorial
 
Back
Top