stvoy-sp-sdk/game/g_boltons.cpp

602 lines
12 KiB
C++
Raw Permalink Normal View History

2002-11-22 00:00:00 +00:00
#include "b_local.h"
#include "boltOns.h"
//#include "b_public.h"
//extern void G_ParseBoltOnList( boltOn_t *boltOn );
extern gentity_t *G_CreateObject ( gentity_t *owner, vec3_t origin, vec3_t angles, int modelIndex, int frame, trType_t trType );
extern qboolean G_ParseLiteral( char **data, const char *string );
extern qboolean G_ParseString( char **data, char **s ) ;
extern qboolean G_ParseInt( char **data, int *i );
extern qboolean G_ParseFloat( char **data, float *f );
#define BOLTON_NONE MAX_BOLT_ONS
boltOn_t knownBoltOns[MAX_GAME_BOLTONS];
int numBoltOns;
char boltOnList[0x10000];
int G_GetBoltOnIndex( const char *boltOnName )
{
for ( int i = 0; i < numBoltOns; i++ )
{
if ( Q_stricmp( knownBoltOns[i].name, boltOnName ) == 0 )
{//found it!
return i;
}
}
G_Error( "ERROR: Unknown boltOn name: %s!\n", boltOnName );
return MAX_GAME_BOLTONS;
}
void G_RegisterBoltOns (void)
{
boltOn_t *boltOn = NULL;
char *token = NULL;
char *value;
char *p;
int n;
float f;
p = boltOnList;
COM_BeginParseSession();
while(1)
{
if ( numBoltOns >= MAX_GAME_BOLTONS )
{
G_Error( "ERROR: Too many boltOns (%d) in boltOn.cfg!\n", MAX_GAME_BOLTONS );
return;
}
boltOn = &knownBoltOns[numBoltOns];
while ( 1 )
{
token = COM_ParseExt( &p, qtrue );
if ( token[0] == 0 )
{
//reached EOF
return;
}
else if ( token[0] == '{' )
{
//WTF? Unnamed boltOn?
continue;
}
else if ( !p )
{
//???
return;
}
else
{
//found a boltOn name
break;
}
}
Q_strncpyz( (char *)&boltOn->name, token, sizeof(boltOn->name), qtrue );
if ( G_ParseLiteral( &p, "{" ) )
{//couldn't find an open brace "{"!
return;
}
//Set default scale
VectorSet(boltOn->model.scaleXYZ, 100, 100, 100);
// parse the boltOn info block
while ( 1 )
{
token = COM_ParseExt( &p, qtrue );
if ( !token[0] )
{
gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", boltOn->name );
return;
}
if ( !Q_stricmp( token, "}" ) )
{
//reached end of boltOn, on to next
break;
}
// modelName
if ( !Q_stricmp( token, "modelName" ) )
{
if ( G_ParseString( &p, &value ) )
{
continue;
}
boltOn->model.modelIndex = G_ModelIndex( value );
continue;
}
// target model to attach to, head, torso, legs or weapon
if ( !Q_stricmp( token, "targetModel" ) )
{
if ( G_ParseInt( &p, &n ) )
{
continue;
}
if ( n < 0 || n >= NUM_TARGET_MODELS )
{
gi.Printf("WARNING boltOn %s has targetModel out of range (<0 or >= %d)\n", boltOn->name, NUM_TARGET_MODELS);
return;
}
boltOn->targetModel = (targetModel_t)n;
continue;
}
// target tag to attach to
if ( !Q_stricmp( token, "targetTag" ) )
{
if ( G_ParseString( &p, &value ) )
{
continue;
}
//boltOn->targetTag = G_NewString(value);
Q_strncpyz( boltOn->targetTag, value, sizeof(boltOn->targetTag), qtrue);
continue;
}
// pitch offset
if ( !Q_stricmp( token, "pitchOffset" ) )
{
if ( G_ParseFloat( &p, &f ) )
{
continue;
}
boltOn->angleOffsets[0] = f;
continue;
}
// yaw offset
if ( !Q_stricmp( token, "yawOffset" ) )
{
if ( G_ParseFloat( &p, &f ) )
{
continue;
}
boltOn->angleOffsets[1] = f;
continue;
}
// roll offset
if ( !Q_stricmp( token, "rollOffset" ) )
{
if ( G_ParseFloat( &p, &f ) )
{
continue;
}
boltOn->angleOffsets[2] = f;
continue;
}
// x offset
if ( !Q_stricmp( token, "xOffset" ) )
{
if ( G_ParseFloat( &p, &f ) )
{
continue;
}
boltOn->originOffsets[0] = f;
continue;
}
// y offset
if ( !Q_stricmp( token, "yOffset" ) )
{
if ( G_ParseFloat( &p, &f ) )
{
continue;
}
boltOn->originOffsets[1] = f;
continue;
}
// z offset
if ( !Q_stricmp( token, "zOffset" ) )
{
if ( G_ParseFloat( &p, &f ) )
{
continue;
}
boltOn->originOffsets[2] = f;
continue;
}
// Uniform XYZ scale
if ( !Q_stricmp( token, "scale" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.scaleXYZ[0] = boltOn->model.scaleXYZ[1] = boltOn->model.scaleXYZ[2] = n;
continue;
}
//X scale
if ( !Q_stricmp( token, "scaleX" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.scaleXYZ[0] = n;
continue;
}
//Y scale
if ( !Q_stricmp( token, "scaleY" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.scaleXYZ[1] = n;
continue;
}
//Z scale
if ( !Q_stricmp( token, "scaleZ" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.scaleXYZ[2] = n;
continue;
}
// Uniform RGB tint
if ( !Q_stricmp( token, "tint" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.customRGB[0] = boltOn->model.customRGB[1] = boltOn->model.customRGB[2] = n;
continue;
}
//red tint
if ( !Q_stricmp( token, "tintRed" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.customRGB[0] = n;
continue;
}
//Green tint
if ( !Q_stricmp( token, "tintGreen" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.customRGB[1] = n;
continue;
}
//Blue tint
if ( !Q_stricmp( token, "tintBlue" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.customRGB[2] = n;
continue;
}
//alpha
if ( !Q_stricmp( token, "alpha" ) )
{
if ( G_ParseInt( &p, &n ) )
{
SkipRestOfLine( &p );
continue;
}
if ( n < 0 )
{
gi.Printf( "bad %s in boltOn '%s'\n", token, boltOn->name );
continue;
}
boltOn->model.customAlpha = n;
continue;
}
}
numBoltOns++;
}
}
void G_ClearBoltOnInfo( boltOnInfo_t *bOInfo )
{
bOInfo->index = MAX_GAME_BOLTONS;
VectorClear( bOInfo->lastOrigin );
VectorClear( bOInfo->lastAngles );
bOInfo->frame = bOInfo->startFrame = bOInfo->endFrame = 0;
bOInfo->loopAnim = qfalse;
}
void G_LoadBoltOns( void )
{
int len;
const char filename[] = "ext_data/boltOns.cfg";
char *buffer;
gi.Printf( "Parsing %s\n", filename );
len = gi.FS_ReadFile( filename, (void **) &buffer );
if ( len == -1 )
{
gi.Printf( "file not found\n" );
return;
}
if ( len >= sizeof( boltOnList ) )
{
G_Error( "ext_data/boltOns.cfg is too large" );
}
strncpy( boltOnList, buffer, sizeof( boltOnList ) - 1 );
gi.FS_FreeFile( buffer );
G_RegisterBoltOns();
}
byte G_AddBoltOn( gentity_t *ent, const char *boltOnName )
{
int freeSlot, newIndex;
if ( !ent || !boltOnName || !boltOnName[0] )
{
return BOLTON_NONE;
}
newIndex = G_GetBoltOnIndex( boltOnName );
if ( newIndex < 0 || newIndex >= numBoltOns )
{
return BOLTON_NONE;
}
if ( !ent->client )
{
freeSlot = 0;
G_ClearBoltOnInfo( &ent->boltOn );
ent->boltOn.index = newIndex;
}
else
{
for ( freeSlot = 0; freeSlot < MAX_BOLT_ONS; freeSlot++ )
{
if ( ent->client->renderInfo.boltOns[freeSlot].index == MAX_GAME_BOLTONS )
{//Found a free slot
break;
}
else if ( ent->client->renderInfo.boltOns[freeSlot].index == newIndex )
{
#ifndef FINAL_BUILD
gi.Printf("WARNING: %s already has boltOn turned on!\n", ent->targetname, boltOnName );
#endif
return BOLTON_NONE;
}
}
if ( freeSlot >= MAX_BOLT_ONS )
{
gi.Printf("WARNING: %s out of free boltOn slots! (MAX = %d)\n", ent->targetname, MAX_BOLT_ONS );
return BOLTON_NONE;
}
G_ClearBoltOnInfo( &ent->client->renderInfo.boltOns[freeSlot] );
ent->client->renderInfo.boltOns[freeSlot].index = newIndex;
}
return freeSlot;
}
void G_RemoveBoltOn( gentity_t *ent, const char *boltOnName )
{
int namedIndex;
if ( !ent || !boltOnName || !boltOnName[0] )
{
return;
}
namedIndex = G_GetBoltOnIndex( boltOnName );
if ( namedIndex < 0 || namedIndex >= numBoltOns )
{
return;
}
if ( !ent->client )
{
if ( ent->boltOn.index == namedIndex )
{
G_ClearBoltOnInfo( &ent->boltOn );
}
}
else
{
for ( int i = 0; i < MAX_BOLT_ONS; i++ )
{
if ( ent->client->renderInfo.boltOns[i].index == namedIndex )
{//Found it, clear it
G_ClearBoltOnInfo( &ent->client->renderInfo.boltOns[i] );
}
}
}
}
void G_DropBoltOn( gentity_t *ent, const char *boltOnName )
{
boltOn_t *boltOn;
int namedIndex;
if ( !ent || !boltOnName || !boltOnName[0] )
{
return;
}
namedIndex = G_GetBoltOnIndex( boltOnName );
if ( namedIndex < 0 || namedIndex >= numBoltOns )
{
return;
}
if ( !ent->client )
{
if ( ent->boltOn.index != namedIndex )
{
//FIXME: error msg
return;
}
if ( ent->boltOn.index < 0 || ent->boltOn.index >= numBoltOns )
{
return;
}
boltOn = &knownBoltOns[ent->boltOn.index];
//FIXME: what about tint, alpha and scale? And animation?
gentity_t *newObject = G_CreateObject( ent, ent->boltOn.lastOrigin, ent->boltOn.lastAngles,
boltOn->model.modelIndex, ent->boltOn.frame, TR_GRAVITY );
if ( newObject )
{
newObject->targetname = G_NewString( va( "%s_%s", ent->targetname, boltOnName ) );
}
//Remove it
G_RemoveBoltOn( ent, boltOnName );
}
else
{
for ( int i = 0; i < MAX_BOLT_ONS; i++ )
{
if ( ent->client->renderInfo.boltOns[i].index < 0 || ent->client->renderInfo.boltOns[i].index >= numBoltOns )
{
continue;
}
if ( ent->client->renderInfo.boltOns[i].index == namedIndex )
{//Found it
boltOn = &knownBoltOns[ent->client->renderInfo.boltOns[i].index];
//GUH!!! Move these onto ENT!!!
gentity_t *newObject = G_CreateObject( ent, ent->client->renderInfo.boltOns[i].lastOrigin,
ent->client->renderInfo.boltOns[i].lastAngles,
boltOn->model.modelIndex,
ent->client->renderInfo.boltOns[i].frame,
TR_GRAVITY );//TR_STATIONARY );//
if ( newObject )
{
newObject->targetname = G_NewString( va( "%s_%s", ent->targetname, boltOnName ) );
}
//FIXME: what about tint, alpha and scale? And animation?
//Remove it
G_RemoveBoltOn( ent, boltOnName );
//Done
return;
}
}
}
}
byte G_BoltOnNumberForName( gentity_t *ent, const char *boltOnName )
{
if ( !ent || !boltOnName || !boltOnName[0] )
{
return MAX_BOLT_ONS;
}
if ( !ent->client )
{//non-clients only have one
return 0;
}
for ( int i = 0; i < MAX_BOLT_ONS; i++ )
{
if ( !Q_stricmp( boltOnName, knownBoltOns[ent->client->renderInfo.boltOns[i].index].name ) )
{//Found it, return it
return i;
}
}
return MAX_BOLT_ONS;
}
void G_InitBoltOnData ( gentity_t *ent )
{
//UG, crappy here, but need to initialize boltOn index to invalid number
ent->activeBoltOn = MAX_BOLT_ONS;
G_ClearBoltOnInfo( &ent->boltOn );
if ( ent->client )
{
for ( int i = 0; i < MAX_BOLT_ONS; i++ )
{
G_ClearBoltOnInfo( &ent->client->renderInfo.boltOns[i] );
}
}
}