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.11 by root, Mon Sep 4 11:07:59 2006 UTC vs.
Revision 1.31 by pippijn, Sat Jan 6 14:42:29 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines