Exemple #1
0
	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();
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
	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;
	}
Exemple #6
0
/**
 * 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;
}
Exemple #9
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);
		});
	});
}