/* ** 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 : Renegade * * * * $Archive:: /Commando/Code/Combat/effectrecycler.cpp $* * * * Original Author:: Greg Hjelstrom * * * * $Author:: Greg_h $* * * * $Modtime:: 7/11/01 5:15p $* * * * $Revision:: 3 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * EffectRecyclerClass::EffectRecyclerClass -- constructor * * EffectRecyclerClass::~EffectRecyclerClass -- destructor * * EffectRecyclerClass::Reset -- releases all resources * * EffectRecyclerClass::Spawn_Effect -- Spawn a timed effect into the combat scene * * EffectRecyclerClass::Spawn_Effect -- spawn an effect into the combat scene * * EffectRecyclerClass::Object_Removed_From_Scene -- physobserver interface, reclaim our obj * * EffectRecyclerClass::internal_get_tdeco -- internally recycle or allocate a tdeco * * EffectRecyclerClass::internal_get_model -- recycle or allocate a render object * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "effectrecycler.h" #include "timeddecophys.h" #include "rendobj.h" #include "combat.h" #include "assetmgr.h" #include "htree.h" #include "hanim.h" #include "part_emt.h" /*********************************************************************************************** * EffectRecyclerClass::EffectRecyclerClass -- constructor * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * *=============================================================================================*/ EffectRecyclerClass::EffectRecyclerClass(void) { } /*********************************************************************************************** * EffectRecyclerClass::~EffectRecyclerClass -- destructor * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * *=============================================================================================*/ EffectRecyclerClass::~EffectRecyclerClass(void) { Reset(); } /*********************************************************************************************** * EffectRecyclerClass::Reset -- releases all resources * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/8/2001 gth : Created. * * 7/11/2001 gth : Created. * *=============================================================================================*/ void EffectRecyclerClass::Reset(void) { ModelRecycler.Reset(); InactiveTDecos.Reset_List(); } /*********************************************************************************************** * EffectRecyclerClass::Spawn_Effect -- Spawn a timed effect into the combat scene * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/8/2001 gth : Created. * *=============================================================================================*/ void EffectRecyclerClass::Spawn_Effect(TimedDecorationPhysDefClass * def,const Matrix3D & tm) { Spawn_Effect(def->Get_Model_Name(),tm,def->Get_Lifetime()); } /*********************************************************************************************** * EffectRecyclerClass::Spawn_Effect -- spawn an effect into the combat scene * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/8/2001 gth : Created. * *=============================================================================================*/ void EffectRecyclerClass::Spawn_Effect(const char * robj_name,const Matrix3D & tm,float time) { // allocate/recycle the render object RenderObjClass * model = internal_get_model(robj_name,tm); if (model != NULL) { // allocate/recycle a TDeco TimedDecorationPhysClass * tdeco = internal_get_tdeco(); if ((time == -1.0f) && (model->Class_ID() == RenderObjClass::CLASSID_PARTICLEEMITTER)) { ParticleEmitterClass * emitter = (ParticleEmitterClass *)model; time = emitter->Get_Lifetime(); } // configure and add to the scene tdeco->Set_Model(model); tdeco->Set_Lifetime(time); tdeco->Enable_Dont_Save(true); tdeco->Enable_Is_Pre_Lit(true); tdeco->Set_Collision_Group(UNCOLLIDEABLE_GROUP); tdeco->Set_Observer(this); COMBAT_SCENE->Add_Dynamic_Object(tdeco); tdeco->Set_Transform(tm); REF_PTR_RELEASE(model); REF_PTR_RELEASE(tdeco); } } /*********************************************************************************************** * EffectRecyclerClass::Object_Removed_From_Scene -- physobserver interface, reclaim our objec * * * * Reclaims the model and tdeco when they expire. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/8/2001 gth : Created. * *=============================================================================================*/ void EffectRecyclerClass::Object_Removed_From_Scene(PhysClass * observed_obj) { WWASSERT(observed_obj != NULL); WWASSERT(observed_obj->As_TimedDecorationPhysClass() != NULL); WWASSERT(observed_obj->Peek_Model() != NULL); TimedDecorationPhysClass * tdeco = observed_obj->As_TimedDecorationPhysClass(); RenderObjClass * model = tdeco->Peek_Model(); ModelRecycler.Return_Render_Object(model); tdeco->Set_Model(NULL); InactiveTDecos.Add(tdeco); } /*********************************************************************************************** * EffectRecyclerClass::internal_get_tdeco -- internally recycle or allocate a tdeco * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/8/2001 gth : Created. * *=============================================================================================*/ TimedDecorationPhysClass * EffectRecyclerClass::internal_get_tdeco(void) { if (InactiveTDecos.Is_Empty()) { return NEW_REF(TimedDecorationPhysClass,()); } else { return InactiveTDecos.Remove_Head(); } } /*********************************************************************************************** * EffectRecyclerClass::internal_get_model -- recycle or allocate a render object * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 5/8/2001 gth : Created. * *=============================================================================================*/ RenderObjClass * EffectRecyclerClass::internal_get_model(const char * robj_name,const Matrix3D & tm) { RenderObjClass * model = ModelRecycler.Get_Render_Object(robj_name,tm); if ((model != NULL) && (model->Get_HTree() != NULL)) { /* ** Auto play an anim if we find it */ StringClass anim_name; anim_name.Format( "%s.%s", model->Get_HTree()->Get_Name(), model->Get_HTree()->Get_Name() ); WWASSERT(WW3DAssetManager::Get_Instance() != NULL); HAnimClass * anim = WW3DAssetManager::Get_Instance()->Get_HAnim( anim_name ); if ( anim != NULL ) { model->Set_Animation( anim, 0, RenderObjClass::ANIM_MODE_ONCE ); anim->Release_Ref(); } } return model; }