#define ZONES_C #include "kernel.h" #include <unistd.h> #include <string.h> #include <strings.h> #include "config.h" #include "zones.h" #include "mobile.h" #include "colors.h" #include "uaf.h" #include "objsys.h" #include "bootstrap.h" #include "rooms.h" #include "mud.h" #include "log.h" #include "clone.h" #include "parse.h" #include "bprintf.h" #include "quest.h" /* * Return the zone index for a given zone name (abbreviation). * -1 if no such zone is found. */ int get_zone_by_name (char *name) { int x; int w = strlen (name); for (x = 0; x < numzon; x++) { if (strncasecmp (name, zname (x), w) == 0) return x; } return -1; } /* Return the zone index among the non-permanent zones which matches * the given name _exacely_. If none exists, create one and return that index. */ int get_wizzone_by_name (char *name) { int i; for (i = num_const_zon; i < numzon; i++) { if (strcasecmp (name, zname (i)) == 0) return i; } if (numzon == zon_array_len) { zon_array_len += 20; zoname = resize_array (zoname, sizeof (ZONE), numzon, zon_array_len); } zname (numzon) = COPY (name); ztemporary (numzon) = True; init_intset (zlocs (numzon), 5); init_intset (zmobs (numzon), 3); init_intset (zobjs (numzon), 3); return numzon++; } /* * Return the ZONE entry index for the zone that 'loc' is member of. * Return -1 if invalid loc number. */ int loc2zone (int loc) { return exists (loc) ? lzone (loc) : -1; } /* * Take a 'loc' as argument and return the zone name and the offset within * the zone for this loc. * If buff = NULL, return the name in a static buffer. */ int findzone (int loc, char *buff) { int z, x; if ((z = loc2zone (loc)) == -1) { strcpy (buff, "TCHAN"); return 0; } strcpy (buff, zname (z)); /* Remove mudlog later if everything seems ok: */ if (!(x = find_int (loc, zlocs (z)))) { mudlog ("Internal error: location %d was not in its zone %d.", loc, z); } return x; } /* * This function is inverse of findzone in that it * from a zone index and offset number finds the loc that it makes up. * 0 is returned on error. */ int getlocid (int z, int off) { int a; if (z == -1 || z >= numzon) return 0; if (off == 0) off = 1; else if (off < 0) return 0; return (a = find_int_number (off - 1, zlocs (z))) == SET_END ? 0 : a; } /* * This function is inverse of findzone in that it * from a zone name and number finds the loc that it makes up. * 0 is returned on error. */ int getlocnum (char *zname, int off) { return getlocid (get_zone_by_name (zname), off); } /* Reset a zone. If r_* != NULL, return the number of locs/objs/mobs that * were successfully reset. d_* = number of items destructed. * * If the zone is a wiz-made zone and the owner hasn't been on for a * certain time since 'now', his zone has 'expired' and will be destructed, * but if 'now' == NULL, proceed as if it had not expired, (ie reset it), * but don't kill any of the temporary (=not stored with STORE) items. */ void reset_zone (int z, time_t * now, int *d_locs, int *d_mobs, int *d_objs, int *r_locs, int *r_mobs, int *r_objs) { PERSONA p; Boolean reused; int i; int xd_locs = 0, xd_mobs = 0, xd_objs = 0, xr_locs = 0, xr_mobs = 0, xr_objs = 0; if (zpermanent (z) || (!ztemporary (z) && (fpbns (zname (z)) > -1 || (getuaf (zname (z), &p) && (now == NULL || *now - p.p_last_on < WIZZONE_EXIST_H * 3600L))) ) ) { for (i = zfirst_mob (z); i != SET_END; i = znext_mob (z)) do { if (!ptemporary (i)) { if (reset_mobile (i)) xr_mobs++; break; } else { if (now == NULL) break; } } while (destruct_mobile (i, &reused) && (xd_mobs++, reused)); for (i = zfirst_obj (z); i != SET_END; i = znext_obj (z)) do { if (!otemporary (i)) { if (reset_object (i)) xr_objs++; break; } else { if (now == NULL) break; } } while (destruct_object (i, &reused) && (xd_objs++, reused)); for (i = zfirst_loc (z); i != SET_END; i = znext_loc (z)) do { if (!ltemporary (i)) { if (reset_location (i)) xr_locs++; break; } else { if (now == NULL) break; } } while (destruct_location (i, &reused) && (xd_locs++, reused)); } else { for (i = zfirst_obj (z); i != SET_END; i = znext_obj (z)) while (destruct_object (i, &reused) && reused); for (i = zfirst_mob (z); i != SET_END; i = znext_mob (z)) while (destruct_mobile (i, &reused) && reused); for (i = zfirst_loc (z); i != SET_END; i = znext_loc (z)) while (destruct_location (i, &reused) && reused); ztemporary (z) = True; } if (d_locs != NULL) *d_locs = xd_locs; /* locs destroyed */ if (d_mobs != NULL) *d_mobs = xd_mobs; /* mobs destroyed */ if (d_objs != NULL) *d_objs = xd_objs; /* objs destroyed */ if (r_locs != NULL) *r_locs = xr_locs; /* locs reset */ if (r_mobs != NULL) *r_mobs = xr_mobs; /* mobs reset */ if (r_objs != NULL) *r_objs = xr_objs; /* objs reset */ } /* Load a zone from disk into the game. * Name, is its owner, which also identifies the files it's stored on. * Place the number of items found and the number actually loaded in the * positions pointed to by the arguments. * Return memory allocated as our function value, -1 on error. */ int load_zone (char *name, int *nlocs, int *nlocs_f, int *nmobs, int *nmobs_f, int *nobjs, int *nobjs_f) { Boolean locs_exist, mobs_exist, objs_exist; char filename[128]; FILE *locfile, *mobfile, *objfile; int loc_mem = 0, mob_mem = 0, obj_mem = 0; int z; if (nlocs != NULL) *nlocs = 0; if (nlocs_f != NULL) *nlocs_f = 0; if (nmobs != NULL) *nmobs = 0; if (nmobs_f != NULL) *nmobs_f = 0; if (nobjs != NULL) *nobjs = 0; if (nobjs_f != NULL) *nobjs_f = 0; wiz_loc_filename (filename, name); locs_exist = (locfile = fopen (filename, "r")) != NULL; wiz_mob_filename (filename, name); mobs_exist = (mobfile = fopen (filename, "r")) != NULL; wiz_obj_filename (filename, name); objs_exist = (objfile = fopen (filename, "r")) != NULL; if (!(locs_exist || mobs_exist || objs_exist)) { return 0; } z = get_wizzone_by_name (name); ztemporary (z) = False; if (locs_exist) { loc_mem = load_locations (z, locfile, nlocs, nlocs_f); fclose (locfile); } if (mobs_exist) { mob_mem = load_mobiles (z, mobfile, nmobs, nmobs_f); fclose (mobfile); } if (objs_exist) { obj_mem = load_objects (z, objfile, nobjs, nobjs_f); fclose (objfile); } reset_zone (z, NULL, NULL, NULL, NULL, NULL, NULL, NULL); return (loc_mem < 0 || mob_mem < 0 || obj_mem < 0) ? -1 : loc_mem + mob_mem + obj_mem; } /* From a character name, get the filenames that will contain his zone. */ static char *wiz_zone_filename (char *buff, char *name, char *contents) { sprintf (buff, "%s/%s.%s", WIZ_ZONES, name, contents); return buff; } char *wiz_mob_filename (char *buff, char *name) { return wiz_zone_filename (buff, name, "mobiles"); } char *wiz_loc_filename (char *buff, char *name) { return wiz_zone_filename (buff, name, "locations"); } char *wiz_obj_filename (char *buff, char *name) { return wiz_zone_filename (buff, name, "objects"); } A_COMMAND(zoneinfocom) { extern const char *authortab[]; extern char *Quests[]; int zonnum; if (brkword() == -1) { char fn[120]; FILE *fp; char *q; int i; sprintf(fn,"%s/TMP/zoneinfo.%s",DATA_DIR,pname(mynum)); fp = fopen(fn,"w"); if (fp == NULL) { bprintf("Unable to open temporary file.\n"); return; } fprintf(fp,"&+wZone Name &+wAuthor(s) &+wQuest\n" "&+w%s\n",DOUBLELINE); for (i = 0; i < num_const_zon; i++) { if (get_quest_of_zone(i) >= 0) q = Quests[get_quest_of_zone(i)]; else q = "-"; fprintf(fp,"&+w%-16.16s &+w%-25.25s &+w%s\n",zname(i),authortab[i],q); } fprintf(fp,"&+w%s\n",DOUBLELINE); fclose(fp); read_file(fn,NULL,True,NULL); unlink(fn); return; } zonnum = get_zone_by_name(wordbuf); if (zonnum < 0) { bprintf("That zone is not available here.\n"); return; } bprintf("&+wZone &+w: &+w%s\n",zname(zonnum)); bprintf("&+wAuthor&+w: &+w%s\n",(zonnum < num_const_zon) ? authortab[zonnum] : zname(zonnum)); if (get_quest_of_zone(zonnum) >= 0) bprintf("&+wQuest &+w: &+w%s\n",Quests[get_quest_of_zone(zonnum)]); if (plev(mynum) >= LVL_APPREN) { bprintf("\n&+wLocations&+w: &+w%d\n",znumloc(zonnum)); bprintf("&+wMobiles &+w: &+w%d\n",znumchars(zonnum)); bprintf("&+wObjects &+w: &+w%d\n",znumobs(zonnum)); } } /* The ZONES command. */ A_COMMAND(zonescom) { FILE *fp; char fn[512]; int a; sprintf(fn,"%szones.%s",TEMP_DIR,pname(mynum)); if ((fp = fopen(fn,"w"))==NULL) { fwerror(fn); return; } fprintf (fp,"&+w Zone-Name Rooms Mobiles Objects " "Zone-Name Rooms Mobiles Objects\n"); fprintf(fp,"&+w%s&*\n",DOUBLELINE); for (a = 0; a < num_const_zon; a++) { fprintf (fp,"&+w%14s&+w%5d %7d %7d", zname (a), znumloc (a), znumchars (a), znumobs (a)); if (a % 2 == 1 || a == num_const_zon - 1) fprintf (fp,"\n"); } fprintf (fp,"\n&+wA total of &+w%d &+wpermanent zones containing " "&+w%d &+wrooms, &+w%d &+wmobiles, &+w%d &+wobjects.\n\n", num_const_zon, num_const_locs, num_const_chars - max_players, num_const_obs); if (numzon != num_const_zon) { int i = 0; fprintf (fp," Zone-Name Rooms Mobiles Objects " "Zone-Name Rooms Mobiles Objects\n\n"); for (a = num_const_zon; a < numzon; a++) { int locs = znumloc (a); int mobs = znumchars (a); int objs = znumobs (a); if (!ztemporary (a) || locs > 0 || mobs > 0 || objs > 0) { fprintf (fp,"%14s%5d %7d %7d", zname (a), locs, mobs, objs); if (i++ % 2 == 1) fprintf (fp,"\n"); } } fprintf (fp,"\n&+w%s&*\nA total of %d Wizard's zones containing " "%d rooms, %d mobiles, %d objects.\n", DOUBLELINE,i, numloc - num_const_locs, numchars - num_const_chars, numobs - num_const_obs); } fclose(fp); read_file(fn,NULL,True,NULL); unlink(fn); } Boolean can_manipulate(int player, int mob) { int z = pzone(mob),q; if (player >= max_players || plev(player) < LVL_APPREN || plev(player) >= LVL_ARCHWIZARD) return True; q = get_quest_of_zone(z); if (q == -1) return True; if (qtstflg(player,q)) return True; return False; } Boolean has_access_to(int player,int loc, int obj) { int owner = -1,q; if (player >= max_players || plev(player) < LVL_APPREN || plev(player) >= LVL_ARCHWIZARD) return True; if (loc >= 0) { if (obj == -1) return True; owner = ozone(obj); } else owner = loc2zone(loc); q = get_quest_of_zone(owner); if (q == -1) return True; if (qtstflg(player,q)) return True; return False; } int get_zone_locs(int zone,int *start, int *end) { if (zone > num_const_zon) return -1; *start = zstartloc(zone); if (zone+1 < num_const_zon) *end = zstartloc(zone+1)+1; else *end = convroom(numloc); return -(*end-*start); }