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; } }
// 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; }
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 ); }