--- deliantra/server/common/treasure.C 2007/04/17 18:40:31 1.48 +++ deliantra/server/common/treasure.C 2007/05/12 18:14:47 1.60 @@ -1,5 +1,5 @@ /* - * CrossFire, A Multiplayer game for X-windows + * CrossFire, A Multiplayer game * * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team * Copyright (C) 2002 Mark Wedel & Crossfire Development Team @@ -147,8 +147,7 @@ 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; @@ -200,8 +199,6 @@ * 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; - if (one) { for (treasure *t = tl->items; t; t = t->next) @@ -233,17 +230,29 @@ 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 - * by another object. - */ - if (flags & GT_ENVIRONMENT && op->type != SPELL) + if (flags & GT_ENVIRONMENT) { - SET_FLAG (op, FLAG_OBJ_ORIGINAL); - op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON); + /* 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 + * by another object. + */ + //TODO: flag such as objects... as such (no drop, anybody?) + if (op->type == SPELL) + { + op->destroy (); + return; + } + + op->expand_tail (); + + 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 { @@ -252,8 +261,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); } } @@ -363,6 +373,12 @@ } } +void +object::create_treasure (treasurelist *tl, int flags) +{ + ::create_treasure (tl, this, flags, map ? map->difficulty : 0); +} + /* This calls the appropriate treasure creation function. tries is passed * to determine how many list transitions or attempts to create treasure * have been made. It is really in place to prevent infinite loops with @@ -383,6 +399,15 @@ return; } + if (op->flag [FLAG_TREASURE_ENV]) + { + // do not generate items when there already is something above the object + if (op->flag [FLAG_IS_FLOOR] && op->above) + return; + + flag |= GT_ENVIRONMENT; + } + if (tl->total_chance) create_one_treasure (tl, op, flag, difficulty, tries); else @@ -399,13 +424,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) @@ -423,7 +448,6 @@ */ static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = { - // chance of magic difficulty // +0 +1 +2 +3 +4 {95, 2, 2, 1, 0}, // 1 @@ -459,14 +483,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) { @@ -628,7 +650,7 @@ case 4: case 5: case 6: - set_attr_value (&op->stats, r, (signed char) (bonus + get_attr_value (&op->stats, r))); + op->stats.stat (r) += bonus; break; case 7: @@ -786,10 +808,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; } @@ -1329,6 +1348,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"); @@ -1399,7 +1420,7 @@ } for (i = 0; i < NUM_STATS; i++) - change_attr_value (&(op->stats), i, get_attr_value (&(change->stats), i)); + change_attr_value (&(op->stats), i, change->stats.stat (i)); op->attacktype |= change->attacktype; op->path_attuned |= change->path_attuned; @@ -1573,14 +1594,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 @@ -1601,6 +1623,7 @@ else if (neg) success = 1; } + return success; }