Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/cache/
/Cache/
/description.json
preview.png
preview.png
Binary file modified Objects/Textures/maths.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 20 additions & 20 deletions Scripts/interactable/NumberLogic/CounterBlock.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ CounterBlock.digs = {
["560202ff"] = -10,
["472800ff"] = -1,
["222222ff"] = -1,

["a0ea00ff"] = 10000000,
["19e753ff"] = 1000000,
["2ce6e6ff"] = 100000,
Expand All @@ -37,7 +37,7 @@ CounterBlock.digs = {
["d02525ff"] = 10,
["df7f00ff"] = 1,
["df7f01ff"] = 1, -- yay the devs made all vanilla stuff color have an offset compared to old vanilla stuff >:-(

["eeaf5cff"] = 0.1,
["f06767ff"] = 0.01,
["ee7bf0ff"] = 0.001,
Expand All @@ -46,7 +46,7 @@ CounterBlock.digs = {
["7eededff"] = 0.000001,
["68ff88ff"] = 0.0000001,
["cbf66fff"] = 0.00000001,

["673b00ff"] = -0.1,
["7c0000ff"] = -0.01,
["720a74ff"] = -0.001,
Expand Down Expand Up @@ -78,7 +78,7 @@ end

function CounterBlock.server_onFixedUpdate( self, dt )
local parents = self.interactable:getParents()

local reset = false
for k,v in pairs(parents) do
local x = self.digs[tostring(v:getShape().color)]
Expand All @@ -88,21 +88,21 @@ function CounterBlock.server_onFixedUpdate( self, dt )
if tostring(sm.shape.getColor(v:getShape())) == "eeeeeeff" and v:isActive() then reset = true end
end
if reset then self.power = 0 end

self.needssave = self.needssave or (self.power ~= sm.interactable.getValue(self.interactable))

local isTime = os.time()%5 == 0
if self.needssave and isTime and self.risingedge then
self.needssave = false
self.storage:save(tostring(self.power)) -- 64 bit precision (storage.save only goes up to 32 bit numbers)
end
self.risingedge = not isTime

if self.power ~= self.power then self.power = 0 end -- NaN check
if math.abs(self.power) >= 3.3*10^38 then -- inf check
if self.power < 0 then self.power = -3.3*10^38 else self.power = 3.3*10^38 end
if self.power < 0 then self.power = -3.3*10^38 else self.power = 3.3*10^38 end
end

mp_updateOutputData(self, self.power, self.power > 0)
end

Expand All @@ -125,7 +125,7 @@ function CounterBlock.server_reset(self)
self.power = 0
end

local sound_id_table =
local sound_id_table =
{
[1] = "GUI Item drag",
[2] = "GUI Item released"
Expand All @@ -139,12 +139,12 @@ 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 converted_text = math.parsenumber(text) --will be nill if the input is invalid
local is_valid = (converted_text ~= nil)

self.counter_gui_input = text
Expand Down Expand Up @@ -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 = math.parsenumber(self.counter_gui_input)
if cur_changer ~= nil then
if is_decrement then
cur_changer = -cur_changer
Expand All @@ -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 = math.parsenumber(self.counter_gui_input)
if cur_value ~= nil then
self.network:sendToServer("server_setNewValue", cur_value)
end
Expand Down Expand Up @@ -248,20 +248,20 @@ function CounterBlock.client_onFixedUpdate(self, dt)

local power = self.interactable.power
if self.powerSkip == power then return end -- more performance (only update uv if power changes)

local on = 0
if power ~= self.lastpower then
on = 6
self.frameindex = (self.frameindex + (power > self.lastpower and 0.25 or -0.25)) % 5
if power == 0 then self.frameindex = 0 end

if power == 0 then self.frameindex = 0 end
end

local index = math.floor(self.frameindex + on)
if index ~= self.lastindex then
if index ~= self.lastindex then
self.interactable:setUvFrameIndex(index)
end

self.powerSkip = (power == self.lastpower and power or false)
self.lastpower = power
self.lastindex = index
Expand Down
43 changes: 41 additions & 2 deletions Scripts/interactable/NumberLogic/MathBlock.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -823,7 +826,43 @@ MathBlock.modeFunctions = {
end
end
self:sv_setValue(power)
end
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,
}


Expand Down Expand Up @@ -904,7 +943,7 @@ function MathBlock.client_onInteract(self, character, lookAt)
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
Expand Down
30 changes: 29 additions & 1 deletion Scripts/libs/math.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,38 @@ function math.roundby( x, by)

end

-- 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:
-- math.parsestring(" 1 000 000 ") == 1000000
-- math.parsestring("0xFF") == 255
-- math.parsestring("0b1000") == 8
-- math.parsestring("1000b") == 8
-- math.parsestring("test") == nil
function math.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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's best to move this function outside of the math namespace, as it's shared with all mod/vanilla scripts. I know we've done it with more functions, but this could interfere with other mods that define a function with the same name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I've moved math.parsenumber to a new lib input (maybe there is a clearly better place to put it?) as mp_parseNumber

function table.size(tablename)
local i = 0
for k, v in pairs(tablename) do
i = i +1
end
return i
end
end