--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
-- This thing is unfinished and pretty unpolished, but you can mess with it if you want to
local PLUGIN = PLUGIN
PLUGIN.name = "Cutscenes/Slideshow"
PLUGIN.author = "chancer, vented/caramel"
PLUGIN.description = "A system for cutscenes."
PLUGIN.fadeDelay = 2
PLUGIN.cutscenes = PLUGIN.cutscenes or {}
ix.config.Add("PlayCutsceneOnCharacterLoad", true, "Whether or not to play a cutscene/slideshow when a player loads a character.", nil, {
category = "!Intro"
})
ix.config.Add("CutsceneID", "act4finale", "The [cutsceneID] of the cutscene/slideshow used for the intro.", nil, {
category = "!Intro"
})
if (SERVER) then
util.AddNetworkString("ix_cutscene")
--runs a cutscene on a single target
function PLUGIN:runCutscene(client, cutsceneID, bIntro)
net.Start("ix_cutscene")
net.WriteString(cutsceneID)
net.WriteBool(bIntro)
net.Send(client)
end
--runs a cutscene on everyone
function PLUGIN:runCutsceneAll(cutsceneID)
for k, client in pairs(player.GetAll()) do
net.Start("ix_cutscene")
net.WriteString(cutsceneID)
net.Send(client)
end
end
else
function PLUGIN:runCutscene(cutsceneID, bIntro)
local cutscene = PLUGIN.cutscenes[cutsceneID]
if (not cutscene) then return end
local client = LocalPlayer()
local cutStarted = false
local fadeDelay = PLUGIN.fadeDelay
--A panel for fading in and fading out.
local fade = vgui.Create("DPanel")
fade:SetSize(ScrW(), ScrH())
fade:SetSkin("Default")
fade:SetBackgroundColor(color_black)
fade:SetAlpha(0)
if bIntro then
fade:SetAlpha(255)
end
fade:SetZPos(999)
--panel that holds the image and subtitles
local scenePanel = vgui.Create("DPanel")
scenePanel:SetSize(ScrW(), ScrH())
scenePanel:SetZPos(999)
--image
local image = scenePanel:Add("DHTML")
image:SetSize(ScrW(), ScrH() * 0.75)
local w, h, ft, clmp
local tSizeX
local tSizeY
--local fade
--local fade2
--local fadeout
w, h = ScrW(), ScrH()
--subtitles
scenePanel.Paint = function()
client = LocalPlayer()
ft = FrameTime()
curTime = CurTime()
--black background
if (cutStarted) then
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(-1, -1, w + 2, h + 2)
end
--subtitle drawing
if (client.scene) then
local scene = client.scene
if (scene.subtitle) then
--subtitle text
surface.SetFont(scene.font)
local textColor = scene.color
local red = textColor and textColor.r or 64
local green = textColor and textColor.g or 100
local blue = textColor and textColor.b or 100
surface.SetTextColor(red, green, blue, 255)
local lines = ix.util.WrapText(scene.subtitle, w * 0.5, scene.font)
local lineOffset = 0
for k, line in pairs(lines) do
tSizeX, tSizeY = surface.GetTextSize(line)
surface.SetTextPos(w * 0.5 - tSizeX * 0.5, h * 0.8 + tSizeY * 0.5 + lineOffset)
surface.DrawText(line)
lineOffset = lineOffset + tSizeY + 8
end
end
end
end
-- Add darkness
local function fadeIn()
fade:AlphaTo(255, fadeDelay, 0)
end
-- Remove darkness
local function fadeOut()
fade:AlphaTo(0, fadeDelay, 0)
end
--change the background image
local function changeImage(url)
if (url) then
image:SetHTML([[
]])
else
image:SetHTML("")
end
end
--starts/changes the subtitles
local function subtitleStart(subtitle)
if (subtitle.sound) then
--surface.PlaySound(subtitle.sound)
LocalPlayer():EmitSound(subtitle.sound, 75, 100, 0.4)
end
--sent to client for drawing
local clientScene = {
subtitle = subtitle.text,
color = subtitle.color,
font = subtitle.font,
sound = subtitle.sound,
}
client.scene = clientScene
end
--ends the
local function endCutscene(scene)
scenePanel:Remove()
fadeOut()
if (scene.songFade and ix.cutsceneMusic) then
local i = 0
timer.Create("cutSongFade", 0.5, 5, function()
i = i + 2
if (ix.cutsceneMusic.SetVolume) then
ix.cutsceneMusic:SetVolume(0.5 - i / 20)
else
ix.cutsceneMusic:ChangeVolume(1 - i / 10)
end
if (ix.cutsceneMusic:GetVolume() == 0) then
ix.cutsceneMusic:Stop()
ix.cutsceneMusic = nil
end
end)
end
timer.Simple(fadeDelay, function()
fade:Remove()
end)
end
--gross timer nonsense here, there's definitely a better way to do this
local delay = 0
--cutscene starts with a fade in
delay = delay + fadeDelay
for k, scene in SortedPairs(cutscene) do
-- every scene starts with a fade out
delay = delay + fadeDelay
scene.startTime = delay
for k, subtitle in pairs(scene.subtitles) do
subtitle.startTime = delay
delay = delay + subtitle.duration
end
-- every scene ends with fade in
delay = delay + fadeDelay
end
--fade in to start cutscene
fadeIn()
sound.PlayURL("common_computer/phone/pick_up.ogg", "noblock", function(music, errorID, fault)
if music then
music:SetVolume(0.5)
ix.cutsceneMainMusic = music
ix.cutsceneMainMusic:Play()
end
end)
for k, scene in SortedPairs(cutscene) do
-- Scene timer, delays the scene
timer.Simple(scene.startTime, function()
fadeOut() -- Remove darkness, revealing the image
cutStarted = true
changeImage(scene.image)
if (scene.sound) then
if (ix.cutsceneMusic) then
ix.cutsceneMusic:Stop()
ix.cutsceneMusic = nil
end
if (scene.sound:find("http")) then
sound.PlayURL(scene.sound, "noplay", function(music, errorID, fault)
if (music) then
music:SetVolume(10.0)
ix.cutsceneMusic = music
ix.cutsceneMusic:Play()
end
end)
else
ix.cutsceneMusic = CreateSound(client, scene.sound)
ix.cutsceneMusic:PlayEx(1, 100)
end
end
end)
for k2, subtitle in SortedPairs(scene.subtitles) do
-- Subtitle timer, delays each subtitle
timer.Simple(subtitle.startTime, function()
subtitleStart(subtitle)
-- last subtitle of scene, fade to black
if (k2 == #scene.subtitles) then
fadeIn()
timer.Simple(fadeDelay, function()
changeImage()
client.scene = nil
-- last subtitle of last scene, end the cutscene
if (k == #cutscene) then
timer.Simple(fadeDelay, function()
endCutscene(scene)
end)
end
end)
end
end)
end
end
end
--server tells client to run cutscene
net.Receive("ix_cutscene", function(cutsceneID)
local cutsceneID = net.ReadString()
local bIntro = net.ReadBool()
PLUGIN:runCutscene(cutsceneID, bIntro)
end)
end
--commands to run these things
ix.command.Add("PlaySlideshowAll", {
adminOnly = true,
syntax = "",
arguments = {ix.type.string},
OnRun = function(self, client, cutsceneID)
-- local cutsceneID = arguments[1]
if (not cutsceneID) then
client:Notify("Missing information.")
return false
end
if (not PLUGIN.cutscenes[cutsceneID]) then
client:Notify("Invalid cutscene " .. cutsceneID .. ".")
return false
end
PLUGIN:runCutsceneAll(cutsceneID)
end
})
--commands to run these things
ix.command.Add("PlaySlideshowTarget", {
adminOnly = true,
syntax = " ",
arguments = {ix.type.player, ix.type.string},
OnRun = function(self, client, target, cutsceneID)
if (IsValid(target) and target:GetCharacter()) then
if (not cutsceneID) then
client:Notify("Missing information.")
return false
end
if (not PLUGIN.cutscenes[cutsceneID]) then
client:Notify("Invalid cutscene " .. cutsceneID .. ".")
return false
end
PLUGIN:runCutscene(target, cutsceneID)
end
end
})
-- run on first spawn
--CharacterLoaded OnCharacterCreated
function PLUGIN:CharacterLoaded(client)
timer.Simple(1, function()
if ix.config.Get("PlayCutsceneOnCharacterLoad", true) then
PLUGIN:runCutscene(client, ix.config.Get("CutsceneID"), true)
end
end)
end