--- deliantra/server/common/treasure.C 2007/04/17 10:06:32 1.46 +++ deliantra/server/common/treasure.C 2007/04/19 19:24:25 1.52 @@ -56,28 +56,6 @@ static tl_map_t tl_map; /* - * Initialize global archtype pointers: - */ -void -init_archetype_pointers () -{ - int prev_warn = warn_archetypes; - - warn_archetypes = 1; - - if (ring_arch == NULL) - ring_arch = archetype::find ("ring"); - if (amulet_arch == NULL) - amulet_arch = archetype::find ("amulet"); - if (staff_arch == NULL) - staff_arch = archetype::find ("staff"); - if (crown_arch == NULL) - crown_arch = archetype::find ("crown"); - - warn_archetypes = prev_warn; -} - -/* * Searches for the given treasurelist */ treasurelist * @@ -130,29 +108,46 @@ tl->total_chance = 0; } +#ifdef TREASURE_DEBUG +/* recursived checks the linked list. Treasurelist is passed only + * so that the treasure name can be printed out + */ +static void +check_treasurelist (const treasure *t, const treasurelist * tl) +{ + if (t->chance >= 100 && t->next_yes && (t->next || t->next_no)) + LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name); + + if (t->next) + check_treasurelist (t->next, tl); + + if (t->next_yes) + check_treasurelist (t->next_yes, tl); + + if (t->next_no) + check_treasurelist (t->next_no, tl); +} +#endif + /* * Reads the lib/treasure file from disk, and parses the contents * into an internal treasure structure (very linked lists) */ static treasure * -load_treasure (object_thawer &f) +read_treasure (object_thawer &f) { treasure *t = new treasure; - int value; - nroftreasures++; + f.next (); for (;;) { coroapi::cede_to_tick_every (10); - f.next (); - switch (f.kw) { case KW_arch: - if (!(t->item = archetype::find (f.get_str ()))) - LOG (llevError, "%s:%d treasure references unknown archetype '%s', skipping.\n", f.name, f.linenum, f.get_str ()); + t->item = archetype::get (f.get_str ()); break; case KW_list: f.get (t->name); break; @@ -163,124 +158,64 @@ case KW_nrof: f.get (t->nrof); break; case KW_magic: f.get (t->magic); break; - case KW_yes: t->next_yes = load_treasure (f); break; - case KW_no: t->next_no = load_treasure (f); break; + case KW_yes: t->next_yes = read_treasure (f); continue; + case KW_no: t->next_no = read_treasure (f); continue; case KW_end: + f.next (); return t; case KW_more: - t->next = load_treasure (f); + t->next = read_treasure (f); return t; default: - if (!f.parse_error ("treasure list")) - return t; // error + if (!f.parse_error ("treasurelist", t->name)) + return 0; return t; } + + f.next (); } } -#ifdef TREASURE_DEBUG -/* recursived checks the linked list. Treasurelist is passed only - * so that the treasure name can be printed out - */ -static void -check_treasurelist (const treasure *t, const treasurelist * tl) -{ - if (t->chance >= 100 && t->next_yes && (t->next || t->next_no)) - LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name); - - if (t->next) - check_treasurelist (t->next, tl); - - if (t->next_yes) - check_treasurelist (t->next_yes, tl); - - if (t->next_no) - check_treasurelist (t->next_no, tl); -} -#endif - /* - * Opens LIBDIR/treasure and reads all treasure-declarations from it. * Each treasure is parsed with the help of load_treasure(). */ -bool -load_treasure_file (const char *filename) +treasurelist * +treasurelist::read (object_thawer &f) { - treasure *t; - int comp, line = 0; + assert (f.kw == KW_treasure || f.kw == KW_treasureone); - object_thawer f (filename); - - if (!f) - { - LOG (llevError, "Can't open treasure file.\n"); - return false; - } + bool one = f.kw == KW_treasureone; + treasurelist *tl = treasurelist::get (f.get_str ()); + clear (tl); + tl->items = read_treasure (f); + if (!tl->items) + return 0; - f.next (); + /* This is a one of the many items on the list should be generated. + * Add up the chance total, and check to make sure the yes & no + * fields of the treasures are not being used. + */ + tl->total_chance = 0; - for (;;) + if (one) { - switch (f.kw) + for (treasure *t = tl->items; t; t = t->next) { - case KW_treasure: - case KW_treasureone: + if (t->next_yes || t->next_no) { - bool one = f.kw == KW_treasureone; - treasurelist *tl = treasurelist::get (f.get_str ()); - - clear (tl); - tl->items = load_treasure (f); - - if (!tl->items) - return false; - - /* This is a one of the many items on the list should be generated. - * Add up the chance total, and check to make sure the yes & no - * fields of the treasures are not being used. - */ - if (one) - { - for (t = tl->items; t; t = t->next) - { -#ifdef TREASURE_DEBUG - if (t->next_yes || t->next_no) - { - LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); - LOG (llevError, " the next_yes or next_no field is set\n"); - } -#endif - tl->total_chance += t->chance; - } - } + LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); + LOG (llevError, " the next_yes or next_no field is set\n"); } - break; - - case KW_EOF: -#ifdef TREASURE_DEBUG - /* Perform some checks on how valid the treasure data actually is. - * verify that list transitions work (ie, the list that it is supposed - * to transition to exists). Also, verify that at least the name - * or archetype is set for each treasure element. - */ - for (treasurelist *tl = first_treasurelist; tl; tl = tl->next) - check_treasurelist (tl->items, tl); -#endif - return true; - - default: - if (!f.parse_error ("treasure lists")) - return false; - break; + tl->total_chance += t->chance; } - - f.next (); } + + return tl; } /* @@ -297,8 +232,6 @@ static void put_treasure (object *op, object *creator, int flags) { - object *tmp; - /* Bit of a hack - spells should never be put onto the map. The entire * treasure stuff is a problem - there is no clear idea of knowing * this is the original object, or if this is an object that should be created @@ -306,8 +239,13 @@ */ if (flags & GT_ENVIRONMENT && op->type != SPELL) { - SET_FLAG (op, FLAG_OBJ_ORIGINAL); - op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON); + if (ob_blocked (op, creator->map, creator->x, creator->y)) + op->destroy (); + else + { + SET_FLAG (op, FLAG_OBJ_ORIGINAL); + op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON); + } } else { @@ -316,8 +254,9 @@ if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) monster_check_apply (creator, op); - if ((flags & GT_UPDATE_INV) && (tmp = creator->in_player ())) - esrv_send_item (tmp, op); + if (flags & GT_UPDATE_INV) + if (object *tmp = creator->in_player ()) + esrv_send_item (tmp, op); } } @@ -349,7 +288,10 @@ if (t->name) { if (difficulty >= t->magic) - create_treasure (treasurelist::find (t->name), op, flag, difficulty, tries); + if (treasurelist *tl = treasurelist::find (t->name)) + create_treasure (tl, op, flag, difficulty, tries); + else + LOG (llevError, "create_all_treasures: undefined reference to treasurelist '%s'.\n", &t->name); } else { @@ -460,13 +402,13 @@ { difficulty = clamp (difficulty, 1, settings.max_level); - object *ob = object::create (), *tmp; + object *ob = object::create (); create_treasure (tl, ob, 0, difficulty, 0); /* Don't want to free the object we are about to return */ - tmp = ob->inv; - if (tmp != NULL) + object *tmp = ob->inv; + if (tmp) tmp->remove (); if (ob->inv) @@ -484,7 +426,6 @@ */ static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = { - // chance of magic difficulty // +0 +1 +2 +3 +4 {95, 2, 2, 1, 0}, // 1 @@ -520,14 +461,12 @@ { 0, 0, 0, 0, 100}, // 31 }; - /* calculate the appropriate level for wands staves and scrolls. * This code presumes that op has had its spell object created (in op->inv) * * elmex Wed Aug 9 17:44:59 CEST 2006: * Removed multiplicator, too many high-level items were generated on low-difficulty maps. */ - int level_for_item (const object *op, int difficulty) { @@ -847,10 +786,7 @@ if (op->randomitems && op->type != SPELL) { - create_treasure (op->randomitems, op, flags, difficulty, 0); - if (!op->inv) - LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->debug_desc ()); - + create_treasure (op->randomitems, op, flags & ~GT_ENVIRONMENT, difficulty, 0); /* So the treasure doesn't get created again */ op->randomitems = 0; } @@ -1356,10 +1292,7 @@ { case KW_allowed: if (!art) - { - art = get_empty_artifact (); - nrofartifacts++; - } + art = get_empty_artifact (); { if (!strcmp (f.get_str (), "all")) @@ -1369,8 +1302,6 @@ do { - nrofallowedstr++; - if ((next = strchr (cp, ','))) *next++ = '\0'; @@ -1395,6 +1326,8 @@ case KW_object: { art->item = object::create (); + f.get (art->item->name); + f.next (); if (!art->item->parse_kv (f)) LOG (llevError, "Init_Artifacts: Could not load object.\n"); @@ -1430,6 +1363,8 @@ done: for (al = first_artifactlist; al; al = al->next) { + al->total_chance = 0; + for (art = al->items; art; art = art->next) { if (!art->chance) @@ -1445,12 +1380,10 @@ LOG (llevDebug, "done.\n"); } - /* * Used in artifact generation. The bonuses of the first object * is modified by the bonuses of the second object. */ - void add_abilities (object *op, object *change) { @@ -1639,14 +1572,15 @@ } static int -legal_artifact_combination (object *op, artifact * art) +legal_artifact_combination (object *op, artifact *art) { int neg, success = 0; linked_char *tmp; const char *name; - if (art->allowed == (linked_char *) NULL) + if (!art->allowed) return 1; /* Ie, "all" */ + for (tmp = art->allowed; tmp; tmp = tmp->next) { #ifdef TREASURE_VERBOSE @@ -1667,6 +1601,7 @@ else if (neg) success = 1; } + return success; } @@ -1813,7 +1748,6 @@ } /* special_potion() - so that old potion code is still done right. */ - int special_potion (object *op) {