also cleanup mount.lua
This commit is contained in:
parent
ddd180f5be
commit
46f7c29451
|
@ -1,110 +1,41 @@
|
|||
local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs
|
||||
local mob_class = mcl_mobs.mob_class
|
||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
||||
-- based on lib_mount by Blert2112 (edited by TenPlus1)
|
||||
|
||||
local enable_crash = false
|
||||
local crash_threshold = 6.5 -- ignored if enable_crash=false
|
||||
local GRAVITY = -9.8
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Helper functions
|
||||
--
|
||||
|
||||
local node_ok = function(pos, fallback)
|
||||
|
||||
fallback = fallback or mcl_mobs.fallback_node
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
|
||||
if node and minetest.registered_nodes[node.name] then
|
||||
return node
|
||||
end
|
||||
|
||||
return {name = fallback}
|
||||
end
|
||||
|
||||
local node_ok = mcl_mobs.node_ok
|
||||
local sign = math.sign -- minetest extension
|
||||
|
||||
local function node_is(pos)
|
||||
|
||||
local node = node_ok(pos)
|
||||
|
||||
if node.name == "air" then
|
||||
return "air"
|
||||
end
|
||||
|
||||
if minetest.get_item_group(node.name, "lava") ~= 0 then
|
||||
return "lava"
|
||||
end
|
||||
|
||||
if minetest.get_item_group(node.name, "liquid") ~= 0 then
|
||||
return "liquid"
|
||||
end
|
||||
|
||||
if minetest.registered_nodes[node.name].walkable == true then
|
||||
return "walkable"
|
||||
end
|
||||
|
||||
if node.name == "air" then return "air" end
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
if not ndef then return "other" end -- unknown/ignore
|
||||
if ndef.groups.lava then return "lava" end
|
||||
if ndef.groups.liquid then return "liquid" end
|
||||
if ndef.walkable then return "walkable" end
|
||||
return "other"
|
||||
end
|
||||
|
||||
|
||||
local function get_sign(i)
|
||||
|
||||
i = i or 0
|
||||
|
||||
if i == 0 then
|
||||
return 0
|
||||
else
|
||||
return i / math.abs(i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function get_velocity(v, yaw, y)
|
||||
|
||||
local x = -math.sin(yaw) * v
|
||||
local z = math.cos(yaw) * v
|
||||
|
||||
return {x = x, y = y, z = z}
|
||||
end
|
||||
|
||||
|
||||
local function get_v(v)
|
||||
return math.sqrt(v.x * v.x + v.z * v.z)
|
||||
end
|
||||
|
||||
|
||||
local function force_detach(player)
|
||||
|
||||
local attached_to = player:get_attach()
|
||||
|
||||
if not attached_to then
|
||||
return
|
||||
end
|
||||
if not attached_to then return end
|
||||
|
||||
local entity = attached_to:get_luaentity()
|
||||
|
||||
if entity.driver
|
||||
and entity.driver == player then
|
||||
|
||||
entity.driver = nil
|
||||
end
|
||||
if entity.driver and entity.driver == player then entity.driver = nil end
|
||||
|
||||
player:set_detach()
|
||||
mcl_player.player_attached[player:get_player_name()] = false
|
||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
player:set_eye_offset(vector.zero(), vector.zero())
|
||||
mcl_player.player_set_animation(player, "stand" , 30)
|
||||
player:set_properties({visual_size = {x = 1, y = 1} })
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
force_detach(player)
|
||||
end)
|
||||
minetest.register_on_leaveplayer(force_detach)
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
local players = minetest.get_connected_players()
|
||||
|
@ -118,39 +49,24 @@ minetest.register_on_dieplayer(function(player)
|
|||
return true
|
||||
end)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function mcl_mobs.attach(entity, player)
|
||||
|
||||
local attach_at, eye_offset
|
||||
|
||||
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
|
||||
entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0}
|
||||
entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0}
|
||||
entity.player_rotation = entity.player_rotation or vector.zero()
|
||||
entity.driver_attach_at = entity.driver_attach_at or vector.zero()
|
||||
entity.driver_eye_offset = entity.driver_eye_offset or vector.zero()
|
||||
entity.driver_scale = entity.driver_scale or {x = 1, y = 1}
|
||||
|
||||
local rot_view = 0
|
||||
|
||||
if entity.player_rotation.y == 90 then
|
||||
rot_view = math.pi/2
|
||||
end
|
||||
|
||||
attach_at = entity.driver_attach_at
|
||||
eye_offset = entity.driver_eye_offset
|
||||
local rot_view = entity.player_rotation.y == 90 and math.pi/2 or 0
|
||||
local attach_at = entity.driver_attach_at
|
||||
local eye_offset = entity.driver_eye_offset
|
||||
entity.driver = player
|
||||
|
||||
force_detach(player)
|
||||
|
||||
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
|
||||
mcl_player.player_attached[player:get_player_name()] = true
|
||||
player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
|
||||
player:set_eye_offset(eye_offset, vector.zero())
|
||||
|
||||
player:set_properties({
|
||||
visual_size = {
|
||||
x = entity.driver_scale.x,
|
||||
y = entity.driver_scale.y
|
||||
}
|
||||
})
|
||||
player:set_properties({ visual_size = entity.driver_scale })
|
||||
|
||||
minetest.after(0.2, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
|
@ -164,162 +80,88 @@ end
|
|||
|
||||
|
||||
function mcl_mobs.detach(player, offset)
|
||||
|
||||
force_detach(player)
|
||||
|
||||
mcl_player.player_set_animation(player, "stand" , 30)
|
||||
|
||||
--local pos = player:get_pos()
|
||||
|
||||
--pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
|
||||
|
||||
player:add_velocity(vector.new(math.random(-6,6),math.random(5,8),math.random(-6,6))) --throw the rider off
|
||||
|
||||
--[[
|
||||
minetest.after(0.1, function(name, pos)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
player:set_pos(pos)
|
||||
end
|
||||
end, player:get_player_name(), pos)
|
||||
]]--
|
||||
player:add_velocity(vector.new(math.random()*12-6,math.random()*3+5,math.random()*12-6)) --throw the rider off
|
||||
end
|
||||
|
||||
|
||||
function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
local rot_view = 0
|
||||
|
||||
if entity.player_rotation.y == 90 then
|
||||
rot_view = math.pi/2
|
||||
end
|
||||
|
||||
local acce_y = 0
|
||||
local velo = entity.object:get_velocity()
|
||||
|
||||
entity.v = get_v(velo) * get_sign(entity.v)
|
||||
local v = math.sqrt(velo.x * velo.x + velo.y * velo.y)
|
||||
local acce_y = GRAVITY
|
||||
|
||||
-- process controls
|
||||
if entity.driver then
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
|
||||
-- move forwards
|
||||
if ctrl.up then
|
||||
|
||||
entity.v = entity.v + entity.accel / 10 * entity.run_velocity / 2.6
|
||||
|
||||
-- move backwards
|
||||
elseif ctrl.down then
|
||||
|
||||
if entity.max_speed_reverse == 0 and entity.v == 0 then
|
||||
return
|
||||
if ctrl.up then -- forward
|
||||
v = v + entity.accel * 0.1 * entity.run_velocity * 0.385
|
||||
elseif ctrl.down then -- backwards
|
||||
if entity.max_speed_reverse == 0 and v == 0 then return end
|
||||
v = v - entity.accel * 0.1 * entity.run_velocity * 0.385
|
||||
end
|
||||
|
||||
entity.v = entity.v - entity.accel / 10
|
||||
end
|
||||
|
||||
-- fix mob rotation
|
||||
entity.object:set_yaw(entity.driver:get_look_horizontal() - entity.rotate)
|
||||
entity:set_yaw(entity.driver:get_look_horizontal() - entity.rotate, 2)
|
||||
|
||||
if can_fly then
|
||||
|
||||
-- FIXME: use acce_y instead?
|
||||
-- fly up
|
||||
if ctrl.jump then
|
||||
velo.y = velo.y + 1
|
||||
if velo.y > entity.accel then velo.y = entity.accel end
|
||||
|
||||
elseif velo.y > 0 then
|
||||
velo.y = math.min(velo.y + 1, entity.accel)
|
||||
elseif velo.y > 0.1 then
|
||||
velo.y = velo.y - 0.1
|
||||
if velo.y < 0 then velo.y = 0 end
|
||||
elseif velo.y > 0 then
|
||||
velo.y = 0
|
||||
end
|
||||
|
||||
-- fly down
|
||||
if ctrl.sneak then
|
||||
velo.y = velo.y - 1
|
||||
if velo.y < -entity.accel then velo.y = -entity.accel end
|
||||
|
||||
elseif velo.y < 0 then
|
||||
velo.y = math.max(velo.y - 1, -entity.accel)
|
||||
elseif velo.y < -0.1 then
|
||||
velo.y = velo.y + 0.1
|
||||
if velo.y > 0 then velo.y = 0 end
|
||||
elseif velo.y < 0 then
|
||||
velo.y = 0
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- jump
|
||||
if ctrl.jump then
|
||||
|
||||
if velo.y == 0 then
|
||||
velo.y = velo.y + entity.jump_height
|
||||
acce_y = acce_y + (acce_y * 3) + 1
|
||||
acce_y = acce_y + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- Stop!
|
||||
local s = get_sign(entity.v)
|
||||
|
||||
entity.v = entity.v - 0.02 * s
|
||||
|
||||
if s ~= get_sign(entity.v) then
|
||||
|
||||
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
entity.v = 0
|
||||
return
|
||||
if math.abs(v) < 0.02 then -- stop
|
||||
entity.object:set_velocity(vector.zero())
|
||||
v = 0
|
||||
else
|
||||
v = v - 0.02 * sign(v) -- slow down
|
||||
end
|
||||
|
||||
-- if not moving then set animation and return
|
||||
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
|
||||
if stand_anim then
|
||||
mcl_mobs:set_animation(entity, stand_anim)
|
||||
end
|
||||
|
||||
if v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
if stand_anim then mcl_mobs:set_animation(entity, stand_anim) end
|
||||
return
|
||||
end
|
||||
|
||||
-- set moving animation
|
||||
if moving_anim then
|
||||
mcl_mobs:set_animation(entity, moving_anim)
|
||||
else
|
||||
if moving_anim then mcl_mobs:set_animation(entity, moving_anim) end
|
||||
end
|
||||
|
||||
-- enforce speed limit forward and reverse
|
||||
local max_spd = entity.max_speed_reverse
|
||||
|
||||
if get_sign(entity.v) >= 0 then
|
||||
max_spd = entity.max_speed_forward
|
||||
end
|
||||
|
||||
if math.abs(entity.v) > max_spd then
|
||||
entity.v = entity.v - get_sign(entity.v)
|
||||
end
|
||||
v = math.max(-entity.max_speed_reverse, math.min(v, entity.max_speed_forward))
|
||||
|
||||
-- Set position, velocity and acceleration
|
||||
local p = entity.object:get_pos()
|
||||
local new_velo
|
||||
local new_acce = {x = 0, y = -9.8, z = 0}
|
||||
|
||||
p.y = p.y - 0.5
|
||||
|
||||
local ni = node_is(p)
|
||||
local v = entity.v
|
||||
|
||||
if ni == "air" then
|
||||
|
||||
if can_fly == true then
|
||||
new_acce.y = 0
|
||||
end
|
||||
|
||||
if can_fly then acce_y = acce_y - GRAVITY end
|
||||
elseif ni == "liquid" or ni == "lava" then
|
||||
|
||||
if ni == "lava" and entity.lava_damage ~= 0 then
|
||||
|
||||
entity.lava_counter = (entity.lava_counter or 0) + dtime
|
||||
|
||||
if entity.lava_counter > 1 then
|
||||
|
||||
minetest.sound_play("default_punch", {
|
||||
object = entity.object,
|
||||
max_hear_distance = 5
|
||||
|
@ -336,18 +178,15 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
if entity.terrain_type == 2
|
||||
or entity.terrain_type == 3 then
|
||||
|
||||
new_acce.y = 0
|
||||
acce_y = 0
|
||||
p.y = p.y + 1
|
||||
|
||||
if node_is(p) == "liquid" then
|
||||
|
||||
if velo.y >= 5 then
|
||||
velo.y = 5
|
||||
elseif velo.y < 0 then
|
||||
new_acce.y = 20
|
||||
acce_y = 20
|
||||
else
|
||||
new_acce.y = 5
|
||||
acce_y = 5
|
||||
end
|
||||
else
|
||||
if math.abs(velo.y) < 1 then
|
||||
|
@ -362,75 +201,51 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
end
|
||||
|
||||
new_velo = get_velocity(v, entity.object:get_yaw() - rot_view, velo.y)
|
||||
new_acce.y = new_acce.y + acce_y
|
||||
local rot_view = entity.player_rotation.y == 90 and math.pi/2 or 0
|
||||
local new_yaw = entity.object:get_yaw() - rot_view
|
||||
local new_velo = vector.new(-math.sin(new_yaw) * v, velo.y, math.cos(new_yaw) * v)
|
||||
|
||||
entity.object:set_velocity(new_velo)
|
||||
entity.object:set_acceleration(new_acce)
|
||||
entity.object:set_acceleration(vector.new(0, acce_y, 0))
|
||||
|
||||
-- CRASH!
|
||||
if enable_crash then
|
||||
|
||||
local intensity = entity.v2 - v
|
||||
|
||||
if intensity >= crash_threshold then
|
||||
|
||||
if v >= crash_threshold then
|
||||
entity.object:punch(entity.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = intensity}
|
||||
damage_groups = {fleshy = v}
|
||||
}, nil)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
entity.v2 = v
|
||||
end
|
||||
|
||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
||||
|
||||
function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
local velo = entity.object:get_velocity()
|
||||
local dir = entity.driver:get_look_dir()
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
||||
local yaw = entity.driver:get_look_horizontal()
|
||||
|
||||
if ctrl.up then
|
||||
entity.object:set_velocity({
|
||||
x = dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
z = dir.z * speed
|
||||
})
|
||||
|
||||
entity.object:set_velocity(vector.new(dir.x * speed, dir.y * speed + 2, dir.z * speed))
|
||||
elseif ctrl.down then
|
||||
entity.object:set_velocity({
|
||||
x = -dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
z = -dir.z * speed
|
||||
})
|
||||
|
||||
entity.object:set_velocity(vector.new(-dir.x * speed, dir.y * speed + 2, -dir.z * speed))
|
||||
elseif not ctrl.down or ctrl.up or ctrl.jump then
|
||||
entity.object:set_velocity({x = 0, y = -2, z = 0})
|
||||
entity.object:set_velocity(vector.new(0, -2, 0))
|
||||
end
|
||||
|
||||
entity.object:set_yaw(yaw + math.pi + math.pi / 2 - entity.rotate)
|
||||
entity:set_yaw(yaw - entity.rotate, 2)
|
||||
|
||||
-- firing arrows
|
||||
if ctrl.LMB and ctrl.sneak and shoots then
|
||||
|
||||
local pos = entity.object:get_pos()
|
||||
local obj = minetest.add_entity({
|
||||
x = pos.x + 0 + dir.x * 2.5,
|
||||
y = pos.y + 1.5 + dir.y,
|
||||
z = pos.z + 0 + dir.z * 2.5}, arrow)
|
||||
|
||||
local obj = minetest.add_entity(vector.offset(pos, dir.x * 2.5, 1.5 + dir.y, dir.z * 2.5), arrow)
|
||||
local ent = obj:get_luaentity()
|
||||
if ent then
|
||||
ent.switch = 1 -- for mob specific arrows
|
||||
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
|
||||
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
|
||||
local vec = vector.new(dir.x * 6, dir.y * 6, dir.z * 6)
|
||||
local yaw = entity.driver:get_look_horizontal()
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
obj:set_yaw(yaw)
|
||||
obj:set_velocity(vec)
|
||||
else
|
||||
obj:remove()
|
||||
|
@ -439,11 +254,9 @@ function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_an
|
|||
|
||||
-- change animation if stopped
|
||||
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
|
||||
mcl_mobs:set_animation(entity, stand_anim)
|
||||
if stand_anim then mcl_mobs:set_animation(entity, stand_anim) end
|
||||
else
|
||||
-- moving animation
|
||||
mcl_mobs:set_animation(entity, moving_anim)
|
||||
if moving_anim then mcl_mobs:set_animation(entity, moving_anim) end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -452,12 +265,7 @@ mcl_mobs.mob_class.fly = mcl_mobs.fly
|
|||
mcl_mobs.mob_class.attach = mcl_mobs.attach
|
||||
|
||||
function mob_class:on_detach_child(child)
|
||||
if self.detach_child then
|
||||
if self.detach_child(self, child) then
|
||||
return
|
||||
end
|
||||
end
|
||||
if self.driver == child then
|
||||
self.driver = nil
|
||||
end
|
||||
if self.detach_child and self.detach_child(self, child) then return end
|
||||
if self.driver == child then self.driver = nil end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue