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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines