1 /** 2 ** Monstinf.h - Information (about NPC's, really) from 'monster.dat'. 3 ** 4 ** Written: 8/13/01 - JSF 5 **/ 6 7 #ifndef INCL_MONSTINF 8 #define INCL_MONSTINF 1 9 10 /* 11 Copyright (C) 2000-2013 The Exult Team 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 <cassert> 30 #include <vector> 31 32 #include "baseinf.h" 33 #include "exult_constants.h" 34 35 class Shape_info; 36 class Shapes_vga_file; 37 38 /* 39 * An element from 'equip.dat', describing a monster's equipment: 40 */ 41 class Equip_element { 42 unsigned short shapenum = 0; // What to create, or 0 for nothing. 43 unsigned char probability = 0; // 0-100: probabilit of creation. 44 unsigned char quantity = 0; // # to create. 45 public: 46 friend class Monster_info; 47 friend class Monster_actor; set(int shnum,int prob,int quant)48 void set(int shnum, int prob, int quant) { 49 shapenum = shnum; 50 probability = prob; 51 quantity = quant; 52 } get_shapenum()53 int get_shapenum() const { 54 return shapenum; 55 } get_probability()56 int get_probability() const { 57 return probability; 58 } get_quantity()59 int get_quantity() const { 60 return quantity; 61 } 62 }; 63 64 /* 65 * A record from 'equip.dat' consists of 10 elements. 66 */ 67 class Equip_record { 68 Equip_element elements[10]; 69 public: 70 friend class Monster_info; 71 friend class Monster_actor; 72 // Set i'th element. set(int i,int shnum,int prob,int quant)73 void set(int i, int shnum, int prob, int quant) { 74 elements[i].set(shnum, prob, quant); 75 } get(int i)76 Equip_element &get(int i) { 77 assert(i >= 0 && i < 10); 78 return elements[i]; 79 } 80 }; 81 82 /* 83 * Monster info. from 'monsters.dat': 84 */ 85 class Monster_info : public Base_info { 86 static std::vector<Equip_record> equip; // ->equipment info. 87 static Monster_info default_info; // For shapes not found. 88 unsigned char strength; // Attributes. 89 unsigned char dexterity; 90 unsigned char intelligence; 91 unsigned char alignment; // Default alignment. 92 unsigned char combat; 93 unsigned char armor; // These are unarmed stats. 94 unsigned char weapon; 95 unsigned char reach; 96 unsigned char flags; // Defined below. 97 // The following are bits corresponding 98 // to Weapon_data::Damage_type. 99 unsigned char vulnerable, immune; 100 unsigned char equip_offset; // Offset in 'equip.dat' (1 based; 101 // if 0, there's none.) 102 short sfx; // Sound used when attacking. We *need* better sfx packs. 103 bool m_splits; // For slimes. 104 bool m_cant_die; 105 bool m_cant_yell; // Can't yell during combat. 106 bool m_cant_bleed; 107 108 bool m_poison_safe; // Can't be poisoned. 109 bool m_charm_safe; // Can't be charmed. 110 bool m_sleep_safe; // Can't be put to sleep. 111 bool m_paralysis_safe; // Can't be paralyzed. 112 bool m_curse_safe; // Can't be cursed. 113 bool m_power_safe; // As above 4 items, plus return of flag 13. 114 bool m_death_safe; // Return of flag 14. Immune to death spells? 115 bool m_int_b1; // May give XP; but what does it do??? 116 117 unsigned char m_attackmode; // Sets initial attack mode. 118 unsigned char m_byte13; // Unknown; Bits 3 through 7 of byte 13. 119 120 bool m_can_teleport; 121 bool m_can_summon; 122 bool m_can_be_invisible; 123 public: 124 friend class Shape_info; 125 friend class Monster_actor; 126 // Read in from file. 127 bool read(std::istream &in, int version, Exult_Game game); 128 // Write out. 129 void write(std::ostream &out, int shapenum, Exult_Game game); 130 enum { is_binary = 1, entry_size = 25 }; 131 static const Monster_info *get_default(); reserve_equip(int cnt)132 static void reserve_equip(int cnt) { 133 equip.reserve(cnt); 134 } add_equip(Equip_record & eq)135 static void add_equip(Equip_record &eq) { 136 equip.push_back(eq); 137 } get_equip_cnt()138 static int get_equip_cnt() { 139 return equip.size(); 140 } get_equip(int i)141 static Equip_record &get_equip(int i) { 142 assert(i >= 0 && static_cast<size_t>(i) < equip.size()); 143 return equip[i]; 144 } splits()145 bool splits() const { 146 return m_splits; 147 } set_splits(bool tf)148 void set_splits(bool tf) { 149 if (m_splits != tf) { 150 set_modified(true); 151 m_splits = tf; 152 } 153 } cant_die()154 bool cant_die() const { 155 return m_cant_die; 156 } set_cant_die(bool tf)157 void set_cant_die(bool tf) { 158 if (m_cant_die != tf) { 159 set_modified(true); 160 m_cant_die = tf; 161 } 162 } cant_yell()163 bool cant_yell() const { 164 return m_cant_yell; 165 } set_cant_yell(bool tf)166 void set_cant_yell(bool tf) { 167 if (m_cant_yell != tf) { 168 set_modified(true); 169 m_cant_yell = tf; 170 } 171 } cant_bleed()172 bool cant_bleed() const { 173 return m_cant_bleed; 174 } set_cant_bleed(bool tf)175 void set_cant_bleed(bool tf) { 176 if (m_cant_bleed != tf) { 177 set_modified(true); 178 m_cant_bleed = tf; 179 } 180 } poison_safe()181 bool poison_safe() const { 182 return m_poison_safe; 183 } set_poison_safe(bool tf)184 void set_poison_safe(bool tf) { 185 if (m_poison_safe != tf) { 186 set_modified(true); 187 m_poison_safe = tf; 188 } 189 } charm_safe()190 bool charm_safe() const { 191 return m_charm_safe; 192 } set_charm_safe(bool tf)193 void set_charm_safe(bool tf) { 194 if (m_charm_safe != tf) { 195 set_modified(true); 196 m_charm_safe = tf; 197 } 198 } sleep_safe()199 bool sleep_safe() const { 200 return m_sleep_safe; 201 } set_sleep_safe(bool tf)202 void set_sleep_safe(bool tf) { 203 if (m_sleep_safe != tf) { 204 set_modified(true); 205 m_sleep_safe = tf; 206 } 207 } paralysis_safe()208 bool paralysis_safe() const { 209 return m_paralysis_safe; 210 } set_paralysis_safe(bool tf)211 void set_paralysis_safe(bool tf) { 212 if (m_paralysis_safe != tf) { 213 set_modified(true); 214 m_paralysis_safe = tf; 215 } 216 } curse_safe()217 bool curse_safe() const { 218 return m_curse_safe; 219 } set_curse_safe(bool tf)220 void set_curse_safe(bool tf) { 221 if (m_curse_safe != tf) { 222 set_modified(true); 223 m_curse_safe = tf; 224 } 225 } power_safe()226 bool power_safe() const { 227 return m_power_safe; 228 } set_power_safe(bool tf)229 void set_power_safe(bool tf) { 230 if (m_power_safe != tf) { 231 set_modified(true); 232 m_power_safe = tf; 233 } 234 } death_safe()235 bool death_safe() const { 236 return m_death_safe; 237 } set_death_safe(bool tf)238 void set_death_safe(bool tf) { 239 if (m_death_safe != tf) { 240 set_modified(true); 241 m_death_safe = tf; 242 } 243 } get_int_b1()244 bool get_int_b1() const { 245 return m_int_b1; 246 } set_int_b1(bool tf)247 void set_int_b1(bool tf) { 248 if (m_int_b1 != tf) { 249 set_modified(true); 250 m_int_b1 = tf; 251 } 252 } get_byte13()253 unsigned char get_byte13() const { 254 return m_byte13; 255 } set_byte13(char c)256 void set_byte13(char c) { 257 if (m_byte13 != c) { 258 set_modified(true); 259 m_byte13 = c; 260 } 261 } get_attackmode()262 unsigned char get_attackmode() const { 263 return m_attackmode; 264 } set_attackmode(unsigned char c)265 void set_attackmode(unsigned char c) { 266 if (m_attackmode != c) { 267 set_modified(true); 268 m_attackmode = c; 269 } 270 } can_teleport()271 bool can_teleport() const { 272 return m_can_teleport; 273 } set_can_teleport(bool tf)274 void set_can_teleport(bool tf) { 275 if (m_can_teleport != tf) { 276 set_modified(true); 277 m_can_teleport = tf; 278 } 279 } can_summon()280 bool can_summon() const { 281 return m_can_summon; 282 } set_can_summon(bool tf)283 void set_can_summon(bool tf) { 284 if (m_can_summon != tf) { 285 set_modified(true); 286 m_can_summon = tf; 287 } 288 } can_be_invisible()289 bool can_be_invisible() const { 290 return m_can_be_invisible; 291 } set_can_be_invisible(bool tf)292 void set_can_be_invisible(bool tf) { 293 if (m_can_be_invisible != tf) { 294 set_modified(true); 295 m_can_be_invisible = tf; 296 } 297 } 298 // Get bits indicating 299 // Weapon_data::damage_type: get_vulnerable()300 unsigned char get_vulnerable() const { 301 return vulnerable; 302 } set_vulnerable(unsigned char v)303 void set_vulnerable(unsigned char v) { 304 if (vulnerable != v) { 305 set_modified(true); 306 vulnerable = v; 307 } 308 } get_immune()309 unsigned char get_immune() const { 310 return immune; 311 } set_immune(unsigned char v)312 void set_immune(unsigned char v) { 313 if (immune != v) { 314 set_modified(true); 315 immune = v; 316 } 317 } 318 enum Flags { 319 fly = 0, 320 swim = 1, 321 walk = 2, 322 ethereal = 3, // Can walk through walls. 323 no_body = 4, // Don't create body. 324 // 5: gazer, hook only. 325 start_invisible = 6, 326 see_invisible = 7 327 }; get_flags()328 unsigned char get_flags() const { // Get above set of flags. 329 return flags; 330 } set_flags(unsigned char f)331 void set_flags(unsigned char f) { 332 if (flags != f) { 333 set_modified(true); 334 flags = f; 335 } 336 } has_no_body()337 bool has_no_body() const { // No dead body? 338 return (flags >> no_body) & 1; 339 } get_strength()340 int get_strength() const { 341 return strength; 342 } get_dexterity()343 int get_dexterity() const { 344 return dexterity; 345 } get_intelligence()346 int get_intelligence() const { 347 return intelligence; 348 } get_alignment()349 int get_alignment() const { 350 return alignment; 351 } set_alignment(int a)352 void set_alignment(int a) { 353 if (alignment != a) { 354 set_modified(true); 355 alignment = a; 356 } 357 } get_combat()358 int get_combat() const { 359 return combat; 360 } get_armor()361 int get_armor() const { 362 return armor; 363 } get_weapon()364 int get_weapon() const { 365 return weapon; 366 } get_reach()367 int get_reach() const { 368 return reach; 369 } 370 void set_stats(int str, int dex, int intel, int cmb, int armour, 371 int wpn, int rch); get_equip_offset()372 int get_equip_offset() const { 373 return equip_offset; 374 } set_equip_offset(int o)375 void set_equip_offset(int o) { 376 if (equip_offset != o) { 377 set_modified(true); 378 equip_offset = o; 379 } 380 } get_hitsfx()381 short get_hitsfx() const { 382 return sfx; 383 } set_hitsfx(short s)384 void set_hitsfx(short s) { 385 if (sfx != s) { 386 set_modified(true); 387 sfx = s; 388 } 389 } get_info_flag()390 static int get_info_flag() { 391 return 8; 392 } 393 int get_base_xp_value() const; 394 }; 395 396 397 398 #endif 399