1 /*
2  *  actors.h - Game actors.
3  *
4  *  Copyright (C) 1998-1999  Jeffrey S. Freedman
5  *  Copyright (C) 2000-2013  The Exult Team
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #ifndef INCL_ACTORS
23 #define INCL_ACTORS 1
24 
25 #include "contain.h"
26 #include "utils.h"      // This is only included for Log2...
27 #include "flags.h"
28 #include "ready.h"
29 #include "ignore_unused_variable_warning.h"
30 
31 class Image_window;
32 class Game_window;
33 class Npc_actor;
34 class Actor_action;
35 class Schedule;
36 class Schedule_change;
37 class Monster_info;
38 class Monster_actor;
39 class Weapon_info;
40 class Dead_body;
41 class Npc_timer_list;
42 class Frames_sequence;
43 class Animator;
44 class Actor_attributes;
45 
46 /*
47  *  An actor:
48  */
49 class Actor : public Container_game_object, public Time_sensitive {
50 	static Game_object_shared editing;      // NPC being edited by ExultStudio.
51 protected:
52 	std::string name;           // Its name.
53 	int usecode;            // # of usecode function.
54 	bool usecode_assigned;      // Usecode # explicitly assigned.
55 	std::string usecode_name;       // Name of usecode fun explicitly assigned.
56 	bool unused;            // If npc_num > 0, this NPC is unused
57 	//   in the game.
58 	short npc_num;          // # in Game_window::npcs list, or -1.
59 	short face_num;         // Which shape for conversations.
60 	short party_id;         // Index in party, or -1.
61 	int properties[12];     // Properties set/used in 'usecode'.
62 	Actor_attributes *atts;     // Generic atts. (for new games/mods).
63 	unsigned char temperature;  // Measure of coldness (0-63).
64 	short shape_save;       // Our old shape, or -1.
65 	short oppressor;        // NPC ID (>= 0) of oppressor, or -1.
66 	Game_object_weak target;        // Who/what we're attacking.
67 	short casting_mode;     //For displaying casting frames.
68 	int casting_shape;  //Shape of casting frames.
69 	// These 2 are set by the Usecode function 'set_to_attack':
70 	Game_object_weak target_object;
71 	Tile_coord target_tile;
72 	int attack_weapon;
73 public:
74 	enum Attack_mode {      // Setting from gump.+++++Save/restore.
75 	    nearest = 0,
76 	    weakest = 1,        // Attack weakest.
77 	    strongest = 2,
78 	    berserk = 3,        // Always attack, never retreat.
79 	    protect = 4,        // Protect NPC with halo.
80 	    defend = 5,
81 	    flank = 6,      // Attempt to attack from side.
82 	    flee = 7,
83 	    random = 8,     // Choose target at random.
84 	    manual = 9
85 	};
86 	enum Casting_mode {
87 	    not_casting = 0,        // The NPC is not casting.
88 	    init_casting = 1,       // When set, the next usecode script will
89 	    // display casting frames (shape 859).
90 	    show_casting_frames = 2 // Used for displaying the casting frames.
91 	                          // Also flags that the when the script finishes, the
92 	                          // casting frames should be disabled.
93 	};
94 protected:
95 	// Party positions
96 	const static short party_pos[4][10][2];
97 
98 	Attack_mode attack_mode;
99 	// A frame sequence for each dir.:
100 	static Frames_sequence *avatar_frames[4];
101 	static Frames_sequence *npc_frames[4];
102 	Frames_sequence **frames;
103 	// Draw weapon in hand
104 	void paint_weapon();
105 	unsigned char schedule_type;    // Schedule type (Schedule_type).
106 	Tile_coord schedule_loc;    // Location (x,y) of Shedule
107 	Tile_coord old_schedule_loc;    // Location (x,y) of old Shedule
108 	unsigned char next_schedule;    // Used so correct schedule type
109 	//   will be saved
110 	Schedule *schedule;     // Current schedule.
111 	int restored_schedule;  // Just restored schedule type.
112 	bool dormant;           // I.e., off-screen.
113 	bool hit;           // Just hit in combat.
114 	bool combat_protected;      // 'Halo' on paperdoll screen.
115 	bool user_set_attack;       // True if player set attack_mode.
116 	short alignment;        // 'Feelings' towards Ava. See below.
117 	short charmalign;       // Alignment of charmed NPC.
118 	Game_object *spots[18];     // Where things can go.  See 'Spots'
119 	//   below for description.
120 	bool two_handed;        // Carrying a two-handed item.
121 	bool two_fingered;      // Carrying gauntlets (both fingers)
122 	bool use_scabbard;      // Carrying an item in scabbard (belt, back 2h, shield).
123 	bool use_neck;          // Carrying cloak (amulet, cloak)
124 	int light_sources;    // # of light sources readied.
125 	unsigned char usecode_dir;  // Direction (0-7) for usecode anim.
126 
127 	unsigned type_flags: 32; // 32 flags used in movement among other things
128 	unsigned char  gear_immunities; // Damage immunities granted by gear.
129 	unsigned short gear_powers;     // Other powers granted by gear.
130 
131 	unsigned char ident;
132 
133 	int skin_color;
134 	Actor_action *action;       // Controls current animation.
135 	std::vector<Actor_action *> deletedactions;     // Halted actions.
136 	int frame_time;         // Time between frames in msecs.  0 if
137 	//   actor not moving.
138 	int step_index;         // Index into walking frames, 1 1st.
139 	int qsteps;             // # steps since last quake.
140 
141 	Npc_timer_list *timers;     // Timers for poison, hunger, etc.
142 	TileRect weapon_rect;      // Screen area weapon was drawn in.
143 	long rest_time;         // # msecs. of not doing anything.
144 	void init();            // Clear stuff during construction.
145 	// Move and change frame.
146 	void movef(Map_chunk *old_chunk, Map_chunk *new_chunk,
147 	           int new_sx, int new_sy, int new_frame, int new_lift);
148 	bool is_really_blocked(Tile_coord &t, bool force);
149     // Empty one hand
150     bool empty_hand(Game_object *obj, Game_object_shared *keep);
151 public:
152 	friend class Clear_casting;
153 	friend class Clear_hit;
154 	static void init_default_frames();  // Set usual frame sequence.
155 	Actor(const std::string &nm, int shapenum, int num = -1, int uc = -1);
156 	~Actor() override;
157 	// Blocked moving onto tile 't'?
158 	bool is_blocked(Tile_coord &t, Tile_coord *f = nullptr, const int move_flags = 0);
159 	Game_object *find_blocking(Tile_coord const &tile, int dir);
160 
161 	void swap_ammo(Game_object *newammo);
162 	bool ready_ammo();      // Find and ready appropriate ammo.
163 	bool ready_best_weapon();   // Find best weapon and ready it.
164 	bool ready_best_shield();   // Find best shield and ready it.
165 	void empty_hands();     // Make sure both hands are empty.
166 	// Force repaint of area taken.
167 	int get_effective_weapon_shape() const;//For displaying casting frames.
168 	bool add_dirty(bool figure_rect = false);
169 	void change_frame(int frnum) override;   // Change frame & set to repaint.
170 	bool figure_weapon_pos(int &weapon_x, int &weapon_y, int &weapon_frame);
171 	void say_hunger_message();
172 	void use_food();        // Decrement food level.
173 	// Increment/decrement temperature.
174 	void check_temperature(bool freeze);
175 	// Get frame seq. for given dir.
get_frames(int dir)176 	Frames_sequence *get_frames(int dir) const {
177 		return frames[dir / 2];
178 	}
get_step_index()179 	int &get_step_index() {     // Get it (for updating).
180 		return step_index;
181 	}
182 	// Get attack frames.
183 	int get_attack_frames(int weapon, bool projectile,
184 	                      int dir, signed char *frames) const;
185 	enum Alignment {        // Describes alignment field.
186 	    neutral = 0,        // See [I]nspect NPC screen in SI for names.
187 	    good = 1,
188 	    evil = 2,
189 	    chaotic = 3
190 	};  // Bees have this, & don't attack until
191 	// Spots where items are carried.
free_hand()192 	int free_hand() const {     // Get index of a free hand, or -1.
193 		// PREFER right hand.
194 		return two_handed ? -1 :
195 		       (!spots[rhand] ? rhand : (!spots[lhand] ? lhand : -1));
196 	}
free_finger()197 	int free_finger() const {   // Get index of a free finger, or -1.
198 		return two_fingered ? -1 :
199 		       (!spots[lfinger] ? lfinger
200 		        : (!spots[rfinger] ? rfinger : -1));
201 	}
is_two_handed()202 	inline bool is_two_handed() const {
203 		return two_handed;
204 	}
is_two_fingered()205 	inline bool is_two_fingered() const {
206 		return two_fingered;
207 	}
is_scabbard_used()208 	inline bool is_scabbard_used() const {
209 		return use_scabbard;
210 	}
is_neck_used()211 	inline bool is_neck_used() const {
212 		return use_neck;
213 	}
get_light_source()214 	int get_light_source() const {  // Carrying a torch?
215 		return light_sources;
216 	}
add_light_source(int brightness)217 	void add_light_source(int brightness) { // Add a torch
218 		light_sources += brightness;
219 	}
220 	void add_light_source(Game_object *obj);
remove_light_source(int brightness)221 	void remove_light_source(int brightness) { // Remove a torch
222 		if (light_sources >= brightness)
223 			light_sources -= brightness;
224 		else
225 			light_sources = 0;
226 	}
227 	void remove_light_source(Game_object *obj);
get_attack_mode()228 	Attack_mode get_attack_mode() const {
229 		return attack_mode;
230 	}
231 	void set_attack_mode(Attack_mode amode, bool byuser = false) {
232 		attack_mode = amode;
233 		user_set_attack = byuser;
234 	}
did_user_set_attack()235 	bool did_user_set_attack() const {
236 		return user_set_attack;
237 	}
is_combat_protected()238 	bool is_combat_protected() const {
239 		return combat_protected;
240 	}
set_combat_protected(bool v)241 	void set_combat_protected(bool v) {
242 		combat_protected = v;
243 	}
get_oppressor()244 	int get_oppressor() const {
245 		return oppressor;
246 	}
set_oppressor(int opp)247 	void set_oppressor(int opp) {
248 		oppressor = opp;
249 	}
250 	enum type_flags {
251 	    tf_fly = 4,
252 	    tf_walk = 5,
253 	    tf_swim = 6,
254 	    tf_ethereal = 7,
255 	    tf_want_primary = 8,
256 	    tf_sex = 9,
257 	    tf_bleeding = 10,
258 	    tf_in_party = 12,
259 	    tf_in_action = 13,
260 	    tf_conjured = 14,
261 	    tf_summonned = 15
262 	};
263 	enum Item_properties {      // Trying to figure out properties.
264 	    strength = 0,       // This is also max. health.
265 	    dexterity = 1,
266 	    intelligence = 2,
267 	    health = 3,
268 	    combat = 4,
269 	    mana = 5,
270 	    magic = 6,      // Max. mana.
271 	    training = 7,       // Training points.
272 	    exp = 8,        // Experience.
273 	    food_level = 9,
274 	    sex_flag = 10,  // Seems to be get/set sex type flag in SI.
275 	    missile_weapon = 11 // Pretty sure it returns 1 if wearing
276 	                     // weapon with uses >= 2, 0 otherwise.
277 	};
278 	enum Frames {           // Frames 0-15.  16-31 are the same,
279 	    //   only S instead of N.
280 	    standing = 0,
281 	    step_right_frame = 1,
282 	    step_left_frame = 2,
283 	    ready_frame = 3,    // Ready to fight?
284 	    raise1_frame = 4,   // 1-handed strikes.
285 	    reach1_frame = 5,
286 	    strike1_frame = 6,
287 	    raise2_frame = 7,   // 2-handed strikes.
288 	    reach2_frame = 8,
289 	    strike2_frame = 9,
290 	    sit_frame = 10,
291 	    bow_frame = 11,
292 	    kneel_frame = 12,
293 	    sleep_frame = 13,
294 	    up_frame = 14,      // Both hands reach up.
295 	    out_frame = 15      // Both hands reach out.
296 	};
297 
get_face_shapenum()298 	int get_face_shapenum() const { // Get "portrait" shape #.
299 		return face_num;    // It's the NPC's #.
300 	}
get_usecode()301 	int get_usecode() const override {
302 		return usecode == -1 ? Game_object::get_usecode() : usecode;
303 	}
304 	bool set_usecode(int funid, const char *nm = nullptr) override {
305 		if (funid < 0) {
306 			usecode_assigned = false;
307 			usecode_name.clear();
308 			usecode = -1;
309 			return true;
310 		}
311 		if (nm)
312 			usecode_name = nm;
313 		else
314 			usecode_name.clear();
315 		usecode = funid;
316 		usecode_assigned = true;
317 		return true;
318 	}
get_schedule()319 	Schedule *get_schedule() const {
320 		return schedule;
321 	}
get_frame_time()322 	int get_frame_time() const { // Return frame time if moving.
323 		return frame_time;
324 	}
set_frame_time(int ftime)325 	void set_frame_time(int ftime) { // Set walking speed.
326 		frame_time = ftime;
327 	}
328 	void stand_at_rest();       // Stand (if not doing anyting else).
clear_rest_time()329 	void clear_rest_time() {
330 		rest_time = 0;
331 	}
resting(int msecs)332 	void resting(int msecs) {   // Increment rest time.
333 		if ((rest_time += msecs) > 2000)
334 			stand_at_rest();// Stand (under certain conditions).
335 	}
is_moving()336 	bool is_moving() const {
337 		return frame_time != 0;
338 	}
is_dormant()339 	bool is_dormant() const {   // Inactive (i.e., off-screen)?
340 		return dormant;
341 	}
is_dead()342 	bool is_dead() const {
343 		return (flags & (1 << Obj_flags::dead)) != 0;
344 	}
is_in_party()345 	bool is_in_party() const {  // (Includes Avatar.)
346 		return (flags & (1 << Obj_flags::in_party)) != 0;
347 	}
set_dormant()348 	void set_dormant() {
349 		dormant = true;
350 	}
get_action()351 	Actor_action *get_action() const { // Return action.
352 		return action;
353 	}
354 	// Set new action.
355 	void set_action(Actor_action *newact);
356 	void purge_deleted_actions();
357 	Tile_coord get_dest() const;      // Get destination.
358 	// Walk to a desired spot.
359 	void walk_to_tile(Tile_coord const &dest, int speed = 250, int delay = 0,
360 	                  int maxblk = 3);
361 	void walk_to_tile(int tx, int ty, int tz, int speed = 250,
362 	                  int delay = 0, int maxblk = 3) {
363 		walk_to_tile(Tile_coord(tx, ty, tz), speed, delay, maxblk);
364 	}
365 	// Get there, avoiding obstacles.
366 	int walk_path_to_tile(Tile_coord const &src, Tile_coord const &dest,
367 	                      int speed = 250, int delay = 0, int dist = 0, int maxblk = 3);
368 	int walk_path_to_tile(Tile_coord const &dest,
369 	                      int speed = 250, int delay = 0, int dist = 0, int maxblk = 3) {
370 		return walk_path_to_tile(get_tile(), dest,
371 		                         speed, delay, dist, maxblk);
372 	}
373 	// Start animation.
374 	void start(int speed = 250, int delay = 0);
375 	void start_std();       // Start with std. speed, delay.
376 	void stop();            // Stop animation.
377 	void follow(const Actor *leader); // Follow the leader.
378 	// Approach another from offscreen.
379 	int approach_another(const Actor *other, bool wait = false);
380 	// Get info. about tile to step onto.
381 	static void get_tile_info(Actor *actor,
382 	                          Game_window *gwin, Map_chunk *nlist,
383 	                          int tx, int ty, bool &water, bool &poison);
384 	// Set combat opponent.
385 	void set_target(Game_object *obj, bool start_combat = false);
get_target()386 	Game_object *get_target() const { // Get who/what we're attacking.
387 	  return target.lock().get();
388 	}
389 	// Works out if an object fits in a spot
390 	bool fits_in_spot(Game_object *obj, int spot);
391 	// The prefered slot for an object
392 	void get_prefered_slots(Game_object *obj, int &prefered, int &alt1, int &alt2) const;
393 	// Find where to put object.
394 	int find_best_spot(Game_object *obj);
395 	int get_prev_schedule_type() const;   // Get previous schedule.
396 	void restore_schedule();    // Set schedule after reading in.
set_schedule_loc(Tile_coord const & loc)397 	void set_schedule_loc(Tile_coord const &loc) {  // For monsters ONLY.
398 		schedule_loc = loc;
399 	}
400 	// Set new schedule.
401 	void set_schedule_type(int new_schedule_type,
402 	                       Schedule *newsched = nullptr);
403 	// Change to new schedule at loc
404 	virtual void set_schedule_and_loc(int new_schedule_type,
405 	                                  Tile_coord const &dest, int delay = -1);
406 	bool teleport_offscreen_to_schedule(Tile_coord const &dest, int dist);
get_schedule_type()407 	int get_schedule_type() const {
408 		return schedule_type;
409 	}
410 	// Get/set 'alignment'.
get_alignment()411 	int get_alignment() const {
412 		return alignment;
413 	}
set_alignment(short a)414 	void set_alignment(short a) {
415 		alignment = a;
416 	}
417 	int get_effective_alignment() const;    // Include 'charmed' flag.
418 	void set_effective_alignment(int newalign); // Include 'charmed' flag.
reset_effective_alignment()419 	void reset_effective_alignment() {
420 		charmalign = alignment;
421 	}
422 	// Update chunks after NPC moved.
switched_chunks(Map_chunk *,Map_chunk *)423 	virtual void switched_chunks(Map_chunk *, Map_chunk *)
424 	{  }
425 	// Update schedule for new 3-hour time.
426 	virtual void update_schedule(int hour3, int delay = -1,
427 	                             Tile_coord *pos = nullptr) {
428 		ignore_unused_variable_warning(hour3, delay, pos);
429 	}
430 	// Render.
431 	void paint() override;
432 	// Run usecode function.
433 	void activate(int event = 1) override;
434 	bool edit() override;        // Edit in ExultStudio.
435 	// Saved from ExultStudio.
436 	static void update_from_studio(unsigned char *data, int datalen);
437 	// Drop another onto this.
438 	bool drop(Game_object *obj) override;
439 	std::string get_name() const override;
440 	std::string get_npc_name() const;
get_npc_name_string()441 	std::string get_npc_name_string() const {
442 		return name;
443 	}
444 	void set_npc_name(const char *n);
445 	void set_property(int prop, int val);
446 	bool try_to_hit(Game_object *attacker, int attval) override;
447 	// Under attack.
448 	Game_object *attacked(Game_object *attacker, int weapon_shape = 0,
449 	                              int ammo_shape = 0, bool explosion = false) override;
450 	int figure_hit_points(Game_object *attacker, int weapon_shape = -1,
451 	                              int ammo_shape = -1, bool explosion = false) override;
452 	int apply_damage(Game_object *attacker, int str,
453 	                         int wpoints, int type, int bias = 0, int *exp = nullptr) override;
454 	// Lose HP's and check for death.
455 	int reduce_health(int delta, int damage_type, Game_object *attacker = nullptr,
456 	                          int *exp = nullptr) override;
457 	void fight_back(Game_object *attacker);
get_attack_target(Game_object * & obj,Tile_coord & t)458 	bool get_attack_target(Game_object *&obj, Tile_coord &t) const {
459 		static Tile_coord invalidloc(-1, -1, 0);
460 		Game_object_shared tobj = target_object.lock();
461 		obj = tobj.get();
462 		t = target_tile;
463 		return obj || target_tile != invalidloc;
464 	}
set_attack_target(Game_object * t,int w)465 	void set_attack_target(Game_object *t, int w) {
466 		target_tile = Tile_coord(-1, -1, 0);
467 		target_object = weak_from_obj(t);
468 		attack_weapon = w;
469 	}
set_attack_target(Tile_coord const & t,int w)470 	void set_attack_target(Tile_coord const &t, int w) {
471 		target_object = Game_object_weak();
472 		target_tile = t;
473 		target_tile.fixme();
474 		attack_weapon = w;
475 	}
476 	int get_effective_range(const Weapon_info *winf = nullptr, int reach = -1) const override;
477 	Game_object *find_weapon_ammo(int weapon, int needed = 1,
478 	                                      bool recursive = false) override;
479 	Game_object *find_best_ammo(int family, int needed = 1);
480 	bool usecode_attack();
481 	int get_property(int prop) const;
482 	int get_effective_prop(int prop) const;
is_dying()483 	bool is_dying() const {     // Dead when health below -1/3 str.
484 		return properties[static_cast<int>(health)] <
485 		       -(properties[static_cast<int>(strength)] / 3);
486 	}
is_knocked_out()487 	bool is_knocked_out() const {
488 		return get_property(static_cast<int>(health)) <= 0;
489 	}
get_level()490 	int get_level() const {     // Get experience level.
491 		return 1 + Log2(get_property(exp) / 50);
492 	}
493 	// Get/set generic attribute.
494 	void set_attribute(const char *nm, int val);
495 	int get_attribute(const char *nm) const;
496 	using Atts_vector = std::vector<std::pair<const char *, int>>;
497 	void get_attributes(Atts_vector &attlist) const;
498 	// Set atts. from savegame.
499 	void read_attributes(const unsigned char *buf, int len) override;
500 	Npc_timer_list *need_timers();
501 	// Set/clear/get actor flag.
502 	void force_sleep();
clear_sleep()503 	void clear_sleep() {
504 		flags &= ~(static_cast<uint32>(1) << Obj_flags::asleep);
505 	}
506 	void set_flag(int flag) override;
507 	void set_type_flag(int flag);
508 	void clear_flag(int flag) override;
509 	void clear_type_flag(int flag);
510 	bool get_type_flag(int flag) const override;
511 	void set_type_flags(unsigned short tflags);
get_skin_color()512 	int get_skin_color() const {
513 		return skin_color;
514 	}
set_skin_color(int color)515 	void set_skin_color(int color) {
516 		skin_color = color;
517 		set_actor_shape();
518 	}
get_type_flags()519 	virtual int get_type_flags() const {
520 		return type_flags;
521 	}
get_casting_mode()522 	short get_casting_mode() const {
523 		return casting_mode;
524 	}
525 	void end_casting_mode(int delay);
get_casting_shape()526 	int get_casting_shape() const {
527 		return casting_shape;
528 	}
begin_casting(int s)529 	void begin_casting(int s) {
530 		casting_mode = init_casting;
531 		casting_shape = s;
532 	}
display_casting_frames()533 	void display_casting_frames() {
534 		casting_mode = show_casting_frames;
535 	}
hide_casting_frames()536 	void hide_casting_frames() {
537 		casting_mode = not_casting;
538 	}
539 //++++++Is_dead() test messes up training.
540 //	unsigned char get_ident() { return is_dead() ? 0 : ident; }
get_ident()541 	unsigned char get_ident() const {
542 		return ident;
543 	}
set_ident(unsigned char id)544 	void set_ident(unsigned char id) {
545 		ident = id;
546 	}
547 
get_temperature()548 	int get_temperature() const { // Get/set measure of coldness.
549 		return temperature;
550 	}
551 	void set_temperature(int v);
get_temperature_zone()552 	int get_temperature_zone() const {
553 		// SI-verified.
554 		if (temperature < 15)
555 			return 1;
556 		else if (temperature < 25)
557 			return 2;
558 		else if (temperature < 40)
559 			return 3;
560 		else if (temperature < 50)
561 			return 4;
562 		else
563 			return 5;
564 	}
565 	int figure_warmth();        // Based on what's worn.
is_unused()566 	bool is_unused() const {    // Free NPC?
567 		return unused;
568 	}
set_unused(bool tf)569 	void set_unused(bool tf) {
570 		unused = tf;
571 	}
572 
get_npc_num()573 	int get_npc_num() const {   // Get its ID (1-num_npcs).
574 		return npc_num;
575 	}
576 	// Get/set index within party.
get_party_id()577 	int get_party_id() const {
578 		return party_id;
579 	}
set_party_id(int i)580 	void set_party_id(int i) {
581 		party_id = i;
582 	}
583 	// Set for Usecode animations.
set_usecode_dir(int d)584 	void set_usecode_dir(int d) {
585 		usecode_dir = d & 7;
586 	}
get_usecode_dir()587 	int get_usecode_dir() const {
588 		return usecode_dir;
589 	}
as_actor()590 	Actor *as_actor() override { // An actor?
591 		return this;
592 	}
is_slime()593 	virtual bool is_slime() const {
594 		return false;
595 	}
596 	void init_readied();        // Call Usecode to init. readied objs.
597 	// Remove an object.
598 	void remove(Game_object *obj) override;
599 	// Add an object.
600 	bool add(Game_object *obj, bool dont_check = false,
601 	                 bool combine = false, bool noset = false) override;
602 	// Add to NPC 'readied' spot.
603 	bool add_readied(Game_object *obj, int index,
604 	                        bool dont_check = false, bool force_pos = false, bool noset = false) override;
605 	int find_readied(Game_object *obj) override;
606 	Game_object *get_readied(int index) const override;
607 	void call_readied_usecode(int index,
608 	                                  Game_object *obj, int eventid) override;
609 	int get_max_weight() const override;   // Get max. weight allowed.
610 	// Change member shape.
611 	void change_member_shape(Game_object *obj, int newshape) override;
612 	// Move out of the way.
613 	bool move_aside(Actor *for_actor, int dir) override;
614 	// Get frame if rotated clockwise.
615 	int get_rotated_frame(int quads) const override;
616 	virtual int get_armor_points() const; // Get total armor value.
617 	// Gets whether the actor is immune or vulnerable to a given
618 	// form of damage:
619 	int is_immune(int type) const;
620 	bool is_goblin() const;
621 	bool can_see_invisible() const;
622 	bool can_speak() const;
623 	bool is_sentient() const;
624 	void refigure_gear();
check_gear_powers(int flags)625 	bool check_gear_powers(int flags) const {
626 		return (gear_powers & flags) != 0;
627 	}
628 	// Get total weapon value.
629 	virtual const Weapon_info *get_weapon(int &points, int &shape,
630 	                                Game_object  *&obj) const;
get_weapon(int & points)631 	const Weapon_info *get_weapon(int &points) const {
632 		int sh;
633 		Game_object *o;
634 		return get_weapon(points, sh, o);
635 	}
636 	static bool roll_to_win(int attacker, int defender);
637 	// Hit-point algorithm:
638 	bool can_act();
639 	bool can_act_charmed(); // checks for charmed and charmed_more_difficult
640 	void set_charmed_combat();
641 	virtual void fall_down();
642 	virtual void lay_down(bool die);
643 	virtual void die(Game_object *attacker);        // We're dead.
644 	Actor *resurrect(Dead_body *body);// Bring back to life.
645 	Game_object_shared clone();     // Create another nearby to this.
646 	void mend_wounds(bool mendmana);        // Restore HP's and MP's.
647 	// Read from file.
648 	void read(IDataSource *nfile, int num, bool has_usecode,
649 	          bool &fix_unused);
650 	// Don't write out to IREG file.
write_ireg(ODataSource * out)651 	void write_ireg(ODataSource *out) override {
652 		ignore_unused_variable_warning(out);
653 	}
get_ireg_size()654 	int get_ireg_size() override {
655 		return 0;
656 	}
657 	void write(ODataSource *nfile);// Write out (to 'npc.dat').
658 	void write_contents(ODataSource *out) override;   // Write contents
659 	void set_actor_shape();     // Set shape based on sex, skin color
660 	void set_polymorph(int shape);  // Set a polymorph shape
661 	void set_polymorph_default();   // Set the default shape
662 	// Get the polymorph shape
get_polymorph()663 	int get_polymorph() const {
664 		return shape_save;
665 	}
666 	// Get the non polymorph shape (note, doesn't returned skin coloured shapes)
667 	// For usecode
668 	int get_shape_real() const;
669 	// This does the same, but will return skin coloured shapes
670 	// For paperdolls/face stats
get_sexed_coloured_shape()671 	int get_sexed_coloured_shape() const {
672 		return shape_save != -1 ? shape_save : get_shapenum();
673 	}
674 
675 	// Set schedule list.
set_schedules(Schedule_change * list,int cnt)676 	virtual void set_schedules(Schedule_change *list, int cnt) {
677 		ignore_unused_variable_warning(list, cnt);
678 	}
set_schedule_time_type(int time,int type)679 	virtual void set_schedule_time_type(int time, int type) {
680 		ignore_unused_variable_warning(time, type);
681 	}
set_schedule_time_location(int time,int x,int y)682 	virtual void set_schedule_time_location(int time, int x, int y) {
683 		ignore_unused_variable_warning(time, x, y);
684 	}
remove_schedule(int time)685 	virtual void remove_schedule(int time) {
686 		ignore_unused_variable_warning(time);
687 	}
get_schedules(Schedule_change * & list,int & cnt)688 	virtual void get_schedules(Schedule_change *&list, int &cnt) const {
689 		list = nullptr;
690 		cnt = 0;
691 	}
find_schedule_at_time(int hour3)692 	virtual int find_schedule_at_time(int hour3) {
693 		ignore_unused_variable_warning(hour3);
694 		return -1;
695 	}
696 
697 	void show_inventory();
698 	int inventory_shapenum();
699 
was_hit()700 	bool was_hit() {
701 		return hit;
702 	}
703 
704 	// Should be virtual???
705 	void cache_out();
706 	bool in_usecode_control() const;
707 	bool quake_on_walk();
708 };
709 using Actor_shared = std::shared_ptr<Actor>;
710 
711 /*
712  *  Actor frame descriptions:
713     0   Standing
714     1   Walk
715     2   Walk
716     3   Beginning to attack
717     4-6 Attacking with one hand
718     7-9 Attacking with two hands
719     9   Also NPC shooting magic
720     10  Sitting down
721     11  Bending over (beginning to sit down)
722     12  Kneeling
723     11  Lying down
724     14  Casting spell (hands raised)
725     15  Casting spell (hands outstretched)
726 
727  */
728 
729 /*
730  *  The main actor.
731  */
732 class Main_actor : public Actor {
733 public:
734 	Main_actor(const std::string &nm, int shapenum, int num = -1, int uc = -1)
Actor(nm,shapenum,num,uc)735 		: Actor(nm, shapenum, num, uc) {
736 		frames = &avatar_frames[0];
737 	}
738 	// For Time_sensitive:
739 	void handle_event(unsigned long curtime, uintptr udata) override;
740 	void get_followers() const;       // Get party to follow.
741 	// Step onto an (adjacent) tile.
742 	bool step(Tile_coord t, int frame, bool force = false) override;
743 	// Update chunks after NPC moved.
744 	void switched_chunks(Map_chunk *olist,
745 	                             Map_chunk *nlist) override;
746 	// Move to new abs. location.
747 	void move(int newtx, int newty, int newlift, int newmap = -1) override;
748 	void die(Game_object *attacker) override;        // We're dead.
749 };
750 using Main_actor_shared = std::shared_ptr<Main_actor>;
751 
752 /*
753  *  A non-player-character that one can converse (or fight) with:
754  */
755 class Npc_actor : public Actor {
756 	bool nearby;       // Queued as a 'nearby' NPC.  This is
757 	//   to avoid being added twice.
758 protected:
759 	unsigned char num_schedules;    // # entries below.
760 	Schedule_change *schedules; // List of schedule changes.
761 	int find_schedule_change(int hour3);
762 public:
763 	Npc_actor(const std::string &nm, int shapenum, int num = -1,
764 	          int uc = -1);
765 	~Npc_actor() override;
set_nearby()766 	void set_nearby() {     // Set/clear/test 'nearby' flag.
767 		nearby = true;
768 	}
clear_nearby()769 	void clear_nearby() {
770 		nearby = false;
771 	}
is_nearby()772 	bool is_nearby() const {
773 		return nearby;
774 	}
775 	// Set schedule list.
776 	void set_schedules(Schedule_change *list, int cnt) override;
777 	void set_schedule_time_type(int time, int type) override;
778 	void set_schedule_time_location(int time, int x, int y) override;
779 	void remove_schedule(int time) override;
780 	void get_schedules(Schedule_change *&list, int &cnt) const override;
781 	// Move and change frame.
782 	void movef(Map_chunk *old_chunk, Map_chunk *new_chunk,
783 	           int new_sx, int new_sy, int new_frame, int new_lift);
784 	// Update schedule for new 3-hour time.
785 	void update_schedule(int hour3, int delay = -1,
786 	                             Tile_coord *pos = nullptr) override;
787 	int find_schedule_at_time(int hour3) override;
788 	// Render.
789 	void paint() override;
790 	// Run usecode function.
791 	void activate(int event = 1) override;
792 	// For Time_sensitive:
793 	void handle_event(unsigned long curtime, uintptr udata) override;
794 	// Step onto an (adjacent) tile.
795 	bool step(Tile_coord t, int frame, bool force = false) override;
796 	// Remove/delete this object.
797 	void remove_this(Game_object_shared *keep = nullptr) override;
798 	// Update chunks after NPC moved.
799 	void switched_chunks(Map_chunk *olist,
800 	                             Map_chunk *nlist) override;
801 	// Move to new abs. location.
802 	void move(int newtx, int newty, int newlift, int newmap = -1) override;
803 
as_npc()804 	Npc_actor *as_npc() override {
805 		return this;
806 	}
807 };
808 using Npc_actor_shared = std::shared_ptr<Npc_actor>;
809 
810 /*
811  *  An actor's dead body:
812  */
813 class Dead_body : public Container_game_object {
814 	short npc_num;          // # of NPC it came from, or -1.
815 public:
Dead_body(int shapenum,int framenum,unsigned int tilex,unsigned int tiley,unsigned int lft,int n)816 	Dead_body(int shapenum, int framenum, unsigned int tilex,
817 	          unsigned int tiley, unsigned int lft, int n)
818 		: Container_game_object(shapenum, framenum, tilex, tiley, lft),
819 		  npc_num(n) {
820 	}
as_body()821 	Dead_body *as_body() override {
822 		return this;
823 	}
824 	int get_live_npc_num() const override;
825 	// Under attack.
826 	Game_object *attacked(Game_object *attacker, int weapon_shape = 0,
827 	                              int ammo_shape = 0, bool explosion = false) override {
828 		ignore_unused_variable_warning(attacker, weapon_shape, ammo_shape, explosion);
829 		return this;    // Not affected.
830 	}
831 	void write_ireg(ODataSource *out) override;
832 	int get_ireg_size() override;
833 };
834 using Dead_body_shared = std::shared_ptr<Dead_body>;
835 
836 #endif
837