diff --git a/README.md b/README.md index 7d860d2c8..7c3cecece 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Use the `/giveme` chat command to obtain them. See the in-game help for an explanation. ## Installation -This game requires [Minetest](http://minetest.net) to run (version 5.4.0 or +This game requires [Minetest](http://minetest.net) to run (version 5.3.0 or later). So you need to install Minetest first. Only stable versions of Minetest are officially supported. There is no support for running MineClone 2 in development versions of Minetest. diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index a9f6bd5a1..ee2426713 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,5 +1,10 @@ local S = minetest.get_translator("mcl_playerplus") +mcl_playerplus = { + elytra = {}, +} + +local player_velocity_old = {x=0, y=0, z=0} local get_connected_players = minetest.get_connected_players local dir_to_yaw = minetest.dir_to_yaw local get_item_group = minetest.get_item_group @@ -19,21 +24,21 @@ local math = math -- Internal player state local mcl_playerplus_internal = {} -local def = {} local time = 0 +local look_pitch = 0 local player_collision = function(player) local pos = player:get_pos() - local vel = player:get_velocity() + --local vel = player:get_velocity() local x = 0 local z = 0 local width = .75 for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do - if object:is_player() - or (object:get_luaentity()._cmi_is_mob == true and object ~= player) then + if object and (object:is_player() + or (object:get_luaentity()._cmi_is_mob == true and object ~= player)) then local pos2 = object:get_pos() local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} @@ -46,7 +51,7 @@ local player_collision = function(player) end end - return({x * 5,z * 5}) + return({x,z}) end -- converts yaw to degrees @@ -54,18 +59,8 @@ local function degrees(rad) return rad * 180.0 / math.pi end -local pi = math.pi -local atann = math.atan -local atan = function(x) - if not x or x ~= x then - return 0 - else - return atann(x) - end -end - local dir_to_pitch = function(dir) - local dir2 = vector.normalize(dir) + --local dir2 = vector.normalize(dir) local xz = math.abs(dir.x) + math.abs(dir.z) return -math.atan2(-dir.y, xz) end @@ -117,7 +112,38 @@ function limit_vel_yaw(player_vel_yaw, yaw) return player_vel_yaw end -local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos +local node_stand, node_stand_below, node_head, node_feet + + +minetest.register_on_punchplayer(function(player, hitter, damage) + if hitter:is_player() then + if hitter:get_player_control().aux1 then + player:add_velocity(hitter:get_velocity()) + end + if hitter:get_velocity().y < -6 then + player:set_hp(player:get_hp() - (damage * math.random(0.50 , 0.75))) + local pos = player:get_pos() + minetest.add_particlespawner({ + amount = 15, + time = 0.1, + minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, + maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, + minvel = {x=-0.1, y=-0.1, z=-0.1}, + maxvel = {x=0.1, y=0.1, z=0.1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 2, + minsize = 1.5, + maxsize = 1.5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + }) + end + end +end) + minetest.register_globalstep(function(dtime) @@ -125,13 +151,6 @@ minetest.register_globalstep(function(dtime) for _,player in pairs(get_connected_players()) do - c_x, c_y = unpack(player_collision(player)) - - if player:get_velocity().x + player:get_velocity().y < .5 and c_x + c_y > 0 then - --minetest.chat_send_player(player:get_player_name(), "pushed at " .. c_x + c_y .. " parsecs.") - player:add_velocity({x=c_x, y=0, z=c_y}) - end - --[[ _ _ _ __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ @@ -141,14 +160,22 @@ minetest.register_globalstep(function(dtime) ]]-- - local controls = player:get_player_control() + local control = player:get_player_control() local name = player:get_player_name() - local meta = player:get_meta() + --local meta = player:get_meta() local parent = player:get_attach() local wielded = player:get_wielded_item() local player_velocity = player:get_velocity() or player:get_player_velocity() - -- controls head bone + local c_x, c_y = unpack(player_collision(player)) + + if player_velocity.x + player_velocity.y < .5 and c_x + c_y > 0 then + local add_velocity = player.add_player_velocity or player.add_velocity + add_velocity(player, {x = c_x, y = 0, z = c_y}) + player_velocity = player:get_velocity() or player:get_player_velocity() + end + + -- control head bone local pitch = - degrees(player:get_look_vertical()) local yaw = degrees(player:get_look_horizontal()) @@ -159,12 +186,74 @@ minetest.register_globalstep(function(dtime) player_vel_yaw = limit_vel_yaw(player_vel_yaw, yaw) player_vel_yaws[name] = player_vel_yaw + local fly_pos = player:get_pos() + local fly_node = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.5, z = fly_pos.z}).name + local elytra = mcl_playerplus.elytra[player] + + elytra.active = player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" + and not player:get_attach() + and (elytra.active or control.jump and player_velocity.y < -6) + and (fly_node == "air" or fly_node == "ignore") + + if elytra.active then + if player_velocity.x < (player_velocity_old.x - 10) or player_velocity.x > (player_velocity_old.x + 10) then + player:set_hp(player:get_hp() - (math.abs(player_velocity_old.x) * 0.2)) + end + if player_velocity.z < (player_velocity_old.z - 10) or player_velocity.z > (player_velocity_old.z + 10) then + player:set_hp(player:get_hp() - (math.abs(player_velocity_old.z) * 0.2)) + end + mcl_player.player_set_animation(player, "fly") + if player_velocity.y < -1.5 then + player:add_velocity({x=0, y=0.17, z=0}) + end + if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then + local dir = minetest.yaw_to_dir(player:get_look_horizontal()) + if degrees(player:get_look_vertical()) * -.01 < .1 then + look_pitch = degrees(player:get_look_vertical()) * -.01 + else + look_pitch = .1 + end + player:add_velocity({x=dir.x, y=look_pitch, z=dir.z}) + end + playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", 0.1) + + if elytra.rocketing > 0 then + elytra.rocketing = elytra.rocketing - dtime + if vector.length(player_velocity) < 40 then + local add_velocity = player.add_velocity or player.add_player_velocity + add_velocity(player, vector.multiply(player:get_look_dir(), 4)) + minetest.add_particlespawner({ + amount = 1, + time = 0.1, + minpos = fly_pos, + maxpos = fly_pos, + minvel = {x = 0, y = 0, z = 0}, + maxvel = {x = 0, y = 0, z = 0}, + minacc = {x = 0, y = 0, z = 0}, + maxacc = {x = 0, y = 0, z = 0}, + minexptime = 0.3, + maxexptime = 0.5, + minsize = 1, + maxsize = 2.5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + glow = 5, + }) + end + end + else + elytra.rocketing = 0 + playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") + end + + player_velocity_old = player:get_velocity() or player:get_player_velocity() -- controls right and left arms pitch when shooting a bow - if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then + if string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB and not control.LMB and not control.up and not control.down and not control.left and not control.right then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) -- when punching - elseif controls.LMB and not parent then + elseif control.LMB and not parent then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) -- when holding an item. @@ -177,30 +266,37 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) end - if parent then - local parent_yaw = degrees(parent:get_yaw()) - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) - elseif controls.sneak then - -- controls head pitch when sneaking - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0)) - -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) - -- sneaking body conrols - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) - elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then - -- set head pitch and yaw when swimming - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) + if elytra.active then + -- set head pitch and yaw when flying + player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + -- control body bone when flying + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) + elseif parent then + local parent_yaw = degrees(parent:get_yaw()) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) + elseif control.sneak then + -- controls head pitch when sneaking + player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw)) + -- sets eye height, and nametag color accordingly + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) + -- sneaking body conrols + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) + elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then + -- set head pitch and yaw when swimming + player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) + -- sets eye height, and nametag color accordingly + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) -- control body bone when swimming player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) else -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) + player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) end @@ -211,9 +307,9 @@ minetest.register_globalstep(function(dtime) mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime end - if controls.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then + if control.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then - pos = player:get_pos() + --pos = player:get_pos() node_stand = mcl_playerinfo[name].node_stand node_stand_below = mcl_playerinfo[name].node_stand_below @@ -285,9 +381,6 @@ minetest.register_globalstep(function(dtime) return end - -- set defaults - def.speed = 1 - -- Standing on soul sand? If so, walk slower (unless player wears Soul Speed boots) if node_stand == "mcl_nether:soul_sand" then -- TODO: Tweak walk speed @@ -442,6 +535,7 @@ minetest.register_on_joinplayer(function(player) swimDistance = 0, jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly } + mcl_playerplus.elytra[player] = {active = false, rocketing = 0} end) -- clear when player leaves @@ -449,4 +543,5 @@ minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() mcl_playerplus_internal[name] = nil + mcl_playerplus.elytra[player] = nil end)