-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.lua
158 lines (141 loc) · 4.92 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
-- player_recorder/init.lua
local recording = false
local recorded_positions = {}
local tick_count = 0
-- Function to start recording
local function start_recording(player)
recording = true
recorded_positions = {}
tick_count = 0
minetest.chat_send_player(player:get_player_name(), "Recording started.")
end
-- Function to stop recording
local function stop_recording(player)
recording = false
minetest.chat_send_player(player:get_player_name(), "Recording stopped.")
end
-- Function to save recorded positions
local function save_recording(player)
local name = player:get_player_name()
local file = io.open(minetest.get_worldpath() .. "/recording_" .. name .. ".txt", "w")
for _, record in ipairs(recorded_positions) do
file:write(minetest.pos_to_string(record.pos) .. " " .. record.yaw .. " " .. record.tick .. "\n")
end
file:close()
minetest.chat_send_player(name, "Recording saved.")
end
-- Register chat commands
minetest.register_chatcommand("start_rec", {
description = "Start recording player movements",
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
start_recording(player)
end
end
})
minetest.register_chatcommand("stop_rec", {
description = "Stop recording player movements",
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
stop_recording(player)
end
end
})
minetest.register_chatcommand("save_recording", {
description = "Save recorded movements",
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
save_recording(player)
end
end
})
-- Globalstep function to record player position and yaw with tick count
minetest.register_globalstep(function(dtime)
if recording then
tick_count = tick_count + 1
for _, player in ipairs(minetest.get_connected_players()) do
table.insert(recorded_positions, {
pos = player:get_pos(),
yaw = player:get_look_horizontal(),
tick = tick_count
})
end
end
end)
-- Function to interpolate between two values
local function lerp(a, b, t)
return a + (b - a) * t
end
-- Function to interpolate between two positions and yaws
local function interpolate_state(state1, state2, t)
return {
pos = {
x = lerp(state1.pos.x, state2.pos.x, t),
y = lerp(state1.pos.y, state2.pos.y, t),
z = lerp(state1.pos.z, state2.pos.z, t)
},
yaw = lerp(state1.yaw, state2.yaw, t)
}
end
-- Function to move a mob along the recorded path with interpolation
local function move_mob_along_path(mob, path)
local step = 1
local current_tick = 0
minetest.register_globalstep(function(dtime)
current_tick = current_tick + 1
if step < #path then
local t = (current_tick - path[step].tick) / (path[step + 1].tick - path[step].tick)
-- Interpolate between the current and next state
local interpolated_state = interpolate_state(path[step], path[step + 1], t)
-- Set the mob's position and yaw
mob:set_pos(interpolated_state.pos)
mob:set_yaw(interpolated_state.yaw)
-- Move to the next step if the tick count has passed
if current_tick >= path[step + 1].tick then
step = step + 1
end
end
end)
end
-- Define a custom mob entity
minetest.register_entity("mocapformt:notplayer", {
initial_properties = {
physical = true,
collide_with_objects = true,
collisionbox = {-0.35, -0.5, -0.35, 0.35, 1, 0.35},
visual = "mesh",
mesh = "character.b3d",
textures = {"character.png"},
},
on_activate = function(self, staticdata, dtime_s)
-- Load the path from the recorded positions
move_mob_along_path(self.object, recorded_positions)
end,
})
minetest.register_chatcommand("playback", {
description = "Playback the recorded path with a custom mob",
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
local pos = player:get_pos()
pos.y = pos.y + 1 -- Spawn mob slightly above the player
local mob = minetest.add_entity(pos, "mocapformt:notplayer")
move_mob_along_path(mob, recorded_positions)
end
end
})
minetest.register_chatcommand("show_rec", {
description = "Playback the recorded path with a custom mob",
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
local pos = player:get_pos()
pos.y = pos.y + 1 -- Spawn mob slightly above the player
local mob = minetest.add_entity(pos, "mocapformt:notplayer")
move_mob_along_path(mob, recorded_positions)
end
end
})