mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Start work on trigger
This commit is contained in:
parent
55411ce6e2
commit
6332f2f5cf
159
tools/level_scripts/trigger.lua
Normal file
159
tools/level_scripts/trigger.lua
Normal file
|
@ -0,0 +1,159 @@
|
|||
|
||||
local sk_definition_writer = require('sk_definition_writer')
|
||||
local sk_scene = require('sk_scene')
|
||||
|
||||
sk_definition_writer.add_header('"../build/src/audio/clips.h"')
|
||||
|
||||
|
||||
local function does_belong_to_cutscene(first_step, step)
|
||||
local offset = step.position - first_step.position
|
||||
local local_pos = first_step.rotation * offset
|
||||
|
||||
return local_pos.y >= 0 and local_pos.x * local_pos.x + local_pos.z * local_pos.z < 0.1
|
||||
end
|
||||
|
||||
local function distance_from_start(first_step, step)
|
||||
local offset = step.position - first_step.position
|
||||
local local_pos = first_step.rotation * offset
|
||||
return local_pos.y
|
||||
end
|
||||
|
||||
local function cutscene_index(cutscenes, name)
|
||||
for index, cutscene in pairs(cutscenes) do
|
||||
if cutscene.name == name then
|
||||
return index - 1
|
||||
end
|
||||
end
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
local function find_label_locations(steps)
|
||||
local result = {}
|
||||
local current_index = 1
|
||||
|
||||
while current_index <= #steps do
|
||||
local step = steps[current_index]
|
||||
|
||||
if step.command == "label" and #step.args >= 1 then
|
||||
result[step.args[1]] = current_index
|
||||
table.remove(steps, current_index)
|
||||
else
|
||||
current_index = current_index + 1
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local function generate_cutscene_step(step)
|
||||
local result = {}
|
||||
|
||||
if step.command == "play_sound" or step.command == "start_sound" and #step.args >= 1 then
|
||||
result.type = step.command == "play_sound" and
|
||||
sk_definition_writer.raw('CutsceneStepTypePlaySound') or
|
||||
sk_definition_writer.raw('CutsceneStepTypeStartSound')
|
||||
else
|
||||
result.type = sk_definition_writer.raw('CutsceneStepTypeNoop')
|
||||
table.noop = 0;
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local function generate_cutscenes()
|
||||
local step_nodes = sk_scene.nodes_for_type("@cutscene")
|
||||
|
||||
local steps = {}
|
||||
local cutscenes = {}
|
||||
|
||||
for _, node_info in pairs(step_nodes) do
|
||||
if #node_info.arguments > 0 then
|
||||
local command = node_info.arguments[1]
|
||||
local args = {table.unpack(node_info.arguments, 2)}
|
||||
|
||||
local scale, rotation, position = node_info.node.transformation:decompose()
|
||||
|
||||
local step = {
|
||||
command = command,
|
||||
args = args,
|
||||
position = position,
|
||||
rotation = rotation:conjugate(),
|
||||
}
|
||||
|
||||
if command == "start" and #args > 1 then
|
||||
table.insert(cutscenes, {
|
||||
name = args[1],
|
||||
steps = {step},
|
||||
})
|
||||
else
|
||||
table.insert(steps, step)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, cutscene in pairs(cutscenes) do
|
||||
for _, step in pairs(steps) do
|
||||
if does_belong_to_cutscene(cutscene.steps[1], step) then
|
||||
table.insert(cutscene.steps, step)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local cutscenes_result = {}
|
||||
|
||||
for _, cutscene in pairs(cutscenes) do
|
||||
local first_step = cutscene.steps[1]
|
||||
local other_steps = {table.unpack(cutscene.steps, 2)}
|
||||
|
||||
table.sort(other_steps, function(a, b)
|
||||
return distance_from_start(first_step, a) < distance_from_start(first_step, b)
|
||||
end)
|
||||
|
||||
local label_locations = find_label_locations(other_steps)
|
||||
|
||||
local steps = {}
|
||||
|
||||
for step_index, step in pairs(other_steps) do
|
||||
table.insert(steps, generate_cutscene_step())
|
||||
end
|
||||
|
||||
sk_definition_writer.add_definition(cutscene.name .. '_steps', 'struct CutsceneStep[]', '_geo', steps)
|
||||
|
||||
table.insert(cutscenes_result, {
|
||||
name = cutscene.name,
|
||||
steps = steps,
|
||||
})
|
||||
end
|
||||
|
||||
return cutscenes_result
|
||||
end
|
||||
|
||||
local function generate_triggers(cutscenes)
|
||||
local result = {}
|
||||
|
||||
for _, trigger in pairs(sk_scene.nodes_for_type('@trigger')) do
|
||||
local first_mesh = trigger.node.meshes[1]
|
||||
local cutscene_index = cutscene_index(cutscenes, trigger.arugments[1])
|
||||
|
||||
if first_mesh and cutscene_index ~= -1 then
|
||||
local transformed = first_mesh:transform(trigger.node.full_transformation)
|
||||
|
||||
table.insert(result, {
|
||||
transformed.bb,
|
||||
cutscene_index,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
local cutscenes = generate_cutscenes()
|
||||
local triggers = generate_triggers(cutscenes)
|
||||
|
||||
sk_definition_writer.add_definition("triggers", "struct Trigger[]", "_geo", triggers)
|
||||
|
||||
return {
|
||||
triggers = triggers,
|
||||
}
|
Loading…
Reference in a new issue