Make cinecam idle waypoints runtime-manageable

Waypoints can be added/removed via chat
commands.  This makes it easier to adapt to
various "points of interest" that may evolve over
time with the world.
This commit is contained in:
Aaron Suen 2023-01-14 10:43:53 -05:00
parent 20d97f7bf4
commit dc22af9e61
2 changed files with 89 additions and 17 deletions

View File

@ -4,8 +4,14 @@ This mod provides a more "cinematic" camera positioning system than
szutil_watch, providing a series of 3rd-party "chase" cams that move
via simple jumpcuts.
WARNING: this mod is heavily WIP and is missing a lot of functionality
When no players are online, the camera will switch to a mode where it
watches the "spawn" area, or rotating through a set of waypoints that
can be managed via chatcommands at runtime.
WARNING: this mod is intentionally missing a lot of functionality
that you would expect, like rendering the player invisible, preventing
the player from falling or taking damage, etc.
the player from falling or taking damage, etc. This is the
responsibility of other mods. See szutil_stealth for the invisibility
feature; the rest will be game-depenent.
------------------------------------------------------------------------

View File

@ -1,13 +1,16 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, pairs, rawget, rawset, tonumber, type
= ipairs, math, minetest, pairs, rawget, rawset, tonumber, type
local ipairs, math, minetest, pairs, rawget, rawset, table, tonumber,
type
= ipairs, math, minetest, pairs, rawget, rawset, table, tonumber,
type
local math_atan2, math_ceil, math_cos, math_pi, math_random, math_sin,
math_sqrt
math_sqrt, table_concat
= math.atan2, math.ceil, math.cos, math.pi, math.random, math.sin,
math.sqrt
math.sqrt, table.concat
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local modstore = minetest.get_mod_storage()
local api = rawget(_G, modname) or {}
rawset(_G, modname, api)
@ -43,7 +46,6 @@ local defaults = {
local config
local enabled_players
local waypoints
local function reconfigure()
config = {}
@ -56,16 +58,6 @@ local function reconfigure()
enabled_players[n] = true
end
end
waypoints = {}
local wpstr = minetest.settings:get(modname .. "_waypoints") or ""
if wpstr == "" then wpstr = minetest.settings:get("static_spawn") or "" end
for _, n in pairs(wpstr:split(';')) do
local xyz = n:split(",")
if #xyz == 3 then
waypoints[#waypoints + 1] = vector.new(xyz[1], xyz[2], xyz[3])
end
end
if #waypoints < 1 then waypoints[1] = vector.new(0, 0, 0) end
return true, modname .. " config reloaded"
end
reconfigure()
@ -76,6 +68,80 @@ minetest.register_chatcommand(modname, {
func = reconfigure
})
local waypoints
do
local explicit_wps
local function waypoint_publish()
waypoints = explicit_wps
if #waypoints < 1 then
local ss = minetest.setting_get_pos("static_spawn")
if ss then waypoints = {ss} end
end
if #waypoints < 1 then
waypoints = {vector.new(0, 0, 0)}
end
end
do
local s = modstore:get_string("waypoints")
explicit_wps = s and minetest.deserialize(s) or {}
waypoint_publish()
end
local function wprm(pos)
for i = #explicit_wps, 1, -1 do
local wp = explicit_wps[i]
if vector.distance(wp, pos) <= 4 then
explicit_wps[i] = explicit_wps[#explicit_wps]
explicit_wps[#explicit_wps] = nil
end
end
end
local function wprpt()
local tbl = {modname, "waypoints:"}
for i = 1, #explicit_wps do
tbl[#tbl + 1] = minetest.pos_to_string(explicit_wps[i], 0)
end
tbl[#tbl + 1] = "total=" .. #explicit_wps
return true, table_concat(tbl, " ")
end
local function waypoint_rmadd(add)
return function(name)
local player = minetest.get_player_by_name(name)
local pos = player and player:get_pos()
if not pos then return false, "must be online" end
wprm(pos)
if add then explicit_wps[#explicit_wps + 1] = pos end
waypoint_publish()
modstore:set_string("waypoints", minetest.serialize(explicit_wps))
return wprpt()
end
end
minetest.register_chatcommand(modname .. "_wpls", {
description = "List current " .. modname .. " waypoints",
privs = {server = true},
func = wprpt
})
minetest.register_chatcommand(modname .. "_wprm", {
description = "Remove current location from " .. modname .. " waypoints",
privs = {server = true},
func = waypoint_rmadd()
})
minetest.register_chatcommand(modname .. "_wpset", {
description = "Add current location to " .. modname .. " waypoints",
privs = {server = true},
func = waypoint_rmadd(true)
})
minetest.register_chatcommand(modname .. "_wpclear", {
description = "Reset all " .. modname .. " waypoints",
privs = {server = true},
func = function()
explicit_wps = {}
waypoint_publish()
modstore:set_string("waypoints", minetest.serialize(explicit_wps))
return wprpt()
end
})
end
local function setcamera(player, pos, target)
local delta = vector.normalize(vector.subtract(target, pos))
player:set_look_horizontal(math_atan2(delta.z, delta.x) - math_pi / 2)