mirror of
https://github.com/minetest/minetest.git
synced 2024-09-12 00:26:50 +02:00
Restore and enhance bouncy behavior (#11939)
This commit is contained in:
parent
907dcdcf7b
commit
6ac38aa2c8
@ -1868,7 +1868,9 @@ to games.
|
|||||||
* `attached_node`: if the node under it is not a walkable block the node will be
|
* `attached_node`: if the node under it is not a walkable block the node will be
|
||||||
dropped as an item. If the node is wallmounted the wallmounted direction is
|
dropped as an item. If the node is wallmounted the wallmounted direction is
|
||||||
checked.
|
checked.
|
||||||
* `bouncy`: value is bounce speed in percent
|
* `bouncy`: value is bounce speed in percent.
|
||||||
|
If positive, jump/sneak on floor impact will increase/decrease bounce height.
|
||||||
|
Negative value is the same bounciness, but non-controllable.
|
||||||
* `connect_to_raillike`: makes nodes of raillike drawtype with same group value
|
* `connect_to_raillike`: makes nodes of raillike drawtype with same group value
|
||||||
connect to each other
|
connect to each other
|
||||||
* `dig_immediate`: Player can always pick up node without reducing tool wear
|
* `dig_immediate`: Player can always pick up node without reducing tool wear
|
||||||
|
@ -331,8 +331,8 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the player's feet touch the topside of any node, this is
|
If the player's feet touch the topside of any node
|
||||||
set to true.
|
at the END of clientstep, then this is set to true.
|
||||||
|
|
||||||
Player is allowed to jump when this is true.
|
Player is allowed to jump when this is true.
|
||||||
*/
|
*/
|
||||||
@ -432,23 +432,47 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
const ContentFeatures &f = nodemgr->get(map->getNode(m_standing_node));
|
const ContentFeatures &f = nodemgr->get(map->getNode(m_standing_node));
|
||||||
const ContentFeatures &f1 = nodemgr->get(map->getNode(m_standing_node + v3s16(0, 1, 0)));
|
const ContentFeatures &f1 = nodemgr->get(map->getNode(m_standing_node + v3s16(0, 1, 0)));
|
||||||
|
|
||||||
|
// We can jump from a bouncy node we collided with this clientstep,
|
||||||
|
// even if we are not "touching" it at the end of clientstep.
|
||||||
|
int standing_node_bouncy = 0;
|
||||||
|
if (result.collides && m_speed.Y > 0.0f) {
|
||||||
|
// must use result.collisions here because sometimes collision_info
|
||||||
|
// is passed in prepopulated with a problematic floor.
|
||||||
|
for (const auto &colinfo : result.collisions) {
|
||||||
|
if (colinfo.axis == COLLISION_AXIS_Y) {
|
||||||
|
// we cannot rely on m_standing_node because "sneak stuff"
|
||||||
|
standing_node_bouncy = itemgroup_get(nodemgr->get(map->getNode(colinfo.node_p)).groups, "bouncy");
|
||||||
|
if (standing_node_bouncy != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine if jumping is possible
|
// Determine if jumping is possible
|
||||||
m_disable_jump = itemgroup_get(f.groups, "disable_jump") ||
|
m_disable_jump = itemgroup_get(f.groups, "disable_jump") ||
|
||||||
itemgroup_get(f1.groups, "disable_jump");
|
itemgroup_get(f1.groups, "disable_jump");
|
||||||
m_can_jump = ((touching_ground && !is_climbing) || sneak_can_jump) && !m_disable_jump;
|
m_can_jump = ((touching_ground && !is_climbing) || sneak_can_jump || standing_node_bouncy != 0)
|
||||||
|
&& !m_disable_jump;
|
||||||
|
|
||||||
// Jump key pressed while jumping off from a bouncy block
|
// Jump/Sneak key pressed while bouncing from a bouncy block
|
||||||
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
|
float jumpspeed = movement_speed_jump * physics_override.jump;
|
||||||
m_speed.Y >= -0.5f * BS) {
|
if (m_can_jump && (control.jump || control.sneak) && standing_node_bouncy > 0) {
|
||||||
float jumpspeed = movement_speed_jump * physics_override.jump;
|
// controllable (>0) bouncy block
|
||||||
if (m_speed.Y > 1.0f) {
|
if (!control.jump) {
|
||||||
// Reduce boost when speed already is high
|
// sneak pressed, but not jump
|
||||||
m_speed.Y += jumpspeed / (1.0f + (m_speed.Y / 16.0f));
|
// Subjective testing indicates 1/3 bounce decrease works well.
|
||||||
|
jumpspeed = -m_speed.Y / 3.0f;
|
||||||
} else {
|
} else {
|
||||||
m_speed.Y += jumpspeed;
|
// jump pressed
|
||||||
|
// Reduce boost when speed already is high
|
||||||
|
jumpspeed = jumpspeed / (1.0f + (m_speed.Y * 2.8f / jumpspeed));
|
||||||
}
|
}
|
||||||
|
m_speed.Y += jumpspeed;
|
||||||
setSpeed(m_speed);
|
setSpeed(m_speed);
|
||||||
m_can_jump = false;
|
m_can_jump = false;
|
||||||
|
} else if(m_speed.Y > jumpspeed && standing_node_bouncy < 0) {
|
||||||
|
// uncontrollable bouncy is limited to normal jump height.
|
||||||
|
m_can_jump = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autojump
|
// Autojump
|
||||||
@ -897,8 +921,8 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
m_standing_node = floatToInt(m_position, BS);
|
m_standing_node = floatToInt(m_position, BS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the player's feet touch the topside of any node, this is
|
If the player's feet touch the topside of any node
|
||||||
set to true.
|
at the END of clientstep, then this is set to true.
|
||||||
|
|
||||||
Player is allowed to jump when this is true.
|
Player is allowed to jump when this is true.
|
||||||
*/
|
*/
|
||||||
@ -1028,22 +1052,45 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||||||
*/
|
*/
|
||||||
const ContentFeatures &f = nodemgr->get(map->getNode(getStandingNodePos()));
|
const ContentFeatures &f = nodemgr->get(map->getNode(getStandingNodePos()));
|
||||||
|
|
||||||
|
// We can jump from a bouncy node we collided with this clientstep,
|
||||||
|
// even if we are not "touching" it at the end of clientstep.
|
||||||
|
int standing_node_bouncy = 0;
|
||||||
|
if (result.collides && m_speed.Y > 0.0f) {
|
||||||
|
// must use result.collisions here because sometimes collision_info
|
||||||
|
// is passed in prepopulated with a problematic floor.
|
||||||
|
for (const auto &colinfo : result.collisions) {
|
||||||
|
if (colinfo.axis == COLLISION_AXIS_Y) {
|
||||||
|
// we cannot rely on m_standing_node because "sneak stuff"
|
||||||
|
standing_node_bouncy = itemgroup_get(nodemgr->get(map->getNode(colinfo.node_p)).groups, "bouncy");
|
||||||
|
if (standing_node_bouncy != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine if jumping is possible
|
// Determine if jumping is possible
|
||||||
m_disable_jump = itemgroup_get(f.groups, "disable_jump");
|
m_disable_jump = itemgroup_get(f.groups, "disable_jump");
|
||||||
m_can_jump = touching_ground && !m_disable_jump;
|
m_can_jump = (touching_ground || standing_node_bouncy != 0) && !m_disable_jump;
|
||||||
|
|
||||||
// Jump key pressed while jumping off from a bouncy block
|
// Jump/Sneak key pressed while bouncing from a bouncy block
|
||||||
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
|
float jumpspeed = movement_speed_jump * physics_override.jump;
|
||||||
m_speed.Y >= -0.5f * BS) {
|
if (m_can_jump && (control.jump || control.sneak) && standing_node_bouncy > 0) {
|
||||||
float jumpspeed = movement_speed_jump * physics_override.jump;
|
// controllable (>0) bouncy block
|
||||||
if (m_speed.Y > 1.0f) {
|
if (!control.jump) {
|
||||||
// Reduce boost when speed already is high
|
// sneak pressed, but not jump
|
||||||
m_speed.Y += jumpspeed / (1.0f + (m_speed.Y / 16.0f));
|
// Subjective testing indicates 1/3 bounce decrease works well.
|
||||||
|
jumpspeed = -m_speed.Y / 3.0f;
|
||||||
} else {
|
} else {
|
||||||
m_speed.Y += jumpspeed;
|
// jump pressed
|
||||||
|
// Reduce boost when speed already is high
|
||||||
|
jumpspeed = jumpspeed / (1.0f + (m_speed.Y * 2.8f / jumpspeed));
|
||||||
}
|
}
|
||||||
|
m_speed.Y += jumpspeed;
|
||||||
setSpeed(m_speed);
|
setSpeed(m_speed);
|
||||||
m_can_jump = false;
|
m_can_jump = false;
|
||||||
|
} else if(m_speed.Y > jumpspeed && standing_node_bouncy < 0) {
|
||||||
|
// uncontrollable bouncy is limited to normal jump height.
|
||||||
|
m_can_jump = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autojump
|
// Autojump
|
||||||
|
Loading…
Reference in New Issue
Block a user