| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463 |
- /*
- ** 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/beacongameobj.cpp $*
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 6/14/02 1:59p $*
- * *
- * $Revision:: 41 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "beacongameobj.h"
- #include "debug.h"
- #include "phys.h"
- #include "combat.h"
- #include "soldier.h"
- #include "persistfactory.h"
- #include "combatchunkid.h"
- #include "weaponmanager.h"
- #include "simpledefinitionfactory.h"
- #include "wwhack.h"
- #include "decophys.h"
- #include "assets.h"
- #include "gameobjmanager.h"
- #include "wwaudio.h"
- #include "wwprofile.h"
- #include "cinematicgameobj.h"
- #include "basecontroller.h"
- #include "playertype.h"
- #include "colmath.h"
- #include "wwaudio.h"
- #include "audiblesound.h"
- #include "translateobj.h"
- #include "translatedb.h"
- #include "messagewindow.h"
- #include "weaponbag.h"
- #include "objlibrary.h"
- #include "hudinfo.h"
- #include "explosion.h"
- #include "backgroundmgr.h"
- #include "weathermgr.h"
- #include "persistentgameobjobserver.h"
- #include "apppackettypes.h"
- #include "weapons.h"
- ////////////////////////////////////////////////////////////////
- // Hacks
- ////////////////////////////////////////////////////////////////
- DECLARE_FORCE_LINK (Beacon)
- ////////////////////////////////////////////////////////////////
- // Editable and persist factories
- ////////////////////////////////////////////////////////////////
- SimplePersistFactoryClass <BeaconGameObjDef, CHUNKID_GAME_OBJECT_DEF_BEACON> _BeaconGameObjDefPersistFactory;
- SimplePersistFactoryClass <BeaconGameObj, CHUNKID_GAME_OBJECT_BEACON> _BeaconGameObjPersistFactory;
- DECLARE_DEFINITION_FACTORY (BeaconGameObjDef, CLASSID_GAME_OBJECT_DEF_BEACON, "Beacon") _BeaconGameObjDefDefFactory;
- ////////////////////////////////////////////////////////////////
- // Save/Load constants
- ////////////////////////////////////////////////////////////////
- enum
- {
- CHUNKID_MONITOR_PARENT = 0x07250256,
- };
- enum
- {
- CHUNKID_DEF_PARENT = 0x02190435,
- CHUNKID_DEF_VARIABLES,
- MICROCHUNKID_DEF_BROADCAST_TIME = 1,
- MICROCHUNKID_DEF_ARM_TIME,
- MICROCHUNKID_DEF_DISARM_TIME,
- MICROCHUNKID_DEF_DETONATE_TIME,
- MICROCHUNKID_DEF_ARMED_SOUNDID,
- MICROCHUNKID_DEF_DISARMING_TEXTID,
- MICROCHUNKID_DEF_DISARMED_TEXTID,
- MICROCHUNKID_DEF_ARMING_TEXTID,
- MICROCHUNKID_DEF_POST_CINEMATIC_DEFID,
- MICROCHUNKID_DEF_ARM_INTERRUPT_TEXTID,
- MICROCHUNKID_DEF_DISARM_INTERRUPT_TEXTID,
- MICROCHUNKID_DEF_ARMING_ANIM_NAME,
- MICROCHUNKID_DEF_PRE_CINEMATIC_DEFID,
- MICROCHUNKID_DEF_EXPLOSION_DEFID,
- MICROCHUNKID_DEF_POST_DETONATE_TIME,
- MICROCHUNKID_DEF_PRE_DETONATE_CINEMATIC_DELAY,
- MICROCHUNKID_DEF_IS_NUKE,
- };
- enum
- {
- CHUNKID_PARENT = 0x0219043,
- CHUNKID_VARIABLES,
- CHUNKID_OWNER,
- CHUNKID_CINEMATIC,
- MICROCHUNKID_STATE = 1,
- MICROCHUNKID_STATE_TIMER,
- MICROCHUNKID_DETONATE_TIMER,
- MICROCHUNKID_PRE_DETONATE_TIMER,
- MICROCHUNKID_IS_ARMED,
- };
- ////////////////////////////////////////////////////////////////
- //
- // BeaconGameObjDef
- //
- ////////////////////////////////////////////////////////////////
- BeaconGameObjDef::BeaconGameObjDef (void) :
- BroadcastToAllTime (5.0F),
- ArmTime (10.0F),
- DisarmTime (10.0F),
- PreDetonateCinematicDelay(0),
- DetonateTime (30.0F),
- PostDetonateTime (10.0F),
- ArmedSoundDefID (0),
- DisarmingTextID (0),
- DisarmedTextID (0),
- ArmingTextID (0),
- ArmingInterruptedTextID (0),
- DisarmingInterruptedTextID (0),
- PreDetonateCinematicDefID (0),
- PostDetonateCinematicDefID (0),
- ExplosionDefID (0),
- IsNuke( true )
- {
- //
- // Editable support
- //
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_STRING, ArmingAnimationName);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_FLOAT, BroadcastToAllTime);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_FLOAT, ArmTime);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_FLOAT, DisarmTime);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_FLOAT, PreDetonateCinematicDelay);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_FLOAT, DetonateTime);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_FLOAT, PostDetonateTime);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, ArmedSoundDefID);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, ArmingTextID);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, ArmingInterruptedTextID);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, DisarmingTextID);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, DisarmingInterruptedTextID);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, DisarmedTextID);
- EDITABLE_PARAM (BeaconGameObjDef, ParameterClass::TYPE_BOOL, IsNuke);
- #ifdef PARAM_EDITING_ON
- GenericDefParameterClass *param = new GenericDefParameterClass (&PreDetonateCinematicDefID);
- param->Set_Class_ID (CLASSID_GAME_OBJECT_DEF_CINEMATIC);
- param->Set_Name ("Pre-Detonate Cinematic Obj");
- GENERIC_EDITABLE_PARAM (BeaconGameObjDef, param)
- param = new GenericDefParameterClass (&PostDetonateCinematicDefID);
- param->Set_Class_ID (CLASSID_GAME_OBJECT_DEF_CINEMATIC);
- param->Set_Name ("Post-Detonate Cinematic Obj");
- GENERIC_EDITABLE_PARAM (BeaconGameObjDef, param)
- param = new GenericDefParameterClass (&ExplosionDefID);
- param->Set_Class_ID (CLASSID_DEF_EXPLOSION);
- param->Set_Name ("Explosion Obj");
- GENERIC_EDITABLE_PARAM (BeaconGameObjDef, param)
- #endif //PARAM_EDITING_ON
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // ~BeaconGameObjDef
- //
- ////////////////////////////////////////////////////////////////
- BeaconGameObjDef::~BeaconGameObjDef (void)
- {
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Class_ID
- //
- ////////////////////////////////////////////////////////////////
- uint32
- BeaconGameObjDef::Get_Class_ID (void) const
- {
- return CLASSID_GAME_OBJECT_DEF_BEACON;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Create
- //
- ////////////////////////////////////////////////////////////////
- PersistClass *
- BeaconGameObjDef::Create (void) const
- {
- BeaconGameObj *beacon = new BeaconGameObj;
- beacon->Init (*this);
- return beacon;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Create
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObjDef::Save (ChunkSaveClass &csave)
- {
- csave.Begin_Chunk (CHUNKID_DEF_PARENT);
- SimpleGameObjDef::Save (csave);
- csave.End_Chunk ();
- csave.Begin_Chunk (CHUNKID_DEF_VARIABLES);
- WRITE_MICRO_CHUNK_WWSTRING (csave, MICROCHUNKID_DEF_ARMING_ANIM_NAME, ArmingAnimationName);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_BROADCAST_TIME, BroadcastToAllTime);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_ARM_TIME, ArmTime);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_DISARM_TIME, DisarmTime);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_PRE_DETONATE_CINEMATIC_DELAY,PreDetonateCinematicDelay);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_DETONATE_TIME, DetonateTime);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_POST_DETONATE_TIME, PostDetonateTime);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_ARMED_SOUNDID, ArmedSoundDefID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_DISARMING_TEXTID, DisarmingTextID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_DISARMED_TEXTID, DisarmedTextID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_ARMING_TEXTID, ArmingTextID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_ARM_INTERRUPT_TEXTID, ArmingInterruptedTextID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_DISARM_INTERRUPT_TEXTID, DisarmingInterruptedTextID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_PRE_CINEMATIC_DEFID, PreDetonateCinematicDefID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_POST_CINEMATIC_DEFID, PostDetonateCinematicDefID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_EXPLOSION_DEFID, ExplosionDefID);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_IS_NUKE, IsNuke);
- csave.End_Chunk ();
- return true;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Load
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObjDef::Load (ChunkLoadClass &cload)
- {
- while (cload.Open_Chunk ())
- {
- switch (cload.Cur_Chunk_ID ())
- {
- case CHUNKID_DEF_PARENT:
- SimpleGameObjDef::Load (cload);
- break;
- case CHUNKID_DEF_VARIABLES:
- Load_Variables (cload);
- break;
- default:
- Debug_Say (("Unrecognized Beacon Def chunkID\n"));
- break;
- }
- cload.Close_Chunk ();
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Load_Variables
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObjDef::Load_Variables (ChunkLoadClass &cload)
- {
- while (cload.Open_Micro_Chunk ()) {
- switch (cload.Cur_Micro_Chunk_ID ())
- {
- READ_MICRO_CHUNK_WWSTRING (cload, MICROCHUNKID_DEF_ARMING_ANIM_NAME, ArmingAnimationName);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_BROADCAST_TIME, BroadcastToAllTime);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_ARM_TIME, ArmTime);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_DISARM_TIME, DisarmTime);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_PRE_DETONATE_CINEMATIC_DELAY, PreDetonateCinematicDelay);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_DETONATE_TIME, DetonateTime);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_POST_DETONATE_TIME, PostDetonateTime);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_ARMED_SOUNDID, ArmedSoundDefID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_DISARMING_TEXTID, DisarmingTextID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_DISARMED_TEXTID, DisarmedTextID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_ARMING_TEXTID, ArmingTextID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_ARM_INTERRUPT_TEXTID, ArmingInterruptedTextID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_DISARM_INTERRUPT_TEXTID, DisarmingInterruptedTextID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_PRE_CINEMATIC_DEFID, PreDetonateCinematicDefID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_POST_CINEMATIC_DEFID, PostDetonateCinematicDefID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_EXPLOSION_DEFID, ExplosionDefID);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_IS_NUKE, IsNuke);
- default:
- Debug_Say (("Unrecognized Beacon Def Variable chunkID\n"));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Factory
- //
- ////////////////////////////////////////////////////////////////
- const PersistFactoryClass &
- BeaconGameObjDef::Get_Factory (void) const
- {
- return _BeaconGameObjDefPersistFactory;
- }
- ////////////////////////////////////////////////////////////////
- //
- // BeaconGameObj
- //
- ////////////////////////////////////////////////////////////////
- BeaconGameObj::BeaconGameObj (void) :
- StateTimer (0),
- PreDetonateTimer (0),
- DetonateTimer (0),
- WarningTimer(0.0f),
- State (0),
- IsArmed (false),
- WeaponDefinition (NULL),
- MessageSound (NULL),
- ArmedSound (NULL),
- OwnerBackup( NULL )
- {
- Set_App_Packet_Type(APPPACKETTYPE_BEACON);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // ~BeaconGameObj
- //
- ////////////////////////////////////////////////////////////////
- BeaconGameObj::~BeaconGameObj (void)
- {
- Stop_Current_Message_Sound ();
- Stop_Armed_Sound ();
- Stop_Owner_Animation ();
- CinematicObject = NULL;
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Factory
- //
- ////////////////////////////////////////////////////////////////
- const PersistFactoryClass &
- BeaconGameObj::Get_Factory (void) const
- {
- return _BeaconGameObjPersistFactory;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Init
- //
- ////////////////////////////////////////////////////////////////
- void BeaconGameObj::Init( void )
- {
- Init( Get_Definition() );
- }
- ////////////////////////////////////////////////////////////////
- //
- // Init
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Init (const BeaconGameObjDef &definition)
- {
- SimpleGameObj::Init (definition);
- //
- // Make the object so its targettable and it collides with the terrain
- //
- Peek_Physical_Object()->Set_Collision_Group (TERRAIN_AND_BULLET_COLLISION_GROUP);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Definition
- //
- ////////////////////////////////////////////////////////////////
- const BeaconGameObjDef &
- BeaconGameObj::Get_Definition (void) const
- {
- return (const BeaconGameObjDef &)BaseGameObj::Get_Definition ();
- }
- ////////////////////////////////////////////////////////////////
- //
- // Init_Beacon
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Init_Beacon
- (
- const WeaponDefinitionClass * definition,
- SoldierGameObj * owner,
- const Vector3 & position
- )
- {
- WeaponDefinition = definition;
- Owner = owner;
- Set_Position (position);
- if ( owner ) {
- OwnerBackup = owner->Get_Player_Data();
- }
- //
- // Become part of the same team as the player who is
- // dropping us
- //
- if (Owner != NULL) {
- Set_Player_Type (Owner.Get_Ptr ()->As_SmartGameObj ()->Get_Player_Type ());
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Save
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObj::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_TIMER, StateTimer);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DETONATE_TIMER, DetonateTimer);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_PRE_DETONATE_TIMER, PreDetonateTimer);
- WRITE_MICRO_CHUNK (csave, MICROCHUNKID_IS_ARMED, IsArmed);
- csave.End_Chunk ();
- //
- // Save the owner (if necessary)
- //
- if (Owner != NULL) {
- csave.Begin_Chunk (CHUNKID_OWNER);
- Owner.Save (csave);
- csave.End_Chunk ();
- }
- if (CinematicObject != NULL) {
- csave.Begin_Chunk (CHUNKID_CINEMATIC);
- CinematicObject.Save (csave);
- csave.End_Chunk ();
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Load
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObj::Load (ChunkLoadClass &cload)
- {
- while (cload.Open_Chunk ()) {
- switch (cload.Cur_Chunk_ID ()) {
- case CHUNKID_PARENT:
- SimpleGameObj::Load (cload);
- break;
- case CHUNKID_VARIABLES:
- Load_Variables (cload);
- break;
- case CHUNKID_OWNER:
- Owner.Load (cload);
- break;
- case CHUNKID_CINEMATIC:
- CinematicObject.Load (cload);
- break;
- default:
- Debug_Say (("Unrecognized Beacon chunkID\n"));
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Load_Variables
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Load_Variables (ChunkLoadClass &cload)
- {
- while (cload.Open_Micro_Chunk ()) {
- switch (cload.Cur_Micro_Chunk_ID ())
- {
- READ_MICRO_CHUNK (cload, MICROCHUNKID_STATE, State);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_STATE_TIMER, StateTimer);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_DETONATE_TIMER, DetonateTimer);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_PRE_DETONATE_TIMER, PreDetonateTimer);
- READ_MICRO_CHUNK (cload, MICROCHUNKID_IS_ARMED, IsArmed);
- default:
- Debug_Say (("Unrecognized Beacon Variable chunkID\n"));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Think
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Think (void)
- {
- WWPROFILE ("Beacon Think");
- Restore_Owner();
- //
- // Let the state think a little
- //
- Update_State ();
- //
- // Check to see if we need to break out of the
- // arming or disarming state
- //
- if ( CombatManager::I_Am_Server() && State == STATE_ARMING )
- {
- //
- // Was the owner interrupted while performing his action?
- //
- if (Was_Owner_Interrupted ()) {
- Stop_Owner_Animation ();
- //
- // Let the player know that the arming operation was cancelled
- //
- Display_Message (Get_Definition ().ArmingInterruptedTextID);
- //
- // If the arming state was interrupted, then
- // return the ammo that created the beacon to its owner.
- //
- SoldierGameObj *soldier = Get_Owner ();
- if (soldier != NULL) {
- WeaponBagClass *weapon_bag = soldier->Get_Weapon_Bag ();
- weapon_bag->Add_Weapon (WeaponDefinition, 1, false);
- //
- // If the user is still holding the beacon weapon then stop its firing
- // sound.
- //
- WeaponClass *curr_weapon = weapon_bag->Get_Weapon ();
- if (curr_weapon != NULL && curr_weapon->Get_ID () == WeaponDefinition->Get_ID ()) {
- curr_weapon->Stop_Firing_Sound ();
- }
- }
- //
- // Now destroy ourselves
- //
- Set_Delete_Pending ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Information
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Get_Information (StringClass &string)
- {
- SimpleGameObj::Get_Information( string );
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Start_Cinematic
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Start_Cinematic ( int id )
- {
- //
- // Create the cinematic controller
- //
- if ( id != 0 ) {
- PhysicalGameObj *game_obj = ObjectLibraryManager::Create_Object ( id );
- if (game_obj != NULL) {
- game_obj->Start_Observers ();
- //
- // Position the cinematic controller in the world
- //
- Vector3 position;
- Get_Position (&position);
- game_obj->Set_Position (position);
-
- CinematicObject = game_obj;
- Debug_Say(( "Beacon Cinematic Started\n" ));
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Stop_Armed_Sound
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Stop_Armed_Sound (void)
- {
- if (ArmedSound != NULL) {
- ArmedSound->Remove_From_Scene ();
- REF_PTR_RELEASE (ArmedSound);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Set_State
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Set_State (int state)
- {
- if (State == state) {
- return ;
- }
- Restore_Owner();
- if ( CombatManager::I_Am_Server() ) {
- //
- // "Dirty" the object for networking
- //
- Set_Object_Dirty_Bit( NetworkObjectClass::BIT_RARE, true );
- }
- bool is_nuke = !!Get_Definition().IsNuke;
- switch (state) {
- case STATE_NULL:
- Stop_Armed_Sound ();
- Display_Message (Get_Definition ().ArmingInterruptedTextID);
- break;
- case STATE_ARMING:
- StateTimer = Get_Definition ().ArmTime;
- Display_Message (Get_Definition ().ArmingTextID);
- Start_Owner_Animation ();
- break;
- case STATE_ARMED:
- if (IsArmed == false) {
- Stop_Owner_Animation ();
- //
- // Set the detonation timer
- //
- DetonateTimer = Get_Definition ().DetonateTime;
- WarningTimer = Get_Definition().BroadcastToAllTime;
- //
- // Create the "armed" sound
- //
- ArmedSound = WWAudioClass::Get_Instance ()->Create_Continuous_Sound (Get_Definition ().ArmedSoundDefID);
- if (ArmedSound != NULL) {
- //
- // Insert the sound object into the world
- //
- ArmedSound->Set_Transform (Get_Transform ());
- ArmedSound->Add_To_Scene ();
- }
- // Only on Server
- if ( CombatManager::I_Am_Server() ) {
- // switch to pre detonate weather
- Debug_Say(( "Pre-Detonate weather override\n" ));
- if ( is_nuke ) {
- BackgroundMgrClass::Override_Sky_Tint ( 0.8f, DetonateTimer/2 );
- WeatherMgrClass::Override_Wind (0, 3, 1, DetonateTimer/2 );
- } else {
- BackgroundMgrClass::Override_Clouds(1.0f, 1.0f, DetonateTimer/2);
- BackgroundMgrClass::Override_Lightning( 0.8f, 0.2f, 0.8f, 0, 1.0f, DetonateTimer/2);
- WeatherMgrClass::Override_Precipitation (WeatherMgrClass::PRECIPITATION_RAIN, 2.0f, DetonateTimer/2);
- }
- }
- // Notify base controllers the beacon is armed
- BaseControllerClass* base = BaseControllerClass::Find_Base(Get_Player_Type());
- if (base) {
- base->On_Beacon_Armed(this);
- }
- PreDetonateTimer = max( Get_Definition ().PreDetonateCinematicDelay, 0.001f );
- IsArmed = true;
- }
- break;
- case STATE_DISARMED: {
- Display_Message (Get_Definition ().DisarmedTextID);
- Stop_Armed_Sound ();
- Stop_Owner_Animation ();
- // Only on Server
- if ( CombatManager::I_Am_Server() ) {
- // cancel weather override
- Debug_Say(( "Cancelling weather override\n" ));
- if ( is_nuke ) {
- BackgroundMgrClass::Restore_Sky_Tint ( 5 );
- WeatherMgrClass::Restore_Wind( 5 );
- } else {
- BackgroundMgrClass::Restore_Clouds( 5 );
- BackgroundMgrClass::Restore_Lightning( 5 );
- WeatherMgrClass::Restore_Precipitation( 5 );
- }
- }
- // Notify base that the beacon is disarmed
- BaseControllerClass* base = BaseControllerClass::Find_Base(Get_Player_Type());
- if (base) {
- base->On_Beacon_Disarmed(this);
- }
- // Stop cinematic
- if ( CinematicObject.Get_Ptr() != NULL ) {
- CinematicObject.Get_Ptr()->Set_Delete_Pending();
- CinematicObject = NULL;
- }
- Set_Delete_Pending ();
- break;
- }
- case STATE_DETONATING:
- Stop_Armed_Sound ();
- Debug_Say(( "Detonate!\n" ));
- IsArmed = false;
- StateTimer = Get_Definition ().PostDetonateTime;
- // Only on Server
- if ( CombatManager::I_Am_Server() ) {
- // Create the cinematic controller
- Start_Cinematic( Get_Definition ().PostDetonateCinematicDefID );
- // switch to post detonate weather
- Debug_Say(( "Post-Detonate weather override\n" ));
- if ( is_nuke ) {
- WeatherMgrClass::Override_Precipitation (WeatherMgrClass::PRECIPITATION_ASH, 0.3f);
- }
- /*
- // Create the explosion, if not in the enemy base
- if ( !Is_In_Enemy_Base() && Get_Definition ().ExplosionDefID != 0 ) {
- Create_Explosion ();
- }
- */
- }
- // Create the explosion, if not in the enemy base
- // if ( !Is_In_Enemy_Base() && Get_Definition ().ExplosionDefID != 0 ) {
- if ( Get_Definition ().ExplosionDefID != 0 ) {
- Create_Explosion ();
- }
- // Hide our model
- if ( Peek_Model() ) {
- Peek_Model()->Set_Hidden( true );
- }
- break;
- }
- State = state;
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Update_State
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Update_State (void)
- {
- StateTimer -= TimeManager::Get_Frame_Seconds ();
- if (IsArmed) {
- //
- // Tweak the pitch of the armed sound
- //
- if (ArmedSound != NULL) {
- float percent = (1.0F - DetonateTimer / Get_Definition ().DetonateTime);
- ArmedSound->Set_Pitch_Factor (1.0F + (percent * 5.0F));
- }
- //
- // Check to see if we've exploded
- //
- DetonateTimer -= TimeManager::Get_Frame_Seconds ();
- if (DetonateTimer <= 0) {
- Set_State (STATE_DETONATING);
- }
- if ( PreDetonateTimer != 0 ) {
- PreDetonateTimer -= TimeManager::Get_Frame_Seconds ();
- if ( PreDetonateTimer <= 0 ) {
- PreDetonateTimer = 0;
- // Only on Server
- if ( CombatManager::I_Am_Server() ) {
- Start_Cinematic( Get_Definition ().PreDetonateCinematicDefID );
- }
- }
- }
- }
- //
- // Handle each state independently
- //
- switch (State) {
- case STATE_NULL:
- break;
- case STATE_ARMING: {
- //
- // Update the action bar in the HUD
- //
- float percent = (1.0F - StateTimer / Get_Definition ().ArmTime);
- HUDInfo::Set_Action_Status_Value (percent);
- //
- // Did the player successfully arm the beacon?
- //
- if (StateTimer <= 0) {
- Set_State (STATE_ARMED);
- }
- }
- break;
- case STATE_ARMED:
- if (WarningTimer != 0.0f) {
- WarningTimer -= TimeManager::Get_Frame_Seconds();
- if (WarningTimer <= 0.0f) {
- WarningTimer = 0.0f;
- // Notify base controller beacon is disarmed
- BaseControllerClass* base = BaseControllerClass::Find_Base(Get_Player_Type());
- if (base) {
- base->On_Beacon_Warning(this);
- }
- }
- }
- break;
- case STATE_DISARMED:
- break;
- case STATE_DETONATING:
- // Wait for post-detonate timer
- if (StateTimer <= 0) {
- // Only on Server
- if ( CombatManager::I_Am_Server() ) {
- if ( CombatManager::Does_Beacon_Placement_Ends_Game() && Is_In_Enemy_Base() ) {
- BaseControllerClass *base = Get_Enemy_Base ();
- if (base != NULL) {
- //
- // Destroy the enemy base
- //
- base->Destroy_Base ();
- base->Set_Beacon_Destroyed_Base(true);
- }
- }
- // cancel weather override
- Debug_Say(( "restore weather override\n" ));
- bool is_nuke = !!Get_Definition().IsNuke;
- if ( is_nuke ) {
- BackgroundMgrClass::Restore_Sky_Tint ( 5 );
- WeatherMgrClass::Restore_Wind( 5 );
- WeatherMgrClass::Restore_Precipitation( 5 );
- } else {
- BackgroundMgrClass::Restore_Clouds( 5 );
- BackgroundMgrClass::Restore_Lightning( 5 );
- WeatherMgrClass::Restore_Precipitation( 5 );
- }
- }
- Set_Delete_Pending();
- }
- break;
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Enemy_Base
- //
- ////////////////////////////////////////////////////////////////
- BaseControllerClass *
- BeaconGameObj::Get_Enemy_Base (void)
- {
- //
- // Lookup the team that this object is associated with
- //
- int player_type = PLAYERTYPE_GDI;
- if (Get_Player_Type () == PLAYERTYPE_GDI) {
- player_type = PLAYERTYPE_NOD;
- }
- return BaseControllerClass::Find_Base (player_type);
- }
- ////////////////////////////////////////////////////////////////
- //
- // Can_Place_Here
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObj::Can_Place_Here (const Vector3 &position)
- {
- // always return true;
- return true;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Is_In_Enemy_Base (CnC mode only)
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObj::Is_In_Enemy_Base( void )
- {
- bool retval = false;
- //
- // Lookup the enemy's base
- //
- BaseControllerClass *base = Get_Enemy_Base ();
- if (base != NULL) {
- //
- // Check to see if the point is inside the beacon's zone
- //
- Vector3 position;
- Get_Position (&position);
- const OBBoxClass &zone = base->Get_Beacon_Zone ();
- if (CollisionMath::Overlap_Test (zone, position) != CollisionMath::OUTSIDE) {
- retval = true;
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Stop_Current_Message_Sound
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Stop_Current_Message_Sound (void)
- {
- if (MessageSound != NULL) {
- MessageSound->Remove_From_Scene ();
- REF_PTR_RELEASE (MessageSound);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Display_Message
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Display_Message (int text_id)
- {
- Stop_Current_Message_Sound ();
- //
- // Lookup the translation object from the strings database
- //
- TDBObjClass *translate_obj = TranslateDBClass::Find_Object (text_id);
- if (translate_obj != NULL) {
- const WCHAR *string = translate_obj->Get_String ();
- int sound_def_id = (int)translate_obj->Get_Sound_ID ();
- float duration = 2.0F;
- //
- // Play the sound effect
- //
- bool display_text = true;
- if (sound_def_id > 0) {
- //
- // Create the sound object
- //
- MessageSound = WWAudioClass::Get_Instance ()->Create_Sound (sound_def_id);
- if (MessageSound != NULL) {
- duration = (MessageSound->Get_Duration () / 1000.0F);
- //
- // Play the sound effect at the lcoation of the beacon
- //
- MessageSound->Set_Transform (Get_Transform ());
- MessageSound->Add_To_Scene ();
- display_text = (MessageSound->Is_Sound_Culled () == false);
- }
- }
- //
- // Display the text on the screen
- //
- if (display_text && string != NULL) {
- float message_duration = max (duration, 5.0F);
- CombatManager::Get_Message_Window ()->Add_Message (string, Vector3 (1, 1, 1),
- NULL, message_duration);
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Begin_Arming
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Begin_Arming (void)
- {
- //
- // Switch states
- //
- Set_State (STATE_ARMING);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Start_Owner_Animation
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Start_Owner_Animation (void)
- {
- Restore_Owner();
- //
- // Release control of the human's animation (if possible)
- //
- SoldierGameObj *soldier = Get_Owner ();
- if (soldier != NULL) {
- //
- // Play the animation looped until we detect its time to stop
- //
- soldier->Set_Animation (Get_Definition ().ArmingAnimationName, true, 0);
- }
- // Only show the HUD if the owner if the star
- if ( soldier == COMBAT_STAR ) {
- HUDInfo::Display_Action_Status_Bar (true);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Stop_Owner_Animation
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Stop_Owner_Animation (void)
- {
- Restore_Owner();
- //
- // Release control of the human's animation (if possible)
- //
- SoldierGameObj *soldier = Get_Owner ();
- if (soldier != NULL) {
- //
- // Stop the animation
- //
- soldier->Set_Animation (NULL);
- }
- // Only show the HUD if the owner if the star
- if ( soldier == COMBAT_STAR ) {
- HUDInfo::Display_Action_Status_Bar (false);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Was_Owner_Interrupted
- //
- ////////////////////////////////////////////////////////////////
- bool
- BeaconGameObj::Was_Owner_Interrupted (void)
- {
- Restore_Owner();
- bool retval = false;
- //
- // The owner is interrupted if he's dead
- //
- SoldierGameObj *soldier = Get_Owner ();
- if (soldier == NULL || soldier->Is_Dead ()) {
- retval = true;
- } else {
- //
- // The owner is also interrupted if he moves
- //
- //
- // Check each movement control
- //
- ControlClass &control = soldier->Get_Control ();
- // Ignore up/down and turning
- // for (int index = 0; index < ControlClass::ANALOG_CONTROL_COUNT; index ++) {
- for (int index = 0; index < ControlClass::ANALOG_MOVE_LEFT+1; index ++) {
- //
- // Check this input to see if the soldier is moving
- //
- if (control.Get_Analog ((ControlClass::AnalogControl)index) != 0) {
- retval = true;
- break;
- }
- }
- //
- // Check each "boolean" control (jumping, etc)
- //
- if (retval == false) {
- for ( index = ControlClass::BOOLEAN_ONE_TIME_FIRST;
- index <= ControlClass::BOOLEAN_DROP_FLAG;
- index ++)
- {
- //
- // Check this input to see if the soldier is moving
- //
- if (control.Get_Boolean ((ControlClass::BooleanControl)index)) {
- retval = true;
- break;
- }
- }
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Owner
- //
- ////////////////////////////////////////////////////////////////
- SoldierGameObj *
- BeaconGameObj::Get_Owner (void)
- {
- SoldierGameObj *soldier = NULL;
- //
- // Dig the soldier pointer out of the referencer object
- //
- if (Owner != NULL) {
- PhysicalGameObj *physical_obj = Owner.Get_Ptr ()->As_PhysicalGameObj ();
- if (physical_obj != NULL) {
- soldier = physical_obj->As_SoldierGameObj ();
- }
- }
- return soldier;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Completely_Damaged
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Completely_Damaged (const OffenseObjectClass &damager)
- {
- if (!Is_Delete_Pending()) {
- Set_State (STATE_DISARMED);
- Set_Delete_Pending ();
- }
- }
- ////////////////////////////////////////////////////////////////
- //
- // Create_Explosion
- //
- ////////////////////////////////////////////////////////////////
- void
- BeaconGameObj::Create_Explosion (void)
- {
- if (CombatManager::I_Am_Server())
- {
- Restore_Owner();
- }
- Debug_Say (("Create Explosion\n"));
- //
- // Create the explosion...
- //
- Vector3 position;
- Get_Position (&position);
-
- //
- // (gth) don't explode if the owner is gone
- //
- if (Get_Owner() != NULL) {
-
- ExplosionManager::Create_Explosion_At (Get_Definition ().ExplosionDefID, Get_Transform (), Get_Owner ());
- if (CombatManager::I_Am_Server())
- {
- //
- // Look-up the explosion that this beacon will create
- //
- ExplosionDefinitionClass *explosion_def = (ExplosionDefinitionClass *)DefinitionMgrClass::Find_Definition (Get_Definition ().ExplosionDefID);
- if (explosion_def != NULL) {
- float outter_radius = explosion_def->DamageRadius;
- float outter_radius2 = outter_radius * outter_radius;
- //
- // Loop over all the buildings in the level
- //
- SLNode<BuildingGameObj> *obj_node = NULL;
- for ( obj_node = GameObjManager::Get_Building_Game_Obj_List()->Head ();
- obj_node != NULL;
- obj_node = obj_node->Next ())
- {
- WWASSERT (obj_node->Data () != NULL);
- BuildingGameObj *building = obj_node->Data ();
- if (building != NULL) {
- //
- // Check to see if any part of the building is inside our damage sphere
- //
- float dist2 = 0;
- building->Find_Closest_Poly (position, &dist2);
- if (dist2 <= outter_radius2) {
- //
- // Determine the strength of the explosion at this location
- //
- float percent = (WWMath::Sqrt (dist2) / outter_radius);
- percent = 1.0F - WWMath::Clamp (percent, 0.0F, 1.0F);
- float strength = percent * explosion_def->DamageStrength;
- //
- // Apply the damage to this building
- //
- OffenseObjectClass offense (strength, explosion_def->DamageWarhead, Get_Owner ());
- building->Apply_Damage_Building (offense, true);
- }
- }
- }
- }
- }
- }
- return ;
- }
- /*
- **
- */
- void BeaconGameObj::Export_Rare( BitStreamClass &packet )
- {
- Restore_Owner();
- SimpleGameObj::Export_Rare( packet );
- packet.Add( State );
- int owner_id = 0;
- if ( Get_Owner() ) {
- owner_id = Get_Owner()->Get_ID();
- }
- packet.Add( owner_id );
- }
- /*
- **
- */
- void BeaconGameObj::Import_Rare( BitStreamClass &packet )
- {
- SimpleGameObj::Import_Rare( packet );
- int state;
- packet.Get( state );
- int owner_id;
- packet.Get( owner_id );
- if ( owner_id != 0 ) {
- Owner = GameObjManager::Find_SmartGameObj( owner_id );
- }
- Set_State( state );
- return ;
- }
- void BeaconGameObj::Restore_Owner( void )
- {
- if ( Get_Owner() == NULL && OwnerBackup != NULL ) {
- // Try and find a smart game obj with the same playerdata
- 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();
- if ( obj->Get_Player_Data() == OwnerBackup ) {
- Owner = obj;
- Debug_Say(( "Found Beacon owner\n" ));
- }
- }
- if ( Get_Owner() == NULL ) {
- Debug_Say(( "Didn't find Beacon owner\n" ));
- }
- }
- }
|