From b12358edc5b4fb95d6d636ba041d5a63a5dc7fed Mon Sep 17 00:00:00 2001 From: Brent Date: Thu, 24 Feb 2022 00:06:41 +0100 Subject: [PATCH 01/26] cleaner code --- .../libs/game_improvements/interactable.lua | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/Scripts/libs/game_improvements/interactable.lua b/Scripts/libs/game_improvements/interactable.lua index 5c11d88..19d0c5f 100644 --- a/Scripts/libs/game_improvements/interactable.lua +++ b/Scripts/libs/game_improvements/interactable.lua @@ -4,28 +4,21 @@ __InteractableImprovements_Loaded = true -- server: local values = {} -- < Date: Fri, 27 May 2022 01:34:39 -0700 Subject: [PATCH 02/26] Removed ticks from debug print function --- Scripts/libs/debugger.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Scripts/libs/debugger.lua b/Scripts/libs/debugger.lua index b5f6598..989afc8 100644 --- a/Scripts/libs/debugger.lua +++ b/Scripts/libs/debugger.lua @@ -1,9 +1,7 @@ -if _loadedModpackDebugger then - return -end +if _loadedModpackDebugger then return end _loadedModpackDebugger = true local printO = print function print(...) -- fancy print by TechnologicNick - printO("[" .. sm.game.getCurrentTick() .. "]", sm.isServerMode() and "[Server]" or "[Client]", ...) -end + printO(sm.isServerMode() and "[Server]" or "[Client]", ...) +end \ No newline at end of file From 5a41b8fc5dbd5000da4c4043b416d752b9c7813e Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Fri, 27 May 2022 01:35:36 -0700 Subject: [PATCH 03/26] Fixed all the interaction texts --- Scripts/interactable/BlockSpawner.lua | 2 +- Scripts/interactable/Locomotion/Gimball.lua | 11 ++++++++++- .../interactable/Locomotion/WASDThruster.lua | 18 ++++++++++++++---- .../interactable/NumberLogic/AsciiBlock.lua | 14 ++++++++++---- .../interactable/NumberLogic/CounterBlock.lua | 5 +++-- Scripts/interactable/NumberLogic/MathBlock.lua | 5 +++-- Scripts/interactable/NumberOut/SmartSensor.lua | 5 +++-- Scripts/interactable/Orientation/Orienter.lua | 5 +++-- Scripts/interactable/Orientation/XOMeter.lua | 6 +++--- 9 files changed, 50 insertions(+), 21 deletions(-) diff --git a/Scripts/interactable/BlockSpawner.lua b/Scripts/interactable/BlockSpawner.lua index 23fc318..800f73c 100644 --- a/Scripts/interactable/BlockSpawner.lua +++ b/Scripts/interactable/BlockSpawner.lua @@ -79,7 +79,7 @@ function BlockSpawner.printDescription() end function BlockSpawner.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") + local _useKey = sm.gui.getKeyBinding("Use", true) sm.gui.setInteractionText("Press", _useKey, "to print color input/output in chat") return true end diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index 92bc6e5..7719995 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -42,6 +42,7 @@ function Gimball.server_onFixedUpdate( self ) --print(self.direction) end end + function Gimball.client_onCreate(self) self.shootEffect = sm.effect.createEffect( "Thruster - Level 2", self.interactable ) self.shootEffect:setOffsetPosition(sm.vec3.zero()) @@ -61,27 +62,35 @@ end function Gimball.client_onDestroy(self) self.shootEffect:stop() end + function Gimball.client_onInteract(self, character, lookAt) if not lookAt or character:getLockingInteractable() then return end self.network:sendToServer("server_changemode", character:isCrouching()) end + function Gimball.server_changemode(self, crouch) self.smode = (self.smode + (crouch and -1 or 1)) % 4 self.storage:save(self.smode+1) self.network:sendToClients("client_mode", {mode = self.smode, sound = true}) end + function Gimball.server_requestmode(self) self.network:sendToClients("client_mode", {mode = self.smode, sound = false}) end + function Gimball.client_mode(self, data) if data.sound then sm.audio.play("ConnectTool - Rotate", self.shape:getWorldPosition()) end self.mode = data.mode end + function Gimball.client_canInteract(self) - sm.gui.setInteractionText("Press", sm.gui.getKeyBinding("Use"), "to change mode") + local use_key = sm.gui.getKeyBinding("Use", true) + + sm.gui.setInteractionText("Press", use_key, "to change mode") sm.gui.setInteractionText("Current mode: "..self.modes[self.mode+1]) + return true end diff --git a/Scripts/interactable/Locomotion/WASDThruster.lua b/Scripts/interactable/Locomotion/WASDThruster.lua index 957de20..b30d763 100644 --- a/Scripts/interactable/Locomotion/WASDThruster.lua +++ b/Scripts/interactable/Locomotion/WASDThruster.lua @@ -74,25 +74,35 @@ function WASDThruster.client_onInteract(self, character, lookAt) if not lookAt or character:getLockingInteractable() then return end self.network:sendToServer("server_changemode", character:isCrouching()) end + function WASDThruster.server_changemode(self, crouch) self.smode = (self.smode + (crouch and -1 or 1))%4 self.storage:save(self.smode+1) self.network:sendToClients("client_mode", {self.smode, true}) end + function WASDThruster.server_requestmode(self) self.network:sendToClients("client_mode", {self.smode}) end + function WASDThruster.client_mode(self, mode) if mode[2] then sm.audio.play("ConnectTool - Rotate", self.shape:getWorldPosition()) end self.mode = mode[1] end + +local default_hypertext = "

%s

" function WASDThruster.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - local _crawlKey = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("Press", _useKey, " / ", _crawlKey.." + ".._useKey, "to change mode") - sm.gui.setInteractionText( "current mode: ".. self.modes[self.mode+1]) + local use_key = sm.gui.getKeyBinding("Use") + local crawl_key = sm.gui.getKeyBinding("Crawl") + + local use_hyper = default_hypertext:format(use_key) + local use_and_crawl_hyper = default_hypertext:format(crawl_key.." + "..use_key) + + sm.gui.setInteractionText("Press", use_hyper, " / ", use_and_crawl_hyper, "to change mode") + sm.gui.setInteractionText("Current mode: "..self.modes[self.mode+1]) + return true end diff --git a/Scripts/interactable/NumberLogic/AsciiBlock.lua b/Scripts/interactable/NumberLogic/AsciiBlock.lua index 7a14c74..ea1585c 100644 --- a/Scripts/interactable/NumberLogic/AsciiBlock.lua +++ b/Scripts/interactable/NumberLogic/AsciiBlock.lua @@ -340,11 +340,17 @@ function AsciiBlock.client_onInteract(self, character, lookAt) self.network:sendToServer("server_changemode", character:isCrouching()) end +local default_hypertext = "

%s

" function AsciiBlock.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - local _crawlKey = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("", _useKey, "to cycle forward") - sm.gui.setInteractionText("", _crawlKey.." + ".._useKey, "to cycle backwards") + local use_key = sm.gui.getKeyBinding("Use") + local crawl_key = sm.gui.getKeyBinding("Crawl") + + local use_hyper = default_hypertext:format(use_key) + local crawl_and_use_hyper = default_hypertext:format(crawl_key.." + "..use_key) + + sm.gui.setInteractionText("", use_hyper, "to cycle forward") + sm.gui.setInteractionText("", crawl_and_use_hyper, "to cycle backwards") + return true end function AsciiBlock.client_playsound(self, sound) diff --git a/Scripts/interactable/NumberLogic/CounterBlock.lua b/Scripts/interactable/NumberLogic/CounterBlock.lua index ed87a83..58a6923 100644 --- a/Scripts/interactable/NumberLogic/CounterBlock.lua +++ b/Scripts/interactable/NumberLogic/CounterBlock.lua @@ -130,8 +130,9 @@ function CounterBlock.client_onCreate(self, dt) end function CounterBlock.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, "to reset counter") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to reset counter") + return true end diff --git a/Scripts/interactable/NumberLogic/MathBlock.lua b/Scripts/interactable/NumberLogic/MathBlock.lua index 3cabb1c..c0b72b6 100644 --- a/Scripts/interactable/NumberLogic/MathBlock.lua +++ b/Scripts/interactable/NumberLogic/MathBlock.lua @@ -972,8 +972,9 @@ function MathBlock.cl_setMode(self, data) end function MathBlock.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, " to select a function") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select a function") + return true end diff --git a/Scripts/interactable/NumberOut/SmartSensor.lua b/Scripts/interactable/NumberOut/SmartSensor.lua index 59c7fdd..cfaf38e 100644 --- a/Scripts/interactable/NumberOut/SmartSensor.lua +++ b/Scripts/interactable/NumberOut/SmartSensor.lua @@ -227,8 +227,9 @@ function SmartSensor.cl_drawButtons(self) end function SmartSensor.client_canInteract(self, character, lookAt) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, "to change mode") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select a sensor mode") + return true end diff --git a/Scripts/interactable/Orientation/Orienter.lua b/Scripts/interactable/Orientation/Orienter.lua index a1106af..ef6be61 100644 --- a/Scripts/interactable/Orientation/Orienter.lua +++ b/Scripts/interactable/Orientation/Orienter.lua @@ -367,8 +367,9 @@ function Orienter.sv_changeMode(self, params) end function Orienter.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, " to change the mode") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select an orient mode") + return true end diff --git a/Scripts/interactable/Orientation/XOMeter.lua b/Scripts/interactable/Orientation/XOMeter.lua index 2904d4a..98bea51 100644 --- a/Scripts/interactable/Orientation/XOMeter.lua +++ b/Scripts/interactable/Orientation/XOMeter.lua @@ -340,9 +340,9 @@ end function XOMeter.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - local _crawlKey = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("Press", _useKey, " to change the meter mode") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select the meter mode") + return true end From 29fc4a9931a62add6cd094e2cc1ebaaa6b9285e6 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Fri, 27 May 2022 09:10:26 -0700 Subject: [PATCH 04/26] More improvements to the interaction texts --- Scripts/interactable/Locomotion/Gimball.lua | 13 ++++++++++--- Scripts/interactable/Locomotion/WASDThruster.lua | 8 +++++--- Scripts/interactable/NumberLogic/AsciiBlock.lua | 3 +-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index 7719995..c6f3b71 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -85,11 +85,18 @@ function Gimball.client_mode(self, data) self.mode = data.mode end +local default_hypertext = "

%s

