/* <333cec> ../cstrike/dlls/bot/cs_bot_init.cpp:81 */ void Bot_RegisterCvars(void) { if (UTIL_IsGame("czero")) { CVAR_REGISTER(&cv_bot_traceview); CVAR_REGISTER(&cv_bot_stop); CVAR_REGISTER(&cv_bot_show_nav); CVAR_REGISTER(&cv_bot_show_danger); CVAR_REGISTER(&cv_bot_nav_edit); CVAR_REGISTER(&cv_bot_nav_zdraw); CVAR_REGISTER(&cv_bot_walk); CVAR_REGISTER(&cv_bot_difficulty); CVAR_REGISTER(&cv_bot_debug); CVAR_REGISTER(&cv_bot_quicksave); CVAR_REGISTER(&cv_bot_quota); CVAR_REGISTER(&cv_bot_quota_match); CVAR_REGISTER(&cv_bot_prefix); CVAR_REGISTER(&cv_bot_allow_rogues); CVAR_REGISTER(&cv_bot_allow_pistols); CVAR_REGISTER(&cv_bot_allow_shotguns); CVAR_REGISTER(&cv_bot_allow_sub_machine_guns); CVAR_REGISTER(&cv_bot_allow_rifles); CVAR_REGISTER(&cv_bot_allow_machine_guns); CVAR_REGISTER(&cv_bot_allow_grenades); CVAR_REGISTER(&cv_bot_allow_snipers); CVAR_REGISTER(&cv_bot_allow_shield); CVAR_REGISTER(&cv_bot_join_team); CVAR_REGISTER(&cv_bot_join_after_player); CVAR_REGISTER(&cv_bot_auto_vacate); CVAR_REGISTER(&cv_bot_zombie); CVAR_REGISTER(&cv_bot_defer_to_human); CVAR_REGISTER(&cv_bot_chatter); CVAR_REGISTER(&cv_bot_profile_db); } }
void Regamedll_Game_Init() { g_bIsCzeroGame = UTIL_IsGame("czero"); g_bAllowedCSBot = UTIL_AreBotsAllowed(); // determine whether bots can be used or not g_bHostageImprov = UTIL_AreHostagesImprov(); // determine whether hostage improv can be used or not WeaponInfoReset(); }
/* <36b0e0> ../cstrike/dlls/bot/cs_bot_manager.cpp:375 */ void CCSBotManager::__MAKE_VHOOK(AddServerCommands)(void) { static bool fFirstTime = true; if (!fFirstTime) return; fFirstTime = false; if (UTIL_IsGame("czero")) { AddServerCommand("bot_about"); AddServerCommand("bot_add"); AddServerCommand("bot_add_t"); AddServerCommand("bot_add_ct"); AddServerCommand("bot_kill"); AddServerCommand("bot_kick"); AddServerCommand("bot_knives_only"); AddServerCommand("bot_pistols_only"); AddServerCommand("bot_snipers_only"); AddServerCommand("bot_all_weapons"); AddServerCommand("entity_dump"); AddServerCommand("bot_nav_delete"); AddServerCommand("bot_nav_split"); AddServerCommand("bot_nav_merge"); AddServerCommand("bot_nav_mark"); AddServerCommand("bot_nav_begin_area"); AddServerCommand("bot_nav_end_area"); AddServerCommand("bot_nav_connect"); AddServerCommand("bot_nav_disconnect"); AddServerCommand("bot_nav_splice"); AddServerCommand("bot_nav_crouch"); AddServerCommand("bot_nav_jump"); AddServerCommand("bot_nav_precise"); AddServerCommand("bot_nav_no_jump"); AddServerCommand("bot_nav_analyze"); AddServerCommand("bot_nav_strip"); AddServerCommand("bot_nav_save"); AddServerCommand("bot_nav_load"); AddServerCommand("bot_nav_use_place"); AddServerCommand("bot_nav_place_floodfill"); AddServerCommand("bot_nav_place_pick"); AddServerCommand("bot_nav_toggle_place_mode"); AddServerCommand("bot_nav_toggle_place_painting"); AddServerCommand("bot_goto_mark"); AddServerCommand("bot_memory_usage"); AddServerCommand("bot_nav_mark_unnamed"); AddServerCommand("bot_nav_warp"); AddServerCommand("bot_nav_corner_select"); AddServerCommand("bot_nav_corner_raise"); AddServerCommand("bot_nav_corner_lower"); AddServerCommand("bot_nav_check_consistency"); } }
void CGrenade::C4Think( void ) { if( !IsInWorld() ) { UTIL_Remove( this ); return; } pev->nextthink = gpGlobals->time + 0.12; if( m_flNextFreq <= gpGlobals->time ) { m_flNextFreq = gpGlobals->time + m_flNextFreqInterval; m_flNextFreqInterval *= 0.9; switch( m_iC4Beep ) { case 0 : { m_flAttenu = 1.5; m_sBeepName = "weapons/c4_beep1.wav"; if( UTIL_IsGame( "czero" ) ) { MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 1 ); WRITE_STRING( "bombticking" ); WRITE_BYTE( 255 ); WRITE_SHORT( 140 ); WRITE_SHORT( 0 ); MESSAGE_END(); } break; } case 1 : { m_flAttenu = 1.0; m_sBeepName = "weapons/c4_beep2.wav"; if( UTIL_IsGame( "czero" ) ) { MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 1 ); WRITE_STRING( "bombticking" ); WRITE_BYTE( 255 ); WRITE_SHORT( 70 ); WRITE_SHORT( 0 ); MESSAGE_END(); } break; } case 2 : { m_flAttenu = 0.8; m_sBeepName = "weapons/c4_beep3.wav"; if( UTIL_IsGame( "czero" ) ) { MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 1 ); WRITE_STRING( "bombticking" ); WRITE_BYTE( 255 ); WRITE_SHORT( 40 ); WRITE_SHORT( 0 ); MESSAGE_END(); } break; } case 3 : { m_flAttenu = 0.5; m_sBeepName = "weapons/c4_beep4.wav"; if( UTIL_IsGame( "czero" ) ) { MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 1 ); WRITE_STRING( "bombticking" ); WRITE_BYTE( 255 ); WRITE_SHORT( 30 ); WRITE_SHORT( 0 ); MESSAGE_END(); } break; } case 4 : { m_flAttenu = 0.2; m_sBeepName = "weapons/c4_beep5.wav"; if( UTIL_IsGame( "czero" ) ) { MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 1 ); WRITE_STRING( "bombticking" ); WRITE_BYTE( 255 ); WRITE_SHORT( 20 ); WRITE_SHORT( 0 ); MESSAGE_END(); } break; } } ++m_iC4Beep; } if( m_flNextBeep <= gpGlobals->time ) { m_flNextBeep = gpGlobals->time + 1.4; EMIT_SOUND( ENT( pev ), CHAN_VOICE, m_sBeepName, VOL_NORM, m_flAttenu ); // TODO: Adds support for bots. // TheBots->OnEvent( EVENT_BOMB_BEEP, this, NULL ); } if( m_flNextBlink <= gpGlobals->time ) { m_flNextBlink = gpGlobals->time + 2.0; MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); WRITE_BYTE( TE_GLOWSPRITE ); WRITE_COORD( pev->origin.x ); WRITE_COORD( pev->origin.y ); WRITE_COORD( pev->origin.z + 5.0 ); WRITE_SHORT( g_sModelIndexC4Glow ); WRITE_BYTE( 1 ); WRITE_BYTE( 3 ); WRITE_BYTE( 255 ); MESSAGE_END(); } if( m_flC4Blow <= gpGlobals->time ) { // TODO: Adds support for bots. // TheBots->OnEvent( EVENT_BOMB_EXPLODED, NULL, NULL ); MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 0 ); MESSAGE_END(); if( m_pentCurBombTarget ) { CBaseEntity *pEntity = CBaseEntity::Instance( m_pentCurBombTarget->pev ); if( pEntity ) { CBaseEntity* pPlayer = CBaseEntity::Instance( pev->owner ); if( pPlayer ) { pEntity->Use( pPlayer, this, USE_TOGGLE, 0 ); } } } CBasePlayer* pPlayer = (CBasePlayer *)CBaseEntity::Instance( pev->owner ); if( pPlayer ) { pPlayer->pev->frags += 3; } MESSAGE_BEGIN( MSG_ALL, gmsgBombPickup ); MESSAGE_END(); g_pGameRules->m_fBombDropped = FALSE; if( pev->waterlevel ) UTIL_Remove( this ); else SetThink( &CGrenade::Detonate2 ); } if( m_fStartDefuse ) { CBasePlayer* pDefuser = (CBasePlayer *)((CBaseEntity *)m_hDefuser); if( pDefuser && m_flDefuseCountDown > gpGlobals->time ) { BOOL isOnGround = !!( pDefuser->pev->flags & FL_ONGROUND ); if( m_flNextDefuseTime < gpGlobals->time || !isOnGround ) { if( !isOnGround ) { ClientPrint( m_hDefuser->pev, HUD_PRINTCENTER, "#C4_Defuse_Must_Be_On_Ground" ); } pDefuser->ResetMaxSpeed(); pDefuser->SetProgressBarTime( 0 ); pDefuser->m_fBombDefusing = FALSE; m_fStartDefuse = FALSE; m_flDefuseCountDown = 0.0; // TODO: Adds support for bots. // TheBots->OnEvent( EVENT_DEFUSE_ABORTED, NULL, NULL ); } } else { // TODO: Adds support for bots. // TheBots->OnEvent( EVENT_BOMB_DEFUSED, pDefuser, NULL ); Broadcast( "BOMBDEF" ); MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); WRITE_BYTE( 9 ); WRITE_BYTE( DRC_CMD_EVENT ); WRITE_SHORT( ENTINDEX( this->edict() ) ); WRITE_SHORT( NULL ); WRITE_ENTITY( DRC_FLAG_FINAL | DRC_FLAG_FACEPLAYER | DRC_FLAG_DRAMATIC | 15 ); MESSAGE_END(); UTIL_LogPrintf( "\"%s<%i><%s><CT>\" triggered \"Defused_The_Bomb\"\n", STRING( pDefuser->pev->netname ), GETPLAYERAUTHID( pDefuser->edict() ), GETPLAYERUSERID( pDefuser->edict() ) ); UTIL_EmitAmbientSound( ENT( pev ), pev->origin, "weapons/c4_beep5.wav", 0, ATTN_NONE, SND_STOP, 0 ); EMIT_SOUND( ENT( pDefuser->pev ), CHAN_WEAPON, "weapons/c4_disarmed.wav", 0.8, ATTN_NORM ); UTIL_Remove( this ); m_fJustBlew = TRUE; pDefuser->ResetMaxSpeed(); pDefuser->m_fBombDefusing = FALSE; MESSAGE_BEGIN( MSG_ALL, gmsgScenarioIcon ); WRITE_BYTE( 0 ); MESSAGE_END(); if( g_pGameRules->IsCareer() ) { // TODO: Adds support for bots. //TheCareerTasks->HandleEvents( EVEN_BOMB_DEFUSED, pDefuser, NULL ); } g_pGameRules->m_bBombDefused = TRUE; g_pGameRules->CheckWinConditions(); pDefuser->pev->frags += 3; MESSAGE_BEGIN( MSG_ALL, gmsgBombPickup ); MESSAGE_END(); g_pGameRules->m_fBombDropped = FALSE; m_fStartDefuse = FALSE; } } }
/* <36b780> ../cstrike/dlls/bot/cs_bot_manager.cpp:1109 */ void CCSBotManager::ValidateMapData(void) { if (IMPLEMENT_ARRAY(m_isMapDataLoaded) || !UTIL_IsGame("czero")) { return; } IMPLEMENT_ARRAY(m_isMapDataLoaded) = true; // TODO: Reverse me if (LoadNavigationMap()) { CONSOLE_ECHO("Failed to load navigation map.\n"); return; } CONSOLE_ECHO("Navigation map loaded.\n"); m_zoneCount = 0; m_gameScenario = SCENARIO_DEATHMATCH; // Search all entities in the map and set the game type and // store all zones (bomb target, etc). CBaseEntity *entity = NULL; int i; for (i = 1; i < gpGlobals->maxEntities; i++) { entity = CBaseEntity::Instance(INDEXENT(i)); if (entity == NULL) continue; bool found = false; bool isLegacy = false; if (FClassnameIs(entity->pev, "func_bomb_target")) { found = true; isLegacy = false; m_gameScenario = SCENARIO_DEFUSE_BOMB; } else if (FClassnameIs(entity->pev, "info_bomb_target")) { found = true; isLegacy = true; m_gameScenario = SCENARIO_DEFUSE_BOMB; } else if (FClassnameIs(entity->pev, "func_hostage_rescue")) { found = true; isLegacy = false; m_gameScenario = SCENARIO_RESCUE_HOSTAGES; } else if (FClassnameIs(entity->pev, "info_hostage_rescue")) { found = true; isLegacy = true; m_gameScenario = SCENARIO_RESCUE_HOSTAGES; } else if (FClassnameIs(entity->pev, "hostage_entity")) { // some very old maps (ie: cs_assault) use info_player_start // as rescue zones, so set the scenario if there are hostages // in the map m_gameScenario = SCENARIO_RESCUE_HOSTAGES; } else if (FClassnameIs(entity->pev, "func_vip_safetyzone")) { found = true; isLegacy = false; m_gameScenario = SCENARIO_ESCORT_VIP; } if (found) { if (m_zoneCount < MAX_ZONES) { if (isLegacy) m_zone[ m_zoneCount ].m_center = entity->pev->origin; else m_zone[ m_zoneCount ].m_center = (entity->pev->absmax + entity->pev->absmin) / 2.0f; m_zone[ m_zoneCount ].m_isLegacy = isLegacy; m_zone[ m_zoneCount ].m_index = m_zoneCount; m_zone[ m_zoneCount ].m_entity = entity; ++m_zoneCount; } else CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n"); } } // If there are no zones and the scenario is hostage rescue, // use the info_player_start entities as rescue zones. if (m_zoneCount == 0 && m_gameScenario == SCENARIO_RESCUE_HOSTAGES) { entity = NULL; while ((entity = UTIL_FindEntityByClassname(entity, "info_player_start")) != NULL) { if (FNullEnt(entity->edict())) break; if (m_zoneCount < MAX_ZONES) { m_zone[ m_zoneCount ].m_center = entity->pev->origin; m_zone[ m_zoneCount ].m_isLegacy = true; m_zone[ m_zoneCount ].m_index = m_zoneCount; m_zone[ m_zoneCount ].m_entity = entity; ++m_zoneCount; } else CONSOLE_ECHO("Warning: Too many zones, some will be ignored.\n"); } } // Collect nav areas that overlap each zone for (i = 0; i < m_zoneCount; i++) { Zone *zone = &m_zone[i]; if (zone->m_isLegacy) { const float legacyRange = 256.0f; zone->m_extent.lo.x = zone->m_center.x - legacyRange; zone->m_extent.lo.y = zone->m_center.y - legacyRange; zone->m_extent.lo.z = zone->m_center.z - legacyRange; zone->m_extent.hi.x = zone->m_center.x + legacyRange; zone->m_extent.hi.y = zone->m_center.y + legacyRange; zone->m_extent.hi.z = zone->m_center.z + legacyRange; } else { zone->m_extent.lo = zone->m_entity->pev->absmin; zone->m_extent.hi = zone->m_entity->pev->absmax; } // ensure Z overlap const float zFudge = 50.0f; zone->m_areaCount = 0; zone->m_extent.lo.z -= zFudge; zone->m_extent.hi.z += zFudge; // build a list of nav areas that overlap this zone for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) { CNavArea *area = (*iter); const Extent *areaExtent = area->GetExtent(); if (areaExtent->hi.x >= zone->m_extent.lo.x && areaExtent->lo.x <= zone->m_extent.hi.x && areaExtent->hi.y >= zone->m_extent.lo.y && areaExtent->lo.y <= zone->m_extent.hi.y && areaExtent->hi.z >= zone->m_extent.lo.z && areaExtent->lo.z <= zone->m_extent.hi.z) { // area overlaps zone zone->m_area[ zone->m_areaCount++ ] = area; if (zone->m_areaCount == MAX_ZONE_NAV_AREAS) { break; } } } } }
/* <36ace2> ../cstrike/dlls/bot/cs_bot_manager.cpp:484 */ void CCSBotManager::__MAKE_VHOOK(ServerCommand)(const char *pcmd) { if (!m_bServerActive || !UTIL_IsGame("czero")) return; char buffer[400]; const char *msg = CMD_ARGV(1); if (FStrEq(pcmd, "bot_about")) { Q_sprintf(buffer, "\n--------------------------------------------------------------------------\nThe Official Counter-Strike Bot V%d.%02d\nCreated by Michael S. Booth\nWeb: www.turtlerockstudios.com\\csbot\nE-mail: [email protected]\n--------------------------------------------------------------------------\n\n", CSBOT_VERSION_MAJOR, CSBOT_VERSION_MINOR); CONSOLE_ECHO(buffer); HintMessageToAllPlayers(buffer); } else if (FStrEq(pcmd, "bot_add")) { BotAddCommand(BOT_TEAM_ANY); } else if (FStrEq(pcmd, "bot_add_t")) { BotAddCommand(BOT_TEAM_T); } else if (FStrEq(pcmd, "bot_add_ct")) { BotAddCommand(BOT_TEAM_CT); } else if (FStrEq(pcmd, "bot_kill")) { bool killThemAll; if (CMD_ARGC() == 1 || FStrEq(msg, "all")) killThemAll = true; else killThemAll = false; for (int iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(iIndex); if (pPlayer == NULL) continue; if (FNullEnt(pPlayer->pev)) continue; const char *name = STRING(pPlayer->pev->netname); if (FStrEq(name, "")) continue; if (pPlayer->IsBot()) { if (killThemAll || FStrEq(name, msg)) { pPlayer->TakeDamage(pPlayer->pev, pPlayer->pev, 9999.9f, DMG_CRUSH); } } } } else if (FStrEq(pcmd, "bot_kick")) { bool kickThemAll; if (CMD_ARGC() == 1 || FStrEq(msg, "all")) kickThemAll = true; else kickThemAll = false; for (int iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(iIndex); if (pPlayer == NULL) continue; if (FNullEnt(pPlayer->pev)) continue; const char *name = STRING(pPlayer->pev->netname); if (FStrEq(name, "")) continue; if (pPlayer->IsBot()) { if (kickThemAll || FStrEq(name, msg)) { SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", name)); CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value - 1); } } } if (kickThemAll || cv_bot_quota.value < 0.0f) { CVAR_SET_FLOAT("bot_quota", 0); } } else if (FStrEq(pcmd, "bot_knives_only")) { CVAR_SET_FLOAT("bot_allow_pistols", 0); CVAR_SET_FLOAT("bot_allow_shotguns", 0); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_rifles", 0); CVAR_SET_FLOAT("bot_allow_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_grenades", 0); CVAR_SET_FLOAT("bot_allow_snipers", 0); CVAR_SET_FLOAT("bot_allow_shield", 0); } else if (FStrEq(pcmd, "bot_pistols_only")) { CVAR_SET_FLOAT("bot_allow_pistols", 1); CVAR_SET_FLOAT("bot_allow_shotguns", 0); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_rifles", 0); CVAR_SET_FLOAT("bot_allow_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_grenades", 0); CVAR_SET_FLOAT("bot_allow_snipers", 0); CVAR_SET_FLOAT("bot_allow_shield", 0); } else if (FStrEq(pcmd, "bot_snipers_only")) { CVAR_SET_FLOAT("bot_allow_pistols", 1); CVAR_SET_FLOAT("bot_allow_shotguns", 0); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_rifles", 0); CVAR_SET_FLOAT("bot_allow_machine_guns", 0); CVAR_SET_FLOAT("bot_allow_grenades", 0); CVAR_SET_FLOAT("bot_allow_snipers", 1); CVAR_SET_FLOAT("bot_allow_shield", 0); } else if (FStrEq(pcmd, "bot_all_weapons")) { CVAR_SET_FLOAT("bot_allow_pistols", 1); CVAR_SET_FLOAT("bot_allow_shotguns", 1); CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 1); CVAR_SET_FLOAT("bot_allow_rifles", 1); CVAR_SET_FLOAT("bot_allow_machine_guns", 1); CVAR_SET_FLOAT("bot_allow_grenades", 1); CVAR_SET_FLOAT("bot_allow_snipers", 1); CVAR_SET_FLOAT("bot_allow_shield", 1); } else if (FStrEq(pcmd, "entity_dump")) { PrintAllEntities(); } else if (FStrEq(pcmd, "bot_nav_delete")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_DELETE; } else if (FStrEq(pcmd, "bot_nav_split")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SPLIT; } else if (FStrEq(pcmd, "bot_nav_merge")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MERGE; } else if (FStrEq(pcmd, "bot_nav_mark")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MARK; } else if (FStrEq(pcmd, "bot_nav_begin_area")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_BEGIN_AREA; } else if (FStrEq(pcmd, "bot_nav_end_area")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_END_AREA; } else if (FStrEq(pcmd, "bot_nav_connect")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_CONNECT; } else if (FStrEq(pcmd, "bot_nav_disconnect")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_DISCONNECT; } else if (FStrEq(pcmd, "bot_nav_splice")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SPLICE; } else if (FStrEq(pcmd, "bot_nav_crouch")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_CROUCH; } else if (FStrEq(pcmd, "bot_nav_jump")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_JUMP; } else if (FStrEq(pcmd, "bot_nav_precise")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_PRECISE; } else if (FStrEq(pcmd, "bot_nav_no_jump")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_NO_JUMP; } else if (FStrEq(pcmd, "bot_nav_analyze")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_isAnalysisRequested) = true; } else if (FStrEq(pcmd, "bot_nav_strip")) { StripNavigationAreas();// TODO: reverse me } else if (FStrEq(pcmd, "bot_nav_save")) { GET_GAME_DIR(buffer); buffer[ Q_strlen(buffer) ] = '\\'; Q_strcat(buffer, CBotManager::GetNavMapFilename()); if (SaveNavigationMap(buffer))// TODO: reverse me CONSOLE_ECHO("Navigation map '%s' saved.\n", buffer); else CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", buffer); } else if (FStrEq(pcmd, "bot_nav_load")) { ValidateMapData(); } else if (FStrEq(pcmd, "bot_nav_use_place")) { if (CMD_ARGC() == 1) { int i = 0; const BotPhraseList *placeList = TheBotPhrases->GetPlaceList(); for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter, i++) { if ((*iter)->GetID() == GetNavPlace()) CONSOLE_ECHO("--> %-26s", (*iter)->GetName()); else CONSOLE_ECHO("%-30s", (*iter)->GetName()); if (!(i % 3)) CONSOLE_ECHO("\n"); } CONSOLE_ECHO("\n"); } else { const BotPhraseList *placeList = TheBotPhrases->GetPlaceList(); const BotPhrase *found = NULL; bool isAmbiguous = false; for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter) { if (!Q_strnicmp((*iter)->GetName(), msg, Q_strlen(msg))) { if (!Q_strcmp((*iter)->GetName(), msg)) { found = (*iter); break; } if (found != NULL) isAmbiguous = true; else found = (*iter); } } if (isAmbiguous) { CONSOLE_ECHO("Ambiguous\n"); return; } if (found != NULL) { CONSOLE_ECHO("Current place set to '%s'\n", found->GetName()); m_navPlace = found->GetID(); } } } else if (FStrEq(pcmd, "bot_nav_toggle_place_mode")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_TOGGLE_PLACE_MODE; } else if (FStrEq(pcmd, "bot_nav_place_floodfill")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_PLACE_FLOODFILL; } else if (FStrEq(pcmd, "bot_nav_place_pick")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_PLACE_PICK; } else if (FStrEq(pcmd, "bot_nav_toggle_place_painting")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_TOGGLE_PLACE_PAINTING; } else if (FStrEq(pcmd, "bot_goto_mark")) { // tell the first bot we find to go to our marked area CNavArea *area = GetMarkedArea();// TODO: reverse me if (area != NULL) { CBaseEntity *pEntity = NULL; while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL) { if (!pEntity->IsPlayer()) continue; if ((pEntity->pev->flags & FL_DORMANT) == FL_DORMANT) continue; CBasePlayer *playerOrBot = GetClassPtr((CBasePlayer *)pEntity->pev); if (playerOrBot->IsBot()) { CCSBot *bot = reinterpret_cast<CCSBot *>(playerOrBot); bot->MoveTo(&area->m_center, FASTEST_ROUTE);// TODO: reverse me return; } } } } else if (FStrEq(pcmd, "bot_memory_usage")) { CONSOLE_ECHO("Memory usage:\n"); CONSOLE_ECHO(" %d bytes per bot\b", sizeof(CCSBot)); CONSOLE_ECHO(" %d Navigation Areas @ %d bytes each = %d bytes\n", TheNavAreaGrid.GetNavAreaCount(), sizeof(CNavArea), TheNavAreaGrid.GetNavAreaCount() * sizeof(CNavArea)); CONSOLE_ECHO(" %d Hiding Spots @ %d bytes each = %d bytes\n", TheHidingSpotList.size(), sizeof(HidingSpot), sizeof(HidingSpot) * TheHidingSpotList.size()); unsigned int encounterMem = 0; for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) { CNavArea *area = (*iter); for (SpotEncounterList::iterator siter = area->m_spotEncounterList.begin(); siter != area->m_spotEncounterList.end(); ++siter) { // TODO: Fix me, this is crashed in HOOK_GAMEDLL SpotEncounter se = (*siter); encounterMem += sizeof(SpotEncounter); encounterMem += sizeof(SpotOrder) * se.spotList.size(); } } CONSOLE_ECHO(" Encounter Spot data = %d bytes\n", encounterMem); } else if (FStrEq(pcmd, "bot_nav_mark_unnamed")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MARK_UNNAMED; } else if (FStrEq(pcmd, "bot_nav_warp")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_WARP_TO_MARK; } else if (FStrEq(pcmd, "bot_nav_corner_select")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SELECT_CORNER; } else if (FStrEq(pcmd, "bot_nav_corner_raise")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_RAISE_CORNER; } else if (FStrEq(pcmd, "bot_nav_corner_lower")) { IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_LOWER_CORNER; } else if (FStrEq(pcmd, "bot_nav_check_consistency")) { if (CMD_ARGC() != 2) { CONSOLE_ECHO("usage: bot_nav_check_consistency <filename>\n"); return; } SanityCheckNavigationMap(msg);// TODO: reverse me } }
/** * Load the bot profile database */ void BotProfileManager::Init( const char *filename, unsigned int *checksum ) { int dataLength; char *dataPointer = (char *)LOAD_FILE_FOR_ME( const_cast<char *>( filename ), &dataLength ); const char *dataFile = dataPointer; if (dataFile == NULL) { if ( UTIL_IsGame( "czero" ) ) { CONSOLE_ECHO( "WARNING: Cannot access bot profile database '%s'\n", filename ); } return; } // compute simple checksum if (checksum) { *checksum = ComputeSimpleChecksum( (const unsigned char *)dataPointer, dataLength ); } // keep list of templates used for inheritance BotProfileList templateList; BotProfile defaultProfile; // // Parse the BotProfile.db into BotProfile instances // while( true ) { dataFile = SharedParse( dataFile ); if (!dataFile) break; char *token = SharedGetToken(); bool isDefault = (!stricmp( token, "Default" )); bool isTemplate = (!stricmp( token, "Template" )); bool isCustomSkin = (!stricmp( token, "Skin" )); if ( isCustomSkin ) { const int BufLen = 64; char skinName[BufLen]; // get skin name dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected skin name\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); snprintf( skinName, BufLen, "%s", token ); // get attribute name dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected 'Model'\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); if (stricmp( "Model", token )) { CONSOLE_ECHO( "Error parsing %s - expected 'Model'\n", filename ); FREE_FILE( dataPointer ); return; } // eat '=' dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected '='\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); if (strcmp( "=", token )) { CONSOLE_ECHO( "Error parsing %s - expected '='\n", filename ); FREE_FILE( dataPointer ); return; } // get attribute value dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected attribute value\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); const char *decoratedName = GetDecoratedSkinName( skinName, filename ); bool skinExists = GetCustomSkinIndex( decoratedName ) > 0; if ( m_nextSkin < NumCustomSkins && !skinExists ) { // decorate the name m_skins[ m_nextSkin ] = CloneString( decoratedName ); // construct the model filename m_skinModelnames[ m_nextSkin ] = CloneString( token ); m_skinFilenames[ m_nextSkin ] = new char[ strlen(token)*2 + strlen("models/player//.mdl") + 1 ]; sprintf( m_skinFilenames[ m_nextSkin ], "models/player/%s/%s.mdl", token, token ); ++m_nextSkin; } // eat 'End' dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected 'End'\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); if (strcmp( "End", token )) { CONSOLE_ECHO( "Error parsing %s - expected 'End'\n", filename ); FREE_FILE( dataPointer ); return; } continue; // it's just a custom skin - no need to do inheritance on a bot profile, etc. } // encountered a new profile BotProfile *profile; if (isDefault) { profile = &defaultProfile; } else { profile = new BotProfile; // always inherit from Default *profile = defaultProfile; } // do inheritance in order of appearance if (!isTemplate && !isDefault) { const BotProfile *inherit = NULL; // template names are separated by "+" while(true) { char *c = strchr( token, '+' ); if (c) *c = '\000'; // find the given template name for( BotProfileList::iterator iter = templateList.begin(); iter != templateList.end(); ++iter ) { if (!stricmp( (*iter)->GetName(), token )) { inherit = *iter; break; } } if (inherit == NULL) { CONSOLE_ECHO( "Error parsing '%s' - invalid template reference '%s'\n", filename, token ); FREE_FILE( dataPointer ); return; } // inherit the data profile->Inherit( inherit, &defaultProfile ); if (c == NULL) break; token = c+1; } } // get name of this profile if (!isDefault) { dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing '%s' - expected name\n", filename ); FREE_FILE( dataPointer ); return; } profile->m_name = CloneString( SharedGetToken() ); /** * HACK HACK * Until we have a generalized means of storing bot preferences, we're going to hardcode the bot's * preference towards silencers based on his name. */ if ( profile->m_name[0] % 2 ) { profile->m_prefersSilencer = true; } } // read attributes for this profile bool isFirstWeaponPref = true; while( true ) { // get next token dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected 'End'\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); // check for End delimiter if (!stricmp( token, "End" )) break; // found attribute name - keep it char attributeName[64]; strcpy( attributeName, token ); // eat '=' dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected '='\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); if (strcmp( "=", token )) { CONSOLE_ECHO( "Error parsing %s - expected '='\n", filename ); FREE_FILE( dataPointer ); return; } // get attribute value dataFile = SharedParse( dataFile ); if (!dataFile) { CONSOLE_ECHO( "Error parsing %s - expected attribute value\n", filename ); FREE_FILE( dataPointer ); return; } token = SharedGetToken(); // store value in appropriate attribute if (!stricmp( "Aggression", attributeName )) { profile->m_aggression = atof(token) / 100.0f; } else if (!stricmp( "Skill", attributeName )) { profile->m_skill = atof(token) / 100.0f; } else if (!stricmp( "Skin", attributeName )) { profile->m_skin = atoi(token); if ( profile->m_skin == 0 ) { // atoi() failed - try to look up a custom skin by name profile->m_skin = GetCustomSkinIndex( token, filename ); } } else if (!stricmp( "Teamwork", attributeName )) { profile->m_teamwork = atof(token) / 100.0f; } else if (!stricmp( "Cost", attributeName )) { profile->m_cost = atoi(token); } else if (!stricmp( "VoicePitch", attributeName )) { profile->m_voicePitch = atoi(token); } else if (!stricmp( "VoiceBank", attributeName )) { profile->m_voiceBank = FindVoiceBankIndex( token ); } else if (!stricmp( "WeaponPreference", attributeName )) { // weapon preferences override parent prefs if (isFirstWeaponPref) { isFirstWeaponPref = false; profile->m_weaponPreferenceCount = 0; } if (!stricmp( token, "none" )) { profile->m_weaponPreferenceCount = 0; } else { if (profile->m_weaponPreferenceCount < BotProfile::MAX_WEAPON_PREFS) { profile->m_weaponPreference[ profile->m_weaponPreferenceCount++ ] = AliasToWeaponID( token ); } } } else if (!stricmp( "ReactionTime", attributeName )) { profile->m_reactionTime = atof(token); #ifndef GAMEUI_EXPORTS // subtract off latency due to "think" update rate. // In GameUI, we don't really care. profile->m_reactionTime -= g_flBotFullThinkInterval; #endif } else if (!stricmp( "AttackDelay", attributeName )) { profile->m_attackDelay = atof(token); } else if (!stricmp( "Difficulty", attributeName )) { // override inheritance profile->m_difficultyFlags = 0; // parse bit flags while(true) { char *c = strchr( token, '+' ); if (c) *c = '\000'; for( int i=0; i<NUM_DIFFICULTY_LEVELS; ++i ) if (!stricmp( BotDifficultyName[i], token )) profile->m_difficultyFlags |= (1 << i); if (c == NULL) break; token = c+1; } } else if (!stricmp( "Team", attributeName )) { if ( !stricmp( token, "T" ) ) { profile->m_teams = BOT_TEAM_T; } else if ( !stricmp( token, "CT" ) ) { profile->m_teams = BOT_TEAM_CT; } else { profile->m_teams = BOT_TEAM_ANY; } } else { CONSOLE_ECHO( "Error parsing %s - unknown attribute '%s'\n", filename, attributeName ); } } if (!isDefault) { if (isTemplate) { // add to template list templateList.push_back( profile ); } else { // add profile to the master list m_profileList.push_back( profile ); } } } FREE_FILE( dataPointer ); // free the templates for( BotProfileList::iterator iter = templateList.begin(); iter != templateList.end(); ++iter ) delete *iter; }