bool CNewRecharge::KeyValue( const char *szKeyName, const char *szValue )
{
	if (	FStrEq(szKeyName, "style") ||
				FStrEq(szKeyName, "height") ||
				FStrEq(szKeyName, "value1") ||
				FStrEq(szKeyName, "value2") ||
				FStrEq(szKeyName, "value3"))
	{
	}
	else if (FStrEq(szKeyName, "dmdelay"))
	{
		m_iReactivate = atoi(szValue);
	}
	else
	{
		return BaseClass::KeyValue( szKeyName, szValue );
	}

	return true;
}
void CElectrifiedWire::KeyValue( KeyValueData* pkvd )
{
	if( FStrEq( pkvd->szKeyName, "sparkfrequency" ) )
	{
		m_iTipSparkFrequency = strtol( pkvd->szValue, nullptr, 10 );

		pkvd->fHandled = true;
	}
	else if( FStrEq( pkvd->szKeyName, "bodysparkfrequency" ) )
	{
		m_iBodySparkFrequency = strtol( pkvd->szValue, nullptr, 10 );

		pkvd->fHandled = true;
	}
	else if( FStrEq( pkvd->szKeyName, "lightningfrequency" ) )
	{
		m_iLightningFrequency = strtol( pkvd->szValue, nullptr, 10 );

		pkvd->fHandled = true;
	}
	else if( FStrEq( pkvd->szKeyName, "xforce" ) )
	{
		m_iXJoltForce = strtol( pkvd->szValue, nullptr, 10 );

		pkvd->fHandled = true;
	}
	else if( FStrEq( pkvd->szKeyName, "yforce" ) )
	{
		m_iYJoltForce = strtol( pkvd->szValue, nullptr, 10 );

		pkvd->fHandled = true;
	}
	else if( FStrEq( pkvd->szKeyName, "zforce" ) )
	{
		m_iZJoltForce = strtol( pkvd->szValue, nullptr, 10 );

		pkvd->fHandled = true;
	}
	else
		BaseClass::KeyValue( pkvd );
}
Beispiel #3
0
int CSqueakGrenade::IRelationship( CBaseEntity *pTarget ) {
	if ( gameplayMods::snarkFriendlyToPlayer.isActive() ) {
		if ( FStrEq( "player", STRING( pTarget->pev->classname ) ) ) {
			return R_AL;
		} else if (
			FStrEq( "monster_bullchicken", STRING( pTarget->pev->classname ) ) ||
			FStrEq( "monster_alien_grunt", STRING( pTarget->pev->classname ) ) ||
			FStrEq( "monster_alien_slave", STRING( pTarget->pev->classname ) )
		) {
			return R_DL;
		}
	}

	if ( gameplayMods::snarkFriendlyToAllies.isActive() &&
			FStrEq( "monster_scientist", STRING( pTarget->pev->classname ) ) ||
			FStrEq( "monster_barney", STRING( pTarget->pev->classname ) )
	) {
		return R_AL;
	}

	return CGrenade::IRelationship( pTarget );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudControlPointIcons::FireGameEvent( IGameEvent *event )
{
	const char *eventname = event->GetName();
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();

	if ( FStrEq( "controlpoint_initialized", eventname ) )
	{
		// Create our control points
		InitIcons();
		return;
	}

	if ( FStrEq( "controlpoint_updateimages", eventname ) )
	{
		// Update the images of our control point icons
		int iIndex = event->GetInt( "index" );
		if ( iIndex == -1 )
		{
			for (int i = 0; i < m_Icons.Count(); i++)
			{
				m_Icons[i]->UpdateImage();
			}
		}
		else
		{
			// Only invalidate the specified cap point
			for (int i = 0; i < m_Icons.Count(); i++)
			{
				if ( m_Icons[i]->GetCapIndex() == iIndex )
				{
					m_Icons[i]->UpdateImage();
				}
			}
		}
		UpdateProgressBarFor( iIndex );
		return;
	}

	if ( FStrEq( "controlpoint_updatelayout", eventname ) )
	{
		// Update the layout of our control point icons
		int iIndex = event->GetInt( "index" );
		if ( iIndex == -1 )
		{
			InvalidateLayout();
		}
		else
		{
			// Only invalidate the specified cap point
			for (int i = 0; i < m_Icons.Count(); i++)
			{
				if ( m_Icons[i]->GetCapIndex() == iIndex )
				{
					m_Icons[i]->InvalidateLayout();
				}
			}
		}
		UpdateProgressBarFor( iIndex );
		return;
	}

	if ( FStrEq( "controlpoint_updatecapping", eventname ) )
	{
		// Update the capping status of our control point icons
		int iIndex = event->GetInt( "index" );
		if ( iIndex == -1 )
		{
			for (int i = 0; i < m_Icons.Count(); i++)
			{
				m_Icons[i]->UpdateCapImage();
			}
		}
		else
		{
			// Only invalidate the specified cap point
			for (int i = 0; i < m_Icons.Count(); i++)
			{
				if ( m_Icons[i]->GetCapIndex() == iIndex )
				{
					m_Icons[i]->UpdateCapImage();
				}
			}
		}

		UpdateProgressBarFor( iIndex );
		return;
	}

	if ( FStrEq( "controlpoint_starttouch", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			m_iCurrentCP = event->GetInt( "area" );
			UpdateProgressBarFor( m_iCurrentCP );
		}
	}
	else if ( FStrEq( "controlpoint_endtouch", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			m_iCurrentCP = -1;
			UpdateProgressBarFor( m_iCurrentCP );
		}
	}
	else if ( FStrEq( "controlpoint_pulse_element", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			for (int i = 0; i < m_Icons.Count(); i++)
			{
				m_Icons[i]->FakePulse( gpGlobals->curtime + (i * PULSE_TIME_PER_ICON) );
			}
		}
	}
	else if ( FStrEq( "controlpoint_fake_capture", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			m_iCurrentCP = event->GetInt( "int_data" );
			m_bFakingCapture = true;
			m_bFakingCaptureMult = false;
			m_flFakeCaptureTime = gpGlobals->curtime + FAKE_CAPTURE_TIME + FAKE_CAPTURE_POST_PAUSE;
			UpdateProgressBarFor( -1 );
		}
	}
	else if ( FStrEq( "controlpoint_fake_capture_mult", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			m_iCurrentCP = event->GetInt( "int_data" );
			m_bFakingCapture = true;
			m_bFakingCaptureMult = true;
			m_flFakeCaptureTime = gpGlobals->curtime + FAKE_CAPTURE_TIME + FAKE_CAPTURE_POST_PAUSE;
			UpdateProgressBarFor( -1 );
		}
	}
	else if ( FStrEq( "intro_nextcamera", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			m_iCurrentCP = -1;
			m_bFakingCapture = false;
			m_bFakingCaptureMult = false;
			UpdateProgressBarFor( -1 );
		}
	}
	else if ( FStrEq( "intro_finish", eventname ) )
	{
		int iPlayer = event->GetInt( "player" );
		if ( pPlayer && iPlayer == pPlayer->entindex() )
		{
			m_iCurrentCP = -1;
			m_flPulseTime = 0;
			m_bFakingCapture = false;
			m_bFakingCaptureMult = false;

			InitIcons();
		}
	}
}
	virtual void ParseKeyValue( void *pData, const char *pKey, const char *pValue )
	{
		breakmodel_t *pModel = (breakmodel_t *)pData;
		if ( !strcmpi( pKey, "model" ) )
		{
			ParseModelName( pModel, pValue );
		}
		else if (!strcmpi( pKey, "ragdoll" ) )
		{
			ParseModelName( pModel, pValue );
			pModel->isRagdoll = true;
		}
		else if (!strcmpi( pKey, "motiondisabled" ) )
		{
			pModel->isMotionDisabled = true;
		}
		else if ( !strcmpi( pKey, "offset" ) )
		{
			UTIL_StringToVector( pModel->offset.Base(), pValue );
		}
		else if ( !strcmpi( pKey, "health" ) )
		{
			pModel->health = atof(pValue);
		}
		else if ( !strcmpi( pKey, "fadetime" ) )
		{
			pModel->fadeTime = atof(pValue);
			if ( !m_wroteCollisionGroup )
			{
				pModel->collisionGroup = COLLISION_GROUP_DEBRIS;
			}
		}
		else if ( !strcmpi( pKey, "fademindist" ) )
		{
			pModel->fadeMinDist = atof(pValue);
		}
		else if ( !strcmpi( pKey, "fademaxdist" ) )
		{
			pModel->fadeMaxDist = atof(pValue);
		}
		else if ( !strcmpi( pKey, "debris" ) )
		{
			pModel->collisionGroup = atoi(pValue) > 0 ? COLLISION_GROUP_DEBRIS : COLLISION_GROUP_INTERACTIVE;
			m_wroteCollisionGroup = true;
		}
		else if ( !strcmpi( pKey, "burst" ) )
		{
			pModel->burstScale = atof( pValue );
		}
		else if ( !strcmpi( pKey, "placementbone" ) )
		{
			Q_strncpy( pModel->placementName, pValue, sizeof(pModel->placementName) );
			pModel->placementIsBone = true;
		}
		else if ( !strcmpi( pKey, "placementattachment" ) )
		{
			Q_strncpy( pModel->placementName, pValue, sizeof(pModel->placementName) );
			pModel->placementIsBone = false;
		}
		else if ( !strcmpi( pKey, "multiplayer_break" ) )
		{
			if ( FStrEq( pValue, "server" ) )
			{
				pModel->mpBreakMode = MULTIPLAYER_BREAK_SERVERSIDE;
			}
			else if ( FStrEq( pValue, "client" ) )
			{
				pModel->mpBreakMode = MULTIPLAYER_BREAK_CLIENTSIDE;
			}
		}
		else if ( !strcmpi( pKey, "velocity" ) )
		{
			UTIL_StringToVector( pModel->velocity.Base(), pValue );
		}
	}
Beispiel #6
0
//=========================================================
//
// SquadRecruit(), get some monsters of my classification and
// link them as a group.  returns the group size
//
//=========================================================
int CSquadMonster :: SquadRecruit( int searchRadius, int maxMembers )
{
    int squadCount;
    int iMyClass = Classify();// cache this monster's class


    // Don't recruit if I'm already in a group
    if ( InSquad() )
        return 0;

    if ( maxMembers < 2 )
        return 0;

    // I am my own leader
    m_hSquadLeader = this;
    squadCount = 1;

    CBaseEntity *pEntity = NULL;

    if ( !FStringNull( pev->netname ) )
    {
        // I have a netname, so unconditionally recruit everyone else with that name.
        pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ) );
        while ( pEntity )
        {
            CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer();

            if ( pRecruit )
            {
                if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass && pRecruit != this )
                {
                    // minimum protection here against user error.in worldcraft.
                    if (!SquadAdd( pRecruit ))
                        break;
                    squadCount++;
                }
            }

            pEntity = UTIL_FindEntityByString( pEntity, "netname", STRING( pev->netname ) );
        }
    }
    else
    {
        while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, searchRadius )) != NULL)
        {
            CSquadMonster *pRecruit = pEntity->MySquadMonsterPointer( );

            if ( pRecruit && pRecruit != this && pRecruit->IsAlive() && !pRecruit->m_pCine )
            {
                // Can we recruit this guy?
                if ( !pRecruit->InSquad() && pRecruit->Classify() == iMyClass &&
                        ( (iMyClass != CLASS_ALIEN_MONSTER) || FStrEq(STRING(pev->classname), STRING(pRecruit->pev->classname))) &&
                        FStringNull( pRecruit->pev->netname ) )
                {
                    TraceResult tr;
                    UTIL_TraceLine( pev->origin + pev->view_ofs, pRecruit->pev->origin + pev->view_ofs, ignore_monsters, pRecruit->edict(), &tr );// try to hit recruit with a traceline.
                    if ( tr.flFraction == 1.0 )
                    {
                        if (!SquadAdd( pRecruit ))
                            break;

                        squadCount++;
                    }
                }
            }
        }
    }

    // no single member squads
    if (squadCount == 1)
    {
        m_hSquadLeader = NULL;
    }

    return squadCount;
}
Beispiel #7
0
bool RadioCreate( edict_t *pEntity )
{
	// Create the radio and stick to the wall

	entvars_t *pPev = VARS( pEntity );

	if (pPev->iuser1 > 0) return 0;


	// make sure we dont already have a radio

	int radiocount = 0;
	int i = 1;
	char *pClassname;
	edict_t *frontEnt;

	for (i; i < 1025; i++) {

		frontEnt = INDEXENT ( i );
		if (frontEnt) {
			pClassname =  (char *)STRING(frontEnt->v.classname); 
			if (FStrEq("building_radio", pClassname)) {

				if (frontEnt->v.euser4 == pEntity) 
				{
					radiocount++;
				}
			}
		}
	}

	
	if (AdminLoggedIn[ENTINDEX(pEntity)] == 0)
	{
		if (radiocount >= 2) {
			ClientPrint( pPev, HUD_PRINTTALK, "* Cant have more than 2 radios!\n");
			return 0;
		}
	}

	UTIL_MakeVectors( pPev->v_angle + pPev->punchangle );
	Vector vecSrc	 = GetGunPosition( pEntity );
	Vector vecAiming = gpGlobals->v_forward;

	TraceResult tr;

	UTIL_TraceLine( vecSrc, vecSrc + vecAiming * 128, dont_ignore_monsters, pEntity , &tr );

	if (tr.flFraction < 1.0 || AdminLoggedIn[ENTINDEX(pEntity)])
	{

		
		if (tr.pHit && !(tr.pHit->v.flags & FL_CONVEYOR) && (FStrEq((char *)STRING(tr.pHit->v.classname), "worldspawn") || FStrEq((char *)STRING(tr.pHit->v.classname), "func_wall") || AdminLoggedIn[ENTINDEX(pEntity)] || FStrEq((char *)STRING(tr.pHit->v.classname), "building_dancemachine")))	// Make sure it isnt a conveyor!
		{
			Vector angles = UTIL_VecToAngles( tr.vecPlaneNormal );

			if ((angles.x > 30 || angles.x < -30) && AdminLoggedIn[ENTINDEX(pEntity)] == 0)
			{
				ClientPrint( pPev, HUD_PRINTTALK, "* Can't place radios on floors or cielings!\n");
				return 0;
			}
			// Create the camera here!
			Vector vecOri = tr.vecEndPos + tr.vecPlaneNormal * 14;
			//Vector vecOri = tr.vecEndPos + tr.vecPlaneNormal * 15;

			int maxdist = (int)CVAR_GET_FLOAT("sa_radiospread");

			// make sure we arent placing it within 400 units of another radio
			for (i=1; i < 1025; i++) {

				frontEnt = INDEXENT ( i );
				if (frontEnt) {
					pClassname =  (char *)STRING(frontEnt->v.classname); 
					if (FStrEq("building_radio", pClassname)) {
						
						if ((frontEnt->v.origin - vecOri).Length() < maxdist && AdminLoggedIn[ENTINDEX(pEntity)] == 0)
						{
							ClientPrint( pPev, HUD_PRINTTALK, "* Can't place a radio so close to another radio!\n");
							return 0;
						}
					}
				}
			}

			KeyValueData	kvd;
			
			//edict_t *pent = CREATE_ENTITY();
			//edict_t *pent = CREATE_NAMED_ENTITY(MAKE_STRING("info_target"));

			edict_t *tEntity;
			tEntity = CREATE_NAMED_ENTITY(MAKE_STRING("info_target"));
		
			entvars_t *pRunOnPev;
			pRunOnPev =  VARS(tEntity);
			
			char buf[80];
			sprintf( buf, "%s", "building_radio");

			// Set the KEYVALUES here!
			kvd.fHandled = FALSE;
			kvd.szClassName = NULL;
			kvd.szKeyName = "classname";
			kvd.szValue = buf;

			DispatchKeyValue( tEntity, &kvd );

			// place this in front

			pRunOnPev->origin = vecOri;
			SET_ORIGIN( tEntity , vecOri );
			pRunOnPev->angles = angles;

			//DispatchSpawn( ENT( pRunOnPev ) );

			pRunOnPev->solid = SOLID_BBOX;

			SET_MODEL( ENT( pRunOnPev ) , "avatar-x/avadd16.avfil");
			UTIL_SetSize( pRunOnPev, Vector( -2, -2 ,-2) - (tr.vecPlaneNormal * 15), Vector(2, 2, 16) - (tr.vecPlaneNormal * 15));
			
			pRunOnPev->takedamage = DAMAGE_YES;
			pRunOnPev->max_health = 40 + 10000;
			pRunOnPev->health = 40 + 10000;
			pRunOnPev->euser4 = pEntity;
			
			/*
			edict_t *pent;
			pent = CREATE_NAMED_ENTITY(MAKE_STRING("xen_tree"));
			entvars_t *pv = VARS( pent );
			
			pv->origin = vecOri;
			SET_ORIGIN(pent, vecOri);

			kvd.fHandled = FALSE;
			kvd.szClassName = NULL;
			kvd.szKeyName = "classname";
			kvd.szValue = "xen_tree";
			DispatchKeyValue( pent, &kvd );

			DispatchSpawn(pent);
			//pev->angles = angles;
			
			
			*/

			//pev->iuser1 = angles.y;
			//pv->vuser3 = angles;

			// for now don't take damage
			//pev->takedamage = DAMAGE_YES;
			//pev->max_health = 40 + 10000;
			//pev->health = 40 + 10000;

			/*
			// Call the SPAWN routine to set more stuff
			kvd.fHandled = FALSE;
			kvd.szClassName = NULL;
			kvd.szKeyName = "classname";
			kvd.szValue = "building_radio";
			//DispatchKeyValue( pent, &kvd );
			kvd.fHandled = FALSE;

			

			
			*/

			RadioSpawn( tEntity );
	
			return 1;
		}
		else
		{
			ClientPrint( pPev, HUD_PRINTTALK, "* Couldn't place radio here!\n");
			return 0;
		}
		
	}
	else
	{
		ClientPrint( pPev, HUD_PRINTTALK, "* Couldn't place radio here!\n");
		
	}
	return 0;
}
Beispiel #8
0
// make the entity enter a scripted sequence
void CCineMonster::PossessEntity(void)
{
	CBaseEntity * pEntity = m_hTargetEnt;
	CBaseMonster *pTarget = NULL;
	if(pEntity)
		pTarget = pEntity->MyMonsterPointer();

	if(pTarget)
	{
// FindEntity() just checked this!
#if 0
		if ( !pTarget->CanPlaySequence(  FCanOverrideState() ) )
		{
			ALERT( at_aiconsole, "Can't possess entity %s\n", STRING(pTarget->pev->classname) );
			return;
		}
#endif

		pTarget->m_pGoalEnt   = this;
		pTarget->m_pCine      = this;
		pTarget->m_hTargetEnt = this;

		m_saved_movetype = pTarget->pev->movetype;
		m_saved_solid    = pTarget->pev->solid;
		m_saved_effects  = pTarget->pev->effects;
		pTarget->pev->effects |= pev->effects;

		switch(m_fMoveTo)
		{
		case 0:
			pTarget->m_scriptState = SCRIPT_WAIT;
			break;

		case 1:
			pTarget->m_scriptState = SCRIPT_WALK_TO_MARK;
			DelayStart(1);
			break;

		case 2:
			pTarget->m_scriptState = SCRIPT_RUN_TO_MARK;
			DelayStart(1);
			break;

		case 4:
			UTIL_SetOrigin(pTarget->pev, pev->origin);
			pTarget->pev->ideal_yaw = pev->angles.y;
			pTarget->pev->avelocity = Vector(0, 0, 0);
			pTarget->pev->velocity  = Vector(0, 0, 0);
			pTarget->pev->effects |= EF_NOINTERP;
			pTarget->pev->angles.y = pev->angles.y;
			pTarget->m_scriptState = SCRIPT_WAIT;
			m_startTime            = gpGlobals->time + 1E6;
			// UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters
			//			pTarget->pev->flags &= ~FL_ONGROUND;
			break;
		}
		//		ALERT( at_aiconsole, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->pev->targetname ), FBitSet(pev->spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" );

		pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT;
		if(m_iszIdle)
		{
			StartSequence(pTarget, m_iszIdle, FALSE);
			if(FStrEq(STRING(m_iszIdle), STRING(m_iszPlay)))
			{
				pTarget->pev->framerate = 0;
			}
		}
	}
}
Beispiel #9
0
// Use CMD_ARGV,  CMD_ARGV, and CMD_ARGC to get pointers the character string command.
void ClientCommand( edict_t *pEntity )
{
	const char *pcmd = CMD_ARGV(0);
	const char *pstr;

	// Is the client spawned yet?
	if ( !pEntity->pvPrivateData )
		return;

	entvars_t *pev = &pEntity->v;

	if ( FStrEq(pcmd, "say" ) )
	{
		Host_Say( pEntity, 0 );
	}
	else if ( FStrEq(pcmd, "say_team" ) )
	{
		Host_Say( pEntity, 1 );
	}
	else if ( FStrEq(pcmd, "fullupdate" ) )
	{
		GetClassPtr((CBasePlayer *)pev)->ForceClientDllUpdate(); 
	}
	else if ( FStrEq(pcmd, "give" ) )
	{
		if ( g_flWeaponCheat != 0.0)
		{
			int iszItem = ALLOC_STRING( CMD_ARGV(1) );	// Make a copy of the classname
			GetClassPtr((CBasePlayer *)pev)->GiveNamedItem( STRING(iszItem) );
		}
	}
	else if ( FStrEq(pcmd, "fire") )
	{
		if ( g_flWeaponCheat != 0.0)
		{
			CBaseEntity *pPlayer = CBaseEntity::Instance(pEntity);
			if (CMD_ARGC() > 1)
			{
				FireTargets(CMD_ARGV(1), pPlayer, pPlayer, USE_TOGGLE, 0);
			}
			else
			{
				TraceResult tr;
				UTIL_MakeVectors(pev->v_angle);
				UTIL_TraceLine(
					pev->origin + pev->view_ofs,
					pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000,
					dont_ignore_monsters, pEntity, &tr
				);

				if (tr.pHit)
				{
					CBaseEntity *pHitEnt = CBaseEntity::Instance(tr.pHit);
					if (pHitEnt)
					{
						pHitEnt->Use(pPlayer, pPlayer, USE_TOGGLE, 0);
						ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "Fired %s \"%s\"\n", STRING(pHitEnt->pev->classname), STRING(pHitEnt->pev->targetname) ) );
					}
				}
			}
		}
	}
	else if ( FStrEq(pcmd, "drop" ) )
	{
		// player is dropping an item. 
		GetClassPtr((CBasePlayer *)pev)->DropPlayerItem((char *)CMD_ARGV(1));
	}
	else if ( FStrEq(pcmd, "fov" ) )
	{
		if ( g_flWeaponCheat && CMD_ARGC() > 1)
		{
			GetClassPtr((CBasePlayer *)pev)->m_iFOV = atoi( CMD_ARGV(1) );
		}
		else
		{
			CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs( "\"fov\" is \"%d\"\n", (int)GetClassPtr((CBasePlayer *)pev)->m_iFOV ) );
		}
	}
	else if ( FStrEq(pcmd, "use" ) )
	{
		GetClassPtr((CBasePlayer *)pev)->SelectItem((char *)CMD_ARGV(1));
	}
	else if (((pstr = strstr(pcmd, "weapon_")) != NULL)  && (pstr == pcmd))
	{
		GetClassPtr((CBasePlayer *)pev)->SelectItem(pcmd);
	}
	else if (FStrEq(pcmd, "lastinv" ))
	{
		GetClassPtr((CBasePlayer *)pev)->SelectLastItem();
	}
	else if ( FStrEq( pcmd, "spectate" ) && (pev->flags & FL_PROXY) )	// added for proxy support
	{
		CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev);

		edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer );
		pPlayer->StartObserver( pev->origin, VARS(pentSpawnSpot)->angles);
	}
	else if ( g_pGameRules->ClientCommand( GetClassPtr((CBasePlayer *)pev), pcmd ) )
	{
		// MenuSelect returns true only if the command is properly handled,  so don't print a warning
	}
	else if ( FStrEq(pcmd, "VModEnable") )
	{
		// clear 'Unknown command: VModEnable' in singleplayer
		return;
	}
	else
	{
		// tell the user they entered an unknown command
		char command[128];

		// check the length of the command (prevents crash)
		// max total length is 192 ...and we're adding a string below ("Unknown command: %s\n")
		strncpy( command, pcmd, 127 );
		command[127] = '\0';

		// tell the user they entered an unknown command
		ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "Unknown command: %s\n", command ) );
	}
}
//--------------------------------------------------------------------------------------------------------------
void BuyState::OnUpdate( CCSBot *me )
{
	char cmdBuffer[256];

	// wait for a Navigation Mesh
	if (!TheNavMesh->IsLoaded())
		return;

	// apparently we cant buy things in the first few seconds, so wait a bit
	if (m_isInitialDelay)
	{
		const float waitToBuyTime = 0.25f;
		if (gpGlobals->curtime - me->GetStateTimestamp() < waitToBuyTime)
			return;

		m_isInitialDelay = false;
	}

	// if we're done buying and still in the freeze period, wait
	if (m_doneBuying)
	{
		if (CSGameRules()->IsMultiplayer() && CSGameRules()->IsFreezePeriod())
		{
			// make sure we're locked and loaded
			me->EquipBestWeapon( MUST_EQUIP );
			me->Reload();
			me->ResetStuckMonitor();
			return;
		}

		me->Idle();
		return;
	}

	// If we're supposed to buy a specific weapon for debugging, do so and then bail
	const char *cheatWeaponString = bot_loadout.GetString();
	if ( cheatWeaponString && *cheatWeaponString )
	{
		CUtlVector<char*, CUtlMemory<char*> > loadout;
		Q_SplitString( cheatWeaponString, " ", loadout );
		for ( int i=0; i<loadout.Count(); ++i )
		{
			const char *item = loadout[i];
			if ( FStrEq( item, "vest" ) )
			{
				me->GiveNamedItem( "item_kevlar" );
			}
			else if ( FStrEq( item, "vesthelm" ) )
			{
				me->GiveNamedItem( "item_assaultsuit" );
			}
			else if ( FStrEq( item, "defuser" ) )
			{
				if ( me->GetTeamNumber() == TEAM_CT )
				{
					me->GiveDefuser();
				}
			}
			else if ( FStrEq( item, "nvgs" ) )
			{
				me->m_bHasNightVision = true;
			}
			else if ( FStrEq( item, "primammo" ) )
			{
				me->AttemptToBuyAmmo( 0 );
			}
			else if ( FStrEq( item, "secammo" ) )
			{
				me->AttemptToBuyAmmo( 1 );
			}
			else
			{
				me->GiveWeapon( item );
			}
		}
		m_doneBuying = true;
		return;
	}


	if (!me->IsInBuyZone())
	{
		m_doneBuying = true;
		CONSOLE_ECHO( "%s bot spawned outside of a buy zone (%d, %d, %d)\n",
						(me->GetTeamNumber() == TEAM_CT) ? "CT" : "Terrorist",
						(int)me->GetAbsOrigin().x,
						(int)me->GetAbsOrigin().y,
						(int)me->GetAbsOrigin().z );
		return;
	}

	// try to buy some weapons
	const float buyInterval = 0.02f;
	if (gpGlobals->curtime - me->GetStateTimestamp() > buyInterval)
	{
		me->m_stateTimestamp = gpGlobals->curtime;

		bool isPreferredAllDisallowed = true;

		// try to buy our preferred weapons first
		if (m_prefIndex < me->GetProfile()->GetWeaponPreferenceCount() && bot_randombuy.GetBool() == false )
		{
			// need to retry because sometimes first buy fails??
			const int maxPrefRetries = 2;
			if (m_prefRetries >= maxPrefRetries)
			{
				// try to buy next preferred weapon
				++m_prefIndex;
				m_prefRetries = 0;
				return;
			}

			int weaponPreference = me->GetProfile()->GetWeaponPreference( m_prefIndex );

			// don't buy it again if we still have one from last round
			char weaponPreferenceName[32];
			Q_snprintf( weaponPreferenceName, sizeof(weaponPreferenceName), "weapon_%s", me->GetProfile()->GetWeaponPreferenceAsString( m_prefIndex ) );
			if( me->Weapon_OwnsThisType(weaponPreferenceName) )//Prefs and buyalias use the short version, this uses the long
			{
				// done with buying preferred weapon
				m_prefIndex = 9999;
				return;
			}

			if (me->HasShield() && weaponPreference == WEAPON_SHIELDGUN)
			{
				// done with buying preferred weapon
				m_prefIndex = 9999;
				return;
			}

			const char *buyAlias = NULL;

			if (weaponPreference == WEAPON_SHIELDGUN)
			{
				if (TheCSBots()->AllowTacticalShield())
					buyAlias = "shield";
			}
			else
			{
				buyAlias = WeaponIDToAlias( weaponPreference );
				WeaponType type = GetWeaponType( buyAlias );
				switch( type )
				{
					case PISTOL:
						if (!TheCSBots()->AllowPistols())
							buyAlias = NULL;
						break;

					case SHOTGUN:
						if (!TheCSBots()->AllowShotguns())
							buyAlias = NULL;
						break;

					case SUB_MACHINE_GUN:
						if (!TheCSBots()->AllowSubMachineGuns())
							buyAlias = NULL;
						break;

					case RIFLE:
						if (!TheCSBots()->AllowRifles())
							buyAlias = NULL;
						break;

					case MACHINE_GUN:
						if (!TheCSBots()->AllowMachineGuns())
							buyAlias = NULL;
						break;

					case SNIPER_RIFLE:
						if (!TheCSBots()->AllowSnipers())
							buyAlias = NULL;
						break;
				}
			}

			if (buyAlias)
			{
				Q_snprintf( cmdBuffer, 256, "buy %s\n", buyAlias );

				CCommand args;
				args.Tokenize( cmdBuffer );
				me->ClientCommand( args );

				me->PrintIfWatched( "Tried to buy preferred weapon %s.\n", buyAlias );
				isPreferredAllDisallowed = false;
			}

			++m_prefRetries;

			// bail out so we dont waste money on other equipment
			// unless everything we prefer has been disallowed, then buy at random
			if (isPreferredAllDisallowed == false)
				return;
		}

		// if we have no preferred primary weapon (or everything we want is disallowed), buy at random
		if (!me->HasPrimaryWeapon() && (isPreferredAllDisallowed || !me->GetProfile()->HasPrimaryPreference()))
		{
			if (m_buyShield)
			{
				// buy a shield
				CCommand args;
				args.Tokenize( "buy shield" );
				me->ClientCommand( args );

				me->PrintIfWatched( "Tried to buy a shield.\n" );
			}
			else 
			{
				// build list of allowable weapons to buy
				BuyInfo *masterPrimary = (me->GetTeamNumber() == TEAM_TERRORIST) ? primaryWeaponBuyInfoT : primaryWeaponBuyInfoCT;
				BuyInfo *stockPrimary[ PRIMARY_WEAPON_BUY_COUNT ];
				int stockPrimaryCount = 0;

				// dont choose sniper rifles as often
				const float sniperRifleChance = 50.0f;
				bool wantSniper = (RandomFloat( 0, 100 ) < sniperRifleChance) ? true : false;

				if ( bot_randombuy.GetBool() )
				{
					wantSniper = true;
				}

				for( int i=0; i<PRIMARY_WEAPON_BUY_COUNT; ++i )
				{
					if ((masterPrimary[i].type == SHOTGUN && TheCSBots()->AllowShotguns()) ||
						(masterPrimary[i].type == SUB_MACHINE_GUN && TheCSBots()->AllowSubMachineGuns()) ||
						(masterPrimary[i].type == RIFLE && TheCSBots()->AllowRifles()) ||
						(masterPrimary[i].type == SNIPER_RIFLE && TheCSBots()->AllowSnipers() && wantSniper) ||
						(masterPrimary[i].type == MACHINE_GUN && TheCSBots()->AllowMachineGuns()))
					{
						stockPrimary[ stockPrimaryCount++ ] = &masterPrimary[i];
					}
				}
 
				if (stockPrimaryCount)
				{
					// buy primary weapon if we don't have one
					int which;

					// on hard difficulty levels, bots try to buy preferred weapons on the first pass
					if (m_retries == 0 && TheCSBots()->GetDifficultyLevel() >= BOT_HARD && bot_randombuy.GetBool() == false )
					{
						// count up available preferred weapons
						int prefCount = 0;
						for( which=0; which<stockPrimaryCount; ++which )
							if (stockPrimary[which]->preferred)
								++prefCount;

						if (prefCount)
						{
							int whichPref = RandomInt( 0, prefCount-1 );
							for( which=0; which<stockPrimaryCount; ++which )
								if (stockPrimary[which]->preferred && whichPref-- == 0)
									break;
						}
						else
						{
							// no preferred weapons available, just pick randomly
							which = RandomInt( 0, stockPrimaryCount-1 );
						}
					}
					else
					{
						which = RandomInt( 0, stockPrimaryCount-1 );
					}

					Q_snprintf( cmdBuffer, 256, "buy %s\n", stockPrimary[ which ]->buyAlias );

					CCommand args;
					args.Tokenize( cmdBuffer );
					me->ClientCommand( args );

					me->PrintIfWatched( "Tried to buy %s.\n", stockPrimary[ which ]->buyAlias );
				}
			}
		}


		//
		// If we now have a weapon, or have tried for too long, we're done
		//
		if (me->HasPrimaryWeapon() || m_retries++ > 5)
		{
			// primary ammo
			CCommand args;
			if (me->HasPrimaryWeapon())
			{
				args.Tokenize( "buy primammo" );
				me->ClientCommand( args );
			}

			// buy armor last, to make sure we bought a weapon first
			args.Tokenize( "buy vesthelm" );
			me->ClientCommand( args );
			args.Tokenize( "buy vest" );
			me->ClientCommand( args );

			// pistols - if we have no preferred pistol, buy at random
			if (TheCSBots()->AllowPistols() && !me->GetProfile()->HasPistolPreference())
			{
				if (m_buyPistol)
				{
					int which = RandomInt( 0, SECONDARY_WEAPON_BUY_COUNT-1 );
					
					const char *what = NULL;

					if (me->GetTeamNumber() == TEAM_TERRORIST)
						what = secondaryWeaponBuyInfoT[ which ].buyAlias;
					else
						what = secondaryWeaponBuyInfoCT[ which ].buyAlias;

					Q_snprintf( cmdBuffer, 256, "buy %s\n", what );
					args.Tokenize( cmdBuffer );
					me->ClientCommand( args );


					// only buy one pistol
					m_buyPistol = false;
				}

				// make sure we have enough pistol ammo
				args.Tokenize( "buy secammo" );
				me->ClientCommand( args );
			}

			// buy a grenade if we wish, and we don't already have one
			if (m_buyGrenade && !me->HasGrenade())
			{
				if (UTIL_IsTeamAllBots( me->GetTeamNumber() ))
				{
					// only allow Flashbangs if everyone on the team is a bot (dont want to blind our friendly humans)
					float rnd = RandomFloat( 0, 100 );

					if (rnd < 10)
					{
						args.Tokenize( "buy smokegrenade" );
						me->ClientCommand( args );	// smoke grenade
					}
					else if (rnd < 35)
					{
						args.Tokenize( "buy flashbang" );
						me->ClientCommand( args );	// flashbang
					}
					else
					{
						args.Tokenize( "buy hegrenade" );
						me->ClientCommand( args );	// he grenade
					}
				}
				else
				{
					if (RandomFloat( 0, 100 ) < 10)
					{
						args.Tokenize( "buy smokegrenade" );	// smoke grenade
						me->ClientCommand( args );
					}
					else
					{
						args.Tokenize( "buy hegrenade" );	// he grenade
						me->ClientCommand( args );
					}
				}
			}

			if (m_buyDefuseKit)
			{
				args.Tokenize( "buy defuser" );
				me->ClientCommand( args );
			}

			m_doneBuying = true;
		}
	}
}
//---------------------------------------------------------------------------------
// Purpose: Load maps into memory
//---------------------------------------------------------------------------------
void	LoadMaps(const char *map_being_loaded)
{	
	FileHandle_t file_handle;
	char	base_filename[512];
	char	map_name[128];
	bool	map_is_in_map_cycle;
	bool	found_match;

	// Don't call FreeMaps() !!!!
	FreeList((void **) &map_list, &map_list_size);
	FreeList((void **) &votemap_list, &votemap_list_size);
	FreeList((void **) &map_in_cycle_list, &map_in_cycle_list_size);
	FreeList((void **) &map_not_in_cycle_list, &map_not_in_cycle_list_size);

	FindMapCVars();

//	MMsg("************ LOADING MAP LISTS *************\n");
	override_changelevel = 0;

//	MMsg("Loading Map [%s]\n", map_being_loaded);
	Q_strcpy(current_map, map_being_loaded);

	// Update last maps list
	last_map_index ++;
	if (last_map_index == MAX_LAST_MAPS)
	{
		last_map_index = 0;
	}


	Q_strcpy(last_map_list[last_map_index].map_name, current_map);

	time_t current_time;
	time(&current_time);
	last_map_list[last_map_index].start_time = current_time;

	SetChangeLevelReason("");

	Q_strcpy(last_map_list[last_map_index].end_reason, "");

	// Reset force map stuff, mani_map_cycle_mode will set these if necessary
	// when server.cfg is run
	Q_strcpy(forced_nextmap,"");
	override_changelevel = 0;
	override_setnextmap = false;

	// Get nextmap on level change
	file_handle = filesystem->Open (mapcyclefile->GetString(),"rt",NULL);
	if (file_handle == NULL)
	{
//		MMsg("Failed to load %s\n", mapcyclefile->GetString());
		Q_strcpy(next_map, map_being_loaded);
		mani_nextmap.SetValue(next_map);
		AddToList((void **) &map_in_cycle_list, sizeof(map_t), &map_in_cycle_list_size);
		Q_strcpy(map_in_cycle_list[map_in_cycle_list_size - 1].map_name, map_being_loaded);
	}
	else
	{
//		MMsg("Mapcycle list [%s]\n", mapcyclefile->GetString());

		while (filesystem->ReadLine (map_name, sizeof(map_name), file_handle) != NULL)
		{
			if (!ParseLine(map_name, true, false))
			{
				continue;
			}

			if (engine->IsMapValid(map_name) == 0) 
			{
//				MMsg("\n*** Map [%s] is not a valid map !!! *****\n", map_name);
				continue;
			}

			AddToList((void **) &map_in_cycle_list, sizeof(map_t), &map_in_cycle_list_size);
			Q_strcpy(map_in_cycle_list[map_in_cycle_list_size - 1].map_name, map_name);
			map_in_cycle_list[map_in_cycle_list_size - 1].selected_for_vote = false;

//			MMsg("[%s] ", map_name);
		}

//		MMsg("\n");
		filesystem->Close(file_handle);
	}
	
	// Check if this map is in the map cycle
	map_is_in_map_cycle = false;
	for (int i = 0; i < map_in_cycle_list_size; i ++)
	{
		if (FStrEq(map_in_cycle_list[i].map_name, current_map))
		{
			map_is_in_map_cycle = true;
			break;
		}
	}

	if (!map_is_in_map_cycle)
	{
		// Map loaded is not in the map cycle list
		// so hl2 will default the next map to 
		// be the first on the map cycle list
		if (map_in_cycle_list_size != 0)
		{
			Q_strcpy(next_map, map_in_cycle_list[0].map_name);
			mani_nextmap.SetValue(next_map);
		}
	}
	else
	{
		// Search map cycle list for nextmap
		for (int i = 0; i < map_in_cycle_list_size; i ++)
		{
			if (FStrEq( map_in_cycle_list[i].map_name, current_map))
			{
				if (i == (map_in_cycle_list_size - 1))
				{
					// End of map list so we must use the first
					// in the list
					Q_strcpy(next_map, map_in_cycle_list[0].map_name);
					mani_nextmap.SetValue(next_map);
				}
				else
				{
					// Set next map
					Q_strcpy(next_map, map_in_cycle_list[i+1].map_name);
					mani_nextmap.SetValue(next_map);
				}

				Q_strcpy(last_map_in_cycle, current_map);

				break;
			}
		}
	}

	//Get Map list
	
       //Default to loading the new location
       if(filesystem->FileExists("cfg/mapcycle.txt",NULL)) { file_handle = filesystem->Open ("cfg/mapcycle.txt","rt",NULL); }
       //If that failed, load the default file from the new location
       else if(filesystem->FileExists("cfg/mapcycle_default.txt",NULL)) { file_handle = filesystem->Open ("cfg/mapcycle_default.txt","rt",NULL); }
       //fall back to the old location
       else { file_handle = filesystem->Open ("maplist.txt","rt",NULL); }
	
	if (file_handle == NULL)
	{
		MMsg("Failed to load maplist.txt/mapcycle.txt YOU MUST HAVE A MAPLIST.TXT FILE!\n");
	}
	else
	{
//		MMsg("Map list\n");

		while (filesystem->ReadLine (map_name, 128, file_handle) != NULL)
		{
			if (!ParseLine(map_name, true, false))
			{
				// String is empty after parsing
				continue;
			}


			if ((!FStrEq( map_name, "test_speakers"))
				&& (!FStrEq( map_name, "test_hardware")))
			{
				if (engine->IsMapValid(map_name) == 0) 
				{
					MMsg("\n*** Map [%s] is not a valid map !!! *****\n", map_name);
					continue;
				}

				AddToList((void **) &map_list, sizeof(map_t), &map_list_size);
				Q_strcpy(map_list[map_list_size-1].map_name, map_name);
				map_list[map_list_size - 1].selected_for_vote = false;
//				MMsg("[%s] ", map_name);
			}
		}

//		MMsg("\n");
		filesystem->Close(file_handle);
	}

//	MMsg("Maps not in [%s]\n", mapcyclefile->GetString());
	// Calculate maps not in mapcycle

	for (int i = 0; i < map_list_size; i ++)
	{
		found_match = false;
		for (int j = 0; j < map_in_cycle_list_size; j++)
		{
			if (FStrEq(map_list[i].map_name, map_in_cycle_list[j].map_name))
			{
				found_match = true;
				break;
			}
		}

		if (!found_match)
		{
			AddToList((void **) &map_not_in_cycle_list, sizeof(map_t), &map_not_in_cycle_list_size);
			Q_strcpy(map_not_in_cycle_list[map_not_in_cycle_list_size - 1].map_name, map_list[i].map_name);
//			MMsg("[%s] ", map_not_in_cycle_list[map_not_in_cycle_list_size - 1].map_name);
		}
	}			

//	MMsg("\n");

	// Check if votemaplist.txt exists, create a new one if it doesn't
	snprintf(base_filename, sizeof (base_filename), "./cfg/%s/votemaplist.txt", mani_path.GetString());
	file_handle = filesystem->Open (base_filename,"rt",NULL);
	if (file_handle == NULL)
	{
		MMsg("Failed to load votemaplist.txt\n");
		MMsg("Attempting to write a new votemaplist.txt file based on maplist.txt\n");

		file_handle = filesystem->Open(base_filename,"wt",NULL);
		if (file_handle == NULL)
		{
//			MMsg("Failed to open votemaplist.txt for writing\n");
		}
		else
		{
			// Write votemaplist.txt in human readable text format
			for (int i = 0; i < map_list_size; i ++)
			{
				char	temp_string[512];
				int		temp_length = snprintf(temp_string, sizeof(temp_string), "%s\n", map_list[i].map_name);

				if (filesystem->Write((void *) temp_string, temp_length, file_handle) == 0)											
				{
					MMsg("Failed to write map [%s] to votemaplist.txt!!\n", map_list[i].map_name);
					filesystem->Close(file_handle);
					break;
				}
			}

			MMsg("Wrote %i maps to votemaplist.txt\n", map_list_size);
			filesystem->Close(file_handle);
		}
	}
	else
	{
		filesystem->Close(file_handle);
	}

	// Read in votemaplist.txt
	file_handle = filesystem->Open (base_filename,"rt",NULL);
	if (file_handle == NULL)
	{
//		MMsg("Failed to load votemaplist.txt\n");
	}
	else
	{
//		MMsg("Votemap list\n");
		while (filesystem->ReadLine (map_name, sizeof(map_name), file_handle) != NULL)
		{
			if (!ParseLine(map_name, true, false))
			{
				// String is empty after parsing
				continue;
			}

			if (engine->IsMapValid(map_name) == 0) 
			{
				MMsg("\n*** Map [%s] is not a valid map !!! *****\n", map_name);
				continue;
			}

			AddToList((void **) &votemap_list, sizeof(map_t), &votemap_list_size);
			Q_strcpy(votemap_list[votemap_list_size - 1].map_name, map_name);
			votemap_list[votemap_list_size - 1].selected_for_vote = false;
//			MMsg("[%s] ", map_name);
		}

//		MMsg("\n");
		filesystem->Close(file_handle);
	}

	// Check if loaded map cycle file is different than
	// the persistent one
	bool	rebuild_proper_map_cycle = false;

	if (map_in_cycle_list_size != proper_map_cycle_mode_list_size)
	{
		rebuild_proper_map_cycle = true;
	}
	else
	{
		// Both cycles the same size so check maps are in same
		// order
		for (int i = 0; i < map_in_cycle_list_size; i ++)
		{
			if (!FStrEq(map_in_cycle_list[i].map_name, 
						proper_map_cycle_mode_list[i].map_name))
			{
				rebuild_proper_map_cycle = true;
				break;
			}
		}
	}

	if (rebuild_proper_map_cycle)
	{
		// Free persistance map cycle and rebuild
		FreeList((void **) &proper_map_cycle_mode_list, &proper_map_cycle_mode_list_size);
		for (int i = 0; i < map_in_cycle_list_size; i++)
		{
			AddToList((void **) &proper_map_cycle_mode_list, sizeof(track_map_t), &proper_map_cycle_mode_list_size);
			Q_strcpy(proper_map_cycle_mode_list[i].map_name, map_in_cycle_list[i].map_name);
			proper_map_cycle_mode_list[i].played = false;
			if (FStrEq(proper_map_cycle_mode_list[i].map_name, current_map))
			{
				proper_map_cycle_mode_list[i].played = true;
			}
		}
	}

//	MMsg("Persistant Map Cycle\n");
	for (int i = 0; i < proper_map_cycle_mode_list_size; i++)
	{
		if (FStrEq(proper_map_cycle_mode_list[i].map_name, current_map))
		{
			proper_map_cycle_mode_list[i].played = true;
		}

		if (proper_map_cycle_mode_list[i].played)
		{
//			MMsg("*[%s] ", proper_map_cycle_mode_list[i].map_name);
		}
		else
		{
//			MMsg("[%s] ", proper_map_cycle_mode_list[i].map_name);
		}
	}

//	MMsg("\n");
//	MMsg("************ MAP LISTS LOADED *************\n");
}
Beispiel #12
0
// Create a custom particle system.  Create a new template instead of reading
// one off disk.
void
AvHCustomParticleSystemEntity::KeyValue( KeyValueData* inPkvd )
{
	// Read tag with ps name and create a new template using it
	if(FStrEq(inPkvd->szKeyName, kpscSystemName))
	{
		// Custom particle systems shouldn't be specifying a system in the .ps to use
		ASSERT(false);
	}
	else if(FStrEq(inPkvd->szKeyName, kpscGenSource) || FStrEq(inPkvd->szKeyName, "particleGenerationSource"))
	{
		char* theEntityName = inPkvd->szValue;
		this->GetCustomTemplate()->SetGenerationEntityName(theEntityName);
		inPkvd->fHandled = TRUE;
	}
	else if(FStrEq(inPkvd->szKeyName, kpscGenShape) || FStrEq(inPkvd->szKeyName, "particleGenerationShape"))
	{
		int theGenerationShape = 0;
		if(sscanf(inPkvd->szValue, "%d", &theGenerationShape))
		{
			ShapeType theShape = PS_Point;
			switch(theGenerationShape)
			{
			case 4:
				theShape = PS_Box;
				break;
			case 5:
				theShape = PS_Sphere;
				break;
			case 8:
				theShape = PS_Blob;
				break;
			}
			this->GetCustomTemplate()->SetGenerationShape(theShape);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscSprite) || FStrEq(inPkvd->szKeyName, "particleSprite"))
	{								   
		// relative path to sprite
		string theSpriteName(inPkvd->szValue);
		this->GetCustomTemplate()->SetSprite(theSpriteName);
		inPkvd->fHandled = TRUE;
	}
	else if(FStrEq(inPkvd->szKeyName, kpscSpriteNumFrames) || FStrEq(inPkvd->szKeyName, "particleSpriteNumFrames"))
	{
		// int number of frames
		int theNumFrames = 0;
		if(sscanf(inPkvd->szValue, "%d", &theNumFrames) == 1)
		{
			this->GetCustomTemplate()->SetNumSpriteFrames(theNumFrames);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscGenShapeParams) || FStrEq(inPkvd->szKeyName, "particleGenerationShapeParams"))
	{
		float theParameter = 0;
		if(sscanf(inPkvd->szValue, "%f", &theParameter) == 1)
		{
			this->GetCustomTemplate()->SetGenerationEntityParameter(theParameter);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscNumParticles) || FStrEq(inPkvd->szKeyName, "particleNumParticles"))
	{
		// max particles, or density
		int theNumParticles = 0;
		if(sscanf(inPkvd->szValue, "%d", &theNumParticles) == 1)
		{
		 	this->GetCustomTemplate()->SetMaxParticles(theNumParticles);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscGenRate) || FStrEq(inPkvd->szKeyName, "particleGenerationRate"))
	{
		// num particles per second
		int theNumParticles = 0;
		if(sscanf(inPkvd->szValue, "%d", &theNumParticles) == 1)
		{
			this->GetCustomTemplate()->SetGenerationRate(theNumParticles);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscSize) || FStrEq(inPkvd->szKeyName, "particleSize"))
	{
		// float particle size
		float theParticleSize = 0;
		if(sscanf(inPkvd->szValue, "%f", &theParticleSize) == 1)
		{
			this->GetCustomTemplate()->SetParticleSize(theParticleSize);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscSystemLifetime) || FStrEq(inPkvd->szKeyName, "particleSystemLifetime"))
	{
		// string system lifetime
		float theLifetime = -1;
		if(sscanf(inPkvd->szValue, "%f", &theLifetime) == 1)
		{
			this->GetCustomTemplate()->SetParticleSystemLifetime(theLifetime);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscAnimationSpeed) || FStrEq(inPkvd->szKeyName, "particleAnimationSpeed"))
	{
		// Sprite animation speed
		float theAnimSpeed = 1.0f;
		if(sscanf(inPkvd->szValue, "%f", &theAnimSpeed) == 1)
		{
			this->GetCustomTemplate()->SetAnimationSpeed(theAnimSpeed);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscParticleLifetime) || FStrEq(inPkvd->szKeyName, "particleLifetime"))
	{
		// string particle lifetime
		float theLifetime = -1;
		if(sscanf(inPkvd->szValue, "%f", &theLifetime) == 1)
		{
			this->GetCustomTemplate()->SetParticleLifetime(theLifetime);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscVelocityShape) || FStrEq(inPkvd->szKeyName, "particleStartingVelocityShape"))
	{
		int theVelocityShape = 0;
		if(sscanf(inPkvd->szValue, "%d", &theVelocityShape))
		{
			ShapeType theShape = PS_Point;
			switch(theVelocityShape)
			{
			case 1:
				theShape = PS_Point;
				break;
			case 2:
				theShape = PS_Box;
				break;
			case 3:
				theShape = PS_Sphere;
				break;
			case 4:
				theShape = PS_Blob;
				break;
			}
			this->GetCustomTemplate()->SetStartingVelocityShape(theShape);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscVelocityParams) || FStrEq(inPkvd->szKeyName, "particleStartingVelParams"))
	{
		// string, 8 comma-delimited parms
		ParticleParams theVelParms;
		if(sscanf(inPkvd->szValue, "%d,%d,%d,%d,%d,%d,%d,%d", theVelParms + 0, theVelParms + 1, theVelParms + 2, theVelParms + 3, theVelParms + 4, theVelParms + 5, theVelParms + 6, theVelParms + 7) == 8)
		{
			this->GetCustomTemplate()->SetStartingVelocityParams(theVelParms);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscScale) || FStrEq(inPkvd->szKeyName, "particleScaling"))
	{
		// float/string particle scaling
		float theScaling = 1.0f;
		if(sscanf(inPkvd->szValue, "%f", &theScaling) == 1)
		{
			this->GetCustomTemplate()->SetParticleScaling(theScaling);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscRendermode) || FStrEq(inPkvd->szKeyName, "particleRenderMode"))
	{
		// 0-5 render mode
		int theRenderMode = 0;
		if(sscanf(inPkvd->szValue, "%d", &theRenderMode) == 1)
		{
			this->GetCustomTemplate()->SetRenderMode(theRenderMode);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscMaxAlpha) || FStrEq(inPkvd->szKeyName, "particleMaxAlpha"))
	{
		float theMaxAlpha = 1.0f;
		if(sscanf(inPkvd->szValue, "%f", &theMaxAlpha) == 1)
		{
			this->GetCustomTemplate()->SetMaxAlpha(theMaxAlpha);
			inPkvd->fHandled = TRUE;
		}
	}
	else if(FStrEq(inPkvd->szKeyName, kpscSystemToGen) || FStrEq(inPkvd->szKeyName, "particleSystemToGenerate"))
	{
		string theSystemToGenerate = inPkvd->szValue;
		this->GetCustomTemplate()->SetParticleSystemToGenerate(theSystemToGenerate);
		inPkvd->fHandled = TRUE;
	}
	else
	{
		// Call down to base class
		AvHParticleSystemEntity::KeyValue(inPkvd);
	}
}
/* <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
	}
}
void CLightning::KeyValue( KeyValueData *pkvd )
{
	if (FStrEq(pkvd->szKeyName, "LightningStart"))
	{
		m_iszStartEntity = ALLOC_STRING( pkvd->szValue );
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "LightningEnd"))
	{
		m_iszEndEntity = ALLOC_STRING( pkvd->szValue );
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "life"))
	{
		m_life = atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "BoltWidth"))
	{
		m_boltWidth = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude"))
	{
		m_noiseAmplitude = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "TextureScroll"))
	{
		m_speed = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "StrikeTime"))
	{
		m_restrike = atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "texture"))
	{
		m_iszSpriteName = ALLOC_STRING(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "framestart"))
	{
		m_frameStart = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "Radius"))
	{
		m_radius = atof( pkvd->szValue );
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "damage"))
	{
		pev->dmg = atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else
		CBeam::KeyValue( pkvd );
}
Beispiel #15
0
void RadioUseCheck(  edict_t *pEntity )
{

	// Elaborate and stupid function to see if the player is pressing USE,
	// cause if we dont do this we cant catch it cause its really handled by the TFC DLL

	int MyNumber = ENTINDEX( pEntity );
	
	entvars_t *pev = VARS( pEntity );

	int buttonsChanged = (lastButtons[MyNumber] ^ pev->button);	// These buttons have changed this frame
	int m_afButtonPressed =  buttonsChanged & pev->button;		// The changed ones still down are "pressed"
	int m_afButtonReleased = buttonsChanged & (~pev->button);	// The ones not down are "released"


	lastButtons[MyNumber] = pev->button;
		

	// Was use pressed or released?
	if ( !(buttonsChanged & IN_USE))
		return;

	CBaseEntity *pObject = NULL;
	CBaseEntity *pClosest = NULL;
	Vector		vecLOS;
	float flMaxDot = VIEW_FIELD_NARROW;
	float flDot;

	UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing

	while ((pObject = UTIL_FindEntityInSphere( pObject, pev->origin, PLAYER_SEARCH_RADIUS )) != NULL)
	{

		char *pClassname = (char *)STRING(pObject->pev->classname);
		if (FStrEq(pClassname, "building_radio"))
		{

			vecLOS = ((pObject->pev->absmin + ( pObject->pev->size * 0.5 )) - (pev->origin + pev->view_ofs));
			vecLOS = UTIL_ClampVectorToBox( vecLOS, pObject->pev->size * 0.5 );
			
			flDot = DotProduct (vecLOS , gpGlobals->v_forward);
			if (flDot > flMaxDot )
			{
				pClosest = pObject;
				flMaxDot = flDot;
			}
		}
	}
	pObject = pClosest;

	// Found an object
	if (pObject )
	{
		
		if (m_afButtonPressed & IN_USE) 
		{
			char *pClassname = (char *)STRING(pObject->pev->classname);

			if (FStrEq(pClassname, "building_radio"))
			{
				// It's a radio. Do the RADIO USE thingummy, letting the radio decide what use does.

				RadioUse( pObject->edict(), pEntity );

			}
		}
	}

}
Beispiel #16
0
void RadioHandleMenuItem(edict_t *pEntity, const char *itm)
{

	int ind = ENTINDEX(pEntity);
	if (!pEntity) return;
	
	// Cant use camera in spec mode
	if (pEntity->v.iuser1 > 0) return;
	
	// Are we even supposed to hangle this?
	if (menushow2[ind] != 0 && (gpGlobals->time <= menushow2[ind])) {

		menushow2[ind] = 0;
		
		edict_t *pentUsed = INDEXENT(lastMenuEnt[ind]);
		if (FNullEnt(pentUsed)) return;

		// dont use if radio is tuning
		if (pentUsed->v.iuser1 == 1) return;


		// See what they pressed.
		
		// menu page 1

		if (lastMenuPage[ind] == 1 || lastMenuPage[ind] == 2)
		{

			if (lastMenuPage[ind] == 1)
			{

				if (FStrEq(itm, "1"))
				{
					RadioSwitchToSong(1, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "2"))
				{
					RadioSwitchToSong(2, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "3"))
				{
					RadioSwitchToSong(3, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "4"))
				{
					RadioSwitchToSong(4, lastMenuEnt[ind]);
				}	
				else if (FStrEq(itm, "5"))
				{
					RadioSwitchToSong(5, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "6"))
				{
					RadioShowMenu( pEntity, pentUsed, 2 );
				}
				
			}
			else if (lastMenuPage[ind] == 2)
			{
				// menu page 2
				if (FStrEq(itm, "1"))
				{
					RadioSwitchToSong(6, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "2"))
				{
					RadioSwitchToSong(7, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "3"))
				{
					RadioSwitchToSong(8, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "4"))
				{
					RadioSwitchToSong(9, lastMenuEnt[ind]);
				}	
				else if (FStrEq(itm, "5"))
				{
					RadioSwitchToSong(10, lastMenuEnt[ind]);
				}
				else if (FStrEq(itm, "6"))
				{
					RadioShowMenu( pEntity, pentUsed, 1 );
				}
			}

			if (FStrEq(itm, "7"))
			{
				RadioSwitchToSong(100, lastMenuEnt[ind]);
			}
			else if (FStrEq(itm, "8"))
			{
				RadioSwitchToSong(101, lastMenuEnt[ind]);
			}
			else if (FStrEq(itm, "9"))
			{
				RadioShowMenu( pEntity, pentUsed, 3 );
			}
		}
		else if (lastMenuPage[ind] == 3)
		{

			if (FStrEq(itm, "1"))
			{
				RadioChangeSongPitch(100, pentUsed);
			}
			else if (FStrEq(itm, "2"))
			{
				RadioChangeSongPitch(50, pentUsed);
			}
			else if (FStrEq(itm, "3"))
			{
				RadioChangeSongPitch(80, pentUsed);
			}
			else if (FStrEq(itm, "4"))
			{
				RadioChangeSongPitch(120, pentUsed);
			}
			else if (FStrEq(itm, "5"))
			{
				RadioChangeSongPitch(140, pentUsed);
			}
			else if (FStrEq(itm, "6"))
			{
				RadioChangeSongPitch(150, pentUsed);
			}
			else if (FStrEq(itm, "7"))
			{
				RadioChangeSongPitch(180, pentUsed);
			}
			else if (FStrEq(itm, "8"))
			{
				RadioChangeSongPitch(200, pentUsed);
			}
			else if (FStrEq(itm, "9"))
			{
				RadioShowMenu( pEntity, pentUsed, 1 );
			}
			
		}
	}
}
Beispiel #17
0
bool CBotMod::IsSteamFolder(char *szSteamFolder)
{
	return FStrEq(m_szSteamFolder, szSteamFolder);
}
//---------------------------------------------------------------------------------
// Purpose: Process the ma_maphistory command
//---------------------------------------------------------------------------------
PLUGIN_RESULT	ProcessMaMapHistory(player_t *player_ptr, const char	*command_name, const int	help_id, const int	command_type)
{
	last_map_t	*last_maps_list = NULL;
	int	number_of_maps = 0;

	if (player_ptr)
	{
		// Check if player is admin
		if (!gpManiClient->HasAccess(player_ptr->index, ADMIN, ADMIN_BASIC_ADMIN, war_mode)) return PLUGIN_BAD_ADMIN;
	}

	last_maps_list = GetLastMapsPlayed (&number_of_maps, MAX_LAST_MAPS);

	if (number_of_maps == 0)
	{
		OutputToConsole(player_ptr, "No Previous maps played!\n");
		return PLUGIN_STOP;
	}

	OutputToConsole(player_ptr, "Last %i maps played\n\n", number_of_maps);

	int count = 1;
	for (int i = 0; i < number_of_maps; i++)
	{
		if (FStrEq(last_maps_list[i].map_name,"")) 
		{
			continue;
		}

		struct	tm	*time_now;
		time_now = localtime(&(last_maps_list[i].start_time));

		char	temp_string[64];

		snprintf(temp_string, sizeof(temp_string), "%02i:%02i:%02i", 
			time_now->tm_hour,
			time_now->tm_min,
			time_now->tm_sec);

		if (i == 0)
		{
			OutputToConsole(player_ptr, "%02i. %s %s (Current Map)\n", count++, last_maps_list[i].map_name, temp_string);
		}
		else
		{
			int t_length = last_maps_list[i - 1].start_time - last_maps_list[i].start_time;

			int	seconds = (int)(t_length % 60);
			int	minutes = (int)(t_length / 60 % 60);
			int	hours = (int)(t_length / 3600 % 24);
			int	days = (int)(t_length / 3600 / 24);
			char	time_online[128];

			if (days > 0)
			{
				snprintf (time_online, sizeof (time_online), 
					"%id %ih %im %is", 
					days, 
					hours,
					minutes,
					seconds);
			}
			else if (hours > 0)
			{
				snprintf (time_online, sizeof (time_online), 
					"%ih %im %is",  
					hours,
					minutes,
					seconds);
			}
			else if (minutes > 0)
			{
				snprintf (time_online, sizeof (time_online), 
					"%im %is",  
					minutes,
					seconds);
			}
			else
			{
				snprintf (time_online, sizeof (time_online), 
					"%is", 
					seconds);
			}

			OutputToConsole(player_ptr, "%02i. %s %s %s %s\n", 
							count++, 
							last_maps_list[i].map_name, 
							temp_string, 
							time_online, 
							last_maps_list[i].end_reason);
		}
	}	

	return PLUGIN_STOP;
}
Beispiel #19
0
bool CBotMod::IsModFolder(char *szModFolder)
{
	return FStrEq(m_szModFolder, szModFolder);
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCSPlayerResource::UpdatePlayerData( void )
{
	int i;

	m_iPlayerC4 = 0;
	m_iPlayerVIP = 0;

	for ( i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CCSPlayer *pPlayer = (CCSPlayer*)UTIL_PlayerByIndex( i );
		
		if ( pPlayer && pPlayer->IsConnected() )
		{
			if ( pPlayer->IsVIP() )
			{
				// we should only have one VIP
				Assert( m_iPlayerVIP == 0 );
				m_iPlayerVIP = i;
			}

			if ( pPlayer->HasC4() )
			{
				// we should only have one bomb
				m_iPlayerC4 = i;
			}
		}
	}

	CBaseEntity *c4 = NULL;
	if ( m_iPlayerC4 == 0 )
	{
		// no player has C4, update C4 position
		if ( g_C4s.Count() > 0 )
		{
			c4 = g_C4s[0];
			m_vecC4 = c4->GetAbsOrigin();
		}
		else
		{
			m_vecC4.Init();
		}
	}

	//int numHostages = g_Hostages.Count();

	for ( i = 0; i < MAX_HOSTAGES; i++ )
	{
		/*if ( i >= numHostages )
		{
//			engine->Con_NPrintf( i, "Dead" );
			m_bHostageAlive.Set( i, false );
			m_isHostageFollowingSomeone.Set( i, false );
			continue;
		}

//		CHostage* pHostage = g_Hostages[i];

		//m_bHostageAlive.Set( i, pHostage->IsRescuable() );

		/*if ( pHostage->IsValid() )
		{
			m_iHostageX.Set( i, (int) pHostage->GetAbsOrigin().x );	
			m_iHostageY.Set( i, (int) pHostage->GetAbsOrigin().y );	
			m_iHostageZ.Set( i, (int) pHostage->GetAbsOrigin().z );	
			m_iHostageEntityIDs.Set( i, pHostage->entindex() );
			//m_isHostageFollowingSomeone.Set( i, pHostage->IsFollowingSomeone() );
//			engine->Con_NPrintf( i, "ID:%d Pos:(%.0f,%.0f,%.0f)", pHostage->entindex(), pHostage->GetAbsOrigin().x, pHostage->GetAbsOrigin().y, pHostage->GetAbsOrigin().z );
		}
		else
		{
//			engine->Con_NPrintf( i, "Invalid" );
		}*/
	}

	if( !m_foundGoalPositions )
	{
		// We only need to update these once a map, but we need the client to know about them.
		CBaseEntity* ent = NULL;
		while ( ( ent = gEntList.FindEntityByClassname( ent, "func_bomb_target" ) ) != NULL )
		{
			const Vector &pos = ent->WorldSpaceCenter();
			CNavArea *area = TheNavMesh->GetNearestNavArea( pos, true );
			const char *placeName = (area) ? TheNavMesh->PlaceToName( area->GetPlace() ) : NULL;
			if ( placeName == NULL )
			{
				// The bomb site has no area or place name, so just choose A then B
				if ( m_bombsiteCenterA.Get().IsZero() )
				{
					m_bombsiteCenterA = pos;
				}
				else
				{
					m_bombsiteCenterB = pos;
				}
			}
			else
			{
				// The bomb site has a place name, so choose accordingly
				if( FStrEq( placeName, "BombsiteA" ) )
				{
					m_bombsiteCenterA = pos;
				}
				else
				{
					m_bombsiteCenterB = pos;
				}
			}
			m_foundGoalPositions = true;
		}

		int hostageRescue = 0;
		while ( (( ent = gEntList.FindEntityByClassname( ent, "func_hostage_rescue" ) ) != NULL)  &&  (hostageRescue < MAX_HOSTAGE_RESCUES) )
		{
			const Vector &pos = ent->WorldSpaceCenter();
			m_hostageRescueX.Set( hostageRescue, (int) pos.x );	
			m_hostageRescueY.Set( hostageRescue, (int) pos.y );	
			m_hostageRescueZ.Set( hostageRescue, (int) pos.z );	

			hostageRescue++;
			m_foundGoalPositions = true;
		}
	}

	bool bombSpotted = false;
	if ( c4 )
	{
		Spotter spotter( c4, m_vecC4, TEAM_CT );
		ForEachPlayer( spotter );
		if ( spotter.Spotted() )
		{
			bombSpotted = true;
		}
	}

	for ( int i=0; i < MAX_PLAYERS+1; i++ )
	{
		CCSPlayer *target = ToCSPlayer( UTIL_PlayerByIndex( i ) );
		if ( !target || !target->IsAlive() )
		{
			m_bPlayerSpotted.Set( i, 0 );
			continue;
		}

		Spotter spotter( target, target->EyePosition(), (target->GetTeamNumber()==TEAM_CT) ? TEAM_TERRORIST : TEAM_CT );
		ForEachPlayer( spotter );
		if ( spotter.Spotted() )
		{
			if ( target->HasC4() )
			{
				bombSpotted = true;
			}
			m_bPlayerSpotted.Set( i, 1 );
		}
		else
		{
			m_bPlayerSpotted.Set( i, 0 );
		}
	}

	if ( bombSpotted )
	{
		m_bBombSpotted = true;
	}
	else
	{
		m_bBombSpotted = false;
	}

	BaseClass::UpdatePlayerData();
}
Beispiel #21
0
void CPathTrack::SetPrevious( CPathTrack *pprev )
{
	// Only set previous if this isn't my alternate path
	if ( pprev && !FStrEq( STRING(pprev->GetEntityName()), STRING(m_altName) ) )
		m_pprevious = pprev;
}
void CASW_EquipmentList::LoadEquipmentList()
{
	m_iNumRegular = 0;
	m_iNumExtra = 0;

	KeyValues *kv = new KeyValues("Equipment");
	// load equipment
	if (kv->LoadFromFile(filesystem, "resource/Equipment.res"))
	{		
		int iNumEquip = 0;
		KeyValues *pKeys = kv;
		while ( pKeys )
		{
			for (KeyValues *details = pKeys->GetFirstSubKey(); details; details = details->GetNextKey())
			{			
				if ( FStrEq( details->GetName(), "Regular" ) )
				{
					//Msg("adding regular equip %s\n", MAKE_STRING( details->GetString() ));
					CASW_EquipItem* equip = new CASW_EquipItem();
					equip->m_EquipClass = MAKE_STRING( details->GetString() );
					equip->m_iItemIndex = iNumEquip;
					equip->m_bSelectableInBriefing = true;
					m_Regular.AddToTail(equip);	
					m_iNumRegular++;
					iNumEquip++;
				}
				else if ( FStrEq( details->GetName(), "Extra" ) )
				{
					//Msg("adding extra equip %s\n", MAKE_STRING( details->GetString() ));
					CASW_EquipItem* equip = new CASW_EquipItem();
					equip->m_EquipClass = MAKE_STRING( details->GetString() );
					equip->m_iItemIndex = iNumEquip;
					equip->m_bSelectableInBriefing = true;
					m_Extra.AddToTail(equip);
					m_iNumExtra++;
					iNumEquip++;							
				}
				// hidden equip
				else if ( FStrEq( details->GetName(), "RegularOther" ) )
				{
					//Msg("adding regular equip %s\n", MAKE_STRING( details->GetString() ));
					CASW_EquipItem* equip = new CASW_EquipItem();
					equip->m_EquipClass = MAKE_STRING( details->GetString() );
					equip->m_iItemIndex = iNumEquip;
					equip->m_bSelectableInBriefing = false;
					m_Regular.AddToTail(equip);	
					iNumEquip++;
				}
				else if ( FStrEq( details->GetName(), "ExtraOther" ) )
				{
					//Msg("adding extra equip %s\n", MAKE_STRING( details->GetString() ));
					CASW_EquipItem* equip = new CASW_EquipItem();
					equip->m_EquipClass = MAKE_STRING( details->GetString() );
					equip->m_iItemIndex = iNumEquip;
					equip->m_bSelectableInBriefing = false;
					m_Extra.AddToTail(equip);
					iNumEquip++;							
				}
			}
			pKeys = pKeys->GetNextKey();
		}							
	}	
}
Beispiel #23
0
int DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity)
{
	CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);

	if(pEntity && pSaveData)
	{
		entvars_t tmpVars;
		Vector    oldOffset;

		CRestore restoreHelper(pSaveData);
		if(globalEntity)
		{
			CRestore tmpRestore(pSaveData);
			tmpRestore.PrecacheMode(0);
			tmpRestore.ReadEntVars("ENTVARS", &tmpVars);

			// HACKHACK - reset the save pointers, we're going to restore for real this time
			pSaveData->size         = pSaveData->pTable[pSaveData->currentIndex].location;
			pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size;
			// -------------------

			const globalentity_t *pGlobal = gGlobalState.EntityFromTable(tmpVars.globalname);

			// Don't overlay any instance of the global that isn't the latest
			// pSaveData->szCurrentMapName is the level this entity is coming from
			// pGlobla->levelName is the last level the global entity was active in.
			// If they aren't the same, then this global update is out of date.
			if(!FStrEq(pSaveData->szCurrentMapName, pGlobal->levelName))
				return 0;

			// Compute the new global offset
			oldOffset               = pSaveData->vecLandmarkOffset;
			CBaseEntity *pNewEntity = FindGlobalEntity(tmpVars.classname, tmpVars.globalname);
			if(pNewEntity)
			{
				//				ALERT( at_console, "Overlay %s with %s\n", STRING(pNewEntity->pev->classname), STRING(tmpVars.classname) );
				// Tell the restore code we're overlaying a global entity from another level
				restoreHelper.SetGlobalMode(1); // Don't overwrite global fields
				pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins;
				pEntity                      = pNewEntity; // we're going to restore this data OVER the old entity
				pent                         = ENT(pEntity->pev);
				// Update the global table to say that the global definition of this entity should come from this level
				gGlobalState.EntityUpdate(pEntity->pev->globalname, gpGlobals->mapname);
			}
			else
			{
				// This entity will be freed automatically by the engine.  If we don't do a restore on a matching entity (below)
				// or call EntityUpdate() to move it to this level, we haven't changed global state at all.
				return 0;
			}
		}

		if(pEntity->ObjectCaps() & FCAP_MUST_SPAWN)
		{
			pEntity->Restore(restoreHelper);
			pEntity->Spawn();
		}
		else
		{
			pEntity->Restore(restoreHelper);
			pEntity->Precache();
		}

		// Again, could be deleted, get the pointer again.
		pEntity = (CBaseEntity *)GET_PRIVATE(pent);

#if 0
		if ( pEntity && pEntity->pev->globalname && globalEntity ) 
		{
			ALERT( at_console, "Global %s is %s\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->model) );
		}
#endif

		// Is this an overriding global entity (coming over the transition), or one restoring in a level
		if(globalEntity)
		{
			//			ALERT( at_console, "After: %f %f %f %s\n", pEntity->pev->origin.x, pEntity->pev->origin.y, pEntity->pev->origin.z, STRING(pEntity->pev->model) );
			pSaveData->vecLandmarkOffset = oldOffset;
			if(pEntity)
			{
				UTIL_SetOrigin(pEntity->pev, pEntity->pev->origin);
				pEntity->OverrideReset();
			}
		}
		else if(pEntity && pEntity->pev->globalname)
		{
			const globalentity_t *pGlobal = gGlobalState.EntityFromTable(pEntity->pev->globalname);
			if(pGlobal)
			{
				// Already dead? delete
				if(pGlobal->state == GLOBAL_DEAD)
					return -1;
				else if(!FStrEq(STRING(gpGlobals->mapname), pGlobal->levelName))
				{
					pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive
				}
				// In this level & not dead, continue on as normal
			}
			else
			{
				ALERT(at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname));
				// Spawned entities default to 'On'
				gGlobalState.EntityAdd(pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON);
			}
		}
	}
	return 0;
}
Beispiel #24
0
void CBaseDoor::Spawn( void )
{
	if( pev->skin == CONTENTS_NONE )
	{
		// normal door
		if( FBitSet( pev->spawnflags, SF_DOOR_PASSABLE ))
			pev->solid = SOLID_NOT;
		else
			pev->solid = SOLID_BSP;
	}
	else
	{
		SetBits( pev->spawnflags, SF_DOOR_SILENT );
		pev->solid = SOLID_NOT; // special contents
	}

	Precache();

	pev->movetype = MOVETYPE_PUSH;
	SET_MODEL( edict(), GetModel() );

	// NOTE: original Half-Life was contain a bug in LinearMove function
	// while m_flWait was equal 0 then object has stopped forever. See code from quake:
	/*
		void LinearMove( Vector vecDest, float flSpeed )
		{
			...
			...
			...
			if( flTravelTime < 0.1f )
			{
				pev->velocity = g_vecZero;
				pev->nextthink = pev->ltime + 0.1f;
				return;
			}
		}
	*/
	// this block was removed from Half-Life and there no difference
	// between wait = 0 and wait = -1. But in Xash this bug was fixed
	// and level-designer errors is now actual. I'm set m_flWait to -1 for compatibility
	if( m_flWait == 0.0f )
		m_flWait = -1;

	if( pev->speed == 0 )
		pev->speed = 100;

	if( pev->movedir == g_vecZero )
		pev->movedir = Vector( 1.0f, 0.0f, 0.0f );

	m_vecPosition1 = GetLocalOrigin();

	// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
	Vector vecSize = pev->size - Vector( 2, 2, 2 );
	m_vecPosition2 = m_vecPosition1 + (pev->movedir * (DotProductAbs( pev->movedir, vecSize ) - m_flLip));

	ASSERTSZ( m_vecPosition1 != m_vecPosition2, "door start/end positions are equal" );

	if( FBitSet( pev->spawnflags, SF_DOOR_START_OPEN ))
	{	
		UTIL_SetOrigin( this, m_vecPosition2 );
		m_vecPosition2 = m_vecPosition1;
		m_vecPosition1 = GetLocalOrigin();
	}
	else
	{
		UTIL_SetOrigin( this, m_vecPosition1 );
	}

	// another hack: PhysX 2.8.4.0 crashed while trying to created kinematic body from this brush-model
	if ( FStrEq( STRING( gpGlobals->mapname ), "c2a5e" ) && FStrEq( STRING( pev->model ), "*103" ));
	else m_pUserData = WorldPhysic->CreateKinematicBodyFromEntity( this );
	m_iState = STATE_OFF;

	// if the door is flagged for USE button activation only, use NULL touch function
	if( FBitSet( pev->spawnflags, SF_DOOR_USE_ONLY ))
	{
		SetTouch( NULL );
	}
	else
	{
		// touchable button
		SetTouch( DoorTouch );
	}
}
//---------------------------------------------------------------------------------
// Purpose: called when a client types in a command (only a subset of commands however, not CON_COMMAND's)
//---------------------------------------------------------------------------------
PLUGIN_RESULT CEmptyServerPlugin::ClientCommand( edict_t *pEntity )
{
	const char *pcmd = engine->Cmd_Argv(0);

	if ( !pEntity || pEntity->IsFree() ) 
	{
		return PLUGIN_CONTINUE;
	}

	if ( FStrEq( pcmd, "menu" ) )
	{
		KeyValues *kv = new KeyValues( "menu" );
		kv->SetString( "title", "You've got options, hit ESC" );
		kv->SetInt( "level", 1 );
		kv->SetColor( "color", Color( 255, 0, 0, 255 ));
		kv->SetInt( "time", 20 );
		kv->SetString( "msg", "Pick an option\nOr don't." );
		
		for( int i = 1; i < 9; i++ )
		{
			char num[10], msg[10], cmd[10];
			Q_snprintf( num, sizeof(num), "%i", i );
			Q_snprintf( msg, sizeof(msg), "Option %i", i );
			Q_snprintf( cmd, sizeof(cmd), "option%i", i );

			KeyValues *item1 = kv->FindKey( num, true );
			item1->SetString( "msg", msg );
			item1->SetString( "command", cmd );
		}

		helpers->CreateMessage( pEntity, DIALOG_MENU, kv, this );
		kv->deleteThis();
		return PLUGIN_STOP; // we handled this function
	}
	else if ( FStrEq( pcmd, "rich" ) )
	{
		KeyValues *kv = new KeyValues( "menu" );
		kv->SetString( "title", "A rich message" );
		kv->SetInt( "level", 1 );
		kv->SetInt( "time", 20 );
		kv->SetString( "msg", "This is a long long long text string.\n\nIt also has line breaks." );
		
		helpers->CreateMessage( pEntity, DIALOG_TEXT, kv, this );
		kv->deleteThis();
		return PLUGIN_STOP; // we handled this function
	}
	else if ( FStrEq( pcmd, "msg" ) )
	{
		KeyValues *kv = new KeyValues( "menu" );
		kv->SetString( "title", "Just a simple hello" );
		kv->SetInt( "level", 1 );
		kv->SetInt( "time", 20 );
		
		helpers->CreateMessage( pEntity, DIALOG_MSG, kv, this );
		kv->deleteThis();
		return PLUGIN_STOP; // we handled this function
	}
	else if ( FStrEq( pcmd, "entry" ) )
	{
		KeyValues *kv = new KeyValues( "entry" );
		kv->SetString( "title", "Stuff" );
		kv->SetString( "msg", "Enter something" );
		kv->SetString( "command", "say" ); // anything they enter into the dialog turns into a say command
		kv->SetInt( "level", 1 );
		kv->SetInt( "time", 20 );
		
		helpers->CreateMessage( pEntity, DIALOG_ENTRY, kv, this );
		kv->deleteThis();
		return PLUGIN_STOP; // we handled this function		
	}


	return PLUGIN_CONTINUE;
}
//---------------------------------------------------------------------------------
// Purpose: Check Player on connect
//---------------------------------------------------------------------------------
bool ManiReservedSlot::NetworkIDValidated(player_t	*player_ptr)
{
	bool		is_reserve_player = false;
	player_t	temp_player;
	int			allowed_players;
	int			total_players;
	
	m_iUnaccountedPlayers--;
	
	if ((war_mode) || (!mani_reserve_slots.GetBool()) || (mani_reserve_slots_number_of_slots.GetInt() == 0))   // with the other method ( zero slots )
	{																		// other player is kicked BEFORE
		return true;														// NetworkIDValidated
	}

	total_players = m_iUnaccountedPlayers + GetNumberOfActivePlayers(true);
	// DirectLogCommand("[DEBUG] Total players on server [%i]\n", total_players);

	if (total_players <= (max_players - mani_reserve_slots_number_of_slots.GetInt()))
	{
		// DirectLogCommand("[DEBUG] No reserve slot action required\n");
		return true;
	}


	GetIPAddressFromPlayer(player_ptr);
	Q_strcpy (player_ptr->steam_id, engine->GetPlayerNetworkIDString(player_ptr->entity));
	IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(player_ptr->entity);
	if (playerinfo && playerinfo->IsConnected())
	{
		Q_strcpy(player_ptr->name, playerinfo->GetName());
	}
	else
	{
		Q_strcpy(player_ptr->name,"");
	}

	if (FStrEq("BOT", player_ptr->steam_id))
		return true;

	player_ptr->is_bot = false;


	if (IsPlayerInReserveList(player_ptr))
		is_reserve_player = true;

	else if (mani_reserve_slots_include_admin.GetBool() && gpManiClient->HasAccess(player_ptr->index, ADMIN, ADMIN_BASIC_ADMIN))
		is_reserve_player = true;

	if (mani_reserve_slots_allow_slot_fill.GetInt() != 1)
	{
		// Keep reserve slots free at all times
		allowed_players = max_players - mani_reserve_slots_number_of_slots.GetInt();
		if (total_players > allowed_players)
		{
			if (!is_reserve_player) {
				DisconnectPlayer(player_ptr);
				return false;
			}

			temp_player.index = FindPlayerToKick();
			FindPlayerByIndex(&temp_player);
			DisconnectPlayer(&temp_player);
		}
	}
	
	return true;
}
Beispiel #27
0
//
// Just to ignore the "wad" field.
//
void CWorld :: KeyValue( KeyValueData *pkvd )
{
	if ( FStrEq(pkvd->szKeyName, "skyname") )
	{
		// Sent over net now.
		CVAR_SET_STRING( "sv_skyname", pkvd->szValue );
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "sounds") )
	{
		gpGlobals->cdAudioTrack = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "WaveHeight") )
	{
		// Sent over net now.
		pev->scale = atof(pkvd->szValue) * (1.0/8.0);
		pkvd->fHandled = TRUE;
		CVAR_SET_FLOAT( "sv_wateramp", pev->scale );
	}
	else if ( FStrEq(pkvd->szKeyName, "MaxRange") )
	{
		pev->speed = atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "chaptertitle") )
	{
		pev->netname = ALLOC_STRING(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "startdark") )
	{
		// UNDONE: This is a gross hack!!! The CVAR is NOT sent over the client/sever link
		// but it will work for single player
		int flag = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
		if ( flag )
			pev->spawnflags |= SF_WORLD_DARK;
	}
	else if ( FStrEq(pkvd->szKeyName, "newunit") )
	{
		// Single player only.  Clear save directory if set
		if ( atoi(pkvd->szValue) )
			CVAR_SET_FLOAT( "sv_newunit", 1 );
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "gametitle") )
	{
		if ( atoi(pkvd->szValue) )
			pev->spawnflags |= SF_WORLD_TITLE;

		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "mapteams") )
	{
		pev->team = ALLOC_STRING( pkvd->szValue );
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "defaultteam") )
	{
		if ( atoi(pkvd->szValue) )
		{
			pev->spawnflags |= SF_WORLD_FORCETEAM;
		}
		pkvd->fHandled = TRUE;
	}

	// Discwar
	else if ( FStrEq(pkvd->szKeyName, "playersperteam") )
	{
		g_iPlayersPerTeam = atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if ( FStrEq(pkvd->szKeyName, "no_arena") )
	{
		if ( atoi(pkvd->szValue) )
			m_iArenaOff = TRUE;
		pkvd->fHandled = TRUE;
	}

	else
		CBaseEntity::KeyValue( pkvd );
}
//=========================================================
// Start task - selects the correct activity and performs
// any necessary calculations to start the next task on the
// schedule. 
//=========================================================
void CBaseMonster :: StartTask ( Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_TURN_RIGHT:
		{
			float flCurrentYaw;
			
			flCurrentYaw = UTIL_AngleMod( pev->angles.y );
			pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw - pTask->flData );
			SetTurnActivity();
			break;
		}
	case TASK_TURN_LEFT:
		{
			float flCurrentYaw;
			
			flCurrentYaw = UTIL_AngleMod( pev->angles.y );
			pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw + pTask->flData );
			SetTurnActivity();
			break;
		}
	case TASK_REMEMBER:
		{
			Remember ( (int)pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_FORGET:
		{
			Forget ( (int)pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_FIND_HINTNODE:
		{
			m_iHintNode = FindHintNode();

			if ( m_iHintNode != NO_NODE )
			{
				TaskComplete();
			}
			else
			{
				TaskFail();
			}
			break;
		}
	case TASK_STORE_LASTPOSITION:
		{
			m_vecLastPosition = pev->origin;
			TaskComplete();
			break;
		}
	case TASK_CLEAR_LASTPOSITION:
		{
			m_vecLastPosition = g_vecZero;
			TaskComplete();
			break;
		}
	case TASK_CLEAR_HINTNODE:
		{
			m_iHintNode = NO_NODE;
			TaskComplete();
			break;
		}
	case TASK_STOP_MOVING:
		{
			if ( m_IdealActivity == m_movementActivity )
			{
				m_IdealActivity = GetStoppedActivity();
			}

			RouteClear();
			TaskComplete();
			break;
		}
	case TASK_PLAY_SEQUENCE_FACE_ENEMY:
	case TASK_PLAY_SEQUENCE_FACE_TARGET:
	case TASK_PLAY_SEQUENCE:
		{
			m_IdealActivity = ( Activity )( int )pTask->flData;
			break;
		}
	case TASK_PLAY_ACTIVE_IDLE:
		{
			// monsters verify that they have a sequence for the node's activity BEFORE
			// moving towards the node, so it's ok to just set the activity without checking here.
			m_IdealActivity = ( Activity )WorldGraph.m_pNodes[ m_iHintNode ].m_sHintActivity;
			break;
		}
	case TASK_SET_SCHEDULE:
		{
			Schedule_t *pNewSchedule;

			pNewSchedule = GetScheduleOfType( (int)pTask->flData );
			
			if ( pNewSchedule )
			{
				ChangeSchedule( pNewSchedule );
			}
			else
			{
				TaskFail();
			}

			break;
		}
	case TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, pTask->flData ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_FAR_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, pTask->flData, CoverRadius() ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, CoverRadius() ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_COVER_FROM_ENEMY:
		{
			entvars_t *pevCover;

			if ( m_hEnemy == NULL )
			{
				// Find cover from self if no enemy available
				pevCover = pev;
//				TaskFail();
//				return;
			}
			else
				pevCover = m_hEnemy->pev;

			if ( FindLateralCover( pevCover->origin, pevCover->view_ofs ) )
			{
				// try lateral first
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else if ( FindCover( pevCover->origin, pevCover->view_ofs, 0, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_COVER_FROM_ORIGIN:
		{
			if ( FindCover( pev->origin, pev->view_ofs, 0, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no cover!
				TaskFail();
			}
		}
		break;
	case TASK_FIND_COVER_FROM_BEST_SOUND:
		{
			CSound *pBestSound;

			pBestSound = PBestSound();

			ASSERT( pBestSound != NULL );
			/*
			if ( pBestSound && FindLateralCover( pBestSound->m_vecOrigin, g_vecZero ) )
			{
				// try lateral first
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			*/

			if ( pBestSound && FindCover( pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever. or no sound in list
				TaskFail();
			}
			break;
		}
	case TASK_FACE_HINTNODE:
		{
			pev->ideal_yaw = WorldGraph.m_pNodes[ m_iHintNode ].m_flHintYaw;
			SetTurnActivity();
			break;
		}
	
	case TASK_FACE_LASTPOSITION:
		MakeIdealYaw ( m_vecLastPosition );
		SetTurnActivity(); 
		break;

	case TASK_FACE_TARGET:
		if ( m_hTargetEnt != NULL )
		{
			MakeIdealYaw ( m_hTargetEnt->pev->origin );
			SetTurnActivity(); 
		}
		else
			TaskFail();
		break;
	case TASK_FACE_ENEMY:
		{
			MakeIdealYaw ( m_vecEnemyLKP );
			SetTurnActivity(); 
			break;
		}
	case TASK_FACE_IDEAL:
		{
			SetTurnActivity();
			break;
		}
	case TASK_FACE_ROUTE:
		{
			if (FRouteClear())
			{
				ALERT(at_aiconsole, "No route to face!\n");
				TaskFail();
			}
			else
			{
				MakeIdealYaw(m_Route[m_iRouteIndex].vecLocation);
				SetTurnActivity();
			}
			break;
		}
	case TASK_WAIT_PVS:
	case TASK_WAIT_INDEFINITE:
		{
			// don't do anything.
			break;
		}
	case TASK_WAIT:
	case TASK_WAIT_FACE_ENEMY:
		{// set a future time that tells us when the wait is over.
			m_flWaitFinished = gpGlobals->time + pTask->flData;	
			break;
		}
	case TASK_WAIT_RANDOM:
		{// set a future time that tells us when the wait is over.
			m_flWaitFinished = gpGlobals->time + RANDOM_FLOAT( 0.1, pTask->flData );
			break;
		}
	case TASK_MOVE_TO_TARGET_RANGE:
		{
			if ( (m_hTargetEnt->pev->origin - pev->origin).Length() < 1 )
				TaskComplete();
			else
			{
				m_vecMoveGoal = m_hTargetEnt->pev->origin;
				if ( !MoveToTarget( ACT_WALK, 2 ) )
					TaskFail();
			}
			break;
		}
	case TASK_RUN_TO_SCRIPT:
	case TASK_WALK_TO_SCRIPT:
		{
			Activity newActivity;

			if ( !m_pGoalEnt || (m_pGoalEnt->pev->origin - pev->origin).Length() < 1 )
				TaskComplete();
			else
			{
				if ( pTask->iTask == TASK_WALK_TO_SCRIPT )
					newActivity = ACT_WALK;
				else
					newActivity = ACT_RUN;
				// This monster can't do this!
				if ( LookupActivity( newActivity ) == ACTIVITY_NOT_AVAILABLE )
					TaskComplete();
				else 
				{
					if ( m_pGoalEnt != NULL )
					{
						Vector vecDest;
						vecDest = m_pGoalEnt->pev->origin;

						if ( !MoveToLocation( newActivity, 2, vecDest ) )
						{
							TaskFail();
							ALERT( at_aiconsole, "%s Failed to reach script!!!\n", STRING(pev->classname) );
							RouteClear();
						}
					}
					else
					{
						TaskFail();
						ALERT( at_aiconsole, "%s: MoveTarget is missing!?!\n", STRING(pev->classname) );
						RouteClear();
					}
				}
			}
			TaskComplete();
			break;
		}
	case TASK_CLEAR_MOVE_WAIT:
		{
			m_flMoveWaitFinished = gpGlobals->time;
			TaskComplete();
			break;
		}
	case TASK_MELEE_ATTACK1_NOTURN:
	case TASK_MELEE_ATTACK1:
		{
			m_IdealActivity = ACT_MELEE_ATTACK1;
			break;
		}
	case TASK_MELEE_ATTACK2_NOTURN:
	case TASK_MELEE_ATTACK2:
		{
			m_IdealActivity = ACT_MELEE_ATTACK2;
			break;
		}
	case TASK_RANGE_ATTACK1_NOTURN:
	case TASK_RANGE_ATTACK1:
		{
			m_IdealActivity = ACT_RANGE_ATTACK1;
			break;
		}
	case TASK_RANGE_ATTACK2_NOTURN:
	case TASK_RANGE_ATTACK2:
		{
			m_IdealActivity = ACT_RANGE_ATTACK2;
			break;
		}
	case TASK_RELOAD_NOTURN:
	case TASK_RELOAD:
		{
			m_IdealActivity = ACT_RELOAD;
			break;
		}
	case TASK_SPECIAL_ATTACK1:
		{
			m_IdealActivity = ACT_SPECIAL_ATTACK1;
			break;
		}
	case TASK_SPECIAL_ATTACK2:
		{
			m_IdealActivity = ACT_SPECIAL_ATTACK2;
			break;
		}
	case TASK_SET_ACTIVITY:
		{
			m_IdealActivity = (Activity)(int)pTask->flData;
			TaskComplete();
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_LKP:
		{
			if ( BuildRoute ( m_vecEnemyLKP, bits_MF_TO_LOCATION, NULL ) )
			{
				TaskComplete();
			}
			else if (BuildNearestRoute( m_vecEnemyLKP, pev->view_ofs, 0, (m_vecEnemyLKP - pev->origin).Length() ))
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToEnemyLKP failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_ENEMY:
		{
			CBaseEntity *pEnemy = m_hEnemy;

			if ( pEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( BuildRoute ( pEnemy->pev->origin, bits_MF_TO_ENEMY, pEnemy ) )
			{
				TaskComplete();
			}
			else if (BuildNearestRoute( pEnemy->pev->origin, pEnemy->pev->view_ofs, 0, (pEnemy->pev->origin - pev->origin).Length() ))
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_CORPSE:
		{
			UTIL_MakeVectors( pev->angles );
			if ( BuildRoute ( m_vecEnemyLKP - gpGlobals->v_forward * 64, bits_MF_TO_LOCATION, NULL ) )
			{
				TaskComplete();
			}
			else
			{
				ALERT ( at_aiconsole, "GetPathToEnemyCorpse failed!!\n" );
				TaskFail();
			}
		}
		break;
	case TASK_GET_PATH_TO_SPOT:
		{
			CBaseEntity *pPlayer = UTIL_FindEntityByClassname( NULL, "player" );
			if ( BuildRoute ( m_vecMoveGoal, bits_MF_TO_LOCATION, pPlayer ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}

	case TASK_GET_PATH_TO_TARGET:
		{
			RouteClear();
			if ( m_hTargetEnt != NULL && MoveToTarget( m_movementActivity, 1 ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_SCRIPT:
		{
			RouteClear();
			if ( m_pCine != NULL && MoveToLocation( m_movementActivity, 1, m_pCine->pev->origin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_HINTNODE:// for active idles!
		{
			if ( MoveToLocation( m_movementActivity, 2, WorldGraph.m_pNodes[ m_iHintNode ].m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToHintNode failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_LASTPOSITION:
		{
			m_vecMoveGoal = m_vecLastPosition;

			if ( MoveToLocation( m_movementActivity, 2, m_vecMoveGoal ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToLastPosition failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_BESTSOUND:
		{
			CSound *pSound;

			pSound = PBestSound();

			if ( pSound && MoveToLocation( m_movementActivity, 2, pSound->m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToBestSound failed!!\n" );
				TaskFail();
			}
			break;
		}
case TASK_GET_PATH_TO_BESTSCENT:
		{
			CSound *pScent;

			pScent = PBestScent();

			if ( pScent && MoveToLocation( m_movementActivity, 2, pScent->m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToBestScent failed!!\n" );
				
				TaskFail();
			}
			break;
		}
	case TASK_RUN_PATH:
		{
			// UNDONE: This is in some default AI and some monsters can't run? -- walk instead?
			if ( LookupActivity( ACT_RUN ) != ACTIVITY_NOT_AVAILABLE )
			{
				m_movementActivity = ACT_RUN;
			}
			else
			{
				m_movementActivity = ACT_WALK;
			}
			TaskComplete();
			break;
		}
	case TASK_WALK_PATH:
		{
			if ( pev->movetype == MOVETYPE_FLY )
			{
				m_movementActivity = ACT_FLY;
			}
			if ( LookupActivity( ACT_WALK ) != ACTIVITY_NOT_AVAILABLE )
			{
				m_movementActivity = ACT_WALK;
			}
			else
			{
				m_movementActivity = ACT_RUN;
			}
			TaskComplete();
			break;
		}
	case TASK_STRAFE_PATH:
		{
			Vector2D	vec2DirToPoint; 
			Vector2D	vec2RightSide;

			// to start strafing, we have to first figure out if the target is on the left side or right side
			UTIL_MakeVectors ( pev->angles );

			vec2DirToPoint = ( m_Route[ 0 ].vecLocation - pev->origin ).Make2D().Normalize();
			vec2RightSide = gpGlobals->v_right.Make2D().Normalize();

			if ( DotProduct ( vec2DirToPoint, vec2RightSide ) > 0 )
			{
				// strafe right
				m_movementActivity = ACT_STRAFE_RIGHT;
			}
			else
			{
				// strafe left
				m_movementActivity = ACT_STRAFE_LEFT;
			}
			TaskComplete();
			break;
		}


	case TASK_WAIT_FOR_MOVEMENT:
		{
			if (FRouteClear())
			{
				TaskComplete();
			}
			break;
		}

	case TASK_EAT:
		{
			Eat( pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_SMALL_FLINCH:
		{
			m_IdealActivity = GetSmallFlinchActivity();
			break;
		}
	case TASK_DIE:
		{
			RouteClear();	
			
			m_IdealActivity = GetDeathActivity();

			pev->deadflag = DEAD_DYING;
			break;
		}
	case TASK_SOUND_WAKE:
		{
			AlertSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_DIE:
		{
			DeathSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_IDLE:
		{
			IdleSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_PAIN:
		{
			PainSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_DEATH:
		{
			DeathSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_ANGRY:
		{
			// sounds are complete as soon as we get here, cause we've already played them.
			ALERT ( at_aiconsole, "SOUND\n" );			
			TaskComplete();
			break;
		}
	case TASK_WAIT_FOR_SCRIPT:
		{
			if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime )
			{
				TaskComplete(); //LRC - start playing immediately
			}
			else if (!m_pCine->IsAction() && m_pCine->m_iszIdle)
			{
				m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszIdle, FALSE );
				if (FStrEq( STRING(m_pCine->m_iszIdle), STRING(m_pCine->m_iszPlay)))
				{
					pev->framerate = 0;
				}
			}
			else
				m_IdealActivity = ACT_IDLE;

			break;
		}
	case TASK_PLAY_SCRIPT:
		{
			if (m_pCine->IsAction())
			{
				//ALERT(at_console,"PlayScript: setting idealactivity %d\n",m_pCine->m_fAction);
				switch(m_pCine->m_fAction)
				{
				case 0:
					m_IdealActivity = ACT_RANGE_ATTACK1; break;
				case 1:
					m_IdealActivity = ACT_RANGE_ATTACK2; break;
				case 2:
					m_IdealActivity = ACT_MELEE_ATTACK1; break;
				case 3:
					m_IdealActivity = ACT_MELEE_ATTACK2; break;
				case 4:
					m_IdealActivity = ACT_SPECIAL_ATTACK1; break;
				case 5:
					m_IdealActivity = ACT_SPECIAL_ATTACK2; break;
				case 6:
					m_IdealActivity = ACT_RELOAD; break;
				case 7:
					m_IdealActivity = ACT_HOP; break;
				}
				pev->framerate = 1.0; // shouldn't be needed, but just in case
				pev->movetype = MOVETYPE_FLY;
				ClearBits(pev->flags, FL_ONGROUND);
			}
			else
			{
				m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszPlay, TRUE );
				if ( m_fSequenceFinished )
					ClearSchedule();
				pev->framerate = 1.0;
				//ALERT( at_aiconsole, "Script %s has begun for %s\n", STRING( m_pCine->m_iszPlay ), STRING(pev->classname) );
			}
			m_scriptState = SCRIPT_PLAYING;
			break;
		}
	case TASK_ENABLE_SCRIPT:
		{
			m_pCine->DelayStart( 0 );
			TaskComplete();
			break;
		}
//LRC
	case TASK_END_SCRIPT:
		{
			m_pCine->SequenceDone( this );
			TaskComplete();
			break;
		}
	case TASK_PLANT_ON_SCRIPT:
		{
			if ( m_pCine != NULL )
			{
				// Plant on script
				// LRC - if it's a teleport script, do the turn too
				if (m_pCine->m_fMoveTo == 4 || m_pCine->m_fMoveTo == 6)
				{
					if (m_pCine->m_fTurnType == 0) //LRC
						pev->angles.y = m_hTargetEnt->pev->angles.y;
					else if (m_pCine->m_fTurnType == 1)
						pev->angles.y = UTIL_VecToYaw(m_hTargetEnt->pev->origin - pev->origin);
					pev->ideal_yaw = pev->angles.y;
					pev->avelocity = Vector( 0, 0, 0 );
					pev->velocity = Vector( 0, 0, 0 );
					pev->effects |= EF_NOINTERP;
				}

				if (m_pCine->m_fMoveTo != 6)
					pev->origin = m_pGoalEnt->pev->origin;
			}

			TaskComplete();
			break;
		}
	case TASK_FACE_SCRIPT:
		{
			if ( m_pCine != NULL && m_pCine->m_fMoveTo != 0) // movetype "no move" makes us ignore turntype
			{
				switch (m_pCine->m_fTurnType)
				{
				case 0:
					pev->ideal_yaw = UTIL_AngleMod( m_pCine->pev->angles.y );
					break;
				case 1:
					// yes, this is inconsistent- turn to face uses the "target" and turn to angle uses the "cine".
					if (m_hTargetEnt)
						MakeIdealYaw ( m_hTargetEnt->pev->origin );
					else
						MakeIdealYaw ( m_pCine->pev->origin );
					break;
				// default: don't turn
				}
			}

			TaskComplete();
			m_IdealActivity = ACT_IDLE;
			RouteClear();
			break;
		}
	case TASK_SUGGEST_STATE:
		{
			m_IdealMonsterState = (MONSTERSTATE)(int)pTask->flData;
			TaskComplete();
			break;
		}

	case TASK_SET_FAIL_SCHEDULE:
		m_failSchedule = (int)pTask->flData;
		TaskComplete();
		break;

	case TASK_CLEAR_FAIL_SCHEDULE:
		m_failSchedule = SCHED_NONE;
		TaskComplete();
		break;

	default:
		{
			ALERT ( at_aiconsole, "No StartTask entry for %d\n", (SHARED_TASKS)pTask->iTask );
			break;
		}
	}
}
Beispiel #29
0
/* <8e19e> ../cstrike/dlls/func_tank.cpp:214 */
void CFuncTank::__MAKE_VHOOK(KeyValue)(KeyValueData *pkvd)
{
	if (FStrEq(pkvd->szKeyName, "yawrate"))
	{
		m_yawRate = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "yawrange"))
	{
		m_yawRange = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "yawtolerance"))
	{
		m_yawTolerance = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "pitchrange"))
	{
		m_pitchRange = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "pitchrate"))
	{
		m_pitchRate = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "pitchtolerance"))
	{
		m_pitchTolerance = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "firerate"))
	{
		m_fireRate = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "barrel"))
	{
		m_barrelPos.x = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "barrely"))
	{
		m_barrelPos.y = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "barrelz"))
	{
		m_barrelPos.z = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "spritescale"))
	{
		m_spriteScale = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "spritesmoke"))
	{
		m_iszSpriteSmoke = ALLOC_STRING(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "spriteflash"))
	{
		m_iszSpriteFlash = ALLOC_STRING(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "rotatesound"))
	{
		pev->noise = ALLOC_STRING(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "persistence"))
	{
		m_persist = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "bullet"))
	{
		m_bulletType = (TANKBULLET)Q_atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "bullet_damage"))
	{
		m_iBulletDamage = Q_atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "firespread"))
	{
		m_spread = Q_atoi(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "minRange"))
	{
		m_minRange = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "maxRange"))
	{
		m_maxRange = Q_atof(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else if (FStrEq(pkvd->szKeyName, "master"))
	{
		m_iszMaster = ALLOC_STRING(pkvd->szValue);
		pkvd->fHandled = TRUE;
	}
	else
		CBaseEntity::KeyValue(pkvd);
}
//-----------------------------------------------------------------------------
// Purpose: Parse a keyvalues section into the prop
//
//			pInteractionSection is a bit of jiggery-pokery to get around the unfortunate
//			fact that the interaction KV sections ("physgun_interactions", "fire_interactions", etc)
//			are OUTSIDE the "prop_data" KV section in the model, but may be contained WITHIN the 
//			specified Base's "prop_data" section (i.e. in propdata.txt)
//-----------------------------------------------------------------------------
int CPropData::ParsePropFromKV( CBaseEntity *pProp, KeyValues *pSection, KeyValues *pInteractionSection )
{
	IBreakableWithPropData *pBreakableInterface = dynamic_cast<IBreakableWithPropData*>(pProp);
	if ( !pBreakableInterface )
		return PARSE_FAILED_BAD_DATA;

	if ( !pBreakableInterface )
		return PARSE_FAILED_BAD_DATA;

	int iBaseResult = PARSE_SUCCEEDED;

	// Do we have a base?
	char const *pszBase = pSection->GetString( "base" );
	if ( pszBase && pszBase[0] )
	{
		iBaseResult = ParsePropFromBase( pProp, pszBase );
		if ( (iBaseResult != PARSE_SUCCEEDED) && (iBaseResult != PARSE_SUCCEEDED_ALLOWED_STATIC) )
			return iBaseResult;
	}

	// Allow overriding of Block LOS
	int iBlockLOS = pSection->GetFloat( "blockLOS", -1 );
	if ( iBlockLOS != -1 )
	{
		pBreakableInterface->SetPropDataBlocksLOS( iBlockLOS != 0 );
	}

	// Set whether AI can walk on this prop
	int iIsWalkable = pSection->GetFloat( "AIWalkable", -1 );
	if ( iIsWalkable != -1 )
	{
		pBreakableInterface->SetPropDataIsAIWalkable( iIsWalkable != 0 );
	}

	// Set custom damage table
	const char *pszTableName;
	if ( pBreakableInterface->GetPhysicsDamageTable() == NULL_STRING )
	{
		pszTableName = pSection->GetString( "damage_table", NULL );
	}
	else
	{
		pszTableName = pSection->GetString( "damage_table", STRING(pBreakableInterface->GetPhysicsDamageTable()) );
	}
	if ( pszTableName && pszTableName[0] )
	{
		pBreakableInterface->SetPhysicsDamageTable( AllocPooledString( pszTableName ) );
	}
	else
	{
		pBreakableInterface->SetPhysicsDamageTable( NULL_STRING );
	}

	// Get multiplayer physics mode if not set by map
	pBreakableInterface->SetPhysicsMode( pSection->GetInt( "physicsmode", 
		pBreakableInterface->GetPhysicsMode() ) );

	const char *multiplayer_break = pSection->GetString( "multiplayer_break", NULL );
	if ( multiplayer_break )
	{
		mp_break_t mode = MULTIPLAYER_BREAK_DEFAULT;
		if ( FStrEq( multiplayer_break, "server" ) )
		{
			mode = MULTIPLAYER_BREAK_SERVERSIDE;
		}
		else if ( FStrEq( multiplayer_break, "client" ) )
		{
			mode = MULTIPLAYER_BREAK_CLIENTSIDE;
		}
		else if ( FStrEq( multiplayer_break, "both" ) )
		{
			mode = MULTIPLAYER_BREAK_BOTH;
		}
		pBreakableInterface->SetMultiplayerBreakMode( mode );
	}

	// Get damage modifiers, but only if they're specified, because our base may have already overridden them.
	pBreakableInterface->SetDmgModBullet( pSection->GetFloat( "dmg.bullets", pBreakableInterface->GetDmgModBullet() ) );
	pBreakableInterface->SetDmgModClub( pSection->GetFloat( "dmg.club", pBreakableInterface->GetDmgModClub() ) );
	pBreakableInterface->SetDmgModExplosive( pSection->GetFloat( "dmg.explosive", pBreakableInterface->GetDmgModExplosive() ) );

	// Get the health (unless this is an override prop)
	if ( !FClassnameIs( pProp, "prop_physics_override" ) && !FClassnameIs( pProp, "prop_dynamic_override" ) )
	{
		pProp->SetHealth( pSection->GetInt( "health", pProp->GetHealth() ) );

		// Explosive?
		pBreakableInterface->SetExplosiveDamage( pSection->GetFloat( "explosive_damage", pBreakableInterface->GetExplosiveDamage() ) );
		pBreakableInterface->SetExplosiveRadius( pSection->GetFloat( "explosive_radius", pBreakableInterface->GetExplosiveRadius() ) );

#ifdef GAME_DLL
		// If we now have health, we're not allowed to ignore physics damage
		if ( pProp->GetHealth() )
		{
			pProp->RemoveSpawnFlags( SF_PHYSPROP_DONT_TAKE_PHYSICS_DAMAGE );
		}
#endif
	}

	const char *pszBreakableModel;
	if ( pBreakableInterface->GetBreakableModel() == NULL_STRING )
	{
		pszBreakableModel = pSection->GetString( "breakable_model", NULL );
	}
	else
	{
		pszBreakableModel = pSection->GetString( "breakable_model", STRING(pBreakableInterface->GetBreakableModel()) );
	}
	if ( pszBreakableModel && pszBreakableModel[0] )
	{
		pBreakableInterface->SetBreakableModel( AllocPooledString( pszBreakableModel ) );
	}
	else
	{
		pBreakableInterface->SetBreakableModel( NULL_STRING );
	}
	pBreakableInterface->SetBreakableSkin( pSection->GetInt( "breakable_skin", pBreakableInterface->GetBreakableSkin() ) );
	pBreakableInterface->SetBreakableCount( pSection->GetInt( "breakable_count", pBreakableInterface->GetBreakableCount() ) );

	// Calculate the maximum size of the breakables this breakable will produce
	Vector vecSize = pProp->CollisionProp()->OBBSize();
	// Throw away the smallest coord
	int iSmallest = SmallestAxis(vecSize);
	vecSize[iSmallest] = 1;
	float flVolume = vecSize.x * vecSize.y * vecSize.z;
	int iMaxSize = floor( flVolume / (32.0*32.0) );
	pBreakableInterface->SetMaxBreakableSize( iMaxSize );

	// Now parse our interactions
	for ( int i = 0; i < PROPINTER_NUM_INTERACTIONS; i++ )
	{
		// If we hit this assert, we have too many interactions for our current storage solution to handle
		Assert( i < 32 );

		propdata_interaction_s *pInteraction = &sPropdataInteractionSections[i];

		KeyValues *pkvCurrentInter = pInteractionSection->FindKey( pInteraction->pszSectionName );
		if ( pkvCurrentInter )
		{
			char const *pszInterBase = pkvCurrentInter->GetString( pInteraction->pszKeyName );
			if ( pszInterBase && pszInterBase[0] && !stricmp( pszInterBase, pInteraction->pszValue ) )
			{
				pBreakableInterface->SetInteraction( (propdata_interactions_t)i );
			}
		}
	}

	// If the base said we're allowed to be static, return that
	if ( iBaseResult == PARSE_SUCCEEDED_ALLOWED_STATIC )
		return PARSE_SUCCEEDED_ALLOWED_STATIC;

	// Otherwise, see if our propdata says we are allowed to be static
	if ( pSection->GetInt( "allowstatic", 0 ) )
		return PARSE_SUCCEEDED_ALLOWED_STATIC;

	return PARSE_SUCCEEDED;
}