--- deliantra/server/common/treasure.C 2007/09/04 05:43:21 1.65 +++ deliantra/server/common/treasure.C 2008/09/29 10:32:50 1.82 @@ -1,11 +1,11 @@ /* - * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. + * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team + * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team * Copyright (©) 1992,2007 Frank Tore Johansen * - * Crossfire TRT is free software: you can redistribute it and/or modify + * Deliantra is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -18,7 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * The authors can be reached via e-mail to + * The authors can be reached via e-mail to */ /* TREASURE_DEBUG does some checking on the treasurelists after loading. @@ -34,7 +34,6 @@ #include #include -#include #include extern char *spell_mapping[]; @@ -48,8 +47,7 @@ treasurelist *, str_hash, str_equal, - slice_allocator< std::pair >, - true + slice_allocator< std::pair > > tl_map_t; static tl_map_t tl_map; @@ -141,12 +139,19 @@ for (;;) { - coroapi::cede_to_tick_every (10); + coroapi::cede_to_tick (); switch (f.kw) { case KW_arch: - t->item = archetype::get (f.get_str ()); + t->item = archetype::find (f.get_str ()); + + if (!t->item) + { + f.parse_warn ("treasure references unknown archetype"); + t->item = archetype::empty; + } + break; case KW_list: f.get (t->name); break; @@ -170,13 +175,19 @@ default: if (!f.parse_error ("treasurelist", t->name)) - return 0; + goto error; return t; } f.next (); } + + // not reached + +error: + delete t; + return 0; } /* @@ -245,7 +256,7 @@ op->expand_tail (); - if (ob_blocked (op, creator->map, creator->x, creator->y)) + if (!creator->is_on_map () || op->blocked (creator->map, creator->x, creator->y)) op->destroy (); else { @@ -259,10 +270,6 @@ if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) monster_check_apply (creator, op); - - if (flags & GT_UPDATE_INV) - if (object *tmp = creator->in_player ()) - esrv_send_item (tmp, op); } } @@ -436,6 +443,7 @@ LOG (llevError, "In generate treasure, created multiple objects.\n"); ob->destroy (); + return tmp; } @@ -491,23 +499,18 @@ int level_for_item (const object *op, int difficulty) { - int olevel = 0; - if (!op->inv) { LOG (llevError, "level_for_item: Object %s has no inventory!\n", &op->name); return 0; } - olevel = (int) (op->inv->level + (double) difficulty * (1 - drand48 () * drand48 () * 2)); + int olevel = op->inv->level + int (difficulty * (1. - rndm () * rndm () * 2.)); if (olevel <= 0) - olevel = rndm (1, MIN (op->inv->level, 1)); + olevel = rndm (1, op->inv->level); - if (olevel > MAXLEVEL) - olevel = MAXLEVEL; - - return olevel; + return min (olevel, MAXLEVEL); } /* @@ -577,14 +580,17 @@ if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */ magic = (-magic); + op->weight = (op->arch->weight * (100 - magic * 10)) / 100; } else { if (op->type == ARMOUR) ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100; + if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */ magic = (-magic); + op->weight = (op->weight * (100 - magic * 10)) / 100; } } @@ -823,7 +829,7 @@ if (!(flags & GT_MINIMAL)) { - if (op->arch == crown_arch) + if (IS_ARCH (op->arch, crown)) { set_magic (difficulty, op, max_magic, flags); num_enchantments = calc_item_power (op, 1); @@ -838,8 +844,7 @@ if ((!was_magic && !rndm (CHANCE_FOR_ARTIFACT)) || op->type == HORN - || difficulty >= settings.max_level) /* high difficulties always generate an artifact, - * used for shop_floors or treasures */ + || difficulty >= settings.max_level) /* high difficulties always generate an artifact, used for shop_floors or treasures */ generate_artifact (op, difficulty); } @@ -891,9 +896,7 @@ /* Handle healing and magic power potions */ if (op->stats.sp && !op->randomitems) { - object *tmp; - - tmp = get_archetype (spell_mapping[op->stats.sp]); + object *tmp = get_archetype (spell_mapping [op->stats.sp]); insert_ob_in_ob (tmp, op); op->stats.sp = 0; } @@ -961,18 +964,11 @@ } case AMULET: - if (op->arch == amulet_arch) + if (IS_ARCH (op->arch, amulet)) op->value *= 5; /* Since it's not just decoration */ case RING: - if (op->arch == NULL) - { - op->destroy (); - op = 0; - break; - } - - if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */ + if (!IS_ARCH (op->arch, ring) && !IS_ARCH (op->arch, amulet)) /* It's a special artifact! */ break; if (!(flags & GT_ONLY_GOOD) && !(rndm (3))) @@ -1135,7 +1131,7 @@ static artifactlist * get_empty_artifactlist (void) { - return salloc0 (); + return salloc0 (); } /* @@ -1144,7 +1140,7 @@ static artifact * get_empty_artifact (void) { - return salloc0 (); + return salloc0 (); } /* @@ -1162,128 +1158,6 @@ } /* - * For debugging purposes. Dumps all tables. - */ -void -dump_artifacts (void) -{ - artifactlist *al; - artifact *art; - linked_char *next; - - fprintf (logfile, "\n"); - for (al = first_artifactlist; al != NULL; al = al->next) - { - fprintf (logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance); - for (art = al->items; art != NULL; art = art->next) - { - fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance); - if (art->allowed != NULL) - { - fprintf (logfile, "\tallowed combinations:"); - for (next = art->allowed; next != NULL; next = next->next) - fprintf (logfile, "%s,", &next->name); - fprintf (logfile, "\n"); - } - } - } - fprintf (logfile, "\n"); -} - -/* - * For debugging purposes. Dumps all treasures recursively (see below). - */ -void -dump_monster_treasure_rec (const char *name, treasure *t, int depth) -{ - treasurelist *tl; - int i; - - if (depth > 100) - return; - - while (t) - { - if (t->name) - { - for (i = 0; i < depth; i++) - fprintf (logfile, " "); - - fprintf (logfile, "{ (list: %s)\n", &t->name); - - tl = treasurelist::find (t->name); - if (tl) - dump_monster_treasure_rec (name, tl->items, depth + 2); - - for (i = 0; i < depth; i++) - fprintf (logfile, " "); - - fprintf (logfile, "} (end of list: %s)\n", &t->name); - } - else - { - for (i = 0; i < depth; i++) - fprintf (logfile, " "); - - if (t->item && t->item->type == FLESH) - fprintf (logfile, "%s's %s\n", name, &t->item->object::name); - else - fprintf (logfile, "%s\n", &t->item->object::name); - } - - if (t->next_yes) - { - for (i = 0; i < depth; i++) - fprintf (logfile, " "); - - fprintf (logfile, " (if yes)\n"); - dump_monster_treasure_rec (name, t->next_yes, depth + 1); - } - - if (t->next_no) - { - for (i = 0; i < depth; i++) - fprintf (logfile, " "); - - fprintf (logfile, " (if no)\n"); - dump_monster_treasure_rec (name, t->next_no, depth + 1); - } - - t = t->next; - } -} - -/* - * For debugging purposes. Dumps all treasures for a given monster. - * Created originally by Raphael Quinet for debugging the alchemy code. - */ -void -dump_monster_treasure (const char *name) -{ - archetype *at; - int found; - - found = 0; - fprintf (logfile, "\n"); - - for_all_archetypes (at) - if (!strcasecmp (at->object::name, name) && at->title == NULL) - { - fprintf (logfile, "treasures for %s (arch: %s)\n", &at->object::name, &at->archname); - if (at->randomitems != NULL) - dump_monster_treasure_rec (at->object::name, at->randomitems->items, 1); - else - fprintf (logfile, "(nothing)\n"); - - fprintf (logfile, "\n"); - found++; - } - - if (found == 0) - fprintf (logfile, "No objects have the name %s!\n\n", name); -} - -/* * Builds up the lists of artifacts from the file in the libdir. */ void @@ -1475,14 +1349,11 @@ */ if (op->type == HORN || op->type == POTION) { - object *tmp_obj; - /* Remove any spells this object currently has in it */ - while (op->inv) - op->inv->destroy (); + op->destroy_inv (false); - tmp_obj = arch_to_object (change->other_arch); - insert_ob_in_ob (tmp_obj, op); + object *tmp = arch_to_object (change->other_arch); + insert_ob_in_ob (tmp, op); } /* No harm setting this for potions/horns */ op->other_arch = change->other_arch; @@ -1808,7 +1679,7 @@ if (at->next) free_artifact (at->next); if (at->allowed) free_charlinks (at->allowed); - at->item->destroy (1); + at->item->destroy (); sfree (at); }