예제 #1
0
void CTFObjectiveResource :: think ()
{
	if ( m_bInitialised && ( m_fNextCheckMonitoredPoint < engine->Time() ) )
	{
		bool bupdate = (m_fUpdatePointTime < engine->Time());

		int team = 0;

		do
		{
			if ( m_iMonitorPoint[team] != -1 )
			{
				for ( int j = 0; j < MAX_PREVIOUS_POINTS; j ++ )
				{
					int prev = GetPreviousPointForPoint(m_iMonitorPoint[team],(team+2),j);

					if ( (prev != -1) && (GetOwningTeam(prev)!=(team+2)) )
					{
						bupdate = true;
						break;
					}
				}
			}
			team++;
		}while ((team < 2) && (bupdate==false));

		if ( bupdate )
		{
			extern ConVar rcbot_tf2_autoupdate_point_time;

			updatePoints();

			m_fNextCheckMonitoredPoint = engine->Time() + 5.0f;
			m_fUpdatePointTime = engine->Time() + rcbot_tf2_autoupdate_point_time.GetFloat();
		}
		else
			m_fNextCheckMonitoredPoint = engine->Time() + 1.0f;
	}
	
}
예제 #2
0
// return true if bots should change attack point
bool CTFObjectiveResource :: updateAttackPoints ( int team )
{	
	int prev;
	int signature = 0;
	CTeamControlPointRound *pRound = CTeamFortress2Mod::getCurrentRound();
	TF2PointProb_t *arr;

	if ( m_ObjectiveResource.get() == NULL ) // not set up yet
		return false;
	if ( team == 0 )
		return false;

	arr = m_ValidPoints[team-2][TF2_POINT_ATTACK];

	// reset array
	memset(arr,0,sizeof(TF2PointProb_t)*MAX_CONTROL_POINTS);
	memset(arr->iPrev,0xFF,sizeof(int)*MAX_PREVIOUS_POINTS);

	if ( (team == TF2_TEAM_RED) && (CTeamFortress2Mod::isAttackDefendMap()) )
	{
		// no attacking for red on this map
		return false;
	}

	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		arr[i].fProb = 1.0f;
		arr[i].fProbMultiplier = 1.0f;
		memset(arr[i].iPrev,0xFF,sizeof(int)*MAX_PREVIOUS_POINTS);

		// not visible
		if ( m_bCPIsVisible[i] == 0 )
			continue;
		// not unlocked
		if ( m_flUnlockTimes[i] > engine->Time() )
			continue;
		// not in round
		if ( m_pControlPoints[i] && pRound && !pRound->isPointInRound(m_pControlPoints[i]) )
			continue;

		// We don't own this point
		if ( GetOwningTeam(i) != team )
		{
			// we can capture
			if ( TeamCanCapPoint(i,team) )
			{
				// if we have captured the previous points we can capture
				if ( (prev = GetPreviousPointForPoint(i,team,0)) != -1 )
				{
					if ( prev == i )
					{
						/*int other = (team==2)?3:2;

						// find the base point
						int basepoint = GetBaseControlPointForTeam(other);

						if ( i == basepoint )
						{
							arr[i].fProb = 0.25f;
						}*/

						arr[i].bValid = true;
					}
					else
					{
						int j;

						bool bCanCap = true;

						for ( j = 0; j < MAX_PREVIOUS_POINTS; j ++ )
						{
							// need to go through each previous point to update the array
							// DONT BREAK!!!
							prev = GetPreviousPointForPoint(i,team,j);
							arr[i].iPrev[j] = prev;

							if ( prev == -1 )
								continue;
							else if ( GetOwningTeam(prev) != team )
								bCanCap = false;
						}

						if ( !bCanCap )
						{
							arr[i].bPrev = true;	
							arr[i].bValid = false;
							// Check later by checking prev points
						}
						else
						{
							arr[i].bValid = true;

							m_iMonitorPoint[team-2] = i;
						}
					}
				}
				else
				{
					if ( !CTeamFortress2Mod::isAttackDefendMap() )
					{
						// if its not an attack defend map check previous points are owned
						int other = (team==2)?3:2;

						// find the base point
						int basepoint = GetBaseControlPointForTeam(other);

						/*if ( i == basepoint )
						{
							arr[i].bValid = true;
							arr[i].fProb = 0.25f;
						}
						else */
					
						if ( basepoint == 0 )
						{
							bool allowned = true;

							// make sure bot owns all points above this point
							for ( int x = i+1; x < *m_iNumControlPoints; x ++ )
							{
								if ( GetOwningTeam(x) != team )
								{
									allowned = false;
									break;
								}
							}				

							if ( allowned )
								arr[i].bValid  = true;
						
							continue;
						}
						else if ( basepoint == ((*m_iNumControlPoints)-1) )
						{
							bool allowned = true;
							// make sure team owns all points below this point
							for ( int x = 0; x < i; x ++ )
							{
								if ( GetOwningTeam(x) != team )
								{
									allowned = false;
									break;
								}
							}				

							if ( allowned )
								arr[i].bValid  = true;

							continue;
						}

					}

					arr[i].bValid  = true;
				}
			}
		}
	}

	// Flush out less important cap points
	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		if ( arr[i].bValid )
		{
			bool bfound = false;

			// find this point in one of the previous points
			for ( int j = 0; j < *m_iNumControlPoints; j ++ )
			{
				if ( i == j )
					continue;

				if ( arr[j].bPrev )
				{
					for ( int k = 0; k < MAX_PREVIOUS_POINTS; k ++ )
					{
						if ( arr[j].iPrev[k] == i )
						{
							bfound = true;
							break;
						}
					}	
				}

				if ( bfound )
					break;

			}

			if ( bfound )
			{
				arr[i].fProb = 1.0f;
			}
			else
			{
				arr[i].fProb = 0.1f;
			}
		}		
	}

	// In Payload give lower numbers higher priority 
	if ( CTeamFortress2Mod::isMapType(TF_MAP_CART) || CTeamFortress2Mod::isMapType(TF_MAP_CARTRACE) )
	{
		for ( int i = 0; i < *m_iNumControlPoints; i ++ )
		{
			if ( arr[i].bValid )
			{
				arr[i].fProb = (float)(*m_iNumControlPoints+1-i);
				arr[i].fProb *= arr[i].fProb; // square it
			}
		}
	}

	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		byte j;
		byte *barr = (byte*)&(arr[i]);

		for ( j = 0; j < sizeof(TF2PointProb_t); j ++ )
			signature = signature + ((barr[j]*(i+1))+j);
	}

	if ( signature != m_PointSignature[team-2][TF2_POINT_ATTACK] )
	{
		m_PointSignature[team-2][TF2_POINT_ATTACK] = signature;
		return true;
	}

	return false;

}
예제 #3
0
bool CTFObjectiveResource :: updateDefendPoints ( int team )
{
	/*int other = (team==2)?3:2;

	return GetCurrentAttackPoint(other);
	*/
	int signature = 0;
	int other;
	int prev;
	bool isPayLoadMap = CTeamFortress2Mod::isMapType(TF_MAP_CART)||CTeamFortress2Mod::isMapType(TF_MAP_CARTRACE);
	TF2PointProb_t *arr;

	//CTeamControlPoint *pPoint;
	//CTeamControlPointMaster *pMaster = CTeamFortress2Mod::getPointMaster();
	CTeamControlPointRound *pRound = CTeamFortress2Mod::getCurrentRound();
	
	if ( m_ObjectiveResource.get() == NULL ) // not set up yet
		return false;
	if ( team == 0 ) // invalid team
		return false;

	arr = m_ValidPoints[team-2][TF2_POINT_DEFEND];

	// reset array
	memset(arr,0,sizeof(TF2PointProb_t)*MAX_CONTROL_POINTS);

	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		arr[i].fProbMultiplier = 1.0f;
		arr[i].fProb = 1.0f;
		memset(arr[i].iPrev,0xFF,sizeof(int)*MAX_PREVIOUS_POINTS);

		// not visible
		if ( m_bCPIsVisible[i] == 0 )
			continue;
		// not unlocked
		if ( m_flUnlockTimes[i] > gpGlobals->curtime )
			continue;
		// not in round
		if ( m_pControlPoints[i] && pRound && !pRound->isPointInRound(m_pControlPoints[i]) )
			continue;
		//int reqcappers = GetRequiredCappers(i,team);

		//if ( m_pControlPoints[i] )
		//	pPoint = CTeamControlPoint::getPoint(m_pControlPoints[i]);
		
		// We own this point
		if ( GetOwningTeam(i) == team )
		{
			// The other team can capture
			other = (team==2)?3:2;

			if ( TeamCanCapPoint(i,other) )
			{
				// if the other team has capture the previous points
				if ( (prev = GetPreviousPointForPoint(i,other,0)) != -1 )
				{
					if ( prev == i )
					{
						arr[i].bValid = true;
						continue;
					}
					else
					{
						// This point needs previous points to be captured first
						int j;
						bool bEnemyCanCap = true;

						for ( j = 0; j < MAX_PREVIOUS_POINTS; j ++ )
						{
							// need to go through each previous point to update the array
							// DONT BREAK!!!
							prev = GetPreviousPointForPoint(i,other,j);
							arr[i].iPrev[j] = prev;

							if ( prev == -1 )
								continue;
							else if ( GetOwningTeam(prev) != other )
								bEnemyCanCap = false;
						}

						if ( !bEnemyCanCap )
						{
							arr[i].bPrev = true;	
							arr[i].bValid = false;
							// Check later by checking prev points
						}
						else
						{
							arr[i].bValid = true;
						}
						/*
						// other team has captured previous points
						if ( j == 3 )
						{
							arr[i].bValid = true;
							continue;
						}
						else
						{
							continue;*/
					}						
				}
				else
				{
					if ( CTeamFortress2Mod::isAttackDefendMap() )
						arr[i].bValid = true;
					else
					{
						int basepoint = GetBaseControlPointForTeam(team);
						arr[i].bValid = true;						

						if ( i == basepoint )
						{
							// check that all other points are owned
							int iNumOwned = 0;
							int iNumAvailable = 0;

							for ( int j = 0; j < *m_iNumControlPoints; j ++ )
							{
								// not visible
								if ( m_bCPIsVisible[j] == 0 )
									continue;
								// not unlocked
								if ( m_flUnlockTimes[j] > gpGlobals->curtime )
									continue;
								// not in round
								if ( m_pControlPoints[j] && pRound && !pRound->isPointInRound(m_pControlPoints[j]) )
									continue;

								if ( GetOwningTeam(j) == other )
									iNumOwned ++;

								iNumAvailable++;
							}

							if ( iNumOwned == (iNumAvailable-1) )
							{								
								// other team can capture
								arr[i].fProb = 1.0f;
							}
							else if ( iNumOwned == (iNumAvailable-2) )
							{							
								extern ConVar bot_defrate;
								// other team can capture this as the next point
								arr[i].fProb = bot_defrate.GetFloat();
							}
							else // still valid but very low probability of ever defending here
								arr[i].fProb = 0.001f;
						}
					}

					continue;
				}
			}
			else
			{
				//arr[i].bValid = true;
				//arr[i].fProb = 0.1f; // 10% of the time defend here
			}
		}
	}
	// do another search through the previous points
	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		if ( arr[i].bPrev )
		{
			int iNumPrevPointsAvail = 0;
			int j;

			// Check this points prevous points
			for ( j = 0; j < MAX_PREVIOUS_POINTS; j ++ )
			{
				if ( arr[i].iPrev[j] != -1 )
				{
					// the previous point is not valid
					if ( arr[arr[i].iPrev[j]].bValid )
						iNumPrevPointsAvail++;
				}
			}

			// only one more point to go until this point
			if ( iNumPrevPointsAvail == 1 )
			{
				// this point is next because the current valid points are required
				arr[i].bNextPoint = true;

				extern ConVar bot_defrate;
		
				// other team can capture this as the next point
				// lower chance of defending the next point before round has started!!! Get everyone up!!
				arr[i].fProb = CTeamFortress2Mod::hasRoundStarted() ? bot_defrate.GetFloat() : (bot_defrate.GetFloat()*0.5f);
			}
		}
	}

	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		if ( arr[i].bNextPoint )
			arr[i].bValid = true;
		else if ( arr[i].bValid )
		{
			bool bfound = false;

			// find this point in one of the previous points
			for ( int j = 0; j < *m_iNumControlPoints; j ++ )
			{
				if ( i == j )
					continue;

				if ( arr[j].bPrev )
				{
					for ( int k = 0; k < MAX_PREVIOUS_POINTS; k ++ )
					{
						if ( arr[j].iPrev[k] == i )
						{
							bfound = true;
							break;
						}
					}	
				}

				if ( bfound )
					break;

			}

			if ( bfound )
			{
				arr[i].fProb = 1.0f;
			}
			else
			{
				arr[i].fProb = 0.1f;
			}
		}		
	}

	// In Payload give lower numbers higher priority 
	if ( isPayLoadMap )
	{
		float fMaxProb = 1.0f;
		bool bFirst = true;
		extern ConVar bot_defrate;
		extern ConVar rcbot_tf2_payload_dist_retreat;

		other = (team==2)?3:2;

		for ( int i = 0; i < *m_iNumControlPoints; i ++ )
		{
			if ( arr[i].bValid )
			{
				edict_t *pPayloadBomb = CTeamFortress2Mod::getPayloadBomb(other);

				if ( pPayloadBomb != NULL )
				{
					if ( bFirst )
					{
						// TO DO update probability depending on distance to payload bomb
						float fDist = (CBotGlobals::entityOrigin(pPayloadBomb) - m_vCPPositions[i]).Length();

						bFirst = false;

						if ( fDist > rcbot_tf2_payload_dist_retreat.GetFloat() )
						{
							arr[i].fProb = 1.0f;

							if ( !CTeamFortress2Mod::hasRoundStarted() )
								fMaxProb = 0.1f;
							else
								fMaxProb = fMaxProb/4;
						}
						else
						{
							arr[i].fProb = bot_defrate.GetFloat();

							int j = i + 1;

							if ( j < *m_iNumControlPoints )
							{
								if ( arr[j].bValid == false )
								{
									if ( !pRound || (m_pControlPoints[j]&&pRound->isPointInRound(m_pControlPoints[j])) )
										arr[j].bValid = true; // this is the next point - move back lads
								}
							}
						}
					}
					else
					{
						arr[i].fProb = fMaxProb;
						fMaxProb = fMaxProb/4;
					}
				}
				else
				{
					arr[i].fProb = fMaxProb;
					fMaxProb = fMaxProb/4;
				}

				
				//arr[i].fProb *= arr[i].fProb; // square it
			}
		}
	}

	// update signature
	for ( int i = 0; i < *m_iNumControlPoints; i ++ )
	{
		byte j;
		byte *barr = (byte*)&(arr[i]);

		for ( j = 0; j < sizeof(TF2PointProb_t); j ++ )
			signature = signature + ((barr[j]*(i+1))+j);
	}

	if ( signature != m_PointSignature[team-2][TF2_POINT_DEFEND] )
	{
		m_PointSignature[team-2][TF2_POINT_DEFEND] = signature;
		return true;
	}

	return false;
}
void C_TFObjectiveResource::SetCappingTeam( int index, int team )
{
	//Display warning that someone is capping our point.
	//Only do this at the start of a cap and if WE own the point.
	//Also don't warn on a point that will do a "Last Point cap" warning.
	if ( GetNumControlPoints() > 0 && GetCapWarningLevel( index ) == CP_WARN_NORMAL && GetCPCapPercentage( index ) == 0.0f && team != TEAM_UNASSIGNED && GetOwningTeam( index ) != TEAM_UNASSIGNED )
	{
		C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
		if ( pLocalPlayer )
		{
			int iLocalTeam = pLocalPlayer->GetTeamNumber();

			if ( iLocalTeam != team )
			{
				CLocalPlayerFilter filter;
				C_BaseEntity::EmitSound( filter, -1, "Announcer.ControlPointContested" );
			}
		}
	}

	BaseClass::SetCappingTeam( index, team );
}