CBasePlayer *CHostageImprov::__MAKE_VHOOK(GetClosestPlayerByTravelDistance)(int team, float *range) const { CBasePlayer *close = NULL; float closeRange = 9.9999998e10f; if (GetLastKnownArea() == NULL) return NULL; for (int i = 1; i <= gpGlobals->maxClients; ++i) { CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i)); if (!IsEntityValid(player)) continue; if (player->IsAlive() && (team == UNASSIGNED || player->m_iTeam == team)) { ShortestPathCost cost; Vector vecCenter = player->Center(); float_precision range = NavAreaTravelDistance(GetLastKnownArea(), TheNavAreaGrid.GetNearestNavArea(&vecCenter), cost); if (range > 0 && range < closeRange) { closeRange = range; close = player; } } } if (range) *range = closeRange; return close; }
// Decide if we should move to help the player, return true if we will bool CCSBot::RespondToHelpRequest(CBasePlayer *them, Place place, float maxRange) { if (IsRogue()) return false; // if we're busy, ignore if (IsBusy()) return false; // if we are too far away, ignore if (maxRange > 0.0f) { // compute actual travel distance PathCost pc(this); real_t travelDistance = NavAreaTravelDistance(m_lastKnownArea, TheNavAreaGrid.GetNearestNavArea(&them->pev->origin), pc); if (travelDistance < 0.0f) return false; if (travelDistance > maxRange) return false; } if (place == UNDEFINED_PLACE) { // if we have no "place" identifier, go directly to them // if we are already there, ignore float rangeSq = (them->pev->origin - pev->origin).LengthSquared(); const float close = 750.0f * 750.0f; if (rangeSq < close) return true; MoveTo(&them->pev->origin, FASTEST_ROUTE); } else { // if we are already there, ignore if (GetPlace() == place) return true; // go to where help is needed const Vector *pos = GetRandomSpotAtPlace(place); if (pos) { MoveTo(pos, FASTEST_ROUTE); } else { MoveTo(&them->pev->origin, FASTEST_ROUTE); } } // acknowledge GetChatter()->Say("OnMyWay"); return true; }
/* <3fd5ab> ../cstrike/dlls/bot/cs_gamestate.cpp:398 */ CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos) const { if (m_owner == NULL) return NULL; CNavArea *startArea = m_owner->GetLastKnownArea(); if (startArea == NULL) return NULL; CHostage *close = NULL; const Vector *closePos = NULL; float closeDistance = 9999999999.9f; for (int i = 0; i < m_hostageCount; ++i) { CHostage *hostage = m_hostage[i].hostage; const Vector *hostagePos = NULL; if (m_owner->m_iTeam == CT) { // we know exactly where the hostages are, and if they are alive if (!m_hostage[i].hostage || !m_hostage[i].hostage->IsValid()) continue; if (m_hostage[i].hostage->IsFollowingSomeone()) continue; hostagePos = &hostage->pev->origin; } else { // use our memory of where we think the hostages are if (m_hostage[i].isValid == false) continue; hostagePos = &m_hostage[i].knownPos; } CNavArea *hostageArea = TheNavAreaGrid.GetNearestNavArea(hostagePos); if (hostageArea != NULL) { ShortestPathCost pc; float travelDistance = NavAreaTravelDistance(startArea, hostageArea, pc); if (travelDistance >= 0.0f && travelDistance < closeDistance) { closePos = hostagePos; closeDistance = travelDistance; close = hostage; } } } // return where we think the hostage is if (knowPos != NULL && closePos != NULL) { knowPos = const_cast<Vector *>(closePos); } return close; }