/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~ Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, ~
~ Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. ~
~ ~
~ Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael ~
~ Chastain, Michael Quan, and Mitchell Tse. ~
~ ~
~ Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley ~
~ ACK!MUD is modified Merc2.0/2.1/2.2 code (c)Stephen Zepp 1998 Ver: 4.3 ~
~ ~
~ In order to use any part of this PA Diku Mud, you must comply with ~
~ both the original Diku license in 'license.doc' as well the Merc ~
~ license in 'license.txt', and the Ack!Mud license in 'ack_license.txt'.~
~ In particular, you may not remove any of these copyright notices. ~
~ ~
~ _______ _____ ~
~ / __ /\ / ___ \ 222222 PA_MUD by Amnon Kruvi ~
~ /______/ / / /___\ \ 2 PA_MUD is modified ~
~ / _______/ / _______ \ 2 Ack!Mud, v4.3 ~
~ /_/ /_/ \_\ 2 ~
~ 2 ~
~ 2222222 ~
~ ~
~ ~
~ Years of work have been invested to create DIKU, Merc, Ack and PA. ~
~ Please show your respect by following the licenses, and issuing ~
~ credits where due. ~
~ ~
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-*/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
/* For forks etc. */
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#ifndef DEC_ACK_H
#include "ack.h"
#include "tables.h"
#endif
#ifndef DEC_STRFUNS_H
#include "strfuns.h"
#endif
void pre_parse( char * list, char * victimname, char * containername, char * things )
{
char arg1[MSL];
char container_name[MSL];
char one_object[MSL];
char holdbuf[MSL];
char victim_name[MSL];
char object_list[MSL];
char * argument = list;
container_name[0] = '\0';
victim_name[0] = '\0';
object_list[0] = '\0';
for ( ; ; )
{
argument = one_argument( argument, arg1 );
if ( arg1[0] == '\0' )
break;
if ( ( !str_cmp( "from", arg1 ) )
|| ( !str_cmp( "in", arg1 ) ) )
{
argument = one_argument( argument, container_name );
}
else if ( !str_cmp( "to", arg1 ) )
{
argument = one_argument( argument, victim_name );
}
else if ( object_list[0] != '\0' )
{
safe_strcat(MSL,victim_name,arg1);
}
else
{
if ( is_number( arg1 ) )
{
argument = one_argument( argument, one_object );
sprintf( holdbuf, "%s %s ", arg1, one_object );
safe_strcat( MSL, object_list, holdbuf );
}
else
{
sprintf( holdbuf, "1 %s ", arg1 );
safe_strcat( MSL, object_list, holdbuf );
}
}
}
// strcpy( victimname , argument );
strcpy( victimname , victim_name );
strcpy( things,object_list);
strcpy( containername , container_name);
return;
}
/*
* Return true if an argument is completely numeric.
*/
bool is_number( char *arg )
{
if ( *arg == '\0' )
return FALSE;
if ( *arg == '+' || *arg == '-' )
arg++;
for ( ; *arg != '\0'; arg++ )
{
if ( !isdigit(*arg) )
return FALSE;
}
return TRUE;
}
bool is_name( const char *str, char *namelist )
{
char name[MAX_INPUT_LENGTH];
for ( ; ; )
{
namelist = one_argument( namelist, name );
if ( name[0] == '\0' )
return FALSE;
if ( !str_prefix( str, name ) )
return TRUE;
}
}
void safe_strcat(int max_len,char * dest,char * source)
{
int a;
char c;
char * orig_dest;
char * orig_source;
if (dest == NULL && source == NULL)
return;
if (dest == NULL)
{
fprintf(stderr,"safe_strcat: Null dest string for source : %s\n",source);
return;
}
if (source == NULL)
{
fprintf(stderr,"safe_strcat: NULL source for dest : %s\n",dest);
return;
}
orig_dest=dest;
orig_source=source;
while (*dest !='\0') /* Check to see if dest is already over limit. */
dest++;
a=dest-orig_dest;
if ( a > max_len )
{
fprintf(stderr,"WARNING: dest string already too long:\nsource: %s\ndest: %s\n",source,orig_dest);
return;
}
if ( a == max_len )
{
fprintf(stderr,"safe_strcat: string too long, source is : %s\n",orig_source);
return;
}
while ( (c = *(source++)) != 0 )
{
*(dest++)=c;
a++;
if ( a == max_len )
{
*(--dest)='\0';
fprintf(stderr,"safe_strcat: string too long, source is : %s\n",orig_source);
return;
}
}
*dest='\0';
return;
}
char * space_pad( const char * str, sh_int final_size )
{
sh_int space_pad = my_strlen( str );
static char padbuf[MSL];
sprintf( padbuf, "%s", str );
for ( ; space_pad != final_size ; space_pad++ )
safe_strcat( MSL, padbuf, " " );
return padbuf;
}
/*
* Removes the tildes from a string.
* Used for player-entered strings that go into disk files.
*/
void smash_tilde( char *str )
{
for ( ; *str != '\0'; str++ )
{
if ( *str == '~' )
*str = '-';
}
return;
}
void smash_system( char *str )
{
for ( ; *str != '\0'; str++ )
{
if ( *str == '%' )
*str = '*';
}
return;
}
char *smash_swear( char *str )
{
int i;
for ( i = 0; str[i] != '\0'; i++ )
{
if ( ( str[i] == 'f' || str[i] == 'F' )
&& ( str[i+1] == 'u' || str[i+1] == 'U' )
&& ( str[i+2] == 'c' || str[i+2] == 'C' )
&& ( str[i+3] == 'k' || str[i+3] == 'K' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
str[i +3] = '*';
i += 3;
}
if ( ( str[i] == 's' || str[i] == 'S' )
&& ( str[i+1] == 'h' || str[i+1] == 'H' )
&& ( str[i+2] == 'i' || str[i+2] == 'I' )
&& ( str[i+3] == 't' || str[i+3] == 'T' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
str[i +3] = '*';
i += 3;
}
if ( ( str[i] == 'c' || str[i] == 'C' )
&& ( str[i+1] == 'u' || str[i+1] == 'U' )
&& ( str[i+2] == 'n' || str[i+2] == 'N' )
&& ( str[i+3] == 't' || str[i+3] == 'T' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
str[i +3] = '*';
i += 3;
}
if ( ( str[i] == 'p' || str[i] == 'P' )
&& ( str[i+1] == 'e' || str[i+1] == 'E' )
&& ( str[i+2] == 'n' || str[i+2] == 'N' )
&& ( str[i+3] == 'i' || str[i+3] == 'I' )
&& ( str[i+4] == 's' || str[i+4] == 'S' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
str[i +3] = '*';
str[i +4] = '*';
i += 4;
}
if ( ( str[i] == 'd' || str[i] == 'D' )
&& ( str[i+1] == 'i' || str[i+1] == 'I' )
&& ( str[i+2] == 'c' || str[i+2] == 'C' )
&& ( str[i+3] == 'k' || str[i+3] == 'K' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
str[i +3] = '*';
i += 3;
}
if ( ( str[i] == 'c' || str[i] == 'C' )
&& ( str[i+1] == 'o' || str[i+1] == 'O' )
&& ( str[i+2] == 'c' || str[i+2] == 'C' )
&& ( str[i+3] == 'k' || str[i+3] == 'K' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
str[i +3] = '*';
i += 3;
}
if ( ( str[i] == 'f' || str[i] == 'F' )
&& ( str[i+1] == 'a' || str[i+1] == 'A' )
&& ( str[i+2] == 'g' || str[i+2] == 'G' ) )
{
str[i] = '*';
str[i +1] = '*';
str[i +2] = '*';
i += 2;
}
if ( ( str[i] == 'b' || str[i] == 'B' )
&& ( str[i+1] == 'i' || str[i+1] == 'I' )
&& ( str[i+2] == 't' || str[i+2] == 'T' )
&& ( str[i+3] == 'c' || str[i+3] == 'C' )
&& ( str[i+4] == 'h' || str[i+4] == 'H' ) )
{
str[i] = '*';
str[i+1] = '*';
str[i+2] = '*';
str[i+3] = '*';
str[i+4] = '*';
i +=4;
}
}
return str;
}
/*
* Compare strings, case insensitive.
* Return TRUE if different
* (compatibility with historical functions).
*/
bool str_cmp( const char *astr, const char *bstr )
{
int count = 0;
bool notrunc = FALSE;
if ( astr == NULL )
return TRUE;
if ( bstr == NULL )
return TRUE;
if ( *astr == '^' )
{
notrunc = TRUE;
astr++;
}
if ( *bstr == '^' )
{
notrunc = TRUE;
bstr++;
}
if ( astr == NULL )
{
/* bug( "Str_cmp: null astr.", 0 ); */
return TRUE;
}
if ( bstr == NULL )
{
return TRUE;
}
for ( ; *astr || *bstr; astr++, bstr++ )
{
if ( !notrunc )
if ( *astr == '*' && count )
return FALSE;
if ( LOWER(*astr) != LOWER(*bstr) )
return TRUE;
count++;
}
return FALSE;
}
/*
* Compare strings, case insensitive, for prefix matching.
* Return TRUE if astr not a prefix of bstr
* (compatibility with historical functions).
*/
bool str_prefix( const char *astr, const char *bstr )
{
if ( astr == NULL )
{
bug( "Strn_cmp: null astr.", 0 );
return TRUE;
}
if ( bstr == NULL )
{
bug( "Strn_cmp: null bstr.", 0 );
return TRUE;
}
for ( ; *astr; astr++, bstr++ )
{
if ( LOWER(*astr) != LOWER(*bstr) )
return TRUE;
}
return FALSE;
}
/*
* Compare strings, case insensitive, for match anywhere.
* Returns TRUE is astr not part of bstr.
* (compatibility with historical functions).
*/
bool str_infix( const char *astr, const char *bstr )
{
int sstr1;
int sstr2;
int ichar;
char c0;
if ( ( c0 = LOWER(astr[0]) ) == '\0' )
return FALSE;
sstr1 = strlen(astr);
sstr2 = strlen(bstr);
for ( ichar = 0; ichar <= sstr2 - sstr1; ichar++ )
{
if ( c0 == LOWER(bstr[ichar]) && !str_prefix( astr, bstr + ichar ) )
return FALSE;
}
return TRUE;
}
/*
* Compare strings, case insensitive, for suffix matching.
* Return TRUE if astr not a suffix of bstr
* (compatibility with historical functions).
*/
bool str_suffix( const char *astr, const char *bstr )
{
int sstr1;
int sstr2;
sstr1 = strlen(astr);
sstr2 = strlen(bstr);
if ( sstr1 <= sstr2 && !str_cmp( astr, bstr + sstr2 - sstr1 ) )
return FALSE;
else
return TRUE;
}
/*
* Returns an initial-capped string.
*/
#if 0
char *capitalize( const char *str )
{
static char strcap[MAX_STRING_LENGTH];
int i;
for ( i = 0; str[i] != '\0'; i++ )
{
if ( ( str[i] == '@' )
&& ( str[i+1] == '@' )
&& ( str[i+2] != '\0' ) )
{
strcap[i] = str[i];
strcap[i +1] = str[i+1];
strcap[i +2] = str[i+2];
i += 2;
}
else
strcap[i] = LOWER(str[i]);
}
strcap[i] = '\0';
for ( i = 0; strcap[i] != '\0' && !isalpha( strcap[i] ); i++ );
if ( ( i > 0 )
&& ( strcap[i] != '\0' ) )
i++;
if ( strcap[i] != '\0' )
strcap[i] = UPPER(strcap[i]);
return strcap;
}
#endif
/* Capitalize function by KaVir: 3th December 1997.
*
* Pass in a pointer to the string to capitalize. The function will return
* a pointer to the corrected string, however for safety purposes the original
* pointer will also be set to point to the new string. Thus if you do:
* char *normal_string = "a piece of text";
* char *cap_string = capitalize( normal_string );
* Then both cap_string and normal_string will contain the capitalized string.
*
* The precise rules of capitalization are as follows:
* 1) The first non-colorcode alphabetic character will be uppercase.
* 2) Any alphabetic character following two or more @'s will be unchanged.
* 3) Any other alphabetic character will be set to lowercase.
* 4) Any other non-alphabetic characters will be ignored.
*/
char *capitalize( const char *str )
{
static char strcap[MAX_STRING_LENGTH]; /* Permanent store */
/* char *oldstr = str; */
int i = 0; /* Position in strcap */
int count = 0; /* Number of previous '@'s encountered */
bool first_letter = TRUE; /* You will UPPER the first letter you find */
bool ignore_next = FALSE; /* Ignore the case of the next letter you find */
/* If this occurs, then you have a bug elsewhere */
if ( ( strcap[i] = *str ) == '\0' )
return NULL;
do /* Begin looping through the string, checking each character */
{
/* Should be more efficient than all those 'if' statements ;) */
switch ( strcap[i] )
{
default: /* Non-alphabetic letters and not '@' */
ignore_next = FALSE; /* Not a color code */
count = 0;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z': /* Any lowercase letter */
if ( ignore_next )
ignore_next = FALSE; /* We ignore the case of the this letter */
else if ( first_letter )
{
first_letter = FALSE; /* Reset the flag */
strcap[i] = UPPER(strcap[i]); /* We set this letter to uppercase */
}
count = 0;
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z': /* Any uppercase letter */
/* Then its the first letter in the string */
if ( ignore_next )
ignore_next = FALSE; /* We ignore the case of the this letter */
else if ( first_letter )
first_letter = FALSE; /* We ignore the case of the this letter */
else
strcap[i] = LOWER(strcap[i]); /* Set this letter to lowercase */
count = 0;
break;
case '@':
if ( ++count >= 2 ) /* If there are two or more '@@'s in a row */
ignore_next = TRUE; /* Set the flag to ignore the next letter */
break;
}
} while ( ( strcap[++i] = *++str ) != '\0' ); /* loop until end of string */
i = 0; /* str = oldstr; Reset variables */
#if 0
/* Copy strcap back into the old string */
while ( ( *str++ = strcap[i++] ) != '\0' )
;
return ( oldstr ); /* Return pointer to start of old string */
#endif
return ( strcap );
}
/*
* We need a replacement for strlen() which will take the color
* codes into account when reporting a string's length.
* -- Stephen
*/
int my_strlen( const char *text )
{
char c;
int i;
int status;
int length;
int strlen_size;
status = 0;
length = 0;
strlen_size = strlen( text );
for ( i = 0; i < strlen_size; i++ )
{
c = text[i];
length++;
switch( status )
{
case 0:
case 1:
if ( c == '@' )
status++;
else
status = 0;
break;
case 2:
if ( c == '@' )
length -= 2;
else
length -= 3; /* Subtract for '@@x' */
status = 0;
break;
}
}
return( length );
}
int nocol_strlen( const char *text )
{
char c;
int i;
int status;
int length;
int strlen_size;
status = 0;
length = 0;
strlen_size = strlen( text );
for ( i = 0; i < strlen_size; i++ )
{
c = text[i];
length++;
switch( status )
{
case 0:
case 1:
if ( c == '@' )
status++;
else
status = 0;
break;
case 2:
length -= 3; /* Subtract for '@@x' */
status=0;
break;
}
}
return( length );
}
int ccode_len( const char *text, sh_int desired )
{
char c;
int i;
int status;
int length;
int strlen_size;
status = 0;
length = 0;
strlen_size = strlen( text );
for ( i = 0; i < strlen_size; i++ )
{
c = text[i];
switch( status )
{
case 0:
case 1:
if ( c == '@' )
status++;
else
status = 0;
break;
case 2:
if ( c != '@' )
length += 3; /* Subtract for '@@x' */
status=0;
break;
}
}
return( length + desired );
}
/* END NOTE */
/* A Function to "center" text, and return a string with
* the required amount of white space either side of the
* original text. --Stephen
*/
char *center_text( char *text, int width )
{
/* This could do with a LOT of improvement sometime! */
/* Improvements done.. -- Altrag */
static char foo[MAX_STRING_LENGTH];
int len, diff;
/* Don't bother with strings too long.. */
if ( (len = my_strlen(text)) >= width )
return text;
diff = strlen(text)-len;
/* Add the spaces and terminate string */
memset(foo, ' ', width+diff);
foo[width+diff] = '\0';
/* Copy old string over */
memcpy(&foo[(width-len)/2], text, len+diff);
return foo;
}
char * str_mod( char * mod_string, char *argument )
{
char arg1 [ MAX_INPUT_LENGTH ];
char buf [ MAX_STRING_LENGTH ];
char *buf2;
char *buf3 = NULL;
char *word;
char temp[MSL];
int i = 0;
bool multiple = FALSE;
if ( !str_cmp( argument, "" ) )
{
sprintf( bug_buf, "Unknown reason for return, argument is -%s-", argument );
monitor_chan( NULL, bug_buf, MONITOR_DEBUG );
return mod_string;
}
if ( argument[0] == '+' || argument[0] == '-' )
{
buf[0] = '\0';
smash_tilde( argument );
if ( argument[0] == '+' )
{
argument++;
if ( mod_string )
safe_strcat( MSL, buf, mod_string );
while ( isspace( *argument ) )
argument++;
if ( !str_infix( argument, mod_string ) )
{
return mod_string;
}
safe_strcat( MSL, buf, argument );
safe_strcat( MSL, buf, " " );
}
if ( argument[0] == '-' )
{
argument++;
if ( argument[0] == '\'' )
multiple = TRUE;
one_argument( argument, arg1 );
if ( multiple )
{
sprintf( temp, "\'%s\'", arg1 );
sprintf( arg1, "%s", temp );
}
if ( arg1 )
{
buf2 = str_dup( mod_string );
buf3 = buf2;
if ( (word = strstr( buf2, arg1 ) ) == NULL )
{
free_string( buf2 );
return mod_string;
}
else
{
while ( buf2 != word )
buf[i++] = *(buf2++);
while ( ( !isspace ( *(buf2++) ) )
|| ( ( multiple )
&& ( ( buf2[0] != '\'' )
&& ( buf2[0] != '\0' ) ) ) );
buf[i] = '\0';
safe_strcat ( MSL, buf, buf2 );
}
}
}
free_string( buf3 );
word = buf2 = buf3 = NULL;
free_string( mod_string );
mod_string = str_dup( buf );
}
return mod_string;
}
void rand_arg( char *argument, char *output )
{
char temp[MSL];
sh_int counter = 0;
argument = one_argument( argument, temp );
while ( temp[0] )
{
if (number_range(0, counter)==0)
strcpy (output, temp);
counter++;
argument = one_argument( argument, temp );
}
}
/*
* Given a string like 14.foo, return 14 and 'foo'
*/
int number_argument( char *argument, char *arg )
{
char *pdot;
int number;
for ( pdot = argument; *pdot != '\0'; pdot++ )
{
if ( *pdot == '.' )
{
*pdot = '\0';
number = atoi( argument );
*pdot = '.';
strcpy( arg, pdot+1 );
return number;
}
}
strcpy( arg, argument );
return 1;
}
/*
* Pick off one argument from a string and return the rest.
* Understands quotes.
*/
char *one_argument( char *argument, char *arg_first )
{
char cEnd;
// char buf[MSL];
if ( argument == NULL )
return NULL;
while ( isspace(*argument) )
argument++;
cEnd = ' ';
if ( *argument == '\'' || *argument == '"' )
cEnd = *argument++;
while ( *argument != '\0' )
{
if ( *argument == cEnd )
{
argument++;
break;
}
*arg_first = LOWER(*argument);
arg_first++;
argument++;
}
*arg_first = '\0';
while ( isspace(*argument) )
argument++;
return argument;
}
/*
* Pick off one argument from a string and return the rest.
* Understands quotes.
*/
char *one_word( char *argument, char *arg_first )
{
char cEnd;
if ( argument == NULL )
return NULL;
while ( isspace(*argument) )
argument++;
cEnd = ' ';
if ( *argument == '\'' || *argument == '"' )
cEnd = *argument++;
while ( *argument != '\0' )
{
if ( *argument == cEnd )
{
argument++;
break;
}
*arg_first = (*argument);
arg_first++;
argument++;
}
*arg_first = '\0';
while ( isspace(*argument) )
argument++;
return argument;
}
char *two_args( char *argument, char *arg_first, char *arg_second )
{
char *temp_arg = argument;
temp_arg = one_argument( temp_arg, arg_first );
temp_arg = one_argument( temp_arg, arg_second );
return temp_arg;
}
char *strip_out(const char *orig, const char *strip)
{
static char buf[MAX_STRING_LENGTH];
char *i, *b = buf;
int slen;
if (!orig || !strip)
{
/* log_f("strip_out called with NULL param"); */
return "!!OUT!!";
}
slen = strlen(strip);
for (i = strstr(orig, strip); i; i = strstr(orig, strip))
{
strncpy(b, orig, (i-orig));
b += i-orig;
orig = i+slen;
}
strcpy(b, orig);
return buf;
}
/* this code donated by Altrag */
char *strip_color(const char *orig, const char *strip)
{
static char buf[MAX_STRING_LENGTH];
char *i, *b = buf;
int slen;
if (!orig || !strip)
{
/* log_f("strip_out called with NULL param"); */
return "!!OUT!!";
}
slen = strlen(strip)+1;
for (i = strstr(orig, strip); i; i = strstr(orig, strip))
{
strncpy(b, orig, (i-orig));
b += i-orig;
orig = i+slen;
}
strcpy(b, orig);
return buf;
}
bool list_in_list( char * first_list, char * second_list )
{
char check_word[MAX_INPUT_LENGTH];
char against_word[MSL];
char * checklist;
char * againstlist;
checklist = first_list ;
againstlist = second_list;
for ( ; ; )
{
checklist = one_argument( checklist, check_word );
againstlist = second_list;
if ( check_word[0] == '\0' )
{
return FALSE;
}
for ( ; ; )
{
againstlist = one_argument( againstlist, against_word );
if ( against_word[0] == '\0' )
break;
if ( !str_cmp( check_word, against_word ) )
{
return TRUE;
}
}
}
}
/*
* Return ascii name of an item type.
*/
char *item_type_name( OBJ_DATA *obj )
{
char log[MAX_STRING_LENGTH];
switch ( obj->item_type )
{
case ITEM_LIGHT: return "light";
case ITEM_AMMO: return "ammo";
case ITEM_BOMB: return "bomb";
case ITEM_BLUEPRINT: return "blueprint";
case ITEM_SUIT: return "suit";
case ITEM_MEDPACK: return "medpack";
case ITEM_WEAPON: return "weapon";
case ITEM_DRONE: return "drone";
case ITEM_ARMOR: return "armor";
case ITEM_POTION: return "potion";
case ITEM_TELEPORTER: return "teleporter";
case ITEM_BOARD: return "bulletin board";
case ITEM_INSTALLATION: return "installation";
case ITEM_TOKEN: return "token";
case ITEM_FLAG: return "flag";
case ITEM_DART_BOARD: return "dart board";
case ITEM_CONTAINER: return "container";
case ITEM_WEAPON_UP: return "weapon upgrade";
case ITEM_PIECE: return "piece";
case ITEM_COMPUTER: return "computer";
case ITEM_LOCATOR: return "item locator";
case ITEM_SKILL_UP: return "skill upgrade";
case ITEM_DISK: return "disk";
case ITEM_TRASH: return "trash";
case ITEM_ASTEROID: return "asteroid";
case ITEM_VEHICLE_UP: return "vehicle addon";
case ITEM_TOOLKIT: return "toolkit";
case ITEM_SCAFFOLD: return "scaffold";
case ITEM_ORE: return "ore";
case ITEM_BIOTUNNEL: return "Bio Tunnel";
case ITEM_BATTERY: return "battery";
}
sprintf( log, "Item_type_name: Object: %d. Unknown Type: %d",
obj->pIndexData->vnum, obj->item_type );
monitor_chan( NULL, log, MONITOR_OBJ );
bug( log, 0 );
return "(unknown)";
}
char *item_type_desc( int type )
{
switch ( type )
{
case ITEM_LIGHT: return "(unknown)";
case ITEM_AMMO: return "Ammo can be LOADed into weapons, so they can fire after they run out.";
case ITEM_BOMB: return "Bombs are dangerous tools of destruction - Just SET them, ARM them, and RUN AWAY!";
case ITEM_BLUEPRINT: return "Blueprints are used to upgrade buildings. They can only upgrade buildings by 1 level at a time.";
case ITEM_SUIT: return "Suits are used with the ACTIVATE command, suits can have special functions such as teleportation.";
case ITEM_MEDPACK: return "Medpacks are used with the HEAL command, they can cure your wounds when you use them.";
case ITEM_WEAPON: return "Weapons are the basic attack items - Wield/wear one, then FIRE or SHOOT at your enemies.";
case ITEM_DRONE: return "Just drop them, and they'll do their job. Repair drones, for example, fix damaged buildings.";
case ITEM_ARMOR: return "Armor can protect you from hits - Each armor type protects against a different damage type.";
case ITEM_POTION: return "Generates a special effect to anyone who drinks it.";
case ITEM_TELEPORTER: return "A Teleporter is used to take you back to one of your controlled buildings, in a certain radius.";
case ITEM_BOARD: return "Boards are found in players' HQs and Government Centers (alliance boards). You can READ and WRITE messages on them!";
case ITEM_INSTALLATION: return "You can INSTALL these into buildings, each giving a different effect.";
case ITEM_TOKEN: return "Tokens give players quest points when they are picked up.";
case ITEM_FLAG: return "Flags you get for destroying a player's base. You can save them at the lodge as trophies!";
case ITEM_DART_BOARD: return "You can play Darts in a hunting lodge, and this is what you play with.";
case ITEM_CONTAINER: return "Containers are what you put elements in before you can mix them.";
case ITEM_WEAPON_UP: return "Weapon Upgrades can be WINSTALLed into weapons to give them special effects.";
case ITEM_PIECE: return "Piece items can be combined together to create new items.";
case ITEM_COMPUTER: return "Computers can be used to upload viruses to enemy buildings and track players down.";
case ITEM_LOCATOR: return "An item locator will scan the surroundings for items, letting you know whether you're close to an enemy base.";
case ITEM_SKILL_UP: return "Skill Upgrades are used to instantly increase your skill at a certain action.";
case ITEM_DISK: return "A disk containing software such as password crackers or viruses.";
case ITEM_TRASH: return "Useless junk.";
case ITEM_ASTEROID: return "Asteroids can be mined for metals in space, and might hold some hidden items within.";
case ITEM_VEHICLE_UP: return "Vehicle addons add special features to vehicles (increased range, scanner, etc).";
case ITEM_TOOLKIT: return "Toolkits are used by engineers to upgrade vehicles.";
case ITEM_SCAFFOLD: return "Creates the layout for a new building.";
case ITEM_ORE: return "Research these to produce new items!";
case ITEM_BIOTUNNEL: return "Transport all the items in the room to a receiving tunnel.";
}
return "(unknown)";
}
/*
* Return ascii name of extra flags vector.
*/
char *extra_bit_name( int extra_flags )
{
static char buf[512];
buf[0] = '\0';
if ( extra_flags & ITEM_INVIS ) safe_strcat( MAX_STRING_LENGTH, buf, " invis" );
if ( extra_flags & ITEM_NODROP ) safe_strcat( MAX_STRING_LENGTH, buf, " nodrop" );
if ( extra_flags & ITEM_NOREMOVE ) safe_strcat( MAX_STRING_LENGTH, buf, " noremove" );
if ( extra_flags & ITEM_NOSAVE ) safe_strcat( MAX_STRING_LENGTH, buf, " nosave" );
if ( extra_flags & ITEM_RARE ) safe_strcat( MAX_STRING_LENGTH, buf, " rare" );
if ( extra_flags & ITEM_UNIQUE ) safe_strcat( MAX_STRING_LENGTH, buf, " unique" );
return ( buf[0] != '\0' ) ? buf+1 : "none";
}