mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-16 08:10:32 +02:00
Switched Doom 3 weapons to native.
This commit is contained in:
@@ -0,0 +1,492 @@
|
||||
// Bot_weapons.cpp
|
||||
//
|
||||
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
|
||||
idCVar bot_weaponsfile( "bot_weaponsfile", "weapons.c", CVAR_GAME | CVAR_CHEAT, "which file to load the weapons weights from" );
|
||||
|
||||
idBotWeaponInfoManager botWeaponInfoManager;
|
||||
|
||||
/*
|
||||
=========================
|
||||
idBotWeaponInfoManager::BotValidWeaponNumber
|
||||
=========================
|
||||
*/
|
||||
int idBotWeaponInfoManager::BotValidWeaponNumber( int weaponnum )
|
||||
{
|
||||
if( weaponnum <= 0 || weaponnum > BOT_MAX_WEAPONS )
|
||||
{
|
||||
gameLocal.Error( "weapon number out of range\n" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=========================
|
||||
idBotWeaponInfoManager::BotWeaponStateFromHandle
|
||||
=========================
|
||||
*/
|
||||
bot_weaponstate_t* idBotWeaponInfoManager::BotWeaponStateFromHandle( int handle )
|
||||
{
|
||||
if( handle <= 0 || handle > MAX_CLIENTS )
|
||||
{
|
||||
gameLocal.Error( "move state handle %d out of range\n", handle );
|
||||
}
|
||||
|
||||
return &botweaponstates[handle];
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idBotWeaponInfoManager::ParseProjectileInfo
|
||||
========================
|
||||
*/
|
||||
void idBotWeaponInfoManager::ParseProjectileInfo( idParser& parser, projectileinfo_t& newProjectileInfo )
|
||||
{
|
||||
idToken token;
|
||||
idToken valueToken;
|
||||
|
||||
parser.ExpectTokenString( "{" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( !parser.ReadToken( &token ) )
|
||||
{
|
||||
parser.Error( "Unexpected end of file found while parsing weaponinfo!" );
|
||||
}
|
||||
|
||||
if( token == "}" )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( !parser.ReadToken( &valueToken ) )
|
||||
{
|
||||
parser.Error( "Failed to read value token, encountered EOF parsing weapon info!" );
|
||||
}
|
||||
|
||||
if( token == "name" )
|
||||
{
|
||||
newProjectileInfo.name = valueToken; // name of the projectile
|
||||
}
|
||||
else if( token == "model" )
|
||||
{
|
||||
newProjectileInfo.model = valueToken; // model of the projectile
|
||||
}
|
||||
else if( token == "flags" )
|
||||
{
|
||||
newProjectileInfo.flags = valueToken.GetIntValue(); // special flags
|
||||
}
|
||||
else if( token == "gravity" )
|
||||
{
|
||||
newProjectileInfo.gravity = valueToken.GetFloatValue(); // amount of gravity applied to the projectile [0,1]
|
||||
}
|
||||
else if( token == "damage" )
|
||||
{
|
||||
newProjectileInfo.damage = valueToken.GetIntValue(); // damage of the projectile
|
||||
}
|
||||
else if( token == "radius" )
|
||||
{
|
||||
newProjectileInfo.radius = valueToken.GetFloatValue(); // radius of damage
|
||||
}
|
||||
else if( token == "visdamage" )
|
||||
{
|
||||
newProjectileInfo.visdamage = valueToken.GetIntValue(); // damage of the projectile to visible entities
|
||||
}
|
||||
else if( token == "damagetype" )
|
||||
{
|
||||
newProjectileInfo.damagetype = valueToken.GetIntValue(); // type of damage (combination of the DAMAGETYPE_? flags)
|
||||
}
|
||||
else if( token == "healthinc" )
|
||||
{
|
||||
newProjectileInfo.healthinc = valueToken.GetIntValue(); // health increase the owner gets
|
||||
}
|
||||
else if( token == "push" )
|
||||
{
|
||||
newProjectileInfo.push = valueToken.GetFloatValue(); // amount a player is pushed away from the projectile impact
|
||||
}
|
||||
else if( token == "detonation" )
|
||||
{
|
||||
newProjectileInfo.detonation = valueToken.GetFloatValue(); // time before projectile explodes after fire pressed
|
||||
}
|
||||
else if( token == "bounce" )
|
||||
{
|
||||
newProjectileInfo.bounce = valueToken.GetFloatValue(); // amount the projectile bounces
|
||||
}
|
||||
else if( token == "bouncefric" )
|
||||
{
|
||||
newProjectileInfo.bouncefric = valueToken.GetFloatValue(); // amount the bounce decreases per bounce
|
||||
}
|
||||
else if( token == "bouncestop" )
|
||||
{
|
||||
newProjectileInfo.bouncestop = valueToken.GetFloatValue(); // minimum bounce value before bouncing stops
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.Error( "ParseProjectileInfo: Unexpected token %s\n", token.c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idBotWeaponInfoManager::ParseWeaponInfo
|
||||
========================
|
||||
*/
|
||||
void idBotWeaponInfoManager::ParseWeaponInfo( idParser& parser, weaponinfo_t& newWeaponInfo )
|
||||
{
|
||||
idToken token;
|
||||
idToken valueToken;
|
||||
|
||||
parser.ExpectTokenString( "{" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( !parser.ReadToken( &token ) )
|
||||
{
|
||||
parser.Error( "Unexpected end of file found while parsing weaponinfo!" );
|
||||
}
|
||||
|
||||
if( token == "}" )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( !parser.ReadToken( &valueToken ) )
|
||||
{
|
||||
parser.Error( "Failed to read value token, encountered EOF parsing weapon info!" );
|
||||
}
|
||||
|
||||
if( token == "number" )
|
||||
{
|
||||
newWeaponInfo.number = valueToken.GetIntValue(); //weapon number
|
||||
}
|
||||
else if( token == "name" )
|
||||
{
|
||||
newWeaponInfo.name = valueToken; //name of the weapon
|
||||
}
|
||||
else if( token == "level" )
|
||||
{
|
||||
newWeaponInfo.level = valueToken.GetIntValue();
|
||||
}
|
||||
else if( token == "model" )
|
||||
{
|
||||
newWeaponInfo.model = valueToken; //model of the weapon
|
||||
}
|
||||
else if( token == "weaponindex" )
|
||||
{
|
||||
newWeaponInfo.weaponindex = valueToken.GetIntValue(); //index of weapon in inventory
|
||||
}
|
||||
else if( token == "flags" )
|
||||
{
|
||||
newWeaponInfo.flags = valueToken.GetIntValue(); //special flags
|
||||
}
|
||||
else if( token == "projectile" )
|
||||
{
|
||||
newWeaponInfo.projectile = valueToken; //projectile used by the weapon
|
||||
}
|
||||
else if( token == "numprojectiles" )
|
||||
{
|
||||
newWeaponInfo.numprojectiles = valueToken.GetIntValue(); //number of projectiles
|
||||
}
|
||||
else if( token == "hspread" )
|
||||
{
|
||||
newWeaponInfo.hspread = valueToken.GetFloatValue(); //horizontal spread of projectiles (degrees from middle)
|
||||
}
|
||||
else if( token == "vspread" )
|
||||
{
|
||||
newWeaponInfo.vspread = valueToken.GetFloatValue(); //vertical spread of projectiles (degrees from middle)
|
||||
}
|
||||
else if( token == "speed" )
|
||||
{
|
||||
newWeaponInfo.speed = valueToken.GetFloatValue(); //speed of the projectile (0 = instant hit)
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.Error( "ParseWeaponInfo: Unexpected token %s\n", token.c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idBotWeaponInfoManager::LoadWeaponConfig
|
||||
========================
|
||||
*/
|
||||
void idBotWeaponInfoManager::LoadWeaponConfig( char* filename )
|
||||
{
|
||||
idParser parser;
|
||||
idToken token;
|
||||
int j;
|
||||
|
||||
if( !parser.LoadFile( filename ) )
|
||||
{
|
||||
gameLocal.Error( "Failed to load bot weapon config %s\n", filename );
|
||||
}
|
||||
|
||||
while( parser.ReadToken( &token ) )
|
||||
{
|
||||
if( token == "weaponinfo" )
|
||||
{
|
||||
weaponinfo_t newWeaponInfo;
|
||||
ParseWeaponInfo( parser, newWeaponInfo );
|
||||
|
||||
if( newWeaponInfo.number < 0 || newWeaponInfo.number >= BOT_MAX_WEAPONS )
|
||||
{
|
||||
parser.Error( "weapon info number %d out of range\n", newWeaponInfo.number );
|
||||
return;
|
||||
}
|
||||
|
||||
weaponinfo[newWeaponInfo.number] = newWeaponInfo;
|
||||
weaponinfo[newWeaponInfo.number].valid = true;
|
||||
}
|
||||
else if( token == "projectileinfo" )
|
||||
{
|
||||
projectileinfo_t newProjectileInfo;
|
||||
|
||||
ParseProjectileInfo( parser, newProjectileInfo );
|
||||
|
||||
projectileinfo.Append( newProjectileInfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.Error( "LoadWeaponConfig: Unknown definintion %s", token.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
// fix up weapons.
|
||||
for( int i = 0; i < BOT_MAX_WEAPONS; i++ )
|
||||
{
|
||||
if( !weaponinfo[i].valid )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( weaponinfo[i].name.Length() <= 0 )
|
||||
{
|
||||
parser.Error( "weapon %d has no name\n", i );
|
||||
return;
|
||||
}
|
||||
|
||||
if( weaponinfo[i].projectile.Length() <= 0 )
|
||||
{
|
||||
parser.Error( "weapon %s has no projectile\n", weaponinfo[i].name );
|
||||
return;
|
||||
}
|
||||
|
||||
//find the projectile info and copy it to the weapon info
|
||||
for( j = 0; j < projectileinfo.Num(); j++ )
|
||||
{
|
||||
if( projectileinfo[j].name == weaponinfo[i].projectile )
|
||||
{
|
||||
memcpy( &weaponinfo[i].proj, &projectileinfo[j], sizeof( projectileinfo_t ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j == projectileinfo.Num() )
|
||||
{
|
||||
parser.Error( "weapon %s uses undefined projectile\n", weaponinfo[i].name.c_str() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idBotWeaponInfoManager::Init
|
||||
========================
|
||||
*/
|
||||
void idBotWeaponInfoManager::Init( void )
|
||||
{
|
||||
rvmScopedLexerBaseFolder scopedBaseFolder( BOTFILESBASEFOLDER );
|
||||
|
||||
LoadWeaponConfig( ( char* )bot_weaponsfile.GetString() );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
WeaponWeightIndex
|
||||
=====================
|
||||
*/
|
||||
void idBotWeaponInfoManager::WeaponWeightIndex( weightconfig_t* wwc, bot_weaponstate_t* weaponState )
|
||||
{
|
||||
for( int i = 0; i < BOT_MAX_WEAPONS; i++ )
|
||||
{
|
||||
weaponState->weaponweightindex[i] = botFuzzyWeightManager.FindFuzzyWeight( wwc, ( char* )weaponinfo[i].name.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idBotWeaponInfoManager::WeaponWeightIndex
|
||||
=====================
|
||||
*/
|
||||
void idBotWeaponInfoManager::BotFreeWeaponWeights( int weaponstate )
|
||||
{
|
||||
bot_weaponstate_t* ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle( weaponstate );
|
||||
if( !ws )
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if (ws->weaponweightconfig)
|
||||
// FreeWeightConfig(ws->weaponweightconfig);
|
||||
// if (ws->weaponweightindex) FreeMemory(ws->weaponweightindex);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
BotLoadWeaponWeights
|
||||
=====================
|
||||
*/
|
||||
int idBotWeaponInfoManager::BotLoadWeaponWeights( int weaponstate, char* filename )
|
||||
{
|
||||
bot_weaponstate_t* ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle( weaponstate );
|
||||
if( !ws )
|
||||
{
|
||||
return BLERR_CANNOTLOADWEAPONWEIGHTS;
|
||||
}
|
||||
|
||||
BotFreeWeaponWeights( weaponstate );
|
||||
|
||||
ws->weaponweightconfig = botFuzzyWeightManager.ReadWeightConfig( filename );
|
||||
if( !ws->weaponweightconfig )
|
||||
{
|
||||
gameLocal.Error( "couldn't load weapon config %s\n", filename );
|
||||
return BLERR_CANNOTLOADWEAPONWEIGHTS;
|
||||
}
|
||||
|
||||
WeaponWeightIndex( ws->weaponweightconfig, ws );
|
||||
return BLERR_NOERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idBotWeaponInfoManager::BotGetWeaponInfo
|
||||
=====================
|
||||
*/
|
||||
void idBotWeaponInfoManager::BotGetWeaponInfo( int weaponstate, int weapon, weaponinfo_t* weaponinfo )
|
||||
{
|
||||
bot_weaponstate_t* ws;
|
||||
|
||||
if( !BotValidWeaponNumber( weapon ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
ws = BotWeaponStateFromHandle( weaponstate );
|
||||
if( !ws )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*weaponinfo = this->weaponinfo[weapon];
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idBotWeaponInfoManager::BotChooseBestFightWeapon
|
||||
=====================
|
||||
*/
|
||||
int idBotWeaponInfoManager::BotChooseBestFightWeapon( int weaponstate, int* inventory )
|
||||
{
|
||||
int i, index, bestweapon;
|
||||
float weight, bestweight;
|
||||
bot_weaponstate_t* ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle( weaponstate );
|
||||
if( !ws )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if the bot has no weapon weight configuration
|
||||
if( !ws->weaponweightconfig )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bestweight = 0;
|
||||
bestweapon = 0;
|
||||
for( i = 0; i < BOT_MAX_WEAPONS; i++ )
|
||||
{
|
||||
if( !weaponinfo[i].valid )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
index = ws->weaponweightindex[i];
|
||||
if( index < 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
weight = botFuzzyWeightManager.FuzzyWeight( inventory, ws->weaponweightconfig, index );
|
||||
if( weight > bestweight )
|
||||
{
|
||||
bestweight = weight;
|
||||
bestweapon = i;
|
||||
}
|
||||
}
|
||||
return bestweapon;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idBotWeaponInfoManager::BotResetWeaponState
|
||||
=====================
|
||||
*/
|
||||
void idBotWeaponInfoManager::BotResetWeaponState( int weaponstate )
|
||||
{
|
||||
weightconfig_t* weaponweightconfig;
|
||||
int* weaponweightindex;
|
||||
bot_weaponstate_t* ws;
|
||||
|
||||
ws = BotWeaponStateFromHandle( weaponstate );
|
||||
if( !ws )
|
||||
{
|
||||
return;
|
||||
}
|
||||
weaponweightconfig = ws->weaponweightconfig;
|
||||
weaponweightindex = ws->weaponweightindex;
|
||||
|
||||
//Com_Memset(ws, 0, sizeof(bot_weaponstate_t));
|
||||
ws->weaponweightconfig = weaponweightconfig;
|
||||
memcpy( ws->weaponweightindex, weaponweightindex, sizeof( int ) * BOT_MAX_WEAPONS );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idBotWeaponInfoManager::BotAllocWeaponState
|
||||
=====================
|
||||
*/
|
||||
int idBotWeaponInfoManager::BotAllocWeaponState( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 1; i <= MAX_CLIENTS; i++ )
|
||||
{
|
||||
if( !botweaponstates[i].inUse )
|
||||
{
|
||||
botweaponstates[i].Reset();
|
||||
botweaponstates[i].inUse = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idBotWeaponInfoManager::BotAllocWeaponState
|
||||
=====================
|
||||
*/
|
||||
void idBotWeaponInfoManager::BotFreeWeaponState( int ws )
|
||||
{
|
||||
botweaponstates[ws].inUse = false;
|
||||
botweaponstates[ws].Reset();
|
||||
}
|
||||
Reference in New Issue
Block a user