simplifying mouse click handling with lua

  • #1, by vozerSunday, 16. February 2014, 17:03 7 years ago
    Hey.

    I´m trying to achieve click-system like runaway, but without having to always add all the actions for setting the cursor, mouse in,mouseout, etc. to an object.

    So im figuring, i could use conditions to dertermine, if an object is lookable, takeable or both. (For NPCs talkable)

    So i would have 2 conditions: look, take

    I would have a script loading at each scene, sth like that:

    if look exists and is "true" and take is false (or non existing)
    {
    on hover change cursor to look
    }

    if look and take exists and is "true"
    {
    on hover change cursor to look_take
    }

    if take exists and is "true" and look is "false" (or non existing)
    {
    on hover change cursor to take
    }

    if object, that is being hovered, is being right_clicked, execute action "rc" of object
    if object, that is being hovered, is being left_clicked, execute action "lc" of object

    then i just add actions lc and rc to the objects and tell them what to do.

    As i see it this would make it a lot easier, no?

    Problem is, i am a real noob in LUA and have no idea where to actually start.

    Maybe someone can tell me if this is b***shjit, that im thinking here or a walk in the good direction.

    And is it possible to say:

    if look and take exists and is "true" and mouse enters object-area?

    cheers

    Newbie

    35 Posts


  • #2, by vozerSunday, 16. February 2014, 17:37 7 years ago
    currently im up to this:


    local set_look_cursor = getObject("Scenes[temp].ObjectActions[set_look]")
    local set_take_cursor = getObject("Scenes[temp].ObjectActions[set_take]")
    local set_look_take_cursor = getObject("Scenes[temp].ObjectActions[set_look_take]")

    -- * adds +1 to the total count value * --
    function check()
    conds = {} -- create a blank table called "conds" ...
    conds['_temporary_'] = '' -- sets table to temporary; in other words: no data is stored in VS save games!
    conds[1] = getObject('Conditions[look?]'):getBool(VConditionValue) -- check condition of "look?"
    conds[2] = getObject('Conditions[take?]'):getBool(VConditionValue) -- check condition of "take?"

    if conds[1] and not conds[2] then
    startAction(set_look_cursor)

    if conds[2] and not conds[1] then
    startAction(set_take_cursor)

    if conds[1] and conds[2] then
    startAction(set_look_take_cursor)

    else

    end
    end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26


    in the action set_look i would do:

    on mousein set cursor look, set action(befehl on german) look

    later i would just set at the object itself: "if action take is done on object, then give text"

    the logical problem i´m having in my head is:

    1) how to tell the action to listen to the mouse_in of the object hovered at and not the one i have in my temp-scene?


    Newbie

    35 Posts

  • #3, by afrlmeSunday, 16. February 2014, 18:17 7 years ago
    I actually wrote a global control script for Thomas (marvel) recently for the directors cut of Zak McKracken 2, for a coin interface in which we have it on mouse over an object get all actions associated with the object to determine which actions of the ring interface should be active.

    Yeah sure it's potentially possible to use Lua & the mouseEvent handler instead of creating cursor enter actions for each object.

    You would use the mouse move listener & then on mouse move you would query if an object exists underneath the cursor which you could then add some queries & code inside to determine what to do.

    here is the script I created for Zak 2... it's not what you are after but you can see how I created a global function with hardly any lines of code.
    --[[
    Globally check what commands for object, character or items are available (v5)
    Written by AFRLme
    -- * --
    label@alternatingfrequencies.com | aim, skype, trillian @ AFRLme
    --]]

    -- * let's create some local variables & tables to store some init stuff * --
    local tblCond = {"ziehe", "benutze", "gib", "schau_an", "rede_mit", "oeffne", "nimm", "druecke", "schliesse"} -- add command/condition names here (should both have same name)
    --local prefix = "_tasche_de"

    -- * let's create the function which will determine what type of object is currently underneath the mouse cursor * --
    function checkObjCmd()
    tblObj = {} -- create an empty table
    tblObj["_temporary_"] = "" -- set the table to temporary
    tblObj["cmd"] = game:getLink(VGameSavedObject) -- store the object underneath the cursor

    print(tblObj["cmd"]) -- print the objects name & table id numbers
    if tblObj["cmd"]:getId().tableId == eCharacters then tblObj["cmd"] = tblObj["cmd"]:getLinks(VCharacterActions) else tblObj["cmd"] = tblObj["cmd"]:getLinks(VObjectActions) end
    for i=1, table.maxn(tblObj["cmd"]) do getCmdCond(i) end -- for each command listed in the table check if condition exists...
    end

    -- * let's create the function which determines if command equals one of the stored conditions & check if condition is true or not * --
    function getCmdCond(val)
    --print(tblObj["cmd"][val]:getName()) -- prints out all of the commands for the object/character
    for i=1, table.maxn(tblCond) do
    if tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' executed" or tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' angewandt" or tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' executed (immediate)" or tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' angewandt (sofort)" then if not getObject("Conditions[" .. tblCond[i] .. "_cond]"):getBool(VConditionValue) then getObject("Conditions[" .. tblCond[i] .. "_cond]"):setValue(VConditionValue, true) end end

    end
    end

    -- * let's create the condition for on mouse out which checks which conditions are true & resets them back to false * --
    function resetCmdCond()
    for i=1, table.maxn(tblCond) do
    --print(tblCond[i] .. " before = ", getObject("Conditions[" .. tblCond[i] .. "_cond]"):getBool(VConditionValue) )
    if getObject("Conditions[" .. tblCond[i] .."_cond]"):getBool(VConditionValue) ~= false then getObject("Conditions[" .. tblCond[i] .. "_cond]"):setValue(VConditionValue, false) end
    --print(tblCond[i] .. " after = ", getObject("Conditions[" .. tblCond[i] .. "_cond]"):getBool(VConditionValue) )
    end
    end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40

    I could look into it when I have some free time... maybe.

    P.S: you must close any if queries with the same amount of end. functions & loops must also be closed with an end.

    examples:
    function func_name()
    -- some code
    end

    if cond then
    -- do something
    else
    -- do something else
    end

    if cond then
    if cond2 then
    -- do something
    end
    end

    if cond then
    -- do something
    elseif cond2 then
    -- do something else
    elseif cond 3 then
    -- do something else
    end

    if cond and not cond2 or cond == true and cond2 == false then
    -- do something
    end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    P.P.S: you would be better off considering using values instead of conditions as you can create infinite values in a single value as opposed to true/false in a single condition.
    P.P.P.S: start/stopAction can be done like you did (I think) or like so...
    startAction("Actions[action_name]")
    1
    2

    Imperator

    6842 Posts

  • #4, by vozerSunday, 16. February 2014, 19:12 7 years ago
    wow, thx. that helps.

    so just to break this code down for myself:

    -- * let's create the function which determines if command equals one of the stored conditions & check if condition is true or not * --
    function getCmdCond(val)
    --print(tblObj["cmd"][val]:getName()) -- prints out all of the commands for the object/character
    for i=1, table.maxn(tblCond) do
    if tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' executed"
    or tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' angewandt"
    or tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' executed (immediate)"
    or tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' angewandt (sofort)"

    then if not getObject("Conditions[" .. tblCond[i] .. "_cond]"):getBool(VConditionValue)
    then getObject("Conditions[" .. tblCond[i] .. "_cond]"):setValue(VConditionValue, true)
    end end

    end
    end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16


    this checks if the condition exists and if it exists and the cond is not true it sets its value to true.
    so, if i give an object the cond "execute" (doesnt matter if true or false), it sets it to true. Nothing more than a security feature, in case i havent set the conditions with the right value.
    meaning if i dont want there to be "execute", then i dont make an condition execute from the beginning.
    right?

    So my

    to check if an object is underneath and perform action i could do:

    if game:getLink(VGameSavedObject) = true (or 1?)

    do checkObjCmd()
    do get_if_look()
    end

    if game:getLink(VGameSavedObject) = false (or 0?)

    do resetObjCmd()
    end

    function get_if_look(val)
    --print(tblObj["cmd"][val]:getName()) -- prints out all of the commands for the object/character
    for i=1, table.maxn(tblCond) do
    if tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' look" and not tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' take"
    then startAction(getObject('Scenes[' .. csname .. '].SceneActions[' .. actname .. ']')

    elseif tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' look" and tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' take"
    then startAction(getObject('Scenes[' .. csname .. '].SceneActions[' .. actname .. ']')

    elseif tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' take" and not tblObj["cmd"][val]:getName() == "'" .. tblCond[i] .. "' take"
    then startAction(getObject('Scenes[' .. csname .. '].SceneActions[' .. actname .. ']')

    end


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27


    Would this work?

    and why would i use print? I see print as an command to display sth on screen, is it different here?

    Newbie

    35 Posts

  • #5, by afrlmeSunday, 16. February 2014, 20:22 7 years ago
    no... hehe.

    I think you should look into the basic fundamentals of Lua Scripting & the data structure entries & player commands & examples on the wiki first before you try to tackle this.

    I would class both my script & what you are wanting to do as an advanced script on the sticky topics page of the forum wiki (via menu above)

    -- * --
    there's no need to add do before calling/executing a function, you simply type the function name.
    -- * the function * --
    function func()
    if i < 10 then i = i +1 end
    end

    -- * execute/call the function * --
    func()
    1
    2
    3
    4
    5
    6
    7
    8

    here's an example of a function containing a variable
    i = 0

    function func(c)
    -- if true & i equals less than 10 then do...
    if c and i < 10 then i = i + 1
    -- if not true & i equals more than 0 then do...
    elseif not c and i > 0 then i = i - 1 end
    print("the value of i = " .. i) -- print a message to the log showing the updated value...
    end

    func(true) -- calls function with c = true (increment)

    func(false) -- calls function with c = false (decrement)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    after an if or elseif there is always a then.
    if cond then
    -- do something
    end
    1
    2
    3
    4

    do, is mostly used in loops.
    for i = 1, 10 do
    -- something
    end

    while cond do
    -- do something
    end
    1
    2
    3
    4
    5
    6
    7
    8

    etc...

    print just prints a message to the messages.txt log file - it's useful for debug purposes while you are writing scripts. you can also view the log via the console panel while running your game via the vs editor by pressing TAB & typing in [print log.

    oh er, almost forgot... here is a wiki page I started in regards to the basics of Lua scripting. It covers the basic operators with examples & screenshots. http://wiki.visionaire-tracker.net/wiki/Basic_lua

    Imperator

    6842 Posts

  • #6, by vozerSunday, 16. February 2014, 20:32 7 years ago
    perfect, thx! will get into it.

    i dont know, but i dont really get along with the wiki, he doesnt find anything, especially because there are 2 wikis?

    also tried to read on lua.org, but almost nothing there is useable for visionaire as i see it.

    cheers

    Newbie

    35 Posts

  • #7, by afrlmeSunday, 16. February 2014, 21:25 7 years ago
    official lua website is usable but it's not the easiest website to understand; especially the examples.

    yeah no idea why we need 2 wikis either. the one linked above is for the forum & the other one is one me & David installed to his server which we added a bug tracker cms to; yet no longer use!

    Media Wiki software has a lot more features than the forum wiki which is why we are using it for the official documentation.

    Imperator

    6842 Posts

Write post