ActionResult<CTFBot> CTFBotMarkGiants::OnStart(CTFBot *actor, Action<CTFBot> *action) { this->m_PathFollower.SetMinLookAheadDistance(actor->GetDesiredPathLookAheadRange()); CTFWeaponBase *weapon = GetMarkForDeathWeapon(actor); if (weapon == nullptr) { return ActionResult<CTFBot>::Done("Don't have a mark-for-death weapon."); } std::vector<CTFPlayer *> potential_victims; ForEachPlayer([&](CBasePlayer *player, bool& done){ CTFPlayer *tfplayer = ToTFPlayer(player); if (tfplayer == nullptr) return; if (IsPlayerMarkable(actor, tfplayer)) { potential_victims.push_back(tfplayer); } }); if (potential_victims.empty()) { return ActionResult<CTFBot>::Done("No eligible mark victims."); } this->m_hTarget = potential_victims[RandomInt(0, potential_victims.size() - 1)]; actor->PushRequiredWeapon(weapon); return ActionResult<CTFBot>::Continue(); }
bool CHostageImprov::IsFriendInTheWay() const { CheckAhead check(this); g_pHostages->ForEachHostage(check); ForEachPlayer(check); return check.IsBlocked(); }
bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) { class cCallback : public cPlayerListCallback { size_t m_BestRating; size_t m_NameLength; const AString m_PlayerName; virtual bool Item (cPlayer * a_pPlayer) { size_t Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName()); if ((Rating > 0) && (Rating >= m_BestRating)) { m_BestMatch = a_pPlayer->GetName(); if (Rating > m_BestRating) { m_NumMatches = 0; } m_BestRating = Rating; ++m_NumMatches; } if (Rating == m_NameLength) // Perfect match { return true; } return false; } public: cCallback (const AString & a_PlayerName) : m_BestRating(0), m_NameLength(a_PlayerName.length()), m_PlayerName(a_PlayerName), m_BestMatch(), m_NumMatches(0) {} AString m_BestMatch; unsigned m_NumMatches; } Callback (a_PlayerName); ForEachPlayer(Callback); if (Callback.m_NumMatches == 1) { return DoWithPlayer(Callback.m_BestMatch, a_Callback); } return false; }
bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback) { class cCallback : public cPlayerListCallback { unsigned int BestRating; unsigned int NameLength; const AString PlayerName; cPlayerListCallback & m_Callback; virtual bool Item (cPlayer * a_pPlayer) { unsigned int Rating = RateCompareString (PlayerName, a_pPlayer->GetName()); if (Rating > 0 && Rating >= BestRating) { BestMatch = a_pPlayer; if( Rating > BestRating ) NumMatches = 0; BestRating = Rating; ++NumMatches; } if (Rating == NameLength) // Perfect match { return false; } return true; } public: cCallback (const AString & a_PlayerName, cPlayerListCallback & a_Callback) : m_Callback( a_Callback ) , BestMatch( NULL ) , BestRating( 0 ) , NumMatches( 0 ) , NameLength( a_PlayerName.length() ) , PlayerName( a_PlayerName ) {} cPlayer * BestMatch; unsigned int NumMatches; } Callback (a_PlayerName, a_Callback); ForEachPlayer( Callback ); if (Callback.NumMatches == 1) { return a_Callback.Item (Callback.BestMatch); } return false; }
bool CTFBotMarkGiants::IsPossible(CTFBot *actor) { if (GetMarkForDeathWeapon(actor) == nullptr) return false; bool victim_exists = false; ForEachPlayer([&](CBasePlayer *player, bool& done){ CTFPlayer *tfplayer = ToTFPlayer(player); if (tfplayer == nullptr) return; if (IsPlayerMarkable(actor, tfplayer)) { victim_exists = true; done = true; } }); return victim_exists; }
/** * Constructor */ CNavNode::CNavNode( const Vector &pos, const Vector &normal, CNavNode *parent ) { m_pos = pos; m_normal = normal; m_id = m_nextID++; int i; for( i=0; i<NUM_DIRECTIONS; ++i ) { m_to[ i ] = NULL; } for ( i=0; i<NUM_CORNERS; ++i ) { m_crouch[ i ] = false; } m_visited = 0; m_parent = parent; m_next = m_list; m_list = this; m_listLength++; m_isCovered = false; m_area = NULL; m_attributeFlags = 0; if ( nav_show_nodes.GetBool() ) { NDebugOverlay::Cross3D( m_pos, 10.0f, 128, 128, 128, true, 10.0f ); NDebugOverlay::Cross3D( m_pos, 10.0f, 255, 255, 255, false, 10.0f ); LookAtTarget lookAt( m_pos ); ForEachPlayer( lookAt ); } }
//----------------------------------------------------------------------------- // 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(); }
void CHostageImprov::UpdatePosition(float deltaT) { CNavArea *area = TheNavAreaGrid.GetNavArea(&m_hostage->pev->origin); if (area != NULL) { m_lastKnownArea = area; } DrawAxes(m_moveGoal, 255, 255, 0); if (IsJumping()) { Vector dir; const float pushSpeed = 100.0f; if (!m_hasJumped) { m_hasJumped = true; m_hasJumpedIntoAir = false; m_hostage->pev->velocity.z += 300.0f; } else ResetJump(); dir = m_jumpTarget - GetFeet(); dir.z = 0; #ifndef PLAY_GAMEDLL // TODO: fix test demo dir.NormalizeInPlace(); m_hostage->pev->velocity.x = dir.x * pushSpeed; m_hostage->pev->velocity.y = dir.y * pushSpeed; #else Vector vecRet = NormalizeMulScalar<float_precision, float_precision, float_precision, float>(dir, pushSpeed); m_hostage->pev->velocity.x = vecRet.x; m_hostage->pev->velocity.y = vecRet.y; #endif m_hostage->SetBoneController(0); m_hostage->SetBoneController(1); FaceTowards(m_jumpTarget, deltaT); return; } if (m_isLookingAt) { Vector angles = UTIL_VecToAngles(m_viewGoal - GetEyes()); float_precision pitch = angles.x - m_hostage->pev->angles.x; float_precision yaw = angles.y - m_hostage->pev->angles.y; while (yaw > 180.0f) yaw -= 360.0f; while (yaw < -180.0f) yaw += 360.0f; while (pitch > 180.0f) pitch -= 360.0f; while (pitch < -180.0f) pitch += 360.0f; m_hostage->SetBoneController(0, yaw); m_hostage->SetBoneController(1, -pitch); if (IsAtMoveGoal() && !HasFaceTo()) { if (yaw < -45.0f || yaw > 45.0f) { FaceTowards(m_viewGoal, deltaT); } } } else { m_hostage->SetBoneController(0); m_hostage->SetBoneController(1); } if (HasFaceTo() && FaceTowards(m_faceGoal, deltaT)) ClearFaceTo(); if (!IsAtMoveGoal() || m_path.GetSegmentCount() > 0) { if (m_path.GetSegmentCount() <= 0) { HostagePathCost pathCost; if (m_path.Compute(&GetFeet(), &m_moveGoal, pathCost)) { m_follower.SetPath(&m_path); m_follower.SetImprov(this); m_follower.Reset(); m_follower.Debug(cv_hostage_debug.value > 0.0); } } m_follower.Update(deltaT, m_inhibitObstacleAvoidance.IsElapsed()); if (m_moveType == Stopped) { m_follower.ResetStuck(); } if (m_follower.IsStuck()) { Wiggle(); } } const float friction = 3.0f; m_vel.x += m_vel.x * -friction * deltaT; m_vel.y += m_vel.y * -friction * deltaT; float_precision speed = m_vel.NormalizeInPlace(); const float maxSpeed = 285.0f; if (speed > maxSpeed) { speed = maxSpeed; } m_vel.x = m_vel.x * speed; m_vel.y = m_vel.y * speed; KeepPersonalSpace spacer(this); ForEachPlayer(spacer); if (g_pHostages != NULL) { g_pHostages->ForEachHostage(spacer); } m_hostage->pev->velocity.x = m_vel.x; m_hostage->pev->velocity.y = m_vel.y; m_moveFlags = 0; }
void GameScene::ScheduleLoad(std::shared_ptr<Loader> loader) { auto rulebook = rules->GetRulebook(); loader->AddLoader("Track and players", [=]{ // Load the selected track std::shared_ptr<Model::Track> track; auto entry = this->rules->GetTrackEntry(); if (!entry) throw Parcel::ObjStreamExn("Track does not exist."); track = Config::GetInstance()->GetTrackBundle().OpenTrack(entry); if (!track) throw Parcel::ObjStreamExn( "Track does not exist: " + entry->name); if (!session->LoadNew(entry->name.c_str(), scripting, track, &display.GetLegacyDisplay())) { throw Parcel::ObjStreamExn("Track load failed."); } // This must be done after the track has loaded. const auto maxPlayers = rules->GetRulebook()->GetMaxPlayers(); int i = 0; std::vector<std::shared_ptr<Player::Player>> localHumans; director.GetParty()->ForEach([&](std::shared_ptr<Player::Player> &p) { if (p->IsCompeting() && i < maxPlayers) { session->AttachPlayer(i, p); i++; if (p->IsLocal() && p->IsHuman()) { localHumans.emplace_back(p); } } }); // Split-screen with multiple viewports. // The bounds of each viewport will be set in LayoutViewports(). for (auto &player : localHumans) { viewports.emplace_back( display, player, new Observer(), new Display::Hud(display, player, track, Display::UiLayoutFlags::FLOATING)); } }); loader->AddLoader("Session", [=]{ metaSession = rulebook->GetMetas().session( std::make_shared<SessionPeer>(*scripting, session)); metaSession->OnInit(); session->SetMeta(metaSession); director.GetSessionChangedSignal()(metaSession); session->AdvancePhase(ClientSession::Phase::PREGAME); auto sessionPeer = metaSession->GetSession(); sessionPeer->ForEachPlayer([&](std::shared_ptr<MetaPlayer> &player) { auto playerPeer = player->GetPlayer(); // Look up the correct HUD for this player. for (auto &viewport : viewports) { if (viewport.player.get() == playerPeer->GetPlayer()) { playerPeer->SetHud( std::make_shared<HudPeer>(*scripting, display, viewport.hud)); break; } } // Get notified when each player finishes. auto mainChar = player->GetPlayer()->GetPlayer()->GetMainCharacter(); mainChar->GetFinishedSignal().connect( std::bind(&GameScene::OnRaceFinish, this)); player->OnJoined(metaSession); }); }); }