PageRenderTime 34ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/init1.c

https://bitbucket.org/ekolis/jackband
C | 4460 lines | 2504 code | 908 blank | 1048 comment | 1277 complexity | f86b0fd1a926979ee1ee65e5a39c5449 MD5 | raw file
  1. /*
  2. * File: init1.c
  3. * Purpose: Parsing the lib/edit/ files into data structures.
  4. *
  5. * Copyright (c) 1997 Ben Harrison
  6. *
  7. * This work is free software; you can redistribute it and/or modify it
  8. * under the terms of either:
  9. *
  10. * a) the GNU General Public License as published by the Free Software
  11. * Foundation, version 2, or
  12. *
  13. * b) the "Angband licence":
  14. * This software may be copied and distributed for educational, research,
  15. * and not for profit purposes provided that this copyright and statement
  16. * are included in all such copies. Other copyrights may also apply.
  17. */
  18. #include "angband.h"
  19. #include "object/tvalsval.h"
  20. /*
  21. * This file is used to initialize various variables and arrays for the
  22. * Angband game. Note the use of "fd_read()" and "fd_write()" to bypass
  23. * the common limitation of "read()" and "write()" to only 32767 bytes
  24. * at a time.
  25. *
  26. * Several of the arrays for Angband are built from "template" files in
  27. * the "lib/file" directory, from which quick-load binary "image" files
  28. * are constructed whenever they are not present in the "lib/data"
  29. * directory, or if those files become obsolete, if we are allowed.
  30. *
  31. * Warning -- the "ascii" file parsers use a minor hack to collect the
  32. * name and text information in a single pass. Thus, the game will not
  33. * be able to load any template file with more than 20K of names or 60K
  34. * of text, even though technically, up to 64K should be legal.
  35. *
  36. * The code could actually be removed and placed into a "stand-alone"
  37. * program, but that feels a little silly, especially considering some
  38. * of the platforms that we currently support.
  39. */
  40. #include "effects.h"
  41. #include "monster/constants.h"
  42. #include "init.h"
  43. /*** Helper arrays for parsing ascii template files ***/
  44. /* Use a slightly unusual include method to create effect_list[] */
  45. static const char *effect_list[] =
  46. {
  47. #define EFFECT(x, y, r, z) #x,
  48. #include "list-effects.h"
  49. #undef EFFECT
  50. };
  51. /*
  52. * Monster blow methods
  53. */
  54. static const char *r_info_blow_method[] =
  55. {
  56. #define RBM(a, b) #a,
  57. #include "list-blow-methods.h"
  58. #undef RBM
  59. NULL
  60. };
  61. /*
  62. * Monster blow effects
  63. */
  64. static const char *r_info_blow_effect[] =
  65. {
  66. #define RBE(a, b) #a,
  67. #include "list-blow-effects.h"
  68. #undef RBE
  69. NULL
  70. };
  71. /*
  72. * Monster race flags
  73. */
  74. static const char *r_info_flags[] =
  75. {
  76. #define RF(a, b) #a,
  77. #include "list-mon-flags.h"
  78. #undef RF
  79. NULL
  80. };
  81. /*
  82. * Monster (race) spell flags
  83. */
  84. static const char *r_info_spell_flags[] =
  85. {
  86. #define RSF(a, b) #a,
  87. #include "list-mon-spells.h"
  88. #undef RSF
  89. NULL
  90. };
  91. /*
  92. * Object (kind) flags
  93. */
  94. static const char *k_info_flags[] =
  95. {
  96. #define OF(a, b) #a,
  97. #include "list-object-flags.h"
  98. #undef OF
  99. NULL
  100. };
  101. /*
  102. * Player race and class flags
  103. */
  104. static const char *player_info_flags[] =
  105. {
  106. #define PF(a, b) #a,
  107. #include "list-player-flags.h"
  108. #undef PF
  109. NULL
  110. };
  111. /*
  112. * Terrain feature flags
  113. */
  114. static const char *f_info_flags[] =
  115. {
  116. "PWALK",
  117. "PPASS",
  118. "MWALK",
  119. "MPASS",
  120. "LOOK",
  121. "DIG",
  122. "DOOR",
  123. "EXIT_UP",
  124. "EXIT_DOWN",
  125. "PERM",
  126. "TRAP",
  127. "SHOP",
  128. "HIDDEN",
  129. "BORING",
  130. NULL
  131. };
  132. /*** Initialize from ascii template files ***/
  133. /*
  134. * Initialize an "*_info" array, by parsing an ascii "template" file
  135. */
  136. errr init_info_txt(ang_file *fp, char *buf, header *head,
  137. parse_info_txt_func parse_info_txt_line)
  138. {
  139. errr err;
  140. /* Not ready yet */
  141. bool okay = FALSE;
  142. /* Just before the first record */
  143. error_idx = -1;
  144. /* Just before the first line */
  145. error_line = 0;
  146. /* Prepare the "fake" stuff */
  147. head->name_size = 0;
  148. head->text_size = 0;
  149. /* Parse */
  150. while (file_getl(fp, buf, 1024))
  151. {
  152. /* Advance the line number */
  153. error_line++;
  154. /* Skip comments and blank lines */
  155. if (!buf[0] || (buf[0] == '#')) continue;
  156. /* Verify correct "colon" format */
  157. if (buf[1] != ':') return (PARSE_ERROR_MISSING_COLON);
  158. /* Hack -- Process 'V' for "Version" */
  159. if (buf[0] == 'V')
  160. {
  161. int v1, v2, v3;
  162. /* Scan for the values */
  163. if ((3 != sscanf(buf+2, "%d.%d.%d", &v1, &v2, &v3)) ||
  164. (v1 != head->v_major) ||
  165. (v2 != head->v_minor) ||
  166. (v3 != head->v_patch))
  167. {
  168. #if 0
  169. return (PARSE_ERROR_OBSOLETE_FILE);
  170. #endif
  171. }
  172. /* Okay to proceed */
  173. okay = TRUE;
  174. /* Continue */
  175. continue;
  176. }
  177. /* No version yet */
  178. if (!okay) return (PARSE_ERROR_OBSOLETE_FILE);
  179. /* Parse the line */
  180. if ((err = (*parse_info_txt_line)(buf, head)) != 0)
  181. return (err);
  182. }
  183. /* Complete the "name" and "text" sizes */
  184. if (head->name_size) head->name_size++;
  185. if (head->text_size) head->text_size++;
  186. /* No version yet */
  187. if (!okay) return (PARSE_ERROR_OBSOLETE_FILE);
  188. /* Success */
  189. return (0);
  190. }
  191. /*
  192. * Add a text to the text-storage and store offset to it.
  193. *
  194. * Returns FALSE when there isn't enough space available to store
  195. * the text.
  196. */
  197. static bool add_text(u32b *offset, header *head, cptr buf)
  198. {
  199. size_t len = strlen(buf);
  200. /* Hack -- Verify space */
  201. if (head->text_size + len + 8 > z_info->fake_text_size)
  202. return (FALSE);
  203. /* New text? */
  204. if (*offset == 0)
  205. {
  206. /* Advance and save the text index */
  207. *offset = ++head->text_size;
  208. }
  209. /* Append chars to the text */
  210. my_strcpy(head->text_ptr + head->text_size, buf, len + 1);
  211. /* Advance the index */
  212. head->text_size += len;
  213. /* Success */
  214. return (TRUE);
  215. }
  216. /*
  217. * Add a name to the name-storage and return an offset to it.
  218. *
  219. * Returns 0 when there isn't enough space available to store
  220. * the name.
  221. */
  222. static u32b add_name(header *head, cptr buf)
  223. {
  224. u32b index;
  225. size_t len = strlen(buf);
  226. /* Hack -- Verify space */
  227. if (head->name_size + len + 8 > z_info->fake_name_size)
  228. return (0);
  229. /* Advance and save the name index */
  230. index = ++head->name_size;
  231. /* Append chars to the names */
  232. my_strcpy(head->name_ptr + head->name_size, buf, len + 1);
  233. /* Advance the index */
  234. head->name_size += len;
  235. /* Return the name index */
  236. return (index);
  237. }
  238. /*
  239. * Grab one flag from a textual string
  240. */
  241. static errr grab_one_flag(u32b *flags, cptr names[], cptr what)
  242. {
  243. int i;
  244. /* Check flags */
  245. for (i = 0; i < 32 && names[i]; i++)
  246. {
  247. if (streq(what, names[i]))
  248. {
  249. *flags |= (1L << i);
  250. return (0);
  251. }
  252. }
  253. return (-1);
  254. }
  255. /*
  256. * This function reads a value of the form "1+2d3M4"
  257. *
  258. * - The 1 is a constant base value.
  259. * - The 2d3 is a dice roll, to be applied with damroll(). The number of dice
  260. * is optional, and if not present, is assumed to be 1.
  261. * - The M4 is a magic bonus, to be applied with m_bonus().
  262. *
  263. * All parts of the random value are optional. The value is read into a
  264. * "random_value" struct and may be used with the randcalc() function to
  265. * determine the minimum, maximum, average, or randomised result of the roll.
  266. */
  267. static bool parse_random_value(const char *str, random_value *bonus)
  268. {
  269. bool negative = FALSE;
  270. char buffer[50];
  271. int i = 0, b, dn, ds, mb;
  272. const char end_chr = '|';
  273. char eov;
  274. /* Entire value may be negated */
  275. if (str[0] == '-')
  276. {
  277. negative = TRUE;
  278. i++;
  279. }
  280. /* Make a working copy of the string */
  281. my_strcpy(buffer, &str[i], N_ELEMENTS(buffer) - 2);
  282. /* Check for invalid negative numbers */
  283. if (NULL != strstr(buffer, "-")) return FALSE;
  284. /*
  285. * Add a sentinal value at the end of the string.
  286. * Used by scanf to make sure there's no text after the final conversion.
  287. */
  288. buffer[strlen(buffer) + 1] = '\0';
  289. buffer[strlen(buffer)] = end_chr;
  290. /* Scan the value, apply defaults for unspecified components */
  291. if (5 == sscanf(buffer, "%d+%dd%dM%d%c", &b, &dn, &ds, &mb, &eov) && eov == end_chr)
  292. {
  293. /* No defaults */
  294. }
  295. else if (4 == sscanf(buffer, "%d+d%dM%d%c", &b, &ds, &mb, &eov) && eov == end_chr)
  296. {
  297. dn = 1;
  298. }
  299. else if (3 == sscanf(buffer, "%d+M%d%c", &b, &mb, &eov) && eov == end_chr)
  300. {
  301. dn = 0; ds = 0;
  302. }
  303. else if (4 == sscanf(buffer, "%d+%dd%d%c", &b, &dn, &ds, &eov) && eov == end_chr)
  304. {
  305. mb = 0;
  306. }
  307. else if (3 == sscanf(buffer, "%d+d%d%c", &b, &ds, &eov) && eov == end_chr)
  308. {
  309. dn = 1; mb = 0;
  310. }
  311. else if (4 == sscanf(buffer, "%dd%dM%d%c", &dn, &ds, &mb, &eov) && eov == end_chr)
  312. {
  313. b = 0;
  314. }
  315. else if (3 == sscanf(buffer, "d%dM%d%c", &ds, &mb, &eov) && eov == end_chr)
  316. {
  317. b = 0; dn = 1;
  318. }
  319. else if (2 == sscanf(buffer, "M%d%c", &mb, &eov) && eov == end_chr)
  320. {
  321. b = 0; dn = 0; ds = 0;
  322. }
  323. else if (3 == sscanf(buffer, "%dd%d%c", &dn, &ds, &eov) && eov == end_chr)
  324. {
  325. b = 0; mb = 0;
  326. }
  327. else if (2 == sscanf(buffer, "d%d%c", &ds, &eov) && eov == end_chr)
  328. {
  329. b = 0; dn = 1; mb = 0;
  330. }
  331. else if (2 == sscanf(buffer, "%d%c", &b, &eov) && eov == end_chr)
  332. {
  333. dn = 0; ds = 0; mb = 0;
  334. }
  335. else
  336. {
  337. return FALSE;
  338. }
  339. /* Assign the values */
  340. bonus->base = b;
  341. bonus->dice = dn;
  342. bonus->sides = ds;
  343. bonus->m_bonus = mb;
  344. /*
  345. * Handle negation (the random components are always positive, so the base
  346. * must be adjusted as necessary).
  347. */
  348. if (negative)
  349. {
  350. bonus->base *= -1;
  351. bonus->base -= bonus->m_bonus;
  352. bonus->base -= bonus->dice * (bonus->sides + 1);
  353. }
  354. return TRUE;
  355. }
  356. /*
  357. * Figure out what index an activation should have
  358. */
  359. static u32b grab_one_effect(const char *what)
  360. {
  361. size_t i;
  362. /* Scan activations */
  363. for (i = 0; i < N_ELEMENTS(effect_list); i++)
  364. {
  365. if (streq(what, effect_list[i]))
  366. return i;
  367. }
  368. /* Oops */
  369. msg_format("Unknown effect '%s'.", what);
  370. /* Error */
  371. return 0;
  372. }
  373. /**
  374. * Initialise the store stocking lists.
  375. */
  376. errr init_store_txt(ang_file *fp, char *buf)
  377. {
  378. int i;
  379. int store_num = -1;
  380. store_type *st_ptr;
  381. error_idx = -1;
  382. error_line = 0;
  383. /* Allocate the stores */
  384. store = C_ZNEW(MAX_STORES, store_type);
  385. for (i = 0; i < MAX_STORES; i++)
  386. {
  387. st_ptr = &store[i];
  388. /* Assume stock */
  389. st_ptr->stock_size = STORE_INVEN_MAX;
  390. st_ptr->stock = C_ZNEW(st_ptr->stock_size, object_type);
  391. }
  392. st_ptr = NULL;
  393. while (file_getl(fp, buf, 1024))
  394. {
  395. error_line++;
  396. if (!buf[0] || buf[0] == '#')
  397. continue;
  398. else if (buf[0] == 'S')
  399. {
  400. int num, slots;
  401. /* Make sure all the previous slots have been filled */
  402. if (st_ptr)
  403. {
  404. if (st_ptr->table_num != st_ptr->table_size)
  405. {
  406. msg_format("Store %d has too few entries (read %d, expected %d).", error_idx, st_ptr->table_num, st_ptr->table_size);
  407. return PARSE_ERROR_TOO_FEW_ENTRIES;
  408. }
  409. }
  410. if (2 != sscanf(buf, "S:%d:%d", &num, &slots))
  411. return PARSE_ERROR_GENERIC;
  412. if (num < 2 || num > 6)
  413. return PARSE_ERROR_GENERIC;
  414. error_idx = num;
  415. /* Account for 0-based indexing */
  416. num--;
  417. store_num = num;
  418. /* Set up this store */
  419. st_ptr = &store[num];
  420. st_ptr->table_size = slots;
  421. st_ptr->table = C_ZNEW(st_ptr->table_size, s16b);
  422. }
  423. else if (buf[0] == 'I')
  424. {
  425. int slots, tval;
  426. int k_idx;
  427. char *tval_s;
  428. char *sval_s;
  429. if (store_num == -1 || !st_ptr)
  430. return PARSE_ERROR_GENERIC;
  431. if (1 != sscanf(buf, "I:%d:", &slots))
  432. return PARSE_ERROR_GENERIC;
  433. if (st_ptr->table_num + slots > st_ptr->table_size)
  434. return PARSE_ERROR_TOO_MANY_ENTRIES;
  435. /* Find the beginning of the tval field */
  436. tval_s = strchr(buf+2, ':');
  437. if (!tval_s) return PARSE_ERROR_MISSING_COLON;
  438. *tval_s++ = '\0';
  439. if (!*tval_s) return PARSE_ERROR_MISSING_FIELD;
  440. /* Now find the beginning of the sval field */
  441. sval_s = strchr(tval_s, ':');
  442. if (!sval_s) return PARSE_ERROR_MISSING_COLON;
  443. *sval_s++ = '\0';
  444. if (!*sval_s) return PARSE_ERROR_MISSING_FIELD;
  445. /* Now convert the tval into its numeric equivalent */
  446. tval = tval_find_idx(tval_s);
  447. if (tval == -1) return PARSE_ERROR_UNRECOGNISED_TVAL;
  448. k_idx = lookup_name(tval, sval_s);
  449. if (!k_idx) return PARSE_ERROR_UNRECOGNISED_SVAL;
  450. while (slots--)
  451. st_ptr->table[st_ptr->table_num++] = k_idx;
  452. }
  453. else
  454. {
  455. return PARSE_ERROR_UNDEFINED_DIRECTIVE;
  456. }
  457. }
  458. /* No errors */
  459. return 0;
  460. }
  461. /**
  462. * Initialise the random name fragments
  463. */
  464. errr init_names_txt(ang_file *fp, char *buf)
  465. {
  466. int i, name_section;
  467. u32b num_names[RANDNAME_NUM_TYPES];
  468. char temp[1024];
  469. int counter = 0;
  470. error_line = 0;
  471. memset(num_names, 0, RANDNAME_NUM_TYPES * sizeof(u32b));
  472. /*
  473. * Go through the file and count the total number of names in each name
  474. * section
  475. */
  476. while (file_getl(fp, buf, 1024))
  477. {
  478. error_line++;
  479. if (!buf[0] || '#' == buf[0])
  480. continue;
  481. else if ('N' == buf[0])
  482. {
  483. if (1 != sscanf(buf, "N:%d", &name_section))
  484. return PARSE_ERROR_GENERIC;
  485. if (name_section > RANDNAME_NUM_TYPES)
  486. return PARSE_ERROR_GENERIC;
  487. }
  488. else if ('D' == buf[0])
  489. {
  490. num_names[name_section]++;
  491. }
  492. else
  493. {
  494. return PARSE_ERROR_UNDEFINED_DIRECTIVE;
  495. }
  496. }
  497. /* Go back to the start of the file */
  498. file_seek(fp, 0);
  499. /* Allocate some memory for pointers to sections */
  500. name_sections = C_ZNEW(RANDNAME_NUM_TYPES, cptr*);
  501. /* Allocate more memory for pointers to names */
  502. /* Add a null element at the end of each array (see randname.c) */
  503. for (i = 0; i < RANDNAME_NUM_TYPES; i++)
  504. {
  505. if (num_names[i])
  506. {
  507. name_sections[i] = C_ZNEW(num_names[i] + 1, cptr);
  508. }
  509. }
  510. /*
  511. * Go through the file again and read each name into the relevant array
  512. */
  513. while (file_getl(fp, buf, 1024))
  514. {
  515. error_line++;
  516. if (!buf[0] || '#' == buf[0])
  517. continue;
  518. else if ('N' == buf[0])
  519. {
  520. if (1 != sscanf(buf, "N:%d", &name_section))
  521. return PARSE_ERROR_GENERIC;
  522. if (name_section > RANDNAME_NUM_TYPES)
  523. return PARSE_ERROR_GENERIC;
  524. counter = 0;
  525. }
  526. else if ('D' == buf[0])
  527. {
  528. if (1 != sscanf(buf, "D:%s", temp))
  529. return PARSE_ERROR_GENERIC;
  530. name_sections[name_section][counter++] = string_make(temp);
  531. }
  532. else
  533. {
  534. return PARSE_ERROR_UNDEFINED_DIRECTIVE;
  535. }
  536. }
  537. /* No errors */
  538. return 0;
  539. }
  540. /*
  541. * Initialize the "z_info" structure, by parsing an ascii "template" file
  542. */
  543. errr parse_z_info(char *buf, header *head)
  544. {
  545. maxima *z_info = head->info_ptr;
  546. /* Hack - Verify 'M:x:' format */
  547. if (buf[0] != 'M') return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  548. if (!buf[2]) return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  549. if (buf[3] != ':') return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  550. /* Process 'F' for "Maximum f_info[] index" */
  551. if (buf[2] == 'F')
  552. {
  553. int max;
  554. /* Scan for the value */
  555. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  556. /* Save the value */
  557. z_info->f_max = max;
  558. }
  559. /* Process 'K' for "Maximum k_info[] index" */
  560. else if (buf[2] == 'K')
  561. {
  562. int max;
  563. /* Scan for the value */
  564. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  565. /* Save the value */
  566. z_info->k_max = max;
  567. }
  568. /* Process 'A' for "Maximum a_info[] index" */
  569. else if (buf[2] == 'A')
  570. {
  571. int max;
  572. /* Scan for the value */
  573. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  574. /* Save the value */
  575. z_info->a_max = max;
  576. }
  577. /* Process 'E' for "Maximum e_info[] index" */
  578. else if (buf[2] == 'E')
  579. {
  580. int max;
  581. /* Scan for the value */
  582. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  583. /* Save the value */
  584. z_info->e_max = max;
  585. }
  586. /* Process 'R' for "Maximum r_info[] index" */
  587. else if (buf[2] == 'R')
  588. {
  589. int max;
  590. /* Scan for the value */
  591. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  592. /* Save the value */
  593. z_info->r_max = max;
  594. }
  595. /* Process 'V' for "Maximum v_info[] index" */
  596. else if (buf[2] == 'V')
  597. {
  598. int max;
  599. /* Scan for the value */
  600. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  601. /* Save the value */
  602. z_info->v_max = max;
  603. }
  604. /* Process 'P' for "Maximum p_info[] index" */
  605. else if (buf[2] == 'P')
  606. {
  607. int max;
  608. /* Scan for the value */
  609. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  610. /* Save the value */
  611. z_info->p_max = max;
  612. }
  613. /* Process 'C' for "Maximum c_info[] index" */
  614. else if (buf[2] == 'C')
  615. {
  616. int max;
  617. /* Scan for the value */
  618. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  619. /* Save the value */
  620. z_info->c_max = max;
  621. }
  622. /* Process 'H' for "Maximum h_info[] index" */
  623. else if (buf[2] == 'H')
  624. {
  625. int max;
  626. /* Scan for the value */
  627. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  628. /* Save the value */
  629. z_info->h_max = max;
  630. }
  631. /* Process 'B' for "Maximum b_info[] subindex" */
  632. else if (buf[2] == 'B')
  633. {
  634. int max;
  635. /* Scan for the value */
  636. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  637. /* Save the value */
  638. z_info->b_max = max;
  639. }
  640. /* Process 'L' for "Maximum flavor_info[] subindex" */
  641. else if (buf[2] == 'L')
  642. {
  643. int max;
  644. /* Scan for the value */
  645. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  646. /* Save the value */
  647. z_info->flavor_max = max;
  648. }
  649. /* Process 'S' for "Maximum s_info[] subindex" */
  650. else if (buf[2] == 'S')
  651. {
  652. int max;
  653. /* Scan for the value */
  654. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  655. /* Save the value */
  656. z_info->s_max = max;
  657. }
  658. /* Process 'O' for "Maximum o_list[] index" */
  659. else if (buf[2] == 'O')
  660. {
  661. int max;
  662. /* Scan for the value */
  663. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  664. /* Save the value */
  665. z_info->o_max = max;
  666. }
  667. /* Process 'M' for "Maximum mon_list[] index" */
  668. else if (buf[2] == 'M')
  669. {
  670. int max;
  671. /* Scan for the value */
  672. if (1 != sscanf(buf+4, "%d", &max)) return (PARSE_ERROR_NOT_NUMBER);
  673. /* Save the value */
  674. z_info->m_max = max;
  675. }
  676. /* Process 'N' for "Fake name size" */
  677. else if (buf[2] == 'N')
  678. {
  679. long max;
  680. /* Scan for the value */
  681. if (1 != sscanf(buf+4, "%ld", &max)) return (PARSE_ERROR_NOT_NUMBER);
  682. /* Save the value */
  683. z_info->fake_name_size = max;
  684. }
  685. /* Process 'T' for "Fake text size" */
  686. else if (buf[2] == 'T')
  687. {
  688. long max;
  689. /* Scan for the value */
  690. if (1 != sscanf(buf+4, "%ld", &max)) return (PARSE_ERROR_NOT_NUMBER);
  691. /* Save the value */
  692. z_info->fake_text_size = max;
  693. }
  694. else
  695. {
  696. /* Oops */
  697. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  698. }
  699. /* Success */
  700. return (0);
  701. }
  702. /*
  703. * Initialize the "v_info" array, by parsing an ascii "template" file
  704. */
  705. errr parse_v_info(char *buf, header *head)
  706. {
  707. int i;
  708. char *s;
  709. /* Current entry */
  710. static vault_type *v_ptr = NULL;
  711. /* Process 'N' for "New/Number/Name" */
  712. if (buf[0] == 'N')
  713. {
  714. /* Find the colon before the name */
  715. s = strchr(buf+2, ':');
  716. /* Verify that colon */
  717. if (!s) return (PARSE_ERROR_MISSING_COLON);
  718. /* Nuke the colon, advance to the name */
  719. *s++ = '\0';
  720. /* Paranoia -- require a name */
  721. if (!*s) return (PARSE_ERROR_GENERIC);
  722. /* Get the index */
  723. i = atoi(buf+2);
  724. /* Verify information */
  725. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  726. /* Verify information */
  727. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  728. /* Save the index */
  729. error_idx = i;
  730. /* Point at the "info" */
  731. v_ptr = (vault_type*)head->info_ptr + i;
  732. /* Store the name */
  733. if ((v_ptr->name = add_name(head, s)) == 0)
  734. return (PARSE_ERROR_OUT_OF_MEMORY);
  735. }
  736. /* Process 'D' for "Description" */
  737. else if (buf[0] == 'D')
  738. {
  739. /* There better be a current v_ptr */
  740. if (!v_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  741. /* Get the text */
  742. s = buf+2;
  743. /* Store the text */
  744. if (!add_text(&v_ptr->text, head, s))
  745. return (PARSE_ERROR_OUT_OF_MEMORY);
  746. }
  747. /* Process 'X' for "Extra info" (one line only) */
  748. else if (buf[0] == 'X')
  749. {
  750. int typ, rat, hgt, wid;
  751. /* There better be a current v_ptr */
  752. if (!v_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  753. /* Scan for the values */
  754. if (4 != sscanf(buf+2, "%d:%d:%d:%d",
  755. &typ, &rat, &hgt, &wid)) return (PARSE_ERROR_GENERIC);
  756. /* Save the values */
  757. v_ptr->typ = typ;
  758. v_ptr->rat = rat;
  759. v_ptr->hgt = hgt;
  760. v_ptr->wid = wid;
  761. /* Check for maximum vault sizes */
  762. if ((v_ptr->typ == 6) && ((v_ptr->wid > 33) || (v_ptr->hgt > 22)))
  763. return (PARSE_ERROR_VAULT_TOO_BIG);
  764. if ((v_ptr->typ == 7) && ((v_ptr->wid > 66) || (v_ptr->hgt > 44)))
  765. return (PARSE_ERROR_VAULT_TOO_BIG);
  766. }
  767. else
  768. {
  769. /* Oops */
  770. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  771. }
  772. /* Success */
  773. return (0);
  774. }
  775. /*
  776. * Initialize the "f_info" array, by parsing an ascii "template" file
  777. */
  778. errr parse_f_info(char *buf, header *head)
  779. {
  780. int i;
  781. char *s;
  782. char *t;
  783. /* Current entry */
  784. static feature_type *f_ptr = NULL;
  785. /* Process 'N' for "New/Number/Name" */
  786. if (buf[0] == 'N')
  787. {
  788. /* Find the colon before the name */
  789. s = strchr(buf+2, ':');
  790. /* Verify that colon */
  791. if (!s) return (PARSE_ERROR_MISSING_COLON);
  792. /* Nuke the colon, advance to the name */
  793. *s++ = '\0';
  794. /* Paranoia -- require a name */
  795. if (!*s) return (PARSE_ERROR_GENERIC);
  796. /* Get the index */
  797. i = atoi(buf+2);
  798. /* Verify information */
  799. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  800. /* Verify information */
  801. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  802. /* Save the index */
  803. error_idx = i;
  804. /* Point at the "info" */
  805. f_ptr = (feature_type*)head->info_ptr + i;
  806. /* Store the name */
  807. if ((f_ptr->name = add_name(head, s)) == 0)
  808. return (PARSE_ERROR_OUT_OF_MEMORY);
  809. /* Default "mimic" */
  810. f_ptr->mimic = i;
  811. }
  812. /* Process 'M' for "Mimic" (one line only) */
  813. else if (buf[0] == 'M')
  814. {
  815. int mimic;
  816. /* There better be a current f_ptr */
  817. if (!f_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  818. /* Scan for the values */
  819. if (1 != sscanf(buf+2, "%d", &mimic))
  820. return (PARSE_ERROR_NOT_NUMBER);
  821. /* Save the values */
  822. f_ptr->mimic = mimic;
  823. }
  824. /* Process 'P' for "Priority" */
  825. else if (buf[0] == 'P')
  826. {
  827. int priority;
  828. /* There better be a current f_ptr */
  829. if (!f_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  830. /* Scan for the values */
  831. if (1 != sscanf(buf+2, "%d", &priority))
  832. return (PARSE_ERROR_NOT_NUMBER);
  833. /* Save the values */
  834. f_ptr->priority = priority;
  835. }
  836. /* Process 'G' for "Graphics" (one line only) */
  837. else if (buf[0] == 'G')
  838. {
  839. char d_char;
  840. int d_attr;
  841. /* There better be a current f_ptr */
  842. if (!f_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  843. /* Paranoia */
  844. if (!buf[2]) return (PARSE_ERROR_GENERIC);
  845. if (!buf[3]) return (PARSE_ERROR_GENERIC);
  846. if (!buf[4]) return (PARSE_ERROR_GENERIC);
  847. /* Extract d_char */
  848. d_char = buf[2];
  849. /* If we have a longer string than expected ... */
  850. if (buf[5])
  851. {
  852. /* Advance "buf" on by 4 */
  853. buf += 4;
  854. /* Extract the colour */
  855. d_attr = color_text_to_attr(buf);
  856. }
  857. else
  858. {
  859. /* Extract the attr */
  860. d_attr = color_char_to_attr(buf[4]);
  861. }
  862. /* Paranoia */
  863. if (d_attr < 0) return (PARSE_ERROR_GENERIC);
  864. /* Save the values */
  865. f_ptr->d_attr = d_attr;
  866. f_ptr->d_char = d_char;
  867. }
  868. /* Process 'F' for flags */
  869. else if (buf[0] == 'F')
  870. {
  871. /* Parse every entry textually */
  872. for (s = buf + 2; *s; )
  873. {
  874. /* Find the end of this entry */
  875. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  876. /* Nuke and skip any dividers */
  877. if (*t)
  878. {
  879. *t++ = '\0';
  880. while ((*t == ' ') || (*t == '|')) t++;
  881. }
  882. /* Parse this entry */
  883. if (0 != grab_one_flag(&f_ptr->flags, f_info_flags, s))
  884. return (PARSE_ERROR_INVALID_FLAG);
  885. /* Start the next entry */
  886. s = t;
  887. }
  888. }
  889. /* Process 'E' for effect */
  890. else if (buf[0] == 'E')
  891. {
  892. f_ptr->effect = grab_one_effect(buf + 2);
  893. if (!f_ptr->effect)
  894. return PARSE_ERROR_GENERIC;
  895. }
  896. /* Process 'X' for extra */
  897. else if (buf[0] == 'X')
  898. {
  899. int locked, jammed, shopnum, dig;
  900. if (4 != sscanf(buf + 2, "%d:%d:%d:%d",
  901. &locked, &jammed, &shopnum, &dig))
  902. return PARSE_ERROR_NOT_NUMBER;
  903. f_ptr->locked = locked;
  904. f_ptr->jammed = jammed;
  905. f_ptr->shopnum = shopnum;
  906. f_ptr->dig = dig;
  907. }
  908. else
  909. {
  910. /* Oops */
  911. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  912. }
  913. /* Success */
  914. return (0);
  915. }
  916. /*
  917. * Find a flag's index from a textual string.
  918. */
  919. static int lookup_flag(const char **flag_table, const char *flag_name)
  920. {
  921. int i = FLAG_START;
  922. while (flag_table[i] && !streq(flag_table[i], flag_name))
  923. i++;
  924. /* End of table reached without match */
  925. if (!flag_table[i]) i = FLAG_END;
  926. return i;
  927. }
  928. /*
  929. * Grab one flag from a string, and set that flag in a bit field
  930. */
  931. static errr grab_flag(bitflag *flags, const size_t size, const char **flag_table, const char *flag_name)
  932. {
  933. int flag = lookup_flag(flag_table, flag_name);
  934. if (flag == FLAG_END) return PARSE_ERROR_INVALID_FLAG;
  935. flag_on(flags, size, flag);
  936. return 0;
  937. }
  938. /*
  939. * Initialize the "k_info" array, by parsing an ascii "template" file
  940. */
  941. errr parse_k_info(char *buf, header *head)
  942. {
  943. int i;
  944. char *s = NULL, *t;
  945. /* Current entry */
  946. static object_kind *k_ptr = NULL;
  947. /* Process 'N' for "New/Number/Name" */
  948. if (buf[0] == 'N')
  949. {
  950. /* Find the colon before the name */
  951. s = strchr(buf+2, ':');
  952. /* Verify that colon */
  953. if (!s) return (PARSE_ERROR_MISSING_COLON);
  954. /* Nuke the colon, advance to the name */
  955. *s++ = '\0';
  956. /* Paranoia -- require a name */
  957. if (!*s) return (PARSE_ERROR_GENERIC);
  958. /* Get the index */
  959. i = atoi(buf+2);
  960. /* Verify information */
  961. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  962. /* Verify information */
  963. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  964. /* Save the index */
  965. error_idx = i;
  966. /* Point at the "info" */
  967. k_ptr = (object_kind*)head->info_ptr + i;
  968. /* Store the name */
  969. if ((k_ptr->name = add_name(head, s)) == 0)
  970. return (PARSE_ERROR_OUT_OF_MEMORY);
  971. /* Success (return early) */
  972. return (0);
  973. }
  974. /* There better be a current k_ptr */
  975. if (!k_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  976. /* Process 'G' for "Graphics" (one line only) */
  977. if (buf[0] == 'G')
  978. {
  979. char d_char;
  980. int d_attr;
  981. /* Paranoia */
  982. if (!buf[2]) return (PARSE_ERROR_GENERIC);
  983. if (!buf[3]) return (PARSE_ERROR_GENERIC);
  984. if (!buf[4]) return (PARSE_ERROR_GENERIC);
  985. /* Extract d_char */
  986. d_char = buf[2];
  987. /* If we have a longer string than expected ... */
  988. if (buf[5])
  989. {
  990. /* Advance "buf" on by 4 */
  991. buf += 4;
  992. /* Extract the colour */
  993. d_attr = color_text_to_attr(buf);
  994. }
  995. else
  996. {
  997. /* Extract the attr */
  998. d_attr = color_char_to_attr(buf[4]);
  999. }
  1000. /* Paranoia */
  1001. if (d_attr < 0) return (PARSE_ERROR_GENERIC);
  1002. /* Save the values */
  1003. k_ptr->d_attr = d_attr;
  1004. k_ptr->d_char = d_char;
  1005. }
  1006. /* Process 'I' for "Info" (one line only) */
  1007. else if (buf[0] == 'I')
  1008. {
  1009. int tval, sval;
  1010. char pval[50];
  1011. /* Scan for the values */
  1012. if (3 != sscanf(buf+2, "%d:%d:%s",
  1013. &tval, &sval, pval)) return (PARSE_ERROR_GENERIC);
  1014. /* Save the values */
  1015. k_ptr->tval = tval;
  1016. k_ptr->sval = sval;
  1017. if (!parse_random_value(pval, &k_ptr->pval)) return PARSE_ERROR_INVALID_VALUE;
  1018. }
  1019. /* Process 'W' for "More Info" (one line only) */
  1020. else if (buf[0] == 'W')
  1021. {
  1022. int level, extra, wgt;
  1023. long cost;
  1024. /* Scan for the values */
  1025. if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
  1026. &level, &extra, &wgt, &cost)) return (PARSE_ERROR_GENERIC);
  1027. /* Save the values */
  1028. k_ptr->level = level;
  1029. k_ptr->weight = wgt;
  1030. k_ptr->cost = cost;
  1031. }
  1032. /* Process 'A' for "Allocation" (one line only) */
  1033. else if (buf[0] == 'A')
  1034. {
  1035. int common, min, max;
  1036. /* Format is "A:<common>:<min> to <max>" */
  1037. if (3 != sscanf(buf+2, "%d:%d to %d", &common, &min, &max))
  1038. return (PARSE_ERROR_GENERIC);
  1039. /* Limit to size a byte */
  1040. if (common < 0 || common > 255) return (PARSE_ERROR_GENERIC);
  1041. if (min < 0 || min > 255) return (PARSE_ERROR_GENERIC);
  1042. if (max < 0 || max > 255) return (PARSE_ERROR_GENERIC);
  1043. /* Set up data */
  1044. k_ptr->alloc_prob = common;
  1045. k_ptr->alloc_min = min;
  1046. k_ptr->alloc_max = max;
  1047. }
  1048. /* Hack -- Process 'P' for "power" and such */
  1049. else if (buf[0] == 'P')
  1050. {
  1051. int ac, hd1, hd2;
  1052. char *th, *td, *ta;
  1053. char fields[150];
  1054. /* Scan for the values "P:0:0d0:0:0:0" */
  1055. if (4 != sscanf(buf+2, "%d:%dd%d:%s",
  1056. &ac, &hd1, &hd2, fields)) return (PARSE_ERROR_GENERIC);
  1057. /* Tokenize the last three fields */
  1058. if(!(th = strtok(fields, ":"))) return PARSE_ERROR_GENERIC;
  1059. if(!(td = strtok(NULL, ":"))) return PARSE_ERROR_GENERIC;
  1060. if(!(ta = strtok(NULL, ":"))) return PARSE_ERROR_GENERIC;
  1061. k_ptr->ac = ac;
  1062. k_ptr->dd = hd1;
  1063. k_ptr->ds = hd2;
  1064. if (!parse_random_value(th, &k_ptr->to_h)) return PARSE_ERROR_INVALID_VALUE;
  1065. if (!parse_random_value(td, &k_ptr->to_d)) return PARSE_ERROR_INVALID_VALUE;
  1066. if (!parse_random_value(ta, &k_ptr->to_a)) return PARSE_ERROR_INVALID_VALUE;
  1067. }
  1068. /* Hack -- Process 'C' for "charges" */
  1069. else if (buf[0] == 'C')
  1070. {
  1071. if(!parse_random_value(buf+2, &k_ptr->charge)) return PARSE_ERROR_INVALID_VALUE;
  1072. }
  1073. /* Process 'M' for "Multiple quantity" (one line only) */
  1074. else if (buf[0] == 'M')
  1075. {
  1076. int prob;
  1077. char stack[50];
  1078. /* Scan for the values */
  1079. if (2 != sscanf(buf+2, "%d:%s", &prob, stack))
  1080. return (PARSE_ERROR_GENERIC);
  1081. /* Save the values */
  1082. k_ptr->gen_mult_prob = prob;
  1083. if (!parse_random_value(stack, &k_ptr->stack_size)) return PARSE_ERROR_INVALID_VALUE;
  1084. }
  1085. /* Hack -- Process 'F' for flags */
  1086. else if (buf[0] == 'F')
  1087. {
  1088. /* Parse every entry textually */
  1089. for (s = buf + 2; *s; )
  1090. {
  1091. /* Find the end of this entry */
  1092. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1093. /* Nuke and skip any dividers */
  1094. if (*t)
  1095. {
  1096. *t++ = '\0';
  1097. while (*t == ' ' || *t == '|') t++;
  1098. }
  1099. /* Parse this entry */
  1100. if (0 != grab_flag(k_ptr->flags, OF_SIZE, k_info_flags, s))
  1101. return (PARSE_ERROR_INVALID_FLAG);
  1102. /* Start the next entry */
  1103. s = t;
  1104. }
  1105. }
  1106. /* Process 'E' for effect */
  1107. else if (buf[0] == 'E')
  1108. {
  1109. /* Find the colon after the name, nuke it and advance */
  1110. s = strchr(buf + 2, ':');
  1111. if (s) *s++ = '\0';
  1112. /* Get the activation */
  1113. k_ptr->effect = grab_one_effect(buf + 2);
  1114. if (!k_ptr->effect) return (PARSE_ERROR_GENERIC);
  1115. /* Get the timeout, if supplied */
  1116. if (s && !parse_random_value(s, &k_ptr->time))
  1117. return (PARSE_ERROR_INVALID_VALUE);
  1118. }
  1119. /* Process 'D' for "Description" */
  1120. else if (buf[0] == 'D')
  1121. {
  1122. /* Store the text */
  1123. if (!add_text(&(k_ptr->text), head, buf + 2))
  1124. return (PARSE_ERROR_OUT_OF_MEMORY);
  1125. }
  1126. else
  1127. {
  1128. /* Oops */
  1129. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  1130. }
  1131. /* Success */
  1132. return (0);
  1133. }
  1134. /*
  1135. * Initialize the "a_info" array, by parsing an ascii "template" file
  1136. */
  1137. errr parse_a_info(char *buf, header *head)
  1138. {
  1139. int i;
  1140. char *s, *t;
  1141. /* Current entry */
  1142. static artifact_type *a_ptr = NULL;
  1143. /* Process 'N' for "New/Number/Name" */
  1144. if (buf[0] == 'N')
  1145. {
  1146. /* Find the colon before the name */
  1147. s = strchr(buf+2, ':');
  1148. /* Verify that colon */
  1149. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1150. /* Nuke the colon, advance to the name */
  1151. *s++ = '\0';
  1152. /* Paranoia -- require a name */
  1153. if (!*s) return (PARSE_ERROR_GENERIC);
  1154. /* Get the index */
  1155. i = atoi(buf+2);
  1156. /* Verify information */
  1157. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  1158. /* Verify information */
  1159. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  1160. /* Save the index */
  1161. error_idx = i;
  1162. /* Point at the "info" */
  1163. a_ptr = (artifact_type*)head->info_ptr + i;
  1164. /* Store the name */
  1165. if ((a_ptr->name = add_name(head, s)) == 0)
  1166. return (PARSE_ERROR_OUT_OF_MEMORY);
  1167. /* Ignore everything */
  1168. flags_set(a_ptr->flags, OF_SIZE, OF_IGNORE_MASK, FLAG_END);
  1169. /* Return early */
  1170. return (0);
  1171. }
  1172. /* There better be a current a_ptr */
  1173. if (!a_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1174. /* Process 'I' for "Info" (one line only) */
  1175. else if (buf[0] == 'I')
  1176. {
  1177. char *tval_s, *sval_s, *pval_s;
  1178. int tval, sval, pval;
  1179. /* Find the beginning of the tval field */
  1180. tval_s = strchr(buf, ':');
  1181. if (!tval_s) return PARSE_ERROR_MISSING_COLON;
  1182. *tval_s++ = '\0';
  1183. if (!*tval_s) return PARSE_ERROR_MISSING_FIELD;
  1184. /* Now find the beginning of the sval field */
  1185. sval_s = strchr(tval_s, ':');
  1186. if (!sval_s) return PARSE_ERROR_MISSING_COLON;
  1187. *sval_s++ = '\0';
  1188. if (!*sval_s) return PARSE_ERROR_MISSING_FIELD;
  1189. /* Now find the beginning of the pval field */
  1190. pval_s = strchr(sval_s, ':');
  1191. if (!pval_s) return PARSE_ERROR_MISSING_COLON;
  1192. *pval_s++ = '\0';
  1193. if (!*pval_s) return PARSE_ERROR_MISSING_FIELD;
  1194. /* Now convert the tval into its numeric equivalent */
  1195. if (1 != sscanf(tval_s, "%d", &tval))
  1196. {
  1197. tval = tval_find_idx(tval_s);
  1198. if (tval == -1) return PARSE_ERROR_UNRECOGNISED_TVAL;
  1199. }
  1200. /* Now find the sval */
  1201. if (1 != sscanf(sval_s, "%d", &sval))
  1202. {
  1203. sval = lookup_sval(tval, sval_s);
  1204. if (sval == -1) return PARSE_ERROR_UNRECOGNISED_SVAL;
  1205. }
  1206. /* Now extract the pval */
  1207. if (1 != sscanf(pval_s, "%d", &pval))
  1208. return PARSE_ERROR_NOT_NUMBER;
  1209. /* Save the values */
  1210. a_ptr->tval = tval;
  1211. a_ptr->sval = sval;
  1212. a_ptr->pval = pval;
  1213. }
  1214. /* Process 'W' for "More Info" (one line only) */
  1215. else if (buf[0] == 'W')
  1216. {
  1217. int level, rarity, wgt;
  1218. long cost;
  1219. /* Scan for the values */
  1220. if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
  1221. &level, &rarity, &wgt, &cost)) return (PARSE_ERROR_GENERIC);
  1222. /* Save the values */
  1223. a_ptr->level = level;
  1224. a_ptr->rarity = rarity;
  1225. a_ptr->weight = wgt;
  1226. a_ptr->cost = cost;
  1227. }
  1228. /* Process 'A' for "Allocation" (one line only) */
  1229. else if (buf[0] == 'A')
  1230. {
  1231. int common, min, max;
  1232. /* Format is "A:<common>:<min> to <max>" */
  1233. if (3 != sscanf(buf+2, "%d:%d to %d", &common, &min, &max))
  1234. return (PARSE_ERROR_GENERIC);
  1235. /* Limit to size a byte */
  1236. if (common < 0 || common > 255) return (PARSE_ERROR_GENERIC);
  1237. if (min < 0 || min > 255) return (PARSE_ERROR_GENERIC);
  1238. if (max < 0 || max > 255) return (PARSE_ERROR_GENERIC);
  1239. /* Set up data */
  1240. a_ptr->alloc_prob = common;
  1241. a_ptr->alloc_min = min;
  1242. a_ptr->alloc_max = max;
  1243. }
  1244. /* Process 'P' for "power" and such */
  1245. else if (buf[0] == 'P')
  1246. {
  1247. int ac, hd1, hd2, th, td, ta;
  1248. /* Scan for the values */
  1249. if (6 != sscanf(buf+2, "%d:%dd%d:%d:%d:%d",
  1250. &ac, &hd1, &hd2, &th, &td, &ta)) return (PARSE_ERROR_GENERIC);
  1251. a_ptr->ac = ac;
  1252. a_ptr->dd = hd1;
  1253. a_ptr->ds = hd2;
  1254. a_ptr->to_h = th;
  1255. a_ptr->to_d = td;
  1256. a_ptr->to_a = ta;
  1257. }
  1258. /* Process 'F' for flags */
  1259. else if (buf[0] == 'F')
  1260. {
  1261. /* Parse every entry textually */
  1262. for (s = buf + 2; *s; )
  1263. {
  1264. /* Find the end of this entry */
  1265. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1266. /* Nuke and skip any dividers */
  1267. if (*t)
  1268. {
  1269. *t++ = '\0';
  1270. while ((*t == ' ') || (*t == '|')) t++;
  1271. }
  1272. /* Parse this entry */
  1273. if (0 != grab_flag(a_ptr->flags, OF_SIZE, k_info_flags, s))
  1274. return (PARSE_ERROR_INVALID_FLAG);
  1275. /* Start the next entry */
  1276. s = t;
  1277. }
  1278. }
  1279. /* Process 'E' for Effect (Activation) & time */
  1280. else if (buf[0] == 'E')
  1281. {
  1282. /* Find the colon after the name */
  1283. s = strchr(buf + 2, ':');
  1284. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1285. /* Nuke the colon, advance to the name */
  1286. *s++ = '\0';
  1287. if (!*s) return (PARSE_ERROR_GENERIC);
  1288. /* Get the activation */
  1289. a_ptr->effect = grab_one_effect(buf + 2);
  1290. if (!a_ptr->effect) return (PARSE_ERROR_GENERIC);
  1291. /* Scan for the values */
  1292. if (!parse_random_value(s, &a_ptr->time))
  1293. return (PARSE_ERROR_INVALID_VALUE);
  1294. }
  1295. /* Process 'M' for "Effect message" */
  1296. else if (buf[0] == 'M')
  1297. {
  1298. /* Store the text */
  1299. if (!add_text(&a_ptr->effect_msg, head, buf+2))
  1300. return (PARSE_ERROR_OUT_OF_MEMORY);
  1301. }
  1302. /* Process 'D' for "Description" */
  1303. else if (buf[0] == 'D')
  1304. {
  1305. /* Store the text */
  1306. if (!add_text(&a_ptr->text, head, buf+2))
  1307. return (PARSE_ERROR_OUT_OF_MEMORY);
  1308. }
  1309. else
  1310. {
  1311. /* Oops */
  1312. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  1313. }
  1314. /* Success */
  1315. return (0);
  1316. }
  1317. /*
  1318. * Initialize the "e_info" array, by parsing an ascii "template" file
  1319. */
  1320. errr parse_e_info(char *buf, header *head)
  1321. {
  1322. int i;
  1323. char *s, *t;
  1324. /* Current entry */
  1325. static ego_item_type *e_ptr = NULL;
  1326. static int cur_t = 0;
  1327. /* Process 'N' for "New/Number/Name" */
  1328. if (buf[0] == 'N')
  1329. {
  1330. /* Find the colon before the name */
  1331. s = strchr(buf+2, ':');
  1332. /* Verify that colon */
  1333. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1334. /* Nuke the colon, advance to the name */
  1335. *s++ = '\0';
  1336. /* Paranoia -- require a name */
  1337. if (!*s) return (PARSE_ERROR_GENERIC);
  1338. /* Get the index */
  1339. i = atoi(buf+2);
  1340. /* Verify information */
  1341. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  1342. /* Verify information */
  1343. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  1344. /* Save the index */
  1345. error_idx = i;
  1346. /* Point at the "info" */
  1347. e_ptr = (ego_item_type*)head->info_ptr + i;
  1348. /* Store the name */
  1349. if ((e_ptr->name = add_name(head, s)) == 0)
  1350. return (PARSE_ERROR_OUT_OF_MEMORY);
  1351. /* Start with the first of the tval indices */
  1352. cur_t = 0;
  1353. }
  1354. /* Process 'W' for "More Info" (one line only) */
  1355. else if (buf[0] == 'W')
  1356. {
  1357. int level, rarity, pad2;
  1358. long cost;
  1359. /* There better be a current e_ptr */
  1360. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1361. /* Scan for the values */
  1362. if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
  1363. &level, &rarity, &pad2, &cost)) return (PARSE_ERROR_GENERIC);
  1364. /* Save the values */
  1365. e_ptr->level = level;
  1366. e_ptr->rarity = rarity;
  1367. /* e_ptr->weight = wgt; */
  1368. e_ptr->cost = cost;
  1369. }
  1370. /* Process 'X' for "Xtra" (one line only) */
  1371. else if (buf[0] == 'X')
  1372. {
  1373. int rating, xtra;
  1374. /* There better be a current e_ptr */
  1375. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1376. /* Scan for the values */
  1377. if (2 != sscanf(buf+2, "%d:%d", &rating, &xtra))
  1378. return (PARSE_ERROR_GENERIC);
  1379. /* Save the values */
  1380. e_ptr->rating = rating;
  1381. e_ptr->xtra = xtra;
  1382. }
  1383. /* Process 'T' for "Types allowed" (up to three lines) */
  1384. else if (buf[0] == 'T')
  1385. {
  1386. int tval, sval1, sval2;
  1387. /* There better be a current e_ptr */
  1388. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1389. /* Scan for the values */
  1390. if (3 != sscanf(buf+2, "%d:%d:%d",
  1391. &tval, &sval1, &sval2)) return (PARSE_ERROR_GENERIC);
  1392. /* Save the values */
  1393. e_ptr->tval[cur_t] = (byte)tval;
  1394. e_ptr->min_sval[cur_t] = (byte)sval1;
  1395. e_ptr->max_sval[cur_t] = (byte)sval2;
  1396. /* Increase counter for 'possible tval' index */
  1397. cur_t++;
  1398. /* Allow only a limited number of T: lines */
  1399. if (cur_t > EGO_TVALS_MAX) return (PARSE_ERROR_GENERIC);
  1400. }
  1401. /* Hack -- Process 'C' for "creation" */
  1402. else if (buf[0] == 'C')
  1403. {
  1404. char *th, *td, *ta, *pv;
  1405. char fields[200];
  1406. /* There better be a current e_ptr */
  1407. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1408. /* Scan for the values */
  1409. if (1 != sscanf(buf+2, "%s", fields)) return (PARSE_ERROR_GENERIC);
  1410. if(!(th = strtok(fields, ":"))) return PARSE_ERROR_GENERIC;
  1411. if(!(td = strtok(NULL, ":"))) return PARSE_ERROR_GENERIC;
  1412. if(!(ta = strtok(NULL, ":"))) return PARSE_ERROR_GENERIC;
  1413. if(!(pv = strtok(NULL, ":"))) return PARSE_ERROR_GENERIC;
  1414. if(!parse_random_value(th, &e_ptr->to_h)) return PARSE_ERROR_INVALID_VALUE;
  1415. if(!parse_random_value(td, &e_ptr->to_d)) return PARSE_ERROR_INVALID_VALUE;
  1416. if(!parse_random_value(ta, &e_ptr->to_a)) return PARSE_ERROR_INVALID_VALUE;
  1417. if(!parse_random_value(pv, &e_ptr->pval)) return PARSE_ERROR_INVALID_VALUE;
  1418. }
  1419. /* Process 'M' for "minimum values" */
  1420. else if (buf[0] == 'M')
  1421. {
  1422. int th, td, ta, pv;
  1423. /* There better be a current e_ptr */
  1424. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1425. /* Scan for the values */
  1426. if (4 != sscanf(buf+2, "%d:%d:%d:%d",
  1427. &th, &td, &ta, &pv)) return (PARSE_ERROR_GENERIC);
  1428. e_ptr->min_to_h = th;
  1429. e_ptr->min_to_d = td;
  1430. e_ptr->min_to_a = ta;
  1431. e_ptr->min_pval = pv;
  1432. }
  1433. /* Hack -- Process 'F' for flags */
  1434. else if (buf[0] == 'F')
  1435. {
  1436. /* There better be a current e_ptr */
  1437. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1438. /* Parse every entry textually */
  1439. for (s = buf + 2; *s; )
  1440. {
  1441. /* Find the end of this entry */
  1442. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1443. /* Nuke and skip any dividers */
  1444. if (*t)
  1445. {
  1446. *t++ = '\0';
  1447. while ((*t == ' ') || (*t == '|')) t++;
  1448. }
  1449. /* Parse this entry */
  1450. if (0 != grab_flag(e_ptr->flags, OF_SIZE, k_info_flags, s))
  1451. return (PARSE_ERROR_INVALID_FLAG);
  1452. /* Start the next entry */
  1453. s = t;
  1454. }
  1455. }
  1456. /* Process 'D' for "Description" */
  1457. else if (buf[0] == 'D')
  1458. {
  1459. /* There better be a current e_ptr */
  1460. if (!e_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1461. /* Get the text */
  1462. s = buf+2;
  1463. /* Store the text */
  1464. if (!add_text(&e_ptr->text, head, s))
  1465. return (PARSE_ERROR_OUT_OF_MEMORY);
  1466. }
  1467. else
  1468. {
  1469. /* Oops */
  1470. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  1471. }
  1472. /* Success */
  1473. return (0);
  1474. }
  1475. /*
  1476. * Initialize the "r_info" array, by parsing an ascii "template" file
  1477. */
  1478. errr parse_r_info(char *buf, header *head)
  1479. {
  1480. int i;
  1481. char *s, *t;
  1482. /* Current entry */
  1483. static monster_race *r_ptr = NULL;
  1484. /* Process 'N' for "New/Number/Name" */
  1485. if (buf[0] == 'N')
  1486. {
  1487. /* Find the colon before the name */
  1488. s = strchr(buf+2, ':');
  1489. /* Verify that colon */
  1490. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1491. /* Nuke the colon, advance to the name */
  1492. *s++ = '\0';
  1493. /* Paranoia -- require a name */
  1494. if (!*s) return (PARSE_ERROR_GENERIC);
  1495. /* Get the index */
  1496. i = atoi(buf+2);
  1497. /* Verify information */
  1498. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  1499. /* Verify information */
  1500. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  1501. /* Save the index */
  1502. error_idx = i;
  1503. /* Point at the "info" */
  1504. r_ptr = (monster_race*)head->info_ptr + i;
  1505. /* Store the name */
  1506. if ((r_ptr->name = add_name(head, s)) == 0)
  1507. return (PARSE_ERROR_OUT_OF_MEMORY);
  1508. return 0;
  1509. }
  1510. /* There better be a current r_ptr */
  1511. if (!r_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1512. /* Process 'D' for "Description" */
  1513. if (buf[0] == 'D')
  1514. {
  1515. /* Store the text */
  1516. if (!add_text(&(r_ptr->text), head, buf+2))
  1517. return (PARSE_ERROR_OUT_OF_MEMORY);
  1518. }
  1519. /* Process 'G' for "Graphics" (one line only) */
  1520. else if (buf[0] == 'G')
  1521. {
  1522. char d_char;
  1523. int d_attr;
  1524. /* Paranoia */
  1525. if (!buf[2]) return (PARSE_ERROR_GENERIC);
  1526. if (!buf[3]) return (PARSE_ERROR_GENERIC);
  1527. if (!buf[4]) return (PARSE_ERROR_GENERIC);
  1528. /* Extract d_char */
  1529. d_char = buf[2];
  1530. /* If we have a longer string than expected ... */
  1531. if (buf[5])
  1532. {
  1533. /* Advance "buf" on by 4 */
  1534. buf += 4;
  1535. /* Extract the colour */
  1536. d_attr = color_text_to_attr(buf);
  1537. }
  1538. else
  1539. {
  1540. /* Extract the attr */
  1541. d_attr = color_char_to_attr(buf[4]);
  1542. }
  1543. /* Paranoia */
  1544. if (d_attr < 0) return (PARSE_ERROR_GENERIC);
  1545. /* Save the values */
  1546. r_ptr->d_attr = d_attr;
  1547. r_ptr->d_char = d_char;
  1548. }
  1549. /* Process 'I' for "Info" (one line only) */
  1550. else if (buf[0] == 'I')
  1551. {
  1552. int spd, lif, aaf, ac, slp;
  1553. /* Scan for the other values */
  1554. if (5 != sscanf(buf+2, "%d:%d:%d:%d:%d",
  1555. &spd, &lif, &aaf, &ac, &slp)) return (PARSE_ERROR_GENERIC);
  1556. /* Save the values */
  1557. r_ptr->speed = spd;
  1558. r_ptr->avg_hp = lif;
  1559. r_ptr->aaf = aaf;
  1560. r_ptr->ac = ac;
  1561. r_ptr->sleep = slp;
  1562. }
  1563. /* Process 'W' for "More Info" (one line only) */
  1564. else if (buf[0] == 'W')
  1565. {
  1566. int lev, rar, pad;
  1567. long exp;
  1568. /* Scan for the values */
  1569. if (4 != sscanf(buf+2, "%d:%d:%d:%ld",
  1570. &lev, &rar, &pad, &exp)) return (PARSE_ERROR_GENERIC);
  1571. /* Save the values */
  1572. r_ptr->level = lev;
  1573. r_ptr->rarity = rar;
  1574. r_ptr->power = pad;
  1575. r_ptr->mexp = exp;
  1576. }
  1577. /* Process 'B' for "Blows" */
  1578. else if (buf[0] == 'B')
  1579. {
  1580. int n1, n2;
  1581. /* Find the next empty blow slot (if any) */
  1582. for (i = 0; i < MONSTER_BLOW_MAX; i++) if (!r_ptr->blow[i].method) break;
  1583. /* Oops, no more slots */
  1584. if (i == MONSTER_BLOW_MAX)
  1585. return (PARSE_ERROR_TOO_MANY_ENTRIES);
  1586. /* Analyze the first field */
  1587. for (s = t = buf+2; *t && (*t != ':'); t++) /* loop */;
  1588. /* Terminate the field (if necessary) */
  1589. if (*t == ':') *t++ = '\0';
  1590. /* Analyze the method */
  1591. for (n1 = 0; r_info_blow_method[n1]; n1++)
  1592. {
  1593. if (streq(s, r_info_blow_method[n1])) break;
  1594. }
  1595. /* Invalid method */
  1596. if (!r_info_blow_method[n1]) return (PARSE_ERROR_UNRECOGNISED_BLOW);
  1597. /* Analyze the second field */
  1598. for (s = t; *t && (*t != ':'); t++) /* loop */;
  1599. /* Terminate the field (if necessary) */
  1600. if (*t == ':') *t++ = '\0';
  1601. /* Analyze effect */
  1602. for (n2 = 0; r_info_blow_effect[n2]; n2++)
  1603. {
  1604. if (streq(s, "")) break;
  1605. if (streq(s, r_info_blow_effect[n2])) break;
  1606. }
  1607. /* Invalid effect */
  1608. if (!r_info_blow_effect[n2]) return (PARSE_ERROR_UNRECOGNISED_BLOW);
  1609. /* Analyze the third field */
  1610. for (s = t; *t && (*t != 'd'); t++) /* loop */;
  1611. /* Terminate the field (if necessary) */
  1612. if (*t == 'd') *t++ = '\0';
  1613. /* Save the method */
  1614. r_ptr->blow[i].method = n1;
  1615. /* Save the effect */
  1616. r_ptr->blow[i].effect = n2;
  1617. /* Extract the damage dice and sides */
  1618. r_ptr->blow[i].d_dice = atoi(s);
  1619. r_ptr->blow[i].d_side = atoi(t);
  1620. }
  1621. /* Process 'F' for "Basic Flags" (multiple lines) */
  1622. else if (buf[0] == 'F')
  1623. {
  1624. /* Parse every entry */
  1625. for (s = buf + 2; *s; )
  1626. {
  1627. /* Find the end of this entry */
  1628. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1629. /* Nuke and skip any dividers */
  1630. if (*t)
  1631. {
  1632. *t++ = '\0';
  1633. while (*t == ' ' || *t == '|') t++;
  1634. }
  1635. /* Parse this entry */
  1636. if (0 != grab_flag(r_ptr->flags, RF_SIZE, r_info_flags, s))
  1637. return (PARSE_ERROR_INVALID_FLAG);
  1638. /* Start the next entry */
  1639. s = t;
  1640. }
  1641. }
  1642. /* Process 'S' for "Spell Flags" (multiple lines) */
  1643. else if (buf[0] == 'S')
  1644. {
  1645. /* Parse every entry */
  1646. for (s = buf + 2; *s; )
  1647. {
  1648. /* Find the end of this entry */
  1649. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1650. /* Nuke and skip any dividers */
  1651. if (*t)
  1652. {
  1653. *t++ = '\0';
  1654. while ((*t == ' ') || (*t == '|')) t++;
  1655. }
  1656. /* XXX Hack -- Read spell frequency */
  1657. if (1 == sscanf(s, "1_IN_%d", &i))
  1658. {
  1659. /* Sanity check */
  1660. if ((i < 1) || (i > 100))
  1661. return (PARSE_ERROR_INVALID_SPELL_FREQ);
  1662. /* Extract a "frequency" */
  1663. r_ptr->freq_spell = r_ptr->freq_innate = 100 / i;
  1664. /* Start at next entry */
  1665. s = t;
  1666. /* Continue */
  1667. continue;
  1668. }
  1669. /* Parse this entry */
  1670. if (0 != grab_flag(r_ptr->spell_flags, RSF_SIZE, r_info_spell_flags, s))
  1671. return (PARSE_ERROR_INVALID_FLAG);
  1672. /* Start the next entry */
  1673. s = t;
  1674. }
  1675. }
  1676. else
  1677. {
  1678. /* Oops */
  1679. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  1680. }
  1681. /* Success */
  1682. return (0);
  1683. }
  1684. /*
  1685. * Helper function for reading a list of skills
  1686. */
  1687. static bool parse_skills(s16b *skills_array, const char *buf)
  1688. {
  1689. int dis, dev, sav, stl, srh, fos, thn, thb, throw, dig;
  1690. /* Scan for the values */
  1691. if (SKILL_MAX != sscanf(buf, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
  1692. &dis, &dev, &sav, &stl, &srh,
  1693. &fos, &thn, &thb, &throw, &dig))
  1694. return FALSE;
  1695. /* Save the values */
  1696. skills_array[SKILL_DISARM] = dis;
  1697. skills_array[SKILL_DEVICE] = dev;
  1698. skills_array[SKILL_SAVE] = sav;
  1699. skills_array[SKILL_STEALTH] = stl;
  1700. skills_array[SKILL_SEARCH] = srh;
  1701. skills_array[SKILL_SEARCH_FREQUENCY] = fos;
  1702. skills_array[SKILL_TO_HIT_MELEE] = thn;
  1703. skills_array[SKILL_TO_HIT_BOW] = thb;
  1704. skills_array[SKILL_TO_HIT_THROW] = throw;
  1705. skills_array[SKILL_DIGGING] = dig;
  1706. return TRUE;
  1707. }
  1708. /*
  1709. * Initialize the "p_info" array, by parsing an ascii "template" file
  1710. */
  1711. errr parse_p_info(char *buf, header *head)
  1712. {
  1713. int i, j;
  1714. char *s, *t;
  1715. /* Current entry */
  1716. static player_race *pr_ptr = NULL;
  1717. /* Process 'N' for "New/Number/Name" */
  1718. if (buf[0] == 'N')
  1719. {
  1720. /* Find the colon before the name */
  1721. s = strchr(buf+2, ':');
  1722. /* Verify that colon */
  1723. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1724. /* Nuke the colon, advance to the name */
  1725. *s++ = '\0';
  1726. /* Paranoia -- require a name */
  1727. if (!*s) return (PARSE_ERROR_MISSING_FIELD);
  1728. /* Get the index */
  1729. i = atoi(buf+2);
  1730. /* Verify information */
  1731. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  1732. /* Verify information */
  1733. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  1734. /* Save the index */
  1735. error_idx = i;
  1736. /* Point at the "info" */
  1737. pr_ptr = (player_race*)head->info_ptr + i;
  1738. /* Store the name */
  1739. if ((pr_ptr->name = add_name(head, s)) == 0)
  1740. return (PARSE_ERROR_OUT_OF_MEMORY);
  1741. }
  1742. /* Process 'S' for "Stats" (one line only) */
  1743. else if (buf[0] == 'S')
  1744. {
  1745. int adj;
  1746. /* There better be a current pr_ptr */
  1747. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1748. /* Start the string */
  1749. s = buf+1;
  1750. /* For each stat */
  1751. for (j = 0; j < A_MAX; j++)
  1752. {
  1753. /* Find the colon before the subindex */
  1754. s = strchr(s, ':');
  1755. /* Verify that colon */
  1756. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1757. /* Nuke the colon, advance to the subindex */
  1758. *s++ = '\0';
  1759. /* Get the value */
  1760. adj = atoi(s);
  1761. /* Save the value */
  1762. pr_ptr->r_adj[j] = adj;
  1763. /* Next... */
  1764. continue;
  1765. }
  1766. }
  1767. /* Process 'R' for "Racial Skills" (one line only) */
  1768. else if (buf[0] == 'R')
  1769. {
  1770. /* There better be a current pr_ptr */
  1771. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1772. /* Verify text */
  1773. if (!buf[1] || !buf[2]) return (PARSE_ERROR_MISSING_FIELD);
  1774. /* Scan and save the values */
  1775. if (!parse_skills(pr_ptr->r_skills, buf+2)) return (PARSE_ERROR_GENERIC);
  1776. }
  1777. /* Process 'X' for "Extra Info" (one line only) */
  1778. else if (buf[0] == 'X')
  1779. {
  1780. int mhp, exp, infra;
  1781. /* There better be a current pr_ptr */
  1782. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1783. /* Scan for the values */
  1784. if (3 != sscanf(buf+2, "%d:%d:%d",
  1785. &mhp, &exp, &infra)) return (PARSE_ERROR_GENERIC);
  1786. /* Save the values */
  1787. pr_ptr->r_mhp = mhp;
  1788. pr_ptr->r_exp = exp;
  1789. pr_ptr->infra = infra;
  1790. }
  1791. /* Hack -- Process 'I' for "info" and such */
  1792. else if (buf[0] == 'I')
  1793. {
  1794. int hist, b_age, m_age;
  1795. /* There better be a current pr_ptr */
  1796. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1797. /* Scan for the values */
  1798. if (3 != sscanf(buf+2, "%d:%d:%d",
  1799. &hist, &b_age, &m_age)) return (PARSE_ERROR_GENERIC);
  1800. pr_ptr->hist = hist;
  1801. pr_ptr->b_age = b_age;
  1802. pr_ptr->m_age = m_age;
  1803. }
  1804. /* Hack -- Process 'H' for "Height" */
  1805. else if (buf[0] == 'H')
  1806. {
  1807. int m_b_ht, m_m_ht, f_b_ht, f_m_ht;
  1808. /* There better be a current pr_ptr */
  1809. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1810. /* Scan for the values */
  1811. if (4 != sscanf(buf+2, "%d:%d:%d:%d",
  1812. &m_b_ht, &m_m_ht, &f_b_ht, &f_m_ht)) return (PARSE_ERROR_GENERIC);
  1813. pr_ptr->m_b_ht = m_b_ht;
  1814. pr_ptr->m_m_ht = m_m_ht;
  1815. pr_ptr->f_b_ht = f_b_ht;
  1816. pr_ptr->f_m_ht = f_m_ht;
  1817. }
  1818. /* Hack -- Process 'W' for "Weight" */
  1819. else if (buf[0] == 'W')
  1820. {
  1821. int m_b_wt, m_m_wt, f_b_wt, f_m_wt;
  1822. /* There better be a current pr_ptr */
  1823. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1824. /* Scan for the values */
  1825. if (4 != sscanf(buf+2, "%d:%d:%d:%d",
  1826. &m_b_wt, &m_m_wt, &f_b_wt, &f_m_wt)) return (PARSE_ERROR_GENERIC);
  1827. pr_ptr->m_b_wt = m_b_wt;
  1828. pr_ptr->m_m_wt = m_m_wt;
  1829. pr_ptr->f_b_wt = f_b_wt;
  1830. pr_ptr->f_m_wt = f_m_wt;
  1831. }
  1832. /* Hack -- Process 'F' for flags */
  1833. else if (buf[0] == 'F')
  1834. {
  1835. /* There better be a current pr_ptr */
  1836. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1837. /* Parse every entry textually */
  1838. for (s = buf + 2; *s; )
  1839. {
  1840. /* Find the end of this entry */
  1841. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1842. /* Nuke and skip any dividers */
  1843. if (*t)
  1844. {
  1845. *t++ = '\0';
  1846. while ((*t == ' ') || (*t == '|')) t++;
  1847. }
  1848. /* Parse this entry */
  1849. if (0 != grab_flag(pr_ptr->flags, OF_SIZE, k_info_flags, s))
  1850. return (PARSE_ERROR_INVALID_FLAG);
  1851. /* Start the next entry */
  1852. s = t;
  1853. }
  1854. }
  1855. /* Hack -- Process 'Y' for new race-only flags */
  1856. else if (buf[0] == 'Y')
  1857. {
  1858. /* There better be a current pr_ptr */
  1859. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1860. /* Parse every entry textually */
  1861. for (s = buf + 2; *s; )
  1862. {
  1863. /* Find the end of this entry */
  1864. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1865. /* Nuke and skip any dividers */
  1866. if (*t)
  1867. {
  1868. *t++ = '\0';
  1869. while ((*t == ' ') || (*t == '|')) t++;
  1870. }
  1871. /* Parse this entry */
  1872. if (0 != grab_flag(pr_ptr->pflags, PF_SIZE, player_info_flags, s))
  1873. return (PARSE_ERROR_INVALID_FLAG);
  1874. /* Start the next entry */
  1875. s = t;
  1876. }
  1877. }
  1878. /* Hack -- Process 'C' for class choices */
  1879. else if (buf[0] == 'C')
  1880. {
  1881. /* There better be a current pr_ptr */
  1882. if (!pr_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1883. /* Parse every entry textually */
  1884. for (s = buf + 2; *s; )
  1885. {
  1886. /* Find the end of this entry */
  1887. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  1888. /* Nuke and skip any dividers */
  1889. if (*t)
  1890. {
  1891. *t++ = '\0';
  1892. while ((*t == ' ') || (*t == '|')) t++;
  1893. }
  1894. /* Hack - Parse this entry */
  1895. pr_ptr->choice |= (1 << atoi(s));
  1896. /* Start the next entry */
  1897. s = t;
  1898. }
  1899. }
  1900. else
  1901. {
  1902. /* Oops */
  1903. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  1904. }
  1905. /* Success */
  1906. return (0);
  1907. }
  1908. /*
  1909. * Initialize the "c_info" array, by parsing an ascii "template" file
  1910. */
  1911. errr parse_c_info(char *buf, header *head)
  1912. {
  1913. int i, j;
  1914. char *s, *t;
  1915. /* Current entry */
  1916. static player_class *pc_ptr = NULL;
  1917. static int cur_title = 0;
  1918. static int cur_equip = 0;
  1919. /* Process 'N' for "New/Number/Name" */
  1920. if (buf[0] == 'N')
  1921. {
  1922. /* Find the colon before the name */
  1923. s = strchr(buf+2, ':');
  1924. /* Verify that colon */
  1925. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1926. /* Nuke the colon, advance to the name */
  1927. *s++ = '\0';
  1928. /* Paranoia -- require a name */
  1929. if (!*s) return (PARSE_ERROR_MISSING_FIELD);
  1930. /* Get the index */
  1931. i = atoi(buf+2);
  1932. /* Verify information */
  1933. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  1934. /* Verify information */
  1935. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  1936. /* Save the index */
  1937. error_idx = i;
  1938. /* Point at the "info" */
  1939. pc_ptr = (player_class*)head->info_ptr + i;
  1940. /* Store the name */
  1941. if ((pc_ptr->name = add_name(head, s)) == 0)
  1942. return (PARSE_ERROR_OUT_OF_MEMORY);
  1943. /* No titles and equipment yet */
  1944. cur_title = 0;
  1945. cur_equip = 0;
  1946. }
  1947. /* Process 'S' for "Stats" (one line only) */
  1948. else if (buf[0] == 'S')
  1949. {
  1950. int adj;
  1951. /* There better be a current pc_ptr */
  1952. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1953. /* Start the string */
  1954. s = buf+1;
  1955. /* For each stat */
  1956. for (j = 0; j < A_MAX; j++)
  1957. {
  1958. /* Find the colon before the subindex */
  1959. s = strchr(s, ':');
  1960. /* Verify that colon */
  1961. if (!s) return (PARSE_ERROR_MISSING_COLON);
  1962. /* Nuke the colon, advance to the subindex */
  1963. *s++ = '\0';
  1964. /* Get the value */
  1965. adj = atoi(s);
  1966. /* Save the value */
  1967. pc_ptr->c_adj[j] = adj;
  1968. /* Next... */
  1969. continue;
  1970. }
  1971. }
  1972. /* Process 'C' for "Class Skills" (one line only) */
  1973. else if (buf[0] == 'C')
  1974. {
  1975. /* There better be a current pc_ptr */
  1976. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1977. /* Verify text */
  1978. if (!buf[1] || !buf[2]) return (PARSE_ERROR_MISSING_FIELD);
  1979. /* Scan and save the values */
  1980. if (!parse_skills(pc_ptr->c_skills, buf+2)) return (PARSE_ERROR_GENERIC);
  1981. }
  1982. /* Process 'X' for "Extra Skills" (one line only) */
  1983. else if (buf[0] == 'X')
  1984. {
  1985. /* There better be a current pc_ptr */
  1986. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1987. /* Verify text */
  1988. if (!buf[1] || !buf[2]) return (PARSE_ERROR_MISSING_FIELD);
  1989. /* Scan and save the values */
  1990. if (!parse_skills(pc_ptr->x_skills, buf+2)) return (PARSE_ERROR_GENERIC);
  1991. }
  1992. /* Process 'I' for "Info" (one line only) */
  1993. else if (buf[0] == 'I')
  1994. {
  1995. int mhp, exp, sense_div;
  1996. long sense_base;
  1997. /* There better be a current pc_ptr */
  1998. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  1999. /* Scan for the values */
  2000. if (4 != sscanf(buf+2, "%d:%d:%ld:%d",
  2001. &mhp, &exp, &sense_base, &sense_div))
  2002. return (PARSE_ERROR_GENERIC);
  2003. /* Save the values */
  2004. pc_ptr->c_mhp = mhp;
  2005. pc_ptr->c_exp = exp;
  2006. pc_ptr->sense_base = sense_base;
  2007. pc_ptr->sense_div = sense_div;
  2008. }
  2009. /* Process 'A' for "Attack Info" (one line only) */
  2010. else if (buf[0] == 'A')
  2011. {
  2012. int max_attacks, min_weight, att_multiply;
  2013. /* There better be a current pc_ptr */
  2014. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2015. /* Scan for the values */
  2016. if (3 != sscanf(buf+2, "%d:%d:%d",
  2017. &max_attacks, &min_weight, &att_multiply))
  2018. return (PARSE_ERROR_GENERIC);
  2019. /* Save the values */
  2020. pc_ptr->max_attacks = max_attacks;
  2021. pc_ptr->min_weight = min_weight;
  2022. pc_ptr->att_multiply = att_multiply;
  2023. }
  2024. /* Process 'M' for "Magic Info" (one line only) */
  2025. else if (buf[0] == 'M')
  2026. {
  2027. int spell_book, spell_stat, spell_first, spell_weight;
  2028. /* There better be a current pc_ptr */
  2029. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2030. /* Scan for the values */
  2031. if (4 != sscanf(buf+2, "%d:%d:%d:%d",
  2032. &spell_book, &spell_stat,
  2033. &spell_first, &spell_weight))
  2034. return (PARSE_ERROR_GENERIC);
  2035. /* Save the values */
  2036. pc_ptr->spell_book = spell_book;
  2037. pc_ptr->spell_stat = spell_stat;
  2038. pc_ptr->spell_first = spell_first;
  2039. pc_ptr->spell_weight = spell_weight;
  2040. }
  2041. /* Process 'B' for "Spell/Prayer book info" */
  2042. else if (buf[0] == 'B')
  2043. {
  2044. int spell, level, mana, fail, exp;
  2045. player_magic *mp_ptr;
  2046. magic_type *spell_ptr;
  2047. /* There better be a current pc_ptr */
  2048. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2049. /* Scan for the values */
  2050. if (5 != sscanf(buf+2, "%d:%d:%d:%d:%d",
  2051. &spell, &level, &mana, &fail, &exp))
  2052. return (PARSE_ERROR_GENERIC);
  2053. /* Validate the spell index */
  2054. if ((spell >= PY_MAX_SPELLS) || (spell < 0))
  2055. return (PARSE_ERROR_OUT_OF_BOUNDS);
  2056. mp_ptr = &pc_ptr->spells;
  2057. spell_ptr = &mp_ptr->info[spell];
  2058. /* Save the values */
  2059. spell_ptr->slevel = level;
  2060. spell_ptr->smana = mana;
  2061. spell_ptr->sfail = fail;
  2062. spell_ptr->sexp = exp;
  2063. }
  2064. /* Process 'T' for "Titles" */
  2065. else if (buf[0] == 'T')
  2066. {
  2067. /* There better be a current pc_ptr */
  2068. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2069. /* Get the text */
  2070. s = buf+2;
  2071. /* Store the text */
  2072. if (!add_text(&pc_ptr->title[cur_title], head, s))
  2073. return (PARSE_ERROR_OUT_OF_MEMORY);
  2074. /* Next title */
  2075. cur_title++;
  2076. /* Limit number of titles */
  2077. if (cur_title > PY_MAX_LEVEL / 5)
  2078. return (PARSE_ERROR_TOO_MANY_ENTRIES);
  2079. }
  2080. /* Process 'E' for "Starting Equipment" */
  2081. else if (buf[0] == 'E')
  2082. {
  2083. char *tval_s, *sval_s, *end_s;
  2084. int tval, sval;
  2085. int min, max;
  2086. start_item *e_ptr;
  2087. /* There better be a current pc_ptr */
  2088. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2089. /* Access the item */
  2090. e_ptr = &pc_ptr->start_items[cur_equip];
  2091. /* Find the beginning of the tval field */
  2092. tval_s = strchr(buf, ':');
  2093. if (!tval_s) return PARSE_ERROR_MISSING_COLON;
  2094. *tval_s++ = '\0';
  2095. if (!*tval_s) return PARSE_ERROR_MISSING_FIELD;
  2096. /* Now find the beginning of the sval field */
  2097. sval_s = strchr(tval_s, ':');
  2098. if (!sval_s) return PARSE_ERROR_MISSING_COLON;
  2099. *sval_s++ = '\0';
  2100. if (!*sval_s) return PARSE_ERROR_MISSING_FIELD;
  2101. /* Now find the beginning of the pval field */
  2102. end_s = strchr(sval_s, ':');
  2103. if (!end_s) return PARSE_ERROR_MISSING_COLON;
  2104. *end_s++ = '\0';
  2105. if (!*end_s) return PARSE_ERROR_MISSING_FIELD;
  2106. /* Now convert the tval into its numeric equivalent */
  2107. if (1 != sscanf(tval_s, "%d", &tval))
  2108. {
  2109. tval = tval_find_idx(tval_s);
  2110. if (tval == -1) return PARSE_ERROR_UNRECOGNISED_TVAL;
  2111. }
  2112. /* Now find the sval */
  2113. if (1 != sscanf(sval_s, "%d", &sval))
  2114. {
  2115. sval = lookup_sval(tval, sval_s);
  2116. if (sval == -1) return PARSE_ERROR_UNRECOGNISED_SVAL;
  2117. }
  2118. /* Scan for the values */
  2119. if (2 != sscanf(end_s, "%d:%d", &min, &max)) return (PARSE_ERROR_GENERIC);
  2120. if ((min < 0) || (max < 0) || (min > 99) || (max > 99))
  2121. return (PARSE_ERROR_INVALID_ITEM_NUMBER);
  2122. /* Save the values */
  2123. e_ptr->tval = tval;
  2124. e_ptr->sval = sval;
  2125. e_ptr->min = min;
  2126. e_ptr->max = max;
  2127. /* Next item */
  2128. cur_equip++;
  2129. /* Limit number of starting items */
  2130. if (cur_equip > MAX_START_ITEMS)
  2131. return (PARSE_ERROR_TOO_MANY_ENTRIES);
  2132. }
  2133. /* Process 'F' for flags */
  2134. else if (buf[0] == 'F')
  2135. {
  2136. /* There better be a current pc_ptr */
  2137. if (!pc_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2138. /* Parse every entry textually */
  2139. for (s = buf + 2; *s; )
  2140. {
  2141. /* Find the end of this entry */
  2142. for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */;
  2143. /* Nuke and skip any dividers */
  2144. if (*t)
  2145. {
  2146. *t++ = '\0';
  2147. while ((*t == ' ') || (*t == '|')) t++;
  2148. }
  2149. /* Parse this entry */
  2150. if (0 != grab_flag(pc_ptr->pflags, PF_SIZE, player_info_flags, s))
  2151. return (PARSE_ERROR_INVALID_FLAG);
  2152. /* Start the next entry */
  2153. s = t;
  2154. }
  2155. }
  2156. else
  2157. {
  2158. /* Oops */
  2159. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  2160. }
  2161. /* Success */
  2162. return (0);
  2163. }
  2164. /*
  2165. * Initialize the "h_info" array, by parsing an ascii "template" file
  2166. */
  2167. errr parse_h_info(char *buf, header *head)
  2168. {
  2169. int i;
  2170. char *s;
  2171. /* Current entry */
  2172. static hist_type *h_ptr = NULL;
  2173. /* Process 'N' for "New/Number" */
  2174. if (buf[0] == 'N')
  2175. {
  2176. int prv, nxt, prc, soc;
  2177. /* Hack - get the index */
  2178. i = error_idx + 1;
  2179. /* Verify information */
  2180. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  2181. /* Verify information */
  2182. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  2183. /* Save the index */
  2184. error_idx = i;
  2185. /* Point at the "info" */
  2186. h_ptr = (hist_type*)head->info_ptr + i;
  2187. /* Scan for the values */
  2188. if (4 != sscanf(buf, "N:%d:%d:%d:%d",
  2189. &prv, &nxt, &prc, &soc)) return (PARSE_ERROR_GENERIC);
  2190. /* Save the values */
  2191. h_ptr->chart = prv;
  2192. h_ptr->next = nxt;
  2193. h_ptr->roll = prc;
  2194. h_ptr->bonus = soc;
  2195. }
  2196. /* Process 'D' for "Description" */
  2197. else if (buf[0] == 'D')
  2198. {
  2199. /* There better be a current h_ptr */
  2200. if (!h_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2201. /* Get the text */
  2202. s = buf+2;
  2203. /* Store the text */
  2204. if (!add_text(&h_ptr->text, head, s))
  2205. return (PARSE_ERROR_OUT_OF_MEMORY);
  2206. }
  2207. else
  2208. {
  2209. /* Oops */
  2210. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  2211. }
  2212. /* Success */
  2213. return (0);
  2214. }
  2215. /*
  2216. * Initialize the "b_info" array, by parsing an ascii "template" file
  2217. */
  2218. errr parse_b_info(char *buf, header *head)
  2219. {
  2220. static int shop_idx = 0;
  2221. static int owner_idx = 0;
  2222. /* Process 'N' for "New/Number/Name" */
  2223. if (buf[0] == 'N')
  2224. {
  2225. /* Confirm the colon */
  2226. if (buf[1] != ':') return PARSE_ERROR_MISSING_COLON;
  2227. /* Get the index */
  2228. shop_idx = atoi(buf+2);
  2229. owner_idx = 0;
  2230. return 0;
  2231. }
  2232. /* Process 'S' for "Owner" */
  2233. else if (buf[0] == 'S')
  2234. {
  2235. owner_type *ot_ptr;
  2236. char *s;
  2237. int purse;
  2238. if (owner_idx >= z_info->b_max)
  2239. return PARSE_ERROR_TOO_MANY_ENTRIES;
  2240. if ((shop_idx * z_info->b_max) + owner_idx >= head->info_num)
  2241. return PARSE_ERROR_TOO_MANY_ENTRIES;
  2242. ot_ptr = (owner_type *)head->info_ptr + (shop_idx * z_info->b_max) + owner_idx;
  2243. if (!ot_ptr) return PARSE_ERROR_GENERIC;
  2244. /* Extract the purse */
  2245. if (1 != sscanf(buf+2, "%d", &purse)) return PARSE_ERROR_GENERIC;
  2246. ot_ptr->max_cost = purse;
  2247. s = strchr(buf+2, ':');
  2248. if (!s || s[1] == 0) return PARSE_ERROR_GENERIC;
  2249. ot_ptr->owner_name = add_name(head, s+1);
  2250. if (!ot_ptr->owner_name)
  2251. return PARSE_ERROR_OUT_OF_MEMORY;
  2252. owner_idx++;
  2253. return 0;
  2254. }
  2255. /* Oops */
  2256. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  2257. }
  2258. /*
  2259. * Initialize the "flavor_info" array, by parsing an ascii "template" file
  2260. */
  2261. errr parse_flavor_info(char *buf, header *head)
  2262. {
  2263. int i;
  2264. /* Current entry */
  2265. static flavor_type *flavor_ptr;
  2266. /* Process 'N' for "Number" */
  2267. if (buf[0] == 'N')
  2268. {
  2269. int tval, sval;
  2270. int result;
  2271. /* Scan the value */
  2272. result = sscanf(buf, "N:%d:%d:%d", &i, &tval, &sval);
  2273. /* Either two or three values */
  2274. if ((result != 2) && (result != 3)) return (PARSE_ERROR_GENERIC);
  2275. /* Verify information */
  2276. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  2277. /* Verify information */
  2278. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  2279. /* Save the index */
  2280. error_idx = i;
  2281. /* Point at the "info" */
  2282. flavor_ptr = (flavor_type*)head->info_ptr + i;
  2283. /* Save the tval */
  2284. flavor_ptr->tval = (byte)tval;
  2285. /* Save the sval */
  2286. if (result == 2)
  2287. {
  2288. /* Megahack - unknown sval */
  2289. flavor_ptr->sval = SV_UNKNOWN;
  2290. }
  2291. else
  2292. flavor_ptr->sval = (byte)sval;
  2293. }
  2294. /* Process 'G' for "Graphics" */
  2295. else if (buf[0] == 'G')
  2296. {
  2297. char d_char;
  2298. int d_attr;
  2299. /* There better be a current flavor_ptr */
  2300. if (!flavor_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2301. /* Paranoia */
  2302. if (!buf[2]) return (PARSE_ERROR_MISSING_FIELD);
  2303. if (!buf[3]) return (PARSE_ERROR_GENERIC);
  2304. if (!buf[4]) return (PARSE_ERROR_GENERIC);
  2305. /* Extract d_char */
  2306. d_char = buf[2];
  2307. /* If we have a longer string than expected ... */
  2308. if (buf[5])
  2309. {
  2310. /* Advance "buf" on by 4 */
  2311. buf += 4;
  2312. /* Extract the colour */
  2313. d_attr = color_text_to_attr(buf);
  2314. }
  2315. else
  2316. {
  2317. /* Extract the attr */
  2318. d_attr = color_char_to_attr(buf[4]);
  2319. }
  2320. /* Paranoia */
  2321. if (d_attr < 0) return (PARSE_ERROR_GENERIC);
  2322. /* Save the values */
  2323. flavor_ptr->d_attr = d_attr;
  2324. flavor_ptr->d_char = d_char;
  2325. }
  2326. /* Process 'D' for "Description" */
  2327. else if (buf[0] == 'D')
  2328. {
  2329. /* There better be a current flavor_ptr */
  2330. if (!flavor_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2331. /* Paranoia */
  2332. if (!buf[1]) return (PARSE_ERROR_MISSING_FIELD);
  2333. if (!buf[2]) return (PARSE_ERROR_MISSING_FIELD);
  2334. /* Store the text */
  2335. if (!add_text(&flavor_ptr->text, head, buf + 2))
  2336. return (PARSE_ERROR_OUT_OF_MEMORY);
  2337. }
  2338. else
  2339. {
  2340. /* Oops */
  2341. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  2342. }
  2343. /* Success */
  2344. return (0);
  2345. }
  2346. /*
  2347. * Initialize the "s_info" array, by parsing an ascii "template" file
  2348. */
  2349. errr parse_s_info(char *buf, header *head)
  2350. {
  2351. int i;
  2352. char *s;
  2353. /* Current entry */
  2354. static spell_type *s_ptr = NULL;
  2355. /* Process 'N' for "New/Number/Name" */
  2356. if (buf[0] == 'N')
  2357. {
  2358. /* Find the colon before the name */
  2359. s = strchr(buf+2, ':');
  2360. /* Verify that colon */
  2361. if (!s) return (PARSE_ERROR_MISSING_COLON);
  2362. /* Nuke the colon, advance to the name */
  2363. *s++ = '\0';
  2364. /* Paranoia -- require a name */
  2365. if (!*s) return (PARSE_ERROR_GENERIC);
  2366. /* Get the index */
  2367. i = atoi(buf+2);
  2368. /* Verify information */
  2369. if (i <= error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  2370. /* Verify information */
  2371. if (i >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  2372. /* Save the index */
  2373. error_idx = i;
  2374. /* Point at the "info" */
  2375. s_ptr = (spell_type*)head->info_ptr + i;
  2376. /* Store the name */
  2377. if ((s_ptr->name = add_name(head, s)) == 0)
  2378. return (PARSE_ERROR_OUT_OF_MEMORY);
  2379. }
  2380. /* Process 'I' for "Info" (one line only) */
  2381. else if (buf[0] == 'I')
  2382. {
  2383. int tval, sval, snum;
  2384. /* There better be a current s_ptr */
  2385. if (!s_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2386. /* Scan for the values */
  2387. if (3 != sscanf(buf+2, "%d:%d:%d",
  2388. &tval, &sval, &snum)) return (PARSE_ERROR_GENERIC);
  2389. /* Save the values */
  2390. s_ptr->tval = tval;
  2391. s_ptr->sval = sval;
  2392. s_ptr->snum = snum;
  2393. /* Hack -- Use tval to calculate realm and spell index */
  2394. s_ptr->realm = tval - TV_MAGIC_BOOK;
  2395. s_ptr->spell_index = error_idx - (s_ptr->realm * PY_MAX_SPELLS);
  2396. }
  2397. /* Process 'D' for "Description" */
  2398. else if (buf[0] == 'D')
  2399. {
  2400. /* There better be a current s_ptr */
  2401. if (!s_ptr) return (PARSE_ERROR_MISSING_RECORD_HEADER);
  2402. /* Get the text */
  2403. s = buf+2;
  2404. /* Store the text */
  2405. if (!add_text(&s_ptr->text, head, s))
  2406. return (PARSE_ERROR_OUT_OF_MEMORY);
  2407. }
  2408. else
  2409. {
  2410. /* Oops */
  2411. return (PARSE_ERROR_UNDEFINED_DIRECTIVE);
  2412. }
  2413. /* Success */
  2414. return (0);
  2415. }
  2416. /*
  2417. * Initialise the info
  2418. */
  2419. errr eval_info(eval_info_post_func eval_info_process, header *head)
  2420. {
  2421. int err;
  2422. /* Process the info */
  2423. err = (*eval_info_process)(head);
  2424. return(err);
  2425. }
  2426. static long eval_blow_effect(int effect, int atk_dam, int rlev)
  2427. {
  2428. switch (effect)
  2429. {
  2430. /*other bad effects - minor*/
  2431. case RBE_EAT_GOLD:
  2432. case RBE_EAT_ITEM:
  2433. case RBE_EAT_FOOD:
  2434. case RBE_EAT_LIGHT:
  2435. case RBE_LOSE_CHR:
  2436. {
  2437. atk_dam += 5;
  2438. break;
  2439. }
  2440. /*other bad effects - poison / disease */
  2441. case RBE_POISON:
  2442. {
  2443. atk_dam *= 5;
  2444. atk_dam /= 4;
  2445. atk_dam += rlev;
  2446. break;
  2447. }
  2448. /*other bad effects - elements / sustains*/
  2449. case RBE_TERRIFY:
  2450. case RBE_ELEC:
  2451. case RBE_COLD:
  2452. case RBE_FIRE:
  2453. {
  2454. atk_dam += 10;
  2455. break;
  2456. }
  2457. /*other bad effects - elements / major*/
  2458. case RBE_ACID:
  2459. case RBE_BLIND:
  2460. case RBE_CONFUSE:
  2461. case RBE_LOSE_STR:
  2462. case RBE_LOSE_INT:
  2463. case RBE_LOSE_WIS:
  2464. case RBE_LOSE_DEX:
  2465. case RBE_HALLU:
  2466. {
  2467. atk_dam += 20;
  2468. break;
  2469. }
  2470. /*other bad effects - major*/
  2471. case RBE_UN_BONUS:
  2472. case RBE_UN_POWER:
  2473. case RBE_LOSE_CON:
  2474. {
  2475. atk_dam += 30;
  2476. break;
  2477. }
  2478. /*other bad effects - major*/
  2479. case RBE_PARALYZE:
  2480. case RBE_LOSE_ALL:
  2481. {
  2482. atk_dam += 40;
  2483. break;
  2484. }
  2485. /* Experience draining attacks */
  2486. case RBE_EXP_10:
  2487. case RBE_EXP_20:
  2488. {
  2489. /* change inspired by Eddie because exp is infinite */
  2490. atk_dam += 5;
  2491. break;
  2492. }
  2493. case RBE_EXP_40:
  2494. case RBE_EXP_80:
  2495. {
  2496. /* as above */
  2497. atk_dam += 10;
  2498. break;
  2499. }
  2500. /*Earthquakes*/
  2501. case RBE_SHATTER:
  2502. {
  2503. atk_dam += 300;
  2504. break;
  2505. }
  2506. /*nothing special*/
  2507. default: break;
  2508. }
  2509. return (atk_dam);
  2510. }
  2511. /*
  2512. * Go through the attack types for this monster.
  2513. * We look for the maximum possible maximum damage that this
  2514. * monster can inflict in 10 game turns.
  2515. *
  2516. * We try to scale this based on assumed resists,
  2517. * chance of casting spells and of spells failing,
  2518. * chance of hitting in melee, and particularly speed.
  2519. */
  2520. static long eval_max_dam(monster_race *r_ptr)
  2521. {
  2522. int hp, rlev, i;
  2523. int melee_dam, atk_dam, spell_dam, breath_dam;
  2524. int dam = 1;
  2525. /*clear the counters*/
  2526. melee_dam = breath_dam = atk_dam = spell_dam = 0;
  2527. /* Evaluate average HP for this monster */
  2528. hp = r_ptr->avg_hp;
  2529. /* Extract the monster level, force 1 for town monsters */
  2530. rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
  2531. /* Assume single resist for the elemental attacks */
  2532. if (rsf_has(r_ptr->spell_flags, RSF_BR_ACID))
  2533. {
  2534. breath_dam = (RES_ACID_ADJ(MIN(BR_ACID_MAX,
  2535. (hp / BR_ACID_DIVISOR)), MINIMISE));
  2536. if (spell_dam < breath_dam) spell_dam = breath_dam + 20;
  2537. }
  2538. if (rsf_has(r_ptr->spell_flags, RSF_BR_ELEC))
  2539. {
  2540. breath_dam = (RES_ELEC_ADJ(MIN(BR_ELEC_MAX,
  2541. (hp / BR_ELEC_DIVISOR)), MINIMISE));
  2542. if (spell_dam < breath_dam) spell_dam = breath_dam + 10;
  2543. }
  2544. if (rsf_has(r_ptr->spell_flags, RSF_BR_FIRE))
  2545. {
  2546. breath_dam = (RES_FIRE_ADJ(MIN(BR_FIRE_MAX,
  2547. (hp / BR_FIRE_DIVISOR)), MINIMISE));
  2548. if (spell_dam < breath_dam) spell_dam = breath_dam + 10;
  2549. }
  2550. if (rsf_has(r_ptr->spell_flags, RSF_BR_COLD))
  2551. {
  2552. breath_dam = (RES_COLD_ADJ(MIN(BR_COLD_MAX,
  2553. (hp / BR_COLD_DIVISOR)), MINIMISE));
  2554. if (spell_dam < breath_dam) spell_dam = breath_dam + 10;
  2555. }
  2556. /* Same for poison, but lower damage cap */
  2557. if (rsf_has(r_ptr->spell_flags, RSF_BR_POIS))
  2558. {
  2559. breath_dam = (RES_POIS_ADJ(MIN(BR_POIS_MAX,
  2560. (hp / BR_POIS_DIVISOR)), MINIMISE));
  2561. if (spell_dam < breath_dam) spell_dam = (breath_dam * 5 / 4)
  2562. + rlev;
  2563. }
  2564. /*
  2565. * Same formula for the high resist attacks
  2566. * (remember, we are assuming maximum resisted damage
  2567. * so we *minimise* the resistance)
  2568. * See also: melee2.c, spells1.c, constants.h
  2569. */
  2570. if (rsf_has(r_ptr->spell_flags, RSF_BR_NETH))
  2571. {
  2572. breath_dam = (RES_NETH_ADJ(MIN(BR_NETH_MAX,
  2573. (hp / BR_NETH_DIVISOR)), MINIMISE));
  2574. if (spell_dam < breath_dam) spell_dam = breath_dam + 2000
  2575. / (rlev + 1);
  2576. }
  2577. if (rsf_has(r_ptr->spell_flags, RSF_BR_CHAO))
  2578. {
  2579. breath_dam = (RES_CHAO_ADJ(MIN(BR_CHAO_MAX,
  2580. (hp / BR_CHAO_DIVISOR)), MINIMISE));
  2581. if (spell_dam < breath_dam) spell_dam = breath_dam + 2000
  2582. / (rlev + 1);
  2583. }
  2584. if (rsf_has(r_ptr->spell_flags, RSF_BR_DISE))
  2585. {
  2586. breath_dam = (RES_DISE_ADJ(MIN(BR_DISE_MAX,
  2587. (hp / BR_DISE_DIVISOR)), MINIMISE));
  2588. if (spell_dam < breath_dam) spell_dam = breath_dam + 50;
  2589. }
  2590. if (rsf_has(r_ptr->spell_flags, RSF_BR_SHAR))
  2591. {
  2592. breath_dam = (RES_SHAR_ADJ(MIN(BR_SHAR_MAX,
  2593. (hp / BR_SHAR_DIVISOR)), MINIMISE));
  2594. if (spell_dam < breath_dam) spell_dam = (breath_dam * 5 / 4)
  2595. + 5;
  2596. }
  2597. if (rsf_has(r_ptr->spell_flags, RSF_BR_LIGHT))
  2598. {
  2599. breath_dam = (RES_LIGHT_ADJ(MIN(BR_LIGHT_MAX,
  2600. (hp / BR_LIGHT_DIVISOR)), MINIMISE));
  2601. if (spell_dam < breath_dam) spell_dam = breath_dam + 10;
  2602. }
  2603. if (rsf_has(r_ptr->spell_flags, RSF_BR_DARK))
  2604. {
  2605. breath_dam = (RES_DARK_ADJ(MIN(BR_DARK_MAX,
  2606. (hp / BR_DARK_DIVISOR)), MINIMISE));
  2607. if (spell_dam < breath_dam) spell_dam = breath_dam + 10;
  2608. }
  2609. if (rsf_has(r_ptr->spell_flags, RSF_BR_CONF))
  2610. {
  2611. breath_dam = (RES_CONF_ADJ(MIN(BR_CONF_MAX,
  2612. (hp / BR_CONF_DIVISOR)), MINIMISE));
  2613. if (spell_dam < breath_dam) spell_dam = breath_dam + 20;
  2614. }
  2615. if (rsf_has(r_ptr->spell_flags, RSF_BR_SOUN))
  2616. {
  2617. breath_dam = (RES_SOUN_ADJ(MIN(BR_SOUN_MAX,
  2618. (hp / BR_SOUN_DIVISOR)), MINIMISE));
  2619. if (spell_dam < breath_dam) spell_dam = breath_dam + 20;
  2620. }
  2621. if (rsf_has(r_ptr->spell_flags, RSF_BR_NEXU))
  2622. {
  2623. breath_dam = (RES_NEXU_ADJ(MIN(BR_NEXU_MAX,
  2624. (hp / BR_NEXU_DIVISOR)), MINIMISE));
  2625. if (spell_dam < breath_dam) spell_dam = breath_dam + 20;
  2626. }
  2627. if (rsf_has(r_ptr->spell_flags, RSF_BR_TIME))
  2628. {
  2629. breath_dam = MIN(BR_TIME_MAX, (hp / BR_TIME_DIVISOR));
  2630. if (spell_dam < breath_dam) spell_dam = breath_dam + 2000 / (rlev + 1);
  2631. }
  2632. if (rsf_has(r_ptr->spell_flags, RSF_BR_INER))
  2633. {
  2634. breath_dam = MIN(BR_INER_MAX, (hp / BR_INER_DIVISOR));
  2635. if (spell_dam < breath_dam) spell_dam = breath_dam + 30;
  2636. }
  2637. if (rsf_has(r_ptr->spell_flags, RSF_BR_GRAV))
  2638. {
  2639. breath_dam = MIN(BR_GRAV_MAX, (hp / BR_GRAV_DIVISOR));
  2640. if (spell_dam < breath_dam) spell_dam = breath_dam + 30;
  2641. }
  2642. if (rsf_has(r_ptr->spell_flags, RSF_BR_PLAS))
  2643. {
  2644. breath_dam = MIN(BR_PLAS_MAX, (hp / BR_PLAS_DIVISOR));
  2645. if (spell_dam < breath_dam) spell_dam = breath_dam + 30;
  2646. }
  2647. if (rsf_has(r_ptr->spell_flags, RSF_BR_WALL))
  2648. {
  2649. breath_dam = MIN(BR_FORC_MAX, (hp / BR_FORC_DIVISOR));
  2650. if (spell_dam < breath_dam) spell_dam = breath_dam + 30;
  2651. }
  2652. /* Handle the attack spells, again assuming minimised single resists for max damage */
  2653. if (rsf_has(r_ptr->spell_flags, RSF_BA_ACID) && spell_dam < (RES_ACID_ADJ(BA_ACID_DMG(rlev, MAXIMISE), MINIMISE) + 20))
  2654. spell_dam = (RES_ACID_ADJ(BA_ACID_DMG(rlev, MAXIMISE), MINIMISE) + 20);
  2655. if (rsf_has(r_ptr->spell_flags, RSF_BA_ELEC) && spell_dam < (RES_ELEC_ADJ(BA_ELEC_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2656. spell_dam = (RES_ELEC_ADJ(BA_ELEC_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2657. if (rsf_has(r_ptr->spell_flags, RSF_BA_FIRE) && spell_dam < (RES_FIRE_ADJ(BA_FIRE_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2658. spell_dam = (RES_FIRE_ADJ(BA_FIRE_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2659. if (rsf_has(r_ptr->spell_flags, RSF_BA_COLD) && spell_dam < (RES_COLD_ADJ(BA_COLD_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2660. spell_dam = (RES_COLD_ADJ(BA_COLD_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2661. if (rsf_has(r_ptr->spell_flags, RSF_BA_POIS) && spell_dam < 8)
  2662. spell_dam = 8;
  2663. if (rsf_has(r_ptr->spell_flags, RSF_BA_NETH) && spell_dam < (RES_NETH_ADJ(BA_NETH_DMG(rlev, MAXIMISE), MINIMISE) + 2000 / (rlev + 1)))
  2664. spell_dam = (RES_NETH_ADJ(BA_NETH_DMG(rlev, MAXIMISE), MINIMISE) + 2000 / (rlev + 1));
  2665. if (rsf_has(r_ptr->spell_flags, RSF_BA_WATE) && spell_dam < (BA_WATE_DMG(rlev, MAXIMISE) + 20))
  2666. spell_dam = (BA_WATE_DMG(rlev, MAXIMISE) + 20);
  2667. if (rsf_has(r_ptr->spell_flags, RSF_BA_MANA) && spell_dam < (BA_MANA_DMG(rlev, MAXIMISE) + 100))
  2668. spell_dam = (BA_MANA_DMG(rlev, MAXIMISE) + 100);
  2669. if (rsf_has(r_ptr->spell_flags, RSF_BA_DARK) && spell_dam < (RES_DARK_ADJ(BA_DARK_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2670. spell_dam = (RES_DARK_ADJ(BA_DARK_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2671. /* Small annoyance value */
  2672. if (rsf_has(r_ptr->spell_flags, RSF_DRAIN_MANA) && spell_dam < 5)
  2673. spell_dam = 5;
  2674. /* For all attack forms the player can save against, spell_damage is halved */
  2675. if (rsf_has(r_ptr->spell_flags, RSF_MIND_BLAST) && spell_dam < (MIND_BLAST_DMG(rlev, MAXIMISE) / 2))
  2676. spell_dam = (MIND_BLAST_DMG(rlev, MAXIMISE) / 2);
  2677. if (rsf_has(r_ptr->spell_flags, RSF_BRAIN_SMASH) && spell_dam < (BRAIN_SMASH_DMG(rlev, MAXIMISE) / 2))
  2678. spell_dam = (BRAIN_SMASH_DMG(rlev, MAXIMISE) / 2);
  2679. if (rsf_has(r_ptr->spell_flags, RSF_CAUSE_1) && spell_dam < (CAUSE1_DMG(rlev, MAXIMISE) / 2))
  2680. spell_dam = (CAUSE1_DMG(rlev, MAXIMISE) / 2);
  2681. if (rsf_has(r_ptr->spell_flags, RSF_CAUSE_2) && spell_dam < (CAUSE2_DMG(rlev, MAXIMISE) / 2))
  2682. spell_dam = (CAUSE2_DMG(rlev, MAXIMISE) / 2);
  2683. if (rsf_has(r_ptr->spell_flags, RSF_CAUSE_3) && spell_dam < (CAUSE3_DMG(rlev, MAXIMISE) / 2))
  2684. spell_dam = (CAUSE3_DMG(rlev, MAXIMISE) / 2);
  2685. if (rsf_has(r_ptr->spell_flags, RSF_CAUSE_4) && spell_dam < (CAUSE4_DMG(rlev, MAXIMISE) / 2))
  2686. spell_dam = (CAUSE4_DMG(rlev, MAXIMISE) / 2);
  2687. if (rsf_has(r_ptr->spell_flags, RSF_BO_ACID) && spell_dam < (RES_ACID_ADJ(BO_ACID_DMG(rlev, MAXIMISE), MINIMISE) + 20))
  2688. spell_dam = (RES_ACID_ADJ(BO_ACID_DMG(rlev, MAXIMISE), MINIMISE) + 20);
  2689. if (rsf_has(r_ptr->spell_flags, RSF_BO_ELEC) && spell_dam < (RES_ELEC_ADJ(BO_ELEC_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2690. spell_dam = (RES_ELEC_ADJ(BO_ELEC_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2691. if (rsf_has(r_ptr->spell_flags, RSF_BO_FIRE) && spell_dam < (RES_FIRE_ADJ(BO_FIRE_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2692. spell_dam = (RES_FIRE_ADJ(BO_FIRE_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2693. if (rsf_has(r_ptr->spell_flags, RSF_BO_COLD) && spell_dam < (RES_COLD_ADJ(BO_COLD_DMG(rlev, MAXIMISE), MINIMISE) + 10))
  2694. spell_dam = (RES_COLD_ADJ(BO_COLD_DMG(rlev, MAXIMISE), MINIMISE) + 10);
  2695. if (rsf_has(r_ptr->spell_flags, RSF_BO_NETH) && spell_dam < (RES_NETH_ADJ(BO_NETH_DMG(rlev, MAXIMISE), MINIMISE) + 2000 / (rlev + 1)))
  2696. spell_dam = (RES_NETH_ADJ(BO_NETH_DMG(rlev, MAXIMISE), MINIMISE) + 2000 / (rlev + 1));
  2697. if (rsf_has(r_ptr->spell_flags, RSF_BO_WATE) && spell_dam < (BO_WATE_DMG(rlev, MAXIMISE) + 20))
  2698. spell_dam = (BO_WATE_DMG(rlev, MAXIMISE) + 20);
  2699. if (rsf_has(r_ptr->spell_flags, RSF_BO_MANA) && spell_dam < (BO_MANA_DMG(rlev, MAXIMISE)))
  2700. spell_dam = (BO_MANA_DMG(rlev, MAXIMISE));
  2701. if (rsf_has(r_ptr->spell_flags, RSF_BO_PLAS) && spell_dam < (BO_PLAS_DMG(rlev, MAXIMISE)))
  2702. spell_dam = (BO_PLAS_DMG(rlev, MAXIMISE));
  2703. if (rsf_has(r_ptr->spell_flags, RSF_BO_ICEE) && spell_dam < (RES_COLD_ADJ(BO_ICEE_DMG(rlev, MAXIMISE), MINIMISE)))
  2704. spell_dam = (RES_COLD_ADJ(BO_ICEE_DMG(rlev, MAXIMISE), MINIMISE));
  2705. if (rsf_has(r_ptr->spell_flags, RSF_MISSILE) && spell_dam < (MISSILE_DMG(rlev, MAXIMISE)))
  2706. spell_dam = (MISSILE_DMG(rlev, MAXIMISE));
  2707. /* Small annoyance value */
  2708. if (rsf_has(r_ptr->spell_flags, RSF_SCARE) && spell_dam < 5)
  2709. spell_dam = 5;
  2710. /* Somewhat higher annoyance values */
  2711. if (rsf_has(r_ptr->spell_flags, RSF_BLIND) && spell_dam < 10)
  2712. spell_dam = 8;
  2713. if (rsf_has(r_ptr->spell_flags, RSF_CONF) && spell_dam < 10)
  2714. spell_dam = 10;
  2715. /* A little more dangerous */
  2716. if (rsf_has(r_ptr->spell_flags, RSF_SLOW) && spell_dam < 15)
  2717. spell_dam = 15;
  2718. /* Quite dangerous at an early level */
  2719. if (rsf_has(r_ptr->spell_flags, RSF_HOLD) && spell_dam < 25)
  2720. spell_dam = 25;
  2721. /* Arbitrary values along similar lines from here on */
  2722. if (rsf_has(r_ptr->spell_flags, RSF_HASTE) && spell_dam < 70)
  2723. spell_dam = 70;
  2724. if (rsf_has(r_ptr->spell_flags, RSF_HEAL) && spell_dam < 30)
  2725. spell_dam = 30;
  2726. if (rsf_has(r_ptr->spell_flags, RSF_BLINK) && spell_dam < 5)
  2727. spell_dam = 15;
  2728. if (rsf_has(r_ptr->spell_flags, RSF_TELE_TO) && spell_dam < 25)
  2729. spell_dam = 25;
  2730. if (rsf_has(r_ptr->spell_flags, RSF_TELE_AWAY) && spell_dam < 25)
  2731. spell_dam = 25;
  2732. if (rsf_has(r_ptr->spell_flags, RSF_TELE_LEVEL) && spell_dam < 40)
  2733. spell_dam = 25;
  2734. if (rsf_has(r_ptr->spell_flags, RSF_DARKNESS) && spell_dam < 5)
  2735. spell_dam = 6;
  2736. if (rsf_has(r_ptr->spell_flags, RSF_TRAPS) && spell_dam < 10)
  2737. spell_dam = 5;
  2738. if (rsf_has(r_ptr->spell_flags, RSF_FORGET) && spell_dam < 25)
  2739. spell_dam = 5;
  2740. /* All summons are assigned arbitrary values */
  2741. /* Summon kin is more dangerous at deeper levels */
  2742. if (rsf_has(r_ptr->spell_flags, RSF_S_KIN) && spell_dam < rlev * 2)
  2743. spell_dam = rlev * 2;
  2744. /* Dangerous! */
  2745. if (rsf_has(r_ptr->spell_flags, RSF_S_HI_DEMON) && spell_dam < 250)
  2746. spell_dam = 250;
  2747. /* Somewhat dangerous */
  2748. if (rsf_has(r_ptr->spell_flags, RSF_S_MONSTER) && spell_dam < 40)
  2749. spell_dam = 40;
  2750. /* More dangerous */
  2751. if (rsf_has(r_ptr->spell_flags, RSF_S_MONSTERS) && spell_dam < 80)
  2752. spell_dam = 80;
  2753. /* Mostly just annoying */
  2754. if (rsf_has(r_ptr->spell_flags, RSF_S_ANIMAL) && spell_dam < 30)
  2755. spell_dam = 30;
  2756. if (rsf_has(r_ptr->spell_flags, RSF_S_SPIDER) && spell_dam < 20)
  2757. spell_dam = 20;
  2758. /* Can be quite dangerous */
  2759. if (rsf_has(r_ptr->spell_flags, RSF_S_HOUND) && spell_dam < 100)
  2760. spell_dam = 100;
  2761. /* Dangerous! */
  2762. if (rsf_has(r_ptr->spell_flags, RSF_S_HYDRA) && spell_dam < 150)
  2763. spell_dam = 150;
  2764. /* Can be quite dangerous */
  2765. if (rsf_has(r_ptr->spell_flags, RSF_S_ANGEL) && spell_dam < 150)
  2766. spell_dam = 150;
  2767. /* All of these more dangerous at higher levels */
  2768. if (rsf_has(r_ptr->spell_flags, RSF_S_DEMON) && spell_dam < (rlev * 3) / 2)
  2769. spell_dam = (rlev * 3) / 2;
  2770. if (rsf_has(r_ptr->spell_flags, RSF_S_UNDEAD) && spell_dam < (rlev * 3) / 2)
  2771. spell_dam = (rlev * 3) / 2;
  2772. if (rsf_has(r_ptr->spell_flags, RSF_S_DRAGON) && spell_dam < (rlev * 3) / 2)
  2773. spell_dam = (rlev * 3) / 2;
  2774. /* Extremely dangerous */
  2775. if (rsf_has(r_ptr->spell_flags, RSF_S_HI_UNDEAD) && spell_dam < 400)
  2776. spell_dam = 400;
  2777. /* Extremely dangerous */
  2778. if (rsf_has(r_ptr->spell_flags, RSF_S_HI_DRAGON) && spell_dam < 400)
  2779. spell_dam = 400;
  2780. /* Extremely dangerous */
  2781. if (rsf_has(r_ptr->spell_flags, RSF_S_WRAITH) && spell_dam < 450)
  2782. spell_dam = 450;
  2783. /* Most dangerous summon */
  2784. if (rsf_has(r_ptr->spell_flags, RSF_S_UNIQUE) && spell_dam < 500)
  2785. spell_dam = 500;
  2786. /* Hack - Apply over 10 rounds */
  2787. spell_dam *= 10;
  2788. /* Scale for frequency and availability of mana / ammo */
  2789. if (spell_dam)
  2790. {
  2791. int freq = r_ptr->freq_spell;
  2792. /* Hack -- always get 1 shot */
  2793. if (freq < 10) freq = 10;
  2794. /* Adjust for frequency */
  2795. spell_dam = spell_dam * freq / 100;
  2796. }
  2797. /* Check attacks */
  2798. for (i = 0; i < 4; i++)
  2799. {
  2800. /* Extract the attack infomation */
  2801. int effect = r_ptr->blow[i].effect;
  2802. int method = r_ptr->blow[i].method;
  2803. int d_dice = r_ptr->blow[i].d_dice;
  2804. int d_side = r_ptr->blow[i].d_side;
  2805. /* Hack -- no more attacks */
  2806. if (!method) continue;
  2807. /* Assume maximum damage*/
  2808. atk_dam = eval_blow_effect(effect, d_dice * d_side, r_ptr->level);
  2809. switch (method)
  2810. {
  2811. /*stun definitely most dangerous*/
  2812. case RBM_PUNCH:
  2813. case RBM_KICK:
  2814. case RBM_BUTT:
  2815. case RBM_CRUSH:
  2816. {
  2817. atk_dam *= 4;
  2818. atk_dam /= 3;
  2819. break;
  2820. }
  2821. /*cut*/
  2822. case RBM_CLAW:
  2823. case RBM_BITE:
  2824. {
  2825. atk_dam *= 7;
  2826. atk_dam /= 5;
  2827. break;
  2828. }
  2829. default:
  2830. {
  2831. break;
  2832. }
  2833. }
  2834. /* Normal melee attack */
  2835. if (!rf_has(r_ptr->flags, RF_NEVER_BLOW))
  2836. {
  2837. /* Keep a running total */
  2838. melee_dam += atk_dam;
  2839. }
  2840. }
  2841. /*
  2842. * Apply damage over 10 rounds. We assume that the monster has to make contact first.
  2843. * Hack - speed has more impact on melee as has to stay in contact with player.
  2844. * Hack - this is except for pass wall and kill wall monsters which can always get to the player.
  2845. * Hack - use different values for huge monsters as they strike out to range 2.
  2846. */
  2847. if (flags_test(r_ptr->flags, RF_SIZE, RF_KILL_WALL, RF_PASS_WALL, FLAG_END))
  2848. melee_dam *= 10;
  2849. else
  2850. {
  2851. melee_dam = melee_dam * 3 + melee_dam * extract_energy[r_ptr->speed + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)] / 7;
  2852. }
  2853. /*
  2854. * Scale based on attack accuracy. We make a massive number of assumptions here and just use monster level.
  2855. */
  2856. melee_dam = melee_dam * MIN(45 + rlev * 3, 95) / 100;
  2857. /* Hack -- Monsters that multiply ignore the following reductions */
  2858. if (!rf_has(r_ptr->flags, RF_MULTIPLY))
  2859. {
  2860. /*Reduce damamge potential for monsters that move randomly */
  2861. if (flags_test(r_ptr->flags, RF_SIZE, RF_RAND_25, RF_RAND_50, FLAG_END))
  2862. {
  2863. int reduce = 100;
  2864. if (rf_has(r_ptr->flags, RF_RAND_25)) reduce -= 25;
  2865. if (rf_has(r_ptr->flags, RF_RAND_50)) reduce -= 50;
  2866. /*even moving randomly one in 8 times will hit the player*/
  2867. reduce += (100 - reduce) / 8;
  2868. /* adjust the melee damage*/
  2869. melee_dam = (melee_dam * reduce) / 100;
  2870. }
  2871. /*monsters who can't move aren't nearly as much of a combat threat*/
  2872. if (rf_has(r_ptr->flags, RF_NEVER_MOVE))
  2873. {
  2874. if (rsf_has(r_ptr->spell_flags, RSF_TELE_TO) ||
  2875. rsf_has(r_ptr->spell_flags, RSF_BLINK))
  2876. {
  2877. /* Scale for frequency */
  2878. melee_dam = melee_dam / 5 + 4 * melee_dam * r_ptr->freq_spell / 500;
  2879. /* Incorporate spell failure chance */
  2880. if (!rf_has(r_ptr->flags, RF_STUPID)) melee_dam = melee_dam / 5 + 4 * melee_dam * MIN(75 + (rlev + 3) / 4, 100) / 500;
  2881. }
  2882. else if (rf_has(r_ptr->flags, RF_INVISIBLE)) melee_dam /= 3;
  2883. else melee_dam /= 5;
  2884. }
  2885. }
  2886. /* But keep at a minimum */
  2887. if (melee_dam < 1) melee_dam = 1;
  2888. /*
  2889. * Get the max damage attack
  2890. */
  2891. if (dam < spell_dam) dam = spell_dam;
  2892. if (dam < melee_dam) dam = melee_dam;
  2893. r_ptr->highest_threat = dam;
  2894. /*
  2895. * Adjust for speed. Monster at speed 120 will do double damage,
  2896. * monster at speed 100 will do half, etc. Bonus for monsters who can haste self.
  2897. */
  2898. dam = (dam * extract_energy[r_ptr->speed + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)]) / 10;
  2899. /*
  2900. * Adjust threat for speed -- multipliers are more threatening.
  2901. */
  2902. if (rf_has(r_ptr->flags, RF_MULTIPLY))
  2903. r_ptr->highest_threat = (r_ptr->highest_threat * extract_energy[r_ptr->speed + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)]) / 5;
  2904. /*
  2905. * Adjust threat for friends.
  2906. */
  2907. if (rf_has(r_ptr->flags, RF_FRIENDS))
  2908. r_ptr->highest_threat *= 2;
  2909. else if (rf_has(r_ptr->flags, RF_FRIEND))
  2910. r_ptr->highest_threat = r_ptr->highest_threat * 3 / 2;
  2911. /*but deep in a minimum*/
  2912. if (dam < 1) dam = 1;
  2913. /* We're done */
  2914. return (dam);
  2915. }
  2916. /* Evaluate and adjust a monsters hit points for how easily the monster is damaged */
  2917. static long eval_hp_adjust(monster_race *r_ptr)
  2918. {
  2919. long hp;
  2920. int resists = 1;
  2921. int hide_bonus = 0;
  2922. /* Get the monster base hitpoints */
  2923. hp = r_ptr->avg_hp;
  2924. /* Never moves with no ranged attacks - high hit points count for less */
  2925. if (rf_has(r_ptr->flags, RF_NEVER_MOVE) && !(r_ptr->freq_innate || r_ptr->freq_spell))
  2926. {
  2927. hp /= 2;
  2928. if (hp < 1) hp = 1;
  2929. }
  2930. /* Just assume healers have more staying power */
  2931. if (rsf_has(r_ptr->spell_flags, RSF_HEAL)) hp = (hp * 6) / 5;
  2932. /* Miscellaneous improvements */
  2933. if (rf_has(r_ptr->flags, RF_REGENERATE)) {hp *= 10; hp /= 9;}
  2934. if (rf_has(r_ptr->flags, RF_PASS_WALL)) {hp *= 3; hp /= 2;}
  2935. /* Calculate hide bonus */
  2936. if (rf_has(r_ptr->flags, RF_EMPTY_MIND)) hide_bonus += 2;
  2937. else
  2938. {
  2939. if (rf_has(r_ptr->flags, RF_COLD_BLOOD)) hide_bonus += 1;
  2940. if (rf_has(r_ptr->flags, RF_WEIRD_MIND)) hide_bonus += 1;
  2941. }
  2942. /* Invisibility */
  2943. if (rf_has(r_ptr->flags, RF_INVISIBLE))
  2944. {
  2945. hp = (hp * (r_ptr->level + hide_bonus + 1)) / MAX(1, r_ptr->level);
  2946. }
  2947. /* Monsters that can teleport are a hassle, and can easily run away */
  2948. if (flags_test(r_ptr->spell_flags, RSF_SIZE, RSF_TPORT, RSF_TELE_AWAY,
  2949. RSF_TELE_LEVEL, FLAG_END))
  2950. hp = (hp * 6) / 5;
  2951. /*
  2952. * Monsters that multiply are tougher to kill
  2953. */
  2954. if (rf_has(r_ptr->flags, RF_MULTIPLY)) hp *= 2;
  2955. /* Monsters with resistances are harder to kill.
  2956. Therefore effective slays / brands against them are worth more. */
  2957. if (rf_has(r_ptr->flags, RF_IM_ACID)) resists += 2;
  2958. if (rf_has(r_ptr->flags, RF_IM_FIRE)) resists += 2;
  2959. if (rf_has(r_ptr->flags, RF_IM_COLD)) resists += 2;
  2960. if (rf_has(r_ptr->flags, RF_IM_ELEC)) resists += 2;
  2961. if (rf_has(r_ptr->flags, RF_IM_POIS)) resists += 2;
  2962. /* Bonus for multiple basic resists and weapon resists */
  2963. if (resists >= 12) resists *= 6;
  2964. else if (resists >= 10) resists *= 4;
  2965. else if (resists >= 8) resists *= 3;
  2966. else if (resists >= 6) resists *= 2;
  2967. /* If quite resistant, reduce resists by defense holes */
  2968. if (resists >= 6)
  2969. {
  2970. if (rf_has(r_ptr->flags, RF_HURT_ROCK)) resists -= 1;
  2971. if (!rf_has(r_ptr->flags, RF_NO_SLEEP)) resists -= 3;
  2972. if (!rf_has(r_ptr->flags, RF_NO_FEAR)) resists -= 2;
  2973. if (!rf_has(r_ptr->flags, RF_NO_CONF)) resists -= 2;
  2974. if (!rf_has(r_ptr->flags, RF_NO_STUN)) resists -= 1;
  2975. if (resists < 5) resists = 5;
  2976. }
  2977. /* If quite resistant, bonus for high resists */
  2978. if (resists >= 3)
  2979. {
  2980. if (rf_has(r_ptr->flags, RF_IM_WATER)) resists += 1;
  2981. if (rf_has(r_ptr->flags, RF_RES_NETH)) resists += 1;
  2982. if (rf_has(r_ptr->flags, RF_RES_NEXUS)) resists += 1;
  2983. if (rf_has(r_ptr->flags, RF_RES_DISE)) resists += 1;
  2984. }
  2985. /* Scale resists */
  2986. resists = resists * 25;
  2987. /* Monster resistances */
  2988. if (resists < (r_ptr->ac + resists) / 3)
  2989. {
  2990. hp += (hp * resists) / (150 + r_ptr->level);
  2991. }
  2992. else
  2993. {
  2994. hp += (hp * (r_ptr->ac + resists) / 3) / (150 + r_ptr->level);
  2995. }
  2996. /*boundry control*/
  2997. if (hp < 1) hp = 1;
  2998. return (hp);
  2999. }
  3000. /*
  3001. * Evaluate the monster power ratings to be stored in r_info.raw
  3002. */
  3003. errr eval_r_power(header *head)
  3004. {
  3005. int i, j;
  3006. byte lvl;
  3007. long hp, av_hp, av_dam;
  3008. long tot_hp[MAX_DEPTH];
  3009. long dam;
  3010. long *power;
  3011. long tot_dam[MAX_DEPTH];
  3012. long mon_count[MAX_DEPTH];
  3013. monster_race *r_ptr = NULL;
  3014. int iteration;
  3015. /* If we came here from the .raw file, the monster power data is already done */
  3016. /* Hack - use Morgy (#547) as the test case */
  3017. r_ptr = (monster_race*)head->info_ptr + 547;
  3018. if (r_ptr->power)
  3019. {
  3020. /* msg_print("Monster power array already filled - returning."); */
  3021. return 0;
  3022. }
  3023. /* Allocate space for power */
  3024. power = C_ZNEW(z_info->r_max, long);
  3025. for (iteration = 0; iteration < 3; iteration ++)
  3026. {
  3027. /* Reset the sum of all monster power values */
  3028. tot_mon_power = 0;
  3029. /* Make sure all arrays start at zero */
  3030. for (i = 0; i < MAX_DEPTH; i++)
  3031. {
  3032. tot_hp[i] = 0;
  3033. tot_dam[i] = 0;
  3034. mon_count[i] = 0;
  3035. }
  3036. /*
  3037. * Go through r_info and evaluate power ratings & flows.
  3038. */
  3039. for (i = 0; i < z_info->r_max; i++)
  3040. {
  3041. /* Point at the "info" */
  3042. r_ptr = (monster_race*)head->info_ptr + i;
  3043. /*** Evaluate power ratings ***/
  3044. /* Set the current level */
  3045. lvl = r_ptr->level;
  3046. /* Maximum damage this monster can do in 10 game turns */
  3047. dam = eval_max_dam(r_ptr);
  3048. /* Adjust hit points based on resistances */
  3049. hp = eval_hp_adjust(r_ptr);
  3050. /* Hack -- set exp */
  3051. if (lvl == 0) r_ptr->mexp = 0L;
  3052. else
  3053. {
  3054. /* Compute depths of non-unique monsters */
  3055. if (!rf_has(r_ptr->flags, RF_UNIQUE))
  3056. {
  3057. long mexp = (hp * dam) / 25;
  3058. long threat = r_ptr->highest_threat;
  3059. /* Compute level algorithmically */
  3060. for (j = 1; (mexp > j + 4) || (threat > j + 5); mexp -= j * j, threat -= (j + 4), j++);
  3061. /* Set level */
  3062. lvl = MIN(( j > 250 ? 90 + (j - 250) / 20 : /* Level 90 and above */
  3063. (j > 130 ? 70 + (j - 130) / 6 : /* Level 70 and above */
  3064. (j > 40 ? 40 + (j - 40) / 3 : /* Level 40 and above */
  3065. j))), 99);
  3066. /* Set level */
  3067. if (arg_rebalance)
  3068. r_ptr->level = lvl;
  3069. }
  3070. if (arg_rebalance)
  3071. {
  3072. /* Hack -- for Ungoliant */
  3073. if (hp > 10000) r_ptr->mexp = (hp / 25) * (dam / lvl);
  3074. else r_ptr->mexp = (hp * dam) / (lvl * 25);
  3075. /* Round to 2 significant figures */
  3076. if (r_ptr->mexp > 100)
  3077. {
  3078. if (r_ptr->mexp < 1000) { r_ptr->mexp = (r_ptr->mexp + 5) / 10; r_ptr->mexp *= 10; }
  3079. else if (r_ptr->mexp < 10000) { r_ptr->mexp = (r_ptr->mexp + 50) / 100; r_ptr->mexp *= 100; }
  3080. else if (r_ptr->mexp < 100000) { r_ptr->mexp = (r_ptr->mexp + 500) / 1000; r_ptr->mexp *= 1000; }
  3081. else if (r_ptr->mexp < 1000000) { r_ptr->mexp = (r_ptr->mexp + 5000) / 10000; r_ptr->mexp *= 10000; }
  3082. else if (r_ptr->mexp < 10000000) { r_ptr->mexp = (r_ptr->mexp + 50000) / 100000; r_ptr->mexp *= 100000; }
  3083. }
  3084. }
  3085. }
  3086. /* If we're rebalancing, this is a nop, if not, we restore the orig value */
  3087. lvl = r_ptr->level;
  3088. if ((lvl) && (r_ptr->mexp < 1L)) r_ptr->mexp = 1L;
  3089. /*
  3090. * Hack - We have to use an adjustment factor to prevent overflow.
  3091. */
  3092. if (lvl >= 90)
  3093. {
  3094. hp /= 1000;
  3095. dam /= 1000;
  3096. }
  3097. else if (lvl >= 65)
  3098. {
  3099. hp /= 100;
  3100. dam /= 100;
  3101. }
  3102. else if (lvl >= 40)
  3103. {
  3104. hp /= 10;
  3105. dam /= 10;
  3106. }
  3107. /* Define the power rating */
  3108. power[i] = hp * dam;
  3109. /* Adjust for group monsters. Average in-level group size is 5 */
  3110. if (rf_has(r_ptr->flags, RF_UNIQUE)) ;
  3111. else if (rf_has(r_ptr->flags, RF_FRIEND)) power[i] *= 2;
  3112. else if (rf_has(r_ptr->flags, RF_FRIENDS)) power[i] *= 5;
  3113. /* Adjust for multiplying monsters. This is modified by the speed,
  3114. * as fast multipliers are much worse than slow ones. We also adjust for
  3115. * ability to bypass walls or doors.
  3116. */
  3117. if (rf_has(r_ptr->flags, RF_MULTIPLY))
  3118. {
  3119. if (flags_test(r_ptr->flags, RF_SIZE, RF_KILL_WALL, RF_PASS_WALL, FLAG_END))
  3120. power[i] = MAX(power[i], power[i] * extract_energy[r_ptr->speed
  3121. + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)]);
  3122. else if (flags_test(r_ptr->flags, RF_SIZE, RF_OPEN_DOOR, RF_BASH_DOOR, FLAG_END))
  3123. power[i] = MAX(power[i], power[i] * extract_energy[r_ptr->speed
  3124. + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)] * 3 / 2);
  3125. else
  3126. power[i] = MAX(power[i], power[i] * extract_energy[r_ptr->speed
  3127. + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)] / 2);
  3128. }
  3129. /*
  3130. * Update the running totals - these will be used as divisors later
  3131. * Total HP / dam / count for everything up to the current level
  3132. */
  3133. for (j = lvl; j < (lvl == 0 ? lvl + 1: MAX_DEPTH); j++)
  3134. {
  3135. int count = 10;
  3136. /*
  3137. * Uniques don't count towards monster power on the level.
  3138. */
  3139. if (rf_has(r_ptr->flags, RF_UNIQUE)) continue;
  3140. /*
  3141. * Specifically placed monsters don't count towards monster power on the level.
  3142. */
  3143. if (!(r_ptr->rarity)) continue;
  3144. /*
  3145. * Hack -- provide adjustment factor to prevent overflow
  3146. */
  3147. if ((j == 90) && (r_ptr->level < 90))
  3148. {
  3149. hp /= 10;
  3150. dam /= 10;
  3151. }
  3152. if ((j == 65) && (r_ptr->level < 65))
  3153. {
  3154. hp /= 10;
  3155. dam /= 10;
  3156. }
  3157. if ((j == 40) && (r_ptr->level < 40))
  3158. {
  3159. hp /= 10;
  3160. dam /= 10;
  3161. }
  3162. /*
  3163. * Hack - if it's a group monster or multiplying monster, add several to the count
  3164. * so that the averages don't get thrown off
  3165. */
  3166. if (rf_has(r_ptr->flags, RF_FRIEND)) count = 20;
  3167. else if (rf_has(r_ptr->flags, RF_FRIENDS)) count = 50;
  3168. if (rf_has(r_ptr->flags, RF_MULTIPLY))
  3169. {
  3170. if (flags_test(r_ptr->flags, RF_SIZE, RF_KILL_WALL, RF_PASS_WALL, FLAG_END))
  3171. count = MAX(1, extract_energy[r_ptr->speed
  3172. + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)]) * count;
  3173. else if (flags_test(r_ptr->flags, RF_SIZE, RF_OPEN_DOOR, RF_BASH_DOOR, FLAG_END))
  3174. count = MAX(1, extract_energy[r_ptr->speed
  3175. + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)] * 3 / 2) * count;
  3176. else
  3177. count = MAX(1, extract_energy[r_ptr->speed
  3178. + (rsf_has(r_ptr->spell_flags, RSF_HASTE) ? 5 : 0)] / 2) * count;
  3179. }
  3180. /*
  3181. * Very rare monsters count less towards total monster power on the level.
  3182. */
  3183. if (r_ptr->rarity > count)
  3184. {
  3185. hp = hp * count / r_ptr->rarity;
  3186. dam = dam * count / r_ptr->rarity;
  3187. count = r_ptr->rarity;
  3188. }
  3189. tot_hp[j] += hp;
  3190. tot_dam[j] += dam;
  3191. mon_count[j] += count / r_ptr->rarity;
  3192. }
  3193. }
  3194. /* Apply divisors now */
  3195. for (i = 0; i < z_info->r_max; i++)
  3196. {
  3197. int new_power;
  3198. /* Point at the "info" */
  3199. r_ptr = (monster_race*)head->info_ptr + i;
  3200. /* Extract level */
  3201. lvl = r_ptr->level;
  3202. /* Paranoia */
  3203. if (tot_hp[lvl] != 0 && tot_dam[lvl] != 0)
  3204. {
  3205. /* Divide by average HP and av damage for all in-level monsters */
  3206. /* Note we have factored in the above 'adjustment factor' */
  3207. av_hp = tot_hp[lvl] * 10 / mon_count[lvl];
  3208. av_dam = tot_dam[lvl] * 10 / mon_count[lvl];
  3209. /* XXX Justifiable paranoia - avoid divide by zero errors */
  3210. if (av_hp > 0) power[i] = power[i] / av_hp;
  3211. if (av_dam > 0) power[i] = power[i] / av_dam;
  3212. /* Assign monster power */
  3213. r_ptr->power = (s16b)power[i];
  3214. /* Never less than 1 */
  3215. if (r_ptr->power < 1) r_ptr->power = 1;
  3216. /* Get power */
  3217. new_power = r_ptr->power;
  3218. /* Compute rarity algorithmically */
  3219. for (j = 1; new_power > j; new_power -= j * j, j++);
  3220. /* Set rarity */
  3221. if (arg_rebalance)
  3222. r_ptr->rarity = j;
  3223. }
  3224. }
  3225. }
  3226. /* Free power array */
  3227. FREE(power);
  3228. /* Success */
  3229. return(0);
  3230. }
  3231. /*
  3232. * Create the slay cache by determining the number of different slay
  3233. * combinations available to ego items
  3234. */
  3235. errr eval_e_slays(header *head)
  3236. {
  3237. int i;
  3238. int j;
  3239. int count = 0;
  3240. bitflag cacheme[OF_SIZE];
  3241. bitflag slay_mask[OF_SIZE];
  3242. bitflag **dupcheck;
  3243. ego_item_type *e_ptr;
  3244. /* Build the slay mask */
  3245. flags_init(slay_mask, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END);
  3246. /* Calculate necessary size of slay_cache */
  3247. dupcheck = C_ZNEW(z_info->e_max, bitflag *);
  3248. for (i = 0; i < z_info->e_max; i++)
  3249. {
  3250. dupcheck[i] = C_ZNEW(OF_SIZE, bitflag);
  3251. e_ptr = (ego_item_type*)head->info_ptr + i;
  3252. /* Find the slay flags on this ego */
  3253. of_copy(cacheme, e_ptr->flags);
  3254. of_inter(cacheme, slay_mask);
  3255. /* Only consider non-empty combinations of slay flags */
  3256. if (!of_is_empty(cacheme))
  3257. {
  3258. /* Skip previously scanned combinations */
  3259. for (j = 0; j < i; j++)
  3260. {
  3261. if (of_is_equal(cacheme, dupcheck[j]))
  3262. continue;
  3263. }
  3264. /* msg_print("Found a new slay combo on an ego item"); */
  3265. count++;
  3266. of_copy(dupcheck[i], cacheme);
  3267. }
  3268. }
  3269. /* Allocate slay_cache with an extra empty element for an iteration stop */
  3270. slay_cache = C_ZNEW((count + 1), flag_cache);
  3271. count = 0;
  3272. /* Populate the slay_cache */
  3273. for (i = 0; i < z_info->e_max; i++)
  3274. {
  3275. if (!of_is_empty(dupcheck[i]))
  3276. {
  3277. of_copy(slay_cache[count].flags, dupcheck[i]);
  3278. slay_cache[count].value = 0;
  3279. count++;
  3280. /*msg_print("Cached a slay combination");*/
  3281. }
  3282. }
  3283. for (i = 0; i < z_info->e_max; i++)
  3284. FREE(dupcheck[i]);
  3285. FREE(dupcheck);
  3286. /* Success */
  3287. return 0;
  3288. }
  3289. /*
  3290. * Emit a "template" file.
  3291. *
  3292. * This allows us to modify an existing template file by parsing it
  3293. * in and then modifying the data structures.
  3294. *
  3295. * We parse the previous "template" file to allow us to include comments.
  3296. */
  3297. errr emit_info_txt(ang_file *fp, ang_file *template, char *buf, header *head,
  3298. emit_info_txt_index_func emit_info_txt_index, emit_info_txt_always_func emit_info_txt_always)
  3299. {
  3300. errr err;
  3301. /* Not ready yet */
  3302. bool okay = FALSE;
  3303. bool comment = FALSE;
  3304. int blanklines = 0;
  3305. /* Just before the first record */
  3306. error_idx = -1;
  3307. /* Just before the first line */
  3308. error_line = 0;
  3309. /* Parse */
  3310. while (file_getl(template, buf, 1024))
  3311. {
  3312. /* Advance the line number */
  3313. error_line++;
  3314. /* Skip blank lines */
  3315. if (!buf[0])
  3316. {
  3317. if (comment) blanklines++;
  3318. continue;
  3319. }
  3320. /* Emit a comment line */
  3321. if (buf[0] == '#')
  3322. {
  3323. /* Skip comments created by emission process */
  3324. if ((buf[1] == '$') && (buf[2] == '#')) continue;
  3325. while (blanklines--) file_put(fp, "\n");
  3326. file_putf(fp, "%s\n", buf);
  3327. comment = TRUE;
  3328. blanklines = 0;
  3329. continue;
  3330. }
  3331. /* Verify correct "colon" format */
  3332. if (buf[1] != ':') return (PARSE_ERROR_GENERIC);
  3333. /* Hack -- Process 'V' for "Version" */
  3334. if (buf[0] == 'V')
  3335. {
  3336. if (comment) file_putf(fp,"\n");
  3337. comment = FALSE;
  3338. /* Output the version number */
  3339. file_putf(fp, "\nV:%d.%d.%d\n\n", head->v_major, head->v_minor, head->v_patch);
  3340. /* Okay to proceed */
  3341. okay = TRUE;
  3342. /* Continue */
  3343. continue;
  3344. }
  3345. /* No version yet */
  3346. if (!okay) return (PARSE_ERROR_OBSOLETE_FILE);
  3347. /* Hack -- Process 'N' for "Name" */
  3348. if ((emit_info_txt_index) && (buf[0] == 'N'))
  3349. {
  3350. int idx;
  3351. idx = atoi(buf + 2);
  3352. /* Verify index order */
  3353. if (idx < ++error_idx) return (PARSE_ERROR_NON_SEQUENTIAL_RECORDS);
  3354. /* Verify information */
  3355. if (idx >= head->info_num) return (PARSE_ERROR_TOO_MANY_ENTRIES);
  3356. if (comment) file_putf(fp,"\n");
  3357. comment = FALSE;
  3358. blanklines = 0;
  3359. while (error_idx < idx)
  3360. {
  3361. file_putf(fp,"### %d - Unused ###\n\n",error_idx++);
  3362. }
  3363. if ((err = (emit_info_txt_index(fp, head, idx))) != 0)
  3364. return (err);
  3365. }
  3366. /* Ignore anything else and continue */
  3367. continue;
  3368. }
  3369. /* No version yet */
  3370. if (!okay) return (PARSE_ERROR_OBSOLETE_FILE);
  3371. if ((emit_info_txt_always) && ((err = (emit_info_txt_always(fp, head))) != 0))
  3372. return (err);
  3373. /* Success */
  3374. return (0);
  3375. }
  3376. /*
  3377. * Emit one textual string based on a bitflag set.
  3378. */
  3379. static errr emit_flags(ang_file *fp, cptr intro_text, bitflag *flags, const size_t size, const char **names)
  3380. {
  3381. const int max_flags = FLAG_MAX(size);
  3382. int i;
  3383. bool intro = TRUE;
  3384. int len = 0;
  3385. /* Check flags */
  3386. for (i = FLAG_START; i < max_flags; i++)
  3387. {
  3388. if (flag_has(flags, size, i))
  3389. {
  3390. /* Newline needed */
  3391. if (len + strlen(names[i]) > 75)
  3392. {
  3393. file_putf(fp,"\n");
  3394. len = 0;
  3395. intro = TRUE;
  3396. }
  3397. /* Introduction needed */
  3398. if (intro)
  3399. {
  3400. file_putf(fp, intro_text);
  3401. len += strlen(intro_text);
  3402. intro = FALSE;
  3403. }
  3404. else
  3405. {
  3406. file_putf(fp," ");
  3407. len++;
  3408. }
  3409. /* Output flag */
  3410. file_putf(fp, "%s |", names[i]);
  3411. len += strlen(names[i]) + 2;
  3412. }
  3413. }
  3414. /* Something output */
  3415. if (!intro) file_putf(fp, "\n");
  3416. return (0);
  3417. }
  3418. /*
  3419. * Emit description to file.
  3420. *
  3421. * TODO: Consider merging with text_out_to_file in util.c,
  3422. * where most of this came from.
  3423. */
  3424. static errr emit_desc(ang_file *fp, cptr intro_text, cptr text)
  3425. {
  3426. /* Current position on the line */
  3427. int pos = 0;
  3428. /* Wrap width */
  3429. int wrap = 75 - strlen(intro_text);
  3430. /* Current location within "str" */
  3431. cptr s = text;
  3432. /* Process the string */
  3433. while (*s)
  3434. {
  3435. char ch;
  3436. int n = 0;
  3437. int len = wrap - pos;
  3438. int l_space = 0;
  3439. /* If we are at the start of the line... */
  3440. if (pos == 0)
  3441. {
  3442. file_putf(fp, intro_text);
  3443. }
  3444. /* Find length of line up to next newline or end-of-string */
  3445. while ((n < len) && !((s[n] == '\n') || (s[n] == '\0')))
  3446. {
  3447. /* Mark the most recent space in the string */
  3448. if (s[n] == ' ') l_space = n;
  3449. /* Increment */
  3450. n++;
  3451. }
  3452. /* If we have encountered no spaces */
  3453. if ((l_space == 0) && (n == len))
  3454. {
  3455. /* If we are at the start of a new line */
  3456. if (pos == 0)
  3457. {
  3458. len = n;
  3459. }
  3460. else
  3461. {
  3462. /* Begin a new line */
  3463. file_putf(fp, "\n");
  3464. /* Reset */
  3465. pos = 0;
  3466. continue;
  3467. }
  3468. }
  3469. else
  3470. {
  3471. /* Wrap at the newline */
  3472. if ((s[n] == '\n') || (s[n] == '\0')) len = n;
  3473. /* Wrap at the last space */
  3474. else len = l_space;
  3475. }
  3476. /* Write that line to file */
  3477. for (n = 0; n < len; n++)
  3478. {
  3479. /* Ensure the character is printable */
  3480. ch = (isprint(s[n]) ? s[n] : ' ');
  3481. /* Write out the character */
  3482. file_putf(fp, "%c", ch);
  3483. /* Increment */
  3484. pos++;
  3485. }
  3486. /* Move 's' past the stuff we've written */
  3487. s += len;
  3488. /* Skip newlines */
  3489. if (*s == '\n') s++;
  3490. /* Begin a new line */
  3491. file_put(fp, "\n");
  3492. /* If we are at the end of the string, end */
  3493. if (*s == '\0') return (0);
  3494. /* Reset */
  3495. pos = 0;
  3496. }
  3497. /* We are done */
  3498. return (0);
  3499. }
  3500. /*
  3501. * Emit the "r_info" array into an ascii "template" file
  3502. */
  3503. errr emit_r_info_index(ang_file *fp, header *head, int i)
  3504. {
  3505. int n;
  3506. /* Current entry */
  3507. monster_race *r_ptr = (monster_race *)head->info_ptr + i;
  3508. /* Output 'N' for "New/Number/Name" */
  3509. file_putf(fp, "N:%d:%s\n", i,head->name_ptr + r_ptr->name);
  3510. /* Output 'G' for "Graphics" (one line only) */
  3511. file_putf(fp, "G:%c:%c\n",r_ptr->d_char,color_table[r_ptr->d_attr].index_char);
  3512. /* Output 'I' for "Info" (one line only) */
  3513. file_putf(fp, "I:%d:%d:%d:%d:%d\n",r_ptr->speed,r_ptr->avg_hp,r_ptr->aaf,r_ptr->ac,r_ptr->sleep);
  3514. /* Output 'W' for "More Info" (one line only) */
  3515. file_putf(fp, "W:%d:%d:%d:%d\n",r_ptr->level, r_ptr->rarity, 0, r_ptr->mexp);
  3516. /* Output 'B' for "Blows" (up to four lines) */
  3517. for (n = 0; n < 4; n++)
  3518. {
  3519. /* End of blows */
  3520. if (!r_ptr->blow[n].method) break;
  3521. /* Output blow method */
  3522. file_putf(fp, "B:%s", r_info_blow_method[r_ptr->blow[n].method]);
  3523. /* Output blow effect */
  3524. if (r_ptr->blow[n].effect)
  3525. {
  3526. file_putf(fp, ":%s", r_info_blow_effect[r_ptr->blow[n].effect]);
  3527. /* Output blow damage if required */
  3528. if ((r_ptr->blow[n].d_dice) && (r_ptr->blow[n].d_side))
  3529. {
  3530. file_putf(fp, ":%dd%d", r_ptr->blow[n].d_dice, r_ptr->blow[n].d_side);
  3531. }
  3532. }
  3533. /* End line */
  3534. file_putf(fp, "\n");
  3535. }
  3536. /* Output 'F' for "Flags" */
  3537. emit_flags(fp, "F:", r_ptr->flags, RF_SIZE, r_info_flags);
  3538. /* Output 'S' for "Spell Flags" (multiple lines) */
  3539. emit_flags(fp, "S:", r_ptr->spell_flags, RSF_SIZE, r_info_spell_flags);
  3540. /* Output 'S' for spell frequency in unwieldy format */
  3541. /* TODO: use this routine to output M:freq_innate:freq_spell or similar to allow these to be
  3542. * specified properly. 'M' is for magic. Could be extended with :spell_power:mana for 4GAI.
  3543. *
  3544. * XXX Need to check for rounding errors here.
  3545. */
  3546. if (r_ptr->freq_innate) file_putf(fp, "S:1_IN_%d\n",100/r_ptr->freq_innate);
  3547. /* Output 'D' for "Description" */
  3548. emit_desc(fp, "D:", head->text_ptr + r_ptr->text);
  3549. file_putf(fp,"\n");
  3550. /* Success */
  3551. return (0);
  3552. }