// uses the marine list to quickly find all marines within a box
int CASW_Game_Resource::EnumerateMarinesInBox(Vector &mins, Vector &maxs)
{
	m_iNumEnumeratedMarines = 0;
	for (int i=0;i<GetMaxMarineResources();i++)
	{
		CASW_Marine_Resource *pMR = GetMarineResource(i);
		if (!pMR)
			continue;

		CASW_Marine *pMarine = pMR->GetMarineEntity();
		if (!pMarine)
			continue;

#ifdef CLIENT_DLL
		if (asw_debug_clientside_avoidance.GetBool())
		{
			Vector mid = (pMarine->WorldAlignMins() + pMarine->WorldAlignMaxs()) / 2.0f;
			Vector omin = pMarine->WorldAlignMins() - mid;
			Vector omax = pMarine->WorldAlignMaxs() - mid;
			debugoverlay->AddBoxOverlay( mid, omin, omax, vec3_angle, 0, 0, 255, true, 0 );
		}
#endif

		Vector omins = pMarine->WorldAlignMins() + pMarine->GetAbsOrigin();
		Vector omaxs = pMarine->WorldAlignMaxs() + pMarine->GetAbsOrigin();
		if (IsBoxIntersectingBox(mins, maxs, omins, omaxs))
		{
			m_pEnumeratedMarines[m_iNumEnumeratedMarines] = pMR->GetMarineEntity();
			m_iNumEnumeratedMarines++;
			if (m_iNumEnumeratedMarines >=12)
				break;
		}
	}
	return m_iNumEnumeratedMarines;
}
예제 #2
0
bool CASW_Spawn_Manager::ValidSpawnPoint( const Vector &vecPosition, const Vector &vecMins, const Vector &vecMaxs, bool bCheckGround, float flMarineNearDistance )
{
    // check if we can fit there
    trace_t tr;
    UTIL_TraceHull( vecPosition,
                    vecPosition + Vector( 0, 0, 1 ),
                    vecMins,
                    vecMaxs,
                    MASK_NPCSOLID,
                    NULL,
                    COLLISION_GROUP_NONE,
                    &tr );

    if( tr.fraction != 1.0 )
        return false;

    // check there's ground underneath this point
    if ( bCheckGround )
    {
        UTIL_TraceHull( vecPosition + Vector( 0, 0, 1 ),
                        vecPosition - Vector( 0, 0, 64 ),
                        vecMins,
                        vecMaxs,
                        MASK_NPCSOLID,
                        NULL,
                        COLLISION_GROUP_NONE,
                        &tr );

        if( tr.fraction == 1.0 )
            return false;
    }

    if ( flMarineNearDistance > 0 )
    {
        CASW_Game_Resource* pGameResource = ASWGameResource();
        float distance = 0.0f;
        for ( int i=0 ; i < pGameResource->GetMaxMarineResources() ; i++ )
        {
            CASW_Marine_Resource* pMR = pGameResource->GetMarineResource(i);
            if ( pMR && pMR->GetMarineEntity() && pMR->GetMarineEntity()->GetHealth() > 0 )
            {
                distance = pMR->GetMarineEntity()->GetAbsOrigin().DistTo( vecPosition );
                if ( distance < flMarineNearDistance )
                {
                    return false;
                }
            }
        }
    }

    return true;
}
예제 #3
0
bool CASW_Mission_Manager::AllMarinesKnockedOut()
{
	if (!ASWGameRules() || !ASWGameResource())
		return false;

	// can't be all dead if we haven't left briefing yet!
	if (ASWGameRules()->GetGameState() < ASW_GS_INGAME)
		return false;

	int iMax = ASWGameResource()->GetMaxMarineResources();
	for (int i=0;i<iMax;i++)
	{
		CASW_Marine_Resource *pMarineResource = ASWGameResource()->GetMarineResource(i);
		if (pMarineResource)
		{
			CASW_Marine *m = pMarineResource->GetMarineEntity();
			if (m)
			{
				if (!m->m_bKnockedOut)
				{
					return false;
				}
			}
		}
	}
	return true;
}
void asw_marine_spectate_f(const CCommand &args)
{
	CASW_Player *pPlayer = ToASW_Player(UTIL_GetCommandClient());
	if ( args.ArgC() < 2 )
	{
		Msg( "Usage: asw_marine_spectate [marine_num]\n" );
		return;
	}

	CASW_Game_Resource* pGameResource = ASWGameResource();
	if (!pGameResource)
		return;

	int iMarine = atof(args[1]);
	if (iMarine < 0 || iMarine >= pGameResource->GetMaxMarineResources())
		return;

	CASW_Marine_Resource* pMR = pGameResource->GetMarineResource(iMarine);
	if (!pMR)
	{
		Msg("No marine resource in that index\n");
		return;
	}

	CASW_Marine *pMarine = pMR->GetMarineEntity();
	if (!pMarine)
	{
		Msg("No live marine in that slot\n");
		return;
	}
		
	pPlayer->SetSpectatingMarine(pMarine);
}
예제 #5
0
// randomly generated levels provide data about each room in the level
// we check that here to react to special rooms
void CASW_Director::UpdateMarineRooms()
{
	CASW_Game_Resource *pGameResource = ASWGameResource();
	if ( !pGameResource || !missionchooser || !missionchooser->RandomMissions())
		return;

	for ( int i=0;i<pGameResource->GetMaxMarineResources();i++ )
	{
		CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
		if ( !pMR || !pMR->GetMarineEntity() || pMR->GetMarineEntity()->GetHealth() <= 0 )
			continue;

		IASW_Room_Details* pRoom = missionchooser->RandomMissions()->GetRoomDetails( pMR->GetMarineEntity()->GetAbsOrigin() );
		if ( !pRoom )
			continue;

		if ( !m_bFinale && pRoom->HasTag( "Escape" ) )
		{
			UpdateMarineInsideEscapeRoom( pMR->GetMarineEntity() );
		}
	}
}
예제 #6
0
// increase intensity as aliens are killed (particularly if they're close to the marines)
void CASW_Director::Event_AlienKilled( CBaseEntity *pAlien, const CTakeDamageInfo &info )
{
	if ( !pAlien )
		return;

	CASW_Game_Resource *pGameResource = ASWGameResource();
	if ( !pGameResource )
		return;

	bool bDangerous = pAlien->Classify() == CLASS_ASW_SHIELDBUG;       // shieldbug
	bool bVeryDangerous = pAlien->Classify() == CLASS_ASW_QUEEN;		// queen

	for ( int i=0;i<pGameResource->GetMaxMarineResources();i++ )
	{
		CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
		if ( !pMR )
			continue;

		CASW_Marine *pMarine = pMR->GetMarineEntity();
		if ( !pMarine || pMarine->GetHealth() <= 0 )
			continue;

		CASW_Intensity::IntensityType stress = CASW_Intensity::MILD;

		if ( bVeryDangerous )
		{
			stress = CASW_Intensity::EXTREME;
		}
		else if ( bDangerous )
		{
			stress = CASW_Intensity::HIGH;
		}
		else
		{
			float distance = pMarine->GetAbsOrigin().DistTo( pAlien->GetAbsOrigin() );
			if ( distance > asw_intensity_far_range.GetFloat() )
			{
				stress = CASW_Intensity::MILD;
			}
			else
			{
				stress = CASW_Intensity::MODERATE;
			}
		}

		pMR->GetIntensity()->Increase( stress );
	}

	ASWArena()->Event_AlienKilled( pAlien, info );
}
int CASW_Game_Resource::CountAllAliveMarines( void )
{
	int m = GetMaxMarineResources();
	int iMarines = 0;
	for ( int i = 0; i < m; i++ )
	{
		CASW_Marine_Resource *pMR = GetMarineResource( i );
		if ( !pMR )
			continue;

		CASW_Marine *pMarine = pMR->GetMarineEntity();
		if ( !pMarine )
			continue;

		if ( pMR->GetHealthPercent() > 0 )
		{
			iMarines++;
		}
	}
	return iMarines;
}
예제 #8
0
bool CASW_Mission_Manager::CheckMissionComplete()
{
	bool bFailed = false;
	bool bSuccess = true;
	bool bAtLeastOneObjective = false;

	// notify all objectives about this event
	if ( !ASWGameResource() )
		return false;

	int iIncomplete = 0;
	int iNumObjectives = 0;
	bool bEscapeIncomplete = false;
	for (int i=0;i<ASW_MAX_OBJECTIVES;i++)
	{
		CASW_Objective* pObjective = ASWGameResource()->GetObjective(i);
		if (pObjective)
		{
			bAtLeastOneObjective = true;
			iNumObjectives++;
			if (!pObjective->IsObjectiveComplete() && !pObjective->IsObjectiveOptional())
			{
				bSuccess = false;
				iIncomplete++;
				if (iIncomplete == 1 && !m_bDoneLeavingChatter)
				{
					CASW_Objective_Escape *pEscape = dynamic_cast<CASW_Objective_Escape*>(pObjective);
					if (pEscape)
						bEscapeIncomplete = true;
				}
			}
			if (pObjective->IsObjectiveFailed())
			{
				bFailed = true;					
			}
		}
	}

	m_bAllMarinesDead = AllMarinesDead();

	if ( m_bAllMarinesDead && ( gpGlobals->curtime > m_flLastMarineDeathTime + asw_last_marine_dead_delay.GetFloat() || GameTimescale()->GetCurrentTimescale() < 1.0f ) )
	{
		bFailed = true;
	}
	
	m_bAllMarinesKnockedOut = AllMarinesKnockedOut();
	if (m_bAllMarinesKnockedOut)
		bFailed = true;

	if (bSuccess && bAtLeastOneObjective)
	{
		MissionSuccess();
		return true;
	}
	else if (bFailed)
	{
		MissionFail();
		return true;
	}
	else
	{
		if (bEscapeIncomplete && iIncomplete)
		{
			// make a marine do the 'time to leave' speech
			if ( ASWGameResource() )
			{
				CASW_Game_Resource *pGameResource = ASWGameResource();
				// count how many live marines we have
				int iNearby = 0;						
				for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
				{
					CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
					CASW_Marine *pMarine = pMR ? pMR->GetMarineEntity() : NULL;
					if (pMarine && pMarine->GetHealth() > 0)
								iNearby++;
				}
				int iChatter = random->RandomInt(0, iNearby-1);
				for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
				{
					CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
					CASW_Marine *pMarine = pMR ? pMR->GetMarineEntity() : NULL;
					if (pMarine && pMarine->GetHealth() > 0)
					{
						if (iChatter <= 0)
						{
							pMarine->GetMarineSpeech()->QueueChatter(CHATTER_TIME_TO_LEAVE, gpGlobals->curtime + 3.0f, gpGlobals->curtime + 6.0f);
							break;
						}
						iChatter--;
					}
				}						
			}
			m_bDoneLeavingChatter = true;
		}
	}
	return false;
}
예제 #9
0
bool CASW_Base_Spawner::CanSpawn( const Vector &vecHullMins, const Vector &vecHullMaxs )
{
	if ( !m_bEnabled )
		return false;

	// is a marine too near?
	if ( !m_bSpawnIfMarinesAreNear && m_flNearDistance > 0 )
	{		
		CASW_Game_Resource* pGameResource = ASWGameResource();
		float distance = 0.0f;
		for ( int i = 0; i < ASW_MAX_MARINE_RESOURCES; i++ )
		{
			CASW_Marine_Resource* pMR = pGameResource->GetMarineResource(i);
			if ( pMR && pMR->GetMarineEntity() && pMR->GetMarineEntity()->GetHealth() > 0 )
			{
				distance = pMR->GetMarineEntity()->GetAbsOrigin().DistTo( GetAbsOrigin() );
				if ( distance < m_flNearDistance )
				{
					if ( asw_debug_spawners.GetBool() )
						Msg("asw_spawner(%s): Alien can't spawn because a marine (%d) is %f away\n", GetEntityName(), i, distance);
					return false;
				}
			}
		}
	}

	Vector mins = GetAbsOrigin() - Vector( 23, 23, 0 );
	Vector maxs = GetAbsOrigin() + Vector( 23, 23, 0 );
	CBaseEntity *pList[128];
	int count = UTIL_EntitiesInBox( pList, 128, mins, maxs, FL_CLIENT|FL_NPC );
	if ( count )
	{
		//Iterate through the list and check the results
		for ( int i = 0; i < count; i++ )
		{
			//Don't build on top of another entity
			if ( pList[i] == NULL )
				continue;

			//If one of the entities is solid, then we may not be able to spawn now
			if ( ( pList[i]->GetSolidFlags() & FSOLID_NOT_SOLID ) == false )
			{
				// Since the outer method doesn't work well around striders on account of their huge bounding box.
				// Find the ground under me and see if a human hull would fit there.
				trace_t tr;
				UTIL_TraceHull( GetAbsOrigin() + Vector( 0, 0, 1 ),
								GetAbsOrigin() - Vector( 0, 0, 1 ),
								vecHullMins,
								vecHullMaxs,
								MASK_NPCSOLID,
								NULL,
								COLLISION_GROUP_NONE,
								&tr );

				if (tr.fraction < 1.0f && tr.DidHitNonWorldEntity())
				{
					// some non-world entity is blocking the spawn point, so don't spawn
					if (tr.m_pEnt)
					{
						if ( m_iMoveAsideCount < 6 )	// don't send 'move aside' commands more than 5 times in a row, else you'll stop blocked NPCs going to sleep.
						{
							IASW_Spawnable_NPC *pSpawnable = dynamic_cast<IASW_Spawnable_NPC*>(tr.m_pEnt);
							if (pSpawnable)
							{
								pSpawnable->MoveAside();		// try and make him move aside
								m_iMoveAsideCount++;
							}
						}
						if (asw_debug_spawners.GetBool())
							Msg("asw_spawner(%s): Alien can't spawn because a non-world entity is blocking the spawn point: %s\n", GetEntityName(), tr.m_pEnt->GetClassname());
					}
					else
					{
						if (asw_debug_spawners.GetBool())
							Msg("asw_spawner(%s): Alien can't spawn because a non-world entity is blocking the spawn point.\n", GetEntityName());
					}
						
					return false;
				}
			}
		}
	}

	// is there something blocking the spawn point?
	if ( m_bCheckSpawnIsClear )
	{
		if ( asw_debug_spawners.GetBool() )
		{
			Msg("Checking spawn is clear...\n");
		}

		trace_t tr;
		UTIL_TraceHull( GetAbsOrigin(),
					GetAbsOrigin() + Vector( 0, 0, 1 ),
					vecHullMins,
					vecHullMaxs,
					MASK_NPCSOLID,
					this,
					COLLISION_GROUP_NONE,
					&tr );

		if( tr.fraction != 1.0 )
		{
			if ( asw_debug_spawners.GetBool() )
				Msg("asw_spawner(%s): Alien can't spawn because he wouldn't fit in the spawn point.\n", GetEntityName());
			// TODO: If we were trying to spawn an uber, change to spawning a regular instead
			return false;
		}
	}

	m_iMoveAsideCount = 0;
	return true;
}
예제 #10
0
void CASW_Spawn_Manager::UpdateCandidateNodes()
{
    // don't update too frequently
    if ( m_CandidateUpdateTimer.HasStarted() && !m_CandidateUpdateTimer.IsElapsed() )
        return;

    m_CandidateUpdateTimer.Start( asw_candidate_interval.GetFloat() );

    if ( !GetNetwork() || !GetNetwork()->NumNodes() )
    {
        m_vecHordePosition = vec3_origin;
        if ( asw_director_debug.GetBool() )
            Msg("Error: Can't spawn hordes as this map has no node network\n");
        return;
    }

    CASW_Game_Resource *pGameResource = ASWGameResource();
    if ( !pGameResource )
        return;

    Vector vecSouthMarine = vec3_origin;
    Vector vecNorthMarine = vec3_origin;
    for ( int i=0; i<pGameResource->GetMaxMarineResources(); i++ )
    {
        CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
        if ( !pMR )
            continue;

        CASW_Marine *pMarine = pMR->GetMarineEntity();
        if ( !pMarine || pMarine->GetHealth() <= 0 )
            continue;

        if ( vecSouthMarine == vec3_origin || vecSouthMarine.y > pMarine->GetAbsOrigin().y )
        {
            vecSouthMarine = pMarine->GetAbsOrigin();
        }
        if ( vecNorthMarine == vec3_origin || vecNorthMarine.y < pMarine->GetAbsOrigin().y )
        {
            vecNorthMarine = pMarine->GetAbsOrigin();
        }
    }
    if ( vecSouthMarine == vec3_origin || vecNorthMarine == vec3_origin )		// no live marines
        return;

    int iNumNodes = GetNetwork()->NumNodes();
    m_northCandidateNodes.Purge();
    m_southCandidateNodes.Purge();
    for ( int i=0 ; i<iNumNodes; i++ )
    {
        CAI_Node *pNode = GetNetwork()->GetNode( i );
        if ( !pNode || pNode->GetType() != NODE_GROUND )
            continue;

        Vector vecPos = pNode->GetPosition( CANDIDATE_ALIEN_HULL );

        // find the nearest marine to this node
        float flDistance = 0;
        CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(UTIL_ASW_NearestMarine( vecPos, flDistance ));
        if ( !pMarine )
            return;

        if ( flDistance > asw_horde_max_distance.GetFloat() || flDistance < asw_horde_min_distance.GetFloat() )
            continue;

        // check node isn't in an exit trigger
        bool bInsideEscapeArea = false;
        for ( int d=0; d<m_EscapeTriggers.Count(); d++ )
        {
            if ( m_EscapeTriggers[d]->CollisionProp()->IsPointInBounds( vecPos ) )
            {
                bInsideEscapeArea = true;
                break;
            }
        }
        if ( bInsideEscapeArea )
            continue;

        if ( vecPos.y >= vecSouthMarine.y )
        {
            if ( asw_director_debug.GetInt() == 3 )
            {
                NDebugOverlay::Box( vecPos, -Vector( 5, 5, 5 ), Vector( 5, 5, 5 ), 32, 32, 128, 10, 60.0f );
            }
            m_northCandidateNodes.AddToTail( i );
        }
        if ( vecPos.y <= vecNorthMarine.y )
        {
            m_southCandidateNodes.AddToTail( i );
            if ( asw_director_debug.GetInt() == 3 )
            {
                NDebugOverlay::Box( vecPos, -Vector( 5, 5, 5 ), Vector( 5, 5, 5 ), 128, 32, 32, 10, 60.0f );
            }
        }
    }
}
void CC_asw_teleport( const CCommand &args )
{
	CASW_Player *pPlayer = ToASW_Player(UTIL_GetCommandClient());
	if ( !pPlayer )
		return;

	Vector vTargetPos = pPlayer->GetAbsOrigin();

	// fires a command from the console
	if ( args.ArgC() < 2 )
	{
		trace_t tr;

		Vector vPlayerForward;
		pPlayer->EyeVectors( &vPlayerForward, NULL, NULL );

		UTIL_TraceLine( pPlayer->GetAbsOrigin(), pPlayer->GetAbsOrigin() + vPlayerForward * 10000.0f, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
		
		if ( tr.DidHit() )
		{
			vTargetPos = tr.endpos;
		}
	}
	else
	{
		// find the named entity
		CBaseEntity *target = gEntList.FindEntityByName( NULL, args[1] );
		if ( !target )
		{
			int i = atoi( args[1] );
			if ( i != 0 )
			{
				target = CBaseEntity::Instance( i );
				if ( !target )
				{
					Msg( "Couldn't find entity!\n" );
					return;
				}
			}
			else
			{
				Msg( "Couldn't find entity!\n" );
				return;
			}
		}

		vTargetPos = target->GetAbsOrigin();
	}

	CASW_Marine *pMarine = pPlayer->GetMarine();

	if ( !pMarine )
	{
		for ( int i = 0; i < ASWGameResource()->GetMaxMarineResources(); ++i )
		{
			CASW_Marine_Resource *pMR = ASWGameResource()->GetMarineResource( i );
			if ( !pMR )
				continue;

			if ( pMR->GetMarineEntity() && pMR->GetMarineEntity()->GetCommander() == pPlayer )
			{
				pMarine = pMR->GetMarineEntity();
				break;
			}
		}
	}

	if ( pMarine )
	{
		// Teleport the dude under our control
		Vector vecPos = vTargetPos;//pNearest->GetOrigin();
		pMarine->Teleport( &vecPos, NULL, NULL );
	}
}