Select the types of activity you want to include in your feed.
[READ-ONLY] Mirror of https://github.com/thoda-dev/du-lua-framework. A framework to simplify coding in Dual Universe. Permit to create most of the code in Unit > onStart
···11# du-lua-framework
22- A framework to simplidy coding in Dual Universe. Permit to add create most of the code in Unit > onStart
22+ A framework to simplidy coding in Dual Universe.
33+44+ Permit to add create most of the code in Unit > onStart
55+66+# Guilded Server (better than Discord)
77+88+You can join me on Guilded for help or suggestions or requests by following that link : https://guilded.jericho.dev
99+1010+1111+# Support or donation
1212+1313+if you like it, [<img src="https://github.com/Jericho1060/DU-Industry-HUD/blob/main/ressources/images/ko-fi.png?raw=true" width="150">](https://ko-fi.com/jericho1060) or you can sponsor me directly on [Github](https://github.com/sponsors/Jericho1060)
1414+1515+# Documentation and examples
1616+1717+## How to use it
1818+1919+Copy the content of the file [`config.json`](https://raw.githubusercontent.com/Jericho1060/du-lua-framework/main/config.json) and paste it on any control unit by right clicking on it and selecting "Advanced" and then "Paste Lua Configuration from clipboard".
2020+2121+*Warning 1: It can happens that the paste is not working in DU, it'f it's your case, please, restart the game and try again.*
2222+2323+*Warning 2: Paste may not work in GeForce Now, please install it from a real PC or ask someone else to install it for you.*
2424+2525+## Major Changes compared to the game logic
2626+2727+System onUpdate and onFlush events are now builded with coroutines, in the framework, onUpdate and onFlush are loading a table of functions that will be runned as coroutines. This way you can have multiple functions running at the same time, and you use the yield function to pause the coroutine and let the other coroutines run. Each coroutine will be resume or restarted if dead each time the system onUpdate or onFlush event is called.
2828+2929+## Code Examples
3030+3131+```lua
3232+--Functions to load as coroutines that will be runned in system > onUpdate (based on FPS)
3333+local system_update = {}
3434+system_update.co1 = function ()
3535+ for i=0, 10 do
3636+ system.print("coroutine 1 --- update --- "..i)
3737+ coroutine.yield() -- pause the coroutine 1, it will wait till the next onUpdate event to be resumed
3838+ end
3939+end
4040+system_update.co2 = function ()
4141+ for i=0, 10 do
4242+ system.print("coroutine 2 --- update --- "..i)
4343+ coroutine.yield() -- pause the coroutine 2, it will wait till the next onUpdate event to be resumed
4444+ end
4545+end
4646+4747+--Functions to load as coroutines that will be runned in system > onFlush (60 times / s)
4848+local system_flush = {}
4949+system_flush.co1 = function ()
5050+ for i=0, 10 do
5151+ system.print("coroutine 1 --- flush --- "..i)
5252+ coroutine.yield() -- pause the coroutine 1, it will wait till the next onFlush event to be resumed
5353+ end
5454+end
5555+system_flush.co2 = function ()
5656+ for i=0, 10 do
5757+ system.print("coroutine 2 --- flush --- "..i)
5858+ coroutine.yield() -- pause the coroutine 2, it will wait till the next onFlush event to be resumed
5959+ end
6060+end
6161+6262+--Function to run on actions
6363+local system_action_start = {}
6464+system_action_start[Script.system.ACTIONS.BRAKE] = function()
6565+ system.print("I'm braking");
6666+end
6767+local system_action_stop = {}
6868+system_action_stop[Script.system.ACTIONS.BRAKE] = function()
6969+ system.print("I stopped braking");
7070+end
7171+local system_action_loop = {}
7272+system_action_loop[Script.system.ACTIONS.BRAKE] = function()
7373+ system.print("I'm still braking");
7474+end
7575+7676+--Function to run when input text to the lua chat
7777+local system_inputText = function (text)
7878+ system.print("Input: " .. text)
7979+end
8080+8181+--Function to run when the program is stopping
8282+local unit_onstop = function ()
8383+ system.print("Program is stopping")
8484+end
8585+8686+--Function to run when the player change parent
8787+local player_onparentchanged = function (oldParent, newParent)
8888+ system.print("Player changed parent from ID "..oldParent.." to ID "..newParent)
8989+end
9090+9191+--Function to run when the construct is docked or undocked
9292+local construct_onDocked = function(id)
9393+ system.print("Construct docked on ID "..id)
9494+end
9595+local construct_onUndocked = function(id)
9696+ system.print("Construct undocked from ID "..id)
9797+end
9898+9999+--Function to run when a player board the construct
100100+local construct_onplayerboarded = function(id)
101101+ system.print("Player with ID " .. id .. " boarded construct")
102102+end
103103+104104+--Function to run when a player enter the VR Station
105105+local construct_vrstationentered = function(id)
106106+ system.print("Player with ID " .. id .. " entered VR Station")
107107+end
108108+109109+--Function to run when another construct is docked on this construct
110110+local construct_constructdocked = function(id)
111111+ system.print("Construct with ID " .. id .. " docked on this construct")
112112+end
113113+114114+--Function to run when pvp timer is changing state
115115+local construct_onpvptimer = function(active)
116116+ if active then
117117+ system.print("PVP is now active")
118118+ else
119119+ system.print("PVP is now inactive")
120120+ end
121121+end
122122+123123+--[[
124124+ Here how to load the functions in the framework
125125+]]
126126+Script.system:onUpdate(system_update) --loading coroutines for system > onUpdate
127127+Script.system:onFlush(system_flush) --loading coroutines for system > onFlush
128128+129129+Script.system:onActionStart(system_action_start) --loading all "actionStart" functions
130130+Script.system:onActionStop(system_action_stop) --loading all "actionStop" functions
131131+Script.system:onActionLoop(system_action_loop) --loading all "actionLoop" functions
132132+133133+Script.system:onInputText(system_inputText) --loading the function to trigger when input text in lua chat
134134+135135+--[[
136136+ Here how to add a timer
137137+ @param name: the name of the timer, used to remove it with Script.unit:stopTimer(name)
138138+ @param delay: the delay between each call of the function in seconds
139139+ @param func: the function to call
140140+]]
141141+Script.unit:setTimer("hello", 1, function()system.print("hello")end) --add a timer displaying "hello" every seconds
142142+Script.unit:setTimer("hello5", 5, function()system.print("hello 5")end) --add a timer displaying "hello 5" every 5 seconds
143143+Script.unit:onStop(unit_onstop) --loading the function to trigger when the program is stopping
144144+145145+Script.player:onParentChanged(player_onparentchanged) --loading the function to trigger when the player change parent
146146+147147+Script.construct:onDocked(construct_onDocked) --loading the function to trigger when the construct is docked
148148+Script.construct:onUndocked(construct_onUndocked) --loading the function to trigger when the construct is undocked
149149+Script.construct:onPlayerBoarded(construct_onplayerboarded) --loading the function to trigger when a player board the construct
150150+Script.construct:onVRStationEntered(construct_vrstationentered) --loading the function to trigger when a player enter the VR Station
151151+Script.construct:onConstructDocked(construct_constructdocked) --loading the function to trigger when another construct is docked on this construct
152152+Script.construct:onPvPTimer(construct_onpvptimer) --loading the function to trigger when pvp timer is changing state
153153+```
154154+155155+## System Actions:
156156+157157+to use with `Script.system.ACTIONS[ActionKey]`
158158+159159+```lua
160160+FORWARD = "forward",
161161+BACKWARD = "backward",
162162+YAW_LEFT = "yawleft",
163163+YAW_RIGHT = "yawright",
164164+STRAFE_LEFT = "strafeleft",
165165+STRAFE_RIGHT = "straferight",
166166+LEFT = "left",
167167+RIGHT = "right",
168168+UP = "up",
169169+DOWN = "down",
170170+GROUND_ALTITUDE_UP = "groundaltitudeup",
171171+GROUND_ALTITUDE_DOWN = "groundaltitudedown",
172172+LEFT_ALT = "lalt",
173173+LEFT_SHIFT = "lshift",
174174+GEAR = "gear",
175175+LIGHT = "light",
176176+BRAKE = "brake",
177177+OPTION_1 = "option1",
178178+OPTION_2 = "option2",
179179+OPTION_3 = "option3",
180180+OPTION_4 = "option4",
181181+OPTION_5 = "option5",
182182+OPTION_6 = "option6",
183183+OPTION_7 = "option7",
184184+OPTION_8 = "option8",
185185+OPTION_9 = "option9",
186186+LEFT_MOUSE = "leftmouse",
187187+STOP_ENGINES = "stopengines",
188188+SPEED_UP = "speedup",
189189+SPEED_DOWN = "speeddown",
190190+ANTIGRAVITY = "antigravity",
191191+BOOSTER = "booster"
192192+```
+1
config.json
···11+{"events":[],"handlers":[{"code":"Script.system:update()","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"10"},{"code":"Script.system:inputText(text)","filter":{"args":[{"variable":"*"}],"signature":"onInputText(text)","slotKey":"-4"},"key":"11"},{"code":"Script.system:flush()","filter":{"args":[],"signature":"onFlush()","slotKey":"-4"},"key":"12"},{"code":"Script.system:actionStop(action)","filter":{"args":[{"variable":"*"}],"signature":"onActionStop(action)","slotKey":"-4"},"key":"13"},{"code":"Script.system:actionStart(action)","filter":{"args":[{"variable":"*"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"14"},{"code":"Script.system:actionLoop(action)","filter":{"args":[{"variable":"*"}],"signature":"onActionLoop(action)","slotKey":"-4"},"key":"15"},{"code":"Script.player:parentChanged(oldId, newId)","filter":{"args":[{"variable":"*"},{"variable":"*"}],"signature":"onParentChanged(oldId,newId)","slotKey":"-3"},"key":"3"},{"code":"Script.construct:VRStationEntered(id)","filter":{"args":[{"variable":"*"}],"signature":"onVRStationEntered(id)","slotKey":"-2"},"key":"6"},{"code":"Script.construct:undocked(id)","filter":{"args":[{"variable":"*"}],"signature":"onUndocked(id)","slotKey":"-2"},"key":"8"},{"code":"Script.construct:PvPTimer(active)","filter":{"args":[{"variable":"*"}],"signature":"onPvPTimer(active)","slotKey":"-2"},"key":"4"},{"code":"Script.construct:playerBoarded(id)","filter":{"args":[{"variable":"*"}],"signature":"onPlayerBoarded(id)","slotKey":"-2"},"key":"7"},{"code":"","filter":{"args":[{"variable":"*"}],"signature":"onDocked(id)","slotKey":"-2"},"key":"9"},{"code":"Script.construct:constructDocked(id)","filter":{"args":[{"variable":"*"}],"signature":"onConstructDocked(id)","slotKey":"-2"},"key":"5"},{"code":"Script.unit:timer(tag)","filter":{"args":[{"variable":"*"}],"signature":"onTimer(tag)","slotKey":"-1"},"key":"1"},{"code":"Script.unit:stop()","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"2"},{"code":"--[[\n DU-LUA-Framework by Jericho\n Permit to code easier by grouping most of the code in a single event Unit > Start\n Unminified Source available here: https://github.com/Jericho1060/du-lua-framework\n]]--\nlocal a=system.print;local b=error;local c=pcall;local d=assert;local e=coroutine;local f=e.create;local g=e.status;local h=e.resume;local i=\"dead\"local j=\"suspended\"function runFunction(k,l,...)local m,n=c(k,...)if not m then b(l..n)end end;local o={__index={cos={update={},flush={}},fns={update={},flush={},action={start={},stop={},loop={}},inputText=nil,start=nil,stop=nil},ACTIONS={FORWARD=\"forward\",BACKWARD=\"backward\",YAW_LEFT=\"yawleft\",YAW_RIGHT=\"yawright\",STRAFE_LEFT=\"strafeleft\",STRAFE_RIGHT=\"straferight\",LEFT=\"left\",RIGHT=\"right\",UP=\"up\",DOWN=\"down\",GROUND_ALTITUDE_UP=\"groundaltitudeup\",GROUND_ALTITUDE_DOWN=\"groundaltitudedown\",LEFT_ALT=\"lalt\",LEFT_SHIFT=\"lshift\",GEAR=\"gear\",LIGHT=\"light\",BRAKE=\"brake\",OPTION_1=\"option1\",OPTION_2=\"option2\",OPTION_3=\"option3\",OPTION_4=\"option4\",OPTION_5=\"option5\",OPTION_6=\"option6\",OPTION_7=\"option7\",OPTION_8=\"option8\",OPTION_9=\"option9\",LEFT_MOUSE=\"leftmouse\",STOP_ENGINES=\"stopengines\",SPEED_UP=\"speedup\",SPEED_DOWN=\"speeddown\",ANTIGRAVITY=\"antigravity\",BOOSTER=\"booster\"},main={update=f(function()end),flush=f(function()end)},update=function(self)local p=g(self.main.update)if p==i then self.main.update=f(function()self:runUpdate()end)elseif p==j then d(h(self.main.update))end end,flush=function(self)local p=g(self.main.flush)if p==i then self.main.flush=f(function()self:runFlush()end)elseif p==j then d(h(self.main.flush))end end,action=function(self,q,r)if self.fns.action[q][r]then runFunction(self.fns.action[q][r],\"System Action \"..q..\" Error: \")end end,actionStart=function(self,r)self:action('start',r)end,actionStop=function(self,r)self:action('stop',r)end,actionLoop=function(self,r)self:action('loop',r)end,inputText=function(self,s)if self.fns.inputText then runFunction(self.fns.inputText,\"System Input Text Error: \",s)end end,runUpdate=function(self)for t,u in pairs(self.cos.update)do local m=g(u)if m==i then self.cos.update[t]=f(self.fns.update[t])elseif m==j then d(h(u))end end end,runFlush=function(self)for t,u in pairs(self.cos.flush)do local m=g(u)if m==i then self.cos.flush[t]=f(self.fns.flush[t])elseif m==j then d(h(u))end end end,onUpdate=function(self,v)for t,w in pairs(v)do self.fns.update[t]=w;self.cos.update[t]=f(w)end end,onFlush=function(self,v)for t,w in pairs(v)do self.fns.flush[t]=w;self.cos.flush[t]=f(w)end end,onAction=function(self,q,v)for t,w in pairs(v)do self.fns.action[q][t]=w end end,onActionStart=function(self,v)self:onAction(\"start\",v)end,onActionStop=function(self,v)self:onAction(\"stop\",v)end,onActionLoop=function(self,v)self:onAction(\"loop\",v)end,onInputText=function(self,k)self.fns.inputText=k end}}local x={__index={timers={},stopFn=function()end,timer=function(self,y)if self.timers[y]then runFunction(self.timers[y],\"Unit Timer \"..y..\" Error: \")end end,setTimer=function(self,y,z,k)self.timers[y]=k;unit.setTimer(y,z)end,stopTimer=function(self,y)unit.stopTimer(y)self.timers[y]=nil end,onStop=function(self,k)self.stopFn=k end,stop=function(self)if self.stopFn then runFunction(self.stopFn,\"Unit Stop Error: \")end end}}local A={__index={parentChangedFn=function(B,C)end,onParentChange=function(self,k)self.parentChangedFn=k end,parentChanged=function(self,B,C)if self.parentChangedFn then runFunction(self.parentChangedFn,\"Player Parent Changed Error: \",B,C)end end}}local D={__index={dockedFn=function(E)end,onDocked=function(self,k)self.dockedFn=k end,docked=function(self,E)if self.dockedFn then runFunction(self.dockedFn,\"Construct Docked Error: \",E)end end,undockedFn=function(E)end,onUndocked=function(self,k)self.undockedFn=k end,undocked=function(self,E)if self.undockedFn then runFunction(self.undockedFn,\"Construct Undocked Error: \",E)end end,playerBoardedFn=function(E)end,onPlayerBoarded=function(self,k)self.playerBoardedFn=k end,playerBoarded=function(self,E)if self.playerBoardedFn then runFunction(self.playerBoardedFn,\"Construct Player Boarded Error: \",E)end end,VRStationEnteredFn=function(E)end,onVRStationEntered=function(self,k)self.VRStationEnteredFn=k end,VRStationEntered=function(self,E)if self.VRStationEnteredFn then runFunction(self.VRStationEnteredFn,\"Construct VR Station Entered Error: \",E)end end,constructDockedFn=function(E)end,onConstructDocked=function(self,k)self.constructDockedFn=k end,constructDocked=function(self,E)if self.constructDockedFn then runFunction(self.constructDockedFn,\"Construct Construct Docked Error: \",E)end end,PvPTimerFn=function(F)end,onPvPTimer=function(self,k)self.PvPTimerFn=k end,PvPTimer=function(self,F)if self.PvPTimerFn then runFunction(self.PvPTimerFn,\"Construct PvP Timer Error: \",F)end end}}DU_Framework={__index={system=setmetatable({},o),unit=setmetatable({},x),player=setmetatable({},A),construct=setmetatable({},D)}}\n\nScript = {}\nsetmetatable(Script, DU_Framework)\n\n\n--[[\n You can declare here all the functions you want to call in the diffent events from system, unit, player and construct.\n Major changes compared to the base game concept:\n - System onUpdate and onFlush events are now builded with coroutines, in the framework, onUpdate and onFlush are loading a table of functions that will be runned as coroutines. This way you can have multiple functions running at the same time, and you use the yield function to pause the coroutine and let the other coroutines run. Each coroutine will be resume or restarted if dead each time the system onUpdate or onFlush event is called.\n\n]]\n\n--Functions to load as coroutines that will be runned in system > onUpdate (based on FPS)\nlocal system_update = {}\nsystem_update.co1 = function ()\n for i=0, 10 do\n system.print(\"coroutine 1 --- update --- \"..i)\n coroutine.yield() -- pause the coroutine 1, it will wait till the next onUpdate event to be resumed\n end\nend\nsystem_update.co2 = function ()\n for i=0, 10 do\n system.print(\"coroutine 2 --- update --- \"..i)\n coroutine.yield() -- pause the coroutine 2, it will wait till the next onUpdate event to be resumed\n end\nend\n\n--Functions to load as coroutines that will be runned in system > onFlush (60 times / s)\nlocal system_flush = {}\nsystem_flush.co1 = function ()\n for i=0, 10 do\n system.print(\"coroutine 1 --- flush --- \"..i)\n coroutine.yield() -- pause the coroutine 1, it will wait till the next onFlush event to be resumed\n end\nend\nsystem_flush.co2 = function ()\n for i=0, 10 do\n system.print(\"coroutine 2 --- flush --- \"..i)\n coroutine.yield() -- pause the coroutine 2, it will wait till the next onFlush event to be resumed\n end\nend\n\n--Function to run on actions\nlocal system_action_start = {}\nsystem_action_start[Script.system.ACTIONS.BRAKE] = function()\n system.print(\"I'm braking\");\nend\nlocal system_action_stop = {}\nsystem_action_stop[Script.system.ACTIONS.BRAKE] = function()\n system.print(\"I stopped braking\");\nend\nlocal system_action_loop = {}\nsystem_action_loop[Script.system.ACTIONS.BRAKE] = function()\n system.print(\"I'm still braking\");\nend\n\n--Function to run when input text to the lua chat\nlocal system_inputText = function (text)\n system.print(\"Input: \" .. text)\nend\n\n--Function to run when the program is stopping\nlocal unit_onstop = function ()\n system.print(\"Program is stopping\")\nend\n\n--Function to run when the player change parent\nlocal player_onparentchanged = function (oldParent, newParent)\n system.print(\"Player changed parent from ID \"..oldParent..\" to ID \"..newParent)\nend\n\n--Function to run when the construct is docked or undocked\nlocal construct_onDocked = function(id)\n system.print(\"Construct docked on ID \"..id)\nend\nlocal construct_onUndocked = function(id)\n system.print(\"Construct undocked from ID \"..id)\nend\n\n--Function to run when a player board the construct\nlocal construct_onplayerboarded = function(id)\n system.print(\"Player with ID \" .. id .. \" boarded construct\")\nend\n\n--Function to run when a player enter the VR Station\nlocal construct_vrstationentered = function(id)\n system.print(\"Player with ID \" .. id .. \" entered VR Station\")\nend\n\n--Function to run when another construct is docked on this construct\nlocal construct_constructdocked = function(id)\n system.print(\"Construct with ID \" .. id .. \" docked on this construct\")\nend\n\n--Function to run when pvp timer is changing state\nlocal construct_onpvptimer = function(active)\n if active then\n system.print(\"PVP is now active\")\n else\n system.print(\"PVP is now inactive\")\n end\nend\n\n--[[\n Here how to load the functions in the framework\n]]\nScript.system:onUpdate(system_update) --loading coroutines for system > onUpdate\nScript.system:onFlush(system_flush) --loading coroutines for system > onFlush\n\nScript.system:onActionStart(system_action_start) --loading all \"actionStart\" functions\nScript.system:onActionStop(system_action_stop) --loading all \"actionStop\" functions\nScript.system:onActionLoop(system_action_loop) --loading all \"actionLoop\" functions\n\nScript.system:onInputText(system_inputText) --loading the function to trigger when input text in lua chat\n\nScript.unit:setTimer(\"hello\", 1, function()system.print(\"hello\")end) --add a timer displaying \"hello\" every seconds\nScript.unit:setTimer(\"hello5\", 5, function()system.print(\"hello 5\")end) --add a timer displaying \"hello 5\" every 5 seconds\nScript.unit:onStop(unit_onstop) --loading the function to trigger when the program is stopping\n\nScript.player:onParentChanged(player_onparentchanged) --loading the function to trigger when the player change parent\n\nScript.construct:onDocked(construct_onDocked) --loading the function to trigger when the construct is docked\nScript.construct:onUndocked(construct_onUndocked) --loading the function to trigger when the construct is undocked\nScript.construct:onPlayerBoarded(construct_onplayerboarded) --loading the function to trigger when a player board the construct\nScript.construct:onVRStationEntered(construct_vrstationentered) --loading the function to trigger when a player enter the VR Station\nScript.construct:onConstructDocked(construct_constructdocked) --loading the function to trigger when another construct is docked on this construct\nScript.construct:onPvPTimer(construct_onpvptimer) --loading the function to trigger when pvp timer is changing state","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"0"}],"methods":[],"slots":{"0":{"name":"slot1","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}}}}
···11+--[[
22+ DU-Nested-Coroutines by Jericho
33+ Permit to easier avoid CPU Load Errors by using nested coroutines and adapt cycles on the FPS
44+ Source unminified available here: https://github.com/Jericho1060/du-nested-coroutines
55+]]--
66+77+local print = system.print
88+local n_error = error
99+local n_pcall = pcall
1010+local n_assert = assert
1111+local cor = coroutine
1212+local co_create = cor.create
1313+local co_status = cor.status
1414+local co_resume = cor.resume
1515+local co_status_dead = "dead"
1616+local co_status_suspended = "suspended"
1717+1818+function runFunction(fn, errorPrefix, ...)
1919+ local s, err = n_pcall(fn, ...)
2020+ if not s then
2121+ n_error(errorPrefix .. err)
2222+ end
2323+end
2424+2525+local DU_System = {
2626+ __index = {
2727+ cos = {
2828+ update = {},
2929+ flush = {}
3030+ },
3131+ fns = {
3232+ update = {},
3333+ flush = {},
3434+ action = {
3535+ start = {},
3636+ stop = {},
3737+ loop = {}
3838+ },
3939+ inputText = nil,
4040+ start = nil,
4141+ stop = nil
4242+ },
4343+ ACTIONS = {
4444+ FORWARD = "forward",
4545+ BACKWARD = "backward",
4646+ YAW_LEFT = "yawleft",
4747+ YAW_RIGHT = "yawright",
4848+ STRAFE_LEFT = "strafeleft",
4949+ STRAFE_RIGHT = "straferight",
5050+ LEFT = "left",
5151+ RIGHT = "right",
5252+ UP = "up",
5353+ DOWN = "down",
5454+ GROUND_ALTITUDE_UP = "groundaltitudeup",
5555+ GROUND_ALTITUDE_DOWN = "groundaltitudedown",
5656+ LEFT_ALT = "lalt",
5757+ LEFT_SHIFT = "lshift",
5858+ GEAR = "gear",
5959+ LIGHT = "light",
6060+ BRAKE = "brake",
6161+ OPTION_1 = "option1",
6262+ OPTION_2 = "option2",
6363+ OPTION_3 = "option3",
6464+ OPTION_4 = "option4",
6565+ OPTION_5 = "option5",
6666+ OPTION_6 = "option6",
6767+ OPTION_7 = "option7",
6868+ OPTION_8 = "option8",
6969+ OPTION_9 = "option9",
7070+ LEFT_MOUSE = "leftmouse",
7171+ STOP_ENGINES = "stopengines",
7272+ SPEED_UP = "speedup",
7373+ SPEED_DOWN = "speeddown",
7474+ ANTIGRAVITY = "antigravity",
7575+ BOOSTER = "booster"
7676+ },
7777+ main = {
7878+ update = co_create(function() end),
7979+ flush = co_create(function() end),
8080+ },
8181+ update = function(self)
8282+ local status = co_status(self.main.update)
8383+ if status == co_status_dead then
8484+ self.main.update = co_create(function() self:runUpdate() end)
8585+ elseif status == co_status_suspended then
8686+ n_assert(co_resume(self.main.update))
8787+ end
8888+ end,
8989+ flush = function(self)
9090+ local status = co_status(self.main.flush)
9191+ if status == co_status_dead then
9292+ self.main.flush = co_create(function() self:runFlush() end)
9393+ elseif status == co_status_suspended then
9494+ n_assert(co_resume(self.main.flush))
9595+ end
9696+ end,
9797+ action = function(self, event, action)
9898+ if self.fns.action[event][action] then
9999+ runFunction(self.fns.action[event][action], "System Action " .. event .. " Error: ")
100100+ end
101101+ end,
102102+ actionStart = function(self, action)
103103+ self:action('start', action)
104104+ end,
105105+ actionStop = function(self, action)
106106+ self:action('stop', action)
107107+ end,
108108+ actionLoop = function(self, action)
109109+ self:action('loop', action)
110110+ end,
111111+ inputText = function(self, text)
112112+ if self.fns.inputText then
113113+ runFunction(self.fns.inputText, "System Input Text Error: ", text)
114114+ end
115115+ end,
116116+ runUpdate = function(self)
117117+ for k,co in pairs(self.cos.update) do
118118+ local s = co_status(co)
119119+ if s == co_status_dead then
120120+ self.cos.update[k] = co_create(self.fns.update[k])
121121+ elseif s == co_status_suspended then
122122+ n_assert(co_resume(co))
123123+ end
124124+ end
125125+ end,
126126+ runFlush = function(self)
127127+ for k,co in pairs(self.cos.flush) do
128128+ local s = co_status(co)
129129+ if s == co_status_dead then
130130+ self.cos.flush[k] = co_create(self.fns.flush[k])
131131+ elseif s == co_status_suspended then
132132+ n_assert(co_resume(co))
133133+ end
134134+ end
135135+ end,
136136+ onUpdate = function(self, fns)
137137+ for k,f in pairs(fns) do
138138+ self.fns.update[k] = f
139139+ self.cos.update[k] = co_create(f)
140140+ end
141141+ end,
142142+ onFlush = function(self, fns)
143143+ for k,f in pairs(fns) do
144144+ self.fns.flush[k] = f
145145+ self.cos.flush[k] = co_create(f)
146146+ end
147147+ end,
148148+ onAction = function(self, event, fns)
149149+ for k,f in pairs(fns) do
150150+ self.fns.action[event][k] = f
151151+ end
152152+ end,
153153+ onActionStart = function(self, fns)
154154+ self:onAction("start", fns)
155155+ end,
156156+ onActionStop = function(self, fns)
157157+ self:onAction("stop", fns)
158158+ end,
159159+ onActionLoop = function(self, fns)
160160+ self:onAction("loop", fns)
161161+ end,
162162+ onInputText = function(self, fn)
163163+ self.fns.inputText = fn
164164+ end
165165+ }
166166+}
167167+168168+local DU_Unit = {
169169+ __index = {
170170+ timers = {},
171171+ stopFn = function() end,
172172+ timer = function (self, tag)
173173+ if self.timers[tag] then
174174+ runFunction(self.timers[tag], "Unit Timer " .. tag .. " Error: ")
175175+ end
176176+ end,
177177+ setTimer = function(self, tag, seconds, fn)
178178+ self.timers[tag] = fn
179179+ unit.setTimer(tag, seconds)
180180+ end,
181181+ stopTimer = function(self, tag)
182182+ unit.stopTimer(tag)
183183+ self.timers[tag]=nil
184184+ end,
185185+ onStop = function (self, fn)
186186+ self.stopFn = fn
187187+ end,
188188+ stop = function(self)
189189+ if self.stopFn then
190190+ runFunction(self.stopFn, "Unit Stop Error: ")
191191+ end
192192+ end
193193+ }
194194+}
195195+196196+local DU_Player = {
197197+ __index = {
198198+ parentChangedFn = function(oldId, newId) end,
199199+ onParentChange = function (self, fn)
200200+ self.parentChangedFn = fn
201201+ end,
202202+ parentChanged = function (self, oldId, newId)
203203+ if self.parentChangedFn then
204204+ runFunction(self.parentChangedFn, "Player Parent Changed Error: ", oldId, newId)
205205+ end
206206+ end,
207207+ }
208208+}
209209+210210+local DU_Construct = {
211211+ __index = {
212212+ dockedFn = function(id) end,
213213+ onDocked = function (self, fn)
214214+ self.dockedFn = fn
215215+ end,
216216+ docked = function (self, id)
217217+ if self.dockedFn then
218218+ runFunction(self.dockedFn, "Construct Docked Error: ", id)
219219+ end
220220+ end,
221221+ undockedFn = function(id) end,
222222+ onUndocked = function (self, fn)
223223+ self.undockedFn = fn
224224+ end,
225225+ undocked = function (self, id)
226226+ if self.undockedFn then
227227+ runFunction(self.undockedFn, "Construct Undocked Error: ", id)
228228+ end
229229+ end,
230230+ playerBoardedFn = function(id) end,
231231+ onPlayerBoarded = function (self, fn)
232232+ self.playerBoardedFn = fn
233233+ end,
234234+ playerBoarded = function (self, id)
235235+ if self.playerBoardedFn then
236236+ runFunction(self.playerBoardedFn, "Construct Player Boarded Error: ", id)
237237+ end
238238+ end,
239239+ VRStationEnteredFn = function(id) end,
240240+ onVRStationEntered = function (self, fn)
241241+ self.VRStationEnteredFn = fn
242242+ end,
243243+ VRStationEntered = function (self, id)
244244+ if self.VRStationEnteredFn then
245245+ runFunction(self.VRStationEnteredFn, "Construct VR Station Entered Error: ", id)
246246+ end
247247+ end,
248248+ constructDockedFn = function(id) end,
249249+ onConstructDocked = function (self, fn)
250250+ self.constructDockedFn = fn
251251+ end,
252252+ constructDocked = function (self, id)
253253+ if self.constructDockedFn then
254254+ runFunction(self.constructDockedFn, "Construct Construct Docked Error: ", id)
255255+ end
256256+ end,
257257+ PvPTimerFn = function(active) end,
258258+ onPvPTimer = function (self, fn)
259259+ self.PvPTimerFn = fn
260260+ end,
261261+ PvPTimer = function (self, active)
262262+ if self.PvPTimerFn then
263263+ runFunction(self.PvPTimerFn, "Construct PvP Timer Error: ", active)
264264+ end
265265+ end,
266266+ }
267267+}
268268+269269+DU_Framework = {
270270+ __index = {
271271+ system = setmetatable({}, DU_System),
272272+ unit = setmetatable({}, DU_Unit),
273273+ player = setmetatable({}, DU_Player),
274274+ construct = setmetatable({}, DU_Construct),
275275+ }
276276+}
277277+Script = {}
278278+setmetatable(Script, DU_Framework)
279279+280280+--[[
281281+ You can declare here all the functions you want to call in the diffent events from system, unit, player and construct.
282282+ Major changes compared to the base game concept:
283283+ - System onUpdate and onFlush events are now builded with coroutines, in the framework, onUpdate and onFlush are loading a table of functions that will be runned as coroutines. This way you can have multiple functions running at the same time, and you use the yield function to pause the coroutine and let the other coroutines run. Each coroutine will be resume or restarted if dead each time the system onUpdate or onFlush event is called.
284284+285285+]]
286286+287287+--Functions to load as coroutines that will be runned in system > onUpdate (based on FPS)
288288+local system_update = {}
289289+system_update.co1 = function ()
290290+ for i=0, 10 do
291291+ system.print("coroutine 1 --- update --- "..i)
292292+ coroutine.yield() -- pause the coroutine 1, it will wait till the next onUpdate event to be resumed
293293+ end
294294+end
295295+system_update.co2 = function ()
296296+ for i=0, 10 do
297297+ system.print("coroutine 2 --- update --- "..i)
298298+ coroutine.yield() -- pause the coroutine 2, it will wait till the next onUpdate event to be resumed
299299+ end
300300+end
301301+302302+--Functions to load as coroutines that will be runned in system > onFlush (60 times / s)
303303+local system_flush = {}
304304+system_flush.co1 = function ()
305305+ for i=0, 10 do
306306+ system.print("coroutine 1 --- flush --- "..i)
307307+ coroutine.yield() -- pause the coroutine 1, it will wait till the next onFlush event to be resumed
308308+ end
309309+end
310310+system_flush.co2 = function ()
311311+ for i=0, 10 do
312312+ system.print("coroutine 2 --- flush --- "..i)
313313+ coroutine.yield() -- pause the coroutine 2, it will wait till the next onFlush event to be resumed
314314+ end
315315+end
316316+317317+--Function to run on actions
318318+local system_action_start = {}
319319+system_action_start[Script.system.ACTIONS.BRAKE] = function()
320320+ system.print("I'm braking");
321321+end
322322+local system_action_stop = {}
323323+system_action_stop[Script.system.ACTIONS.BRAKE] = function()
324324+ system.print("I stopped braking");
325325+end
326326+local system_action_loop = {}
327327+system_action_loop[Script.system.ACTIONS.BRAKE] = function()
328328+ system.print("I'm still braking");
329329+end
330330+331331+--Function to run when input text to the lua chat
332332+local system_inputText = function (text)
333333+ system.print("Input: " .. text)
334334+end
335335+336336+--Function to run when the program is stopping
337337+local unit_onstop = function ()
338338+ system.print("Program is stopping")
339339+end
340340+341341+--Function to run when the player change parent
342342+local player_onparentchanged = function (oldParent, newParent)
343343+ system.print("Player changed parent from ID "..oldParent.." to ID "..newParent)
344344+end
345345+346346+--Function to run when the construct is docked or undocked
347347+local construct_onDocked = function(id)
348348+ system.print("Construct docked on ID "..id)
349349+end
350350+local construct_onUndocked = function(id)
351351+ system.print("Construct undocked from ID "..id)
352352+end
353353+354354+--Function to run when a player board the construct
355355+local construct_onplayerboarded = function(id)
356356+ system.print("Player with ID " .. id .. " boarded construct")
357357+end
358358+359359+--Function to run when a player enter the VR Station
360360+local construct_vrstationentered = function(id)
361361+ system.print("Player with ID " .. id .. " entered VR Station")
362362+end
363363+364364+--Function to run when another construct is docked on this construct
365365+local construct_constructdocked = function(id)
366366+ system.print("Construct with ID " .. id .. " docked on this construct")
367367+end
368368+369369+--Function to run when pvp timer is changing state
370370+local construct_onpvptimer = function(active)
371371+ if active then
372372+ system.print("PVP is now active")
373373+ else
374374+ system.print("PVP is now inactive")
375375+ end
376376+end
377377+378378+--[[
379379+ Here how to load the functions in the framework
380380+]]
381381+Script.system:onUpdate(system_update) --loading coroutines for system > onUpdate
382382+Script.system:onFlush(system_flush) --loading coroutines for system > onFlush
383383+384384+Script.system:onActionStart(system_action_start) --loading all "actionStart" functions
385385+Script.system:onActionStop(system_action_stop) --loading all "actionStop" functions
386386+Script.system:onActionLoop(system_action_loop) --loading all "actionLoop" functions
387387+388388+Script.system:onInputText(system_inputText) --loading the function to trigger when input text in lua chat
389389+390390+--[[
391391+ Here how to add a timer
392392+ @param name: the name of the timer, used to remove it with Script.unit:stopTimer(name)
393393+ @param delay: the delay between each call of the function in seconds
394394+ @param func: the function to call
395395+]]
396396+Script.unit:setTimer("hello", 1, function()system.print("hello")end) --add a timer displaying "hello" every seconds
397397+Script.unit:setTimer("hello5", 5, function()system.print("hello 5")end) --add a timer displaying "hello 5" every 5 seconds
398398+399399+Script.unit:onStop(unit_onstop) --loading the function to trigger when the program is stopping
400400+401401+Script.player:onParentChanged(player_onparentchanged) --loading the function to trigger when the player change parent
402402+403403+Script.construct:onDocked(construct_onDocked) --loading the function to trigger when the construct is docked
404404+Script.construct:onUndocked(construct_onUndocked) --loading the function to trigger when the construct is undocked
405405+Script.construct:onPlayerBoarded(construct_onplayerboarded) --loading the function to trigger when a player board the construct
406406+Script.construct:onVRStationEntered(construct_vrstationentered) --loading the function to trigger when a player enter the VR Station
407407+Script.construct:onConstructDocked(construct_constructdocked) --loading the function to trigger when another construct is docked on this construct
408408+Script.construct:onPvPTimer(construct_onpvptimer) --loading the function to trigger when pvp timer is changing state