diff --git a/.gitignore b/.gitignore index 7233211..3f07c1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /cache/ +/Cache/ /description.json preview.png \ No newline at end of file diff --git a/Objects/Textures/maths.png b/Objects/Textures/maths.png index 8d85dfc..ec82fc2 100644 Binary files a/Objects/Textures/maths.png and b/Objects/Textures/maths.png differ diff --git a/Scripts/interactable/NumberLogic/CounterBlock.lua b/Scripts/interactable/NumberLogic/CounterBlock.lua index a7beb64..98701f3 100644 --- a/Scripts/interactable/NumberLogic/CounterBlock.lua +++ b/Scripts/interactable/NumberLogic/CounterBlock.lua @@ -144,7 +144,7 @@ function CounterBlock.client_onInteract(self, character, lookAt) end function CounterBlock.client_onTextChangedCallback(self, widget, text) - local converted_text = tonumber(text) --will be nill if the input is invalid + local converted_text = mp_parseNumber(text) --will be nill if the input is invalid local is_valid = (converted_text ~= nil) self.counter_gui_input = text @@ -178,7 +178,7 @@ end function CounterBlock.client_gui_changeSavedValue(self, widget) local is_decrement = (widget:sub(0, 1) == "D") - local cur_changer = tonumber(self.counter_gui_input) + local cur_changer = mp_parseNumber(self.counter_gui_input) if cur_changer ~= nil then if is_decrement then cur_changer = -cur_changer @@ -189,7 +189,7 @@ function CounterBlock.client_gui_changeSavedValue(self, widget) end function CounterBlock.client_gui_saveWrittenValue(self) - local cur_value = tonumber(self.counter_gui_input) + local cur_value = mp_parseNumber(self.counter_gui_input) if cur_value ~= nil then self.network:sendToServer("server_setNewValue", cur_value) end diff --git a/Scripts/interactable/NumberLogic/MathBlock.lua b/Scripts/interactable/NumberLogic/MathBlock.lua index ef39fb1..efbc4e0 100644 --- a/Scripts/interactable/NumberLogic/MathBlock.lua +++ b/Scripts/interactable/NumberLogic/MathBlock.lua @@ -56,6 +56,9 @@ MathBlock.modetable = {--"value" aka "savevalue", gets saved, gets loaded. {value = 29, icon = "seated", name = "Seated" ,description = "Becomes active and outputs the value of input seats occupied"}, {value = 30, icon = "A/D", name = "A/D" ,description = "Outputs the A/D value, range: -1 to 1\nMultiple driverseat inputs: average of A/D output of inputs,\nExcellent for teamwork!"}, {value = 31, icon = "W/S", name = "W/S" ,description = "Outputs the W/S value, range: -1 to 1\nMultiple driverseat inputs: average of W/S output of inputs,\nExcellent for teamwork!"}, + {value = 39, icon = "OR", name = "Bitwise OR" ,description = "Outputs a number where each bit is 1 if the corresponding bit of ANY input is 1\n\nNegative inputs are treated as 0, non-integer inputs are rounded"}, + {value = 40, icon = "AND", name = "Bitwise AND" ,description = "Outputs a number where each bit is 1 if the corresponding bit of ALL inputs is 1\n\nNegative inputs are treated as 0, non-integer inputs are rounded"}, + {value = 41, icon = "XOR", name = "Bitwise XOR" ,description = "Outputs a number where each bit is 1 if the corresponding bit of AN ODD NUMBER of inputs is 1\n\nNegative inputs are treated as 0, non-integer inputs are rounded"}, } MathBlock.savemodes = {} for k,v in pairs(MathBlock.modetable) do @@ -823,7 +826,43 @@ MathBlock.modeFunctions = { end end self:sv_setValue(power) + end, + + [39] = function(self, parents) -- bitiwise or + local result = 0 + + for k, parent in pairs(parents) do + local value = math.round(sm.interactable.getValue(parent) or parent.power) + result = bit.bor(result, value) + end + + self:sv_setValue(result) + end, + + [40] = function(self, parents) -- bitiwise and + local result = 0 + + if #parents >1 then + result = bit.bnot(0) + for k, parent in pairs(parents) do + local value = math.round(sm.interactable.getValue(parent) or parent.power) + result = bit.band(result, value) + end + end + + self:sv_setValue(result) + end, + + [41] = function(self, parents) -- bitiwise xor + local result = 0 + + for k, parent in pairs(parents) do + local value = math.round(sm.interactable.getValue(parent) or parent.power) + result = bit.bxor(result, value) end + + self:sv_setValue(result) + end, } diff --git a/Scripts/libs/input.lua b/Scripts/libs/input.lua new file mode 100644 index 0000000..4e952d7 --- /dev/null +++ b/Scripts/libs/input.lua @@ -0,0 +1,30 @@ +if __Input_Loaded then return end +__Input_Loaded = true + +-- parses user-provided number strings +-- - removes all spaces +-- - parses binary numbers with the "0b", "0B" prefixes or "b" suffix +-- - parses hexadecimal numbers with the "0x", "0X" prefixes +-- returns nil for incorrectly formatted strings +-- +-- Examples: +-- mp_parseNumber(" 1 000 000 ") == 1000000 +-- mp_parseNumber("0xFF") == 255 +-- mp_parseNumber("0b1000") == 8 +-- mp_parseNumber("1000b") == 8 +-- mp_parseNumber("test") == nil +function mp_parseNumber(input) + normalized = string.gsub(input, "%s+", "") -- remove spaces + + prefix = string.sub(normalized, 1, 2) + suffix = string.sub(normalized, -1, -1) + if suffix == "b" or suffix == "B" then + return tonumber(string.sub(normalized, 1, -2), 2) + elseif prefix == "0b" or prefix == "0B" then + return tonumber(string.sub(normalized, 3, -1), 2) + elseif prefix == "0x" or prefix == "0X" then + return tonumber(string.sub(normalized, 3, -1), 16) + else + return tonumber(normalized, 10) + end +end diff --git a/Scripts/libs/load_libs.lua b/Scripts/libs/load_libs.lua index 3c6d409..735e02b 100644 --- a/Scripts/libs/load_libs.lua +++ b/Scripts/libs/load_libs.lua @@ -37,6 +37,7 @@ end dofile "debugger.lua" dofile "color.lua" +dofile "input.lua" dofile "math.lua" dofile "other.lua" dofile "virtual_buttons.lua"