/* general.m Subprogram to cheezmud. Copyright (C) 1995 David Flater. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "cheezmud.h" /* Find something. */ id global_find (char *name, int number) { return generic_find (world, name, number); } int global_number (char *name, id what) { return generic_number (world, name, what); } /* Support multiple cascaded finds. */ id generic_find_creturn (id wherein, char *name, int *number) { int i,m; BOOL flag = YES; id victim = NULL; /* Guard against underflow, or else some dork will crash the mud asking */ /* for the -maxint sword. */ if (*number <= 0) return NULL; for(i=0,m=[wherein size];(i<m) && flag;i++) { id whatever = [wherein at:i]; if (!strcmp ([whatever mudname], name)) { if (!(--(*number))) { flag = NO; victim = whatever; } } } return victim; } /* Find something. */ id generic_find (id wherein, char *name, int number) { return generic_find_creturn (wherein, name, &number); } /* This is kind of the opposite of generic_find. */ int generic_number (id wherein, char *name, id what) { int i,m,n = 0; BOOL flag = YES; for(i=0,m=[wherein size];(i<m) && flag;i++) { id whatever = [wherein at:i]; if (!strcmp ([whatever mudname], name)) { n++; if (what == whatever) flag = NO; } } if (flag == NO) return n; return 0; } /* Find something, preserving the count over two separate containers. */ id generic_find_cascade (id wherein1, id wherein2, char *name, int number) { id victim = NULL; victim = generic_find_creturn (wherein1, name, &number); if (victim) return victim; return generic_find_creturn (wherein2, name, &number); } int generic_number_cascade (id wherein1, id wherein2, char *name, id what) { int i,m,n = 0; BOOL flag = YES; for(i=0,m=[wherein1 size];(i<m) && flag;i++) { id whatever = [wherein1 at:i]; if (!strcmp ([whatever mudname], name)) { n++; if (what == whatever) flag = NO; } } if (flag == NO) return n; for(i=0,m=[wherein2 size];(i<m) && flag;i++) { id whatever = [wherein2 at:i]; if (!strcmp ([whatever mudname], name)) { n++; if (what == whatever) flag = NO; } } if (flag == NO) return n; return 0; } /* This assumes that t1 >= t2 and that they are not that far apart. Return */ /* value is in microseconds. */ long difftimeval (struct timeval *t1, struct timeval *t2) { return ((t1->tv_sec - t2->tv_sec) * 1000000 + t1->tv_usec) - t2->tv_usec; } /* Return number of microseconds since last heartbeat. */ /* As an auxilliary duty, this function stabilizes things if the system clock */ /* takes a flying leap. */ long timesincelastheartbeat () { struct timeval t; gettimeofday (&t, NULL); /* Has the clock run backwards? Is it way ahead of us (10 seconds)? */ if (((t.tv_sec < lastheartbeat.tv_sec) || (t.tv_sec == lastheartbeat.tv_sec && t.tv_usec < lastheartbeat.tv_usec)) || (t.tv_sec - lastheartbeat.tv_sec > 9)) { /* Arrrgh! Fix it! */ lastheartbeat.tv_sec = t.tv_sec; lastheartbeat.tv_usec = t.tv_usec; return 0; } return difftimeval (&t, &lastheartbeat); } char * capitalize (char *a) { static char b[80]; strcpy (b, a); if (b[0] >= 'a' && b[0] <= 'z') b[0] = b[0] - 'a' + 'A'; return b; } id get_random_member (id from) { id r = nil; BOOL flag = YES; int i,m,c, n; if (!(c = [from size])) return NULL; n = random() % c; for(i=0,m=[from size];(i<m) && flag;i++) { id whatever = [from at:i]; if (!(n--)) { flag = NO; r = whatever; } } return r; } /* This is preferable to cat_text_file since it will work for non-players. */ /* However, lines will be cut off at 1000 chars. */ void echo_text_file (id who, char *fname) { FILE *fp; if ((fp = fopen (fname, "r"))) { char buf[1000]; while (fgets (buf, 1000, fp)) [who echo: noeol (buf)]; fclose (fp); } } /* Save all players immediately. */ void checkpoint () { int i,m; for(i=0,m=[world size];i<m;i++) { id whatever = [world at:i]; if ([whatever isKindOf: [Player class]]) [whatever save]; } }