Beispiel #1
0
/* <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);
	}
}
Beispiel #2
0
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");
	}
}
Beispiel #4
0
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
	}
}
Beispiel #7
0
/**
 * 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;
}