ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/treasure.C
(Generate patch)

Comparing deliantra/server/common/treasure.C (file contents):
Revision 1.15 by root, Sat Sep 9 21:48:28 2006 UTC vs.
Revision 1.24 by root, Tue Dec 12 21:39:56 2006 UTC

1
2/*
3 * static char *rcs_treasure_c =
4 * "$Id: treasure.C,v 1.15 2006/09/09 21:48:28 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
28*/ 22*/
29 23
30#define ALLOWED_COMBINATION 24#define ALLOWED_COMBINATION
31 25
32/* TREASURE_DEBUG does some checking on the treasurelists after loading. 26/* TREASURE_DEBUG does some checking on the treasurelists after loading.
35 * left on 29 * left on
36 */ 30 */
37#define TREASURE_DEBUG 31#define TREASURE_DEBUG
38 32
39/* TREASURE_VERBOSE enables copious output concerning artifact generation */ 33/* TREASURE_VERBOSE enables copious output concerning artifact generation */
34
40/* #define TREASURE_VERBOSE */ 35/* #define TREASURE_VERBOSE */
41 36
42#include <global.h> 37#include <global.h>
43#include <treasure.h> 38#include <treasure.h>
44#include <funcpoint.h> 39#include <funcpoint.h>
45#include <loader.h> 40#include <loader.h>
46 41
47 42
48static void change_treasure (treasure * t, object * op); /* overrule default values */ 43static void change_treasure (treasure *t, object *op); /* overrule default values */
49extern char *spell_mapping[]; 44extern char *spell_mapping[];
50 45
51/* 46/*
52 * Initialize global archtype pointers: 47 * Initialize global archtype pointers:
53 */ 48 */
54 49
55void 50void
56init_archetype_pointers () 51init_archetype_pointers ()
57{ 52{
58 int prev_warn = warn_archetypes; 53 int prev_warn = warn_archetypes;
54
59 warn_archetypes = 1; 55 warn_archetypes = 1;
60 if (ring_arch == NULL) 56 if (ring_arch == NULL)
61 ring_arch = find_archetype ("ring"); 57 ring_arch = archetype::find ("ring");
62 if (amulet_arch == NULL) 58 if (amulet_arch == NULL)
63 amulet_arch = find_archetype ("amulet"); 59 amulet_arch = archetype::find ("amulet");
64 if (staff_arch == NULL) 60 if (staff_arch == NULL)
65 staff_arch = find_archetype ("staff"); 61 staff_arch = archetype::find ("staff");
66 if (crown_arch == NULL) 62 if (crown_arch == NULL)
67 crown_arch = find_archetype ("crown"); 63 crown_arch = archetype::find ("crown");
68 warn_archetypes = prev_warn; 64 warn_archetypes = prev_warn;
69} 65}
70 66
71/* 67/*
72 * Allocate and return the pointer to an empty treasurelist structure. 68 * Allocate and return the pointer to an empty treasurelist structure.
108 while (fgets (buf, MAX_BUF, fp) != NULL) 104 while (fgets (buf, MAX_BUF, fp) != NULL)
109 { 105 {
110 (*line)++; 106 (*line)++;
111 107
112 if (*buf == '#') 108 if (*buf == '#')
113 continue; 109 continue;
114 if ((cp = strchr (buf, '\n')) != NULL) 110 if ((cp = strchr (buf, '\n')) != NULL)
115 *cp = '\0'; 111 *cp = '\0';
116 cp = buf; 112 cp = buf;
117 while (isspace (*cp)) /* Skip blanks */ 113 while (isspace (*cp)) /* Skip blanks */
118 cp++; 114 cp++;
119 115
120 if (sscanf (cp, "arch %s", variable)) 116 if (sscanf (cp, "arch %s", variable))
121 { 117 {
122 if ((t->item = find_archetype (variable)) == NULL) 118 if ((t->item = archetype::find (variable)) == NULL)
123 LOG (llevError, "Treasure lacks archetype: %s\n", variable); 119 LOG (llevError, "Treasure lacks archetype: %s\n", variable);
124 } 120 }
125 else if (sscanf (cp, "list %s", variable)) 121 else if (sscanf (cp, "list %s", variable))
126 t->name = variable; 122 t->name = variable;
127 else if (sscanf (cp, "change_name %s", variable)) 123 else if (sscanf (cp, "change_name %s", variable))
128 t->change_arch.name = variable; 124 t->change_arch.name = variable;
129 else if (sscanf (cp, "change_title %s", variable)) 125 else if (sscanf (cp, "change_title %s", variable))
130 t->change_arch.title = variable; 126 t->change_arch.title = variable;
131 else if (sscanf (cp, "change_slaying %s", variable)) 127 else if (sscanf (cp, "change_slaying %s", variable))
132 t->change_arch.slaying = variable; 128 t->change_arch.slaying = variable;
133 else if (sscanf (cp, "chance %d", &value)) 129 else if (sscanf (cp, "chance %d", &value))
134 t->chance = (uint8) value; 130 t->chance = (uint8) value;
135 else if (sscanf (cp, "nrof %d", &value)) 131 else if (sscanf (cp, "nrof %d", &value))
136 t->nrof = (uint16) value; 132 t->nrof = (uint16) value;
137 else if (sscanf (cp, "magic %d", &value)) 133 else if (sscanf (cp, "magic %d", &value))
138 t->magic = (uint8) value; 134 t->magic = (uint8) value;
139 else if (!strcmp (cp, "yes")) 135 else if (!strcmp (cp, "yes"))
140 t->next_yes = load_treasure (fp, line); 136 t->next_yes = load_treasure (fp, line);
141 else if (!strcmp (cp, "no")) 137 else if (!strcmp (cp, "no"))
142 t->next_no = load_treasure (fp, line); 138 t->next_no = load_treasure (fp, line);
143 else if (!strcmp (cp, "end")) 139 else if (!strcmp (cp, "end"))
144 return t; 140 return t;
145 else if (!strcmp (cp, "more")) 141 else if (!strcmp (cp, "more"))
146 { 142 {
147 t->next = load_treasure (fp, line); 143 t->next = load_treasure (fp, line);
148 return t; 144 return t;
149 } 145 }
150 else 146 else
151 LOG (llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, &t->name, *line); 147 LOG (llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, &t->name, *line);
152 } 148 }
153 LOG (llevError, "treasure lacks 'end'.\n"); 149 LOG (llevError, "treasure lacks 'end'.\n");
154 return t; 150 return t;
155} 151}
156 152
157#ifdef TREASURE_DEBUG 153#ifdef TREASURE_DEBUG
154
158/* recursived checks the linked list. Treasurelist is passed only 155/* recursived checks the linked list. Treasurelist is passed only
159 * so that the treasure name can be printed out 156 * so that the treasure name can be printed out
160 */ 157 */
161static void 158static void
162check_treasurelist (const treasure * t, const treasurelist * tl) 159check_treasurelist (const treasure *t, const treasurelist * tl)
163{ 160{
164 if (t->item == NULL && t->name == NULL) 161 if (t->item == NULL && t->name == NULL)
165 LOG (llevError, "Treasurelist %s has element with no name or archetype\n", &tl->name); 162 LOG (llevError, "Treasurelist %s has element with no name or archetype\n", &tl->name);
166 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no)) 163 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
167 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name); 164 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name);
199 } 196 }
200 while (fgets (buf, MAX_BUF, fp) != NULL) 197 while (fgets (buf, MAX_BUF, fp) != NULL)
201 { 198 {
202 line++; 199 line++;
203 if (*buf == '#') 200 if (*buf == '#')
204 continue; 201 continue;
205 202
206 if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name)) 203 if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name))
207 { 204 {
208 treasurelist *tl = get_empty_treasurelist (); 205 treasurelist *tl = get_empty_treasurelist ();
206
209 tl->name = name; 207 tl->name = name;
210 if (previous == NULL) 208 if (previous == NULL)
211 first_treasurelist = tl; 209 first_treasurelist = tl;
212 else 210 else
213 previous->next = tl; 211 previous->next = tl;
214 previous = tl; 212 previous = tl;
215 tl->items = load_treasure (fp, &line); 213 tl->items = load_treasure (fp, &line);
216 214
217 /* This is a one of the many items on the list should be generated. 215 /* This is a one of the many items on the list should be generated.
218 * Add up the chance total, and check to make sure the yes & no 216 * Add up the chance total, and check to make sure the yes & no
219 * fields of the treasures are not being used. 217 * fields of the treasures are not being used.
220 */ 218 */
221 if (!strncmp (buf, "treasureone", 11)) 219 if (!strncmp (buf, "treasureone", 11))
222 { 220 {
223 for (t = tl->items; t != NULL; t = t->next) 221 for (t = tl->items; t != NULL; t = t->next)
224 { 222 {
225#ifdef TREASURE_DEBUG 223#ifdef TREASURE_DEBUG
226 if (t->next_yes || t->next_no) 224 if (t->next_yes || t->next_no)
227 { 225 {
228 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); 226 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name);
229 LOG (llevError, " the next_yes or next_no field is set\n"); 227 LOG (llevError, " the next_yes or next_no field is set\n");
230 } 228 }
231#endif 229#endif
232 tl->total_chance += t->chance; 230 tl->total_chance += t->chance;
233 } 231 }
234 } 232 }
235 } 233 }
236 else 234 else
237 LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line); 235 LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line);
238 } 236 }
239 close_and_delete (fp, comp); 237 close_and_delete (fp, comp);
240 238
241#ifdef TREASURE_DEBUG 239#ifdef TREASURE_DEBUG
242 /* Perform some checks on how valid the treasure data actually is. 240 /* Perform some checks on how valid the treasure data actually is.
255 */ 253 */
256 254
257treasurelist * 255treasurelist *
258find_treasurelist (const char *name) 256find_treasurelist (const char *name)
259{ 257{
260 /* Special cases - randomitems of NULL is to override default. If 258 shstr_cmp name_ (name);
261 * first_treasurelist is null, it means we are on the first pass of 259
262 * of loading archetypes, so for now, just return - second pass will
263 * init these values.
264 */
265 if (!name) 260 if (!name_)
266 return 0; 261 return 0;
267 262
268 if (const char *tmp = shstr::find (name))
269 for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next) 263 for (treasurelist * tl = first_treasurelist; tl != 0; tl = tl->next)
270 if (tmp == tl->name) 264 if (name_ == tl->name)
271 return tl; 265 return tl;
272 266
273 if (first_treasurelist) 267 if (first_treasurelist)
274 LOG (llevError, "Couldn't find treasurelist %s\n", name); 268 LOG (llevError, "Couldn't find treasurelist %s\n", name);
275 269
276 return 0; 270 return 0;
289 * start with equipment, but only their abilities). 283 * start with equipment, but only their abilities).
290 */ 284 */
291 285
292 286
293static void 287static void
294put_treasure (object * op, object * creator, int flags) 288put_treasure (object *op, object *creator, int flags)
295{ 289{
296 object *tmp; 290 object *tmp;
297 291
298 /* Bit of a hack - spells should never be put onto the map. The entire 292 /* Bit of a hack - spells should never be put onto the map. The entire
299 * treasure stuff is a problem - there is no clear idea of knowing 293 * treasure stuff is a problem - there is no clear idea of knowing
309 } 303 }
310 else 304 else
311 { 305 {
312 op = insert_ob_in_ob (op, creator); 306 op = insert_ob_in_ob (op, creator);
313 if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) 307 if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER))
314 monster_check_apply (creator, op); 308 monster_check_apply (creator, op);
315 if ((flags & GT_UPDATE_INV) && (tmp = is_player_inv (creator)) != NULL) 309 if ((flags & GT_UPDATE_INV) && (tmp = is_player_inv (creator)) != NULL)
316 esrv_send_item (tmp, op); 310 esrv_send_item (tmp, op);
317 } 311 }
318} 312}
319 313
320/* if there are change_xxx commands in the treasure, we include the changes 314/* if there are change_xxx commands in the treasure, we include the changes
321 * in the generated object 315 * in the generated object
343 object *tmp; 337 object *tmp;
344 338
345 if ((int) t->chance >= 100 || (RANDOM () % 100 + 1) < (int) t->chance) 339 if ((int) t->chance >= 100 || (RANDOM () % 100 + 1) < (int) t->chance)
346 { 340 {
347 if (t->name) 341 if (t->name)
348 { 342 {
349 if (strcmp (t->name, "NONE") && difficulty >= t->magic) 343 if (strcmp (t->name, "NONE") && difficulty >= t->magic)
350 create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries); 344 create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries);
351 } 345 }
352 else 346 else
353 { 347 {
354 if (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)) 348 if (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE))
355 { 349 {
356 tmp = arch_to_object (t->item); 350 tmp = arch_to_object (t->item);
357 if (t->nrof && tmp->nrof <= 1) 351 if (t->nrof && tmp->nrof <= 1)
358 tmp->nrof = RANDOM () % ((int) t->nrof) + 1; 352 tmp->nrof = RANDOM () % ((int) t->nrof) + 1;
359 fix_generated_item (tmp, op, difficulty, t->magic, flag); 353 fix_generated_item (tmp, op, difficulty, t->magic, flag);
360 change_treasure (t, tmp); 354 change_treasure (t, tmp);
361 put_treasure (tmp, op, flag); 355 put_treasure (tmp, op, flag);
362 } 356 }
363 } 357 }
364 358
365 if (t->next_yes != NULL) 359 if (t->next_yes != NULL)
366 create_all_treasures (t->next_yes, op, flag, difficulty, tries); 360 create_all_treasures (t->next_yes, op, flag, difficulty, tries);
367 } 361 }
368 else if (t->next_no != NULL) 362 else if (t->next_no != NULL)
369 create_all_treasures (t->next_no, op, flag, difficulty, tries); 363 create_all_treasures (t->next_no, op, flag, difficulty, tries);
370 364
371 if (t->next != NULL) 365 if (t->next != NULL)
372 create_all_treasures (t->next, op, flag, difficulty, tries); 366 create_all_treasures (t->next, op, flag, difficulty, tries);
373} 367}
374 368
375void 369void
376create_one_treasure (treasurelist *tl, object * op, int flag, int difficulty, int tries) 370create_one_treasure (treasurelist * tl, object *op, int flag, int difficulty, int tries)
377{ 371{
378 int value = RANDOM () % tl->total_chance; 372 int value = RANDOM () % tl->total_chance;
379 treasure *t; 373 treasure *t;
380 374
381 if (tries++ > 100) 375 if (tries++ > 100)
387 for (t = tl->items; t != NULL; t = t->next) 381 for (t = tl->items; t != NULL; t = t->next)
388 { 382 {
389 value -= t->chance; 383 value -= t->chance;
390 384
391 if (value < 0) 385 if (value < 0)
392 break; 386 break;
393 } 387 }
394 388
395 if (!t || value >= 0) 389 if (!t || value >= 0)
396 { 390 {
397 LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n"); 391 LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n");
400 } 394 }
401 395
402 if (t->name) 396 if (t->name)
403 { 397 {
404 if (!strcmp (t->name, "NONE")) 398 if (!strcmp (t->name, "NONE"))
405 return; 399 return;
406 400
407 if (difficulty >= t->magic) 401 if (difficulty >= t->magic)
408 create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries); 402 create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries);
409 else if (t->nrof) 403 else if (t->nrof)
410 create_one_treasure (tl, op, flag, difficulty, tries); 404 create_one_treasure (tl, op, flag, difficulty, tries);
411 405
412 return; 406 return;
413 } 407 }
414 408
415 if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) 409 if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE)
416 { 410 {
417 object *tmp = arch_to_object (t->item); 411 object *tmp = arch_to_object (t->item);
418 412
419 if (!tmp) 413 if (!tmp)
420 return; 414 return;
421 415
422 if (t->nrof && tmp->nrof <= 1) 416 if (t->nrof && tmp->nrof <= 1)
423 tmp->nrof = RANDOM () % ((int) t->nrof) + 1; 417 tmp->nrof = RANDOM () % ((int) t->nrof) + 1;
424 418
425 fix_generated_item (tmp, op, difficulty, t->magic, flag); 419 fix_generated_item (tmp, op, difficulty, t->magic, flag);
426 change_treasure (t, tmp); 420 change_treasure (t, tmp);
427 put_treasure (tmp, op, flag); 421 put_treasure (tmp, op, flag);
428 } 422 }
434 * list transitions, or so that excessively good treasure will not be 428 * list transitions, or so that excessively good treasure will not be
435 * created on weak maps, because it will exceed the number of allowed tries 429 * created on weak maps, because it will exceed the number of allowed tries
436 * to do that. 430 * to do that.
437 */ 431 */
438void 432void
439create_treasure (treasurelist * t, object * op, int flag, int difficulty, int tries) 433create_treasure (treasurelist * t, object *op, int flag, int difficulty, int tries)
440{ 434{
441 435
442 if (tries++ > 100) 436 if (tries++ > 100)
443 { 437 {
444 LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n"); 438 LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
456 * inserted into, and then return that treausre 450 * inserted into, and then return that treausre
457 */ 451 */
458object * 452object *
459generate_treasure (treasurelist * t, int difficulty) 453generate_treasure (treasurelist * t, int difficulty)
460{ 454{
461 object *ob = get_object (), *tmp; 455 object *ob = object::create (), *tmp;
462 456
463 create_treasure (t, ob, 0, difficulty, 0); 457 create_treasure (t, ob, 0, difficulty, 0);
464 458
465 /* Don't want to free the object we are about to return */ 459 /* Don't want to free the object we are about to return */
466 tmp = ob->inv; 460 tmp = ob->inv;
467 if (tmp != NULL) 461 if (tmp != NULL)
468 remove_ob (tmp); 462 tmp->remove ();
463
469 if (ob->inv) 464 if (ob->inv)
470 {
471 LOG (llevError, "In generate treasure, created multiple objects.\n"); 465 LOG (llevError, "In generate treasure, created multiple objects.\n");
472 } 466
473 free_object (ob); 467 ob->destroy ();
474 return tmp; 468 return tmp;
475} 469}
476 470
477/* 471/*
478 * This is a new way of calculating the chance for an item to have 472 * This is a new way of calculating the chance for an item to have
480 * The array has two arguments, the difficulty of the level, and the 474 * The array has two arguments, the difficulty of the level, and the
481 * magical bonus "wanted". 475 * magical bonus "wanted".
482 */ 476 */
483 477
484static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = { 478static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = {
479
485/*chance of magic difficulty*/ 480/*chance of magic difficulty*/
481
486/* +0 +1 +2 +3 +4 */ 482/* +0 +1 +2 +3 +4 */
487 {95, 2, 2, 1, 0}, /*1 */ 483 {95, 2, 2, 1, 0}, /*1 */
488 {92, 5, 2, 1, 0}, /*2 */ 484 {92, 5, 2, 1, 0}, /*2 */
489 {85, 10, 4, 1, 0}, /*3 */ 485 {85, 10, 4, 1, 0}, /*3 */
490 {80, 14, 4, 2, 0}, /*4 */ 486 {80, 14, 4, 2, 0}, /*4 */
491 {75, 17, 5, 2, 1}, /*5 */ 487 {75, 17, 5, 2, 1}, /*5 */
492 {70, 18, 8, 3, 1}, /*6 */ 488 {70, 18, 8, 3, 1}, /*6 */
493 {65, 21, 10, 3, 1}, /*7 */ 489 {65, 21, 10, 3, 1}, /*7 */
494 {60, 22, 12, 4, 2}, /*8 */ 490 {60, 22, 12, 4, 2}, /*8 */
495 {55, 25, 14, 4, 2}, /*9 */ 491 {55, 25, 14, 4, 2}, /*9 */
496 {50, 27, 16, 5, 2}, /*10 */ 492 {50, 27, 16, 5, 2}, /*10 */
497 {45, 28, 18, 6, 3}, /*11 */ 493 {45, 28, 18, 6, 3}, /*11 */
498 {42, 28, 20, 7, 3}, /*12 */ 494 {42, 28, 20, 7, 3}, /*12 */
499 {40, 27, 21, 8, 4}, /*13 */ 495 {40, 27, 21, 8, 4}, /*13 */
500 {38, 25, 22, 10, 5}, /*14 */ 496 {38, 25, 22, 10, 5}, /*14 */
501 {36, 23, 23, 12, 6}, /*15 */ 497 {36, 23, 23, 12, 6}, /*15 */
502 {33, 21, 24, 14, 8}, /*16 */ 498 {33, 21, 24, 14, 8}, /*16 */
503 {31, 19, 25, 16, 9}, /*17 */ 499 {31, 19, 25, 16, 9}, /*17 */
504 {27, 15, 30, 18, 10}, /*18 */ 500 {27, 15, 30, 18, 10}, /*18 */
505 {20, 12, 30, 25, 13}, /*19 */ 501 {20, 12, 30, 25, 13}, /*19 */
506 {15, 10, 28, 30, 17}, /*20 */ 502 {15, 10, 28, 30, 17}, /*20 */
507 {13, 9, 27, 28, 23}, /*21 */ 503 {13, 9, 27, 28, 23}, /*21 */
508 {10, 8, 25, 28, 29}, /*22 */ 504 {10, 8, 25, 28, 29}, /*22 */
509 {8, 7, 23, 26, 36}, /*23 */ 505 {8, 7, 23, 26, 36}, /*23 */
510 {6, 6, 20, 22, 46}, /*24 */ 506 {6, 6, 20, 22, 46}, /*24 */
511 {4, 5, 17, 18, 56}, /*25 */ 507 {4, 5, 17, 18, 56}, /*25 */
512 {2, 4, 12, 14, 68}, /*26 */ 508 {2, 4, 12, 14, 68}, /*26 */
513 {0, 3, 7, 10, 80}, /*27 */ 509 {0, 3, 7, 10, 80}, /*27 */
514 {0, 0, 3, 7, 90}, /*28 */ 510 {0, 0, 3, 7, 90}, /*28 */
515 {0, 0, 0, 3, 97}, /*29 */ 511 {0, 0, 0, 3, 97}, /*29 */
516 {0, 0, 0, 0, 100}, /*30 */ 512 {0, 0, 0, 0, 100}, /*30 */
517 {0, 0, 0, 0, 100}, /*31 */ 513 {0, 0, 0, 0, 100}, /*31 */
518}; 514};
519 515
520 516
521/* calculate the appropriate level for wands staves and scrolls. 517/* calculate the appropriate level for wands staves and scrolls.
522 * This code presumes that op has had its spell object created (in op->inv) 518 * This code presumes that op has had its spell object created (in op->inv)
524 * elmex Wed Aug 9 17:44:59 CEST 2006: 520 * elmex Wed Aug 9 17:44:59 CEST 2006:
525 * Removed multiplicator, too many high-level items were generated on low-difficulty maps. 521 * Removed multiplicator, too many high-level items were generated on low-difficulty maps.
526 */ 522 */
527 523
528int 524int
529level_for_item (const object * op, int difficulty) 525level_for_item (const object *op, int difficulty)
530{ 526{
531 int olevel = 0; 527 int olevel = 0;
532 528
533 if (!op->inv) 529 if (!op->inv)
534 { 530 {
577 for (magic = 0; magic < (MAXMAGIC + 1); magic++) 573 for (magic = 0; magic < (MAXMAGIC + 1); magic++)
578 { 574 {
579 percent -= difftomagic_list[scaled_diff][magic]; 575 percent -= difftomagic_list[scaled_diff][magic];
580 576
581 if (percent < 0) 577 if (percent < 0)
582 break; 578 break;
583 } 579 }
584 580
585 if (magic == (MAXMAGIC + 1)) 581 if (magic == (MAXMAGIC + 1))
586 { 582 {
587 LOG (llevError, "Warning, table for difficulty (scaled %d) %d bad.\n", scaled_diff, difficulty); 583 LOG (llevError, "Warning, table for difficulty (scaled %d) %d bad.\n", scaled_diff, difficulty);
600 * This function doesn't work properly, should add use of archetypes 596 * This function doesn't work properly, should add use of archetypes
601 * to make it truly absolute. 597 * to make it truly absolute.
602 */ 598 */
603 599
604void 600void
605set_abs_magic (object * op, int magic) 601set_abs_magic (object *op, int magic)
606{ 602{
607 if (!magic) 603 if (!magic)
608 return; 604 return;
609 605
610 op->magic = magic; 606 op->magic = magic;
611 if (op->arch) 607 if (op->arch)
612 { 608 {
613 if (op->type == ARMOUR) 609 if (op->type == ARMOUR)
614 ARMOUR_SPEED (op) = (ARMOUR_SPEED (&op->arch->clone) * (100 + magic * 10)) / 100; 610 ARMOUR_SPEED (op) = (ARMOUR_SPEED (&op->arch->clone) * (100 + magic * 10)) / 100;
615 611
616 if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */ 612 if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */
617 magic = (-magic); 613 magic = (-magic);
618 op->weight = (op->arch->clone.weight * (100 - magic * 10)) / 100; 614 op->weight = (op->arch->clone.weight * (100 - magic * 10)) / 100;
619 } 615 }
620 else 616 else
621 { 617 {
622 if (op->type == ARMOUR) 618 if (op->type == ARMOUR)
623 ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100; 619 ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100;
624 if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */ 620 if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */
625 magic = (-magic); 621 magic = (-magic);
626 op->weight = (op->weight * (100 - magic * 10)) / 100; 622 op->weight = (op->weight * (100 - magic * 10)) / 100;
627 } 623 }
628} 624}
629 625
630/* 626/*
631 * Sets a random magical bonus in the given object based upon 627 * Sets a random magical bonus in the given object based upon
632 * the given difficulty, and the given max possible bonus. 628 * the given difficulty, and the given max possible bonus.
633 */ 629 */
634 630
635static void 631static void
636set_magic (int difficulty, object * op, int max_magic, int flags) 632set_magic (int difficulty, object *op, int max_magic, int flags)
637{ 633{
638 int i; 634 int i;
635
639 i = magic_from_difficulty (difficulty); 636 i = magic_from_difficulty (difficulty);
640 if ((flags & GT_ONLY_GOOD) && i < 0) 637 if ((flags & GT_ONLY_GOOD) && i < 0)
641 i = -i; 638 i = -i;
642 if (i > max_magic) 639 if (i > max_magic)
643 i = max_magic; 640 i = max_magic;
654 * other bonuses previously rolled and ones the item might natively have. 651 * other bonuses previously rolled and ones the item might natively have.
655 * 2) Add code to deal with new PR method. 652 * 2) Add code to deal with new PR method.
656 */ 653 */
657 654
658void 655void
659set_ring_bonus (object * op, int bonus) 656set_ring_bonus (object *op, int bonus)
660{ 657{
661 658
662 int r = RANDOM () % (bonus > 0 ? 25 : 11); 659 int r = RANDOM () % (bonus > 0 ? 25 : 11);
663 660
664 if (op->type == AMULET) 661 if (op->type == AMULET)
665 { 662 {
666 if (!(RANDOM () % 21)) 663 if (!(RANDOM () % 21))
667 r = 20 + RANDOM () % 2; 664 r = 20 + RANDOM () % 2;
668 else 665 else
669 { 666 {
670 if (RANDOM () & 2) 667 if (RANDOM () & 2)
671 r = 10; 668 r = 10;
672 else 669 else
673 r = 11 + RANDOM () % 9; 670 r = 11 + RANDOM () % 9;
674 } 671 }
675 } 672 }
676 673
677 switch (r) 674 switch (r)
678 { 675 {
679 /* Redone by MSW 2000-11-26 to have much less code. Also, 676 /* Redone by MSW 2000-11-26 to have much less code. Also,
680 * bonuses and penalties will stack and add to existing values. 677 * bonuses and penalties will stack and add to existing values.
681 * of the item. 678 * of the item.
682 */ 679 */
683 case 0: 680 case 0:
684 case 1: 681 case 1:
685 case 2: 682 case 2:
686 case 3: 683 case 3:
687 case 4: 684 case 4:
688 case 5: 685 case 5:
689 case 6: 686 case 6:
690 set_attr_value (&op->stats, r, (signed char) (bonus + get_attr_value (&op->stats, r))); 687 set_attr_value (&op->stats, r, (signed char) (bonus + get_attr_value (&op->stats, r)));
691 break; 688 break;
692 689
693 case 7: 690 case 7:
694 op->stats.dam += bonus; 691 op->stats.dam += bonus;
695 break; 692 break;
696 693
697 case 8: 694 case 8:
698 op->stats.wc += bonus; 695 op->stats.wc += bonus;
699 break; 696 break;
700 697
701 case 9: 698 case 9:
702 op->stats.food += bonus; /* hunger/sustenance */ 699 op->stats.food += bonus; /* hunger/sustenance */
703 break; 700 break;
704 701
705 case 10: 702 case 10:
706 op->stats.ac += bonus; 703 op->stats.ac += bonus;
707 break; 704 break;
708 705
709 /* Item that gives protections/vulnerabilities */ 706 /* Item that gives protections/vulnerabilities */
710 case 11: 707 case 11:
711 case 12: 708 case 12:
712 case 13: 709 case 13:
713 case 14: 710 case 14:
714 case 15: 711 case 15:
715 case 16: 712 case 16:
716 case 17: 713 case 17:
717 case 18: 714 case 18:
718 case 19: 715 case 19:
719 { 716 {
720 int b = 5 + FABS (bonus), val, resist = RANDOM () % num_resist_table; 717 int b = 5 + FABS (bonus), val, resist = RANDOM () % num_resist_table;
721 718
722 /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */ 719 /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
723 val = 10 + RANDOM () % b + RANDOM () % b + RANDOM () % b + RANDOM () % b; 720 val = 10 + RANDOM () % b + RANDOM () % b + RANDOM () % b + RANDOM () % b;
724 721
725 /* Cursed items need to have higher negative values to equal out with 722 /* Cursed items need to have higher negative values to equal out with
726 * positive values for how protections work out. Put another 723 * positive values for how protections work out. Put another
727 * little random element in since that they don't always end up with 724 * little random element in since that they don't always end up with
728 * even values. 725 * even values.
729 */ 726 */
730 if (bonus < 0) 727 if (bonus < 0)
731 val = 2 * -val - RANDOM () % b; 728 val = 2 * -val - RANDOM () % b;
732 if (val > 35) 729 if (val > 35)
733 val = 35; /* Upper limit */ 730 val = 35; /* Upper limit */
734 b = 0; 731 b = 0;
735 while (op->resist[resist_table[resist]] != 0 && b < 4) 732 while (op->resist[resist_table[resist]] != 0 && b < 4)
736 { 733 {
737 resist = RANDOM () % num_resist_table; 734 resist = RANDOM () % num_resist_table;
738 } 735 }
739 if (b == 4) 736 if (b == 4)
740 return; /* Not able to find a free resistance */ 737 return; /* Not able to find a free resistance */
741 op->resist[resist_table[resist]] = val; 738 op->resist[resist_table[resist]] = val;
742 /* We should probably do something more clever here to adjust value 739 /* We should probably do something more clever here to adjust value
743 * based on how good a resistance we gave. 740 * based on how good a resistance we gave.
744 */ 741 */
745 break; 742 break;
746 } 743 }
747 case 20: 744 case 20:
748 if (op->type == AMULET) 745 if (op->type == AMULET)
749 { 746 {
750 SET_FLAG (op, FLAG_REFL_SPELL); 747 SET_FLAG (op, FLAG_REFL_SPELL);
751 op->value *= 11; 748 op->value *= 11;
752 } 749 }
753 else 750 else
754 { 751 {
755 op->stats.hp = 1; /* regenerate hit points */ 752 op->stats.hp = 1; /* regenerate hit points */
756 op->value *= 4; 753 op->value *= 4;
757 } 754 }
758 break; 755 break;
759 756
760 case 21: 757 case 21:
761 if (op->type == AMULET) 758 if (op->type == AMULET)
762 { 759 {
763 SET_FLAG (op, FLAG_REFL_MISSILE); 760 SET_FLAG (op, FLAG_REFL_MISSILE);
764 op->value *= 9; 761 op->value *= 9;
765 } 762 }
766 else 763 else
767 { 764 {
768 op->stats.sp = 1; /* regenerate spell points */ 765 op->stats.sp = 1; /* regenerate spell points */
769 op->value *= 3; 766 op->value *= 3;
770 } 767 }
771 break; 768 break;
772 769
773 case 22: 770 case 22:
774 op->stats.exp += bonus; /* Speed! */ 771 op->stats.exp += bonus; /* Speed! */
775 op->value = (op->value * 2) / 3; 772 op->value = (op->value * 2) / 3;
776 break; 773 break;
777 } 774 }
778 if (bonus > 0) 775 if (bonus > 0)
779 op->value *= 2 * bonus; 776 op->value *= 2 * bonus;
780 else 777 else
781 op->value = -(op->value * 2 * bonus) / 3; 778 op->value = -(op->value * 2 * bonus) / 3;
792 789
793int 790int
794get_magic (int diff) 791get_magic (int diff)
795{ 792{
796 int i; 793 int i;
794
797 if (diff < 3) 795 if (diff < 3)
798 diff = 3; 796 diff = 3;
799 for (i = 0; i < 4; i++) 797 for (i = 0; i < 4; i++)
800 if (RANDOM () % diff) 798 if (RANDOM () % diff)
801 return i; 799 return i;
808/* 806/*
809 * fix_generated_item(): This is called after an item is generated, in 807 * fix_generated_item(): This is called after an item is generated, in
810 * order to set it up right. This produced magical bonuses, puts spells 808 * order to set it up right. This produced magical bonuses, puts spells
811 * into scrolls/books/wands, makes it unidentified, hides the value, etc. 809 * into scrolls/books/wands, makes it unidentified, hides the value, etc.
812 */ 810 */
811
813/* 4/28/96 added creator object from which op may now inherit properties based on 812/* 4/28/96 added creator object from which op may now inherit properties based on
814 * op->type. Right now, which stuff the creator passes on is object type 813 * op->type. Right now, which stuff the creator passes on is object type
815 * dependant. I know this is a spagetti manuever, but is there a cleaner 814 * dependant. I know this is a spagetti manuever, but is there a cleaner
816 * way to do this? b.t. */ 815 * way to do this? b.t. */
816
817/* 817/*
818 * ! (flags & GT_ENVIRONMENT): 818 * ! (flags & GT_ENVIRONMENT):
819 * Automatically calls fix_flesh_item(). 819 * Automatically calls fix_flesh_item().
820 * 820 *
821 * flags: 821 * flags:
825 * a working object - don't change magic, value, etc, but set it material 825 * a working object - don't change magic, value, etc, but set it material
826 * type as appropriate, for objects that need spell objects, set those, etc 826 * type as appropriate, for objects that need spell objects, set those, etc
827 */ 827 */
828 828
829void 829void
830fix_generated_item (object * op, object * creator, int difficulty, int max_magic, int flags) 830fix_generated_item (object *op, object *creator, int difficulty, int max_magic, int flags)
831{ 831{
832 int was_magic = op->magic, num_enchantments = 0, save_item_power = 0; 832 int was_magic = op->magic, num_enchantments = 0, save_item_power = 0;
833 833
834 if (!creator || creator->type == op->type) 834 if (!creator || creator->type == op->type)
835 creator = op; /*safety & to prevent polymorphed objects giving attributes */ 835 creator = op; /*safety & to prevent polymorphed objects giving attributes */
836 836
837 /* If we make an artifact, this information will be destroyed */ 837 /* If we make an artifact, this information will be destroyed */
838 save_item_power = op->item_power; 838 save_item_power = op->item_power;
839 op->item_power = 0; 839 op->item_power = 0;
840 840
841 if (op->randomitems && op->type != SPELL) 841 if (op->randomitems && op->type != SPELL)
842 { 842 {
843 create_treasure (op->randomitems, op, flags, difficulty, 0); 843 create_treasure (op->randomitems, op, flags, difficulty, 0);
844 if (!op->inv) 844 if (!op->inv)
845 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", &op->name); 845 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", &op->name);
846 846
847 /* So the treasure doesn't get created again */ 847 /* So the treasure doesn't get created again */
848 op->randomitems = NULL; 848 op->randomitems = NULL;
849 } 849 }
850 850
851 if (difficulty < 1) 851 if (difficulty < 1)
852 difficulty = 1; 852 difficulty = 1;
853 853
854 if (INVOKE_OBJECT (ADD_BONUS, op,
855 ARG_OBJECT (creator != op ? creator : 0),
856 ARG_INT (difficulty), ARG_INT (max_magic),
857 ARG_INT (flags)))
858 return;
859
854 if (!(flags & GT_MINIMAL)) 860 if (!(flags & GT_MINIMAL))
855 { 861 {
856 if (op->arch == crown_arch) 862 if (op->arch == crown_arch)
857 { 863 {
858 set_magic (difficulty, op, max_magic, flags); 864 set_magic (difficulty, op, max_magic, flags);
859 num_enchantments = calc_item_power (op, 1); 865 num_enchantments = calc_item_power (op, 1);
860 generate_artifact (op, difficulty); 866 generate_artifact (op, difficulty);
861 } 867 }
862 else 868 else
863 { 869 {
864 if (!op->magic && max_magic) 870 if (!op->magic && max_magic)
865 set_magic (difficulty, op, max_magic, flags); 871 set_magic (difficulty, op, max_magic, flags);
866 872
867 num_enchantments = calc_item_power (op, 1); 873 num_enchantments = calc_item_power (op, 1);
868 874
869 if ((!was_magic && !(RANDOM () % CHANCE_FOR_ARTIFACT)) || op->type == HORN || difficulty >= settings.max_level) /* high difficulties always generate an artifact, 875 if ((!was_magic && !(RANDOM () % CHANCE_FOR_ARTIFACT)) || op->type == HORN || difficulty >= settings.max_level) /* high difficulties always generate an artifact,
870 * used for shop_floors or treasures */ 876 * used for shop_floors or treasures */
871 generate_artifact (op, difficulty); 877 generate_artifact (op, difficulty);
872 } 878 }
873 879
874 /* Object was made an artifact. Calculate its item_power rating. 880 /* Object was made an artifact. Calculate its item_power rating.
875 * the item_power in the object is what the artfiact adds. 881 * the item_power in the object is what the artfiact adds.
876 */ 882 */
877 if (op->title) 883 if (op->title)
878 { 884 {
879 /* if save_item_power is set, then most likely we started with an 885 /* if save_item_power is set, then most likely we started with an
880 * artifact and have added new abilities to it - this is rare, but 886 * artifact and have added new abilities to it - this is rare, but
881 * but I have seen things like 'strange rings of fire'. So just figure 887 * but I have seen things like 'strange rings of fire'. So just figure
882 * out the power from the base power plus what this one adds. Note 888 * out the power from the base power plus what this one adds. Note
883 * that since item_power is not quite linear, this actually ends up 889 * that since item_power is not quite linear, this actually ends up
884 * being somewhat of a bonus 890 * being somewhat of a bonus
885 */ 891 */
886 if (save_item_power) 892 if (save_item_power)
887 op->item_power = save_item_power + get_power_from_ench (op->item_power); 893 op->item_power = save_item_power + get_power_from_ench (op->item_power);
888 else 894 else
889 op->item_power = get_power_from_ench (op->item_power + num_enchantments); 895 op->item_power = get_power_from_ench (op->item_power + num_enchantments);
890 } 896 }
891 else if (save_item_power) 897 else if (save_item_power)
892 { 898 {
893 /* restore the item_power field to the object if we haven't changed it. 899 /* restore the item_power field to the object if we haven't changed it.
894 * we don't care about num_enchantments - that will basically just 900 * we don't care about num_enchantments - that will basically just
895 * have calculated some value from the base attributes of the archetype. 901 * have calculated some value from the base attributes of the archetype.
896 */ 902 */
897 op->item_power = save_item_power; 903 op->item_power = save_item_power;
898 } 904 }
899 else 905 else
900 { 906 {
901 /* item_power was zero. This is suspicious, as it may be because it 907 /* item_power was zero. This is suspicious, as it may be because it
902 * was never previously calculated. Let's compute a value and see if 908 * was never previously calculated. Let's compute a value and see if
903 * it is non-zero. If it indeed is, then assign it as the new 909 * it is non-zero. If it indeed is, then assign it as the new
904 * item_power value. 910 * item_power value.
905 * - gros, 21th of July 2006. 911 * - gros, 21th of July 2006.
906 */ 912 */
907 op->item_power = calc_item_power (op, 0); 913 op->item_power = calc_item_power (op, 0);
908 save_item_power = op->item_power; /* Just in case it would get used 914 save_item_power = op->item_power; /* Just in case it would get used
909 * again below */ 915 * again below */
910 } 916 }
911 } 917 }
912 918
913 /* materialtype modifications. Note we allow this on artifacts. */ 919 /* materialtype modifications. Note we allow this on artifacts. */
914 set_materialname (op, difficulty, NULL); 920 set_materialname (op, difficulty, NULL);
915 921
916 if (flags & GT_MINIMAL) 922 if (flags & GT_MINIMAL)
917 { 923 {
918 if (op->type == POTION) 924 if (op->type == POTION)
919 /* Handle healing and magic power potions */ 925 /* Handle healing and magic power potions */
920 if (op->stats.sp && !op->randomitems) 926 if (op->stats.sp && !op->randomitems)
921 { 927 {
922 object *tmp; 928 object *tmp;
923 929
924 tmp = get_archetype (spell_mapping[op->stats.sp]); 930 tmp = get_archetype (spell_mapping[op->stats.sp]);
925 insert_ob_in_ob (tmp, op); 931 insert_ob_in_ob (tmp, op);
926 op->stats.sp = 0; 932 op->stats.sp = 0;
927 } 933 }
928 } 934 }
929 else if (!op->title) /* Only modify object if not special */ 935 else if (!op->title) /* Only modify object if not special */
930 switch (op->type) 936 switch (op->type)
931 { 937 {
932 case WEAPON: 938 case WEAPON:
933 case ARMOUR: 939 case ARMOUR:
934 case SHIELD: 940 case SHIELD:
935 case HELMET: 941 case HELMET:
936 case CLOAK: 942 case CLOAK:
937 if (QUERY_FLAG (op, FLAG_CURSED) && !(RANDOM () % 4)) 943 if (QUERY_FLAG (op, FLAG_CURSED) && !(RANDOM () % 4))
938 set_ring_bonus (op, -DICE2); 944 set_ring_bonus (op, -DICE2);
939 break; 945 break;
940 946
941 case BRACERS: 947 case BRACERS:
942 if (!(RANDOM () % (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20))) 948 if (!(RANDOM () % (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20)))
943 { 949 {
950 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
951 if (!QUERY_FLAG (op, FLAG_CURSED))
952 op->value *= 3;
953 }
954 break;
955
956 case POTION:
957 {
958 int too_many_tries = 0, is_special = 0;
959
960 /* Handle healing and magic power potions */
961 if (op->stats.sp && !op->randomitems)
962 {
963 object *tmp;
964
965 tmp = get_archetype (spell_mapping[op->stats.sp]);
966 insert_ob_in_ob (tmp, op);
967 op->stats.sp = 0;
968 }
969
970 while (!(is_special = special_potion (op)) && !op->inv)
971 {
972 generate_artifact (op, difficulty);
973 if (too_many_tries++ > 10)
974 break;
975 }
976
977 /* don't want to change value for healing/magic power potions,
978 * since the value set on those is already correct.
979 */
980 if (op->inv && op->randomitems)
981 {
982 /* value multiplier is same as for scrolls */
983 op->value = (op->value * op->inv->value);
984 op->level = op->inv->level / 2 + RANDOM () % difficulty + RANDOM () % difficulty;
985 }
986 else
987 {
988 op->name = "potion";
989 op->name_pl = "potions";
990 }
991
992 if (!(flags & GT_ONLY_GOOD) && RANDOM () % 2)
993 SET_FLAG (op, FLAG_CURSED);
994 break;
995 }
996
997 case AMULET:
998 if (op->arch == amulet_arch)
999 op->value *= 5; /* Since it's not just decoration */
1000
1001 case RING:
1002 if (op->arch == NULL)
1003 {
1004 op->destroy ();
1005 op = 0;
1006 break;
1007 }
1008
1009 if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */
1010 break;
1011
1012 if (!(flags & GT_ONLY_GOOD) && !(RANDOM () % 3))
1013 SET_FLAG (op, FLAG_CURSED);
1014
944 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2); 1015 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
945 if (!QUERY_FLAG (op, FLAG_CURSED))
946 op->value *= 3;
947 }
948 break;
949 1016
950 case POTION:
951 {
952 int too_many_tries = 0, is_special = 0;
953
954 /* Handle healing and magic power potions */
955 if (op->stats.sp && !op->randomitems)
956 {
957 object *tmp;
958
959 tmp = get_archetype (spell_mapping[op->stats.sp]);
960 insert_ob_in_ob (tmp, op);
961 op->stats.sp = 0;
962 }
963
964 while (!(is_special = special_potion (op)) && !op->inv)
965 {
966 generate_artifact (op, difficulty);
967 if (too_many_tries++ > 10)
968 break;
969 }
970
971 /* don't want to change value for healing/magic power potions,
972 * since the value set on those is already correct.
973 */
974 if (op->inv && op->randomitems)
975 {
976 /* value multiplier is same as for scrolls */
977 op->value = (op->value * op->inv->value);
978 op->level = op->inv->level / 2 + RANDOM () % difficulty + RANDOM () % difficulty;
979 }
980 else
981 {
982 op->name = "potion";
983 op->name_pl = "potions";
984 }
985
986 if (!(flags & GT_ONLY_GOOD) && RANDOM () % 2)
987 SET_FLAG (op, FLAG_CURSED);
988 break;
989 }
990
991 case AMULET:
992 if (op->arch == amulet_arch)
993 op->value *= 5; /* Since it's not just decoration */
994
995 case RING:
996 if (op->arch == NULL)
997 {
998 remove_ob (op);
999 free_object (op);
1000 op = NULL;
1001 break;
1002 }
1003
1004 if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */
1005 break;
1006
1007 if (!(flags & GT_ONLY_GOOD) && !(RANDOM () % 3))
1008 SET_FLAG (op, FLAG_CURSED);
1009
1010 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
1011
1012 if (op->type != RING) /* Amulets have only one ability */ 1017 if (op->type != RING) /* Amulets have only one ability */
1013 break; 1018 break;
1014 1019
1015 if (!(RANDOM () % 4)) 1020 if (!(RANDOM () % 4))
1016 { 1021 {
1017 int d = (RANDOM () % 2 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; 1022 int d = (RANDOM () % 2 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1018 1023
1019 if (d > 0) 1024 if (d > 0)
1020 op->value *= 3; 1025 op->value *= 3;
1021 1026
1022 set_ring_bonus (op, d); 1027 set_ring_bonus (op, d);
1023 1028
1024 if (!(RANDOM () % 4)) 1029 if (!(RANDOM () % 4))
1025 { 1030 {
1026 int d = (RANDOM () % 3 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; 1031 int d = (RANDOM () % 3 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1027 if (d > 0)
1028 op->value *= 5;
1029 set_ring_bonus (op, d);
1030 }
1031 }
1032 1032
1033 if (d > 0)
1034 op->value *= 5;
1035 set_ring_bonus (op, d);
1036 }
1037 }
1038
1033 if (GET_ANIM_ID (op)) 1039 if (GET_ANIM_ID (op))
1034 SET_ANIMATION (op, RANDOM () % ((int) NUM_ANIMATIONS (op))); 1040 SET_ANIMATION (op, RANDOM () % ((int) NUM_ANIMATIONS (op)));
1035 1041
1036 break; 1042 break;
1037 1043
1038 case BOOK: 1044 case BOOK:
1039 /* Is it an empty book?, if yes lets make a special· 1045 /* Is it an empty book?, if yes lets make a special·
1040 * msg for it, and tailor its properties based on the· 1046 * msg for it, and tailor its properties based on the·
1041 * creator and/or map level we found it on. 1047 * creator and/or map level we found it on.
1042 */ 1048 */
1043 if (!op->msg && RANDOM () % 10) 1049 if (!op->msg && RANDOM () % 10)
1044 { 1050 {
1045 /* set the book level properly */ 1051 /* set the book level properly */
1046 if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE)) 1052 if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE))
1047 { 1053 {
1048 if (op->map && op->map->difficulty) 1054 if (op->map && op->map->difficulty)
1049 op->level = RANDOM () % (op->map->difficulty) + RANDOM () % 10 + 1; 1055 op->level = RANDOM () % (op->map->difficulty) + RANDOM () % 10 + 1;
1050 else 1056 else
1051 op->level = RANDOM () % 20 + 1; 1057 op->level = RANDOM () % 20 + 1;
1052 } 1058 }
1053 else 1059 else
1054 op->level = RANDOM () % creator->level; 1060 op->level = RANDOM () % creator->level;
1055 1061
1056 tailor_readable_ob (op, (creator && creator->stats.sp) ? creator->stats.sp : -1); 1062 tailor_readable_ob (op, (creator && creator->stats.sp) ? creator->stats.sp : -1);
1057 /* books w/ info are worth more! */ 1063 /* books w/ info are worth more! */
1058 op->value *= ((op->level > 10 ? op->level : (op->level + 1) / 2) * ((strlen (op->msg) / 250) + 1)); 1064 op->value *= ((op->level > 10 ? op->level : (op->level + 1) / 2) * ((strlen (op->msg) / 250) + 1));
1059 /* creator related stuff */ 1065 /* creator related stuff */
1060 1066
1061 /* for library, chained books. Note that some monsters have no_pick 1067 /* for library, chained books. Note that some monsters have no_pick
1062 * set - we don't want to set no pick in that case. 1068 * set - we don't want to set no pick in that case.
1063 */ 1069 */
1064 if (QUERY_FLAG (creator, FLAG_NO_PICK) && !QUERY_FLAG (creator, FLAG_MONSTER)) 1070 if (QUERY_FLAG (creator, FLAG_NO_PICK) && !QUERY_FLAG (creator, FLAG_MONSTER))
1065 SET_FLAG (op, FLAG_NO_PICK); 1071 SET_FLAG (op, FLAG_NO_PICK);
1066 if (creator->slaying && !op->slaying) /* for check_inv floors */ 1072 if (creator->slaying && !op->slaying) /* for check_inv floors */
1067 op->slaying = creator->slaying; 1073 op->slaying = creator->slaying;
1068 1074
1069 /* add exp so reading it gives xp (once) */ 1075 /* add exp so reading it gives xp (once) */
1070 op->stats.exp = op->value > 10000 ? op->value / 5 : op->value / 10; 1076 op->stats.exp = op->value > 10000 ? op->value / 5 : op->value / 10;
1071 } 1077 }
1072 break; 1078 break;
1073 1079
1074 case SPELLBOOK: 1080 case SPELLBOOK:
1075 op->value = op->value * op->inv->value; 1081 op->value = op->value * op->inv->value;
1076 /* add exp so learning gives xp */ 1082 /* add exp so learning gives xp */
1077 op->level = op->inv->level; 1083 op->level = op->inv->level;
1078 op->stats.exp = op->value; 1084 op->stats.exp = op->value;
1079 break; 1085 break;
1080 1086
1081 case WAND: 1087 case WAND:
1082 /* nrof in the treasure list is number of charges, 1088 /* nrof in the treasure list is number of charges,
1083 * not number of wands. So copy that into food (charges), 1089 * not number of wands. So copy that into food (charges),
1084 * and reset nrof. 1090 * and reset nrof.
1085 */ 1091 */
1086 op->stats.food = op->inv->nrof; 1092 op->stats.food = op->inv->nrof;
1087 op->nrof = 1; 1093 op->nrof = 1;
1088 /* If the spell changes by level, choose a random level 1094 /* If the spell changes by level, choose a random level
1089 * for it, and adjust price. If the spell doesn't 1095 * for it, and adjust price. If the spell doesn't
1090 * change by level, just set the wand to the level of 1096 * change by level, just set the wand to the level of
1091 * the spell, and value calculation is simpler. 1097 * the spell, and value calculation is simpler.
1092 */ 1098 */
1093 if (op->inv->duration_modifier || op->inv->dam_modifier || op->inv->range_modifier) 1099 if (op->inv->duration_modifier || op->inv->dam_modifier || op->inv->range_modifier)
1094 { 1100 {
1101 op->level = level_for_item (op, difficulty);
1102 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1103 }
1104 else
1105 {
1106 op->level = op->inv->level;
1107 op->value = op->value * op->inv->value;
1108 }
1109 break;
1110
1111 case ROD:
1095 op->level = level_for_item (op, difficulty); 1112 op->level = level_for_item (op, difficulty);
1113 /* Add 50 to both level an divisor to keep prices a little more
1114 * reasonable. Otherwise, a high level version of a low level
1115 * spell can be worth tons a money (eg, level 20 rod, level 2 spell =
1116 * 10 time multiplier). This way, the value are a bit more reasonable.
1117 */
1096 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50); 1118 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1097 } 1119 /* maxhp is used to denote how many 'charges' the rod holds before */
1098 else 1120 if (op->stats.maxhp)
1099 { 1121 op->stats.maxhp *= MAX (op->inv->stats.sp, op->inv->stats.grace);
1100 op->level = op->inv->level; 1122 else
1101 op->value = op->value * op->inv->value; 1123 op->stats.maxhp = 2 * MAX (op->inv->stats.sp, op->inv->stats.grace);
1102 }
1103 break;
1104 1124
1125 op->stats.hp = op->stats.maxhp;
1126 break;
1127
1105 case ROD: 1128 case SCROLL:
1106 op->level = level_for_item (op, difficulty); 1129 op->level = level_for_item (op, difficulty);
1107 /* Add 50 to both level an divisor to keep prices a little more
1108 * reasonable. Otherwise, a high level version of a low level
1109 * spell can be worth tons a money (eg, level 20 rod, level 2 spell =
1110 * 10 time multiplier). This way, the value are a bit more reasonable.
1111 */
1112 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50); 1130 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1113 /* maxhp is used to denote how many 'charges' the rod holds before */
1114 if (op->stats.maxhp)
1115 op->stats.maxhp *= MAX (op->inv->stats.sp, op->inv->stats.grace);
1116 else
1117 op->stats.maxhp = 2 * MAX (op->inv->stats.sp, op->inv->stats.grace);
1118 1131
1119 op->stats.hp = op->stats.maxhp;
1120 break;
1121
1122 case SCROLL:
1123 op->level = level_for_item (op, difficulty);
1124 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1125
1126 /* add exp so reading them properly gives xp */ 1132 /* add exp so reading them properly gives xp */
1127 op->stats.exp = op->value / 5; 1133 op->stats.exp = op->value / 5;
1128 op->nrof = op->inv->nrof; 1134 op->nrof = op->inv->nrof;
1129 break; 1135 break;
1130 1136
1131 case RUNE: 1137 case RUNE:
1132 trap_adjust (op, difficulty); 1138 trap_adjust (op, difficulty);
1133 break; 1139 break;
1134 1140
1135 case TRAP: 1141 case TRAP:
1136 trap_adjust (op, difficulty); 1142 trap_adjust (op, difficulty);
1137 break; 1143 break;
1138 } /* switch type */ 1144 } /* switch type */
1139 1145
1140 if (flags & GT_STARTEQUIP) 1146 if (flags & GT_STARTEQUIP)
1141 { 1147 {
1142 if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN)) 1148 if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN))
1143 SET_FLAG (op, FLAG_STARTEQUIP); 1149 SET_FLAG (op, FLAG_STARTEQUIP);
1144 else if (op->type != MONEY) 1150 else if (op->type != MONEY)
1145 op->value = 0; 1151 op->value = 0;
1146 } 1152 }
1147 1153
1148 if (!(flags & GT_ENVIRONMENT)) 1154 if (!(flags & GT_ENVIRONMENT))
1149 fix_flesh_item (op, creator); 1155 fix_flesh_item (op, creator);
1150} 1156}
1163 1169
1164static artifactlist * 1170static artifactlist *
1165get_empty_artifactlist (void) 1171get_empty_artifactlist (void)
1166{ 1172{
1167 artifactlist *tl = (artifactlist *) malloc (sizeof (artifactlist)); 1173 artifactlist *tl = (artifactlist *) malloc (sizeof (artifactlist));
1174
1168 if (tl == NULL) 1175 if (tl == NULL)
1169 fatal (OUT_OF_MEMORY); 1176 fatal (OUT_OF_MEMORY);
1170 tl->next = NULL; 1177 tl->next = NULL;
1171 tl->items = NULL; 1178 tl->items = NULL;
1172 tl->total_chance = 0; 1179 tl->total_chance = 0;
1179 1186
1180static artifact * 1187static artifact *
1181get_empty_artifact (void) 1188get_empty_artifact (void)
1182{ 1189{
1183 artifact *t = (artifact *) malloc (sizeof (artifact)); 1190 artifact *t = (artifact *) malloc (sizeof (artifact));
1191
1184 if (t == NULL) 1192 if (t == NULL)
1185 fatal (OUT_OF_MEMORY); 1193 fatal (OUT_OF_MEMORY);
1186 t->item = NULL; 1194 t->item = NULL;
1187 t->next = NULL; 1195 t->next = NULL;
1188 t->chance = 0; 1196 t->chance = 0;
1221 fprintf (logfile, "\n"); 1229 fprintf (logfile, "\n");
1222 for (al = first_artifactlist; al != NULL; al = al->next) 1230 for (al = first_artifactlist; al != NULL; al = al->next)
1223 { 1231 {
1224 fprintf (logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance); 1232 fprintf (logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance);
1225 for (art = al->items; art != NULL; art = art->next) 1233 for (art = al->items; art != NULL; art = art->next)
1226 { 1234 {
1227 fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance); 1235 fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance);
1228 if (art->allowed != NULL) 1236 if (art->allowed != NULL)
1229 { 1237 {
1230 fprintf (logfile, "\tAllowed combinations:"); 1238 fprintf (logfile, "\tAllowed combinations:");
1231 for (next = art->allowed; next != NULL; next = next->next) 1239 for (next = art->allowed; next != NULL; next = next->next)
1232 fprintf (logfile, "%s,", &next->name); 1240 fprintf (logfile, "%s,", &next->name);
1233 fprintf (logfile, "\n"); 1241 fprintf (logfile, "\n");
1234 } 1242 }
1235 } 1243 }
1236 } 1244 }
1237 fprintf (logfile, "\n"); 1245 fprintf (logfile, "\n");
1238} 1246}
1239 1247
1240/* 1248/*
1241 * For debugging purposes. Dumps all treasures recursively (see below). 1249 * For debugging purposes. Dumps all treasures recursively (see below).
1242 */ 1250 */
1243void 1251void
1244dump_monster_treasure_rec (const char *name, treasure * t, int depth) 1252dump_monster_treasure_rec (const char *name, treasure *t, int depth)
1245{ 1253{
1246 treasurelist *tl; 1254 treasurelist *tl;
1247 int i; 1255 int i;
1248 1256
1249 if (depth > 100) 1257 if (depth > 100)
1250 return; 1258 return;
1251 while (t != NULL) 1259 while (t != NULL)
1252 { 1260 {
1253 if (t->name != NULL) 1261 if (t->name != NULL)
1254 { 1262 {
1255 for (i = 0; i < depth; i++) 1263 for (i = 0; i < depth; i++)
1256 fprintf (logfile, " "); 1264 fprintf (logfile, " ");
1257 fprintf (logfile, "{ (list: %s)\n", &t->name); 1265 fprintf (logfile, "{ (list: %s)\n", &t->name);
1258 tl = find_treasurelist (t->name); 1266 tl = find_treasurelist (t->name);
1259 dump_monster_treasure_rec (name, tl->items, depth + 2); 1267 dump_monster_treasure_rec (name, tl->items, depth + 2);
1260 for (i = 0; i < depth; i++) 1268 for (i = 0; i < depth; i++)
1261 fprintf (logfile, " "); 1269 fprintf (logfile, " ");
1262 fprintf (logfile, "} (end of list: %s)\n", &t->name); 1270 fprintf (logfile, "} (end of list: %s)\n", &t->name);
1263 } 1271 }
1264 else 1272 else
1265 { 1273 {
1266 for (i = 0; i < depth; i++) 1274 for (i = 0; i < depth; i++)
1267 fprintf (logfile, " "); 1275 fprintf (logfile, " ");
1268 if (t->item->clone.type == FLESH) 1276 if (t->item->clone.type == FLESH)
1269 fprintf (logfile, "%s's %s\n", name, &t->item->clone.name); 1277 fprintf (logfile, "%s's %s\n", name, &t->item->clone.name);
1270 else 1278 else
1271 fprintf (logfile, "%s\n", &t->item->clone.name); 1279 fprintf (logfile, "%s\n", &t->item->clone.name);
1272 } 1280 }
1273 if (t->next_yes != NULL) 1281 if (t->next_yes != NULL)
1274 { 1282 {
1275 for (i = 0; i < depth; i++) 1283 for (i = 0; i < depth; i++)
1276 fprintf (logfile, " "); 1284 fprintf (logfile, " ");
1277 fprintf (logfile, " (if yes)\n"); 1285 fprintf (logfile, " (if yes)\n");
1278 dump_monster_treasure_rec (name, t->next_yes, depth + 1); 1286 dump_monster_treasure_rec (name, t->next_yes, depth + 1);
1279 } 1287 }
1280 if (t->next_no != NULL) 1288 if (t->next_no != NULL)
1281 { 1289 {
1282 for (i = 0; i < depth; i++) 1290 for (i = 0; i < depth; i++)
1283 fprintf (logfile, " "); 1291 fprintf (logfile, " ");
1284 fprintf (logfile, " (if no)\n"); 1292 fprintf (logfile, " (if no)\n");
1285 dump_monster_treasure_rec (name, t->next_no, depth + 1); 1293 dump_monster_treasure_rec (name, t->next_no, depth + 1);
1286 } 1294 }
1287 t = t->next; 1295 t = t->next;
1288 } 1296 }
1289} 1297}
1290 1298
1291/* 1299/*
1302 found = 0; 1310 found = 0;
1303 fprintf (logfile, "\n"); 1311 fprintf (logfile, "\n");
1304 for (at = first_archetype; at != NULL; at = at->next) 1312 for (at = first_archetype; at != NULL; at = at->next)
1305 if (!strcasecmp (at->clone.name, name) && at->clone.title == NULL) 1313 if (!strcasecmp (at->clone.name, name) && at->clone.title == NULL)
1306 { 1314 {
1307 fprintf (logfile, "treasures for %s (arch: %s)\n", &at->clone.name, &at->name); 1315 fprintf (logfile, "treasures for %s (arch: %s)\n", &at->clone.name, &at->name);
1308 if (at->clone.randomitems != NULL) 1316 if (at->clone.randomitems != NULL)
1309 dump_monster_treasure_rec (at->clone.name, at->clone.randomitems->items, 1); 1317 dump_monster_treasure_rec (at->clone.name, at->clone.randomitems->items, 1);
1310 else 1318 else
1311 fprintf (logfile, "(nothing)\n"); 1319 fprintf (logfile, "(nothing)\n");
1312 fprintf (logfile, "\n"); 1320 fprintf (logfile, "\n");
1313 found++; 1321 found++;
1314 } 1322 }
1315 if (found == 0) 1323 if (found == 0)
1316 fprintf (logfile, "No objects have the name %s!\n\n", name); 1324 fprintf (logfile, "No objects have the name %s!\n\n", name);
1317} 1325}
1318 1326
1342 return; 1350 return;
1343 1351
1344 while (fgets (buf, HUGE_BUF, thawer) != NULL) 1352 while (fgets (buf, HUGE_BUF, thawer) != NULL)
1345 { 1353 {
1346 if (*buf == '#') 1354 if (*buf == '#')
1347 continue; 1355 continue;
1348 if ((cp = strchr (buf, '\n')) != NULL) 1356 if ((cp = strchr (buf, '\n')) != NULL)
1349 *cp = '\0'; 1357 *cp = '\0';
1350 cp = buf; 1358 cp = buf;
1351 while (*cp == ' ') /* Skip blanks */ 1359 while (*cp == ' ') /* Skip blanks */
1352 cp++; 1360 cp++;
1353 if (*cp == '\0') 1361 if (*cp == '\0')
1354 continue; 1362 continue;
1355 1363
1356 if (!strncmp (cp, "Allowed", 7)) 1364 if (!strncmp (cp, "Allowed", 7))
1357 { 1365 {
1358 if (art == NULL) 1366 if (art == NULL)
1359 { 1367 {
1360 art = get_empty_artifact (); 1368 art = get_empty_artifact ();
1361 nrofartifacts++; 1369 nrofartifacts++;
1362 } 1370 }
1363 cp = strchr (cp, ' ') + 1; 1371 cp = strchr (cp, ' ') + 1;
1364 if (!strcmp (cp, "all")) 1372 if (!strcmp (cp, "all"))
1365 continue; 1373 continue;
1366 1374
1367 do 1375 do
1368 { 1376 {
1369 nrofallowedstr++; 1377 nrofallowedstr++;
1370 if ((next = strchr (cp, ',')) != NULL) 1378 if ((next = strchr (cp, ',')) != NULL)
1371 *(next++) = '\0'; 1379 *(next++) = '\0';
1372 tmp = new linked_char; 1380 tmp = new linked_char;
1381
1373 tmp->name = cp; 1382 tmp->name = cp;
1374 tmp->next = art->allowed; 1383 tmp->next = art->allowed;
1375 art->allowed = tmp; 1384 art->allowed = tmp;
1376 } 1385 }
1377 while ((cp = next) != NULL); 1386 while ((cp = next) != NULL);
1378 } 1387 }
1379 else if (sscanf (cp, "chance %d", &value)) 1388 else if (sscanf (cp, "chance %d", &value))
1380 art->chance = (uint16) value; 1389 art->chance = (uint16) value;
1381 else if (sscanf (cp, "difficulty %d", &value)) 1390 else if (sscanf (cp, "difficulty %d", &value))
1382 art->difficulty = (uint8) value; 1391 art->difficulty = (uint8) value;
1383 else if (!strncmp (cp, "Object", 6)) 1392 else if (!strncmp (cp, "Object", 6))
1384 { 1393 {
1385 art->item = get_object (); 1394 art->item = object::create ();
1386 1395
1387 if (!load_object (thawer, art->item, 0)) 1396 if (!load_object (thawer, art->item, 0))
1388 LOG (llevError, "Init_Artifacts: Could not load object.\n"); 1397 LOG (llevError, "Init_Artifacts: Could not load object.\n");
1389 1398
1390 art->item->name = strchr (cp, ' ') + 1; 1399 art->item->name = strchr (cp, ' ') + 1;
1391 al = find_artifactlist (art->item->type); 1400 al = find_artifactlist (art->item->type);
1392 if (al == NULL) 1401 if (al == NULL)
1393 { 1402 {
1394 al = get_empty_artifactlist (); 1403 al = get_empty_artifactlist ();
1395 al->type = art->item->type; 1404 al->type = art->item->type;
1396 al->next = first_artifactlist; 1405 al->next = first_artifactlist;
1397 first_artifactlist = al; 1406 first_artifactlist = al;
1398 } 1407 }
1399 art->next = al->items; 1408 art->next = al->items;
1400 al->items = art; 1409 al->items = art;
1401 art = NULL; 1410 art = NULL;
1402 } 1411 }
1403 else 1412 else
1404 LOG (llevError, "Unknown input in artifact file: %s\n", buf); 1413 LOG (llevError, "Unknown input in artifact file: %s\n", buf);
1405 } 1414 }
1406 1415
1407 for (al = first_artifactlist; al != NULL; al = al->next) 1416 for (al = first_artifactlist; al != NULL; al = al->next)
1408 { 1417 {
1409 for (art = al->items; art != NULL; art = art->next) 1418 for (art = al->items; art != NULL; art = art->next)
1410 { 1419 {
1411 if (!art->chance) 1420 if (!art->chance)
1412 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name); 1421 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name);
1413 else 1422 else
1414 al->total_chance += art->chance; 1423 al->total_chance += art->chance;
1415 } 1424 }
1416#if 0 1425#if 0
1417 LOG (llevDebug, "Artifact list type %d has %d total chance\n", al->type, al->total_chance); 1426 LOG (llevDebug, "Artifact list type %d has %d total chance\n", al->type, al->total_chance);
1418#endif 1427#endif
1419 } 1428 }
1420 1429
1426 * Used in artifact generation. The bonuses of the first object 1435 * Used in artifact generation. The bonuses of the first object
1427 * is modified by the bonuses of the second object. 1436 * is modified by the bonuses of the second object.
1428 */ 1437 */
1429 1438
1430void 1439void
1431add_abilities (object * op, object * change) 1440add_abilities (object *op, object *change)
1432{ 1441{
1433 int i, tmp; 1442 int i, tmp;
1434 1443
1435 if (change->face != blank_face) 1444 if (change->face != blank_face)
1436 { 1445 {
1477 if (QUERY_FLAG (change, FLAG_STAND_STILL)) 1486 if (QUERY_FLAG (change, FLAG_STAND_STILL))
1478 { 1487 {
1479 CLEAR_FLAG (op, FLAG_ANIMATE); 1488 CLEAR_FLAG (op, FLAG_ANIMATE);
1480 /* so artifacts will join */ 1489 /* so artifacts will join */
1481 if (!QUERY_FLAG (op, FLAG_ALIVE)) 1490 if (!QUERY_FLAG (op, FLAG_ALIVE))
1482 op->speed = 0.0; 1491 op->speed = 0.0;
1483 1492
1484 update_ob_speed (op); 1493 update_ob_speed (op);
1485 } 1494 }
1486 1495
1487 if (change->nrof) 1496 if (change->nrof)
1488 op->nrof = RANDOM () % ((int) change->nrof) + 1; 1497 op->nrof = RANDOM () % ((int) change->nrof) + 1;
1489 1498
1490 op->stats.exp += change->stats.exp; /* Speed modifier */ 1499 op->stats.exp += change->stats.exp; /* Speed modifier */
1491 op->stats.wc += change->stats.wc; 1500 op->stats.wc += change->stats.wc;
1492 op->stats.ac += change->stats.ac; 1501 op->stats.ac += change->stats.ac;
1493 1502
1494 if (change->other_arch) 1503 if (change->other_arch)
1495 { 1504 {
1496 /* Basically, for horns & potions, the other_arch field is the spell 1505 /* Basically, for horns & potions, the other_arch field is the spell
1497 * to cast. So convert that to into a spell and put it into 1506 * to cast. So convert that to into a spell and put it into
1498 * this object. 1507 * this object.
1499 */ 1508 */
1500 if (op->type == HORN || op->type == POTION) 1509 if (op->type == HORN || op->type == POTION)
1501 { 1510 {
1502 object *tmp_obj; 1511 object *tmp_obj;
1512
1503 /* Remove any spells this object currently has in it */ 1513 /* Remove any spells this object currently has in it */
1504 while (op->inv) 1514 while (op->inv)
1505 { 1515 op->inv->destroy ();
1506 tmp_obj = op->inv;
1507 remove_ob (tmp_obj);
1508 free_object (tmp_obj);
1509 }
1510 1516
1511 tmp_obj = arch_to_object (change->other_arch); 1517 tmp_obj = arch_to_object (change->other_arch);
1512 insert_ob_in_ob (tmp_obj, op); 1518 insert_ob_in_ob (tmp_obj, op);
1513 } 1519 }
1514 /* No harm setting this for potions/horns */ 1520 /* No harm setting this for potions/horns */
1515 op->other_arch = change->other_arch; 1521 op->other_arch = change->other_arch;
1516 } 1522 }
1517 1523
1518 if (change->stats.hp < 0) 1524 if (change->stats.hp < 0)
1551 op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100; 1557 op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100;
1552 1558
1553 op->item_power = change->item_power; 1559 op->item_power = change->item_power;
1554 1560
1555 for (i = 0; i < NROFATTACKS; i++) 1561 for (i = 0; i < NROFATTACKS; i++)
1556 {
1557 if (change->resist[i]) 1562 if (change->resist[i])
1558 {
1559 op->resist[i] += change->resist[i]; 1563 op->resist[i] += change->resist[i];
1560 }
1561 }
1562 1564
1563 if (change->stats.dam) 1565 if (change->stats.dam)
1564 { 1566 {
1565 if (change->stats.dam < 0) 1567 if (change->stats.dam < 0)
1566 op->stats.dam = (-change->stats.dam); 1568 op->stats.dam = (-change->stats.dam);
1567 else if (op->stats.dam) 1569 else if (op->stats.dam)
1568 { 1570 {
1569 tmp = (signed char) (((int) op->stats.dam * (int) change->stats.dam) / 10); 1571 tmp = (signed char) (((int) op->stats.dam * (int) change->stats.dam) / 10);
1570 if (tmp == op->stats.dam) 1572 if (tmp == op->stats.dam)
1571 { 1573 {
1572 if (change->stats.dam < 10) 1574 if (change->stats.dam < 10)
1573 op->stats.dam--; 1575 op->stats.dam--;
1576 else
1577 op->stats.dam++;
1578 }
1574 else 1579 else
1575 op->stats.dam++;
1576 }
1577 else
1578 op->stats.dam = tmp; 1580 op->stats.dam = tmp;
1579 } 1581 }
1580 } 1582 }
1581 1583
1582 if (change->weight) 1584 if (change->weight)
1583 { 1585 {
1584 if (change->weight < 0) 1586 if (change->weight < 0)
1585 op->weight = (-change->weight); 1587 op->weight = (-change->weight);
1586 else 1588 else
1587 op->weight = (op->weight * (change->weight)) / 100; 1589 op->weight = (op->weight * (change->weight)) / 100;
1588 } 1590 }
1589 1591
1590 if (change->last_sp) 1592 if (change->last_sp)
1591 { 1593 {
1592 if (change->last_sp < 0) 1594 if (change->last_sp < 0)
1593 op->last_sp = (-change->last_sp); 1595 op->last_sp = (-change->last_sp);
1594 else 1596 else
1595 op->last_sp = (signed char) (((int) op->last_sp * (int) change->last_sp) / (int) 100); 1597 op->last_sp = (signed char) (((int) op->last_sp * (int) change->last_sp) / (int) 100);
1596 } 1598 }
1597 1599
1598 if (change->gen_sp_armour) 1600 if (change->gen_sp_armour)
1599 { 1601 {
1600 if (change->gen_sp_armour < 0) 1602 if (change->gen_sp_armour < 0)
1601 op->gen_sp_armour = (-change->gen_sp_armour); 1603 op->gen_sp_armour = (-change->gen_sp_armour);
1602 else 1604 else
1603 op->gen_sp_armour = (signed char) (((int) op->gen_sp_armour * ((int) change->gen_sp_armour)) / (int) 100); 1605 op->gen_sp_armour = (signed char) (((int) op->gen_sp_armour * ((int) change->gen_sp_armour)) / (int) 100);
1604 } 1606 }
1605 1607
1606 op->value *= change->value; 1608 op->value *= change->value;
1607 1609
1608 if (change->material) 1610 if (change->material)
1620 if (change->msg) 1622 if (change->msg)
1621 op->msg = change->msg; 1623 op->msg = change->msg;
1622} 1624}
1623 1625
1624static int 1626static int
1625legal_artifact_combination (object * op, artifact * art) 1627legal_artifact_combination (object *op, artifact * art)
1626{ 1628{
1627 int neg, success = 0; 1629 int neg, success = 0;
1628 linked_char *tmp; 1630 linked_char *tmp;
1629 const char *name; 1631 const char *name;
1630 1632
1631 if (art->allowed == (linked_char *) NULL) 1633 if (art->allowed == (linked_char *) NULL)
1632 return 1; /* Ie, "all" */ 1634 return 1; /* Ie, "all" */
1633 for (tmp = art->allowed; tmp; tmp = tmp->next) 1635 for (tmp = art->allowed; tmp; tmp = tmp->next)
1634 { 1636 {
1635#ifdef TREASURE_VERBOSE 1637#ifdef TREASURE_VERBOSE
1636 LOG (llevDebug, "legal_art: %s\n", tmp->name); 1638 LOG (llevDebug, "legal_art: %s\n", tmp->name);
1637#endif 1639#endif
1638 if (*tmp->name == '!') 1640 if (*tmp->name == '!')
1639 name = tmp->name + 1, neg = 1; 1641 name = tmp->name + 1, neg = 1;
1640 else 1642 else
1641 name = tmp->name, neg = 0; 1643 name = tmp->name, neg = 0;
1642 1644
1643 /* If we match name, then return the opposite of 'neg' */ 1645 /* If we match name, then return the opposite of 'neg' */
1644 if (!strcmp (name, op->name) || (op->arch && !strcmp (name, op->arch->name))) 1646 if (!strcmp (name, op->name) || (op->arch && !strcmp (name, op->arch->name)))
1645 return !neg; 1647 return !neg;
1646 1648
1647 /* Set success as true, since if the match was an inverse, it means 1649 /* Set success as true, since if the match was an inverse, it means
1648 * everything is allowed except what we match 1650 * everything is allowed except what we match
1649 */ 1651 */
1650 else if (neg) 1652 else if (neg)
1651 success = 1; 1653 success = 1;
1652 } 1654 }
1653 return success; 1655 return success;
1654} 1656}
1655 1657
1656/* 1658/*
1663{ 1665{
1664 char new_name[MAX_BUF]; 1666 char new_name[MAX_BUF];
1665 1667
1666 sprintf (new_name, "of %s", &artifct->name); 1668 sprintf (new_name, "of %s", &artifct->name);
1667 op->title = new_name; 1669 op->title = new_name;
1668 add_abilities (op, artifct); /* Give out the bonuses */ 1670 add_abilities (op, artifct); /* Give out the bonuses */
1669 1671
1670#if 0 /* Bit verbose, but keep it here until next time I need it... */ 1672#if 0 /* Bit verbose, but keep it here until next time I need it... */
1671 { 1673 {
1672 char identified = QUERY_FLAG (op, FLAG_IDENTIFIED); 1674 char identified = QUERY_FLAG (op, FLAG_IDENTIFIED);
1675
1673 SET_FLAG (op, FLAG_IDENTIFIED); 1676 SET_FLAG (op, FLAG_IDENTIFIED);
1674 LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL)); 1677 LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL));
1675 if (!identified) 1678 if (!identified)
1676 CLEAR_FLAG (op, FLAG_IDENTIFIED); 1679 CLEAR_FLAG (op, FLAG_IDENTIFIED);
1677 } 1680 }
1689 1692
1690/* Give 1 re-roll attempt per artifact */ 1693/* Give 1 re-roll attempt per artifact */
1691#define ARTIFACT_TRIES 2 1694#define ARTIFACT_TRIES 2
1692 1695
1693void 1696void
1694generate_artifact (object * op, int difficulty) 1697generate_artifact (object *op, int difficulty)
1695{ 1698{
1696 artifactlist *al; 1699 artifactlist *al;
1697 artifact *art; 1700 artifact *art;
1698 int i; 1701 int i;
1699 1702
1700 al = find_artifactlist (op->type); 1703 al = find_artifactlist (op->type);
1701 1704
1702 if (al == NULL) 1705 if (al == NULL)
1703 { 1706 {
1704#if 0 /* This is too verbose, usually */ 1707#if 0 /* This is too verbose, usually */
1705 LOG (llevDebug, "Couldn't change %s into artifact - no table.\n", op->name); 1708 LOG (llevDebug, "Couldn't change %s into artifact - no table.\n", op->name);
1706#endif 1709#endif
1707 return; 1710 return;
1708 } 1711 }
1709 1712
1710 for (i = 0; i < ARTIFACT_TRIES; i++) 1713 for (i = 0; i < ARTIFACT_TRIES; i++)
1711 { 1714 {
1712 int roll = RANDOM () % al->total_chance; 1715 int roll = RANDOM () % al->total_chance;
1713 1716
1714 for (art = al->items; art != NULL; art = art->next) 1717 for (art = al->items; art != NULL; art = art->next)
1715 { 1718 {
1716 roll -= art->chance; 1719 roll -= art->chance;
1717 if (roll < 0) 1720 if (roll < 0)
1718 break; 1721 break;
1719 } 1722 }
1720 1723
1721 if (art == NULL || roll >= 0) 1724 if (art == NULL || roll >= 0)
1722 { 1725 {
1723#if 1 1726#if 1
1724 LOG (llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", op->type); 1727 LOG (llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", op->type);
1725#endif 1728#endif
1726 return; 1729 return;
1727 } 1730 }
1728 if (!strcmp (art->item->name, "NONE")) 1731 if (!strcmp (art->item->name, "NONE"))
1729 return; 1732 return;
1730 if (FABS (op->magic) < art->item->magic) 1733 if (FABS (op->magic) < art->item->magic)
1731 continue; /* Not magic enough to be this item */ 1734 continue; /* Not magic enough to be this item */
1732 1735
1733 /* Map difficulty not high enough */ 1736 /* Map difficulty not high enough */
1734 if (difficulty < art->difficulty) 1737 if (difficulty < art->difficulty)
1735 continue; 1738 continue;
1736 1739
1737 if (!legal_artifact_combination (op, art)) 1740 if (!legal_artifact_combination (op, art))
1738 { 1741 {
1739#ifdef TREASURE_VERBOSE 1742#ifdef TREASURE_VERBOSE
1740 LOG (llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name); 1743 LOG (llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name);
1741#endif 1744#endif
1742 continue; 1745 continue;
1743 } 1746 }
1744 give_artifact_abilities (op, art->item); 1747 give_artifact_abilities (op, art->item);
1745 return; 1748 return;
1746 } 1749 }
1747} 1750}
1748 1751
1750 * FOOD, except they inherit properties (name, food value, etc). 1753 * FOOD, except they inherit properties (name, food value, etc).
1751 * based on the original owner (or 'donor' if you like). -b.t. 1754 * based on the original owner (or 'donor' if you like). -b.t.
1752 */ 1755 */
1753 1756
1754void 1757void
1755fix_flesh_item (object * item, object * donor) 1758fix_flesh_item (object *item, object *donor)
1756{ 1759{
1757 char tmpbuf[MAX_BUF]; 1760 char tmpbuf[MAX_BUF];
1758 int i; 1761 int i;
1759 1762
1760 if (item->type == FLESH && donor) 1763 if (item->type == FLESH && donor)
1761 { 1764 {
1762 /* change the name */ 1765 /* change the name */
1763 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name); item->name = tmpbuf; 1766 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name);
1767 item->name = tmpbuf;
1764 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name_pl); item->name_pl = tmpbuf; 1768 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name_pl);
1769 item->name_pl = tmpbuf;
1765 1770
1766 /* weight is FLESH weight/100 * donor */ 1771 /* weight is FLESH weight/100 * donor */
1767 if ((item->weight = (signed long) (((double) item->weight / (double) 100.0) * (double) donor->weight)) == 0) 1772 if ((item->weight = (signed long) (((double) item->weight / (double) 100.0) * (double) donor->weight)) == 0)
1768 item->weight = 1; 1773 item->weight = 1;
1769 1774
1770 /* value is multiplied by level of donor */ 1775 /* value is multiplied by level of donor */
1771 item->value *= isqrt (donor->level * 2); 1776 item->value *= isqrt (donor->level * 2);
1772 1777
1773 /* food value */ 1778 /* food value */
1775 1780
1776 /* flesh items inherit some abilities of donor, but not 1781 /* flesh items inherit some abilities of donor, but not
1777 * full effect. 1782 * full effect.
1778 */ 1783 */
1779 for (i = 0; i < NROFATTACKS; i++) 1784 for (i = 0; i < NROFATTACKS; i++)
1780 item->resist[i] = donor->resist[i] / 2; 1785 item->resist[i] = donor->resist[i] / 2;
1781 1786
1782 /* item inherits donor's level (important for quezals) */ 1787 /* item inherits donor's level (important for quezals) */
1783 item->level = donor->level; 1788 item->level = donor->level;
1784 1789
1785 /* if donor has some attacktypes, the flesh is poisonous */ 1790 /* if donor has some attacktypes, the flesh is poisonous */
1786 if (donor->attacktype & AT_POISON) 1791 if (donor->attacktype & AT_POISON)
1787 item->type = POISON; 1792 item->type = POISON;
1788 if (donor->attacktype & AT_ACID) 1793 if (donor->attacktype & AT_ACID)
1789 item->stats.hp = -1 * item->stats.food; 1794 item->stats.hp = -1 * item->stats.food;
1790 SET_FLAG (item, FLAG_NO_STEAL); 1795 SET_FLAG (item, FLAG_NO_STEAL);
1791 } 1796 }
1792} 1797}
1793 1798
1794/* special_potion() - so that old potion code is still done right. */ 1799/* special_potion() - so that old potion code is still done right. */
1795 1800
1796int 1801int
1797special_potion (object * op) 1802special_potion (object *op)
1798{ 1803{
1799 1804
1800 int i; 1805 int i;
1801 1806
1802 if (op->attacktype) 1807 if (op->attacktype)
1811 1816
1812 return 0; 1817 return 0;
1813} 1818}
1814 1819
1815void 1820void
1816free_treasurestruct (treasure * t) 1821free_treasurestruct (treasure *t)
1817{ 1822{
1818 if (t->next) 1823 if (t->next)
1819 free_treasurestruct (t->next); 1824 free_treasurestruct (t->next);
1820 if (t->next_yes) 1825 if (t->next_yes)
1821 free_treasurestruct (t->next_yes); 1826 free_treasurestruct (t->next_yes);
1824 1829
1825 delete t; 1830 delete t;
1826} 1831}
1827 1832
1828void 1833void
1829free_charlinks (linked_char * lc) 1834free_charlinks (linked_char *lc)
1830{ 1835{
1831 if (lc->next) 1836 if (lc->next)
1832 free_charlinks (lc->next); 1837 free_charlinks (lc->next);
1833 1838
1834 delete lc; 1839 delete lc;
1841 free_artifact (at->next); 1846 free_artifact (at->next);
1842 1847
1843 if (at->allowed) 1848 if (at->allowed)
1844 free_charlinks (at->allowed); 1849 free_charlinks (at->allowed);
1845 1850
1846 at->item->free (1); 1851 at->item->destroy (1);
1847 1852
1848 delete at; 1853 delete at;
1849} 1854}
1850 1855
1851void 1856void
1852free_artifactlist (artifactlist * al) 1857free_artifactlist (artifactlist * al)
1853{ 1858{
1854 artifactlist *nextal; 1859 artifactlist *nextal;
1855 1860
1856 for (al = first_artifactlist; al != NULL; al = nextal) 1861 for (al = first_artifactlist; al; al = nextal)
1857 { 1862 {
1858 nextal = al->next; 1863 nextal = al->next;
1859 1864
1860 if (al->items) 1865 if (al->items)
1861 free_artifact (al->items); 1866 free_artifact (al->items);
1862 1867
1863 free (al); 1868 free (al);
1864 } 1869 }
1865} 1870}
1866 1871
1872 1877
1873 for (tl = first_treasurelist; tl != NULL; tl = next) 1878 for (tl = first_treasurelist; tl != NULL; tl = next)
1874 { 1879 {
1875 next = tl->next; 1880 next = tl->next;
1876 if (tl->items) 1881 if (tl->items)
1877 free_treasurestruct (tl->items); 1882 free_treasurestruct (tl->items);
1878 delete tl; 1883 delete tl;
1879 } 1884 }
1880 free_artifactlist (first_artifactlist); 1885 free_artifactlist (first_artifactlist);
1881} 1886}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines