1 /*
2  *  Schedule.h - Schedules for characters.
3  *
4  *  Copyright (C) 2000-2013  The Exult Team
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef SCHEDULE_H
22 #define SCHEDULE_H  1
23 
24 #include "tiles.h"
25 #include "singles.h"
26 #include <memory>
27 #include <string>
28 #include <vector>
29 #include "ignore_unused_variable_warning.h"
30 
31 class Game_object;
32 class Actor;
33 class TileRect;
34 class Actor_action;
35 class Usecode_value;
36 
37 using Game_object_weak = std::weak_ptr<Game_object>;
38 using Game_object_vector = std::vector<Game_object *>;
39 
40 /*
41  *  A Schedule controls the NPC it is assigned to.
42  */
43 class Schedule : public Game_singletons {
44 protected:
45 	Actor *npc;         // Who this controls.
46 	Tile_coord blocked;     // Tile where actor was blocked.
47 	Tile_coord start_pos;	// When schedule created.
48 	short prev_type;        // Actor's previous schedule.
49 	int street_maintenance_failures;// # times failed to find path.
50 	long street_maintenance_time;   // Time (msecs) when last tried.
51 public:
52 	Schedule(Actor *n);
53 	virtual ~Schedule() = default;
get_prev_type()54 	int get_prev_type() const {
55 		return prev_type;
56 	}
set_blocked(Tile_coord const & b)57 	void set_blocked(Tile_coord const &b) {
58 		blocked = b;
59 	}
get_start_pos()60 	Tile_coord get_start_pos() const {
61 		return start_pos;
62 	}
63 	enum Schedule_types {
64 	    combat = 0, horiz_pace = 1,
65 	    vert_pace = 2,  talk = 3,
66 	    dance = 4,  eat = 5,
67 	    farm = 6,   tend_shop = 7,
68 	    miner = 8,  hound = 9,
69 	    stand = 10, loiter = 11,
70 	    wander = 12,    blacksmith = 13,
71 	    sleep = 14, wait = 15,
72 	    sit = 16,   graze = 17,
73 	    bake = 18,  sew = 19,
74 	    shy = 20,   lab = 21,
75 	    thief = 22, waiter = 23,
76 	    special = 24,   kid_games = 25,
77 	    eat_at_inn = 26, duel = 27,
78 	    preach = 28,    patrol = 29,
79 	    desk_work = 30, follow_avatar = 31,
80 	    // Our own:
81 	    walk_to_schedule = 32,
82 	    street_maintenance = 33,
83 	    arrest_avatar = 34,
84 	    first_scripted_schedule = 0x80
85 	};
86 	// Set actor to walk somewhere, then
87 	//   do something.
88 	static void set_action_sequence(Actor *actor, Tile_coord const &dest,
89 	                                Actor_action *when_there, bool from_off_screen = false,
90 	                                int delay = 0);
91 	static Game_object *set_procure_item_action(Actor *actor, Game_object *obj,
92 	        int dist, int shnum, int frnum);
93 	static bool set_pickup_item_action(Actor *actor, Game_object *obj,
94 	                                   int delay);
95 	static Game_object *find_nearest(Actor *actor, Game_object_vector &nearby);
96 	int try_street_maintenance();   // Handle street-lamps, shutters.
97 	virtual void now_what() = 0;    // Npc calls this when it's done
98 	//   with its last task.
99 	virtual void im_dormant();  // Npc calls this when it goes from
100 	//  being active to dormant.
ending(int newtype)101 	virtual void ending(int newtype) { // Switching to another schedule.
102 		ignore_unused_variable_warning(newtype);
103 	}
104 	virtual void set_weapon(bool removed = false) { // Set weapon info.
105 		ignore_unused_variable_warning(removed);
106 	}
107 	// Set where to sleep.
set_bed(Game_object * b)108 	virtual void set_bed(Game_object *b) {
109 		ignore_unused_variable_warning(b);
110 	}
111 	// For Usecode intrinsic.
112 	virtual int get_actual_type(Actor *npc) const;
113 	// Look for foes.
114 	bool seek_foes();
115 	bool try_proximity_usecode(int odds);
116 };
117 
118 /*
119  *	A schedule that creates objects that need to be cleaned up after.
120  */
121 class Schedule_with_objects : public Schedule {
122 	std::vector<Game_object_weak> created;	// Items we created.
123 	Game_object_weak current_item;		// One we're using/walking to.
124 protected:
get_current_item()125     Game_object *get_current_item() {
126 	  return current_item.lock().get();
127 	}
128 	void set_current_item(Game_object *obj);
129     int items_in_hand; 	  	// # NPC's desk items.
130 	void cleanup();				// Remove items we created.
131 public:
Schedule_with_objects(Actor * n)132 	Schedule_with_objects(Actor *n) : Schedule(n), items_in_hand(0) {
133 	}
134 	~Schedule_with_objects() override;
135 	void add_object(Game_object *obj);
136 	// Find desk or waiter items.
137 	virtual int find_items(Game_object_vector& vec, int dist) = 0;
138 	bool walk_to_random_item(int dist = 16);
139 	bool drop_item(Game_object *to_drop, Game_object *table);
140 };
141 
142 /*
143  *  Schedule is implemented as Usecode functions.
144  */
145 class Scripted_schedule : public Schedule {
146 	Usecode_value *inst;        // Usecode schedule instance.
147 	// Usecode function #'s:
148 	int now_what_id, im_dormant_id, ending_id, set_weapon_id, set_bed_id;
149 	void run(int id);
150 public:
151 	Scripted_schedule(Actor *n, int type);
152 	~Scripted_schedule() override;
now_what()153 	void now_what() override {
154 		run(now_what_id);
155 	}
im_dormant()156 	void im_dormant() override {
157 		run(im_dormant_id);
158 	}
ending(int newtype)159 	void ending(int newtype) override {
160 		ignore_unused_variable_warning(newtype);
161 		run(ending_id);
162 	}
163 	void set_weapon(bool removed = false) override {
164 		ignore_unused_variable_warning(removed);
165 		run(set_weapon_id);
166 	}
set_bed(Game_object * b)167 	void set_bed(Game_object *b) override {
168 		ignore_unused_variable_warning(b);
169 		run(set_bed_id);
170 	}
171 };
172 
173 /*
174  *  Street maintenance (turn lamps on/off).
175  */
176 class Street_maintenance_schedule : public Schedule {
177 	Game_object_weak obj;       // Lamp/shutters.
178 	int shapenum, framenum;     // Save original shapenum.
179 	Actor_action *paction;      // Path to follow to get there.
180 	Tile_coord oldloc;
181 public:
182 	Street_maintenance_schedule(Actor *n, Actor_action *p, Game_object *o);
183 	void now_what() override;
184 	// For Usecode intrinsic.
185 	int get_actual_type(Actor *npc) const override;
186 	void ending(int newtype) override;
187 };
188 
189 /*
190  *  For following the Avatar (by party members):
191  */
192 class Follow_avatar_schedule : public Schedule {
193 	unsigned long next_path_time;   // Next time we're allowed to use
194 	//   pathfinding to follow leader.
195 public:
Follow_avatar_schedule(Actor * n)196 	Follow_avatar_schedule(Actor *n) : Schedule(n), next_path_time(0)
197 	{  }
198 	void now_what() override;    // Now what should NPC do?
199 };
200 
201 /*
202  *  A 'do nothing' schedule.
203  */
204 class Wait_schedule : public Schedule {
205 public:
Wait_schedule(Actor * n)206 	Wait_schedule(Actor *n) : Schedule(n)
207 	{  }
208 	void now_what() override;    // Now what should NPC do?
209 };
210 
211 /*
212  *  A schedule for pacing between two obstacles:
213  */
214 class Pace_schedule : public Schedule {
215 	char which;     // 0 for north-south, 1 for east-west
216 	Tile_coord loc; // The starting position of the schedule
217 	int phase;      // Current phase
218 public:
Pace_schedule(Actor * n,char dir,Tile_coord const & pos)219 	Pace_schedule(Actor *n, char dir, Tile_coord const &pos)
220 		: Schedule(n), which(dir), loc(pos), phase(0)
221 	{  }
222 	// Create common schedules:
223 	static Pace_schedule *create_horiz(Actor *n);
224 	static Pace_schedule *create_vert(Actor *n);
225 	static void pace(Actor *npc, char &which, int &phase, Tile_coord &blocked, int delay);
226 	void now_what() override;    // Now what should NPC do?
227 };
228 
229 /*
230  *  A schedule for eating at an inn.
231  */
232 class Eat_at_inn_schedule : public Schedule {
233 	bool sitting_at_chair;
234 public:
Eat_at_inn_schedule(Actor * n)235 	Eat_at_inn_schedule(Actor *n) : Schedule(n), sitting_at_chair(false)
236 	{  }
237 	void now_what() override;    // Now what should NPC do?
238 	void ending(int new_type) override; // Switching to another schedule
239 	void im_dormant() override;  // Just went dormant.
240 };
241 
242 /*
243  *  A schedule for preaching.
244  */
245 class Preach_schedule : public Schedule {
246 	enum {
247 	    find_podium,
248 	    at_podium,
249 	    exhort,
250 	    visit,
251 	    talk_member,
252 	    find_icon,
253 	    pray
254 	} state;
255 public:
Preach_schedule(Actor * n)256 	Preach_schedule(Actor *n) : Schedule(n), state(find_podium)
257 	{  }
258 	void now_what() override;    // Now what should NPC do?
259 };
260 
261 /*
262  *  A schedule for patrolling along 'path' objects.
263  */
264 class Patrol_schedule : public Schedule {
265 	enum {PATH_SHAPE = 607};
266 	static int num_path_eggs;
267 	std::vector<Game_object *> paths; // Each 'path' object.
268 	int pathnum;            // # of next we're heading towards.
269 	int dir;                // 1 or -1;
270 	int state;              // The patrol state.
271 	Tile_coord center;      // For 'loiter' and 'pace' path eggs.
272 	char whichdir;          // For 'pace' path eggs.
273 	int phase;              // For 'pace' path eggs.
274 	int pace_count;         // For 'pace' path eggs.
275 	Game_object_weak hammer;    // For 'hammer' path eggs.
276 	Game_object_weak book;      // For 'read' path eggs.
277 	bool seek_combat;       // The NPC should seek enemies while patrolling.
278 	bool forever;           // If should keep executing last path egg.
279 public:
280 	Patrol_schedule(Actor *n);
281 	void now_what() override;    // Now what should NPC do?
282 	void ending(int new_type) override; // Switching to another schedule
283 };
284 
285 /*
286  *  Talk to avatar.
287  */
288 class Talk_schedule : public Schedule {
289 	int firstbark, lastbark;
290 	int eventid;
291 protected:
292 	int phase;          // 0=walk to Av., 1=talk, 2=done.
293 	Talk_schedule(Actor *n, int fb, int lb, int eid);
294 public:
295 	Talk_schedule(Actor *n);
296 	void now_what() override;    // Now what should NPC do?
297 };
298 
299 /*
300  *  Arrest avatar.
301  */
302 class Arrest_avatar_schedule : public Talk_schedule {
303 public:
304 	Arrest_avatar_schedule(Actor *n);
305 	// For Usecode intrinsic.
306 	int get_actual_type(Actor *npc) const override;
307 	void ending(int newtype) override;// Switching to another schedule.
308 };
309 
310 /*
311  *  Loiter within a rectangle.
312  */
313 class Loiter_schedule : public Schedule {
314 protected:
315 	Tile_coord center;      // Center of rectangle.
316 	int dist;           // Distance in tiles to roam in each
317 	//   dir.
318 public:
319 	Loiter_schedule(Actor *n, int d = 12);
320 	void now_what() override;    // Now what should NPC do?
321 };
322 
323 /*
324  *  Graze within a rectangle.
325  */
326 class Graze_schedule : public Loiter_schedule {
327 protected:
328 	int phase;
329 public:
Loiter_schedule(n,d)330 	Graze_schedule(Actor *n, int d = 12) : Loiter_schedule(n, d), phase(0) {  }
331 	void now_what() override;    // Now what should NPC do?
332 };
333 
334 /*
335  *  Kid games.
336  */
337 class Kid_games_schedule : public Loiter_schedule {
338 	std::vector<Actor *> kids;           // Other kids playing.
339 public:
Kid_games_schedule(Actor * n)340 	Kid_games_schedule(Actor *n) : Loiter_schedule(n, 10)
341 	{  }
342 	void now_what() override;    // Now what should NPC do?
343 };
344 
345 /*
346  *  Dance.
347  */
348 class Dance_schedule : public Loiter_schedule {
349 public:
Dance_schedule(Actor * n)350 	Dance_schedule(Actor *n) : Loiter_schedule(n, 4)
351 	{  }
352 	void now_what() override;    // Now what should NPC do?
353 };
354 
355 /*
356  *  Miner/farmer:
357  */
358 class Tool_schedule : public Loiter_schedule {
359 protected:
360 	int toolshape;          // Pick/scythe shape.
361 	Game_object_weak tool;
362 	void get_tool();
363 public:
Tool_schedule(Actor * n,int shnum)364 	Tool_schedule(Actor *n, int shnum) : Loiter_schedule(n, 12),
365 		toolshape(shnum)
366 	{  }
367 	void now_what() override = 0;    // Now what should NPC do?
368 	void ending(int newtype) override;// Switching to another schedule.
369 };
370 
371 /*
372  *  Farmer.
373  */
374 class Farmer_schedule : public Tool_schedule {
375 	Game_object_weak crop;
376 	int grow_cnt;
377 	enum {
378 	    start,
379 	    find_crop,
380 	    attack_crop,
381 	    crop_attacked,
382 	    wander
383 	} state;
384 public:
Farmer_schedule(Actor * n)385 	Farmer_schedule(Actor *n) : Tool_schedule(n, 618),
386 		grow_cnt(0), state(start)
387 	{  }
388 	void now_what() override;    // Now what should NPC do?
389 };
390 
391 /*
392  *  Miner.
393  */
394 class Miner_schedule : public Tool_schedule {
395 	Game_object_weak ore;
396 	enum {
397 	    find_ore,
398 	    attack_ore,
399 	    ore_attacked,
400 	    wander
401 	} state;
402 public:
Miner_schedule(Actor * n)403 	Miner_schedule(Actor *n) : Tool_schedule(n, 624), state(find_ore)
404 	{  }
405 	void now_what() override;    // Now what should NPC do?
406 };
407 
408 /*
409  *  Hound the Avatar.
410  */
411 class Hound_schedule : public Schedule {
412 public:
Hound_schedule(Actor * n)413 	Hound_schedule(Actor *n) : Schedule(n)
414 	{  }
415 	void now_what() override;    // Now what should NPC do?
416 };
417 
418 /*
419  *  Wander all over the place, using pathfinding.
420  */
421 class Wander_schedule : public Loiter_schedule {
422 public:
Wander_schedule(Actor * n)423 	Wander_schedule(Actor *n) : Loiter_schedule(n, 128)
424 	{  }
425 	void now_what() override;    // Now what should NPC do?
426 };
427 
428 /*
429  *  Sleep in a  bed.
430  */
431 class Sleep_schedule : public Schedule {
432 	Tile_coord floorloc;        // Where NPC was standing before.
433 	Game_object_weak bed;       // Bed being slept on, or 0.
434 	int state;
435 	int spread0, spread1;       // Range of bedspread frames.
436 	bool for_nap_time;
437 public:
438 	Sleep_schedule(Actor *n);
439 	void now_what() override;    // Now what should NPC do?
440 	void ending(int new_type) override;// Switching to another schedule.
441 	// Set where to sleep.
442 	void set_bed(Game_object *b) override;
443 	void im_dormant() override;  // Just went dormant.
444 	static bool is_bed_occupied(Game_object *bed, Actor *npc);
445 };
446 
447 /*
448  *  Sit in a chair.
449  */
450 class Sit_schedule : public Schedule {
451 	Game_object_weak chair;     // What to sit in.
452 	bool sat;           // True if we already sat down.
453 	bool did_barge_usecode;     // So we only call it once.
454 public:
455 	Sit_schedule(Actor *n, Game_object *ch = nullptr);
456 	void now_what() override;    // Now what should NPC do?
457 	void im_dormant() override;  // Just went dormant.
458 	static bool is_occupied(Game_object *chairobj, Actor *actor);
459 	static bool set_action(Actor *actor, Game_object *chairobj = nullptr,
460 	                       int delay = 0, Game_object **chair_found = nullptr);
461 };
462 
463 /*
464  *  Desk work - Just sit in front of desk.
465  */
466 class Desk_schedule : public Schedule_with_objects {
467 	Game_object_weak chair;     // What to sit in.
468 	Game_object_weak desk, table;
469 	std::vector<Game_object_weak> tables;	// Other tables to work at.
470 	enum {
471 	    desk_setup,
472 	    sit_at_desk,
473 	    get_desk_item,
474 	    picked_up_item,
475 	    work_at_table
476 	} state;
477 	int find_items(Game_object_vector& vec, int dist) override;
478 	void find_tables(int shapenum);
479 	bool walk_to_table();
480 public:
481 	Desk_schedule(Actor *n);
482 	void now_what() override;    // Now what should NPC do?
483 	void ending(int new_type) override;// Switching to another schedule.
484 	void im_dormant() override;  // Just went dormant.
485 };
486 
487 /*
488  *  Shy away from Avatar.
489  */
490 class Shy_schedule : public Schedule {
491 public:
Shy_schedule(Actor * n)492 	Shy_schedule(Actor *n) : Schedule(n)
493 	{  }
494 	void now_what() override;    // Now what should NPC do?
495 };
496 
497 /*
498  *  Lab work.
499  */
500 class Lab_schedule : public Schedule {
501 	std::vector<Game_object_weak> tables;
502 	Game_object_weak chair;     // Chair to sit in.
503 	Game_object_weak book;      // Book to read.
504 	Game_object_weak cauldron;
505 	Tile_coord spot_on_table;
506 	enum {
507 	    start,
508 	    walk_to_cauldron,
509 	    use_cauldron,
510 	    sit_down,
511 	    read_book,
512 	    stand_up,
513 	    walk_to_table,
514 	    use_potion
515 	} state;
516 	void init();
517 public:
518 	Lab_schedule(Actor *n);
519 	void now_what() override;    // Now what should NPC do?
520 };
521 
522 /*
523  *  Be a thief.
524  */
525 class Thief_schedule : public Schedule {
526 	unsigned long next_steal_time;  // Next time we can try to steal.
527 	void steal(Actor *from);
528 public:
Thief_schedule(Actor * n)529 	Thief_schedule(Actor *n) : Schedule(n), next_steal_time(0)
530 	{  }
531 	void now_what() override;
532 };
533 
534 /*
535  *  Wait tables.
536  */
537 class Waiter_schedule : public Schedule_with_objects {
538 	Tile_coord startpos;        // Starting position.
539 	Actor *customer;        // Current customer.
540 	Game_object_weak prep_table;    // Table we're working at.
541 	bool cooking;
542 	std::vector<Actor *> customers;  // List of customers.
543 	std::vector<Actor *> customers_ordered;  // Taken orders from these.
544 	std::vector<Game_object_weak > prep_tables; // Prep. tables.
545 	std::vector<Game_object_weak > counters;    // Places to hang out.
546 	std::vector<Game_object_weak > eating_tables; // Tables with chairs around them.
547 	std::vector<Game_object_weak > unattended_plates;
548 	enum {
549 	    waiter_setup,
550 	    get_customer,
551 	    get_order,
552 	    took_order,
553 	    give_plate,
554 	    prep_food,
555 	    bring_food,
556 	    serve_food,
557 	    served_food,
558 	    wait_at_counter,
559 	    get_waiter_item,
560 	    picked_up_item,
561 	    walk_to_cleanup_food,
562 	    cleanup_food
563 	} state;
564 	int find_items(Game_object_vector& vec, int dist) override;
565 	bool find_unattended_plate();
566 	bool find_customer();
567 	void find_tables(int shapenum, int dist, bool is_prep = false);
568 	void find_prep_tables();
569 	bool walk_to_customer(int min_delay = 0);
570 	bool walk_to_work_spot(bool counter);
walk_to_prep()571 	bool walk_to_prep() {
572 		return walk_to_work_spot(false);
573 	}
walk_to_counter()574 	bool walk_to_counter() {
575 		return walk_to_work_spot(true);
576 	}
577 	Game_object *create_customer_plate();
578 	Game_object *find_serving_spot(Tile_coord &spot);
579 public:
580 	Waiter_schedule(Actor *n);
581 	void now_what() override;    // Now what should NPC do?
582 	void ending(int new_type) override;// Switching to another schedule.
583 };
584 
585 /*
586  *  Sew/weave schedule.
587  */
588 class Sew_schedule : public Schedule {
589 	Game_object_weak bale;      // Bale of wool.
590 	Game_object_weak spinwheel;
591 	Game_object_weak chair;     // In front of spinning wheel.
592 	Game_object_weak spindle;       // Spindle of thread.
593 	Game_object_weak loom;
594 	Game_object_weak cloth;
595 	Game_object_weak work_table, wares_table;
596 	int sew_clothes_cnt;
597 	enum {
598 	    get_wool,
599 	    sit_at_wheel,
600 	    spin_wool,
601 	    get_thread,
602 	    weave_cloth,
603 	    get_cloth,
604 	    to_work_table,
605 	    set_to_sew,
606 	    sew_clothes,
607 	    get_clothes,
608 	    display_clothes,
609 	    done
610 	} state;
611 public:
612 	Sew_schedule(Actor *n);
613 	void now_what() override;    // Now what should NPC do?
614 	void ending(int new_type) override;// Switching to another schedule.
615 };
616 
617 /*
618  *  Bake schedule
619  */
620 class Bake_schedule : public Schedule {
621 	Game_object_weak oven;
622 	Game_object_weak worktable;
623 	Game_object_weak displaytable;
624 	Game_object_weak flourbag;
625 	Game_object_weak dough;
626 	Game_object_weak dough_in_oven;
627 	bool clearing;
628 	enum {
629 	    find_leftovers,     // Look for misplaced dough already made by this schedule
630 	    to_flour,           // Looks for flourbag and walks to it if found
631 	    get_flour,          // Bend over flourbag and change the frame to zero if nonzero
632 	    to_table,           // Walk over to worktable and create flour
633 	    make_dough,         // Changes flour to flat dough then dough ball
634 	    remove_from_oven,   // Changes dough in oven to food %7 and picks it up
635 	    display_wares,      // Walk to displaytable. Put food on it. If table full, go to
636 	    // clear_display which eventualy comes back here to place food
637 	    clear_display,      // Mark food for deletion by remove_food
638 	    remove_food,        // Delete food on display table one by one with a slight delay
639 	    get_dough,          // Walk to work table and pick up dough
640 	    put_in_oven         // Walk to oven and put dough on in.
641 	} state;
642 public:
643 	Bake_schedule(Actor *n);
644 	void now_what() override;
645 	void ending(int new_type) override;
646 };
647 
648 /*
649  *  Blacksmith schedule
650  */
651 class Forge_schedule : public Schedule {
652 	Game_object_weak tongs;
653 	Game_object_weak hammer;
654 	Game_object_weak blank;
655 	Game_object_weak firepit;
656 	Game_object_weak anvil;
657 	Game_object_weak trough;
658 	Game_object_weak bellows;
659 	enum {
660 	    put_sword_on_firepit,
661 	    use_bellows,
662 	    get_tongs,
663 	    sword_on_anvil,
664 	    get_hammer,
665 	    use_hammer,
666 	    walk_to_trough,
667 	    fill_trough,
668 	    get_tongs2,
669 	    use_trough,
670 	    done
671 	} state;
672 public:
673 	Forge_schedule(Actor *n);
674 	void now_what() override;    // Now what should NPC do?
675 	void ending(int new_type) override; // Switching to another schedule
676 };
677 
678 /*
679  *  Eat without a server
680  */
681 class Eat_schedule : public Schedule {
682 	Game_object_weak plate;
683 	enum {
684 	    eat,        // eat food and say food barks
685 	    find_plate, // make sure there is a plate, create one if not
686 	    serve_food  // put food on the plate
687 	} state;
688 public:
689 	Eat_schedule(Actor *n);
690 	void now_what() override;    // Now what should NPC do?
691 	void ending(int new_type) override; // Switching to another schedule
692 	void im_dormant() override;  // Just went dormant.
693 };
694 
695 /*
696  *  Walk to the destination for a new schedule.
697  */
698 class Walk_to_schedule : public Schedule {
699 	Tile_coord dest;        // Where we're going.
700 	int first_delay;        // Starting delay (1/1000's sec.)
701 	int new_schedule;       // Schedule to set when we get there.
702 	int retries;            // # failures at finding path.
703 	int legs;           // # times restarted walk.
704 	// Set to walk off screen.
705 	void walk_off_screen(TileRect &screen, Tile_coord &goal);
706 public:
707 	Walk_to_schedule(Actor *n, Tile_coord const &d, int new_sched,
708 	                 int delay = -1);
709 	void now_what() override;    // Now what should NPC do?
710 	void im_dormant() override;  // Just went dormant.
711 	// For Usecode intrinsic.
712 	int get_actual_type(Actor *npc) const override;
713 };
714 
715 /*
716  *  An NPC schedule change:
717  */
718 class Schedule_change {
719 	static std::vector<std::string> script_names; // For Scripted_schedule's.
720 	unsigned char time = 0;     // Time*3hours when this takes effect.
721 	unsigned char type = 0;     // Schedule_type value.
722 	unsigned char days = 0x7f;  // A bit for each day (0-6).  We don't
723 	//   yet use this.
724 	Tile_coord pos;         // Location.
725 public:
726 	static void clear();
get_script_names()727 	static std::vector<std::string> &get_script_names() {
728 		return script_names;
729 	}
730 	void set4(const unsigned char *ent);  // Create from 4-byte entry.
731 	void set8(const unsigned char *ent);  // Create from Exult entry (v. -1).
732 	void write8(unsigned char *ent) const;// Write out 8-byte Exult entry.
733 	void set(int ax, int ay, int az,
734 	         unsigned char stype, unsigned char stime);
get_type()735 	int get_type() const {
736 		return type;
737 	}
get_time()738 	int get_time() const {
739 		return time;
740 	}
get_pos()741 	Tile_coord get_pos() const {
742 		return pos;
743 	}
get_script_name(int ty)744 	static const char *get_script_name(int ty) {
745 		return ty >= Schedule::first_scripted_schedule ?
746 		       script_names[ty - Schedule::first_scripted_schedule].c_str() : nullptr;
747 	}
748 };
749 
750 #endif
751