incrementaltp: respect physics overrides
[waspsaliva.git] / clientmods / incrementaltp / init.lua
blob9ae6cc7da9bbf8c5e0537dfc0e15cab02c429b08
1 -- CC0/Unlicense Emilia 2021
3 incremental_tp = {}
5 incremental_tp.fudge = 0.8 -- cause the tp time isn't synced with the server
6 incremental_tp.tpactive=false
8 -- for Clamity
9 incremental_tp.max_instantaneous_tp = {
10 x = 5,
11 y = 45,
12 z = 5
15 function incremental_tp.get_actual_speed()
16 local po=minetest.localplayer:get_physics_override()
17 local rt=vector.new()
18 rt.x=incremental_tp.max_instantaneous_tp.x * po.speed
19 rt.y=incremental_tp.max_instantaneous_tp.y * po.speed
20 rt.z=incremental_tp.max_instantaneous_tp.z * po.speed
21 return rt
22 end
23 local wason=false
24 local function sign(n)
25 if n == 0 then
26 return 0
27 end
29 return n / math.abs(n)
30 end
32 local function max_dist_per(vec, time)
33 local mitp = vector.multiply(incremental_tp.get_actual_speed(),
34 incremental_tp.fudge)
35 local nvec = {x = 0, y = 0, z = 0}
36 nvec.x = sign(vec.x) * math.min(math.abs(vec.x), mitp.x * time)
37 nvec.z = sign(vec.z) * math.min(math.abs(vec.z), mitp.z * time)
38 -- negative y speed cap is infinity, so if y < 0 it is always allowed
39 nvec.y = math.min(vec.y, mitp.y * time)
40 return nvec
41 end
43 local function tpstep(target, time, second, variance,sfunc)
44 local pos = minetest.localplayer:get_pos()
45 local vec = vector.subtract(target, pos)
46 minetest.settings:set_bool("free_move",true)
47 if not incremental_tp.tpactive and wason then
48 wason=false
49 return
50 end
51 wason=true
52 incremental_tp.tpactive=true
53 if vector.distance(pos,target) < 3 then
54 minetest.localplayer:set_pos(target)
55 incremental_tp.tpactive=false
56 --minetest.display_chat_message("Arrived at " .. minetest.pos_to_string(target))
57 if sfunc then
58 minetest.after(time, function()
59 sfunc(target)
60 end)
61 end
62 return
63 end
65 if second < 0.001 then
66 second = 1
67 end
69 local intime = math.min(time, second)
70 if variance then
71 -- you can't move faster than 1 second of distance instantaneously
72 intime = math.min(1, math.random() * variance - variance / 2 + intime)
73 end
75 local nvec = max_dist_per(vec, intime)
76 local trg=vector.add(pos, nvec)
77 --local safe=ws.find_closest_reachable_airpocket(trg)
78 minetest.localplayer:set_pos(trg)
79 minetest.after(intime, function()
80 tpstep(target, time, second - intime, variance,sfunc)
81 end)
82 end
84 function incremental_tp.tpstep(target, time, variance,sfunc)
85 if incremental_tp.tpactive then return end
86 tpstep(target, time, 1, variance,sfunc)
87 end
89 function incremental_tp.tp(target, time, variance)
90 incremental_tp.tpactive=false
91 minetest.after(time,function()
92 tpstep(target,time,1,variance)
93 end)
94 end
96 function incremental_tp.tpafter(target,time,variance,sfunc)
97 incremental_tp.tpactive=false
98 minetest.after(time,function()
99 tpstep(target,time,1,variance,sfunc)
100 end)
103 if autofly then autofly.register_transport('itp',function(pos,name) incremental_tp.tp(pos,1) end) end
105 if autofly then autofly.register_transport('jitp',function(pos,name) incremental_tp.tp(pos,0.5,0.4) end) end
107 minetest.register_chatcommand("itp", {
108 description = "Teleport to destination with fixed increments.",
109 params = "<destination>",
110 func = function(params)
111 local pos = minetest.string_to_pos(params)
113 incremental_tp.tp(pos, 1)
117 minetest.register_chatcommand("jittertp", {
118 description = "Teleport to destination with jittery increments.",
119 params = "<destination>",
120 func = function(params)
121 local pos = minetest.string_to_pos(params)
123 incremental_tp.tp(pos, 0.5, 0.4)
127 -- chunk_rand