#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 "locations.h"
#include "mobiles.h"
#include "stdinc.h"
/* Create a new object by copying an existing one. A new name and
* zone for it to belong to (both optional) may be given.
*
* Return the new object's index number, or -1 on error.
*/
int clone_object(int obj, int new_zone, char *new_name)
{
int i;
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);
}
objects[numobs] = objects[obj];
oname(numobs) = new_name != NULL ? COPY(new_name)
: oname(obj) != NULL ? COPY(oname(obj)) : NULL;
if (oaltname(obj) != NULL) oaltname(numobs) = COPY(oaltname(obj));
for (i = 0; i < 4; i++)
if (olongt(obj, i) != NULL) olongt(numobs, i) = COPY(olongt(obj, i));
if (oexam_text(obj) != NULL) oexam_text(numobs) =COPY(oexam_text(obj));
otemporary(numobs) = True;
create(numobs);
init_intset(oinv(numobs), otstbit(numobs, OFL_CONTAINER) ? 15 : 0);
setoloc(numobs, oloc(numobs), ocarrf(numobs));
insert_entry( (obj_id(numobs) = id_counter++), numobs, &id_table );
if (new_zone > -1) {
zadd_obj(numobs, ozone(numobs) = new_zone);
}
else {
zadd_obj(numobs, ozone(obj));
}
return numobs++;
}
/* 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;
Boolean reused = False;
if (opermanent(obj) || obj >= numobs) return False;
/* 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); i != SET_END; i = onext_obj(obj)) {
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);
/* Change all references in the inventory of 'numobs-1' to obj
*/
for (i = ofirst_obj(obj); i != SET_END; i = onext_obj(obj)) {
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);
}
ublock[numchars] = ublock[mob];
if (new_name != NULL) {
setpname(numchars, new_name);
pname_reset(numchars) = COPY( new_name );
}
else {
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);
ptemporary(numchars) = True;
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, j;
Boolean reused = False;
if (ppermanent(mob) || mob >= numchars) return False;
setpfighting(mob, -1);
/* If someone is aliasing it, lose them.
*/
if ((j = find_pretender(mob)) > -1) {
unalias(j);
unpolymorph(j);
}
/* If it carries something, drop it
*/
for (i = pfirst_obj(mob); i != SET_END; i = pnext_obj(mob)) {
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));
/* If someone was aliasing the last mobile in the array,
* change his alias-entry to this mobile's new index:
*/
if ((j = find_pretender(numchars - 1)) > -1) {
players[j].pretend = 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); i != SET_END; i = pnext_obj(mob)) {
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];
room_data[numloc].temporary = True;
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;
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.
*/
for (i = lfirst_mob(l); i != SET_END; i = lnext_mob(l)) {
destroy_mobile(i);
}
/* If it contains objects, destroy them.
*/
for (i = lfirst_obj(l); i != SET_END; i = lnext_obj(l)) {
destroy(i);
}
/* Clear exits
*/
for (i = 0; i < NEXITS; i++) setexit(l, i, 0);
for (i = first_int(lexits_to_me(l)); i != SET_END;
i = next_int(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 (i = lfirst_obj(l); i != SET_END; i = lnext_obj(l)) {
setoloc(i, l, ocarrf(i));
}
for (i = lfirst_mob(l); i != SET_END; i = lnext_mob(l)) {
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 == '^';
}
/* The CLONE command.
*/
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 (ltstflg(ploc(mynum), LFL_JAIL) && (plev(mynum) < LVL_DEMI)) {
bprintf ("The guards won't let you\n");
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));
send_msg(DEST_ALL, MODE_QUIET, max(pvis(mynum), LVL_GOD),
LVL_MAX, mynum, NOBODY,
"&+G[%s CLONEd &+Rlocation &+G%s]&+w\n",
pname(mynum), showname(a));
}
else if ((a = fpbn(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;
}
/* Make sure we're not trying to clone a player */
if(getuaf(pname(a),&P)) {
bprintf("You can't clone players.\n");
return;
}
if(p != NULL) if ( getuaf(p, &P2)) {
bprintf("There is a player with that name!\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("[%d]\n", GLOBAL_MAX_OBJS + id);
sendf(ploc(mynum), "%s appears before you!\n", pname(id));
send_msg(DEST_ALL, MODE_QUIET, max(pvis(mynum), LVL_GOD),
LVL_MAX, mynum, NOBODY,
"&+G[%s CLONEd a &+Rmobile &+Gto %s in %s]&+w\n",
pname(mynum), pname(id), showname(ploc(mynum)));
}
else if ((a = fobn(name)) != -1) {
if (digits || graphic || blanks) {
bprintf("New object name: letters only.\n");
return;
}
if (is_classname(p)) {
bprintf("Can't be same name as a class of objects.\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)) < 0) {
bprintf("The max # of objs (%d) has been reached.\n",
GLOBAL_MAX_OBJS);
return;
}
setoloc(id, ploc(mynum), IN_ROOM);
obaseval(id) = 0;
odamage(id) = 0;
oarmor(id) = 0;
bprintf("[%d]\n", id);
sendf(ploc(mynum),"The %s is created before you!\n",oname(id));
send_msg(DEST_ALL, MODE_QUIET, max(pvis(mynum), LVL_GOD),
LVL_MAX, mynum, NOBODY,
"&+G[%s CLONEd &+Robject &+G%s to %s in %s]&+w\n",
pname(mynum), oname(a),oname(id), showname(ploc(mynum)));
}
else if (a == 1) {
strcat( wordbuf, "1" );
clonecom(False);
}
else {
bprintf("I don't know any %s.\n", name);
}
}
/* The DESTRUCT command.
*/
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 (lpermanent(a)) {
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");
}
}
else if ((a = fpbn(args)) != -1 && a >= max_players) {
if (ppermanent(a)) {
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");
destruct_mobile(a, NULL);
}
else if ((a = fobn(args)) != -1) {
if (opermanent(a)) {
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");
destruct_object(a, NULL);
}
else if (a == 1) {
destructcom( strcat(args, "1") );
}
else {
bprintf("I don't know any %s\n", args);
}
}
/* The STORE command.
*/
void storecom()
{
char filename[128];
char *p;
int z, x, i, j, zlev;
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;
}
p = (brkword() == -1) ? pname(mynum) : wordbuf;
if ((z = get_zone_by_name(p)) < num_const_zon) {
bprintf("%s: Nothing to store.\n", p);
return;
}
zlev = (x = fpbns(p)) >= 0 ? plev(x)
: getuaf(p, &P) ? P.p_level : LVL_MIN;
if (!EQ(pname(mynum), zname(z))
&& !do_okay_l(plev(mynum), zlev, False)) {
bprintf("You're not powerful enough.\n");
return;
}
/* Mark zone not temporary
*/
ztemporary(z) = False;
/* Update the id_counter file so that when the server exits or crashes
* the saved id-counter is allways greater then any saved item's ID.
*/
if (!save_id_counter()) {
bprintf("%s", err_unsucc);
return;
}
wiz_mob_filename(filename, zname(z));
if (!is_empty(zmobs(z))) {
if ((f = fopen(filename, "w")) == NULL) {
progerror(filename);
bprintf("%s", err_unsucc);
return;
}
fprintf(f, "%d\n", n_mobs = znumchars(z));
for (i = zfirst_mob(z); i != SET_END; i = znext_mob(z)) {
/* Mark him not to be destroyed on reset:
*/
ptemporary(i) = False;
/* Set his reset values to his current state:
*/
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);
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);
/* Store it on file
*/
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\n",
sflags(i),
pflags(i).b1, pflags(i).b2, pflags(i).b3);
fprintf(f, "0x%08lx:0x%08lx\n",
mflags(i).h, mflags(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);
bprintf("%s", err_unsucc);
return;
}
if ((f = fopen(filename, "w")) == NULL) {
progerror(filename);
bprintf("%s", err_unsucc);
fclose(obj_file);
return;
}
fprintf(f, "%d\n", n_objs = znumobs(z));
for (i = zfirst_obj(z); i != SET_END; i = znext_obj(z)) {
/* Mark it not to be destroyed on reset:
*/
otemporary(i) = False;
/* Set its reset values to its current state:
*/
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 %d %d %d %d\n",
oname(i),
oaltname(i) != NULL ? 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), omaxstate(i), obaseval(i),
osize(i),
0 /*weight*/);
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);
bprintf("%s", err_unsucc);
return;
}
fprintf(f, "%d\n", n_locs = znumloc(z));
for (i = zfirst_loc(z); i != SET_END; i = znext_loc(z)) {
/* Mark it not to be destroyed on resets:
*/
ltemporary(i) = False;
/* Set its reset values to its current state:
*/
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);
/* Store it on file
*/
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\n%s^\n", xlflags(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);
}
bprintf("Zone %s: Stored %d room(s), %d mobile(s) and %d object(s).\n",
zname(z), n_locs, n_mobs, n_objs);
}
/* The LOAD command.
*/
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 = fpbns(wordbuf)) >= 0) {
zlev = plev(plr);
p = pname(plr);
}
else if (getuaf(wordbuf, &P)) {
zlev = P.p_level;
p = P.p_name;
}
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");
}
}
}
Boolean is_classname(char *name)
{
return name != NULL && findclass(name) != NULL;
}