engine/bin/data/scenes/ss2/scripts/camera.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 )