/******************************************************************************
Snippet: Dynamic description generator.
Author: Richard Woolcock (aka KaVir).
Date: 14th October 1999.
******************************************************************************
This code is copyright (C) 1999 by Richard Woolcock. It may be used and
distributed freely, as long as you don't remove this copyright notice.
******************************************************************************
[({clan} == {caitiff}) || ({clan} == {brujah})]
You're a {clan}!
VARIABLE_FUNCTION_STRING: Functions returning strings.
VARIABLE_CONSTANT_STRING: Constant strings.
VARIABLE_FUNCTION_NUMBER: Functions returning numbers.
VARIABLE_CONSTANT_NUMBER: Constant numbers.
Only the strings may be used within general text replacement. Only the
numbers may be used within expressions. You may have a string variable
and a number variable of the same name (in fact I recommend you do this).
That's how the above example (with {clan}) would work - {clan} string
returns the name of the person's clan as a string, while the {clan} number
returns a number appropriate to that particular clan.
void io_parse args( ( CHAR_DATA *ch, char *in_ptr, char *out_ptr ) );
void io_display args( ( CHAR_DATA *ch, char text[] ) );
void io_main args( ( CHAR_DATA *ch ) );
int io_calculate args( ( CHAR_DATA *ch, char *calculation ) );
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <time.h>
#include "merc.h"
typedef enum
{
VARIABLE_FUNCTION_STRING,
VARIABLE_CONSTANT_STRING,
VARIABLE_FUNCTION_NUMBER,
VARIABLE_CONSTANT_NUMBER
} VARIABLE_TYPE;
typedef enum
{
STATE_NONE,
STATE_LEFT_SIGN,
STATE_LEFT,
STATE_DONE_LEFT,
STATE_OPERATOR,
STATE_RIGHT_SIGN,
STATE_RIGHT
} STATE_TYPE;
typedef struct
{
const char * variable;
const VARIABLE_TYPE type;
void * replace;
} var_type;
/*********************************************************/
/* FUNCTION PROTOTYPES */
/*********************************************************/
static int main_calc ( CHAR_DATA *ch, char calc_string[] );
bool string_var ( char *var_ptr, char **out_ptr,
CHAR_DATA *ch, OBJ_DATA *obj );
bool number_var ( char *var_ptr, char *out_ptr,
CHAR_DATA *ch, OBJ_DATA *obj );
OBJ_DATA * setup_variables ( CHAR_DATA *ch );
char * numberize args( ( int n ) );
extern const struct where_type where_name [MAX_WEAR];
#define CFUN( fun ) char *fun( CHAR_DATA *ch, OBJ_DATA *obj )
#define IFUN( fun ) int fun( CHAR_DATA *ch, OBJ_DATA *obj )
char *short_obj_desc( CHAR_DATA *ch, OBJ_DATA *obj, bool fShort )
{
static char buf[MAX_STRING_LENGTH];
char pre[MAX_STRING_LENGTH];
buf[0] = '\0';
pre[0] = '\0';
if( IS_OBJ_STAT( obj, ITEM_INVIS) ) strcat( pre, "invisible " );
if( IS_AFFECTED(ch, AFF_DETECT_MAGIC)
&& IS_OBJ_STAT(obj, ITEM_MAGIC ) ) strcat( pre, "shimmering ");
if( IS_OBJ_STAT(obj, ITEM_GLOW ) ) strcat( pre, "glowing " );
if( IS_OBJ_STAT(obj, ITEM_HUM ) ) strcat( pre, "humming " );
switch( obj->item_type )
{
default: break;
case ITEM_DRINK_CON:
if ( !obj->value[0] ) strcat( pre, "empty " ); break;
case ITEM_ARMOR:
if( obj->value[0] )
{
int percent;
percent = PERCENTAGE( obj->value[4], 100);
strcat( pre,
percent < 10 ? "destroyed " :
percent < 20 ? "poor " :
percent < 30 ? "badly damaged " :
percent < 40 ? "damaged " :
percent < 50 ? "worn " :
percent < 80 ? "somewhat used " :
"new " );
}
break;
}
if( pre[0] != '\0' )
{
sprintf( buf, "%s %s%s", IS_VOWEL(pre[0]) ? "an" : "a", pre,
smash_article( STR(obj, short_descr) ) );
}
else
strcat( buf, STR(obj,short_descr) );
if ( obj->item_type == ITEM_DRINK_CON
&& IS_SET(obj->extra_flags, ITEM_INVENTORY)
&& obj->value[0] != 0 )
{
if ( obj->value[2] < 0 || obj->value[2] >= LIQ_MAX )
{
obj->value[2] = 0;
bug( "Invalid liquid on object %d.", obj->pIndexData->vnum);
}
strcat( buf, " of " );
strcat( buf, liq_table[obj->value[2]].liq_name );
}
return buf;
}
/*********************************************************************/
/**************************** PURE STRING ****************************/
/*********************************************************************/
CFUN( get_name ) { return ( ch->name ); }
CFUN( get_he_she ) { return HE_SHE(ch); }
CFUN( get_him_her ) { return HIM_HER(ch); }
CFUN( get_his_her ) { return HIS_HER(ch); }
CFUN( obj_where_text )
{
static char buf [MAX_INPUT_LENGTH];
if ( !obj ) return "";
if ( obj->in_obj )
{
sprintf( buf, "inside his %s",
short_obj_desc(ch,obj->in_obj,FALSE) );
return buf;
}
if ( obj->carried_by == ch )
{
if ( obj->wear_loc >= WEAR_LIGHT && obj->wear_loc < MAX_WEAR )
{
sprintf( buf, where_name[obj->wear_loc].r_name, HIS_HER(ch) );
return &buf[2];
}
}
return "";
}
/*********************************************************************/
/**************************** PURE NUMBER ****************************/
/*********************************************************************/
IFUN( get_class ) { return ( ch->class ); }
/*********************************************************************/
/********************** BOTH STRING AND NUMBER ***********************/
/*********************************************************************/
IFUN( get_wpn ) { return ( !obj ); }
CFUN( get_wpn_text ) { return obj ? short_obj_desc(ch,obj,FALSE) : "fist" ; }
IFUN( wpn_type ) { return obj ? obj->value[3] : 0; }
CFUN( wpn_type_text ) { return numberize(wpn_type(ch,obj)); }
IFUN( wpn_dam ) { return obj ? obj->value[2] : 0; }
CFUN( wpn_dam_text ) { return numberize(wpn_dam(ch,obj)); }
IFUN( wpn_where ) { return obj ? obj->wear_loc : -1; }
CFUN( wpn_where_text ) { return obj_where_text( ch, obj ); }
IFUN( get_generation ) { return GET_GEN(ch); }
CFUN( get_generation_text)
{
switch ( GET_GEN(ch) )
{
default: return "bugged";
case 15: return "15th";
case 14: return "14th";
case 13: return "13th";
case 12: return "12th";
case 11: return "11th";
case 10: return "10th";
case 9: return "9th";
case 8: return "8th";
case 7: return "7th";
case 6: return "6th";
case 5: return "5th";
case 4: return "4th";
case 3: return "3rd";
case 2: return "2nd";
case 1: return "1st";
}
}
CFUN( get_attribute_str_text ) { return numberize(get_curr_str(ch)); }
IFUN( get_attribute_str ) { return get_curr_str(ch); }
CFUN( get_attribute_int_text ) { return numberize(get_curr_int(ch)); }
IFUN( get_attribute_int ) { return get_curr_int(ch); }
CFUN( get_attribute_wis_text ) { return numberize(get_curr_wis(ch)); }
IFUN( get_attribute_wis ) { return get_curr_wis(ch); }
CFUN( get_attribute_dex_text ) { return numberize(get_curr_dex(ch)); }
IFUN( get_attribute_dex ) { return get_curr_dex(ch); }
CFUN( get_attribute_con_text ) { return numberize(get_curr_con(ch)); }
IFUN( get_attribute_con ) { return get_curr_con(ch); }
/*********************************************************/
#define STRING_FUNCTION(f) VARIABLE_FUNCTION_STRING, (void *) (f)
#define STRING_CONSTANT(f) VARIABLE_CONSTANT_STRING, (void *) (f)
#define NUMBER_FUNCTION(f) VARIABLE_FUNCTION_NUMBER, (void *) (f)
#define NUMBER_CONSTANT(f) VARIABLE_CONSTANT_NUMBER, (void *) (f)
#define END_OF_LIST VARIABLE_CONSTANT_NUMBER, NULL
/*********************************************************/
/* VARIABLE TABLE */
/*********************************************************/
const var_type var_table[] =
{
/* Pure string functions */
{ "name", STRING_FUNCTION(get_name) },
{ "he/she", STRING_FUNCTION(get_he_she) },
{ "him/her", STRING_FUNCTION(get_him_her) },
{ "his/her", STRING_FUNCTION(get_his_her) },
/* Pure number functions */
{ "class", NUMBER_FUNCTION(get_class) },
{ "mortal", NUMBER_CONSTANT(CLASS_NONE) },
{ "vampire", NUMBER_CONSTANT(CLASS_VAMPIRE) },
{ "werewolf", NUMBER_CONSTANT(CLASS_WEREWOLF) },
{ "mage", NUMBER_CONSTANT(CLASS_MAGE) },
{ "demon", NUMBER_CONSTANT(CLASS_DEMON) },
{ "monk", NUMBER_CONSTANT(CLASS_MONK) },
{ "priest", NUMBER_CONSTANT(CLASS_PRIEST) },
{ "ninja", NUMBER_CONSTANT(CLASS_NINJA) },
{ "angel", NUMBER_CONSTANT(CLASS_ANGEL) },
{ "drow", NUMBER_CONSTANT(CLASS_DROW) },
{ "true", NUMBER_CONSTANT(1) },
{ "false", NUMBER_CONSTANT(0) },
/* String AND number functions */
{ "generation", STRING_FUNCTION(get_generation_text) },
{ "generation", NUMBER_FUNCTION(get_generation) },
{ "strength", STRING_FUNCTION(get_attribute_str_text) },
{ "strength", NUMBER_FUNCTION(get_attribute_str) },
{ "intellect", STRING_FUNCTION(get_attribute_int_text) },
{ "intellect", NUMBER_FUNCTION(get_attribute_int) },
{ "wisdom", STRING_FUNCTION(get_attribute_wis_text) },
{ "wisdom", NUMBER_FUNCTION(get_attribute_wis) },
{ "dexterity", STRING_FUNCTION(get_attribute_dex_text) },
{ "dexterity", NUMBER_FUNCTION(get_attribute_dex) },
{ "constitution", STRING_FUNCTION(get_attribute_con_text) },
{ "constitution", NUMBER_FUNCTION(get_attribute_con) },
{ "get.weapon", STRING_FUNCTION(get_wpn_text) },
{ "get.weapon", NUMBER_FUNCTION(get_wpn) },
{ "weapon.type", STRING_FUNCTION(wpn_type_text) },
{ "weapon.type", NUMBER_FUNCTION(wpn_type) },
{ "weapon.damage", STRING_FUNCTION(wpn_dam_text) },
{ "weapon.damage", NUMBER_FUNCTION(wpn_dam) },
{ "wpn.where", STRING_FUNCTION(wpn_where_text) },
{ "wpn.where", NUMBER_FUNCTION(wpn_where) },
{ NULL, END_OF_LIST } /* Always leave this at end */
};
/*********************************************************/
static jmp_buf jBuf;
static int s_iIndex;
static int s_iLevel;
int io_calculate( CHAR_DATA *ch, char *calculation )
{
int iResult;
s_iIndex = -1;
s_iLevel = 0;
if ( setjmp( jBuf ) )
{
return 0; /* Unable to perform calculation */
}
if ( calculation[0] == '\0' )
{
return 0; /* Unable to perform calculation */
}
iResult = main_calc( ch, calculation );
if ( s_iLevel != 1 )
{
ch_printf( ch, "\nNon-matching brackets.\n");
return 0;
}
s_iIndex = -1;
s_iLevel = 0;
return ( iResult );
}
static int main_calc( CHAR_DATA *ch, char calc_string[] )
{
STATE_TYPE eState = STATE_NONE;
int iLeft = 0;
int iRight = 0;
bool bLeftNeg = FALSE;
bool bRightNeg = FALSE;
char chOperator = 0;
bool bGLEqual = FALSE;
s_iLevel++;
while ( calc_string[++s_iIndex] != '\0' )
{
switch ( calc_string[s_iIndex] )
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
switch ( eState )
{
case STATE_LEFT_SIGN:
bLeftNeg = TRUE;
case STATE_NONE:
case STATE_LEFT:
case STATE_DONE_LEFT: /* TBD - check this */
eState = STATE_LEFT;
if ( bLeftNeg == TRUE ) iLeft = 0 - iLeft; /* Make positive */
iLeft *= 10;
iLeft += (int) (calc_string[s_iIndex] - '0');
if ( bLeftNeg == TRUE ) iLeft = 0 - iLeft; /* Make negative */
break;
case STATE_RIGHT_SIGN:
bRightNeg = TRUE;
case STATE_OPERATOR:
case STATE_RIGHT:
eState = STATE_RIGHT;
if ( bRightNeg == TRUE ) iRight = 0 - iRight; /* Make positive */
iRight *= 10;
iRight += (int) (calc_string[s_iIndex] - '0');
if ( bRightNeg == TRUE ) iRight = 0 - iRight; /* Make negative */
break;
}
break;
case '+': case '-': case '*': case '/':
if ( eState == STATE_RIGHT )
{
switch ( chOperator )
{
case '+':
iLeft = iLeft + iRight;
break;
case '-':
iLeft = iLeft - iRight;
break;
case '*':
iLeft = iLeft * iRight;
break;
case '/':
if ( iRight == 0 )
{
stc("\nDivision by zero.\n", ch );
longjmp( jBuf, 1 );
}
iLeft = iLeft / iRight;
break;
default:
stc("\nInvalid position of closed bracket.\n", ch );
longjmp( jBuf, 1 );
}
bRightNeg = FALSE;
iRight = 0;
eState = STATE_OPERATOR;
}
else if ( eState == STATE_NONE && calc_string[s_iIndex] == '-' )
{
bLeftNeg = TRUE;
eState = STATE_LEFT_SIGN;
}
else if ( eState == STATE_OPERATOR && calc_string[s_iIndex] == '-' )
{
bRightNeg = TRUE;
eState = STATE_RIGHT_SIGN;
}
else if ( eState > STATE_OPERATOR )
{
stc("\nInvalid position of operator.\n", ch );
longjmp( jBuf, 1 );
}
else
{
eState = STATE_OPERATOR;
chOperator = calc_string[s_iIndex];
}
break;
case '=': case '!':
if ( calc_string[s_iIndex+1] != '=' )
{
ch_printf(ch,"\nInvalid operator '%c'.\n", calc_string[s_iIndex] );
longjmp( jBuf, 1 );
}
++s_iIndex;
if ( eState == STATE_RIGHT )
{
switch ( chOperator )
{
case '=':
iLeft = (iLeft == iRight);
break;
case '!':
iLeft = (iLeft != iRight);
break;
default:
stc("\nInvalid position of closed bracket.\n", ch );
longjmp( jBuf, 1 );
}
bRightNeg = FALSE;
iRight = 0;
}
else if ( eState > STATE_OPERATOR )
{
stc("\nInvalid position of operator.\n", ch );
longjmp( jBuf, 1 );
}
else
{
eState = STATE_OPERATOR;
chOperator = calc_string[s_iIndex-1];
}
break;
case '<': case '>':
if ( calc_string[s_iIndex+1] == '=' )
{
++s_iIndex;
bGLEqual = TRUE;
}
if ( eState == STATE_RIGHT )
{
switch ( chOperator )
{
case '[':
iLeft = (iLeft <= iRight);
break;
case '<':
iLeft = (iLeft < iRight);
break;
case ']':
iLeft = (iLeft >= iRight);
break;
case '>':
iLeft = (iLeft > iRight);
break;
default:
stc("\nInvalid position of closed bracket.\n", ch );
longjmp( jBuf, 1 );
}
bRightNeg = FALSE;
iRight = 0;
}
else if ( eState > STATE_OPERATOR )
{
stc("\nInvalid position of operator.\n", ch );
longjmp( jBuf, 1 );
}
else
{
eState = STATE_OPERATOR;
if ( bGLEqual )
{
if ( calc_string[s_iIndex-1] == '<' )
{
chOperator = '[';
}
else /* calc_string[s_iIndex-1] == '>' */
{
chOperator = ']';
}
}
else
{
chOperator = calc_string[s_iIndex];
}
}
bGLEqual = FALSE;
break;
case '&':
if ( calc_string[s_iIndex+1] != '&' )
{
ch_printf(ch,"\nInvalid operator '%c'.\n",calc_string[s_iIndex]);
longjmp( jBuf, 1 );
}
++s_iIndex;
if ( eState == STATE_RIGHT )
{
switch ( chOperator )
{
case '&':
iLeft = (iLeft && iRight);
break;
default:
stc("\nInvalid position of closed bracket.\n",ch );
longjmp( jBuf, 1 );
}
bRightNeg = FALSE;
iRight = 0;
}
else if ( eState > STATE_OPERATOR )
{
stc("\nInvalid position of operator.\n",ch );
longjmp( jBuf, 1 );
}
else
{
eState = STATE_OPERATOR;
chOperator = calc_string[s_iIndex-1];
}
break;
case '|':
if ( calc_string[s_iIndex+1] != '|' )
{
ch_printf( ch,"\nInvalid operator '%c'.\n",
calc_string[s_iIndex] );
longjmp( jBuf, 1 );
}
++s_iIndex;
if ( eState == STATE_RIGHT )
{
switch ( chOperator )
{
case '|':
iLeft = (iLeft || iRight);
break;
default:
stc("\nInvalid position of closed bracket.\n",ch );
longjmp( jBuf, 1 );
}
bRightNeg = FALSE;
iRight = 0;
}
else if ( eState > STATE_OPERATOR )
{
stc("\nInvalid position of operator.\n",ch );
longjmp( jBuf, 1 );
}
else
{
eState = STATE_OPERATOR;
chOperator = calc_string[s_iIndex-1];
}
break;
case ' ':
break;
case '(':
if ( eState == STATE_NONE )
{
iLeft = main_calc( ch, calc_string );
eState = STATE_DONE_LEFT;
}
else if ( eState == STATE_OPERATOR )
{
iRight = main_calc( ch, calc_string );
eState = STATE_RIGHT;
}
else
{
stc("\nInvalid position of open bracket.\n",ch );
longjmp( jBuf, 1 );
}
break;
case ')':
s_iLevel--;
if ( eState == STATE_DONE_LEFT || eState == STATE_LEFT )
{
return ( iLeft );
}
if ( eState != STATE_RIGHT )
{
stc("\nInvalid position of closed bracket.\n",ch );
longjmp( jBuf, 1 );
}
switch ( chOperator )
{
case '+': return ( iLeft + iRight );
case '-': return ( iLeft - iRight );
case '*': return ( iLeft * iRight );
case '/':
if ( iRight == 0 )
{
stc("\nDivision by zero.\n", ch );
longjmp( jBuf, 1 );
}
return ( iLeft / iRight );
case '=': return ( iLeft == iRight );
case '!': return ( iLeft != iRight );
case '<': return ( iLeft < iRight );
case '>': return ( iLeft > iRight );
case '[': return ( iLeft <= iRight );
case ']': return ( iLeft >= iRight );
case '&': return ( iLeft && iRight );
case '|': return ( iLeft || iRight );
}
stc("\nInvalid position of closed bracket.\n",ch );
longjmp( jBuf, 1 );
case '\0':
if ( s_iLevel > 1 )
{
ch_printf(ch,"\nInvalid character '%d'.\n", calc_string[s_iIndex] );
longjmp( jBuf, 1 );
}
stc("\nDone.\n",ch );
longjmp( jBuf, 1 );
default: /* zzz */
ch_printf(ch,"\nInvalid character '%c'.\n", calc_string[s_iIndex] );
longjmp( jBuf, 1 );
}
};
if ( s_iLevel != 1 )
{
stc("\nNon-matching brackets.\n", ch );
longjmp( jBuf, 1 );
}
if ( eState != STATE_RIGHT )
{
if ( eState == STATE_DONE_LEFT || eState == STATE_LEFT )
{
return ( iLeft );
}
stc("\nInvalid calc_string.\n", ch );
longjmp( jBuf, 1 );
}
switch ( chOperator )
{
case '+': return ( iLeft + iRight );
case '-': return ( iLeft - iRight );
case '*': return ( iLeft * iRight );
case '/':
if ( iRight == 0 )
{
stc("\nDivision by zero.\n", ch );
longjmp( jBuf, 1 );
}
return ( iLeft / iRight );
case '=': return ( iLeft == iRight );
case '!': return ( iLeft != iRight );
case '<': return ( iLeft < iRight );
case '>': return ( iLeft > iRight );
case '[': return ( iLeft <= iRight );
case ']': return ( iLeft >= iRight );
case '&': return ( iLeft && iRight );
case '|': return ( iLeft || iRight );
}
stc("\nInvalid calculation.\n", ch );
return 0;
}
/*********************************************************/
void io_parse( CHAR_DATA *ch, char *in_ptr, char *out_ptr )
{
char var_buf[256];
int var_count = 0;
bool var_name = FALSE;
char calc_buf[256];
int calc_count = 0;
bool calc_name = FALSE;
int nest_text = 0;
int valid_nest = 0;
OBJ_DATA *obj;
obj = setup_variables( ch );
while ( *in_ptr )
{
switch ( *in_ptr )
{
default:
if ( valid_nest != nest_text )
{
in_ptr++;
}
else if ( var_name )
{
var_buf[var_count++] = *in_ptr++;
}
else if ( calc_name )
{
calc_buf[calc_count++] = *in_ptr++;
}
else
{
*out_ptr++ = *in_ptr++;
}
break;
case '{':
if ( valid_nest != nest_text )
{
in_ptr++;
break;
}
in_ptr++;
var_buf[var_count=0] = '\0';
if ( var_name )
stc( "Nested variable names not allowed.\n\r", ch );
var_name = TRUE;
break;
case '}':
if ( valid_nest != nest_text )
{
in_ptr++;
break;
}
if ( !var_name )
stc( "Variable terminator without variable.\n\r", ch );
var_buf[var_count] = '\0';
in_ptr++;
var_name = FALSE;
if ( calc_name )
{
number_var( &var_buf[0], &calc_buf[calc_count],ch,obj );
calc_count = strlen( calc_buf );
}
else
string_var( &var_buf[0], &out_ptr,ch,obj ); /* String variable */
break;
case '[':
if ( valid_nest != nest_text )
{
in_ptr++;
break;
}
in_ptr++;
calc_buf[calc_count=0] = '\0';
if ( calc_name )
stc( "Nested calculations not allowed.\n\r", ch );
calc_name = TRUE;
break;
case ']':
if ( valid_nest != nest_text )
{
nest_text++;
in_ptr++;
break;
}
if ( !calc_name )
stc( "Calculation terminator without calculation.\n\r", ch );
calc_buf[calc_count] = '\0';
in_ptr++;
nest_text++;
valid_nest += !!io_calculate( ch, &calc_buf[0] );
calc_name = FALSE;
break;
case '|':
if ( --nest_text < 0 )
{
stc( "Conditional terminator without condition.\n\r", ch );
nest_text = 0;
}
if ( valid_nest > nest_text ) valid_nest = nest_text;
in_ptr++;
break;
}
}
*out_ptr = '\0';
}
bool string_var( char *var_ptr, char **out_ptr, CHAR_DATA *ch, OBJ_DATA *obj )
{
int i = -1;
while ( var_table[++i].variable != NULL )
{
if ( !strcmp( var_ptr, var_table[i].variable ) )
{
char *replace_ptr = NULL;
switch ( var_table[i].type )
{
case VARIABLE_FUNCTION_STRING:
replace_ptr = ((char*(*)())(var_table[i].replace))(ch,obj);
break;
case VARIABLE_CONSTANT_STRING:
replace_ptr = var_table[i].replace;
break;
default:
continue; /* Cannot resolve numbers */
}
while ( *replace_ptr ) *(*out_ptr)++ = *replace_ptr++;
return TRUE;
}
}
return FALSE;
}
bool number_var( char *var_ptr, char *out_ptr, CHAR_DATA *ch, OBJ_DATA *obj )
{
int i = -1;
while ( var_table[++i].variable != NULL )
{
if ( !strcmp( var_ptr, var_table[i].variable ) )
{
int replace_num = 0;
char replace_buf[64];
char *replace_ptr = &replace_buf[0];
switch ( var_table[i].type )
{
case VARIABLE_FUNCTION_NUMBER:
replace_num = ((int(*)())(var_table[i].replace))(ch,obj);
break;
case VARIABLE_CONSTANT_NUMBER:
replace_num = (int) var_table[i].replace;
break;
default:
continue; /* Cannot resolve strings */
}
sprintf( replace_ptr, "%d", replace_num );
while ( (*out_ptr++ = *replace_ptr++) );
return TRUE;
}
}
return FALSE;
}
void io_display( CHAR_DATA *ch, char text[] )
{
int align = 0;
int i;
while ( *text )
{
switch ( *text )
{
default:
ch_printf( ch,"%c", *text );
break;
case '[':
ch_printf( ch,"\n");
for ( i = 0; i < align; i++ ) stc( " ",ch );
stc( "[",ch );
break;
case ']':
stc( "]\n",ch );
align++;
for ( i = 0; i < align; i++ ) stc( " ",ch );
break;
case '|':
stc( "\n",ch );
align--;
for ( i = 0; i < align; i++ ) stc( " ",ch );
stc( "|",ch );
break;
}
text++;
}
stc( "\n",ch );
}
void io_main( CHAR_DATA *ch )
{
char in_buf [256];
char out_buf [256];
in_buf[0] = '\0';
out_buf[0] = '\0';
strcpy( in_buf,
"Hello there {name}!"
"Your current strength is {strength}.");
// io_display( ch, in_buf );
io_parse( ch, in_buf, out_buf );
ch_printf( ch, "String:[%s]\n\r", out_buf );
}
OBJ_DATA * setup_variables ( CHAR_DATA *ch )
{
OBJ_DATA *obj, *obj2, *wpn;
wpn = NULL;
for ( obj = ch->carrying; obj; obj = obj->next_content )
{
if ( obj->item_type == ITEM_WEAPON )
{
wpn = obj;
break;
}
}
if ( wpn )
return wpn;
for ( obj = ch->carrying; obj; obj = obj->next_content )
{
for ( obj2 = obj->contains; obj2; obj2 = obj2->next_content )
{
if ( obj2->item_type == ITEM_WEAPON )
{
wpn = obj2;
break;
}
}
}
return wpn;
}