Esempio n. 1
0
bool CWeaponFireDesc::FindEventHandler (const CString &sEvent, SEventHandlerDesc *retEvent) const

//	FindEventHandler
//
//	Returns an event handler (if found)

	{
	//	Look for an event handler at the weapon fire level

	ICCItem *pCode;
	if (m_Events.FindEvent(sEvent, &pCode))
		{
		if (retEvent)
			{
			retEvent->pExtension = m_pExtension;
			retEvent->pCode = pCode;
			}

		return true;
		}

	//	Then look for an event handler at the item level

	CItemType *pDevice;
	CItemType *pAmmo = GetWeaponType(&pDevice);
	if (pAmmo && pAmmo->FindEventHandler(sEvent, retEvent))
		return true;

	if (pDevice && pAmmo != pDevice && pDevice->FindEventHandler(sEvent, retEvent))
		return true;

	//	Otherwise, we have no event

	return false;
	}
Esempio n. 2
0
bool CAIActionAttack::ValidateContextPreconditions( CAI* pAI, CAIWorldState& wsWorldStateGoal, bool bIsPlanning )
{
	// No target.

	if( !pAI->HasTarget( kTarget_Character | kTarget_CombatOpportunity | kTarget_Object ) )
	{
		return false;
	}

	// Target is not visible.

	if( m_bValidateVisibility )
	{
		if( ( !pAI->GetAIBlackBoard()->GetBBTargetVisibleFromWeapon() ) &&
			( !IsAI( pAI->GetTarget()->GetVisionBlocker() ) ) )
		{
			return false;
		}
	}

	// AI does not have a weapon of the correct type

	if (!AIWeaponUtils::HasWeaponType(pAI, GetWeaponType(), bIsPlanning))
	{
		return false;
	}

	// Target is not in range.

	if (!AIWeaponUtils::IsInRange(pAI, GetWeaponType(), bIsPlanning))
	{
		return false;
	}

	// AI does not have any ammo required by this weapon type.

	if ( !AIWeaponUtils::HasAmmo(pAI, GetWeaponType(), bIsPlanning ) )
	{
		return false;
	}

	return true;
}
Esempio n. 3
0
void CAIActionAttack::ActivateAction( CAI* pAI, CAIWorldState& wsWorldStateGoal )
{
	super::ActivateAction( pAI, wsWorldStateGoal );

	// Set our weapon of the desired type as current weapon.

	pAI->SetCurrentWeapon( GetWeaponType() );

	// Set animate state.

	pAI->SetState( kState_Animate );

	// Set attack animation.

	CAnimationProps	animProps;
	SetAttackAnimProps( pAI, &animProps );

	CAIStateAnimate* pStateAnimate = (CAIStateAnimate*)( pAI->GetState() );
	pStateAnimate->SetAnimation( animProps, GetLoopAttackAnimation( pAI ) );

	// Turn off any automatic reloading that may have been previously set.

	pAI->GetAIBlackBoard()->SetBBAutoReload( false );

	// Get the target.

	HOBJECT hTarget = NULL;
	if( pAI->HasTarget( kTarget_Character | kTarget_Object | kTarget_CombatOpportunity) )
	{
		hTarget = pAI->GetAIBlackBoard()->GetBBTargetObject();
	}

	// Play attack sound.
	// Only play if we've been targeting someone for at least 5 seconds.
	// This ensures we first play higher priority reaction sounds.

	if( ( m_bPlayAISound && pAI->GetAIBlackBoard()->GetBBTargetVisibleFromWeapon() ) &&
		( pAI->GetAIBlackBoard()->GetBBTargetChangeTime() < g_pLTServer->GetTime() - 10.f ) )
	{
		if( IsTurret( hTarget ) )
		{
			g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_TurretStress, kAISndCat_Event, hTarget, 0.f );
		}
		else if( g_pAICoordinator->FindAlly( pAI->m_hObject, NULL ) )
		{
			g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_Attack, kAISndCat_Combat, hTarget, 0.f );
		}
	}

	// Torso tracking.

	pAI->GetAIBlackBoard()->SetBBTargetTrackerFlags( kTrackerFlag_AimAt );
	pAI->GetAIBlackBoard()->SetBBFaceTarget( true );
}
Esempio n. 4
0
eWeaponHandType CGoods::GetWeaponHandType()
{
	eWeaponType eWT=GetWeaponType();
	if(eWT!=WHT_UNKNOWN)
	{
		if(eWT==WT_SINGLE_SWORD || eWT==WT_SINGLE_KNIFE || eWT==WT_SINGLE_HAMMER)
			return WHT_SINGLE_HAND;
		else
			return WHT_DOUBLE_HAND;
	}
	else
		return WHT_UNKNOWN;
}
Esempio n. 5
0
bool CWeaponFireDesc::FireOnFragment (const CDamageSource &Source, CSpaceObject *pShot, const CVector &vHitPos, CSpaceObject *pNearestObj, CSpaceObject *pTarget)

