--- deliantra/server/common/treasure.C 2006/09/12 18:15:34 1.17 +++ deliantra/server/common/treasure.C 2007/03/01 12:28:16 1.39 @@ -1,32 +1,27 @@ - /* - * static char *rcs_treasure_c = - * "$Id: treasure.C,v 1.17 2006/09/12 18:15:34 root Exp $"; + * CrossFire, A Multiplayer game for X-windows + * + * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team + * Copyright (C) 2002 Mark Wedel & Crossfire Development Team + * Copyright (C) 1992 Frank Tore Johansen + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * The authors can be reached via e-mail at */ -/* - CrossFire, A Multiplayer game for X-windows - - Copyright (C) 2002 Mark Wedel & Crossfire Development Team - Copyright (C) 1992 Frank Tore Johansen - - This program 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 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - The authors can be reached via e-mail at crossfire-devel@real-time.com -*/ - #define ALLOWED_COMBINATION /* TREASURE_DEBUG does some checking on the treasurelists after loading. @@ -60,13 +55,13 @@ warn_archetypes = 1; if (ring_arch == NULL) - ring_arch = find_archetype ("ring"); + ring_arch = archetype::find ("ring"); if (amulet_arch == NULL) - amulet_arch = find_archetype ("amulet"); + amulet_arch = archetype::find ("amulet"); if (staff_arch == NULL) - staff_arch = find_archetype ("staff"); + staff_arch = archetype::find ("staff"); if (crown_arch == NULL) - crown_arch = find_archetype ("crown"); + crown_arch = archetype::find ("crown"); warn_archetypes = prev_warn; } @@ -121,7 +116,7 @@ if (sscanf (cp, "arch %s", variable)) { - if ((t->item = find_archetype (variable)) == NULL) + if ((t->item = archetype::find (variable)) == NULL) LOG (llevError, "Treasure lacks archetype: %s\n", variable); } else if (sscanf (cp, "list %s", variable)) @@ -164,13 +159,11 @@ static void check_treasurelist (const treasure *t, const treasurelist * tl) { - if (t->item == NULL && t->name == NULL) - LOG (llevError, "Treasurelist %s has element with no name or archetype\n", &tl->name); 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); /* find_treasurelist will print out its own error message */ if (t->name && *t->name) - (void) find_treasurelist (t->name); + find_treasurelist (t->name); if (t->next) check_treasurelist (t->next, tl); if (t->next_yes) @@ -266,7 +259,7 @@ if (!name_) return 0; - for (treasurelist * tl = first_treasurelist; tl != 0; tl = tl->next) + for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next) if (name_ == tl->name) return tl; @@ -288,8 +281,6 @@ * abilities. This is used by summon spells, thus no summoned monsters * start with equipment, but only their abilities). */ - - static void put_treasure (object *op, object *creator, int flags) { @@ -302,17 +293,17 @@ */ if (flags & GT_ENVIRONMENT && op->type != SPELL) { - op->x = creator->x; - op->y = creator->y; SET_FLAG (op, FLAG_OBJ_ORIGINAL); - insert_ob_in_map (op, creator->map, op, INS_NO_MERGE | INS_NO_WALK_ON); + op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON); } else { - op = insert_ob_in_ob (op, creator); + op = creator->insert (op); + if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) monster_check_apply (creator, op); - if ((flags & GT_UPDATE_INV) && (tmp = is_player_inv (creator)) != NULL) + + if ((flags & GT_UPDATE_INV) && (tmp = creator->in_player ())) esrv_send_item (tmp, op); } } @@ -342,20 +333,25 @@ { object *tmp; - if ((int) t->chance >= 100 || (RANDOM () % 100 + 1) < (int) t->chance) + if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance) { if (t->name) { - if (strcmp (t->name, "NONE") && difficulty >= t->magic) - create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries); + if (difficulty >= t->magic) + { + treasurelist *tl = find_treasurelist (t->name); + if (tl) + create_treasure (tl, op, flag, difficulty, tries); + } } else { - if (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)) + if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE))) { tmp = arch_to_object (t->item); if (t->nrof && tmp->nrof <= 1) - tmp->nrof = RANDOM () % ((int) t->nrof) + 1; + tmp->nrof = rndm (t->nrof) + 1; + fix_generated_item (tmp, op, difficulty, t->magic, flag); change_treasure (t, tmp); put_treasure (tmp, op, flag); @@ -373,9 +369,9 @@ } void -create_one_treasure (treasurelist * tl, object *op, int flag, int difficulty, int tries) +create_one_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries) { - int value = RANDOM () % tl->total_chance; + int value = rndm (tl->total_chance); treasure *t; if (tries++ > 100) @@ -401,18 +397,19 @@ if (t->name) { - if (!strcmp (t->name, "NONE")) - return; - if (difficulty >= t->magic) - create_treasure (find_treasurelist (t->name), op, flag, difficulty, tries); + { + treasurelist *tl = find_treasurelist (t->name); + if (tl) + create_treasure (tl, op, flag, difficulty, tries); + } else if (t->nrof) create_one_treasure (tl, op, flag, difficulty, tries); return; } - if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) + if (t->item && (t->item->clone.invisible != 0 || flag != GT_INVISIBLE)) { object *tmp = arch_to_object (t->item); @@ -420,7 +417,7 @@ return; if (t->nrof && tmp->nrof <= 1) - tmp->nrof = RANDOM () % ((int) t->nrof) + 1; + tmp->nrof = rndm (t->nrof) + 1; fix_generated_item (tmp, op, difficulty, t->magic, flag); change_treasure (t, tmp); @@ -436,18 +433,18 @@ * to do that. */ void -create_treasure (treasurelist * t, object *op, int flag, int difficulty, int tries) +create_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries) { - if (tries++ > 100) { LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n"); return; } - if (t->total_chance) - create_one_treasure (t, op, flag, difficulty, tries); + + if (tl->total_chance) + create_one_treasure (tl, op, flag, difficulty, tries); else - create_all_treasures (t->items, op, flag, difficulty, tries); + create_all_treasures (tl->items, op, flag, difficulty, tries); } /* This is similar to the old generate treasure function. However, @@ -456,21 +453,23 @@ * inserted into, and then return that treausre */ object * -generate_treasure (treasurelist * t, int difficulty) +generate_treasure (treasurelist *tl, int difficulty) { - object *ob = get_object (), *tmp; + difficulty = clamp (difficulty, 1, settings.max_level); - create_treasure (t, ob, 0, difficulty, 0); + object *ob = object::create (), *tmp; + + 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) - remove_ob (tmp); + tmp->remove (); + if (ob->inv) - { - LOG (llevError, "In generate treasure, created multiple objects.\n"); - } - free_object (ob); + LOG (llevError, "In generate treasure, created multiple objects.\n"); + + ob->destroy (); return tmp; } @@ -574,7 +573,7 @@ if (scaled_diff >= DIFFLEVELS) scaled_diff = DIFFLEVELS - 1; - percent = RANDOM () % 100; + percent = rndm (100); for (magic = 0; magic < (MAXMAGIC + 1); magic++) { @@ -590,7 +589,7 @@ magic = 0; } - magic = (RANDOM () % 3) ? magic : -magic; + magic = (rndm (3)) ? magic : -magic; /* LOG(llevDebug, "Chose magic %d for difficulty (scaled %d) %d\n", magic, scaled_diff, difficulty); */ return magic; @@ -615,7 +614,7 @@ if (op->type == ARMOUR) ARMOUR_SPEED (op) = (ARMOUR_SPEED (&op->arch->clone) * (100 + magic * 10)) / 100; - if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */ + if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */ magic = (-magic); op->weight = (op->arch->clone.weight * (100 - magic * 10)) / 100; } @@ -623,7 +622,7 @@ { if (op->type == ARMOUR) ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100; - if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */ + if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */ magic = (-magic); op->weight = (op->weight * (100 - magic * 10)) / 100; } @@ -662,18 +661,18 @@ set_ring_bonus (object *op, int bonus) { - int r = RANDOM () % (bonus > 0 ? 25 : 11); + int r = rndm (bonus > 0 ? 25 : 11); if (op->type == AMULET) { - if (!(RANDOM () % 21)) - r = 20 + RANDOM () % 2; + if (!(rndm (21))) + r = 20 + rndm (2); else { - if (RANDOM () & 2) + if (rndm (2)) r = 10; else - r = 11 + RANDOM () % 9; + r = 11 + rndm (9); } } @@ -720,10 +719,10 @@ case 18: case 19: { - int b = 5 + FABS (bonus), val, resist = RANDOM () % num_resist_table; + int b = 5 + abs (bonus), val, resist = rndm (num_resist_table); /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */ - val = 10 + RANDOM () % b + RANDOM () % b + RANDOM () % b + RANDOM () % b; + val = 10 + rndm (b) + rndm (b) + rndm (b) + rndm (b); /* Cursed items need to have higher negative values to equal out with * positive values for how protections work out. Put another @@ -731,16 +730,17 @@ * even values. */ if (bonus < 0) - val = 2 * -val - RANDOM () % b; + val = 2 * -val - rndm (b); if (val > 35) val = 35; /* Upper limit */ b = 0; + while (op->resist[resist_table[resist]] != 0 && b < 4) - { - resist = RANDOM () % num_resist_table; - } + resist = rndm (num_resist_table); + if (b == 4) return; /* Not able to find a free resistance */ + op->resist[resist_table[resist]] = val; /* We should probably do something more clever here to adjust value * based on how good a resistance we gave. @@ -778,6 +778,7 @@ op->value = (op->value * 2) / 3; break; } + if (bonus > 0) op->value *= 2 * bonus; else @@ -792,7 +793,6 @@ * rings and amulets. * Another scheme is used to calculate the magic of weapons and armours. */ - int get_magic (int diff) { @@ -800,14 +800,16 @@ if (diff < 3) diff = 3; + for (i = 0; i < 4; i++) - if (RANDOM () % diff) + if (rndm (diff)) return i; + return 4; } #define DICE2 (get_magic(2)==2?2:1) -#define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3) +#define DICESPELL (rndm (3) + rndm (3) + rndm (3) + rndm (3) + rndm (3)) /* * fix_generated_item(): This is called after an item is generated, in @@ -831,7 +833,6 @@ * a working object - don't change magic, value, etc, but set it material * type as appropriate, for objects that need spell objects, set those, etc */ - void fix_generated_item (object *op, object *creator, int difficulty, int max_magic, int flags) { @@ -857,6 +858,12 @@ if (difficulty < 1) difficulty = 1; + if (INVOKE_OBJECT (ADD_BONUS, op, + ARG_OBJECT (creator != op ? creator : 0), + ARG_INT (difficulty), ARG_INT (max_magic), + ARG_INT (flags))) + return; + if (!(flags & GT_MINIMAL)) { if (op->arch == crown_arch) @@ -872,7 +879,9 @@ num_enchantments = calc_item_power (op, 1); - if ((!was_magic && !(RANDOM () % CHANCE_FOR_ARTIFACT)) || op->type == HORN || difficulty >= settings.max_level) /* high difficulties always generate an artifact, + 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 */ generate_artifact (op, difficulty); } @@ -940,12 +949,12 @@ case SHIELD: case HELMET: case CLOAK: - if (QUERY_FLAG (op, FLAG_CURSED) && !(RANDOM () % 4)) + if (QUERY_FLAG (op, FLAG_CURSED) && !(rndm (4))) set_ring_bonus (op, -DICE2); break; case BRACERS: - if (!(RANDOM () % (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20))) + if (!rndm (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20)) { set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2); if (!QUERY_FLAG (op, FLAG_CURSED)) @@ -981,7 +990,7 @@ { /* value multiplier is same as for scrolls */ op->value = (op->value * op->inv->value); - op->level = op->inv->level / 2 + RANDOM () % difficulty + RANDOM () % difficulty; + op->level = op->inv->level / 2 + rndm (difficulty) + rndm (difficulty); } else { @@ -989,7 +998,7 @@ op->name_pl = "potions"; } - if (!(flags & GT_ONLY_GOOD) && RANDOM () % 2) + if (!(flags & GT_ONLY_GOOD) && rndm (2)) SET_FLAG (op, FLAG_CURSED); break; } @@ -1001,16 +1010,15 @@ case RING: if (op->arch == NULL) { - remove_ob (op); - free_object (op); - op = NULL; + op->destroy (); + op = 0; break; } if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */ break; - if (!(flags & GT_ONLY_GOOD) && !(RANDOM () % 3)) + if (!(flags & GT_ONLY_GOOD) && !(rndm (3))) SET_FLAG (op, FLAG_CURSED); set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2); @@ -1018,18 +1026,18 @@ if (op->type != RING) /* Amulets have only one ability */ break; - if (!(RANDOM () % 4)) + if (!(rndm (4))) { - int d = (RANDOM () % 2 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; + int d = (rndm (2) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; if (d > 0) op->value *= 3; set_ring_bonus (op, d); - if (!(RANDOM () % 4)) + if (!(rndm (4))) { - int d = (RANDOM () % 3 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; + int d = (rndm (3) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; if (d > 0) op->value *= 5; @@ -1038,7 +1046,7 @@ } if (GET_ANIM_ID (op)) - SET_ANIMATION (op, RANDOM () % ((int) NUM_ANIMATIONS (op))); + SET_ANIMATION (op, rndm (NUM_ANIMATIONS (op))); break; @@ -1047,18 +1055,18 @@ * msg for it, and tailor its properties based on theĀ· * creator and/or map level we found it on. */ - if (!op->msg && RANDOM () % 10) + if (!op->msg && rndm (10)) { /* set the book level properly */ if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE)) { if (op->map && op->map->difficulty) - op->level = RANDOM () % (op->map->difficulty) + RANDOM () % 10 + 1; + op->level = rndm (op->map->difficulty) + rndm (10) + 1; else - op->level = RANDOM () % 20 + 1; + op->level = rndm (20) + 1; } else - op->level = RANDOM () % creator->level; + op->level = rndm (creator->level); tailor_readable_ob (op, (creator && creator->stats.sp) ? creator->stats.sp : -1); /* books w/ info are worth more! */ @@ -1167,59 +1175,57 @@ /* * Allocate and return the pointer to an empty artifactlist structure. */ - static artifactlist * get_empty_artifactlist (void) { - artifactlist *tl = (artifactlist *) malloc (sizeof (artifactlist)); + artifactlist *al = (artifactlist *) malloc (sizeof (artifactlist)); - if (tl == NULL) + if (al == NULL) fatal (OUT_OF_MEMORY); - tl->next = NULL; - tl->items = NULL; - tl->total_chance = 0; - return tl; + al->next = NULL; + al->items = NULL; + al->total_chance = 0; + return al; } /* * Allocate and return the pointer to an empty artifact structure. */ - static artifact * get_empty_artifact (void) { - artifact *t = (artifact *) malloc (sizeof (artifact)); + artifact *a = (artifact *) malloc (sizeof (artifact)); - if (t == NULL) + if (a == NULL) fatal (OUT_OF_MEMORY); - t->item = NULL; - t->next = NULL; - t->chance = 0; - t->difficulty = 0; - t->allowed = NULL; - return t; + + a->item = NULL; + a->next = NULL; + a->chance = 0; + a->difficulty = 0; + a->allowed = NULL; + return a; } /* * Searches the artifact lists and returns one that has the same type * of objects on it. */ - artifactlist * find_artifactlist (int type) { artifactlist *al; - for (al = first_artifactlist; al != NULL; al = al->next) + for (al = first_artifactlist; al; al = al->next) if (al->type == type) return al; - return NULL; + + return 0; } /* * For debugging purposes. Dumps all tables. */ - void dump_artifacts (void) { @@ -1236,7 +1242,7 @@ fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance); if (art->allowed != NULL) { - fprintf (logfile, "\tAllowed combinations:"); + fprintf (logfile, "\tallowed combinations:"); for (next = art->allowed; next != NULL; next = next->next) fprintf (logfile, "%s,", &next->name); fprintf (logfile, "\n"); @@ -1257,15 +1263,16 @@ if (depth > 100) return; - while (t != NULL) + while (t) { - if (t->name != NULL) + if (t->name) { for (i = 0; i < depth; i++) fprintf (logfile, " "); fprintf (logfile, "{ (list: %s)\n", &t->name); tl = find_treasurelist (t->name); - dump_monster_treasure_rec (name, tl->items, depth + 2); + 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); @@ -1274,25 +1281,28 @@ { for (i = 0; i < depth; i++) fprintf (logfile, " "); - if (t->item->clone.type == FLESH) + if (t->item && t->item->clone.type == FLESH) fprintf (logfile, "%s's %s\n", name, &t->item->clone.name); else fprintf (logfile, "%s\n", &t->item->clone.name); } - if (t->next_yes != NULL) + + 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 != NULL) + + 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; } } @@ -1310,6 +1320,7 @@ found = 0; fprintf (logfile, "\n"); + for (at = first_archetype; at != NULL; at = at->next) if (!strcasecmp (at->clone.name, name) && at->clone.title == NULL) { @@ -1318,9 +1329,11 @@ dump_monster_treasure_rec (at->clone.name, at->clone.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); } @@ -1328,15 +1341,12 @@ /* * Builds up the lists of artifacts from the file in the libdir. */ - void init_artifacts (void) { static int has_been_inited = 0; - char filename[MAX_BUF], buf[HUGE_BUF], *cp, *next; + char filename[MAX_BUF]; artifact *art = NULL; - linked_char *tmp; - int value; artifactlist *al; if (has_been_inited) @@ -1345,78 +1355,94 @@ has_been_inited = 1; sprintf (filename, "%s/artifacts", settings.datadir); - object_thawer thawer (filename); + object_thawer f (filename); - if (!thawer) + if (!f) return; - while (fgets (buf, HUGE_BUF, thawer) != NULL) - { - if (*buf == '#') - continue; - if ((cp = strchr (buf, '\n')) != NULL) - *cp = '\0'; - cp = buf; - while (*cp == ' ') /* Skip blanks */ - cp++; - if (*cp == '\0') - continue; + f.next (); - if (!strncmp (cp, "Allowed", 7)) + for (;;) + { + switch (f.kw) { - if (art == NULL) - { - art = get_empty_artifact (); - nrofartifacts++; - } - cp = strchr (cp, ' ') + 1; - if (!strcmp (cp, "all")) - continue; + case KW_allowed: + if (!art) + { + art = get_empty_artifact (); + nrofartifacts++; + } - do { - nrofallowedstr++; - if ((next = strchr (cp, ',')) != NULL) - *(next++) = '\0'; - tmp = new linked_char; - - tmp->name = cp; - tmp->next = art->allowed; - art->allowed = tmp; + if (!strcmp (f.get_str (), "all")) + break; + + char *next, *cp = f.get_str (); + + do + { + nrofallowedstr++; + + if ((next = strchr (cp, ','))) + *next++ = '\0'; + + linked_char *tmp = new linked_char; + + tmp->name = cp; + tmp->next = art->allowed; + art->allowed = tmp; + } + while ((cp = next)); } - while ((cp = next) != NULL); - } - else if (sscanf (cp, "chance %d", &value)) - art->chance = (uint16) value; - else if (sscanf (cp, "difficulty %d", &value)) - art->difficulty = (uint8) value; - else if (!strncmp (cp, "Object", 6)) - { - art->item = get_object (); - - if (!load_object (thawer, art->item, 0)) - LOG (llevError, "Init_Artifacts: Could not load object.\n"); - - art->item->name = strchr (cp, ' ') + 1; - al = find_artifactlist (art->item->type); - if (al == NULL) + break; + + case KW_chance: + f.get (art->chance); + break; + + case KW_difficulty: + f.get (art->difficulty); + break; + + case KW_object: { - al = get_empty_artifactlist (); - al->type = art->item->type; - al->next = first_artifactlist; - first_artifactlist = al; + art->item = object::create (); + + if (!art->item->parse_kv (f)) + LOG (llevError, "Init_Artifacts: Could not load object.\n"); + + al = find_artifactlist (art->item->type); + + if (!al) + { + al = get_empty_artifactlist (); + al->type = art->item->type; + al->next = first_artifactlist; + first_artifactlist = al; + } + + art->next = al->items; + al->items = art; + art = 0; } - art->next = al->items; - al->items = art; - art = NULL; + continue; + + case KW_EOF: + goto done; + + default: + if (!f.parse_error ("artifacts file")) + cleanup ("artifacts file required"); + break; } - else - LOG (llevError, "Unknown input in artifact file: %s\n", buf); + + f.next (); } - for (al = first_artifactlist; al != NULL; al = al->next) +done: + for (al = first_artifactlist; al; al = al->next) { - for (art = al->items; art != NULL; art = art->next) + for (art = al->items; art; art = art->next) { if (!art->chance) LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name); @@ -1491,11 +1517,11 @@ if (!QUERY_FLAG (op, FLAG_ALIVE)) op->speed = 0.0; - update_ob_speed (op); + op->set_speed (op->speed); } if (change->nrof) - op->nrof = RANDOM () % ((int) change->nrof) + 1; + op->nrof = rndm (change->nrof) + 1; op->stats.exp += change->stats.exp; /* Speed modifier */ op->stats.wc += change->stats.wc; @@ -1513,11 +1539,7 @@ /* Remove any spells this object currently has in it */ while (op->inv) - { - tmp_obj = op->inv; - remove_ob (tmp_obj); - free_object (tmp_obj); - } + op->inv->destroy (); tmp_obj = arch_to_object (change->other_arch); insert_ob_in_ob (tmp_obj, op); @@ -1564,12 +1586,8 @@ op->item_power = change->item_power; for (i = 0; i < NROFATTACKS; i++) - { - if (change->resist[i]) - { - op->resist[i] += change->resist[i]; - } - } + if (change->resist[i]) + op->resist[i] += change->resist[i]; if (change->stats.dam) { @@ -1616,8 +1634,8 @@ op->value *= change->value; - if (change->material) - op->material = change->material; + if (change->materials) + op->materials = change->materials; if (change->materialname) op->materialname = change->materialname; @@ -1721,9 +1739,9 @@ for (i = 0; i < ARTIFACT_TRIES; i++) { - int roll = RANDOM () % al->total_chance; + int roll = rndm (al->total_chance); - for (art = al->items; art != NULL; art = art->next) + for (art = al->items; art; art = art->next) { roll -= art->chance; if (roll < 0) @@ -1810,16 +1828,13 @@ int special_potion (object *op) { - - int i; - if (op->attacktype) return 1; if (op->stats.Str || op->stats.Dex || op->stats.Con || op->stats.Pow || op->stats.Wis || op->stats.Int || op->stats.Cha) return 1; - for (i = 0; i < NROFATTACKS; i++) + for (int i = 0; i < NROFATTACKS; i++) if (op->resist[i]) return 1; @@ -1857,7 +1872,7 @@ if (at->allowed) free_charlinks (at->allowed); - at->item->free (1); + at->item->destroy (1); delete at; } @@ -1867,7 +1882,7 @@ { artifactlist *nextal; - for (al = first_artifactlist; al != NULL; al = nextal) + for (al = first_artifactlist; al; al = nextal) { nextal = al->next;