191 lines
5.6 KiB
Lua
191 lines
5.6 KiB
Lua
local scene = entities.currentScene()
|
|
local controller = entities.controller()
|
|
local controllerTransform = controller:getComponent("Transform")
|
|
local timer = Timer.new()
|
|
if not timer:running() then
|
|
timer:start();
|
|
end
|
|
local metadata = ent:getComponent("Metadata")
|
|
local soundEmitter = ent:loadChild("./sound.json",true)
|
|
local playSound = function( key )
|
|
if not loop then loop = false end
|
|
local url = "./audio/sfx/" .. key .. ".ogg"
|
|
soundEmitter:queueHook("sound:Emit.%UID%", {
|
|
filename = string.resolveURI(url, metadata["system"]["root"]),
|
|
spatial = true,
|
|
loop = loop,
|
|
volume = "sfx",
|
|
streamed = true
|
|
}, 0)
|
|
end
|
|
local playSoundscape = function( key )
|
|
local url = "./audio/soundscape/" .. key .. ".ogg"
|
|
soundEmitter:queueHook("sound:Emit.%UID%", {
|
|
filename = string.resolveURI(url, metadata["system"]["root"]),
|
|
spatial = false,
|
|
volume = "sfx",
|
|
loop = true,
|
|
streamed = true
|
|
}, 0)
|
|
end
|
|
local stopSoundscape = function( key )
|
|
local url = "./audio/soundscape/" .. key .. ".ogg"
|
|
soundEmitter:queueHook("sound:Stop.%UID%", {
|
|
filename = string.resolveURI(url, metadata["system"]["root"])
|
|
}, 0)
|
|
end
|
|
|
|
local target = Vector3f(0,0,0)
|
|
local transform = ent:getComponent("Transform")
|
|
local speed = metadata["speed"] or 1.0 / 3.0
|
|
local angle = metadata["angle"] or 1.5
|
|
transform.orientation = Quaternion.axisAngle( Vector3f(0,1,0), 1.5 )
|
|
local starting = transform.orientation:multiply(Quaternion.axisAngle( Vector3f(0,1,0), -angle ))
|
|
local ending = transform.orientation:multiply(Quaternion.axisAngle( Vector3f(0,1,0), angle ))
|
|
-- on tick
|
|
local delta = 0
|
|
local watch = 0
|
|
local alerted = false
|
|
local light = nil
|
|
local lightOffset = nil
|
|
|
|
for k, v in pairs(ent:getChildren()) do
|
|
if v:uid() ~= soundEmitter:uid() then
|
|
light = v
|
|
local transform = v:getComponent("Transform")
|
|
lightOffset = Vector3f(transform.position) --:magnitude()
|
|
end
|
|
end
|
|
|
|
ent:bind( "tick", function(self)
|
|
soundEmitter:getComponent("Transform").position = transform.position
|
|
|
|
local angleThreshold = metadata["sensitivity"] or 20
|
|
|
|
local controllerPosition = Vector3f(controllerTransform.position.x, 0, controllerTransform.position.z)
|
|
local cameraPosition = Vector3f(transform.position.x, 0, transform.position.z)
|
|
local distance = cameraPosition:distance(controllerPosition)
|
|
local direction = cameraPosition - controllerPosition
|
|
|
|
local lightTransform = light and light:getComponent("Transform") or nil
|
|
local lightMetadata = light and light:getComponent("Metadata") or {}
|
|
if lightTransform ~= nil then
|
|
lightTransform.position = transform.orientation:rotate( lightOffset );
|
|
if lightMetadata and lightMetadata["light"] and lightMetadata["light"]["static"] then
|
|
lightTransform.position = lightTransform.position + transform.position
|
|
end
|
|
end
|
|
|
|
local angle = math.acos(transform.orientation:rotate( Vector3f(0,0,1):normalize() ):dot( direction:normalize() )) * 180.0 / 3.1415926
|
|
if angle < angleThreshold and distance < 16 then
|
|
if watch == 0 then
|
|
watch = 6
|
|
playSound("camera_see")
|
|
if light then
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.color",
|
|
value = {
|
|
[1] = 1,
|
|
[2] = 1,
|
|
[3] = 0
|
|
}
|
|
} )
|
|
end
|
|
end
|
|
watch = watch + time.delta()
|
|
if watch > 12 and not alerted then
|
|
playSound("camera_alert")
|
|
playSound("xerxes_alert")
|
|
playSoundscape("alarm")
|
|
alerted = true
|
|
timer:reset()
|
|
if light then
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.color",
|
|
value = {
|
|
[1] = 1,
|
|
[2] = 0,
|
|
[3] = 0
|
|
}
|
|
} )
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.fade",
|
|
value = {
|
|
rate = 1,
|
|
power = 0.01,
|
|
timeout= 0.5
|
|
}
|
|
} )
|
|
end
|
|
end
|
|
else
|
|
if watch > 0 and not alerted then
|
|
watch = watch - time.delta()
|
|
if watch < 0 then
|
|
io.print("CAMERA LOST")
|
|
watch = 0
|
|
speed = metadata["speed"] or 1.0 / 3.0
|
|
if light then
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.color",
|
|
value = {
|
|
[1] = 0,
|
|
[2] = 1,
|
|
[3] = 0
|
|
}
|
|
} )
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.fade",
|
|
value = nil
|
|
} )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not alerted and watch > 0 and light then
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.fade.rate",
|
|
value = math.floor(watch / 2),
|
|
} )
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.fade.power",
|
|
value = 0.01,
|
|
} )
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.fade.timeout",
|
|
value = 0.5,
|
|
} )
|
|
end
|
|
if alerted and timer:elapsed() >= 60 then
|
|
timer:reset()
|
|
alerted = false
|
|
watch = 0
|
|
io.print("ALERT OVER")
|
|
playSound("camera_lost")
|
|
stopSoundscape("alarm");
|
|
if light then
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.color",
|
|
value = {
|
|
[1] = 0,
|
|
[2] = 1,
|
|
[3] = 0
|
|
}
|
|
} )
|
|
light:callHook( "object:UpdateMetadata.%UID%", {
|
|
path = "light.fade",
|
|
value = nil
|
|
} )
|
|
end
|
|
end
|
|
|
|
delta = delta + time.delta() * speed
|
|
local nextRotation = starting:slerp( ending, math.cos(delta) * 0.5 + 0.5 )
|
|
-- stop if we are going to look away from player
|
|
local angleNext = math.acos(nextRotation:rotate( Vector3f(0,0,1):normalize() ):dot( direction:normalize() )) * 180.0 / 3.1415926
|
|
if watch > 0 and angleNext > angle then
|
|
delta = delta - time.delta() * speed * 3
|
|
nextRotation = starting:slerp( ending, math.cos(delta) * 0.5 + 0.5 )
|
|
end
|
|
transform.orientation = nextRotation
|
|
end ) |