@@ -77,25 +77,36 @@ procedure Node005;
7777 ndebug("guard post state == "+x); \
7878 set_local_var(LVAR_Post_State, x)
7979
80- #define check_door_open the_door := false; \
81- if (becky_door_obj != 0) then \
82- if ((obj_is_open(becky_door_obj)) and (obj_can_see_obj(self_obj, becky_door_obj))) then \
83- the_door := true
84-
8580#define wander_tile (17267)
8681
87- #define set_becky_guard \
88- if (becky_guard_obj == 0) then begin \
89- becky_guard_obj := self_obj; \
90- end else if (tile_distance_objs(self_obj, dude_obj) < tile_distance_objs(becky_guard_obj, dude_obj)) then begin \
91- becky_guard_obj := self_obj; \
92- end
82+ /** South East */
83+ #define DIRECTION_SE 2
84+ /** North West */
85+ #define DIRECTION_NW 5
86+
87+ /**
88+ * Tile near basement entry door
89+ */
90+ #define TILE_NEAR_DOOR tile_num_in_direction(tile_num(becky_door_obj), DIRECTION_SE, 1)
91+ /**
92+ * Door tile
93+ */
94+ #define TILE_DOOR tile_num(becky_door_obj)
95+ /**
96+ * Tile in basement entry room
97+ */
98+ #define TILE_NEAR_BASEMENT_ENTRY tile_num_in_direction(tile_num(becky_door_obj), DIRECTION_NW, 1)
9399
94100import variable becky_guard_obj;
95101import variable becky_door_guard_obj;
96102import variable becky_door_obj;
97103
98104variable the_door;
105+ /**
106+ * Guard is in the process of closing the door
107+ */
108+ variable is_closing = false;
109+
99110
100111/* Imported variables from the Map scripts. These should only be
101112 pointers and variables that need not be saved. If a variable
@@ -107,6 +118,23 @@ procedure start begin
107118 becky_door_guard_obj := self_obj;
108119end
109120
121+ /**
122+ * obj_can_see_obj doesn't work from home tile so we also check distance.
123+ * @ret {bool} True if the guard "sees" door open, False otherwise.
124+ */
125+ procedure see_door_open begin
126+ variable door_is_open = false;
127+ if (becky_door_obj != 0) then begin
128+ if (obj_is_open(becky_door_obj)
129+ and (obj_can_see_obj(self_obj, becky_door_obj) or (tile_distance_objs(self_obj, becky_door_obj) < 3))
130+ )
131+ then begin
132+ door_is_open := true;
133+ end
134+ end
135+ return door_is_open;
136+ end
137+
110138procedure timed_event_p_proc begin
111139 if (fixed_param == timed_event_door_tamper) then begin
112140 call Node003;
@@ -144,20 +172,54 @@ procedure map_exit_p_proc begin
144172end
145173
146174procedure critter_p_proc begin
175+ variable i_see_open_door = see_door_open;
176+ // Guard closed the door, can walk back
177+ if is_closing and (not obj_is_open(becky_door_obj)) then begin
178+ is_closing = false;
179+ end
180+
181+ // P1: attack
147182 if (self_can_see_dude) then begin
148- check_door_open;
149- if ((hostile) or (the_door)) then begin
183+ if (hostile or (i_see_open_door and (tile_distance_objs(dude_obj, becky_door_obj) < 2))) then begin
150184 self_attack_dude;
151- end set_becky_guard
185+ end
186+ end
187+
188+ // P2: attack if found in room
189+ if (self_tile == TILE_NEAR_BASEMENT_ENTRY) then begin
190+ if self_can_see_dude and (tile_distance_objs(self_obj, dude_obj) < 2) then begin
191+ // Remember that PC was in restricted area. Helps if PC ran downstairs.
192+ set_hostile;
193+ self_attack_dude;
194+ end else begin
195+ self_walk_to_tile(TILE_NEAR_DOOR);
196+ obj_close(becky_door_obj);
197+ // ^ Close does not happen immediately, so we reset is_closing higher up
198+ obj_lock(becky_door_obj);
199+ end
200+ return;
201+ end
202+
203+ // P3: close door
204+ if (i_see_open_door) then begin
205+ // Guard is in the process of closing the door, skip
206+ if is_closing then begin
207+ return;
208+ end
209+ // Noticed open door, run to check
210+ is_closing = true;
211+ floater(375);
212+ self_run_to_tile_force(TILE_NEAR_BASEMENT_ENTRY);
213+ return; // Next run will trigger attack or door close.
214+ end
215+
216+ // P4: watch PC
217+ if (self_can_see_dude) then begin
218+ set_becky_guard
152219 end else if (anim_busy(self_obj) == false) then begin
220+ // P5: Normal walking around
153221 if (post_state == post_state_done) then begin
154- check_door_open;
155- if (the_door) then begin
156- if (anim_busy(becky_door_obj) == false) then begin
157- use_obj_on_obj(self_obj, becky_door_obj);
158- display_mstr(375);
159- end
160- end else if (self_tile != local_var(LVAR_Home_Tile)) then begin
222+ if (self_tile != local_var(LVAR_Home_Tile)) then begin
161223 self_walk_to_tile(local_var(LVAR_Home_Tile));
162224 end else if (self_cur_rot != local_var(LVAR_Home_Rotation)) then begin
163225 self_rotate(local_var(LVAR_Home_Rotation));
0 commit comments