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.9 by elmex, Sun Sep 3 14:33:48 2006 UTC vs.
Revision 1.29 by root, Tue Dec 26 20:04:09 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines