浏览代码

diagonal movement testing stuff

Michael Panzlaff 6 年前
父节点
当前提交
cd94fb9a96
共有 4 个文件被更改,包括 323 次插入57 次删除
  1. 38
    1
      patches/overworlds/npc_walk.asm
  2. 2
    2
      src/overworld/dynamic_overworld.c
  3. 167
    10
      src/player_interaction/npc_walk.c
  4. 116
    44
      src/player_interaction/sideway_stair.c

+ 38
- 1
patches/overworlds/npc_walk.asm 查看文件

@@ -30,4 +30,41 @@ bxr4_npc_walk:
30 30
 .org 0x080BD308
31 31
     ldr r1, =npc_bike_hook|1
32 32
     bx r1
33
-.pool
33
+.pool
34
+
35
+.org 0x08068A8C
36
+    ldr r2, =little_steps_single_hook|1
37
+    bx r2
38
+.pool
39
+
40
+.org 0x08068AAC
41
+    ldr r2, =little_steps_double_hook|1
42
+    bx r2
43
+.pool
44
+
45
+.org 0x08068AD0
46
+    ldr r2, =little_steps_triple_hook|1
47
+    bx r2
48
+.pool
49
+
50
+.org 0x08068AF8
51
+    ldr r2, =little_steps_quad_hook|1
52
+    bx r2
53
+.pool
54
+
55
+.org 0x08068B1C
56
+    ldr r2, =little_steps_octa_hook|1
57
+    bx r2
58
+.pool
59
+
60
+
61
+
62
+.org 0x08063A40
63
+.word tile_movement_dirs
64
+
65
+.org 0x08063A68
66
+.word tile_movement_dirs
67
+
68
+.org 0x08063AD0
69
+.word tile_movement_dirs
70
+

+ 2
- 2
src/overworld/dynamic_overworld.c 查看文件

