------------------------ -- 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_bone = entity.driver_attach_bone or "" 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, entity.driver_attach_bone, 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 local tyaw = self.driver:get_look_horizontal() or 0 if tvel > 0 then mobkit.animate(self, "walk") mobkit.turn2yaw(self, tyaw, self.turn_rate or 4) end self.object:set_velocity({x = vel.x, y = vel.y, z = vel.y}) go_forward(self, tvel) if ctrl.sneak then mob_core.detach(self.driver, {x = 1, y = 0, z = 1}) return true end end mobkit.queue_high(self, func, prty) end