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