[TFS 1.2] Modal Window Helper Lib

Discussion in 'Mods & Lua Functions' started by Non Sequitur, Dec 11, 2015.

  1. Non Sequitur

    Non Sequitur Member

    Joined:
    Dec 1, 2015
    Messages:
    84
    Likes Received:
    73
    Best Answers:
    0
    Reasoning
    The current way we can implement modal windows is quite cumbersome in my opinion, having to create it somewhere, register an event, add buttons in some weird order to make it work and having to take account of window ids, button ids, choice ids in a complete different file than the one you've created the modal window. That is not optimal so I've created this helper library to help with that.

    What you can do with it
    Code (Lua):
    1. -- The helper lib is used by passing a table value to the ModalWindow function
    2. local window = ModalWindow {
    3.     title = 'Title',
    4.     message = 'Please, choose the lowest number and press [Ok]'
    5. }
    6.  
    7. local lowestChoice
    8. for i = 1, 5 do
    9.     local value = math.random(1, 100)
    10.     -- modalWindow:addChoice() returns the choice object that will be passed to the callbacks
    11.     local choice = window:addChoice(value)
    12.     -- This way we can pass extra information to the callback
    13.     choice.value = value
    14.     if not lowestChoice or lowestChoice.value > value then
    15.         lowestChoice = choice
    16.     end
    17. end
    18.  
    19. lowestChoice.correct = true
    20.  
    21. -- Add a button with a specific callback
    22. window:addButton('Ok',
    23.     function(button, choice)
    24.         if choice.correct then
    25.             print('Player selected the correct option.')
    26.         else
    27.             print('Player selected the incorrect option.')
    28.         end
    29.     end
    30. )
    31. -- Set this button as the default enter button
    32. window:setDefaultEnterButton('Ok')
    33.  
    34. -- Add a button without a specific callback
    35. window:addButton('Close')
    36. window:setDefaultEscapeButton('Close')
    37.  
    38. -- If a button without a specific callback is pressed, this fucntion will be called
    39. window:setDefaultCallback(
    40.     function(button, choice)
    41.         print('Default callback, button pressed: ' .. button.text .. ' player choice: ' .. choice.text)
    42.     end
    43. )
    44.  
    45. window:sendToPlayer(player)
    You can use this example in a talkaction and test it for yourself (check the output on your server console). Other than what is shown in the above code, you can also use modalWindow:addButtons(...) and modalWindow:addChoices(...) to add multiple buttons/choices at once.

    Installing

    • In data/lib/lib.lua
      Code (Lua):
      1. dofile('data/lib/modalwindow.lua')
    • Create the file data/lib/modalwindow.lua
      Code (Lua):
      1. if not modalWindows then
      2.     modalWindows = {
      3.         modalWindowConstructor = ModalWindow,
      4.         nextFreeId = 500,
      5.  
      6.         windows = {}
      7.     }
      8. end
      9.  
      10. local MT = {}
      11. MT.__index = MT
      12.  
      13. function ModalWindow(...)
      14.     local args = {...}
      15.     if type(args[1]) == 'table' then
      16.         local self = setmetatable(args[1], MT)
      17.         local id = modalWindows.nextFreeId        
      18.         self.id = id
      19.         self.buttons = {}
      20.         self.choices = {}
      21.         self.players = {}
      22.         self.created = false
      23.  
      24.         modalWindows.nextFreeId = id + 1
      25.         table.insert(modalWindows.windows, self)
      26.         return self
      27.     end
      28.  
      29.     return modalWindows.modalWindowConstructor(...)
      30. end
      31.  
      32. function MT:setDefaultCallback(callback)
      33.     self.defaultCallback = callback
      34. end
      35.  
      36. function MT:addButton(text, callback)
      37.     local button = {text = tostring(text), callback = callback}
      38.     table.insert(self.buttons, button)
      39.     return button
      40. end
      41.  
      42. function MT:addButtons(...)
      43.     for _, text in ipairs({...}) do
      44.         table.insert(self.buttons, {text = tostring(text)})
      45.     end
      46. end
      47.  
      48. function MT:addChoice(text)
      49.     local choice = {text = tostring(text)}
      50.     table.insert(self.choices, choice)
      51.     return choice
      52. end
      53.  
      54. function MT:addChoices(...)
      55.     for _, text in ipairs({...}) do
      56.         table.insert(self.choices, {text = tostring(text)})
      57.     end
      58. end
      59.  
      60. function MT:setDefaultEnterButton(text)
      61.     self.defaultEnterButton = text
      62. end
      63.  
      64. function MT:setDefaultEscapeButton(text)
      65.     self.defaultEscapeButton = text
      66. end
      67.  
      68. function MT:setTitle(title)
      69.     self.title = tostring(title)
      70. end
      71.  
      72. function MT:setMessage(message)
      73.     self.message = tostring(message)
      74. end
      75.  
      76. local buttonOrder = {
      77.     [4] = {3, 4, 2, 1},
      78.     [3] = {2, 3, 1},
      79.     [2] = {1, 2},
      80.     [1] = {1}
      81. }
      82. function MT:create()
      83.     local modalWindow = modalWindows.modalWindowConstructor(self.id, self.title, self.message)
      84.     local order = buttonOrder[math.min(#self.buttons, 4)]
      85.  
      86.     if order then
      87.         for _, i in ipairs(order) do
      88.             local button = self.buttons[i]
      89.             modalWindow:addButton(i, button.text)
      90.             button.id = i
      91.  
      92.             if button.text == self.defaultEnterButton then
      93.                 modalWindow:setDefaultEnterButton(i)
      94.             elseif button.text == self.defaultEscapeButton then
      95.                 modalWindow:setDefaultEscapeButton(i)
      96.             end
      97.         end
      98.     end
      99.  
      100.     for _, choice in ipairs(self.choices) do
      101.         modalWindow:addChoice(_, choice.text)
      102.         choice.id = _
      103.     end
      104.  
      105.     self.modalWindow = modalWindow
      106. end
      107.  
      108. function MT:sendToPlayer(player)
      109.     if not self.modalWindow then
      110.         self:create()
      111.     end
      112.  
      113.     player:registerEvent('ModalWindowHelper')
      114.     self.players[player:getId()] = true
      115.     return self.modalWindow:sendToPlayer(player)
      116. end
    • In data/creaturescripts/creaturescripts.xml
      Code (XML):
      1. <event type="modalwindow" name="ModalWindowHelper" script="modalwindowhelper.lua" />
    • Create the file data/creaturescripts/scripts/modalwindowhelper.lua
      Code (Lua):
      1. function onModalWindow(player, modalWindowId, buttonId, choiceId)
      2.     local modalWindow
      3.     for _, window in ipairs(modalWindows.windows) do
      4.         if window.id == modalWindowId then
      5.             modalWindow = window
      6.             break
      7.         end
      8.     end
      9.  
      10.     if not modalWindow then
      11.         return true
      12.     end
      13.  
      14.     local playerId = player:getId()
      15.     if not modalWindow.players[playerId] then
      16.         return true
      17.     end
      18.     modalWindow.players[playerId] = nil
      19.  
      20.     local choice = modalWindow.choices[choiceId]
      21.  
      22.     for _, button in ipairs(modalWindow.buttons) do
      23.         if button.id == buttonId then
      24.             local callback = button.callback or modalWindow.defaultCallback
      25.             if callback then
      26.                 callback(button, choice)
      27.                 break
      28.             end
      29.         end
      30.     end
      31.  
      32.     return true
      33. end
    The end

    That's it. Later today I will post a !rank talkaction I've made using this library.

    EDIT: Here it is.
     
    Last edited by a moderator: Jul 24, 2017
    grilo13, HeberPcL, Kuzyn and 5 others like this.
  2. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,348
    Best Answers:
    1
    so... what is the point of that verification?
     
  3. Non Sequitur

    Non Sequitur Member

    Joined:
    Dec 1, 2015
    Messages:
    84
    Likes Received:
    73
    Best Answers:
    0
    What verification?
     
  4. zbizu

    zbizu Retired

    Joined:
    Nov 22, 2010
    Messages:
    2,440
    Likes Received:
    1,348
    Best Answers:
    1
    print('Player selected the correct option.')
    else
    print('Player selected the incorrect option.')
     
  5. Non Sequitur

    Non Sequitur Member

    Joined:
    Dec 1, 2015
    Messages:
    84
    Likes Received:
    73
    Best Answers:
    0
    That is just a sample code, and it's on the button callback, so the player may choose the wrong option and choice.correct will be nil, not true.
     
  6. strutZ

    strutZ Australian OT Member {AKA Beastn}

    Joined:
    Nov 16, 2014
    Messages:
    1,283
    Likes Received:
    454
    Best Answers:
    4
    This is great now that i know how to use it lol question though how does one use
    Code (Text):
    1. getChoiceCount()
    Is there another way to use it?

    EDIT:
    Ran into another issue.. Converting my addon doll script, I am hiding already unlocked outfits/addons from the choices my command
    Code (Text):
    1. self:addOutfitAddon(outfits[choice.id].male, 3)
    is wrong because choice ID 1 will always being citizen... so when i unlock that and it hides the top addon changes to choice ID one so BAM! i get citizen again >.<
     
    Last edited: May 24, 2016
  7. BloodGauntlet

    BloodGauntlet Member

    Joined:
    Jul 27, 2016
    Messages:
    45
    Likes Received:
    16
    Best Answers:
    0
    Great contribution, going to help me along nicely.
     
  8. Colors

    Colors

    Joined:
    Mar 22, 2013
    Messages:
    909
    Likes Received:
    251
    Best Answers:
    0
    If I create a ModalWindow, but I don't use it for x reason, do I need to destroy the object to avoid memory leaks? Or it doesn't matter?
     
  9. adahum

    adahum New Member

    Joined:
    Feb 28, 2015
    Messages:
    13
    Likes Received:
    0
    Best Answers:
    0


    i did exactly what u say to do but for some reason, appears it when i start my server:

    [9:57:14.242] data/lib/modalwindow.lua:83: attempt to call field 'modalWindowConstructor' (a nil value)
    [9:57:14.242] [Warning - Event::loadScript] Cannot load script (data/talkactions/scripts/bests.lua)

    [9:57:14.285] [Error - CreatureEvent::configureEvent] No valid type for creature event.modalwindow
    [9:57:14.285] [Warning - BaseEvents::loadFromXml] Cannot configure an event




    i dont know how fix it. my server is 8.60
     
  10. Static_

    Static_ Well-Known Member

    Joined:
    Feb 14, 2015
    Messages:
    3,136
    Likes Received:
    1,356
    Best Answers:
    188
    you can't use modalwindows for 8.6, they were implemented in 9.6+
     
  11. adahum

    adahum New Member

    Joined:
    Feb 28, 2015
    Messages:
    13
    Likes Received:
    0
    Best Answers:
    0
    there's no one version to 8.60?nothing? :( thats so bad.
     
  12. Static_

    Static_ Well-Known Member

    Joined:
    Feb 14, 2015
    Messages:
    3,136
    Likes Received:
    1,356
    Best Answers:
    188
    that's what i just said

    you could use otclient but i have no idea how to implement modalwindows for it
    would probably just be easier to move to a higher client version
     
    adahum likes this.
  13. Dbzl

    Dbzl Member

    Joined:
    Jan 22, 2017
    Messages:
    39
    Likes Received:
    1
    Best Answers:
    0
    Can anyone help me with a problem using this lib?
    I will post the code below, but firstly, let me explain the problem:
    I'm creating a couple windows that are called from the main window.
    A few of these created windows, got own player's information.
    When a first player trigger this code, it runs with no problem. But when a second player tries to run, somehow the one that receives the window is the first player.
    It seems weird, right?
    Literally it's what happens.
    >first player uses the windows with no problems
    >first player closes every window and stay still
    >second player tries to open the main window
    >don't work on second player
    >check first player
    >the window was open there

    And not if it was the only problem, if you manage to log off from first player, when the second player tries to open the main window, the informations there are doubled.
    Anyway, you can always check this ingame to make things clear with the code below.
    By the way, I've only experienced this thing with Action codes. I've created a couple talkActions and never had any problem like that.

    If anyone knows how to fix this, pleaase, let me know!

    Code (Text):
    1.  
    2. local window = 0
    3. local window2v2 = 0
    4. local window2v2_info = 0
    5. local window3v3 = 0
    6. local window3v3_info = 0
    7.  
    8. function createWindows(player)
    9.     window = ModalWindow {
    10.        title = "Arena Window",
    11.        message = "Please choose the PVP mode below:"
    12.     }
    13.  
    14.     window2v2 = ModalWindow {
    15.        title = "2v2 Window",
    16.        message = "Please choose a 2v2 option below:"
    17.     }
    18.  
    19.     window3v3 = ModalWindow {
    20.        title = "3v3 Window",
    21.        message = "Please choose a 3v3 option below:"
    22.     }
    23.  
    24.     window2v2_info = ModalWindow {
    25.        title = "2v2 Player Info",
    26.        message = ""
    27.     }
    28.  
    29.     window3v3_info = ModalWindow {
    30.        title = "3v3 Player Info",
    31.        message = ""
    32.     }
    33.  
    34.     window:addChoice("2v2")
    35.     window:addChoice("3v3")
    36.  
    37.     window2v2:addChoice("Join 2v2 Queue")
    38.     window2v2:addChoice("Player Info")
    39.  
    40.     window3v3:addChoice("Join 3v3 Queue")
    41.     window3v3:addChoice("Player Info")
    42.  
    43.     window2v2_info.title = player:getName().. "'s info"
    44.     window2v2_info:addChoice("Total Games: 0")
    45.     window2v2_info:addChoice("Win Rate: 0%")
    46.     window2v2_info:addChoice("Elo Points: 0")
    47.     window2v2_info:addChoice("Total Medals: 0")
    48.  
    49.     window3v3_info.title = player:getName().. "'s info"
    50.     window3v3_info:addChoice("Total Games: 0")
    51.     window3v3_info:addChoice("Win Rate: 0%")
    52.     window3v3_info:addChoice("Elo Points: 0")
    53.     window3v3_info:addChoice("Total Medals: 0")
    54.  
    55.     -- Main Window
    56.     window:addButton("Select",
    57.        function(button, choice)
    58.             if choice.text == "2v2" then
    59.                 window2v2:sendToPlayer(player)
    60.             elseif choice.text == "3v3" then
    61.                 window3v3:sendToPlayer(player)
    62.            end
    63.        end
    64.     )
    65.     window:setDefaultEnterButton("Select")
    66.     window:addButton('Close')
    67.     window:setDefaultEscapeButton('Close')
    68.  
    69.     -- 2v2 Window
    70.     window2v2:addButton("Select",
    71.        function(button, choice)
    72.             if choice.text == "Join Queue" then
    73.             elseif choice.text == "Player Info" then
    74.                 window2v2_info:sendToPlayer(player)
    75.            end
    76.        end
    77.     )
    78.     window2v2:setDefaultEnterButton("Select")
    79.     window2v2:addButton('Ranking')
    80.     window2v2:addButton("Back",
    81.        function(button, choice)
    82.             window:sendToPlayer(player)
    83.        end
    84.     )
    85.     window2v2:setDefaultEscapeButton('Back')
    86.  
    87.     -- 3v3 Window
    88.     window3v3:addButton("Select",
    89.        function(button, choice)
    90.             if choice.text == "Join Queue" then
    91.             elseif choice.text == "Player Info" then
    92.                 window3v3_info:sendToPlayer(player)
    93.            end
    94.        end
    95.     )
    96.     window3v3:setDefaultEnterButton("Select")
    97.     window3v3:addButton("Ranking")
    98.     window3v3:addButton("Back",
    99.        function(button, choice)
    100.             window:sendToPlayer(player)
    101.        end
    102.     )
    103.     window3v3:setDefaultEscapeButton("Back")
    104.  
    105.     -- 2v2 Info Window
    106.     window2v2_info:addButton("Select",
    107.        function(button, choice)
    108.             window2v2_info:sendToPlayer(player)
    109.        end
    110.     )
    111.     window2v2_info:setDefaultEnterButton("Select")
    112.     window2v2_info:addButton("Back",
    113.        function(button, choice)
    114.             window2v2:sendToPlayer(player)
    115.        end
    116.     )
    117.     window2v2_info:setDefaultEscapeButton("Back")
    118.  
    119.     -- 3v3 Info Window
    120.     window3v3_info:addButton("Select",
    121.        function(button, choice)
    122.             window3v3_info:sendToPlayer(player)
    123.        end
    124.     )
    125.     window3v3_info:setDefaultEnterButton("Select")
    126.     window3v3_info:addButton("Back",
    127.        function(button, choice)
    128.             window3v3:sendToPlayer(player)
    129.        end
    130.     )
    131.     window3v3_info:setDefaultEscapeButton("Back")
    132.     return true
    133. end
    134.  
    135. function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    136.     createWindows(player)
    137.  
    138.     window:sendToPlayer(player)
    139.     return true
    140. end
    141.  
    142. [/CODE~
    143.  
    144. The code is totally weird, I was just trying to make it work firstly.
    145. Don't take it serious =p
     
  14. Dbzl

    Dbzl Member

    Joined:
    Jan 22, 2017
    Messages:
    39
    Likes Received:
    1
    Best Answers:
    0
    I messed up pretty bad the /CODE last part. If any mod can edit my post to fix this problem, Thanks.
    Also, please delete this one post after fixing the text error xD
     
  15. Dbzl

    Dbzl Member

    Joined:
    Jan 22, 2017
    Messages:
    39
    Likes Received:
    1
    Best Answers:
    0
    I've discovered that, if I reload actions after the first player finishes what he was doing in the window, the second player can normally open and use the window.
    But it requires a reload everytime the main window is closed. (when the script finishes, in this case)

    Anyone? x_x
     
  16. Evil Hero

    Evil Hero Legacy Member

    Joined:
    Dec 12, 2007
    Messages:
    1,086
    Likes Received:
    452
    Best Answers:
    0
    that's easily explained, you basicly have to keep a save for every different player on modal windows, it keeps showing first player only because you do only save that one
    here is a code snippet from my old ingame manager where it shows how you can do it.
    Code (Text):
    1.  
    2. if state[player:getId()] == nil then
    3.        state[player:getId()] = 1
    4.    end
    5.    --######Management######--
    6.    if modalWindowId == windows.Management then
    7.        state[player:getId()] = 1
    8.        if buttonId == 0x00 then
    9.            if choiceId == managementOptions.Player[1] then -- Players
    10.                state[player:getId()] = 1
    11.                if Game.getPlayerCount() > 0 then
    12.                    playerChoices = {}
    13.                    onlinePlayers = {}
    14.                    for k, v in pairs(getOnlinePlayers()) do
    15.                        table.insert(onlinePlayers, v)
    16.                    end
    17.                    table.sort(onlinePlayers)
    18.                    playerChoices = cacheData1(onlinePlayers, state[player:getId()])
    19.                    createWindowWithButtons(player, players, windows.Management_Players, "Players List", "Select Player", preButtons, playerChoices, true, false)
    20.                else
    21.                    createWindowWithButtons(player, management, windows.Management, "Management", "Ingame Administration Tool:\nCreated by Evil Hero @ otland", managementButtons, managementChoices, true, false)
    22.                end
    23.            elseif choiceId == managementOptions.NPC[1] then -- NPCs
    24.                if Game.getNpcCount() > 0 then
    25.                    npcChoices = {}
    26.                    onlineNpcs = {}
    27.                    npcButtons = {{id = 0x00, text = "Select", enter = false, escape = false}, {id = 0x01, text = "End", enter = false, escape = true}, {id = 0x02, text = "Back", enter = false, escape = false}, {id = 0x03, text = "TP", enter = true, escape = false}}
    28.                    for k, v in pairs(getOnlineNpcs()) do
    29.                        onlineNpcs[#onlineNpcs == nil and 1 or #onlineNpcs + 1] = {}
    30.                        onlineNpcs[#onlineNpcs][1] = v[1]
    31.                        onlineNpcs[#onlineNpcs][2] = v[2]
    32.                    end
    33.                    npcChoices = cacheData2(onlineNpcs, state[player:getId()])
    34.                    createWindowWithButtons(player, npcs, windows.Management_NPC, "NPC List", "Select NPC", npcButtons, npcChoices, true, false)
    35.                else
    36.                    createWindowWithButtons(player, management, windows.Management, "Management", "Ingame Administration Tool:\nCreated by Evil Hero @ otland", managementButtons, managementChoices, true, false)
    37.                end
    38.            elseif choiceId == managementOptions.Monster_Type[1] then -- Monsters
    39.                if Game.getMonsterCount() > 0 then
    40.                    monsterTypeChoices = {}
    41.                    monsterType = {}
    42.                    for k,v in pairs(monsters) do
    43.                        table.insert(monsterType, k)
    44.                    end
    45.                    table.sort(monsterType)
    46.                    monsterTypeChoices = cacheData1(monsterType, state[player:getId()])
    47.                    createWindowWithButtons(player, monsters1, windows.Management_Monster_Type, "Monster Type List", "Select Monster Type", preButtons, monsterTypeChoices, true, false)
    48.                else
    49.                    createWindowWithButtons(player, management, windows.Management, "Management", "Ingame Administration Tool:\nCreated by Evil Hero @ otland", managementButtons, managementChoices, true, false)
    50.                end
    51.            elseif choiceId == managementOptions.Tp_Players_To_Temple[1] then -- teleport all players to temple
    52.                local online = getOnlinePlayers()
    53.                local counter = 0
    54.                for k,v in pairs(online) do
    55.                    local tpPlayer = Player(v)
    56.                    if tpPlayer then
    57.                        doTeleportThing(tpPlayer, tpPlayer:getTown():getTemplePosition(), true)
    58.                        tpPlayer:sendTextMessage(22, "You have been teleported to temple")
    59.                        counter = counter + 1
    60.                    end
    61.                end
    62.                player:sendTextMessage(22, "You have successfully teleported ".. counter .."/".. #online .." players to temple")
    63.                createWindowWithButtons(player, management, windows.Management, "Management", "Ingame Administration Tool:\nCreated by Evil Hero @ otland", managementButtons, managementChoices, true, false)
    64.            end
    65.        end
    66.    end
    Code (Text):
    1. state[player:getId()]
    is what you should take a closer look on.
     
    Non Sequitur and Dbzl like this.
  17. Dbzl

    Dbzl Member

    Joined:
    Jan 22, 2017
    Messages:
    39
    Likes Received:
    1
    Best Answers:
    0
    Thank you very much for your help. As soon as I'm able to, I will read it and try changing my code!
     
  18. Dbzl

    Dbzl Member

    Joined:
    Jan 22, 2017
    Messages:
    39
    Likes Received:
    1
    Best Answers:
    0
    Thanks for the code.
    I kinda understood what was the point of my problem, but I don't know I understood how to exactly replicate.
    That's what I tried:

    Code (Text):
    1.  
    2. function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    3.     if player_modal_save[player:getId()] == nil then
    4.         player_modal_save[player:getId()] = {}
    5.     end
    6.  
    7.     player_modal_save[player:getId()].name = player:getName()
    8.  
    9.     createWindows(player)
    10.     window:sendToPlayer(player)
    11.     return true
    12. end
    13.  
    I created a table for each player that used the modal window. Then I inserted there some infos I would use from these players.
    Like name, some storages, etc.
    At first, it does work. But when both the players try to reload the window, here:

    Code (Text):
    1.  
    2.     window2v2_info:addButton("Select",
    3.        function(button, choice)
    4.             window2v2_info:sendToPlayer(player)
    5.        end
    6.     )
    7.  
    It updates with the other player's info (the one that opened the modal after he did)

    Then I tried updating inside the code above, every information, to check if it would remain with the own player's information, like that:

    Code (Text):
    1.  
    2.     window2v2_info:addButton("Select",
    3.        function(button, choice)
    4.             player_modal_save[player:getId()].name = player:getName()
    5.             window2v2_info:sendToPlayer(player)
    6.        end
    7.     )
    8.  
    But it didn't work.
    Have you got any idea what am I doing wrong? x_x
     
  19. Mkalo

    Mkalo ボーカロイド Support Team

    Joined:
    Jun 1, 2011
    Messages:
    1,118
    Likes Received:
    880
    Best Answers:
    53
    Firstly, when using this lib you shouldn't ever assume that the userdata will be in a valid state when the callback function get called, so you should never use any userdata upvalue inside the callback functions.

    Now to your problem, I couldn't really understand what you want exactly, can you tell exactly how the navigation between modal windows should work?
     
  20. Dbzl

    Dbzl Member

    Joined:
    Jan 22, 2017
    Messages:
    39
    Likes Received:
    1
    Best Answers:
    0
    Maybe it would be better to don't use this lib, then

    This modal window is supposed to have two functions: get inside a player queue or checking your own info.
    It would be something like that:
    If the player wants to simply join a queue, he will just select this first option and enter the queue.
    This should be easy, if there were not the problem I will describe below.
    [​IMG] (1)

    If the player wants to check it's info, he will receive this:
    [​IMG] (2)

    The main problem is the userdata is changed whenever a new player opens the modal window, for every player with it opened.
    If I have this window opened, like you can see at (2)
    And the character Test Character 1, opens it, it will update Gamemaster's info to Test Character 1's info.

    Evil Hero said, as you can see in his post, that I needed to keep a "save" for each player that uses the modal window.
    I've tried, actually, inserting the player's info inside a global table, where I would access it whenever I needed.
    But since the userdata gets replaced, it changes from every other windows opened.

    x_x
     

Share This Page

Loading...