/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ABERED (AberMUD Dirt3 editor) * * * * Function related to loctaions including those required to change them * * and those required to move around the editor. * * * * Copyright (C) 1993 James Willie. All rights reseved. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <stdio.h> #include <ctype.h> #include "types.h" #include "macros.h" #include "extern.h" #include "prototyp.h" #ifdef ANSI_C static void rename_all(PLOC l, char *n); static Bool check_dup_name(char *s); static void free_loc(PLOC l); #else static void rename_all(l,n); static Bool check_dup_name(s); static void free_loc(l); #endif static char *dir[] = { "North:", "East:", "South:", "West:", "Up:", "Down:" }; /* ** Find location by name */ PLOC flbname(s) char *s; { PLOC l = loc; if (EMPTY(s)) return NULL; while (l != NULL) { if (strcasecmp(l->name, s) == 0) return l; l = l->next; } return NULL; } /* ** Connect exits of locations to their rooms or objects. */ void fix_exit(l) PLOC l; { int i; if (l == NULL) return; for (i = 0; i < NEXITS; i++) { switch(l->exit_type[i]) { case X_NORMAL: l->exits[i] = (PLOC)flbname(l->ename[i]); break; case X_OBJECT: l->exits[i] = (POBJ)fobname(l->ename[i]); break; default: l->exits[i] = NULL; break; } } return; } /* ** Fix all the exits */ void fix_exits() { PLOC l = loc; while (l != NULL) { fix_exit(l); l = l->next; } return; } /* ** look in a room see what the hecks there */ void lookin(l) PLOC l; { POBJ o = obj; PMOB m = mob; if (l == NULL) { printf("\n A void beyond the universe as we know it\n"); return; } printf("%s\n", l->pname); if (!brief) write_string(l->desc,stdout); /* This one likely to be to long */ /* Display objects in the room */ while (o != NULL) { if ((o->ltype == IN_ROOM) && ((PLOC)o->location == l) && (!EMPTY(o->desc[o->state]))) { printf("%s\n", o->desc[o->state]); } o = o->next; } /* Display mobiles in the room */ while (m != NULL) { if (m->loc == l) { if (!EMPTY(m->desc)) printf("%s\n",m->desc); else printf("%s is here.\n",m->pname); } m = m->next; } return; } /* ** Lets move */ void dodirn(x) int x; { PLOC l; POBJ o; if ((myloc == NULL) || (x >= NEXITS) || (x < 0)) { printf("\033[1;35m*GIGGLE* *LAUGH* *ROFL*\033[0;0m\nOh, your serious :(\n"); return; } if (myloc->exits[x] == NULL) fix_exit(myloc); switch(myloc->exit_type[x]) { case X_NORMAL: l = (PLOC)myloc->exits[x]; break; case X_OBJECT: l = NULL; if (myloc->exits[x] != NULL) { o = fobname(((POBJ)myloc->exits[x])->name); if (o != NULL) { o = fobname(o->link); if ((o != NULL) && (o->ltype == IN_ROOM)) l = (PLOC)o->location; else printf("Link object unknown\n"); } else printf("Pointer to unknown object\n"); } else printf("NULL exit\n"); break; case X_NONE: printf("No exit that way\n"); return; break; default: printf("Unknown exit type\n"); l = NULL; break; } if (l == NULL) printf("Error somewhere :(\n"); else { myloc = l; lookin(myloc); } return; } /* ** Show stats of a room, in dirt loc format, default room is myloc */ void rstatscom() { PLOC l; if (EMPTY(arg[0])) l = myloc; else if ((l = flbname(arg[0])) == NULL) l = myloc; write_dirt_loc(l,stdout); return; } /* ** Show list if exits in the room */ void exitcom() { int i; if (myloc == NULL) { printf("None\n"); return; } if (!EMPTY(arg[0])) { i = lookup(dir,arg[0]); if ((i < 0) || (i >= NEXITS)) { printf("What exit might that be?\n"); return; } if (!EMPTY(arg[1])) { create_exit(myloc,i,arg[1]); printf("Exit created\n"); return; } delete_exit(myloc,i); printf("Exit destroyed\n"); return; } for(i = 0; i < NEXITS; i++) { if (myloc->exit_type[i] == X_NORMAL) { printf("%s%s%c\n", dir[i], myloc->ename[i], (myloc->exits[i] == NULL) ? '*' : ' '); } else if (myloc->exit_type[i] == X_OBJECT) { printf("%s^%s%c\n", dir[i], myloc->ename[i], (myloc->exits[i] == NULL) ? '*' : ' '); } else { printf("%sNone\n", dir[i]); } } return; } /* ** goto the room in arg ** Search for room, or object to match. (Objects must be in a room) */ void gotocom() { PLOC l = NULL; POBJ o = NULL; PMOB m = NULL; if (arg[0] == NULL) l = NULL; else l = flbname(arg[0]); if (l == NULL) { m = fmobile(arg[0]); if (m != NULL) l = (PLOC)m->loc; } if (l == NULL) { o = fobject(arg[0]); if ((o != NULL) && (o->ltype == IN_ROOM)) l = (PLOC)o->location; } if (l == NULL) printf("Where's that?\n"); else { myloc = l; lookin(myloc); } } void create_exit(l,x,s) PLOC l; int x; char *s; { char *t; if ((x < 0) || (x > NEXITS)) return; if (s[0] == '^') { t = &(s[1]); l->exit_type[x] = X_OBJECT; l->exits[x] = fobname(t); } else { t = s; l->exit_type[x] = X_NORMAL; l->exits[x] = (PLOC)flbname(t); } l->ename[x] = COPY(t); modified = TRUE; } /* ** Delete one of the exits */ void delete_exit(l,x) PLOC l; int x; { if ((x < 0) || (x >= NEXITS)) return; l->exit_type[x] = X_NONE; FREE(l->ename[x]); l->exits[x] = NULL; modified = TRUE; return; } /* ** This is infact no editor, merely allows you to enter text for the room ** description. If you want to edit, use an editor later on. */ Bool redit_com() { char *s; PLOC l = myloc; int which = 0, i; if (arg[0] != NULL) { if (arg[1] != NULL) { if (ABREV_EQ("NAME", arg[0])) which = 2; else if (ABREV_EQ("PNAME", arg[0])) which = 1; else if (ABREV_EQ("DESCRIPTION", arg[0])) which = 0; else { printf("redit <DESCRIPTION|PNAME|NAME> <LOCATION>\n"); printf("The default is desc, eg ledit loc == ledit desc loc\n"); return FALSE; } arg[0] = arg[1]; l = flbname(arg[0]); } else { if (ABREV_EQ("NAME", arg[0])) which = 2; else if (ABREV_EQ("PNAME", arg[0])) which = 1; else if (ABREV_EQ("DESCRIPTION", arg[0])) which = 0; else l = flbname(arg[0]); } } if (l == NULL) { printf("Don't know that room.\n"); return FALSE; } switch(which) { case 0: #ifdef IBM_MLJ_EDIT set_header("\tEnter your room description"); s = edit_string(l->desc, 1); #else printf("Enter the new description for room %s\nPress ^<CR> to end\n", l->pname); s = get_text(stdin,'^'); NEWLINE(stdin); #endif if ((s == NULL) || (s[0] == '\0')) { printf("No change\n"); return FALSE; } free(l->desc); l->desc = s; break; case 1: printf("Enter the new pname for room %s\nHit <CR> when done\n",l->pname); s = get_text(stdin, '\n'); if ((s == NULL) || (s[0] == '\0')) { printf("No change\n"); return FALSE; } free(l->pname); l->pname = s; break; case 2: printf("Enter the new name for room %s\nONE word only\n", l->pname); s = get_text(stdin, '\n'); if ((s == NULL) || (s[0] == '\0') || check_dup_name(s)) { printf("No change\n"); return FALSE; } for(i = 0; (!isspace(s[i])) && (s[i] != '\0'); i++) ; s[i] = '\0'; rename_all(l,s); free(l->name); l->name = COPY(s); FREE(s); break; } modified = TRUE; return TRUE; } /* ** Change the names on exits, objects etc, when a room name changes. ** If n == NULL, it just deletes the exit, or sets mob/obj loc to NULL */ static void rename_all(l,n) PLOC l; char *n; { PLOC r = loc; int i; while(r != NULL) { for(i = 0; i < NEXITS; i++) if (r->exits[i] == l) { free(r->ename[i]); if (n == NULL) { r->ename[i] = NULL; r->exit_type[i] = X_NONE; r->exits[i] = NULL; } else r->ename[i] = COPY(n); } r = r->next; } return; } /* ** Set/show lflags. It can optionally take an argument of which room ** but defaults to player/editors current location */ void lflags() { int k; PLOC l; char *f, *t; if ((l = flbname(arg[0])) == NULL) /* find location we a looking at */ { l = myloc; /* 2 args, def loc is myloc */ f = arg[0]; t = arg[1]; } else /* found loc, look arg 1,2 for args */ { f = arg[1]; t = arg[2]; } if (l == NULL) { printf("What location?\n"); return; } if (EMPTY(f)) /* Query all flags in the room */ { for (k = 0; k < NUM_LFLAGS; k++) { if (l->lflags[k] == TRUE) { printf("%s ",l_flags[k]); } } printf("\n"); return; } k = lookup(l_flags, f); if (k < 0) { printf("No such flag\n"); return; } if (EMPTY(t)) /* Query flag f */ { printf("%s", arg[0]); if (l->lflags[k]) printf(" is true.\n"); else printf(" is false.\n"); } else if (ABREV_EQ("TRUE",t)) /* Set flag f, to t */ { l->lflags[k] = TRUE; modified = TRUE; } else if (ABREV_EQ("FALSE",t)) { l->lflags[k] = FALSE; modified = TRUE; } else printf("Set it TRUE or FALSE?\n"); return; } /* ** print a list of locations */ void list_loc() { PLOC l = loc; int i,j; while(l != NULL) { j = strlen(l->name); printf("%s",l->name); for(i = j; i <= 20; i++) putc(' ', stdout); printf("%s\n",l->pname); l = l->next; } } /* ** Create a complete new location */ void create_loc() { PLOC l, tmp; char *name = arg[0]; int i; l = NEW(LOC); /* Initialise the data structure */ l->name = COPY("NEW"); l->pname = COPY("NEW"); l->desc = COPY("NEW"); for (i = 0; l_flags[i] != TABLE_END; i++) l->lflags[i] = FALSE; for(i = 0; i < NEXITS; i++) { l->exits[i] = NULL; l->ename[i] = NULL; l->exit_type[i] = X_NONE; } /* Move me to the new room and remember old one in case creation fails */ tmp = myloc; myloc = l; /* Rooms name (MUST be unique) */ if (EMPTY(name) || check_dup_name(name)) { set_args("NAME",NULL,NULL); if (redit_com() == FALSE) { free_loc(l); myloc = tmp; return; } } else l->name = COPY(name); /* The rooms Pname */ set_args("PNAME", NULL, NULL); if (redit_com() == FALSE) { free_loc(l); myloc = tmp; return; } /* New description for the room */ free_args(); redit_com(); /* Insert new room somewhere in the list of rooms */ if (loc == NULL) { myloc = l; loc = l; loc->next = NULL; } else { l->next = tmp->next; tmp->next = l; } modified = TRUE; numloc++; return; } /* ** Destroy a location, if myloc is to be destroyed, move me, and fix the ** exits into the location. */ void do_destroy_loc(l) PLOC l; { PLOC r = loc; PMOB m = mob; POBJ o = obj; if (l == NULL) return; rename_all(l, NULL); /* Delete all exits from other rooms into here */ /* Delete mobile location pointers to the room */ while (m != NULL) { if (m->loc == l) m->loc = NULL; m = m->next; } /* Delete object location pointers to the room */ while (o != NULL) { if ((o->ltype == IN_ROOM) && (((PLOC)o->location) == l)) o->location = NULL; o = o->next; } if (loc == l) { loc = l->next; } else { for(r = loc; r != NULL; r = r->next) if (r->next == l) break; r->next = l->next; } if (l == myloc) { printf("The universe begins to crackle, distant suns explode, as you \n"); printf("enjoy your dinner at millyways\n"); printf("When it's all over you find yourself, safe in a new location\n"); myloc = loc; } free_loc(l); modified = TRUE; numloc--; return; } /* ** The destroy location command. */ void destroy_loc() { PLOC l; if (EMPTY(arg[0])) { printf("Destroy what room?\n"); return; } l = flbname(arg[0]); if (l == NULL) { printf("The room is only in YOUR imagination, how am I supposed to "); printf("destroy it\n"); return; } printf("Are you sure you want to destroy %s [%s] [NO/yes] ? ", l->name,l->pname); get_command(); pnt = cmdln; cmd = get_arg(); if (EMPTY(cmd) || !ABREV_EQ(cmd,"Yes")) { printf("Location _NOT_ destroyed\n"); return; } do_destroy_loc(l); printf("Location destroyed\n"); return; } static Bool check_dup_name(s) char *s; { if (flbname(s) != NULL) { printf("\nSorry, a location exist with that name. [Try adding a number]\n"); return TRUE; } return FALSE; } static void free_loc(l) PLOC l; { if (l == NULL) return; FREE(l->name); FREE(l->pname); FREE(l->desc); FREE(l); return; } /* ** clone_loc() exactly clones another room, lflags, description etc */ void clone_loc(s, t) char *s; char *t; { PLOC l, tmp; int i; tmp = flbname(s); if (tmp == NULL) { /* Maybe they gave args in wrong order */ tmp = flbname(t); if (tmp == NULL) { printf("Error: I can't find room %s to clone it. Sorry!\n", s); return; } t = s; } l = flbname(t); if (l != NULL) { printf("Error: Sorry can't clone %s to %s because destination exists.\n", tmp->name, t); return; } l = NEW(LOC); /* Initialise the data structure */ l->pname = COPY((char *)tmp->pname); l->name = COPY(t); l->desc = COPY((char *)tmp->desc); for (i = 0; l_flags[i] != TABLE_END; i++) l->lflags[i] = tmp->lflags[i]; for(i = 0; i < NEXITS; i++) { l->exits[i] = tmp->exits[i]; if ((tmp->exits[i] == NULL) && (!EMPTY(tmp->ename[i]))) l->ename[i] = COPY((char *)tmp->ename[i]); else l->ename[i] = NULL; l->exit_type[i] = tmp->exit_type[i]; } /* Insert new room into list */ if (loc == NULL) { myloc = l; loc = l; loc->next = NULL; } else { l->next = tmp->next; tmp->next = l; } printf("Cloned location `%s' [%s] to [%s].\n", l->pname, tmp->name, l->name); modified = TRUE; numloc++; return; }