Add Climb, Crouch

Climbing Animation added
Crouching Animation added
Improved Fly vs Fall animations
master
Sirrobzeroone 2020-12-08 21:25:12 +11:00
parent ea2f8906a7
commit f450ed305a
9 changed files with 311 additions and 57 deletions

View File

@ -4,7 +4,7 @@
armor:register_armor("3d_armor_flyswim:demo_cape", {
description = "Someones Cape",
inventory_image = "3d_armor_flyswim_demo_cape_inv.png",
groups = {armor_capes=1, physics_speed=.5, armor_use=1000},
groups = {armor_capes=1, physics_speed=1, armor_use=1000},
armor_groups = {fleshy=5},
damage_groups = {cracky=3, snappy=3, choppy=2, crumbly=2, level=1},
on_equip = function(player)

View File

@ -8,18 +8,23 @@
------------------------------------------------------------------
----------------------------------------
-- Check node fly/swim by drawtype --
-- Check specific node fly/swim --
-- 1=player feet, 2=one below feet, --
-- Thanks Gundul --
----------------------------------------
function node_fsable(n_draw,type)
function node_fsable(pos,num,type)
local draw_ta = {"airlike"}
local draw_tl = {"liquid","flowingliquid"}
local compare = draw_ta
local node = minetest.get_node({x=pos.x,y=pos.y-(num-1),z=pos.z})
local n_draw = minetest.registered_nodes[node.name].drawtype
if type == "s" then
compare = draw_tl
end
for k,v in ipairs(compare) do
end
for k,v in ipairs(compare) do
if n_draw == v then
return true
end
@ -27,6 +32,77 @@ function node_fsable(n_draw,type)
return false
end
-----------------------------------------------
-- Check X number nodes down fly/Swimmable --
-----------------------------------------------
function node_down_fsable(pos,num,type)
local draw_ta = {"airlike"}
local draw_tl = {"liquid","flowingliquid"}
local i = 0
local nodes = {}
local result ={}
local compare = draw_ta
while (i < num ) do
table.insert(nodes, minetest.get_node({x=pos.x,y=pos.y-i,z=pos.z}))
i=i+1
end
if type == "s" then
compare = draw_tl
end
for k,v in pairs(nodes) do
n_draw = minetest.registered_nodes[v.name].drawtype
for k2,v2 in ipairs(compare) do
if n_draw == v2 then
table.insert(result,"t")
end
end
end
if #result == num then
return true
else
return false
end
end
------------------------------------------
-- Workaround for odd crouch behaviour --
------------------------------------------
function crouch_wa(player,pos)
local is_slab = 0 -- is_slab var holder 0=not_slab, 1=slab
local pos_w = {} -- Empty table
local angle = (player:get_look_horizontal())*180/math.pi -- Convert Look direction to angles
if angle <= 45 or angle >= 315 then -- +Z North
pos_w={x=pos.x,y=pos.y+1,z=pos.z+1}
elseif angle > 45 and angle < 135 then -- -X West
pos_w={x=pos.x-1,y=pos.y+1,z=pos.z}
elseif angle >= 135 and angle <= 225 then -- -Z South
pos_w={x=pos.x,y=pos.y+1,z=pos.z-1}
elseif angle > 225 and angle < 315 then -- +X East
pos_w={x=pos.x+1,y=pos.y+1,z=pos.z}
end
local check = minetest.get_node(pos_w) -- Get the node that is in front of the players look direction
local check_g = minetest.registered_nodes[check.name].groups -- Get the groups assigned to node
for k,v in pairs(check_g) do
if k == "slab" then -- Any of the keys == slab then slab
is_slab = 1 -- is_slab set to 1
end
end
return is_slab -- return 1 or 0
end

282
init.lua
View File

@ -27,6 +27,8 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local add_capes = minetest.setting_getbool("capes_add_to_3darmor")
local d_fall_anim = 0 -- Stop fall animation from playing after pressing shift_dwn
-- and flying otherwise looks funny flicking to falling.
if add_capes == nil then -- To cover mod.conf/settings update issue
add_capes = true
@ -84,7 +86,10 @@ default.player_register_model(player_mod, {
fly = {x=325, y=334},
fly_atk = {x=340, y=349},
fall = {x=355, y=364},
fall_atk = {x=365, y=374},
fall_atk = {x=365, y=374},
duck_std = {x=380, y=380},
duck = {x=381, y=399},
climb = {x=410, y=429},
},
})
@ -111,88 +116,261 @@ minetest.register_globalstep(function()
local attached_to = player:get_attach() -- If the players attached to something we need to know
local privs = minetest.get_player_privs(player:get_player_name())-- Privs crude attempt to differentiate potenital flying from falling
local pos = player:get_pos()
local node = minetest.get_node(pos) -- Node player is in (lower legs)
node = minetest.registered_nodes[node.name].drawtype -- Set node to node drawtype
local node_b = minetest.get_node({x=pos.x,y=pos.y -1,z=pos.z}) -- Node below players feet
node_b = minetest.registered_nodes[node_b.name].drawtype -- Set node to node drawtype
local node_bb = minetest.get_node({x=pos.x,y=pos.y -2,z=pos.z}) -- Next node down
node_bb = minetest.registered_nodes[node_bb.name].drawtype -- Set node to node drawtype
local node_bbb = minetest.get_node({x=pos.x,y=pos.y -3,z=pos.z}) -- Next node down (falling starts later)
node_bbb = minetest.registered_nodes[node_bbb.name].drawtype-- Set node to node drawtype
local node_bbbb = minetest.get_node({x=pos.x,y=pos.y -4,z=pos.z})-- Next node down (falling starts later)
node_bbbb = minetest.registered_nodes[node_bbbb.name].drawtype-- Set node to node drawtype
local offset = 0 -- Used for Headanim
local ladder_n = minetest.get_node(pos)
local ladder_n_b = minetest.get_node({x=pos.x,y=pos.y -1,z=pos.z})
local offset = 0 -- Used for Headanim
local is_slab = crouch_wa(player,pos) -- Function specifically for Crouch-walk work around
local cur_anim = player_api.get_animation(player)
local pmeta = player:get_meta()
if (controls.up or controls.down or
-- reset player collisionbox, eye height, speed override
player:set_properties({collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}})
player:set_properties({eye_height = 1.47})
if pmeta:get_int("flyswim_suss") == 1 then
player:set_physics_override({speed = pmeta:get_float("flyswim_orgor")})
pmeta:set_int("flyswim_suss", 0)
end
local vel = player:get_player_velocity()
local play_s = (math.sqrt(math.pow(math.abs(vel.x),2) +
math.pow(math.abs(vel.y),2) +
math.pow(math.abs(vel.z),2) ))*3.6 -- basically 3D Pythagorean Theorem km/h
-- Catch to stop flicking to falling when --
-- flying down and then letting go of shift --
if controls.sneak then
d_fall_anim = 7 -- each "1" == 0.05sec delay, 7 delay covers about 200Kph
end
-- Sets terminal velocity to about 100Kkm/hr beyond --
-- this speed chunk load issues become more noticable --
if vel.y < -27 and controls.sneak ~= true then
local tv_offset_y = -1*((-1*(vel.y+1)) + vel.y) --(-1*(vel.y+1)) - catch those holding shift and over acceleratering when falling so dynamic end point so we dont bounce back up
-- Remove above replace with 27 and then acclerate down (hold shift) for 5-6 secs then let go you'll "bounce" back up :)
player:add_player_velocity({x=0, y=tv_offset_y, z=0})
end
---------------------------------------------------------
-- Start of Animation Cases --
---------------------------------------------------------
-----------------------------
--stop standing under slabs--
-----------------------------
local ch = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
local ch_g = minetest.registered_nodes[ch.name].groups
local ch_slab = 0
for k,v in pairs(ch_g) do
if k == "slab" then
ch_slab = 1
end
end
if ch_slab == 1 and
node_fsable(pos,2,"a") ~= true and
controls.sneak ~= true and
(controls.up == true or
controls.down == true or
controls.left == true or
controls.right == true) then
player_api.set_animation(player, "duck",ani_spd/2)
player:set_properties({collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.45, 0.3}})
player:set_properties({eye_height = 1.27})
local play_or_2 =player:get_physics_override()
pmeta:set_int("flyswim_suss", 1)
pmeta:set_float("flyswim_orgor", play_or_2.speed)
player:set_physics_override({speed = play_or_2.speed*0.2})
elseif ch_slab == 1 and
node_fsable(pos,2,"a") ~= true and
controls.sneak ~= true and
(controls.up ~= true or
controls.down ~= true or
controls.left ~= true or
controls.right ~= true) then
player_api.set_animation(player, "duck_std",ani_spd)
player:set_properties({collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.45, 0.3}})
player:set_properties({eye_height = 1.27})
-----------------------------
-- Climb Cases --
-----------------------------
elseif minetest.registered_nodes[ladder_n.name].climbable and -- Player standing in node that is climable and
(controls.jump or controls.sneak) then -- Moving up or Moving down
if controls.sneak and -- Climbing down but at bottom of the climable node
minetest.registered_nodes[ladder_n_b.name].climbable ~= true then
-- #nothing
else
player_api.set_animation(player, "climb",ani_spd) -- Do climbing animation
--player:set_animation({x=410, y=429},30,0,true) -- experimenting removing player_api dependancy
end
-----------------------------
-- Swim Cases --
-----------------------------
elseif (controls.up or controls.down or
controls.left or controls.right) and -- Must be moving in a direction
(controls.LMB or controls.RMB) and -- Must be swinging
node_fsable(node,"s") == true and -- Node player standing in must be swimmable
node_fsable(node_b,"s") == true then -- Node below must be swimmable
node_down_fsable(pos,2,"s") == true then -- Node player standing in and 1 below must be swimmable
player_api.set_animation(player,"swim_atk",ani_spd) -- Set to swimming attack animation
offset = 90 -- Offset for Headanim
elseif (controls.up or controls.down or
controls.left or controls.right) and -- Must be moving in a direction
node_fsable(node,"s") == true and -- Node player standing in must be swimmable
node_fsable(node_b,"s") == true then -- Node below must be swimmable
node_down_fsable(pos,2,"s") == true then -- Node player standing in and 1 below must be swimmable
player_api.set_animation(player, "swim",ani_spd) -- Set to swimming animation
offset = 90 -- Offset for Headanim
elseif not attached_to and privs.fly == true then -- If player attached to something dont do flying animation
elseif
controls.sneak == true and
node_down_fsable(pos,1,"s") == true then -- Node player standing in swimmable
player_api.set_animation(player, "swim",ani_spd) -- Set to swimming animation
player:set_properties({collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4}})
player:set_properties({eye_height = 0.7})
offset = 90 -- Offset for Headanim
-----------------------------
-- Sneak Cases --
-----------------------------
----------------------------------------------------------
-- Crouch-walk workaround Start -- This is to workaround the strange crouch-walk behaviour,
-- can only walk halfway under 1st slab then stops,
-- This workaround allows walking through 1st strangly blocked slab
elseif controls.sneak == true and -- Must be sneaking
controls.up == true and -- Must be moving forwards
node_fsable(pos,2,"a") ~= true and -- No air node below feet
play_s <= 1 and is_slab == 1 then -- Speed < 1 kph and node infront and up 1 must be slab see functions
player_api.set_animation(player, "duck",ani_spd/2) -- Set to duck/crouch animation
player:set_properties({collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3}}) -- Workaround set collision box to 1 high
player:set_properties({eye_height = 1.27}) -- eye hieght dropped a bit
-- Crouch-walk workaround end
----------------------------------------------------------
elseif controls.sneak == true and -- Must be sneaking
node_fsable(pos,2,"a") ~= true and -- No air node below feet
(controls.up == true or -- Moving in a direction otherwise we are standing
controls.down == true or
controls.left == true or
controls.right == true) then
player_api.set_animation(player, "duck",ani_spd/2)
player:set_properties({collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.45, 0.3}})
player:set_properties({eye_height = 1.27})
elseif controls.sneak == true and -- Must be sneaking
node_fsable(pos,2,"a") ~= true and -- No air node below feet
(controls.up ~= true or -- Not moving in any direction
controls.down ~= true or
controls.left ~= true or
controls.right ~= true) then
player_api.set_animation(player, "duck_std",ani_spd)
player:set_properties({collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.45, 0.3}})
player:set_properties({eye_height = 1.27})
-----------------------------
-- Flying Cases --
-----------------------------
elseif not attached_to and privs.fly == true then -- If player attached to something dont do flying animation
if(controls.up or controls.down or -- must also have fly privs or we should definitly be falling.
controls.left or controls.right) and -- Must be moving in a direction
(controls.LMB or controls.RMB) and -- Must be swinging
node_fsable(node,"a") == true and -- Node player is standing in must be flyable
node_fsable(node_b,"a") == true and -- node below must be flyable
node_fsable(node_bb,"a") == true then -- node 2 down must be flyable
node_down_fsable(pos,3,"a") == true and -- Node player is standing in must be flyable and 2 down
(vel.y >= 0 or controls.sneak == true) then
player_api.set_animation(player, "fly_atk",ani_spd) -- Show fly attack animation
offset = 90 -- Offset for Headanim
elseif(controls.up or controls.down or
controls.left or controls.right) and -- Must be moving in a direction
node_fsable(node,"a") == true and -- Node player is standing in must be flyable
node_fsable(node_b,"a") == true and -- node below must be flyable
node_fsable(node_bb,"a") == true then -- node 2 down must be flyable
node_down_fsable(pos,3,"a") == true and -- Node player is standing in must be flyable and 2 down
(vel.y >= 0 or controls.sneak == true) then
player_api.set_animation(player, "fly",ani_spd) -- Show fly animation or swan dive if falling
offset = 90 -- Offset for Headanim
elseif (controls.up or controls.down or
controls.left or controls.right) and -- Must be moving in a direction
controls.sneak ~= true and -- catch case to stop fall animation from playing
d_fall_anim > 0 and -- when player has been flying down
node_down_fsable(pos,3,"a") == true then -- Node player is standing in must be flyable and 2 down
player_api.set_animation(player, "fly",ani_spd) -- Show fly down animation (add fly down animation)
d_fall_anim = d_fall_anim - 1
offset = 90 -- Offset for Headanim
elseif controls.sneak ~= true and -- catch case to stop fall animation from playing
d_fall_anim > 0 and -- when player has been flying down
node_down_fsable(pos,3,"a") == true then -- Node player is standing in must be flyable and 2 down
player_api.set_animation(player, "stand",ani_spd) -- Show fly down animation (add fly down animation)
d_fall_anim = d_fall_anim - 1
offset = 90 -- Offset for Headanim
elseif controls.sneak ~= true and -- not pressing down and
vel.y < 0 and -- We have velocity downwards (negative y blocks)
(controls.LMB or controls.RMB) and -- Must be swinging
node_down_fsable(pos,3,"a") == true then -- Node player is standing in must be flyable and 2 down
player_api.set_animation(player, "fall_atk",ani_spd) -- Show falling
offset = 90 -- Offset for Headanim
elseif controls.sneak ~= true and -- not pressing down and
vel.y < 0 and -- We have velocity downwards (negative y blocks)
node_down_fsable(pos,3,"a") == true then -- Node player is standing in must be flyable and 2 down
player_api.set_animation(player, "fall",ani_spd) -- Show falling
offset = 90 -- Offset for Headanim
end
elseif not attached_to then -- If player attached to something dont do falling animation
-----------------------------
-- Falling Cases --
-----------------------------
elseif not attached_to and
controls.sneak ~= true then -- If player attached to something dont do falling animation
if(controls.LMB or controls.RMB) and -- Must be swinging
node_fsable(node,"a") == true and -- Node player is standing in must be flyable/fallable
node_fsable(node_b,"a") == true and -- node below must be flyable/fallable
node_fsable(node_bb,"a") == true and -- node 2 down must be flyable/fallable
node_fsable(node_bbb,"a") == true and -- node 3 down must be flyable/fallable
node_fsable(node_bbbb,"a") == true then -- node 4 down must be flyable/fallable
vel.y < -0.5 and -- We have velocity downwards (negative y blocks) need 0.5 as slight engine in-accuracy when standing on cliff edge?
node_down_fsable(pos,5,"a") == true then -- Node player is standing in and 4 below must be flyable/fallable
player_api.set_animation(player, "fall_atk",ani_spd) -- falling and flailing around
offset = 90 -- Offset for Headanim
elseif node_fsable(node,"a") == true and -- Node player is standing in must be flyable/fallable
node_fsable(node_b,"a") == true and -- node below must be flyable/fallable
node_fsable(node_bb,"a") == true and -- node 2 down must be flyable/fallable
node_fsable(node_bbb,"a") == true and -- node 3 down must be flyable/fallable
node_fsable(node_bbbb,"a") == true then -- node 4 down must be flyable/fallable
elseif vel.y < -0.5 and -- We have velocity downwards (negative y blocks) need 0.5 as slight engine in-accuracy when standing on cliff edge?
node_down_fsable(pos,5,"a") == true then -- Node player is standing in and 4 below must be flyable/fallable
player_api.set_animation(player, "fall",ani_spd) -- falling
offset = 90 -- Offset for Headanim
end
offset = 90 -- Offset for Headanim
end
end
---------------------------------------------------------
-- End of Animation Cases --
---------------------------------------------------------
---------------------------------------------------------
-- Post MT 5.3 Head Animation --
---------------------------------------------------------
local check_v = minetest.is_creative_enabled -- this function was added in 5.3 which has the bone position change break animations fix - i think (MT #9807)
-- I'm not too sure how to directly test for the bone fix so I simply check for this function.
if check_v ~= nil then -- If creative_enabled function is nil we are pre-5.3
local look_degree = -math.deg(player:get_look_vertical())-- Kept this near code
if look_degree > 29 and offset ~= 0 then
offset = offset - (look_degree-30)
elseif look_degree > 60 and offset == 0 then
offset = offset - (look_degree-60)
elseif look_degree < -60 and offset == 0 then
offset = offset - (look_degree+60)
end
local look_degree = -math.deg(player:get_look_vertical()) -- Kept this near code
-- Code by LoneWolfHT - Headanim mod MIT Licence --
player:set_bone_position("Head", vector.new(0, 6.35, 0),vector.new(look_degree + offset, 0, 0))
-- Code by LoneWolfHT - Headanim mod MIT Licence --
end
--minetest.chat_send_all(play_s.." km/h") -- for diagnosing chunk emerge issues when falling currently unsolved
if look_degree > 29 and offset ~= 0 then
offset = offset - (look_degree-30)
elseif look_degree > 60 and offset == 0 then
offset = offset - (look_degree-60)
elseif look_degree < -60 and offset == 0 then
offset = offset - (look_degree+60)
end
-- Code by LoneWolfHT - Headanim mod MIT Licence --
player:set_bone_position("Head", vector.new(0, 6.35, 0),vector.new(look_degree + offset, 0, 0))
-- Code by LoneWolfHT - Headanim mod MIT Licence --
end
end
end)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.