" function Gimball.client_canInteract(self) - local use_key = sm.gui.getKeyBinding("Use", true) + local use_key = sm.gui.getKeyBinding("Use") + local crawl_key = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("Press", use_key, "to change mode") - sm.gui.setInteractionText("Current mode: "..self.modes[self.mode+1]) + local use_hyper = default_hypertext:format(use_key) + local crawl_and_use_hyper = default_hypertext:format(crawl_key.." + "..use_key) + + sm.gui.setInteractionText("Press", use_hyper, "or", crawl_and_use_hyper, "to change mode") + + local cur_mode_hyper = default_hypertext:format("Mode: "..self.modes[self.mode+1]) + sm.gui.setInteractionText("", cur_mode_hyper) return true end diff --git a/Scripts/interactable/Locomotion/WASDThruster.lua b/Scripts/interactable/Locomotion/WASDThruster.lua index b30d763..d0a6ab8 100644 --- a/Scripts/interactable/Locomotion/WASDThruster.lua +++ b/Scripts/interactable/Locomotion/WASDThruster.lua @@ -59,7 +59,7 @@ function WASDThruster.client_onCreate(self) self.currentVPose = 0.5 self.mode = 0 self.network:sendToServer("server_requestmode") - self.modes = {"wasd", "ws reversed", "only WS", "only AD"} + self.modes = {"WASD", "WS Reversed", "Only WS", "Only AD"} self.interactable:setAnimEnabled( "animY", true ) self.interactable:setAnimEnabled( "animX", true ) @@ -100,8 +100,10 @@ function WASDThruster.client_canInteract(self) local use_hyper = default_hypertext:format(use_key) local use_and_crawl_hyper = default_hypertext:format(crawl_key.." + "..use_key) - sm.gui.setInteractionText("Press", use_hyper, " / ", use_and_crawl_hyper, "to change mode") - sm.gui.setInteractionText("Current mode: "..self.modes[self.mode+1]) + sm.gui.setInteractionText("Press", use_hyper, "or", use_and_crawl_hyper, "to change mode") + + local cur_mode_hyper = default_hypertext:format("Mode: "..self.modes[self.mode+1]) + sm.gui.setInteractionText("", cur_mode_hyper) return true end diff --git a/Scripts/interactable/NumberLogic/AsciiBlock.lua b/Scripts/interactable/NumberLogic/AsciiBlock.lua index ea1585c..ae3bab8 100644 --- a/Scripts/interactable/NumberLogic/AsciiBlock.lua +++ b/Scripts/interactable/NumberLogic/AsciiBlock.lua @@ -348,8 +348,7 @@ function AsciiBlock.client_canInteract(self) local use_hyper = default_hypertext:format(use_key) local crawl_and_use_hyper = default_hypertext:format(crawl_key.." + "..use_key) - sm.gui.setInteractionText("", use_hyper, "to cycle forward") - sm.gui.setInteractionText("", crawl_and_use_hyper, "to cycle backwards") + sm.gui.setInteractionText("Press", use_hyper, "or", crawl_and_use_hyper, "to change") return true end From 4416cfb3173c31c456f6efdaff60769d8473859c Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Fri, 27 May 2022 10:33:49 -0700 Subject: [PATCH 05/26] Added a Counter Block GUI --- Gui/Layouts/CounterBlockGui.layout | 55 +++++++++ .../interactable/NumberLogic/CounterBlock.lua | 112 +++++++++++++++++- 2 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 Gui/Layouts/CounterBlockGui.layout diff --git a/Gui/Layouts/CounterBlockGui.layout b/Gui/Layouts/CounterBlockGui.layout new file mode 100644 index 0000000..e71ed7f --- /dev/null +++ b/Gui/Layouts/CounterBlockGui.layout @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Scripts/interactable/NumberLogic/CounterBlock.lua b/Scripts/interactable/NumberLogic/CounterBlock.lua index 58a6923..d408ff5 100644 --- a/Scripts/interactable/NumberLogic/CounterBlock.lua +++ b/Scripts/interactable/NumberLogic/CounterBlock.lua @@ -106,37 +106,141 @@ function CounterBlock.server_onFixedUpdate( self, dt ) mp_updateOutputData(self, self.power, self.power > 0) end +function CounterBlock.server_setNewValue(self, value, caller) + self.power = value + + self.network:sendToClient(caller, "client_playSound", 2) +end + +function CounterBlock.server_receiveValue(self, value, caller) + self.power = self.power + value + + self.network:sendToClient(caller, "client_playSound", 2) +end function CounterBlock.server_reset(self) if self.power > 0 then - self.network:sendToClients("client_resetSound") + self.network:sendToClients("client_playSound", 1) end self.power = 0 end -function CounterBlock.client_resetSound(self) - sm.audio.play("GUI Item drag", self.shape:getWorldPosition()) +local sound_id_table = +{ + [1] = "GUI Item drag", + [2] = "GUI Item released" +} + +function CounterBlock.client_playSound(self, sound_id) + local sound_id_table = sound_id_table[sound_id] + + sm.audio.play(sound_id_table, self.shape:getWorldPosition()) end function CounterBlock.client_onInteract(self, character, lookAt) if not lookAt or character:getLockingInteractable() then return end + self.network:sendToServer("server_reset") end +function CounterBlock.client_onTextChangedCallback(self, widget, text) + local converted_text = tonumber(text) --will be nill if the input is invalid + local is_valid = (converted_text ~= nil) + + self.counter_gui_input = text + + local count_gui = self.counter_gui + count_gui:setVisible("ValueError", not is_valid) + + count_gui:setVisible("IncrementWith", is_valid) + count_gui:setVisible("DecrementWith", is_valid) + count_gui:setVisible("SaveWrittenVal", is_valid) +end + +function CounterBlock.client_onGuiCloseCallback(self) + local count_gui = self.counter_gui + if count_gui and sm.exists(count_gui) then + if count_gui:isActive() then + count_gui:close() + end + + count_gui:destroy() + end + + self.counter_gui_input = nil + self.counter_gui = nil +end + +function CounterBlock.client_gui_updateSavedValueText(self) + self.counter_gui:setText("SavedValue", "Saved Value: #ffff00"..tostring(self.interactable.power).."#ffffff") +end + +function CounterBlock.client_gui_changeSavedValue(self, widget) + local is_decrement = (widget:sub(0, 1) == "D") + + local cur_changer = tonumber(self.counter_gui_input) + if cur_changer ~= nil then + if is_decrement then + cur_changer = -cur_changer + end + + self.network:sendToServer("server_receiveValue", cur_changer) + end +end + +function CounterBlock.client_gui_saveWrittenValue(self) + local cur_value = tonumber(self.counter_gui_input) + if cur_value ~= nil then + self.network:sendToServer("server_setNewValue", cur_value) + end +end + +function CounterBlock.client_onTinker(self, character, lookAt) + if not lookAt or character:getLockingInteractable() then return end + + local count_gui = sm.gui.createGuiFromLayout("$CONTENT_DATA/Gui/Layouts/CounterBlockGui.layout", false, { backgroundAlpha = 0.5 }) + + count_gui:setText("SavedValue", "Saved Value: #ffff00"..tostring(self.interactable.power).."#ffffff") + count_gui:setText("ValueInput", "0") + + count_gui:setButtonCallback("IncrementWith", "client_gui_changeSavedValue") + count_gui:setButtonCallback("DecrementWith", "client_gui_changeSavedValue") + count_gui:setButtonCallback("SaveWrittenVal", "client_gui_saveWrittenValue") + + count_gui:setTextChangedCallback("ValueInput", "client_onTextChangedCallback") + count_gui:setOnCloseCallback("client_onGuiCloseCallback") + + count_gui:open() + + self.counter_gui_input = "0" + self.counter_gui = count_gui +end function CounterBlock.client_onCreate(self, dt) self.frameindex = 0 self.lastpower = 0 end +function CounterBlock.client_onDestroy(self) + self:client_onGuiCloseCallback() +end + function CounterBlock.client_canInteract(self) - local use_key = sm.gui.getKeyBinding("Use", true) + local use_key = sm.gui.getKeyBinding("Use", true) + local tinker_key = sm.gui.getKeyBinding("Tinker", true) + sm.gui.setInteractionText("Press", use_key, "to reset counter") + sm.gui.setInteractionText("Press", tinker_key, "to open gui") return true end function CounterBlock.client_onFixedUpdate(self, dt) + local count_gui = self.counter_gui + if count_gui then + self:client_gui_updateSavedValueText() + end + local power = self.interactable.power if self.powerSkip == power then return end -- more performance (only update uv if power changes) From 2a20d1f57817b483331bd6d24f8f48db7a44305a Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Fri, 27 May 2022 10:37:57 -0700 Subject: [PATCH 06/26] Replaced spaces with tabs in layout files --- Gui/Layouts/MathBlock.layout | 398 ++++++++++++++++----------------- Gui/Layouts/Orienter.layout | 396 ++++++++++++++++---------------- Gui/Layouts/SmartSensor.layout | 154 ++++++------- Gui/Layouts/XOMeter.layout | 234 +++++++++---------- 4 files changed, 591 insertions(+), 591 deletions(-) diff --git a/Gui/Layouts/MathBlock.layout b/Gui/Layouts/MathBlock.layout index e1c4532..ef86723 100644 --- a/Gui/Layouts/MathBlock.layout +++ b/Gui/Layouts/MathBlock.layout @@ -1,202 +1,202 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/Orienter.layout b/Gui/Layouts/Orienter.layout index 30a668b..ab49ea5 100644 --- a/Gui/Layouts/Orienter.layout +++ b/Gui/Layouts/Orienter.layout @@ -1,206 +1,206 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/SmartSensor.layout b/Gui/Layouts/SmartSensor.layout index 9fe3205..b60fc1e 100644 --- a/Gui/Layouts/SmartSensor.layout +++ b/Gui/Layouts/SmartSensor.layout @@ -1,79 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/XOMeter.layout b/Gui/Layouts/XOMeter.layout index eee9d7b..24f74c6 100644 --- a/Gui/Layouts/XOMeter.layout +++ b/Gui/Layouts/XOMeter.layout @@ -1,119 +1,119 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 273045fee6af69b21400470f80d52bd0c8304192 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Fri, 27 May 2022 10:56:27 -0700 Subject: [PATCH 07/26] Guis will now close if interactable is destroyed --- .../interactable/NumberLogic/MathBlock.lua | 22 ++++++++++++++++++- .../interactable/NumberOut/SmartSensor.lua | 22 ++++++++++++++++++- Scripts/interactable/Orientation/Orienter.lua | 21 +++++++++++++++++- Scripts/interactable/Orientation/XOMeter.lua | 22 ++++++++++++++++++- 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/Scripts/interactable/NumberLogic/MathBlock.lua b/Scripts/interactable/NumberLogic/MathBlock.lua index c0b72b6..6c0915f 100644 --- a/Scripts/interactable/NumberLogic/MathBlock.lua +++ b/Scripts/interactable/NumberLogic/MathBlock.lua @@ -879,12 +879,32 @@ function MathBlock.client_onCreate(self) self.network:sendToServer("sv_senduvtoclient") end +function MathBlock.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + +function MathBlock.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function MathBlock.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/MathBlock.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/MathBlock.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for i = 0, 23 do self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" ) end + for i = 1, 3 do self.gui:setButtonCallback( "Page" .. tostring( i ), "cl_onPageButtonClick" ) end diff --git a/Scripts/interactable/NumberOut/SmartSensor.lua b/Scripts/interactable/NumberOut/SmartSensor.lua index cfaf38e..fd32edd 100644 --- a/Scripts/interactable/NumberOut/SmartSensor.lua +++ b/Scripts/interactable/NumberOut/SmartSensor.lua @@ -197,12 +197,32 @@ function SmartSensor.client_onCreate(self) self.network:sendToServer("sv_requestMode") end +function SmartSensor.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + +function SmartSensor.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function SmartSensor.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/SmartSensor.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/SmartSensor.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for i = 0, 5 do self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" ) end + self:cl_drawButtons() self.gui:open() end diff --git a/Scripts/interactable/Orientation/Orienter.lua b/Scripts/interactable/Orientation/Orienter.lua index ef6be61..0829f36 100644 --- a/Scripts/interactable/Orientation/Orienter.lua +++ b/Scripts/interactable/Orientation/Orienter.lua @@ -161,6 +161,10 @@ function Orienter.client_onCreate(self) self.network:sendToServer("sv_sendModeToClient") end +function Orienter.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + function Orienter.sv_sendModeToClient(self) local _UvIndex = self.modetable[self.mode].savevalue - 1 self.network:sendToClients("cl_setMode", { uvIndex = _UvIndex, mode = self.mode }) @@ -182,9 +186,24 @@ local _UnitTable = { 'UnitsTotebot', 'UnitsWoc', 'UnitsGlowworm' } +function Orienter.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function Orienter.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/Orienter.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/Orienter.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for _, buttonName in pairs(targetTable) do self.gui:setButtonCallback(buttonName, "cl_onTargetButtonClick") end diff --git a/Scripts/interactable/Orientation/XOMeter.lua b/Scripts/interactable/Orientation/XOMeter.lua index 98bea51..ea29590 100644 --- a/Scripts/interactable/Orientation/XOMeter.lua +++ b/Scripts/interactable/Orientation/XOMeter.lua @@ -358,6 +358,10 @@ function XOMeter.client_onCreate(self) self.network:sendToServer("server_sendModeToClient") end +function XOMeter.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + function XOMeter.client_onFixedUpdate(self, dt) local mode = self.modetable[self.mode_client] @@ -439,12 +443,28 @@ function XOMeter.client_onFixedUpdate(self, dt) end end +function XOMeter.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function XOMeter.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/XOMeter.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/XOMeter.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for i = 0, 10 do self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" ) end + self:cl_drawButtons() self.gui:open() end From 5909cd194612255e397b473b6f69889da0104891 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 28 May 2022 04:51:34 -0700 Subject: [PATCH 08/26] Improved Counter Block GUI --- Gui/Layouts/CounterBlockGui.layout | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Gui/Layouts/CounterBlockGui.layout b/Gui/Layouts/CounterBlockGui.layout index e71ed7f..0439402 100644 --- a/Gui/Layouts/CounterBlockGui.layout +++ b/Gui/Layouts/CounterBlockGui.layout @@ -1,43 +1,43 @@  - - + + - - - + + + - + - + - + - - + + - - + + - + From 040c527b88114b8f27f8d2e0147cc4865c769b66 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Thu, 9 Jun 2022 06:20:28 -0700 Subject: [PATCH 09/26] Added crafting recipes --- CraftingRecipes/craftbot.json | 2494 +++++++++++++++++++++++++++++++++ 1 file changed, 2494 insertions(+) create mode 100644 CraftingRecipes/craftbot.json diff --git a/CraftingRecipes/craftbot.json b/CraftingRecipes/craftbot.json new file mode 100644 index 0000000..5fe8898 --- /dev/null +++ b/CraftingRecipes/craftbot.json @@ -0,0 +1,2494 @@ +[ + { + // "Diamond Plate Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 20 + } + ], + "itemId": "c97c17c3-81bb-48b5-9e9c-8a5117ee431a", + "quantity": 10 + }, + { + // "Paintable Glass Flat Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 20 + } + ], + "itemId": "036ffd32-45df-11e6-beb8-9e71128cae77", + "quantity": 10 + }, + { + // "Glowing Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 5 + }, + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 5 + } + ], + "itemId": "e50485da-4545-4def-a585-0a5f158c6104", + "quantity": 10 + }, + { + // "Invisible Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 30 + } + ], + "itemId": "7a73cc98-b2d4-4b28-9095-f8b9077548e4", + "quantity": 10 + }, + { + // "Mirror Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 10 + } + ], + "itemId": "906c76ee-189a-4983-ae82-b31722e56b23", + "quantity": 10 + }, + { + // "Bling Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 100 + } + ], + "itemId": "bc3efcdf-ae18-4037-b0aa-c5af14e03547", + "quantity": 10 + }, + { + // "Game Grid Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 30 + } + ], + "itemId": "b51ad015-66e9-41b9-916c-277f9c93232d", + "quantity": 10 + }, + { + // "Luxury Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 100 + } + ], + "itemId": "e7f7b758-6492-4c6a-8760-8fb95da530be", + "quantity": 1 + }, + { + // "Smooth Ice", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "30a2288b-e88e-4a92-a916-1edbfc2b2dac", + "quantity": 4 + }, + { + "itemId": "869d4736-289a-4952-96cd-8a40117a2d28", + "quantity": 5 + } + ], + "itemId": "116325e1-1020-40ec-8f31-0678f8bb98bc", + "quantity": 10 + }, + { + // "Icy Rocks", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "30a2288b-e88e-4a92-a916-1edbfc2b2dac", + "quantity": 4 + }, + { + "itemId": "869d4736-289a-4952-96cd-8a40117a2d28", + "quantity": 5 + } + ], + "itemId": "b742cff1-98a7-469f-b514-a7402f705924", + "quantity": 10 + }, + { + // "Rubber Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "30a2288b-e88e-4a92-a916-1edbfc2b2dac", + "quantity": 4 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "123425e2-2020-40ec-8f31-0678f8bc99bd", + "quantity": 10 + }, + { + // "Reduced Collision Block", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + } + ], + "itemId": "bf8f8e24-806b-4223-9345-2bac7c1e265d", + "quantity": 1 + }, + { + // "Vent Block", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + } + ], + "itemId": "9c40e3ab-8d03-40bc-a88b-eaebc61257d6", + "quantity": 1 + }, + { + // "Invisible Bearing", + "craftTime": 30, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 20 + } + ], + "itemId": "ebafd24a-7bbc-4e75-87f5-a67cdcf31e29", + "quantity": 1 + }, + { + // "Steering Pipe", + "craftTime": 30, + "ingredientList": [ + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 20 + } + ], + "itemId": "8f762ab9-5c78-4d9c-a22e-3119bf447169", + "quantity": 1 + }, + { + // "Mini Suspension - Short", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 4 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 2 + } + ], + "itemId": "c0d086eb-de4a-4ba9-922a-1c66f129d2ae", + "quantity": 1 + }, + { + // "Mini Suspension - Long", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "8d6e5264-9f90-400a-a471-6c0cae101f4d", + "quantity": 1 + }, + { + // "Suspension - 4x", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 7 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "9f016a8d-8cbe-4471-b210-f36f5f280758", + "quantity": 1 + }, + { + // "Suspension - 5x", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 10 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "dd676b18-fd06-4aed-baa0-55d4599fdfa3", + "quantity": 1 + }, + { + // "Engine Suspension", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 15 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 15 + } + ], + "itemId": "93e08947-be6d-436c-a64f-932727428c89", + "quantity": 1 + }, + { + // "Mod Piston (256)", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 10 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 2 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 15 + } + ], + "itemId": "a6d186ad-c9ba-4b6d-922c-6c13dfcea230", + "quantity": 1 + }, + { + // "Motorcycle Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 4 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "0513fc6d-fb29-46b6-9409-3ec1a4b79c6f", + "quantity": 1 + }, + { + // "Racing Driver Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 4 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "ffddc616-2799-4883-8c62-193ba30b6fa8", + "quantity": 1 + }, + { + // "Racing Passenger Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "8c355d48-88cd-467b-863f-12c12b72304d", + "quantity": 1 + }, + { + // "Ship's Wheel Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 10 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "88e045aa-d3ab-435e-b248-60b34c206e6f", + "quantity": 1 + }, + { + // "Jetpack Seat - Or Mech, Gunner, etc", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "ad671132-c345-4edc-96c7-ec835ab3a2c9", + "quantity": 1 + }, + { + // "Standing Driver Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "3b41f562-70c4-4747-9045-3d26ff0e0243", + "quantity": 1 + }, + { + // "Sleeping Bed - Driver", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 20 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "a3da3841-5a76-4d72-a177-cdc4e572efc7", + "quantity": 1 + }, + { + // "Driver's Pillow", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "784bf71e-2331-4d56-a70f-b00a3994231b", + "quantity": 1 + }, + { + // "Modular Seat 1 - Standard", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 7 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "b15f557c-872f-4bf5-9c0b-2891a34f430e", + "quantity": 1 + }, + { + // "Modular Seat 2 - Saddle", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 7 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "86d5ca1b-f1fa-42a9-9645-0d276e711b27", + "quantity": 1 + }, + { + // "Modular Seat 3 - Race", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "d9f49f49-0ef9-41d6-a9a5-ec454be87082", + "quantity": 1 + }, + { + // "Arrow Button", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "685ccdd5-8ee9-480d-a64a-2696c31e1db0", + "quantity": 1 + }, + { + // "Hidden Button Block", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "e426ee20-2cf7-40c9-ad5e-145f43752fab", + "quantity": 1 + }, + { + // "Pull-start Button", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "f694b406-4f59-46cb-bf33-05e11851eaac", + "quantity": 1 + }, + { + // "Dial Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "deeb37a4-b9ba-4ba7-ad4b-6f5fd5e1d6f2", + "quantity": 1 + }, + { + // "Paddle Latch Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "70e5729d-0706-4c28-80a2-2ab9d7e7532c", + "quantity": 1 + }, + { + // "Door Handle Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "f6619b4a-a627-40c0-939c-a44432ebc66a", + "quantity": 1 + }, + { + // "Throttle Lever - Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "7022c522-7b33-4638-8dfb-0dfa7c6eb36f", + "quantity": 1 + }, + { + // "Medium Lever - Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "e9ab70ae-2c6c-4f68-86c3-2f652c180fc5", + "quantity": 1 + }, + { + // "Large Lever - Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "ee92187e-8363-4ff6-a7ae-c96e60450537", + "quantity": 1 + }, + { + // "Pipe Valve Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "73f35954-e7d2-4a32-bc7c-b88a341ab792", + "quantity": 1 + }, + { + // "Pixel Light Block - Black-Off, Light-On", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "7947150d-a21c-4195-a4a8-76aab023ba3c", + "quantity": 1 + }, + { + // "Off/On Light - Round", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "bfbd310d-7c07-4f08-a8cc-9a69e70a9ff0", + "quantity": 1 + }, + { + // "Off/On Light - Rectangle", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "d7de689e-5082-4323-b6c4-eb1ce8f29719", + "quantity": 1 + }, + { + // "Off/On Light - Round Mini", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "5a3ea22a-99b1-48eb-b169-3243ad49b27c", + "quantity": 1 + }, + { + // "Off/On Light - Square", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "7b51eae8-c55c-4102-b9eb-6c23ca547e83", + "quantity": 1 + }, + { + // "Off/On Light - Cube", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "e83e6fd9-e963-485f-8be0-43895af58ee3", + "quantity": 1 + }, + { + // "Slim Light", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "0f994efc-b697-48e4-8ce0-f53eae15d41b", + "quantity": 1 + }, + { + // "Surface Controller", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "9687439e-70a7-4c52-8dd1-d6fa6ec93df8", + "quantity": 1 + }, + { + // "Surface Logic", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "60375a3b-0d70-43a2-a97a-4a4234b500dd", + "quantity": 1 + }, + { + // "Surface Timer", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "f6b70b49-ea25-47cc-9dac-e2dc90e67d07", + "quantity": 1 + }, + { + // "Decoupler", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + } + ], + "itemId": "f907144d-ae63-4e5e-bff9-f9ca413e2090", + "quantity": 1 + }, + { + // "Time Block ", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "6613bebe-be9f-435c-b415-42a0b45cc8e3", + "quantity": 1 + }, + { + // "Smart Sensor", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 4 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 6 + } + ], + "itemId": "4081ca6f-6b80-4c39-9e79-e1f747039bec", + "quantity": 1 + }, + { + // "Laser Sight", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "c7a99aa6-c5a4-43ad-84c9-c85f7d842a93", + "quantity": 1 + }, + { + // "Tracker", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 10 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 25 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 30 + } + ], + "itemId": "6594dff0-c652-4b44-8bb6-c725aaadea05", + "quantity": 1 + }, + { + // "Radar Jammer", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 30 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 20 + } + ], + "itemId": "55bb3871-8455-40dc-a968-3dc635a32b7e", + "quantity": 1 + }, + { + // "Wireless Router", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 13 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 20 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 20 + } + ], + "itemId": "e627986c-b7dd-4365-8fd8-a0f8707af63d", + "quantity": 1 + }, + { + // "Orientation Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "ccaa33b6-e5bb-4edc-9329-b40f6efe2c9e", + "quantity": 1 + }, + { + // "Number Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "efbd14a8-f896-4268-a273-b2b382db520c", + "quantity": 1 + }, + { + // "Math Block\n(Function Block)", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "289e08ef-e3d8-4f1b-bc10-a0bcf36fa0ce", + "quantity": 1 + }, + { + // "Counter", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "d8296109-2ffb-4efb-819a-54bd8cadf549", + "quantity": 1 + }, + { + // "Memory Panel", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "b39faec9-1ed0-4475-8bc0-78d125df1b58", + "quantity": 1 + }, + { + // "x-o-meter", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "d88ba569-f7a5-42e3-bb11-d7979b60ddad", + "quantity": 1 + }, + { + // "Tick Button", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "6f2dd83e-bc0d-43f3-8ba5-d5209eb03d07", + "quantity": 1 + }, + { + // "Smart Timer", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "a1d0b1a0-4ec7-4614-8b7a-9a7c521cc03e", + "quantity": 1 + }, + { + // "Keypad Input", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "d3eda549-778f-432b-bf21-65a32ae53378", + "quantity": 1 + }, + { + // "Color Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "921a2ace-b543-4ca3-8a9b-6f3dd3132fa9", + "quantity": 1 + }, + { + // "Ascii Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "9c47ec58-bdfc-43a4-b066-852156ad812a", + "quantity": 1 + }, + { + // "Ascii Block Inverted", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "8d27520e-2ebc-4f14-bd2c-b99ee8976799", + "quantity": 1 + }, + { + // "Ascii Block Colored", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "a459eb96-7f0a-42e6-a841-44f9c0561a55", + "quantity": 1 + }, + { + // "Smart Engine Controller", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 40 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 20 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 20 + } + ], + "itemId": "fe8978ec-5798-4b24-bdb2-8375387f171b", + "quantity": 1 + }, + { + // "Gas Engine 3-Wide", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "c0dfdea5-a39d-433a-b94a-299345a5df46", + "quantity": 20 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "f55aa240-d4b2-48cc-9c6b-a90fce299bf4", + "quantity": 1 + }, + { + // "Pico thruster - Low power", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "c0dfdea5-a39d-433a-b94a-299345a5df46", + "quantity": 20 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "c394b6e8-554c-4074-a119-ab2fec55e456", + "quantity": 1 + }, + { + // "1x1 Micro Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "c0dfdea5-a39d-433a-b94a-299345a5df46", + "quantity": 20 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "036fbe44-45df-11e6-beb8-9e71128cae77", + "quantity": 1 + }, + { + // "Smart Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 35 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 17 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 30 + } + ], + "itemId": "a4342028-9a61-4961-99a4-2ae372ee2481", + "quantity": 1 + }, + { + // "WASD Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 35 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 25 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 25 + } + ], + "itemId": "cec7c353-34ab-43a4-ade5-411df02eaa2a", + "quantity": 1 + }, + { + // "Gimbal Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 25 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 25 + } + ], + "itemId": "41d596a6-882c-4f97-b0e0-3e11bff194e2", + "quantity": 1 + }, + { + // "Gravity Module", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 45 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 30 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 55 + } + ], + "itemId": "c9e34f58-b30d-4ab5-92c5-76f707090c45", + "quantity": 1 + }, + { + // "Gravity Modulator", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 50 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 40 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 60 + } + ], + "itemId": "e93ca226-4166-49e3-97cd-bb8df20242d7", + "quantity": 1 + }, + { + // "Large Wing", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "e2cc7014-85f3-4bb8-a7ca-b70b6502d91e", + "quantity": 1 + }, + { + // "Small Wing / Propeller", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "1bfccc0a-828f-475c-882c-87d5a96054c9", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "b5222776-1702-4c22-a8c5-ca26cc0290e7", + "quantity": 1 + }, + { + // "Timed Explosive - Dynamite", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "c071509a-9854-4359-8857-296f16edf15d", + "quantity": 1 + }, + { + // "Tone Generator", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + } + ], + "itemId": "f73fd8c7-61eb-416f-8374-9a4c26e6db8f", + "quantity": 1 + }, + { + // "Smart Totebot", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 4 + } + ], + "itemId": "1d5d997e-efa9-478c-98ee-e452f5ff0dd2", + "quantity": 1 + }, + { + // "Radar", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 3 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 10 + } + ], + "itemId": "a053e38d-608b-4b9a-8d04-c3da2b6fdff7", + "quantity": 1 + }, + { + // "Roller Wheel - 1x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 3 + } + ], + "itemId": "b57c8185-2f95-4ba8-818d-eed258e01d00", + "quantity": 1 + }, + { + // "Roller Wheel - 2x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 6 + } + ], + "itemId": "4e1452d0-a9c2-42d4-91cf-1aea84c533ed", + "quantity": 1 + }, + { + // "Rounded Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "c460f40f-c7b7-4695-a627-9f01749724b6", + "quantity": 1 + }, + { + // "Hubless Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "c9cf3b88-86f3-4146-af16-a7b16c917ecc", + "quantity": 1 + }, + { + // "Invisible Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "4358b01f-3303-42a2-91d2-cc950e23b59b", + "quantity": 1 + }, + { + // "Dirt Wheel - 3x1/2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 13 + } + ], + "itemId": "27b6541d-2be0-420f-abb8-d59f566e85bd", + "quantity": 1 + }, + { + // "Dirt Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "68a7fe0a-4d48-4552-a29d-044d3c7b9e02", + "quantity": 1 + }, + { + // "Dirt Wheel - 4x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 16 + } + ], + "itemId": "92d3c375-0e45-4df4-8691-90e49e8ce24d", + "quantity": 1 + }, + { + // "Dirt Wheel - 5x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 18 + } + ], + "itemId": "041ae0ae-07d5-4ac5-9767-be396ba2445d", + "quantity": 1 + }, + { + // "Dirt Wheel - 5x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "c47ff0cd-e1f2-4727-ba40-c85d0512d6d0", + "quantity": 1 + }, + { + // "Dirt Wheel - 5x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 21 + } + ], + "itemId": "784bf162-b2d1-4a6d-9cf4-091827871a40", + "quantity": 1 + }, + { + // "Street Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "5a9ff028-a6cb-4010-bcd4-c88eb230bcdb", + "quantity": 1 + }, + { + // "Street Wheel - 4x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 17 + } + ], + "itemId": "58e7fdd0-9f15-466c-aaba-60805044fe67", + "quantity": 1 + }, + { + // "Street Wheel - 4x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 18 + } + ], + "itemId": "3147a872-cb90-487c-b6ce-438c6403b09c", + "quantity": 1 + }, + { + // "Street Wheel - 5x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "a02f96b2-26c3-4b3e-a00c-32254af91a5d", + "quantity": 1 + }, + { + // "Street Wheel - 6x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 22 + } + ], + "itemId": "d3954d83-78ee-4fbf-9a60-70e4872e1d39", + "quantity": 1 + }, + { + // "Combat Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "d59bd448-6401-4476-849a-e6fc86d28b7b", + "quantity": 1 + }, + { + // "Combat Wheel - 5x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "96fc86b1-57e7-4795-9d39-90e74f52ba87", + "quantity": 1 + }, + { + // "Combat Wheel - 7x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 28 + } + ], + "itemId": "fafdc38f-e374-49fd-8fea-4062a4b5c93a", + "quantity": 1 + }, + { + // "Combat Wheel - 9x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "4dee7b84-ee4c-42ce-9a42-4c6ced837ff5", + "quantity": 1 + }, + { + // "Combat Wheel - 11x4", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 32 + } + ], + "itemId": "583f20c9-a7da-477b-b852-aac404467e3a", + "quantity": 1 + }, + { + // "Combat Wheel - 13x5", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 35 + } + ], + "itemId": "90bc9601-b874-45e2-8970-09d5e5ff3ca9", + "quantity": 1 + }, + { + // "Sand Wheel - 3x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "abe5a33f-a3cc-41a8-b32a-731ec2b184c1", + "quantity": 1 + }, + { + // "Sand Wheel - 5x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 25 + } + ], + "itemId": "0761c82c-7a3f-4c22-8ec1-46223f10a2de", + "quantity": 1 + }, + { + // "Sand Wheel - 7x4", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "ee8869cb-9cce-43c3-a04a-e8b37b9de0ed", + "quantity": 1 + }, + { + // "Sand Wheel - 9x5", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 35 + } + ], + "itemId": "2210586c-3a93-43ff-b861-542e2d2d12d6", + "quantity": 1 + }, + { + // "Sand Wheel - 11x6", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 40 + } + ], + "itemId": "6afcb463-925a-4a2e-b9bf-3397ef094df9", + "quantity": 1 + }, + { + // "Sand Wheel - 13x6", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 45 + } + ], + "itemId": "b0f71aed-04f0-4bba-b969-cba57f3fc667", + "quantity": 1 + }, + { + // "Sand Wheel - 15x7", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 50 + } + ], + "itemId": "87f8f460-eba5-43c1-a1ad-facfb3d3f376", + "quantity": 1 + }, + { + // "Sand Wheel - 17x8", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 55 + } + ], + "itemId": "2bcc8c8f-1e94-4f9d-97b9-6e7423ca40b0", + "quantity": 1 + }, + { + // "Sand Wheel - 19x9", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 60 + } + ], + "itemId": "61a70b37-ea24-4022-b1e6-45a5a3ae179d", + "quantity": 1 + }, + { + // "Big Wheel - 7x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 40 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "036fc6d2-45df-11e6-beb8-9e71128cae77", + "quantity": 1 + }, + { + // "Big Wheel - 9x4", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 40 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 35 + } + ], + "itemId": "036fc79a-45df-11e6-beb8-9e71128cae77", + "quantity": 1 + }, + { + // "Chained Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 50 + } + ], + "itemId": "d739fdf9-2c61-47ea-88ab-beac6a6c35c0", + "quantity": 1 + }, + { + // "Spiked Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 60 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 60 + } + ], + "itemId": "d739fdf9-2c61-47ea-88ab-beac6a6c35c1", + "quantity": 1 + } +] \ No newline at end of file From ad5e06c3cfa26c798246b253355cacc859d92235 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 03:20:44 -0700 Subject: [PATCH 10/26] 3-Wide engine and Engine Suspension are now scripted --- Objects/Database/ShapeSets/interactive.json | 42 +- .../interactable/Locomotion/ModGasEngine.lua | 678 ++++++++++++++++++ 2 files changed, 686 insertions(+), 34 deletions(-) create mode 100644 Scripts/interactable/Locomotion/ModGasEngine.lua diff --git a/Objects/Database/ShapeSets/interactive.json b/Objects/Database/ShapeSets/interactive.json index a87e70d..3665322 100644 --- a/Objects/Database/ShapeSets/interactive.json +++ b/Objects/Database/ShapeSets/interactive.json @@ -345,27 +345,10 @@ }, "density": 1250.0, "physicsMaterial": "Metal", - "gasEngine": { - "gears": [ - { "velocity": 0, "power": 0 }, - { "velocity": 45, "power": 8 }, - { "velocity": 90, "power": 16 }, - { "velocity": 180, "power": 32 }, - { "velocity": 360, "power": 64 }, - { "velocity": 720, "power": 128 }, - { "velocity": 1440, "power": 256 }, - { "velocity": 2880, "power": 512 }, - { "velocity": 5760, "power": 1024 }, - { "velocity": 10000, "power": 2048 }, - { "velocity": 10000, "power": 4096 }, - { "velocity": 10000, "power": 8192 }, - { "velocity": 10000, "power": 16384 }, - { "velocity": 10000, "power": 32768 }, - { "velocity": 10000, "power": 65536 }, - { "velocity": 10000, "power": 131072 }, - { "velocity": 10000, "power": 262144 } - ], - "effect": "GasEngine - Level 1" + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModGasEngine.lua", + "classname": "GasEngine", + "data": {} }, "qualityLevel": 4 }, @@ -1064,19 +1047,10 @@ "box": { "x": 3, "y": 2, "z": 2 }, "density": 1250.0, "physicsMaterial": "Metal", - "gasEngine": { - "gears": [ - { "velocity": 0, "power": 0 }, - { "velocity": 45, "power": 8 }, - { "velocity": 90, "power": 16 }, - { "velocity": 180, "power": 32 }, - { "velocity": 360, "power": 64 }, - { "velocity": 720, "power": 128 }, - { "velocity": 1440, "power": 256 }, - { "velocity": 2880, "power": 512 }, - { "velocity": 5760, "power": 1024 } - ], - "effect": "GasEngine - Level 1" + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModGasEngine.lua", + "classname": "GasEngine", + "data": {} }, "qualityLevel": 5 }, diff --git a/Scripts/interactable/Locomotion/ModGasEngine.lua b/Scripts/interactable/Locomotion/ModGasEngine.lua new file mode 100644 index 0000000..6d9d75a --- /dev/null +++ b/Scripts/interactable/Locomotion/ModGasEngine.lua @@ -0,0 +1,678 @@ +-- GasEngine.lua -- +dofile("$SURVIVAL_DATA/Scripts/game/survival_constants.lua") +dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") + +dofile("$SURVIVAL_DATA/Scripts/util.lua") + +GasEngine = class() +GasEngine.maxParentCount = 2 +GasEngine.maxChildCount = 255 +GasEngine.connectionInput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power + sm.interactable.connectionType.gasoline +GasEngine.connectionOutput = sm.interactable.connectionType.bearing +GasEngine.colorNormal = sm.color.new( 0xff8000ff ) +GasEngine.colorHighlight = sm.color.new( 0xff9f3aff ) +GasEngine.poseWeightCount = 1 + +local ScrapGears = { + { power = 0 }, + { power = 30 }, + { power = 60 }, + { power = 90 } +} + +local Gears = { + { power = 0 }, + { power = 30 }, + { power = 60 }, + { power = 90 }, + { power = 150 }, -- 1 + { power = 240 }, + { power = 390 }, -- 2 + { power = 630 }, + { power = 1020 }, -- 3 + { power = 1650 }, + { power = 2670 }, -- 4 + { power = 4320 }, + { power = 6990 }, -- 5 +} + +--[[ Gas Engine 3-Wide old power settings + { "velocity": 0, "power": 0 }, + { "velocity": 45, "power": 8 }, + { "velocity": 90, "power": 16 }, + { "velocity": 180, "power": 32 }, + { "velocity": 360, "power": 64 }, + { "velocity": 720, "power": 128 }, + { "velocity": 1440, "power": 256 }, + { "velocity": 2880, "power": 512 }, + { "velocity": 5760, "power": 1024 } +]] + +local GasEngine3WideGears = { + { power = 0 }, + { power = 8 }, + { power = 16 }, + { power = 32 }, + { power = 64 }, + { power = 128 }, + { power = 256 }, + { power = 512 }, + { power = 1024 } +} + +--[[ Engine Suspension old power settings + { "velocity": 0, "power": 0 }, + { "velocity": 45, "power": 8 }, + { "velocity": 90, "power": 16 }, + { "velocity": 180, "power": 32 }, + { "velocity": 360, "power": 64 }, + { "velocity": 720, "power": 128 }, + { "velocity": 1440, "power": 256 }, + { "velocity": 2880, "power": 512 }, + { "velocity": 5760, "power": 1024 }, + { "velocity": 10000, "power": 2048 }, + { "velocity": 10000, "power": 4096 }, + { "velocity": 10000, "power": 8192 }, + { "velocity": 10000, "power": 16384 }, + { "velocity": 10000, "power": 32768 }, + { "velocity": 10000, "power": 65536 }, + { "velocity": 10000, "power": 131072 }, + { "velocity": 10000, "power": 262144 } +]] + +local EngineSuspensionGears = { + { power = 0 }, + { power = 8 }, + { power = 16 }, + { power = 32 }, + { power = 64 }, + { power = 128 }, + { power = 256 }, + { power = 512 }, + { power = 1024 }, + { power = 2048 }, + { power = 4096 }, + { power = 8192 }, + { power = 16384 }, + { power = 32768 }, + { power = 65536 }, + { power = 131072 }, + { power = 262144 } +} + +local EngineLevels = { + ["f55aa240-d4b2-48cc-9c6b-a90fce299bf4"] = { --Gas Engine 3-Wide + gears = GasEngine3WideGears, + gearCount = #GasEngine3WideGears, + title = "Modpack Continuation", + bearingCount = 5, + pointsPerFuel = 15000, + effect = "GasEngine - Level 1" + }, + ["93e08947-be6d-436c-a64f-932727428c89"] = { --Engine Suspension + gears = EngineSuspensionGears, + gearCount = #EngineSuspensionGears, + title = "Modpack Continuation", + bearingCount = 5, + pointsPerFuel = 11000, + effect = "GasEngine - Level 1" + } +} + +local RadPerSecond_100KmPerHourOn3BlockDiameterTyres = 74.074074 +local RadPerSecond_1MeterPerSecondOn3BlockDiameterTyres = 2.6666667 + +--[[ Server ]] + +function GasEngine.server_onCreate( self ) + local container = self.shape.interactable:getContainer( 0 ) + if not container then + container = self.shape:getInteractable():addContainer( 0, 1, 10 ) + end + container:setFilters( { obj_consumable_gas } ) + + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + assert(level) + if level.fn then + level.fn( self ) + end + + self.scrapOffset = 0 + self.pointsPerFuel = level.pointsPerFuel + self.gears = level.gears + self:server_init() +end + +function GasEngine.server_onRefresh( self ) + self:server_init() +end + +function GasEngine.server_init( self ) + + self.saved = self.storage:load() + if self.saved == nil then + self.saved = {} + end + if self.saved.gearIdx == nil then + self.saved.gearIdx = 1 + end + if self.saved.fuelPoints == nil then + self.saved.fuelPoints = 0 + end + + self.power = 0 + self.motorVelocity = 0 + self.motorImpulse = 0 + self.fuelPoints = self.saved.fuelPoints + self.hasFuel = false + self.dirtyStorageTable = false + self.dirtyClientTable = false + + self:sv_setGear( self.saved.gearIdx ) +end + +function GasEngine.sv_setGear( self, gearIdx ) + self.saved.gearIdx = gearIdx + self.dirtyStorageTable = true + self.dirtyClientTable = true +end + +function GasEngine.sv_updateFuelStatus( self, fuelContainer ) + + if self.saved.fuelPoints ~= self.fuelPoints then + self.saved.fuelPoints = self.fuelPoints + self.dirtyStorageTable = true + end + + local hasFuel = ( self.fuelPoints > 0 ) or sm.container.canSpend( fuelContainer, obj_consumable_gas, 1 ) + if self.hasFuel ~= hasFuel then + self.hasFuel = hasFuel + self.dirtyClientTable = true + end + +end + +function GasEngine.controlEngine( self, direction, active, timeStep, gearIdx ) + direction = clamp( direction, -1, 1 ) + if ( math.abs( direction ) > 0 or not active ) then + self.power = self.power + timeStep + else + self.power = self.power - timeStep + end + self.power = clamp( self.power, 0, 1 ) + + if direction == 0 and active then + self.power = 0 + end + + self.motorVelocity = ( active and direction or 0 ) * RadPerSecond_100KmPerHourOn3BlockDiameterTyres + self.motorImpulse = ( active and self.power or 2 ) * self.gears[gearIdx].power +end + +function GasEngine.getInputs( self ) + + local parents = self.interactable:getParents() + local active = true + local direction = 1 + local fuelContainer = nil + local hasInput = false + if parents[2] then + if parents[2]:hasOutputType( sm.interactable.connectionType.logic ) then + active = parents[2]:isActive() + hasInput = true + end + if parents[2]:hasOutputType( sm.interactable.connectionType.power ) then + active = parents[2]:isActive() + direction = parents[2]:getPower() + hasInput = true + end + if parents[2]:hasOutputType( sm.interactable.connectionType.gasoline ) then + fuelContainer = parents[2]:getContainer( 0 ) + end + end + if parents[1] then + if parents[1]:hasOutputType( sm.interactable.connectionType.logic ) then + active = parents[1]:isActive() + hasInput = true + end + if parents[1]:hasOutputType( sm.interactable.connectionType.power ) then + active = parents[1]:isActive() + direction = parents[1]:getPower() + hasInput = true + end + if parents[1]:hasOutputType( sm.interactable.connectionType.gasoline ) then + fuelContainer = parents[1]:getContainer( 0 ) + end + end + + return active, direction, fuelContainer, hasInput + +end + +function GasEngine.server_onFixedUpdate( self, timeStep ) + + -- Check engine connections + local hadInput = self.hasInput == nil and true or self.hasInput --Pretend to have had input if nil to avoid starting engines at load + local active, direction, fuelContainer, hasInput = self:getInputs() + self.hasInput = hasInput + local useCreativeFuel = not sm.game.getEnableFuelConsumption() and fuelContainer == nil + + -- Check fuel container + if not fuelContainer or fuelContainer:isEmpty() then + fuelContainer = self.shape.interactable:getContainer( 0 ) + end + + -- Check bearings + local bearings = {} + local joints = self.interactable:getJoints() + for _, joint in ipairs( joints ) do + if joint:getType() == "bearing" then + bearings[#bearings+1] = joint + end + end + + -- Update motor gear when a steering is added + if not hadInput and hasInput then + if self.saved.gearIdx == 1 then + self:sv_setGear( 2 ) + end + end + + -- Consume fuel for fuel points + local canSpend = false + if self.fuelPoints <= 0 then + canSpend = sm.container.canSpend( fuelContainer, obj_consumable_gas, 1 ) + end + + -- Control engine + if self.fuelPoints > 0 or canSpend or useCreativeFuel then + + if hasInput == false then + self.power = 1 + self:controlEngine( 1, true, timeStep, self.saved.gearIdx ) + else + self:controlEngine( direction, active, timeStep, self.saved.gearIdx ) + end + + if not useCreativeFuel then + -- Consume fuel points + local appliedImpulseCost = 0.015625 + local fuelCost = 0 + for _, bearing in ipairs( bearings ) do + if bearing.appliedImpulse * bearing.angularVelocity < 0 then -- No added fuel cost if the bearing is decelerating + fuelCost = fuelCost + math.abs( bearing.appliedImpulse ) * appliedImpulseCost + end + end + fuelCost = math.min( fuelCost, math.sqrt( fuelCost / 7.5 ) * 7.5 ) + + self.fuelPoints = self.fuelPoints - fuelCost + + if self.fuelPoints <= 0 and fuelCost > 0 then + sm.container.beginTransaction() + sm.container.spend( fuelContainer, obj_consumable_gas, 1, true ) + if sm.container.endTransaction() then + self.fuelPoints = self.fuelPoints + self.pointsPerFuel + end + end + end + + else + self:controlEngine( 0, false, timeStep, self.saved.gearIdx ) + end + + -- Update rotational joints + for _, bearing in ipairs( bearings ) do + bearing:setMotorVelocity( self.motorVelocity, self.motorImpulse ) + end + + self:sv_updateFuelStatus( fuelContainer ) + + -- Storage table dirty + if self.dirtyStorageTable then + self.storage:save( self.saved ) + self.dirtyStorageTable = false + end + + -- Client table dirty + if self.dirtyClientTable then + self.network:setClientData( { gearIdx = self.saved.gearIdx, engineHasFuel = self.hasFuel or useCreativeFuel, scrapOffset = self.scrapOffset } ) + self.dirtyClientTable = false + end +end + +--[[ Client ]] + +function GasEngine.client_onCreate( self ) + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + self.gears = level.gears + self.client_gearIdx = 1 + self.effect = sm.effect.createEffect( level.effect, self.interactable ) + self.engineHasFuel = false + self.scrapOffset = self.scrapOffset or 0 + self.power = 0 +end + +function GasEngine.client_onClientDataUpdate( self, params ) + + if self.gui then + if self.gui:isActive() and params.gearIdx ~= self.client_gearIdx then + self.gui:setSliderPosition("Setting", params.gearIdx - 1 ) + end + end + + self.client_gearIdx = params.gearIdx + self.interactable:setPoseWeight( 0, params.gearIdx / #self.gears ) + + if self.engineHasFuel and not params.engineHasFuel then + local character = sm.localPlayer.getPlayer().character + if character then + if ( self.shape.worldPosition - character.worldPosition ):length2() < 100 then + sm.gui.displayAlertText( "#{INFO_OUT_OF_FUEL}" ) + end + end + end + + if params.engineHasFuel then + self.effect:setParameter("gas", 0.0 ) + else + self.effect:setParameter("gas", 1.0 ) + end + + self.engineHasFuel = params.engineHasFuel + self.scrapOffset = params.scrapOffset +end + +function GasEngine.client_onDestroy( self ) + self.effect:destroy() + + if self.gui then + self.gui:close() + self.gui:destroy() + self.gui = nil + end +end + +function GasEngine.client_onFixedUpdate( self, timeStep ) + + local active, direction, externalFuelTank, hasInput = self:getInputs() + + + if self.gui then + self.gui:setVisible( "FuelContainer", externalFuelTank ~= nil ) + end + + if sm.isHost then + return + end + + -- Check bearings + local bearings = {} + local joints = self.interactable:getJoints() + for _, joint in ipairs( joints ) do + if joint:getType() == "bearing" then + bearings[#bearings+1] = joint + end + end + + -- Control engine + if self.engineHasFuel then + if hasInput == false then + self.power = 1 + + self:controlEngine( 1, true, timeStep, self.client_gearIdx ) + else + + self:controlEngine( direction, active, timeStep, self.client_gearIdx ) + end + else + self:controlEngine( 0, false, timeStep, self.client_gearIdx ) + end + + -- Update rotational joints + for _, bearing in ipairs( bearings ) do + bearing:setMotorVelocity( self.motorVelocity, self.motorImpulse ) + end +end + +function GasEngine.client_onUpdate( self, dt ) + + local active, direction = self:getInputs() + + self:cl_updateEffect( direction, active ) +end + +function GasEngine.client_onInteract( self, character, state ) + if state == true then + self.gui = sm.gui.createEngineGui() + + self.gui:setText( "Name", "#{CONTROLLER_ENGINE_GAS_TITLE}" ) + self.gui:setText( "Interaction", "#{CONTROLLER_ENGINE_INSTRUCTION}" ) + self.gui:setOnCloseCallback( "cl_onGuiClosed" ) + self.gui:setSliderCallback( "Setting", "cl_onSliderChange" ) + self.gui:setSliderData( "Setting", #self.gears, self.client_gearIdx - 1 ) + self.gui:setIconImage( "Icon", self.shape:getShapeUuid() ) + self.gui:setButtonCallback( "Upgrade", "cl_onUpgradeClicked" ) + + local fuelContainer = self.shape.interactable:getContainer( 0 ) + + if fuelContainer then + self.gui:setContainer( "Fuel", fuelContainer ) + end + + local _, _, externalFuelContainer, _ = self:getInputs() + if externalFuelContainer then + self.gui:setVisible( "FuelContainer", true ) + end + + if not sm.game.getEnableFuelConsumption() then + self.gui:setVisible( "BackgroundGas", false ) + self.gui:setVisible( "FuelGrid", false ) + end + + self.gui:open() + + local level = EngineLevels[ tostring( self.shape:getShapeUuid() ) ] + if level then + if level.upgrade then + local nextLevel = EngineLevels[ level.upgrade ] + self.gui:setData( "UpgradeInfo", { Gears = nextLevel.gearCount - level.gearCount, Bearings = nextLevel.bearingCount - level.bearingCount, Efficiency = 1 } ) + self.gui:setIconImage( "UpgradeIcon", sm.uuid.new( level.upgrade ) ) + else + self.gui:setVisible( "UpgradeIcon", false ) + self.gui:setData( "UpgradeInfo", nil ) + end + + self.gui:setText( "SubTitle", level.title ) + self.gui:setSliderRangeLimit( "Setting", level.gearCount ) + + if sm.game.getEnableUpgrade() and level.cost then + local inventory = sm.localPlayer.getPlayer():getInventory() + local availableKits = sm.container.totalQuantity( inventory, obj_consumable_component ) + local upgradeData = { cost = level.cost, available = availableKits } + self.gui:setData( "Upgrade", upgradeData ) + else + self.gui:setVisible( "Upgrade", false ) + end + end + end +end + +function GasEngine.client_getAvailableParentConnectionCount( self, connectionType ) + if bit.band( connectionType, bit.bor( sm.interactable.connectionType.logic, sm.interactable.connectionType.power ) ) ~= 0 then + return 1 - #self.interactable:getParents( bit.bor( sm.interactable.connectionType.logic, sm.interactable.connectionType.power ) ) + end + if bit.band( connectionType, sm.interactable.connectionType.gasoline ) ~= 0 then + return 1 - #self.interactable:getParents( sm.interactable.connectionType.gasoline ) + end + return 0 +end + +function GasEngine.client_getAvailableChildConnectionCount( self, connectionType ) + if connectionType ~= sm.interactable.connectionType.bearing then + return 0 + end + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + assert(level) + local maxBearingCount = level.bearingCount or 255 + return maxBearingCount - #self.interactable:getChildren( sm.interactable.connectionType.bearing ) +end + +function GasEngine.cl_onGuiClosed( self ) + self.gui:destroy() + self.gui = nil +end + +function GasEngine.cl_onSliderChange( self, sliderName, sliderPos ) + self.network:sendToServer( "sv_setGear", sliderPos + 1 ) + self.client_gearIdx = sliderPos + 1 +end + +function GasEngine.cl_onUpgradeClicked( self, buttonName ) + print( "upgrade clicked" ) + self.network:sendToServer("sv_n_tryUpgrade", sm.localPlayer.getPlayer() ) +end + +function GasEngine.cl_updateEffect( self, direction, active ) + local bearings = {} + local joints = self.interactable:getJoints() + for _, joint in ipairs( joints ) do + if joint:getType() == "bearing" then + bearings[#bearings+1] = joint + end + end + + local RadPerSecond_100KmPerHourOn3BlockDiameterTyres = 74.074074 + local avgImpulse = 0 + local avgVelocity = 0 + + if #bearings > 0 then + for _, currentBearing in ipairs( bearings ) do + avgImpulse = avgImpulse + math.abs( currentBearing.appliedImpulse ) + avgVelocity = avgVelocity + math.abs( currentBearing.angularVelocity ) + end + + avgImpulse = avgImpulse / #bearings + avgVelocity = avgVelocity / #bearings + + avgVelocity = math.min( avgVelocity, RadPerSecond_100KmPerHourOn3BlockDiameterTyres ) + end + + local impulseFraction = 0 + local velocityFraction = avgVelocity / ( RadPerSecond_100KmPerHourOn3BlockDiameterTyres / 1.2 ) + + if direction ~= 0 and self.gears[self.client_gearIdx].power > 0 then + impulseFraction = math.abs( avgImpulse ) / self.gears[self.client_gearIdx].power + end + + local maxRPM = 0.9 * (self.client_gearIdx / #self.gears) + local rpm = 0.1 + + if avgVelocity > 0 then + rpm = rpm + math.min( velocityFraction * maxRPM, maxRPM ) + end + + local engineLoad = 0 + + if direction ~= 0 then + engineLoad = impulseFraction - math.min( velocityFraction, 1.0 ) + end + + local onLift = self.shape:getBody():isOnLift() + if #self.interactable:getParents() == 0 then + if self.effect:isPlaying() == false and #bearings > 0 and not onLift and self.gears[self.client_gearIdx].power > 0 then + self.effect:start() + elseif self.effect:isPlaying() and ( #bearings == 0 or onLift or self.gears[self.client_gearIdx].power == 0 ) then + self.effect:setParameter( "load", 0.5 ) + self.effect:setParameter( "rpm", 0 ) + self.effect:stop() + end + else + if self.effect:isPlaying() and ( #bearings == 0 or onLift or active == false or self.gears[self.client_gearIdx].power == 0 ) then + self.effect:setParameter( "load", 0.5 ) + self.effect:setParameter( "rpm", 0 ) + self.effect:stop() + elseif self.effect:isPlaying() == false and #bearings > 0 and not onLift and active == true and self.gears[self.client_gearIdx].power > 0 then + self.effect:start() + end + end + + if self.effect:isPlaying() then + self.effect:setParameter( "rpm", rpm ) + self.effect:setParameter( "load", engineLoad * 0.5 + 0.5 ) + end +end + +function GasEngine.sv_n_tryUpgrade( self, player ) + + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + if level and level.upgrade then + local function fnUpgrade() + local nextLevel = EngineLevels[level.upgrade] + assert( nextLevel ) + self.gears = nextLevel.gears + self.network:sendToClients( "cl_n_onUpgrade", level.upgrade ) + + if nextLevel.fn then + nextLevel.fn( self ) + end + + self.shape:replaceShape( sm.uuid.new( level.upgrade ) ) + end + + if sm.game.getEnableUpgrade() then + local inventory = player:getInventory() + + if sm.container.totalQuantity( inventory, obj_consumable_component ) >= level.cost then + + if sm.container.beginTransaction() then + sm.container.spend( inventory, obj_consumable_component, level.cost, true ) + + if sm.container.endTransaction() then + fnUpgrade() + end + end + else + print( "Cannot afford upgrade" ) + end + end + else + print( "Can't be upgraded" ) + end + +end + +function GasEngine.cl_n_onUpgrade( self, upgrade ) + local level = EngineLevels[upgrade] + self.gears = level.gears + self.pointsPerFuel = level.pointsPerFuel + + if self.gui and self.gui:isActive() then + self.gui:setIconImage( "Icon", sm.uuid.new( upgrade ) ) + + if sm.game.getEnableUpgrade() and level.cost then + local inventory = sm.localPlayer.getPlayer():getInventory() + local availableKits = sm.container.totalQuantity( inventory, obj_consumable_component ) + local upgradeData = { cost = level.cost, available = availableKits } + self.gui:setData( "Upgrade", upgradeData ) + else + self.gui:setVisible( "Upgrade", false ) + end + + self.gui:setText( "SubTitle", level.title ) + self.gui:setSliderRangeLimit( "Setting", level.gearCount ) + if level.upgrade then + local nextLevel = EngineLevels[ level.upgrade ] + self.gui:setData( "UpgradeInfo", { Gears = nextLevel.gearCount - level.gearCount, Bearings = nextLevel.bearingCount - level.bearingCount, Efficiency = 1 } ) + self.gui:setIconImage( "UpgradeIcon", sm.uuid.new( level.upgrade ) ) + else + self.gui:setVisible( "UpgradeIcon", false ) + self.gui:setData( "UpgradeInfo", nil ) + end + end + + if self.effect then + --self.effect:destroy() + end + self.effect = sm.effect.createEffect( level.effect, self.interactable ) + sm.effect.playHostedEffect( "Part - Upgrade", self.interactable ) +end \ No newline at end of file From 068a1b0abebaa5d1dacfae967683379c997ca5ae Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 05:26:20 -0700 Subject: [PATCH 11/26] Added the old engine parts back --- CraftingRecipes/craftbot.json | 4 +- .../English/inventoryDescriptions.json | 12 ++ Objects/Database/ShapeSets/interactive.json | 106 +++++++++++++++++- .../interactable/Locomotion/ModGasEngine.lua | 43 +------ 4 files changed, 120 insertions(+), 45 deletions(-) diff --git a/CraftingRecipes/craftbot.json b/CraftingRecipes/craftbot.json index 5fe8898..0b7d57b 100644 --- a/CraftingRecipes/craftbot.json +++ b/CraftingRecipes/craftbot.json @@ -292,7 +292,7 @@ "quantity": 15 } ], - "itemId": "93e08947-be6d-436c-a64f-932727428c89", + "itemId": "b69bf080-2467-4360-9677-72cfd48806c9", "quantity": 1 }, { @@ -1500,7 +1500,7 @@ "quantity": 5 } ], - "itemId": "f55aa240-d4b2-48cc-9c6b-a90fce299bf4", + "itemId": "70cbacf2-ec5a-471f-9896-0ee944c581d1", "quantity": 1 }, { diff --git a/Gui/Language/English/inventoryDescriptions.json b/Gui/Language/English/inventoryDescriptions.json index 54a0fb2..3753a43 100644 --- a/Gui/Language/English/inventoryDescriptions.json +++ b/Gui/Language/English/inventoryDescriptions.json @@ -112,6 +112,12 @@ "keywords": [ "modpack", "spring" ] }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Engine Suspension [#ffff00DEPRECATED#ffffff]", + "description": "This part is an engine! Put this part on a bearing and connect this engine to the bearing! Connect some pipes to one end where your wheel (and steering) will go, and use the other end to limit the range of movement. Set the power of this engine for a loose or firm engine-suspension.", + "keywords": [ "modpack", "motor", "suspension", "spring", "angle", "controller" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Engine Suspension", "description": "This part is an engine! Put this part on a bearing and connect this engine to the bearing! Connect some pipes to one end where your wheel (and steering) will go, and use the other end to limit the range of movement. Set the power of this engine for a loose or firm engine-suspension.", @@ -194,6 +200,12 @@ // engines "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Gas Engine 3-Wide [#ffff00DEPRECATED#ffffff]", + "description": "It's a gas engine that conforms to the size of an electric engine. Perfect for balance gas-powered odd-width creations!", + "keywords": [ "modpack", "motor", "odd", "odd-width", "width" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Gas Engine 3-Wide", "description": "It's a gas engine that conforms to the size of an electric engine. Perfect for balance gas-powered odd-width creations!", diff --git a/Objects/Database/ShapeSets/interactive.json b/Objects/Database/ShapeSets/interactive.json index 3665322..e6abf96 100644 --- a/Objects/Database/ShapeSets/interactive.json +++ b/Objects/Database/ShapeSets/interactive.json @@ -310,7 +310,68 @@ "stackSize": 5 }, { - "uuid": "93e08947-be6d-436c-a64f-932727428c89", + "uuid": "93e08947-be6d-436c-a64f-932727428c89", //OLD Engine Suspension + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$MOD_DATA/Objects/Textures/mod_decor_cone_dif.png", + "$MOD_DATA/Objects/Textures/mod_decor_cone_asg.png", + "$GAME_DATA/Textures/nonor_nor.tga" + ], + "material": "DifAsg" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/mjm_EngineSuspension.mesh" + } + ] + }, + "rotationSet": "PropY", + "color": "df7f00", + "hull": { + "x": 1, "y": 1, "z": 3, + "pointList": [ + { "x": 0.0, "y": 1.0, "z": 1.0 }, + { "x": 1.0, "y": 0.0, "z": 1.0 }, + { "x": 0.0, "y": -1.0, "z": 1.0 }, + { "x": -1.0, "y": 0.0, "z": 1.0 }, + { "x": -0.1, "y": 1.0, "z": -1.0 }, + { "x": 0.1, "y": 1.0, "z": -1.0 }, + { "x": 0.1, "y": -1.0, "z": -1.0 }, + { "x": -0.1, "y": -1.0, "z": -1.0 } + ] + }, + "density": 1250.0, + "physicsMaterial": "Metal", + "gasEngine": { + "gears": [ + { "velocity": 0, "power": 0 }, + { "velocity": 45, "power": 8 }, + { "velocity": 90, "power": 16 }, + { "velocity": 180, "power": 32 }, + { "velocity": 360, "power": 64 }, + { "velocity": 720, "power": 128 }, + { "velocity": 1440, "power": 256 }, + { "velocity": 2880, "power": 512 }, + { "velocity": 5760, "power": 1024 }, + { "velocity": 10000, "power": 2048 }, + { "velocity": 10000, "power": 4096 }, + { "velocity": 10000, "power": 8192 }, + { "velocity": 10000, "power": 16384 }, + { "velocity": 10000, "power": 32768 }, + { "velocity": 10000, "power": 65536 }, + { "velocity": 10000, "power": 131072 }, + { "velocity": 10000, "power": 262144 } + ], + "effect": "GasEngine - Level 1" + }, + "qualityLevel": 4, + "showInInventory": false + }, + { + "uuid": "b69bf080-2467-4360-9677-72cfd48806c9", //NEW Engine Suspension "renderable": { "lodList": [ { @@ -1024,7 +1085,48 @@ "flammable": false }, { - "uuid": "f55aa240-d4b2-48cc-9c6b-a90fce299bf4", + "uuid": "f55aa240-d4b2-48cc-9c6b-a90fce299bf4", //OLD Gas Engine 3-Wide + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginegas_dif.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginegas_asg.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginegas_nor.tga" + ], + "material": "DifAsgNor" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/mjm_EngineGasOdd.mesh" + } + ] + }, + "rotationSet": "PropYf", + "color": "df7f00", + "box": { "x": 3, "y": 2, "z": 2 }, + "density": 1250.0, + "physicsMaterial": "Metal", + "gasEngine": { + "gears": [ + { "velocity": 0, "power": 0 }, + { "velocity": 45, "power": 8 }, + { "velocity": 90, "power": 16 }, + { "velocity": 180, "power": 32 }, + { "velocity": 360, "power": 64 }, + { "velocity": 720, "power": 128 }, + { "velocity": 1440, "power": 256 }, + { "velocity": 2880, "power": 512 }, + { "velocity": 5760, "power": 1024 } + ], + "effect": "GasEngine - Level 1" + }, + "qualityLevel": 5, + "showInInventory": false + }, + { + "uuid": "70cbacf2-ec5a-471f-9896-0ee944c581d1", //NEW Gas Engine 3-Wide "renderable": { "lodList": [ { diff --git a/Scripts/interactable/Locomotion/ModGasEngine.lua b/Scripts/interactable/Locomotion/ModGasEngine.lua index 6d9d75a..d41c11e 100644 --- a/Scripts/interactable/Locomotion/ModGasEngine.lua +++ b/Scripts/interactable/Locomotion/ModGasEngine.lua @@ -13,13 +13,6 @@ GasEngine.colorNormal = sm.color.new( 0xff8000ff ) GasEngine.colorHighlight = sm.color.new( 0xff9f3aff ) GasEngine.poseWeightCount = 1 -local ScrapGears = { - { power = 0 }, - { power = 30 }, - { power = 60 }, - { power = 90 } -} - local Gears = { { power = 0 }, { power = 30 }, @@ -36,18 +29,6 @@ local Gears = { { power = 6990 }, -- 5 } ---[[ Gas Engine 3-Wide old power settings - { "velocity": 0, "power": 0 }, - { "velocity": 45, "power": 8 }, - { "velocity": 90, "power": 16 }, - { "velocity": 180, "power": 32 }, - { "velocity": 360, "power": 64 }, - { "velocity": 720, "power": 128 }, - { "velocity": 1440, "power": 256 }, - { "velocity": 2880, "power": 512 }, - { "velocity": 5760, "power": 1024 } -]] - local GasEngine3WideGears = { { power = 0 }, { power = 8 }, @@ -60,26 +41,6 @@ local GasEngine3WideGears = { { power = 1024 } } ---[[ Engine Suspension old power settings - { "velocity": 0, "power": 0 }, - { "velocity": 45, "power": 8 }, - { "velocity": 90, "power": 16 }, - { "velocity": 180, "power": 32 }, - { "velocity": 360, "power": 64 }, - { "velocity": 720, "power": 128 }, - { "velocity": 1440, "power": 256 }, - { "velocity": 2880, "power": 512 }, - { "velocity": 5760, "power": 1024 }, - { "velocity": 10000, "power": 2048 }, - { "velocity": 10000, "power": 4096 }, - { "velocity": 10000, "power": 8192 }, - { "velocity": 10000, "power": 16384 }, - { "velocity": 10000, "power": 32768 }, - { "velocity": 10000, "power": 65536 }, - { "velocity": 10000, "power": 131072 }, - { "velocity": 10000, "power": 262144 } -]] - local EngineSuspensionGears = { { power = 0 }, { power = 8 }, @@ -101,7 +62,7 @@ local EngineSuspensionGears = { } local EngineLevels = { - ["f55aa240-d4b2-48cc-9c6b-a90fce299bf4"] = { --Gas Engine 3-Wide + ["70cbacf2-ec5a-471f-9896-0ee944c581d1"] = { --Gas Engine 3-Wide gears = GasEngine3WideGears, gearCount = #GasEngine3WideGears, title = "Modpack Continuation", @@ -109,7 +70,7 @@ local EngineLevels = { pointsPerFuel = 15000, effect = "GasEngine - Level 1" }, - ["93e08947-be6d-436c-a64f-932727428c89"] = { --Engine Suspension + ["b69bf080-2467-4360-9677-72cfd48806c9"] = { --Engine Suspension gears = EngineSuspensionGears, gearCount = #EngineSuspensionGears, title = "Modpack Continuation", From 7b192c0ccc1ca0f9f7f9f94dfd545119a9200caa Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 05:33:39 -0700 Subject: [PATCH 12/26] Added icons for the new versions of engines --- Gui/IconMap.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Gui/IconMap.xml b/Gui/IconMap.xml index e49f441..a394e54 100644 --- a/Gui/IconMap.xml +++ b/Gui/IconMap.xml @@ -59,6 +59,9 @@ + + + @@ -97,6 +100,9 @@ + + + From 8c6fe295bf520569df5edaa4ecfbf7d3e4d4245d Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 07:04:38 -0700 Subject: [PATCH 13/26] SmartThruster consumes fuel in survival mode now --- .../interactable/Locomotion/SmartThruster.lua | 50 ++++++++++++++++--- Scripts/libs/fuel_consumption_manager.lua | 20 ++++++++ Scripts/libs/load_libs.lua | 1 + 3 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 Scripts/libs/fuel_consumption_manager.lua diff --git a/Scripts/interactable/Locomotion/SmartThruster.lua b/Scripts/interactable/Locomotion/SmartThruster.lua index 4c9abca..b562332 100644 --- a/Scripts/interactable/Locomotion/SmartThruster.lua +++ b/Scripts/interactable/Locomotion/SmartThruster.lua @@ -2,6 +2,7 @@ Copyright (c) 2020 Modpack Team Brent Batch#9261 ]]-- + dofile "../../libs/load_libs.lua" print("loading SmartThruster.lua") @@ -10,7 +11,7 @@ print("loading SmartThruster.lua") SmartThruster = class( nil ) SmartThruster.maxParentCount = -1 SmartThruster.maxChildCount = 0 -SmartThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +SmartThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.gasoline SmartThruster.connectionOutput = sm.interactable.connectionType.none SmartThruster.colorNormal = sm.color.new( 0x009999ff ) SmartThruster.colorHighlight = sm.color.new( 0x11B2B2ff ) @@ -18,7 +19,8 @@ SmartThruster.poseWeightCount = 2 function SmartThruster.server_onCreate( self ) - + self.sv_fuel_points = self.storage:load() or 0 + self.sv_saved_fuel_points = self.sv_fuel_points end function SmartThruster.server_onRefresh( self ) @@ -26,16 +28,16 @@ function SmartThruster.server_onRefresh( self ) end - +local st_logic_and_power = bit.bor(sm.interactable.connectionType.power, sm.interactable.connectionType.logic) function SmartThruster.server_onFixedUpdate( self, dt ) - local parents = self.interactable:getParents() + local parents = self.interactable:getParents(st_logic_and_power) local power = #parents>0 and 100 or 0 local hasnumber = false local logicinput = 1 for k,v in pairs(parents) do local typeparent = v:getType() - if v:getType() == "scripted" and tostring(v:getShape():getShapeUuid()) ~= "6f2dd83e-bc0d-43f3-8ba5-d5209eb03d07" then + if typeparent == "scripted" and tostring(v:getShape():getShapeUuid()) ~= "6f2dd83e-bc0d-43f3-8ba5-d5209eb03d07" then -- number if not hasnumber then power = 1 end power = power * v.power @@ -51,13 +53,44 @@ function SmartThruster.server_onFixedUpdate( self, dt ) if math.abs(power) >= 3.3*10^38 then -- inf check if power < 0 then power = -3.3*10^38 else power = 3.3*10^38 end end + + local can_consume_fuel = sm.game.getEnableFuelConsumption() + if can_consume_fuel and self.sv_fuel_points <= 0 then + power = 0 + end mp_updateOutputData(self, power * (logicinput or 1), logicinput > 0) - power = power * logicinput - + if power ~= 0 and math.abs(power) ~= math.huge then sm.physics.applyImpulse(self.shape, sm.vec3.new(0,0, 0 - power)) + + if can_consume_fuel then + local abs_power = math.abs(power) * 0.35 + self.sv_fuel_points = self.sv_fuel_points - (abs_power * dt) --calculate fuel consumption + end + end + + mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + self.storage:save(self.sv_saved_fuel_points) + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfFuel") + end + end +end + +function SmartThruster:client_onOutOfFuel() + local l_player = sm.localPlayer.getPlayer() + local l_character = l_player:getCharacter() + + if l_character then + if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then + sm.gui.displayAlertText("#{INFO_OUT_OF_FUEL}") + end end end @@ -97,7 +130,8 @@ function SmartThruster.client_onUpdate(self, dt) -- 1 tick delayed vs server but else if self.shootEffect:isPlaying() then - self.shootEffect:stop() end + self.shootEffect:stop() + end end self.interactable:setPoseWeight(0, poseVal0) diff --git a/Scripts/libs/fuel_consumption_manager.lua b/Scripts/libs/fuel_consumption_manager.lua new file mode 100644 index 0000000..92dc00c --- /dev/null +++ b/Scripts/libs/fuel_consumption_manager.lua @@ -0,0 +1,20 @@ +dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") --to get the uuids of consumable items + +function mp_fuel_updateFuelConsumption(self, obj_uuid, fuel_points) + if not sm.game.getEnableFuelConsumption() or self.sv_fuel_points > 0 then return end + + local parents = self.interactable:getParents(sm.interactable.connectionType.gasoline) + for k, v in pairs(parents) do + local gas_container = v:getContainer() + + if sm.container.canSpend(gas_container, obj_uuid, 1) then + sm.container.beginTransaction() + sm.container.spend(gas_container, obj_uuid, 1, true) + + if sm.container.endTransaction() then + self.sv_fuel_points = fuel_points + break + end + end + end +end \ No newline at end of file diff --git a/Scripts/libs/load_libs.lua b/Scripts/libs/load_libs.lua index ec3c925..cd00180 100644 --- a/Scripts/libs/load_libs.lua +++ b/Scripts/libs/load_libs.lua @@ -18,6 +18,7 @@ dofile "color.lua" dofile "math.lua" dofile "other.lua" dofile "virtual_buttons.lua" +dofile "fuel_consumption_manager.lua" dofile "game_improvements/interactable.lua" From 9dc2eba6006cf24ba5e5c29a5304eb74de6af2c8 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 09:02:44 -0700 Subject: [PATCH 14/26] WASD thruster can consume fuel now --- .../interactable/Locomotion/SmartThruster.lua | 17 +----- .../interactable/Locomotion/WASDThruster.lua | 59 ++++++++++++++++--- Scripts/libs/fuel_consumption_manager.lua | 22 ++++++- 3 files changed, 75 insertions(+), 23 deletions(-) diff --git a/Scripts/interactable/Locomotion/SmartThruster.lua b/Scripts/interactable/Locomotion/SmartThruster.lua index b562332..6c5d108 100644 --- a/Scripts/interactable/Locomotion/SmartThruster.lua +++ b/Scripts/interactable/Locomotion/SmartThruster.lua @@ -54,8 +54,7 @@ function SmartThruster.server_onFixedUpdate( self, dt ) if power < 0 then power = -3.3*10^38 else power = 3.3*10^38 end end - local can_consume_fuel = sm.game.getEnableFuelConsumption() - if can_consume_fuel and self.sv_fuel_points <= 0 then + if sm.game.getEnableFuelConsumption() and self.sv_fuel_points <= 0 then power = 0 end @@ -65,10 +64,7 @@ function SmartThruster.server_onFixedUpdate( self, dt ) if power ~= 0 and math.abs(power) ~= math.huge then sm.physics.applyImpulse(self.shape, sm.vec3.new(0,0, 0 - power)) - if can_consume_fuel then - local abs_power = math.abs(power) * 0.35 - self.sv_fuel_points = self.sv_fuel_points - (abs_power * dt) --calculate fuel consumption - end + mp_fuel_consumeFuelPoints(self, power, 0.35, dt) end mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) @@ -84,14 +80,7 @@ function SmartThruster.server_onFixedUpdate( self, dt ) end function SmartThruster:client_onOutOfFuel() - local l_player = sm.localPlayer.getPlayer() - local l_character = l_player:getCharacter() - - if l_character then - if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then - sm.gui.displayAlertText("#{INFO_OUT_OF_FUEL}") - end - end + mp_fuel_displayOutOfFuelMessage(self) end diff --git a/Scripts/interactable/Locomotion/WASDThruster.lua b/Scripts/interactable/Locomotion/WASDThruster.lua index d0a6ab8..5b6c6cd 100644 --- a/Scripts/interactable/Locomotion/WASDThruster.lua +++ b/Scripts/interactable/Locomotion/WASDThruster.lua @@ -9,7 +9,7 @@ print("loading WASDThruster.lua") WASDThruster = class( nil ) WASDThruster.maxParentCount = -1 WASDThruster.maxChildCount = 0 -WASDThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +WASDThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.gasoline WASDThruster.connectionOutput = sm.interactable.connectionType.none WASDThruster.colorNormal = sm.color.new( 0x009999ff ) WASDThruster.colorHighlight = sm.color.new( 0x11B2B2ff ) @@ -26,11 +26,21 @@ function WASDThruster.server_init( self ) self.power = 0 self.direction = sm.vec3.new(0,0,1) self.smode = 0 + + self.sv_fuel_points = 0 local stored = self.storage:load() - if stored and type(stored)=="number" then - self.smode = stored - 1 + if stored then + local stored_type = type(stored) + if stored_type == "number" then + self.smode = stored - 1 + elseif stored_type == "table" then + self.smode = stored[1] - 1 + self.sv_fuel_points = stored[2] + end end + + self.sv_saved_fuel_points = self.sv_fuel_points end function WASDThruster.server_onRefresh( self ) @@ -44,10 +54,35 @@ function WASDThruster.server_onFixedUpdate( self, dt ) if self.power > 0 and math.abs(self.power) ~= math.huge then sm.physics.applyImpulse(self.shape, self.direction*self.power*-1) --print(self.direction) + + mp_fuel_consumeFuelPoints(self, self.power, 0.35, dt) + end + + mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + + self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) + self.network:setClientData(self.sv_fuel_points > 0) + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfFuel") + end end end +function WASDThruster:client_onClientDataUpdate(params) + self.cl_has_fuel = params +end + + +function WASDThruster:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self) +end + + function WASDThruster.client_onCreate(self) self.shootEffect = sm.effect.createEffect( "Thruster - Level 2", self.interactable ) self.shootEffect:setOffsetPosition(sm.vec3.zero()) @@ -67,7 +102,7 @@ end function WASDThruster.client_onDestroy(self) - self.shootEffect:stop() + self.shootEffect:stopImmediate() end function WASDThruster.client_onInteract(self, character, lookAt) @@ -77,7 +112,7 @@ end function WASDThruster.server_changemode(self, crouch) self.smode = (self.smode + (crouch and -1 or 1))%4 - self.storage:save(self.smode+1) + self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) self.network:sendToClients("client_mode", {self.smode, true}) end @@ -109,8 +144,9 @@ function WASDThruster.client_canInteract(self) end +local wasdt_logic_and_power = bit.bor(sm.interactable.connectionType.logic, sm.interactable.connectionType.power) function WASDThruster.client_onFixedUpdate(self, dt) - local parents = self.interactable:getParents() + local parents = self.interactable:getParents(wasdt_logic_and_power) local power = #parents>0 and 100 or 0 local hasnumber = false local logicinput = 1 @@ -225,12 +261,19 @@ function WASDThruster.client_onFixedUpdate(self, dt) local worldRot = sm.vec3.getRotation( getLocal(self.shape,sm.shape.getUp(self.shape)),self.direction) self.shootEffect:setOffsetRotation(worldRot) --self.shootEffect:setOffsetPosition((-sm.vec3.new(0,0,1.25)+self.direction)*0.36) --old calculations + + if sm.game.getEnableAmmoConsumption() and not self.cl_has_fuel then + self.power = 0 + end + if self.power > 0 then if not self.shootEffect:isPlaying() then - self.shootEffect:start() end + self.shootEffect:start() + end else if self.shootEffect:isPlaying() then - self.shootEffect:stop() end + self.shootEffect:stop() + end end diff --git a/Scripts/libs/fuel_consumption_manager.lua b/Scripts/libs/fuel_consumption_manager.lua index 92dc00c..9a9ba20 100644 --- a/Scripts/libs/fuel_consumption_manager.lua +++ b/Scripts/libs/fuel_consumption_manager.lua @@ -1,7 +1,16 @@ dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") --to get the uuids of consumable items +local _sm_getEnableFuelConsumption = sm.game.getEnableFuelConsumption + +function mp_fuel_consumeFuelPoints(self, power, multiplier, dt) + if _sm_getEnableFuelConsumption() then + local abs_power = math.abs(power) * multiplier + self.sv_fuel_points = self.sv_fuel_points - (abs_power * dt) --calculate fuel consumption + end +end + function mp_fuel_updateFuelConsumption(self, obj_uuid, fuel_points) - if not sm.game.getEnableFuelConsumption() or self.sv_fuel_points > 0 then return end + if not _sm_getEnableFuelConsumption() or self.sv_fuel_points > 0 then return end local parents = self.interactable:getParents(sm.interactable.connectionType.gasoline) for k, v in pairs(parents) do @@ -17,4 +26,15 @@ function mp_fuel_updateFuelConsumption(self, obj_uuid, fuel_points) end end end +end + +function mp_fuel_displayOutOfFuelMessage(self) + local l_player = sm.localPlayer.getPlayer() + local l_character = l_player:getCharacter() + + if l_character then + if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then + sm.gui.displayAlertText("#{INFO_OUT_OF_FUEL}") + end + end end \ No newline at end of file From 88d066bd91c21e5a84b7d6e2d8a24df99efd70ef Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 09:32:34 -0700 Subject: [PATCH 15/26] Added fuel consumption for Gimball thruster --- Scripts/interactable/Locomotion/Gimball.lua | 52 +++++++++++++++++---- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index c6f3b71..9aeaefe 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -10,7 +10,7 @@ print("loading Gimball.lua") Gimball = class() Gimball.maxParentCount = -1 Gimball.maxChildCount = 0 -Gimball.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +Gimball.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.gasoline Gimball.connectionOutput = sm.interactable.connectionType.none Gimball.colorNormal = sm.color.new( 0x009999ff )--sm.color.new( 0x844040ff ) Gimball.colorHighlight = sm.color.new( 0x11B2B2ff )-- = sm.color.new( 0xb25959ff ) @@ -25,24 +25,55 @@ function Gimball.server_init( self ) self.power = 0 self.smode = 0 self.direction = sm.vec3.new(0,0,1) + self.sv_fuel_points = 0 local stored = self.storage:load() if stored then - self.smode = stored - 1 + local stored_type = type(stored) + if stored_type == "number" then + self.smode = stored - 1 + elseif stored_type == "table" then + self.smode = stored[1] - 1 + self.sv_fuel_points = stored[2] + end end + + self.sv_saved_fuel_points = self.sv_fuel_points end function Gimball.server_onRefresh( self ) self:server_init() end -function Gimball.server_onFixedUpdate( self ) +function Gimball.server_onFixedUpdate( self, dt ) if self.power ~= 0 and math.abs(self.power) ~= math.huge then sm.physics.applyImpulse(self.shape, self.direction*math.abs(self.power), true) - --print(self.direction) + + mp_fuel_consumeFuelPoints(self, self.power, 0.35, dt) + end + + mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + + self.network:setClientData(self.sv_fuel_points > 0) + self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfFuel") + end end end +function Gimball:client_onClientDataUpdate(params) + self.cl_has_fuel = params +end + +function Gimball:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self) +end + function Gimball.client_onCreate(self) self.shootEffect = sm.effect.createEffect( "Thruster - Level 2", self.interactable ) self.shootEffect:setOffsetPosition(sm.vec3.zero()) @@ -70,7 +101,7 @@ end function Gimball.server_changemode(self, crouch) self.smode = (self.smode + (crouch and -1 or 1)) % 4 - self.storage:save(self.smode+1) + self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) self.network:sendToClients("client_mode", {mode = self.smode, sound = true}) end @@ -101,8 +132,9 @@ function Gimball.client_canInteract(self) return true end +local gb_logic_and_power = bit.bor(sm.interactable.connectionType.logic, sm.interactable.connectionType.power) function Gimball.client_onFixedUpdate(self, dt) - local parents = self.interactable:getParents() + local parents = self.interactable:getParents(gb_logic_and_power) local power = #parents>0 and 100 or 0 local hasnumber = false local logicinput = 1 @@ -284,10 +316,10 @@ function Gimball.client_onFixedUpdate(self, dt) ]] - if false then --visualise x and z + --[[if false then --visualise x and z sm.particle.createParticle("construct_welding", self.shape.worldPosition + localX) sm.particle.createParticle("construct_welding", self.shape.worldPosition + localZ) - end + end]] -- direction to pose translation: local localvec = getLocal(self.shape, self.direction*-1) @@ -302,6 +334,10 @@ function Gimball.client_onFixedUpdate(self, dt) local worldRot = sm.vec3.getRotation( getLocal(self.shape,sm.shape.getUp(self.shape)),-self.direction) local localRot = self.shape:transformRotation( worldRot ) self.shootEffect:setOffsetRotation(localRot) + + if sm.game.getEnableFuelConsumption() and not self.cl_has_fuel then + self.power = 0 + end --self.shootEffect:setOffsetPosition(-sm.vec3.new(0,0,0.5)) old calculations if self.power ~= 0 then From 735450564159b736e7c4bbd8d00d8544189df2e1 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 14:54:54 -0700 Subject: [PATCH 16/26] Pico thruster and 1x1 thruster can consume fuel now --- CraftingRecipes/craftbot.json | 4 +- Gui/IconMap.xml | 6 + .../English/inventoryDescriptions.json | 12 + Objects/Database/ShapeSets/interactive.json | 84 ++++- .../interactable/Locomotion/ModGasEngine.lua | 2 +- .../interactable/Locomotion/ModThruster.lua | 310 ++++++++++++++++++ 6 files changed, 413 insertions(+), 5 deletions(-) create mode 100644 Scripts/interactable/Locomotion/ModThruster.lua diff --git a/CraftingRecipes/craftbot.json b/CraftingRecipes/craftbot.json index 0b7d57b..ea91864 100644 --- a/CraftingRecipes/craftbot.json +++ b/CraftingRecipes/craftbot.json @@ -1520,7 +1520,7 @@ "quantity": 5 } ], - "itemId": "c394b6e8-554c-4074-a119-ab2fec55e456", + "itemId": "9235b582-fc25-48a8-a807-68d98755d077", "quantity": 1 }, { @@ -1540,7 +1540,7 @@ "quantity": 5 } ], - "itemId": "036fbe44-45df-11e6-beb8-9e71128cae77", + "itemId": "a07a3673-a446-44a3-b16d-abb732c7a525", "quantity": 1 }, { diff --git a/Gui/IconMap.xml b/Gui/IconMap.xml index a394e54..4f10f83 100644 --- a/Gui/IconMap.xml +++ b/Gui/IconMap.xml @@ -106,10 +106,16 @@ + + + + + + diff --git a/Gui/Language/English/inventoryDescriptions.json b/Gui/Language/English/inventoryDescriptions.json index 3753a43..015786f 100644 --- a/Gui/Language/English/inventoryDescriptions.json +++ b/Gui/Language/English/inventoryDescriptions.json @@ -212,12 +212,24 @@ "keywords": [ "modpack", "motor", "odd", "odd-width", "width" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico thruster - Low power [#ffff00DEPRECATED#ffffff]", + "description": "Maneuvering thrusters, or just a low power thruster", + "keywords": [ "modpack", "rocket", "booster", "boost", "force", "exhaust" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico thruster - Low power", "description": "Maneuvering thrusters, or just a low power thruster", "keywords": [ "modpack", "rocket", "booster", "boost", "force", "exhaust" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro Thruster [#ffff00DEPRECATED#ffffff]", + "description": "Micro Thruster with more power levels", + "keywords": [ "modpack", "rocket", "booster", "boost", "force", "exhaust" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro Thruster", "description": "Micro Thruster with more power levels", diff --git a/Objects/Database/ShapeSets/interactive.json b/Objects/Database/ShapeSets/interactive.json index e6abf96..2a981eb 100644 --- a/Objects/Database/ShapeSets/interactive.json +++ b/Objects/Database/ShapeSets/interactive.json @@ -1157,7 +1157,7 @@ "qualityLevel": 5 }, { - "uuid": "c394b6e8-554c-4074-a119-ab2fec55e456", + "uuid": "c394b6e8-554c-4074-a119-ab2fec55e456", //OLD pico thruster "renderable": { "lodList": [ { @@ -1212,11 +1212,56 @@ "sticky": "-Z", "physicsMaterial": "Mechanical", "density": 250.0, + "qualityLevel": 4, + "showInInventory": false + }, + { + "uuid": "9235b582-fc25-48a8-a807-68d98755d077", //NEW pico thruster + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$MOD_DATA/Objects/Textures/mod_decor_cone_dif.png", + "$MOD_DATA/Objects/Textures/mod_decor_cone_asg.png", + "$MOD_DATA/Objects/Textures/mod_decor_cone_nor.png" + ], + "material": "DifAsgNor" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/mjm_PicoThruster.mesh" + } + ] + }, + "color": "df7f00", + "hull": { + "x": 1, "y": 1, "z": 1, + "margin": 0.0, + "pointList": [ + { "x": 1.0, "y": 0.0, "z": -1.0 }, + { "x": 0.0, "y": 1.0, "z": -1.0 }, + { "x": -1.0, "y": 0.0, "z": -1.0 }, + { "x": 0.0, "y": -1.0, "z": -1.0 }, + { "x": 1.0, "y": 0.0, "z": -0.8 }, + { "x": 0.0, "y": 1.0, "z": -0.8 }, + { "x": -1.0, "y": 0.0, "z": -0.8 }, + { "x": 0.0, "y": -1.0, "z": -0.8 } + ] + }, + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModThruster.lua", + "classname": "ModThruster" + }, + "rotationSet": "PropZ", + "sticky": "-Z", + "physicsMaterial": "Mechanical", + "density": 250.0, "qualityLevel": 4 }, { "legacyId": 3222, - "uuid": "036fbe44-45df-11e6-beb8-9e71128cae77", + "uuid": "036fbe44-45df-11e6-beb8-9e71128cae77", //OLD 1x1 Micro thruster "renderable": { "lodList": [ { @@ -1261,6 +1306,41 @@ "sticky": "-Z", "physicsMaterial": "Mechanical", "density": 250.0, + "qualityLevel": 4, + "showInInventory": false + }, + { + "uuid": "a07a3673-a446-44a3-b16d-abb732c7a525", //NEW 1x1 Micro thruster + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginejet_dif.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginejet_asg.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginejet_nor.tga" + ], + "material": "3PoseAnimDifAsgNor" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_off.obj", + "pose0": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_off01.obj", + "pose1": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_on.obj", + "pose2": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_on01.obj" + } + ] + }, + "color": "007fdf", + "box": { "x": 1, "y": 1, "z": 1 }, + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModThruster.lua", + "classname": "ModThruster" + }, + "rotationSet": "PropZ", + "sticky": "-Z", + "physicsMaterial": "Mechanical", + "density": 250.0, "qualityLevel": 4 }, { diff --git a/Scripts/interactable/Locomotion/ModGasEngine.lua b/Scripts/interactable/Locomotion/ModGasEngine.lua index d41c11e..591a99a 100644 --- a/Scripts/interactable/Locomotion/ModGasEngine.lua +++ b/Scripts/interactable/Locomotion/ModGasEngine.lua @@ -443,7 +443,7 @@ function GasEngine.client_onInteract( self, character, state ) self.gui:setData( "UpgradeInfo", nil ) end - self.gui:setText( "SubTitle", level.title ) + self.gui:setVisible("SubTitle", false) self.gui:setSliderRangeLimit( "Setting", level.gearCount ) if sm.game.getEnableUpgrade() and level.cost then diff --git a/Scripts/interactable/Locomotion/ModThruster.lua b/Scripts/interactable/Locomotion/ModThruster.lua new file mode 100644 index 0000000..0f7b055 --- /dev/null +++ b/Scripts/interactable/Locomotion/ModThruster.lua @@ -0,0 +1,310 @@ +dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") + +ModThruster = class() +ModThruster.maxParentCount = 3 +ModThruster.maxChildCount = 0 +ModThruster.connectionInput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power + sm.interactable.connectionType.gasoline +ModThruster.connectionOutput = sm.interactable.connectionType.none +ModThruster.colorNormal = sm.color.new(0x29CCCDff) +ModThruster.colorHighlight = sm.color.new(0x36F3F7ff) +ModThruster.poseWeightCount = 3 + + +local PicoThrusterGears = { + { averageForce = 800 }, + { averageForce = 1250 }, + { averageForce = 1500 }, + { averageForce = 2000 }, + { averageForce = 3000 }, + { averageForce = 4000 }, + { averageForce = 5000 }, + { averageForce = 7000 }, + { averageForce = 9000 }, + { averageForce = 11000 }, + { averageForce = 15000 }, + { averageForce = 20000 }, + { averageForce = 25000 } +} + +local OneByOneMicroThruster = { + { averageForce = 2222.22 }, + { averageForce = 3333.33 }, + { averageForce = 5000 }, + { averageForce = 7500 }, + { averageForce = 11250 }, + { averageForce = 16875 }, + { averageForce = 25312.5 }, + { averageForce = 37968.5 }, + { averageForce = 56953.25 }, + { averageForce = 85429.875 }, + { averageForce = 128144.31 }, + { averageForce = 192216.97 }, + { averageForce = 288325.96 } +} + +local thruster_uuid_data = { + ["9235b582-fc25-48a8-a807-68d98755d077"] = { + gears = PicoThrusterGears, + gear_count = #PicoThrusterGears, + effect_offset = sm.vec3.new(0, 0, -0.57) + }, + ["a07a3673-a446-44a3-b16d-abb732c7a525"] = { + gears = OneByOneMicroThruster, + gear_count = #OneByOneMicroThruster, + effect_offset = sm.vec3.new(0, 0, -0.3) + } +} + +function ModThruster:client_onCreate() + local cur_data = thruster_uuid_data[tostring(self.shape.uuid)] + self.gears = cur_data.gears + self.gear_count = cur_data.gear_count + + self.thrust_effect = sm.effect.createEffect("Thruster - Level 1", self.interactable) + self.thrust_effect:setOffsetPosition(cur_data.effect_offset) + + self.cl_thruster_active = false + self.cl_cur_gear = 0 + self.cl_time_val = 0 + self.cl_time_val2 = 0 +end + +function ModThruster:client_onDestroy() + if self.thrust_effect:isPlaying() then + self.thrust_effect:stopImmediate() + end + + if self.gui then + self.gui:close() + self.gui:destroy() + self.gui = nil + end + + self.thrust_effect:destroy() +end + +function ModThruster:client_onClientDataUpdate(params) + local is_active = params[2] + self.cl_thruster_active = is_active + self.cl_cur_gear = params[1] + + local cur_weight = self.cl_cur_gear / (self.gear_count - 1) + self.interactable:setPoseWeight(2, cur_weight) + + local th_effect = self.thrust_effect + + if is_active then + if not th_effect:isPlaying() then + th_effect:start() + end + else + if th_effect:isPlaying() then + th_effect:stop() + end + end +end + +function ModThruster:client_onFixedUpdate() + if self.cl_thruster_active then + local vel_length = sm.util.clamp(self.shape.velocity:length2() / 25, 0, 50) + self.thrust_effect:setParameter("velocity", vel_length) + + self.cl_time_val = self.cl_time_val + 0.2 + self.cl_time_val2 = self.cl_time_val2 + 0.8 + + local light_noise = sm.noise.simplexNoise1d(self.cl_time_val) * 0.5 + self.thrust_effect:setParameter("intensity", 2 + light_noise) + + local thruster_noise = math.abs(math.sin(self.cl_time_val2)) * 0.4 + self.interactable:setPoseWeight(1, thruster_noise) + else + self.interactable:setPoseWeight(1, 0) + end +end + +function ModThruster:client_onSliderChange(widget, value) + self.cl_cur_gear = value + self.network:sendToServer("server_setGear", value) +end + +function ModThruster:client_onGuiClose() + self.gui:destroy() + self.gui = nil +end + +function ModThruster:client_onInteract(character, state) + if state then + local s_gui = sm.gui.createEngineGui() + + s_gui:setText("Name", "#{CONTROLLER_THRUSTER_TITLE}") + s_gui:setText("Interaction", "#{CONTROLLER_THRUSTER_INSTRUCTION}") + s_gui:setSliderCallback("Setting", "client_onSliderChange") + s_gui:setOnCloseCallback("client_onGuiClose") + s_gui:setSliderData("Setting", self.gear_count, self.cl_cur_gear) + s_gui:setIconImage("Icon", self.shape:getShapeUuid()) + s_gui:setVisible("SubTitle", false) + + local fuelContainer = self.interactable:getContainer(0) + if fuelContainer then + s_gui:setContainer("Fuel", fuelContainer) + end + + local externalFuelContainer, _, _ = self:getInputs() + if externalFuelContainer then + s_gui:setVisible("FuelContainer", true) + end + + if not sm.game.getEnableFuelConsumption() then + s_gui:setVisible("BackgroundGas", false) + s_gui:setVisible("FuelGrid", false) + end + + s_gui:open() + self.gui = s_gui + end +end + +function ModThruster:server_onCreate() + self.sv_thruster_active = false + + --load the thruster data + self.saved = self.storage:load() + if self.saved == nil then + self.saved = {} + end + if self.saved.gearIdx == nil then + local cur_data = thruster_uuid_data[tostring(self.shape.uuid)] + + self.saved.gearIdx = math.floor(cur_data.gear_count / 2) + end + if self.saved.fuelPoints == nil then + self.saved.fuelPoints = 0 + end + + self.sv_fuel_points = self.saved.fuelPoints + self:server_setGear(self.saved.gearIdx) + + --create the container or reuse the saved one + local s_container = self.interactable:getContainer(0) + if not s_container then + s_container = self.interactable:addContainer(0, 1, 20) + end + + s_container:setFilters({ obj_consumable_gas }) +end + +function ModThruster:server_setGear(gear) + self.saved.gearIdx = gear + self.sv_data_dirty = true + self.sv_storage_dirty = true +end + +function ModThruster:client_getAvailableParentConnectionCount(connectionType) + if bit.band( connectionType, sm.interactable.connectionType.logic ) == sm.interactable.connectionType.logic then + return 1 - #self.interactable:getParents(sm.interactable.connectionType.logic) + end + + if bit.band( connectionType, sm.interactable.connectionType.power ) == sm.interactable.connectionType.power then + return 1 - #self.interactable:getParents(sm.interactable.connectionType.power) + end + + if bit.band( connectionType, sm.interactable.connectionType.gasoline ) == sm.interactable.connectionType.gasoline then + return 1 - #self.interactable:getParents(sm.interactable.connectionType.gasoline) + end + + return 0 +end + +local s_connection_type = sm.interactable.connectionType +function ModThruster:getInputs() + local s_inter = self.interactable + local l_container_inter = s_inter:getParents(s_connection_type.gasoline)[1] + local l_logic = s_inter:getParents(s_connection_type.logic)[1] + local l_driver_seat = s_inter:getParents(s_connection_type.power)[1] + + local l_container = nil + if l_container_inter then + l_container = l_container_inter:getContainer(0) + end + + return l_container, l_logic, l_driver_seat +end + +function ModThruster:client_onOutOfGas() + local l_player = sm.localPlayer.getPlayer() + local l_character = l_player:getCharacter() + + if l_character then + if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then + sm.gui.displayAlertText("#{INFO_OUT_OF_FUEL}") + end + end +end + +function ModThruster:server_updateFuelStatus() + if self.saved.fuelPoints ~= self.sv_fuel_points then + self.saved.fuelPoints = self.sv_fuel_points + self.sv_storage_dirty = true + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfGas") + end + end +end + +function ModThruster:server_onFixedUpdate(dt) + local l_container, l_logic, l_driver_seat = self:getInputs() + local useCreativeFuel = not sm.game.getEnableFuelConsumption() and l_container == nil + + if not l_container or l_container:isEmpty() then + l_container = self.interactable:getContainer(0) + end + + local l_active = false + if l_driver_seat and l_driver_seat.power > 0 then + l_active = true + elseif l_logic and l_logic.active then + l_active = true + end + + local canSpend = false + if self.sv_fuel_points <= 0 then + canSpend = sm.container.canSpend(l_container, obj_consumable_gas, 1) + end + + local is_valid_active = l_active and (self.sv_fuel_points > 0 or canSpend or useCreativeFuel) + if is_valid_active then + local cur_power = self.gears[self.saved.gearIdx + 1].averageForce + sm.physics.applyImpulse(self.shape, sm.vec3.new(0, 0, 0 - cur_power * dt)) + + if not useCreativeFuel then + local fuel_cost = cur_power * 0.1 + self.sv_fuel_points = self.sv_fuel_points - (fuel_cost * dt) + + if self.sv_fuel_points <= 0 then + sm.container.beginTransaction() + sm.container.spend(l_container, obj_consumable_gas, 1, true) + if sm.container.endTransaction() then + self.sv_fuel_points = 10000 + end + end + end + end + + self:server_updateFuelStatus() + + if self.sv_thruster_active ~= is_valid_active then + self.sv_thruster_active = is_valid_active + self.sv_data_dirty = true + end + + if self.sv_storage_dirty then + self.sv_storage_dirty = false + self.storage:save(self.saved) + end + + if self.sv_data_dirty then + self.sv_data_dirty = false + self.network:setClientData({ self.saved.gearIdx, is_valid_active }) + end +end \ No newline at end of file From 2107db2ce7892812fdfdc67d290836443d6fab4f Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 11 Jun 2022 15:28:47 -0700 Subject: [PATCH 17/26] Added the deprecated sign to all languages --- .../Chinese/inventoryDescriptions.json | 19 +++++++++++++++ Gui/Language/Dutch/inventoryDescriptions.json | 20 ++++++++++++++++ .../French/inventoryDescriptions.json | 24 +++++++++++++++++++ .../German/inventoryDescriptions.json | 24 +++++++++++++++++++ .../Italian/inventoryDescriptions.json | 24 +++++++++++++++++++ .../Japanese/inventoryDescriptions.json | 24 +++++++++++++++++++ .../Russian/inventoryDescriptions.json | 24 +++++++++++++++++++ .../Spanish/inventoryDescriptions.json | 24 +++++++++++++++++++ 8 files changed, 183 insertions(+) diff --git a/Gui/Language/Chinese/inventoryDescriptions.json b/Gui/Language/Chinese/inventoryDescriptions.json index c813fd1..ef87daf 100644 --- a/Gui/Language/Chinese/inventoryDescriptions.json +++ b/Gui/Language/Chinese/inventoryDescriptions.json @@ -92,6 +92,10 @@ "description": "适用于长行程悬挂" }, "93e08947-be6d-436c-a64f-932727428c89": { + "title": "悬架发动机 [#ffff00已弃用#ffffff]", + "description": "可以放在轴承上作为悬挂的零件,\n并且作为燃气发动机使用." + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "悬架发动机", "description": "可以放在轴承上作为悬挂的零件,\n并且作为燃气发动机使用." }, @@ -154,16 +158,31 @@ }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "燃气发动机-宽 [#ffff00已弃用#ffffff]", + "description": "完美平衡的奇数!" + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "燃气发动机-宽", "description": "完美平衡的奇数!" }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "迷你喷射器-低功率 [#ffff00已弃用#ffffff]", + "description": "适用于微调的喷射器" + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "迷你喷射器-低功率", "description": "适用于微调的喷射器" }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 迷你喷射器 [#ffff00已弃用#ffffff]", + "description": "推力稍大的迷你喷射器" + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 迷你喷射器", "description": "推力稍大的迷你喷射器" diff --git a/Gui/Language/Dutch/inventoryDescriptions.json b/Gui/Language/Dutch/inventoryDescriptions.json index a85c0f0..0159271 100644 --- a/Gui/Language/Dutch/inventoryDescriptions.json +++ b/Gui/Language/Dutch/inventoryDescriptions.json @@ -148,11 +148,21 @@ "description": "Een onzichtbaar bestuurders zetel dat kan geplaats worden op andere blokken" }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Motor Vering [#ffff00VEROUDERD#ffffff]", + "description": "Dit deel is een motor! Zet dit deel op een lager en connecteer deze motor met de lager! Zet de kracht van de motor voor de kracht van de vering" + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Motor Vering", "description": "Dit deel is een motor! Zet dit deel op een lager en connecteer deze motor met de lager! Zet de kracht van de motor voor de kracht van de vering" }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "3 wijde motor [#ffff00VEROUDERD#ffffff]", + "description": "Het is een benzine motor die 3 wijd is. Perfect voor gelijke wagens te maken" + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "3 wijde motor", "description": "Het is een benzine motor die 3 wijd is. Perfect voor gelijke wagens te maken" @@ -160,6 +170,11 @@ "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico Stuwer - Lage kracht [#ffff00VEROUDERD#ffffff]", + "description": "Bestuurs Stuwer, of gewoon een lage kracht stuwer" + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico Stuwer - Lage kracht", "description": "Bestuurs Stuwer, of gewoon een lage kracht stuwer" @@ -555,6 +570,11 @@ "description": "A controller with a different appearance" }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Mini stuwer [#ffff00VEROUDERD#ffffff]", + "description": "Mini stuwer met meerdere kracht-levels" + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Mini stuwer", "description": "Mini stuwer met meerdere kracht-levels" diff --git a/Gui/Language/French/inventoryDescriptions.json b/Gui/Language/French/inventoryDescriptions.json index 03473e1..6ce313a 100644 --- a/Gui/Language/French/inventoryDescriptions.json +++ b/Gui/Language/French/inventoryDescriptions.json @@ -99,6 +99,12 @@ "description": "Cette pi�ce est un moteur! Placez cette pi�ce sur un roulement et connectez ce moteur au roulement! Connectez des tuyaux � une extr�mit� o� iront votre roue (et votre direction) et utilisez l'autre extr�mit� pour limiter la port�e R�gler la puissance de ce moteur pour une suspension de moteur l�che ou ferme. ", "keywords": ["modpack", "moteur", "suspension", "ressort", "angle", "contr�leur"] }, + "b69bf080-2467-4360-9677-72cfd48806c9": + { + "title": "Suspension de moteur [#ffff00OBSOLÈTE#ffffff]", + "description": "Cette pi�ce est un moteur! Placez cette pi�ce sur un roulement et connectez ce moteur au roulement! Connectez des tuyaux � une extr�mit� o� iront votre roue (et votre direction) et utilisez l'autre extr�mit� pour limiter la port�e R�gler la puissance de ce moteur pour une suspension de moteur l�che ou ferme. ", + "keywords": ["modpack", "moteur", "suspension", "ressort", "angle", "contr�leur"] + }, "a6d186ad-c9ba-4b6d-922c-6c13dfcea230": { "title": "Mod Piston (256)", @@ -176,18 +182,36 @@ // moteurs "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Gas Engine 3-Wide [#ffff00OBSOLÈTE#ffffff]", + "description": "Il s�agit d�un moteur � essence de la taille d�un moteur �lectrique. Id�al pour les cr�ations � largeur irr�guli�re � essence � essence!", + "keywords": ["modpack", "motor", "impair", "impair-width", "width"] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Gas Engine 3-Wide", "description": "Il s�agit d�un moteur � essence de la taille d�un moteur �lectrique. Id�al pour les cr�ations � largeur irr�guli�re � essence � essence!", "keywords": ["modpack", "motor", "impair", "impair-width", "width"] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico thruster - Low power [#ffff00OBSOLÈTE#ffffff]", + "description": "Des propulseurs en man�uvre, ou tout simplement un propulseur basse consommation", + "keywords": ["modpack", "rocket", "booster", "boost", "force", "�chappement"] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico thruster - Low power", "description": "Des propulseurs en man�uvre, ou tout simplement un propulseur basse consommation", "keywords": ["modpack", "rocket", "booster", "boost", "force", "�chappement"] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro Thruster [#ffff00OBSOLÈTE#ffffff]", + "description": "Micro Thruster avec plusieurs niveaux de puissance", + "keywords": ["modpack", "rocket", "booster", "boost", "force", "�chappement"] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro Thruster", "description": "Micro Thruster avec plusieurs niveaux de puissance", diff --git a/Gui/Language/German/inventoryDescriptions.json b/Gui/Language/German/inventoryDescriptions.json index 508f65c..ae41694 100644 --- a/Gui/Language/German/inventoryDescriptions.json +++ b/Gui/Language/German/inventoryDescriptions.json @@ -170,24 +170,48 @@ // engines "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Motor Feder [#ffff00VERALTET#ffffff]", + "description": "Dieses Teil ist ein Motor! Setze diesen Motor auf ein ein Lager und verbinde ihn damit! Platziere Rohre an einem Ende wo das Rad (und dessen Lenkung) sein wird. Nutze die andere Seite um die Bewegungsfreiheit zu begrenzen. Pass die Motorstärke an um die Federkraft einzustellen.", + "keywords": ["modpack", "motor", "Federung", "Feder", "Federung", "Winkel", " regler", "Controller", "Steuerung" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Motor Feder", "description": "Dieses Teil ist ein Motor! Setze diesen Motor auf ein ein Lager und verbinde ihn damit! Platziere Rohre an einem Ende wo das Rad (und dessen Lenkung) sein wird. Nutze die andere Seite um die Bewegungsfreiheit zu begrenzen. Pass die Motorstärke an um die Federkraft einzustellen.", "keywords": ["modpack", "motor", "Federung", "Feder", "Federung", "Winkel", " regler", "Controller", "Steuerung" ] }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Verbrennungsmotor (3 Böcke Breit) [#ffff00VERALTET#ffffff]", + "description": "Ein Verbrennungsmotor, welcher der Größe eines Elektromotors entspricht. Perfekt geeignet für ausbalancierte, ungerade breite Kreationen!", + "keywords": ["modpack", "motor", "ungerade", "ungerade breit", " breit", "lang" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Verbrennungsmotor (3 Böcke Breit)", "description": "Ein Verbrennungsmotor, welcher der Größe eines Elektromotors entspricht. Perfekt geeignet für ausbalancierte, ungerade breite Kreationen!", "keywords": ["modpack", "motor", "ungerade", "ungerade breit", " breit", "lang" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico-Schubdüse (geringer Schub) [#ffff00VERALTET#ffffff]", + "description": "Als Manövrierschubdüse oder Schubdüse mit geringer Schubkraft nutzbar.", + "keywords": [ "modpack", "Rakete", "booster", "boost", "Schub", "Düse", "Triebwerk", "Kraft", "Auspuff", "Leistung" , "Pico", "gering" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico-Schubdüse (geringer Schub)", "description": "Als Manövrierschubdüse oder Schubdüse mit geringer Schubkraft nutzbar.", "keywords": [ "modpack", "Rakete", "booster", "boost", "Schub", "Düse", "Triebwerk", "Kraft", "Auspuff", "Leistung" , "Pico", "gering" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro-Schubdüse [#ffff00VERALTET#ffffff]", + "description": "Micro-Schubdüse mit mehreren Leistungsstufen.", + "keywords": [ "modpack", "Rakete", "booster", "boost", "Schub", "Düse", "Triebwerk", "Kraft", "Auspuff", "Leistung", "Micro" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro-Schubdüse", "description": "Micro-Schubdüse mit mehreren Leistungsstufen.", diff --git a/Gui/Language/Italian/inventoryDescriptions.json b/Gui/Language/Italian/inventoryDescriptions.json index 7a552f5..19fffa5 100644 --- a/Gui/Language/Italian/inventoryDescriptions.json +++ b/Gui/Language/Italian/inventoryDescriptions.json @@ -170,24 +170,48 @@ // engines "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Motore per Sospensione [#ffff00DEPRECATA#ffffff]", + "description": "Questo blocco è un motore! Metti questo blocco su un cuscinetto e connetti questo motore al cuscinetto! Metti dei tubi alla fine di dove la ruota (e lo sterzo) sarà posizionata, e usa l'altro capo per limitare la gamma. Imposta la potenza di questo motore per avere una sospensione lenta o solida.", + "keywords": [ "modpack", "motore", "sospensione", "molla", "angolo", "controllore" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Motore per Sospensione", "description": "Questo blocco è un motore! Metti questo blocco su un cuscinetto e connetti questo motore al cuscinetto! Metti dei tubi alla fine di dove la ruota (e lo sterzo) sarà posizionata, e usa l'altro capo per limitare la gamma. Imposta la potenza di questo motore per avere una sospensione lenta o solida.", "keywords": [ "modpack", "motore", "sospensione", "molla", "angolo", "controllore" ] }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Motore a Gas - Largo 3 [#ffff00DEPRECATA#ffffff]", + "description": "È un motore a gas largo come un motore elettrico. Perfetto per creazioni di larghezza dispari!", + "keywords": [ "modpack", "motore", "dispari", "largo" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Motore a Gas - Largo 3", "description": "È un motore a gas largo come un motore elettrico. Perfetto per creazioni di larghezza dispari!", "keywords": [ "modpack", "motore", "dispari", "largo" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico Propulsore - Bassa Potenza [#ffff00DEPRECATA#ffffff]", + "description": "Propulsori di manovra, oppure soltanto dei propulsori a bassa potenza", + "keywords": [ "modpack", "razzo", "propulsore", "forza", "marmitta" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico Propulsore - Bassa Potenza", "description": "Propulsori di manovra, oppure soltanto dei propulsori a bassa potenza", "keywords": [ "modpack", "razzo", "propulsore", "forza", "marmitta" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "Mini Propulsore - 1x4 [#ffff00DEPRECATA#ffffff]", + "description": "Un propulsore più piccolo. Ottimo per missili!", + "keywords": [ "modpack", "razzo", "propulsore", "forza", "marmitta" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "Mini Propulsore - 1x4", "description": "Un propulsore più piccolo. Ottimo per missili!", diff --git a/Gui/Language/Japanese/inventoryDescriptions.json b/Gui/Language/Japanese/inventoryDescriptions.json index 69f08ae..7db9175 100644 --- a/Gui/Language/Japanese/inventoryDescriptions.json +++ b/Gui/Language/Japanese/inventoryDescriptions.json @@ -94,6 +94,12 @@ "keywords": [ "modpack", "modopaku", "モドパク", "サスペンション" ] }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "エンジン サスペンション [#ffff00非推奨#ffffff]", + "description": "この 部分 は エンジンです! この 部品 を ベアリング に 取り付け、 この エンジン を ベアリング に 接続し ます! ホイール (および ステアリング) が 行く 一方 の 端 に いくつ か の パイプ を 接続 し、 もう 一方 の 端 を 使用し て 可動 範囲 を 制限し ます。 緩い または しっかり した エンジン サスペンション の ため に、 この エンジン の 出力 を 設定 します。", + "keywords": [ "modpack", "modopaku", "モドパク", "モーター", "サスペンション", "サスペンション", "角度", "コントローラー" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "エンジン サスペンション", "description": "この 部分 は エンジンです! この 部品 を ベアリング に 取り付け、 この エンジン を ベアリング に 接続し ます! ホイール (および ステアリング) が 行く 一方 の 端 に いくつ か の パイプ を 接続 し、 もう 一方 の 端 を 使用し て 可動 範囲 を 制限し ます。 緩い または しっかり した エンジン サスペンション の ため に、 この エンジン の 出力 を 設定 します。", @@ -176,18 +182,36 @@ // engines "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "ガスエンジン 3x [#ffff00非推奨#ffffff]", + "description": "電気 エンジン の サイズ に 適合す る ガス エンジン です。 バランス の 取れた ガス 駆動 の 奇数 幅 の 作成に 最適です!", + "keywords": [ "modpack", "modopaku", "モドパク", "モーター", "奇数幅" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "ガスエンジン 3x", "description": "電気 エンジン の サイズ に 適合す る ガス エンジン です。 バランス の 取れた ガス 駆動 の 奇数 幅 の 作成に 最適です!", "keywords": [ "modpack", "modopaku", "モドパク", "モーター", "奇数幅" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "ピコ スラスタ [#ffff00非推奨#ffffff]", + "description": "操縦 スラスタ または 単なる 低出力 スラスタ", + "keywords": [ "modpack", "modopaku", "モドパク", "ロケット", "力", "排気" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "ピコ スラスタ", "description": "操縦 スラスタ または 単なる 低出力 スラスタ", "keywords": [ "modpack", "modopaku", "モドパク", "ロケット", "力", "排気" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "小さな スラスタ 1x1 [#ffff00非推奨#ffffff]", + "description": "より 多く の 出力 レベル を 持つ マイクロスラスタ", + "keywords": [ "modpack", "modopaku", "モドパク", "ロケット", "力", "排気" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "小さな スラスタ 1x1", "description": "より 多く の 出力 レベル を 持つ マイクロスラスタ", diff --git a/Gui/Language/Russian/inventoryDescriptions.json b/Gui/Language/Russian/inventoryDescriptions.json index d086568..879732e 100644 --- a/Gui/Language/Russian/inventoryDescriptions.json +++ b/Gui/Language/Russian/inventoryDescriptions.json @@ -188,24 +188,48 @@ // engines "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Двигатель-подвеска [#ffff00УСТАРЕЛ#ffffff]", + "description": "Эта деталь является двигателем! Прикрепите эту деталь на подшипник и подключите к подшипнику! Подключите трубы к одному концу где ваше колесо (и поворотный механизм) будет стоять, и используйте другой конец чтобы ограничить движение. Установите мощность двигателя если хотите сделать подвеску мягкой или жесткой.", + "keywords": [ "модпак", "мотор", "подвеска", "пружина", "угол", "контроллер" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Двигатель-подвеска", "description": "Эта деталь является двигателем! Прикрепите эту деталь на подшипник и подключите к подшипнику! Подключите трубы к одному концу где ваше колесо (и поворотный механизм) будет стоять, и используйте другой конец чтобы ограничить движение. Установите мощность двигателя если хотите сделать подвеску мягкой или жесткой.", "keywords": [ "модпак", "мотор", "подвеска", "пружина", "угол", "контроллер" ] }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Бензиновый двигатель 3x [#ffff00УСТАРЕЛ#ffffff]", + "description": "Этот бензиновый двигаетль схож по размеру с электрическим двигателем. Идеален для построек с нечетной шириной!", + "keywords": [ "модпак", "мотор", "нечётный", "нечётная ширина", "ширина" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Бензиновый двигатель 3x", "description": "Этот бензиновый двигаетль схож по размеру с электрическим двигателем. Идеален для построек с нечетной шириной!", "keywords": [ "модпак", "мотор", "нечётный", "нечётная ширина", "ширина" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Ускоритель - малая мощность [#ffff00УСТАРЕЛ#ffffff]", + "description": "Маневровые ускоритель, или просто маломощный ускоритель", + "keywords": [ "модпак", "ракета", "ускоритель", "ускорение", "сила", "выхлоп" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Ускоритель - малая мощность", "description": "Маневровые ускоритель, или просто маломощный ускоритель", "keywords": [ "модпак", "ракета", "ускоритель", "ускорение", "сила", "выхлоп" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Ускоритель [#ffff00УСТАРЕЛ#ffffff]", + "description": "Маленький ускоритель, с более большим количеством уровней тяги", + "keywords": [ "модпак", "ракета", "ускоритель", "ускорение", "сила", "выхлоп" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Ускоритель", "description": "Маленький ускоритель, с более большим количеством уровней тяги", diff --git a/Gui/Language/Spanish/inventoryDescriptions.json b/Gui/Language/Spanish/inventoryDescriptions.json index 8ed6fbf..ef8bf1e 100644 --- a/Gui/Language/Spanish/inventoryDescriptions.json +++ b/Gui/Language/Spanish/inventoryDescriptions.json @@ -94,6 +94,12 @@ "keywords": [ "modpack", "resorte" ] }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Suspensión del motor [#ffff00OBSOLETA#ffffff]", + "description": "¡Esta parte es un motor! ¡Ponga esta parte en un rodamiento y conecte este motor al rodamiento! Conecte algunas tuberías a un extremo donde irá la rueda (y la dirección), y use el otro extremo para limitar el alcance de movimiento. Establezca la potencia de este motor para una suspensión del motor suelta o firme", + "keywords": [ "modpack", "motor", "suspensión", "resorte", "ángulo", "controlador" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Suspensión del motor", "description": "¡Esta parte es un motor! ¡Ponga esta parte en un rodamiento y conecte este motor al rodamiento! Conecte algunas tuberías a un extremo donde irá la rueda (y la dirección), y use el otro extremo para limitar el alcance de movimiento. Establezca la potencia de este motor para una suspensión del motor suelta o firme", @@ -176,18 +182,36 @@ // motores "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Motor de gas de 3 anchos [#ffff00OBSOLETA#ffffff]", + "description": "Es un motor de gasolina que se ajusta al tamaño de un motor eléctrico. Perfecto para equilibrar creaciones de gas de ancho extraño", + "keywords": [ "modpack", "motor", "impar", "ancho impar", "ancho" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Motor de gas de 3 anchos", "description": "Es un motor de gasolina que se ajusta al tamaño de un motor eléctrico. Perfecto para equilibrar creaciones de gas de ancho extraño", "keywords": [ "modpack", "motor", "impar", "ancho impar", "ancho" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Cohete Pico - Baja potencia [#ffff00OBSOLETA#ffffff]", + "description": "Propulsores de maniobra, o simplemente un propulsor de baja potencia", + "keywords": [ "modpack", "cohete", "refuerzo", "impulso", "fuerza", "escape" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Cohete Pico - Baja potencia", "description": "Propulsores de maniobra, o simplemente un propulsor de baja potencia", "keywords": [ "modpack", "cohete", "refuerzo", "impulso", "fuerza", "escape" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro Cohete [#ffff00OBSOLETA#ffffff]", + "description": "Micro Cohete con más niveles de potencia", + "keywords": [ "modpack", "cohete", "refuerzo", "impulso", "fuerza", "escape" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro Cohete", "description": "Micro Cohete con más niveles de potencia", From e7d0840d104236302027763f621b4c5f06cc350c Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 05:01:45 -0700 Subject: [PATCH 18/26] Better fuel manager --- Scripts/interactable/Locomotion/Gimball.lua | 37 +++++++++------ .../interactable/Locomotion/SmartThruster.lua | 21 ++++++--- .../interactable/Locomotion/WASDThruster.lua | 41 ++++++++++------ Scripts/libs/fuel_consumption_manager.lua | 47 +++++++++++++------ 4 files changed, 96 insertions(+), 50 deletions(-) diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index 9aeaefe..c6b2933 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -25,7 +25,8 @@ function Gimball.server_init( self ) self.power = 0 self.smode = 0 self.direction = sm.vec3.new(0,0,1) - self.sv_fuel_points = 0 + + mp_fuel_initialize(self, obj_consumable_gas, 0.35) local stored = self.storage:load() if stored then @@ -46,18 +47,24 @@ function Gimball.server_onRefresh( self ) end function Gimball.server_onFixedUpdate( self, dt ) - if self.power ~= 0 and math.abs(self.power) ~= math.huge then + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_consume = mp_fuel_canConsumeFuel(self, l_container) + + if can_activate and self.power ~= 0 and math.abs(self.power) ~= math.huge then sm.physics.applyImpulse(self.shape, self.direction*math.abs(self.power), true) - mp_fuel_consumeFuelPoints(self, self.power, 0.35, dt) + if can_consume then + mp_fuel_consumeFuelPoints(self, l_container, self.power, dt) + end end - mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) + if self.sv_saved_can_activate ~= can_activate then + self.sv_saved_can_activate = can_activate + self.network:setClientData(can_activate) + end if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points - - self.network:setClientData(self.sv_fuel_points > 0) self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) if self.sv_fuel_points <= 0 then @@ -67,7 +74,7 @@ function Gimball.server_onFixedUpdate( self, dt ) end function Gimball:client_onClientDataUpdate(params) - self.cl_has_fuel = params + self.cl_can_activate = params end function Gimball:client_onOutOfFuel() @@ -226,9 +233,15 @@ function Gimball.client_onFixedUpdate(self, dt) end end - self.power = power * logicinput * canfire - if math.abs(self.power) == math.huge or self.power ~= self.power then self.power = 0 end - + if self.cl_can_activate then + self.power = power * logicinput * canfire + else + self.power = 0 + end + + if math.abs(self.power) == math.huge or self.power ~= self.power then + self.power = 0 + end if self.mode == 0 then if ws then self.angleX = ws*90 end @@ -334,10 +347,6 @@ function Gimball.client_onFixedUpdate(self, dt) local worldRot = sm.vec3.getRotation( getLocal(self.shape,sm.shape.getUp(self.shape)),-self.direction) local localRot = self.shape:transformRotation( worldRot ) self.shootEffect:setOffsetRotation(localRot) - - if sm.game.getEnableFuelConsumption() and not self.cl_has_fuel then - self.power = 0 - end --self.shootEffect:setOffsetPosition(-sm.vec3.new(0,0,0.5)) old calculations if self.power ~= 0 then diff --git a/Scripts/interactable/Locomotion/SmartThruster.lua b/Scripts/interactable/Locomotion/SmartThruster.lua index 6c5d108..51f654c 100644 --- a/Scripts/interactable/Locomotion/SmartThruster.lua +++ b/Scripts/interactable/Locomotion/SmartThruster.lua @@ -19,7 +19,13 @@ SmartThruster.poseWeightCount = 2 function SmartThruster.server_onCreate( self ) - self.sv_fuel_points = self.storage:load() or 0 + mp_fuel_initialize(self, obj_consumable_gas, 0.35) + + local saved_data = self.storage:load() + if saved_data ~= nil then + self.sv_fuel_points = saved_data + end + self.sv_saved_fuel_points = self.sv_fuel_points end @@ -54,21 +60,24 @@ function SmartThruster.server_onFixedUpdate( self, dt ) if power < 0 then power = -3.3*10^38 else power = 3.3*10^38 end end - if sm.game.getEnableFuelConsumption() and self.sv_fuel_points <= 0 then + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_consume = mp_fuel_canConsumeFuel(self, l_container) + + if not can_activate then power = 0 end mp_updateOutputData(self, power * (logicinput or 1), logicinput > 0) power = power * logicinput - if power ~= 0 and math.abs(power) ~= math.huge then + if can_activate and power ~= 0 and math.abs(power) ~= math.huge then sm.physics.applyImpulse(self.shape, sm.vec3.new(0,0, 0 - power)) - mp_fuel_consumeFuelPoints(self, power, 0.35, dt) + if can_consume then + mp_fuel_consumeFuelPoints(self, l_container, power, dt) + end end - mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) - if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points self.storage:save(self.sv_saved_fuel_points) diff --git a/Scripts/interactable/Locomotion/WASDThruster.lua b/Scripts/interactable/Locomotion/WASDThruster.lua index 5b6c6cd..81dec35 100644 --- a/Scripts/interactable/Locomotion/WASDThruster.lua +++ b/Scripts/interactable/Locomotion/WASDThruster.lua @@ -27,7 +27,7 @@ function WASDThruster.server_init( self ) self.direction = sm.vec3.new(0,0,1) self.smode = 0 - self.sv_fuel_points = 0 + mp_fuel_initialize(self, obj_consumable_gas, 0.35) local stored = self.storage:load() if stored then @@ -48,23 +48,29 @@ function WASDThruster.server_onRefresh( self ) end function WASDThruster.server_onFixedUpdate( self, dt ) + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_consume = mp_fuel_canConsumeFuel(self, l_container) + if self.interactable.power ~= self.power then self.interactable:setPower(self.power) end - if self.power > 0 and math.abs(self.power) ~= math.huge then + + if can_activate and self.power > 0 and math.abs(self.power) ~= math.huge then sm.physics.applyImpulse(self.shape, self.direction*self.power*-1) - --print(self.direction) - mp_fuel_consumeFuelPoints(self, self.power, 0.35, dt) + if can_consume then + mp_fuel_consumeFuelPoints(self, l_container, self.power, dt) + end end - mp_fuel_updateFuelConsumption(self, obj_consumable_gas, 10000) + if self.sv_saved_can_activate ~= can_activate then + self.sv_saved_can_activate = can_activate + self.network:setClientData(can_activate) + end - if self.sv_saved_fuel_points ~= self.sv_fuel_points then + if self.sv_saved_fuel_points ~= self.sv_fuel_points then --update fuel status self.sv_saved_fuel_points = self.sv_fuel_points - self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) - self.network:setClientData(self.sv_fuel_points > 0) if self.sv_fuel_points <= 0 then self.network:sendToClients("client_onOutOfFuel") @@ -74,7 +80,7 @@ end function WASDThruster:client_onClientDataUpdate(params) - self.cl_has_fuel = params + self.cl_can_activate = params end @@ -242,8 +248,17 @@ function WASDThruster.client_onFixedUpdate(self, dt) if ws or ad then self.currentVPose = 0.5 end -- -1 to 1 => 0 to 1 if ad then self.currentHPose = (ad+1)/2 end -- -1 to 1 => 0 to 1 end - self.power = power * logicinput * canfire - if math.abs(self.power) == math.huge or self.power ~= self.power then self.power = 0 end + + --check if the thruster is allowed to have any power + if self.cl_can_activate then + self.power = power * logicinput * canfire + else + self.power = 0 + end + + if math.abs(self.power) == math.huge or self.power ~= self.power then + self.power = 0 + end self.interactable:setUvFrameIndex(self.mode) @@ -262,10 +277,6 @@ function WASDThruster.client_onFixedUpdate(self, dt) self.shootEffect:setOffsetRotation(worldRot) --self.shootEffect:setOffsetPosition((-sm.vec3.new(0,0,1.25)+self.direction)*0.36) --old calculations - if sm.game.getEnableAmmoConsumption() and not self.cl_has_fuel then - self.power = 0 - end - if self.power > 0 then if not self.shootEffect:isPlaying() then self.shootEffect:start() diff --git a/Scripts/libs/fuel_consumption_manager.lua b/Scripts/libs/fuel_consumption_manager.lua index 9a9ba20..107c0bb 100644 --- a/Scripts/libs/fuel_consumption_manager.lua +++ b/Scripts/libs/fuel_consumption_manager.lua @@ -2,30 +2,47 @@ dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") --to get the uuids of c local _sm_getEnableFuelConsumption = sm.game.getEnableFuelConsumption -function mp_fuel_consumeFuelPoints(self, power, multiplier, dt) - if _sm_getEnableFuelConsumption() then - local abs_power = math.abs(power) * multiplier - self.sv_fuel_points = self.sv_fuel_points - (abs_power * dt) --calculate fuel consumption - end +function mp_fuel_initialize(self, fuel_uuid, fuel_multiplier) + self.sv_fuel_points = 0 + self.sv_fuel_multiplier = fuel_multiplier + self.sv_fuel_uuid = fuel_uuid end -function mp_fuel_updateFuelConsumption(self, obj_uuid, fuel_points) - if not _sm_getEnableFuelConsumption() or self.sv_fuel_points > 0 then return end +function mp_fuel_consumeFuelPoints(self, container, power, dt) + local abs_power = math.abs(power) * self.sv_fuel_multiplier + self.sv_fuel_points = self.sv_fuel_points - (abs_power * dt) --calculate fuel consumption + + if self.sv_fuel_points <= 0 then + sm.container.beginTransaction() + sm.container.spend(container, self.sv_fuel_uuid, 1, true) + if sm.container.endTransaction() then + self.sv_fuel_points = 10000 + end + end +end +function mp_fuel_getValidFuelContainer(self) local parents = self.interactable:getParents(sm.interactable.connectionType.gasoline) for k, v in pairs(parents) do local gas_container = v:getContainer() - if sm.container.canSpend(gas_container, obj_uuid, 1) then - sm.container.beginTransaction() - sm.container.spend(gas_container, obj_uuid, 1, true) - - if sm.container.endTransaction() then - self.sv_fuel_points = fuel_points - break - end + if gas_container ~= nil then + return gas_container end end + + return nil +end + +function mp_fuel_canConsumeFuel(self, container) + local useCreativeFuel = not _sm_getEnableFuelConsumption() and container == nil + local canSpend = false + if self.sv_fuel_points <= 0 and container then + canSpend = sm.container.canSpend(container, self.sv_fuel_uuid, 1) + end + + local is_valid_active = (self.sv_fuel_points > 0 or canSpend or useCreativeFuel) + return is_valid_active, not useCreativeFuel end function mp_fuel_displayOutOfFuelMessage(self) From 8606ef6cda227f4855c49e9f1cfc34a4e7219df2 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 11:13:14 -0700 Subject: [PATCH 19/26] SmartController can consume electricity now --- .../interactable/Locomotion/SmartControl.lua | 60 +++++++++++++++---- Scripts/libs/fuel_consumption_manager.lua | 9 +-- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/Scripts/interactable/Locomotion/SmartControl.lua b/Scripts/interactable/Locomotion/SmartControl.lua index 1bd69e8..10532ca 100644 --- a/Scripts/interactable/Locomotion/SmartControl.lua +++ b/Scripts/interactable/Locomotion/SmartControl.lua @@ -10,20 +10,24 @@ print("loading SmartControl.lua") SmartControl = class( nil ) SmartControl.maxChildCount = -1 SmartControl.maxParentCount = -1 -SmartControl.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +SmartControl.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.electricity SmartControl.connectionOutput = sm.interactable.connectionType.piston + sm.interactable.connectionType.bearing SmartControl.colorNormal = sm.color.new(0xe54500ff) SmartControl.colorHighlight = sm.color.new(0xff7033ff) SmartControl.poseWeightCount = 1 -function SmartControl.server_onCreate(self) +function SmartControl:server_onCreate() self.last_length = {} + self.delta_length = {} + mp_fuel_initialize(self, obj_consumable_battery, 0.35, sm.interactable.connectionType.electricity) end + --smart engine/controller (setangle mode(angle, speed, strength), setspeed mode(speed, strength)) --smart piston/suspension (length, speed , strength -function SmartControl.server_onFixedUpdate(self, dt) - local parents = self.interactable:getParents() +local sc_logic_and_power = bit.bor(sm.interactable.connectionType.logic, sm.interactable.connectionType.power) +function SmartControl:server_onFixedUpdate(dt) + local parents = self.interactable:getParents(sc_logic_and_power) local anglelength = nil local speed = nil @@ -73,9 +77,16 @@ function SmartControl.server_onFixedUpdate(self, dt) if strength then strength = sm.util.clamp(strength, -3.402e+38, 3.402e+38) end if anglelength then anglelength = sm.util.clamp(anglelength, -3.402e+38, 3.402e+38) end if stiffness then stiffness = sm.util.clamp(stiffness, -3.402e+38, 3.402e+38) end - - if logic ~= 0 then + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_spend_fuel = mp_fuel_canConsumeFuel(self, l_container) + + if not can_activate then + speed = 0 + end + + local fuel_cost = 0 + if logic ~= 0 and can_activate then local angle = (anglelength ~= nil and math.rad(anglelength) or nil) local rotationspeed = (speed ~= nil and math.rad(speed) or math.rad(0))-- speed 0 by default as to not let it rotate bearing when no inputs local rotationstrength = (strength ~= nil and strength or 10000) @@ -88,22 +99,32 @@ function SmartControl.server_onFixedUpdate(self, dt) local angle1 = math.deg(angle)%360 - (math.deg(angle)%360 > 180 and 360 or 0) local angle2 = (math.deg(v.angle)%360 - (math.deg(v.angle)%360 > 180 and 360 or 0))*(v.reversed and 1 or -1) local extraforce = math.abs(((angle1 - angle2)+180)%360-180)/1000*stiffness + sm.joint.setTargetAngle( v, angle*seat, rotationspeed, rotationstrength*(1+ extraforce) - v.angularVelocity*10) -- change 10 to 1-200 depending on how well dampening oscillations works - - end + end + + local rotation_val = math.abs(v.angularVelocity) * rotationstrength + fuel_cost = fuel_cost + (rotation_val * 0.04) end local length = (anglelength ~= nil and anglelength or 0) local pistonspeed = (speed ~= nil and speed or 15)--default to 15 local pistonstrength = (strength ~= nil and strength or 6666) for k, v in pairs(sm.interactable.getPistons(self.interactable )) do + local v_id = v.id + local old_length = self.delta_length[v_id] or 0 + -- delta length for suspension-ish - if not self.last_length[v.id] then self.last_length[v.id] = v.length end - local extraforce = math.abs(length - (v.length-1))*stiffness/100 + if not self.last_length[v_id] then self.last_length[v_id] = v.length end + if self.delta_length[v_id] ~= v.length then self.delta_length[v_id] = v.length end - local maxImpulse = pistonstrength*(1+ extraforce ) - (v.length-self.last_length[v.id])*10 -- change 10 to 1-200 depending on how well dampening oscillations works + local extraforce = math.abs(length - (v.length-1))*stiffness/100 + local maxImpulse = pistonstrength*(1+ extraforce ) - (v.length-self.last_length[v_id])*10 -- change 10 to 1-200 depending on how well dampening oscillations works maxImpulse = sm.util.clamp(maxImpulse, -3.402e+38, 3.402e+38) + local p_speed = math.abs(old_length - v.length) * 0.1 + fuel_cost = fuel_cost + (pistonspeed * pistonstrength) * p_speed + sm.joint.setTargetLength( v, length*seat, pistonspeed, maxImpulse ) end else @@ -136,4 +157,21 @@ function SmartControl.server_onFixedUpdate(self, dt) sm.joint.setTargetLength( v, 0, pistonspeed, maxImpulse ) end end + + if can_spend_fuel then + mp_fuel_consumeFuelPoints(self, l_container, fuel_cost, dt) + end + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + self.storage:save(self.sv_fuel_points) + + if self.sv_fuel_points < 0 then + self.network:sendToClients("client_onOutOfFuel") + end + end end + +function SmartControl:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self, "#{INFO_OUT_OF_ENERGY}") +end \ No newline at end of file diff --git a/Scripts/libs/fuel_consumption_manager.lua b/Scripts/libs/fuel_consumption_manager.lua index 107c0bb..53a0fd1 100644 --- a/Scripts/libs/fuel_consumption_manager.lua +++ b/Scripts/libs/fuel_consumption_manager.lua @@ -2,10 +2,11 @@ dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") --to get the uuids of c local _sm_getEnableFuelConsumption = sm.game.getEnableFuelConsumption -function mp_fuel_initialize(self, fuel_uuid, fuel_multiplier) +function mp_fuel_initialize(self, fuel_uuid, fuel_multiplier, connection_type) self.sv_fuel_points = 0 self.sv_fuel_multiplier = fuel_multiplier self.sv_fuel_uuid = fuel_uuid + self.sv_fuel_connect_type = connection_type or sm.interactable.connectionType.gasoline end function mp_fuel_consumeFuelPoints(self, container, power, dt) @@ -22,7 +23,7 @@ function mp_fuel_consumeFuelPoints(self, container, power, dt) end function mp_fuel_getValidFuelContainer(self) - local parents = self.interactable:getParents(sm.interactable.connectionType.gasoline) + local parents = self.interactable:getParents(self.sv_fuel_connect_type) for k, v in pairs(parents) do local gas_container = v:getContainer() @@ -45,13 +46,13 @@ function mp_fuel_canConsumeFuel(self, container) return is_valid_active, not useCreativeFuel end -function mp_fuel_displayOutOfFuelMessage(self) +function mp_fuel_displayOutOfFuelMessage(self, custom_message) local l_player = sm.localPlayer.getPlayer() local l_character = l_player:getCharacter() if l_character then if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then - sm.gui.displayAlertText("#{INFO_OUT_OF_FUEL}") + sm.gui.displayAlertText(custom_message or "#{INFO_OUT_OF_FUEL}") end end end \ No newline at end of file From dc813968f3bf698a404df3cec023d0b439dada89 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 11:23:13 -0700 Subject: [PATCH 20/26] Fixed a script crash --- .../interactable/Locomotion/SmartControl.lua | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Scripts/interactable/Locomotion/SmartControl.lua b/Scripts/interactable/Locomotion/SmartControl.lua index 10532ca..c3369f2 100644 --- a/Scripts/interactable/Locomotion/SmartControl.lua +++ b/Scripts/interactable/Locomotion/SmartControl.lua @@ -21,6 +21,13 @@ function SmartControl:server_onCreate() self.delta_length = {} mp_fuel_initialize(self, obj_consumable_battery, 0.35, sm.interactable.connectionType.electricity) + + local saved_points = self.storage:load() + if saved_points ~= nil then + self.sv_fuel_points = saved_points + end + + self.sv_saved_fuel_points = self.sv_fuel_points end --smart engine/controller (setangle mode(angle, speed, strength), setspeed mode(speed, strength)) @@ -84,9 +91,10 @@ function SmartControl:server_onFixedUpdate(dt) if not can_activate then speed = 0 end - - local fuel_cost = 0 + if logic ~= 0 and can_activate then + local fuel_cost = 0 + local angle = (anglelength ~= nil and math.rad(anglelength) or nil) local rotationspeed = (speed ~= nil and math.rad(speed) or math.rad(0))-- speed 0 by default as to not let it rotate bearing when no inputs local rotationstrength = (strength ~= nil and strength or 10000) @@ -127,6 +135,10 @@ function SmartControl:server_onFixedUpdate(dt) sm.joint.setTargetLength( v, length*seat, pistonspeed, maxImpulse ) end + + if can_spend_fuel then + mp_fuel_consumeFuelPoints(self, l_container, fuel_cost, dt) + end else local rotationspeed = (speed ~= nil and math.rad(speed) or math.rad(90)) -- if no input speed setting set , give it a 90°/s speed as to be able to reset bearing to 0° local rotationstrength = (strength ~= nil and strength or 10000) @@ -158,10 +170,6 @@ function SmartControl:server_onFixedUpdate(dt) end end - if can_spend_fuel then - mp_fuel_consumeFuelPoints(self, l_container, fuel_cost, dt) - end - if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points self.storage:save(self.sv_fuel_points) From 7bee027e7577d1f040b100bb759f7563bbe3a151 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 11:32:19 -0700 Subject: [PATCH 21/26] Better text input --- Scripts/interactable/NumberLogic/CounterBlock.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Scripts/interactable/NumberLogic/CounterBlock.lua b/Scripts/interactable/NumberLogic/CounterBlock.lua index d408ff5..802dae3 100644 --- a/Scripts/interactable/NumberLogic/CounterBlock.lua +++ b/Scripts/interactable/NumberLogic/CounterBlock.lua @@ -200,8 +200,10 @@ function CounterBlock.client_onTinker(self, character, lookAt) local count_gui = sm.gui.createGuiFromLayout("$CONTENT_DATA/Gui/Layouts/CounterBlockGui.layout", false, { backgroundAlpha = 0.5 }) + self.counter_gui_input = tostring(self.interactable.power) + count_gui:setText("SavedValue", "Saved Value: #ffff00"..tostring(self.interactable.power).."#ffffff") - count_gui:setText("ValueInput", "0") + count_gui:setText("ValueInput", self.counter_gui_input) count_gui:setButtonCallback("IncrementWith", "client_gui_changeSavedValue") count_gui:setButtonCallback("DecrementWith", "client_gui_changeSavedValue") @@ -212,7 +214,6 @@ function CounterBlock.client_onTinker(self, character, lookAt) count_gui:open() - self.counter_gui_input = "0" self.counter_gui = count_gui end From e983f9e0df67adfcc56845b08706f9c6266ca945 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 12:53:47 -0700 Subject: [PATCH 22/26] Less table lookups --- .../libs/game_improvements/interactable.lua | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Scripts/libs/game_improvements/interactable.lua b/Scripts/libs/game_improvements/interactable.lua index d7bb320..6d5f3a7 100644 --- a/Scripts/libs/game_improvements/interactable.lua +++ b/Scripts/libs/game_improvements/interactable.lua @@ -5,20 +5,29 @@ __InteractableImprovements_Loaded = true local values = {} -- < Date: Sun, 12 Jun 2022 13:10:30 -0700 Subject: [PATCH 23/26] Added a fuel save timer --- Scripts/interactable/Locomotion/Gimball.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index c6b2933..c294eb2 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -65,10 +65,20 @@ function Gimball.server_onFixedUpdate( self, dt ) if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points - self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) if self.sv_fuel_points <= 0 then + self.sv_fuel_save_timer = 0.01 self.network:sendToClients("client_onOutOfFuel") + else + self.sv_fuel_save_timer = 2 + end + end + + if self.sv_fuel_save_timer then + self.sv_fuel_save_timer = (self.sv_fuel_save_timer > 0 and self.sv_fuel_save_timer - dt or nil) + + if self.sv_fuel_save_timer == nil then + self.storage:save({ self.smode+1, self.sv_fuel_points }) end end end From b9d670297fa362f3b840f0d39d1aee8bbd835dc0 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 13:27:17 -0700 Subject: [PATCH 24/26] Improved fuel save timer --- Scripts/interactable/Locomotion/Gimball.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index c294eb2..c2ca09b 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -67,17 +67,17 @@ function Gimball.server_onFixedUpdate( self, dt ) self.sv_saved_fuel_points = self.sv_fuel_points if self.sv_fuel_points <= 0 then - self.sv_fuel_save_timer = 0.01 self.network:sendToClients("client_onOutOfFuel") else - self.sv_fuel_save_timer = 2 + self.sv_fuel_save_timer = 1 end end - if self.sv_fuel_save_timer then - self.sv_fuel_save_timer = (self.sv_fuel_save_timer > 0 and self.sv_fuel_save_timer - dt or nil) + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt - if self.sv_fuel_save_timer == nil then + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil self.storage:save({ self.smode+1, self.sv_fuel_points }) end end From 8e5c4c06b9b951171409a077342c5eabe19a6764 Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 13:47:31 -0700 Subject: [PATCH 25/26] Add fuel timer to all modded thrusters and engines --- Scripts/interactable/Locomotion/Gimball.lua | 3 +-- Scripts/interactable/Locomotion/SmartControl.lua | 11 ++++++++++- Scripts/interactable/Locomotion/SmartThruster.lua | 11 ++++++++++- Scripts/interactable/Locomotion/WASDThruster.lua | 11 ++++++++++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index c2ca09b..4ea7b54 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -65,11 +65,10 @@ function Gimball.server_onFixedUpdate( self, dt ) if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points + self.sv_fuel_save_timer = 1 if self.sv_fuel_points <= 0 then self.network:sendToClients("client_onOutOfFuel") - else - self.sv_fuel_save_timer = 1 end end diff --git a/Scripts/interactable/Locomotion/SmartControl.lua b/Scripts/interactable/Locomotion/SmartControl.lua index c3369f2..9c1a11f 100644 --- a/Scripts/interactable/Locomotion/SmartControl.lua +++ b/Scripts/interactable/Locomotion/SmartControl.lua @@ -172,12 +172,21 @@ function SmartControl:server_onFixedUpdate(dt) if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points - self.storage:save(self.sv_fuel_points) + self.sv_fuel_save_timer = 1 if self.sv_fuel_points < 0 then self.network:sendToClients("client_onOutOfFuel") end end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save(self.sv_fuel_points) + end + end end function SmartControl:client_onOutOfFuel() diff --git a/Scripts/interactable/Locomotion/SmartThruster.lua b/Scripts/interactable/Locomotion/SmartThruster.lua index 51f654c..f3ec9cf 100644 --- a/Scripts/interactable/Locomotion/SmartThruster.lua +++ b/Scripts/interactable/Locomotion/SmartThruster.lua @@ -80,12 +80,21 @@ function SmartThruster.server_onFixedUpdate( self, dt ) if self.sv_saved_fuel_points ~= self.sv_fuel_points then self.sv_saved_fuel_points = self.sv_fuel_points - self.storage:save(self.sv_saved_fuel_points) + self.sv_fuel_save_timer = 1 if self.sv_fuel_points <= 0 then self.network:sendToClients("client_onOutOfFuel") end end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save(self.sv_fuel_points) + end + end end function SmartThruster:client_onOutOfFuel() diff --git a/Scripts/interactable/Locomotion/WASDThruster.lua b/Scripts/interactable/Locomotion/WASDThruster.lua index 81dec35..b5584b0 100644 --- a/Scripts/interactable/Locomotion/WASDThruster.lua +++ b/Scripts/interactable/Locomotion/WASDThruster.lua @@ -70,12 +70,21 @@ function WASDThruster.server_onFixedUpdate( self, dt ) if self.sv_saved_fuel_points ~= self.sv_fuel_points then --update fuel status self.sv_saved_fuel_points = self.sv_fuel_points - self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) + self.sv_fuel_save_timer = 1 if self.sv_fuel_points <= 0 then self.network:sendToClients("client_onOutOfFuel") end end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save({ self.smode+1, self.sv_fuel_points }) + end + end end From d8297e7d46490b88610e3a34c77af832b873741c Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sun, 12 Jun 2022 14:00:59 -0700 Subject: [PATCH 26/26] Added fuel timers to "vanilla" engines and thrusters --- Scripts/interactable/Locomotion/ModGasEngine.lua | 11 ++++++++++- Scripts/interactable/Locomotion/ModThruster.lua | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Scripts/interactable/Locomotion/ModGasEngine.lua b/Scripts/interactable/Locomotion/ModGasEngine.lua index 591a99a..9bafeb5 100644 --- a/Scripts/interactable/Locomotion/ModGasEngine.lua +++ b/Scripts/interactable/Locomotion/ModGasEngine.lua @@ -142,7 +142,7 @@ function GasEngine.sv_updateFuelStatus( self, fuelContainer ) if self.saved.fuelPoints ~= self.fuelPoints then self.saved.fuelPoints = self.fuelPoints - self.dirtyStorageTable = true + self.sv_fuel_save_timer = 1 end local hasFuel = ( self.fuelPoints > 0 ) or sm.container.canSpend( fuelContainer, obj_consumable_gas, 1 ) @@ -288,6 +288,15 @@ function GasEngine.server_onFixedUpdate( self, timeStep ) self:sv_updateFuelStatus( fuelContainer ) + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - timeStep + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.dirtyStorageTable = true + end + end + -- Storage table dirty if self.dirtyStorageTable then self.storage:save( self.saved ) diff --git a/Scripts/interactable/Locomotion/ModThruster.lua b/Scripts/interactable/Locomotion/ModThruster.lua index 0f7b055..fd1099c 100644 --- a/Scripts/interactable/Locomotion/ModThruster.lua +++ b/Scripts/interactable/Locomotion/ModThruster.lua @@ -244,7 +244,7 @@ end function ModThruster:server_updateFuelStatus() if self.saved.fuelPoints ~= self.sv_fuel_points then self.saved.fuelPoints = self.sv_fuel_points - self.sv_storage_dirty = true + self.sv_fuel_save_timer = 1 if self.sv_fuel_points <= 0 then self.network:sendToClients("client_onOutOfGas") @@ -293,6 +293,15 @@ function ModThruster:server_onFixedUpdate(dt) self:server_updateFuelStatus() + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.sv_storage_dirty = true + end + end + if self.sv_thruster_active ~= is_valid_active then self.sv_thruster_active = is_valid_active self.sv_data_dirty = true