| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Combat/combat.cpp $*
- * *
- * $Author:: Bhayes $*
- * *
- * $Modtime:: 2/17/02 10:25a $*
- * *
- * $Revision:: 265 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "combat.h"
- #include "ccamera.h"
- #include "gameobjmanager.h"
- #include "input.h"
- #include "weaponmanager.h"
- #include "wwprofile.h"
- #include "scripts.h"
- #include "pscene.h"
- #include "damage.h"
- #include "ww3d.h"
- #include "assets.h"
- #include "timemgr.h"
- #include "soldier.h"
- #include "SoundScene.H"
- #include "weapons.h"
- #include "vehicle.h"
- #include "bones.h"
- #include "humanstate.h"
- #include "surfaceeffects.h"
- #include "debug.h"
- #include "backgroundmgr.h"
- #include "cover.h"
- #include "spawn.h"
- #include "vehiclephys.h"
- #include "building.h"
- #include "objectives.h"
- #include "conversationmgr.h"
- #include "bullet.h"
- #include "dazzle.h"
- #include "messagewindow.h"
- #include "hudinfo.h"
- #include "weathermgr.h"
- #include "thread.h"
- #include "savegame.h"
- #include "assetdep.h"
- #include "saveloadstatus.h"
- #include <stdio.h>
- #include "soundenvironment.h"
- #include "weaponview.h"
- #include "hud.h"
- #include "mapmgr.h"
- #include "gametype.h"
- #include "staticnetworkobject.h"
- #include "diaglog.h"
- #include "combatdazzle.h"
- #include "ffactorylist.h"
- #include "definitionfactorymgr.h"
- #include "definitionfactory.h"
- #include "globalsettings.h"
- #include "dx8wrapper.h"
- #include "except.h"
- #include "cheatmgr.h"
- #include "systeminfolog.h"
- #include "assetstatus.h"
- #include "wwmemlog.h"
- #include "unitcoordinationzonemgr.h"
- #include "fastallocator.h"
- #include "screenfademanager.h"
- #include "animatedsoundmgr.h"
- #include "render2dsentence.h"
- #include "stylemgr.h"
- #include "translatedb.h"
- #include "string_ids.h"
- const int DEFAULT_MAX_SHADOWS = 4;
- /*
- **
- */
- CCameraClass * CombatManager::MainCamera = NULL;
- SimpleSceneClass * CombatManager::BackgroundScene = NULL;
- SoundEnvironmentClass * CombatManager::SoundEnvironment = NULL;
- DazzleLayerClass * CombatManager::DazzleLayer = NULL;
- GameObjReference CombatManager::TheStar;
- bool CombatManager::IsStarDeterminingTarget = true;
- //bool CombatManager::IAmServer = true;
- //bool CombatManager::IAmClient = true;
- bool CombatManager::IAmServer = false;
- bool CombatManager::IAmClient = false;
- bool CombatManager::IAmOnlyClient = false;
- bool CombatManager::IAmOnlyServer = false;
- int CombatManager::MyId = 0;
- int CombatManager::SyncTime = 0;
- CombatNetworkHandlerClass * CombatManager::NetworkHandler = NULL;
- CombatMiscHandlerClass * CombatManager::MiscHandler = NULL;
- MessageWindowClass * CombatManager::MessageWindow = NULL;
- bool CombatManager::EnableSkeletonSliderDemo = false;
- int CombatManager::DifficultyLevel = 1;
- bool CombatManager::AutoTransitions = true;
- int CombatManager::StarDamageDirection = 0;
- bool CombatManager::AreObserversActive = true;
- bool CombatManager::FirstPerson = true;
- bool CombatManager::FirstPersonDefault = true;
- bool CombatManager::IsFirstLoad = false;
- int CombatManager::StarKillerID = 0;
- bool CombatManager::IsGamePaused = false;
- bool CombatManager::IsLevelInitialized = false;
- StringClass CombatManager::StartScript;
- StringClass CombatManager::RespawnScript;
- bool CombatManager::AutosaveRequested = false;
- DWORD CombatManager::LastRoundTripPingMs = 0;
- DWORD CombatManager::AvgRoundTripPingMs = 0;
- bool CombatManager::FriendlyFirePermitted = false;
- bool CombatManager::BeaconPlacementEndsGame = false;
- bool CombatManager::HitReticleEnabled = true;
- bool CombatManager::IsGameplayPermitted = false;
- int CombatManager::CombatMode = CombatManager::COMBAT_MODE_NONE;
- int CombatManager::ReloadCount = 0;
- StringClass CombatManager::LastLSDName;
- int CombatManager::LoadProgress;
- bool CombatManager::MultiplayRenderingAllowed = true;
- static PhysicsSceneClass * GameScene = NULL;
- /*
- **
- */
- void CombatManager::Init( bool render_available )
- {
- // Debug_Say(("CombatManager::Init\n"));
- IsGameplayPermitted=false;
- ConversationMgrClass::Initialize ();
- MessageWindow = new MessageWindowClass;
- MessageWindow->Initialize ();
- ScriptManager::Init();
- BonesManager::Init();
- ArmorWarheadManager::Init();
- CCameraClass::Init();
- SurfaceEffectsManager::Init();
- ObjectiveManager::Init();
- CombatSoundManager::Init();
- // create THE camera
- MainCamera = new CCameraClass();
- // create the dazzle layer
- if (render_available) {
- DazzleLayer = new DazzleLayerClass;
- DazzleRenderObjClass::Set_Current_Dazzle_Layer(DazzleLayer);
- } else {
- DazzleRenderObjClass::Set_Current_Dazzle_Layer(NULL);
- }
- // Pass the main camera onto the 3D audio library as the
- // listener's position.
- SoundSceneClass *sound_scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
- if (sound_scene != NULL) {
- sound_scene->Attach_Listener_To_Obj (MainCamera);
- }
- HUDClass::Init(render_available);
- ScreenFadeManager::Init();
- FirstPerson = FirstPersonDefault;
- }
- /*
- **
- */
- void CombatManager::Shutdown( void )
- {
- // Debug_Say(("CombatManager::Shutdown\n"));
- ScreenFadeManager::Shutdown();
- HUDClass::Shutdown();
- if ( GameScene != NULL ) {
- // Debug_Say(( "Releasing the PScene with %d Refs\n", GameScene->Num_Refs() ));
- GameScene->Release_Ref();
- GameScene = NULL;
- }
- //
- // Reset the audio library
- //
- if (WWAudioClass::Get_Instance () != NULL) {
- SoundSceneClass *sound_scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
- if (sound_scene != NULL) {
- sound_scene->Attach_Listener_To_Obj (NULL);
- }
- }
- if (DazzleLayer != NULL) {
- delete DazzleLayer;
- DazzleLayer = NULL;
- DazzleRenderObjClass::Set_Current_Dazzle_Layer(NULL);
- }
- MainCamera->Release_Ref();
- MainCamera = NULL;
- CombatSoundManager::Shutdown();
- ObjectiveManager::Shutdown();
- SurfaceEffectsManager::Shutdown();
- CCameraClass::Shutdown();
- ArmorWarheadManager::Shutdown();
- BonesManager::Shutdown();
- ScriptManager::Shutdown();
- if (MessageWindow != NULL) {
- MessageWindow->Shutdown ();
- delete MessageWindow;
- MessageWindow = NULL;
- }
- ConversationMgrClass::Shutdown ();
- // Debug_Say(( "Combat Shutdown %d refs\n", RefCountClass::Total_Refs() ));
- }
- void CombatManager::Scene_Init( void )
- {
- // Game scene is where the main action occurs!
- GameScene = new PhysicsSceneClass;
- GameScene->Set_Ambient_Light(Vector3(0.55f,0.55f,0.55f));
- GameScene->Set_Ambient_Light(Vector3(1,1,1));
- GameScene->Set_Fog_Color(Vector3(0.6f,0.6f,0.6f)); //Vector3(80.0f/255.0f,130.0f/255.0f,180.0f/255.0f));
- // Do all 'Enable_All's, then all 'Disable_All's, then the individual pairs
- COMBAT_SCENE->Enable_All_Collision_Detections( DEFAULT_COLLISION_GROUP );
- COMBAT_SCENE->Enable_All_Collision_Detections( BULLET_COLLISION_GROUP );
- COMBAT_SCENE->Enable_All_Collision_Detections( TERRAIN_COLLISION_GROUP );
- COMBAT_SCENE->Enable_All_Collision_Detections( PhysicsSceneClass::COLLISION_GROUP_WORLD );
- COMBAT_SCENE->Enable_All_Collision_Detections( SOLDIER_GHOST_COLLISION_GROUP );
- COMBAT_SCENE->Enable_All_Collision_Detections( SOLDIER_COLLISION_GROUP );
- COMBAT_SCENE->Disable_All_Collision_Detections( UNCOLLIDEABLE_GROUP );
- COMBAT_SCENE->Disable_All_Collision_Detections( TERRAIN_ONLY_COLLISION_GROUP );
- COMBAT_SCENE->Disable_All_Collision_Detections( TERRAIN_AND_BULLET_COLLISION_GROUP );
- COMBAT_SCENE->Disable_All_Collision_Detections( BULLET_ONLY_COLLISION_GROUP );
- COMBAT_SCENE->Enable_Collision_Detection( TERRAIN_ONLY_COLLISION_GROUP, TERRAIN_COLLISION_GROUP );
- COMBAT_SCENE->Enable_Collision_Detection( TERRAIN_AND_BULLET_COLLISION_GROUP, TERRAIN_COLLISION_GROUP );
- COMBAT_SCENE->Enable_Collision_Detection( TERRAIN_AND_BULLET_COLLISION_GROUP, BULLET_COLLISION_GROUP );
- COMBAT_SCENE->Disable_Collision_Detection( BULLET_COLLISION_GROUP, BULLET_COLLISION_GROUP );
- COMBAT_SCENE->Enable_Collision_Detection( BULLET_ONLY_COLLISION_GROUP, BULLET_COLLISION_GROUP );
- COMBAT_SCENE->Disable_Collision_Detection( PhysicsSceneClass::COLLISION_GROUP_WORLD,PhysicsSceneClass::COLLISION_GROUP_WORLD );
- COMBAT_SCENE->Disable_Collision_Detection( SOLDIER_GHOST_COLLISION_GROUP, SOLDIER_COLLISION_GROUP );
- COMBAT_SCENE->Disable_Collision_Detection( SOLDIER_GHOST_COLLISION_GROUP, SOLDIER_GHOST_COLLISION_GROUP );
- }
- /*
- ** Note: The editor calls these per level functions only once per program execution.
- ** If you have code that requires a init/shutdown/reset call with each level load,
- ** notify Pat so he can add those calls manually
- **
- */
- void CombatManager::Pre_Load_Level( bool render_available )
- {
- MultiplayRenderingAllowed = true;
- if ( !IS_MISSION && !I_Am_Server() ) {
- MultiplayRenderingAllowed = false;
- }
- HUDClass::Enable( true );
- HUDClass::Reset();
- IsGamePaused = false;
- GameObjObserverManager::Reset();
- CoverManager::Init();
- GameObjManager::Init();
- BulletManager::Init();
- cEncoderList::Clear_Entries();
- cPacket::Init_Encoder();
- BackgroundScene = NEW_REF (SimpleSceneClass, ());
- SoundEnvironment = NEW_REF (SoundEnvironmentClass, ());
- BackgroundMgrClass::Init (BackgroundScene, SoundEnvironment, render_available);
- WeatherMgrClass::Init (SoundEnvironment);
- WeaponViewClass::Init();
- SmartGameObj::Set_Global_Sight_Range_Scale( 1.0f );
- // SoundSystem::Set_Global_Listener_Scale( 1.0f );
- //
- // Map initialization (temporary -- until its more data driven)
- //
- /*MapMgrClass::Set_Map_Texture ("L1-MAP.TGA");
- MapMgrClass::Set_Map_Center (Vector2 (308.0F, 414.0F));
- MapMgrClass::Set_Map_Scale (Vector2 (0.53F, 0.54F));
- MapMgrClass::Cloud_All_Cells ();*/
- ScreenFadeManager::Enable_Letterbox( 0, 0 );
- ScreenFadeManager::Set_Screen_Overlay_Opacity( 0, 0 );
- HUDInfo::Set_HUD_Help_Text( L"" ); // Clear text
- }
- bool _preload_assets;
- StringClass _load_map_name;
- static class LoadThreadClass : public ThreadClass
- {
- public:
- LoadThreadClass(const char *thread_name = "Game loader thread") : ThreadClass(thread_name, &Exception_Handler) {}
- void Thread_Function() {
- CombatManager::Set_Load_Progress( 0 );
- WWMEMLOG(MEM_GAMEDATA);
- WWLOG_PREPARE_TIME_AND_MEMORY("Game loader thread");
- #ifndef PARAM_EDITING_ON
- // Tell the datasafe to expect calls from this thread now.
- GenericDataSafeClass::Set_Preferred_Thread(GetCurrentThreadId());
- #endif // PARAM_EDITING_ON
- CombatManager::Inc_Load_Progress();
- // Reload the definition databases (to support level-specific temp ddb's)
- INIT_STATUS("Free definition databases");
- DefinitionMgrClass::Free_Definitions();
- WWLOG_INTERMEDIATE("Free definitions");
- INIT_STATUS("Load definition databases");
- SaveGameManager::Load_Definitions();
- WWLOG_INTERMEDIATE("Load definitions");
- CombatManager::Inc_Load_Progress();
- //
- // Make sure the animated-sound system is setup. This needs
- // to be done after the definition databases are loaded...
- //
- AnimatedSoundMgrClass::Initialize ();
- StringClass filename_to_load( _load_map_name, true );
- StringClass lsd_filename( _load_map_name,true );
- // Prep the level loading
- INIT_STATUS("Pre Load level");
- PlayerInfoLog::Set_Current_Map_Name(_load_map_name);
- SaveGameManager::Pre_Load_Game(_load_map_name, filename_to_load, lsd_filename);
- CombatManager::Set_Last_LSD_Name( lsd_filename );
- WWLOG_INTERMEDIATE("Preload game");
- CombatManager::Inc_Load_Progress();
- //
- // Preload the assets
- //
- if ( _preload_assets ) {
- INIT_STATUS("Preload assets");
- AssetDependencyManager::Load_Always_Assets();
- WWLOG_INTERMEDIATE("Preload always assets");
- CombatManager::Inc_Load_Progress();
- AssetDependencyManager::Load_Level_Assets( lsd_filename );
- WWLOG_INTERMEDIATE("Preload level assets");
- } else {
- CombatManager::Inc_Load_Progress();
- }
- CombatManager::Inc_Load_Progress();
- // Now load the level
- INIT_STATUS("Load level");
- SaveGameManager::Load_Game( filename_to_load );
- WWLOG_INTERMEDIATE("Load game");
- CombatManager::Inc_Load_Progress();
- }
- } thread;
- void CombatManager::Load_Level_Threaded( const char * map_name, bool preload_assets )
- {
- //
- // Turn off music and sound effects while loading
- //
- IsLevelInitialized = false;
- WWAudioClass::Get_Instance ()->Enable_New_Sounds (false);
- _preload_assets = preload_assets;
- _load_map_name = map_name;
- WWASSERT(!thread.Is_Running());
- thread.Execute();
- }
- bool CombatManager::Is_Load_Level_Complete( void )
- {
- ThreadClass::Sleep_Ms(50);
- return (thread.Is_Running() == false);
- }
- bool CombatManager::Is_Loading_Level( void )
- {
- return (thread.Is_Running());
- }
- /*
- ** Note: The editor calls these per level functions only once per program execution.
- ** If you have code that requires a init/shutdown/reset call with each level load,
- ** notify Pat so he can add those calls manually
- **
- */
- void CombatManager::Post_Load_Level( void )
- {
- // Dont reset SyncTime. Level from the editor should have it at 0, and levels from
- // the game need it set to continue cinematics
- // SyncTime = 0;
- CombatMode = COMBAT_MODE_NONE;
- Input::Flush();
- HitReticleEnabled = true; // Default for on when you start each level
- Clear_Star_Damage_Direction();
- #if 0
- // Re-init all objects loaded from editor
- if ( CombatManager::Is_First_Load() ) {
- Debug_Say(( "Re-Initing all game objects\n" ));
- GameObjManager::Init_All();
- }
- #endif
- //
- // Build network wrappers for every static anim object in the level
- //
- StaticNetworkObjectClass::Generate_Static_Network_Objects ();
- // Debug code to create a definition
- #if 0
- DefinitionFactoryClass * def_factory = (DefinitionFactoryClass *)DefinitionFactoryMgrClass::Find_Factory( CLASSID_GLOBAL_SETTINGS_DEF_HUMAN_ANIM_OVERRIDE );
- if ( def_factory != NULL ) {
- HumanAnimOverrideDef * def = (HumanAnimOverrideDef *)def_factory->Create();
- if ( def != NULL ) {
- def->Set_Name( "HAO Test" );
- def->Set_ID (DefinitionMgrClass::Get_New_ID (def->Get_Class_ID ()));
- def->WalkEmptyHands = "H_A_432A";
- def->RunEmptyHands = "H_A_J43B";
- DefinitionMgrClass::Register_Definition( def );
- }
- }
- #endif
- if (IsLevelInitialized == false && TheStar != NULL) {
- IsLevelInitialized = true;
- //
- // Turn music and sound effects back on...
- //
- WWAudioClass::Get_Instance ()->Enable_New_Sounds (true);
- }
- //
- // Generate the unit coordination zones
- //
- UnitCoordinationZoneMgr::Build_Zones ();
- return ;
- }
- /*
- ** Note: The editor calls these per level functions only once per program execution.
- ** If you have code that requires a init/shutdown/reset call with each level load,
- ** notify Pat so he can add those calls manually
- **
- */
- void CombatManager::Unload_Level( void )
- {
- // Display please wait screen.....
- Render2DSentenceClass backdropText;
- backdropText.Set_Texture_Size_Hint( 256 );
- FontCharsClass *font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_BIG_TXT );
- if (font != NULL) {
- backdropText.Set_Font( font );
- WideStringClass wide_str = TRANSLATE( IDS_MP_LOADING );
- backdropText.Build_Sentence( wide_str );
- Vector2 extents = backdropText.Get_Text_Extents( wide_str );
- float x = (Render2DClass::Get_Screen_Resolution().Right - extents.X) / 2.0f;
- float y = (Render2DClass::Get_Screen_Resolution().Bottom - extents.Y) / 2.0f;
- backdropText.Set_Location( Vector2( (int)x, (int)y ) );
- backdropText.Draw_Sentence( 0xFF00FF00 ); // Green
- WW3D::Begin_Render( true, true, Vector3(0.0f,0.0f,0.0f), NULL);
- backdropText.Render();
- WW3D::End_Render();
- }
- WWLOG_PREPARE_TIME_AND_MEMORY("Unload level");
- WWDEBUG_SAY(("CombatManager::Unload_Level\n"));
- SystemInfoLog::Set_State_Exiting();
- WWLOG_INTERMEDIATE("SystemInfoLog::Set_State_Exiting()");
- // Don't log load-on-demands after the game is over
- AssetStatusClass::Peek_Instance()->Enable_Load_On_Demand_Reporting(false);
- WWLOG_INTERMEDIATE("AssetStatusClass::Peek_Instance()->Enable_Load_On_Demand_Reporting(false)");
- //
- // Free the static anim phys object network wrappers
- //
- StaticNetworkObjectClass::Free_Static_Network_Objects ();
- WWLOG_INTERMEDIATE("StaticNetworkObjectClass::Free_Static_Network_Objects ()");
- WeaponViewClass::Shutdown();
- WWLOG_INTERMEDIATE("WeaponViewClass::Shutdown()");
- GameObjManager::Shutdown();
- WWLOG_INTERMEDIATE("GameObjManager::Shutdown()");
- CoverManager::Shutdown();
- WWLOG_INTERMEDIATE("CoverManager::Shutdown()");
- BulletManager::Shutdown();
- WWLOG_INTERMEDIATE("BulletManager::Shutdown()");
- ObjectiveManager::Reset();
- WWLOG_INTERMEDIATE("ObjectiveManager::Reset()");
- WeatherMgrClass::Shutdown();
- WWLOG_INTERMEDIATE("WeatherMgrClass::Shutdown()");
- BackgroundMgrClass::Shutdown();
- WWLOG_INTERMEDIATE("BackgroundMgrClass::Shutdown()");
- REF_PTR_RELEASE (SoundEnvironment);
- WWLOG_INTERMEDIATE("REF_PTR_RELEASE (SoundEnvironment)");
- REF_PTR_RELEASE (BackgroundScene);
- WWLOG_INTERMEDIATE("REF_PTR_RELEASE (BackgroundScene)");
- WW3DAssetManager::Get_Instance()->Free_Assets(); // Free all assets
- WWLOG_INTERMEDIATE("WW3DAssetManager::Get_Instance()->Free_Assets()");
- WWLOG_INTERMEDIATE("Delete factories");
- //
- // Kill the background music and flush the cache
- //
- if (WWAudioClass::Get_Instance () != NULL) {
- WWAudioClass::Get_Instance ()->Set_Background_Music (NULL);
- WWAudioClass::Get_Instance ()->Flush_Cache ();
- }
- WWLOG_INTERMEDIATE("Flush audio cache");
- SystemInfoLog::Reset_State();
- WWLOG_INTERMEDIATE("SystemInfoLog::Reset_State()");
- if (MessageWindow != NULL) {
- MessageWindow->Clear();
- MessageWindow->Clear_Log();
- }
- //
- // Shutdown the animated-sound system
- //
- AnimatedSoundMgrClass::Shutdown();
- WWLOG_INTERMEDIATE("AnimatedSoundMgrClass::Shutdown");
- return ;
- }
- /*
- **
- */
- PhysicsSceneClass * CombatManager::Get_Scene( void )
- {
- return PhysicsSceneClass::Get_Instance();
- }
- /*
- ** Note: Generate_Control and Think are separated because network update needs
- ** to happen in-between them.
- */
- /*
- **
- */
- void CombatManager::Generate_Control( void )
- {
- WWPROFILE( "Generate Control" );
- // First, generate input control for all necessary game objects and
- // possibly send those control to the server
- GameObjManager::Generate_Control();
- }
- /*
- **
- */
- void CombatManager::Handle_Input()
- {
- if ( Input::Get_State( INPUT_FUNCTION_FIRST_PERSON_TOGGLE ) ) {
- Set_First_Person( !Is_First_Person() );
- if ( COMBAT_STAR ) {
- Vector3 pos;
- COMBAT_STAR->Get_Position( &pos );
- DIAG_LOG(( "SWPE", "%1.2f; %1.2f; %1.2f; %s ", pos.X, pos.Y, pos.Z, Is_First_Person() ? "First" : "Third" ));
- }
- }
- }
- /*
- **
- */
- void CombatManager::Think()
- {
- SyncTime += (int)((TimeManager::Get_Frame_Seconds() * 1000.0f) + 0.5f);
- WWPROFILE( "CombatManager Think" );
- IsGameplayPermitted=NetworkHandler->Is_Gameplay_Permitted();
- { WWPROFILE( "Input" );
- Handle_Input();
- }
- // GroupControllerManager::Update();
- //
- // Display debug boxes for the coordinate zones as necessary
- //
- if ( SoldierGameObj::Is_Ghost_Collision_Debug_Display_Enabled() ) {
- UnitCoordinationZoneMgr::Display_Debug_Boxes();
- }
- { WWPROFILE( "Bullets" );
- BulletManager::Update();
- }
- ObjectiveManager::Update( TimeManager::Get_Frame_Seconds() );
- // Now, Process all objects logically
- ConversationMgrClass::Think();
- { WWPROFILE( "Game Obj Think" );
- GameObjManager::Think();
- // Now, Process all objects physically
- }{ WWPROFILE( "Scene" );
- COMBAT_SCENE->Update( TimeManager::Get_Frame_Seconds(), 0 );
- }{ WWPROFILE( "Star" );
- Update_Star();
- // In normal mode, the camera must think before Post_Think, since the
- // camera update calls Set_Targeting on the star, which must feed Update_Animation
- }{ WWPROFILE( "Camera 1" );
- if ( !MainCamera->Is_Using_Host_Model() ) {
- MainCamera->Update();
- }
- // Now, Post Process all objects logically
- }{ WWPROFILE( "Post Think" );
- GameObjManager::Post_Think();
- }
- // In host_model mode, the camera must think after Post_Think, so the host model has
- // a chance to determine where the camera should be
- if ( MainCamera->Is_Using_Host_Model() ) {
- MainCamera->Update();
- }
- // The targeting comes from the update weapons in the post_think
- Update_Star_Targeting();
- Do_Skeleton_Slider_Demo();
- { WWPROFILE( "Message Window" );
- MessageWindow->On_Frame_Update();
- }
- SpawnManager::Update();
- { WWPROFILE( "Sound Environment" );
- if ( SoundEnvironment != NULL ) {
- SoundEnvironment->Update (COMBAT_SCENE, MainCamera);
- }
- }
- { WWPROFILE( "Background" );
- BackgroundMgrClass::Update (COMBAT_SCENE, MainCamera);
- }
- { WWPROFILE( "Weather" );
- WeatherMgrClass::Update (COMBAT_SCENE, MainCamera);
- }
- HUDClass::Think();
- WeaponViewClass::Think();
- ScreenFadeManager::Think();
- }
- /*
- **
- */
- void CombatManager::Render()
- {
- if ( COMBAT_STAR != NULL ) {
- MultiplayRenderingAllowed = true;
- }
- if ( MultiplayRenderingAllowed ) {
- SystemInfoLog::Record_Frame();
- {
- WWPROFILE( "Camera Shakes" );
- COMBAT_SCENE->Apply_Camera_Shakes (*MainCamera);
- }
- DazzleRenderObjClass::Install_Dazzle_Visibility_Handler(&_TheCombatDazzleHandler);
- {
- WWPROFILE( "Combat Render BG" );
- WW3D::Render (BackgroundScene, MainCamera);
- }
- {
- WWPROFILE( "Combat Render FG" );
- WW3D::Render(COMBAT_SCENE, MainCamera);
- }
- {
- WWPROFILE( "DazzleRenderer" );
- DazzleLayerClass * dlayer = COMBAT_DAZZLE_LAYER;
- if (dlayer != NULL) {
- dlayer->Render(COMBAT_CAMERA);
- }
- }
- DazzleRenderObjClass::Install_Dazzle_Visibility_Handler(NULL);
- HUDClass::Render();
- ScreenFadeManager::Render();
- }
- }
- /*
- **
- */
- enum {
- CHUNKID_THE_STAR = 916991712,
- CHUNKID_FIRST_LOAD,
- CHUNKID_NOT_FIRST_LOAD, // Delete this one, ( and change default to false )
- CHUNKID_VARIABLES,
- CHUNKID_CCAMERA,
- MICROCHUNKID_FIRST_LOAD = 1,
- MICROCHUNKID_DIFFICULTY_LEVEL = 2,
- MICROCHUNKID_SYNC_TIME = 3,
- MICROCHUNKID_START_SCRIPT,
- MICROCHUNKID_RESPAWN_SCRIPT,
- MICROCHUNKID_RELOAD_COUNT,
- MICROCHUNKID_CHEAT_HISTORY,
- MICROCHUNKID_FIRST_PERSON,
- };
- bool CombatManager::Save( ChunkSaveClass &csave )
- {
- csave.Begin_Chunk( CHUNKID_THE_STAR );
- TheStar.Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_VARIABLES );
- bool first_load = !Are_Observers_Active();
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_FIRST_LOAD, first_load );
- if ( !first_load ) {
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DIFFICULTY_LEVEL, DifficultyLevel );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_FIRST_PERSON, FirstPerson );
- }
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_SYNC_TIME, SyncTime );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_START_SCRIPT, StartScript );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_RESPAWN_SCRIPT, RespawnScript );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_RELOAD_COUNT, ReloadCount );
- #ifndef PARAM_EDITING_ON
- int cheat_history = CheatMgrClass::Get_Instance()->Get_History();
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_CHEAT_HISTORY, cheat_history );
- #endif //PARAM_EDITING_ON
- csave.End_Chunk();
- if ( COMBAT_CAMERA != NULL ) {
- csave.Begin_Chunk( CHUNKID_CCAMERA );
- COMBAT_CAMERA->Save( csave );
- csave.End_Chunk();
- }
- return true;
- }
- bool CombatManager::Load( ChunkLoadClass &cload )
- {
- ReloadCount = 0; // Legacy
- IsFirstLoad = true; // Default
- int legacy_dificulty_level = DifficultyLevel;
- int cheat_history = 0;
- FirstPerson = FirstPersonDefault;
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_THE_STAR:
- TheStar.Load( cload );
- break;
- case CHUNKID_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_FIRST_LOAD, IsFirstLoad );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DIFFICULTY_LEVEL, DifficultyLevel );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_SYNC_TIME, SyncTime );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_START_SCRIPT, StartScript );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_RESPAWN_SCRIPT, RespawnScript );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_RELOAD_COUNT, ReloadCount );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_CHEAT_HISTORY, cheat_history );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_FIRST_PERSON, FirstPerson );
- default:
- Debug_Say(( "Unrecognized CombatManager variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- case CHUNKID_CCAMERA:
- if ( COMBAT_CAMERA != NULL ) {
- COMBAT_CAMERA->Load( cload );
- }
- break;
- default:
- Debug_Say(( "Unrecognized CombatManager chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- if ( IsFirstLoad ) {
- DifficultyLevel = legacy_dificulty_level;
- ReloadCount = 0;
- CheatMgrClass::Get_Instance()->Reset_History();
- } else {
- ReloadCount++; // Count another load!
- CheatMgrClass::Get_Instance()->Set_History( cheat_history );
- CheatMgrClass::Get_Instance()->Update_History();
- }
- return true;
- }
- /*
- **
- */
- bool CombatManager::Can_Damage(ArmedGameObj * p_armed_damager, PhysicalGameObj * p_phys_victim)
- {
- if (NetworkHandler != NULL) {
- return NetworkHandler->Can_Damage(p_armed_damager, p_phys_victim);
- } else {
- return true;
- }
- }
- float CombatManager::Get_Damage_Factor(ArmedGameObj * p_armed_damager, PhysicalGameObj * p_phys_victim)
- {
- if (NetworkHandler != NULL) {
- return NetworkHandler->Get_Damage_Factor(p_armed_damager, p_phys_victim);
- } else {
- return 1.0f;
- }
- }
- void CombatManager::On_Soldier_Kill(SoldierGameObj * p_soldier, SoldierGameObj * p_victim)
- {
- WWASSERT(p_soldier != NULL);
- WWASSERT(p_victim != NULL);
- if (NetworkHandler != NULL) {
- NetworkHandler->On_Soldier_Kill(p_soldier, p_victim);
- }
- }
- void CombatManager::On_Soldier_Death(SoldierGameObj * p_soldier)
- {
- WWASSERT(p_soldier != NULL);
- if (NetworkHandler != NULL) {
- NetworkHandler->On_Soldier_Death(p_soldier);
- }
- }
- bool CombatManager::Is_Gameplay_Permitted(void)
- {
- if (NetworkHandler == NULL) {
- return true;
- } else {
- return IsGameplayPermitted;
- // return NetworkHandler->Is_Gameplay_Permitted();
- }
- }
- /*
- ** Misc Handler
- */
- void CombatManager::Mission_Complete( bool success )
- {
- if (MiscHandler != NULL) {
- MiscHandler->Mission_Complete( success );
- }
- }
- void CombatManager::Star_Killed( void )
- {
- if (MiscHandler != NULL) {
- MiscHandler->Star_Killed();
- }
- }
- /*
- **
- */
- void CombatManager::Set_Camera_Profile( const char * profile_name )
- {
- if ( profile_name == NULL ) {
- COMBAT_CAMERA->Use_Default_Profile();
- } else {
- COMBAT_CAMERA->Use_Profile( profile_name );
- }
- }
- /*
- **
- */
- void CombatManager::Set_The_Star( SoldierGameObj *target, bool is_star_determining_target )
- {
- if ( TheStar != target ) {
- HUDClass::Reset(); // Reset the HUD (clear damage and powerups)
- }
- TheStar = target;
- IsStarDeterminingTarget = is_star_determining_target;
- if ( target != NULL ) {
- COMBAT_CAMERA->Force_Heading( target->Get_Facing() );
- }
- HUDClass::Force_Weapon_Chart_Update();
- WeaponViewClass::Reset();
- if (IsLevelInitialized == false) {
- IsLevelInitialized = true;
- //
- // Turn music and sound effects back on...
- //
- WWAudioClass::Get_Instance ()->Enable_New_Sounds (true);
- }
- }
- /*
- **
- */
- void CombatManager::Update_Star( void )
- {
- SoldierGameObj * star = COMBAT_STAR;
- if ( star == NULL ) {
- return;
- }
- if ( star->Is_Destroyed() ) {
- Set_Combat_Mode( COMBAT_MODE_CORPSE );
- } else if ( star->Is_Dead() ) {
- Set_Combat_Mode( COMBAT_MODE_DIEING );
- } else if ( star->Get_Profile_Vehicle() != NULL ) {
- Set_Combat_Mode( COMBAT_MODE_IN_VEHICLE );
- } else if ( star->Is_Sniping() ) {
- Set_Combat_Mode( COMBAT_MODE_SNIPING );
- } else if ( star->Use_Ladder_View() ) {
- Set_Combat_Mode( COMBAT_MODE_ON_LADDER );
- } else if ( Is_First_Person() ) {
- Set_Combat_Mode( COMBAT_MODE_FIRST_PERSON );
- } else {
- Set_Combat_Mode( COMBAT_MODE_THIRD_PERSON );
- }
- Update_Combat_Mode();
- //
- // Update the map
- //
- Vector3 star_pos;
- star->Get_Position (&star_pos);
- MapMgrClass::Clear_Cloud_Cell (star_pos);
- return ;
- }
- void CombatManager::Update_Star_Targeting( void )
- {
- WWPROFILE( "Targeting" );
- SmartGameObj * star = NULL;
- if ( COMBAT_STAR != NULL ) {
- SoldierGameObj * soldier = COMBAT_STAR;
- WWASSERT(soldier != NULL);
- star = soldier;
- if ( soldier->Get_Vehicle() ) {
- star = soldier->Get_Vehicle();
- }
- // Now, if the star has a weapon, gather the information needing to be displayed
- // such as where the bullets will hit, what we are targeting, distance, etc.
- HUDInfo::Set_Weapon_Target_Object( NULL );
- WeaponClass * weapon = star->Get_Weapon();
- if ( weapon ) {
- WWPROFILE( "Display_Targeting" );
- weapon->Display_Targeting();
- }
- }
- }
- bool CombatManager::Is_In_Camera_Frustrum(Vector3 & position)
- {
- WWASSERT(COMBAT_CAMERA != NULL);
- Vector3 projected_mid_point;
- bool is_visible = (COMBAT_CAMERA->Project(projected_mid_point, position) == CameraClass::INSIDE_FRUSTUM);
- return is_visible;
- }
- void CombatManager::Do_Skeleton_Slider_Demo( void )
- {
- if (( EnableSkeletonSliderDemo == false ) ||
- ( COMBAT_CAMERA->Is_2D_Targeting() == false )) {
- return;
- }
- if ( COMBAT_STAR != NULL ) {
- Vector2 sliders = COMBAT_CAMERA->Get_Camera_Target_2D_Offset();
- // Slide is 0-1, height * widht should be -scale - scale
- sliders.X = (sliders.X - 0.5f) * 2;
- sliders.Y = (sliders.Y - 0.5f) * -2;
- float scale = 1;
- float height = sliders.Y * scale;
- float width = sliders.X * scale;
- // Debug_Say(( "Height %f, width %f\n", height, width ));
- COMBAT_STAR->Adjust_Skeleton( height, width );
- }
- }
- /*
- **
- */
- void Vehicle_Panic( VehicleGameObj * vehicle )
- {
- VehiclePhysClass * rbody = vehicle->Peek_Vehicle_Phys();
- if (rbody != NULL) {
- #if 1
- // Try to put the vehicle up-right in its current position
- Matrix3D tm = rbody->Get_Transform();
- Vector3 position;
- Vector3 forward;
- tm.Get_Translation(&position);
- tm.Get_X_Vector(&forward);
- if (forward.Z > 0.707f) {
- tm.Get_Z_Vector(&forward);
- }
- forward.Z = 0.0f;
- position.Z += 3.0f;
- Matrix3D new_tm;
- new_tm.Obj_Look_At(position,position+forward,0.0f);
- rbody->Set_Transform(new_tm);
- #endif
- }
- }
- /*
- ** Combat Mode Management
- */
- void CombatManager::Set_Combat_Mode( int mode )
- {
- // I don't know how to handle loading a saved game in cinematics, so postpone
- // this mode change until the camera is not host controlled?
- if ( COMBAT_CAMERA && COMBAT_CAMERA->Is_Using_Host_Model() ) {
- return;
- }
- if ( mode != CombatMode ) {
- //Debug_Say(( "Switching CombatMode to %d\n", mode ));
- // When changing to or from ladder, lerp
- if ( ( CombatMode == COMBAT_MODE_ON_LADDER ) || ( mode == COMBAT_MODE_ON_LADDER ) ) {
- COMBAT_CAMERA->Set_Lerp_Time( 0.5f );
- }
- CombatMode = mode;
- // Pause game in single player corpse mode
- // IsGamePaused = (CombatMode == COMBAT_MODE_CORPSE) && IS_SOLOPLAY;
- SoldierGameObj * star = COMBAT_STAR;
- switch ( CombatMode ) {
- case COMBAT_MODE_NONE:
- break;
- case COMBAT_MODE_FIRST_PERSON:
- COMBAT_CAMERA->Set_Is_Star_Sniping( false );
- COMBAT_CAMERA->Use_Profile( "First_Person" );
- COMBAT_CAMERA->Set_Profile_Distance( 0 );
- star->Peek_Model()->Set_Hidden( true );
- WeaponViewClass::Enable( true );
- break;
- case COMBAT_MODE_ON_LADDER:
- case COMBAT_MODE_THIRD_PERSON:
- star->Peek_Model()->Set_Hidden( false );
- COMBAT_CAMERA->Set_Is_Star_Sniping( false );
- COMBAT_CAMERA->Use_Default_Profile();
- WeaponViewClass::Enable( false );
- break;
- case COMBAT_MODE_SNIPING:
- COMBAT_CAMERA->Set_Is_Star_Sniping( true );
- star->Peek_Model()->Set_Hidden( true );
- COMBAT_CAMERA->Use_Profile( "Sniper" );
- COMBAT_CAMERA->Set_Profile_Height( star->Get_Weapon_Height() );
- COMBAT_CAMERA->Set_Profile_Distance( -star->Get_Weapon_Length() );
- COMBAT_CAMERA->Enable_2D_Targeting( false );
- WeaponViewClass::Enable( false );
- break;
- case COMBAT_MODE_IN_VEHICLE:
- {
- VehicleGameObj * vehicle = star->Get_Profile_Vehicle();
- WWASSERT( vehicle );
- COMBAT_CAMERA->Set_Is_Star_Sniping( false );
- if ( vehicle->Get_Profile() != NULL ) {
- COMBAT_CAMERA->Use_Profile( vehicle->Get_Profile() );
- } else {
- COMBAT_CAMERA->Use_Default_Profile();
- }
- WeaponViewClass::Enable( false );
- }
- break;
- case COMBAT_MODE_DIEING:
- star->Peek_Model()->Set_Hidden( false );
- COMBAT_CAMERA->Set_Is_Star_Sniping( false );
- COMBAT_CAMERA->Use_Profile( "Death" );
- COMBAT_CAMERA->Set_Lerp_Time( 0.5f );
- WeaponViewClass::Enable( false );
- break;
- case COMBAT_MODE_CORPSE:
- break;
- case COMBAT_MODE_SNAP_SHOT:
- break;
- default:
- Debug_Say(( "Bad CombatMode %d\n", CombatMode ));
- CombatMode = COMBAT_MODE_NONE;
- break;
- }
- }
- }
- void CombatManager::Update_Combat_Mode( void )
- {
- SoldierGameObj * star = COMBAT_STAR;
- Vector3 pos;
- star->Get_Position( &pos );
- COMBAT_CAMERA->Set_Anchor_Position( pos );
- //XXX
- //COMBAT_CAMERA->Enable_2D_Targeting(true);
- switch ( CombatMode ) {
- case COMBAT_MODE_NONE:
- break;
- case COMBAT_MODE_FIRST_PERSON:
- star->Peek_Model()->Set_Hidden( true ); // Putting it here, because vehicles are turning it back on
- COMBAT_CAMERA->Set_Profile_Height( star->Get_Weapon_Height() ); // This is every frame for crouching
- // COMBAT_CAMERA->Enable_2D_Targeting( Input::Get_State(INPUT_FUNCTION_CURSOR_TARGETING) );
- COMBAT_CAMERA->Enable_2D_Targeting( false );
- break;
- case COMBAT_MODE_ON_LADDER:
- case COMBAT_MODE_THIRD_PERSON:
- COMBAT_CAMERA->Enable_2D_Targeting( Input::Get_State(INPUT_FUNCTION_CURSOR_TARGETING ) );
- if ( star->Is_On_Ladder() ) {
- COMBAT_CAMERA->Force_Heading( star->Get_Facing() );
- }
- break;
- case COMBAT_MODE_SNIPING:
- COMBAT_CAMERA->Set_Profile_Height( star->Get_Weapon_Height() ); // This is every frame for crouching
- break;
- case COMBAT_MODE_IN_VEHICLE:
- {
- VehicleGameObj * vehicle = star->Get_Profile_Vehicle();
- WWASSERT( vehicle );
- #ifdef WWDEBUG
- if ( Input::Get_State( INPUT_FUNCTION_PANIC ) ) {
- Vehicle_Panic( vehicle );
- }
- #endif
- Vector3 pos;
- vehicle->Get_Position( &pos );
- COMBAT_CAMERA->Set_Anchor_Position( pos );
- // bool target_2d = ( !vehicle->Use_2D_Aiming() ^ Input::Get_State(INPUT_FUNCTION_CURSOR_TARGETING) ^ VehicleGameObj::Is_Target_Steering() );
- bool target_2d = (Input::Get_State(INPUT_FUNCTION_CURSOR_TARGETING) ^ VehicleGameObj::Is_Target_Steering() );
- // This can be used to always for the V key down for vehicles
- if ( VehicleGameObj::Get_Camera_Locked_To_Turret() ) {
- target_2d = !target_2d;
- }
- if ( !vehicle->Use_2D_Aiming() ) {
- target_2d = true;
- }
- if ( vehicle->Get_Gunner() == COMBAT_STAR ) {
- target_2d = true;
- }
- if ( target_2d ) {
- COMBAT_CAMERA->Enable_2D_Targeting( false );
- } else {
- COMBAT_CAMERA->Enable_2D_Targeting( true );
- // Lateral velocity offset camera code
- float desired_heading = vehicle->Get_Facing();;
- VehiclePhysClass * vehiclephys = vehicle->Peek_Physical_Object()->As_VehiclePhysClass();
- if (vehiclephys != NULL) {
- Vector3 vel,localvel;
- vehiclephys->Get_Velocity(&vel);
- Matrix3D invtm;
- vehiclephys->Get_Transform().Get_Orthogonal_Inverse(invtm);
- Matrix3D::Rotate_Vector(invtm,vel,&localvel);
- // float lateralvel = localvel.Y;
- float heading_offset = WWMath::Atan2(localvel.Y,localvel.X);
- heading_offset = WWMath::Clamp(heading_offset,DEG_TO_RADF(-45.0f),DEG_TO_RADF(45.0f));
- float offset_scale = localvel.X / 5.0f;
- offset_scale = WWMath::Clamp(offset_scale,0.0f,1.0f);
- heading_offset *= offset_scale;
- desired_heading += heading_offset;
- }
- COMBAT_CAMERA->Force_Heading( desired_heading );
- COMBAT_CAMERA->Set_Tilt( 0 );
- }
- }
- break;
- case COMBAT_MODE_DIEING:
- // Make the camera look towards the star killer
- if ( StarKillerID != 0 ) {
- PhysicalGameObj * killer = GameObjManager::Find_PhysicalGameObj( StarKillerID );
- if ( killer ) {
- Vector3 star_pos;
- Vector3 killer_pos;
- COMBAT_STAR->Get_Position( &star_pos );
- killer->Get_Position( &killer_pos );
- Vector3 dif = killer_pos - star_pos;
- float heading = WWMath::Atan2(dif.Y,dif.X);
- COMBAT_CAMERA->Force_Heading( heading );
- }
- }
- break;
- case COMBAT_MODE_CORPSE:
- break;
- case COMBAT_MODE_SNAP_SHOT:
- break;
- }
- }
- void CombatManager::Register_Star_Killer( ArmedGameObj * killer )
- {
- if ( killer != NULL ) {
- StarKillerID = killer->Get_ID();
- } else {
- StarKillerID = 0;
- }
- }
|