Multiplayer Fixing

Now each player can make and save recordings with my new behaviours (rotation, flying scenes when looking a target ...)
Change key to stop playback by 'aux1'
Add detailled help command: /camera help
This commit is contained in:
sys4-fr 2018-02-17 19:22:59 +01:00
parent 38596c37dc
commit 1f6cfa99b1

195
init.lua
View File

@ -1,10 +1,7 @@
--[[ --[[
Copyright 2016-2017 - Auke Kok <sofar@foo-projects.org> Copyright 2016-2017 - Auke Kok <sofar@foo-projects.org>
Copyright 2017 - Elijah Duffy <theoctacian@gmail.com> Copyright 2017 - Elijah Duffy <theoctacian@gmail.com>
Copyright 2017 - sys4 <sys4@free.fr> Copyright 2017 - sys4 <sys4@free.fr>
License: License:
- Code: MIT - Code: MIT
- Models and textures: CC-BY-SA-3.0 - Models and textures: CC-BY-SA-3.0
@ -16,7 +13,7 @@ Usage: /camera
- use left/right to rotate if looking target is set - use left/right to rotate if looking target is set
- use crouch to stop rotating - use crouch to stop rotating
Use /camera play to play back the last recording. While playing back: Use /camera play to play back the last recording. While playing back:
- use crouch to stop playing back - use aux1 to stop playing back
Use /camera play <name> to play a specific recording Use /camera play <name> to play a specific recording
Use /camera save <name> to save the last recording Use /camera save <name> to save the last recording
- saved recordings exist through game restarts - saved recordings exist through game restarts
@ -78,12 +75,22 @@ minetest.register_on_shutdown(save)
-- Table for storing unsaved temporary recordings -- Table for storing unsaved temporary recordings
local temp = {} local temp = {}
-- Table and functions for storing params per players
local player_params = {}
local function get_player_params(playern)
if not player_params[playern] then
player_params[playern] = {}
end
return player_params[playern]
end
-- Camera definition -- Camera definition
local camera = { local camera = {
description = "Camera", description = "Camera",
visual = "wielditem", visual = "wielditem",
textures = {}, textures = {},
physical = false,
is_visible = false, is_visible = false,
collide_with_objects = false, collide_with_objects = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
@ -100,15 +107,10 @@ local camera = {
self.driver = player self.driver = player
self.mode = mode self.mode = mode
self.path = {} self.path = {}
self.look_dir_init = player:get_look_dir()
end, end,
} }
local player_look_dir = nil -- player look direction when starting record
local target_look_position = nil -- looking target
local speed_factor = 0.1 -- default speed factor
local rec_mode = 0 -- record mode
local rotate = false
local rotate_speed = 0
-- [event] On step -- [event] On step
function camera:on_step(dtime) function camera:on_step(dtime)
@ -120,36 +122,24 @@ function camera:on_step(dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
local vel = self.object:getvelocity() local vel = self.object:getvelocity()
local dir = self.driver:get_look_dir()
local cos_yaw, sin_yaw
-- if record mode -- if record mode
if self.mode == 0 or self.mode == 2 then if self.mode == 0 or self.mode == 2 then
-- Calculate pitch and yaw if target_look_position defined -- Calculate pitch and yaw if look target of player is defined
if target_look_position then local look_target = player_params[self.driver:get_player_name()].look_target
local vec_pos = vector.subtract(target_look_position, pos)
if look_target then
local vec_pos = vector.subtract(look_target, pos)
-- Pitch -- Pitch
local opp = vec_pos.y
local adj = vec_pos.x
if math.abs(vec_pos.z) > math.abs(vec_pos.x) then if math.abs(vec_pos.z) > math.abs(vec_pos.x) then
adj = vec_pos.z self.driver:set_look_vertical(-math.atan2(vec_pos.y, math.abs(vec_pos.z)))
else
self.driver:set_look_vertical(-math.atan2(vec_pos.y, math.abs(vec_pos.x)))
end end
self.driver:set_look_vertical(-math.atan2(opp, math.abs(adj)))
-- Yaw -- Yaw
opp = vec_pos.x self.driver:set_look_horizontal(-math.atan2(vec_pos.x, vec_pos.z))
adj = vec_pos.z
local yaw = -math.atan2(opp,adj)
self.driver:set_look_horizontal(yaw)
-- Make velocity to rotate camera
if rotate then
cos_yaw = math.cos(yaw)
sin_yaw = math.sin(yaw)
else
cos_yaw, sin_yaw = 0, 0
end
end end
-- Update path -- Update path
@ -164,6 +154,8 @@ function camera:on_step(dtime)
self.object:set_look_vertical(self.driver:get_look_vertical()) self.object:set_look_vertical(self.driver:get_look_vertical())
self.object:set_look_horizontal(self.driver:get_look_horizontal()) self.object:set_look_horizontal(self.driver:get_look_horizontal())
local params = get_player_params(self.driver:get_player_name())
-- Get controls -- Get controls
local ctrl = self.driver:get_player_control() local ctrl = self.driver:get_player_control()
@ -172,25 +164,21 @@ function camera:on_step(dtime)
-- if up, accelerate forward -- if up, accelerate forward
if ctrl.up then if ctrl.up then
speed = math.min(speed + speed_factor, 20) speed = math.min(speed + (params.speed_step or 0.1), 20)
end end
-- if down, accelerate backward -- if down, accelerate backward
if ctrl.down then if ctrl.down then
speed = math.max(speed - speed_factor, -20) speed = math.max(speed - (params.speed_step or 0.1), -20)
end end
if ctrl.right and target_look_position then -- if jump, brake
rotate = true if ctrl.jump then
rotate_speed = math.min(rotate_speed + speed_factor, 0.5) speed = math.max(speed * 0.9, 0.0)
params.rotate_speed = math.max((params.rotate_speed or 0) * 0.9, 0.0)
end end
if ctrl.left and target_look_position then -- if aux1 (aka key 'e'), stop recording
rotate = true
rotate_speed = math.max(rotate_speed - speed_factor, -1)
end
-- if aux1 (aka key 'e') then stop recording
if ctrl.aux1 then if ctrl.aux1 then
self.driver:set_detach() self.driver:set_detach()
minetest.chat_send_player(self.driver:get_player_name(), "Recorded stopped after " .. #self.path .. " points") minetest.chat_send_player(self.driver:get_player_name(), "Recorded stopped after " .. #self.path .. " points")
@ -199,42 +187,46 @@ function camera:on_step(dtime)
return return
end end
-- if jump, brake -- if sneak, stop rotation
if ctrl.jump then if ctrl.sneak then
speed = math.max(speed * 0.5, 0.0) params.rotate = false
rotate_speed = math.max(speed * 0.5, 0.0) params.rotate_speed = 0.0
end end
-- if sneak, stop rotating -- if right, accelerate rotation to right
if ctrl.sneak then if ctrl.right and params.look_target then
rotate = false params.rotate = true
rotate_speed = 0 params.rotate_speed = math.min((params.rotate_speed or 0.0) + (params.speed_step or 0.1), 0.5)
end
-- if left, accelerate rotation to left
if ctrl.left and params.look_target then
params.rotate = true
params.rotate_speed = math.max((params.rotate_speed or 0.0) - (params.speed_step or 0.1), -1)
end end
-- Set updated velocity -- Set updated velocity
if self.mode == 0 then if self.mode == 0 then
self.object:setvelocity(vector.multiply(self.driver:get_look_dir(), speed)) self.object:setvelocity(vector.multiply(self.driver:get_look_dir(), speed))
elseif self.mode == 2 then elseif self.mode == 2 then
if rotate then if params.rotate then
self.object:setvelocity( self.object:setvelocity(
vector.multiply( vector.multiply(
{ {
x = self.object:get_velocity().x+cos_yaw, x = self.object:get_velocity().x + math.cos(self.driver:get_look_horizontal()),
y = 0, y = 0,
z = self.object:get_velocity().z+sin_yaw z = self.object:get_velocity().z + math.sin(self.driver:get_look_horizontal())
} }, params.rotate_speed))
, rotate_speed)) else
else self.object:setvelocity(vector.multiply(self.look_dir_init, speed))
self.object:setvelocity(vector.multiply(player_look_dir, speed)) end
end
end end
elseif self.mode == 1 then -- elseif playback mode elseif self.mode == 1 then -- elseif playback mode
-- Get controls -- Get controls
local ctrl = self.driver:get_player_control() local ctrl = self.driver:get_player_control()
-- if sneak or no path, stop playback -- if aux1 or no path, stop playback
if ctrl.sneak or #self.path < 1 then if ctrl.aux1 or #self.path < 1 then
self.driver:set_detach() self.driver:set_detach()
minetest.chat_send_player(self.driver:get_player_name(), "Playback stopped") minetest.chat_send_player(self.driver:get_player_name(), "Playback stopped")
self.object:remove() self.object:remove()
@ -264,12 +256,12 @@ minetest.register_chatcommand("camera", {
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
local param1, param2 = param:split(" ")[1], param:split(" ")[2] local param1, param2 = param:split(" ")[1], param:split(" ")[2]
-- if play, begin playback preparation -- if play, begin playback preperation
if param1 == "play" then if param1 == "play" then
local function play(path) local function play(path)
local object = minetest.add_entity(player:getpos(), "camera:camera") local object = minetest.add_entity(player:getpos(), "camera:camera")
object:get_luaentity():init(player, 1) object:get_luaentity():init(player, 1)
object:setyaw(player:get_look_horizontal()) object:setyaw(player:get_look_yaw())
player:set_attach(object, "", {x=5,y=10,z=0}, {x=0,y=0,z=0}) player:set_attach(object, "", {x=5,y=10,z=0}, {x=0,y=0,z=0})
object:get_luaentity().path = path object:get_luaentity().path = path
end end
@ -309,54 +301,81 @@ minetest.register_chatcommand("camera", {
elseif param1 == "look" then elseif param1 == "look" then
if param2 and param2 ~= "" then if param2 and param2 ~= "" then
if param2 == "nil" then if param2 == "nil" then
target_look_position = nil get_player_params(name).look_target = nil
return true, "Looking target removed" return true, "Looking target removed"
elseif param2 == "here" then elseif param2 == "here" then
rec_mode = 2 local player_params = get_player_params(name)
target_look_position = player:getpos() player_params.mode = 2
player_params.look_target = player:getpos()
return true, "Looking target fixed" return true, "Looking target fixed"
else else
local coord = string.split(param2, ",") local look_target = string.split(param2, ",")
if #coord == 3 then if #look_target == 3 then
target_look_position = {x=tonumber(coord[1]), y=tonumber(coord[2]), z=tonumber(coord[3])} local player_params = get_player_params(name)
rec_mode = 2 player_params.mode = 2
player_params.look_target =
{ x = tonumber(look_target[1]),
y = tonumber(look_target[2]),
z = tonumber(look_target[3])
}
return true, "Looking target fixed" return true, "Looking target fixed"
else else
return false, "Wrong formated look coords (/camera look <x,y,z>)" return false, "Looking target wrong format (/camera look <x,y,z>)"
end end
end end
else else
return false, "Missing look parameter (/camera look <nil|here|x,y,z>)" return false, "Parameters of looking target are missing (/camera look <nil|here|x,y,z)"
end end
elseif param1 == "speed" then elseif param1 == "speed" then
if param2 and param2 ~= "" then if param2 and param ~= "" then
local speed = tonumber(param2) local speed = tonumber(param2)
if speed then if speed then
speed_factor = 1/speed get_player_params(name).speed_step = 1/speed
return true, "Speed factor fixed to "..speed_factor return true, "Speed step fixed to "..get_player_params(name).speed_step
else else
return false, "Invalid speed factor (/camera speed <number>)" return false, "Invalid speed step (/camera speed <number>)"
end end
else else return false, "Missing speed step parameter (/camera speed <number>)"
return false, "Missing speed parameter (/camera speed <number>)"
end end
elseif param1 == "mode" then elseif param1 == "mode" then
if param2 and param2 ~= "" then if param2 and param2 ~= "" then
local mode = tonumber(param2) local mode = tonumber(param2)
if mode == 0 or mode == 2 then if mode == 0 or mode == 2 then
rec_mode = mode get_player_params(name).mode = mode
return true, "Record mode is set" return true, "Record mode is set"
else else return false, "Invalid mode (0: Velocity follow mouse (default), 2: Velocity locked to player first look direction)"
return false, "Invalid mode (0: Velocity follow mouse (default), 2: Velocity locked to player first look direction)"
end end
else else return false, "Missing mod parameter (/camera mode <0|2>)"
return false, "Missing mode parameter (/camera mode <0|2>)"
end end
elseif param1 == "help" then
local str = "Usage: /camera\n"..
"Execute command to start recording. While recording:\n"..
"- use up/down to accelerate/decelerate\n"..
"- use jump to brake\n"..
"- use aux1 to stop recording\n"..
"- use left/right to rotate if looking target is set\n"..
"- use crouch to stop rotating\n"..
"Use /camera play to play back the last recording. While playing back:\n"..
"- use aux1 to stop playing back\n"..
"Use /camera play <name> to play a specific recording\n"..
"Use /camera save <name> to save the last recording\n"..
"- saved recordings exist through game restarts\n"..
"Use /camera list to show all saved recording\n"..
"Use /camera mode <0|2> to change the velocity behaviour\n"..
"- 0: Velocity follow mouse (default),\n"..
"- 2: Velocity locked to player's first look direction with released mouse\n"..
"Use /camera look <nil|here|x,y,z>\n"..
"- nil: remove looking target,\n"..
"- here: set looking target to player position,\n"..
"- x,y,z: Coords to look at\n"..
"Use /camera speed <speed>\n"..
"- 10 is default speed,\n"..
"- > 10 decrease speed factor,\n"..
"- < 10 increase speed factor"
return true, str
else -- else, begin recording else -- else, begin recording
player_look_dir = player:get_look_dir()
local object = minetest.add_entity(player:getpos(), "camera:camera") local object = minetest.add_entity(player:getpos(), "camera:camera")
object:get_luaentity():init(player, rec_mode) object:get_luaentity():init(player, get_player_params(name).mode)
object:setyaw(player:get_look_horizontal()) object:setyaw(player:get_look_horizontal())
player:set_attach(object, "", {x=0,y=10,z=0}, {x=0,y=0,z=0}) player:set_attach(object, "", {x=0,y=10,z=0}, {x=0,y=0,z=0})
return true, "Recording started" return true, "Recording started"