summaryrefslogtreecommitdiff
path: root/src/localplayer.cpp
diff options
context:
space:
mode:
authorparamat <mat.gregory@virginmedia.com>2017-04-06 15:58:12 +0100
committerparamat <mat.gregory@virginmedia.com>2017-04-11 05:41:13 +0100
commit59911761ef529f118e7ba697d4f5983d43dbb383 (patch)
tree405f23520008a8702d162db43f4b3fc58b31e171 /src/localplayer.cpp
parenteb587996e42544ec8624b256e6d5eea12f9bab88 (diff)
downloadminetest-59911761ef529f118e7ba697d4f5983d43dbb383.tar.gz
minetest-59911761ef529f118e7ba697d4f5983d43dbb383.tar.bz2
minetest-59911761ef529f118e7ba697d4f5983d43dbb383.zip
Sneak glitch: Detect ledge for 2-node climb-up
Re-creates the old sneak-jump behaviour in new code. Enabled by the 'sneak glitch' physics override. When a ledge is detected the jump speed modifier is set to the larger of 'physics override jump' and 1.3 to allow a 2-node climb-up. An unexpected side-effect is the simple sneak ladder working smoothly.
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r--src/localplayer.cpp47
1 files changed, 43 insertions, 4 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 4bf3012dd..9dc3bf5aa 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -70,6 +70,7 @@ LocalPlayer::LocalPlayer(Client *client, const char *name):
m_sneak_node_exists(false),
m_need_to_get_new_sneak_node(true),
m_sneak_ladder_detected(false),
+ m_ledge_detected(false),
m_old_node_below(32767,32767,32767),
m_old_node_below_type("air"),
m_can_jump(false),
@@ -149,6 +150,29 @@ static bool detectSneakLadder(Map *map, INodeDefManager *nodemgr, v3s16 pos)
return false;
}
+static bool detectLedge(Map *map, INodeDefManager *nodemgr, v3s16 pos)
+{
+ bool is_valid_position;
+ MapNode node;
+ // X/Z vectors for 4 neighboring nodes
+ static const v2s16 vecs[] = {v2s16(-1, 0), v2s16(1, 0), v2s16(0, -1), v2s16(0, 1)};
+
+ for (u16 i = 0; i < ARRLEN(vecs); i++) {
+ const v2s16 vec = vecs[i];
+
+ node = GETNODE(map, pos, vec, 1, &is_valid_position);
+ if (is_valid_position && nodemgr->get(node).walkable) {
+ // Ledge exists
+ node = GETNODE(map, pos, vec, 2, &is_valid_position);
+ if (is_valid_position && !nodemgr->get(node).walkable)
+ // Space above ledge exists
+ return true;
+ }
+ }
+
+ return false;
+}
+
#undef GETNODE
void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
@@ -410,6 +434,13 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
}
/*
+ If 'sneak glitch' enabled detect ledge for old sneak-jump
+ behaviour of climbing onto a ledge 2 nodes up.
+ */
+ if (physics_override_sneak_glitch && control.sneak && control.jump)
+ m_ledge_detected = detectLedge(map, nodemgr, floatToInt(position, BS));
+
+ /*
Set new position
*/
setPosition(position);
@@ -648,10 +679,18 @@ void LocalPlayer::applyControl(float dtime)
at its starting value
*/
v3f speedJ = getSpeed();
- if(speedJ.Y >= -0.5 * BS)
- {
- speedJ.Y = movement_speed_jump * physics_override_jump;
- setSpeed(speedJ);
+ if(speedJ.Y >= -0.5 * BS) {
+ if (m_ledge_detected) {
+ // Limit jump speed to a minimum that allows
+ // jumping up onto a ledge 2 nodes up.
+ speedJ.Y = movement_speed_jump *
+ MYMAX(physics_override_jump, 1.3f);
+ setSpeed(speedJ);
+ m_ledge_detected = false;
+ } else {
+ speedJ.Y = movement_speed_jump * physics_override_jump;
+ setSpeed(speedJ);
+ }
MtEvent *e = new SimpleTriggerEvent("PlayerJump");
m_client->event()->put(e);