Written by Cameron Taylor, a.k.a. Shanyr
I don't strictly require any credit, but if you have a 'snippets' help file, I would appreciate an entry similar to: Object randomization code by Cameron Taylor.


In 'obj_index_data', add:

    char *      random_string;

In 'create_object', after the strings have been copied from 'obj_index_data' (i.e. after the stuff that looks like 'obj->foo = pObjIndex->foo;'), add:

    if ( check_randomized_obj(obj) )
        set_randomized_obj( obj );

I use these two macros for strings:

#define STR_HASDATA(str) (str != NULL && str[0] != '\0')
#define STR_NODATA(str)  (str == NULL || str[0] == '\0')

Modify the code that loads objects. I added to the 'letter loop', following the 'else if ( letter == 'E' )' block:

            else if ( letter == 'S' )
            {
                word = fread_word(fp);

                if( !str_prefix( word, "random" ) )
                {
                    pObjIndex->random_string  = fread_string( fp );
                }
            }

Add these two functions somewhere, I put them in 'db.c'.

/*
 *  Determine if this object has randomization data
 *  Programmer: Cameron Taylor
 */
bool check_randomized_obj( OBJ_DATA * obj )
{
    bool rval = FALSE;

    if ( STR_HASDATA(obj->pIndexData->random_string) )
        rval = TRUE;

    return rval;
}

/*
 *  Set up the randomized data
 *  Programmer: Cameron Taylor
 */
void set_randomized_obj( OBJ_DATA * obj )
{
    char rstr[10][128];
    char buf[MAX_STRING_LENGTH];
    char * rdata, * pbuf, * prstr, * tstr;
    int rcount;
    int ri,r;
    int nest_level;

    rdata = obj->pIndexData->random_string;

    /*
     * Parse out the strings for #0 - #9
     */
    for(ri=0;ri<10;ri++)
    {
        /*
         * Skip leading spaces
         */
        while ( *rdata != '[' )
            if (*rdata == '\0')
                break;
            else
                rdata++;
        if ( STR_NODATA(rdata) )
            break;

        /*
         * Count the choices for this #n, and save them into buf
         */
        pbuf = buf; rdata++; nest_level = 0;
        rcount = 1;
        for( ;*rdata!='\0'; )
        {
            if ( *rdata == '|' && nest_level == 0 )
                rcount++;
            if ( *rdata == '[' )
                nest_level++;
            if ( *rdata == ']' )
                nest_level--;
            if ( nest_level < 0 )
                break;

            *pbuf++ = *rdata++;
        }
        *pbuf = '\0';

        /*
         * Select one of the choices, and copy it into rstr[ri]  (#n)
         */
        r = number_range( 1, rcount );

        prstr = rstr[ri]; pbuf = buf; nest_level = 0;
        rcount = 1;
        for( ;*pbuf!='\0'; )
        {
            if ( *pbuf == '|' && nest_level == 0 )
            {
                rcount++;
                pbuf++;
                continue;
            }
            if ( *pbuf == '[' )
                nest_level++;
            if ( *pbuf == ']' )
                nest_level--;
            if ( nest_level < 0 )
                break;

            if ( rcount == r)
                *prstr++ = *pbuf;

            pbuf++;
        }
        *prstr = '\0';
    }

    /*
     * Now that the choices are selected, do the actual replacing
     */
    for(ri=0;ri<10;ri++)
    {
        char * rnstr = "# \0""0123456789";
        rnstr[1] = rnstr[ri+3];

        tstr = str_dup(obj->name);
        free_string(obj->name);
        obj->name = str_replace(tstr,rnstr,rstr[ri]);
        free_string(tstr);

        tstr = str_dup(obj->short_descr);
        free_string(obj->short_descr);
        obj->short_descr = str_replace(tstr,rnstr,rstr[ri]);
        free_string(tstr);

        tstr = str_dup(obj->description);
        free_string(obj->description);
        obj->description = str_replace(tstr,rnstr,rstr[ri]);
        free_string(tstr);
    }

    return;
}


Here is an example object:

#28
cloak #0 #1~
a #0 #1 cloak~
A pile of #1 cloth is lying here.~
cloth~
armor 0 AC
2 3 4 0 1
3 40 310 P
S random [short|long][red|green|blue]~
When this object is loaded, the possible results for the name and descriptions are:
cloak short red~
a short red cloak~
A pile of red cloth is lying here.~

cloak short green~
a short green cloak~
A pile of green cloth is lying here.~

cloak short blue~
a short blue cloak~
A pile of blue cloth is lying here.~

cloak long red~
a long red cloak~
A pile of red cloth is lying here.~

cloak long green~
a long green cloak~
A pile of green cloth is lying here.~

cloak long blue~
a long blue cloak~
A pile of blue cloth is lying here.~