void Turret::Update( ) { if( m_hOperatingObject && IsPlayer( m_hOperatingObject )) { if( m_swtDestroyedDeactivationDelay.IsStarted( ) && m_swtDestroyedDeactivationDelay.IsTimedOut( )) { Deactivate( ); // Remove the turret weapon since the turret is getting removed as well... m_Arsenal.RemoveAllActiveWeapons( ); // Remove ourselves now that we're dead... g_pLTServer->RemoveObject( m_hObject ); return; } CPlayerObj *pPlayer = dynamic_cast<CPlayerObj*>(g_pLTServer->HandleToObject( m_hOperatingObject )); if( !pPlayer || !pPlayer->IsAlive( )) { Deactivate( ); return; } CWeapon *pPlayerWeapon = pPlayer->GetArsenal( )->GetCurWeapon( ); if( pPlayerWeapon ) pPlayerWeapon->HideWeapon( true ); LTRigidTransform tView; pPlayer->GetTrueViewTransform( tView ); CWeapon *pTurretWeapon = m_Arsenal.GetCurWeapon( ); if( pTurretWeapon ) { HMODELSOCKET hPivot = INVALID_MODEL_SOCKET; g_pModelLT->GetSocket( m_hObject, "Pivot", hPivot ); LTTransform tPivot; g_pModelLT->GetSocketTransform( m_hObject, hPivot, tPivot, true ); HOBJECT hWeapon = pTurretWeapon->GetModelObject( ); LTRigidTransform rtCur; g_pLTServer->GetObjectTransform( hWeapon, &rtCur ); // Update the position if it's changed. if( !rtCur.m_vPos.NearlyEquals( tPivot.m_vPos, 0.0001f ) || !rtCur.m_rRot.NearlyEquals( tView.m_rRot, 0.00001f )) { g_pLTServer->SetObjectTransform( hWeapon, LTRigidTransform(tPivot.m_vPos, tView.m_rRot) ); } } } else { CWeapon *pTurretWeapon = m_Arsenal.GetCurWeapon( ); if( pTurretWeapon ) { HMODELSOCKET hPivot = INVALID_MODEL_SOCKET; g_pModelLT->GetSocket( m_hObject, "Pivot", hPivot ); LTTransform tPivot; g_pModelLT->GetSocketTransform( m_hObject, hPivot, tPivot, true ); HOBJECT hWeapon = pTurretWeapon->GetModelObject( ); LTRigidTransform rtCur; g_pLTServer->GetObjectTransform( hWeapon, &rtCur ); // Update the position if it's changed. if( !rtCur.m_vPos.NearlyEquals( tPivot.m_vPos, 0.0001f ) || !rtCur.m_rRot.NearlyEquals( tPivot.m_rRot, 0.00001f )) { g_pLTServer->SetObjectTransform( hWeapon, tPivot ); } } } SetNextUpdate( UPDATE_NEXT_FRAME ); }
void ServerVoteMgr::HandleVoteStart(HCLIENT hSender, ILTMessage_Read* pMsg) { if (!hSender) { return; } if (IsVoteInProgress()) { // Tell the player why their vote didn't start SendCancelVoteInProgress( hSender ); return; } VoteType eVoteType = (VoteType)pMsg->ReadBits( FNumBitsExclusive<kNumVoteTypes>::k_nValue ); //check to see if we have a real client uint32 nCallerID = g_pLTServer->GetClientID( hSender ); HCLIENT hCallerClient = g_pLTServer->GetClientHandle( nCallerID ); if( !hCallerClient ) return; GameClientData* pCallerGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hCallerClient ); if( !pCallerGameClientData ) return; //check to see if the client has a live player... if (!GameModeMgr::Instance( ).m_grbAllowDeadVoting) { CPlayerObj* pPlayerObj = ( CPlayerObj* )g_pLTServer->HandleToObject( pCallerGameClientData->GetPlayer( )); if( !pPlayerObj || !pPlayerObj->IsAlive( )) { return; } }; // Make sure we start fresh. ClearVote( ); switch(eVoteType) { case eVote_Kick: case eVote_TeamKick: case eVote_Ban: { uint32 nTargetID = pMsg->Readuint32(); HCLIENT hTargetClient = g_pLTServer->GetClientHandle( nTargetID ); if( !hTargetClient ) return; GameClientData* pTargetGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hTargetClient ); if( !pTargetGameClientData ) return; // Iterate through all the clients and see if anyone is ready to vote. ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; // Skip clients that aren't ready to play yet. if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld ) continue; // Client must have reached the inworld state. if( !pGameClientData->IsClientInWorld( )) continue; // Restrict elibible voters if it's a team kick. if( eVoteType == eVote_TeamKick ) { if( pCallerGameClientData->GetLastTeamId() != pGameClientData->GetLastTeamId( )) continue; } // Add to the eligible voter list. m_lstEligibleVoter.push_back( pGameClientData->GetClient( )); } // Check if we have a quorum of voters. uint32 nQuorum = ( eVoteType == eVote_TeamKick ) ? GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForTeamVote : GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote; //figure out how many votes are needed to pass uint8 nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half //if we have less than the "minimum" number of players, the vote must pass unanimously if( m_lstEligibleVoter.size( ) < nQuorum ) { nVotesNeeded = m_lstEligibleVoter.size( ); } // Put the caller on the list of voters already cast. m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( )); float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime; m_VoteTimer.Start(fDuration); m_CurrentVote.m_eVoteType = eVoteType; m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes m_CurrentVote.m_nTargetID = nTargetID; m_CurrentVote.m_nCallerID = nCallerID; m_CurrentVote.m_nNoVotes = 0; m_CurrentVote.m_nYesVotes = 1; m_CurrentVote.m_nVotesNeeded = nVotesNeeded; CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); cMsg.Writeuint32( nCallerID ); cMsg.Writeuint32( nTargetID ); cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded ); cMsg.Writedouble( m_VoteTimer.GetTimeLeft( )); // Send the vote start info to the eligible voters. SendToEligibleVoters( *cMsg.Read( )); // Check if we've already achieved necessary votes. CheckVoteStatus(); } break; case eVote_NextRound: case eVote_NextMap: { // Iterate through all the clients and see if anyone is ready to vote. ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; // Skip clients that aren't ready to play yet. if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld ) continue; // Client must have reached the inworld state. if( !pGameClientData->IsClientInWorld( )) continue; // Add to the eligible voter list. m_lstEligibleVoter.push_back( pGameClientData->GetClient( )); } // Check if we have a quorum of voters. uint32 nQuorum = GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote; //figure out how many votes are needed to pass uint8 nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half //if we have less than the "minimum" number of players, the vote must pass unanimously if( m_lstEligibleVoter.size( ) < nQuorum ) { nVotesNeeded = m_lstEligibleVoter.size( ); } // Put the caller on the list of voters already cast. m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( )); float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime; m_VoteTimer.Start(fDuration); m_CurrentVote.m_eVoteType = eVoteType; m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes m_CurrentVote.m_nTargetID = 0; m_CurrentVote.m_nCallerID = nCallerID; m_CurrentVote.m_nNoVotes = 0; m_CurrentVote.m_nYesVotes = 1; m_CurrentVote.m_nVotesNeeded = nVotesNeeded; CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); cMsg.Writeuint32( nCallerID ); cMsg.Writeuint32( 0 ); cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded ); cMsg.Writedouble( m_VoteTimer.GetTimeLeft( )); // Send the vote start info to the eligible voters. SendToEligibleVoters( *cMsg.Read( )); // Check if we've already achieved necessary votes. CheckVoteStatus(); } break; case eVote_SelectMap: { uint32 nMapIndex = pMsg->Readuint32(); uint32 nCallerID = g_pLTServer->GetClientID( hSender ); HCLIENT hCallerClient = g_pLTServer->GetClientHandle( nCallerID ); if( !hCallerClient ) return; GameClientData* pCallerGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hCallerClient ); if( !pCallerGameClientData ) return; // Iterate through all the clients and see if anyone is ready to vote. ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; // Skip clients that aren't ready to play yet. if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld ) continue; // Client must have reached the inworld state. if( !pGameClientData->IsClientInWorld( )) continue; // Add to the eligible voter list. m_lstEligibleVoter.push_back( pGameClientData->GetClient( )); } // Check if we have a quorum of voters. uint32 nQuorum = GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote; //figure out how many votes are needed to pass uint8 nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half //if we have less than the "minimum" number of players, the vote must pass unanimously if( m_lstEligibleVoter.size( ) < nQuorum ) { nVotesNeeded = m_lstEligibleVoter.size( ); } // Put the caller on the list of voters already cast. m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( )); float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime; m_VoteTimer.Start(fDuration); m_CurrentVote.m_eVoteType = eVoteType; m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes m_CurrentVote.m_nTargetID = nMapIndex; m_CurrentVote.m_nCallerID = nCallerID; m_CurrentVote.m_nNoVotes = 0; m_CurrentVote.m_nYesVotes = 1; m_CurrentVote.m_nVotesNeeded = nVotesNeeded; CAutoMessage cMsg; cMsg.Writeuint8( MID_VOTE ); cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue ); cMsg.Writeuint8( m_CurrentVote.m_nVoteID ); cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue ); cMsg.Writeuint32( nCallerID ); cMsg.Writeuint32( nMapIndex ); cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded ); cMsg.Writedouble( m_VoteTimer.GetTimeLeft( )); // Send the vote start info to the eligible voters. SendToEligibleVoters( *cMsg.Read( )); // Check if we've already achieved necessary votes. CheckVoteStatus(); } break; } }