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.7 by root, Sun Sep 3 00:18:40 2006 UTC vs.
Revision 1.21 by root, Wed Sep 27 00:36:08 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines