#include <unistd.h>
#include <stdlib.h>
#include "kernel.h"
#include "bootstrap.h"
#include "mobile.h"
#include "pflags.h"
#include "cflags.h"
#include "sendsys.h"
#include "objsys.h"
#include "oflags.h"
#include "zones.h"
#include "parse.h"
#include "fight.h"
#include "exits.h"
#include "clone.h"
#include "eflags.h"
#include "sflags.h"
#include "commands.h"
#include "rooms.h"
#include "bprintf.h"
#include "uaf.h"
#include "log.h"
/* copy existing object */
int clone_object (int obj, int new_zone, char *new_name, int loc, int carrf) {
int i, newobj;
if (numobs >= GLOBAL_MAX_OBJS)
return -1;
if (numobs == obj_array_len) {
obj_array_len = min (obj_array_len + 75, GLOBAL_MAX_OBJS);
objects = resize_array (objects, sizeof(Object), numobs, obj_array_len);
}
newobj = numobs++;
memcpy(&objects[newobj], &objects[obj], sizeof(Object));
if (new_name != NULL)
oname(newobj) = COPY(new_name);
else
oname(newobj) = COPY(oname(obj));
if (oaltname (obj) != NULL)
oaltname(newobj) = COPY(oaltname(obj));
for (i = 0; i < 4; i++)
if (olongt(obj, i) != NULL)
olongt(newobj, i) = COPY(olongt(obj, i));
if (oexam_text(obj) != NULL)
oexam_text(newobj) = COPY(oexam_text(obj));
otemporary(newobj) = True;
oclrbit (newobj, OFL_DESTROYED);
init_intset(oinv(newobj), otstbit(newobj, OFL_CONTAINER) ? 15 : 0);
oloc(newobj) = numobs + 1; /* set to illegal loc, so setoloc doesnt remove */
setoloc(newobj, loc, carrf);
insert_entry((obj_id(newobj) = id_counter++), newobj, &id_table);
if (new_zone > -1) {
ozone(newobj) = new_zone;
zadd_obj(newobj, new_zone);
}
else
zadd_obj(newobj, ozone (obj));
return(newobj);
}
/* Destruct an object created by clone_object().
*
* If destructed, and its index was assigned to another object from the
* same zone, place True in *index_reused.
*/
Boolean destruct_object (int obj, Boolean * index_reused)
{
int i, ct, plr;
Boolean reused = False;
if (opermanent (obj) || obj >= numobs)
return False;
if ((plr = oloc(obj)) < max_players && plr > -1) {
if (iswornby(obj, plr))
removeobj(False, obj, plr);
else if (iswieldby(obj, plr))
setpwpn(plr, -1);
}
/* If container, empty it's contents */
if (!is_empty (oinv (obj))) {
int new_loc = oloc (obj);
int new_carrf = ocarrf (obj);
switch (ocarrf (obj)) {
case IN_CONTAINER:
case IN_ROOM:
break;
case CARRIED_BY:
case WORN_BY:
case WIELDED_BY:
case BOTH_BY:
new_loc = ploc (oloc (obj));
new_carrf = IN_ROOM;
break;
}
for (i = ofirst_obj(obj), ct = 0; ct < onumobs(obj); i = oobj_nr(++ct,obj)){
if (new_loc != oloc(i))
ct--;
setoloc(i, new_loc, new_carrf);
}
}
/* Remove the object from the world by setting it to to an illegal loc. */
setoloc (obj, 0, IN_ROOM);
/* Remove its ID from the id-table. */
remove_entry (obj_id (obj), &id_table);
/* FREE the allocated memory. */
free_intset (oinv (obj));
if (oname (obj) != NULL)
FREE (oname (obj));
if (oaltname (obj) != NULL)
FREE (oaltname (obj));
if (oexam_text (obj) != NULL)
FREE (oexam_text (obj));
for (i = 0; i < 4; i++)
if (olongt (obj, i) != NULL)
FREE (olongt (obj, i));
/* If this was one side of a door, shut the other side */
if (olinked (obj) > -1) {
olinked (olinked (obj)) = -1;
state (olinked (obj)) = EX_CLOSED;
}
/* Move the last object in the objects array down to fill up the gap. */
zremove_obj (numobs - 1, ozone (numobs - 1));
if (obj != numobs - 1) {
if (!(reused = ozone (numobs - 1) == ozone (obj))) {
zremove_obj (obj, ozone (obj));
zadd_obj (obj, ozone (numobs - 1));
}
objects[obj] = objects[numobs - 1];
setoloc (numobs - 1, 0, IN_ROOM);
setoloc (obj, oloc (obj), ocarrf (obj));
if (olinked (obj) != -1)
olinked (olinked (obj)) = obj;
/* Change the value of the moved object's index in the id-table */
change_entry (obj_id (obj), obj, &id_table);
for (i = ofirst_obj (obj), ct = 0; ct < onumobs(obj); i = oobj_nr(++ct, obj)) {
if (obj != ploc(i))
ct--;
setoloc (i, obj, ocarrf (i));
}
}
if (--numobs < obj_array_len - 140) {
obj_array_len -= 75;
objects = resize_array (objects, sizeof (Object),
numobs, obj_array_len);
}
if (index_reused != NULL)
*index_reused = reused;
return True;
}
/* Create a new mobile by copying an existing one.
* Return the new mobile number, or -1 on error.
*/
int clone_mobile (int mob, int new_zone, char *new_name) {
if (numchars >= GLOBAL_MAX_MOBS + max_players)
return -1;
if (numchars == char_array_len) {
char_array_len =
min (char_array_len + 75, GLOBAL_MAX_MOBS + max_players);
ublock = resize_array (ublock, sizeof (Mobile),
numchars, char_array_len);
}
memcpy(&ublock[numchars], &ublock[mob], sizeof(UBLOCK_REC));
if (new_name != NULL) {
setpname (numchars, new_name);
pname_reset (numchars) = COPY (new_name);
}
else {
setpname (numchars, pname(mob));
pname_reset (numchars) = COPY (pname_reset (mob));
}
if (pexam (mob) != NULL)
pexam (numchars) = COPY (pexam (mob));
if (pftxt (mob) != NULL) {
char b[128];
pftxt (numchars) = COPY (new_name == NULL ? pftxt (mob)
: (sprintf (b, "%s is here.", new_name), b));
}
init_intset (pinv (numchars), 4);
setploc (numchars, ploc (numchars));
insert_entry ((mob_id (numchars) = id_counter++), numchars, &id_table);
if (new_zone > -1)
zadd_mob (numchars, pzone (numchars) = new_zone);
else
zadd_mob (numchars, pzone (mob));
return numchars++;
}
/* Destruct a mobile created with clone_mobile().
*
* If destructed, and its index was assigned to another mobile from the
* same zone, place True in index_reused.
*/
Boolean destruct_mobile (int mob, Boolean * index_reused)
{
int i, ct;
Boolean reused = False;
if (ppermanent (mob) || mob >= numchars)
return False;
setpfighting (mob, -1);
/* If someone is aliasing it, lose them.
*/
if (ststflg(mob, SFL_OCCUPIED))
unalias(mob);
/* If it carries something, drop it */
for (i = pfirst_obj(mob), ct = 0; ct < pnumobs(mob); i = pobj_nr(++ct, mob)) {
if (ploc(mob) != ploc(i))
ct--;
setoloc (i, ploc (mob), IN_ROOM);
}
/* Remove mobile from the world by setting it to to an illegal room.
*/
setploc (mob, 0);
/* Remove its ID from the id-table.
*/
remove_entry (mob_id (mob), &id_table);
/* FREE the allocated memory. */
free_intset (pinv (mob));
FREE (pname_reset (mob));
if (pexam (mob) != NULL)
FREE (pexam (mob));
if (pftxt (mob) != NULL)
FREE (pftxt (mob));
/* Move the last mobile in the mobile array down to fill up the gap. */
zremove_mob (numchars - 1, pzone (numchars - 1));
if (mob != numchars - 1) {
if (!(reused = pzone (mob) == pzone (numchars - 1))) {
zremove_mob (mob, pzone (mob));
zadd_mob (mob, pzone (numchars - 1));
}
ublock[mob] = ublock[numchars - 1];
setploc (numchars - 1, 0);
setploc (mob, ploc (mob));
/* Update the id-table with its new index. */
change_entry (mob_id (mob), mob, &id_table);
/* Change the references of its inventory to its new number */
for (i = pfirst_obj(mob), ct = 0; ct < pnumobs(mob); i = pobj_nr(++ct, mob))
{
if (ploc(i) != mob)
ct--;
setoloc(i, mob, ocarrf (i));
}
/* Change the references to it for its fight opponents &helpers */
for (i = 0; i < lnumchars (ploc (mob)); i++) {
if (phelping (lmob_nr (i, ploc (mob))) == numchars - 1)
setphelping (lmob_nr (i, ploc (mob)), mob);
if (pfighting (lmob_nr (i, ploc (mob))) == numchars - 1)
setpfighting (lmob_nr (i, ploc (mob)), mob);
}
}
if (--numchars < char_array_len - 140) {
char_array_len -= 75;
ublock = resize_array (ublock, sizeof (Mobile),
numchars, char_array_len);
}
if (index_reused != NULL)
*index_reused = reused;
return True;
}
/* Create a new location by copying an existing one.
* Return the new location number, or 0 on error.
*/
int
clone_location (int l, int new_zone, char *new_name)
{
int i;
int loc_array_index = convroom (l);
int c_numloc = convroom (numloc);
if (numloc >= GLOBAL_MAX_LOCS)
return 0;
if (numloc == loc_array_len) {
loc_array_len = min (loc_array_len + 100, GLOBAL_MAX_LOCS);
room_data = resize_array (room_data, sizeof (Location),
numloc, loc_array_len);
}
room_data[numloc] = room_data[loc_array_index];
for (i = 0; i < NEXITS; i++)
setexit (c_numloc, i, lexit (c_numloc, i));
lshort (c_numloc) = new_name != NULL ? COPY (new_name)
: lshort (l) != NULL ? COPY (lshort (l)) : NULL;
if (llong (l) != NULL)
llong (c_numloc) = COPY (llong (l));
init_intset (linv (c_numloc), 7);
init_intset (lmobs (c_numloc), 5);
init_intset (lexits_to_me (c_numloc), 4);
insert_entry (loc_id (c_numloc) = id_counter++, c_numloc, &id_table);
if (new_zone > -1) {
zadd_loc (c_numloc, lzone (c_numloc) = new_zone);
} else {
zadd_loc (c_numloc, lzone (l));
}
++numloc;
return c_numloc;
}
/* Destruct a location created by clone_location().
*
* If destructed, and its index was assigned to another location from the
* same zone, place True in index_reused.
*/
Boolean destruct_location (int l, Boolean * index_reused)
{
int i, j, ct;
Boolean reused = False;
int loc_array_index = convroom (l);
if (lpermanent (l) || loc_array_index >= numloc)
return False;
/* If it contains players, don't destruct.
*/
for (i = 0; i < lnumchars(l); i++)
if (lmob_nr(i, l) < max_players)
return False;
/* If it contains mobiles, move them away. */
while(lnumchars(l) > 0)
destroy_mobile(lfirst_mob(l));
/* If it contains objects, destroy them. */
while(lnumobs(l) > 0)
destroy(lfirst_obj(l));
/* Clear exits -- ??? CURI */
for (i = 0; i < NEXITS; i++)
setexit (l, i, 0);
for (i = first_int(lexits_to_me(l)), ct = 0 ; ct < set_size(lexits_to_me(l));
i = int_number(++ct, lexits_to_me(l))) {
for (j = 0; j < NEXITS; j++)
if (lexit (i, j) == l)
setexit (i, j, 0);
}
/* FREE the allocated memory. */
free_intset (linv (l));
free_intset (lmobs (l));
free_intset (lexits_to_me (l));
if (lshort (l) != NULL)
FREE (lshort (l));
if (llong (l) != NULL)
FREE (llong (l));
/* Remove its ID entry in the ID table.
*/
remove_entry (loc_id (l), &id_table);
/* Move the last room in the locations array down to fill up the gap.
*/
zremove_loc (convroom (numloc - 1), lzone (convroom (numloc - 1)));
if (loc_array_index != numloc - 1) {
if (!(reused = lzone (l) == lzone (convroom (numloc - 1)))) {
zremove_loc (l, lzone (l));
zadd_loc (l, lzone (convroom (numloc - 1)));
}
room_data[loc_array_index] = room_data[numloc - 1];
change_entry (loc_id (l), l, &id_table);
/* Change the references of its inventory to its new number */
for (ct = 0, i = lfirst_obj(l); ct < lnumobs(l); i = lobj_nr(++ct, l)) {
if (l != ploc(i))
ct--;
setoloc (i, l, ocarrf(i));
}
for (ct = 0, i = lfirst_mob (l); ct < lnumchars(l); i = lmob_nr(++ct, l)) {
if (l != ploc(i))
ct--;
setploc (i, l);
}
}
if (--numloc < loc_array_len - 140) {
loc_array_len -= 75;
room_data = resize_array (room_data, sizeof (Location),
numloc, loc_array_len);
}
if (index_reused != NULL)
*index_reused = reused;
return True;
}
/* Illegal characters in all names, descs etc.
*/
static int
illegal_char (int c)
{
return c == '^';
}
void clonecom (Boolean do_brkword)
{
int id, a;
int zone;
char name[MAX_COM_LEN], new_name[MAX_COM_LEN];
char *p, *q;
int blanks = 0, digits = 0, graphic = 0, others = 0, illegal = 0;
PERSONA P, P2;
if (!ptstflg (mynum, PFL_CLONE)) {
erreval ();
return;
}
if (do_brkword && brkword () == -1) {
bprintf ("Clone what ?\n");
return;
}
strcpy (name, wordbuf);
if (EMPTY (p = getreinput (new_name)))
p = NULL;
else {
for (q = p; *q != '\0'; q++) {
if (isdigit (*q))
digits++;
else if (illegal_char (*q))
illegal++;
else if (*q == ' ')
blanks++;
else if (!isalpha (*q) && isgraph (*q))
graphic++;
else if (!isalpha (*q))
others++;
}
/* Remove trailing spaces: */
while (--q > p && *q == ' ') ;
*++q = '\0';
}
if (illegal || others) {
bprintf ("Illegal character(s) in name.\n");
return;
}
zone = get_wizzone_by_name (pname (mynum));
if ((a = find_loc_by_name (name)) < 0) {
if ((id = clone_location (a, zone, p)) == 0) {
bprintf ("The max # of rooms (%d) has been reached.\n",
GLOBAL_MAX_LOCS);
return;
}
bprintf ("[%s]\n", showname (id));
#ifdef LOG_CLONE_ROOM
mudlog ("CLONE: Location: %s cloned %s to %s", pname (mynum), p, sdesc (id));
#endif
}
else if ((a = fmbn (name)) != -1) {
if (digits || graphic) {
bprintf ("New mobile name: blanks and letters only.\n");
return;
}
if (p != NULL && strlen (p) > MNAME_LEN) {
bprintf ("Mobile name %s too long (max = %d chars.)\n",
p, MNAME_LEN);
return;
}
if ((p == NULL && getuaf(pname(a), &P)) || (p != NULL && getuaf(p, &P2))) {
bprintf ("There is a player with that name!\n");
return;
}
if (strstr (pname (a), "Puff") != NULL) {
bprintf ("Sorry, we don't need any more fractal dragons running around!\n");
return;
}
if ((id = clone_mobile (a, zone, p)) < 0) {
bprintf ("The max # of mobs (%d) has been reached.\n",
GLOBAL_MAX_MOBS);
return;
}
reset_mobile (id);
setploc (id, ploc (mynum));
bprintf ("%s (%d) appears before you!\n", pname (id), GLOBAL_MAX_OBJS + id);
send_msg (ploc (mynum), 0, LVL_MIN, LVL_MAX, mynum, NOBODY,
"%s appears before you!\n", pname (id));
#ifdef LOG_CLONE_MOBILE
mudlog ("CLONE: Mobile: %s has cloned %s to %s", pname (mynum), pname (a), pname (id));
#endif
}
else if ((a = fobn(name)) != -1) {
if (digits || graphic || blanks) {
bprintf ("New object name: letters only.\n");
return;
}
if (p != NULL && strlen (p) > ONAME_LEN) {
bprintf ("Object name %s too long (max = %d chars.)\n", p, ONAME_LEN);
return;
}
if (olinked (a) > -1) {
bprintf ("That's a door-type object and can't be cloned (yet)\n");
return;
}
if ((id = clone_object (a, zone, p, ploc(mynum), IN_ROOM)) < 0) {
bprintf ("The max # of objs (%d) has been reached.\n", GLOBAL_MAX_OBJS);
return;
}
setoloc (id, ploc (mynum), IN_ROOM);
bprintf ("The %s (%d) is created before you!\n", oname (id), id);
send_msg (ploc (mynum), 0, LVL_MIN, LVL_MAX, mynum, NOBODY,
"The %s is created before you!\n", oname (id));
#ifdef LOG_CLONE_OBJECT
mudlog ("CLONE: Object: %s cloned %s to %s", pname (mynum), oname (a), oname (id));
#endif
}
else if (a == 1) {
strcat (wordbuf, "1");
clonecom (False);
}
else {
bprintf ("I don't know any %s\n", name);
}
}
void destructcom (char *args) {
int a;
if (!ptstflg (mynum, PFL_CLONE)) {
erreval ();
return;
}
if (args == NULL && (args = wordbuf, brkword () == -1)) {
bprintf ("Destruct what ?\n");
return;
}
if ((a = find_loc_by_name (args)) < 0) {
if (-a < num_const_locs)
bprintf ("That's a permanent location.\n");
else if (!destruct_location (a, NULL))
bprintf ("There are players in that location.\n");
else {
bprintf ("Ok.\n");
#ifdef LOG_DEST_ROOM
mudlog ("DESTRUCT: Location: %s destructed %s", pname (mynum), showname (a));
#endif
}
}
else if ((a = fmbn (args)) != -1 && a >= max_players) {
if (a < num_const_chars) {
bprintf ("That's a permanent mobile.\n");
return;
}
send_msg (ploc (a), 0, pvis (a), LVL_MAX, NOBODY, NOBODY,
"%s crumbles to dust.\n", pname (a));
if (!is_empty (pinv (a)))
send_msg (ploc (a), 0, pvis (a), LVL_MAX, NOBODY, NOBODY,
"Its belongings drop to the ground.\n");
#ifdef LOG_DEST_MOBILE
mudlog ("DESTRUCT: Mobile: %s destructed %s", pname (mynum), pname (a));
#endif
destruct_mobile (a, NULL);
}
else if ((a = fobn (args)) != -1) {
if (a < num_const_obs) {
bprintf ("That's a permanent object.\n");
return;
}
send_msg (obj_loc (a), 0, ovis (a), LVL_MAX, NOBODY, NOBODY,
"The %s crumbles to dust.\n", oname (a));
if (!is_empty (oinv (a)) && ocarrf (a) >= CARRIED_BY)
send_msg (obj_loc (a), 0, ovis (a), LVL_MAX, NOBODY, NOBODY,
"Its contents drops to the ground.\n");
#ifdef LOG_DEST_OBJECT
mudlog ("DESTRUCT: Object: %s destructed %s", pname (mynum), oname (a));
#endif
destruct_object (a, NULL);
}
else if (a == 1)
destructcom (strcat (args, "1"));
else
bprintf ("I don't know any %s\n", args);
}
/* storecom: if the store is silent, don't save temp items */
void storecom (char *player, Boolean silent)
{
char filename[128];
char *p;
int z, x, i, j, zlev, ct;
PERSONA P;
FILE *f;
int n_locs = 0, n_mobs = 0, n_objs = 0;
char *err_unsucc = "Store was unsuccessful.\n";
if (!ptstflg (mynum, PFL_LD_STORE)) {
erreval ();
return;
}
if (player == NULL)
p = (brkword () == -1) ? pname (mynum) : wordbuf;
else
p = player;
if ((z = get_zone_by_name (p)) < num_const_zon) {
if (!silent) bprintf ("%s: Nothing to store.\n", p);
return;
}
if (!EQ (pname(mynum), zname(z))) {
if ((x = fpbn(p)) != -1)
zlev = plev(x);
else if (getuaf(p, &P))
zlev = P.ublock.plev;
else
zlev = LVL_MIN;
if (!do_okay_l(plev(mynum), zlev, False)) {
bprintf("You're not powerful enough.\n");
return;
}
}
if (!save_id_counter ()) {
if (!silent) bprintf ("%s", err_unsucc);
return;
}
wiz_mob_filename (filename, zname (z));
if (!is_empty (zmobs (z))) {
if ((f = FOPEN(filename, "w")) == NULL) {
progerror (filename);
if (!silent) bprintf ("%s", err_unsucc);
return;
}
fprintf (f, "%d\n", n_mobs = znumchars (z));
for (i = zfirst_mob (z), ct = 0; ct < n_mobs ; i = zmob_nr(++ct, z)) {
ploc_reset (i) = loc_id (ploc (i));
pstr_reset (i) = pstr (i);
pvis_reset (i) = pvis (i);
sflags_reset (i) = sflags (i);
pflags_reset (i) = pflags (i);
mflags_reset (i) = mflags (i);
nflags_reset (i) = 0;
eflags_reset (i) = eflags (i);
plev_reset (i) = plev (i);
pagg_reset (i) = pagg (i);
pspeed_reset (i) = pspeed (i);
pdam_reset (i) = pdam (i);
parmor_reset (i) = parmor (i);
pwimpy_reset (i) = pwimpy (i);
fprintf (f, "%s^\n",
EMPTY (pname (i)) ? pname_reset (i) : pname (i));
fprintf (f, "%ld %d %d %ld %d %d %d %d %d %d %d\n",
mob_id (i), pnum (i), z, ploc_reset (i),
pstr (i), pdam (i), pagg (i), parmor (i),
pspeed (i), pvis (i), pwimpy (i));
fprintf (f, "0x%08lx:0x%08lx 0x%08lx:0x%08lx:0x%08lx\n",
sflags (i).h, sflags (i).l,
pflags (i).u, pflags (i).h, pflags (i).l);
fprintf (f, "0x%08lx:0x%08lx 0x%08lx:0x%08lx\n",
mflags (i).h, mflags (i).l, eflags (i).h, eflags (i).l);
fprintf (f, "%s^\n", pftxt (i) == NULL ? "" : pftxt (i));
fprintf (f, "%s^\n\n", pexam (i) == NULL ? "" : pexam (i));
}
FCLOSE(f);
}
else
unlink (filename);
wiz_obj_filename (filename, zname (z));
if (!is_empty (zobjs (z))) {
FILE *obj_file;
if ((obj_file = FOPEN(OBJECTS, "r")) == NULL) {
progerror (OBJECTS);
if (!silent) bprintf ("%s", err_unsucc);
return;
}
if ((f = FOPEN(filename, "w")) == NULL) {
progerror (filename);
if (!silent) bprintf ("%s", err_unsucc);
FCLOSE(obj_file);
return;
}
fprintf (f, "%d\n", n_objs = znumobs (z));
for (i = zfirst_obj (z), ct = 0; ct < n_objs ; i = zobj_nr(++ct, z)) {
if (otemporary(i) && silent)
return;
else
otemporary(i) = False;
oloc_reset (i) = ocarrf (i) == IN_ROOM ? loc_id (oloc (i))
: ocarrf (i) == IN_CONTAINER ? obj_id (oloc (i))
: mob_id (oloc (i));
osize_reset (i) = osize (i);
ovalue_reset (i) = obaseval (i);
ovis_reset (i) = ovis (i);
odamage_reset (i) = odamage (i);
oarmor_reset (i) = oarmor (i);
ocarrf_reset (i) = ocarrf (i);
state_reset (i) = state (i);
obits_reset (i) = obits (i);
fprintf (f, "%s %s %d %ld %d %ld "
"%d %d %ld %d %d %d %ld:%ld %ld %d %d %d %d\n",
oname(i), oaltname(i) ? oaltname(i) : "<null>",
z, obj_id (i), onum (i),
olinked(i) == -1 ? -1L : obj_id(olinked (i)),
ovis(i), ocarrf(i), oloc_reset (i),
state(i), odamage(i), oarmor(i),
obits(i).l, obits(i).h, abits(i),
omaxstate(i), obaseval(i), osize(i), oweight(i));
for (j = 0; j < 4; j++) {
if (olongt (i, j) != NULL)
fprintf (f, "%s", olongt (i, j));
fprintf (f, "^\n");
}
if (oexam_text (i) != NULL)
fprintf (f, "%s", oexam_text (i));
else if (oexamine (i) > 0) {
int c;
fseek (obj_file, oexamine (i), 0);
while ((c = getc (obj_file)) != '^' && c != EOF)
putc (c, f);
}
fprintf (f, "^\n\n");
}
FCLOSE(obj_file);
FCLOSE(f);
}
else
unlink (filename);
wiz_loc_filename (filename, zname (z));
if (!is_empty (zlocs (z))) {
if ((f = FOPEN(filename, "w")) == NULL) {
progerror (filename);
if (!silent) bprintf ("%s", err_unsucc);
return;
}
fprintf (f, "%d\n", n_locs = znumloc (z));
for (i = zfirst_loc(z), ct = 0; ct < n_locs ; i = zloc_nr(++ct, z)) {
ltouched (i) = False;
for (j = 0; j < NEXITS; j++) {
lexit_reset (i, j) = lexit (i, j);
if (exists (lexit (i, j)))
lexit_reset (i, j) = loc_id (lexit (i, j));
}
xlflags_reset (i) = xlflags (i);
fprintf (f, "%ld %d", loc_id (i), z);
for (j = 0; j < NEXITS; j++) {
fprintf (f, " %ld", lexit_reset (i, j));
}
fprintf (f, "\n0x%08lx:0x%08lx\n%d\nCloned^\n%s^\n",
xlflags (i).h, xlflags (i).l, laltitude(i), lshort (i));
if (llong (i) != NULL) {
char *q = llong (i);
while (*q != '\0')
putc (*q++, f);
}
fprintf (f, "^\n");
}
FCLOSE(f);
}
else
unlink (filename);
if (!silent)
bprintf ("Zone %s: Stored %d room(s), %d mobile(s) and %d object(s).\n",
zname (z), n_locs, n_mobs, n_objs);
}
void loadcom (void) {
char *p;
int zlev;
PERSONA P;
int plr;
int nlocs, nlocs_f, nmobs, nmobs_f, nobjs, nobjs_f;
int mem_used;
if (!ptstflg (mynum, PFL_LD_STORE)) {
erreval ();
return;
}
if (brkword () == -1) {
zlev = plev (mynum);
p = pname (mynum);
}
else if ((plr = fpbn(wordbuf)) >= 0) {
zlev = plev (plr);
p = pname (plr);
}
else if (getuaf (wordbuf, &P)) {
zlev = P.ublock.plev;
p = P.ublock.pname;
}
else {
bprintf ("No such player: %s\n", wordbuf);
return;
}
if (!EQ (pname (mynum), p) && !do_okay_l (plev (mynum), zlev, True)) {
bprintf ("You're not powerful enough.\n");
return;
}
mem_used = load_zone (p, &nlocs, &nlocs_f, &nmobs, &nmobs_f,
&nobjs, &nobjs_f);
if (mem_used < 0) {
bprintf ("Load failed for zone %s.\n", p);
} else {
if (nlocs_f == 0 && nmobs_f == 0 && nobjs_f == 0) {
bprintf ("Can't find anything stored for %s.\n", p);
return;
}
bprintf ("Zone %s:\n\n", p);
if (nlocs_f > 0) {
bprintf ("Loaded %d location(s) from %d",
nlocs, nlocs_f);
if (nlocs != nlocs_f)
bprintf (" (%d already existed)",
nlocs_f - nlocs);
bprintf ("\n");
}
if (nmobs_f > 0) {
bprintf ("Loaded %d mobile(s) from %d",
nmobs, nmobs_f);
if (nmobs != nmobs_f)
bprintf (" (%d already existed)",
nmobs_f - nmobs);
bprintf ("\n");
}
if (nobjs_f > 0) {
bprintf ("Loaded %d object(s) from %d",
nobjs, nobjs_f);
if (nobjs != nobjs_f)
bprintf (" (%d already existed)",
nobjs_f - nobjs);
bprintf ("\n");
}
}
}
void
linkcom (void)
{
int obj1, obj2;
if (plev (mynum) < LVL_WIZARD) {
erreval ();
return;
}
if ((obj1 = ob1) == -1) {
bprintf ("Object 1 does not exist.\n");
return;
}
if ((obj2 = ob2) == -1) {
bprintf ("Object 2 does not exist.\n");
return;
}
olinked (obj1) = obj2;
olinked (obj2) = obj1;
mudlog ("LINK: %s linked %s (%d) to %s (%d)", pname (mynum), oname (obj1),
onum (obj1), oname (obj2), onum (obj2));
bprintf ("Linked %s to %s.\n", oname (obj1), oname (obj2));
}
void
maxstatecom (void)
{
int obj, st;
if (plev (mynum) < LVL_WIZARD) {
erreval ();
return;
}
if ((obj = ob1) == -1) {
bprintf ("Object does not exist.\n");
return;
}
if (EMPTY (txt2)) {
bprintf ("A new MaxState must be provided.\n");
return;
}
st = max (0, atoi (txt2));
if (st > 3) {
bprintf ("MaxState too large: %d.\n", st);
return;
} else {
bprintf ("Setting MaxState to %d.\n", st);
}
mudlog ("MAXSTATE: %s set the MaxState of %s (%d) to %d", pname (mynum),
oname (obj), onum (obj), st);
omaxstate (obj) = st;
}