?? db.c
字號:
if ( iList == MAX_MEM_LIST )
{
bug( "Free_mem: size %d too large.", sMem );
exit( 1 );
}
pMem = memset( pMem, 0, sMem );
* ((void **) pMem) = rgFreeList[iList];
rgFreeList[iList] = pMem;
return;
#endif
}
/*
* Allocate some permanent memory.
* Permanent memory is never freed,
* pointers into it may be copied safely.
*/
void *alloc_perm( int sMem )
{
static char *pMemPerm;
static int iMemPerm;
void *pMem;
while ( sMem % sizeof(long) != 0 )
sMem++;
if ( sMem > MAX_PERM_BLOCK )
{
bug( "Alloc_perm: %d too large.", sMem );
exit( 1 );
}
if ( pMemPerm == NULL || iMemPerm + sMem > MAX_PERM_BLOCK )
{
iMemPerm = 0;
if ( ( pMemPerm = calloc( 1, MAX_PERM_BLOCK ) ) == NULL )
{
perror( "Alloc_perm" );
exit( 1 );
}
}
pMem = pMemPerm + iMemPerm;
iMemPerm += sMem;
nAllocPerm += 1;
sAllocPerm += sMem;
return pMem;
}
/*
* Duplicate a string into dynamic memory.
* Fread_strings are read-only and shared.
*/
char *str_dup( const char *str )
{
char *str_new;
#if 1 // %%%
if ( str[0] == '\0' )
return &str_empty[0];
if ( str >= string_space && str < top_string )
return (char *) str;
#endif
str_new = alloc_mem( strlen(str) + 1 );
strcpy( str_new, str );
return str_new;
}
/*
* Free a string.
* Null is legal here to simplify callers.
* Read-only shared strings are not touched.
*/
void free_string( char *pstr )
{
if ( pstr == NULL
|| pstr == &str_empty[0]
|| ( pstr >= string_space && pstr < top_string ) )
return;
free_mem( pstr, strlen(pstr) + 1 );
return;
}
//#if 0
void do_areas( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
AREA_DATA *pArea1;
AREA_DATA *pArea2;
int iArea;
int iAreaHalf;
iAreaHalf = (top_area + 1) / 2;
pArea1 = area_first;
pArea2 = area_first;
for ( iArea = 0; iArea < iAreaHalf; iArea++ )
pArea2 = pArea2->next;
for ( iArea = 0; iArea < iAreaHalf; iArea++ )
{
sprintf( buf, "%-39s%-39s\n\r",
pArea1->name, (pArea2 != NULL) ? pArea2->name : "" );
send_to_char( buf, ch );
pArea1 = pArea1->next;
if ( pArea2 != NULL )
pArea2 = pArea2->next;
}
return;
}
void do_memory( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "Affects %5d\n\r", top_affect ); send_to_char( buf, ch );
sprintf( buf, "Areas %5d\n\r", top_area ); send_to_char( buf, ch );
sprintf( buf, "ExDes %5d\n\r", top_ed ); send_to_char( buf, ch );
sprintf( buf, "Exits %5d\n\r", top_exit ); send_to_char( buf, ch );
sprintf( buf, "Helps %5d\n\r", top_help ); send_to_char( buf, ch );
sprintf( buf, "Mobs %5d\n\r", top_mob_index ); send_to_char( buf, ch );
sprintf( buf, "Objs %5d\n\r", top_obj_index ); send_to_char( buf, ch );
sprintf( buf, "Resets %5d\n\r", top_reset ); send_to_char( buf, ch );
sprintf( buf, "Rooms %5d\n\r", top_room ); send_to_char( buf, ch );
sprintf( buf, "Shops %5d\n\r", top_shop ); send_to_char( buf, ch );
sprintf( buf, "Strings %5d strings of %7d bytes (max %d).\n\r",
nAllocString, sAllocString, MAX_STRING );
send_to_char( buf, ch );
sprintf( buf, "Perms %5d blocks of %7d bytes.\n\r",
nAllocPerm, sAllocPerm );
send_to_char( buf, ch );
return;
}
//#endif
/*
* Stick a little fuzz on a number.
*/
int number_fuzzy( int number )
{
switch ( number_bits( 2 ) )
{
case 0: number -= 1; break;
case 3: number += 1; break;
}
return UMAX( 1, number );
}
/*
* Generate a random number.
*/
int number_range( int from, int to )
{
int power;
int number;
if ( ( to = to - from + 1 ) <= 1 )
return from;
for ( power = 2; power < to; power <<= 1 )
;
while ( ( number = number_mm( ) & (power - 1) ) >= to )
;
return from + number;
}
/*
* Generate a percentile roll.
*/
int number_percent( void )
{
int percent;
while ( ( percent = number_mm( ) & (128-1) ) > 99 )
;
return 1 + percent;
}
/*
* Generate a random door.
*/
int number_door( void )
{
int door;
while ( ( door = number_mm( ) & (8-1) ) > 5 )
;
return door;
}
int number_bits( int width )
{
return number_mm( ) & ( ( 1 << width ) - 1 );
}
/*
* I've gotten too many bad reports on OS-supplied random number generators.
* This is the Mitchell-Moore algorithm from Knuth Volume II.
* Best to leave the constants alone unless you've read Knuth.
* -- Furey
*/
static int rgiState[2+55];
void init_mm( )
{
int *piState;
int iState;
piState = &rgiState[2];
piState[-2] = 55 - 55;
piState[-1] = 55 - 24;
piState[0] = ((int) current_time) & ((1 << 30) - 1);
piState[1] = 1;
for ( iState = 2; iState < 55; iState++ )
{
piState[iState] = (piState[iState-1] + piState[iState-2])
& ((1 << 30) - 1);
}
return;
}
int number_mm( void )
{
int *piState;
int iState1;
int iState2;
int iRand;
piState = &rgiState[2];
iState1 = piState[-2];
iState2 = piState[-1];
iRand = (piState[iState1] + piState[iState2])
& ((1 << 30) - 1);
piState[iState1] = iRand;
if ( ++iState1 == 55 )
iState1 = 0;
if ( ++iState2 == 55 )
iState2 = 0;
piState[-2] = iState1;
piState[-1] = iState2;
return iRand >> 6;
}
/*
* Roll some dice.
*/
int dice( int number, int size )
{
int idice;
int sum;
switch ( size )
{
case 0: return 0;
case 1: return number;
}
for ( idice = 0, sum = 0; idice < number; idice++ )
sum += number_range( 1, size );
return sum;
}
/*
* Simple linear interpolation.
*/
int interpolate( int level, int value_00, int value_32 )
{
return value_00 + level * (value_32 - value_00) / 32;
}
/*
* 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;
}
/*
* Compare strings, case insensitive.
* Return TRUE if different
* (compatibility with historical functions).
*/
bool str_cmp( const char *astr, const char *bstr )
{
if ( astr == NULL )
{
bug( "Str_cmp: null astr.", 0 );
return TRUE;
}
if ( bstr == NULL )
{
bug( "Str_cmp: null bstr.", 0 );
return TRUE;
}
for ( ; *astr || *bstr; astr++, bstr++ )
{
if ( LOWER(*astr) != LOWER(*bstr) )
return TRUE;
}
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.
*/
char *capitalize( const char *str )
{
static char strcap[MAX_STRING_LENGTH];
int i;
for ( i = 0; str[i] != '\0'; i++ )
strcap[i] = LOWER(str[i]);
strcap[i] = '\0';
strcap[0] = UPPER(strcap[0]);
return strcap;
}
/*
* Append a string to a file.
*/
void append_file( CHAR_DATA *ch, char *file, char *str )
{
FILE *fp;
if ( IS_NPC(ch) || str[0] == '\0' )
return;
fclose( fpReserve );
if ( ( fp = fopen( file, "a" ) ) == NULL )
{
perror( file );
send_to_char( "Could not open the file!\n\r", ch );
}
else
{
fprintf( fp, "[%5d] %s: %s\n",
ch->in_room ? ch->in_room->vnum : 0, ch->name, str );
fclose( fp );
}
fpReserve = fopen( NULL_FILE, "r" );
return;
}
#if 0
/*
* Reports a bug.
*/
void bug( const char *str, int param )
{
char buf[MAX_STRING_LENGTH];
FILE *fp;
if ( fpArea != NULL )
{
int iLine;
int iChar;
if ( fpArea == stdin )
{
iLine = 0;
}
else
{
iChar = ftell( fpArea );
fseek( fpArea, 0, 0 );
for ( iLine = 0; ftell( fpArea ) < iChar; iLine++ )
{
while ( getc( fpArea ) != '\n' )
;
}
fseek( fpArea, iChar, 0 );
}
sprintf( buf, "[*****] FILE: %s LINE: %d", strArea, iLine );
log_string( buf );
if ( ( fp = fopen( "shutdown.txt", "a" ) ) != NULL )
{
fprintf( fp, "[*****] %s\n", buf );
fclose( fp );
}
}
strcpy( buf, "[*****] BUG: " );
sprintf( buf + strlen(buf), str, param );
log_string( buf );
fclose( fpReserve );
if ( ( fp = fopen( BUG_FILE, "a" ) ) != NULL )
{
fprintf( fp, "%s\n", buf );
fclose( fp );
}
fpReserve = fopen( NULL_FILE, "r" );
MessageBox(0, buf, "Merc2.2 server", MB_ICONHAND|MB_OK);
DebugBreak();
return;
}
#endif
#ifdef SINGLEUSER
/*
* Writes a string to the log.
*/
void log_string( const char *str )
{
char *strtime;
strtime = ctime( ¤t_time );
strtime[strlen(strtime)-1] = '\0';
fprintf( stderr, "%s :: %s\n", strtime, str );
return;
}
#endif
/*
* This function is here to aid in debugging.
* If the last expression in a function is another function call,
* gcc likes to generate a JMP instead of a CALL.
* This is called "tail chaining."
* It hoses the debugger call stack for that call.
* So I make this the last call in certain critical functions,
* where I really need the call stack to be right for debugging!
*
* If you don't understand this, then LEAVE IT ALONE.
* Don't remove any calls to tail_chain anywhere.
*
* -- Furey
*/
void tail_chain( void )
{
return;
}
/*
* MOBprogram code block
*/
/*
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -