@@ -27,6 +27,10 @@ function cart_entity:on_rightclick(clicker)
27
27
elseif not self .driver then
28
28
self .driver = player_name
29
29
carts :manage_attachment (clicker , self .object )
30
+
31
+ -- player_api does not update the animation
32
+ -- when the player is attached, reset to default animation
33
+ player_api .set_animation (clicker , " stand" )
30
34
end
31
35
end
32
36
@@ -36,7 +40,7 @@ function cart_entity:on_activate(staticdata, dtime_s)
36
40
return
37
41
end
38
42
local data = minetest .deserialize (staticdata )
39
- if not data or type (data ) ~= " table" then
43
+ if type (data ) ~= " table" then
40
44
return
41
45
end
42
46
self .railtype = data .railtype
@@ -52,6 +56,13 @@ function cart_entity:get_staticdata()
52
56
})
53
57
end
54
58
59
+ -- 0.5.x and later: When the driver leaves
60
+ function cart_entity :on_detach_child (child )
61
+ if child and child :get_player_name () == self .driver then
62
+ self .driver = nil
63
+ end
64
+ end
65
+
55
66
function cart_entity :on_punch (puncher , time_from_last_punch , tool_capabilities , direction )
56
67
local pos = self .object :get_pos ()
57
68
local vel = self .object :get_velocity ()
@@ -82,7 +93,7 @@ function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities,
82
93
local player = minetest .get_player_by_name (self .driver )
83
94
carts :manage_attachment (player , nil )
84
95
end
85
- for _ ,obj_ in ipairs (self .attached_items ) do
96
+ for _ , obj_ in ipairs (self .attached_items ) do
86
97
if obj_ then
87
98
obj_ :set_detach ()
88
99
end
@@ -165,6 +176,7 @@ local function get_railparams(pos)
165
176
return carts .railparams [node .name ] or {}
166
177
end
167
178
179
+ local v3_len = vector .length
168
180
local function rail_on_step (self , dtime )
169
181
local vel = self .object :get_velocity ()
170
182
if self .punched then
@@ -201,17 +213,23 @@ local function rail_on_step(self, dtime)
201
213
202
214
local stop_wiggle = false
203
215
if self .old_pos and same_dir then
204
- -- Detection for "skipping" nodes
205
- local found_path = carts :pathfinder (
206
- pos , self .old_pos , self .old_dir , ctrl , self .old_switch , self .railtype
216
+ -- Detection for "skipping" nodes (perhaps use average dtime?)
217
+ -- It's sophisticated enough to take the acceleration in account
218
+ local acc = self .object :get_acceleration ()
219
+ local distance = dtime * (v3_len (vel ) + 0.5 * dtime * v3_len (acc ))
220
+
221
+ local new_pos , new_dir = carts :pathfinder (
222
+ pos , self .old_pos , self .old_dir , distance , ctrl ,
223
+ self .old_switch , self .railtype
207
224
)
208
225
209
- if not found_path then
210
- -- No rail found: reset back to the expected position
211
- pos = vector . new ( self . old_pos )
226
+ if new_pos then
227
+ -- No rail found: set to the expected position
228
+ pos = new_pos
212
229
update .pos = true
230
+ cart_dir = new_dir
213
231
end
214
- elseif self .old_pos and cart_dir . y ~= - 1 and not self .punched then
232
+ elseif self .old_pos and self . old_dir . y ~= 1 and not self .punched then
215
233
-- Stop wiggle
216
234
stop_wiggle = true
217
235
end
@@ -223,12 +241,14 @@ local function rail_on_step(self, dtime)
223
241
local dir , switch_keys = carts :get_rail_direction (
224
242
pos , cart_dir , ctrl , self .old_switch , self .railtype
225
243
)
244
+ local dir_changed = not vector .equals (dir , self .old_dir )
226
245
227
246
local new_acc = {x = 0 , y = 0 , z = 0 }
228
247
if stop_wiggle or vector .equals (dir , {x = 0 , y = 0 , z = 0 }) then
229
248
vel = {x = 0 , y = 0 , z = 0 }
230
249
local pos_r = vector .round (pos )
231
- if not carts :is_rail (pos_r , self .railtype ) then
250
+ if not carts :is_rail (pos_r , self .railtype )
251
+ and self .old_pos then
232
252
pos = self .old_pos
233
253
elseif not stop_wiggle then
234
254
pos = pos_r
@@ -239,7 +259,7 @@ local function rail_on_step(self, dtime)
239
259
update .vel = true
240
260
else
241
261
-- Direction change detected
242
- if not vector . equals ( dir , self . old_dir ) then
262
+ if dir_changed then
243
263
vel = vector .multiply (dir , math.abs (vel .x + vel .z ))
244
264
update .vel = true
245
265
if dir .y ~= self .old_dir .y then
@@ -291,7 +311,7 @@ local function rail_on_step(self, dtime)
291
311
end
292
312
293
313
self .object :set_acceleration (new_acc )
294
- self .old_pos = vector .new (pos )
314
+ self .old_pos = vector .round (pos )
295
315
if not vector .equals (dir , {x = 0 , y = 0 , z = 0 }) and not stop_wiggle then
296
316
self .old_dir = vector .new (dir )
297
317
end
@@ -338,9 +358,15 @@ local function rail_on_step(self, dtime)
338
358
end
339
359
self .object :set_animation (anim , 1 , 0 )
340
360
341
- self .object :set_velocity (vel )
361
+ if update .vel then
362
+ self .object :set_velocity (vel )
363
+ end
342
364
if update .pos then
343
- self .object :set_pos (pos )
365
+ if dir_changed then
366
+ self .object :set_pos (pos )
367
+ else
368
+ self .object :move_to (pos )
369
+ end
344
370
end
345
371
346
372
-- call event handler
0 commit comments