#include "rp.h" #pragma hdrstop #include "rpplayer.h" #include "..\munga\dropzone.h" #include "..\munga\mission.h" #include "scorzone.h" #include "rpcnsl.h" #include "..\munga\app.h" #include "vtv.h" #include "..\munga\hostmgr.h" #include "..\munga\nttmgr.h" //############################################################################# //######################## RPPlayer__StatusMessage ###################### //############################################################################# MemoryBlock *RPPlayer__StatusMessage::GetAllocatedMemory() { static MemoryBlock allocatedMemory(sizeof(RPPlayer__StatusMessage), RPPlayer__StatusMessage::numberOfAllocatedBlocks, RPPlayer__StatusMessage::numberOfAllocatedBlocks); return &allocatedMemory; } //############################################################################# //############################### RPPlayer ############################## //############################################################################# //############################################################################# // Message Support // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // General PlayerType Message Handlers // const Receiver::HandlerEntry RPPlayer::MessageHandlerEntries[]= { MESSAGE_ENTRY(RPPlayer, TakeDamage), MESSAGE_ENTRY(RPPlayer, VehicleDead), MESSAGE_ENTRY(RPPlayer, Score), MESSAGE_ENTRY(RPPlayer, DropZoneReply), MESSAGE_ENTRY(RPPlayer, ScoreZoneReply), MESSAGE_ENTRY(RPPlayer, MissionStarting), MESSAGE_ENTRY(RPPlayer, MissionEnding) }; Receiver::MessageHandlerSet& RPPlayer::GetMessageHandlers() { static Receiver::MessageHandlerSet messageHandlers(ELEMENTS(RPPlayer::MessageHandlerEntries), RPPlayer::MessageHandlerEntries, Player::GetMessageHandlers()); return messageHandlers; } //############################################################################# // Shared Data Support // Derivation* RPPlayer::GetClassDerivations() { static Derivation classDerivations(Player::GetClassDerivations(), "RPPlayer"); return &classDerivations; } RPPlayer::SharedData RPPlayer::DefaultData( RPPlayer::GetClassDerivations(), RPPlayer::GetMessageHandlers(), RPPlayer::GetAttributeIndex(), RPPlayer::StateCount, (RPPlayer::MakeHandler)RPPlayer::Make ); //############################################################################# // Attribute Support // const RPPlayer::IndexEntry RPPlayer::AttributePointers[]= { ATTRIBUTE_ENTRY(RPPlayer, GoalEntity, goalEntity) }; RPPlayer::AttributeIndexSet& RPPlayer::GetAttributeIndex() { static RPPlayer::AttributeIndexSet attributeIndex(ELEMENTS(RPPlayer::AttributePointers), RPPlayer::AttributePointers, Player::GetAttributeIndex() ); return attributeIndex; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // static Origin first_drop; Entity *first_goal; void RPPlayer::MissionStartingMessageHandler(Message *message) { Check(this); Check(message); Player::MissionStartingMessageHandler(message); Check(application); if (application->GetApplicationState() == Application::ResumingMission) { Check(playerVehicle); if (playerVehicle->IsDerivedFrom(*VTV::GetClassDerivations())) { currentScore = 1000.0f; } } else { first_goal = goalEntity; } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::MissionEndingMessageHandler(Message *message) { Player::MissionEndingMessageHandler(message); Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); if (application->GetApplicationState() == Application::EndingMission) { ConsoleApplicationEndMissionMessage score_message(ownerID, (int)currentScore); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &score_message ); } else { ConsoleApplicationAbortMissionMessage score_message(ownerID); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &score_message ); } } lastConsoleUpdate -= 15.0f; Check(application); if (application->GetApplicationState() == Application::SuspendingMission) { Check(playerVehicle); if (playerVehicle->IsDerivedFrom(*VTV::GetClassDerivations())) { if (first_goal != goalEntity) { ScoreZone::ProcessScoreZoneRequestMessage message( ScoreZone::ProcessScoreZoneRequestMessageID, sizeof(ScoreZone::ProcessScoreZoneRequestMessage), GetEntityID(), ScoreZoneReplyMessageID, goalEntity->localOrigin.linearPosition ); goalEntity->Dispatch(&message); } VTV *vtv = (VTV*) playerVehicle; Check(vtv); vtv->Reset(first_drop, True); ForceUpdate(); } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::CreatePlayerVehicle(Origin vtv_location) { Check(this); Check(&vtv_location); Check(application); ResourceFile *resources = application->GetResourceFile(); Check(resources); Check_Pointer(playerMission->GetGameModel()); HostManager *host_manager = application->GetHostManager(); Check(host_manager); // // Create MUNGA level vehicles // Player::CreatePlayerVehicle(vtv_location); // //----------------------------------------------------------------------- // If the player has made no vehicle yet, make him a new one and link the // player to it //----------------------------------------------------------------------- // if (!playerVehicle) { ResourceDescription *vtv_res = resources->FindResourceDescription( playerMission->GetGameModel(), ResourceDescription::ModelListResourceType ); Check(vtv_res); vtv_res->Lock(); VTV::MakeMessage create_player( VTV::MakeMessageID, sizeof(VTV::MakeMessage), EntityID(host_manager->GetLocalHostID()), VTV::VTVClassID, EntityID::Null, vtv_res->resourceID, VTV::DefaultFlags|VTV::InitialStasisFlag, vtv_location, Motion::Identity, Motion::Identity, playerMission->GetBadgeName(), playerMission->GetColorName() ); vtv_res->Unlock(); playerVehicle = application->MakeAndLinkViewpointEntity(&create_player); Register_Object(playerVehicle); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::InitializePlayerLink() { Check(this); PlayerLinkMessage player_link_message ( PlayerLinkMessageID, sizeof(PlayerLinkMessage), this->GetEntityID() ); Check(playerVehicle); playerVehicle->Dispatch(&player_link_message); playerVehicle->DispatchToReplicants(&player_link_message); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::SetGoalToFirstScoreZone() { // //---------------------------------------------------------- // Change the goalEntity to the first sequential scorezone //---------------------------------------------------------- // EntityGroup *score_zone_group = application->GetEntityManager()->FindGroup("ActiveScoreZones"); if(score_zone_group) { ChainIteratorOf iterator(score_zone_group->groupMembers); ScoreZone *score_zone; while ((score_zone = (ScoreZone*)iterator.ReadAndNext()) != NULL) { if ( ( (score_zone->scoreZoneType == LocalSequential) || (score_zone->scoreZoneType == GlobalSequential) ) && score_zone->sequenceNumber == 1 ) { goalEntity = score_zone; break; } } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::PointVTVTowardGoal() { Check(this); if (!goalEntity) { return; } Vector3D to_goal; to_goal.Subtract( goalEntity->localOrigin.linearPosition, playerVehicle->localOrigin.linearPosition ); UnitVector current_heading; playerVehicle->localToWorld.GetFromAxis(Z_Axis, ¤t_heading); Scalar length_to_goal; length_to_goal = to_goal.LengthSquared(); if (length_to_goal > SMALL) { Scalar dot_prod; dot_prod = (to_goal * current_heading) / Sqrt(length_to_goal); if (dot_prod >= 0.0f) { Quaternion turn_around; Quaternion y_roll(0.0f,1.0f,0.0f,0.0); Check(playerVehicle); turn_around.Multiply( playerVehicle->localOrigin.angularPosition, y_roll ); playerVehicle->localOrigin.angularPosition = turn_around; playerVehicle->localToWorld = playerVehicle->localOrigin; playerVehicle->ForceUpdate(); } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::ResetAfterDeath(DropZone::ReplyMessage *message) { Check(this); Check(message); Check(application); message->deathCount = ++deathCount; ForceUpdate(); SetSimulationState(DropZoneAcquiredState); dropZoneLocation = message->dropZoneLocation; Time when = Now(); when += 1.0f; application->Post(HighEventPriority, this, message, when); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::DropZoneReplyMessageHandler( DropZone::ReplyMessage *message ) { Check(this); Check(message); // //----------------------------------------------------------------------- // If the player has made no vehicle yet, make him a new one and link the // player to it //----------------------------------------------------------------------- // if (!playerVehicle) { first_drop = message->dropZoneLocation; CreatePlayerVehicle(message->dropZoneLocation); InitializePlayerLink(); SetGoalToFirstScoreZone(); switch(playerVehicle->GetClassID()) { case VTVClassID: SetPerformance(&RPPlayer::PlayerSimulation); break; case CameraShipClassID: SetPerformance(&RPPlayer::CameraShipSimulation); playerRanking = -1; break; } AlwaysExecute(); deathCount = 0; } // //------------------------------------------------------------------------- // Otherwise, just set the new position of the VTV and turn off the burning // stuff. //------------------------------------------------------------------------- // else if (deathCount == message->deathCount) { if (GetSimulationState() == MissionEndingState) { Check_Fpu(); return; } if (GetSimulationState() != DropZoneAcquiredState) { ResetAfterDeath(message); return; } } // //--------------------------------- // Make sure we ignore old messages //--------------------------------- // else { Check_Fpu(); return; } // //----------------------------------- // Delete All offensivePlayers //----------------------------------- // DeleteAllOffensivePlayers(); ForceUpdate(); SetSimulationState(VehicleTranslocatedState); if (playerVehicle->GetClassID() == VTVClassID) { VTV *vtv = (VTV*)playerVehicle; Check(vtv); vtv->Reset(message->dropZoneLocation, VTV::RegularReset); } // //--------------------------------------------------- // Always Point vtv in the direction of the scorezone //--------------------------------------------------- // PointVTVTowardGoal(); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // GetPlayer // RPPlayer* RPPlayer::GetPlayer(EntityID playerID) { Check(this); Check(&playerID); // //--------------------------------------------------- // Get the pointer to the RPPlayer from the playerID //--------------------------------------------------- // Check(application); HostManager *host = application->GetHostManager(); Check(host); RPPlayer *rp_player = Cast_Object( RPPlayer*, host->GetEntityPointer(playerID) ); Check(rp_player); Check_Fpu(); return rp_player; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::DeleteAllOffensivePlayers() { VChainIteratorOf iterator(offensivePlayerList); OffensivePlayer *current_player; while ((current_player = iterator.GetCurrent()) != NULL) { Unregister_Object(current_player); delete current_player; } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::CleanUpOffensivePlayers() { VChainIteratorOf iterator(offensivePlayerList); OffensivePlayer *current_player; while ((current_player = iterator.GetCurrent()) != NULL) { Check(current_player); if(Now() - current_player->timeStamp >= 2.0f) { OffensivePlayer *stale_player = iterator.GetCurrent(); Unregister_Object(stale_player); delete stale_player; } else { iterator.Next(); } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::TakeDamageMessageHandler (TakeDamageMessage *message) { Check(this); Check(message); // //------------------------------------------------------- // Scale the damage amount to point loss on this vehicle //------------------------------------------------------- // VTV* our_vtv = (VTV*)playerVehicle; Check(our_vtv); if (GetSimulationState() != MissionEndingState) { Scalar score_loss = message->damageData.damageAmount; if (message->damageData.damageType == Damage::CollisionDamageType) { score_loss *= our_vtv->deathConstant; } ScoreMessage score_message( RPPlayer::ScoreMessageID, sizeof(RPPlayer::ScoreMessageID), DamageScoreLossPointType, -score_loss, GetEntityID() ); Dispatch(&score_message); // //----------------------------------------------------------- // Clean up the list, and look for a player to give points to //----------------------------------------------------------- // CleanUpOffensivePlayers(); VChainIteratorOf iterator(offensivePlayerList); if(iterator.GetCurrent()) { // //-------------------------------------------------------- // Send a score message to the player at the top // of the offensivePlayer list the points for this damage //-------------------------------------------------------- // OffensivePlayer *top_player = iterator.GetCurrent(); RPPlayer *player_points = top_player->offensivePlayer; if ( top_player->deathBonus && top_player->timeStamp < ((RPPlayer*)our_vtv)->lastPerformance && top_player->offensivePlayer != this ) { if (top_player->deathBonus < 0.0f) { score_loss = -score_loss; } ScoreMessage score_message( RPPlayer::ScoreMessageID, sizeof(RPPlayer::ScoreMessage), DamageBonusPointType, score_loss, GetEntityID() ); if (score_loss < 0.0f) { score_message.scoreType = DropZoneHitType; } player_points->Dispatch(&score_message); Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVDamagedMessage scored_message( ownerID, player_points->ownerID, score_loss, score_loss ); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &scored_message ); } } } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::AddOffensivePlayer(OffensivePlayer &offensive_player) { Check(this); Check(&offensive_player); // //---------------------------------------------------------------- // Calculate the deathBonus based on playerType and damageType //---------------------------------------------------------------- // if(offensive_player.damageType == Damage::CollisionDamageType) { offensive_player.deathBonus = 500.0f; } else { offensive_player.deathBonus = 0.0f; } offensivePlayerList.AddValue( &offensive_player, offensive_player.damageType ); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::ScoreMessageHandler(ScoreMessage *message) { Check(this); Check(message); Check(playerVehicle); if (GetSimulationState() == MissionEndingState) { return; } // //------------------------------------------------------------------------- // If this is a score zone message, tell the console (if there is one) that // we scored //------------------------------------------------------------------------- // Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); switch (message->scoreType) { case ScoreZonePointType: { Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVScoredMessage scored_message(ownerID); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &scored_message ); } //------------------------------------- // Inform pilot of score zone entry //------------------------------------- RPPlayer *player = (RPPlayer*)host_manager->GetEntityPointer(message->pointSender); Check(player); if (player->playerType != RunnerPlayerType) { RPStatusMessage *message = new RPStatusMessage(NULL, RPStatusMessage::ScoreZoneMessage, 6.0f); Register_Object(message); AddStatusMessage((StatusMessage *) message); } } break; case DeathBonusPointType: case DropZoneKillType: { //------------------------------------- // Inform pilot of killer's identity //------------------------------------- RPPlayer *killer = (RPPlayer*)host_manager->GetEntityPointer(message->pointSender); Check(killer); RPStatusMessage *message = new RPStatusMessage(killer, RPStatusMessage::DestroyedMessage, 6.0f); Register_Object(message); AddStatusMessage((StatusMessage *) message); } break; } Player::ScoreMessageHandler(message); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::VehicleDeadMessageHandler(VehicleDeadMessage *message) { Check(this); Check(message); if (GetSimulationState() == MissionEndingState) { Check_Fpu(); return; } // //------------------------------------------------------------------------- // If this is not the initial death notice, or we are still looking for our // initial dropzone, let the player handler do its thing //------------------------------------------------------------------------- // if (message->deathCount != -1) { Player::VehicleDeadMessageHandler(message); Check_Fpu(); return; } // //------------------------- // Reset the VTV subsystems //------------------------- // Check(playerVehicle); VTV *vtv = (VTV*) playerVehicle; Check(vtv); if ((playerType == CrusherPlayerType) || (playerType == BlockerPlayerType) ) { vtv->DeathShutdown(VTV::FootballReset); } else { vtv->DeathShutdown(VTV::RegularReset); } // //---------------------------------------------------- // See if any other players get points for this death //---------------------------------------------------- // CleanUpOffensivePlayers(); HostID killer_id = ownerID; VChainIteratorOf iterator(offensivePlayerList); if (iterator.GetCurrent()) { // //---------------------------------------------------- // Yes, send score messages... //---------------------------------------------------- // OffensivePlayer *offensive_player = iterator.GetCurrent(); Check(offensive_player); ScoreMessage score_message( RPPlayer::ScoreMessageID, sizeof(RPPlayer::ScoreMessage), DeathBonusPointType, offensive_player->deathBonus, GetEntityID() ); if (offensive_player->deathBonus < 0.0f) { score_message.scoreType = DropZoneKillType; } RPPlayer *other_player = offensive_player->offensivePlayer; Check(other_player); other_player->Dispatch(&score_message); Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVDamagedMessage scored_message( ownerID, other_player->ownerID, offensive_player->deathBonus, offensive_player->deathBonus ); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &scored_message ); } // //---------------------------------------------------- // ...keep track of the killer... //---------------------------------------------------- // killer_id = other_player->ownerID; // //---------------------------------------------------- // ...and send a notice to the pilot. //---------------------------------------------------- // RPStatusMessage *message = new RPStatusMessage(other_player, RPStatusMessage::DestroyedByMessage, 6.0f); Register_Object(message); AddStatusMessage((StatusMessage *)message); } else { // //---------------------------------------------------- // No, tell the pilot that it was self-induced. //---------------------------------------------------- // RPStatusMessage *message = new RPStatusMessage(NULL, RPStatusMessage::PilotErrorMessage, 6.0f); Register_Object(message); AddStatusMessage((StatusMessage *) message); } // //------------------------------------------------ // Tell the console (if there is one) that we died //------------------------------------------------ // Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVKilledMessage killed_message(ownerID, killer_id); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &killed_message ); } // //------------------------------------------------------------------------ // Send a score message of deathpointloss, and notify ourselves again in 5 // seconds so we can begin looking for the drop zone //------------------------------------------------------------------------ // ScoreMessage score_message( RPPlayer::ScoreMessageID, sizeof(RPPlayer::ScoreMessage), DeathScoreLossPointType, -vtv->deathScoreLoss, GetEntityID() ); Dispatch(&score_message); Time when = Now(); when += 5.0f; message->deathCount = deathCount; application->Post(HighEventPriority, this, message, when); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::ScoreZoneReplyMessageHandler( ScoreZone::ReplyMessage *message ) { Check(this); Check(message); if (GetSimulationState() == MissionEndingState) { Check_Fpu(); return; } // //------------------------------------------------- // Send Score message if score zone was covered //------------------------------------------------- // ScoreMessage score_message( RPPlayer::ScoreMessageID, sizeof(RPPlayer::ScoreMessageID), ScoreZonePointType, message->pointValue, GetEntityID() ); Dispatch(&score_message); // //-------------------------------------------------------------------- // Change the goalEntity to the new sequential scorezone if necessary //-------------------------------------------------------------------- // EntityGroup *score_zone_group = application->GetEntityManager()->FindGroup("ActiveScoreZones"); if(score_zone_group) { ChainIteratorOf iterator(score_zone_group->groupMembers); ScoreZone *score_zone; while ((score_zone = (ScoreZone*) iterator.ReadAndNext()) != NULL) { Check(score_zone); if ( (score_zone->scoreZoneType == LocalSequential) || (score_zone->scoreZoneType == GlobalSequential) ) { goalEntity = score_zone; } } } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::PlayerSimulation(Scalar time_slice) { Check(this); Check(application); Check(application->GetEntityManager()); Check(playerVehicle); // //------------------------------------------------------------------------ // Check for our synchronization signal //------------------------------------------------------------------------ // if ( (GetSimulationState() == MissionStartingState) && ((fadeTimeRemaining - time_slice) <= 0.0f) ) { lastConsoleUpdate = Now(); } if (!goalEntity) { SetGoalToFirstScoreZone(); PointVTVTowardGoal(); } // //------------------------------------------------------------------------ // Call PlayerSimulation //------------------------------------------------------------------------ // Player::PlayerSimulation(time_slice); if ( application->GetApplicationState() != Application::RunningMission && application->GetApplicationState() != Application::EndingMission ) { return; } // //------------------------------------------------------------------------ // Update everybody once per second //------------------------------------------------------------------------ // if (lastPerformance - lastUpdate >= 1.0f) { ForceUpdate(); } // //------------------------------------------------------------------------ // Update the console every 15 seconds //------------------------------------------------------------------------ // if (lastPerformance - lastConsoleUpdate >= 15.0f) { lastConsoleUpdate = lastPerformance; // //--------------------------------------------- // Tell the console (if there is one) our score //--------------------------------------------- // Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); Host *console_host = host_manager->GetConsoleHost(); if (console_host) { Check(console_host); ConsolePlayerVTVScoreUpdateMessage score_message(ownerID, (int)currentScore); application->SendMessage( console_host->GetHostID(), NetworkClient::ConsoleClientID, &score_message ); } } // //------------------------------------------------------------------------ // See if there are any zones to check //------------------------------------------------------------------------ // if ( GetSimulationState() != MissionEndingState && application->GetApplicationState() == Application::RunningMission ) { EntityGroup *score_zone_group = application->GetEntityManager()->FindGroup("ActiveScoreZones"); if(!score_zone_group) { Check_Fpu(); return; } // //---------------------------------- // If VTV is in a BurningState ie. dead // Exit from loop and don't check // score zones //---------------------------------- // VTV *vtv = (VTV*)playerVehicle; Check(vtv); if (vtv->GetSimulationState() == VTV::BurningState) { Check_Fpu(); return; } // //---------------------------------- // Make an iterator and send the // "do I get points" message to // all the active score zones //---------------------------------- // Check(score_zone_group); ChainIteratorOf iterator(score_zone_group->groupMembers); ScoreZone::ProcessScoreZoneRequestMessage message( ScoreZone::ProcessScoreZoneRequestMessageID, sizeof(ScoreZone::ProcessScoreZoneRequestMessage), GetEntityID(), ScoreZoneReplyMessageID, playerVehicle->localOrigin.linearPosition ); ScoreZone *score_zone; while ((score_zone = (ScoreZone*)iterator.ReadAndNext()) != NULL) { score_zone->Dispatch(&message); } // //--------------------------------- // Get Points for speed if // going in the right direction //--------------------------------- // AccumulateSpeedPoints(time_slice); Check_Fpu(); } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int RPPlayer::CalcRanking() { Check(this); Player::CalcRanking(); Check_Fpu(); return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::CalcFootballRanking() { // //--------------------------------------- // Get all players from the Runner group //--------------------------------------- // EntityGroup *runner_group = application->GetEntityManager()->FindGroup("RunnerPlayers"); Check(runner_group); Player *active_runner; // //----------------------------------------------------- // Iterate through the players add to the sorted chain //----------------------------------------------------- // ChainIteratorOf iterator(runner_group->groupMembers); VChainOf player_rank(NULL, False); while ((active_runner = (Player*) iterator.ReadAndNext()) != NULL) { player_rank.AddValue(active_runner, active_runner->currentScore); } int num_runners = iterator.GetSize() - 1; // //------------------------------------------------ // Iterate through the chain assigning the rank //------------------------------------------------ // VChainIteratorOf rank_iterator(player_rank); while ((active_runner = rank_iterator.ReadAndNext()) != NULL) { active_runner->playerRanking = num_runners; --num_runners; } Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RPPlayer::AccumulateSpeedPoints(Scalar time_slice) { Check(this); Scalar compression=1.0f; if(scoreCompression) { Scalar top_score=-1.0f; EntityGroup *player_group = application->GetEntityManager()->FindGroup("Players"); Check(player_group); Player *active_player; // //----------------------------------------------------- // Iterate through the players find top ranked player //----------------------------------------------------- // ChainIteratorOf iterator(player_group->groupMembers); while ((active_player = (Player*) iterator.ReadAndNext()) != NULL) { if (active_player->playerRanking == 0) { top_score = active_player->currentScore; break; } } if (currentScore < (top_score - 400.0f)) { compression *= ( (top_score - currentScore) + 400.0f)/800; } } // //------------------------------------------------------ // Get Points for speed if going in the right direction //------------------------------------------------------ // Check(playerVehicle); Check(goalEntity); Vector3D to_goal, current_heading; VTV *vtv = Cast_Object(VTV*, playerVehicle); to_goal.Subtract( vtv->localOrigin.linearPosition, goalEntity->localOrigin.linearPosition); current_heading = vtv->worldLinearVelocity; Scalar length_to_goal, length_current_heading; length_to_goal = to_goal.LengthSquared(); length_current_heading = current_heading.LengthSquared(); if (length_to_goal > SMALL && length_current_heading > SMALL) { Scalar dot_prod = (to_goal * current_heading) / (Sqrt(length_to_goal) * Sqrt(length_current_heading)); if (dot_prod <= 0.985f) { Scalar speed_bonus = length_current_heading; speed_bonus /= POINTS_SPEED_RATIO; speed_bonus *= time_slice * compression; // //------------------------------------------- // Send a score message with the speed bonus //------------------------------------------- // ScoreMessage score_message( RPPlayer::ScoreMessageID, sizeof(RPPlayer::ScoreMessageID), SpeedBonusPointType, speed_bonus, GetEntityID() ); if (!vtv->insideWorld) { score_message.scoreAward = -speed_bonus; score_message.scoreType = OutOfBoundsType; } Dispatch(&score_message); } } Check_Fpu(); } //############################################################################# // Construction and Destruction // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RPPlayer::RPPlayer( RPPlayer::MakeMessage *creation_message, SharedData &shared_data ): Player(creation_message, shared_data), offensivePlayerList(NULL, 0) { currentScore = 1000.0f; lastConsoleUpdate = Now(); goalEntity = NULL; // //-------------------------------- // Get the info from the mission //-------------------------------- // teamID = creation_message->teamID; scoreCompression = creation_message->scoreCompression; playerType = (PlayerType) creation_message->playerType; Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RPPlayer* RPPlayer::Make(RPPlayer::MakeMessage *creation_message) { return new RPPlayer(creation_message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RPPlayer::~RPPlayer() { Check(this); DeleteAllOffensivePlayers(); Check_Fpu(); } //############################################################################# // Offensive Player // RPPlayer__OffensivePlayer::RPPlayer__OffensivePlayer(RPPlayer *offensive_player, int damage_type, Time time_stamp) { // //----------------------------------------- // Initialize the offensivePlayer fields //----------------------------------------- // offensivePlayer = offensive_player; damageType = damage_type; timeStamp = time_stamp; deathBonus = 0.0f; Check_Fpu(); } //############################################################################# // RP Status message // RPPlayer__StatusMessage::RPPlayer__StatusMessage( RPPlayer *player_involved, int message_type, Scalar display_time, Scalar damage_amount ) : Player__StatusMessage( (Player *) player_involved, message_type, display_time ) { damageAmount = damage_amount; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical RPPlayer::TestInstance() const { return IsDerivedFrom(*GetClassDerivations()); }