diff --git a/Content/Luprex/lxUtilityMacroLibrary.uasset b/Content/Luprex/lxUtilityMacroLibrary.uasset index 0cb444c9..e2dad1bb 100644 --- a/Content/Luprex/lxUtilityMacroLibrary.uasset +++ b/Content/Luprex/lxUtilityMacroLibrary.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27482302100b9c4eeba1edc7374980d2ac77b52eb7d7f866eeb734e8255d6b1c -size 28966 +oid sha256:d0750bdcdc33b7bac7b0c98416655ee0ec26308ad835b6518d3a6dc00a847b01 +size 29530 diff --git a/Content/Luprex/lxWidgetMacroLibrary.uasset b/Content/Luprex/lxWidgetMacroLibrary.uasset index 4bf643f6..41b1a7b0 100644 --- a/Content/Luprex/lxWidgetMacroLibrary.uasset +++ b/Content/Luprex/lxWidgetMacroLibrary.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63f1f07b5ff207ab5f77eed372a6cd447e19b116d4889a447939b9ac0265ff40 -size 20802 +oid sha256:f9c4824122c5a04fab2aaeb5a7c7bae66b6cfb760c7b6acc846b9283a6471a09 +size 21089 diff --git a/Content/Widgets/WB_Console.uasset b/Content/Widgets/WB_Console.uasset index d55ec523..bc0f8628 100644 --- a/Content/Widgets/WB_Console.uasset +++ b/Content/Widgets/WB_Console.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31714d3863887a8681b7d27f8bd7b0bc58d3631416724409af2f6cf596418c1f -size 159474 +oid sha256:922737df4d08eed23042d52ace705eec39ec8db47b7a6c9e3781222b3e0dee0b +size 159257 diff --git a/Content/Widgets/WB_Hotkey_Action.uasset b/Content/Widgets/WB_Hotkey_Action.uasset index 00263b9f..96a118e4 100644 --- a/Content/Widgets/WB_Hotkey_Action.uasset +++ b/Content/Widgets/WB_Hotkey_Action.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6859be680d25da70d4efa4849db9d04586358e91c2f852eefb0f9851cd20a46 -size 48485 +oid sha256:41b59add5323a9707d5af4d771d1a66ad807e3660eac4b62f094bec15dfc4bef +size 48247 diff --git a/Content/Widgets/WB_Hotkeys.uasset b/Content/Widgets/WB_Hotkeys.uasset index 06904cbf..46c1dd76 100644 --- a/Content/Widgets/WB_Hotkeys.uasset +++ b/Content/Widgets/WB_Hotkeys.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1dc59d38be438ae97dffa9439b6ab436d187424403c97c2a86bbb46f7d974945 -size 319453 +oid sha256:2585183c86857cb4adff06a5aafdca74a454d0ef0f2c4b02dc9c1ad1b3b66b17 +size 312290 diff --git a/Content/Widgets/WB_Menu.uasset b/Content/Widgets/WB_Menu.uasset new file mode 100644 index 00000000..d58eb453 --- /dev/null +++ b/Content/Widgets/WB_Menu.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96cdc7748c45229bb09f179be195cabfe429c1bce6d1376f6bf2b65368fe3948 +size 259793 diff --git a/Content/Widgets/WB_Menu_Item.uasset b/Content/Widgets/WB_Menu_Item.uasset new file mode 100644 index 00000000..299d68be --- /dev/null +++ b/Content/Widgets/WB_Menu_Item.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d05c0fe160bba07ae62fa218b35285fe04ba8ad23f536157babc4748bb179c3 +size 58565 diff --git a/instructions.txt b/instructions.txt new file mode 100644 index 00000000..fdbba34b --- /dev/null +++ b/instructions.txt @@ -0,0 +1,55 @@ + +Currently, my demo game includes a hotkey system. You will use the +existing hotkey system as inspiration to build a menu system. + +In my lua code, I can create a class such as "sphere." Then +I can create an instance of that class and make it appear in +the world. + +I can also define a lua function "sphere.lookhotkeys" which adds +hotkeys to objects of class sphere. When I aim the crosshairs +at a sphere, a widget WB_Hotkeys appears, and it shows me the +hotkeys for spheres. + +I can then press one of those hotkeys. The WB_Hotkeys widget +handles the key event, displaying visual feedback, and it +also invokes a lua function which eventually leads to the +proper hotkey action being taken in lua. + +I want you to study this mechanism, learning exactly how this +process works. Then, I want you to implement a menu system +that operates on exactly the same principles. + +Currently, my demo game contains a sphere and a cube which +both have hotkeys. I want you to reprogram the cube +so that it has a menu instead of hotkeys. + +The menu system will require me to write a lua function +such as cube.lookmenu, which generates the contents of the +menu. When I point the crosshairs at a cube, the menu +widget WB_Menu will appear in minimized form. In minimized +form, the WB_Menu widget will just look like a little +circle or something. This is just enough of a clue to +the user that a menu is there to be activated. + +When the user clicks the left mouse button, WB_Menu will +switch to active form: it will display the menu and put +the mouse pointer on the first menu item. I can then +drag the mouse and select a menu item, or I can drag off +the menu to choose nothing. When I release the mouse +button, if the mouse is over a menu item, there's some +visual feedback, and the appropriate lua closure is +invoked. Then, the menu goes back to minimized state. + +You must implement all of this using a combination of lua +and blueprint-language. No C++. You can use the UE +Wingman plugin to edit blueprints. + +Along the way, it is possible that the UE Wingman plugin may +fail - it's still in beta. If so, please pause, notify me, +and you and I will work together to get things up and +running again. + + + + diff --git a/luprex/lua/login.lua b/luprex/lua/login.lua index 0857b939..47aa36ce 100644 --- a/luprex/lua/login.lua +++ b/luprex/lua/login.lua @@ -33,10 +33,10 @@ function moveto(x, y) tangible.animate{tan=actor, anim={action="moveto", xyz={x, y, z}, facing=math.auto}} end -function cube.lookhotkeys(add) - add("Z", "Cube Hi", function () dprint("Doing Cube Hi") end) - add("X", "Cube Bye", function () dprint("Doing Cube Bye") end) - add("C", "Cube Yo", function () dprint("Doing Cube Yo") end) +function cube.lookmenu(add) + add("Cube Hi", function () dprint("Doing Cube Hi") end) + add("Cube Bye", function () dprint("Doing Cube Bye") end) + add("Cube Yo", function () dprint("Doing Cube Yo") end) end function sphere.lookhotkeys(add) @@ -60,6 +60,12 @@ function engio.getlookat() return "hotkeys" end + -- if the class has a function 'lookmenu', then the correct + -- look-at widget is 'menu'. + if class.lookmenu ~= nil then + return "menu" + end + -- otherwise, if the class has a function 'getlookat', use that. if class.getlookat ~= nil then return class.getlookat() diff --git a/luprex/lua/menu.lua b/luprex/lua/menu.lua new file mode 100644 index 00000000..f5562aa1 --- /dev/null +++ b/luprex/lua/menu.lua @@ -0,0 +1,68 @@ +---------------------------------------------------------------- +-- +-- To add a menu to an object (such as a Brick Oven), you will +-- be adding a function 'lookmenu' to the appropriate class, +-- like this: +-- +-- function brickoven.lookmenu(add) +-- add("Light Oven", function () ... end) +-- add("Add Fuel", function () ... end) +-- end +-- +-- This function will get called twice: once in a 'probe' when +-- Unreal wants to know what menu items exist, and a second time +-- in an 'invoke' to find the right closure. The 'add' function +-- which is passed in can therefore be one of two functions. +-- +-- In probe mode, the goal is to build up an array that looks +-- like this: +-- +-- {"Light Oven", "Add Fuel"} +-- +-- So therefore, in probe mode, the 'add' function is a closure +-- that adds the label to the array. +-- +-- In invoke mode, the goal is to find the right closure. So +-- therefore, in invoke mode, the 'add' function is a closure +-- that compares the label to the menu item which was already +-- selected. If there's a match, it records the closure. +-- +---------------------------------------------------------------- + +makeclass('engio') + +function engio.getmenu() + local class = tangible.getclass(place) + + -- if the tangible doesn't have a 'lookmenu' function, do nothing + if class == nil or class.lookmenu == nil then + return {} + end + + local items = {} + local add = function(label, closure) + table.insert(items, label) + end + class.lookmenu(add) + return items +end + +function engio.pressmenu(label) + local class = tangible.getclass(place) + + -- if the tangible doesn't have a 'lookmenu' function, do nothing + if class == nil or class.lookmenu == nil then + return + end + + local result = nil + local add = function(lbl, closure) + if (lbl == label) then + result = closure + end + end + class.lookmenu(add) + if result ~= nil then + result() + end +end