1 /** 2 ** Shapeinf.h: Info. about shapes read from various data files. 3 ** 4 ** Written: 4/29/99 - JSF 5 **/ 6 7 #ifndef INCL_SHAPEINF 8 #define INCL_SHAPEINF 1 9 10 /* 11 Copyright (C) 1998 Jeffrey S. Freedman 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License 15 as published by the Free Software Foundation; either version 2 16 of the License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 */ 27 28 #include <iosfwd> 29 #include <vector> 30 #include <map> 31 #include <algorithm> 32 #include <iostream> 33 #include "baseinf.h" 34 #include "utils.h" 35 36 class Armor_info; 37 class Weapon_info; 38 class Ammo_info; 39 class Monster_info; 40 class SFX_info; 41 class Animation_info; 42 class Explosion_info; 43 class Body_info; 44 class Paperdoll_npc; 45 class Paperdoll_item; 46 class Effective_hp_info; 47 class Frame_name_info; 48 class Frame_flags_info; 49 class Frame_usecode_info; 50 class Light_info; 51 class Warmth_info; 52 class Content_rules; 53 class Shapes_vga_file; 54 55 template <typename T, class Info, T Info::*data> 56 class Text_reader_functor; 57 template <typename T, class Info, T Info::*data1, T Info::*data2> 58 class Text_pair_reader_functor; 59 template <typename T, class Info, T Info::*data, int bit> 60 class Bit_text_reader_functor; 61 template <typename T, class Info, T Info::*data> 62 class Bit_field_text_reader_functor; 63 template <typename T, class Info, T Info::*data, unsigned pad> 64 class Binary_reader_functor; 65 template < typename T1, typename T2, class Info, 66 T1 Info::*data1, T2 Info::*data2, unsigned pad > 67 class Binary_pair_reader_functor; 68 template <typename T, class Info, T *Info::*data> 69 class Class_reader_functor; 70 template <typename T, class Info, std::vector<T> Info::*data> 71 class Vector_reader_functor; 72 template <class Info> 73 class Null_functor; 74 template <int flag, class Info> 75 class Patch_flags_functor; 76 77 class Gump_reader_functor; 78 class Ready_type_functor; 79 class Actor_flags_functor; 80 class Paperdoll_npc_functor; 81 82 template <int flag, class Info> 83 class Flag_check_functor; 84 template <int flag, typename T, class Info, T Info::*data> 85 class Text_writer_functor; 86 template <int flag, typename T, class Info, T Info::*data1, T Info::*data2> 87 class Text_pair_writer_functor; 88 template <int flag, typename T, class Info, T Info::*data, int bit> 89 class Bit_text_writer_functor; 90 template <int flag, typename T, class Info, T Info::*data> 91 class Bit_field_text_writer_functor; 92 template <int flag, typename T, class Info, T Info::*data, int pad> 93 class Binary_writer_functor; 94 template < int flag, typename T1, typename T2, class Info, 95 T1 Info::*data1, T2 Info::*data2, int pad > 96 class Binary_pair_writer_functor; 97 template <typename T, class Info, T *Info::*data> 98 class Class_writer_functor; 99 template <typename T, class Info, std::vector<T> Info::*data> 100 class Vector_writer_functor; 101 102 class Readytype_writer_functor; 103 104 enum Data_flag_bits { 105 tf_ready_type_flag = 0, 106 tf_gump_shape_flag, 107 tf_monster_food_flag, 108 tf_actor_flags_flag, 109 tf_mountain_top_flag, 110 tf_altready_type_flag, 111 tf_barge_type_flag, 112 tf_field_type_flag, 113 // ++++ Keep shape flags last! 114 tf_usecode_events_flag, 115 tf_is_body_flag, 116 tf_lightweight_flag, 117 tf_quantity_frames_flag, 118 tf_locked_flag, 119 tf_is_volatile_flag, 120 tf_jawbone_flag, 121 tf_mirror_flag, 122 tf_on_fire_flag, 123 tf_extradimensional_storage_flag 124 }; 125 enum Data_flag_names { 126 ready_type_flag = (1U << tf_ready_type_flag), 127 gump_shape_flag = (1U << tf_gump_shape_flag), 128 monster_food_flag = (1U << tf_monster_food_flag), 129 actor_flags_flag = (1U << tf_actor_flags_flag), 130 mountain_top_flag = (1U << tf_mountain_top_flag), 131 altready_type_flag = (1U << tf_altready_type_flag), 132 barge_type_flag = (1U << tf_barge_type_flag), 133 field_type_flag = (1U << tf_field_type_flag), 134 usecode_events_flag = (1U << tf_usecode_events_flag), 135 is_body_flag = (1U << tf_is_body_flag), 136 lightweight_flag = (1U << tf_lightweight_flag), 137 quantity_frames_flag = (1U << tf_quantity_frames_flag), 138 locked_flag = (1U << tf_locked_flag), 139 is_volatile_flag = (1U << tf_is_volatile_flag), 140 jawbone_flag = (1U << tf_jawbone_flag), 141 mirror_flag = (1U << tf_mirror_flag), 142 on_fire_flag = (1U << tf_on_fire_flag), 143 extradimensional_storage_flag = (1U << tf_extradimensional_storage_flag) 144 }; 145 146 /* 147 * This class contains information only about shapes from "shapes.vga". 148 */ 149 class Shape_info { 150 protected: 151 // For some non-class data (see Data_flag_names enum). 152 unsigned int modified_flags = 0; 153 unsigned int frompatch_flags = 0; 154 // For class data (to indicate an invalid entry should 155 // be written by ES). 156 unsigned int have_static_flags = 0; 157 unsigned char tfa[3] = {0}; // From "tfa.dat".+++++Keep for 158 // debugging, for now. 159 // 3D dimensions in tiles: 160 unsigned char dims[3] = {0}; // (x, y, z) 161 unsigned char weight = 0, volume = 0; // From "wgtvol.dat". 162 unsigned char shpdims[2] = {0}; // From "shpdims.dat". 163 unsigned char *weapon_offsets = nullptr; // From "wihh.dat": pixel offsets 164 // for drawing weapon in hand 165 Armor_info *armor = nullptr; // From armor.dat. 166 Weapon_info *weapon = nullptr; // From weapon.dat, if a weapon. 167 Ammo_info *ammo = nullptr; // From ammo.dat, if ammo. 168 Monster_info *monstinf = nullptr; // From monster.dat. 169 SFX_info *sfxinf = nullptr; 170 Animation_info *aniinf = nullptr; 171 Explosion_info *explosion = nullptr; 172 Body_info *body = nullptr; 173 Paperdoll_npc *npcpaperdoll = nullptr; 174 // These vectors should be totally ordered by the strict-weak 175 // order operator defined for the classes. 176 std::vector<Paperdoll_item> objpaperdoll; 177 std::vector<Effective_hp_info> hpinf; 178 std::vector<Frame_name_info> nameinf; 179 std::vector<Frame_flags_info> frflagsinf; 180 std::vector<Frame_usecode_info> frucinf; 181 std::vector<Light_info> lightinf; 182 std::vector<Warmth_info> warminf; 183 std::vector<Content_rules> cntrules; 184 short gump_shape = -1; // From container.dat. 185 short gump_font = -1; // From container.dat v2+. 186 short monster_food = -1; 187 unsigned short shape_flags = 0; 188 unsigned char mountain_top = 0; 189 unsigned char barge_type = 0; 190 unsigned char actor_flags = 0; 191 signed char field_type = -1; 192 unsigned char ready_type = 0xff; // From "ready.dat": where item can be worn. 193 unsigned char alt_ready1 = 0xff; // Alternate spot where item can be worn. 194 unsigned char alt_ready2 = 0xff; // Second alternate spot where item can be worn. 195 bool spell_flag = false; // Flagged as spell in 'ready.dat'. 196 bool occludes_flag = false; // Flagged in 'occlude.dat'. Roof. set_tfa_data()197 void set_tfa_data() { // Set fields from tfa. 198 dims[0] = static_cast<unsigned char>(1 + (tfa[2] & 7)); 199 dims[1] = static_cast<unsigned char>(1 + ((tfa[2] >> 3) & 7)); 200 dims[2] = static_cast<unsigned char>(tfa[0] >> 5); 201 } 202 // Set/clear tfa bit. set_tfa(int i,int bit,bool tf)203 void set_tfa(int i, int bit, bool tf) { 204 tfa[i] = static_cast<unsigned char>(tf ? 205 (tfa[i] | (1 << bit)) : (tfa[i]&~(1 << bit))); 206 } 207 public: 208 enum Actor_flags { 209 cold_immune = 0, 210 doesnt_eat, 211 teleports, 212 summons, 213 turns_invisible, 214 armageddon_safe, 215 quake_walk, 216 goblin 217 }; 218 enum Shape_flags { 219 usecode_events = 0, 220 is_body, 221 lightweight, 222 quantity_frames, 223 locked, 224 is_volatile, 225 jawbone, 226 mirror, 227 on_fire, 228 extradimensional_storage 229 }; 230 enum Mountain_tops { 231 not_mountain_top = 0, 232 normal_mountain_top, 233 snow_mountain_top 234 }; 235 enum Barge_types { 236 barge_generic = 0, 237 barge_raft, 238 barge_seat, 239 barge_sails, 240 barge_wheel, 241 barge_draftanimal, 242 barge_turtle 243 }; 244 enum Field_types { 245 no_field = -1, 246 fire_field = 0, 247 sleep_field, 248 poison_field, 249 caltrops 250 }; 251 friend class Shapes_vga_file; // Class that reads in data. 252 253 template <typename T, class Info, T Info::*data> 254 friend class Text_reader_functor; 255 template <typename T, class Info, T Info::*data1, T Info::*data2> 256 friend class Text_pair_reader_functor; 257 template <typename T, class Info, T Info::*data, int bit> 258 friend class Bit_text_reader_functor; 259 template <typename T, class Info, T Info::*data> 260 friend class Bit_field_text_reader_functor; 261 template <typename T, class Info, T Info::*data, unsigned pad> 262 friend class Binary_reader_functor; 263 template < typename T1, typename T2, class Info, 264 T1 Info::*data1, T2 Info::*data2, unsigned pad > 265 friend class Binary_pair_reader_functor; 266 template <typename T, class Info, T *Info::*data> 267 friend class Class_reader_functor; 268 template <typename T, class Info, std::vector<T> Info::*data> 269 friend class Vector_reader_functor; 270 template <class Info> 271 friend class Null_functor; 272 template <int flag, class Info> 273 friend class Patch_flags_functor; 274 275 friend class Gump_reader_functor; 276 friend class Ready_type_functor; 277 friend class Actor_flags_functor; 278 friend class Paperdoll_npc_functor; 279 280 template <int flag, class Info> 281 friend class Flag_check_functor; 282 template <int flag, typename T, class Info, T Info::*data> 283 friend class Text_writer_functor; 284 template <int flag, typename T, class Info, T Info::*data1, T Info::*data2> 285 friend class Text_pair_writer_functor; 286 template <int flag, typename T, class Info, T Info::*data, int bit> 287 friend class Bit_text_writer_functor; 288 template <int flag, typename T, class Info, T Info::*data> 289 friend class Bit_field_text_writer_functor; 290 template <int flag, typename T, class Info, T Info::*data, int pad> 291 friend class Binary_writer_functor; 292 template < int flag, typename T1, typename T2, class Info, 293 T1 Info::*data1, T2 Info::*data2, int pad > 294 friend class Binary_pair_writer_functor; 295 template <typename T, class Info, T *Info::*data> 296 friend class Class_writer_functor; 297 template <typename T, class Info, std::vector<T> Info::*data> 298 friend class Vector_writer_functor; 299 300 friend class Readytype_writer_functor; 301 302 Shape_info(); 303 // This copy constructor and assignment operator intentionally cause 304 // errors. 305 Shape_info(const Shape_info &other); 306 Shape_info &operator = (const Shape_info &other); 307 ~Shape_info(); 308 void copy(const Shape_info &inf2, bool skip_dolls = false); 309 get_weight()310 int get_weight() const { // Get weight, volume. 311 return weight; 312 } get_volume()313 int get_volume() const { 314 return volume; 315 } set_weight_volume(int w,int v)316 void set_weight_volume(int w, int v) { 317 weight = static_cast<unsigned char>(w); 318 volume = static_cast<unsigned char>(v); 319 } 320 321 int get_armor() const; 322 int get_armor_immunity() const; 323 324 int get_explosion_sprite() const; 325 int get_explosion_sfx() const; 326 327 int get_body_shape() const; 328 int get_body_frame() const; 329 has_weapon_info()330 bool has_weapon_info() const { 331 return weapon != nullptr; 332 } 333 const Weapon_info *get_weapon_info_safe() const; get_weapon_info()334 const Weapon_info *get_weapon_info() const { 335 return weapon; 336 } 337 Weapon_info *set_weapon_info(bool tf); 338 has_ammo_info()339 bool has_ammo_info() const { 340 return ammo != nullptr; 341 } 342 const Ammo_info *get_ammo_info_safe() const; get_ammo_info()343 const Ammo_info *get_ammo_info() const { 344 return ammo; 345 } 346 Ammo_info *set_ammo_info(bool tf); 347 has_armor_info()348 bool has_armor_info() const { 349 return armor != nullptr; 350 } get_armor_info()351 const Armor_info *get_armor_info() const { 352 return armor; 353 } 354 Armor_info *set_armor_info(bool tf); 355 has_monster_info()356 bool has_monster_info() const { 357 return monstinf != nullptr; 358 } 359 const Monster_info *get_monster_info_safe() const; get_monster_info()360 const Monster_info *get_monster_info() const { 361 return monstinf; 362 } 363 Monster_info *set_monster_info(bool tf); 364 has_npc_paperdoll_info()365 bool has_npc_paperdoll_info() const { 366 return npcpaperdoll != nullptr; 367 } get_npc_paperdoll()368 const Paperdoll_npc *get_npc_paperdoll() const { 369 return npcpaperdoll; 370 } 371 Paperdoll_npc *set_npc_paperdoll_info(bool tf); 372 const Paperdoll_npc *get_npc_paperdoll_safe(bool sex) const; 373 has_sfx_info()374 bool has_sfx_info() const { 375 return sfxinf != nullptr; 376 } get_sfx_info()377 const SFX_info *get_sfx_info() const { 378 return sfxinf; 379 } 380 SFX_info *set_sfx_info(bool tf); 381 has_explosion_info()382 bool has_explosion_info() const { 383 return explosion != nullptr; 384 } get_explosion_info()385 const Explosion_info *get_explosion_info() const { 386 return explosion; 387 } 388 Explosion_info *set_explosion_info(bool tf); 389 has_animation_info()390 bool has_animation_info() const { 391 return aniinf != nullptr; 392 } get_animation_info()393 const Animation_info *get_animation_info() const { 394 return aniinf; 395 } 396 const Animation_info *get_animation_info_safe(int shnum, int nframes); 397 Animation_info *set_animation_info(bool tf); 398 has_body_info()399 bool has_body_info() const { 400 return body != nullptr; 401 } get_body_info()402 const Body_info *get_body_info() const { 403 return body; 404 } 405 Body_info *set_body_info(bool tf); 406 407 bool has_paperdoll_info() const; get_paperdoll_info()408 const std::vector<Paperdoll_item> &get_paperdoll_info() const { 409 return objpaperdoll; 410 } 411 std::vector<Paperdoll_item> &set_paperdoll_info(bool tf); 412 void clean_invalid_paperdolls(); 413 void clear_paperdoll_info(); 414 void add_paperdoll_info(Paperdoll_item &add); 415 const Paperdoll_item *get_item_paperdoll(int frame, int spot) const; is_object_allowed(int frame,int spot)416 bool is_object_allowed(int frame, int spot) const { 417 return get_item_paperdoll(frame, spot) != nullptr; 418 } 419 420 bool has_content_rules() const; get_content_rules()421 const std::vector<Content_rules> &get_content_rules() const { 422 return cntrules; 423 } 424 std::vector<Content_rules> &set_content_rules(bool tf); 425 void clean_invalid_content_rules(); 426 void clear_content_rules(); 427 void add_content_rule(Content_rules &add); 428 bool is_shape_accepted(int shape) const; 429 430 bool has_effective_hp_info() const; get_effective_hp_info()431 const std::vector<Effective_hp_info> &get_effective_hp_info() const { 432 return hpinf; 433 } 434 std::vector<Effective_hp_info> &set_effective_hp_info(bool tf); 435 void clean_invalid_hp_info(); 436 void clear_effective_hp_info(); 437 void add_effective_hp_info(Effective_hp_info &add); 438 int get_effective_hps(int frame, int quality) const; 439 440 bool has_frame_name_info() const; get_frame_name_info()441 const std::vector<Frame_name_info> &get_frame_name_info() const { 442 return nameinf; 443 } 444 std::vector<Frame_name_info> &set_frame_name_info(bool tf); 445 void clean_invalid_name_info(); 446 void clear_frame_name_info(); 447 void add_frame_name_info(Frame_name_info &add); 448 const Frame_name_info *get_frame_name(int frame, int quality) const; 449 450 bool has_frame_usecode_info() const; get_frame_usecode_info()451 const std::vector<Frame_usecode_info> &get_frame_usecode_info() const { 452 return frucinf; 453 } 454 std::vector<Frame_usecode_info> &set_frame_usecode_info(bool tf); 455 void clean_invalid_usecode_info(); 456 void clear_frame_usecode_info(); 457 void add_frame_usecode_info(Frame_usecode_info &add); 458 const Frame_usecode_info *get_frame_usecode(int frame, int quality) const; 459 460 bool has_frame_flags() const; get_frame_flags()461 const std::vector<Frame_flags_info> &get_frame_flags() const { 462 return frflagsinf; 463 } 464 std::vector<Frame_flags_info> &set_frame_flags(bool tf); 465 void clean_invalid_frame_flags(); 466 void clear_frame_flags(); 467 void add_frame_flags(Frame_flags_info &add); 468 int get_object_flags(int frame, int qual) const; has_object_flag(int frame,int qual,int p)469 bool has_object_flag(int frame, int qual, int p) const { 470 return (get_object_flags(frame, qual) & (1 << p)) != 0; 471 } 472 473 bool has_light_info() const; get_light_info()474 const std::vector<Light_info> &get_light_info() const { 475 return lightinf; 476 } 477 std::vector<Light_info> &set_light_info(bool tf); 478 void clean_invalid_light_info(); 479 void clear_light_info(); 480 void add_light_info(Light_info &add); 481 int get_object_light(int frame) const; 482 483 bool has_warmth_info() const; get_warmth_info()484 const std::vector<Warmth_info> &get_warmth_info() const { 485 return warminf; 486 } 487 std::vector<Warmth_info> &set_warmth_info(bool tf); 488 void clean_invalid_warmth_info(); 489 void clear_warmth_info(); 490 void add_warmth_info(Warmth_info &add); 491 int get_object_warmth(int frame) const; 492 get_monster_food()493 int get_monster_food() const { 494 return monster_food; 495 } set_monster_food(int sh)496 void set_monster_food(int sh) { 497 if (monster_food != static_cast<short>(sh)) { 498 modified_flags |= monster_food_flag; 499 monster_food = static_cast<short>(sh); 500 } 501 } 502 get_mountain_top_type()503 int get_mountain_top_type() const { 504 return mountain_top; 505 } set_mountain_top(int sh)506 void set_mountain_top(int sh) { 507 if (mountain_top != static_cast<unsigned char>(sh)) { 508 modified_flags |= mountain_top_flag; 509 mountain_top = static_cast<unsigned char>(sh); 510 } 511 } 512 get_barge_type()513 int get_barge_type() const { 514 return barge_type; 515 } set_barge_type(int sh)516 void set_barge_type(int sh) { 517 if (barge_type != static_cast<unsigned char>(sh)) { 518 modified_flags |= barge_type_flag; 519 barge_type = static_cast<unsigned char>(sh); 520 } 521 } 522 get_field_type()523 int get_field_type() const { 524 return field_type; 525 } set_field_type(int sh)526 void set_field_type(int sh) { 527 if (field_type != static_cast<signed char>(sh)) { 528 modified_flags |= field_type_flag; 529 field_type = static_cast<signed char>(sh); 530 } 531 } 532 get_gump_shape()533 int get_gump_shape() const { 534 return gump_shape; 535 } get_gump_font()536 int get_gump_font() const { 537 return gump_font; 538 } set_gump_data(int sh,int fnt)539 void set_gump_data(int sh, int fnt) { 540 if (gump_shape != static_cast<short>(sh) 541 || gump_font != static_cast<short>(sh)) { 542 modified_flags |= gump_shape_flag; 543 gump_shape = static_cast<short>(sh); 544 gump_font = static_cast<short>(fnt); 545 } 546 } 547 get_shape_flags()548 unsigned short get_shape_flags() const { 549 return shape_flags; 550 } set_shape_flags(unsigned short flags)551 void set_shape_flags(unsigned short flags) { 552 if (shape_flags != flags) { 553 int diff = (shape_flags ^ flags) * usecode_events_flag; 554 modified_flags |= diff; 555 shape_flags = flags; 556 } 557 } get_shape_flag(int tf)558 bool get_shape_flag(int tf) const { 559 return (shape_flags & (1U << tf)) != 0; 560 } set_shape_flag(int tf,int mod)561 void set_shape_flag(int tf, int mod) { 562 if (!(shape_flags & (1U << tf))) { 563 modified_flags |= (1U << mod); 564 shape_flags |= (1U << tf); 565 } 566 } clear_shape_flag(int tf,int mod)567 void clear_shape_flag(int tf, int mod) { 568 if (shape_flags & (1U << tf)) { 569 modified_flags |= (1U << mod); 570 shape_flags &= ~(1U << tf); 571 } 572 } 573 has_usecode_events()574 bool has_usecode_events() const { 575 return get_shape_flag(usecode_events); 576 } is_body_shape()577 bool is_body_shape() const { 578 return get_shape_flag(is_body); 579 } is_lightweight()580 bool is_lightweight() const { 581 return get_shape_flag(lightweight); 582 } has_quantity_frames()583 bool has_quantity_frames() const { 584 return get_shape_flag(quantity_frames); 585 } is_container_locked()586 bool is_container_locked() const { 587 return get_shape_flag(locked); 588 } is_explosive()589 bool is_explosive() const { 590 return get_shape_flag(is_volatile); 591 } is_jawbone()592 bool is_jawbone() const { 593 return get_shape_flag(jawbone); 594 } is_mirror()595 bool is_mirror() const { 596 return get_shape_flag(mirror); 597 } is_on_fire()598 bool is_on_fire() const { 599 return get_shape_flag(on_fire); 600 } has_extradimensional_storage()601 bool has_extradimensional_storage() const { 602 return get_shape_flag(extradimensional_storage); 603 } 604 get_actor_flags()605 unsigned char get_actor_flags() const { 606 return actor_flags; 607 } set_actor_flags(char flags)608 void set_actor_flags(char flags) { 609 if (actor_flags != flags) { 610 modified_flags |= actor_flags_flag; 611 actor_flags = flags; 612 } 613 } get_actor_flag(int tf)614 bool get_actor_flag(int tf) const { 615 return (actor_flags & (1 << tf)) != 0; 616 } set_actor_flag(int tf)617 void set_actor_flag(int tf) { 618 if (!(actor_flags & (1 << tf))) { 619 modified_flags |= actor_flags_flag; 620 actor_flags |= (1U << tf); 621 } 622 } clear_actor_flag(int tf)623 void clear_actor_flag(int tf) { 624 if (actor_flags & (1 << tf)) { 625 modified_flags |= actor_flags_flag; 626 actor_flags &= ~(1U << tf); 627 } 628 } 629 is_cold_immune()630 bool is_cold_immune() const { 631 return get_actor_flag(cold_immune); 632 } does_not_eat()633 bool does_not_eat() const { 634 return get_actor_flag(doesnt_eat); 635 } can_teleport()636 bool can_teleport() const { 637 return get_actor_flag(teleports); 638 } can_summon()639 bool can_summon() const { 640 return get_actor_flag(summons); 641 } can_be_invisible()642 bool can_be_invisible() const { 643 return get_actor_flag(turns_invisible); 644 } survives_armageddon()645 bool survives_armageddon() const { 646 return get_actor_flag(armageddon_safe); 647 } quake_on_walk()648 bool quake_on_walk() const { 649 return get_actor_flag(quake_walk); 650 } is_goblin()651 bool is_goblin() const { 652 return get_actor_flag(goblin); 653 } 654 // Get tile dims., flipped for 655 // reflected (bit 5) frames. get_3d_xtiles(unsigned int framenum)656 int get_3d_xtiles(unsigned int framenum) const { 657 return dims[(framenum >> 5) & 1]; 658 } get_3d_ytiles(unsigned int framenum)659 int get_3d_ytiles(unsigned int framenum) const { 660 return dims[1 ^ ((framenum >> 5) & 1)]; 661 } get_3d_height()662 int get_3d_height() const { // Height (in lifts?). 663 return dims[2]; 664 } 665 void set_3d(int xt, int yt, int zt); get_tfa(int i)666 unsigned char get_tfa(int i) const { // For debugging: 667 return tfa[i]; 668 } has_sfx()669 bool has_sfx() const { // Has a sound effect (guessing). 670 return (tfa[0] & (1 << 0)) != 0; 671 } set_sfx(bool tf)672 void set_sfx(bool tf) { 673 set_tfa(0, 0, tf); 674 } has_strange_movement()675 bool has_strange_movement() const { // Slimes, sea monsters. 676 return (tfa[0] & (1 << 1)) != 0; 677 } set_strange_movement(bool tf)678 void set_strange_movement(bool tf) { 679 set_tfa(0, 1, tf); 680 } is_animated()681 bool is_animated() const { 682 return (tfa[0] & (1 << 2)) != 0; 683 } set_animated(bool tf)684 void set_animated(bool tf) { 685 set_tfa(0, 2, tf); 686 } is_solid()687 bool is_solid() const { // Guessing. Means can't walk through. 688 return (tfa[0] & (1 << 3)) != 0; 689 } set_solid(bool tf)690 void set_solid(bool tf) { 691 set_tfa(0, 3, tf); 692 } is_water()693 bool is_water() const { // Guessing. 694 return (tfa[0] & (1 << 4)) != 0; 695 } set_water(bool tf)696 void set_water(bool tf) { 697 set_tfa(0, 4, tf); 698 } is_poisonous()699 bool is_poisonous() const { // Swamps. Applies to tiles. 700 return (tfa[1] & (1 << 4)) != 0; 701 } is_field()702 bool is_field() const { // Applies to Game_objects?? 703 return (tfa[1] & (1 << 4)) != 0; 704 } set_field(bool tf)705 void set_field(bool tf) { 706 set_tfa(1, 4, tf); 707 } is_door()708 bool is_door() const { 709 return (tfa[1] & (1 << 5)) != 0; 710 } set_door(bool tf)711 void set_door(bool tf) { 712 set_tfa(1, 5, tf); 713 } is_barge_part()714 bool is_barge_part() const { 715 return (tfa[1] & (1 << 6)) != 0; 716 } set_barge_part(bool tf)717 void set_barge_part(bool tf) { 718 set_tfa(1, 6, tf); 719 } is_transparent()720 bool is_transparent() const { // ?? 721 return (tfa[1] & (1 << 7)) != 0; 722 } set_transparent(bool tf)723 void set_transparent(bool tf) { 724 set_tfa(1, 7, tf); 725 } is_light_source()726 bool is_light_source() const { 727 return (tfa[2] & (1 << 6)) != 0; 728 } set_light_source(bool tf)729 void set_light_source(bool tf) { 730 set_tfa(2, 6, tf); 731 } has_translucency()732 bool has_translucency() const { 733 return (tfa[2] & (1 << 7)) != 0; 734 } set_translucency(bool tf)735 void set_translucency(bool tf) { 736 set_tfa(2, 7, tf); 737 } is_xobstacle()738 bool is_xobstacle() const { // Obstacle in x-dir.??? 739 return (shpdims[1] & 1) != 0; 740 } is_yobstacle()741 bool is_yobstacle() const { // Obstacle in y-dir.??? 742 return (shpdims[0] & 1) != 0; 743 } set_obstacle(bool x,bool y)744 void set_obstacle(bool x, bool y) { 745 shpdims[1] = x ? (shpdims[1] | 1) : (shpdims[1]&~1); 746 shpdims[0] = y ? (shpdims[0] | 1) : (shpdims[0]&~1); 747 } 748 /* 749 * TFA[1][b0-b3] seems to indicate object types: 750 */ 751 enum Shape_class { 752 unusable = 0, // Trees. 753 quality = 2, 754 quantity = 3, // Can have more than 1: coins, arrs. 755 has_hp = 4, // Breakable items (if hp != 0, that is) 756 quality_flags = 5, // Item quality is set of flags: 757 // Bit 3 = okay-to-take. 758 container = 6, 759 hatchable = 7, // Eggs, traps, moongates. 760 spellbook = 8, 761 barge = 9, 762 virtue_stone = 11, 763 monster = 12, // Non-human's. 764 human = 13, // Human NPC's. 765 building = 14 // Roof, window, mountain. 766 }; get_shape_class()767 Shape_class get_shape_class() const { 768 return static_cast<Shape_class>(tfa[1] & 15); 769 } set_shape_class(Shape_class c)770 void set_shape_class(Shape_class c) { 771 tfa[1] = (tfa[1]&~15) | static_cast<int>(c); 772 } is_npc()773 bool is_npc() const { 774 Shape_class c = get_shape_class(); 775 return c == human || c == monster; 776 } has_quantity()777 bool has_quantity() const { 778 return get_shape_class() == quantity; 779 } has_quality_flags()780 bool has_quality_flags() const { // Might be more... 781 return get_shape_class() == quality_flags; 782 } has_quality()783 bool has_quality() const { 784 Shape_class c = get_shape_class(); 785 return c == 2 || c == 6 || c == 7 || c == 11 || c == 12 || c == 13; 786 // return qual[(int) c]; 787 } occludes()788 bool occludes() const { 789 return occludes_flag; 790 } set_occludes(bool tf)791 void set_occludes(bool tf) { 792 occludes_flag = tf; 793 } get_ready_type()794 unsigned char get_ready_type() const { 795 return ready_type; 796 } set_ready_type(unsigned char t)797 void set_ready_type(unsigned char t) { 798 if (ready_type != t) { 799 modified_flags |= ready_type_flag; 800 ready_type = t; 801 } 802 } is_spell()803 bool is_spell() const { 804 return spell_flag; 805 } set_is_spell(bool tf)806 void set_is_spell(bool tf) { 807 if (spell_flag != tf) { 808 modified_flags |= ready_type_flag; 809 spell_flag = tf; 810 } 811 } get_alt_ready1()812 unsigned char get_alt_ready1() const { 813 return alt_ready1; 814 } get_alt_ready2()815 unsigned char get_alt_ready2() const { 816 return alt_ready2; 817 } set_alt_ready(unsigned char t1,unsigned char t2)818 void set_alt_ready(unsigned char t1, unsigned char t2) { 819 if (alt_ready1 != t1 || alt_ready2 != t2) { 820 modified_flags |= altready_type_flag; 821 alt_ready1 = t1; 822 alt_ready2 = t2; 823 } 824 } 825 // Sets x to 255 if there is no weapon offset get_weapon_offset(int frame,unsigned char & x,unsigned char & y)826 void get_weapon_offset(int frame, unsigned char &x, unsigned char &y) const { 827 if (!weapon_offsets) { 828 x = 255; 829 y = 255; 830 } else { 831 // x could be 255 (see read_info()) 832 x = weapon_offsets[frame * 2]; 833 y = weapon_offsets[frame * 2 + 1]; 834 } 835 } 836 void set_weapon_offset(int frame, unsigned char x, unsigned char y); 837 int get_rotated_frame(int curframe, int quads) const; 838 }; 839 840 #endif 841