/* ** 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 . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Combat * * * * $Archive:: /Commando/Code/Combat/specialeffectsgameobj.cpp $* * * * Author:: Patrick Smith * * * * $Modtime:: 1/15/02 2:33p $* * * * $Revision:: 6 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "specialeffectsgameobj.h" #include "combatchunkid.h" #include "wwaudio.h" #include "hanim.h" #include "assetmgr.h" #include "wwhack.h" #include "persistfactory.h" #include "simpledefinitionfactory.h" #include "chunkio.h" #include "rendobj.h" #include "timemgr.h" #include "debug.h" #include "phys.h" #include "combat.h" #include "wwprofile.h" DECLARE_FORCE_LINK (SpecialEffects) /////////////////////////////////////////////////////////////////////////// // Persist and Editable framework support /////////////////////////////////////////////////////////////////////////// SimplePersistFactoryClass _SpecialEffectsGameObjPersistFactory; SimplePersistFactoryClass _SpecialEffectsGameObjDefPersistFactory; DECLARE_DEFINITION_FACTORY (SpecialEffectsGameObjDef, CLASSID_GAME_OBJECT_DEF_SPECIAL_EFFECTS, "Special Effects") _SpecialEffectsGameObjDefDefFactory; /////////////////////////////////////////////////////////////////////////// // Constants /////////////////////////////////////////////////////////////////////////// enum { CHUNKID_DEF_PARENT = 0x09010212, CHUNKID_DEF_VARIABLES, VARID_DEF_ANIMATION_NAME = 1, VARID_DEF_SOUNDID, }; enum { CHUNKID_PARENT = 0x09010236, CHUNKID_VARIABLES, VARID_LIFE_REMAINING = 1, VARID_IS_INITIALIZED }; /////////////////////////////////////////////////////////////////////////// // // SpecialEffectsGameObjDef // /////////////////////////////////////////////////////////////////////////// SpecialEffectsGameObjDef::SpecialEffectsGameObjDef (void) : SoundDefID (0) { MODEL_DEF_PARAM(SpecialEffectsGameObjDef, PhysDefID, "TimedDecorationPhysDef"); EDITABLE_PARAM (SpecialEffectsGameObjDef, ParameterClass::TYPE_STRING, AnimationName); EDITABLE_PARAM (SpecialEffectsGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, SoundDefID); return ; } /////////////////////////////////////////////////////////////////////////// // // ~SpecialEffectsGameObjDef // /////////////////////////////////////////////////////////////////////////// SpecialEffectsGameObjDef::~SpecialEffectsGameObjDef (void) { return ; } /////////////////////////////////////////////////////////////////////////// // // Get_Class_ID // /////////////////////////////////////////////////////////////////////////// uint32 SpecialEffectsGameObjDef::Get_Class_ID (void) const { return CLASSID_GAME_OBJECT_DEF_SPECIAL_EFFECTS; } /////////////////////////////////////////////////////////////////////////// // // Create // /////////////////////////////////////////////////////////////////////////// PersistClass * SpecialEffectsGameObjDef::Create (void) const { SpecialEffectsGameObj *obj = new SpecialEffectsGameObj; obj->Init (*this); return obj; } /////////////////////////////////////////////////////////////////////////// // // Save // /////////////////////////////////////////////////////////////////////////// bool SpecialEffectsGameObjDef::Save (ChunkSaveClass &csave) { csave.Begin_Chunk (CHUNKID_DEF_PARENT); PhysicalGameObjDef::Save (csave); csave.End_Chunk (); csave.Begin_Chunk (CHUNKID_DEF_VARIABLES); Save_Variables (csave); csave.End_Chunk (); return true; } /////////////////////////////////////////////////////////////////////////// // // Load // /////////////////////////////////////////////////////////////////////////// bool SpecialEffectsGameObjDef::Load (ChunkLoadClass &cload) { while (cload.Open_Chunk ()) { switch(cload.Cur_Chunk_ID ()) { case CHUNKID_DEF_PARENT: PhysicalGameObjDef::Load (cload); break; case CHUNKID_DEF_VARIABLES: Load_Variables (cload); break; default: Debug_Say (("Unrecognized SpecialEffectsGameObjDef chunk ID\n")); break; } cload.Close_Chunk (); } return true; } /////////////////////////////////////////////////////////////////////////// // // Save_Variables // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObjDef::Save_Variables (ChunkSaveClass &csave) { WRITE_MICRO_CHUNK_WWSTRING (csave, VARID_DEF_ANIMATION_NAME, AnimationName); WRITE_MICRO_CHUNK (csave, VARID_DEF_SOUNDID, SoundDefID); return ; } /////////////////////////////////////////////////////////////////////////// // // Load_Variables // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObjDef::Load_Variables (ChunkLoadClass &cload) { while (cload.Open_Micro_Chunk()) { switch (cload.Cur_Micro_Chunk_ID()) { READ_MICRO_CHUNK_WWSTRING (cload, VARID_DEF_ANIMATION_NAME, AnimationName); READ_MICRO_CHUNK (cload, VARID_DEF_SOUNDID, SoundDefID); default: Debug_Say (("Unrecognized SpecialEffectsGameObjDef Variable chunkID %d\n", cload.Cur_Micro_Chunk_ID ())); break; } cload.Close_Micro_Chunk (); } return ; } /////////////////////////////////////////////////////////////////////////// // // Get_Factory // /////////////////////////////////////////////////////////////////////////// const PersistFactoryClass & SpecialEffectsGameObjDef::Get_Factory (void) const { return _SpecialEffectsGameObjDefPersistFactory; } /* ** ** Start of SpecialEffectsGameObj ** */ /////////////////////////////////////////////////////////////////////////// // // SpecialEffectsGameObj // /////////////////////////////////////////////////////////////////////////// SpecialEffectsGameObj::SpecialEffectsGameObj (void) : LifeRemaining (-1.0F), IsInitialized (false) { return ; } /////////////////////////////////////////////////////////////////////////// // // ~SpecialEffectsGameObj // /////////////////////////////////////////////////////////////////////////// SpecialEffectsGameObj::~SpecialEffectsGameObj (void) { return ; } /////////////////////////////////////////////////////////////////////////// // // Get_Factory // /////////////////////////////////////////////////////////////////////////// const PersistFactoryClass & SpecialEffectsGameObj::Get_Factory (void) const { return _SpecialEffectsGameObjPersistFactory; } //////////////////////////////////////////////////////////////// // // Init // //////////////////////////////////////////////////////////////// void SpecialEffectsGameObj::Init( void ) { Init( Get_Definition() ); } /////////////////////////////////////////////////////////////////////////// // // Init // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObj::Init (const SpecialEffectsGameObjDef &definition) { PhysicalGameObj::Init (definition); // // Make sure collisions are turned off on this effect // PhysClass *phys_obj = Peek_Physical_Object(); if (phys_obj != NULL) { phys_obj->Set_Collision_Group( UNCOLLIDEABLE_GROUP ); } return ; } /////////////////////////////////////////////////////////////////////////// // // Get_Definition // /////////////////////////////////////////////////////////////////////////// const SpecialEffectsGameObjDef & SpecialEffectsGameObj::Get_Definition (void) const { return (const SpecialEffectsGameObjDef &)BaseGameObj::Get_Definition(); } /////////////////////////////////////////////////////////////////////////// // // Save // /////////////////////////////////////////////////////////////////////////// bool SpecialEffectsGameObj::Save (ChunkSaveClass & csave) { csave.Begin_Chunk (CHUNKID_PARENT); PhysicalGameObj::Save (csave); csave.End_Chunk (); csave.Begin_Chunk (CHUNKID_VARIABLES); Save_Variables (csave); csave.End_Chunk (); return true; } /////////////////////////////////////////////////////////////////////////// // // Load // /////////////////////////////////////////////////////////////////////////// bool SpecialEffectsGameObj::Load (ChunkLoadClass &cload) { while (cload.Open_Chunk ()) { switch(cload.Cur_Chunk_ID ()) { case CHUNKID_PARENT: PhysicalGameObj::Load (cload); break; case CHUNKID_VARIABLES: Load_Variables (cload); break; default: Debug_Say (("Unrecognized SpecialEffectsGameObj chunk ID\n")); break; } cload.Close_Chunk (); } return true; } /////////////////////////////////////////////////////////////////////////// // // Do_Effect // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObj::Do_Effect (void) { // // Make sure we have a render object // RenderObjClass *model = Peek_Model (); WWASSERT (model != NULL); if (model != NULL) { // // Should we play an animation? // const StringClass &anim_name = Get_Definition ().AnimationName; if (anim_name.Get_Length () > 0) { // // Load the animation // HAnimClass *animation = WW3DAssetManager::Get_Instance ()->Get_HAnim (anim_name); if (animation != NULL) { LifeRemaining = animation->Get_Total_Time (); model->Set_Animation (animation, 0, RenderObjClass::ANIM_MODE_ONCE); REF_PTR_RELEASE(animation); } } // // Should we play a sound? // if (Get_Definition ().SoundDefID > 0) { WWAudioClass::Get_Instance()->Create_Instant_Sound (Get_Definition ().SoundDefID, Get_Transform ()); } } return ; } /////////////////////////////////////////////////////////////////////////// // // Save_Variables // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObj::Save_Variables (ChunkSaveClass &csave) { WRITE_MICRO_CHUNK (csave, VARID_LIFE_REMAINING, LifeRemaining); WRITE_MICRO_CHUNK (csave, VARID_IS_INITIALIZED, IsInitialized); return ; } /////////////////////////////////////////////////////////////////////////// // // Load_Variables // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObj::Load_Variables (ChunkLoadClass &cload) { while (cload.Open_Micro_Chunk()) { switch (cload.Cur_Micro_Chunk_ID()) { READ_MICRO_CHUNK (cload, VARID_LIFE_REMAINING, LifeRemaining); READ_MICRO_CHUNK (cload, VARID_IS_INITIALIZED, IsInitialized); default: Debug_Say (("Unrecognized SpecialEffectsGameObj Variable chunkID %d\n", cload.Cur_Micro_Chunk_ID ())); break; } cload.Close_Micro_Chunk (); } return ; } /////////////////////////////////////////////////////////////////////////// // // Think // /////////////////////////////////////////////////////////////////////////// void SpecialEffectsGameObj::Think (void) { WWPROFILE( "SpecialEffects Think" ); // // Kick off the special effect // if (IsInitialized == false) { Do_Effect (); IsInitialized = true; } // // Check to see if we should make ourselves go away // if (LifeRemaining >= 0) { LifeRemaining -= TimeManager::Get_Frame_Seconds (); if (LifeRemaining <= 0) { Set_Delete_Pending (); } } return ; }