| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884 |
- /*
- ** 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/powerup.cpp $*
- * *
- * $Author:: Byon_g $*
- * *
- * $Modtime:: 12/17/01 10:57a $*
- * *
- * $Revision:: 93 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "powerup.h"
- #include "debug.h"
- #include "combat.h"
- #include "phys.h"
- #include "persistfactory.h"
- #include "combatchunkid.h"
- #include "simpledefinitionfactory.h"
- #include "wwhack.h"
- #include "weaponbag.h"
- #include "damage.h"
- #include "gameobjmanager.h"
- #include "colmath.h"
- #include "movephys.h"
- #include "wwaudio.h"
- #include "audiblesound.h"
- #include "hanim.h"
- #include "timemgr.h"
- #include "assetmgr.h"
- #include "animcontrol.h"
- #include "soldier.h"
- #include "wwprofile.h"
- #include "objlibrary.h"
- #include "gameobjobserver.h"
- #include "diaglog.h"
- #include "weaponmanager.h"
- #include "weapons.h"
- #include "hud.h"
- #include "playerdata.h"
- #include "physinttest.h"
- #include "encyclopediamgr.h"
- #include "vehicle.h"
- #include "combatmaterialeffectmanager.h"
- #include "transitioneffect.h"
- #include "apppackettypes.h"
- #include "hudinfo.h"
- #include "string_ids.h"
- #include "translatedb.h"
- /*
- ** PowerUpGameObjDef
- */
- DECLARE_FORCE_LINK( PowerUp )
- SimplePersistFactoryClass<PowerUpGameObjDef, CHUNKID_GAME_OBJECT_DEF_POWERUP> _PowerUpGameObjDefPersistFactory;
- DECLARE_DEFINITION_FACTORY(PowerUpGameObjDef, CLASSID_GAME_OBJECT_DEF_POWERUP, "PowerUp") _PowerUpGameObjDefDefFactory;
- PowerUpGameObjDef::PowerUpGameObjDef( void ) :
- GrantShieldType( 0 ),
- GrantShieldStrength( 0 ),
- GrantShieldStrengthMax( 0 ),
- GrantHealth( 0 ),
- GrantHealthMax( 0 ),
- GrantWeaponID( 0 ),
- GrantWeapon( true ),
- GrantWeaponClips( false ),
- GrantWeaponRounds( 0 ),
- Persistent( false ),
- //IsCaptureTheFlag( false ),
- GrantKey( 0 ),
- GrantSoundID( 0 ),
- IdleSoundID( 0 ),
- AlwaysAllowGrant( false )
- {
- #ifdef PARAM_EDITING_ON
- // EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_INT, GrantShieldType );
- EnumParameterClass *param;
- param = new EnumParameterClass( &GrantShieldType );
- param->Set_Name ( "GrantShieldType" );
- for ( int param_counter = 0; param_counter < ArmorWarheadManager::Get_Num_Armor_Types(); param_counter++ ) {
- param->Add_Value(ArmorWarheadManager::Get_Armor_Name(param_counter), param_counter);
- }
- GENERIC_EDITABLE_PARAM( PowerUpGameObjDef, param )
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_FLOAT, GrantShieldStrength );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_FLOAT, GrantShieldStrengthMax );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_FLOAT, GrantHealth );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_FLOAT, GrantHealthMax );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_WEAPONOBJDEFINITIONID, GrantWeaponID );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_BOOL, GrantWeapon );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_BOOL, GrantWeaponClips );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_INT, GrantWeaponRounds );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_BOOL, Persistent );
- //EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_BOOL, false );//IsCaptureTheFlag );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_INT, GrantKey );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_BOOL, AlwaysAllowGrant );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_STRING, GrantAnimationName );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_STRING, IdleAnimationName );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, GrantSoundID );
- EDITABLE_PARAM( PowerUpGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, IdleSoundID );
- #endif //PARAM_EDITING_ON
- }
- uint32 PowerUpGameObjDef::Get_Class_ID (void) const
- {
- return CLASSID_GAME_OBJECT_DEF_POWERUP;
- }
- PersistClass * PowerUpGameObjDef::Create( void ) const
- {
- PowerUpGameObj * obj = new PowerUpGameObj;
- obj->Init( *this );
- return obj;
- }
- enum {
- CHUNKID_DEF_PARENT = 909991656,
- CHUNKID_DEF_VARIABLES,
- XXXMICROCHUNKID_DEF_PARAMETERS = 1,
- MICROCHUNKID_DEF_PERSISTENT,
- MICROCHUNKID_DEF_GRANT_SHIELD_TYPE,
- MICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH,
- XXXMICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH_MAX,
- MICROCHUNKID_DEF_GRANT_HEALTH,
- XXXMICROCHUNKID_DEF_GRANT_HEALTH_MAX,
- MICROCHUNKID_DEF_GRANT_WEAPON_ID,
- MICROCHUNKID_DEF_GRANT_WEAPON,
- MICROCHUNKID_DEF_GRANT_WEAPON_ROUNDS,
- XXXMICROCHUNKID_DEF_IS_CAPTURE_THE_FLAG,
- XXXMICROCHUNKID_DEF_GRANT_KEY_MASK,
- MICROCHUNKID_DEF_GRANT_ANIMATION_NAME,
- MICROCHUNKID_DEF_GRANT_SOUNDID,
- MICROCHUNKID_DEF_IDLE_ANIMATION_NAME,
- MICROCHUNKID_DEF_IDLE_SOUNDID,
- MICROCHUNKID_DEF_GRANT_KEY,
- MICROCHUNKID_DEF_ALWAYS_ALLOW_GRANT,
- MICROCHUNKID_DEF_GRANT_WEAPON_CLIPS,
- MICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH_MAX,
- MICROCHUNKID_DEF_GRANT_HEALTH_MAX,
- };
- bool PowerUpGameObjDef::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_DEF_PARENT );
- SimpleGameObjDef::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_SHIELD_TYPE, GrantShieldType );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH, GrantShieldStrength );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH_MAX,GrantShieldStrengthMax );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_HEALTH, GrantHealth );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_HEALTH_MAX, GrantHealthMax );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_WEAPON_ID, GrantWeaponID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_WEAPON, GrantWeapon );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_WEAPON_CLIPS, GrantWeaponClips );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_WEAPON_ROUNDS, GrantWeaponRounds );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_PERSISTENT, Persistent );
- //WRITE_MICRO_CHUNK( csave, XXXMICROCHUNKID_DEF_IS_CAPTURE_THE_FLAG, IsCaptureTheFlag );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_KEY, GrantKey );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GRANT_SOUNDID, GrantSoundID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_IDLE_SOUNDID, IdleSoundID );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_DEF_GRANT_ANIMATION_NAME, GrantAnimationName );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_DEF_IDLE_ANIMATION_NAME, IdleAnimationName );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_ALWAYS_ALLOW_GRANT, AlwaysAllowGrant );
- csave.End_Chunk();
- return true;
- }
- bool PowerUpGameObjDef::Load( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_DEF_PARENT:
- SimpleGameObjDef::Load( cload );
- break;
- case CHUNKID_DEF_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_SHIELD_TYPE, GrantShieldType );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH, GrantShieldStrength );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_SHIELD_STRENGTH_MAX, GrantShieldStrengthMax );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_HEALTH, GrantHealth );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_HEALTH_MAX, GrantHealthMax );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_WEAPON_ID, GrantWeaponID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_WEAPON, GrantWeapon );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_WEAPON_CLIPS, GrantWeaponClips );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_WEAPON_ROUNDS, GrantWeaponRounds );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_PERSISTENT, Persistent );
- //READ_MICRO_CHUNK( cload, XXXMICROCHUNKID_DEF_IS_CAPTURE_THE_FLAG, IsCaptureTheFlag );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_KEY, GrantKey );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GRANT_SOUNDID, GrantSoundID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_IDLE_SOUNDID, IdleSoundID );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_DEF_GRANT_ANIMATION_NAME, GrantAnimationName );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_DEF_IDLE_ANIMATION_NAME, IdleAnimationName );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_ALWAYS_ALLOW_GRANT, AlwaysAllowGrant );
- default:
- Debug_Say(("Unhandled Micro Chunk:%d File:%s Line:%d\r\n",cload.Cur_Micro_Chunk_ID(),__FILE__,__LINE__));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- default:
- Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- const PersistFactoryClass & PowerUpGameObjDef::Get_Factory (void) const
- {
- return _PowerUpGameObjDefPersistFactory;
- }
- bool PowerUpGameObjDef::Grant( SmartGameObj * obj, PowerUpGameObj * p_powerup, bool hud_display ) const
- {
- int no_grant_message = 0;
- bool granted = false;
- WWASSERT(CombatManager::I_Am_Server());
- DefenseObjectClass * defense = obj->Get_Defense_Object();
- // Grant the shield
- if ( GrantShieldType != 0 ) {
- if ( GrantShieldType > (int)defense->Get_Shield_Type() ) {
- defense->Set_Shield_Type( GrantShieldType );
- granted = true;
- } else {
- no_grant_message = IDS_M00DSGN_DSGN1015I1DSGN_TXT; //"You are already at full shield."
- }
- }
- if ( GrantShieldStrengthMax != 0 ) {
- float add = GrantShieldStrengthMax * (float)obj->Get_Definition().Get_DefenseObjectDef().ShieldStrengthMax;
- switch ( CombatManager::Get_Difficulty_Level() ) {
- case 0: add *= 2.0f; break;
- case 2: add *= 0.75f; break;
- };
- // Round up to next int
- add = (int)(add + 0.95f);
- defense->Set_Shield_Strength_Max( defense->Get_Shield_Strength_Max() + add );
- granted = true;
- if ( hud_display && obj == COMBAT_STAR ) {
- HUDClass::Add_Shield_Upgrade_Grant( add );
- }
- }
- if ( GrantShieldStrength != 0 ) {
- if ( (defense->Get_Shield_Strength() < defense->Get_Shield_Strength_Max()) ) {
- defense->Add_Shield_Strength( GrantShieldStrength );
- granted = true;
- if ( obj == COMBAT_STAR ) {
- Vector3 pos;
- obj->Get_Position( &pos );
- DIAG_LOG(( "AMPU", "%1.2f; %1.2f; %1.2f; %1.2f; %1.2f", pos.X, pos.Y, pos.Z, defense->Get_Shield_Strength(), defense->Get_Health() ));
- }
- } else {
- no_grant_message = IDS_M00DSGN_DSGN1015I1DSGN_TXT; //"You are already at full shield."
- }
- }
- if ( granted && hud_display ) {
- if ( obj == COMBAT_STAR ) {
- if ( GrantShieldStrengthMax == 0 ) {
- HUDClass::Add_Shield_Grant( GrantShieldStrength );
- }
- }
- }
- // Grant the Health
- if ( GrantHealthMax != 0 ) {
- float add = GrantHealthMax * (float)obj->Get_Definition().Get_DefenseObjectDef().HealthMax;
- switch ( CombatManager::Get_Difficulty_Level() ) {
- case 0: add *= 2.0f; break;
- case 2: add *= 0.75f; break;
- };
- // Round up to next int
- add = (int)(add + 0.95f);
- defense->Set_Health_Max( defense->Get_Health_Max() + add );
- granted = true;
- if ( hud_display && obj == COMBAT_STAR ) {
- HUDClass::Add_Health_Upgrade_Grant( add );
- }
- }
- if ( GrantHealth != 0 ) {
- if ( defense->Get_Health() < defense->Get_Health_Max() ) {
- defense->Add_Health( GrantHealth );
- granted = true;
- if ( obj == COMBAT_STAR && hud_display ) {
- if ( GrantHealthMax == 0 ) {
- HUDClass::Add_Health_Grant( GrantHealth );
- }
- }
- if ( obj == COMBAT_STAR ) {
- Vector3 pos;
- obj->Get_Position( &pos );
- DIAG_LOG(( "HEPU", "%1.2f; %1.2f; %1.2f; %1.2f; %1.2f", pos.X, pos.Y, pos.Z, defense->Get_Shield_Strength(), defense->Get_Health() ));
- }
- } else {
- no_grant_message = IDS_M00DSGN_DSGN1014I1DSGN_TXT; //"You are already at full health."
- }
- }
- // Grant the Weapon
- if ( GrantWeaponID != 0 ) {
- if ( ( GrantWeapon && !obj->Get_Weapon_Bag()->Is_Weapon_Owned( GrantWeaponID ) ) ||
- ( !obj->Get_Weapon_Bag()->Is_Ammo_Full( GrantWeaponID ) ) ) {
- if ( obj == COMBAT_STAR && hud_display ) {
- if ( GrantWeapon && !obj->Get_Weapon_Bag()->Is_Weapon_Owned( GrantWeaponID ) ) {
- HUDClass::Add_Powerup_Weapon( GrantWeaponID, GrantWeaponRounds );
- } else {
- if ( !obj->Get_Weapon_Bag()->Is_Ammo_Full( GrantWeaponID ) ) {
- HUDClass::Add_Powerup_Ammo( GrantWeaponID, GrantWeaponRounds );
- }
- }
- }
- obj->Get_Weapon_Bag()->Add_Weapon( GrantWeaponID, GrantWeaponRounds, GrantWeapon );
- granted = true;
- if ( obj == COMBAT_STAR ) {
- Vector3 pos;
- obj->Get_Position( &pos );
- const char * grant_name = "";
- const WeaponDefinitionClass * def = WeaponManager::Find_Weapon_Definition( GrantWeaponID );
- if ( def ) {
- grant_name = def->Get_Name();
- }
- const char * weapon_name = "";
- int ammo = 0;
- if ( obj->Get_Weapon() ) {
- weapon_name = obj->Get_Weapon()->Get_Definition()->Get_Name();
- ammo = obj->Get_Weapon()->Get_Total_Rounds();
- }
- DIAG_LOG(( "WEPU", "%1.2f; %1.2f; %1.2f; %s; %d; %s; %d", pos.X, pos.Y, pos.Z, grant_name, GrantWeaponRounds, weapon_name, ammo ));
- }
- } else {
- no_grant_message = IDS_M00DSGN_DSGN1016I1DSGN_TXT; //"Your weapon is full."
- }
- } else if ( GrantWeaponClips ) {
-
- //
- // Loop over all the weapons in the owner's bag
- //
- WeaponBagClass *weapon_bag = obj->Get_Weapon_Bag();
- for ( int weapon_index = 0; weapon_index < weapon_bag->Get_Count(); weapon_index ++ ) {
- WeaponClass *weapon = weapon_bag->Peek_Weapon( weapon_index );
- if( weapon != NULL && weapon->Get_Definition ()->CanReceiveGenericCnCAmmo ) {
- //
- // Grant "x" number of clips to the weapon
- //
- int clip_rounds = weapon->Get_Definition()->ClipSize;
- weapon->Add_Rounds( clip_rounds * GrantWeaponRounds );
- }
- }
- }
- // Grant the key
- if ( GrantKey != 0 ) {
- SoldierGameObj * soldier = obj->As_SoldierGameObj();
- if ( soldier && soldier->Is_Human_Controlled() ) {
- if ( !soldier->Has_Key( GrantKey ) ) {
- soldier->Give_Key( GrantKey );
- granted = true;
- }
- }
- if ( obj == COMBAT_STAR ) {
- Vector3 pos;
- obj->Get_Position( &pos );
- DIAG_LOG(( "KEPU", "%1.2f; %1.2f; %1.2f; %d", pos.X, pos.Y, pos.Z, GrantKey ));
- }
- if ( granted && hud_display && obj == COMBAT_STAR ) {
- HUDClass::Add_Key_Grant( GrantKey );
- }
- }
- /*
- // Handle Capture the Flag
- if ( IsCaptureTheFlag && p_powerup != NULL && obj->As_SoldierGameObj() != NULL ) {
- CombatManager::Soldier_Contacts_Flag( obj->As_SoldierGameObj(), p_powerup );
- granted = true;
- }
- */
- if ( AlwaysAllowGrant ) {
- granted = true;
- }
- if ( granted && p_powerup != NULL ) {
- p_powerup->Set_State( PowerUpGameObj::STATE_GRANTING );
- //
- // Reveal this object to the player
- //
- if ( COMBAT_STAR == obj ) {
- EncyclopediaMgrClass::Reveal_Object( p_powerup );
- }
- }
- // Stats
- if ( granted && obj->Get_Player_Data() ) {
- obj->Get_Player_Data()->Stats_Add_Powerup();
- }
- if ( !granted && ( COMBAT_STAR == obj ) && no_grant_message != 0 ) {
- HUDInfo::Set_HUD_Help_Text( TRANSLATE( no_grant_message ), Vector3( 0,1,0 ) );
- }
- return granted;
- }
- /*
- ** PowerUpGameObj
- */
- SimplePersistFactoryClass<PowerUpGameObj, CHUNKID_GAME_OBJECT_POWERUP> _PowerUpGameObjPersistFactory;
- PowerUpGameObj::PowerUpGameObj (void) :
- IdleSoundObj( NULL ),
- State( STATE_BECOMING_IDLE ),
- WeaponBag( NULL )
- {
- Set_App_Packet_Type(APPPACKETTYPE_POWERUP);
- }
- PowerUpGameObj::~PowerUpGameObj (void)
- {
- //
- // Cleanup the idle sound
- //
- if ( IdleSoundObj != NULL ) {
- IdleSoundObj->Remove_From_Scene();
- IdleSoundObj->Release_Ref();
- IdleSoundObj = NULL;
- }
- if ( WeaponBag != NULL ) {
- delete WeaponBag;
- WeaponBag = NULL;
- }
- return ;
- }
- const PersistFactoryClass & PowerUpGameObj::Get_Factory (void) const
- {
- return _PowerUpGameObjPersistFactory;
- }
- /*
- **
- */
- void PowerUpGameObj::Init( void )
- {
- Init( Get_Definition() );
- }
- /*
- **
- */
- void PowerUpGameObj::Init( const PowerUpGameObjDef & definition )
- {
- SimpleGameObj::Init( definition );
- // Only collide with terrain!
- Peek_Physical_Object()->Set_Collision_Group( TERRAIN_ONLY_COLLISION_GROUP );
- }
- const PowerUpGameObjDef & PowerUpGameObj::Get_Definition( void ) const
- {
- return (const PowerUpGameObjDef &)BaseGameObj::Get_Definition();
- }
- /*
- ** PowerUpGameObj Save and Load
- */
- enum {
- CHUNKID_PARENT = 927991635,
- CHUNKID_VARIABLES,
- CHUNKID_WEAPONBAG,
- MICROCHUNKID_STATE = 1,
- MICROCHUNKID_STATE_END_TIMER,
- };
- bool PowerUpGameObj::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_PARENT );
- SimpleGameObj::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STATE, State );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STATE_END_TIMER, StateEndTimer );
- csave.End_Chunk();
- if ( WeaponBag != NULL ) {
- csave.Begin_Chunk( CHUNKID_WEAPONBAG );
- WeaponBag->Save( csave );
- csave.End_Chunk();
- }
- // We don't save IdleSoundObj
- return true;
- }
- bool PowerUpGameObj::Load( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_PARENT:
- SimpleGameObj::Load( cload );
- break;
- case CHUNKID_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_STATE, State );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_STATE_END_TIMER, StateEndTimer );
- default:
- Debug_Say(( "Unrecognized PowerupGameObj Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- case CHUNKID_WEAPONBAG:
- WWASSERT( WeaponBag == NULL );
- WeaponBag = new WeaponBagClass( NULL );
- WeaponBag->Load( cload );
- break;
- default:
- Debug_Say(( "Unrecognized PowerUpGameObj chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- SaveLoadSystemClass::Register_Post_Load_Callback(this); // MOVED
- return true;
- }
- void PowerUpGameObj::On_Post_Load( void )
- {
- SimpleGameObj::On_Post_Load();
- Peek_Physical_Object()->Set_Collision_Group( UNCOLLIDEABLE_GROUP ); // MOVED
- if ( Peek_Physical_Object()->As_MoveablePhysClass() != NULL ) {
- Peek_Physical_Object()->As_MoveablePhysClass()->Set_Gravity_Multiplier( 0 );
- }
- // This allows the idle sound and animation to start after loading
- if ( State == STATE_IDLING ) {
- State = STATE_BECOMING_IDLE;
- }
- }
- void PowerUpGameObj::Set_State( int state )
- {
- if (state != State) {
- State = state;
- StateEndTimer = 0;
- if ( State == STATE_GRANTING ) {
- //
- // Stop the idling sound (if necessary)
- //
- if ( IdleSoundObj != NULL ) {
- IdleSoundObj->Remove_From_Scene();
- IdleSoundObj->Stop();
- }
- //
- // Play the grant sound (if exists)
- //
- if ( Get_Definition ().GrantSoundID != 0 ) {
- WWAudioClass::Get_Instance()->Create_Instant_Sound( Get_Definition ().GrantSoundID, Get_Transform () );
- }
- //
- // Play the grant animation (if exists)
- //
- if ( Get_Definition ().GrantAnimationName.Get_Length () > 0 ) {
- Set_Animation( Get_Definition ().GrantAnimationName, false );
- HAnimClass *animation = WW3DAssetManager::Get_Instance ()->Get_HAnim( Get_Anim_Control ()->Get_Animation_Name () );
- if ( animation != NULL ) {
- StateEndTimer = animation->Get_Total_Time();
- REF_PTR_RELEASE( animation );
- }
- }
- }
- }
- return ;
- }
- void PowerUpGameObj::Update_State( void )
- {
- switch ( State )
- {
- case STATE_IDLING:
- break;
- case STATE_BECOMING_IDLE:
- //
- // Start playing the idle sound
- //
- if ( Get_Definition ().IdleSoundID != 0 ) {
- if ( IdleSoundObj == NULL ) {
- IdleSoundObj = WWAudioClass::Get_Instance ()->Create_Continuous_Sound( Get_Definition ().IdleSoundID );
- }
- if ( IdleSoundObj != NULL ) {
- IdleSoundObj->Set_Transform( Get_Transform () );
- IdleSoundObj->Add_To_Scene( true );
- }
- }
- //
- // Start playing the idle animation
- //
- if ( Get_Definition ().IdleAnimationName.Get_Length () > 0 ) {
- Set_Animation( Get_Definition ().IdleAnimationName, true );
- }
- State = STATE_IDLING;
- break;
- case STATE_GRANTING:
- //
- // If the granting animation has finished, then change to another state (or remove
- // the powerup from the world).
- //
- StateEndTimer -= TimeManager::Get_Frame_Seconds();
- if ( StateEndTimer <= 0 ) {
- //if ( Get_Definition().IsCaptureTheFlag || Get_Definition().Persistent ) {
- if ( Get_Definition().Persistent ) {
- Set_State ( STATE_BECOMING_IDLE );
- } else {
- Set_Delete_Pending();
- }
- }
- break;
- case STATE_EXPIRING:
- //
- // If the granting animation has finished, then change to another state (or remove
- // the powerup from the world).
- //
- StateEndTimer -= TimeManager::Get_Frame_Seconds();
- if ( StateEndTimer <= 0 ) {
- Set_Delete_Pending();
- }
- break;
- }
- return ;
- }
- void PowerUpGameObj::Grant( SmartGameObj * obj )
- {
- WWASSERT ( State != STATE_GRANTING );
- WWASSERT( obj );
- // Grant Def
- Get_Definition().Grant( obj, this );
- // If we have a weapon bag, move it
- if ( WeaponBag != NULL ) {
- WWASSERT( obj->Get_Weapon_Bag() );
- if ( obj->Get_Weapon_Bag()->Move_Contents( WeaponBag ) ) {
- Set_State( PowerUpGameObj::STATE_GRANTING );
- }
- }
- if ( State == STATE_GRANTING ) {
- const GameObjObserverList & observer_list = Get_Observers();
- for( int index = 0; index < observer_list.Count(); index++ ) {
- observer_list[ index ]->Custom( this, CUSTOM_EVENT_POWERUP_GRANTED, 0, obj );
- }
- }
- }
- void PowerUpGameObj::Think( void )
- {
- SimpleGameObj::Think();
- WWPROFILE( "PowerUp Think" );
- //
- // Make sure the powerup is playing its correct animation and sound
- //
- Update_State();
- //
- // If this powerup isn't currently granting itself to a player, then check
- // to see if it should!
- //
- // The server grants the prize, but allow the client to destroy
- // the powerup before being instructed to do so,
- // so that this doesn't lag
- //
- if ( CombatManager::I_Am_Server() && State != STATE_GRANTING ) {
- // Check my bounding box for collisions with Soldiers
- AABoxClass box = Peek_Model()->Get_Bounding_Box();
- SLNode<SmartGameObj> * smart_objnode;
- for (smart_objnode = GameObjManager::Get_Smart_Game_Obj_List()->Head(); smart_objnode; smart_objnode = smart_objnode->Next()) {
- SmartGameObj * obj = smart_objnode->Data();
- WWASSERT( obj != NULL );
- SoldierGameObj * soldier = obj->As_SoldierGameObj();
- if ( obj->As_VehicleGameObj() ) {
- soldier = obj->As_VehicleGameObj()->Get_Driver();
- }
- if ( soldier && soldier->Wants_Powerups() ) {
- PhysAABoxIntersectionTestClass test( box, DEFAULT_COLLISION_GROUP, COLLISION_TYPE_PHYSICAL );
- bool result = obj->Peek_Physical_Object()->Intersection_Test(test);
- if ( result ) {
- Grant( soldier ); // Don't grant any more
- break;
- }
- }
- }
- }
- return ;
- }
- PowerUpGameObj * PowerUpGameObj::Create_Backpack( ArmedGameObj * provider )
- {
- WWASSERT( provider );
- // Debug_Say(( "Creating a Backpack\n" ));
- PowerUpGameObj * backpack = (PowerUpGameObj *)ObjectLibraryManager::Create_Object( "Backpack" );
- if ( backpack != NULL ) {
- Matrix3D tm(1);
- tm.Set_Translation( provider->Get_Bullseye_Position() );
- backpack->Set_Transform(tm);
- backpack->WeaponBag = new WeaponBagClass( NULL );
- backpack->WeaponBag->Move_Contents( provider->Get_Weapon_Bag() );
- backpack->Start_Observers();
- }
- return backpack;
- }
- //void PowerUpGameObj::Get_Extended_Information( StringClass & description )
- void PowerUpGameObj::Get_Description( StringClass & description )
- {
- //
- // Construct a diagnostic string
- //
- StringClass line;
- line.Format("ID: %d\n", Get_ID());
- description += line;
- line.Format("Name: %s\n", Get_Definition().Get_Name());
- description += line;
- Vector3 position;
- Get_Position(&position);
- line.Format("POS: %-5.2f, %-5.2f, %-5.2f\n", position.X, position.Y, position.Z);
- description += line;
-
- if (Get_Defense_Object() != NULL) {
- line.Format("HLTH: %-5.2f\n", Get_Defense_Object()->Get_Health());
- description += line;
- }
- line.Format("HIB: %d\n", Is_Hibernating());
- description += line;
- line.Format("ISC: %d\n", Get_Import_State_Count());
- description += line;
- }
- void PowerUpGameObj::Expire( void )
- {
- #define EXPIRE_TIME 2
- if ( State != STATE_EXPIRING ) {
- /*
- ** If the definition calls for it, add a material effect to the object
- */
- PhysClass * physobj = Peek_Physical_Object();
- if (physobj != NULL) {
- TransitionEffectClass * effect = CombatMaterialEffectManager::Get_Death_Effect();
- effect->Set_Transition_Time( EXPIRE_TIME );
- physobj->Add_Effect_To_Me(effect);
- REF_PTR_RELEASE(effect);
- }
- State = STATE_EXPIRING;
- StateEndTimer = EXPIRE_TIME;
- }
- }
|