@@ -70,6 +70,7 @@ LocalPlayer::LocalPlayer(Client *client, const char *name):
70
70
m_sneak_node_exists(false ),
71
71
m_need_to_get_new_sneak_node(true ),
72
72
m_sneak_ladder_detected(false ),
73
+ m_ledge_detected(false ),
73
74
m_old_node_below(32767 ,32767 ,32767 ),
74
75
m_old_node_below_type(" air" ),
75
76
m_can_jump(false ),
@@ -149,6 +150,29 @@ static bool detectSneakLadder(Map *map, INodeDefManager *nodemgr, v3s16 pos)
149
150
return false ;
150
151
}
151
152
153
+ static bool detectLedge (Map *map, INodeDefManager *nodemgr, v3s16 pos)
154
+ {
155
+ bool is_valid_position;
156
+ MapNode node;
157
+ // X/Z vectors for 4 neighboring nodes
158
+ static const v2s16 vecs[] = {v2s16 (-1 , 0 ), v2s16 (1 , 0 ), v2s16 (0 , -1 ), v2s16 (0 , 1 )};
159
+
160
+ for (u16 i = 0 ; i < ARRLEN (vecs); i++) {
161
+ const v2s16 vec = vecs[i];
162
+
163
+ node = GETNODE (map, pos, vec, 1 , &is_valid_position);
164
+ if (is_valid_position && nodemgr->get (node).walkable ) {
165
+ // Ledge exists
166
+ node = GETNODE (map, pos, vec, 2 , &is_valid_position);
167
+ if (is_valid_position && !nodemgr->get (node).walkable )
168
+ // Space above ledge exists
169
+ return true ;
170
+ }
171
+ }
172
+
173
+ return false ;
174
+ }
175
+
152
176
#undef GETNODE
153
177
154
178
void LocalPlayer::move (f32 dtime, Environment *env, f32 pos_max_d,
@@ -409,6 +433,13 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
409
433
}
410
434
}
411
435
436
+ /*
437
+ If 'sneak glitch' enabled detect ledge for old sneak-jump
438
+ behaviour of climbing onto a ledge 2 nodes up.
439
+ */
440
+ if (physics_override_sneak_glitch && control.sneak && control.jump )
441
+ m_ledge_detected = detectLedge (map, nodemgr, floatToInt (position, BS));
442
+
412
443
/*
413
444
Set new position
414
445
*/
@@ -648,10 +679,18 @@ void LocalPlayer::applyControl(float dtime)
648
679
at its starting value
649
680
*/
650
681
v3f speedJ = getSpeed ();
651
- if (speedJ.Y >= -0.5 * BS)
652
- {
653
- speedJ.Y = movement_speed_jump * physics_override_jump;
654
- setSpeed (speedJ);
682
+ if (speedJ.Y >= -0.5 * BS) {
683
+ if (m_ledge_detected) {
684
+ // Limit jump speed to a minimum that allows
685
+ // jumping up onto a ledge 2 nodes up.
686
+ speedJ.Y = movement_speed_jump *
687
+ MYMAX (physics_override_jump, 1 .3f );
688
+ setSpeed (speedJ);
689
+ m_ledge_detected = false ;
690
+ } else {
691
+ speedJ.Y = movement_speed_jump * physics_override_jump;
692
+ setSpeed (speedJ);
693
+ }
655
694
656
695
MtEvent *e = new SimpleTriggerEvent (" PlayerJump" );
657
696
m_client->event ()->put (e);
0 commit comments