2 -- lib_mount by Blert2112 (edited by TenPlus1)
4 local enable_crash
= false
5 local crash_threshold
= 6.5 -- ignored if enable_crash=false
7 ------------------------------------------------------------------------------
13 local node_ok
= function(pos
, fallback
)
15 fallback
= fallback
or mobs
.fallback_node
17 local node
= minetest
.get_node_or_nil(pos
)
19 if node
and minetest
.registered_nodes
[node
.name
] then
23 return {name
= fallback
}
27 local function node_is(pos
)
29 local node
= node_ok(pos
)
31 if node
.name
== "air" then
35 if minetest
.get_item_group(node
.name
, "lava") ~= 0 then
39 if minetest
.get_item_group(node
.name
, "liquid") ~= 0 then
43 if minetest
.registered_nodes
[node
.name
].walkable
== true then
51 local function get_sign(i
)
58 return i
/ math
.abs(i
)
63 local function get_velocity(v
, yaw
, y
)
65 local x
= -math
.sin(yaw
) * v
66 local z
= math
.cos(yaw
) * v
68 return {x
= x
, y
= y
, z
= z
}
72 local function get_v(v
)
73 return math
.sqrt(v
.x
* v
.x
+ v
.z
* v
.z
)
77 local function force_detach(player
)
79 local attached_to
= player
:get_attach()
81 if not attached_to
then
85 local entity
= attached_to
:get_luaentity()
88 and entity
.driver
== player
then
94 mcl_player
.player_attached
[player
:get_player_name()] = false
95 player
:set_eye_offset({x
= 0, y
= 0, z
= 0}, {x
= 0, y
= 0, z
= 0})
96 mcl_player
.player_set_animation(player
, "stand" , 30)
97 player
:set_properties({visual_size
= {x
= 1, y
= 1} })
101 -------------------------------------------------------------------------------
104 minetest
.register_on_leaveplayer(function(player
)
108 minetest
.register_on_shutdown(function()
109 local players
= minetest
.get_connected_players()
110 for i
= 1, #players
do
111 force_detach(players
[i
])
115 minetest
.register_on_dieplayer(function(player
)
120 -------------------------------------------------------------------------------
122 function mobs
.attach(entity
, player
)
124 local attach_at
, eye_offset
= {}, {}
126 entity
.player_rotation
= entity
.player_rotation
or {x
= 0, y
= 0, z
= 0}
127 entity
.driver_attach_at
= entity
.driver_attach_at
or {x
= 0, y
= 0, z
= 0}
128 entity
.driver_eye_offset
= entity
.driver_eye_offset
or {x
= 0, y
= 0, z
= 0}
129 entity
.driver_scale
= entity
.driver_scale
or {x
= 1, y
= 1}
133 if entity
.player_rotation
.y
== 90 then
137 attach_at
= entity
.driver_attach_at
138 eye_offset
= entity
.driver_eye_offset
139 entity
.driver
= player
143 player
:set_attach(entity
.object
, "", attach_at
, entity
.player_rotation
)
144 mcl_player
.player_attached
[player
:get_player_name()] = true
145 player
:set_eye_offset(eye_offset
, {x
= 0, y
= 0, z
= 0})
147 player
:set_properties({
149 x
= entity
.driver_scale
.x
,
150 y
= entity
.driver_scale
.y
154 minetest
.after(0.2, function()
155 mcl_player
.player_set_animation(player
, "sit" , 30)
158 --player:set_look_yaw(entity.object:get_yaw() - rot_view)
159 player
:set_look_horizontal(entity
.object
:get_yaw() - rot_view
)
163 function mobs
.detach(player
, offset
)
167 mcl_player
.player_set_animation(player
, "stand" , 30)
169 local pos
= player
:get_pos()
171 pos
= {x
= pos
.x
+ offset
.x
, y
= pos
.y
+ 0.2 + offset
.y
, z
= pos
.z
+ offset
.z
}
173 minetest
.after(0.1, function()
179 function mobs
.drive(entity
, moving_anim
, stand_anim
, can_fly
, dtime
)
181 local rot_steer
, rot_view
= math
.pi
/2, 0
183 if entity
.player_rotation
.y
== 90 then
184 rot_steer
, rot_view
= 0, math
.pi
/2
188 local velo
= entity
.object
:getvelocity()
190 entity
.v
= get_v(velo
) * get_sign(entity
.v
)
193 if entity
.driver
then
195 --print ("---velo", get_v(velo))
197 local ctrl
= entity
.driver
:get_player_control()
202 entity
.v
= entity
.v
+ entity
.accel
/ 10
205 elseif ctrl
.down
then
207 if entity
.max_speed_reverse
== 0 and entity
.v
== 0 then
211 entity
.v
= entity
.v
- entity
.accel
/ 10
215 entity
.object
:setyaw(entity
.driver
:get_look_horizontal() - entity
.rotate
)
222 if velo
.y
> entity
.accel
then velo
.y
= entity
.accel
end
224 elseif velo
.y
> 0 then
225 velo
.y
= velo
.y
- 0.1
226 if velo
.y
< 0 then velo
.y
= 0 end
232 if velo
.y
< -entity
.accel
then velo
.y
= -entity
.accel
end
234 elseif velo
.y
< 0 then
235 velo
.y
= velo
.y
+ 0.1
236 if velo
.y
> 0 then velo
.y
= 0 end
245 velo
.y
= velo
.y
+ entity
.jump_height
246 acce_y
= acce_y
+ (acce_y
* 3) + 1
253 -- if not moving then set animation and return
254 if entity
.v
== 0 and velo
.x
== 0 and velo
.y
== 0 and velo
.z
== 0 then
257 mobs
:set_animation(entity
, stand_anim
)
263 -- set moving animation
265 mobs
:set_animation(entity
, moving_anim
)
269 local s
= get_sign(entity
.v
)
271 entity
.v
= entity
.v
- 0.02 * s
273 if s
~= get_sign(entity
.v
) then
275 entity
.object
:setvelocity({x
= 0, y
= 0, z
= 0})
280 -- enforce speed limit forward and reverse
281 local max_spd
= entity
.max_speed_reverse
283 if get_sign(entity
.v
) >= 0 then
284 max_spd
= entity
.max_speed_forward
287 if math
.abs(entity
.v
) > max_spd
then
288 entity
.v
= entity
.v
- get_sign(entity
.v
)
291 -- Set position, velocity and acceleration
292 local p
= entity
.object
:get_pos()
293 local new_velo
= {x
= 0, y
= 0, z
= 0}
294 local new_acce
= {x
= 0, y
= -9.8, z
= 0}
298 local ni
= node_is(p
)
303 if can_fly
== true then
307 elseif ni
== "liquid" or ni
== "lava" then
309 if ni
== "lava" and entity
.lava_damage
~= 0 then
311 entity
.lava_counter
= (entity
.lava_counter
or 0) + dtime
313 if entity
.lava_counter
> 1 then
315 minetest
.sound_play("default_punch", {
316 object
= entity
.object
,
317 max_hear_distance
= 5
320 entity
.object
:punch(entity
.object
, 1.0, {
321 full_punch_interval
= 1.0,
322 damage_groups
= {fleshy
= entity
.lava_damage
}
325 entity
.lava_counter
= 0
329 if entity
.terrain_type
== 2
330 or entity
.terrain_type
== 3 then
335 if node_is(p
) == "liquid" then
339 elseif velo
.y
< 0 then
345 if math
.abs(velo
.y
) < 1 then
346 local pos
= entity
.object
:get_pos()
347 pos
.y
= math
.floor(pos
.y
) + 0.5
348 entity
.object
:setpos(pos
)
357 new_velo
= get_velocity(v
, entity
.object
:get_yaw() - rot_view
, velo
.y
)
358 new_acce
.y
= new_acce
.y
+ acce_y
360 entity
.object
:setvelocity(new_velo
)
361 entity
.object
:setacceleration(new_acce
)
366 local intensity
= entity
.v2
- v
368 if intensity
>= crash_threshold
then
370 --print("----------- crash", intensity)
372 entity
.object
:punch(entity
.object
, 1.0, {
373 full_punch_interval
= 1.0,
374 damage_groups
= {fleshy
= intensity
}
384 -- directional flying routine by D00Med (edited by TenPlus1)
386 function mobs
.fly(entity
, dtime
, speed
, shoots
, arrow
, moving_anim
, stand_anim
)
388 local ctrl
= entity
.driver
:get_player_control()
389 local velo
= entity
.object
:getvelocity()
390 local dir
= entity
.driver
:get_look_dir()
391 local yaw
= entity
.driver
:get_look_horizontal() + 1.57 -- offset fix between old and new commands
392 local rot_steer
, rot_view
= math
.pi
/ 2, 0
394 if entity
.player_rotation
.y
== 90 then
395 rot_steer
, rot_view
= 0, math
.pi
/ 2
399 entity
.object
:setvelocity({
401 y
= dir
.y
* speed
+ 2,
405 elseif ctrl
.down
then
406 entity
.object
:setvelocity({
408 y
= dir
.y
* speed
+ 2,
412 elseif not ctrl
.down
or ctrl
.up
or ctrl
.jump
then
413 entity
.object
:setvelocity({x
= 0, y
= -2, z
= 0})
416 entity
.object
:setyaw(yaw
+ math
.pi
+ math
.pi
/ 2 - entity
.rotate
)
419 if ctrl
.LMB
and ctrl
.sneak
and shoots
then
421 local pos
= entity
.object
:get_pos()
422 local obj
= minetest
.add_entity({
423 x
= pos
.x
+ 0 + dir
.x
* 2.5,
424 y
= pos
.y
+ 1.5 + dir
.y
,
425 z
= pos
.z
+ 0 + dir
.z
* 2.5}, arrow
)
427 local ent
= obj
:get_luaentity()
429 ent
.switch
= 1 -- for mob specific arrows
430 ent
.owner_id
= tostring(entity
.object
) -- so arrows dont hurt entity you are riding
431 local vec
= {x
= dir
.x
* 6, y
= dir
.y
* 6, z
= dir
.z
* 6}
432 local yaw
= entity
.driver
:get_look_horizontal()
433 obj
:setyaw(yaw
+ math
.pi
/ 2)
440 -- change animation if stopped
441 if velo
.x
== 0 and velo
.y
== 0 and velo
.z
== 0 then
443 mobs
:set_animation(entity
, stand_anim
)
446 mobs
:set_animation(entity
, moving_anim
)