@@ -84,7 +84,7 @@ void npc_dynamic_reset() {
84 84
 void npc_dynamic_remove_entry(u8 id) {
85 85
     if (stored_palettes[id].reference_count > 0) {
86 86
         stored_palettes[id].reference_count--;
87
-        dprintf("npc_dynamic: removed entry #%d\n", id);
87
+        //dprintf("npc_dynamic: removed entry #%d\n", id);
88 88
         if (stored_palettes[id].reference_count == 0)
89 89
             stored_palettes[id].tag = 0;
90 90
     }
@@ -200,5 +200,5 @@ void npc_delete_obj_and_free_tiles_for_npc_hack(struct NpcState *state) {
200 200
     u8 pal_num = objects[state->oam_id].final_oam.palette_num;
201 201
     obj_delete_and_free(&objects[state->oam_id]);
202 202
     npc_dynamic_remove_entry(pal_num);
203
-    dprintf("deleted npc state at x: %d y: %d\n", state->to.x, state->to.y);
203
+    //dprintf("deleted npc state at x: %d y: %d\n", state->to.x, state->to.y);
204 204
 }

+ 167
- 10
src/player_interaction/npc_walk.c 查看文件

@@ -2,12 +2,40 @@
2 2
 
3 3
 typedef bool (*MoveCallback)(struct NpcState* npc, struct Object* obj);
4 4
 
5
+const struct Coords16 tile_movement_dirs[17] = {
6
+    { 0, 0 },   // [0] nothing
7
+
8
+    { 0, 1 },   // [1] down
9
+    { 0, -1 },  // [2] up
10
+    { -1, 0 },  // [3] left
11
+    { 1, 0 },   // [4] right
12
+
13
+    { -1, 1 },  // [5] down left
14
+    { 1, 1 },   // [6] down right
15
+    { -1, -1 }, // [7] up left
16
+    { 1, -1 },  // [8] up right
17
+
18
+    { -1, 0 },  // [9] down left (enter)
19
+    { 1, 0 },   // [10] down right (enter)
20
+    { -1, -1 }, // [11] up left (enter)
21
+    { 1, -1 },  // [12] up right (enter)
22
+
23
+    { -1, 1 },  // [13] down left (leave)
24
+    { 1, 1 },   // [14] down right (leave)
25
+    { -1, 0 },  // [15] up left (leave)
26
+    { 1, 0 },   // [16] up right (leave)
27
+};
28
+
5 29
 void npc_walk_modify_diagonal(struct NpcState* npc, struct Object* obj, u8 direction) {
6
-    npc->to.x = walking_directions[direction].x + npc->from.x;
7
-    npc->to.y = walking_directions[direction].y + npc->from.y;
30
+    npc->to.x = tile_movement_dirs[direction].x + npc->from.x;
31
+    npc->to.y = tile_movement_dirs[direction].y + npc->from.y;
32
+    //dprintf("npc->from.x=%d npc->from.y=%d direction=%d\n", npc->from.x, npc->from.y, direction);
33
+    //dprintf("npc->to.x=%d npc->to.y=%d\n", npc->to.x, npc->to.y);
8 34
     obj->priv[3] = direction;
9 35
 }
10 36
 
37
+// stairs to stairs
38
+
11 39
 bool npc_walk_mdia_ul(struct NpcState* npc, struct Object* obj) {
12 40
     npc_run_any(npc, obj, 3, 0);
13 41
     npc_walk_modify_diagonal(npc,obj,7);
@@ -22,7 +50,7 @@ bool npc_walk_mdia_ur(struct NpcState* npc, struct Object* obj) {
22 50
 
23 51
 bool npc_walk_mdia_dl(struct NpcState* npc, struct Object* obj) {
24 52
     npc_run_any(npc, obj, 3, 0);
25
-    npc_update_direction(npc, 3);
53
+    //npc_update_direction(npc, 3);
26 54
     npc_walk_modify_diagonal(npc,obj,5);
27 55
     return npc_run_is_finished(npc,obj);
28 56
 }
@@ -33,13 +61,78 @@ bool npc_walk_mdia_dr(struct NpcState* npc, struct Object* obj) {
33 61
     return npc_run_is_finished(npc,obj);
34 62
 }
35 63
 
36
-MoveCallback npc_walk_anim_mdia_ul[3] = {npc_walk_mdia_ul, npc_run_is_finished, npc_move_end};
37
-MoveCallback npc_walk_anim_mdia_ur[3] = {npc_walk_mdia_ur, npc_run_is_finished, npc_move_end};
38
-MoveCallback npc_walk_anim_mdia_dl[3] = {npc_walk_mdia_dl, npc_run_is_finished, npc_move_end};
39
-MoveCallback npc_walk_anim_mdia_dr[3] = {npc_walk_mdia_dr, npc_run_is_finished, npc_move_end};
64
+// enter stairs
65
+
66
+bool npc_walk_mdia_ul_enter(struct NpcState* npc, struct Object* obj) {
67
+    npc_run_any(npc, obj, 3, 0);
68
+    npc_walk_modify_diagonal(npc,obj,7+4);
69
+    return npc_run_is_finished(npc,obj);
70
+}
71
+
72
+bool npc_walk_mdia_ur_enter(struct NpcState* npc, struct Object* obj) {
73
+    npc_run_any(npc, obj, 4, 0);
74
+    npc_walk_modify_diagonal(npc,obj,8+4);
75
+    return npc_run_is_finished(npc,obj);
76
+}
77
+
78
+bool npc_walk_mdia_dl_enter(struct NpcState* npc, struct Object* obj) {
79
+    npc_run_any(npc, obj, 3, 0);
80
+    //npc_update_direction(npc, 3);
81
+    npc_walk_modify_diagonal(npc,obj,5+4);
82
+    return npc_run_is_finished(npc,obj);
83
+}
84
+
85
+bool npc_walk_mdia_dr_enter(struct NpcState* npc, struct Object* obj) {
86
+    npc_run_any(npc, obj, 4, 0);
87
+    npc_walk_modify_diagonal(npc,obj,6+4);
88
+    return npc_run_is_finished(npc,obj);
89
+}
90
+
91
+// leave stairs
92
+
93
+bool npc_walk_mdia_ul_leave(struct NpcState* npc, struct Object* obj) {
94
+    npc_run_any(npc, obj, 3, 0);
95
+    npc_walk_modify_diagonal(npc,obj,7+8);
96
+    return npc_run_is_finished(npc,obj);
97
+}
98
+
99
+bool npc_walk_mdia_ur_leave(struct NpcState* npc, struct Object* obj) {
100
+    npc_run_any(npc, obj, 4, 0);
101
+    npc_walk_modify_diagonal(npc,obj,8+8);
102
+    return npc_run_is_finished(npc,obj);
103
+}
104
+
105
+bool npc_walk_mdia_dl_leave(struct NpcState* npc, struct Object* obj) {
106
+    npc_run_any(npc, obj, 3, 0);
107
+    //npc_update_direction(npc, 3);
108
+    npc_walk_modify_diagonal(npc,obj,5+8);
109
+    return npc_run_is_finished(npc,obj);
110
+}
111
+
112
+bool npc_walk_mdia_dr_leave(struct NpcState* npc, struct Object* obj) {
113
+    npc_run_any(npc, obj, 4, 0);
114
+    npc_walk_modify_diagonal(npc,obj,6+8);
115
+    return npc_run_is_finished(npc,obj);
116
+}
117
+
118
+static const MoveCallback npc_walk_anim_mdia_ul[3] = {npc_walk_mdia_ul, npc_run_is_finished, npc_move_end};
119
+static const MoveCallback npc_walk_anim_mdia_ur[3] = {npc_walk_mdia_ur, npc_run_is_finished, npc_move_end};
120
+static const MoveCallback npc_walk_anim_mdia_dl[3] = {npc_walk_mdia_dl, npc_run_is_finished, npc_move_end};
121
+static const MoveCallback npc_walk_anim_mdia_dr[3] = {npc_walk_mdia_dr, npc_run_is_finished, npc_move_end};
122
+
123
+static const MoveCallback npc_walk_anim_mdia_ul_enter[3] = {npc_walk_mdia_ul_enter, npc_run_is_finished, npc_move_end};
124
+static const MoveCallback npc_walk_anim_mdia_ur_enter[3] = {npc_walk_mdia_ur_enter, npc_run_is_finished, npc_move_end};
125
+static const MoveCallback npc_walk_anim_mdia_dl_enter[3] = {npc_walk_mdia_dl_enter, npc_run_is_finished, npc_move_end};
126
+static const MoveCallback npc_walk_anim_mdia_dr_enter[3] = {npc_walk_mdia_dr_enter, npc_run_is_finished, npc_move_end};
127
+
128
+static const MoveCallback npc_walk_anim_mdia_ul_leave[3] = {npc_walk_mdia_ul_leave, npc_run_is_finished, npc_move_end};
129
+static const MoveCallback npc_walk_anim_mdia_ur_leave[3] = {npc_walk_mdia_ur_leave, npc_run_is_finished, npc_move_end};
130
+static const MoveCallback npc_walk_anim_mdia_dl_leave[3] = {npc_walk_mdia_dl_leave, npc_run_is_finished, npc_move_end};
131
+static const MoveCallback npc_walk_anim_mdia_dr_leave[3] = {npc_walk_mdia_dr_leave, npc_run_is_finished, npc_move_end};
132
+
40 133
 
41 134
 /* first new is 170 */
42
-const MoveCallback* npc_walk_animations[174] =
135
+const MoveCallback* npc_walk_animations[182] =
43 136
 {
44 137
     (MoveCallback*)0x83a6864u, (MoveCallback*)0x83a686cu, (MoveCallback*)0x83a6874u, (MoveCallback*)0x83a687cu, 
45 138
     (MoveCallback*)0x83a6a30u, (MoveCallback*)0x83a6a38u, (MoveCallback*)0x83a6a40u, (MoveCallback*)0x83a6a48u, 
@@ -84,5 +177,69 @@ const MoveCallback* npc_walk_animations[174] =
84 177
     (MoveCallback*)0x83a6a00u, (MoveCallback*)0x83a6a0cu, (MoveCallback*)0x83a6a18u, (MoveCallback*)0x83a6a24u, 
85 178
     (MoveCallback*)0x83a700cu, (MoveCallback*)0x83a7018u, (MoveCallback*)0x83a6c3cu, (MoveCallback*)0x83a6c48u, 
86 179
     (MoveCallback*)0x83a6c54u, (MoveCallback*)0x83A6C60u, npc_walk_anim_mdia_ul, npc_walk_anim_mdia_ur,
87
-    npc_walk_anim_mdia_dl, npc_walk_anim_mdia_dr
88
-};
180
+    npc_walk_anim_mdia_dl, npc_walk_anim_mdia_dr, npc_walk_anim_mdia_ul_enter, npc_walk_anim_mdia_ur_enter,
181
+    npc_walk_anim_mdia_dl_enter, npc_walk_anim_mdia_dr_enter, npc_walk_anim_mdia_ul_leave, npc_walk_anim_mdia_ur_leave,
182
+    npc_walk_anim_mdia_dl_leave, npc_walk_anim_mdia_dr_leave,
183
+};
184
+
185
+static const struct Coords16 enter_leave_table[4] = {
186
+    { -1, 0 },
187
+    { 1, 0 },
188
+    { -1, 0 },
189
+    { 1, 0 },
190
+};
191
+
192
+static inline void little_steps_var(struct Object *obj, u16 movement, int mult) {
193
+    if (movement <= 8) {
194
+        // normal
195
+        obj->pos1.x += tile_movement_dirs[movement].x * mult;
196
+        obj->pos1.y += tile_movement_dirs[movement].y * mult;
197
+    } else if (movement <= 12) {
198
+        dprintf("--------------\n");
199
+        dprintf("animation phase: %d\n", obj->priv[5]);
200
+        dprintf("pos2.x=%d pos2.y=%d\n", obj->pos2.x, obj->pos2.y);
201
+        dprintf("OLD: x=%d y=%d\n", obj->pos1.x, obj->pos1.y);
202
+        // enter diagonal
203
+        if (obj->priv[5] < 8) {
204
+            obj->pos1.x += enter_leave_table[movement - 9].x * mult;
205
+            obj->pos1.y += enter_leave_table[movement - 9].y * mult;
206
+        } else {
207
+            obj->pos1.x += tile_movement_dirs[movement - 4].x * mult;
208
+            obj->pos1.y += tile_movement_dirs[movement - 4].y * mult;
209
+        }
210
+        dprintf("NEW: x=%d y=%d\n", obj->pos1.x, obj->pos1.y);
211
+    } else {
212
+        dprintf("--------------\n");
213
+        dprintf("animation phase: %d\n", obj->priv[5]);
214
+        dprintf("pos2.x=%d pos2.y=%d\n", obj->pos2.x, obj->pos2.y);
215
+        dprintf("OLD: x=%d y=%d\n", obj->pos1.x, obj->pos1.y);
216
+        if (obj->priv[5] < 8) {
217
+            obj->pos1.x += tile_movement_dirs[movement - 8].x * mult;
218
+            obj->pos1.y += tile_movement_dirs[movement - 8].y * mult;
219
+        } else {
220
+            obj->pos1.x += enter_leave_table[movement - 13].x * mult;
221
+            obj->pos1.y += enter_leave_table[movement - 13].y * mult;
222
+        }
223
+        dprintf("NEW: x=%d y=%d\n", obj->pos1.x, obj->pos1.y);
224
+    }
225
+}
226
+
227
+void little_steps_single_hook(struct Object *obj, u16 movement) {
228
+    little_steps_var(obj, movement, 1);
229
+}
230
+
231
+void little_steps_double_hook(struct Object *obj, u16 movement) {
232
+    little_steps_var(obj, movement, 2);
233
+}
234
+
235
+void little_steps_triple_hook(struct Object *obj, u16 movement) {
236
+    little_steps_var(obj, movement, 3);
237
+}
238
+
239
+void little_steps_quad_hook(struct Object *obj, u16 movement) {
240
+    little_steps_var(obj, movement, 4);
241
+}
242
+
243
+void little_steps_octa_hook(struct Object *obj, u16 movement) {
244
+    little_steps_var(obj, movement, 8);
245
+}

+ 116
- 44
src/player_interaction/sideway_stair.c 查看文件

@@ -5,10 +5,25 @@
5 5
 #define BLOCK_STATE_SIDEWAY_NE 0x81
6 6
 #define BLOCK_STATE_SIDEWAY_SW 0x82
7 7
 #define BLOCK_STATE_SIDEWAY_SE 0x83
8
+
9
+#define BLOCK_STATE_SIDEWAY_NW_ENTER 0x84
10
+#define BLOCK_STATE_SIDEWAY_NE_ENTER 0x85
11
+#define BLOCK_STATE_SIDEWAY_SW_ENTER 0x86
12
+#define BLOCK_STATE_SIDEWAY_SE_ENTER 0x87
13
+
14
+#define BLOCK_STATE_SIDEWAY_NW_LEAVE 0x88
15
+#define BLOCK_STATE_SIDEWAY_NE_LEAVE 0x89
16
+#define BLOCK_STATE_SIDEWAY_SW_LEAVE 0x8A
17
+#define BLOCK_STATE_SIDEWAY_SE_LEAVE 0x8B
18
+
8 19
 #define BEHAVIOR_STAIR_WEST 0xE0
9 20
 #define BEHAVIOR_STAIR_EAST 0xE1
10 21
 
11
-const u8 diagonal_animations[4] = {170,171,172,173};
22
+const u8 diagonal_animations[12] = {
23
+    170,171,172,173,
24
+    174,175,176,177,
25
+    178,179,180,181,
26
+};
12 27
 
13 28
 bool npc_sideway_try_walking(u8 block_state)
14 29
 {
@@ -20,62 +35,119 @@ bool npc_sideway_try_walking(u8 block_state)
20 35
     return false;
21 36
 }
22 37
 
38
+static void invalid_stair_layout(void) {
39
+    dprintf("invalid stair layout! please fix map data!\n");
40
+    while (1);
41
+}
42
+
23 43
 u8 npc_get_walkable_status(struct NpcState *npc, u16 x, u16 y, enum Direction direction, u8 roleTo) {
24 44
     dprintf("get_walkable: %d, %d, %d, %d\n", x,y, direction, roleTo);
25
-    u8 block = npc_block_way(npc, x,y,direction);
26 45
 
27 46
     //check for diagonal stair stuff here
28
-    struct NpcState dummyNpc;
29
-    memcpy(&dummyNpc, npc, sizeof(struct NpcState));
47
+    struct NpcState dummyNpc = *npc;
48
+
49
+    int fx = npc->from.x, fy = npc->from.y;
50
+
51
+    int roleFrom = cur_mapdata_block_role_at(fx, fy);
30 52
 
31
-    u16 roleFrom = cur_mapdata_block_role_at(npc->from.x, npc->from.y);
32 53
     if (direction == WEST) {
33
-        dprintf("WEST with from: %d\n", roleFrom);
34
-        if(roleFrom == BEHAVIOR_STAIR_WEST) {
35
-            
36
-            //walk up the stair to the west
37
-            dummyNpc.from.y--;
38
-            dummyNpc.to.y--;
39
-            u8 altBlocked = npc_block_way(&dummyNpc, x,y-1, direction);
40
-            dprintf("trying NW: %d\n", altBlocked);
41
-            u8 roleStairTo = cur_mapdata_block_role_at(x, y-1);
42
-            if(roleStairTo == BEHAVIOR_STAIR_WEST)
54
+        if (roleFrom == BEHAVIOR_STAIR_WEST) {
55
+            int roleTo = cur_mapdata_block_role_at(fx - 1, fy);
56
+            if (roleTo == BEHAVIOR_STAIR_WEST) {
57
+                dprintf("walk north west / up left\n");
58
+                dummyNpc.from.y--;
59
+                dummyNpc.to.y--;
60
+                int altBlocked = npc_block_way(&dummyNpc, fx - 1, fy - 1, direction);
43 61
                 return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NW : altBlocked;
44
-        }
45
-        else if(roleFrom == BEHAVIOR_STAIR_EAST){
46
-            //walk down the stair to the west
47
-            dummyNpc.from.y++;
48
-            dummyNpc.to.y++;
49
-            u8 altBlocked = npc_block_way(&dummyNpc, x,y+1, direction);
50
-            dprintf("trying SW: %d\n", altBlocked);
51
-            u8 roleStairTo = cur_mapdata_block_role_at(x, y+1);
52
-            if(roleStairTo == BEHAVIOR_STAIR_EAST)
62
+            } else if (roleTo == BEHAVIOR_STAIR_EAST) {
63
+                invalid_stair_layout();
64
+            } else {
65
+                dprintf("leave north west / up left\n");
66
+                int altBlocked = npc_block_way(&dummyNpc, fx - 1, fy, direction);
67
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NW_LEAVE : altBlocked;
68
+            }
69
+        } else if (roleFrom == BEHAVIOR_STAIR_EAST) {
70
+            int roleTo = cur_mapdata_block_role_at(fx - 1, fy + 1);
71
+            if (roleTo == BEHAVIOR_STAIR_WEST) {
72
+                invalid_stair_layout();
73
+            } else if (roleTo == BEHAVIOR_STAIR_EAST) {
74
+                dprintf("walk south west / down left\n");
75
+                dummyNpc.from.y++;
76
+                dummyNpc.to.y++;
77
+                int altBlocked = npc_block_way(&dummyNpc, fx - 1, fy + 1, direction);
53 78
                 return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_SW : altBlocked;
79
+            } else {
80
+                dprintf("leave south west / down left\n");
81
+                dummyNpc.from.y++;
82
+                dummyNpc.to.y++;
83
+                int altBlocked = npc_block_way(&dummyNpc, fx - 1, fy + 1, direction);
84
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_SW_LEAVE : altBlocked;
85
+            }
86
+        } else {
87
+            int roleTo = cur_mapdata_block_role_at(fx - 1, fy);
88
+            if (roleTo == BEHAVIOR_STAIR_WEST) {
89
+                dprintf("enter north west / up left\n");
90
+                dummyNpc.from.y--;
91
+                dummyNpc.to.y--;
92
+                int altBlocked = npc_block_way(&dummyNpc, fx - 1, fy - 1, direction);
93
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NW_ENTER : altBlocked;
94
+            } else if (roleTo == BEHAVIOR_STAIR_EAST) {
95
+                dprintf("enter south west / down left\n");
96
+                int altBlocked = npc_block_way(&dummyNpc, fx - 1, fy, direction);
97
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_SW_ENTER : altBlocked;
98
+            }
54 99
         }
55
-    } else if(direction == EAST) {
56
-        if(roleFrom == BEHAVIOR_STAIR_EAST) {
57
-            //walk up the stair to the east
58
-            dummyNpc.from.y--;
59
-            dummyNpc.to.y--;
60
-            u8 altBlocked = npc_block_way(&dummyNpc, x,y-1, direction);
61
-            dprintf("trying NE: %d\n", altBlocked);
62
-            u8 roleStairTo = cur_mapdata_block_role_at(x, y-1);
63
-            dprintf("x: %d, y: %d, roleStairTo: %d\n",x, dummyNpc.to.y, roleStairTo);
64
-            if(roleStairTo == BEHAVIOR_STAIR_EAST)
65
-                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NE : altBlocked;
66
-
67
-        } else if (roleFrom == BEHAVIOR_STAIR_WEST) {
68
-            //walk down the stair to the east
69
-            dummyNpc.from.y++;
70
-            dummyNpc.to.y++;
71
-            u8 altBlocked = npc_block_way(&dummyNpc, x,y+1, direction);
72
-            dprintf("trying SW: %d\n", altBlocked);
73
-            u8 roleStairTo = cur_mapdata_block_role_at(x, y+1);
74
-            if(roleStairTo == BEHAVIOR_STAIR_WEST)
100
+    } else if (direction == EAST) {
101
+        if (roleFrom == BEHAVIOR_STAIR_WEST) {
102
+            int roleTo = cur_mapdata_block_role_at(fx + 1, fy + 1);
103
+            if (roleTo == BEHAVIOR_STAIR_WEST) {
104
+                dprintf("walk south east / down right\n");
105
+                dummyNpc.from.y++;
106
+                dummyNpc.to.y++;
107
+                int altBlocked = npc_block_way(&dummyNpc, fx + 1, fy + 1, direction);
75 108
                 return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_SE : altBlocked;
109
+            } else if (roleTo == BEHAVIOR_STAIR_EAST) {
110
+                invalid_stair_layout();
111
+            } else {
112
+                dprintf("leave south east / down right\n");
113
+                dummyNpc.from.y++;
114
+                dummyNpc.to.y++;
115
+                int altBlocked = npc_block_way(&dummyNpc, fx + 1, fy + 1, direction);
116
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_SE_LEAVE : altBlocked;
117
+            }
118
+        } else if (roleFrom == BEHAVIOR_STAIR_EAST) {
119
+            int roleTo = cur_mapdata_block_role_at(fx + 1, fy);
120
+            if (roleTo == BEHAVIOR_STAIR_WEST) {
121
+                invalid_stair_layout();
122
+            } else if (roleTo == BEHAVIOR_STAIR_EAST) {
123
+                dprintf("walk north east / up right\n");
124
+                dummyNpc.from.y--;
125
+                dummyNpc.to.y--;
126
+                int altBlocked = npc_block_way(&dummyNpc, fx + 1, fy - 1, direction);
127
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NE : altBlocked;
128
+            } else {
129
+                dprintf("leave north east / up right\n");
130
+                int altBlocked = npc_block_way(&dummyNpc, fx + 1, fy, direction);
131
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NE_LEAVE : altBlocked;
132
+            }
133
+        } else {
134
+            int roleTo = cur_mapdata_block_role_at(fx + 1, fy);
135
+            if (roleTo == BEHAVIOR_STAIR_WEST) {
136
+                dprintf("enter south east / down right\n");
137
+                int altBlocked = npc_block_way(&dummyNpc, fx + 1, fy, direction);
138
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_SE_ENTER : altBlocked;
139
+            } else if (roleTo == BEHAVIOR_STAIR_EAST) {
140
+                dprintf("enter north east / up right\n");
141
+                dummyNpc.from.y--;
142
+                dummyNpc.to.y--;
143
+                int altBlocked = npc_block_way(&dummyNpc, fx + 1, fy - 1, direction);
144
+                return (altBlocked == 0) ? BLOCK_STATE_SIDEWAY_NE_ENTER : altBlocked;
145
+            }
76 146
         }
77 147
     }
78 148
 
149
+    u8 block = npc_block_way(npc, x,y,direction);
150
+
79 151
     //continue with game code
80 152
 
81 153
     if(block == 3 && npc_is_passable_maybe(x,y,direction))