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 ); }
//----------------------------------------------------------------------------- // 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(); }
//----------------------------------------------------------------------------- // 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; }
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 ); } } }
//----------------------------------------------------------------------------- // 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; } } } }
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; } } } }
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; }