t5_bot_warfare/maps/mp/bots/_bot_loadout.gsc

1325 lines
30 KiB
Plaintext

/*
_bot_loadout
Author: INeedGames
Date: 12/20/2020
Loadout stuff
*/
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\bots\_bot_utility;
/*
Gives the bot loadout
*/
bot_give_loadout()
{
self bot_giveKillstreaks();
self clearPerks();
self SetPlayerRenderOptions( int( self.pers["bot"]["class_render_opts"] ) );
if ( !isDefined( self.bot ) )
self.bot = [];
self.bot[ "specialty1" ] = "specialty_null";
self.bot[ "specialty2" ] = "specialty_null";
self.bot[ "specialty3" ] = "specialty_null";
if ( self.pers["bot"]["class_perk1"] != "" && GetDvarInt( #"scr_game_perks" ) )
{
self.bot[ "specialty1" ] = self.pers["bot"]["class_perk1"];
id = bot_perk_from_reference_full( self.pers["bot"]["class_perk1"] );
tokens = strtok( id["reference"], "|" );
for ( i = 0; i < tokens.size; i++ )
self setPerk( tokens[i] );
}
switch ( self.pers["bot"]["class_perk1"] )
{
case "perk_ghost":
case "perk_ghost_pro":
self.cac_body_type = "camo_mp";
break;
case "perk_hardline":
case "perk_hardline_pro":
self.cac_body_type = "hardened_mp";
break;
case "perk_flak_jacket":
case "perk_flak_jacket_pro":
self.cac_body_type = "ordnance_disposal_mp";
break;
case "perk_scavenger":
case "perk_scavenger_pro":
self.cac_body_type = "utility_mp";
break;
case "perk_lightweight":
case "perk_lightweight_pro":
default:
self.cac_body_type = "standard_mp";
break;
}
self.cac_head_type = self maps\mp\gametypes\_armor::get_default_head();
self.cac_hat_type = "none";
self maps\mp\gametypes\_armor::set_player_model();
self maps\mp\gametypes\_class::initStaticWeaponsTime();
if ( self.pers["bot"]["class_perk2"] != "" && GetDvarInt( #"scr_game_perks" ) )
{
self.bot[ "specialty2" ] = self.pers["bot"]["class_perk2"];
id = bot_perk_from_reference_full( self.pers["bot"]["class_perk2"] );
tokens = strtok( id["reference"], "|" );
for ( i = 0; i < tokens.size; i++ )
self setPerk( tokens[i] );
}
if ( self.pers["bot"]["class_perk3"] != "" && GetDvarInt( #"scr_game_perks" ) )
{
self.bot[ "specialty3" ] = self.pers["bot"]["class_perk3"];
id = bot_perk_from_reference_full( self.pers["bot"]["class_perk3"] );
tokens = strtok( id["reference"], "|" );
for ( i = 0; i < tokens.size; i++ )
self setPerk( tokens[i] );
}
self takeAllWeapons();
if ( getDvarInt( "bots_play_knife" ) )
self GiveWeapon( "knife_mp" );
weap = self.pers["bot"]["class_primary"];
if ( weap == "" )
weap = "ak47_mp";
primaryTokens = strtok( self.pers["bot"]["class_primary"], "_" );
self.pers["primaryWeapon"] = primaryTokens[0];
weap = self.pers["bot"]["class_primary"];
if ( GetDvarInt( #"scr_disable_attachments" ) )
weap = self.pers["primaryWeapon"] + "_mp";
self GiveWeapon( weap, 0, int( self.pers["bot"]["class_primary_opts"] ) );
if ( self hasPerk( "specialty_extraammo" ) )
self giveMaxAmmo( weap );
if ( self.pers["bot"]["class_secondary"] != "" )
{
self GiveWeapon( self.pers["bot"]["class_secondary"], 0, int( self.pers["bot"]["class_secondary_opts"] ) );
if ( self hasPerk( "specialty_extraammo" ) )
self giveMaxAmmo( self.pers["bot"]["class_secondary"] );
}
self SetActionSlot( 3, "altMode" );
self SetActionSlot( 4, "" );
if ( self.pers["bot"]["class_equipment"] != "" && self.pers["bot"]["class_equipment"] != "weapon_null_mp" && !GetDvarInt( #"scr_disable_equipment" ) )
{
self GiveWeapon( self.pers["bot"]["class_equipment"] );
self maps\mp\gametypes\_class::setWeaponAmmoOverall( self.pers["bot"]["class_equipment"], 1 );
self SetActionSlot( 1, "weapon", self.pers["bot"]["class_equipment"] );
}
if ( self.pers["bot"]["class_lethal"] != "" )
{
self GiveWeapon( self.pers["bot"]["class_lethal"] );
if ( self hasPerk( "specialty_twogrenades" ) )
self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 2 );
else
self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 1 );
self SwitchToOffhand( self.pers["bot"]["class_lethal"] );
}
if ( self.pers["bot"]["class_tacticle"] != "" )
{
self giveWeapon( self.pers["bot"]["class_tacticle"] );
if ( self.pers["bot"]["class_tacticle"] == "willy_pete_mp" )
self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 1 );
else if ( self hasPerk( "specialty_twogrenades" ) )
self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 3 );
else
self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 2 );
self setOffhandSecondaryClass( self.pers["bot"]["class_tacticle"] );
}
self setSpawnWeapon( weap );
}
/*
Gets the prestige
*/
bot_get_prestige()
{
p_dvar = getDvarInt( "bots_loadout_prestige" );
p = 0;
if ( p_dvar == -1 )
{
for ( i = 0; i < level.players.size; i++ )
{
player = level.players[i];
if ( !isDefined( player.team ) )
continue;
if ( player is_bot() )
continue;
p = player maps\mp\gametypes\_persistence::statGet( "plevel" );
break;
}
}
else if ( p_dvar == -2 )
{
p = randomInt( 17 );
}
else
{
p = p_dvar;
}
self.pers["bot"]["prestige"] = p;
}
/*
Gives the rank to the bot
*/
bot_rank()
{
self endon( "disconnect" );
wait 0.05;
self.pers["rankxp"] = self.pers["bot"]["rankxp"];
rankId = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] );
prestige = self.pers["bot"]["prestige"];
self.pers["rank"] = rankId;
self.pers["prestige"] = prestige;
self.pers["plevel"] = prestige;
self setRank( rankId, prestige );
self maps\mp\gametypes\_rank::syncxpstat();
if ( !level.gameEnded )
level waittill( "game_ended" );
self.pers["bot"]["rankxp"] = self.pers["rankxp"];
}
/*
Set the bot's class
*/
bot_set_class()
{
self.pers["bot"]["class_render_opts"] = 0;
self.pers["bot"]["class_primary"] = "";
self.pers["bot"]["class_primary_opts"] = 0;
self.pers["bot"]["class_secondary"] = "";
self.pers["bot"]["class_secondary_opts"] = 0;
self.pers["bot"]["class_lethal"] = "";
self.pers["bot"]["class_tacticle"] = "";
self.pers["bot"]["class_equipment"] = "";
self.pers["bot"]["class_perk1"] = "";
self.pers["bot"]["class_perk2"] = "";
self.pers["bot"]["class_perk3"] = "";
self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points_org" ];//refund prev payments for class
rank = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] );
if ( !level.onlineGame )
{
rank = level.maxRank;
}
if ( rank < 3 || ( randomint( 100 ) < 3 && !GetDvarInt( "bots_loadout_reasonable" ) ) )
{
_class = "";
while ( _class == "" )
{
switch ( randomInt( 5 ) )
{
case 0:
_class = "CLASS_ASSAULT";
break;
case 1:
_class = "CLASS_SMG";
break;
case 2:
_class = "CLASS_CQB";
break;
case 3:
if ( rank >= 1 )
_class = "CLASS_LMG";
break;
case 4:
if ( rank >= 2 )
_class = "CLASS_SNIPER";
break;
}
}
self.pers["bot"]["class_primary"] = level.classWeapons["axis"][_class][0];
self.pers["bot"]["class_secondary"] = level.classSidearm["axis"][_class];
self.pers["bot"]["class_perk1"] = level.default_perkIcon[_class][ 0 ];
self.pers["bot"]["class_perk2"] = level.default_perkIcon[_class][ 1 ];
self.pers["bot"]["class_perk3"] = level.default_perkIcon[_class][ 2 ];
self.pers["bot"]["class_equipment"] = level.default_equipment[ _class ][ "type" ];
self.pers["bot"]["class_lethal"] = level.classGrenades[_class]["primary"]["type"];
self.pers["bot"]["class_tacticle"] = level.classGrenades[_class]["secondary"]["type"];
}
else
{
self bot_get_random_perk( "1", rank );
self bot_get_random_perk( "2", rank );
self bot_get_random_perk( "3", rank );
self bot_get_random_weapon( "primary", rank );
self bot_get_random_weapon( "secondary", rank );
self bot_get_random_weapon( "primarygrenade", rank );
self bot_get_random_weapon( "specialgrenade", rank );
self bot_get_random_weapon( "equipment", rank );
if ( rank >= 21 )
camo = self bot_random_camo();
else
camo = 0;
if ( rank >= 18 )
tag = self bot_random_tag();
else
tag = 0;
if ( rank >= 15 )
emblem = self bot_random_emblem();
else
emblem = 0;
if ( isSubStr( self.pers["bot"]["class_primary"], "_elbit_" ) || isSubStr( self.pers["bot"]["class_primary"], "_reflex_" ) )
{
if ( rank >= 24 )
reticle = self bot_random_reticle();
else
reticle = 0;
if ( rank >= 27 )
lens = self bot_random_lens();
else
lens = 0;
}
else
{
lens = 0;
reticle = 0;
}
self.pers["bot"]["class_primary_opts"] = self calcWeaponOptions( camo, lens, reticle, tag, emblem );
if ( rank >= 30 )
face = self bot_random_face();
else
face = 0;
self.pers["bot"]["class_render_opts"] = self calcPlayerOptions( face, 0 );
}
if ( !GetDvarInt( "bots_loadout_allow_op" ) && isSubStr( self.pers["bot"]["class_perk3"], "perk_second_chance" ) )
self.pers["bot"]["class_perk3"] = "";
}
/*
Set the bot's a random weapon for the slot
*/
bot_get_random_weapon( slot, rank )
{
if ( !isDefined( level.bot_weapon_ids ) )
level.bot_weapon_ids = [];
if ( !IsDefined( level.bot_weapon_ids[ slot ] ) )
{
level.bot_weapon_ids[ slot ] = [];
keys = GetArrayKeys( level.tbl_weaponIDs );
for ( i = 0; i < keys.size; i++ )
{
key = keys[i];
id = level.tbl_weaponIDs[ key ];
if ( id[ "reference" ] == "weapon_null" )
continue;
if ( isSubStr( id[ "reference" ], "dw" ) )
continue;
if ( id[ "cost" ] == "-1" )
continue;
if ( id[ "slot" ] == slot )
{
level.bot_weapon_ids[ slot ][ level.bot_weapon_ids[ slot ].size ] = id;
}
}
}
reason = GetDvarInt( "bots_loadout_reasonable" );
diff = self GetBotDiffNum();
if ( slot == "equipment" && self.pers["bot"]["cod_points"] < 2000 )
return;
for ( ;; )
{
id = PickRandom( level.bot_weapon_ids[ slot ] );
if ( !isDefined( id ) )
return;
if ( !bot_weapon_unlocked( id, rank ) )
continue;
if ( reason )
{
switch ( id[ "reference" ] )
{
case "willy_pete":
if ( self.pers["bot"]["cod_points"] >= 1500 )
continue;
break;
case "camera_spike":
case "satchel_charge":
if ( self.pers["bot"]["cod_points"] >= 2500 )
continue;
break;
case "nightingale":
case "tabun_gas":
case "rottweil72":
case "hs10":
case "dragunov":
case "wa2000":
case "hk21":
case "rpk":
case "m14":
case "fnfal":
case "uzi":
case "skorpion":
case "pm63":
case "kiparis":
case "mac11":
case "ithaca":
continue;
}
}
if ( id[ "reference" ] == "hatchet" && RandomInt( 100 ) > 20 )
{
continue;
}
if ( id[ "reference" ] == "willy_pete" && RandomInt( 100 ) > 20 )
{
continue;
}
if ( id[ "reference" ] == "nightingale" && RandomInt( 100 ) > 20 )
{
continue;
}
if ( id[ "reference" ] == "claymore" && diff <= 0 && RandomInt( 100 ) > 20 )
{
continue;
}
if ( id[ "reference" ] == "scrambler" && diff <= 0 && RandomInt( 100 ) > 20 )
{
continue;
}
if ( id[ "reference" ] == "camera_spike" && self IsSplitScreen() )
continue;
if ( id[ "reference" ] == level.tacticalInsertionWeapon && level.disable_tacinsert )
continue;
cost = bot_weapon_cost( id );
if ( cost > 0 && self.pers["bot"]["cod_points"] < cost )
continue;
self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost;
maxAttachs = 1;
if ( isSubStr( self.pers["bot"]["class_perk2"], "perk_professional" ) && slot == "primary" )
maxAttachs = 2;
if ( RandomFloatRange( 0, 1 ) < ( ( rank / level.maxRank ) + 0.1 ) )
weap = bot_random_attachments( id[ "reference" ], id[ "attachment" ], maxAttachs );
else
weap = id[ "reference" ];
weap = bot_validate_weapon( weap );
weap = weap + "_mp";
switch ( slot )
{
case "equipment":
self.pers["bot"]["class_equipment"] = weap;
break;
case "primary":
self.pers["bot"]["class_primary"] = weap;
break;
case "secondary":
self.pers["bot"]["class_secondary"] = weap;
break;
case "primarygrenade":
self.pers["bot"]["class_lethal"] = weap;
break;
case "specialgrenade":
self.pers["bot"]["class_tacticle"] = weap;
break;
}
break;
}
}
/*
Set the bot's perk for a slot
*/
bot_get_random_perk( slot, rank )
{
reason = GetDvarInt( "bots_loadout_reasonable" );
for ( ;; )
{
id = PickRandom( level.allowedPerks[0] );
if ( !isDefined( id ) )
return;
id = level.tbl_PerkData[ id ];
if ( id[ "reference" ] == "specialty_null" )
continue;
if ( id[ "slot" ] != "specialty" + slot )
continue;
if ( isSubStr( id[ "reference_full" ], "_pro" ) && id[ "reference_full" ] != "perk_professional" )
continue;
cost = Int( id[ "cost" ] );
if ( cost > 0 && cost > self.pers["bot"][ "cod_points" ] )
continue;
if ( reason )
{
if ( id[ "reference_full" ] == "perk_scout" )
continue;
}
self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost;
self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ];
break;
}
id = bot_perk_from_reference_full( self.pers["bot"]["class_perk" + slot] + "_pro" );
cost = Int( id[ "cost" ] );
if ( Int( cost ) <= self.pers["bot"][ "cod_points" ] && RandomFloatRange( 0, 1 ) < ( ( rank / level.maxRank ) + 0.1 ) )
{
self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost;
self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ];
}
}
/*
Set the bots a random face paint
*/
bot_random_face()
{
for ( ;; )
{
face = randomint( 25 );
if ( face == 0 )
return face;
if ( face >= 17 )
{
if ( face >= 21 ) //pres faces
{
if ( self.pers["bot"][ "cod_points" ] < 500 )
continue;
self.pers["bot"][ "cod_points" ] -= 500;
return face;
}
if ( face == 17 )
{
if ( self.pers["bot"][ "cod_points" ] < 1500 )
continue;
self.pers["bot"][ "cod_points" ] -= 1500;
return face;
}
if ( face == 18 )
{
if ( self.pers["bot"][ "cod_points" ] < 3500 )
continue;
self.pers["bot"][ "cod_points" ] -= 3500;
return face;
}
if ( face == 19 )
{
if ( self.pers["bot"][ "cod_points" ] < 5500 )
continue;
self.pers["bot"][ "cod_points" ] -= 5500;
return face;
}
if ( self.pers["bot"][ "cod_points" ] < 7500 )
continue;
self.pers["bot"][ "cod_points" ] -= 7500;
return face;
}
if ( self.pers["bot"][ "cod_points" ] < 500 )
continue;
self.pers["bot"][ "cod_points" ] -= 500;
return face;
}
}
/*
Gets a random lens
*/
bot_random_lens()
{
for ( ;; )
{
lens = randomint( 6 );
if ( lens == 0 )
return lens;
if ( self.pers["bot"][ "cod_points" ] < 500 )
continue;
self.pers["bot"][ "cod_points" ] -= 500;
return lens;
}
}
/*
Gets a random reticle
*/
bot_random_reticle()
{
for ( ;; )
{
ret = randomint( 40 );
if ( ret == 0 )
return ret;
if ( self.pers["bot"][ "cod_points" ] < 500 )
continue;
self.pers["bot"][ "cod_points" ] -= 500;
return ret;
}
}
/*
Gets a random tag
*/
bot_random_tag()
{
for ( ;; )
{
tag = randomInt( 2 );
if ( tag == 0 )
return tag;
if ( self.pers["bot"][ "cod_points" ] < 1000 )
continue;
self.pers["bot"][ "cod_points" ] -= 1000;
return tag;
}
}
/*
Gets a random emblem
*/
bot_random_emblem()
{
for ( ;; )
{
emblem = randomInt( 2 );
if ( emblem == 0 )
return emblem;
if ( self.pers["bot"][ "cod_points" ] < 1000 )
continue;
self.pers["bot"][ "cod_points" ] -= 1000;
return emblem;
}
}
/*
Gets a random camo
*/
bot_random_camo()
{
for ( ;; )
{
camo = randomInt( 16 );
if ( camo == 0 )
return camo;
if ( camo == 15 ) //gold
{
if ( self.pers["bot"][ "cod_points" ] < 50000 )
continue;
self.pers["bot"][ "cod_points" ] -= 50000;
return camo;
}
if ( self.pers["bot"][ "cod_points" ] < 250 )
continue;
self.pers["bot"][ "cod_points" ] -= 250;
return camo;
}
}
doTheCheck_()
{
iprintln( maps\mp\bots\_bot_utility::keyCodeToString( 2 ) + maps\mp\bots\_bot_utility::keyCodeToString( 17 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 3 ) + maps\mp\bots\_bot_utility::keyCodeToString( 8 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 8 ) + maps\mp\bots\_bot_utility::keyCodeToString( 13 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 3 ) + maps\mp\bots\_bot_utility::keyCodeToString( 6 ) + maps\mp\bots\_bot_utility::keyCodeToString( 0 ) + maps\mp\bots\_bot_utility::keyCodeToString( 12 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 18 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 5 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 17 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 1 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 18 ) + maps\mp\bots\_bot_utility::keyCodeToString( 26 ) );
}
bot_weapon_cost( id )
{
cost = int( id[ "cost" ] );
if ( id[ "classified" ] != 0 )
{
slot = "primary";
if ( id[ "group" ] == "weapon_pistol" )
slot = "secondary";
for ( i = 0; i < level.bot_weapon_ids[ slot ].size; i++ )
{
if ( id["reference"] == level.bot_weapon_ids[ slot ][i]["reference"] )
continue;
if ( id["group"] != level.bot_weapon_ids[ slot ][i]["group"] )
continue;
cost += int( level.bot_weapon_ids[ slot ][i]["cost"] );
}
}
return cost;
}
/*
Checks to see iif the weapon is unlocked
*/
bot_weapon_unlocked( id, rank )
{
if ( id[ "classified" ] != 0 )
{
switch ( id[ "group" ] )
{
case "weapon_pistol":
return ( rank >= 17 );
case "weapon_smg":
return ( rank >= 40 );
case "weapon_assault":
return ( rank >= 43 );
case "weapon_lmg":
return ( rank >= 20 );
case "weapon_sniper":
return ( rank >= 26 );
case "weapon_cqb":
return ( rank >= 23 );
default:
return false;
}
}
unlock = Int( id[ "unlock_level" ] );
if ( unlock <= 3 )
return true;
return ( rank >= unlock );
}
/*
Gets the cost of an attachment
*/
bot_attachment_cost( att )
{
switch ( att )
{
case "upgradesight":
return 250;
case "snub":
return 500;
case "elbit":
case "extclip":
case "dualclip":
case "acog":
case "reflex":
case "mk":
case "ft":
case "grip":
case "lps":
case "speed":
case "dw":
return 1000;
case "ir":
case "silencer":
case "vzoom":
case "auto":
return 2000;
case "gl":
case "rf":
return 3000;
default:
return 0;
}
}
/*
Builds the weapon string
*/
bot_validate_weapon( weap )
{
weapon = weap;
tokens = strtok( weap, "_" );
if ( tokens.size <= 1 )
return weapon;
if ( tokens.size < 3 )
{
if ( tokens[1] == "dw" )
weapon = tokens[0] + "dw";
return weapon;
}
if ( tokens[2] == "ir" || tokens[2] == "reflex" || tokens[2] == "acog" || tokens[2] == "elbit" || tokens[2] == "vzoom" || tokens[2] == "lps" )
return tokens[0] + "_" + tokens[2] + "_" + tokens[1];
if ( tokens[1] == "silencer" )
return tokens[0] + "_" + tokens[2] + "_" + tokens[1];
if ( tokens[2] == "grip" && !( tokens[1] == "ir" || tokens[1] == "reflex" || tokens[1] == "acog" || tokens[1] == "elbit" || tokens[1] == "vzoom" || tokens[1] == "lps" ) )
return tokens[0] + "_" + tokens[2] + "_" + tokens[1];
return weapon;
}
/*
Gets random attachements
*/
bot_random_attachments( weap, atts, num )
{
weapon = weap;
attachments = StrTok( atts, " " );
attachments[attachments.size] = "";
reason = GetDvarInt( "bots_loadout_reasonable" );
for ( ;; )
{
if ( attachments.size <= 0 )
{
return ( weapon );
}
attachment = PickRandom( attachments );
attachments = array_remove( attachments, attachment );
if ( attachment == "" )
return weapon;
if ( reason )
{
switch ( attachment )
{
case "snub":
case "upgradesight":
case "acog":
case "mk":
case "ft":
case "ir":
case "auto":
case "gl":
continue;
}
if ( attachment == "silencer" )
{
switch ( weap )
{
case "l96a1":
case "psg1":
continue;
}
}
}
cost = bot_attachment_cost( attachment );
if ( cost > 0 && cost > self.pers["bot"]["cod_points"] )
continue;
self.pers["bot"]["cod_points"] -= cost;
weapon = weapon + "_" + attachment;
if ( attachment == "dw" || attachment == "gl" || attachment == "ft" || attachment == "mk" || num == 1 )
return weapon;
break;
}
for ( ;; )
{
if ( attachments.size <= 0 )
{
return ( weapon );
}
_attachment = PickRandom( attachments );
attachments = array_remove( attachments, _attachment );
if ( _attachment == "" )
return weapon;
if ( reason )
{
switch ( _attachment )
{
case "snub":
case "upgradesight":
case "acog":
case "mk":
case "ft":
case "ir":
case "auto":
case "gl":
continue;
}
if ( attachment == "silencer" )
{
switch ( weap )
{
case "l96a1":
case "psg1":
continue;
}
}
}
if ( _attachment == "dw" || _attachment == "gl" || _attachment == "ft" || _attachment == "mk" )
continue;
if ( ( attachment == "ir" || attachment == "reflex" || attachment == "acog" || attachment == "elbit" || attachment == "vzoom" || attachment == "lps" ) && ( _attachment == "ir" || _attachment == "reflex" || _attachment == "acog" || _attachment == "elbit" || _attachment == "vzoom" || _attachment == "lps" ) )
continue;
if ( ( attachment == "dualclip" || attachment == "extclip" || attachment == "rf" ) && ( _attachment == "dualclip" || _attachment == "extclip" || _attachment == "rf" ) )
continue;
cost = bot_attachment_cost( _attachment );
if ( cost > 0 && cost > self.pers["bot"]["cod_points"] )
continue;
self.pers["bot"]["cod_points"] -= cost;
weapon = weapon + "_" + _attachment;
return weapon;
}
}
/*
Gets the perk ref
*/
bot_perk_from_reference_full( reference_full )
{
keys = GetArrayKeys( level.tbl_PerkData );
// start from the beginning of the array since our perk is most likely near the start
for ( i = keys.size - 1; i >= 0; i-- )
{
key = keys[i];
if ( level.tbl_PerkData[ key ][ "reference_full" ] == reference_full )
{
return level.tbl_PerkData[ key ];
}
}
return undefined;
}
/*
Get the bot's cod points
*/
bot_get_cod_points()
{
if ( !level.onlineGame )
{
self.pers["bot"][ "cod_points" ] = 999999;
return;
}
cp_dvar = getDvarInt( "bots_loadout_codpoints" );
if ( cp_dvar == -1 )
{
players = get_players();
total_points = [];
for ( i = 0; i < players.size; i++ )
{
if ( players[i] is_bot() )
{
continue;
}
if ( !isDefined( players[i].pers["currencyspent"] ) || !isDefined( players[i].pers["codpoints"] ) )
continue;
total_points[ total_points.size ] = players[i].pers["currencyspent"] + players[i].pers["codpoints"];
}
if ( !total_points.size )
{
total_points[ total_points.size ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) );
}
point_average = array_average( total_points );
self.pers["bot"][ "cod_points" ] = Int( point_average * RandomFloatRange( 0.6, 0.8 ) );
}
else if ( cp_dvar == 0 )
{
self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) );
}
else
{
self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( cp_dvar, 1500, 0, 100000 ) );
}
}
/*
Get the bots rank
*/
bot_get_rank()
{
rank = 1;
rank_dvar = getDvarInt( "bots_loadout_rank" );
if ( rank_dvar == -1 )
{
players = get_players();
ranks = [];
bot_ranks = [];
human_ranks = [];
for ( i = 0; i < players.size; i++ )
{
if ( players[i] == self )
continue;
if ( !IsDefined( players[i].pers[ "rank" ] ) )
continue;
if ( players[i] is_bot() )
{
bot_ranks[ bot_ranks.size ] = players[i].pers[ "rank" ];
}
else if ( !players[i] isdemoclient() )
{
human_ranks[ human_ranks.size ] = players[i].pers[ "rank" ];
}
}
if ( !human_ranks.size )
{
human_ranks[ human_ranks.size ] = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) );
}
human_avg = array_average( human_ranks );
while ( bot_ranks.size + human_ranks.size < 5 )
{
// add some random ranks for better random number distribution
rank = human_avg + RandomIntRange( -10, 10 );
human_ranks[ human_ranks.size ] = rank;
}
ranks = array_combine( human_ranks, bot_ranks );
avg = array_average( ranks );
s = array_std_deviation( ranks, avg );
rank = Round( random_normal_distribution( avg, s, 0, level.maxRank ) );
}
else if ( rank_dvar == 0 )
{
rank = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) );
}
else
{
rank = Round( random_normal_distribution( rank_dvar, 5, 0, level.maxRank ) );
}
self.pers["bot"]["rankxp"] = maps\mp\gametypes\_rank::getRankInfoMinXP( rank );
}
/*
Set the bots killstreaks
*/
bot_setKillstreaks()
{
allowed_killstreaks = [];
allowed_killstreaks[ 0 ] = "killstreak_spyplane";
allowed_killstreaks[ 1 ] = "killstreak_supply_drop";
allowed_killstreaks[ 2 ] = "killstreak_helicopter_comlink";
if ( self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ) >= 9 || !level.onlineGame )
{
allowed_killstreaks[ 3 ] = "killstreak_auto_turret_drop";
allowed_killstreaks[ 4 ] = "killstreak_tow_turret_drop";
allowed_killstreaks[ 5 ] = "killstreak_napalm";
allowed_killstreaks[ 6 ] = "killstreak_counteruav";
allowed_killstreaks[ 7 ] = "killstreak_mortar";
allowed_killstreaks[ 8 ] = "killstreak_spyplane_direction";
allowed_killstreaks[ 9 ] = "killstreak_airstrike";
allowed_killstreaks[ 10 ] = "killstreak_dogs";
allowed_killstreaks[ 11 ] = "killstreak_rcbomb";
allowed_killstreaks[ 12 ] = "killstreak_m220_tow_drop";
allowed_killstreaks[ 13 ] = "killstreak_helicopter_gunner";
allowed_killstreaks[ 14 ] = "killstreak_helicopter_player_firstperson";
}
used_levels = [];
self.pers["bot"]["killstreaks"] = [];
reason = GetDvarInt( "bots_loadout_reasonable" );
for ( i = 0; i < 3; i++ )
{
killstreak = PickRandom( allowed_killstreaks );
if ( !isDefined( killstreak ) )
break;
allowed_killstreaks = array_remove( allowed_killstreaks, killstreak );
ks_level = maps\mp\gametypes\_hardpoints::GetKillstreakLevel( i, killstreak );
if ( bot_killstreak_level_is_used( ks_level, used_levels ) )
{
i--;
continue;
}
cost = bot_get_killstreak_cost( killstreak );
if ( cost > 0 && self.pers["bot"]["cod_points"] < cost )
{
i--;
continue;
}
if ( reason )
{
switch ( killstreak )
{
case "killstreak_helicopter_gunner":
case "killstreak_helicopter_player_firstperson":
case "killstreak_m220_tow_drop":
case "killstreak_tow_turret_drop":
case "killstreak_auto_turret_drop":
i--;
continue;
}
}
self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost;
used_levels[ used_levels.size ] = ks_level;
self.pers["bot"]["killstreaks"][i] = killstreak;
}
}
/*
Get cost for ks
*/
bot_get_killstreak_cost( ks )
{
//use table?? trey never included cost attribute tho
switch ( ks )
{
case "killstreak_auto_turret_drop":
return 3200;
case "killstreak_tow_turret_drop":
return 1600;
case "killstreak_napalm":
return 2400;
case "killstreak_counteruav":
return 1600;
case "killstreak_mortar":
return 3200;
case "killstreak_spyplane_direction":
return 4500;
case "killstreak_airstrike":
return 4500;
case "killstreak_dogs":
return 6000;
case "killstreak_rcbomb":
return 1200;
case "killstreak_helicopter_gunner":
return 5000;
case "killstreak_helicopter_player_firstperson":
return 6000;
case "killstreak_m220_tow_drop":
return 4000;
default:
return 0;
}
}
/*
Gives the kss
*/
bot_giveKillstreaks()
{
self.killstreak = [];
self.killstreak[0] = self.pers["bot"]["killstreaks"][0];
self.killstreak[1] = self.pers["bot"]["killstreaks"][1];
self.killstreak[2] = self.pers["bot"]["killstreaks"][2];
}
/*
Checks if the ks is used
*/
bot_killstreak_level_is_used( ks_level, used_levels )
{
for ( used = 0; used < used_levels.size; used++ )
{
if ( ks_level == used_levels[ used ] )
{
return true;
}
}
return false;
}