1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef NUVIE_ACTORS_ACTOR_H
24 #define NUVIE_ACTORS_ACTOR_H
25 
26 #include "ultima/shared/std/containers.h"
27 #include "ultima/shared/std/string.h"
28 #include "ultima/nuvie/misc/actor_list.h"
29 #include "ultima/nuvie/core/map.h"
30 #include "ultima/nuvie/core/obj_manager.h"
31 
32 namespace Ultima {
33 namespace Nuvie {
34 
35 using Std::map;
36 using Std::list;
37 using Std::string;
38 using Std::vector;
39 
40 #define ACTOR_NO_READIABLE_LOCATION -1
41 #define ACTOR_HEAD   0
42 #define ACTOR_NECK   1
43 #define ACTOR_BODY   2
44 #define ACTOR_ARM    3
45 #define ACTOR_ARM_2  4
46 #define ACTOR_HAND   5
47 #define ACTOR_HAND_2 6
48 #define ACTOR_FOOT   7
49 #define ACTOR_NOT_READIABLE 8
50 
51 // actor alignment
52 #define ACTOR_ALIGNMENT_DEFAULT 0
53 #define ACTOR_ALIGNMENT_NEUTRAL 1
54 #define ACTOR_ALIGNMENT_EVIL    2
55 #define ACTOR_ALIGNMENT_GOOD    3
56 #define ACTOR_ALIGNMENT_CHAOTIC 4
57 
58 // move-flags
59 #define ACTOR_FORCE_MOVE    1
60 #define ACTOR_IGNORE_OTHERS 2
61 #define ACTOR_OPEN_DOORS    4
62 #define ACTOR_IGNORE_DANGER 8
63 #define ACTOR_IGNORE_MOVES 0x10
64 #define ACTOR_IGNORE_PARTY_MEMBERS 0x20 // only used in Actor::check_move. In U6, player diagonal movement
65 // between two blocked tiles isn't allowed (non-party actors block)
66 
67 // push-flags (exclusive)
68 #define ACTOR_PUSH_ANYWHERE 0
69 #define ACTOR_PUSH_HERE     1
70 #define ACTOR_PUSH_FORWARD  2
71 
72 #define ACTOR_SHOW_BLOOD true
73 #define ACTOR_FORCE_HIT true
74 
75 #define ACTOR_STATUS_PROTECTED 0x1
76 #define ACTOR_STATUS_PARALYZED 0x2
77 #define ACTOR_STATUS_ASLEEP    0x4
78 #define ACTOR_STATUS_POISONED  0x8
79 #define ACTOR_STATUS_DEAD      0x10
80 #define ACTOR_STATUS_ATTACK_EVIL 0x20
81 #define ACTOR_STATUS_ATTACK_GOOD 0x40
82 #define ACTOR_STATUS_IN_PARTY  0x80
83 #define ACTOR_STATUS_ALIGNMENT_MASK 0x60
84 
85 #define ACTOR_MOVEMENT_HIT_FLAG 0x8
86 #define ACTOR_MOVEMENT_FLAGS_OLD_ALIGNMENT_MASK 0x60
87 
88 #define ACTOR_OBJ_FLAG_
89 #define ACTOR_NO_ERROR 0
90 #define ACTOR_OUT_OF_MOVES 1
91 #define ACTOR_BLOCKED 2
92 #define ACTOR_BLOCKED_BY_OBJECT 3
93 #define ACTOR_BLOCKED_BY_ACTOR 4
94 
95 #define ACTOR_MAX_READIED_OBJECTS 8
96 
97 #define ACTOR_WT_FOLLOW 1
98 #define ACTOR_WT_PLAYER 2
99 #define ACTOR_WT_RANGED 4
100 #define ACTOR_WT_RETREAT 7
101 #define ACTOR_WT_ASSAULT 8
102 
103 #define ACTOR_CHANGE_BASE_OBJ_N true
104 
105 #define ACTOR_VEHICLE_ID_N 0
106 #define ACTOR_AVATAR_ID_N  1
107 
108 #define INV_EXCLUDE_READIED_OBJECTS false
109 #define INV_INCLUDE_READIED_OBJECTS true
110 
111 #define ACTOR_MD_OBJ_FLAG_HYPOXIA 6
112 #define ACTOR_MD_OBJ_FLAG_FRENZY  7
113 
114 #define ACTOR_MD_STATUS_FLAG_COLD 0
115 
116 class Map;
117 class MapCoord;
118 class UseCode;
119 class ActorPathFinder;
120 class U6LList;
121 class GameClock;
122 class Path;
123 
124 typedef struct {
125 	uint16 x;
126 	uint16 y;
127 	uint8 z;
128 	uint8 hour;
129 	uint8 day_of_week; // 0 = any day 1..7
130 	uint8 worktype;
131 } Schedule;
132 
133 typedef enum { ATTACK_TYPE_NONE, ATTACK_TYPE_HAND, ATTACK_TYPE_THROWN, ATTACK_TYPE_MISSLE } AttackType;
134 
135 typedef struct {
136 	uint16 obj_n;
137 
138 	union {
139 		uint8 defence;
140 		uint8 defense;
141 	};
142 	union {
143 		uint8 attack;
144 		uint8 damage;
145 	};
146 
147 	uint16 hit_range;
148 	AttackType attack_type;
149 
150 	uint16 missle_tile_num;
151 	uint16 thrown_obj_n;
152 
153 	bool breaks_on_contact;
154 } CombatType;
155 
156 typedef struct {
157 	Obj *obj;
158 	const CombatType *combat_type;
159 	bool double_handed;
160 } ReadiedObj;
161 
162 typedef uint8 ActorErrorCode;
163 typedef struct {
164 	ActorErrorCode err;
165 	Obj *blocking_obj;
166 	Actor *blocking_actor;
167 } ActorError;
168 
169 typedef uint8 ActorMoveFlags;
170 
171 typedef enum {
172 	ACTOR_ST, // single tile
173 	ACTOR_DT, // double tile
174 	ACTOR_QT, // quad tile
175 	ACTOR_MT  // multi tile
176 } ActorTileType;
177 
178 class Actor {
179 	friend class ActorManager;
180 	friend class MapWindow;
181 	friend class Party;
182 	friend class Player;
183 	friend class U6UseCode;
184 
185 public:
186 	struct cmp_level {
operatorcmp_level187 		bool operator()(Actor *a1, Actor *a2) const {
188 			return (a1->level > a2->level);
189 		}
190 	};
191 
192 	struct cmp_dex {
operatorcmp_dex193 		bool operator()(Actor *a1, Actor *a2) const {
194 			return (a1->dex > a2->dex);
195 		}
196 	};
197 
198 	struct cmp_moves {
operatorcmp_moves199 		bool operator()(Actor *a1, Actor *a2) const {
200 			return (a1->moves > a2->moves);
201 		}
202 	};
203 
204 	struct cmp_move_fraction {
operatorcmp_move_fraction205 		bool operator()(Actor *a1, Actor *a2) const {
206 			if (a1->dex == 0) {
207 				a1->dex = 1;
208 				DEBUG(0, LEVEL_WARNING, "%s (%d) has 0 dex!\n", a1->get_name(), a1->id_n);
209 			}
210 			if (a2->dex == 0) {
211 				a2->dex = 1;
212 				DEBUG(0, LEVEL_WARNING, "%s (%d) has 0 dex!\n", a2->get_name(), a2->id_n);
213 			}
214 			return (a1->moves / a1->dex > a2->moves / a2->dex);
215 		}
216 	};
217 
218 	struct cmp_distance_to_loc {
219 		MapCoord cmp_loc;
operatorcmp_distance_to_loc220 		void operator()(const MapCoord &cmp_loc2) {
221 			cmp_loc = cmp_loc2;
222 		}
operatorcmp_distance_to_loc223 		bool operator()(Actor *a1, Actor *a2) {
224 			MapCoord loc1(a1->x, a1->y, a1->z);
225 			MapCoord loc2(a2->x, a2->y, a2->z);
226 			return (loc1.distance(cmp_loc) < loc2.distance(cmp_loc));
227 		}
228 	};
229 
230 protected:
231 
232 	uint8 id_n;
233 
234 	Map *map;
235 	ObjManager *obj_manager;
236 	GameClock *clock;
237 	UseCode *usecode;
238 	ActorPathFinder *pathfinder;
239 
240 	uint16 x;
241 	uint16 y;
242 	uint16 z;
243 
244 	uint8 worktype;
245 	MapCoord work_location;
246 	uint32 move_time; // time (in clock ticks) of last update() (for display)
247 	// FIXME: replace with animation
248 	uint16 obj_n;
249 	uint16 frame_n;
250 	uint16 base_obj_n;
251 	uint16 old_frame_n;
252 
253 	uint8 direction;
254 	uint8 walk_frame;
255 
256 	uint8 obj_flags;
257 	uint8 status_flags;
258 	uint8 talk_flags;
259 	uint8 movement_flags; //0x19f1
260 
261 	bool ethereal;
262 	bool can_move;
263 	bool temp_actor;
264 	bool met_player;
265 
266 	bool visible_flag;
267 // bool active; // "cached in"
268 
269 	sint8 moves; // number of moves actor has this turn
270 	uint8 light; // level of light around actor (normally 0)
271 	vector<uint8> light_source;
272 
273 	ActorError error_struct; // error/status; result of previous action
274 
275 	uint8 strength;
276 	uint8 dex;
277 	uint8 intelligence;
278 	uint8 hp;
279 	uint8 level;
280 	uint16 exp;
281 	uint8 magic;
282 	uint8 combat_mode;
283 	uint8 alignment;
284 
285 	uint8 body_armor_class;
286 	uint8 readied_armor_class;
287 
288 	string name;
289 
290 	ReadiedObj *readied_objects[ACTOR_MAX_READIED_OBJECTS];
291 
292 	Schedule **sched;
293 	int num_schedules;
294 
295 	U6LList *obj_inventory;
296 
297 //current schedule pos;
298 	uint16 sched_pos;
299 
300 	list<Obj *> surrounding_objects; //used for multi-tile actors.
301 	Std::map<uint16, uint16> *custom_tile_tbl;
302 
303 public:
304 
305 	Actor(Map *m, ObjManager *om, GameClock *c);
306 	virtual ~Actor();
307 
308 	virtual bool init(uint8 obj_status = NO_OBJ_STATUS);
309 	void init_from_obj(Obj *obj, bool change_base_obj = false);
310 
is_avatar()311 	bool is_avatar() {
312 		return (id_n == ACTOR_AVATAR_ID_N);
313 	}
is_onscreen()314 	bool is_onscreen() {
315 		return (MapCoord(x, y, z).is_visible());
316 	}
is_in_party()317 	bool is_in_party() {
318 		return ((status_flags & ACTOR_STATUS_IN_PARTY) == ACTOR_STATUS_IN_PARTY);
319 	}
320 	bool is_in_vehicle();
is_visible()321 	bool is_visible() {
322 		return visible_flag;
323 	}
is_alive()324 	bool is_alive() {
325 		return (status_flags & ACTOR_STATUS_DEAD) ? false : true;
326 	}
327 	bool is_nearby(Actor *other);
328 	bool is_nearby(uint8 actor_num);
329 	bool is_nearby(MapCoord &where, uint8 thresh = 5);
330 	bool is_at_position(Obj *obj);
331 	virtual bool is_passable();
is_temp()332 	bool is_temp() {
333 		return temp_actor;
334 	}
335 
336 //for lack of a better name:
is_met()337 	bool is_met() {
338 		return (talk_flags & 0x01);
339 	}
is_poisoned()340 	bool is_poisoned() {
341 		return (status_flags & ACTOR_STATUS_POISONED);
342 	}
is_invisible()343 	bool is_invisible() {
344 		return (obj_flags & OBJ_STATUS_INVISIBLE);
345 	}
346 	virtual bool is_immobile(); // frozen by worktype or status
is_sleeping()347 	virtual bool is_sleeping() {
348 		return (status_flags & ACTOR_STATUS_ASLEEP);
349 	}
is_paralyzed()350 	virtual bool is_paralyzed() {
351 		return (status_flags & ACTOR_STATUS_PARALYZED);
352 	}
is_protected()353 	virtual bool is_protected() {
354 		return (status_flags & ACTOR_STATUS_PROTECTED);
355 	}
is_charmed()356 	virtual bool is_charmed() {
357 		return (obj_flags & OBJ_STATUS_CHARMED);
358 	}
is_cursed()359 	virtual bool is_cursed() {
360 		return (obj_flags & OBJ_STATUS_CURSED);
361 	}
get_corpser_flag()362 	virtual bool get_corpser_flag() {
363 		return false;
364 	}
is_hit()365 	bool is_hit() {
366 		return (movement_flags & ACTOR_MOVEMENT_HIT_FLAG);
367 	}
368 
set_name(const char * actor_name)369 	void set_name(const char *actor_name) {
370 		name = actor_name;
371 	}
372 	const char *get_name(bool force_real_name = false);
373 
374 	void get_location(uint16 *ret_x, uint16 *ret_y, uint8 *ret_level);
375 	MapCoord get_location();
376 
377 	uint16 get_tile_num();
378 	Tile *get_tile();
379 	virtual uint16 get_downward_facing_tile_num();
get_actor_num()380 	uint8 get_actor_num() {
381 		return (id_n);
382 	}
get_talk_flags()383 	uint8 get_talk_flags() {
384 		return (talk_flags);
385 	}
get_tile_type()386 	virtual ActorTileType get_tile_type() {
387 		return (ACTOR_ST);
388 	}
389 
get_frame_n()390 	uint16 get_frame_n() {
391 		return (frame_n);
392 	}
get_old_frame_n()393 	uint16 get_old_frame_n() {
394 		return (old_frame_n);
395 	}
get_x()396 	uint16 get_x() {
397 		return (x);
398 	}
get_y()399 	uint16 get_y() {
400 		return (y);
401 	}
get_z()402 	uint8  get_z() {
403 		return (z);
404 	}
405 
get_strength()406 	uint8 get_strength() {
407 		return (strength);
408 	}
get_dexterity()409 	uint8 get_dexterity() {
410 		return (dex);
411 	}
get_intelligence()412 	uint8 get_intelligence() {
413 		return (intelligence);
414 	}
get_hp()415 	uint8 get_hp() {
416 		return (hp);
417 	}
get_hp_text_color()418 	virtual uint8 get_hp_text_color() {
419 		return 0;
420 	}
get_str_text_color()421 	virtual uint8 get_str_text_color() {
422 		return 0;
423 	}
get_dex_text_color()424 	virtual uint8 get_dex_text_color() {
425 		return 0;
426 	}
427 
get_level()428 	uint8 get_level() {
429 		return (level);
430 	}
get_exp()431 	uint16 get_exp() {
432 		return (exp);
433 	}
get_magic()434 	uint8 get_magic() {
435 		return (magic);
436 	}
get_alignment()437 	uint8 get_alignment() {
438 		return (alignment);
439 	}
get_old_alignment()440 	uint8 get_old_alignment() {
441 		return ((movement_flags & ACTOR_MOVEMENT_FLAGS_OLD_ALIGNMENT_MASK) >> 5) + 1;
442 	}
get_moves_left()443 	sint8 get_moves_left() {
444 		return (moves);
445 	}
get_maxhp()446 	virtual uint8 get_maxhp() {
447 		return 0;
448 	}
get_maxmagic()449 	virtual uint8 get_maxmagic() {
450 		return 0;
451 	}
get_obj_flag(uint8 bitFlag)452 	bool get_obj_flag(uint8 bitFlag) {
453 		return bitFlag < 8 ? (obj_flags & (1 << bitFlag)) : false;
454 	}
get_status_flag(uint8 bitFlag)455 	bool get_status_flag(uint8 bitFlag) {
456 		return bitFlag < 8 ? (status_flags & (1 << bitFlag)) : false;
457 	}
458 
get_base_obj_n()459 	uint16 get_base_obj_n() {
460 		return base_obj_n;
461 	}
change_base_obj_n(uint16 val)462 	virtual void change_base_obj_n(uint16 val) {
463 		base_obj_n = obj_n = val;
464 		frame_n = 0;
465 	}
set_obj_n(uint16 val)466 	void set_obj_n(uint16 val) {
467 		obj_n = val;
468 	}
set_frame_n(uint16 val)469 	void set_frame_n(uint16 val) {
470 		frame_n = val;
471 	}
set_strength(uint8 val)472 	void set_strength(uint8 val) {
473 		strength = val;
474 	}
set_dexterity(uint8 val)475 	void set_dexterity(uint8 val) {
476 		dex = val;
477 	}
set_intelligence(uint8 val)478 	void set_intelligence(uint8 val) {
479 		intelligence = val;
480 	}
481 	void set_hp(uint8 val);
set_level(uint8 val)482 	void set_level(uint8 val) {
483 		level = val;
484 	}
set_exp(uint16 val)485 	void set_exp(uint16 val) {
486 		exp = clamp_max(val, 9999);
487 	}
set_magic(uint8 val)488 	void set_magic(uint8 val) {
489 		magic = val;
490 	}
set_alignment(uint8 a)491 	void set_alignment(uint8 a) {
492 		alignment = a;
493 	}
set_old_alignment(uint8 a)494 	void set_old_alignment(uint8 a) {
495 		if (a > 0 && a < 5) {
496 			movement_flags |= (a - 1) << 5;
497 		}
498 	}
499 	uint8 get_light_level();
500 	void add_light(uint8 val);
501 	void subtract_light(uint8 val);
heal()502 	void heal() {
503 		set_hp(get_maxhp());
504 	}
505 	void cure();
506 	void set_moves_left(sint8 val);
507 	void set_dead_flag(bool value);
update_time()508 	virtual void update_time() {
509 		set_moves_left(get_moves_left() + get_dexterity());
510 	}
511 	void set_poisoned(bool poisoned);
set_paralyzed(bool paralyzed)512 	virtual void set_paralyzed(bool paralyzed) {
513 		return;
514 	}
set_protected(bool val)515 	virtual void set_protected(bool val) {
516 		return;
517 	}
set_charmed(bool val)518 	virtual void set_charmed(bool val) {
519 		return;
520 	}
set_corpser_flag(bool val)521 	virtual void set_corpser_flag(bool val) {
522 		return;
523 	}
set_cursed(bool val)524 	virtual void set_cursed(bool val) {
525 		return;
526 	}
set_asleep(bool val)527 	virtual void set_asleep(bool val) {
528 		return;
529 	}
530 	void set_obj_flag(uint8 bitFlag, bool value);
531 	void set_status_flag(uint8 bitFlag, bool value);
532 	void set_hit_flag(bool val);
533 
534 	void set_invisible(bool invisible);
535 	void set_custom_tile_num(uint16 obj_num, uint16 tile_num);
536 
537 	uint8 get_worktype();
538 	uint8 get_sched_worktype();
539 	virtual void set_worktype(uint8 new_worktype, bool init = false);
get_combat_mode()540 	uint8 get_combat_mode() {
541 		return combat_mode;
542 	}
543 	void set_combat_mode(uint8 new_mode);
revert_worktype()544 	virtual void revert_worktype() { }
545 
get_direction()546 	uint8 get_direction() {
547 		return (direction);
548 	}
549 	void set_direction(sint16 rel_x, sint16 rel_y);
550 	virtual void set_direction(uint8 d);
551 	void face_location(MapCoord &loc);
552 	virtual void face_location(uint16 lx, uint16 ly);
553 	void face_actor(Actor *a);
554 
set_talk_flags(uint8 newflags)555 	void set_talk_flags(uint8 newflags) {
556 		talk_flags = newflags;
557 	}
558 	uint8 get_flag(uint8 bitflag);
559 	void set_flag(uint8 bitflag);
560 	void clear_flag(uint8 bitflag);
561 	void show();
562 	void hide();
563 	void set_error(ActorErrorCode err);
564 	void clear_error();
565 	ActorError *get_error();
566 
get_surrounding_obj_list()567 	list<Obj *> *get_surrounding_obj_list() {
568 		return surrounding_objects.empty() ? NULL : &surrounding_objects;
569 	}
570 	void add_surrounding_obj(Obj *obj);
571 	void unlink_surrounding_objects(bool make_objects_temporary = false);
572 
573 	bool moveRelative(sint16 rel_x, sint16 rel_y, ActorMoveFlags flags = 0);
574 	virtual bool move(uint16 new_x, uint16 new_y, uint8 new_z, ActorMoveFlags flags = 0);
575 	virtual bool check_move(uint16 new_x, uint16 new_y, uint8 new_z, ActorMoveFlags flags = 0);
576 	bool check_moveRelative(sint16 rel_x, sint16 rel_y, ActorMoveFlags flags = 0);
577 
578 	virtual bool can_be_moved();
579 	virtual bool can_be_passed(Actor *other);
580 	virtual void update();
581 	void set_in_party(bool state);
582 	void set_pathfinder(ActorPathFinder *new_pf, Path *path_type = 0);
get_pathfinder()583 	ActorPathFinder *get_pathfinder() {
584 		return (pathfinder);
585 	}
586 	void delete_pathfinder();
587 	virtual void pathfind_to(MapCoord &d);
588 	void pathfind_to(uint16 gx, uint16 gy, uint8 gz = 255);
589 	bool walk_path();
preform_worktype()590 	virtual void preform_worktype() {
591 		return;
592 	}
593 
594 // combat methods
595 //void attack(MapCoord pos); // attack at a given map location
596 	Obj *get_weapon_obj(sint8 readied_obj_location);
597 	void attack(sint8 readied_obj_location, MapCoord target, Actor *foe = NULL);
598 	const CombatType *get_weapon(sint8 readied_obj_location);
599 	void attract_to(Actor *target);
600 	void repel_from(Actor *target);
601 
602 	void hit(uint8 dmg, bool force_hit = false);
603 	void reduce_hp(uint8 amount);
604 	virtual void die(bool create_body = true);
605 	void resurrect(MapCoord new_position, Obj *body_obj = NULL);
606 	uint8 get_range(uint16 target_x, uint16 target_y);
607 	bool weapon_can_hit(const CombatType *weapon, uint16 target_x, uint16 target_y);
weapon_can_hit(const CombatType * weapon,Actor * target,uint16 * hit_x,uint16 * hit_y)608 	virtual bool weapon_can_hit(const CombatType *weapon, Actor *target, uint16 *hit_x, uint16 *hit_y) {
609 		*hit_x = target->get_x();
610 		*hit_y = target->get_y();
611 		return true;
612 	}
613 	void display_condition();
614 	ActorList *find_enemies(); // returns list or 0 if no enemies nearby
615 
616 	U6LList *get_inventory_list();
617 	bool inventory_has_object(uint16 obj_n, uint8 qual = 0, bool match_quality = OBJ_MATCH_QUALITY, uint8 frame_n = 0, bool match_frame_n = OBJ_NOMATCH_FRAME_N);
618 	uint32 inventory_count_objects(bool inc_readied_objects);
619 	uint32 inventory_count_object(uint16 obj_n);
620 	Obj *inventory_get_object(uint16 obj_n, uint8 qual = 0, bool match_quality = OBJ_MATCH_QUALITY, uint8 frame_n = 0, bool match_frame_n = OBJ_NOMATCH_FRAME_N);
621 	bool is_double_handed_obj_readied();
622 	Obj *inventory_get_readied_object(uint8 location);
inventory_get_readied_obj_n(uint8 location)623 	sint16 inventory_get_readied_obj_n(uint8 location) {
624 		return (inventory_get_readied_object(location) == NULL ? -1 : inventory_get_readied_object(location)->obj_n);
625 	}
626 	virtual Obj *inventory_get_food(Obj *container = 0) {
627 		return 0;
628 	}
629 	const CombatType *inventory_get_readied_object_combat_type(uint8 location);
630 	bool inventory_add_object(Obj *obj, Obj *container = 0, bool stack = true);
631 	bool inventory_add_object_nostack(Obj *obj, Obj *container = 0) {
632 		return inventory_add_object(obj, container, false);
633 	}
634 	void inventory_del_all_objs();
635 	bool inventory_remove_obj(Obj *obj, bool run_usecode = true);
636 	Obj *inventory_new_object(uint16 obj_n, uint32 qty, uint8 quality = 0);
637 	uint32 inventory_del_object(uint16 obj_n, uint32 qty, uint8 quality);
inventory_get_max_weight()638 	float inventory_get_max_weight() {
639 		return ((strength * 2));
640 	}
641 	float get_inventory_weight();
642 	float get_inventory_equip_weight();
643 	void inventory_drop_all();
644 	void all_items_to_container(Obj *container_obj, bool stack);
645 	bool can_carry_weight(Obj *obj);
646 	bool can_carry_weight(float obj_weight); // return from get_obj_weight()
647 	virtual bool can_carry_object(uint16 obj_n, uint32 qty = 0);
648 	virtual bool can_carry_object(Obj *obj);
649 
650 	virtual uint8 get_object_readiable_location(Obj *obj);
get_object_combat_type(uint16 objN)651 	virtual const CombatType *get_object_combat_type(uint16 objN) {
652 		return NULL;
653 	}
654 
655 	bool can_ready_obj(Obj *obj);
656 	bool add_readied_object(Obj *obj);
657 	void remove_readied_object(Obj *obj, bool run_usecode = true); // run_usecode to stop from running usecode twice or an infinite loop
658 	void remove_readied_object(uint8 location, bool run_usecode = true);
659 
660 	void remove_all_readied_objects();
661 	bool has_readied_objects();
662 	sint8 count_readied_objects(sint32 obj_n = -1, sint16 frame_n = -1, sint16 quality = -1);
663 
twitch()664 	virtual void twitch() {
665 		return;
666 	}
667 	bool push(Actor *pusher, uint8 where = ACTOR_PUSH_ANYWHERE);
668 
669 	Obj *make_obj();
get_obj_n()670 	uint16 get_obj_n() {
671 		return (obj_n);
672 	}
673 	virtual void clear();
674 	virtual bool morph(uint16 obj_n); // change actor type
675 
676 	bool get_schedule_location(MapCoord *loc);
677 	bool is_at_scheduled_location();
get_number_of_schedules()678 	int get_number_of_schedules() {
679 		return num_schedules;
680 	}
681 	Schedule *get_schedule(uint8 index);
will_not_talk()682 	virtual bool will_not_talk() {
683 		return false;
684 	}
685 	uint16 get_custom_tile_num(uint16 obj_num);
686 protected:
687 
688 	void loadSchedule(unsigned char *schedule_data, uint16 num);
689 	virtual bool updateSchedule(uint8 hour, bool teleport = false);
690 	uint16 getSchedulePos(uint8 hour);
691 // uint16 getSchedulePos(uint8 hour, uint8 day_of_week);
692 // inline uint16 Actor::getSchedulePos(uint8 hour);
693 
694 	void inventory_parse_readied_objects(); //this is used to initialise the readied_objects array on load.
695 
get_hand_combat_type()696 	virtual const CombatType *get_hand_combat_type() {
697 		return NULL;
698 	}
699 
set_ethereal(bool val)700 	virtual void set_ethereal(bool val) {
701 		ethereal = val;
702 	}
703 	virtual void print();
handle_lightsource(uint8 hour)704 	virtual void handle_lightsource(uint8 hour) {
705 		return;
706 	}
get_worktype_string(uint32 wt)707 	virtual const char *get_worktype_string(uint32 wt) {
708 		return NULL;
709 	}
710 
711 	Obj *find_body();
712 	uint16 get_tile_num(uint16 obj_num);
get_num_light_sources()713 	uint8 get_num_light_sources() {
714 		return light_source.size();
715 	}
716 
717 private:
718 
719 };
720 
721 const char *get_actor_alignment_str(uint8 alignment);
722 
723 } // End of namespace Nuvie
724 } // End of namespace Ultima
725 
726 #endif
727