//	FireOnFragment
//
//	Event fires when a shot fragments. If we return TRUE then we skip the default
//	fragmentation event.

	{
	SEventHandlerDesc Event;
	if (FindEventHandler(evtOnFragment, &Event))
		{
		//	Setup arguments

		CCodeChainCtx CCCtx;

		CCCtx.SaveAndDefineSourceVar(pShot);
		CCCtx.DefineSpaceObject(CONSTLIT("aNearestObj"), pNearestObj);
		CCCtx.DefineSpaceObject(CONSTLIT("aTargetObj"), pTarget);
		CCCtx.DefineVector(CONSTLIT("aHitPos"), vHitPos);
		CCCtx.DefineInteger(CONSTLIT("aHitDir"), (pShot ? pShot->GetRotation() : 0));
		CCCtx.DefineItemType(CONSTLIT("aWeaponType"), GetWeaponType());
		CCCtx.DefineString(CONSTLIT("aWeaponFragment"), m_sUNID);

		CSpaceObject *pAttacker = Source.GetObj();
		CCCtx.DefineSpaceObject(CONSTLIT("aCause"), pShot);
		CCCtx.DefineSpaceObject(CONSTLIT("aAttacker"), pAttacker);
		CCCtx.DefineSpaceObject(CONSTLIT("aOrderGiver"), (pAttacker ? pAttacker->GetOrderGiver(Source.GetCause()) : NULL));

		ICCItem *pResult = CCCtx.Run(Event);
		if (pResult->IsError())
			pShot->ReportEventError(ON_FRAGMENT_EVENT, pResult);

		//	If we return Nil, then we continue processing

		bool bResult;
		if (pResult->IsNil())
			bResult = false;

		//	Otherwise, we skip fragmentation

		else
			bResult = true;

		CCCtx.Discard(pResult);

		return bResult;
		}
	else
		return false;
	}
