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

Comparing deliantra/server/common/treasure.C (file contents):
Revision 1.15 by root, Sat Sep 9 21:48:28 2006 UTC vs.
Revision 1.29 by root, Tue Dec 26 20:04:09 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines