Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bitwise AND, OR and XOR modes to math block #91

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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