コード例 #1
0
void CAreaCapture::SetOwner( int team )
{
	//break any current capturing
	BreakCapture( false );

	//set the owner to the passed value
	m_nOwningTeam = team;
	g_pObjectiveResource->SetOwningTeam( m_pPoint->GetPointIndex(), m_nOwningTeam );
}
コード例 #2
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTriggerAreaCapture::SetOwner( int team )
{
	//break any current capturing
	BreakCapture( false );

	HandleRespawnTimeAdjustments( m_nOwningTeam, team );

	//set the owner to the passed value
	m_nOwningTeam = team;

	UpdateOwningTeam();
}
コード例 #3
0
//-----------------------------------------------------------------------------
// Purpose: Check if this player's death causes a block
// return FALSE if the player is not in this area
// return TRUE otherwise ( eg player is in area, but his death does not cause break )
//-----------------------------------------------------------------------------
bool CAreaCapture::CheckIfDeathCausesBlock( CDODPlayer *pVictim, CDODPlayer *pKiller )
{
	// This shouldn't happen
	if ( !pVictim || !pKiller )
	{
		Assert( !"Why are null players getting here?" );
		return false;
	}

	// make sure this player is in this area
	if ( pVictim->GetCapAreaIndex() != m_iAreaIndex )
		return false;

	// Teamkills shouldn't give a block reward
	if ( pVictim->GetTeamNumber() == pKiller->GetTeamNumber() )
		return true;

	// return if the area is not being capped
	if ( !m_bCapturing )
		return true;

	int iTeam = pVictim->GetTeamNumber();

	// return if this player's team is not capping the area
	if ( iTeam != m_nCapturingTeam )
		return true;

	bool bBlocked = false;

	if ( m_nCapturingTeam == TEAM_ALLIES )
	{
		if ( m_nNumAllies-1 < m_nAlliesNumCap )
			bBlocked = true;
	}
	else if ( m_nCapturingTeam == TEAM_AXIS )
	{
		if ( m_nNumAxis-1 < m_nAxisNumCap )
			bBlocked = true;
	}

	// break early incase we kill multiple people in the same frame
	if ( bBlocked )
	{
		m_pPoint->CaptureBlocked( pKiller );
		BreakCapture( false );
	}

	return true;
}
コード例 #4
0
void CTriggerAreaCapture::InputSetControlPoint( inputdata_t &inputdata )
{
	BreakCapture( false );	// clear the capping for the previous point, forces us to recalc on the new one

	char parseString[255];
	Q_strncpy(parseString, inputdata.value.String(), sizeof(parseString));

	m_iszCapPointName = MAKE_STRING( parseString );
	m_hPoint = NULL;	// force a reset of this
	InputRoundSpawn( inputdata );

	// force everyone touching to re-touch so the hud gets set up properly
	for ( int i = 0; i < m_hTouchingEntities.Count(); i++ )
	{
		CBaseEntity *ent = m_hTouchingEntities[i];
		if ( ent && ent->IsPlayer() )
		{
			EndTouch( ent );
			StartTouch( ent );
		}
	}
}
コード例 #5
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTriggerAreaCapture::CaptureThink( void )
{
	SetNextThink( gpGlobals->curtime + AREA_THINK_TIME );

	// make sure this point is in the round being played (if we're playing one)
	CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
	if ( pMaster && m_hPoint )
	{
		if ( !pMaster->IsInRound( m_hPoint ) )
		{
			return;
		}
	}

	if ( !TeamplayGameRules()->PointsMayBeCaptured() )
	{
		// Points aren't allowed to be captured. If we were 
		// being captured, we need to clean up and reset.
		if ( m_bCapturing )
		{
			BreakCapture( false );
			UpdateNumPlayers();
		}
		return;
	}

	// go through our list of players
	Assert( GetNumberOfTeams() <= MAX_CAPTURE_TEAMS );
	int iNumPlayers[MAX_CAPTURE_TEAMS];
	int iNumBlockablePlayers[MAX_CAPTURE_TEAMS]; // Players in the zone who can't cap, but can block / pause caps
	CBaseMultiplayerPlayer *pFirstPlayerTouching[MAX_CAPTURE_TEAMS];
	for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
	{
		iNumPlayers[i] = 0;
		iNumBlockablePlayers[i] = 0;
		pFirstPlayerTouching[i] = NULL;
	}

	if ( m_hPoint )
	{
		// Loop through the entities we're touching, and find players
		for ( int i = 0; i < m_hTouchingEntities.Count(); i++ )
		{
			CBaseEntity *ent = m_hTouchingEntities[i];
			if ( ent && ent->IsPlayer() )
			{
				CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer(ent);
				if ( pPlayer->IsAlive() )
				{	
					int iTeam = pPlayer->GetTeamNumber();

					// If a team's not allowed to cap a point, don't count players in it at all
					if ( !TeamplayGameRules()->TeamMayCapturePoint( iTeam, m_hPoint->GetPointIndex() ) )
						continue;

					if ( !TeamplayGameRules()->PlayerMayCapturePoint( pPlayer, m_hPoint->GetPointIndex() ) )
					{
						if ( TeamplayGameRules()->PlayerMayBlockPoint( pPlayer, m_hPoint->GetPointIndex() ) )
						{
							if ( iNumPlayers[iTeam] == 0 && iNumBlockablePlayers[iTeam] == 0 )
							{
								pFirstPlayerTouching[iTeam] = pPlayer;
							}

							iNumBlockablePlayers[iTeam] += TeamplayGameRules()->GetCaptureValueForPlayer( pPlayer );
						}
						continue;
					}

					if ( iTeam >= FIRST_GAME_TEAM )
					{
						if ( iNumPlayers[iTeam] == 0 && iNumBlockablePlayers[iTeam] == 0 )
						{
							pFirstPlayerTouching[iTeam] = pPlayer;
						}

						iNumPlayers[iTeam] += TeamplayGameRules()->GetCaptureValueForPlayer( pPlayer );
					}
				}
			}
		}
	}

	int iTeamsInZone = 0;
	bool bUpdatePlayers = false;
	m_nTeamInZone = TEAM_UNASSIGNED;
	for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
	{
		iNumPlayers[i] *= mp_simulatemultiplecappers.GetInt();

		if ( m_TeamData[i].iNumTouching != iNumPlayers[i] )
		{
			m_TeamData[i].iNumTouching = iNumPlayers[i];
			bUpdatePlayers = true;
		}
		m_TeamData[i].iBlockedTouching = m_TeamData[i].iNumTouching;

		if ( m_TeamData[i].iNumTouching )
		{
			iTeamsInZone++;

			m_nTeamInZone = i;
		}
	}

	if ( iTeamsInZone > 1 )
	{
		m_nTeamInZone = TEAM_UNASSIGNED;
	}
	else
	{
		// If we've got non-cappable, yet blockable players here for the team that's defending, they 
		// need to block the cap. This catches cases like the TF invulnerability, which needs to block
		// caps, but isn't allowed to contribute to a cap.
		for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
		{
			if ( !iNumBlockablePlayers[i] || m_nTeamInZone == i )
				continue;

			iTeamsInZone++;
		}
	}

	UpdateTeamInZone();

	bool bBlocked = false;

	// If the cap is being blocked, reset the number of players so the client
	// knows to stop the capture as well.
	if ( mp_blockstyle.GetInt() == 1 )
	{
		if ( m_bCapturing && iTeamsInZone > 1 )
		{
			bBlocked = true;

			for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
			{
				iNumPlayers[i] = 0;
				if ( m_TeamData[i].iNumTouching != iNumPlayers[i] )
				{
					m_TeamData[i].iNumTouching = iNumPlayers[i];
					bUpdatePlayers = true;
				}
			}
		}
	}

	if ( bUpdatePlayers )
	{
		UpdateNumPlayers( bBlocked );
	}

	// When a player blocks, tell them the cap index and attempt number
	// only give successive blocks to them if the attempt number is different
	if ( m_bCapturing )
	{
		if ( m_hPoint )
		{
			m_hPoint->SetLastContestedAt( gpGlobals->curtime );
		}

		// Calculate the amount of modification to the cap time
		float flTimeDelta = gpGlobals->curtime - m_flLastReductionTime;

		float flReduction = flTimeDelta;
		if ( CaptureModeScalesWithPlayers() )
		{
			// Diminishing returns for successive players.
			for ( int i = 1; i < m_TeamData[m_nTeamInZone].iNumTouching; i++ )
			{
				flReduction += (flTimeDelta / (float)(i+1));
			}
		}
		m_flLastReductionTime = gpGlobals->curtime;

		//if more than one team is in the zone
		if( iTeamsInZone > 1 )
		{
			if ( !m_bBlocked )
			{
				m_bBlocked = true;
				UpdateBlocked();
			}

			// See if anyone gets credit for the block
			float flPercentToGo = m_fTimeRemaining / m_flCapTime;
			if ( CaptureModeScalesWithPlayers() )
			{
				flPercentToGo = m_fTimeRemaining / ((m_flCapTime * 2) * m_TeamData[m_nCapturingTeam].iNumRequiredToCap);
			}

			if ( ( flPercentToGo <= 0.5 || TeamplayGameRules()->PointsMayAlwaysBeBlocked() ) && m_hPoint )
			{
				// find the first player that is not on the capturing team
				// they have just broken a cap and should be rewarded		
				// tell the player the capture attempt number, for checking later
				CBaseMultiplayerPlayer *pBlockingPlayer = NULL;
				for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
				{
					if ( m_nCapturingTeam == i )
						continue;

					if ( pFirstPlayerTouching[i] )
					{
						pBlockingPlayer = pFirstPlayerTouching[i];
						break;
					}
				}
				Assert( pBlockingPlayer );

				if ( pBlockingPlayer )
				{
					bool bRepeatBlocker = false;
					for ( int i = m_Blockers.Count()-1; i >= 0; i-- )
					{
						if ( m_Blockers[i].hPlayer != pBlockingPlayer )
							continue;

						// If this guy's was a blocker, but not valid now, remove him from the list
						if ( m_Blockers[i].iCapAttemptNumber != m_iCapAttemptNumber || !IsTouching(m_Blockers[i].hPlayer) ||
							 ( TeamplayGameRules()->PointsMayAlwaysBeBlocked() && m_Blockers[i].flNextBlockTime < gpGlobals->curtime && m_bStartTouch ) )
						{
							m_Blockers.Remove(i);
							continue;
						}

						bRepeatBlocker = true;
						break;
					}

					if ( !bRepeatBlocker )
					{
                        m_hPoint->CaptureBlocked( pBlockingPlayer );

						// Add this guy to our blocker list
						int iNew = m_Blockers.AddToTail();
						m_Blockers[iNew].hPlayer = pBlockingPlayer;
						m_Blockers[iNew].iCapAttemptNumber = m_iCapAttemptNumber;
						m_Blockers[iNew].flNextBlockTime = gpGlobals->curtime + 10.0f;
					}
				}
			}

			if ( mp_blockstyle.GetInt() == 0 )
			{
				BreakCapture( false );
			}
			return;
		}

		if ( m_bBlocked )
		{
			m_bBlocked = false;
			UpdateBlocked();
		}

		float flTotalTimeToCap = m_flCapTime;
		if ( CaptureModeScalesWithPlayers() )
		{
			flTotalTimeToCap = ((m_flCapTime * 2) * m_TeamData[m_nCapturingTeam].iNumRequiredToCap);
		}

		// Now remove the reduction amount after we've determined there's only 1 team in the area
		if ( m_nCapturingTeam == m_nTeamInZone )
		{
			SetCapTimeRemaining( m_fTimeRemaining - flReduction );
		}
		else if ( m_nOwningTeam == TEAM_UNASSIGNED && m_nTeamInZone != TEAM_UNASSIGNED )
		{
			SetCapTimeRemaining( m_fTimeRemaining + flReduction );
		}
		else
		{
			// Caps deteriorate over time
			if ( TeamplayRoundBasedRules() && m_hPoint && TeamplayRoundBasedRules()->TeamMayCapturePoint(m_nCapturingTeam,m_hPoint->GetPointIndex()) )
			{
				float flDecreaseScale = CaptureModeScalesWithPlayers() ? mp_capdeteriorate_time.GetFloat() : flTotalTimeToCap;
				float flDecrease = (flTotalTimeToCap / flDecreaseScale) * flTimeDelta;
				if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->InOvertime() )
				{
					flDecrease *= 6;
				}
				SetCapTimeRemaining( m_fTimeRemaining + flDecrease );
			}
			else
			{
				SetCapTimeRemaining( flTotalTimeToCap );
			}
		}

		/*
		//if no-one is in the area
		if( iTeamsInZone == 0 )
		{
			BreakCapture( true );
			return;
		}
		
		//if they've lost the number of players needed to cap
		int iTeamMembersHere = m_TeamData[m_nCapturingTeam].iNumTouching + iNumBlockablePlayers[m_nCapturingTeam];
		if ( (iTeamMembersHere == 0 ) || (mp_capstyle.GetInt() == 0 && iTeamMembersHere < m_TeamData[m_nCapturingTeam].iNumRequiredToCap) )
		{
			BreakCapture( true );
			return;
		}
		*/

		// if the cap is done
		if ( m_fTimeRemaining <= 0 )
		{
			EndCapture( m_nCapturingTeam );
			return;		//we're done
		}
		else
		{
			// We may get several simultaneous CaptureThink calls from StartTouch if there are several players on the trigger 
			// when it is enabled (like in Raid mode). We haven't started reducing m_fTimeRemaining yet but the second call to CaptureThink
			// from StartTouch has m_bCapturing set to true and we hit this condition and call BreakCapture right away.
			// We put this check here to prevent calling BreakCapture from the StartTouch call to CaptureThink. If the capture should
			// really be broken it will happen the next time the trigger thinks on its own.
			if ( !m_bStartTouch )
			{
				if ( m_fTimeRemaining >= flTotalTimeToCap )
				{
					BreakCapture( false );
					return;
				}
			}
		}
	}
	else	
	{
		// If there are any teams in the zone that aren't the owner, try to start capping
		if ( iTeamsInZone > 0 )
		{
			for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
			{
				if ( !m_TeamData[i].bCanCap || m_nOwningTeam == i )
					continue;

				if ( m_TeamData[i].iNumTouching == 0 )
					continue;

				if ( m_TeamData[i].iNumTouching < m_TeamData[i].iNumRequiredToStartCap )
					continue;

				if ( !CaptureModeScalesWithPlayers() && m_TeamData[i].iNumTouching < m_TeamData[i].iNumRequiredToCap )
					continue;

				StartCapture( i, CAPTURE_NORMAL );
				break;
			}
		}
	}
}
コード例 #6
0
void CAreaCapture::Think( void )
{
	SetNextThink( gpGlobals->curtime + AREA_THINK_TIME );

	if( DODGameRules()->State_Get() != STATE_RND_RUNNING )
	{
		// If we were being capped, cancel it
		if( m_nNumAllies > 0 || m_nNumAxis > 0 )
		{
			m_nNumAllies = 0;
			m_nNumAxis = 0;
			SendNumPlayers();

			if( m_pPoint )
			{
				g_pObjectiveResource->SetCappingTeam( m_pPoint->GetPointIndex(), TEAM_UNASSIGNED );
			}
		}
		return;
	}

	// go through our list of players

	int iNumAllies = 0;
	int iNumAxis = 0;

	CDODPlayer *pFirstAlliedTouching = NULL;
	CDODPlayer *pFirstAxisTouching = NULL;

	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CBaseEntity *ent = UTIL_PlayerByIndex( i );
		if ( ent )
		{
			CDODPlayer *pPlayer = ToDODPlayer(ent);

			//First check if the player is in fact in this area
			if ( ( pPlayer->m_signals.GetState() & SIGNAL_CAPTUREAREA ) &&
				pPlayer->GetCapAreaIndex() == m_iAreaIndex &&
				pPlayer->IsAlive() )		// alive check is kinda unnecessary, but there is some
											// case where non-present people are messing up this count
			{	
				if ( pPlayer->GetTeamNumber() == TEAM_ALLIES )
				{
					if ( iNumAllies == 0 )
						pFirstAlliedTouching = pPlayer;

					iNumAllies++;					
				}
				else if ( pPlayer->GetTeamNumber() == TEAM_AXIS )
				{
					if ( iNumAxis == 0 )
						pFirstAxisTouching = pPlayer;

					iNumAxis++;
				}
			}
		}
	}

	iNumAllies *= dod_simulatemultiplecappers.GetInt();
	iNumAxis *= dod_simulatemultiplecappers.GetInt();

	if( iNumAllies != m_nNumAllies || iNumAxis != m_nNumAxis )
	{
		m_nNumAllies = iNumAllies;
		m_nNumAxis = iNumAxis;
		SendNumPlayers();
	}

	// when a player blocks, tell them the cap index and attempt number
	// only give successive blocks to them if the attempt number is different

	if( m_bCapturing )
	{
		//its a regular cap
		//Subtract some time from the cap
		m_fTimeRemaining -= AREA_THINK_TIME;

		//if both teams are in the area
		if( iNumAllies > 0 && iNumAxis > 0 )
		{
			// See if anyone gets credit for the block
			float flPercentToGo = m_fTimeRemaining / m_flCapTime;
			if ( flPercentToGo <= 0.5 && m_pPoint )
			{
				// find the first player that is not on the capturing team
				// they have just broken a cap and should be rewarded		
				// tell the player the capture attempt number, for checking later
				CDODPlayer *pBlockingPlayer = ( m_nCapturingTeam == TEAM_ALLIES ) ? pFirstAxisTouching : pFirstAlliedTouching;

				if ( pBlockingPlayer )
				{
					if ( pBlockingPlayer->GetCapAreaIndex() == m_iAreaIndex &&
						 pBlockingPlayer->GetLastBlockCapAttempt() == m_iCapAttemptNumber )
					{
						// this is a repeat block on the same cap, ignore it
						NULL;
					}
					else
					{
                        m_pPoint->CaptureBlocked( pBlockingPlayer );
						pBlockingPlayer->StoreCaptureBlock( m_iAreaIndex, m_iCapAttemptNumber );
					}
				}
			}

			BreakCapture( false );
			return;
		}

		//if no-one is in the area
		if( iNumAllies == 0 && iNumAxis == 0 )
		{
			BreakCapture( true );
			return;
		}
		
		if( m_nCapturingTeam == TEAM_ALLIES )
		{
			if( iNumAllies < m_nAlliesNumCap )
			{
				BreakCapture( true );
			}
		}
		else if( m_nCapturingTeam == TEAM_AXIS )
		{
			if( iNumAxis < m_nAxisNumCap )
			{
				BreakCapture( true );
			}
		}

		//if the cap is done
		if( m_fTimeRemaining <= 0 )
		{
			EndCapture( m_nCapturingTeam );
			return;		//we're done
		}			
	}
	else	//not capturing yet
	{
		bool bStarted = false;
		
		if( iNumAllies > 0 && iNumAxis <= 0 && m_bAlliesCanCap && m_nOwningTeam != TEAM_ALLIES )
		{
			if( iNumAllies >= m_nAlliesNumCap )
			{
				m_iCappingRequired = m_nAlliesNumCap;	
				m_iCappingPlayers = iNumAllies;	
				StartCapture( TEAM_ALLIES, CAPTURE_NORMAL );
				bStarted = true;
			}
		}
		else if( iNumAxis > 0 && iNumAllies <= 0 && m_bAxisCanCap && m_nOwningTeam != TEAM_AXIS )
		{
			if( iNumAxis >= m_nAxisNumCap )
			{
				m_iCappingRequired = m_nAxisNumCap;	
				m_iCappingPlayers = iNumAxis;	
				StartCapture( TEAM_AXIS, CAPTURE_NORMAL );
				bStarted = true;
			}
		}
	}
}
コード例 #7
0
ファイル: formmgr.cpp プロジェクト: Ahmar/hostile-takeover
bool MultiFormMgr::StealCapturePen2(Event *pevt, FormMgr *pfrmmChildCapture)
{
    // If this is penDownEvent, remember the pre-cooked event for later
    // use.

    if (pevt->eType == penDownEvent) {
        m_evtPen1Down = *pevt;
        return false;
    }

    // The playfield allows multi-touch select. Sometimes
    // finger 1 goes down on a control surrounding the playfield accidentially,
    // and finger 2 goes down on the playfield. In this case, finger 1
    // needs to be "uncaptured", and both finger 1 and finger 2 down events
    // routed to the playfield. 

    if (pevt->eType != penDownEvent2) {
        return false;
    }

    // Find a form that demands pen 2

    Form *pfrmWantsPen2 = FindPen2Form();
    if (pfrmWantsPen2 == NULL) {
        for (int i = 0; i < m_cfrmm; i++) {
            pfrmWantsPen2 = m_apfrmm[i]->FindPen2Form();
            if (pfrmWantsPen2 != NULL) {
                break;
            }
        }
    }
    if (pfrmWantsPen2 == NULL) {
        return false;
    }

    // If this form already has capture, then no need to "steal" capture;
    // process normally.

    FormMgr *pfrmmWantsPen2 = pfrmWantsPen2->GetFormMgr();
    if (pfrmmWantsPen2->HasCapture()) {
        return false;
    }

    // Any modal forms up? Don't steal pen2

    if (GetModalForm() != NULL) {
        return false;
    }
    for (int i = 0; i < m_cfrmm; i++) {
        if (m_apfrmm[i]->GetModalForm() != NULL) {
            return false;
        }
    }

    // Pen1 is captured in a different form manager. Steal that, then
    // send pen1down and pen2down to the new form.

    if (pfrmmChildCapture != NULL) {
        pfrmmChildCapture->BreakCapture();
    } else {
        if (HasCapture()) {
            BreakCapture();
        }
    }

    // Force capture to this form specifically. This will by-pass
    // hit testing.

    pfrmmWantsPen2->m_idfCapture = pfrmWantsPen2->GetId();

    // Find the formmgr's rect
    Rect rc;
    rc.SetEmpty();
    for (int i = 0; i < m_cfrmm; i++) {
        if (m_apfrmm[i] == pfrmmWantsPen2) {
            rc = m_arcFormMgr[i];
            break;
        }
    }

    // These events need to be processed in the right order.
    // To do this, they will get posted after being cooked.

    Event evtT;
    evtT = m_evtPen1Down;
    evtT.x -= rc.left;
    evtT.y -= rc.top;
    pfrmmWantsPen2->CookEvent(&evtT);
    gevm.PostEvent(&evtT, false);

    evtT = *pevt;
    evtT.x -= rc.left;
    evtT.y -= rc.top;
    pfrmmWantsPen2->CookEvent(&evtT);
    gevm.PostEvent(&evtT, false);

    // This current event is going to be processed so change it
    // to something nop-ish.

    pevt->eType = nullEvent;
    pevt->idf = 0;
    return true;
}