Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
26 changes: 26 additions & 0 deletions Gui/Layouts/MemoryPanelGui.layout
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<MyGUI type="Layout" version="3.2.0">
<Widget type="Widget" skin="BackgroundInteractableWide" name="BackPanel" position_real="0 0 0.2604166666666667 0.6018518518518519">
<Widget type="TextBox" align="HCenter Top" skin="TextBox" name="Title" position_real="0.208 0.023076923076923078 0.584 0.07692307692307693">
<Property key="Caption" value="#ffff00M E M O R Y#ffffff" />
<Property key="FontName" value="SM_Button" />
<Property key="TextAlign" value="Center" />
<Property key="TextShadow" value="true" />
</Widget>
<Widget type="Widget" align="HCenter Bottom" skin="NonBlurryBackgroundDarkRoundedLowerLeft" position_real="0 0.12307692307692308 1 0.8769230769230769">
<Widget type="Widget" align="Left Top" skin="SearchBarBackground" position_real="0.05 0.02631578947368421 0.9 0.8333333333333334">
<Widget type="EditBox" align="HStretch VStretch" skin="PhotoDescription" name="ValueInput" position_real="0.011111111111111112 0.021052631578947368 0.9777777777777777 0.9578947368421052">
<Property key="FontName" value="SM_Button" />
<Property key="TextShadow" value="false" />
<Property key="TextAlign" value="Left Top" />
<Property key="MultiLine" value="true" />
<Property key="VisibleVScroll" value="true" />
</Widget>
</Widget>
<Widget type="Button" align="Left Top" skin="PrimaryButton" name="SaveWrittenVal" position_real="0.04 0.8771929824561403 0.92 0.09649122807017543">
<Property key="FontName" value="SM_Button" />
<Property key="TextAlign" value="Center" />
<Property key="Caption" value="Write" />
</Widget>
</Widget>
</Widget>
</MyGUI>
126 changes: 124 additions & 2 deletions Scripts/interactable/NumberLogic/MemoryPanel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ MemoryPanel.colorNormal = sm.color.new( 0x7F567Dff )
MemoryPanel.colorHighlight = sm.color.new( 0x9f7fa5ff )
MemoryPanel.poseWeightCount = 1

function formatInput(text)
-- sanitize allowed characters: digits, colon, comma, period, minus
text = text:gsub("[^%d:,%.-]", "")
-- insert spaces after each colon not at the end
text = text:gsub(":([^$])", ": %1")
-- insert newlines after each comma not at the end
text = text:gsub(",([^$])", ",\n%1")
return text
end

function MemoryPanel.server_onRefresh( self )
sm.isDev = true
Expand Down Expand Up @@ -58,12 +67,11 @@ function MemoryPanel.server_onCreate( self )
memorypanels[self.interactable.id] = self
end

function MemoryPanel.server_setData(self, saveData)
function MemoryPanel.server_setData(self, saveData, caller)
self.data = saveData
self.storage:save(saveData)
end


function MemoryPanel.server_onFixedUpdate( self, dt )
local parents = self.interactable:getParents()
local address = 0
Expand Down Expand Up @@ -129,6 +137,16 @@ function MemoryPanel.client_onCreate(self)
self.time = 0
end

function MemoryPanel.client_onDestroy(self)
self:client_onGuiCloseCallback()
end

function MemoryPanel.client_canInteract(self)
local use_key = sm.gui.getKeyBinding("Use", true)
sm.gui.setInteractionText("Press", use_key, "to edit contents")
return true
end

function MemoryPanel.client_onFixedUpdate(self, dt)
local parents = self.interactable:getParents()
local address = 0
Expand Down Expand Up @@ -200,4 +218,108 @@ function MemoryPanel.client_setUvValue(self, value)
if value > 255 then value = 255 end
if value == math.huge then value = 0 end
self.interactable:setUvFrameIndex(value)
end

function MemoryPanel.client_displayData(self, data)
local parts = {}

local keys = {}
for k, v in pairs(data) do
if v ~= 0 or k == 0 then table.insert(keys, k) end
end

table.sort(keys)

for _, k in ipairs(keys) do
table.insert(parts, k .. ": " .. data[k])
end

self.mem_gui_input = table.concat(parts, ",\n")

self.mem_gui:setText("ValueInput", self.mem_gui_input)
end

function MemoryPanel.client_onInteract(self, character, lookAt)
if mp_deprecated_game_version or not lookAt or character:getLockingInteractable() then return end
local mem_gui = sm.gui.createGuiFromLayout("$CONTENT_DATA/Gui/Layouts/MemoryPanelGui.layout", false, { backgroundAlpha = 0.5 })
mem_gui:setButtonCallback("SaveWrittenVal", "client_gui_saveWrittenValue")
mem_gui:setTextChangedCallback("ValueInput", "client_onTextChangedCallback")
mem_gui:setOnCloseCallback("client_onGuiCloseCallback")
self.mem_gui = mem_gui
if sm.isHost then
self:client_displayData(self.data)
else
self.network:sendToServer("server_getAndDisplayData")
end
mem_gui:open()
end

function MemoryPanel.server_getAndDisplayData(self, _, caller)
self.network:sendToClient(caller, "client_displayData", self.data)
end

function MemoryPanel.client_onTextChangedCallback(self, widget, text)
self.mem_gui_input = formatInput(text)
if text~=self.mem_gui_input then
self.mem_gui:setText("ValueInput", self.mem_gui_input)
end
end

function MemoryPanel.client_onGuiCloseCallback(self)
local mem_gui = self.mem_gui
if mem_gui and sm.exists(mem_gui) then
if mem_gui:isActive() then
mem_gui:close()
end

mem_gui:destroy()
end

self.mem_gui_input = nil
self.mem_gui = nil
end


function MemoryPanel.parseData(input)
local data = {}

for entry in input:gmatch("([^,]+)") do
-- trim surrounding whitespace
entry = entry:match("^%s*(.-)%s*$") or ""
if entry ~= "" then
-- require exactly one ':' and non-empty lhs and rhs
local addrStr, valStr = entry:match("^([^:]+):([^:]+)$")
if addrStr and valStr then
addrStr = addrStr:match("^%s*(.-)%s*$") or ""
valStr = valStr:match("^%s*(.-)%s*$") or ""
if addrStr ~= "" and valStr ~= "" then
-- parse address to integer, make positive
local addr = tonumber(addrStr)
if addr then
addr = math.floor(math.abs(addr))

-- parse value
local numVal = tonumber(valStr)
if numVal then
data[addr] = tostring(numVal)
end
end
end
end
end
end

-- ensure there's at least a default entry (address 0) if nothing parsed
if not next(data) then
data[0] = "0"
end

return data
end

function MemoryPanel.client_gui_saveWrittenValue(self)
local data = self.parseData(self.mem_gui_input)
self:client_displayData(data)
self.network:sendToServer("server_setData", data)
sm.audio.play("GUI Item released", self.shape:getWorldPosition())
end