77 lines
2.9 KiB
Lua
77 lines
2.9 KiB
Lua
-- No webcam (webcam_number -1, or it would not open): the scan fails like collabo_smart's failed_end (sprite 146).
|
|
-- The shutter drops over the camera window, the rest of the screen dims, the notes box pops up, then black.
|
|
CameraFailed = {}
|
|
CameraFailed.__index = CameraFailed
|
|
|
|
local S = tex.get_screen_scale()
|
|
local DIR = "campaign/camera_failed"
|
|
local F = 1000 / 60
|
|
local END_F = 586
|
|
-- everything but the camera window (330, 60.3)-(950, 522.9) dims
|
|
local DIM = { { 0, 0, 330, 720 }, { 950, 0, 330, 720 }, { 330, 0, 620, 60.3 }, { 330, 522.9, 620, 197.1 } }
|
|
local CUES = { { 0, "smart_se_shutterdown" }, { 39, "smart_se_shutterclose" }, { 39, "smart_vo_failed" } }
|
|
|
|
local function play(name)
|
|
if audio.has_sound(name) then audio.play_sound(name, name:find("_vo_") and "voice" or "sound") end
|
|
end
|
|
|
|
local function ramp(f, at, len) return math.max(0, math.min(1, (f - at) / len)) end
|
|
local function ease_in(u) return u * u end
|
|
local function ease_out(u) return u * (2 - u) end
|
|
|
|
-- shutter offset from its rest: falls in 40 f, bounces 30 px and lands again
|
|
local function shutter_dy(f)
|
|
if f < 40 then return -488 * (1 - ease_in(f / 40)) end
|
|
if f < 47 then return -10.6 - 29.4 * ease_out(ramp(f, 41, 6)) end
|
|
if f < 51 then return -37.5 * (1 - ease_in(ramp(f, 48, 3))) end
|
|
return 0
|
|
end
|
|
|
|
function CameraFailed.new(now)
|
|
local self = setmetatable({}, CameraFailed)
|
|
self.tex = {}
|
|
for _, key in ipairs({ "shutter", "failed_text", "failed_don", "notes" }) do
|
|
self.tex[key] = tex.get_texture(DIR .. "/" .. key)
|
|
end
|
|
self.box = tex.get_texture("campaign/smart_scan/keep_box")
|
|
self.t0, self.now, self.cue_f = now, now, -1
|
|
return self
|
|
end
|
|
|
|
function CameraFailed:frames() return (self.now - self.t0) / F end
|
|
|
|
function CameraFailed:update(now)
|
|
self.now = now
|
|
local f = self:frames()
|
|
for _, cue in ipairs(CUES) do
|
|
if cue[1] > self.cue_f and cue[1] <= f then play(cue[2]) end
|
|
end
|
|
self.cue_f = f
|
|
end
|
|
|
|
function CameraFailed:is_done() return self:frames() >= END_F end
|
|
|
|
-- inside the camera window: draw before the holed background
|
|
function CameraFailed:draw_window()
|
|
local f, tx = self:frames(), self.tex
|
|
tex.draw_texture(tx.shutter, { y = shutter_dy(f) * S })
|
|
local fade = ramp(f, 40, 19)
|
|
tex.draw_texture(tx.failed_text, { fade = fade })
|
|
tex.draw_texture(tx.failed_don, { fade = fade })
|
|
end
|
|
|
|
-- over the whole scene
|
|
function CameraFailed:draw_overlay()
|
|
local f = self:frames()
|
|
local dim = math.floor(255 * 0.641 * ramp(f, 40, 20))
|
|
for _, r in ipairs(DIM) do tex.draw_rect(r[1] * S, r[2] * S, r[3] * S, r[4] * S, 0, 0, 0, dim) end
|
|
if f >= 120 then
|
|
local fade = ease_in(ramp(f, 120, 5))
|
|
tex.draw_texture(self.box, { y = -43 * S, fade = fade }) -- the keep box, 43 px higher
|
|
tex.draw_texture(self.tex.notes, { fade = fade })
|
|
end
|
|
if f >= 526 then
|
|
tex.draw_rect(0, 0, tex.get_screen_width(), tex.get_screen_height(), 0, 0, 0, 255 * ramp(f, 526, 60))
|
|
end
|
|
end
|