Esempio n. 6
0
// Calculate weapon range using efficient stuffs
float CPlayer::GetWeaponRangeFromSlot( uint uiSlot )
{
    eWeaponType eWeapon = static_cast < eWeaponType > ( GetWeaponType ( uiSlot ) );
    float fSkill = GetPlayerStat ( CWeaponStatManager::GetSkillStatIndex ( eWeapon ) );

    if ( fSkill != m_fWeaponRangeLastSkill || eWeapon != m_eWeaponRangeLastWeapon || CWeaponStat::GetAllWeaponStatsRevision() != m_uiWeaponRangeLastStatsRevision )
    {
        m_fWeaponRangeLastSkill = fSkill;
        m_eWeaponRangeLastWeapon = eWeapon;
        m_uiWeaponRangeLastStatsRevision = CWeaponStat::GetAllWeaponStatsRevision();
        m_fWeaponRangeLast = g_pGame->GetWeaponStatManager ( )->GetWeaponRangeFromSkillLevel ( eWeapon, fSkill );       
    }
    return m_fWeaponRangeLast;
}
Esempio n. 7
0
void ItemDef :: Debug_WriteReport(ReportBuffer &report)
{
	report.AddLine("%s [%d] lev:%d, qlev:%d", mDisplayName.c_str(), mID, mLevel, mQualityLevel);
	report.AddLine("%s | %s | %s", GetEquipType(mEquipType), GetArmorType(mArmorType), GetWeaponType(mWeaponType));
	report.AddLine("str:%d, dex:%d, con:%d, psy:%d, spi:%d", mBonusStrength, mBonusDexterity, mBonusConstitution, mBonusPsyche, mBonusSpirit);
	report.AddLine("armor:%d, dmg:%d-%d", mArmorResistMelee, mWeaponDamageMin, mWeaponDamageMax);
	if(mFlavorText.size() > 0)
	{
		std::string tmp = mFlavorText;
		size_t pos;
		pos = tmp.find(FLAVOR_TEXT_HEADER);
		if(pos != string::npos)
			tmp.erase(pos, strlen(FLAVOR_TEXT_HEADER));
		pos = tmp.find(FLAVOR_TEXT_FOOTER);
		if(pos != string::npos)
			tmp.erase(pos, strlen(FLAVOR_TEXT_FOOTER));

		report.AddLine("flavor:%s", tmp.c_str());
	}
	report.AddLine(NULL);
}
Esempio n. 8
0
bool CAIActionAttack::ValidateAction( CAI* pAI )
{
	if( !super::ValidateAction( pAI ) )
	{
		return false;
	}

	// Target is not visible.
	// And target is not obscured by an AI.

	if( m_bValidateVisibility)
	{
		if ( !pAI->GetAIBlackBoard()->GetBBTargetVisibleFromWeapon() 
			&& ( !IsAI( pAI->GetTarget()->GetVisionBlocker() ) ) )
		{
			return false;
		}
	}
 
	// Target is not in range.

	if ( m_bInterruptActionIfEnemyIsOutOfRange )
	{
		if( pAI->GetAIBlackBoard()->GetBBWeaponStatus(GetWeaponType()) != kRangeStatus_Ok )
		{
			return false;
		}
	}

	// Weapon is unloaded.

	SAIWORLDSTATE_PROP* pProp = pAI->GetAIWorldState()->GetWSProp( kWSK_WeaponLoaded, pAI->m_hObject );
	if( pProp && !pProp->bWSValue )
	{
		return false;
	}

	return true;
}
Esempio n. 9
0
bool CAIActionAttackGrenade::ValidateContextPreconditions( CAI* pAI, CAIWorldState& wsWorldStateGoal, bool bIsPlanning )
{
	// Target is not visible.

	if( !pAI->HasTarget( kTarget_Character | kTarget_Object ) )
	{
		return false;
	}

	// AI does not have a weapon of the correct type

	if (!AIWeaponUtils::HasWeaponType(pAI, GetWeaponType(), bIsPlanning))
	{
		return false;
	}

	// AI does not have any ammo for this weapon.

	if ( !AIWeaponUtils::HasAmmo( pAI, GetWeaponType(), bIsPlanning ) )
	{
		return false;
	}

	// At a node that does not allow grenade throwing.

	bool bAtNode = false;
	bool bStraightPathCheckRequired = true;
	SAIWORLDSTATE_PROP* pProp = pAI->GetAIWorldState()->GetWSProp( kWSK_AtNode, pAI->m_hObject );
	if( pProp && pProp->hWSValue )
	{
		AINode* pNode = (AINode*)g_pLTServer->HandleToObject( pProp->hWSValue );
		if( !pNode )
		{
			return false;
		}

		if( !pNode->AllowThrowGrenades() )
		{
			return false;
		}

		if( !pNode->IsNodeValid( pAI, pAI->GetPosition(), pAI->GetAIBlackBoard()->GetBBTargetObject(), kThreatPos_TargetPos, kNodeStatus_ThreatOutsideFOV ) )
		{
			return false;
		}

		bStraightPathCheckRequired = pNode->RequiresStraightPathToThrowGrenades();
		bAtNode = true;
	}

	// Target is not in range.

	if (!AIWeaponUtils::IsInRange(pAI, GetWeaponType(), bIsPlanning))
	{
		return false;
	}

	// Someone else has thrown a grenade recently.

	CAIWMFact factQuery;
	factQuery.SetFactType(kFact_Knowledge);
	factQuery.SetKnowledgeType(kKnowledge_NextGrenadeTime);
	CAIWMFact* pFact = g_pAIWorkingMemoryCentral->FindWMFact(factQuery);
	if(pFact && g_pLTServer->GetTime() < pFact->GetTime() )
	{
		return false;
	}

	// Throw at the last known position.

	CAIWMFact factTargetQuery;
	HOBJECT hTarget = pAI->GetAIBlackBoard()->GetBBTargetObject();
	factTargetQuery.SetFactType( kFact_Character );
	factTargetQuery.SetTargetObject( hTarget );
	pFact = pAI->GetAIWorkingMemory()->FindWMFact( factTargetQuery );
	if( !pFact )
	{
		return false;
	}
	LTVector vTargetPos = pFact->GetPos();

	/***
	// Only throw a grenade when not at a node when there is a 
	// straight path to the target.  This is to ensure the 
	// grenade won't bounce back and kill the thrower.

	if( bStraightPathCheckRequired )
	{
		if( !g_pAIPathMgrNavMesh->StraightPathExists( pAI, pAI->GetCharTypeMask(), pAI->GetPosition(), vTargetPos, pAI->GetLastNavMeshPoly(), 0.f ) )
		{
			return false;
		}
	}
	***/

	/***
	// Don't throw if someone is closer to the target than me, 
	// because I might hit them!

	if( pAI != g_pCharacterMgr->FindNearestAIAlly( pAI, vTargetPos ) )
	{
		return false;
	}
	***/

	// Get the grenade explosion radius.

	HAMMO hAmmo = AIWeaponUtils::GetWeaponAmmo( pAI, GetWeaponType(), bIsPlanning );
	HAMMODATA hAmmoData = g_pWeaponDB->GetAmmoData(hAmmo,true);
	float fRadius = g_pWeaponDB->GetFloat( hAmmoData, WDB_AMMO_fAreaDamageRadius );
	fRadius *= 1.2f;

	// Don't throw if we're in the radius!

	if( pAI->GetPosition().DistSqr( vTargetPos ) < fRadius * fRadius )
	{
		return false;
	}

	// Don't throw if an ally is in the blast radius.

	if( g_pCharacterMgr->FindAIAllyInRadius( pAI, vTargetPos, fRadius ) )
	{
		return false;
	}

/***
	// Don't throw grenade at allies.

	CTList<CCharacter*> lstChars;
	if( g_pCharacterMgr->FindCharactersWithinRadius( &lstChars, vTargetPos, fRadius, CCharacterMgr::kList_AIs ) )
	{
		// Iterate over characters in grenade's radius.

		CCharacter** pCur = lstChars.GetItem(TLIT_FIRST);
		while( pCur )
		{
			CCharacter* pChar = (CCharacter*)*pCur;
			pCur = lstChars.GetItem(TLIT_NEXT);

			// Skip the AI himself.

			if( pChar == pAI )
			{
				continue;
			}

			// Action is invalid if grenade could hit someone 
			// that the AI does not hate.

			if( g_pCharacterDB->GetStance( pAI->GetAlignment(), pChar->GetAlignment() ) != kCharStance_Hate )
			{
				return false;
			}
		}
	}
***/

	// Throw a grenade.

	return true;
}
bool CAIActionAttackLungeUncloaked::ValidateContextPreconditions( CAI* pAI, CAIWorldState& wsWorldStateGoal, bool bIsPlanning )
{
	// AI doesn't have a target.

	if (!pAI->HasTarget( kTarget_Character ))
	{
		return false;
	}

	// Target is not visible.

	if( !pAI->GetAIBlackBoard()->GetBBTargetVisibleFromWeapon() )
	{
		return false;
	}

	// AI does not have a weapon of the correct type

	if (!AIWeaponUtils::HasWeaponType(pAI, GetWeaponType(), bIsPlanning))
	{
		return false;
	}

	// AI does not have any ammo for this weapon.

	if ( !AIWeaponUtils::HasAmmo( pAI, GetWeaponType(), bIsPlanning ) )
	{
		return false;
	}

	// Someone else is lunging.  Only one AI may lunge at a time.

	CAIWMFact factQuery;
	factQuery.SetFactType( kFact_Knowledge );
	factQuery.SetKnowledgeType( kKnowledge_Lunging );
	CAIWMFact* pFact = g_pAIWorkingMemoryCentral->FindWMFact(factQuery);
	if( pFact )
	{
		// Clear records of dead AI.

		if( IsDeadAI( pFact->GetSourceObject() ) )
		{
			g_pAIWorkingMemoryCentral->ClearWMFacts( factQuery );
		}
		else return false;
	}

	// Bail if the Action's SmartObject record does not exist.

	AIDB_SmartObjectRecord* pSmartObjectRecord = g_pAIDB->GetAISmartObjectRecord( m_pActionRecord->eSmartObjectID );
	if( !pSmartObjectRecord )
	{
		return false;
	}


	// Someone has lunged too recently.

	if( pSmartObjectRecord->fTimeout > 0.f )
	{
		factQuery.SetFactType( kFact_Knowledge );
		factQuery.SetKnowledgeType( kKnowledge_NextLungeTime );
		pFact = g_pAIWorkingMemoryCentral->FindWMFact(factQuery);
		if( pFact && ( pFact->GetTime() > g_pLTServer->GetTime() ) )
		{
			return false;
		}
	}

	// Bail if the AI does not have the desire to lunge.
	// The desire indicates the max range of the lunge.

	CAIWMFact factDesireQuery;
	factDesireQuery.SetFactType( kFact_Desire );
	factDesireQuery.SetDesireType( kDesire_Lunge );
	CAIWMFact* pDesireFact = pAI->GetAIWorkingMemory()->FindWMFact( factDesireQuery );
	if( !pDesireFact )
	{
		return false;
	}

	// Target must be in range.

	LTVector vTarget = pAI->GetAIBlackBoard()->GetBBTargetPosition();
	float fDistSqr = vTarget.DistSqr( pAI->GetPosition() );

	// Target too close.

	if( fDistSqr < pSmartObjectRecord->fMinDist * pSmartObjectRecord->fMinDist )
	{
		return false;
	}

	// Target too far.

	float fMaxDist = GetLungeMaxDist( pAI, pDesireFact );
	if( fDistSqr > fMaxDist * fMaxDist )
	{
		return false;
	}

	// No straight path to the target.

	LTVector vDir = vTarget - pAI->GetPosition();
	vDir.Normalize();
	LTVector vDest = pAI->GetPosition() + ( vDir * ( fMaxDist + 50.f ) );
	if( !g_pAIPathMgrNavMesh->StraightPathExists( pAI, pAI->GetCharTypeMask(), pAI->GetPosition(), vDest, pAI->GetAIBlackBoard()->GetBBTargetReachableNavMeshPoly(), pAI->GetRadius() ) )
	{
		return false;
	}

	// Lunge!

	return true;
}
Esempio n. 11
0
//--------------------------------------------------------------------------------------------------------------
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;
		}
	}
}
Esempio n. 12
0
void CPlayerStats::UpdatePlayerWeapon(uint8 nWeapon, LTBOOL bForce)
{
    if (!m_pClientShell) return;
    if (m_nCurrentWeapon == nWeapon && !bForce) return;

    if (GetWeaponType((RiotWeaponId)nWeapon) == MELEE && m_pClientShell)
    {
        // we will not be drawing the ammo count, so make sure all of it gets removed...
        m_pClientShell->AddToClearScreenCount();
    }

    m_nCurrentWeapon = nWeapon;

    if (m_hAmmoIcon)
    {
        m_pClientDE->DeleteSurface (m_hAmmoIcon);
        m_hAmmoIcon = LTNULL;
    }

    char strFilename[MAX_CS_FILENAME_LEN];
    switch (nWeapon)
    {
    case GUN_PULSERIFLE_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_PulseRifle.pcx");
        break;
    case GUN_SPIDER_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Spider.pcx");
        break;
    case GUN_BULLGUT_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Bullgut.pcx");
        break;
    case GUN_SNIPERRIFLE_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_SniperRifle.pcx");
        break;
    case GUN_JUGGERNAUT_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Juggernaut.pcx");
        break;
    case GUN_SHREDDER_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Shredder.pcx");
        break;
    case GUN_REDRIOT_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_RedRiot.pcx");
        break;

    case GUN_COLT45_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Colt45.pcx");
        break;
    case GUN_SHOTGUN_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Shotgun.pcx");
        break;
    case GUN_ASSAULTRIFLE_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_AssaultRifle.pcx");
        break;
    case GUN_ENERGYGRENADE_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_EnergyGrenade.pcx");
        break;
    case GUN_KATOGRENADE_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_KatoGrenade.pcx");
        break;
    case GUN_MAC10_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Mac10.pcx");
        break;
    case GUN_TOW_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_Tow.pcx");
        break;
    case GUN_LASERCANNON_ID:
        SAFE_STRCPY(strFilename, "interface/Ammo_LaserCannon.pcx");
        break;

    // handle the melee weapons (turn off ammo display)

    case GUN_SQUEAKYTOY_ID:
    case GUN_ENERGYBATON_ID:
    case GUN_ENERGYBLADE_ID:
    case GUN_KATANA_ID:
    case GUN_MONOKNIFE_ID:
    case GUN_TANTO_ID:
    {
        SetDrawAmmo (LTFALSE);
        return;
    }

    default:
        SAFE_STRCPY(strFilename, "");
        break;
    }

    if (!m_pClientShell->IsVehicleMode())
    {
        SetDrawAmmo (LTTRUE);
    }

    if (strFilename[0] != '\0') m_hAmmoIcon = m_pClientDE->CreateSurfaceFromBitmap (strFilename);
    if (m_hAmmoIcon)
    {
        m_pClientDE->GetSurfaceDims (m_hAmmoIcon, &m_cxAmmoIcon, &m_cyAmmoIcon);
    }

    m_bAmmoChanged = LTTRUE;
    Update();
}
Esempio n. 13
0
void BuyState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
{
	// wait for a Navigation Mesh
	if (!TheNavAreaList.size())
		return;

	// apparently we cant buy things in the first few seconds, so wait a bit
	if (m_isInitialDelay)
	{
		const float waitToBuyTime = 2.0f; // 0.25f;
		if (gpGlobals->time - 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())
		{
#ifdef REGAMEDLL_FIXES
			// make sure we're locked and loaded
			me->EquipBestWeapon(MUST_EQUIP);
			me->Reload();
			me->ResetStuckMonitor();
#endif
			return;
		}

		me->Idle();

#ifdef REGAMEDLL_FIXES
		return;
#endif
	}

	// is the bot spawned outside of a buy zone?
	if (!(me->m_signals.GetState() & SIGNAL_BUY))
	{
		m_doneBuying = true;
		UTIL_DPrintf("%s bot spawned outside of a buy zone (%d, %d, %d)\n", (me->m_iTeam == CT) ? "CT" : "Terrorist", int(me->pev->origin.x), int(me->pev->origin.y), int(me->pev->origin.z));
		return;
	}

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

		bool isPreferredAllDisallowed = true;

		// try to buy our preferred weapons first
		if (m_prefIndex < me->GetProfile()->GetWeaponPreferenceCount())
		{
			// 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
			CBasePlayerWeapon *weapon = me->GetActiveWeapon();
			if (weapon != NULL && weapon->m_iId == weaponPreference)
			{
				// 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)
			{
				me->ClientCommand(buyAlias);
				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->m_bHasPrimary && (isPreferredAllDisallowed || !me->GetProfile()->HasPrimaryPreference()))
		{
			if (m_buyShield)
			{
				// buy a shield
				me->ClientCommand("shield");
				me->PrintIfWatched("Tried to buy a shield.\n");
			}
			else
			{
				// build list of allowable weapons to buy
				BuyInfo *masterPrimary = (me->m_iTeam == 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 = (RANDOM_FLOAT(0, 100) < sniperRifleChance) ? true : false;

				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)
					{
						// count up available preferred weapons
						int prefCount = 0;
						for (which = 0; which < stockPrimaryCount; ++which)
						{
							if (stockPrimary[which]->preferred)
								++prefCount;
						}

						if (prefCount)
						{
							int whichPref = RANDOM_LONG(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 = RANDOM_LONG(0, stockPrimaryCount - 1);
						}
					}
					else
					{
						which = RANDOM_LONG(0, stockPrimaryCount - 1);
					}

					me->ClientCommand(stockPrimary[ which ]->buyAlias);
					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->m_bHasPrimary || m_retries++ > 5)
		{
			// primary ammo
			if (me->m_bHasPrimary)
			{
				me->ClientCommand("primammo");
			}

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

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

					if (me->m_iTeam == TERRORIST)
						me->ClientCommand(secondaryWeaponBuyInfoT[ which ].buyAlias);
					else
						me->ClientCommand(secondaryWeaponBuyInfoCT[ which ].buyAlias);

					// only buy one pistol
					m_buyPistol = false;
				}

				me->ClientCommand("secammo");
			}

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

					if (rnd < 10.0f)
					{
						// smoke grenade
						me->ClientCommand("sgren");
					}
					else if (rnd < 35.0f)
					{
						// flashbang
						me->ClientCommand("flash");
					}
					else
					{
						// he grenade
						me->ClientCommand("hegren");
					}
				}
				else
				{
					if (RANDOM_FLOAT(0, 100) < 10.0f)
					{
						// smoke grenade
						me->ClientCommand("sgren");
					}
					else
					{
						// he grenade
						me->ClientCommand("hegren");
					}
				}
			}

			if (m_buyDefuseKit)
			{
				me->ClientCommand("defuser");
			}

			m_doneBuying = true;
		}
	}
}
Esempio n. 14
0
//Nothing important, just used to write out arbitrary data to a file to help with whatever
//sorting or data analysis is needed at the time.
void ItemDef :: Debug_WriteToStream(FILE *output)
{
	fprintf(output, "%d;%d;%d;%d;", mID, mQualityLevel, mLevel, mMinUseLevel);
	fprintf(output, "%s;%s;%s;%s;", mDisplayName.c_str(), GetEquipType(mEquipType), GetArmorType(mArmorType), GetWeaponType(mWeaponType));
	if(mBonusStrength != 0) fprintf(output, "%d;", mBonusStrength); else fputc(';', output);
	if(mBonusDexterity != 0) fprintf(output, "%d;", mBonusDexterity); else fputc(';', output);
	if(mBonusConstitution != 0) fprintf(output, "%d;", mBonusConstitution); else fputc(';', output);
	if(mBonusPsyche != 0) fprintf(output, "%d;", mBonusPsyche); else fputc(';', output);
	if(mBonusSpirit != 0) fprintf(output, "%d;", mBonusSpirit); else fputc(';', output);
	fprintf(output, "%d;%d;", mArmorResistMelee, mValue);
	if(mWeaponDamageMax != 0) fprintf(output, "%d-%d;", mWeaponDamageMin, mWeaponDamageMax); else fputc(';', output);
	switch(mBindingType)
	{
	case BIND_ON_EQUIP: fputs("E;", output); break;
	case BIND_ON_PICKUP: fputs("P;", output); break;
	default: fputc(';', output); break;
	}
	fprintf(output, "%s;%s;", mSv1.c_str(), mFlavorText.c_str());
	fputs("\r\n", output);
}