312 lines
6.5 KiB
C++
312 lines
6.5 KiB
C++
|
#include "../idlib/precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "Game_local.h"
|
||
|
|
||
|
const idEventDef EV_OpenGate( "<openGate>" );
|
||
|
const idEventDef EV_CloseGate( "<closeGate>" );
|
||
|
|
||
|
//=======================================================
|
||
|
//
|
||
|
// rvTramGate
|
||
|
//
|
||
|
//=======================================================
|
||
|
CLASS_DECLARATION( idAnimatedEntity, rvTramGate )
|
||
|
EVENT( EV_Touch, rvTramGate::Event_Touch )
|
||
|
EVENT( EV_Activate, rvTramGate::Event_Activate )
|
||
|
EVENT( EV_OpenGate, rvTramGate::Event_OpenGate )
|
||
|
EVENT( EV_CloseGate, rvTramGate::Event_CloseGate )
|
||
|
EVENT( EV_Door_Lock, rvTramGate::Event_Lock )
|
||
|
EVENT( EV_Door_IsOpen, rvTramGate::Event_IsOpen )
|
||
|
EVENT( EV_Door_IsLocked, rvTramGate::Event_IsLocked )
|
||
|
END_CLASS
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Spawn
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Spawn() {
|
||
|
SpawnDoors();
|
||
|
|
||
|
AdjustFrameRate();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::~rvTramGate
|
||
|
================
|
||
|
*/
|
||
|
rvTramGate::~rvTramGate() {
|
||
|
doorList.RemoveContents( true );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::SpawnDoors
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::SpawnDoors() {
|
||
|
idDict args;
|
||
|
idVec3 dir = spawnArgs.GetAngles("doorsAxisOffset").ToMat3() * GetPhysics()->GetAxis()[1];
|
||
|
|
||
|
args.Set( "team", GetName() );
|
||
|
args.SetMatrix( "rotation", dir.ToMat3() );
|
||
|
args.SetVector( "origin", GetPhysics()->GetOrigin() );
|
||
|
|
||
|
int len = strlen("door_");
|
||
|
for( const idKeyValue* kv = spawnArgs.MatchPrefix("door"); kv; kv = spawnArgs.MatchPrefix("door", kv) ) {
|
||
|
args.Set( kv->GetKey().Right(kv->GetKey().Length() - len), kv->GetValue() );
|
||
|
}
|
||
|
|
||
|
args.SetFloat( "movedir", (-dir).ToYaw() );
|
||
|
idDoor* door = gameLocal.SpawnSafeEntityDef<idDoor>( spawnArgs.GetString("def_door1"), &args );
|
||
|
if( door ) {
|
||
|
doorList.Alloc() = door;
|
||
|
door->SetDoorFrameController( this );
|
||
|
}
|
||
|
|
||
|
args.SetFloat( "movedir", dir.ToYaw() );
|
||
|
door = gameLocal.SpawnSafeEntityDef<idDoor>( spawnArgs.GetString("def_door2"), &args );
|
||
|
if( door ) {
|
||
|
doorList.Alloc() = door;
|
||
|
door->SetDoorFrameController( this );
|
||
|
}
|
||
|
|
||
|
//assert( GetDoorMaster() == door->GetMoveMaster() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::AdjustFrameRate
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::AdjustFrameRate() {
|
||
|
GetAnimator()->SetPlaybackRate( "open", spawnArgs.GetFloat("openFrameRateScale") );
|
||
|
GetAnimator()->SetPlaybackRate( "close", spawnArgs.GetFloat("closeFrameRateScale") );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::OpenGate
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::OpenGate() {
|
||
|
PlayAnim( ANIMCHANNEL_ALL, "open" );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::CloseGate
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::CloseGate() {
|
||
|
PlayAnim( ANIMCHANNEL_ALL, "close" );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Save
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Save( idSaveGame *savefile ) const {
|
||
|
savefile->WriteInt( doorList.Num() );
|
||
|
for( int i = 0; i < doorList.Num(); i++ ) {
|
||
|
doorList[i].Save( savefile );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Restore
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Restore( idRestoreGame *savefile ) {
|
||
|
int num = 0;
|
||
|
idEntityPtr<idDoor> temp;
|
||
|
savefile->ReadInt( num );
|
||
|
for( int i = 0; i < num; i++ ) {
|
||
|
temp.Restore( savefile );
|
||
|
doorList.Append( temp );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::PlayAnim
|
||
|
================
|
||
|
*/
|
||
|
int rvTramGate::PlayAnim( int channel, const char* animName, int blendFrames ) {
|
||
|
int animHandle = GetAnimator()->GetAnim( animName );
|
||
|
|
||
|
if( !animHandle ) {
|
||
|
ClearAllAnims( blendFrames );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
GetAnimator()->PlayAnim( channel, animHandle, gameLocal.GetTime(), FRAME2MS(blendFrames) );
|
||
|
return GetAnimator()->CurrentAnim(channel)->PlayLength();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::CycleAnim
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::CycleAnim( int channel, const char* animName, int blendFrames ) {
|
||
|
int animHandle = GetAnimator()->GetAnim( animName );
|
||
|
|
||
|
if( !animHandle ) {
|
||
|
ClearAllAnims( blendFrames );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
GetAnimator()->CycleAnim( channel, animHandle, gameLocal.GetTime(), FRAME2MS(blendFrames) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_Touch
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::ClearAllAnims( int blendFrames ) {
|
||
|
GetAnimator()->ClearAllAnims( gameLocal.GetTime(), FRAME2MS(blendFrames) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_Touch
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::ClearAnim( int channel, int blendFrames ) {
|
||
|
GetAnimator()->Clear( channel, gameLocal.GetTime(), FRAME2MS(blendFrames) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_Touch
|
||
|
================
|
||
|
*/
|
||
|
bool rvTramGate::AnimIsPlaying( int channel, int blendFrames ) {
|
||
|
return GetAnimator()->CurrentAnim(channel)->GetEndTime() - FRAME2MS(blendFrames) >= gameLocal.GetTime();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::IsOpen
|
||
|
================
|
||
|
*/
|
||
|
bool rvTramGate::IsOpen() const {
|
||
|
return (IsDoorMasterValid()) ? GetDoorMaster()->IsOpen() : false;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::IsClosed
|
||
|
================
|
||
|
*/
|
||
|
bool rvTramGate::IsClosed() const {
|
||
|
return (IsDoorMasterValid()) ? GetDoorMaster()->IsClosed() : false;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::GetDoorMaster
|
||
|
================
|
||
|
*/
|
||
|
idDoor* rvTramGate::GetDoorMaster() const {
|
||
|
return doorList.Num() ? doorList[0] : NULL;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::IsDoorMasterValid
|
||
|
================
|
||
|
*/
|
||
|
bool rvTramGate::IsDoorMasterValid() const {
|
||
|
return GetDoorMaster() != NULL;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_Touch
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_Touch( idEntity* other, trace_t* trace ) {
|
||
|
if( !IsDoorMasterValid() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if( IsClosed() ) {
|
||
|
OpenGate();
|
||
|
GetDoorMaster()->ProcessEvent( &EV_Touch, this, trace );
|
||
|
} else if( IsOpen() ) {
|
||
|
GetDoorMaster()->ProcessEvent( &EV_Touch, this, trace );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_Activate
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_Activate( idEntity* activator ) {
|
||
|
if( !IsDoorMasterValid() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// FIXME: may need some better logic than this.
|
||
|
const char* animName = (IsClosed()) ? "open" : (IsOpen()) ? "close" : NULL;
|
||
|
if( animName ) {
|
||
|
PlayAnim( ANIMCHANNEL_ALL, animName );
|
||
|
GetDoorMaster()->ProcessEvent( &EV_Activate, this );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_OpenGate
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_OpenGate() {
|
||
|
OpenGate();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_CloseGate
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_CloseGate() {
|
||
|
CloseGate();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_IsOpen
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_IsOpen( void ) {
|
||
|
idThread::ReturnInt( IsOpen() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_IsLocked
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_IsLocked( void ) {
|
||
|
idThread::ReturnInt( (IsDoorMasterValid()) ? GetDoorMaster()->IsLocked() : 0 );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvTramGate::Event_Lock
|
||
|
================
|
||
|
*/
|
||
|
void rvTramGate::Event_Lock( int f ) {
|
||
|
if( IsDoorMasterValid() ) {
|
||
|
GetDoorMaster()->Lock( f );
|
||
|
}
|
||
|
}
|