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.10 by root, Sun Sep 3 22:45:55 2006 UTC vs.
Revision 1.30 by elmex, Wed Jan 3 02:30:51 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines