1 | |
1 | |
2 | /* |
2 | /* |
3 | * static char *rcs_treasure_c = |
3 | * static char *rcs_treasure_c = |
4 | * "$Id: treasure.C,v 1.7 2006/09/03 00:18:40 root Exp $"; |
4 | * "$Id: treasure.C,v 1.13 2006/09/05 17:58:11 root Exp $"; |
5 | */ |
5 | */ |
6 | |
6 | |
7 | /* |
7 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
8 | CrossFire, A Multiplayer game for X-windows |
9 | |
9 | |
… | |
… | |
121 | { |
121 | { |
122 | if ((t->item = find_archetype (variable)) == NULL) |
122 | if ((t->item = find_archetype (variable)) == NULL) |
123 | LOG (llevError, "Treasure lacks archetype: %s\n", variable); |
123 | LOG (llevError, "Treasure lacks archetype: %s\n", variable); |
124 | } |
124 | } |
125 | else if (sscanf (cp, "list %s", variable)) |
125 | else if (sscanf (cp, "list %s", variable)) |
126 | t->name = variable; |
126 | t->name = variable; |
127 | else if (sscanf (cp, "change_name %s", variable)) |
127 | else if (sscanf (cp, "change_name %s", variable)) |
128 | t->change_arch.name = variable; |
128 | t->change_arch.name = variable; |
129 | else if (sscanf (cp, "change_title %s", variable)) |
129 | else if (sscanf (cp, "change_title %s", variable)) |
130 | t->change_arch.title = variable; |
130 | t->change_arch.title = variable; |
131 | else if (sscanf (cp, "change_slaying %s", variable)) |
131 | else if (sscanf (cp, "change_slaying %s", variable)) |
… | |
… | |
255 | */ |
255 | */ |
256 | |
256 | |
257 | treasurelist * |
257 | treasurelist * |
258 | find_treasurelist (const char *name) |
258 | find_treasurelist (const char *name) |
259 | { |
259 | { |
260 | const char *tmp = shstr::find (name); |
|
|
261 | treasurelist *tl; |
|
|
262 | |
|
|
263 | /* Special cases - randomitems of none is to override default. If |
260 | /* Special cases - randomitems of NULL is to override default. If |
264 | * first_treasurelist is null, it means we are on the first pass of |
261 | * 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 |
262 | * of loading archetypes, so for now, just return - second pass will |
266 | * init these values. |
263 | * init these values. |
267 | */ |
264 | */ |
268 | if (!name || !*name) |
265 | if (!name) |
269 | return NULL; |
266 | return 0; |
270 | |
267 | |
271 | if (tmp != NULL) |
268 | if (const char *tmp = shstr::find (name)) |
272 | for (tl = first_treasurelist; tl != NULL; tl = tl->next) |
269 | for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next) |
273 | if (tmp == tl->name) |
270 | if (tmp == tl->name) |
274 | return tl; |
271 | return tl; |
275 | |
272 | |
|
|
273 | if (first_treasurelist) |
276 | LOG (llevError, "Couldn't find treasurelist %s\n", name); |
274 | LOG (llevError, "Couldn't find treasurelist %s\n", name); |
|
|
275 | |
277 | return NULL; |
276 | return 0; |
278 | } |
277 | } |
279 | |
278 | |
280 | |
279 | |
281 | /* |
280 | /* |
282 | * Generates the objects specified by the given treasure. |
281 | * Generates the objects specified by the given treasure. |
… | |
… | |
320 | |
319 | |
321 | /* if there are change_xxx commands in the treasure, we include the changes |
320 | /* if there are change_xxx commands in the treasure, we include the changes |
322 | * in the generated object |
321 | * in the generated object |
323 | */ |
322 | */ |
324 | static void |
323 | static void |
325 | change_treasure (treasure * t, object * op) |
324 | change_treasure (treasure *t, object *op) |
326 | { |
325 | { |
327 | /* CMD: change_name xxxx */ |
326 | /* CMD: change_name xxxx */ |
328 | if (t->change_arch.name) |
327 | if (t->change_arch.name) |
329 | { |
328 | { |
330 | op->name = t->change_arch.name; |
329 | op->name = t->change_arch.name; |
… | |
… | |
337 | if (t->change_arch.slaying) |
336 | if (t->change_arch.slaying) |
338 | op->slaying = t->change_arch.slaying; |
337 | op->slaying = t->change_arch.slaying; |
339 | } |
338 | } |
340 | |
339 | |
341 | void |
340 | void |
342 | create_all_treasures (treasure * t, object * op, int flag, int difficulty, int tries) |
341 | create_all_treasures (treasure *t, object *op, int flag, int difficulty, int tries) |
343 | { |
342 | { |
344 | object *tmp; |
343 | object *tmp; |
345 | |
|
|
346 | |
344 | |
347 | if ((int) t->chance >= 100 || (RANDOM () % 100 + 1) < (int) t->chance) |
345 | if ((int) t->chance >= 100 || (RANDOM () % 100 + 1) < (int) t->chance) |
348 | { |
346 | { |
349 | if (t->name) |
347 | if (t->name) |
350 | { |
348 | { |
… | |
… | |
361 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
359 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
362 | change_treasure (t, tmp); |
360 | change_treasure (t, tmp); |
363 | put_treasure (tmp, op, flag); |
361 | put_treasure (tmp, op, flag); |
364 | } |
362 | } |
365 | } |
363 | } |
|
|
364 | |
366 | if (t->next_yes != NULL) |
365 | if (t->next_yes != NULL) |
367 | create_all_treasures (t->next_yes, op, flag, difficulty, tries); |
366 | create_all_treasures (t->next_yes, op, flag, difficulty, tries); |
368 | } |
367 | } |
369 | else if (t->next_no != NULL) |
368 | else if (t->next_no != NULL) |
370 | create_all_treasures (t->next_no, op, flag, difficulty, tries); |
369 | create_all_treasures (t->next_no, op, flag, difficulty, tries); |
|
|
370 | |
371 | if (t->next != NULL) |
371 | if (t->next != NULL) |
372 | create_all_treasures (t->next, op, flag, difficulty, tries); |
372 | create_all_treasures (t->next, op, flag, difficulty, tries); |
373 | } |
373 | } |
374 | |
374 | |
375 | void |
375 | void |
376 | create_one_treasure (treasurelist * tl, object * op, int flag, int difficulty, int tries) |
376 | create_one_treasure (treasurelist *tl, object * op, int flag, int difficulty, int tries) |
377 | { |
377 | { |
378 | int value = RANDOM () % tl->total_chance; |
378 | int value = RANDOM () % tl->total_chance; |
379 | treasure *t; |
379 | treasure *t; |
380 | |
380 | |
381 | if (tries++ > 100) |
381 | if (tries++ > 100) |
382 | { |
382 | { |
383 | LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n"); |
383 | LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n"); |
384 | return; |
384 | return; |
385 | } |
385 | } |
|
|
386 | |
386 | for (t = tl->items; t != NULL; t = t->next) |
387 | for (t = tl->items; t != NULL; t = t->next) |
387 | { |
388 | { |
388 | value -= t->chance; |
389 | value -= t->chance; |
|
|
390 | |
389 | if (value < 0) |
391 | if (value < 0) |
390 | break; |
392 | break; |
391 | } |
393 | } |
392 | |
394 | |
393 | if (!t || value >= 0) |
395 | if (!t || value >= 0) |
394 | { |
396 | { |
395 | LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n"); |
397 | LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n"); |
396 | abort (); |
398 | abort (); |
397 | return; |
399 | return; |
398 | } |
400 | } |
|
|
401 | |
399 | if (t->name) |
402 | if (t->name) |
400 | { |
403 | { |
401 | if (!strcmp (t->name, "NONE")) |
404 | if (!strcmp (t->name, "NONE")) |
402 | return; |
405 | return; |
|
|
406 | |
403 | if (difficulty >= t->magic) |
407 | if (difficulty >= t->magic) |
404 | create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries); |
408 | create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries); |
405 | else if (t->nrof) |
409 | else if (t->nrof) |
406 | create_one_treasure (tl, op, flag, difficulty, tries); |
410 | create_one_treasure (tl, op, flag, difficulty, tries); |
|
|
411 | |
407 | return; |
412 | return; |
408 | } |
413 | } |
|
|
414 | |
409 | if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) |
415 | if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) |
410 | { |
416 | { |
411 | object *tmp = arch_to_object (t->item); |
417 | object *tmp = arch_to_object (t->item); |
|
|
418 | |
412 | if (!tmp) |
419 | if (!tmp) |
413 | return; |
420 | return; |
|
|
421 | |
414 | if (t->nrof && tmp->nrof <= 1) |
422 | if (t->nrof && tmp->nrof <= 1) |
415 | tmp->nrof = RANDOM () % ((int) t->nrof) + 1; |
423 | tmp->nrof = RANDOM () % ((int) t->nrof) + 1; |
|
|
424 | |
416 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
425 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
417 | change_treasure (t, tmp); |
426 | change_treasure (t, tmp); |
418 | put_treasure (tmp, op, flag); |
427 | put_treasure (tmp, op, flag); |
419 | } |
428 | } |
420 | } |
429 | } |
… | |
… | |
1371 | art->chance = (uint16) value; |
1380 | art->chance = (uint16) value; |
1372 | else if (sscanf (cp, "difficulty %d", &value)) |
1381 | else if (sscanf (cp, "difficulty %d", &value)) |
1373 | art->difficulty = (uint8) value; |
1382 | art->difficulty = (uint8) value; |
1374 | else if (!strncmp (cp, "Object", 6)) |
1383 | else if (!strncmp (cp, "Object", 6)) |
1375 | { |
1384 | { |
1376 | art->item = (object *) calloc (1, sizeof (object)); |
1385 | art->item = get_object (); |
1377 | reset_object (art->item); |
1386 | |
1378 | if (!load_object (thawer, art->item, LO_LINEMODE, 0)) |
1387 | if (!load_object (thawer, art->item, 0)) |
1379 | LOG (llevError, "Init_Artifacts: Could not load object.\n"); |
1388 | LOG (llevError, "Init_Artifacts: Could not load object.\n"); |
|
|
1389 | |
1380 | art->item->name = strchr (cp, ' ') + 1; |
1390 | art->item->name = strchr (cp, ' ') + 1; |
1381 | al = find_artifactlist (art->item->type); |
1391 | al = find_artifactlist (art->item->type); |
1382 | if (al == NULL) |
1392 | if (al == NULL) |
1383 | { |
1393 | { |
1384 | al = get_empty_artifactlist (); |
1394 | al = get_empty_artifactlist (); |
… | |
… | |
1468 | { |
1478 | { |
1469 | CLEAR_FLAG (op, FLAG_ANIMATE); |
1479 | CLEAR_FLAG (op, FLAG_ANIMATE); |
1470 | /* so artifacts will join */ |
1480 | /* so artifacts will join */ |
1471 | if (!QUERY_FLAG (op, FLAG_ALIVE)) |
1481 | if (!QUERY_FLAG (op, FLAG_ALIVE)) |
1472 | op->speed = 0.0; |
1482 | op->speed = 0.0; |
|
|
1483 | |
1473 | update_ob_speed (op); |
1484 | update_ob_speed (op); |
1474 | } |
1485 | } |
1475 | |
1486 | |
1476 | if (change->nrof) |
1487 | if (change->nrof) |
1477 | op->nrof = RANDOM () % ((int) change->nrof) + 1; |
1488 | op->nrof = RANDOM () % ((int) change->nrof) + 1; |
… | |
… | |
1646 | * Fixes the given object, giving it the abilities and titles |
1657 | * Fixes the given object, giving it the abilities and titles |
1647 | * it should have due to the second artifact-template. |
1658 | * it should have due to the second artifact-template. |
1648 | */ |
1659 | */ |
1649 | |
1660 | |
1650 | void |
1661 | void |
1651 | give_artifact_abilities (object * op, object * artifct) |
1662 | give_artifact_abilities (object *op, object *artifct) |
1652 | { |
1663 | { |
1653 | char new_name[MAX_BUF]; |
1664 | char new_name[MAX_BUF]; |
1654 | |
1665 | |
1655 | sprintf (new_name, "of %s", &artifct->name); |
1666 | sprintf (new_name, "of %s", &artifct->name); |
1656 | op->title = new_name; |
1667 | op->title = new_name; |
… | |
… | |
1808 | free_treasurestruct (t->next); |
1819 | free_treasurestruct (t->next); |
1809 | if (t->next_yes) |
1820 | if (t->next_yes) |
1810 | free_treasurestruct (t->next_yes); |
1821 | free_treasurestruct (t->next_yes); |
1811 | if (t->next_no) |
1822 | if (t->next_no) |
1812 | free_treasurestruct (t->next_no); |
1823 | free_treasurestruct (t->next_no); |
1813 | free (t); |
1824 | |
|
|
1825 | delete t; |
1814 | } |
1826 | } |
1815 | |
1827 | |
1816 | void |
1828 | void |
1817 | free_charlinks (linked_char * lc) |
1829 | free_charlinks (linked_char * lc) |
1818 | { |
1830 | { |