//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int BotInterpolateCharacters( int handle1, int handle2, int desiredskill ) { bot_character_t *ch1, *ch2, *out; int i, handle; float scale; ch1 = BotCharacterFromHandle( handle1 ); ch2 = BotCharacterFromHandle( handle2 ); if ( !ch1 || !ch2 ) { return 0; } //find a free spot for a character for ( handle = 1; handle <= MAX_CLIENTS; handle++ ) { if ( !botcharacters[ handle ] ) { break; } } //end for if ( handle > MAX_CLIENTS ) { return 0; } out = ( bot_character_t * ) GetClearedMemory( sizeof( bot_character_t ) + MAX_CHARACTERISTICS * sizeof( bot_characteristic_t ) ); out->skill = desiredskill; strcpy( out->filename, ch1->filename ); botcharacters[ handle ] = out; scale = ( float )( desiredskill - 1 ) / ( ch2->skill - ch1->skill ); for ( i = 0; i < MAX_CHARACTERISTICS; i++ ) { // if ( ch1->c[ i ].type == CT_FLOAT && ch2->c[ i ].type == CT_FLOAT ) { out->c[ i ].type = CT_FLOAT; out->c[ i ].value._float = ch1->c[ i ].value._float + ( ch2->c[ i ].value._float - ch1->c[ i ].value._float ) * scale; } //end if else if ( ch1->c[ i ].type == CT_INTEGER ) { out->c[ i ].type = CT_INTEGER; out->c[ i ].value.integer = ch1->c[ i ].value.integer; } //end else if else if ( ch1->c[ i ].type == CT_STRING ) { out->c[ i ].type = CT_STRING; out->c[ i ].value.string = ( char * ) GetMemory( strlen( ch1->c[ i ].value.string ) + 1 ); strcpy( out->c[ i ].value.string, ch1->c[ i ].value.string ); } //end else if } //end for return handle; } //end of the function BotInterpolateCharacters
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void Characteristic_String( int character, int index, char *buf, int size ) { bot_character_t *ch; ch = BotCharacterFromHandle( character ); if ( !ch ) { return; } //check if the index is in range if ( !CheckCharacteristicIndex( character, index ) ) { return; } //an integer will be converted to a float if ( ch->c[ index ].type == CT_STRING ) { strncpy( buf, ch->c[ index ].value.string, size - 1 ); buf[ size - 1 ] = '\0'; return; } //end if else { botimport.Print( PRT_ERROR, "characteristic %d is not a string\n", index ); return; } //end else if return; } //end of the function Characteristic_String
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int Characteristic_BInteger( int character, int index, int min, int max ) { int value; bot_character_t *ch; ch = BotCharacterFromHandle( character ); if ( !ch ) { return 0; } if ( min > max ) { botimport.Print( PRT_ERROR, "cannot bound characteristic %d between %d and %d\n", index, min, max ); return 0; } //end if value = Characteristic_Integer( character, index ); if ( value < min ) { return min; } if ( value > max ) { return max; } return value; } //end of the function Characteristic_BInteger
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int Characteristic_Integer( int character, int index ) { bot_character_t *ch; ch = BotCharacterFromHandle( character ); if ( !ch ) { return 0; } //check if the index is in range if ( !CheckCharacteristicIndex( character, index ) ) { return 0; } //an integer will just be returned if ( ch->c[ index ].type == CT_INTEGER ) { return ch->c[ index ].value.integer; } //end if //floats are casted to integers else if ( ch->c[ index ].type == CT_FLOAT ) { return ( int ) ch->c[ index ].value._float; } //end else if else { botimport.Print( PRT_ERROR, "characteristic %d is not a integer\n", index ); return 0; } //end else if // return 0; } //end of the function Characteristic_Integer
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int CheckCharacteristicIndex( int character, int index ) { bot_character_t *ch; ch = BotCharacterFromHandle( character ); if ( !ch ) { return qfalse; } if ( index < 0 || index >= MAX_CHARACTERISTICS ) { botimport.Print( PRT_ERROR, "characteristic %d does not exist\n", index ); return qfalse; } //end if if ( !ch->c[ index ].type ) { botimport.Print( PRT_ERROR, "characteristic %d is not initialized\n", index ); return qfalse; } //end if return qtrue; } //end of the function CheckCharacteristicIndex
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== float Characteristic_Float(int character, int index) { bot_character_t *ch; ch = BotCharacterFromHandle(character); if (!ch) return 0; //check if the index is in range if (!CheckCharacteristicIndex(character, index)) return 0; //an integer will be converted to a float if (ch->c[index].type == CT_INTEGER) { return (float) ch->c[index].value.integer; } //end if //floats are just returned else if (ch->c[index].type == CT_FLOAT) { return ch->c[index].value._float; } //end else if //cannot convert a string pointer to a float else { botimport.Print(PRT_ERROR, "characteristic %d is not a float\n", index); return 0; } //end else if // return 0; } //end of the function Characteristic_Float
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int BotInterpolateCharacters(int handle1, int handle2, float desiredskill) { bot_character_t *ch1, *ch2, *out; int i, handle; float scale; ch1 = BotCharacterFromHandle(handle1); ch2 = BotCharacterFromHandle(handle2); if (!ch1 || !ch2) return 0; //find a free spot for a character for (handle = 1; handle < MAX_BOT_CHARACTERS; handle++) { if (!botcharacters[handle].skill) break; } //end for if (handle >= MAX_BOT_CHARACTERS) return 0; out = &botcharacters[handle]; out->skill = desiredskill; strcpy(out->filename, ch1->filename); scale = (float) (desiredskill - ch1->skill) / (ch2->skill - ch1->skill); for (i = 0; i < MAX_CHARACTERISTICS; i++) { // if (ch1->c[i].type == CT_FLOAT && ch2->c[i].type == CT_FLOAT) { out->c[i].type = CT_FLOAT; out->c[i].value._float = ch1->c[i].value._float + (ch2->c[i].value._float - ch1->c[i].value._float) * scale; } //end if else if (ch1->c[i].type == CT_INTEGER) { out->c[i].type = CT_INTEGER; out->c[i].value.integer = ch1->c[i].value.integer; } //end else if else if (ch1->c[i].type == CT_STRING) { out->c[i].type = CT_STRING; out->c[i].value.string = (char *) trap_Alloc(strlen(ch1->c[i].value.string)+1, NULL); strcpy(out->c[i].value.string, ch1->c[i].value.string); } //end else if } //end for return handle; } //end of the function BotInterpolateCharacters
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== float Characteristic_BFloat(int character, int index, float min, float max) { float value; bot_character_t *ch; ch = BotCharacterFromHandle(character); if (!ch) return 0; if (min > max) { botimport.Print(PRT_ERROR, "cannot bound characteristic %d between %f and %f\n", index, min, max); return 0; } //end if value = Characteristic_Float(character, index); if (value < min) return min; if (value > max) return max; return value; } //end of the function Characteristic_BFloat
int Characteristic_Integer(int character, int index) { bot_character_t *ch; ch = BotCharacterFromHandle(character); if(!ch) return 0; /* check if the index is in range */ if(!CheckCharacteristicIndex(character, index)) return 0; /* an integer will just be returned */ if(ch->c[index].type == CT_INTEGER) return ch->c[index].value.integer; /* floats are casted to integers */ else if(ch->c[index].type == CT_FLOAT) return (int)ch->c[index].value._float; else{ botimport.Print(PRT_ERROR, "characteristic %d is not a integer\n", index); return 0; } /* return 0; */ }
float Characteristic_Float(int character, int index) { bot_character_t *ch; ch = BotCharacterFromHandle(character); if(!ch) return 0; /* check if the index is in range */ if(!CheckCharacteristicIndex(character, index)) return 0; /* an integer will be converted to a float */ if(ch->c[index].type == CT_INTEGER) return (float)ch->c[index].value.integer; /* floats are just returned */ else if(ch->c[index].type == CT_FLOAT) return ch->c[index].value._float; /* cannot convert a string pointer to a float */ else{ botimport.Print(PRT_ERROR, "characteristic %d is not a float\n", index); return 0; } /* return 0; */ }