//===========================================================================// // File: btplayer.cpp // // Project: BattleTech // // Contents: Implementation details for the BT player // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // // //---------------------------------------------------------------------------// // Copyright (C) 1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include #pragma hdrstop #if !defined(BTPLAYER_HPP) # include #endif #if !defined(BTTEAM_HPP) # include #endif #if !defined(BTMSSN_HPP) # include #endif #if !defined(NTTMGR_HPP) # include #endif #if !defined(APP_HPP) # include #endif #if !defined(DROPZONE_HPP) # include #endif #if !defined(MECH_HPP) # include #endif #if !defined(RESOURCE_HPP) # include #endif #if !defined(HOSTMGR_HPP) # include #endif #if !defined(MISSION_HPP) # include #endif // //############################################################################# // Shared data support //############################################################################# // Derivation BTPlayer::ClassDerivations( Player::ClassDerivations, "BTPlayer" ); const Receiver::HandlerEntry BTPlayer::MessageHandlerEntries[]= { MESSAGE_ENTRY(BTPlayer,DropZoneReply), MESSAGE_ENTRY(BTPlayer,VehicleDead), MESSAGE_ENTRY(BTPlayer,Score), MESSAGE_ENTRY(BTPlayer,ScoreInflicted), MESSAGE_ENTRY(BTPlayer,ScoreUpdate) }; BTPlayer::MessageHandlerSet BTPlayer::MessageHandlers( ELEMENTS(BTPlayer::MessageHandlerEntries), BTPlayer::MessageHandlerEntries, Player::MessageHandlers ); BTPlayer::SharedData BTPlayer::DefaultData( BTPlayer::ClassDerivations, BTPlayer::MessageHandlers, Player::AttributeIndex, 1, (Entity::MakeHandler)BTPlayer::Make ); // //############################################################################# // Constructor // // Copies the team name out of the creation message, resolves the owning // BTTeam, caches the mission, and derives the game-mode display / heat-model // flags from the mission's experience level and advanced-damage flag. //############################################################################# // BTPlayer::BTPlayer( MakeMessage *creation_message, SharedData &shared_data ): Player(creation_message, shared_data) { consoleAttached = False; suppressConsole = False; currentScore = 0; deathPending = False; // // Remember our team name from the creation message. // strcpy(teamName, creation_message->teamName); // // Resolve the BTTeam entity that owns this team name. // teamEntity = NULL; EntityGroup *teams = application->GetEntityManager()->FindGroup("Teams"); if (teams) { ChainIteratorOf iterator(teams->groupMembers); BTTeam *team; while ((team = (BTTeam *)iterator.ReadAndNext()) != NULL) { if (strcmp(team->teamName, teamName) == 0) { teamEntity = team; break; } } } freeForAll = True; // // Cache the mission (experience level / advanced-damage source). // BTMission *bt_mission = Cast_Object(BTMission *, application->GetCurrentMission()); btMission = bt_mission; if (GetInstance() == ReplicantInstance) { // // Replicant: driven by console-update messages. // SetPerformance(&BTPlayer::PlayerSimulation); } else { // // Master: derive the game-mode flags from the mission experience // level (novice / standard / veteran / expert) and advanced-damage // technician flag. See BTPLAYER.NOTES.md for the flag mapping. // Check(bt_mission); switch (bt_mission->ExperienceLevel()) { case BTMission::NoviceMode: showDamageReceived = 0; showKills = 0; roleReturnDelay2 = 0; showScore = 0; break; case BTMission::StandardMode: showDamageReceived = 1; showKills = 0; roleReturnDelay2 = 1; showScore = 1; break; case BTMission::VeteranMode: showDamageReceived = 1; showKills = 1; roleReturnDelay2 = 1; showScore = 1; break; case BTMission::ExpertMode: showDamageReceived = 1; showKills = 1; roleReturnDelay2 = 0; showScore = 1; break; } showDamageInflicted = bt_mission->AdvancedDamageOn(); roleReturnDelay = bt_mission->AdvancedDamageOn(); roleClassIndex = bt_mission->ExperienceLevel(); } killCount = 0; padScore = 0; objectiveMech = NULL; lastPerformance = lastConsoleUpdate = lastUpdate; Check_Fpu(); } // //############################################################################# //############################################################################# // BTPlayer::~BTPlayer() { Check(this); Check_Fpu(); } // //############################################################################# // Make //############################################################################# // BTPlayer* BTPlayer::Make(MakeMessage *creation_message) { return new BTPlayer(creation_message); } // //############################################################################# //############################################################################# // Logical BTPlayer::TestInstance() const { return IsDerivedFrom(ClassDerivations); } // //############################################################################# // GetExperienceLevel //############################################################################# // Enumeration BTPlayer::GetExperienceLevel() { Check(this); Check(btMission); return Cast_Object(BTMission *, btMission)->ExperienceLevel(); } // //############################################################################# // DropZoneReplyMessageHandler The spawn / respawn handshake: when the drop // zone replies with our spawn location we create (or, on respawn, reset) the // player's vehicle there and bind it to us. // // The mech placement / respawn-reset tail depends on the Mech subsystem // (Mech::MechClassID / Mech::Reset), which is not yet reconstructed; the // dispatch skeleton below halts at CreatePlayerVehicle -> Mech::Make on the // first (fresh-drop) reply. See BTPLAYER.NOTES.md. //############################################################################# // void BTPlayer::DropZoneReplyMessageHandler(DropZone__ReplyMessage *message) { Check(this); Check(message); if (!playerVehicle) { CreatePlayerVehicle(message->dropZoneLocation); InitializePlayerLink(); // // A piloted mech runs the combat PlayerSimulation and is a scoring // player; a camera-ship observer runs CameraShipSimulation and never // ranks. (Vehicle-class dispatch + mech placement deferred with the // Mech subsystem.) // AlwaysExecute(); deathCount = 0; } else if (deathCount == message->deathCount) { if (GetSimulationState() == MissionEndingState) { Check_Fpu(); return; } // // Respawn: reset the existing dead mech in place (deferred with the // Mech subsystem). // } Check_Fpu(); } // //############################################################################# // CreatePlayerVehicle Build the player's mech from the mission game-model // resource and bind it as the viewpoint entity. (An observer player gets a // MUNGA camera ship from the base Player::CreatePlayerVehicle instead.) // // Constructs the Mech::MakeMessage and hands it to MakeAndLinkViewpointEntity, // which routes through the registry to Mech::Make -> the Mech ctor (the mech // subsystem, not yet reconstructed -- current boot frontier). //############################################################################# // void BTPlayer::CreatePlayerVehicle(Origin mech_location) { Check(this); Check(application); ResourceFile *resources = application->GetResourceFile(); Check(resources); Check_Pointer(playerMission->GetGameModel()); HostManager *host_manager = application->GetHostManager(); Check(host_manager); // // Make any MUNGA-level vehicle (a camera ship for an observer player). // Player::CreatePlayerVehicle(mech_location); // // If the player still has no vehicle, build him a mech and link to it. // if (!playerVehicle) { ResourceDescription *mech_res = resources->FindResourceDescription( playerMission->GetGameModel(), ResourceDescription::ModelListResourceType ); Check(mech_res); mech_res->Lock(); Mech::MakeMessage create_player( Mech::MakeMessageID, sizeof(Mech::MakeMessage), EntityID(host_manager->GetLocalHostID()), (Entity::ClassID)MechClassID, EntityID::Null, mech_res->resourceID, Mech::DefaultFlags, mech_location, Motion::Identity, Motion::Identity, playerMission->GetBadgeName(), playerMission->GetColorName(), ((BTMission *)playerMission)->GetPatchName() ); mech_res->Unlock(); playerVehicle = application->MakeAndLinkViewpointEntity(&create_player); Register_Object(playerVehicle); } } void BTPlayer::InitializePlayerLink() { Fail("BTPlayer::InitializePlayerLink -- btplayer.cpp not yet reconstructed"); } // //############################################################################# // Scoring / death handlers -- exercised in combat, not during bring-up boot. //############################################################################# // void BTPlayer::VehicleDeadMessageHandler(VehicleDeadMessage *) { Fail("BTPlayer::VehicleDeadMessageHandler -- btplayer.cpp not yet reconstructed"); } void BTPlayer::ScoreMessageHandler(ScoreMessage *) { Fail("BTPlayer::ScoreMessageHandler -- btplayer.cpp not yet reconstructed"); } void BTPlayer::ScoreInflictedMessageHandler(ScoreMessage *) { Fail("BTPlayer::ScoreInflictedMessageHandler -- btplayer.cpp not yet reconstructed"); } void BTPlayer::ScoreUpdateMessageHandler(ScoreMessage *) { Fail("BTPlayer::ScoreUpdateMessageHandler -- btplayer.cpp not yet reconstructed"); } // //############################################################################# // PlayerSimulation -- console-update performance (not yet reconstructed). // The constructor installs this as the replicant Performance; its body is // exercised only on a networked console-driven run. //############################################################################# // void BTPlayer::PlayerSimulation(Scalar) { Fail("BTPlayer::PlayerSimulation -- btplayer.cpp not yet reconstructed"); }