223 lines
6.7 KiB
Lua
223 lines
6.7 KiB
Lua
local ent = ent
|
|
local scene = entities.currentScene()
|
|
|
|
local metadata = ent:getComponent("Metadata")
|
|
local darkMeta = metadata["dark"] or {}
|
|
local schemaDb = darkMeta["schema_db"] or {}
|
|
local classTags = darkMeta["class_tags"] or ""
|
|
|
|
_G.DarkTargets = _G.DarkTargets or {}
|
|
if darkMeta["id"] then
|
|
_G.DarkTargets[darkMeta["id"]] = ent:uid()
|
|
end
|
|
|
|
_G.DarkScripts = _G.DarkScripts or {}
|
|
|
|
_G.DarkScripts["RelayTrap"] = function(entity, payload, dMeta)
|
|
local msg = payload.message
|
|
local eName = entity or entity:uid()
|
|
--print(string.format("%s (RelayTrap) is forwarding %s down its links...", eName, msg))
|
|
|
|
entity:callHook("link:Broadcast.%UID%", {
|
|
message = msg,
|
|
flavors = { "ControlDevice", "SwitchLink" },
|
|
caller = entity:uid(),
|
|
callerDarkID = payload.callerDarkID
|
|
})
|
|
end
|
|
_G.DarkScripts["ElevatorButton"] = _G.DarkScripts["RelayTrap"]
|
|
|
|
_G.DarkScripts["RequireAllTrap"] = function(entity, payload, dMeta)
|
|
local msg = payload.message
|
|
local callerDarkID = payload.callerDarkID
|
|
|
|
_G.RAT_States = _G.RAT_States or {}
|
|
local uid = entity:uid()
|
|
_G.RAT_States[uid] = _G.RAT_States[uid] or { inputs = {}, wasOn = false }
|
|
local state = _G.RAT_States[uid]
|
|
|
|
if callerDarkID then
|
|
state.inputs[callerDarkID] = (msg == "TurnOn")
|
|
end
|
|
|
|
local allOn = true
|
|
local incoming = dMeta["incoming_connections"] or {}
|
|
for i = 1, #incoming do
|
|
local conn = incoming[i]
|
|
if conn.flavor == "ControlDevice" or conn.flavor == "SwitchLink" then
|
|
if not state.inputs[conn.source_id] then
|
|
allOn = false
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if allOn and not state.wasOn then
|
|
state.wasOn = true
|
|
--print(entity .. " (RequireAllTrap) conditions met! Broadcasting TurnOn.")
|
|
entity:callHook("link:Broadcast.%UID%", { message = "TurnOn", flavors = { "ControlDevice", "SwitchLink" }, callerDarkID = dMeta["id"], caller = uid })
|
|
elseif not allOn and state.wasOn then
|
|
state.wasOn = false
|
|
--print(entity .. " (RequireAllTrap) condition lost! Broadcasting TurnOff.")
|
|
entity:callHook("link:Broadcast.%UID%", { message = "TurnOff", flavors = { "ControlDevice", "SwitchLink" }, callerDarkID = dMeta["id"], caller = uid })
|
|
end
|
|
end
|
|
|
|
--[[
|
|
_G.DarkScripts["BaseElevator"] = function(entity, payload, dMeta)
|
|
local msg = payload.message
|
|
local eName = entity or entity:uid()
|
|
|
|
print(string.format("%s (Elevator) received command: %s", eName, msg))
|
|
|
|
if msg == "TurnOn" or msg == "TurnOff" then
|
|
print(string.format("--> Commanding Lift '%s' to move!", eName))
|
|
end
|
|
end
|
|
|
|
_G.DarkScripts["Elevator"] = _G.DarkScripts["BaseElevator"]
|
|
]]
|
|
|
|
ent:addHook("link:Message.%UID%", function(payload)
|
|
local msg = payload.message
|
|
local caller = payload.caller
|
|
local eName = ent:name() or ent:uid()
|
|
|
|
--print(string.format("Entity %s (Dark ID: %s) received message: %s from UID: %s", eName, darkMeta["id"] or "Unknown", msg, tostring(caller)))
|
|
|
|
local scripts = darkMeta["scripts"] or {}
|
|
local scriptHandled = false
|
|
|
|
for _, script in ipairs(scripts) do
|
|
if _G.DarkScripts[script] then
|
|
_G.DarkScripts[script](ent, payload, darkMeta)
|
|
scriptHandled = true
|
|
end
|
|
end
|
|
|
|
if not scriptHandled then
|
|
if eName:lower():match("filter") or eName:lower():match("trigger") then
|
|
_G.DarkScripts["RelayTrap"](ent, payload, darkMeta)
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function playButtonSound()
|
|
if not classTags or classTags == "" then return end
|
|
local myDeviceType = string.match(classTags, "DeviceType%s+([^%s,]+)")
|
|
|
|
local bestMatch = nil
|
|
local bestScore = -1
|
|
|
|
for _, schema in ipairs(schemaDb) do
|
|
local sTags = schema.tags or ""
|
|
local score = 0
|
|
|
|
if myDeviceType then
|
|
local paddedTags = sTags .. ","
|
|
|
|
if string.find(paddedTags, "DeviceType%s+" .. myDeviceType .. "[,%s]") then
|
|
score = score + 10
|
|
elseif string.find(paddedTags, "DeviceType%s+Gen[,%s]") then
|
|
score = score + 5
|
|
elseif string.find(sTags, "DeviceType") then
|
|
score = score - 10
|
|
end
|
|
|
|
if score > 0 then
|
|
if string.find(sTags, "Reject") then
|
|
score = score + 5
|
|
elseif string.find(sTags, "StateChange") or string.find(sTags, "Activate") then
|
|
score = score + 5
|
|
end
|
|
end
|
|
end
|
|
|
|
if score > bestScore then
|
|
bestScore = score
|
|
bestMatch = schema
|
|
end
|
|
end
|
|
|
|
print("Button sound resolution:", ent, classTags, myDeviceType, bestMatch and bestMatch.name or "None", bestScore)
|
|
|
|
if bestMatch and bestScore > 0 and bestMatch.wavs and #bestMatch.wavs > 0 then
|
|
local pick = bestMatch.wavs[math.random(#bestMatch.wavs)]
|
|
local resolvedUrl = string.resolveURI(pick, metadata["system"]["root"])
|
|
ent:callHook("sound:Emit.%UID%", {
|
|
filename = resolvedUrl, spatial = true, volume = 1.0, maxDistance = 15.0, rolloffFactor = 1.0, unique = true
|
|
})
|
|
end
|
|
end
|
|
|
|
local connections = darkMeta["connections"]
|
|
|
|
ent:addHook("link:Broadcast.%UID%", function(payload)
|
|
local msg = payload.message
|
|
local validFlavors = payload.flavors or { "ControlDevice", "SwitchLink" }
|
|
|
|
if not connections then
|
|
return
|
|
end
|
|
|
|
for i = 1, #connections do
|
|
local conn = connections[i]
|
|
local isValid = false
|
|
for _, flav in ipairs(validFlavors) do
|
|
if conn.flavor == flav then isValid = true break end
|
|
end
|
|
|
|
if isValid then
|
|
local targetUID = _G.DarkTargets[conn.target_id]
|
|
--print(string.format("Broadcasting %s to Dark ID %s (UID: %s) via %s", msg, conn.target_id, tostring(targetUID), conn.flavor))
|
|
|
|
if targetUID then
|
|
local targetEnt = entities.get(targetUID)
|
|
if targetEnt and targetEnt:uid() then
|
|
targetEnt:callHook("link:Message." .. targetUID, {
|
|
message = msg,
|
|
caller = ent:uid(),
|
|
callerDarkID = darkMeta["id"] or payload.callerDarkID
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
if darkMeta["frob"] ~= nil then
|
|
ent:addHook("entity:Use.%UID%", function(payload)
|
|
local frobWorld = darkMeta["frob"]["world"] or 0
|
|
|
|
local kFrobMove = 1 -- 1 << 0
|
|
local kFrobScript = 2 -- 1 << 1
|
|
|
|
if bit.band(frobWorld, kFrobScript) ~= 0 then
|
|
print(ent, json.encode( darkMeta ))
|
|
playButtonSound()
|
|
|
|
ent:callHook("link:Broadcast.%UID%", {
|
|
message = "TurnOn",
|
|
flavors = { "ControlDevice", "SwitchLink" },
|
|
caller = payload.user,
|
|
callerDarkID = darkMeta["id"]
|
|
})
|
|
end
|
|
|
|
if bit.band(frobWorld, kFrobMove) ~= 0 then
|
|
print("Item picked up!")
|
|
-- ent:callHook("inventory:Pickup.%UID%", { user = payload.user })
|
|
end
|
|
end)
|
|
end
|
|
|
|
ent:addHook("entity:Destroy.%UID%", function()
|
|
if darkMeta["id"] and _G.DarkTargets[darkMeta["id"]] == ent:uid() then
|
|
_G.DarkTargets[darkMeta["id"]] = nil
|
|
end
|
|
|
|
if _G.RAT_States and _G.RAT_States[ent:uid()] then
|
|
_G.RAT_States[ent:uid()] = nil
|
|
end
|
|
end) |