local ent = ent local scene = entities.currentScene() local metadata = ent:getComponent("Metadata") local metadataValve = metadata["valve"] or {} local physicsBody = ent:getComponent("PhysicsBody") local timer = Timer.new() if not timer:running() then timer:start() end local classname = metadataValve["classname"] or "trigger_multiple" local wait = tonumber(metadataValve["wait"]) or 0.2 local isActive = true if classname == "trigger_once" then wait = -1 end local touching = {} local nextTriggerTime = 0 ent:bind( "tick", function(self) if not isActive or not physicsBody:initialized() then return end local currentCollisions = {} local collisionEvents = physicsBody:getCollisionEvents() for i, event in ipairs(collisionEvents) do local other = nil if event.a:getObject():uid() == ent:uid() then other = event.b elseif event.b:getObject():uid() == ent:uid() then other = event.a end if other then local uid = other:getObject():uid() currentCollisions[uid] = true if not touching[uid] then touching[uid] = true ent:queueHook("io:FireOutput.%UID%", { output = "OnStartTouch" }, 0) if wait == -1 or timer:elapsed() >= nextTriggerTime then ent:queueHook("io:FireOutput.%UID%", { output = "OnTrigger" }, 0) if wait == -1 then isActive = false --entities.destroy(ent) return else nextTriggerTime = timer:elapsed() + wait end end end end end for uid, _ in pairs(touching) do if not currentCollisions[uid] then touching[uid] = nil ent:queueHook("io:FireOutput.%UID%", { output = "OnEndTouch" }, 0) end end end )