mob_core/mount.lua

169 lines
5.1 KiB
Lua

------------------------
-- Mob Core Mount API --
------------------------
-------- Ver 1.0 -------
local player_attached = {}
local animate_player = {}
if minetest.get_modpath("default") then
player_attached = default.player_attached
animate_player = default.player_set_animation
elseif minetest.get_modpath("mcl_player") then
player_attached = mcl_player.player_attached
animate_player = mcl_player.player_set_animation
end
----------------------
-- Helper functions --
----------------------
local function detach(name)
local player = minetest.get_player_by_name(name)
if not player then
return
end
local attached_to = player:get_attach()
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
mobkit.clear_queue_high(entity)
entity.status = mobkit.remember(entity,"status","")
player:set_detach()
if player_attached ~= nil then
player_attached[player:get_player_name()] = false
end
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
animate_player(player, "stand" , 30)
player:set_properties({visual_size = {x = 1, y = 1}, pointable = true })
end
function mob_core.force_detach(player)
minetest.after(0, detach, player:get_player_name())
end
local function reverse_animation(self,anim,output_name)
if self.animation and self.animation[anim] then
local frame_x = self.animation[anim].range.x
local frame_y = self.animation[anim].range.y
local loop = self.animation[anim].loop
local speed = self.animation[anim].speed
self.animation[output_name] = {range={x=frame_x,y=frame_y},speed=-speed,loop=loop}
end
end
minetest.register_on_leaveplayer(function(player)
mob_core.force_detach(player)
end)
minetest.register_on_shutdown(function()
local players = minetest.get_connected_players()
for i = 1, #players do
mob_core.force_detach(players[i])
end
end)
minetest.register_on_dieplayer(function(player)
mob_core.force_detach(player)
return true
end)
function mob_core.attach(entity, player)
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},{x = 0, y = 0, z = 0}}
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
local attach_at = entity.driver_attach_at
local eye_offset = entity.driver_eye_offset[1] or {x = 0, y = 0, z = 0}
local eye_offset_3p = entity.driver_eye_offset[2] or {x = 0, y = 0, z = 0}
entity.driver = player
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
if player_attached ~= nil then
player_attached[player:get_player_name()] = true
end
player:set_eye_offset(eye_offset,eye_offset_3p)
player:set_properties({
visual_size = {
x = entity.driver_scale.x,
y = entity.driver_scale.y
},
pointable = false
})
minetest.after(0.2, function()
animate_player(player, "sit" , 30)
end)
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
end
function mob_core.detach(player, offset)
mob_core.force_detach(player)
animate_player(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}
minetest.after(0.1, function()
player:set_pos(pos)
end)
end
local function go_forward(self,tvel)
local y = self.object:get_velocity().y
local yaw = self.object:get_yaw()
local vel = vector.multiply(minetest.yaw_to_dir(yaw),tvel)
vel.y = y
self.object:set_velocity(vel)
end
function mob_core.hq_mount_logic(self,prty)
local tvel = 0
local func = function(self)
if not self.driver then return true end
local vel = self.object:get_velocity()
local ctrl = self.driver:get_player_control()
if ctrl.up then
tvel = self.max_speed_forward
elseif ctrl.down and self.isonground then -- move backwards
if self.max_speed_reverse == 0 and vel == 0 then
return
end
tvel = -self.max_speed_reverse
reverse_animation(self, "walk", "walk_reverse")
mobkit.animate(self, "walk_reverse")
elseif tvel < 0.25 or tvel == 0 then
tvel = 0
self.object:set_velocity({x=0,y=vel.y,z=0})
mobkit.animate(self, "stand")
end
-- jump
if self.isonground then
if ctrl.jump then
vel.y = (self.jump_height)+4
end
end
--stand
if tvel ~= 0 and not ctrl.up or ctrl.down then
tvel = tvel*0.75
end
if tvel > 0 then
mobkit.animate(self,"walk")
end
local tyaw = self.driver:get_look_horizontal() or 0
self.object:set_yaw(tyaw)
self.object:set_velocity({x=vel.x,y=vel.y,z=vel.y})
go_forward(self,tvel)
if ctrl.sneak then
mobkit.clear_queue_low(self)
mobkit.clear_queue_high(self)
mob_core.detach(self.driver, {x = 1, y = 0, z = 1})
end
end
mobkit.queue_high(self,func,prty)
end