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(player
)
155 if player
:is_player() then
156 mcl_player
.player_set_animation(player
, "sit" , 30)
160 player
:set_look_horizontal(entity
.object
:get_yaw() - rot_view
)
164 function mobs
.detach(player
, offset
)
168 mcl_player
.player_set_animation(player
, "stand" , 30)
170 local pos
= player
:get_pos()
172 pos
= {x
= pos
.x
+ offset
.x
, y
= pos
.y
+ 0.2 + offset
.y
, z
= pos
.z
+ offset
.z
}
174 minetest
.after(0.1, function(player
, pos
)
175 if player
:is_player() then
182 function mobs
.drive(entity
, moving_anim
, stand_anim
, can_fly
, dtime
)
184 local rot_steer
, rot_view
= math
.pi
/2, 0
186 if entity
.player_rotation
.y
== 90 then
187 rot_steer
, rot_view
= 0, math
.pi
/2
191 local velo
= entity
.object
:getvelocity()
193 entity
.v
= get_v(velo
) * get_sign(entity
.v
)
196 if entity
.driver
then
198 local ctrl
= entity
.driver
:get_player_control()
203 entity
.v
= entity
.v
+ entity
.accel
/ 10
206 elseif ctrl
.down
then
208 if entity
.max_speed_reverse
== 0 and entity
.v
== 0 then
212 entity
.v
= entity
.v
- entity
.accel
/ 10
216 entity
.object
:setyaw(entity
.driver
:get_look_horizontal() - entity
.rotate
)
223 if velo
.y
> entity
.accel
then velo
.y
= entity
.accel
end
225 elseif velo
.y
> 0 then
226 velo
.y
= velo
.y
- 0.1
227 if velo
.y
< 0 then velo
.y
= 0 end
233 if velo
.y
< -entity
.accel
then velo
.y
= -entity
.accel
end
235 elseif velo
.y
< 0 then
236 velo
.y
= velo
.y
+ 0.1
237 if velo
.y
> 0 then velo
.y
= 0 end
246 velo
.y
= velo
.y
+ entity
.jump_height
247 acce_y
= acce_y
+ (acce_y
* 3) + 1
254 -- if not moving then set animation and return
255 if entity
.v
== 0 and velo
.x
== 0 and velo
.y
== 0 and velo
.z
== 0 then
258 mobs
:set_animation(entity
, stand_anim
)
264 -- set moving animation
266 mobs
:set_animation(entity
, moving_anim
)
270 local s
= get_sign(entity
.v
)
272 entity
.v
= entity
.v
- 0.02 * s
274 if s
~= get_sign(entity
.v
) then
276 entity
.object
:setvelocity({x
= 0, y
= 0, z
= 0})
281 -- enforce speed limit forward and reverse
282 local max_spd
= entity
.max_speed_reverse
284 if get_sign(entity
.v
) >= 0 then
285 max_spd
= entity
.max_speed_forward
288 if math
.abs(entity
.v
) > max_spd
then
289 entity
.v
= entity
.v
- get_sign(entity
.v
)
292 -- Set position, velocity and acceleration
293 local p
= entity
.object
:get_pos()
294 local new_velo
= {x
= 0, y
= 0, z
= 0}
295 local new_acce
= {x
= 0, y
= -9.8, z
= 0}
299 local ni
= node_is(p
)
304 if can_fly
== true then
308 elseif ni
== "liquid" or ni
== "lava" then
310 if ni
== "lava" and entity
.lava_damage
~= 0 then
312 entity
.lava_counter
= (entity
.lava_counter
or 0) + dtime
314 if entity
.lava_counter
> 1 then
316 minetest
.sound_play("default_punch", {
317 object
= entity
.object
,
318 max_hear_distance
= 5
321 entity
.object
:punch(entity
.object
, 1.0, {
322 full_punch_interval
= 1.0,
323 damage_groups
= {fleshy
= entity
.lava_damage
}
326 entity
.lava_counter
= 0
330 if entity
.terrain_type
== 2
331 or entity
.terrain_type
== 3 then
336 if node_is(p
) == "liquid" then
340 elseif velo
.y
< 0 then
346 if math
.abs(velo
.y
) < 1 then
347 local pos
= entity
.object
:get_pos()
348 pos
.y
= math
.floor(pos
.y
) + 0.5
349 entity
.object
:setpos(pos
)
358 new_velo
= get_velocity(v
, entity
.object
:get_yaw() - rot_view
, velo
.y
)
359 new_acce
.y
= new_acce
.y
+ acce_y
361 entity
.object
:setvelocity(new_velo
)
362 entity
.object
:setacceleration(new_acce
)
367 local intensity
= entity
.v2
- v
369 if intensity
>= crash_threshold
then
371 entity
.object
:punch(entity
.object
, 1.0, {
372 full_punch_interval
= 1.0,
373 damage_groups
= {fleshy
= intensity
}
383 -- directional flying routine by D00Med (edited by TenPlus1)
385 function mobs
.fly(entity
, dtime
, speed
, shoots
, arrow
, moving_anim
, stand_anim
)
387 local ctrl
= entity
.driver
:get_player_control()
388 local velo
= entity
.object
:getvelocity()
389 local dir
= entity
.driver
:get_look_dir()
390 local yaw
= entity
.driver
:get_look_horizontal() + 1.57 -- offset fix between old and new commands
391 local rot_steer
, rot_view
= math
.pi
/ 2, 0
393 if entity
.player_rotation
.y
== 90 then
394 rot_steer
, rot_view
= 0, math
.pi
/ 2
398 entity
.object
:setvelocity({
400 y
= dir
.y
* speed
+ 2,
404 elseif ctrl
.down
then
405 entity
.object
:setvelocity({
407 y
= dir
.y
* speed
+ 2,
411 elseif not ctrl
.down
or ctrl
.up
or ctrl
.jump
then
412 entity
.object
:setvelocity({x
= 0, y
= -2, z
= 0})
415 entity
.object
:setyaw(yaw
+ math
.pi
+ math
.pi
/ 2 - entity
.rotate
)
418 if ctrl
.LMB
and ctrl
.sneak
and shoots
then
420 local pos
= entity
.object
:get_pos()
421 local obj
= minetest
.add_entity({
422 x
= pos
.x
+ 0 + dir
.x
* 2.5,
423 y
= pos
.y
+ 1.5 + dir
.y
,
424 z
= pos
.z
+ 0 + dir
.z
* 2.5}, arrow
)
426 local ent
= obj
:get_luaentity()
428 ent
.switch
= 1 -- for mob specific arrows
429 ent
.owner_id
= tostring(entity
.object
) -- so arrows dont hurt entity you are riding
430 local vec
= {x
= dir
.x
* 6, y
= dir
.y
* 6, z
= dir
.z
* 6}
431 local yaw
= entity
.driver
:get_look_horizontal()
432 obj
:setyaw(yaw
+ math
.pi
/ 2)
439 -- change animation if stopped
440 if velo
.x
== 0 and velo
.y
== 0 and velo
.z
== 0 then
442 mobs
:set_animation(entity
, stand_anim
)
445 mobs
:set_animation(entity
, moving_anim
)