| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- /*
- ** 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/cinematicgameobj.cpp $*
- * *
- * $Author:: Tom_s $*
- * *
- * $Modtime:: 10/10/01 11:37a $*
- * *
- * $Revision:: 32 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /*
- ** Includes
- */
- #include "cinematicgameobj.h"
- #include "debug.h"
- #include "animcontrol.h"
- #include "Sound3D.H"
- #include "combat.h"
- #include "pscene.h"
- #include "persistfactory.h"
- #include "combatchunkid.h"
- #include "simpledefinitionfactory.h"
- #include "wwhack.h"
- #include "weapons.h"
- #include "gameobjmanager.h"
- #include "assets.h"
- #include "ccamera.h"
- #include "explosion.h"
- #include "damage.h"
- #include "dynamicanimphys.h"
- #include "wwprofile.h"
- #include "apppackettypes.h"
- /*
- ** CinematicGameObjDef
- */
- DECLARE_FORCE_LINK( Cinematic )
- SimplePersistFactoryClass<CinematicGameObjDef, CHUNKID_GAME_OBJECT_DEF_CINEMATIC> _CinematicGameObjDefPersistFactory;
- DECLARE_DEFINITION_FACTORY(CinematicGameObjDef, CLASSID_GAME_OBJECT_DEF_CINEMATIC, "Cinematic") _CinematicGameObjDefDefFactory;
- CinematicGameObjDef::CinematicGameObjDef( void ) :
- SoundDefID( 0 ),
- AutoFireWeapon( false ),
- DestroyAfterAnimation( true ),
- CameraRelative( false )
- {
- MODEL_DEF_PARAM( CinematicGameObjDef, PhysDefID, "DynamicAnimPhysDef" );
- EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, SoundDefID );
- EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_STRING, SoundBoneName );
- FILENAME_PARAM( CinematicGameObjDef, AnimationName, "Animation", ".W3D" );
- EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_BOOL, AutoFireWeapon );
- EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_BOOL, DestroyAfterAnimation );
- EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_BOOL, CameraRelative );
- }
- uint32 CinematicGameObjDef::Get_Class_ID (void) const
- {
- return CLASSID_GAME_OBJECT_DEF_CINEMATIC;
- }
- const PersistFactoryClass & CinematicGameObjDef::Get_Factory (void) const
- {
- return _CinematicGameObjDefPersistFactory;
- }
- PersistClass * CinematicGameObjDef::Create( void ) const
- {
- CinematicGameObj * obj = new CinematicGameObj;
- obj->Init( *this );
- return obj;
- }
- enum {
- CHUNKID_DEF_PARENT = 418001957,
- CHUNKID_DEF_VARIABLES,
- MICROCHUNKID_DEF_SOUND_DEF_ID = 1,
- MICROCHUNKID_DEF_SOUND_BONE_NAME,
- XXX_MICROCHUNKID_DEF_ANIMATION_NAME,
- MICROCHUNKID_DEF_AUTO_FIRE_WEAPON,
- MICROCHUNKID_DEF_DESTROY_AFTER_ANIMATION,
- MICROCHUNKID_DEF_CAMERA_RELATIVE,
- };
- bool CinematicGameObjDef::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_DEF_PARENT );
- ArmedGameObjDef::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_SOUND_DEF_ID, SoundDefID );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_DEF_SOUND_BONE_NAME, SoundBoneName );
- WRITE_MICRO_CHUNK_WWSTRING( csave, XXX_MICROCHUNKID_DEF_ANIMATION_NAME, AnimationName );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_AUTO_FIRE_WEAPON,AutoFireWeapon );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DESTROY_AFTER_ANIMATION, DestroyAfterAnimation );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_CAMERA_RELATIVE, CameraRelative );
- csave.End_Chunk();
- return true;
- }
- bool CinematicGameObjDef::Load( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_DEF_PARENT:
- ArmedGameObjDef::Load( cload );
- break;
- case CHUNKID_DEF_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_SOUND_DEF_ID, SoundDefID );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_DEF_SOUND_BONE_NAME, SoundBoneName );
- READ_MICRO_CHUNK_WWSTRING( cload, XXX_MICROCHUNKID_DEF_ANIMATION_NAME, AnimationName );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_AUTO_FIRE_WEAPON,AutoFireWeapon );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DESTROY_AFTER_ANIMATION, DestroyAfterAnimation );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_CAMERA_RELATIVE, CameraRelative );
- default:
- Debug_Say(( "Unrecognized CinematicDef Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- default:
- Debug_Say(( "Unrecognized CinematicDef chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- /*
- ** CinematicGameObj
- */
- SimplePersistFactoryClass<CinematicGameObj, CHUNKID_GAME_OBJECT_CINEMATIC> _CinematicGameObjPersistFactory;
- const PersistFactoryClass & CinematicGameObj::Get_Factory (void) const
- {
- return _CinematicGameObjPersistFactory;
- }
- CinematicGameObj::CinematicGameObj() :
- Sound( NULL )
- {
- Set_App_Packet_Type(APPPACKETTYPE_CINEMATIC);
- }
- CinematicGameObj::~CinematicGameObj()
- {
- Set_Sound( 0 );
- COMBAT_SCENE->Remove_From_Dirty_Cull_List( Peek_Physical_Object() );
- }
- /*
- **
- */
- void CinematicGameObj::Init( void )
- {
- Init( Get_Definition() );
- }
- /*
- **
- */
- void CinematicGameObj::Init( const CinematicGameObjDef & definition )
- {
- ArmedGameObj::Init( definition );
- Cinematic_Init();
- }
- void CinematicGameObj::Cinematic_Init( void )
- {
- /*
- ** (gth) cinematic game objects behave like animated terrain so they are in the
- ** terrain collision group
- */
- Peek_Physical_Object()->Set_Collision_Group( PhysicsSceneClass::COLLISION_GROUP_WORLD );
- // COMBAT_SCENE->Add_To_Dirty_Cull_List( Peek_Physical_Object() );
- Set_Sound( Get_Definition().SoundDefID, Get_Definition().SoundBoneName );
- }
- const CinematicGameObjDef & CinematicGameObj::Get_Definition( void ) const
- {
- return (const CinematicGameObjDef &)BaseGameObj::Get_Definition();
- }
- /*
- ** CinematicGameObj Save and Load
- */
- enum {
- CHUNKID_PARENT = 418002008,
- XXXCHUNKID_VARIABLES,
- XXXCHUNKID_ANIM_CONTROL,
- XXXMICROCHUNKID_PHYSICAL_OBJECT = 1,
- };
- bool CinematicGameObj::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_PARENT );
- ArmedGameObj::Save( csave );
- csave.End_Chunk();
- // We don't need to save the sound
- return true;
- }
- bool CinematicGameObj::Load( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_PARENT:
- ArmedGameObj::Load( cload );
- break;
- default:
- Debug_Say(( "Unrecognized Cinematic chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- SaveLoadSystemClass::Register_Post_Load_Callback(this);
- return true;
- }
- void CinematicGameObj::On_Post_Load( void )
- {
- ArmedGameObj::On_Post_Load();
- Cinematic_Init();
- }
- /*
- **
- */
- void CinematicGameObj::Set_Sound( int sound_def_id, const char * bone_name )
- {
- // Stop Old Sound
- if ( Sound != NULL ) {
- Sound->Stop();
- Sound->Attach_To_Object( NULL );
- Sound->Remove_From_Scene();
- Sound->Release_Ref();
- Sound = NULL;
- }
- // Start new Sound
- if ( sound_def_id != 0 ) {
- Sound = WWAudioClass::Get_Instance()->Create_Continuous_Sound( sound_def_id );
- if ( Sound != NULL ) {
- RenderObjClass * model = Peek_Model();
- WWASSERT( model );
- int bone_index = model->Get_Bone_Index( bone_name );
- Sound->Attach_To_Object( Peek_Model(), bone_index );
- Sound->Add_To_Scene( true );
- }
- }
- }
- void CinematicGameObj::Think( void )
- {
- { WWPROFILE( "Cinematic Think" );
- // If auto fire weapon
- if ( Get_Definition().AutoFireWeapon ) {
- PhysicalGameObj * enemy = NULL;
- Vector3 my_pos;
- Get_Position( &my_pos );
- // if any enemies can be found in range
- SLNode<BaseGameObj> *objnode;
- for ( objnode = GameObjManager::Get_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
- PhysicalGameObj *obj = objnode->Data()->As_PhysicalGameObj();
- if ( obj && obj->Peek_Physical_Object() ) { // zones have no phy obj CHANGE THIS
- if ( obj == this ) {
- continue;
- }
- if ( Is_Teammate( obj ) ) {
- continue;
- }
- Vector3 v;
- obj->Get_Position(&v);
- v -= my_pos;
- if ( v.Length() < Get_Weapon()->Get_Range() ) {
- enemy = obj;
- }
- }
- }
- if ( enemy != NULL ) {
- Vector3 enemy_pos;
- enemy->Get_Position( &enemy_pos );
- enemy_pos.Z += 1;
- if ( Set_Targeting( enemy_pos ) == false ) {
- Get_Weapon()->Set_Primary_Triggered( false );
- } else {
- Get_Weapon()->Set_Primary_Triggered( true ); // Fire Primary
- }
- } else {
- Get_Weapon()->Set_Primary_Triggered( false );
- }
- }
- if ( Get_Definition().CameraRelative && COMBAT_CAMERA != NULL ) {
- Matrix3D tm = COMBAT_CAMERA->Get_Transform();
- tm.Rotate_Z( DEG_TO_RADF(90.0) );
- tm.Rotate_Y( DEG_TO_RADF(90.0) );
- Set_Transform( tm );
- }
- }
- ArmedGameObj::Think();
- }
- void CinematicGameObj::Post_Think( void )
- {
- ArmedGameObj::Post_Think();
- WWPROFILE( "Cinematic PostThink" );
- // Animation is handled by the DynamicAnimPhysClass for this class
- WWASSERT(Get_Anim_Control() == NULL);
- if (Get_Definition().DestroyAfterAnimation) {
- PhysClass * pobj = Peek_Physical_Object();
- if (pobj != NULL) {
- DynamicAnimPhysClass * dpobj = pobj->As_DynamicAnimPhysClass();
- if ((dpobj != NULL) &&
- (dpobj->Get_Animation_Manager().Peek_Animation() != NULL) &&
- (dpobj->Get_Animation_Manager().Is_At_Target()) )
- {
- Set_Delete_Pending();
- }
- }
- }
- }
- void CinematicGameObj::Completely_Damaged( const OffenseObjectClass & damager )
- {
- if ( Get_Definition().KilledExplosion != 0 ) {
- Vector3 pos;
- Get_Position(&pos);
- WWASSERT(pos.Is_Valid());// most likely candidate for explosion damage bug....?
- // If the object has a moving bounding box, use its center point for the explosion
- RenderObjClass * model = Peek_Model();
- if (model != NULL) {
- RenderObjClass * bbox = model->Get_Sub_Object_By_Name("BoundingBox");
- if (bbox != NULL) {
- Matrix3D bbox_tm = bbox->Get_Transform();
- bbox_tm.Get_Translation(&pos);
- REF_PTR_RELEASE(bbox);
- }
- }
- ExplosionManager::Create_Explosion_At( Get_Definition().KilledExplosion, pos, damager.Get_Owner() ); // no one gets credit for this
- }
- Set_Delete_Pending();
- }
- float CinematicGameObj::Get_Animation_Length( void )
- {
- float length = 0;
- //
- // Try to get the dynamic anim phys object from the physics object
- //
- PhysClass *phys_obj = Peek_Physical_Object();
- if (phys_obj != NULL) {
- DynamicAnimPhysClass * dynamic_anim_phys = phys_obj->As_DynamicAnimPhysClass();
- if (dynamic_anim_phys != NULL) {
- //
- // Peek at this object's animation
- //
- AnimCollisionManagerClass &anim_mgr = dynamic_anim_phys->Get_Animation_Manager();
- HAnimClass *anim = anim_mgr.Peek_Animation();
- if (anim != NULL) {
- //
- // Return the length of the animation to the caller
- //
- length = anim->Get_Total_Time();
- }
- }
- }
- return length;
- }
- /*
- void
- CinematicGameObj::Import_Creation( BitStreamClass &packet )
- {
- ArmedGameObj::Import_Creation (packet);
- return ;
- }
- */
- void CinematicGameObj::Export_Rare( BitStreamClass &packet )
- {
- ArmedGameObj::Export_Rare( packet );
- StringClass animation_name;
- AnimCollisionManagerClass::AnimModeType anim_mode = AnimCollisionManagerClass::ANIMATE_TARGET;
- //
- // Dig the animation data out of the physics object
- //
- DynamicAnimPhysClass *dynanim = Peek_Physical_Object()->As_DynamicAnimPhysClass();
- if (dynanim != NULL) {
- AnimCollisionManagerClass &anim_mgr = dynanim->Get_Animation_Manager();
- //
- // Get the animation name
- //
- HAnimClass *anim = anim_mgr.Peek_Animation();
- if (anim != NULL) {
- animation_name = anim->Get_Name();
- }
- //
- // Get the animation mode
- //
- anim_mode = anim_mgr.Get_Animation_Mode ();
- }
- //
- // Send the animation data to the client
- //
- packet.Add_Terminated_String( (const char *)animation_name, true );
- packet.Add( anim_mode );
- return ;
- }
- void CinematicGameObj::Import_Rare( BitStreamClass &packet )
- {
- ArmedGameObj::Import_Rare( packet );
- //
- // Get information about the animation
- //
- StringClass animation_name;
- int anim_mode = AnimCollisionManagerClass::ANIMATE_TARGET;
- packet.Get_Terminated_String( animation_name.Get_Buffer( 256 ), 256, true );
- packet.Get( anim_mode );
- //
- // Pass the animation information onto the controller
- //
- DynamicAnimPhysClass *dynanim = Peek_Physical_Object()->As_DynamicAnimPhysClass();
- if (dynanim != NULL) {
- AnimCollisionManagerClass &anim_mgr = dynanim->Get_Animation_Manager();
- anim_mgr.Set_Animation( animation_name );
- anim_mgr.Set_Animation_Mode( (AnimCollisionManagerClass::AnimModeType)anim_mode );
- }
- return ;
- }
|