@@ -77,25 +77,37 @@ 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+ /**
89+ * Door tile
90+ */
91+ #define TILE_DOOR tile_num(becky_door_obj)
92+ /**
93+ * Tile near basement entry door
94+ */
95+ #define TILE_NEAR_DOOR tile_num_in_direction(TILE_DOOR, DIRECTION_SE, 1)
96+ /**
97+ * Tile in basement entry room
98+ */
99+ #define TILE_NEAR_BASEMENT_ENTRY tile_num_in_direction(TILE_DOOR, DIRECTION_NW, 1)
93100
94101import variable becky_guard_obj;
95102import variable becky_door_guard_obj;
96103import variable becky_door_obj;
97104
98105variable the_door;
106+ /**
107+ * Guard is in the process of closing the door
108+ */
109+ variable is_closing = false;
110+
99111
100112/* Imported variables from the Map scripts. These should only be
101113 pointers and variables that need not be saved. If a variable
@@ -107,6 +119,23 @@ procedure start begin
107119 becky_door_guard_obj := self_obj;
108120end
109121
122+ /**
123+ * obj_can_see_obj doesn't work from home tile so we also check distance.
124+ * @ret {bool} True if the guard "sees" door open, False otherwise.
125+ */
126+ procedure see_door_open begin
127+ variable door_is_open = false;
128+ if (becky_door_obj != 0) then begin
129+ if (obj_is_open(becky_door_obj)
130+ and (obj_can_see_obj(self_obj, becky_door_obj) or (tile_distance_objs(self_obj, becky_door_obj) < 3))
131+ )
132+ then begin
133+ door_is_open := true;
134+ end
135+ end
136+ return door_is_open;
137+ end
138+
110139procedure timed_event_p_proc begin
111140 if (fixed_param == timed_event_door_tamper) then begin
112141 call Node003;
@@ -144,20 +173,54 @@ procedure map_exit_p_proc begin
144173end
145174
146175procedure critter_p_proc begin
176+ variable i_see_open_door = see_door_open;
177+ // Guard closed the door, can walk back
178+ if is_closing and (not obj_is_open(becky_door_obj)) then begin
179+ is_closing = false;
180+ end
181+
182+ // P1: attack
147183 if (self_can_see_dude) then begin
148- check_door_open;
149- if ((hostile) or (the_door)) then begin
184+ if (hostile or (i_see_open_door and (tile_distance_objs(dude_obj, becky_door_obj) < 2))) then begin
150185 self_attack_dude;
151- end set_becky_guard
186+ end
187+ end
188+
189+ // P2: attack if found in room
190+ if (self_tile == TILE_NEAR_BASEMENT_ENTRY) then begin
191+ if self_can_see_dude and (tile_distance_objs(self_obj, dude_obj) < 2) then begin
192+ // Remember that PC was in restricted area. Helps if PC ran downstairs.
193+ set_hostile;
194+ self_attack_dude;
195+ end else begin
196+ self_walk_to_tile(TILE_NEAR_DOOR);
197+ obj_close(becky_door_obj);
198+ // ^ Close does not happen immediately, so we reset is_closing higher up
199+ obj_lock(becky_door_obj);
200+ end
201+ return;
202+ end
203+
204+ // P3: close door
205+ if (i_see_open_door) then begin
206+ // Guard is in the process of closing the door, skip
207+ if is_closing then begin
208+ return;
209+ end
210+ // Noticed open door, run to check
211+ is_closing = true;
212+ floater(375);
213+ self_run_to_tile_force(TILE_NEAR_BASEMENT_ENTRY);
214+ return; // Next run will trigger attack or door close.
215+ end
216+
217+ // P4: watch PC
218+ if (self_can_see_dude) then begin
219+ set_becky_guard
152220 end else if (anim_busy(self_obj) == false) then begin
221+ // P5: Normal walking around
153222 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
223+ if (self_tile != local_var(LVAR_Home_Tile)) then begin
161224 self_walk_to_tile(local_var(LVAR_Home_Tile));
162225 end else if (self_cur_rot != local_var(LVAR_Home_Rotation)) then begin
163226 self_rotate(local_var(LVAR_Home_Rotation));
0 commit comments