/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code 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.
Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see .
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef __GAME_MOVER_H__
#define __GAME_MOVER_H__
extern const idEventDef EV_TeamBlocked;
extern const idEventDef EV_PartBlocked;
extern const idEventDef EV_ReachedPos;
extern const idEventDef EV_ReachedAng;
/*
===============================================================================
General movers.
===============================================================================
*/
class idMover : public idEntity {
public:
CLASS_PROTOTYPE( idMover );
idMover();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
virtual void Hide();
virtual void Show();
void SetPortalState( bool open );
protected:
typedef enum {
ACCELERATION_STAGE,
LINEAR_STAGE,
DECELERATION_STAGE,
FINISHED_STAGE
} moveStage_t;
typedef enum {
MOVER_NONE,
MOVER_ROTATING,
MOVER_MOVING,
MOVER_SPLINE
} moverCommand_t;
//
// mover directions. make sure to change script/doom_defs.script if you add any, or change their order
//
typedef enum {
DIR_UP = -1,
DIR_DOWN = -2,
DIR_LEFT = -3,
DIR_RIGHT = -4,
DIR_FORWARD = -5,
DIR_BACK = -6,
DIR_REL_UP = -7,
DIR_REL_DOWN = -8,
DIR_REL_LEFT = -9,
DIR_REL_RIGHT = -10,
DIR_REL_FORWARD = -11,
DIR_REL_BACK = -12
} moverDir_t;
typedef struct {
moveStage_t stage;
int acceleration;
int movetime;
int deceleration;
idVec3 dir;
} moveState_t;
typedef struct {
moveStage_t stage;
int acceleration;
int movetime;
int deceleration;
idAngles rot;
} rotationState_t;
idPhysics_Parametric physicsObj;
void Event_OpenPortal();
void Event_ClosePortal();
void Event_PartBlocked( idEntity *blockingEntity );
void MoveToPos( const idVec3 &pos);
void UpdateMoveSound( moveStage_t stage );
void UpdateRotationSound( moveStage_t stage );
void SetGuiStates( const char *state );
void FindGuiTargets();
void SetGuiState( const char *key, const char *val ) const;
virtual void DoneMoving();
virtual void DoneRotating();
virtual void BeginMove( idThread *thread = NULL );
virtual void BeginRotation( idThread *thread, bool stopwhendone );
moveState_t move;
private:
rotationState_t rot;
int move_thread;
int rotate_thread;
idAngles dest_angles;
idAngles angle_delta;
idVec3 dest_position;
idVec3 move_delta;
float move_speed;
int move_time;
int deceltime;
int acceltime;
bool stopRotation;
bool useSplineAngles;
idEntityPtr splineEnt;
moverCommand_t lastCommand;
float damage;
qhandle_t areaPortal; // 0 = no portal
idList< idEntityPtr, TAG_MOVER > guiTargets;
void VectorForDir( float dir, idVec3 &vec );
idCurve_Spline *GetSpline( idEntity *splineEntity ) const;
void Event_SetCallback();
void Event_TeamBlocked( idEntity *blockedPart, idEntity *blockingEntity );
void Event_StopMoving();
void Event_StopRotating();
void Event_UpdateMove();
void Event_UpdateRotation();
void Event_SetMoveSpeed( float speed );
void Event_SetMoveTime( float time );
void Event_SetDecelerationTime( float time );
void Event_SetAccellerationTime( float time );
void Event_MoveTo( idEntity *ent );
void Event_MoveToPos( idVec3 &pos );
void Event_MoveDir( float angle, float distance );
void Event_MoveAccelerateTo( float speed, float time );
void Event_MoveDecelerateTo( float speed, float time );
void Event_RotateDownTo( int axis, float angle );
void Event_RotateUpTo( int axis, float angle );
void Event_RotateTo( idAngles &angles );
void Event_Rotate( idAngles &angles );
void Event_RotateOnce( idAngles &angles );
void Event_Bob( float speed, float phase, idVec3 &depth );
void Event_Sway( float speed, float phase, idAngles &depth );
void Event_SetAccelSound( const char *sound );
void Event_SetDecelSound( const char *sound );
void Event_SetMoveSound( const char *sound );
void Event_FindGuiTargets();
void Event_InitGuiTargets();
void Event_EnableSplineAngles();
void Event_DisableSplineAngles();
void Event_RemoveInitialSplineAngles();
void Event_StartSpline( idEntity *splineEntity );
void Event_StopSpline();
void Event_Activate( idEntity *activator );
void Event_PostRestore( int start, int total, int accel, int decel, int useSplineAng );
void Event_IsMoving();
void Event_IsRotating();
};
class idSplinePath : public idEntity {
public:
CLASS_PROTOTYPE( idSplinePath );
idSplinePath();
void Spawn();
};
struct floorInfo_s {
idVec3 pos;
idStr door;
int floor;
};
class idElevator : public idMover {
public:
CLASS_PROTOTYPE( idElevator );
idElevator();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
void Event_GotoFloor( int floor );
floorInfo_s * GetFloorInfo( int floor );
protected:
virtual void DoneMoving();
virtual void BeginMove( idThread *thread = NULL );
void SpawnTrigger( const idVec3 &pos );
void GetLocalTriggerPosition();
void Event_Touch( idEntity *other, trace_t *trace );
private:
typedef enum {
INIT,
IDLE,
WAITING_ON_DOORS
} elevatorState_t;
elevatorState_t state;
idList floorInfo;
int currentFloor;
int pendingFloor;
int lastFloor;
bool controlsDisabled;
float returnTime;
int returnFloor;
int lastTouchTime;
class idDoor * GetDoor( const char *name );
void Think();
void OpenInnerDoor();
void OpenFloorDoor( int floor );
void CloseAllDoors();
void DisableAllDoors();
void EnableProperDoors();
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_Activate( idEntity *activator );
void Event_PostFloorArrival();
void Event_SetGuiStates();
};
/*
===============================================================================
Binary movers.
===============================================================================
*/
typedef enum {
MOVER_POS1,
MOVER_POS2,
MOVER_1TO2,
MOVER_2TO1
} moverState_t;
class idMover_Binary : public idEntity {
public:
CLASS_PROTOTYPE( idMover_Binary );
idMover_Binary();
~idMover_Binary();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void PreBind();
virtual void PostBind();
void Enable( bool b );
void InitSpeed( idVec3 &mpos1, idVec3 &mpos2, float mspeed, float maccelTime, float mdecelTime );
void InitTime( idVec3 &mpos1, idVec3 &mpos2, float mtime, float maccelTime, float mdecelTime );
void GotoPosition1();
void GotoPosition2();
void Use_BinaryMover( idEntity *activator );
void SetGuiStates( const char *state );
void UpdateBuddies( int val );
idMover_Binary * GetActivateChain() const { return activateChain; }
idMover_Binary * GetMoveMaster() const { return moveMaster; }
void BindTeam( idEntity *bindTo );
void SetBlocked( bool b );
bool IsBlocked();
idEntity * GetActivator() const;
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
void SetPortalState( bool open );
protected:
idVec3 pos1;
idVec3 pos2;
moverState_t moverState;
idMover_Binary * moveMaster;
idMover_Binary * activateChain;
int soundPos1;
int sound1to2;
int sound2to1;
int soundPos2;
int soundLoop;
float wait;
float damage;
int duration;
int accelTime;
int decelTime;
idEntityPtr activatedBy;
int stateStartTime;
idStr team;
bool enabled;
int move_thread;
int updateStatus; // 1 = lock behaviour, 2 = open close status
idStrList buddies;
idPhysics_Parametric physicsObj;
qhandle_t areaPortal; // 0 = no portal
bool blocked;
bool playerOnly;
idList< idEntityPtr, TAG_MOVER > guiTargets;
void MatchActivateTeam( moverState_t newstate, int time );
void JoinActivateTeam( idMover_Binary *master );
void UpdateMoverSound( moverState_t state );
void SetMoverState( moverState_t newstate, int time );
moverState_t GetMoverState() const { return moverState; }
void FindGuiTargets();
void SetGuiState( const char *key, const char *val ) const;
void Event_SetCallback();
void Event_ReturnToPos1();
void Event_Use_BinaryMover( idEntity *activator );
void Event_Reached_BinaryMover();
void Event_MatchActivateTeam( moverState_t newstate, int time );
void Event_Enable();
void Event_Disable();
void Event_OpenPortal();
void Event_ClosePortal();
void Event_FindGuiTargets();
void Event_InitGuiTargets();
static void GetMovedir( float dir, idVec3 &movedir );
};
class idDoor : public idMover_Binary {
public:
CLASS_PROTOTYPE( idDoor );
idDoor();
~idDoor();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void Think();
virtual void PreBind();
virtual void PostBind();
virtual void Hide();
virtual void Show();
bool IsOpen();
bool IsNoTouch();
bool AllowPlayerOnly( idEntity *ent );
int IsLocked();
void Lock( int f );
void Use( idEntity *other, idEntity *activator );
void Close();
void Open();
void SetCompanion( idDoor *door );
private:
float triggersize;
bool crusher;
bool noTouch;
bool aas_area_closed;
idStr buddyStr;
idClipModel * trigger;
idClipModel * sndTrigger;
int nextSndTriggerTime;
idVec3 localTriggerOrigin;
idMat3 localTriggerAxis;
idStr requires;
int removeItem;
idStr syncLock;
int normalAxisIndex; // door faces X or Y for spectator teleports
idDoor * companionDoor;
void SetAASAreaState( bool closed );
void GetLocalTriggerPosition( const idClipModel *trigger );
void CalcTriggerBounds( float size, idBounds &bounds );
void Event_Reached_BinaryMover();
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_PartBlocked( idEntity *blockingEntity );
void Event_Touch( idEntity *other, trace_t *trace );
void Event_Activate( idEntity *activator );
void Event_StartOpen();
void Event_SpawnDoorTrigger();
void Event_SpawnSoundTrigger();
void Event_Close();
void Event_Open();
void Event_Lock( int f );
void Event_IsOpen();
void Event_Locked();
void Event_SpectatorTouch( idEntity *other, trace_t *trace );
void Event_OpenPortal();
void Event_ClosePortal();
};
class idPlat : public idMover_Binary {
public:
CLASS_PROTOTYPE( idPlat );
idPlat();
~idPlat();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void RunPhysics_NoBlocking();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void Think();
virtual void PreBind();
virtual void PostBind();
private:
idClipModel * trigger;
idVec3 localTriggerOrigin;
idMat3 localTriggerAxis;
void GetLocalTriggerPosition( const idClipModel *trigger );
void SpawnPlatTrigger( idVec3 &pos );
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_PartBlocked( idEntity *blockingEntity );
void Event_Touch( idEntity *other, trace_t *trace );
};
/*
===============================================================================
Special periodic movers.
===============================================================================
*/
class idMover_Periodic : public idEntity {
public:
CLASS_PROTOTYPE( idMover_Periodic );
idMover_Periodic();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
protected:
idPhysics_Parametric physicsObj;
float damage;
void Event_TeamBlocked( idEntity *blockedEntity, idEntity *blockingEntity );
void Event_PartBlocked( idEntity *blockingEntity );
};
class idRotater : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idRotater );
idRotater();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idEntityPtr activatedBy;
void Event_Activate( idEntity *activator );
};
class idBobber : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idBobber );
idBobber();
void Spawn();
private:
};
class idPendulum : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idPendulum );
idPendulum();
void Spawn();
private:
};
class idRiser : public idMover_Periodic {
public:
CLASS_PROTOTYPE( idRiser );
idRiser();
void Spawn();
private:
void Event_Activate( idEntity *activator );
};
#endif /* !__GAME_MOVER_H__ */