| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006 |
- /*
- ** 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/elevator.cpp $*
- * *
- * $Author:: Byon_g $*
- * *
- * $Modtime:: 9/13/01 12:03p $*
- * *
- * $Revision:: 25 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "elevator.h"
- #include "simpledefinitionfactory.h"
- #include "persistfactory.h"
- #include "wwphysids.h"
- #include "bitstream.h"
- #include "debug.h"
- #include "hanim.h"
- #include "wwhack.h"
- #include "combat.h"
- #include "smartgameobj.h"
- #include "gameobjmanager.h"
- #include "soldier.h"
- #include "wwprofile.h"
- #include "audiblesound.h"
- #include "wwaudio.h"
- #include "bitpackids.h"
- DECLARE_FORCE_LINK( elevatorphys );
- /*
- ** Local constants
- */
- enum
- {
- EFFECT_DOOR_OPENING,
- EFFECT_DOOR_CLOSING,
- EFFECT_DOOR_UNLOCKED,
- EFFECT_ACCESS_DENIED,
- EFFECT_ELEVATOR_MOVING,
- EFFECT_ELEVATOR_STOPPED_MOVING,
- };
- /*
- ** ElevatorPhysDefClass
- */
- SimplePersistFactoryClass<ElevatorPhysDefClass, PHYSICS_CHUNKID_ELEVATORPHYSDEF> _ElevatorPhysDefPersistFactory;
- DECLARE_DEFINITION_FACTORY(ElevatorPhysDefClass, CLASSID_ELEVATORPHYSDEF, "ElevatorPhys") _ElevatorPhysDefDefFactory;
- ElevatorPhysDefClass::ElevatorPhysDefClass( void ) :
- AccessiblePhysDefClass(),
- CloseDelay( 2 ),
- /*LowerCallZone( Vector3( 0,0,0), Vector3( 1,1,1 ) ),
- LowerInsideZone( Vector3( 0,0,0), Vector3( 1,1,1 ) ),
- UpperCallZone( Vector3( 0,0,0), Vector3( 1,1,1 ) ),
- UpperInsideZone( Vector3( 0,0,0), Vector3( 1,1,1 ) ),*/
- DoorClosedTop_FrameNum( -1 ),
- DoorOpeningBottom_FrameNum( -1 ),
- ElevatorStartTop_FrameNum( -1 ),
- ElevatorStoppedBottom_FrameNum( -1 ),
- DoorOpenSoundDefID( 0 ),
- DoorCloseSoundDefID( 0 ),
- DoorUnlockSoundDefID( 0 ),
- DoorAccessDeniedSoundDefID( 0 ),
- ElevatorMovingSoundDefID( 0 )
- {
- for (int index = 0; index < ZONE_MAX; index ++) {
- CallZones[index].Center = Vector3( 0, 0, 0 );
- CallZones[index].Extent = Vector3( 1, 1, 1 );
- }
- ZONE_PARAM(ElevatorPhysDefClass, CallZones[ZONE_LOWER_CALL], "LowerCallZone" );
- ZONE_PARAM(ElevatorPhysDefClass, CallZones[ZONE_LOWER_INSIDE], "LowerInsideZone" );
- ZONE_PARAM(ElevatorPhysDefClass, CallZones[ZONE_UPPER_CALL], "UpperCallZone" );
- ZONE_PARAM(ElevatorPhysDefClass, CallZones[ZONE_UPPER_INSIDE], "UpperInsideZone" );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_FLOAT, CloseDelay );
- PARAM_SEPARATOR(ElevatorPhysDefClass, "Frame Numbers");
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_FLOAT, DoorClosedTop_FrameNum );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_FLOAT, DoorOpeningBottom_FrameNum );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_FLOAT, ElevatorStartTop_FrameNum );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_FLOAT, ElevatorStoppedBottom_FrameNum );
-
- PARAM_SEPARATOR(ElevatorPhysDefClass, "Sounds");
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_SOUNDDEFINITIONID, DoorOpenSoundDefID );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_SOUNDDEFINITIONID, DoorCloseSoundDefID );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_SOUNDDEFINITIONID, DoorUnlockSoundDefID );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_SOUNDDEFINITIONID, DoorAccessDeniedSoundDefID );
- EDITABLE_PARAM(ElevatorPhysDefClass, ParameterClass::TYPE_SOUNDDEFINITIONID, ElevatorMovingSoundDefID );
- }
- uint32 ElevatorPhysDefClass::Get_Class_ID (void) const
- {
- return CLASSID_ELEVATORPHYSDEF;
- }
- bool ElevatorPhysDefClass::Is_Type(const char * type_name)
- {
- if (stricmp(type_name,ElevatorPhysDefClass::Get_Type_Name()) == 0) {
- return true;
- } else {
- return AccessiblePhysDefClass::Is_Type(type_name);
- }
- }
- PersistClass * ElevatorPhysDefClass::Create( void ) const
- {
- ElevatorPhysClass * elevator = new ElevatorPhysClass;
- elevator->Init( *this );
- return elevator;
- }
- enum {
- CHUNKID_DEF_OLD_PARENT = 714001418,
- CHUNKID_DEF_VARIABLES,
- CHUNKID_DEF_PARENT,
- MICROCHUNKID_DEF_CLOSE_DELAY = 1,
- MICROCHUNKID_DEF_LOCK_CODE,
- MICROCHUNKID_DEF_UPPER_CALL_ZONE,
- MICROCHUNKID_DEF_UPPER_INSIDE_ZONE,
- MICROCHUNKID_DEF_LOWER_CALL_ZONE,
- MICROCHUNKID_DEF_LOWER_INSIDE_ZONE,
- MICROCHUNKID_DEF_DOORCLOSED_FRAMENUM,
- MICROCHUNKID_DEF_DOOROPENING_FRAMENUM,
- MICROCHUNKID_DEF_ELEVATOR_START_FRAMENUM,
- MICROCHUNKID_DEF_ELEVATOR_STOPPED_FRAMENUM,
- MICROCHUNKID_DEF_DOOR_OPEN_SOUNDID,
- MICROCHUNKID_DEF_DOOR_CLOSE_SOUNDID,
- MICROCHUNKID_DEF_DOOR_UNLOCK_SOUNDID,
- MICROCHUNKID_DEF_DOOR_ACCESS_DENIED_SOUNDID,
- MICROCHUNKID_DEF_ELEVATOR_MOVING_SOUNDID
- };
- bool ElevatorPhysDefClass::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_DEF_PARENT );
- AccessiblePhysDefClass::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_CLOSE_DELAY, CloseDelay );
- //WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_LOCK_CODE, LockCode );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_LOWER_CALL_ZONE, CallZones[ZONE_LOWER_CALL] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_LOWER_INSIDE_ZONE, CallZones[ZONE_LOWER_INSIDE] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_UPPER_CALL_ZONE, CallZones[ZONE_UPPER_CALL] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_UPPER_INSIDE_ZONE, CallZones[ZONE_UPPER_INSIDE] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DOORCLOSED_FRAMENUM, DoorClosedTop_FrameNum );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DOOROPENING_FRAMENUM, DoorOpeningBottom_FrameNum );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_ELEVATOR_START_FRAMENUM, ElevatorStartTop_FrameNum );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_ELEVATOR_STOPPED_FRAMENUM, ElevatorStoppedBottom_FrameNum );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DOOR_OPEN_SOUNDID, DoorOpenSoundDefID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DOOR_CLOSE_SOUNDID, DoorCloseSoundDefID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DOOR_UNLOCK_SOUNDID, DoorUnlockSoundDefID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DOOR_ACCESS_DENIED_SOUNDID, DoorAccessDeniedSoundDefID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_ELEVATOR_MOVING_SOUNDID, ElevatorMovingSoundDefID );
- csave.End_Chunk();
- return true;
- }
- bool ElevatorPhysDefClass::Load( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_DEF_OLD_PARENT:
- StaticAnimPhysDefClass::Load( cload );
- break;
- case CHUNKID_DEF_PARENT:
- AccessiblePhysDefClass::Load( cload );
- break;
-
- case CHUNKID_DEF_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_CLOSE_DELAY, CloseDelay );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_LOCK_CODE, LockCode );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_LOWER_CALL_ZONE, CallZones[ZONE_LOWER_CALL] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_LOWER_INSIDE_ZONE, CallZones[ZONE_LOWER_INSIDE] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_UPPER_CALL_ZONE, CallZones[ZONE_UPPER_CALL] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_UPPER_INSIDE_ZONE, CallZones[ZONE_UPPER_INSIDE] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DOORCLOSED_FRAMENUM, DoorClosedTop_FrameNum );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DOOROPENING_FRAMENUM, DoorOpeningBottom_FrameNum );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_ELEVATOR_START_FRAMENUM, ElevatorStartTop_FrameNum );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_ELEVATOR_STOPPED_FRAMENUM, ElevatorStoppedBottom_FrameNum );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DOOR_OPEN_SOUNDID, DoorOpenSoundDefID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DOOR_CLOSE_SOUNDID, DoorCloseSoundDefID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DOOR_UNLOCK_SOUNDID, DoorUnlockSoundDefID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DOOR_ACCESS_DENIED_SOUNDID, DoorAccessDeniedSoundDefID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_ELEVATOR_MOVING_SOUNDID, ElevatorMovingSoundDefID );
- default:
- Debug_Say(( "Unrecognized ElevatorPhys Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- default:
- Debug_Say(( "Unrecognized ElevatorPhys chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- const PersistFactoryClass & ElevatorPhysDefClass::Get_Factory (void) const
- {
- return _ElevatorPhysDefPersistFactory;
- }
- /*
- **
- */
- SimplePersistFactoryClass<ElevatorPhysClass, PHYSICS_CHUNKID_ELEVATORPHYS> _ElevatorPhysPersistFactory;
- const PersistFactoryClass & ElevatorPhysClass::Get_Factory (void) const
- {
- return _ElevatorPhysPersistFactory;
- }
- /*
- **
- */
- ElevatorPhysClass::ElevatorPhysClass( void ) :
- CheckTimer( 0 ),
- State( STATE_UP ),
- MovingSoundObj( NULL ),
- PrevFrame( 0 ),
- IsCallTimerSet( false ),
- CallTimer( 0 ),
- TriggerRequest( 0 )
- {
- DoorStates[TOP] = DOOR_STATE_NORMAL;
- DoorStates[BOTTOM] = DOOR_STATE_NORMAL;
- }
- ElevatorPhysClass::~ElevatorPhysClass( void )
- {
- if ( MovingSoundObj != NULL ) {
- MovingSoundObj->Stop();
- MovingSoundObj->Remove_From_Scene();
- REF_PTR_RELEASE( MovingSoundObj );
- }
- }
- void ElevatorPhysClass::Init( const ElevatorPhysDefClass & def )
- {
- AccessiblePhysClass::Init(def);
- AnimManager.Set_Animation_Mode( AnimCollisionManagerClass::ANIMATE_TARGET );
- AnimManager.Set_Target_Frame( 0 );
- }
- /*
- ** Save and Load
- */
- enum {
- CHUNKID_PARENT = 714001438,
- CHUNKID_VARIABLES,
- CHUNKID_RIDER_OBJECT,
- MICROCHUNKID_ = 1,
- MICROCHUNKID_STATE,
- MICROCHUNKID_TOP_DOOR_STATE,
- MICROCHUNKID_BOTTOM_DOOR_STATE
- };
- bool ElevatorPhysClass::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_PARENT );
- AccessiblePhysClass::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STATE, State );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TOP_DOOR_STATE, DoorStates[TOP] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_BOTTOM_DOOR_STATE, DoorStates[BOTTOM] );
- csave.End_Chunk();
- if ( CurrentAIRider != NULL ) {
- csave.Begin_Chunk( CHUNKID_RIDER_OBJECT );
- CurrentAIRider.Save( csave );
- csave.End_Chunk();
- }
- return true;
- }
- bool ElevatorPhysClass::Load( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_PARENT:
- AccessiblePhysClass::Load( cload );
- break;
- case CHUNKID_RIDER_OBJECT:
- CurrentAIRider.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_TOP_DOOR_STATE, DoorStates[TOP] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_BOTTOM_DOOR_STATE, DoorStates[BOTTOM] );
- default:
- Debug_Say(( "Unrecognized ElevatorPhys Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- default:
- Debug_Say(( "Unrecognized ElevatorPhys chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- AnimManager.Set_Animation_Mode( AnimCollisionManagerClass::ANIMATE_TARGET );
- AnimManager.Set_Target_Frame( 0 );
- return true;
- }
- void ElevatorPhysClass::Save_State( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_PARENT );
- AccessiblePhysClass::Save_State( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STATE, State );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TOP_DOOR_STATE, DoorStates[TOP] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_BOTTOM_DOOR_STATE, DoorStates[BOTTOM] );
- csave.End_Chunk();
- if ( CurrentAIRider != NULL ) {
- csave.Begin_Chunk( CHUNKID_RIDER_OBJECT );
- CurrentAIRider.Save( csave );
- csave.End_Chunk();
- }
- }
- #define LEGACY_STATICANIMPHYS_CHUNK_ANIMMANAGER 0x01170012
- void ElevatorPhysClass::Load_State( ChunkLoadClass &cload )
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_PARENT:
- AccessiblePhysClass::Load_State( cload );
- break;
- case CHUNKID_RIDER_OBJECT:
- CurrentAIRider.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_TOP_DOOR_STATE, DoorStates[TOP] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_BOTTOM_DOOR_STATE, DoorStates[BOTTOM] );
- default:
- Debug_Say(( "Unrecognized ElevatorPhys Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- case LEGACY_STATICANIMPHYS_CHUNK_ANIMMANAGER:
- AnimManager.Load(cload);
- break;
- default:
- Debug_Say(( "Unrecognized ElevatorPhys chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- }
- void ElevatorPhysClass::Timestep( float dt )
- {
- AccessiblePhysClass::Timestep( dt );
- /*const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
- for (int index = 0; index < ZONE_MAX; index ++) {
- OBBoxClass world_box;
- OBBoxClass::Transform( Get_Transform(), def->CallZones[index], &world_box );
- PhysicsSceneClass::Get_Instance ()->Add_Debug_OBBox (world_box, Vector3 (1, 0, 0));
- }*/
-
- {
- WWPROFILE("ElevatorPhys::Timestep");
- // Delayed Open/close
- if ( AnimManager.Peek_Animation() != NULL ) {
-
- //
- // Make sure the door sounds play at the appropriate times
- //
- Update_Sound_Effects();
- if ( IsCallTimerSet ) {
- CallTimer -= dt;
- }
- //
- // Should we evaluate the state of the elevator?
- //
- CheckTimer -= dt;
- if ( CheckTimer <= 0 ) {
- CheckTimer = 0.5F;
- Update_State();
- }
- }
- }
- return ;
- }
- void ElevatorPhysClass::Set_Door_State( int new_state, int door_id )
- {
- if ( new_state != DoorStates[door_id] ) {
-
- switch ( new_state )
- {
- case DOOR_STATE_NORMAL:
- break;
- case DOOR_STATE_UNLOCKED:
- Play_Effect( EFFECT_DOOR_UNLOCKED, door_id == TOP );
- break;
- case DOOR_STATE_ACCESS_DENIED:
- Play_Effect( EFFECT_ACCESS_DENIED, door_id == TOP );
- break;
- }
-
- DoorStates[door_id] = new_state;
- }
- return ;
- }
- void ElevatorPhysClass::Set_State( int new_state )
- {
- if ( new_state != State ) {
-
- switch ( new_state )
- {
- case STATE_DOWN:
- case STATE_UP:
- //
- // Leave the elevator in this state for at least 4 seconds (before it checks
- // to see if it should move to the next level).
- //
- //Timer = 4;
- break;
- case STATE_MOVING_UP:
- AnimManager.Set_Animation_Mode( AnimCollisionManagerClass::ANIMATE_TARGET );
- AnimManager.Set_Target_Frame( 0 );
- break;
- case STATE_MOVING_DOWN:
- AnimManager.Set_Animation_Mode( AnimCollisionManagerClass::ANIMATE_TARGET );
- AnimManager.Set_Target_Frame( AnimManager.Peek_Animation()->Get_Num_Frames() - 1 );
- break;
- }
-
- State = new_state;
- }
- return ;
- }
- void ElevatorPhysClass::Update_State(void)
- {
- switch ( State ) {
- case STATE_MOVING_UP:
- if ( AnimManager.Get_Current_Frame() == 0 ) {
- Set_State( STATE_UP );
- }
- break;
- case STATE_MOVING_DOWN:
- if ( AnimManager.Get_Current_Frame() == AnimManager.Peek_Animation()->Get_Num_Frames() - 1 ) {
- Set_State( STATE_DOWN );
- }
- break;
- case STATE_UP:
- if ( CombatManager::I_Am_Server() ) {
-
- if ( IsCallTimerSet && CallTimer <= 0 ) {
- IsCallTimerSet = false;
- if ( Triggered( ZONE_LOWER_CALL ) || Triggered( ZONE_UPPER_INSIDE ) ) {
- Set_State( STATE_MOVING_DOWN );
- TriggerRequest = 0;
- }
- } else if ( IsCallTimerSet == false ) {
- bool in_call = Triggered( ZONE_LOWER_CALL );
- bool in_inside = Triggered( ZONE_UPPER_INSIDE );
-
- if ( in_call && !in_inside ) {
- IsCallTimerSet = true;
- CallTimer = 1.0F;
- } else if ( in_call || in_inside ) {
- IsCallTimerSet = true;
- CallTimer = 1.0F;
- }
- }
- }
- break;
- case STATE_DOWN:
- if ( CombatManager::I_Am_Server() ) {
-
- if ( IsCallTimerSet && CallTimer <= 0 ) {
- IsCallTimerSet = false;
- if ( Triggered( ZONE_LOWER_INSIDE ) || Triggered( ZONE_UPPER_CALL ) ) {
- Set_State( STATE_MOVING_UP );
- TriggerRequest = 0;
- }
- } else if ( IsCallTimerSet == false ) {
-
- bool in_call = Triggered( ZONE_UPPER_CALL );
- bool in_inside = Triggered( ZONE_LOWER_INSIDE );
- if ( in_call && !in_inside ) {
- IsCallTimerSet = true;
- CallTimer = 1.0F;
- } else if ( in_call || in_inside ) {
- IsCallTimerSet = true;
- CallTimer = 1.0F;
- }
- }
- }
- break;
- }
- return ;
- }
- inline bool Is_Top_Zone ( int zone_id )
- {
- return ((zone_id > ZONE_LOWER_INSIDE) && (zone_id <= ZONE_UPPER_INSIDE));
- }
- inline bool Is_Call_Zone ( int zone_id )
- {
- return (zone_id == ZONE_LOWER_CALL) || (zone_id == ZONE_UPPER_CALL);
- }
- bool ElevatorPhysClass::Triggered( int zone_id )
- {
- const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
- OBBoxClass world_box;
- OBBoxClass::Transform( Get_Transform(), def->CallZones[zone_id], &world_box );
- //
- // Get information about the zone we are checking
- //
- bool is_top = ::Is_Top_Zone( zone_id );
- bool is_call = ::Is_Call_Zone( zone_id );
- //
- // Quick return if an AI is requesting the elevator
- //
- if (TriggerRequest & (1 << zone_id)) {
- return true;
- }
- //
- // Get the list of all the players in the world
- //
- SList<SoldierGameObj> *player_list = GameObjManager::Get_Star_Game_Obj_List();
- //
- // Loop over each player
- //
- SLNode<SoldierGameObj> *objnode;
- for ( objnode = player_list->Head(); objnode; objnode = objnode->Next()) {
- SoldierGameObj *soldier = objnode->Data();
- if ( soldier != NULL ) {
- //
- // Is this player inside the trigger zone?
- //
- Vector3 pos;
- soldier->Get_Position( &pos );
- if ( CollisionMath::Overlap_Test(world_box, pos) == CollisionMath::INSIDE ) {
- //
- // Is the door locked?
- //
- if ( Get_ElevatorPhysDef()->LockCode != 0 ) {
- bool open_door = true;
- if ( is_call ) {
- if ( soldier->Has_Key( Get_ElevatorPhysDef()->LockCode ) ) {
-
- //
- // The player just unlocked this door...
- //
- Set_Door_State( DOOR_STATE_UNLOCKED, is_top ? TOP : BOTTOM );
- } else {
- //
- // Someone tried to enter this door without unlocking it...
- //
- Set_Door_State( DOOR_STATE_ACCESS_DENIED, is_top ? TOP : BOTTOM );
- open_door = false;
- }
- }
- if ( open_door ) {
- return true;
- }
- } else {
-
- //
- // Reset the state of the door to 'normal'
- //
- if ( is_call ) {
- Set_Door_State( DOOR_STATE_NORMAL, is_top ? TOP : BOTTOM );
- }
- return true;
- }
- }
- }
- }
- //
- // Reset the state of the door to 'normal'
- //
- if ( is_call ) {
- Set_Door_State( DOOR_STATE_NORMAL, is_top ? TOP : BOTTOM );
- }
- return false;
- }
- inline bool Has_Frame_Occured (float prev_frame, float current_frame, float target_frame)
- {
- bool retval = false;
- //
- // Check to see if the animation passed the target frame in either direction
- //
- if ( target_frame >= 0 ) {
- retval = ((prev_frame <= target_frame) && (current_frame >= target_frame));
- retval |= ((prev_frame >= target_frame) && (current_frame <= target_frame));
- }
- return retval;
- }
- void ElevatorPhysClass::Update_Sound_Effects( void )
- {
- const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
- float curr_frame = AnimManager.Get_Current_Frame();
- float prev_frame = PrevFrame;
- if ( State == STATE_MOVING_DOWN ) {
- //
- // Check to see if we should play the opening or closing sounds on the door
- //
- if ( Has_Frame_Occured( prev_frame, curr_frame, 0 ) ) {
- Play_Effect( EFFECT_DOOR_CLOSING, true );
- } else if ( Has_Frame_Occured( prev_frame, curr_frame, def->DoorOpeningBottom_FrameNum ) ) {
- Play_Effect( EFFECT_DOOR_OPENING, false );
- }
-
- //
- // Check to see if we should start or stop the elevator moving sound
- //
- if ( Has_Frame_Occured( prev_frame, curr_frame, def->ElevatorStartTop_FrameNum ) ) {
- Play_Effect( EFFECT_ELEVATOR_MOVING, true );
- } else if ( Has_Frame_Occured( prev_frame, curr_frame, def->ElevatorStoppedBottom_FrameNum ) ) {
- Play_Effect( EFFECT_ELEVATOR_STOPPED_MOVING, false );
- }
-
- } else if ( State == STATE_MOVING_UP ) {
- //
- // Check to see if we should play the opening or closing sounds on the door
- //
- if ( Has_Frame_Occured( prev_frame, curr_frame, AnimManager.Peek_Animation()->Get_Num_Frames()-1 ) ) {
- Play_Effect( EFFECT_DOOR_CLOSING, false );
- } else if ( Has_Frame_Occured( prev_frame, curr_frame, def->DoorClosedTop_FrameNum ) ) {
- Play_Effect( EFFECT_DOOR_OPENING, true );
- }
-
- //
- // Check to see if we should start or stop the elevator moving sound
- //
- if ( Has_Frame_Occured( prev_frame, curr_frame, def->ElevatorStoppedBottom_FrameNum ) ) {
- Play_Effect( EFFECT_ELEVATOR_MOVING, false );
- } else if ( Has_Frame_Occured( prev_frame, curr_frame, def->ElevatorStartTop_FrameNum ) ) {
- Play_Effect( EFFECT_ELEVATOR_STOPPED_MOVING, true );
- }
- }
-
- PrevFrame = curr_frame;
- return ;
- }
- void ElevatorPhysClass::Play_Effect( int effect_id, bool is_top )
- {
- const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
- switch ( effect_id )
- {
- case EFFECT_DOOR_OPENING:
- {
- Matrix3D tm(1);
- Get_Door_Transform( is_top, tm );
- WWAudioClass::Get_Instance()->Create_Instant_Sound( def->DoorOpenSoundDefID, tm );
- }
- break;
- case EFFECT_DOOR_CLOSING:
- {
- Matrix3D tm(1);
- Get_Door_Transform( is_top, tm );
- WWAudioClass::Get_Instance()->Create_Instant_Sound( def->DoorCloseSoundDefID, tm );
- }
- break;
- case EFFECT_DOOR_UNLOCKED:
- {
- Matrix3D tm(1);
- Get_Door_Transform( is_top, tm );
- WWAudioClass::Get_Instance()->Create_Instant_Sound( def->DoorUnlockSoundDefID, tm );
- }
- break;
- case EFFECT_ACCESS_DENIED:
- {
- Matrix3D tm(1);
- Get_Door_Transform( is_top, tm );
- WWAudioClass::Get_Instance()->Create_Instant_Sound( def->DoorAccessDeniedSoundDefID, tm );
- }
- break;
- case EFFECT_ELEVATOR_MOVING:
- {
- if ( def->ElevatorMovingSoundDefID != 0 ) {
- RenderObjClass *model = Peek_Model ();
- if (model != NULL) {
-
- //
- // Lookup the bone we need to attach this sound to
- //
- int bone_index = model->Get_Bone_Index( "ELESOUND" );
- if ( bone_index > 0) {
- //
- // Create the sound object (if necessary)
- //
- if ( MovingSoundObj == NULL ) {
- MovingSoundObj = WWAudioClass::Get_Instance ()->Create_Continuous_Sound( def->ElevatorMovingSoundDefID );
- }
- //
- // Attach the sound to the elevator car and insert it into the scene
- //
- if ( MovingSoundObj != NULL ) {
- MovingSoundObj->Attach_To_Object( model, bone_index );
- MovingSoundObj->Add_To_Scene( true );
- }
- }
- }
- }
- }
- break;
- case EFFECT_ELEVATOR_STOPPED_MOVING:
- {
- if ( MovingSoundObj != NULL ) {
- MovingSoundObj->Stop();
- MovingSoundObj->Remove_From_Scene();
- }
- }
- break;
- }
- return ;
- }
- void ElevatorPhysClass::Get_Door_Transform( bool is_top, Matrix3D &tm )
- {
- const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
- tm.Make_Identity();
- Matrix3D curr_tm = Get_Transform();
- //
- // We assume the door is 'about' halfway between the call and inside zones.
- //
- if ( is_top ) {
- Vector3 zone_vector = def->CallZones[ZONE_UPPER_CALL].Center - def->CallZones[ZONE_UPPER_INSIDE].Center;
- Vector3 center_point = def->CallZones[ZONE_UPPER_INSIDE].Center + (zone_vector * 0.5F);
- tm.Set_Translation( center_point + curr_tm.Get_Translation () );
- } else {
- Vector3 zone_vector = def->CallZones[ZONE_LOWER_CALL].Center - def->CallZones[ZONE_LOWER_INSIDE].Center;
- Vector3 center_point = def->CallZones[ZONE_LOWER_INSIDE].Center + (zone_vector * 0.5F);
- tm.Set_Translation( center_point + curr_tm.Get_Translation () );
- }
- return ;
- }
- void ElevatorPhysClass::Set_Precision(void)
- {
- cEncoderList::Set_Precision( BITPACK_ELEVATOR_STATE, 0, (int)ElevatorPhysClass::STATE_MAX );
- cEncoderList::Set_Precision( BITPACK_ELEVATOR_TOP_DOOR_STATE, 0, (int)ElevatorPhysClass::DOOR_STATE_MAX );
- cEncoderList::Set_Precision( BITPACK_ELEVATOR_BOTTOM_DOOR_STATE, 0, (int)ElevatorPhysClass::DOOR_STATE_MAX );
- return ;
- }
- bool ElevatorPhysClass::Can_Object_Enter (SmartGameObj *game_obj)
- {
- bool retval = false;
- WWASSERT( game_obj != NULL && game_obj->Peek_Physical_Object () != NULL );
- if( game_obj == NULL || game_obj->Peek_Physical_Object () == NULL ) {
- return false;
- }
- //
- // Don't let other objects on if we've already got an AI rider
- //
- if (CurrentAIRider != NULL) {
- return false;
- }
- //
- // Get the object's bounding box
- //
- RenderObjClass *model = game_obj->Peek_Physical_Object()->Peek_Model ();
- const AABoxClass &obj_box = model->Get_Bounding_Box ();
- //
- // Get the bottom and top call zones
- //
- const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
- OBBoxClass bottom_box;
- OBBoxClass top_box;
- OBBoxClass::Transform( Get_Transform(), def->CallZones[STATE_DOWN], &bottom_box );
- OBBoxClass::Transform( Get_Transform(), def->CallZones[STATE_UP], &top_box );
- //
- // Which floor is the object waiting on?
- //
- if( CollisionMath::Intersection_Test( bottom_box, obj_box ) ) {
- retval = (State == STATE_DOWN);
- } else if( CollisionMath::Intersection_Test( top_box, obj_box ) ) {
- retval = (State == STATE_UP);
- }
-
- return retval;
- }
- bool ElevatorPhysClass::Can_Object_Exit (SmartGameObj * /*game_obj*/)
- {
- bool retval = false;
- //
- // If the elevator is at rest, then the object can exit
- //
- if (State == STATE_DOWN || State == STATE_UP) {
- retval = true;
- }
- return retval;
- }
- void ElevatorPhysClass::Request_Elevator (SmartGameObj *game_obj)
- {
- WWASSERT( game_obj != NULL && game_obj->Peek_Physical_Object () != NULL );
- if( game_obj == NULL || game_obj->Peek_Physical_Object () == NULL ) {
- return ;
- }
- //
- // Get the object's bounding box
- //
- RenderObjClass *model = game_obj->Peek_Physical_Object()->Peek_Model ();
- const AABoxClass &obj_box = model->Get_Bounding_Box ();
- //
- // Get the bottom and top call zones
- //
- const ElevatorPhysDefClass *def = Get_ElevatorPhysDef();
-
- //
- // See what trigger zone the object is in...
- //
- for ( int index = 0; index < ZONE_MAX; index ++) {
-
- //
- // Transform the trigger zone into world space
- //
- OBBoxClass world_box;
- OBBoxClass::Transform( Get_Transform(), def->CallZones[index], &world_box );
- //
- // Is this the trigger zone the object is standing in?
- //
- if( CollisionMath::Intersection_Test( world_box, obj_box ) ) {
- TriggerRequest |= (1 << index);
- }
- }
-
- return ;
- }
- int ElevatorPhysClass::Get_Floor (void)
- {
- int floor = 13;
- //
- // Return 0 if the elevator is currently sitting on the bottom floor
- // or return 1 if the elevator is sitting at the top floor
- //
- if (State == STATE_DOWN) {
- floor = 0;
- } else if (State == STATE_UP) {
- floor = 1;
- }
- return floor;
- }
|