diff --git a/mods/ENTITIES/mcl_mobs/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index e6b6de78f..750b3f9f4 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -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 - end - - entity.v = entity.v - entity.accel / 10 + 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 - -- 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 - -- 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 +