/***************************************************************************** ** Actions handler - Combined from dyrt/dirt ** Structured by Marty *****************************************************************************/ #define ACTIONS_C #include <malloc.h> #include <sys/param.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <strings.h> #include "kernel.h" #include "config.h" #include "sendsys.h" #include "global.h" #include "sflags.h" #include "bprintf.h" #include "parse.h" #include "fight.h" #include "log.h" #include "special.h" struct _ext_msg { char code; /* Codes EXT_TNAM..EXT_ONAM uses this form */ char *next; /* Pointer to next part of string. */ }; struct _ext_msg1 { struct _ext_msg e; char *str; /* Code EXT_STRING uses this form */ }; struct _ext_msg2 { struct _ext_msg e; /* Codes EXT_TARGET and EXT_ACTOR uses this form */ char *male_txt; char *female_txt; }; /* struct for the external commands */ typedef struct _ext { struct _ext *next; int flags; char *verb; char *msg_to_all; char *msg_to_me; } EXTERN_CMD_REC; /* These are in addition if the command accept a target */ struct _ext2 { EXTERN_CMD_REC e; char *msg_to_target; char *msg_to_sender; char *msg_to_others; }; /* Datatypes */ static char *ext_msg_names[] = {"all", "me", "target", "sender", "others", TABLE_END}; static char *s_ext[] = { "Flowers", "Hate", "Koosh", "Nod", "Pet", "Pray", "Rose", "Tickle", "Wave", TABLE_END }; /* code is one of the following: */ #define EXT_STRING 1 /* insert string here */ #define EXT_TARGET 2 /* Select string on psex(target) */ #define EXT_ACTOR 3 /* Select string on psex(actor) */ #define EXT_TNAM 4 /* insert pname(target) here */ #define EXT_ANAM 5 /* insert pname(actor) here */ #define EXT_THIM 6 /* Insert psex(target) ? "her" : "him" here */ #define EXT_AHIM 7 /* Insert psex(actor) ? "her" : "him" here */ #define EXT_THIS 8 /* Insert psex(target) ? "her" : "his" here */ #define EXT_AHIS 9 /* Insert psex(actor) ? "her" : "his" here */ #define EXT_ONAM 10 /* Insert oname(ob2) here if EXTF_OBJ */ #define EXT_MTXT 11 /* Insert user text via %s here */ #define EXT_ERROR ((char *)(-2)) /* Error return from various functions. */ #define EXTF_ALL 0x01 #define EXTF_SINGLE 0x02 #define EXTF_HOSTILE 0x04 #define EXTF_ALOOF 0x08 #define EXTF_OBJ 0x10 /* Command takes an object as arg */ #define EXTF_TEXT 0x20 /* Command accepts a string at the end */ #define EXTF_FAR 0x40 /* Target may be in other room */ #define EXT_MSG_ALL 0 #define EXT_MSG_ME 1 #define EXT_MSG_TARGET 2 #define EXT_MSG_SENDER 3 #define EXT_MSG_OTHERS 4 #define EXT_ANGLE_OPEN 0x100 /* %< ok? */ #define EXT_ANGLE_MIDDLE 0x200 /* %: ok? */ #define EXT_ANGLE_CLOSE 0x400 /* %> ok? */ #define EXT_SQ_MIDDLE 0x800 /* %/ ok? */ #define EXT_SQ_CLOSE 0x1000 /* %] ok? */ #define EXT_HAT 0x2000 /* %^ or %~ ok? */ #define EXT_T 0x2000 /* %t ok? */ #define EXT_O 0x4000 /* %o ok? */ #define EXT_M 0x8000 /* %m ok? */ static void ext_free_msg (char *s); static int ext_get_tok (void); static char *ext_get_itm (void); static char *ext_get_string (void); static char *ext_get_simple (int code); static char *ext_get_mf (int code, int middle, int end, int fla_m, int fla_c); static struct _ext_msg *ext_mk_struct (char *s); static char *ext_get_anything (void); static char *ext_get_msg (int *w, FILE * f, int bsiz, int l, int h, int *mem_used); static char *build_action (char *a); EXTERN_CMD_REC *externs; static char *buffer; static char *bufp; static int cur_tok; static int ext_who; static int mused; static int ext_lino; static int ext_flags; /* * Function to free a msg. */ static void ext_free_msg (char *s) { if (s == NULL || s == EXT_ERROR) return; if (*s < ' ' || *s > '~') { switch (((struct _ext_msg *) s)->code) { case EXT_STRING: ext_free_msg (((struct _ext_msg1 *) s)->str); break; case EXT_TARGET: case EXT_ACTOR: ext_free_msg (((struct _ext_msg2 *) s)->male_txt); ext_free_msg (((struct _ext_msg2 *) s)->female_txt); break; case EXT_TNAM: case EXT_ANAM: case EXT_THIM: case EXT_AHIM: case EXT_THIS: case EXT_AHIS: case EXT_ONAM: break; default: mudlog ("Illegal extern code %d\n", ((struct _ext_msg *) s)->code); return; /* Don't free anything */ } ext_free_msg (((struct _ext_msg *) s)->next); /* Free the next part */ } free (s); } void clear_all_ext(void) { EXTERN_CMD_REC *r,*p; p = externs; while (p != NULL) { r = p->next; ext_free_msg(p->verb); p = r; } } static int ext_get_tok (void) { int c; int k; if ((c = *bufp++) == '%') { switch (c = *bufp++) { case 'A': c = 'a'; case 'a': case '[': return cur_tok = 0400 + c; case '%': return cur_tok = c; case '<': k = EXT_ANGLE_OPEN; break; case ':': k = EXT_ANGLE_MIDDLE; break; case '>': k = EXT_ANGLE_CLOSE; break; case '~': case '^': k = EXT_HAT; break; case 'T': c = 't'; case 't': k = EXT_T; break; case '/': k = EXT_SQ_MIDDLE; break; case ']': k = EXT_SQ_CLOSE; break; case 'O': c = 'o'; case 'o': k = EXT_O; break; case 'M': c = 'm'; case 'm': k = EXT_M; break; default: k = 0; } if (k != 0 && (ext_flags & k) != 0) return cur_tok = c + 0400; c = '%'; --bufp; } if (c < ' ' || c > '~') c = 0; return cur_tok = c; } static char *ext_get_itm (void) { switch (cur_tok) { case 0400 + '<': return ext_get_mf (EXT_TARGET, ':', '>', EXT_ANGLE_MIDDLE, EXT_ANGLE_CLOSE); case 0400 + '[': return ext_get_mf (EXT_ACTOR, '/', ']', EXT_SQ_MIDDLE, EXT_SQ_CLOSE); case 0400 + '/': case 0400 + ':': case 0400 + '>': case 0400 + ']': case 0: return NULL; case 0400 + '^': return ext_get_simple (ext_who == EXT_MSG_SENDER ? EXT_THIS : EXT_AHIS); case 0400 + '~': return ext_get_simple (ext_who == EXT_MSG_SENDER ? EXT_THIM : EXT_AHIM); case 0400 + 'a': return ext_get_simple (EXT_ANAM); case 0400 + 't': return ext_get_simple (EXT_TNAM); case 0400 + 'o': return ext_get_simple (EXT_ONAM); case 0400 + 'm': ext_flags &= ~EXT_M; return ext_get_simple (EXT_MTXT); } return ext_get_string (); } static char *ext_get_string (void) { char b[256]; int c = cur_tok; int ct = 0; while (c >= ' ' && c <= '~') { b[ct++] = c; c = ext_get_tok (); } if (ct == 0) return NULL; mused += ct + 1; b[ct] = '\0'; return COPY (b); } static char *ext_get_simple (int code) { struct _ext_msg *m; (void) ext_get_tok (); m = NEW (struct _ext_msg, 1); m->code = code; m->next = NULL; mused += sizeof (struct _ext_msg); return (char *) m; } static char *ext_get_mf (int code, int middle, int end, int fla_m, int fla_c) { struct _ext_msg2 *s; char *m, *f; int flags = ext_flags; (void) ext_get_tok (); ext_flags |= fla_m | fla_c; if ((m = ext_get_anything ()) == EXT_ERROR) { ext_flags = flags; return EXT_ERROR; } f = NULL; ext_flags = flags; if (cur_tok == 0400 + middle) { ext_flags |= fla_c; (void) ext_get_tok (); if ((f = ext_get_anything ()) == EXT_ERROR) { ext_free_msg (m); ext_flags = flags; return EXT_ERROR; } ext_flags = flags; } if (cur_tok == 0400 + end) (void) ext_get_tok (); s = NEW (struct _ext_msg2, 1); ((struct _ext_msg *) s)->next = NULL; ((struct _ext_msg *) s)->code = code; s->male_txt = m; s->female_txt = f; mused += sizeof (struct _ext_msg2); return (char *) s; } static struct _ext_msg *ext_mk_struct (char *s) { struct _ext_msg1 *m; int c; if (s == NULL || s == EXT_ERROR) return (struct _ext_msg *) s; if (*s >= ' ' && *s <= '~') { m = NEW (struct _ext_msg1, 1); m->str = s; ((struct _ext_msg *) m)->code = EXT_STRING; ((struct _ext_msg *) m)->next = NULL; mused += sizeof (struct _ext_msg1); return (struct _ext_msg *) m; } c = ((struct _ext_msg *) s)->code; if (c >= EXT_STRING && c <= EXT_ONAM) return (struct _ext_msg *) s; mudlog ("ext_mk_struct: Illegal ext code %d", c); return (struct _ext_msg *) EXT_ERROR; } static char *ext_get_anything (void) { struct _ext_msg *first, *second_last; char *s, *t; if ((s = ext_get_itm ()) == NULL || s == EXT_ERROR) return s; if ((t = ext_get_itm ()) == EXT_ERROR) { ext_free_msg (s); return EXT_ERROR; } if (t == NULL) return s; /* build a list with s as first and t as last */ second_last = first = ext_mk_struct (s); /* make sure s is a struct */ first->next = t; while ((s = ext_get_itm ()) != NULL && s != EXT_ERROR) { /* Make sure last is a struct */ second_last->next = (char *) ext_mk_struct (second_last->next); /* move second_last to point to last */ second_last = (struct _ext_msg *) second_last->next; second_last->next = s; /* append s to the list */ } if (s == EXT_ERROR) { /* Clear the list */ ext_free_msg ((char *) first); return EXT_ERROR; } return (char *) first; } static char *ext_get_msg (int *w, FILE * f, int bsiz, int l, int h, int *mem_used) { char *s; int x = *w; int fl = ext_flags; if (bufp == EXT_ERROR) return EXT_ERROR; if (feof (f) || fgets (buffer, bsiz, f) == NULL) return NULL; ++ext_lino; bufp = buffer; if ((s = strchr (bufp, ':')) != NULL && s > bufp) { *s = 0; if ((x = tlookup (bufp, ext_msg_names)) < l || x > h) { x = *w; } else { *w = x; bufp = s + 1; } *s = ':'; } if ((ext_who = x) >= EXT_MSG_TARGET) { ext_flags |= EXT_T | EXT_ANGLE_OPEN; } if (x < EXT_MSG_OTHERS) { ext_flags |= EXT_HAT; } mused = 0; (void) ext_get_tok (); if ((s = ext_get_anything ()) == EXT_ERROR) { ext_flags = fl; return bufp = EXT_ERROR; } if (cur_tok != 0) { ext_free_msg (s); printf ("Illegal syntax in actions file\n"); ext_flags = fl; return bufp = EXT_ERROR; } *mem_used += mused; ext_flags = fl; if (s != NULL) ext_flags |= (1 << x); return s; } static void dump_action (EXTERN_CMD_REC * v) { if (v == NULL) return; bprintf ("Data about %s:\n", v->verb); bprintf ("Next verb: %s\n", (v->next == NULL) ? "<none>" : v->next->verb); bprintf ("Flags: "); if ((v->flags & EXTF_ALL) != 0) bprintf ("a"); if ((v->flags & EXTF_SINGLE) != 0) bprintf ("s"); if ((v->flags & EXTF_HOSTILE) != 0) bprintf ("h"); if ((v->flags & EXTF_ALOOF) != 0) bprintf ("i"); if ((v->flags & EXTF_FAR) != 0) bprintf ("f"); if ((v->flags & EXTF_OBJ) != 0) bprintf ("o"); if ((v->flags & EXTF_TEXT) != 0) bprintf ("t"); bprintf ("\n"); if ((v->flags & EXTF_ALL) != 0) { bprintf ("Msg to all: %s\n", build_action (v->msg_to_all)); bprintf ("Msg to me: %s\n", build_action (v->msg_to_me)); } if ((v->flags & EXTF_SINGLE) != 0) { bprintf ("Msg to target: %s\n", build_action (((struct _ext2 *) v)->msg_to_target)); bprintf ("Msg to sender: %s\n", build_action (((struct _ext2 *) v)->msg_to_sender)); if (((struct _ext2 *) v)->msg_to_others != NULL) { bprintf ("Msg to others: %s\n", build_action (((struct _ext2 *) v)->msg_to_others)); } } bprintf ("\n"); } static void dump_act_vb (char *s) { EXTERN_CMD_REC *v; int i; for (v = externs; v != NULL && !EQ (v->verb, wordbuf); v = v->next); if (v == NULL) { if ((i = tlookup (wordbuf, s_ext)) < 0) { bprintf ("I don't know about any %s action.\n", wordbuf); } else { bprintf ("%s is a special action.\n", s_ext[i]); } } else { dump_action (v); } } int boot_extern (FILE * f, char *fname) { char buff[256]; char *verb; EXTERN_CMD_REC *first = NULL, *last = NULL, *this; int flags; int i, j, low, high; char *s, *t; int mem_used = 0; int m_used = 0; int lino = 0; char *msgs[5]; buffer = buff; externs = NULL; while (!feof (f) && fgets (buff, sizeof buff, f) != NULL) { ++ext_lino; if (*buff != ':') continue; s = buff; while (*++s == ' ' || *s == '\t'); t = s; while (isalpha (*t)) ++t; *t = 0; if (t == s) { /* No verb given */ printf ("Error in actions file line %d, no verb given.", lino); continue; } verb = COPY (s); lowercase (verb); m_used = strlen (s) + 1; flags = 0; do { ++t; } while (*t != '\0' && !isalpha (*t)); while (isalpha (*t)) { switch (*t++) { case 'h': case 'H': flags |= EXTF_HOSTILE; break; case 'i': case 'I': flags |= EXTF_ALOOF; break; case 'a': case 'A': flags |= EXTF_ALL; break; case 's': case 'S': flags |= EXTF_SINGLE; break; case 'o': case 'O': flags |= EXTF_OBJ; break; case 't': case 'T': flags |= EXTF_TEXT; break; case 'f': case 'F': flags |= EXTF_FAR; break; } } if ((flags & EXTF_SINGLE) == 0) flags |= EXTF_ALL; low = ((flags & EXTF_ALL) != 0) ? EXT_MSG_ALL : EXT_MSG_TARGET; high = ((flags & EXTF_SINGLE) != 0) ? EXT_MSG_OTHERS : EXT_MSG_ME; ext_flags = 0; if ((flags & EXTF_OBJ) != 0) ext_flags |= EXT_O; for (i = EXT_MSG_ALL; i <= EXT_MSG_OTHERS;) msgs[i++] = NULL; for (i = low; i <= high; i++) { j = i; if ((flags & EXTF_TEXT) != 0) ext_flags |= EXT_M; s = ext_get_msg (&j, f, sizeof buff, low, high, &m_used); if (s == EXT_ERROR) break; if ((t = msgs[j]) != NULL) { mudlog ("ACTION: Double definition for msg for verb %s.\n", verb); ext_free_msg (t); } msgs[j] = s; } if (s == EXT_ERROR) { mudlog ("ACTION: Error in actions file for verb %s, error in messages.\n", verb); } else { s = NULL; if (low == EXT_MSG_ALL && (ext_flags & 0x03) != 0x03) { mudlog ("ACTION: Error in actions file for verb %s, missing ALL messages.\n", verb); s = EXT_ERROR; } else if (high == EXT_MSG_OTHERS && (ext_flags & 0x0c) != 0x0c) { mudlog ("ACTION: Error in actions file for verb %s, missing TARGET messages.\n", verb); s = EXT_ERROR; } } if (s == EXT_ERROR) { for (i = EXT_MSG_ALL; i <= EXT_MSG_OTHERS; i++) { if ((s = msgs[i]) != NULL) ext_free_msg (s); } free (verb); continue; } if ((ext_flags & 0x0c) == 0x0c) { this = (EXTERN_CMD_REC *) NEW (struct _ext2, 1); m_used += sizeof (struct _ext2); ((struct _ext2 *) this)->msg_to_target = msgs[EXT_MSG_TARGET]; ((struct _ext2 *) this)->msg_to_sender = msgs[EXT_MSG_SENDER]; ((struct _ext2 *) this)->msg_to_others = msgs[EXT_MSG_OTHERS]; } else { this = NEW (EXTERN_CMD_REC, 1); m_used += sizeof (EXTERN_CMD_REC); } this->next = NULL; this->flags = flags; this->verb = verb; this->msg_to_all = msgs[EXT_MSG_ALL]; this->msg_to_me = msgs[EXT_MSG_ME]; /* dump_action(this); */ if (first == NULL) { first = last = this; } else { last->next = this; last = this; } mem_used += m_used; } externs = first; return mem_used; } static char *ext_copy (char *b, char *m) { char *p; char v[50]; if (m == NULL || m == EXT_ERROR) { *b = 0; return b; } if (*m >= ' ' && *m <= '~') return x_strcpy (b, m); p = v; switch (((struct _ext_msg *) m)->code) { case EXT_STRING: p = ((struct _ext_msg1 *) m)->str; break; case EXT_TARGET: p = psex (pl1) ? ((struct _ext_msg2 *) m)->female_txt : ((struct _ext_msg2 *) m)->male_txt; break; case EXT_ACTOR: p = (psex (mynum) ? ((struct _ext_msg2 *) m)->female_txt : ((struct _ext_msg2 *) m)->male_txt); break; case EXT_TNAM: sprintf (p, "\001p%s\003", pname (pl1)); break; case EXT_ANAM: sprintf (p, "\001p%s\003", pname (mynum)); break; case EXT_THIM: p = psex (pl1) ? "her" : "him"; break; case EXT_AHIM: p = psex (mynum) ? "her" : "him"; break; case EXT_THIS: p = psex (pl1) ? "her" : "his"; break; case EXT_AHIS: p = psex (mynum) ? "her" : "his"; break; case EXT_ONAM: p = oname (ob2); break; case EXT_MTXT: p = "%s"; default: return b; } b = x_strcpy (b, p); return ext_copy (b, ((struct _ext_msg *) m)->next); } static char * build_act_msg (char *b, char *m) { if (m == NULL || m == EXT_ERROR) { *b = 0; return b; } if (*m >= ' ' && *m <= '~') return x_strcpy (b, m); switch (((struct _ext_msg *) m)->code) { case EXT_STRING: b = x_strcpy (b, ((struct _ext_msg1 *) m)->str); break; case EXT_TARGET: *b++ = '%'; *b++ = '<'; b = build_act_msg (b, ((struct _ext_msg2 *) m)->male_txt); *b++ = '%'; *b++ = ':'; b = build_act_msg (b, ((struct _ext_msg2 *) m)->female_txt); *b++ = '%'; *b++ = '>'; break; case EXT_ACTOR: *b++ = '%'; *b++ = '['; b = build_act_msg (b, ((struct _ext_msg2 *) m)->male_txt); *b++ = '%'; *b++ = '/'; b = build_act_msg (b, ((struct _ext_msg2 *) m)->female_txt); *b++ = '%'; *b++ = ']'; break; case EXT_TNAM: *b++ = '%'; *b++ = 't'; break; case EXT_ANAM: *b++ = '%'; *b++ = 'a'; break; case EXT_THIM: case EXT_AHIM: *b++ = '%'; *b++ = '~'; break; case EXT_THIS: case EXT_AHIS: *b++ = '%'; *b++ = '^'; break; case EXT_ONAM: *b++ = '%'; *b++ = 'o'; break; case EXT_MTXT: *b++ = '%'; *b++ = 'm'; break; default: return b; } *b = 0; return build_act_msg (b, ((struct _ext_msg *) m)->next); } static char * build_action (char *a) { static char b[256]; char *t; t = build_act_msg (b, a); *t = 0; return b; } /* * ** (C) Brian Preble (rassilon@eddie.mit.edu) * ** Handles external commands such as Kiss, Hug, Tickle, etc. * ** * ** Enhancements of Alf. */ int fextern (char *verb) { struct _ext *v; char *m; int p; int o; char b[MAX_COM_LEN]; char b2[MAX_COM_LEN]; char b3[MAX_COM_LEN]; v = externs; verb = strcpy (b, verb); o = -1; /* Stupid, parse_2, doesn't use vb, but we must give one */ if (!parse_2 (1)) return -1; for (; v != NULL; v = v->next) { if (!EQ (verb, v->verb)) continue; stp = 0; (void) brkword (); if ((v->flags & EXTF_ALL) == 0) { if (pl1 < 0) continue; p = pl1; brkword (); /* skip player */ if ((v->flags & EXTF_OBJ) != 0) { if (ob2 < 0) continue; o = ob2; brkword (); } } else if ((v->flags & EXTF_SINGLE) == 0) { p = -1; if ((v->flags & EXTF_OBJ) != 0) { if (ob1 < 0) continue; o = ob1; brkword (); /* Skip object */ } } else if ((p = pl1) < 0) { if ((v->flags & EXTF_OBJ) != 0) { if (ob1 < 0) continue; o = ob1; brkword (); } } else { brkword (); if ((v->flags & EXTF_OBJ) != 0) { if (ob2 < 0) continue; o = ob2; brkword (); } } if ((v->flags & EXTF_TEXT) != 0) { getreinput (b3); if (EMPTY (b3)) continue; } else { *b3 = '\0'; } ob2 = o; /* Now pl1 >= 0 if target, ob2 >= 0 if object and b3 is !EMPTY if txt */ /* Verb found */ if (pfighting (mynum) >= 0) { bprintf ("Not in a fight!\n"); return 0; } if (psitting(mynum) > 1 && plev(mynum) < LVL_APPREN) { bprintf("You're fantasizing in your dreams again eh?\n"); return 0; } if ((v->flags & EXTF_HOSTILE) != 0 && pl1 >= 0) { if (testpeace (mynum)) { bprintf ("Nah, that's violent.\n"); return 0; } } if (p < 0) { if (ob1 > 0 && obj_fun(ob1) != NULL) { param_s.ob = ob1; param_s.plx = mynum; param_s.pl = p; param_s.loc = ploc(mynum); param_s.ret = 1; param_s.buf = v->verb; obj_fun(ob1)(E_ONACTION); if (param_s.ret != 1) return param_s.ret; } (void) ext_copy (b, v->msg_to_all); sprintf (b2, b, b3); sprintf (b, "\001s%%s\003%s\n\003", b2); sillycom (b); (void) ext_copy (b, v->msg_to_me); sprintf (b2, b, b3); bprintf ("%s\n", b2); return 0; } if (pvis(p) > plev(real_mynum)) { bprintf("Good trick, that.\n"); return 0; } if ((v->flags & EXTF_FAR) == 0 && ploc (pl1) != ploc (mynum)) { bprintf ("%s is not here.\n", psex (pl1) ? "She" : "He"); return 0; } if (p == mynum) { bprintf ("Good trick, that.\n"); return 0; } if ((v->flags & EXTF_ALOOF) != 0 && ststflg (p, SFL_ALOOF) && plev (mynum) < LVL_APPREN) { bprintf ("%s thinks %s's too good for mere mortals.\n", pname (p), (psex (p) ? "she" : "he")); return 0; } if (mob_fun(p) != NULL) { param_s.plx = mynum; param_s.pl = p; param_s.buf = v->verb; param_s.ret = 1; param_s.loc = ploc(mynum); mob_fun(p)(E_ONACTION); if (param_s.ret != 1) return param_s.ret; } ext_copy (b2, ((struct _ext2 *) v)->msg_to_target); sprintf (b, b2, b3); m = b + strlen (b); strcpy (m, "\n"); send_msg (p, 0, LVL_MIN, LVL_MAX, NOBODY, NOBODY, b); if ((m = ((struct _ext2 *) v)->msg_to_others) != NULL) { ext_copy (b2, m); sprintf (b, b2, b3); send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, real_mynum, p, "%s\n", b); } ext_copy (b2, ((struct _ext2 *) v)->msg_to_sender); sprintf (b, b2, b3); bprintf ("%s\n", b); /* Hostile action? */ if ((v->flags & EXTF_HOSTILE) != 0 && p >= max_players) { hit_player (p, mynum, pwpn (p)); } return 0; } return -1; /* Command not found in extern list */ } /* * ** Displays list of external commands such as Kiss, Hug, Tickle, etc. */ /*int lisextern (void)*/ A_COMMAND(lisextern) { char line[80]; int i = -1; char **t; EXTERN_CMD_REC *v; FILE *fp; char fn[50]; if (brkword () != -1) { dump_act_vb (wordbuf); } else { sprintf(fn,"%s/%s.actions",TEMP_DIR,pname(mynum)); if ((fp = fopen(fn,"w")) != NULL) { fprintf(fp,"The following actions are defined:\n"); for (v = externs; v != NULL; v = v->next) { ++i; if (i % 9 == 0) fprintf (fp,"\n"); strcpy (line, v->verb); *line = toupper (*line); fprintf (fp,"%s\t", line); } for (t = s_ext; *t != TABLE_END; ++t) { ++i; if (i % 9 == 0) fprintf (fp,"\n"); fprintf (fp,"%s%c", *t, t[1] == TABLE_END ? '\n' : '\t'); } fprintf (fp,"\n"); fclose(fp); read_file(fn,NULL,True,NULL); unlink(fn); } else { fwerror(fn); bprintf ("Dumping directly to screen instead.\nThe following actions are defined:\n"); for (v = externs; v != NULL; v = v->next) { ++i; if (i % 9 == 0) bprintf ("\n"); strcpy (line, v->verb); *line = toupper (*line); bprintf ("%s\t", line); } for (t = s_ext; *t != TABLE_END; ++t) { ++i; if (i % 9 == 0) bprintf ("\n"); bprintf ("%s%c", *t, t[1] == TABLE_END ? '\n' : '\t'); } bprintf ("\n"); } } /* return 0;*/ }