/***************************************************************************** ** ** ** Neversoft Entertainment. ** ** ** ** Copyright (C) 2000 - All Rights Reserved ** ** ** ****************************************************************************** ** ** ** Project: Skate3 ** ** ** ** Module: GameNet ** ** ** ** File name: Player.cpp ** ** ** ** Created by: 08/09/01 - spg ** ** ** ** Description: PlayerInfo functionality ** ** ** *****************************************************************************/ /***************************************************************************** ** Includes ** *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include // mostly getting score /***************************************************************************** ** DBG Information ** *****************************************************************************/ namespace GameNet { /***************************************************************************** ** Externals ** *****************************************************************************/ /***************************************************************************** ** Defines ** *****************************************************************************/ enum { vINVULNERABILITY_PERIOD = 10, // in frames vINVULNERABILITY_BAIL_SECONDS = 1, // in seconds vPROJECTILE_INVULNERABILITY_INTERVAL = 5000,// in ms }; /***************************************************************************** ** Private Types ** *****************************************************************************/ /***************************************************************************** ** Private Data ** *****************************************************************************/ /***************************************************************************** ** Public Data ** *****************************************************************************/ /***************************************************************************** ** Private Prototypes ** *****************************************************************************/ /***************************************************************************** ** Private Functions ** *****************************************************************************/ int Manager::GetTeamScore( int team_id ) { PlayerInfo* player, *local_player; Mdl::Skate * skate_mod = Mdl::Skate::Instance(); Lst::Search< PlayerInfo > sh; Mdl::Score* score_obj; int score; bool in_goal_attack; score = 0; local_player = GetLocalPlayer(); in_goal_attack = skate_mod->GetGameMode()->GetNameChecksum() == Script::GenerateCRC( "netgoalattack" ); // Next create a sorted list of the players (sorted in order of highest to lowest score) for( player = FirstPlayerInfo( sh ); player; player = NextPlayerInfo( sh )) { // Only show the names/scores of players that are fully in the game if((player->IsFullyIn() == false ) || ( player->m_Team != team_id )) { continue; } if( in_goal_attack && !local_player->IsObserving()) { Game::CGoalManager* pGoalManager; pGoalManager = Game::GetGoalManager(); return pGoalManager->NumGoalsBeatenByTeam( team_id ); } else { Obj::CSkaterScoreComponent* p_skater_score_component = GetSkaterScoreComponentFromObject(player->m_Skater); Dbg_Assert(p_skater_score_component); score_obj = p_skater_score_component->GetScore(); score += score_obj->GetTotalScore(); } } return score; } int Manager::GetPlayerScore( int obj_id ) { bool in_goal_attack; Mdl::Skate * skate_mod = Mdl::Skate::Instance(); GameNet::PlayerInfo* local_player; local_player = GetLocalPlayer(); in_goal_attack = skate_mod->GetGameMode()->GetNameChecksum() == Script::GenerateCRC( "netgoalattack" ); if( in_goal_attack && !local_player->IsObserving()) { Game::CGoalManager* pGoalManager; pGoalManager = Game::GetGoalManager(); return pGoalManager->NumGoalsBeatenBy( obj_id ); } else { Mdl::Score* score_obj; PlayerInfo* player; player = GetPlayerByObjectID( obj_id ); Dbg_Assert( player ); Obj::CSkaterScoreComponent* p_skater_score_component = GetSkaterScoreComponentFromObject(player->m_Skater); Dbg_Assert(p_skater_score_component); score_obj = p_skater_score_component->GetScore(); return score_obj->GetTotalScore(); } } void Manager::s_render_scores_code( const Tsk::Task< Manager >& task ) { Front::CScreenElementManager* p_screen_elem_man = Front::CScreenElementManager::Instance(); Mdl::Skate * skate_mod = Mdl::Skate::Instance(); Script::CScriptStructure *pParams; Game::CGameMode* pGameMode; PlayerInfo* player; Lst::Search< PlayerInfo > sh; static Tmr::Time last_update = 0; Tmr::Time cur_time; Lst::Head< ScoreRank > rank_list; Lst::Search< ScoreRank > rank_sh; ScoreRank* rank, *next; bool show_score, king_mode; Manager& man = task.GetData(); // Only draw the scores in modes in which the score accumulates pGameMode = skate_mod->GetGameMode(); show_score = skate_mod->GetGameMode()->GetNameChecksum() != CRCD( 0x1c471c60, "netlobby" ); // in King of the hill games, "score" is actually milliseconds with the crown king_mode = ( skate_mod->GetGameMode()->GetNameChecksum() == CRCD( 0x6ef8fda0, "netking" )) || ( skate_mod->GetGameMode()->GetNameChecksum() == CRCD( 0x5d32129c, "king" )); cur_time = Tmr::GetTime(); if(( cur_time - last_update ) >= Tmr::Seconds( 1 )) { int i, j; uint32 id; last_update = cur_time; // First clear all previous entries Script::RunScript( "clear_scores" ); if( show_score && man.ShouldDisplayTeamScores()) { ScoreRank* ranks[vMAX_TEAMS]; for( j = 0; j < skate_mod->GetGameMode()->NumTeams(); j++ ) { if( man.NumTeamMembers( j ) > 0 ) { uint32 team_name_checksum; switch( j ) { case 0: team_name_checksum = CRCD( 0x3224348d, "team_1_name" ); break; case 1: team_name_checksum = CRCD( 0xb4b04623, "team_2_name" ); break; case 2: team_name_checksum = CRCD( 0x7fec9586, "team_3_name" ); break; case 3: team_name_checksum = CRCD( 0x62e9a53e, "team_4_name" ); break; default: Dbg_Assert( 0 ); team_name_checksum = 0; break; } ranks[j] = new ScoreRank; strcpy( ranks[j]->m_Name, Script::GetString( team_name_checksum )); ranks[j]->m_IsKing = false; ranks[j]->m_HasFlag = false; ranks[j]->m_WhichFlags = 0; ranks[j]->m_ColorIndex = j + 2; ranks[j]->m_TotalScore = man.GetTeamScore( j ); } } // Next create a sorted list of the players (sorted in order of highest to lowest score) for( player = man.FirstPlayerInfo( sh ); player; player = man.NextPlayerInfo( sh )) { // Only show the names/scores of players that are fully in the game if( !( player->IsFullyIn())) { continue; } if( player->IsLocalPlayer()) { char new_name[64]; // This is my team. Make that obvious to the players sprintf( new_name, "> %s", ranks[player->m_Team]->m_Name ); strcpy( ranks[player->m_Team]->m_Name, new_name ); } if( player->IsKing()) { ranks[player->m_Team]->m_IsKing = true; } if( player->HasCTFFlag()) { ranks[player->m_Team]->m_HasFlag = true; ranks[player->m_Team]->m_WhichFlags |= ( 1 << player->HasWhichFlag()); } } for( j = 0; j < skate_mod->GetGameMode()->NumTeams(); j++ ) { if( man.NumTeamMembers( j ) > 0 ) { // Lists sort based on node's priority so set the node's priority to that of // the team's score and add it to the list ranks[j]->SetPri( ranks[j]->m_TotalScore ); rank_list.AddNode( ranks[j] ); } } } else { // Next create a sorted list of the players (sorted in order of highest to lowest score) for( player = man.FirstPlayerInfo( sh ); player; player = man.NextPlayerInfo( sh )) { // Only show the names/scores of players that are fully in the game if( !( player->IsFullyIn())) { continue; } rank = new ScoreRank; if( player->IsLocalPlayer()) { // This is me. Make that obvious. sprintf( rank->m_Name, "> %s", player->m_Name ); } else { strcpy( rank->m_Name, player->m_Name ); } rank->m_IsKing = player->IsKing(); if( skate_mod->GetGameMode()->IsTeamGame()) { rank->m_ColorIndex = player->m_Team + 2; } else { rank->m_ColorIndex = player->m_Skater->GetID() + 2; } if( player->HasCTFFlag()) { rank->m_HasFlag = true; rank->m_WhichFlags |= ( 1 << player->HasWhichFlag()); } if( show_score ) { // Lists sort based on node's priority so set the node's priority to that of // the player's score and add him to the list rank->SetPri( man.GetPlayerScore( player->m_Skater->GetID())); rank_list.AddNode( rank ); } else { // Just add the player to the list so that the order is the same regardless of score rank_list.AddToTail( rank ); } } } // Now loop through the sorted list in order of highest to lowest score and print them out i = 0; for( rank = rank_sh.FirstItem( rank_list ); rank; rank = next ) { char score_str[64]; char title[16]; title[0]='\0'; if( rank->m_IsKing ) { #if ENGLISH == 0 sprintf( title, Script::GetLocalString( "player_str_king_abbreviation" )); #else sprintf( title, "K" ); #endif } else { if( rank->m_HasFlag ) { if( rank->m_WhichFlags & 1 ) { strcat( title, "\\s0" ); } if( rank->m_WhichFlags & 2 ) { strcat( title, "\\s1" ); } if( rank->m_WhichFlags & 4 ) { strcat( title, "\\s2" ); } if( rank->m_WhichFlags & 8 ) { strcat( title, "\\s3" ); } } else { title[0] = '\0'; } } next = rank_sh.NextItem(); if( show_score ) { if( king_mode ) { int seconds; seconds = Tmr::InSeconds( rank->GetPri() ); if( seconds >= 3600 ) { sprintf( score_str, "\\c4%s\\c%d %s \\c%d %d:%.2d:%.2d", title, rank->m_ColorIndex, rank->m_Name, rank->m_ColorIndex, seconds / 3600, ( seconds % 3600 ) / 60, seconds % 60 ); } else { sprintf( score_str, "\\c4%s\\c%d %s \\c%d %d:%.2d", title, rank->m_ColorIndex, rank->m_Name, rank->m_ColorIndex, seconds / 60, seconds % 60 ); } } else { sprintf( score_str, "%s\\c%d %s \\c%d %d", title, rank->m_ColorIndex, rank->m_Name, rank->m_ColorIndex, rank->GetPri()); } } else { sprintf( score_str, "\\c%d%s", rank->m_ColorIndex, rank->m_Name ); } switch( i ) { case 0: id = CRCD( 0x2b083809, "net_score_1" ); break; case 1: id = CRCD( 0xb20169b3, "net_score_2" ); break; case 2: id = CRCD( 0xc5065925, "net_score_3" ); break; case 3: id = CRCD( 0x5b62cc86, "net_score_4" ); break; case 4: id = CRCD( 0x2c65fc10, "net_score_5" ); break; case 5: id = CRCD( 0xb56cadaa, "net_score_6" ); break; case 6: id = CRCD( 0xc26b9d3c, "net_score_7" ); break; case 7: id = CRCD( 0x52d480ad, "net_score_8" ); break; default: Dbg_Assert( 0 ); id = 0; break; } pParams = new Script::CScriptStructure; pParams->AddComponent( CRCD( 0xc4745838, "text" ), ESYMBOLTYPE_STRING, score_str ); pParams->AddComponent( CRCD( 0x40c698af, "id" ), ESYMBOLTYPE_NAME, id ); Front::CScreenElement* p_name_elem = p_screen_elem_man->GetElement( id, Front::CScreenElementManager::DONT_ASSERT ); // If any operable menus are up, ignore input if( p_name_elem ) { //make sure the scores are enabled //if(!Mdl::Skate::Instance()->GetCareer()->GetGlobalFlag(Script::GetInteger(CRCD(0xfbb66146,"NO_DISPLAY_NET_SCORES"))))) p_name_elem->SetProperties( pParams ); } Script::RunScript( "update_score", pParams ); delete pParams; delete rank; i++; } } } /******************************************************************/ /* */ /* */ /******************************************************************/ PlayerInfo::PlayerInfo( int flags ) : Lst::Node< PlayerInfo > ( this ) { int i, j; sprintf( m_Name, "" ); for( i = 0; i < Mdl::Skate::vMAX_SKATERS; i++ ) { m_LastSentProps.m_LastSkaterFlagsUpdate[i] = -1; m_LastSentProps.m_LastSkaterStateUpdate[i] = -1; m_LastSentProps.m_LastDoingTrickUpdate[i] = -1; for( j = 0; j < 3; j++ ) { m_LastSentProps.m_LastSkaterPosUpdate[i][j] = -1; m_LastSentProps.m_LastSkaterRotUpdate[i][j] = -1; } } m_flags = flags; m_observer_logic_task = NULL; m_jump_in_frame = 0; m_last_object_update_id = vMAX_PLAYERS - 1; m_face_data = NULL; m_Skater = NULL; mp_SkaterProfile = NULL; m_last_bail_time = 0; m_last_hit_time = 0; m_Team = vTEAM_RED; m_Profile = 0; m_Rating = 0; m_VehicleControlType = 0; } /******************************************************************/ /* */ /* */ /******************************************************************/ PlayerInfo::~PlayerInfo( void ) { if ( mp_SkaterProfile ) delete mp_SkaterProfile; if( m_observer_logic_task ) { delete m_observer_logic_task; } if( m_face_data ) { delete [] m_face_data; m_face_data = NULL; } } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::SetSkater( Obj::CSkater* skater ) { Manager * gamenet_man = Manager::Instance(); m_Skater = skater; if( !IsLocalPlayer()) { if( gamenet_man->GetCurrentlyObservedPlayer() == this ) { gamenet_man->ObservePlayer( this ); } } } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::SetFaceData( uint8* face_data, int size ) { uint8 player_id; Dbg_Assert( m_face_data == NULL ); Dbg_Assert( face_data != NULL ); Dbg_Assert( m_Skater != NULL ); Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().NetMiscHeap()); player_id = m_Skater->GetID(); // Store the player's skater id as the first byte of the face data m_face_data = new uint8[size+1]; *m_face_data = player_id; memcpy( m_face_data + 1, face_data, size ); Mem::Manager::sHandle().PopContext(); } /******************************************************************/ /* */ /* */ /******************************************************************/ // The player's skater id is the first byte of the face data uint8* PlayerInfo::GetFaceData( void ) { return m_face_data; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::CopyProfile( Obj::CSkaterProfile* pSkaterProfile ) { Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().SkaterInfoHeap()); Dbg_Assert( pSkaterProfile ); #if 0 // copy it to the server's player info data uint8* pTempBuffer = new uint8[vMAX_APPEARANCE_DATA_SIZE]; uint32 size = pSkaterProfile->WriteToBuffer(pTempBuffer, vMAX_APPEARANCE_DATA_SIZE); Dbg_Printf("Appearance data size is %d bytes\n", size); mp_SkaterProfile = new Obj::CSkaterProfile; Dbg_Assert( mp_SkaterProfile ); mp_SkaterProfile->ReadFromBuffer(pTempBuffer); delete pTempBuffer; #endif // now uses assignment operator to copy over the info as well mp_SkaterProfile = new Obj::CSkaterProfile; *mp_SkaterProfile = *pSkaterProfile; Mem::Manager::sHandle().PopContext(); } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsLocalPlayer( void ) { return m_flags.TestMask( mLOCAL_PLAYER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsServerPlayer( void ) { return m_flags.TestMask( mSERVER_PLAYER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsObserving( void ) { return m_flags.TestMask( mOBSERVER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsSurveying( void ) { return m_flags.TestMask( mSURVEYING ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsRestarting( void ) { m_flags.SetMask( mRESTARTING ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsNonCollidable( void ) { m_last_bail_time = Tmr::GetTime(); return m_flags.SetMask( mNON_COLLIDABLE ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::ClearNonCollidable( void ) { return m_flags.ClearMask( mNON_COLLIDABLE ); } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsNonCollidable( void ) { Mdl::Skate * skate_mod = Mdl::Skate::Instance(); if( !m_Conn->TestStatus( Net::Conn::mSTATUS_READY )) { return true; } if( m_Skater->IsInWorld() == false ) { return true; } // Make skaters invulnerable for the first 10 frames of the game if( m_Skater->GetStateHistory()->GetNumPosUpdates() < vINVULNERABILITY_PERIOD ) { return true; } if(( Tmr::GetTime() - m_last_bail_time ) < Tmr::Seconds( vINVULNERABILITY_BAIL_SECONDS )) { return true; } // Don't collide with eliminated players in firefight if( skate_mod->GetGameMode()->GetNameChecksum() == CRCD(0xbff33600,"netfirefight")) { Mdl::Score* score_obj; Obj::CSkaterScoreComponent* p_score_component = GetSkaterScoreComponentFromObject(m_Skater); Dbg_Assert(p_score_component); score_obj = p_score_component->GetScore(); if( score_obj->GetTotalScore() <= 0 ) { return true; } } // If they've been in this state for more than 5 seconds, that means that // for one reason or another, we didn't get their "NotifyBailDone" message. // This will rectify things. if(( Tmr::GetTime() - m_last_bail_time ) > Tmr::Seconds( 5 )) { ClearNonCollidable(); return false; } if( m_flags.TestMask( mNON_COLLIDABLE )) { return true; } return false; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsFullyIn( void ) { Manager * gamenet_man = Manager::Instance(); m_flags.SetMask( mFULLY_IN ); if( gamenet_man->InNetGame() && gamenet_man->OnServer() && !IsLocalPlayer()) { switch( gamenet_man->GetHostMode()) { case vHOST_MODE_SERVE: break; case vHOST_MODE_AUTO_SERVE: { Net::Server* server; Net::MsgDesc msg_desc; server = gamenet_man->GetServer(); Dbg_Assert( server ); msg_desc.m_Id = MSG_ID_AUTO_SERVER_NOTIFICATION; msg_desc.m_Queue = Net::QUEUE_SEQUENCED; msg_desc.m_GroupId = vSEQ_GROUP_PLAYER_MSGS; // Tell the client that they're in an auto-serving server server->EnqueueMessage( GetConnHandle(), &msg_desc ); break; } case vHOST_MODE_FCFS: { PlayerInfo* player; player = gamenet_man->GetServerPlayer(); // If we don't currently have a player acting as the host // make this new player the host if( player == NULL ) { gamenet_man->ChooseNewServerPlayer(); } break; } } } } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsFullyIn( void ) { return m_flags.TestMask( mFULLY_IN | mLOCAL_PLAYER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsServerPlayer( void ) { m_flags.SetMask( mSERVER_PLAYER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsNotServerPlayer( void ) { m_flags.ClearMask( mSERVER_PLAYER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::HasCTFFlag( void ) { return m_flags.TestMask( mHAS_ANY_FLAG ); } /******************************************************************/ /* */ /* */ /******************************************************************/ int PlayerInfo::HasWhichFlag( void ) { if( m_flags.TestMask( mHAS_RED_FLAG )) { return 0; } if( m_flags.TestMask( mHAS_BLUE_FLAG )) { return 1; } if( m_flags.TestMask( mHAS_GREEN_FLAG )) { return 2; } if( m_flags.TestMask( mHAS_YELLOW_FLAG )) { return 3; } return -1; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::ClearCTFState( void ) { m_flags.ClearMask( mHAS_ANY_FLAG ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::CapturedFlag( int team ) { Manager * gamenet_man = Manager::Instance(); PlayerInfo* local_player; char team_str[64]; Script::CStruct* pParams; sprintf( team_str, "team_%d_name", team + 1 ); local_player = gamenet_man->GetLocalPlayer(); // Make sure they have a flag on them Dbg_Assert( HasCTFFlag()); pParams = new Script::CStruct; if( IsLocalPlayer()) { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); pParams->AddInteger( "team", team ); Script::RunScript( "captured_flag_you", pParams ); } else { Dbg_Printf( "***** Captured Flag : My Team %d, Flag Team %d\n", local_player->m_Team, team ); if( ( !local_player->IsObserving()) && ( local_player->m_Team == team )) { Dbg_Printf( "***** Captured Flag 2\n" ); pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); pParams->AddInteger( "team", team ); Script::RunScript( "hide_ctf_arrow" ); Script::RunScript( "captured_your_flag", pParams ); } else { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); pParams->AddComponent( Script::GenerateCRC("String1"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); pParams->AddInteger( "team", team ); Script::RunScript( "captured_flag_other", pParams ); } } m_flags.ClearMask( mHAS_ANY_FLAG ); delete pParams; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::StoleFlag( int team ) { // Shouldn't have any flag already Dbg_Assert( !HasCTFFlag()); Dbg_Printf( "********* In StoleFlag\n" ); Manager * gamenet_man = Manager::Instance(); PlayerInfo* local_player, *player; Lst::Search< PlayerInfo > sh; char team_str[64]; Script::CStruct* pParams; sprintf( team_str, "team_%d_name", team + 1 ); pParams = new Script::CStruct; local_player = gamenet_man->GetLocalPlayer(); if( IsLocalPlayer()) { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); Script::RunScript( "stole_flag_you", pParams ); } else { Dbg_Printf( "***** FLAG STOLEN: Team %d, I had %d\n", team, local_player->HasWhichFlag() ); if( !local_player->IsObserving() && ( local_player->HasWhichFlag() == team )) { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); pParams->AddComponent( Script::GenerateCRC("String1"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); Script::RunScript( "stole_flag_from_you", pParams ); } else { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); pParams->AddComponent( Script::GenerateCRC("String1"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); Script::RunScript( "stole_flag_other", pParams ); } } delete pParams; for( player = gamenet_man->FirstPlayerInfo( sh ); player; player = gamenet_man->NextPlayerInfo( sh )) { if( player->HasWhichFlag() == team ) { player->m_flags.ClearMask(( mHAS_RED_FLAG << team )); player->ClearCTFState(); Dbg_Assert( !player->HasCTFFlag()); } } m_flags.SetMask(( mHAS_RED_FLAG << team )); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::TookFlag( int team ) { // Shouldn't have any flag already Dbg_Assert( !HasCTFFlag()); Manager * gamenet_man = Manager::Instance(); PlayerInfo* local_player; char team_str[64]; Script::CStruct* pParams; sprintf( team_str, "team_%d_name", team + 1 ); pParams = new Script::CStruct; local_player = gamenet_man->GetLocalPlayer(); if( IsLocalPlayer()) { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); Script::RunScript( "took_flag_you", pParams ); } else { Script::CStruct* arrow_params; if(( !local_player->IsObserving()) && ( team == local_player->m_Team )) { arrow_params = new Script::CStruct; arrow_params->AddInteger( "team", local_player->m_Team ); Script::RunScript( "show_ctf_arrow", arrow_params ); delete arrow_params; pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); Script::RunScript( "took_flag_yours", pParams ); } else { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); pParams->AddComponent( Script::GenerateCRC("String1"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); Script::RunScript( "took_flag_other", pParams ); } } delete pParams; m_flags.SetMask(( mHAS_RED_FLAG << team )); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::RetrievedFlag( void ) { Manager * gamenet_man = Manager::Instance(); GameNet::PlayerInfo* player, *local_player; Lst::Search< PlayerInfo > sh; char team_str[64]; Script::CStruct* pParams; sprintf( team_str, "team_%d_name", m_Team + 1 ); pParams = new Script::CStruct; if( IsLocalPlayer()) { pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); pParams->AddInteger( "team", m_Team ); Script::RunScript( "hide_ctf_arrow" ); Script::RunScript( "retrieved_flag_you", pParams ); } else { local_player = gamenet_man->GetLocalPlayer(); if( local_player && !local_player->IsObserving()) { if( local_player->m_Team == m_Team ) { Script::RunScript( "hide_ctf_arrow" ); } } pParams->AddComponent( Script::GenerateCRC("String0"), ESYMBOLTYPE_STRING, m_Name ); pParams->AddComponent( Script::GenerateCRC("String1"), ESYMBOLTYPE_STRING, Script::GetString( team_str )); pParams->AddInteger( "team", m_Team ); Script::RunScript( "retrieved_flag_other", pParams ); } for( player = gamenet_man->FirstPlayerInfo( sh ); player; player = gamenet_man->NextPlayerInfo( sh )) { if( player->HasWhichFlag() == m_Team ) { player->ClearCTFState(); break; } } } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsKing( bool mark ) { Manager * gamenet_man = Manager::Instance(); Mdl::Skate * skate_mod = Mdl::Skate::Instance(); if( mark ) { PlayerInfo* former_king; // There can only be one king, so dethrone the last former_king = gamenet_man->GetKingOfTheHill(); if( former_king ) { former_king->MarkAsKing( false ); } if( !m_flags.TestMask( mKING_OF_THE_HILL )) { m_flags.SetMask( mKING_OF_THE_HILL ); if( IsLocalPlayer()) { Script::CStruct* pParams; pParams = new Script::CStruct; if( m_Skater->GetHeapIndex() == 0 ) { pParams->AddChecksum( "player_1", Script::GenerateCRC( "player_1")); } else { pParams->AddChecksum( "player_2", Script::GenerateCRC( "player_2")); } // If we just picked up the crown, hide the arrow Script::RunScript( "hide_crown_arrow", pParams ); delete pParams; /*gamenet_man->CreateNetPanelMessage( false, Script::GenerateCRC("net_message_new_king_you"), NULL, NULL, m_Skater );*/ Script::RunScript( "NewKingYou" ); } else { Script::CStruct* pParams; pParams = new Script::CStruct; pParams->AddChecksum( "player_1", Script::GenerateCRC( "player_1")); // If someone else just picked up the crown, show the arrow Script::RunScript( "show_crown_arrow", pParams ); pParams->AddString( "String0", m_Name ); Script::RunScript( "NewKingOther", pParams ); /*gamenet_man->CreateNetPanelMessage( false, Script::GenerateCRC( "net_message_new_king_other"), m_Name, NULL );*/ delete pParams; } if( !gamenet_man->InNetGame()) { int other_id; PlayerInfo* other_player; // NOTE: This code only works for 2-player splitscreen. If we ever go to four, // it needs to be more sophisticated if( m_Skater->GetID() == 0 ) { other_id = 1; } else { other_id = 0; } other_player = gamenet_man->GetPlayerByObjectID( other_id ); if( other_player ) { Script::CStruct* pParams; pParams = new Script::CStruct; pParams->AddString( "String0", (char*)m_Skater->GetDisplayName()); Script::RunScript( "NewKingOther", pParams ); /*gamenet_man->CreateNetPanelMessage( false, Script::GenerateCRC("net_message_new_king_other"), (char*)m_Skater->GetDisplayName(), NULL, other_player->m_Skater );*/ delete pParams; } } m_flags.SetMask( mKING_OF_THE_HILL ); } Obj::CCrown* crown; crown = gamenet_man->GetCrown(); if( crown ) { crown->PlaceOnKing( m_Skater ); } } else { if( m_flags.TestMask( mKING_OF_THE_HILL )) { if( IsLocalPlayer()) { // If we lost the crown, show the arrow again, but only if we're still in koth mode if( skate_mod->GetGameMode()->GetNameChecksum() == Script::GenerateCRC( "netking" ) || skate_mod->GetGameMode()->GetNameChecksum() == Script::GenerateCRC( "king" )) { Script::CStruct* pParams; pParams = new Script::CStruct; pParams->AddChecksum( "player_1", Script::GenerateCRC( "player_1")); pParams->AddChecksum( "player_2", Script::GenerateCRC( "player_2")); Script::RunScript( "show_crown_arrow", pParams ); delete pParams; } } m_flags.ClearMask( mKING_OF_THE_HILL ); } } } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsKing( void ) { return m_flags.TestMask( mKING_OF_THE_HILL ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsNotReady( int time ) { if( m_Conn && m_Conn->IsRemote()) { if( time != 0 ) { m_latest_ready_query = time; } m_Conn->ClearStatus( Net::Conn::mSTATUS_READY ); m_Conn->SetStatus( Net::Conn::mSTATUS_BUSY ); } } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::SetReadyQueryTime( int time ) { m_latest_ready_query = time; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::MarkAsReady( int time ) { if( m_latest_ready_query == time ) { if( m_Conn ) { m_Conn->ClearStatus( Net::Conn::mSTATUS_BUSY ); m_Conn->SetStatus( Net::Conn::mSTATUS_READY ); // Now that they're ready, we need to keep track of how many times we're resending to // them so that we can detect bad connections m_Conn->ClearNumResends(); } m_latest_ready_query = 0; } } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsVulnerable( void ) { return (( Tmr::GetTime() - m_last_hit_time ) > vPROJECTILE_INVULNERABILITY_INTERVAL ); } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::ResetProjectileVulnerability( void ) { m_last_hit_time = 0; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::SetHitTime( Tmr::Time hit_time ) { m_last_hit_time = hit_time; } /******************************************************************/ /* */ /* */ /******************************************************************/ int PlayerInfo::GetConnHandle( void ) { if( m_Conn ) { return m_Conn->GetHandle(); } return Net::Conn::vHANDLE_INVALID; } /******************************************************************/ /* */ /* */ /******************************************************************/ int PlayerInfo::GetSkaterNumber( void ) { Dbg_Assert( m_Skater ); return m_Skater->GetSkaterNumber(); } /******************************************************************/ /* */ /* */ /******************************************************************/ int PlayerInfo::GetLastObjectUpdateID( void ) { return m_last_object_update_id; } /******************************************************************/ /* */ /* */ /******************************************************************/ void PlayerInfo::SetLastObjectUpdateID( int id ) { m_last_object_update_id = id; } /******************************************************************/ /* */ /* */ /******************************************************************/ int PlayerInfo::GetMaxObjectUpdates( void ) { if( m_Conn->GetBandwidthType() == Net::Conn::vBROADBAND ) { return 2; } return 1; } /******************************************************************/ /* */ /* */ /******************************************************************/ bool PlayerInfo::IsPendingPlayer( void ) { return m_flags.TestMask( mPENDING_PLAYER ); } /******************************************************************/ /* */ /* */ /******************************************************************/ NewPlayerInfo::NewPlayerInfo(void) { Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().SkaterInfoHeap()); mpSkaterProfile = new Obj::CSkaterProfile; JumpInFrame = 0; Profile = 0; Rating = 0; Score = 0; VehicleControlType = 0; Mem::Manager::sHandle().PopContext(); } /******************************************************************/ /* */ /* */ /******************************************************************/ NewPlayerInfo::~NewPlayerInfo(void) { Dbg_Assert( mpSkaterProfile ); delete mpSkaterProfile; } /******************************************************************/ /* */ /* */ /******************************************************************/ } // namespace GameNet