-- Alarm box will blink periodically when alarm is not triggered and -- faster when alarm is triggered. Alarm is triggered if ay of: -- 1) Box is broken -- 2) Box is tampered with (multiple modes, depending on how the box is attached) -- 3) Any rope connected to this box is detached JOINTED_STATIC = 1 JOINTED_DYNAMIC = 2 FIXED_STATIC = 3 FIXED_DYNAMIC = 4 alarmType = nil blinkTimer = nil function init() box = FindShape("alarmbox") local joints = GetShapeJoints(box) wires = {} wireVehicle = {} for i=1,#joints do if GetJointType(joints[i]) == "rope" then wires[#wires+1] = joints[i] local otherShape = GetJointOtherShape(joints[i],box) wireVehicle[#wireVehicle+1] = GetBodyVehicle(GetShapeBody(otherShape)) else joint = joints[i] end end if joint then local s = GetJointOtherShape(joint, box) if IsBodyDynamic(GetShapeBody(s)) then alarmType = JOINTED_DYNAMIC initialMass = GetBodyMass(GetShapeBody(s)) else alarmType = JOINTED_STATIC end else if IsBodyDynamic(GetShapeBody(box)) then alarmType = FIXED_DYNAMIC initialMass = GetBodyMass(GetShapeBody(box)) else alarmType = FIXED_STATIC end end SetShapeEmissiveScale(box, 0) blinkTimer = 0 end function tick(dt) if GetBool("level.alarmdisabled") then SetShapeEmissiveScale(box, 0) return end blinkTimer = blinkTimer + dt local t = math.fmod(blinkTimer, 1.0) local alarm = GetBool("level.alarm") if alarm then --Alarm blink if t < 0.5 then SetShapeEmissiveScale(box, 1) else SetShapeEmissiveScale(box, 0) end else --Regular blink if t > 0.9 then SetShapeEmissiveScale(box, 0.5) else SetShapeEmissiveScale(box, 0) end end --Check if alarm should be triggered if not alarm then local triggerAlarm = false -- Trigger alarm if any wire is broken for i=1,#wires do if IsJointBroken(wires[i]) then triggerAlarm = true else if wireVehicle[i] ~= 0 then local otherShape = GetJointOtherShape(wires[i],box) if wireVehicle[i] ~= GetBodyVehicle(GetShapeBody(otherShape)) then triggerAlarm = true end end end end -- Trigger alarm if box is broken if IsShapeBroken(box) then triggerAlarm = true end if alarmType == FIXED_STATIC then if IsBodyDynamic(GetShapeBody(box)) then triggerAlarm = true end elseif alarmType == FIXED_DYNAMIC then local currentMass = GetBodyMass(GetShapeBody(box)) if currentMass < 0.5 * initialMass then triggerAlarm = true end elseif alarmType == JOINTED_STATIC then if IsJointBroken(joint) then triggerAlarm = true else local s = GetJointOtherShape(joint, box) if IsBodyDynamic(GetShapeBody(s)) then triggerAlarm = true end end elseif alarmType == JOINTED_DYNAMIC then if IsJointBroken(joint) then triggerAlarm = true else local s = GetJointOtherShape(joint, box) local currentMass = GetBodyMass(GetShapeBody(s)) if currentMass < 0.5 * initialMass then triggerAlarm = true end end end if triggerAlarm then local challengeState = GetString("challenge.state") if challengeState == "unavailable" then SetBool("level.alarm", true) end if GetString("challenge.state") ~= "done" then SetBool("level.alarm", true) end blinkTimer = 0 end end end