Initial commit

This commit is contained in:
Brian Harris
2012-11-26 12:58:24 -06:00
parent a5214f79ef
commit 5016f605b8
1115 changed files with 587266 additions and 0 deletions

1272
neo/d3xp/AF.cpp Normal file

File diff suppressed because it is too large Load Diff

120
neo/d3xp/AF.h Normal file
View File

@@ -0,0 +1,120 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_AF_H__
#define __GAME_AF_H__
/*
===============================================================================
Articulated figure controller.
===============================================================================
*/
typedef struct jointConversion_s {
int bodyId; // id of the body
jointHandle_t jointHandle; // handle of joint this body modifies
AFJointModType_t jointMod; // modify joint axis, origin or both
idVec3 jointBodyOrigin; // origin of body relative to joint
idMat3 jointBodyAxis; // axis of body relative to joint
} jointConversion_t;
typedef struct afTouch_s {
idEntity * touchedEnt;
idClipModel * touchedClipModel;
idAFBody * touchedByBody;
} afTouch_t;
class idAF {
public:
idAF();
~idAF();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetAnimator( idAnimator *a ) { animator = a; }
bool Load( idEntity *ent, const char *fileName );
bool IsLoaded() const { return isLoaded && self != NULL; }
const char * GetName() const { return name.c_str(); }
void SetupPose( idEntity *ent, int time );
void ChangePose( idEntity *ent, int time );
int EntitiesTouchingAF( afTouch_t touchList[ MAX_GENTITIES ] ) const;
void Start();
void StartFromCurrentPose( int inheritVelocityTime );
void Stop();
void Rest();
bool IsActive() const { return isActive; }
void SetConstraintPosition( const char *name, const idVec3 &pos );
idPhysics_AF * GetPhysics() { return &physicsObj; }
const idPhysics_AF * GetPhysics() const { return &physicsObj; }
idBounds GetBounds() const;
bool UpdateAnimation();
void GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) const;
void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
int BodyForClipModelId( int id ) const;
void SaveState( idDict &args ) const;
void LoadState( const idDict &args );
void AddBindConstraints();
void RemoveBindConstraints();
protected:
idStr name; // name of the loaded .af file
idPhysics_AF physicsObj; // articulated figure physics
idEntity * self; // entity using the animated model
idAnimator * animator; // animator on entity
int modifiedAnim; // anim to modify
idVec3 baseOrigin; // offset of base body relative to skeletal model origin
idMat3 baseAxis; // axis of base body relative to skeletal model origin
idList<jointConversion_t, TAG_AF> jointMods; // list with transforms from skeletal model joints to articulated figure bodies
idList<int, TAG_AF> jointBody; // table to find the nearest articulated figure body for a joint of the skeletal model
int poseTime; // last time the articulated figure was transformed to reflect the current animation pose
int restStartTime; // time the articulated figure came to rest
bool isLoaded; // true when the articulated figure is properly loaded
bool isActive; // true if the articulated figure physics is active
bool hasBindConstraints; // true if the bind constraints have been added
protected:
void SetBase( idAFBody *body, const idJointMat *joints );
void AddBody( idAFBody *body, const idJointMat *joints, const char *jointName, const AFJointModType_t mod );
bool LoadBody( const idDeclAF_Body *fb, const idJointMat *joints );
bool LoadConstraint( const idDeclAF_Constraint *fc );
bool TestSolid() const;
};
#endif /* !__GAME_AF_H__ */

3676
neo/d3xp/AFEntity.cpp Normal file

File diff suppressed because it is too large Load Diff

597
neo/d3xp/AFEntity.h Normal file
View File

@@ -0,0 +1,597 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_AFENTITY_H__
#define __GAME_AFENTITY_H__
/*
===============================================================================
idMultiModelAF
Entity using multiple separate visual models animated with a single
articulated figure. Only used for debugging!
===============================================================================
*/
const int GIB_DELAY = 200; // only gib this often to keep performace hits when blowing up several mobs
class idMultiModelAF : public idEntity {
public:
CLASS_PROTOTYPE( idMultiModelAF );
void Spawn();
~idMultiModelAF();
virtual void Think();
virtual void Present();
protected:
idPhysics_AF physicsObj;
void SetModelForId( int id, const idStr &modelName );
private:
idList<idRenderModel *, TAG_AF> modelHandles;
idList<int, TAG_AF> modelDefHandles;
};
/*
===============================================================================
idChain
Chain hanging down from the ceiling. Only used for debugging!
===============================================================================
*/
class idChain : public idMultiModelAF {
public:
CLASS_PROTOTYPE( idChain );
void Spawn();
protected:
void BuildChain( const idStr &name, const idVec3 &origin, float linkLength, float linkWidth, float density, int numLinks, bool bindToWorld = true );
};
/*
===============================================================================
idAFAttachment
===============================================================================
*/
class idAFAttachment : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idAFAttachment );
idAFAttachment();
virtual ~idAFAttachment();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetBody( idEntity *bodyEnt, const char *headModel, jointHandle_t attachJoint );
void ClearBody();
idEntity * GetBody() const;
virtual void Think();
virtual void Hide();
virtual void Show();
void PlayIdleAnim( int blendTime );
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
void SetCombatModel();
idClipModel * GetCombatModel() const;
virtual void LinkCombat();
virtual void UnlinkCombat();
protected:
idEntity * body;
idClipModel * combatModel; // render model for hit detection of head
int idleAnim;
jointHandle_t attachJoint;
};
/*
===============================================================================
idAFEntity_Base
===============================================================================
*/
class idAFEntity_Base : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idAFEntity_Base );
idAFEntity_Base();
virtual ~idAFEntity_Base();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual bool UpdateAnimationControllers();
virtual void FreeModelDef();
virtual bool LoadAF();
bool IsActiveAF() const { return af.IsActive(); }
const char * GetAFName() const { return af.GetName(); }
idPhysics_AF * GetAFPhysics() { return af.GetPhysics(); }
void SetCombatModel();
idClipModel * GetCombatModel() const;
// contents of combatModel can be set to 0 or re-enabled (mp)
void SetCombatContents( bool enable );
virtual void LinkCombat();
virtual void UnlinkCombat();
int BodyForClipModelId( int id ) const;
void SaveState( idDict &args ) const;
void LoadState( const idDict &args );
void AddBindConstraints();
void RemoveBindConstraints();
virtual void ShowEditingDialog();
static void DropAFs( idEntity *ent, const char *type, idList<idEntity *> *list );
protected:
idAF af; // articulated figure
idClipModel * combatModel; // render model for hit detection
int combatModelContents;
idVec3 spawnOrigin; // spawn origin
idMat3 spawnAxis; // rotation axis used when spawned
int nextSoundTime; // next time this can make a sound
void Event_SetConstraintPosition( const char *name, const idVec3 &pos );
};
/*
===============================================================================
idAFEntity_Gibbable
===============================================================================
*/
extern const idEventDef EV_Gib;
extern const idEventDef EV_Gibbed;
class idAFEntity_Gibbable : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_Gibbable );
idAFEntity_Gibbable();
~idAFEntity_Gibbable();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Present();
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
void SetThrown( bool isThrown );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
bool IsGibbed() { return gibbed; };
protected:
idRenderModel * skeletonModel;
int skeletonModelDefHandle;
bool gibbed;
bool wasThrown;
virtual void Gib( const idVec3 &dir, const char *damageDefName );
void InitSkeletonModel();
void Event_Gib( const char *damageDefName );
};
/*
===============================================================================
idAFEntity_Generic
===============================================================================
*/
class idAFEntity_Generic : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAFEntity_Generic );
idAFEntity_Generic();
~idAFEntity_Generic();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
void KeepRunningPhysics() { keepRunningPhysics = true; }
private:
void Event_Activate( idEntity *activator );
bool keepRunningPhysics;
};
/*
===============================================================================
idAFEntity_WithAttachedHead
===============================================================================
*/
class idAFEntity_WithAttachedHead : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAFEntity_WithAttachedHead );
idAFEntity_WithAttachedHead();
~idAFEntity_WithAttachedHead();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetupHead();
virtual void Think();
virtual void Hide();
virtual void Show();
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
virtual void LinkCombat();
virtual void UnlinkCombat();
protected:
virtual void Gib( const idVec3 &dir, const char *damageDefName );
public:
idEntityPtr<idAFAttachment> head;
void Event_Gib( const char *damageDefName );
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idAFEntity_Vehicle
===============================================================================
*/
class idAFEntity_Vehicle : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_Vehicle );
idAFEntity_Vehicle();
void Spawn();
void Use( idPlayer *player );
protected:
idPlayer * player;
jointHandle_t eyesJoint;
jointHandle_t steeringWheelJoint;
float wheelRadius;
float steerAngle;
float steerSpeed;
const idDeclParticle * dustSmoke;
float GetSteerAngle();
};
/*
===============================================================================
idAFEntity_VehicleSimple
===============================================================================
*/
class idAFEntity_VehicleSimple : public idAFEntity_Vehicle {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleSimple );
idAFEntity_VehicleSimple();
~idAFEntity_VehicleSimple();
void Spawn();
virtual void Think();
protected:
idClipModel * wheelModel;
idAFConstraint_Suspension * suspension[4];
jointHandle_t wheelJoints[4];
float wheelAngles[4];
};
/*
===============================================================================
idAFEntity_VehicleFourWheels
===============================================================================
*/
class idAFEntity_VehicleFourWheels : public idAFEntity_Vehicle {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleFourWheels );
idAFEntity_VehicleFourWheels();
void Spawn();
virtual void Think();
protected:
idAFBody * wheels[4];
idAFConstraint_Hinge * steering[2];
jointHandle_t wheelJoints[4];
float wheelAngles[4];
};
/*
===============================================================================
idAFEntity_VehicleSixWheels
===============================================================================
*/
class idAFEntity_VehicleSixWheels : public idAFEntity_Vehicle {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleSixWheels );
idAFEntity_VehicleSixWheels();
void Spawn();
virtual void Think();
float force;
float velocity;
float steerAngle;
private:
idAFBody * wheels[6];
idAFConstraint_Hinge * steering[4];
jointHandle_t wheelJoints[6];
float wheelAngles[6];
};
/*
===============================================================================
idAFEntity_VehicleAutomated
===============================================================================
*/
class idAFEntity_VehicleAutomated : public idAFEntity_VehicleSixWheels {
public:
CLASS_PROTOTYPE( idAFEntity_VehicleAutomated );
void Spawn();
void PostSpawn();
virtual void Think();
private:
idEntity *waypoint;
float steeringSpeed;
float currentSteering;
float idealSteering;
float originHeight;
void Event_SetVelocity( float _velocity );
void Event_SetTorque( float _torque );
void Event_SetSteeringSpeed( float _steeringSpeed );
void Event_SetWayPoint( idEntity *_waypoint );
};
/*
===============================================================================
idAFEntity_SteamPipe
===============================================================================
*/
class idAFEntity_SteamPipe : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_SteamPipe );
idAFEntity_SteamPipe();
~idAFEntity_SteamPipe();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
private:
int steamBody;
float steamForce;
float steamUpForce;
idForce_Constant force;
renderEntity_t steamRenderEntity;
qhandle_t steamModelDefHandle;
void InitSteamRenderEntity();
};
/*
===============================================================================
idAFEntity_ClawFourFingers
===============================================================================
*/
class idAFEntity_ClawFourFingers : public idAFEntity_Base {
public:
CLASS_PROTOTYPE( idAFEntity_ClawFourFingers );
idAFEntity_ClawFourFingers();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idAFConstraint_Hinge * fingers[4];
void Event_SetFingerAngle( float angle );
void Event_StopFingers();
};
/**
* idHarvestable contains all of the code required to turn an entity into a harvestable
* entity. The entity must create an instance of this class and call the appropriate
* interface methods at the correct time.
*/
class idHarvestable : public idEntity {
public:
CLASS_PROTOTYPE( idHarvestable );
idHarvestable();
~idHarvestable();
void Spawn();
void Init(idEntity* parent);
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetParent(idEntity* parent);
void Think();
void Gib();
protected:
idEntityPtr<idEntity> parentEnt;
float triggersize;
idClipModel * trigger;
float giveDelay;
float removeDelay;
bool given;
idEntityPtr<idPlayer> player;
int startTime;
bool fxFollowPlayer;
idEntityPtr<idEntityFx> fx;
idStr fxOrient;
protected:
void BeginBurn();
void BeginFX();
void CalcTriggerBounds( float size, idBounds &bounds );
bool GetFxOrientationAxis(idMat3& mat);
void Event_SpawnHarvestTrigger();
void Event_Touch( idEntity *other, trace_t *trace );
} ;
/*
===============================================================================
idAFEntity_Harvest
===============================================================================
*/
class idAFEntity_Harvest : public idAFEntity_WithAttachedHead {
public:
CLASS_PROTOTYPE( idAFEntity_Harvest );
idAFEntity_Harvest();
~idAFEntity_Harvest();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
virtual void Gib( const idVec3 &dir, const char *damageDefName );
protected:
idEntityPtr<idHarvestable> harvestEnt;
protected:
void Event_SpawnHarvestEntity();
};
#endif /* !__GAME_AFENTITY_H__ */

537
neo/d3xp/Achievements.cpp Normal file
View File

@@ -0,0 +1,537 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "..\..\doomclassic\doom\doomdef.h"
idCVar achievements_Verbose( "achievements_Verbose", "1", CVAR_BOOL, "debug spam" );
idCVar g_demoMode( "g_demoMode", "0", CVAR_INTEGER, "this is a demo" );
bool idAchievementManager::cheatingDialogShown = false;
const struct achievementInfo_t {
int required;
bool lifetime; // true means the current count is stored on the player profile. Doesn't matter for single count achievements.
} achievementInfo [ACHIEVEMENTS_NUM] = {
{ 50, true }, // ACHIEVEMENT_EARN_ALL_50_TROPHIES
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_0
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_1
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_2
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_3
{ 64, false }, // ACHIEVEMENT_PDAS_BASE
{ 14, false }, // ACHIEVEMENT_WATCH_ALL_VIDEOS
{ 1, false }, // ACHIEVEMENT_KILL_MONSTER_WITH_1_HEALTH_LEFT
{ 35, false }, // ACHIEVEMENT_OPEN_ALL_LOCKERS
{ 20, true }, // ACHIEVEMENT_KILL_20_ENEMY_FISTS_HANDS
{ 1, true }, // ACHIEVEMENT_KILL_SCI_NEXT_TO_RCR
{ 1, true }, // ACHIEVEMENT_KILL_TWO_IMPS_ONE_SHOTGUN
{ 1, true }, // ACHIEVEMENT_SCORE_25000_TURKEY_PUNCHER
{ 50, true }, // ACHIEVEMENT_DESTROY_BARRELS
{ 1, true }, // ACHIEVEMENT_GET_BFG_FROM_SECURITY_OFFICE
{ 1, true }, // ACHIEVEMENT_COMPLETE_LEVEL_WITHOUT_TAKING_DMG
{ 1, true }, // ACHIEVEMENT_FIND_RAGE_LOGO
{ 1, true }, // ACHIEVEMENT_SPEED_RUN
{ 1, true }, // ACHIEVEMENT_DEFEAT_VAGARY_BOSS
{ 1, true }, // ACHIEVEMENT_DEFEAT_GUARDIAN_BOSS
{ 1, true }, // ACHIEVEMENT_DEFEAT_SABAOTH_BOSS
{ 1, true }, // ACHIEVEMENT_DEFEAT_CYBERDEMON_BOSS
{ 1, true }, // ACHIEVEMENT_SENTRY_BOT_ALIVE_TO_DEST
{ 20, true }, // ACHIEVEMENT_KILL_20_ENEMY_WITH_CHAINSAW
{ 1, true }, // ACHIEVEMENT_ID_LOGO_SECRET_ROOM
{ 1, true }, // ACHIEVEMENT_BLOODY_HANDWORK_OF_BETRUGER
{ 1, true }, // ACHIEVEMENT_TWO_DEMONS_FIGHT_EACH_OTHER
{ 20, true }, // ACHIEVEMENT_USE_SOUL_CUBE_TO_DEFEAT_20_ENEMY
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_0
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_1
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_2
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_3
{ 22, false }, // ACHIEVEMENT_PDAS_ROE
{ 1, true }, // ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME
{ 1, true }, // ACHIEVEMENT_DEFEAT_HELLTIME_HUNTER
{ 1, true }, // ACHIEVEMENT_DEFEAT_BERSERK_HUNTER
{ 1, true }, // ACHIEVEMENT_DEFEAT_INVULNERABILITY_HUNTER
{ 1, true }, // ACHIEVEMENT_DEFEAT_MALEDICT_BOSS
{ 20, true }, // ACHIEVEMENT_GRABBER_KILL_20_ENEMY
{ 20, true }, // ACHIEVEMENT_ARTIFACT_WITH_BERSERK_PUNCH_20
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_0
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_1
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_2
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_3
{ 10, false }, // ACHIEVEMENT_PDAS_LE
{ 1, true }, // ACHIEVEMENT_MP_KILL_PLAYER_VIA_TELEPORT
{ 1, true }, // ACHIEVEMENT_MP_CATCH_ENEMY_IN_ROFC
{ 5, true }, // ACHIEVEMENT_MP_KILL_5_PLAYERS_USING_INVIS
{ 1, true }, // ACHIEVEMENT_MP_COMPLETE_MATCH_WITHOUT_DYING
{ 1, true }, // ACHIEVEMENT_MP_USE_BERSERK_TO_KILL_PLAYER
{ 1, true }, // ACHIEVEMENT_MP_KILL_2_GUYS_IN_ROOM_WITH_BFG
};
/*
================================================================================================
idAchievementManager
================================================================================================
*/
/*
========================
idAchievementManager::idAchievementManager
========================
*/
idAchievementManager::idAchievementManager() :
lastImpKilledTime( 0 ),
lastPlayerKilledTime( 0 ),
playerTookDamage( false ) {
counts.Zero();
ResetHellTimeKills();
}
/*
========================
idAchievementManager::Init
========================
*/
void idAchievementManager::Init( idPlayer * player ) {
owner = player;
SyncAchievments();
}
/*
========================
idAchievementManager::SyncAchievments
========================
*/
void idAchievementManager::SyncAchievments() {
idLocalUser * user = GetLocalUser();
if ( user == NULL || user->GetProfile() == NULL ) {
return;
}
// Set achievement counts
for ( int i = 0; i < counts.Num(); i++ ) {
if ( user->GetProfile()->GetAchievement( i ) ) {
counts[i] = achievementInfo[i].required;
} else if ( achievementInfo[i].lifetime ) {
counts[i] = user->GetStatInt( i );
}
}
}
/*
========================
idAchievementManager::GetLocalUser
========================
*/
idLocalUser * idAchievementManager::GetLocalUser() {
if ( !verify( owner != NULL ) ) {
return NULL;
}
return session->GetGameLobbyBase().GetLocalUserFromLobbyUser( gameLocal.lobbyUserIDs[ owner->GetEntityNumber() ] );
}
/*
========================
idAchievementManager::Save
========================
*/
void idAchievementManager::Save( idSaveGame * savefile ) const {
owner.Save( savefile );
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
savefile->WriteInt( counts[i] );
}
savefile->WriteInt( lastImpKilledTime );
savefile->WriteInt( lastPlayerKilledTime );
savefile->WriteBool( playerTookDamage );
savefile->WriteInt( currentHellTimeKills );
}
/*
========================
idAchievementManager::Restore
========================
*/
void idAchievementManager::Restore( idRestoreGame * savefile ) {
owner.Restore( savefile );
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
savefile->ReadInt( counts[i] );
}
savefile->ReadInt( lastImpKilledTime );
savefile->ReadInt( lastPlayerKilledTime );
savefile->ReadBool( playerTookDamage );
savefile->ReadInt( currentHellTimeKills );
SyncAchievments();
}
/*
========================
idAchievementManager::EventCompletesAchievement
========================
*/
void idAchievementManager::EventCompletesAchievement( const achievement_t eventId ) {
if ( g_demoMode.GetBool() ) {
return;
}
idLocalUser * localUser = GetLocalUser();
if ( localUser == NULL || localUser->GetProfile() == NULL ) {
// Send a Reliable Message to the User that needs to unlock this.
if ( owner != NULL ) {
int playerId = owner->entityNumber;
const int bufferSize = sizeof( playerId ) + sizeof( eventId );
byte buffer[ bufferSize ];
idBitMsg msg;
msg.InitWrite( buffer, bufferSize );
msg.WriteByte( playerId );
msg.WriteByte( eventId );
msg.WriteByteAlign();
idLib::Printf( "Host Sending Achievement\n");
session->GetActingGameStateLobbyBase().SendReliableToLobbyUser( gameLocal.lobbyUserIDs[ owner->entityNumber ], GAME_RELIABLE_MESSAGE_ACHIEVEMENT_UNLOCK, msg );
}
return; // Remote user or build game
}
// Check to see if we've already given the achievement.
// If so, don't do again because we don't want to autosave every time a trigger is hit
if ( localUser->GetProfile()->GetAchievement( eventId ) ) {
return;
}
#ifdef ID_RETAIL
if ( common->GetConsoleUsed() ) {
if ( !cheatingDialogShown ) {
common->Dialog().AddDialog( GDM_ACHIEVEMENTS_DISABLED_DUE_TO_CHEATING, DIALOG_ACCEPT, NULL, NULL, true );
cheatingDialogShown = true;
}
return;
}
#endif
counts[eventId]++;
if ( counts[eventId] >= achievementInfo[eventId].required ) {
session->GetAchievementSystem().AchievementUnlock( localUser, eventId );
} else {
if ( achievementInfo[eventId].lifetime ) {
localUser->SetStatInt( eventId, counts[eventId] );
}
}
}
/*
========================
idAchievementManager::IncrementHellTimeKills
========================
*/
void idAchievementManager::IncrementHellTimeKills() {
currentHellTimeKills++;
if ( currentHellTimeKills >= 5 ) {
EventCompletesAchievement( ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME );
}
}
/*
========================
idAchievementManager::SavePersistentData
========================
*/
void idAchievementManager::SavePersistentData( idDict & playerInfo ) {
for ( int i = 0; i < ACHIEVEMENTS_NUM; ++i ) {
playerInfo.SetInt( va( "ach_%d", i ), counts[i] );
}
}
/*
========================
idAchievementManager::RestorePersistentData
========================
*/
void idAchievementManager::RestorePersistentData( const idDict & spawnArgs ) {
for( int i = 0; i < ACHIEVEMENTS_NUM; ++i ) {
counts[i] = spawnArgs.GetInt( va( "ach_%d", i), "0" );
}
}
/*
========================
idAchievementManager::LocalUser_CompleteAchievement
========================
*/
void idAchievementManager::LocalUser_CompleteAchievement( achievement_t id ) {
idLocalUser * localUser = session->GetSignInManager().GetMasterLocalUser();
// Check to see if we've already given the achievement.
// If so, don't do again because we don't want to autosave every time a trigger is hit
if( localUser == NULL || localUser->GetProfile()->GetAchievement( id ) ) {
return;
}
#ifdef ID_RETAIL
if ( common->GetConsoleUsed() ) {
if ( !cheatingDialogShown ) {
common->Dialog().AddDialog( GDM_ACHIEVEMENTS_DISABLED_DUE_TO_CHEATING, DIALOG_ACCEPT, NULL, NULL, true );
cheatingDialogShown = true;
}
return;
}
#endif
session->GetAchievementSystem().AchievementUnlock( localUser, id );
}
/*
========================
idAchievementManager::CheckDoomClassicsAchievements
Processed when the player finishes a level.
========================
*/
void idAchievementManager::CheckDoomClassicsAchievements( int killcount, int itemcount, int secretcount, int skill, int mission, int map, int episode, int totalkills, int totalitems, int totalsecret ) {
const skill_t difficulty = (skill_t)skill;
const currentGame_t currentGame = common->GetCurrentGame();
const GameMission_t expansion = (GameMission_t)mission;
idLocalUser * localUser = session->GetSignInManager().GetMasterLocalUser();
if ( localUser != NULL && localUser->GetProfile() != NULL ) {
// GENERAL ACHIEVEMENT UNLOCKING.
if( currentGame == DOOM_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_NEOPHYTE_COMPLETE_ANY_LEVEL );
} else if( currentGame == DOOM2_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_JUST_GETTING_STARTED_COMPLETE_ANY_LEVEL );
}
// Complete Any Level on Nightmare.
if ( difficulty == sk_nightmare && currentGame == DOOM_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_NIGHTMARE_COMPLETE_ANY_LEVEL_NIGHTMARE );
}
const bool gotAllKills = killcount >= totalkills;
const bool gotAllItems = itemcount >= totalitems;
const bool gotAllSecrets = secretcount >= totalsecret;
if ( gotAllItems && gotAllKills && gotAllSecrets ) {
if( currentGame == DOOM_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS );
} else if( currentGame == DOOM2_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS );
}
}
// DOOM EXPANSION ACHIEVEMENTS
if( expansion == doom ) {
if( map == 8 ) {
// Medium or higher skill level.
if( difficulty >= sk_medium ) {
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
}
// Hard or higher skill level.
if( difficulty >= sk_hard ) {
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD + ( episode - 1 ), 1 );
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
}
if ( difficulty == sk_nightmare ) {
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD + ( episode - 1 ), 1 );
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
}
// Save the Settings.
localUser->SaveProfileSettings();
}
// Check to see if we've completed all episodes.
const int episode1completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM );
const int episode2completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_2_MEDIUM );
const int episode3completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_3_MEDIUM );
const int episode4completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_4_MEDIUM );
const int episode1completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD );
const int episode2completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_2_HARD );
const int episode3completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_3_HARD );
const int episode4completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_4_HARD );
if ( currentGame == DOOM_CLASSIC ) {
if ( episode1completed ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE1_COMPLETE_MEDIUM );
}
if ( episode2completed ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE2_COMPLETE_MEDIUM );
}
if ( episode3completed ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE3_COMPLETE_MEDIUM );
}
if ( episode4completed ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE4_COMPLETE_MEDIUM );
}
if ( episode1completed_hard && episode2completed_hard && episode3completed_hard && episode4completed_hard ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_RAMPAGE_COMPLETE_ALL_HARD );
}
}
} else if( expansion == doom2 ) {
if( map == 30 ) {
if ( currentGame == DOOM2_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_FROM_EARTH_TO_HELL_COMPLETE_HELL_ON_EARTH );
if ( difficulty >= sk_hard ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_SUPERIOR_FIREPOWER_COMPLETE_ALL_HARD );
}
}
}
} else if( expansion == pack_nerve ) {
if( map == 8 ) {
if ( currentGame == DOOM2_CLASSIC ) {
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_AND_BACK_AGAIN_COMPLETE_NO_REST );
}
}
}
}
}
/*
=================
AchievementsReset
=================
*/
CONSOLE_COMMAND( AchievementsReset, "Lock an achievement", NULL ) {
idLocalUser * user = session->GetSignInManager().GetMasterLocalUser();
if ( user == NULL ) {
idLib::Printf( "Must be signed in\n" );
return;
}
if ( args.Argc() == 1 ) {
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
user->SetStatInt( i, 0 );
session->GetAchievementSystem().AchievementLock( user, i );
}
} else {
int i = atoi( args.Argv( 1 ) );
user->SetStatInt( i, 0 );
session->GetAchievementSystem().AchievementLock( user, i );
}
user->SaveProfileSettings();
}
/*
=================
AchievementsUnlock
=================
*/
CONSOLE_COMMAND( AchievementsUnlock, "Unlock an achievement", NULL ) {
idLocalUser * user = session->GetSignInManager().GetMasterLocalUser();
if ( user == NULL ) {
idLib::Printf( "Must be signed in\n" );
return;
}
if ( args.Argc() == 1 ) {
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
user->SetStatInt( i, achievementInfo[i].required );
session->GetAchievementSystem().AchievementUnlock( user, i );
}
} else {
int i = atoi( args.Argv( 1 ) );
user->SetStatInt( i, achievementInfo[i].required );
session->GetAchievementSystem().AchievementUnlock( user, i );
}
user->SaveProfileSettings();
}
/*
=================
AchievementsList
=================
*/
CONSOLE_COMMAND( AchievementsList, "Lists achievements and status", NULL ) {
idPlayer * player = gameLocal.GetLocalPlayer();
idLocalUser * user = ( player == NULL ) ? session->GetSignInManager().GetMasterLocalUser() : session->GetGameLobbyBase().GetLocalUserFromLobbyUser( gameLocal.lobbyUserIDs[ player->GetEntityNumber() ] );
if ( user == NULL ) {
idLib::Printf( "Must be signed in\n" );
return;
}
idPlayerProfile * profile = user->GetProfile();
idArray<bool, 128> achievementState;
bool achievementStateValid = session->GetAchievementSystem().GetAchievementState( user, achievementState );
for ( int i = 0; i < ACHIEVEMENTS_NUM; i++ ) {
const char * pInfo = "";
if ( profile == NULL ) {
pInfo = S_COLOR_RED "unknown" S_COLOR_DEFAULT;
} else if ( !profile->GetAchievement( i ) ) {
pInfo = S_COLOR_YELLOW "locked" S_COLOR_DEFAULT;
} else {
pInfo = S_COLOR_GREEN "unlocked" S_COLOR_DEFAULT;
}
const char * sInfo = "";
if ( !achievementStateValid ) {
sInfo = S_COLOR_RED "unknown" S_COLOR_DEFAULT;
} else if ( !achievementState[i] ) {
sInfo = S_COLOR_YELLOW "locked" S_COLOR_DEFAULT;
} else {
sInfo = S_COLOR_GREEN "unlocked" S_COLOR_DEFAULT;
}
int count = 0;
if ( achievementInfo[i].lifetime ) {
count = user->GetStatInt( i );
} else if ( player != NULL ) {
count = player->GetAchievementManager().GetCount( (achievement_t) i );
} else {
count = 0;
}
achievementDescription_t data;
bool descriptionValid = session->GetAchievementSystem().GetAchievementDescription( user, i, data );
idLib::Printf( "%02d: %2d/%2d | %12.12s | %12.12s | %s%s\n", i, count, achievementInfo[i].required, pInfo, sInfo, descriptionValid ? data.hidden ? "(hidden) " : "" : "(unknown) ", descriptionValid ? data.name : "" );
}
}

184
neo/d3xp/Achievements.h Normal file
View File

@@ -0,0 +1,184 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __ACHIEVEMENTS_H__
#define __ACHIEVEMENTS_H__
enum achievement_t {
ACHIEVEMENT_INVALID = -1,
ACHIEVEMENT_EARN_ALL_50_TROPHIES, // 0 // DONE -- (automagic?)
ACHIEVEMENT_COMPLETED_DIFFICULTY_0, // 1 // DONE -- Recruit
ACHIEVEMENT_COMPLETED_DIFFICULTY_1, // 2 // DONE -- Marine
ACHIEVEMENT_COMPLETED_DIFFICULTY_2, // 3 // DONE -- Veteran
ACHIEVEMENT_COMPLETED_DIFFICULTY_3, // 4 // DONE -- Nightmare
ACHIEVEMENT_PDAS_BASE, // 5 // DONE --
ACHIEVEMENT_WATCH_ALL_VIDEOS, // 6 // DONE --
ACHIEVEMENT_KILL_MONSTER_WITH_1_HEALTH_LEFT, // 7 // DONE --
ACHIEVEMENT_OPEN_ALL_LOCKERS, // 8 // DONE --
ACHIEVEMENT_KILL_20_ENEMY_FISTS_HANDS, // 9 // DONE --- kill 20 enemies with fists & hands
ACHIEVEMENT_KILL_SCI_NEXT_TO_RCR, // 10 // DONE -----> ADD TARGET TO MAP kill scientist trapped next to reactor control room
ACHIEVEMENT_KILL_TWO_IMPS_ONE_SHOTGUN, // 11 // DONE --
ACHIEVEMENT_SCORE_25000_TURKEY_PUNCHER, // 12 // DONE --
ACHIEVEMENT_DESTROY_BARRELS, // 13 // DONE --
ACHIEVEMENT_GET_BFG_FROM_SECURITY_OFFICE, // 14 // DONE -----> ADD TARGET TO MAP
ACHIEVEMENT_COMPLETE_LEVEL_WITHOUT_TAKING_DMG, // 15 // DONE --
ACHIEVEMENT_FIND_RAGE_LOGO, // 16 // DONE -----> ADD TARGET TO MAP (jerry)
ACHIEVEMENT_SPEED_RUN, // 17 // DONE --
ACHIEVEMENT_DEFEAT_VAGARY_BOSS, // 18 // DONE --
ACHIEVEMENT_DEFEAT_GUARDIAN_BOSS, // 19 // DONE --
ACHIEVEMENT_DEFEAT_SABAOTH_BOSS, // 20 // DONE --
ACHIEVEMENT_DEFEAT_CYBERDEMON_BOSS, // 21 // DONE --
ACHIEVEMENT_SENTRY_BOT_ALIVE_TO_DEST, // 22 // DONE -----> ADD TARGET TO MAP
ACHIEVEMENT_KILL_20_ENEMY_WITH_CHAINSAW, // 23 // DONE --
ACHIEVEMENT_ID_LOGO_SECRET_ROOM, // 24 // DONE -----> ADD TARGET TO MAP
ACHIEVEMENT_BLOODY_HANDWORK_OF_BETRUGER, // 25 // DONE -----> ADD TARGET TO MAP
ACHIEVEMENT_TWO_DEMONS_FIGHT_EACH_OTHER, // 26 // DONE --
ACHIEVEMENT_USE_SOUL_CUBE_TO_DEFEAT_20_ENEMY, // 27 // DONE --
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_0, // 28 // DONE -- Recruit
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_1, // 29 // DONE -- Marine
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_2, // 30 // DONE -- Veteran
ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_3, // 31 // DONE -- Nightmare
ACHIEVEMENT_PDAS_ROE, // 32 // DONE -- read all pdas in RoE
ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME, // 33 // DONE --
ACHIEVEMENT_DEFEAT_HELLTIME_HUNTER, // 34 // DONE --
ACHIEVEMENT_DEFEAT_BERSERK_HUNTER, // 35 // DONE --
ACHIEVEMENT_DEFEAT_INVULNERABILITY_HUNTER, // 36 // DONE --
ACHIEVEMENT_DEFEAT_MALEDICT_BOSS, // 37 // DONE --
ACHIEVEMENT_GRABBER_KILL_20_ENEMY, // 38 // DONE --
ACHIEVEMENT_ARTIFACT_WITH_BERSERK_PUNCH_20, // 39 // DONE --
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_0, // 40 // DONE -- Recruit
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_1, // 41 // DONE -- Marine
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_2, // 42 // DONE -- Veteran
ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_3, // 43 // DONE -- Nightmare
ACHIEVEMENT_PDAS_LE, // 44 // DONE -- read all pdas in LE
ACHIEVEMENT_MP_KILL_PLAYER_VIA_TELEPORT, // 45 // DONE --
ACHIEVEMENT_MP_CATCH_ENEMY_IN_ROFC, // 46 // DONE -- needs to be tested -- Reactor of Frag Chamber
ACHIEVEMENT_MP_KILL_5_PLAYERS_USING_INVIS, // 47 // DONE --
ACHIEVEMENT_MP_COMPLETE_MATCH_WITHOUT_DYING, // 48 // DONE --
ACHIEVEMENT_MP_USE_BERSERK_TO_KILL_PLAYER, // 49 // DONE --
ACHIEVEMENT_MP_KILL_2_GUYS_IN_ROOM_WITH_BFG, // 50 // DONE --
ACHIEVEMENT_DOOM1_NEOPHYTE_COMPLETE_ANY_LEVEL, // 51
ACHIEVEMENT_DOOM1_EPISODE1_COMPLETE_MEDIUM, // 52
ACHIEVEMENT_DOOM1_EPISODE2_COMPLETE_MEDIUM, // 53
ACHIEVEMENT_DOOM1_EPISODE3_COMPLETE_MEDIUM, // 54
ACHIEVEMENT_DOOM1_EPISODE4_COMPLETE_MEDIUM, // 55
ACHIEVEMENT_DOOM1_RAMPAGE_COMPLETE_ALL_HARD, // 56
ACHIEVEMENT_DOOM1_NIGHTMARE_COMPLETE_ANY_LEVEL_NIGHTMARE, // 57
ACHIEVEMENT_DOOM1_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS, // 58
ACHIEVEMENT_DOOM2_JUST_GETTING_STARTED_COMPLETE_ANY_LEVEL, // 59
ACHIEVEMENT_DOOM2_FROM_EARTH_TO_HELL_COMPLETE_HELL_ON_EARTH, // 60
ACHIEVEMENT_DOOM2_AND_BACK_AGAIN_COMPLETE_NO_REST, // 61
ACHIEVEMENT_DOOM2_SUPERIOR_FIREPOWER_COMPLETE_ALL_HARD, // 62
ACHIEVEMENT_DOOM2_REALLY_BIG_GUN_FIND_BFG_SINGLEPLAYER, // 63
ACHIEVEMENT_DOOM2_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS, // 64
ACHIEVEMENT_DOOM2_IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET, // 65
ACHIEVEMENTS_NUM,
STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM,
STAT_DOOM_COMPLETED_EPISODE_2_MEDIUM,
STAT_DOOM_COMPLETED_EPISODE_3_MEDIUM,
STAT_DOOM_COMPLETED_EPISODE_4_MEDIUM,
STAT_DOOM_COMPLETED_EPISODE_1_HARD,
STAT_DOOM_COMPLETED_EPISODE_2_HARD,
STAT_DOOM_COMPLETED_EPISODE_3_HARD,
STAT_DOOM_COMPLETED_EPISODE_4_HARD,
};
compile_time_assert( ACHIEVEMENTS_NUM <= idPlayerProfile::MAX_PLAYER_PROFILE_STATS );
/*
================================================
idAchievementManager
Manages a List of Achievements associated with a particular Player.
This is setup to only have one achievement manager per game.
================================================
*/
class idAchievementManager {
public:
idAchievementManager();
void Init( idPlayer * player );
bool IsInitialized() const { return owner != NULL; }
// save games
void Save( idSaveGame * savefile ) const; // archives object for save game file
void Restore( idRestoreGame * savefile ); // unarchives object from save game file
// Debug tool to reset achievement state and counts
void Reset();
int GetCount( const achievement_t eventId ) const { return counts[eventId]; }
// Adds a count to the tracked number of events, these events can be applied to multiple achievements
void EventCompletesAchievement( const achievement_t eventId );
int GetLastImpKilledTime() { return lastImpKilledTime; }
void SetLastImpKilledTime( int time) { lastImpKilledTime = time; }
int GetLastPlayerKilledTime() { return lastPlayerKilledTime; }
void SetLastPlayerKilledTime( int time ) { lastPlayerKilledTime = time; }
bool GetPlayerTookDamage() { return playerTookDamage; }
void SetPlayerTookDamage( bool bl ) { playerTookDamage = bl; }
void IncrementHellTimeKills();
void ResetHellTimeKills() { currentHellTimeKills = 0; }
void SavePersistentData( idDict & playerInfo );
void RestorePersistentData( const idDict & spawnArgs );
static void LocalUser_CompleteAchievement( achievement_t id );
static void CheckDoomClassicsAchievements( int killcount, int itemcount, int secretcount, int skill, int mission, int map, int episode, int totalkills, int totalitems, int totalsecret );
private:
idEntityPtr< idPlayer > owner;
idArray<int, ACHIEVEMENTS_NUM> counts; // How many times has each achievement been given
int lastPlayerKilledTime;
int lastImpKilledTime;
bool playerTookDamage;
int currentHellTimeKills;
static bool cheatingDialogShown;
idLocalUser * GetLocalUser();
void SyncAchievments();
};
#endif // !__ACHIEVEMENTS_H__

3474
neo/d3xp/Actor.cpp Normal file

File diff suppressed because it is too large Load Diff

333
neo/d3xp/Actor.h Normal file
View File

@@ -0,0 +1,333 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_ACTOR_H__
#define __GAME_ACTOR_H__
/*
===============================================================================
idActor
===============================================================================
*/
extern const idEventDef AI_EnableEyeFocus;
extern const idEventDef AI_DisableEyeFocus;
extern const idEventDef EV_Footstep;
extern const idEventDef EV_FootstepLeft;
extern const idEventDef EV_FootstepRight;
extern const idEventDef EV_EnableWalkIK;
extern const idEventDef EV_DisableWalkIK;
extern const idEventDef EV_EnableLegIK;
extern const idEventDef EV_DisableLegIK;
extern const idEventDef AI_SetAnimPrefix;
extern const idEventDef AI_PlayAnim;
extern const idEventDef AI_PlayCycle;
extern const idEventDef AI_AnimDone;
extern const idEventDef AI_SetBlendFrames;
extern const idEventDef AI_GetBlendFrames;
extern const idEventDef AI_SetState;
class idDeclParticle;
class idAnimState {
public:
bool idleAnim;
idStr state;
int animBlendFrames;
int lastAnimBlendFrames; // allows override anims to blend based on the last transition time
public:
idAnimState();
~idAnimState();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Init( idActor *owner, idAnimator *_animator, int animchannel );
void Shutdown();
void SetState( const char *name, int blendFrames );
void StopAnim( int frames );
void PlayAnim( int anim );
void CycleAnim( int anim );
void BecomeIdle();
bool UpdateState();
bool Disabled() const;
void Enable( int blendFrames );
void Disable();
bool AnimDone( int blendFrames ) const;
bool IsIdle() const;
animFlags_t GetAnimFlags() const;
private:
idActor * self;
idAnimator * animator;
idThread * thread;
int channel;
bool disabled;
};
class idAttachInfo {
public:
idEntityPtr<idEntity> ent;
int channel;
};
typedef struct {
jointModTransform_t mod;
jointHandle_t from;
jointHandle_t to;
} copyJoints_t;
class idActor : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idActor );
int team;
int rank; // monsters don't fight back if the attacker's rank is higher
idMat3 viewAxis; // view axis of the actor
idLinkList<idActor> enemyNode; // node linked into an entity's enemy list for quick lookups of who is attacking him
idLinkList<idActor> enemyList; // list of characters that have targeted the player as their enemy
public:
idActor();
virtual ~idActor();
void Spawn();
virtual void Restart();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Hide();
virtual void Show();
virtual int GetDefaultSurfaceType() const;
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
virtual bool LoadAF();
void SetupBody();
void CheckBlink();
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// script state management
void ShutdownThreads();
virtual bool ShouldConstructScriptObjectAtSpawn() const;
virtual idThread * ConstructScriptObject();
void UpdateScript();
const function_t *GetScriptFunction( const char *funcname );
void SetState( const function_t *newState );
void SetState( const char *statename );
// vision testing
void SetEyeHeight( float height );
float EyeHeight() const;
idVec3 EyeOffset() const;
idVec3 GetEyePosition() const;
virtual void GetViewPos( idVec3 &origin, idMat3 &axis ) const;
void SetFOV( float fov );
bool CheckFOV( const idVec3 &pos ) const;
bool CanSee( idEntity *ent, bool useFOV ) const;
bool PointVisible( const idVec3 &point ) const;
virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos );
// damage
void SetupDamageGroups();
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
int GetDamageForLocation( int damage, int location );
const char * GetDamageGroup( int location );
void ClearPain();
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// model/combat model/ragdoll
void SetCombatModel();
idClipModel * GetCombatModel() const;
virtual void LinkCombat();
virtual void UnlinkCombat();
bool StartRagdoll();
void StopRagdoll();
virtual bool UpdateAnimationControllers();
// delta view angles to allow movers to rotate the view of the actor
const idAngles & GetDeltaViewAngles() const;
void SetDeltaViewAngles( const idAngles &delta );
bool HasEnemies() const;
idActor * ClosestEnemyToPoint( const idVec3 &pos );
idActor * EnemyWithMostHealth();
virtual bool OnLadder() const;
virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const;
void Attach( idEntity *ent );
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
virtual renderView_t * GetRenderView();
// animation state control
int GetAnim( int channel, const char *name );
void UpdateAnimState();
void SetAnimState( int channel, const char *name, int blendFrames );
const char * GetAnimState( int channel ) const;
bool InAnimState( int channel, const char *name ) const;
const char * WaitState() const;
void SetWaitState( const char *_waitstate );
bool AnimDone( int channel, int blendFrames ) const;
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
idEntity* GetHeadEntity() { return head.GetEntity(); };
protected:
friend class idAnimState;
float fovDot; // cos( fovDegrees )
idVec3 eyeOffset; // offset of eye relative to physics origin
idVec3 modelOffset; // offset of visual model relative to the physics origin
idAngles deltaViewAngles; // delta angles relative to view input angles
int pain_debounce_time; // next time the actor can show pain
int pain_delay; // time between playing pain sound
int pain_threshold; // how much damage monster can take at any one time before playing pain animation
idStrList damageGroups; // body damage groups
idList<float, TAG_ACTOR> damageScale; // damage scale per damage gruop
bool use_combat_bbox; // whether to use the bounding box for combat collision
idEntityPtr<idAFAttachment> head;
idList<copyJoints_t, TAG_ACTOR> copyJoints; // copied from the body animation to the head model
// state variables
const function_t *state;
const function_t *idealState;
// joint handles
jointHandle_t leftEyeJoint;
jointHandle_t rightEyeJoint;
jointHandle_t soundJoint;
idIK_Walk walkIK;
idStr animPrefix;
idStr painAnim;
// blinking
int blink_anim;
int blink_time;
int blink_min;
int blink_max;
// script variables
idThread * scriptThread;
idStr waitState;
idAnimState headAnim;
idAnimState torsoAnim;
idAnimState legsAnim;
bool allowPain;
bool allowEyeFocus;
bool finalBoss;
int painTime;
bool damageNotByFists;
idList<idAttachInfo, TAG_ACTOR> attachments;
int damageCap;
virtual void Gib( const idVec3 &dir, const char *damageDefName );
// removes attachments with "remove" set for when character dies
void RemoveAttachments();
// copies animation from body to head joints
void CopyJointsFromBodyToHead();
private:
void SyncAnimChannels( int channel, int syncToChannel, int blendFrames );
void FinishSetup();
void SetupHead();
void PlayFootStepSound();
void Event_EnableEyeFocus();
void Event_DisableEyeFocus();
void Event_Footstep();
void Event_EnableWalkIK();
void Event_DisableWalkIK();
void Event_EnableLegIK( int num );
void Event_DisableLegIK( int num );
void Event_SetAnimPrefix( const char *name );
void Event_LookAtEntity( idEntity *ent, float duration );
void Event_PreventPain( float duration );
void Event_DisablePain();
void Event_EnablePain();
void Event_GetPainAnim();
void Event_StopAnim( int channel, int frames );
void Event_PlayAnim( int channel, const char *name );
void Event_PlayCycle( int channel, const char *name );
void Event_IdleAnim( int channel, const char *name );
void Event_SetSyncedAnimWeight( int channel, int anim, float weight );
void Event_OverrideAnim( int channel );
void Event_EnableAnim( int channel, int blendFrames );
void Event_SetBlendFrames( int channel, int blendFrames );
void Event_GetBlendFrames( int channel );
void Event_AnimState( int channel, const char *name, int blendFrames );
void Event_GetAnimState( int channel );
void Event_InAnimState( int channel, const char *name );
void Event_FinishAction( const char *name );
void Event_AnimDone( int channel, int blendFrames );
void Event_HasAnim( int channel, const char *name );
void Event_CheckAnim( int channel, const char *animname );
void Event_ChooseAnim( int channel, const char *animname );
void Event_AnimLength( int channel, const char *animname );
void Event_AnimDistance( int channel, const char *animname );
void Event_HasEnemies();
void Event_NextEnemy( idEntity *ent );
void Event_ClosestEnemyToPoint( const idVec3 &pos );
void Event_StopSound( int channel, int netsync );
void Event_SetNextState( const char *name );
void Event_SetState( const char *name );
void Event_GetState();
void Event_GetHead();
void Event_SetDamageGroupScale( const char* groupName, float scale);
void Event_SetDamageGroupScaleAll( float scale );
void Event_GetDamageGroupScale( const char* groupName );
void Event_SetDamageCap( float _damageCap );
void Event_SetWaitState( const char* waitState);
void Event_GetWaitState();
};
#endif /* !__GAME_ACTOR_H__ */

436
neo/d3xp/AimAssist.cpp Normal file
View File

@@ -0,0 +1,436 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
================================================================================================
Contains the AimAssist implementation.
================================================================================================
*/
idCVar aa_targetAimAssistEnable ( "aa_targetAimAssistEnable", "0", CVAR_BOOL | CVAR_ARCHIVE, "Enables/Disables the entire Aim Assist system" );
idCVar aa_targetAdhesionEnable ( "aa_targetAdhesionEnable", "1", CVAR_BOOL, "Enables Target Adhesion" );
idCVar aa_targetFrictionEnable ( "aa_targetFrictionEnable", "1", CVAR_BOOL, "Enables Target Friction" );
// Selection
idCVar aa_targetMaxDistance ( "aa_targetMaxDistance", "3000", CVAR_FLOAT, "The Maximum Distance away for a target to be considered for adhesion, friction and target lock-to" );
idCVar aa_targetSelectionRadius ( "aa_targetSelectionRadius", "128.0", CVAR_FLOAT, "Radius used to select targets for auto aiming" );
// Adhesion
idCVar aa_targetAdhesionRadius ( "aa_targetAdhesionRadius", "96.0", CVAR_FLOAT, "Radius used to apply adhesion amount" );
idCVar aa_targetAdhesionYawSpeedMax ( "aa_targetAdhesionYawSpeedMax", "0.6", CVAR_FLOAT, "Max Yaw Adhesion Speed" );
idCVar aa_targetAdhesionPitchSpeedMax ( "aa_targetAdhesionPitchSpeedMax", "0.6", CVAR_FLOAT, "Max Pitch Adhesion Speed" );
idCVar aa_targetAdhesionContributionPctMax ( "aa_targetAdhesionContributionPctMax", "0.25", CVAR_FLOAT, "Max Adhesion Contribution Percentage - Range 0.0 - 1.0" );
idCVar aa_targetAdhesionPlayerSpeedThreshold ( "aa_targetAdhesionPlayerSpeedThreshold", "10.0", CVAR_FLOAT, "Speed Threshold that determines how fast the player needs to move before adhesion is allowed to kick in" );
// Friction
idCVar aa_targetFrictionMaxDistance ( "aa_targetFrictionMaxDistance", "1024.0", CVAR_FLOAT, "Minimum Distance Friction takes effect" );
idCVar aa_targetFrictionOptimalDistance ( "aa_targetFrictionOptimalDistance", "768.0", CVAR_FLOAT, "Optimal Distance for Friction to take an effect" );
idCVar aa_targetFrictionRadius ( "aa_targetFrictionRadius", "96.0", CVAR_FLOAT, "Friction Collision Sphere Radius" );
idCVar aa_targetFrictionOptimalRadius ( "aa_targetFrictionOptimalRadius", "192.0", CVAR_FLOAT, "Friction Collision Sphere Radius when at Optimal Distance" );
idCVar aa_targetFrictionMultiplierMin ( "aa_targetFrictionMultiplierMin", "1.0", CVAR_FLOAT, "Minimum Friction Scalar" );
idCVar aa_targetFrictionMultiplierMax ( "aa_targetFrictionMultiplierMax", "0.4", CVAR_FLOAT, "Maximum Friction Scalar" );
/*
========================
idAimAssist::Init
========================
*/
void idAimAssist::Init( idPlayer *player_ ) {
player = player_;
angleCorrection = ang_zero;
frictionScalar = 1.0f;
lastTargetPos = vec3_zero;
}
/*
========================
idAimAssist::Update
========================
*/
void idAimAssist::Update() {
angleCorrection = ang_zero;
UpdateNewAimAssist();
}
/*
========================
idAimAssist::UpdateNewAimAssist
========================
*/
void idAimAssist::UpdateNewAimAssist() {
angleCorrection = ang_zero;
frictionScalar = 1.0f;
idEntity* lastTarget = targetEntity;
targetEntity = NULL;
// is aim assisting allowed? If not then just bail out
if ( !aa_targetAimAssistEnable.GetBool() ) {
return;
}
bool forceLastTarget = false;
idVec3 targetPos;
idEntity * entity = NULL;
if ( forceLastTarget ) {
entity = lastTarget;
targetPos = lastTargetPos;
} else {
entity = FindAimAssistTarget( targetPos );
}
if ( entity != NULL ) {
UpdateFriction( entity, targetPos );
// by default we don't allow adhesion when we are standing still
const float playerMovementSpeedThreshold = Square( aa_targetAdhesionPlayerSpeedThreshold.GetFloat() );
float playerSpeed = player->GetPhysics()->GetLinearVelocity().LengthSqr();
// only allow adhesion on actors (ai) or players. Disallow adhesion on any static world entities such as explosive barrels
if ( playerSpeed > playerMovementSpeedThreshold ) {
UpdateAdhesion( entity, targetPos );
}
targetEntity = entity;
}
lastTargetPos = targetPos;
}
/*
========================
idAimAssist::FindAimAssistTarget
========================
*/
idEntity* idAimAssist::FindAimAssistTarget( idVec3& targetPos ) {
if ( player == NULL ) {
return NULL;
}
//TO DO: Make this faster
//TO DO: Defer Traces
idEntity * optimalTarget = NULL;
float currentBestScore = -idMath::INFINITY;
targetPos = vec3_zero;
idVec3 cameraPos;
idMat3 cameraAxis;
player->GetViewPos( cameraPos, cameraAxis );
float maxDistanceSquared = Square( aa_targetMaxDistance.GetFloat() );
idVec3 dirToTarget;
float distanceToTargetSquared;
idVec3 primaryTargetPos;
idVec3 secondaryTargetPos;
for ( idEntity * entity = gameLocal.aimAssistEntities.Next(); entity != NULL; entity = entity->aimAssistNode.Next() ) {
if ( !entity->IsActive() ) {
continue;
}
if ( entity->IsHidden() ) {
continue;
}
if ( entity->IsType( idActor::Type ) ) {
idActor * actor = static_cast<idActor *>( entity );
if ( actor->team == player->team ) {
// In DM, LMS, and Tourney, all players are on the same team
if ( gameLocal.gameType == GAME_CTF || gameLocal.gameType == GAME_TDM || gameLocal.gameType == GAME_SP ) {
continue;
}
}
}
if ( entity->IsType( idAI::Type ) ) {
idAI * aiEntity = static_cast<idAI *>( entity );
if ( aiEntity->ReactionTo( player ) == ATTACK_IGNORE ) {
continue;
}
}
// check whether we have a valid target position for this entity - skip it if we don't
if ( !ComputeTargetPos( entity, primaryTargetPos, secondaryTargetPos ) ) {
continue;
}
// is it close enough to us
dirToTarget = primaryTargetPos-cameraPos;
distanceToTargetSquared = dirToTarget.LengthSqr();
if ( distanceToTargetSquared > maxDistanceSquared ) {
continue;
}
// Compute a score in the range of 0..1 for how much are looking towards the target.
idVec3 forward = cameraAxis[ 0 ];
forward.Normalize();
dirToTarget.Normalize();
float ViewDirDotTargetDir = idMath::ClampFloat( -1.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
// throw out anything thats outside of weapon's global FOV.
if ( ViewDirDotTargetDir < 0.0f ) {
continue;
}
// to be consistent we always use the primaryTargetPos to compute the score for this entity
float computedScore = ComputeEntityAimAssistScore( primaryTargetPos, cameraPos, cameraAxis );
// check if the current score beats our current best score and we have line of sight to it.
if ( computedScore > currentBestScore ) {
// determine if the current target is in our line of sight
trace_t tr;
gameLocal.clip.TracePoint( tr, cameraPos, primaryTargetPos, MASK_MONSTERSOLID, player );
// did our trace fail?
if ( ( ( tr.fraction < 1.0f ) && ( tr.c.entityNum != entity->entityNumber ) ) || ( tr.fraction >= 1.0f ) ) {
// if the collision test failed for the primary position -- check the secondary position
trace_t tr2;
gameLocal.clip.TracePoint( tr2, cameraPos, secondaryTargetPos, MASK_MONSTERSOLID, player );
if ( ( ( tr2.fraction < 1.0f ) && ( tr2.c.entityNum != entity->entityNumber ) ) || ( tr2.fraction >= 1.0f ) ) {
// if the secondary position is also not visible then give up
continue;
}
// we can see the secondary target position so we should consider this entity but use
// the secondary position as the target position
targetPos = secondaryTargetPos;
} else {
targetPos = primaryTargetPos;
}
// if we got here then this is our new best score
optimalTarget = entity;
currentBestScore = computedScore;
}
}
return optimalTarget;
}
/*
========================
idAimAssist::ComputeEntityAimAssistScore
========================
*/
float idAimAssist::ComputeEntityAimAssistScore( const idVec3& targetPos, const idVec3& cameraPos, const idMat3& cameraAxis ) {
float score = 0.0f;
idVec3 dirToTarget = targetPos - cameraPos;
float distanceToTarget = dirToTarget.Length();
// Compute a score in the range of 0..1 for how much are looking towards the target.
idVec3 forward = cameraAxis[0];
forward.Normalize();
dirToTarget.Normalize();
float ViewDirDotTargetDir = idMath::ClampFloat( 0.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
// the more we look at the target the higher our score
score = ViewDirDotTargetDir;
// weigh the score from the view angle higher than the distance score
static float aimWeight = 0.8f;
score *= aimWeight;
// Add a score of 0..1 for how close the target is to the player
if ( distanceToTarget < aa_targetMaxDistance.GetFloat() ) {
float distanceScore = 1.0f - ( distanceToTarget / aa_targetMaxDistance.GetFloat() );
float distanceWeight = 1.0f - aimWeight;
score += ( distanceScore * distanceWeight );
}
return score * 1000.0f;
}
/*
========================
idAimAssist::UpdateAdhesion
========================
*/
void idAimAssist::UpdateAdhesion( idEntity* pTarget, const idVec3& targetPos ) {
if ( !aa_targetAdhesionEnable.GetBool() ) {
return;
}
if ( !pTarget ) {
return;
}
float contributionPctMax = aa_targetAdhesionContributionPctMax.GetFloat();
idVec3 cameraPos;
idMat3 cameraAxis;
player->GetViewPos(cameraPos, cameraAxis);
idAngles cameraViewAngles = cameraAxis.ToAngles();
cameraViewAngles.Normalize180();
idVec3 cameraViewPos = cameraPos;
idVec3 dirToTarget = targetPos - cameraViewPos;
float distanceToTarget = dirToTarget.Length();
idAngles aimAngles = dirToTarget.ToAngles();
aimAngles.Normalize180();
// find the delta
aimAngles -= cameraViewAngles;
// clamp velocities to some max values
aimAngles.yaw = idMath::ClampFloat( -aa_targetAdhesionYawSpeedMax.GetFloat(), aa_targetAdhesionYawSpeedMax.GetFloat(), aimAngles.yaw );
aimAngles.pitch = idMath::ClampFloat( -aa_targetAdhesionPitchSpeedMax.GetFloat(), aa_targetAdhesionPitchSpeedMax.GetFloat(), aimAngles.pitch );
idVec3 forward = cameraAxis[0];
forward.Normalize();
dirToTarget.Normalize();
float ViewDirDotTargetDir = idMath::ClampFloat( 0.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
float aimLength = ViewDirDotTargetDir * distanceToTarget;
idVec3 aimPoint = cameraPos + ( forward * aimLength );
float delta = idMath::Sqrt( Square( distanceToTarget ) - Square( aimLength ) );
float contribution = idMath::ClampFloat( 0.0f, contributionPctMax, 1.0f - ( delta / aa_targetAdhesionRadius.GetFloat() ) );
angleCorrection.yaw = aimAngles.yaw * contribution;
angleCorrection.pitch = aimAngles.pitch * contribution;
}
/*
========================
idAimAssist::ComputeFrictionRadius
========================
*/
float idAimAssist::ComputeFrictionRadius( float distanceToTarget ) {
if ( ( distanceToTarget <= idMath::FLT_SMALLEST_NON_DENORMAL ) || distanceToTarget > aa_targetFrictionMaxDistance.GetFloat() ) {
return aa_targetFrictionRadius.GetFloat();
}
float distanceContributionScalar = ( aa_targetFrictionOptimalDistance.GetFloat() > 0.0f ) ? ( distanceToTarget / aa_targetFrictionOptimalDistance.GetFloat() ) : 0.0f;
if ( distanceToTarget > aa_targetFrictionOptimalDistance.GetFloat() ) {
const float range = idMath::ClampFloat( 0.0f, aa_targetFrictionMaxDistance.GetFloat(), aa_targetFrictionMaxDistance.GetFloat() - aa_targetFrictionOptimalDistance.GetFloat() );
if ( range > idMath::FLT_SMALLEST_NON_DENORMAL ) {
distanceContributionScalar = 1.0f - ( ( distanceToTarget - aa_targetFrictionOptimalDistance.GetFloat() ) / range );
}
}
return Lerp( aa_targetFrictionRadius.GetFloat(), aa_targetFrictionOptimalRadius.GetFloat(), distanceContributionScalar );
}
/*
========================
idAimAssist::UpdateFriction
========================
*/
void idAimAssist::UpdateFriction( idEntity* pTarget, const idVec3& targetPos ) {
if ( !aa_targetFrictionEnable.GetBool() ) {
return;
}
if ( pTarget == NULL ) {
return;
}
idVec3 cameraPos;
idMat3 cameraAxis;
player->GetViewPos(cameraPos, cameraAxis);
idVec3 dirToTarget = targetPos - cameraPos;
float distanceToTarget = dirToTarget.Length();
idVec3 forward = cameraAxis[0];
forward.Normalize();
dirToTarget.Normalize();
float ViewDirDotTargetDir = idMath::ClampFloat( 0.0f, 1.0f, forward * dirToTarget ); // compute the dot and clamp to account for floating point error
float aimLength = ViewDirDotTargetDir * distanceToTarget;
idVec3 aimPoint = cameraPos + ( forward * aimLength );
float delta = idMath::Sqrt( Square( distanceToTarget ) - Square( aimLength ) );
const float radius = ComputeFrictionRadius( distanceToTarget );
if ( delta < radius ) {
float alpha = 1.0f - ( delta / radius );
frictionScalar = Lerp( aa_targetFrictionMultiplierMin.GetFloat(), aa_targetFrictionMultiplierMax.GetFloat(), alpha );
}
}
/*
========================
idAimAssist::ComputeTargetPos
========================
*/
bool idAimAssist::ComputeTargetPos( idEntity* entity, idVec3& primaryTargetPos, idVec3& secondaryTargetPos ) {
primaryTargetPos = vec3_zero;
secondaryTargetPos = vec3_zero;
if ( entity == NULL ) {
return false;
}
// The target point on actors can now be either the head or the torso
idActor * actor = NULL;
if ( entity->IsType( idActor::Type ) ) {
actor = ( idActor *) entity;
}
if ( actor != NULL ) {
// Actor AimPoint
idVec3 torsoPos;
idVec3 headPos = actor->GetEyePosition();
if ( actor->GetHeadEntity() != NULL ) {
torsoPos = actor->GetHeadEntity()->GetPhysics()->GetOrigin();
} else {
const float offsetScale = 0.9f;
torsoPos = actor->GetPhysics()->GetOrigin() + ( actor->EyeOffset() * offsetScale );
}
primaryTargetPos = torsoPos;
secondaryTargetPos = headPos;
return true;
} else if ( entity->GetPhysics()->GetClipModel() != NULL ) {
const idBounds& box = entity->GetPhysics()->GetClipModel()->GetAbsBounds();
primaryTargetPos = box.GetCenter();
secondaryTargetPos = box.GetCenter();
return true;
}
return false;
}

75
neo/d3xp/AimAssist.h Normal file
View File

@@ -0,0 +1,75 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __AIMASSIST_H__
#define __AIMASSIST_H__
/*
================================================================================================
Contains the AimAssist declaration.
================================================================================================
*/
class idEntity;
class idPlayer;
/*
================================================
idAimAssist modifies the angle of Weapon firing to help the Player
hit a Target.
================================================
*/
class idAimAssist {
public:
idAimAssist() : angleCorrection( ang_zero ), frictionScalar( 1.0f ), lastTargetPos( vec3_zero ), player( NULL ) {}
void Init( idPlayer * player );
void Update();
void GetAngleCorrection( idAngles & correction ) const { correction = angleCorrection; }
float GetFrictionScalar () const { return frictionScalar; }
idEntity * GetLastTarget() { return targetEntity; }
idEntity * FindAimAssistTarget( idVec3 & targetPos );
private:
void UpdateNewAimAssist();
float ComputeEntityAimAssistScore( const idVec3 & targetPos, const idVec3 & cameraPos, const idMat3 & cameraAxis );
bool ComputeTargetPos( idEntity * pTarget, idVec3 & primaryTargetPos, idVec3 & secondaryTargetPos );
float ComputeFrictionRadius( float distanceToTarget );
void UpdateAdhesion( idEntity * pTarget, const idVec3 & targetPos);
void UpdateFriction( idEntity * pTarget, const idVec3 & targetPos);
idPlayer * player; // player associated with this object
idAngles angleCorrection; // the angle delta to apply for aim assistance
float frictionScalar; // friction scalar
idEntityPtr<idEntity> targetEntity; // the last target we had (updated every frame)
idVec3 lastTargetPos; // the last target position ( updated every frame );
};
#endif // !__AIMASSIST_H__

1386
neo/d3xp/BrittleFracture.cpp Normal file

File diff suppressed because it is too large Load Diff

141
neo/d3xp/BrittleFracture.h Normal file
View File

@@ -0,0 +1,141 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_BRITTLEFRACTURE_H__
#define __GAME_BRITTLEFRACTURE_H__
/*
===============================================================================
B-rep Brittle Fracture - Static entity using the boundary representation
of the render model which can fracture.
===============================================================================
*/
typedef struct shard_s {
idClipModel * clipModel;
idFixedWinding winding;
idList<idFixedWinding *, TAG_PHYSICS_BRITTLE> decals;
idList<bool> edgeHasNeighbour;
idList<struct shard_s *, TAG_PHYSICS_BRITTLE> neighbours;
idPhysics_RigidBody physicsObj;
int droppedTime;
bool atEdge;
int islandNum;
} shard_t;
class idBrittleFracture : public idEntity {
public:
CLASS_PROTOTYPE( idBrittleFracture );
idBrittleFracture();
virtual ~idBrittleFracture();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Present();
virtual void Think();
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName );
bool IsBroken() const;
enum {
EVENT_PROJECT_DECAL = idEntity::EVENT_MAXEVENTS,
EVENT_SHATTER,
EVENT_MAXEVENTS
};
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void ClientPredictionThink();
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
private:
// setttings
const idMaterial * material;
const idMaterial * decalMaterial;
float decalSize;
float maxShardArea;
float maxShatterRadius;
float minShatterRadius;
float linearVelocityScale;
float angularVelocityScale;
float shardMass;
float density;
float friction;
float bouncyness;
idStr fxFracture;
struct fractureEvent_s {
int eventType;
idVec3 point;
idVec3 vector;
};
idList<fractureEvent_s> storedEvents;
bool processStoredEvents;
idRenderModel * defaultRenderModel;
bool isXraySurface;
// state
idPhysics_StaticMulti physicsObj;
idList<shard_t *, TAG_PHYSICS_BRITTLE> shards;
idBounds bounds;
bool disableFracture;
// for rendering
mutable int lastRenderEntityUpdate;
mutable bool changed;
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
void AddShard( idClipModel *clipModel, idFixedWinding &w );
void RemoveShard( int index );
void DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time );
void Shatter( const idVec3 &point, const idVec3 &impulse, const int time );
void DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time );
void Break();
void Fracture_r( idFixedWinding &w, idRandom2 & random );
void CreateFractures( const idRenderModel *renderModel );
void FindNeighbours();
void Event_Activate( idEntity *activator );
void Event_Touch( idEntity *other, trace_t *trace );
};
#endif /* !__GAME_BRITTLEFRACTURE_H__ */

636
neo/d3xp/Camera.cpp Normal file
View File

@@ -0,0 +1,636 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
===============================================================================
idCamera
Base class for cameras
===============================================================================
*/
ABSTRACT_DECLARATION( idEntity, idCamera )
END_CLASS
/*
=====================
idCamera::Spawn
=====================
*/
void idCamera::Spawn() {
}
/*
=====================
idCamera::GetRenderView
=====================
*/
renderView_t *idCamera::GetRenderView() {
renderView_t *rv = idEntity::GetRenderView();
GetViewParms( rv );
return rv;
}
/***********************************************************************
idCameraView
***********************************************************************/
const idEventDef EV_Camera_SetAttachments( "<getattachments>", NULL );
CLASS_DECLARATION( idCamera, idCameraView )
EVENT( EV_Activate, idCameraView::Event_Activate )
EVENT( EV_Camera_SetAttachments, idCameraView::Event_SetAttachments )
END_CLASS
/*
===============
idCameraView::idCameraView
================
*/
idCameraView::idCameraView() {
fov = 90.0f;
attachedTo = NULL;
attachedView = NULL;
}
/*
===============
idCameraView::Save
================
*/
void idCameraView::Save( idSaveGame *savefile ) const {
savefile->WriteFloat( fov );
savefile->WriteObject( attachedTo );
savefile->WriteObject( attachedView );
}
/*
===============
idCameraView::Restore
================
*/
void idCameraView::Restore( idRestoreGame *savefile ) {
savefile->ReadFloat( fov );
savefile->ReadObject( reinterpret_cast<idClass *&>( attachedTo ) );
savefile->ReadObject( reinterpret_cast<idClass *&>( attachedView ) );
}
/*
===============
idCameraView::Event_SetAttachments
================
*/
void idCameraView::Event_SetAttachments( ) {
SetAttachment( &attachedTo, "attachedTo" );
SetAttachment( &attachedView, "attachedView" );
}
/*
===============
idCameraView::Event_Activate
================
*/
void idCameraView::Event_Activate( idEntity *activator ) {
if (spawnArgs.GetBool("trigger")) {
if (gameLocal.GetCamera() != this) {
if ( g_debugCinematic.GetBool() ) {
gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() );
}
gameLocal.SetCamera(this);
} else {
if ( g_debugCinematic.GetBool() ) {
gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
}
gameLocal.SetCamera(NULL);
}
}
}
/*
=====================
idCameraView::Stop
=====================
*/
void idCameraView::Stop() {
if ( g_debugCinematic.GetBool() ) {
gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
}
gameLocal.SetCamera(NULL);
ActivateTargets( gameLocal.GetLocalPlayer() );
}
/*
=====================
idCameraView::Spawn
=====================
*/
void idCameraView::SetAttachment( idEntity **e, const char *p ) {
const char *cam = spawnArgs.GetString( p );
if ( strlen ( cam ) ) {
*e = gameLocal.FindEntity( cam );
}
}
/*
=====================
idCameraView::Spawn
=====================
*/
void idCameraView::Spawn() {
// if no target specified use ourself
const char *cam = spawnArgs.GetString("cameraTarget");
if ( strlen ( cam ) == 0) {
spawnArgs.Set("cameraTarget", spawnArgs.GetString("name"));
}
fov = spawnArgs.GetFloat("fov", "90");
PostEventMS( &EV_Camera_SetAttachments, 0 );
UpdateChangeableSpawnArgs(NULL);
}
/*
=====================
idCameraView::GetViewParms
=====================
*/
void idCameraView::GetViewParms( renderView_t *view ) {
assert( view );
if (view == NULL) {
return;
}
idVec3 dir;
idEntity *ent;
if ( attachedTo ) {
ent = attachedTo;
} else {
ent = this;
}
view->vieworg = ent->GetPhysics()->GetOrigin();
if ( attachedView ) {
dir = attachedView->GetPhysics()->GetOrigin() - view->vieworg;
dir.Normalize();
view->viewaxis = dir.ToMat3();
} else {
view->viewaxis = ent->GetPhysics()->GetAxis();
}
gameLocal.CalcFov( fov, view->fov_x, view->fov_y );
}
/*
===============================================================================
idCameraAnim
===============================================================================
*/
const idEventDef EV_Camera_Start( "start", NULL );
const idEventDef EV_Camera_Stop( "stop", NULL );
CLASS_DECLARATION( idCamera, idCameraAnim )
EVENT( EV_Thread_SetCallback, idCameraAnim::Event_SetCallback )
EVENT( EV_Camera_Stop, idCameraAnim::Event_Stop )
EVENT( EV_Camera_Start, idCameraAnim::Event_Start )
EVENT( EV_Activate, idCameraAnim::Event_Activate )
END_CLASS
/*
=====================
idCameraAnim::idCameraAnim
=====================
*/
idCameraAnim::idCameraAnim() {
threadNum = 0;
offset.Zero();
frameRate = 0;
cycle = 1;
starttime = 0;
activator = NULL;
}
/*
=====================
idCameraAnim::~idCameraAnim
=====================
*/
idCameraAnim::~idCameraAnim() {
if ( gameLocal.GetCamera() == this ) {
gameLocal.SetCamera( NULL );
}
}
/*
===============
idCameraAnim::Save
================
*/
void idCameraAnim::Save( idSaveGame *savefile ) const {
savefile->WriteInt( threadNum );
savefile->WriteVec3( offset );
savefile->WriteInt( frameRate );
savefile->WriteInt( starttime );
savefile->WriteInt( cycle );
activator.Save( savefile );
}
/*
===============
idCameraAnim::Restore
================
*/
void idCameraAnim::Restore( idRestoreGame *savefile ) {
savefile->ReadInt( threadNum );
savefile->ReadVec3( offset );
savefile->ReadInt( frameRate );
savefile->ReadInt( starttime );
savefile->ReadInt( cycle );
activator.Restore( savefile );
LoadAnim();
}
/*
=====================
idCameraAnim::Spawn
=====================
*/
void idCameraAnim::Spawn() {
if ( spawnArgs.GetVector( "old_origin", "0 0 0", offset ) ) {
offset = GetPhysics()->GetOrigin() - offset;
} else {
offset.Zero();
}
// always think during cinematics
cinematic = true;
LoadAnim();
}
/*
================
idCameraAnim::Load
================
*/
void idCameraAnim::LoadAnim() {
int version;
idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT );
idToken token;
int numFrames;
int numCuts;
int i;
idStr filename;
const char *key;
key = spawnArgs.GetString( "anim" );
if ( !key ) {
gameLocal.Error( "Missing 'anim' key on '%s'", name.c_str() );
}
filename = spawnArgs.GetString( va( "anim %s", key ) );
if ( !filename.Length() ) {
gameLocal.Error( "Missing 'anim %s' key on '%s'", key, name.c_str() );
}
filename.SetFileExtension( MD5_CAMERA_EXT );
if ( !parser.LoadFile( filename ) ) {
gameLocal.Error( "Unable to load '%s' on '%s'", filename.c_str(), name.c_str() );
}
cameraCuts.Clear();
cameraCuts.SetGranularity( 1 );
camera.Clear();
camera.SetGranularity( 1 );
parser.ExpectTokenString( MD5_VERSION_STRING );
version = parser.ParseInt();
if ( version != MD5_VERSION ) {
parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION );
}
// skip the commandline
parser.ExpectTokenString( "commandline" );
parser.ReadToken( &token );
// parse num frames
parser.ExpectTokenString( "numFrames" );
numFrames = parser.ParseInt();
if ( numFrames <= 0 ) {
parser.Error( "Invalid number of frames: %d", numFrames );
}
// parse framerate
parser.ExpectTokenString( "frameRate" );
frameRate = parser.ParseInt();
if ( frameRate <= 0 ) {
parser.Error( "Invalid framerate: %d", frameRate );
}
// parse num cuts
parser.ExpectTokenString( "numCuts" );
numCuts = parser.ParseInt();
if ( ( numCuts < 0 ) || ( numCuts > numFrames ) ) {
parser.Error( "Invalid number of camera cuts: %d", numCuts );
}
// parse the camera cuts
parser.ExpectTokenString( "cuts" );
parser.ExpectTokenString( "{" );
cameraCuts.SetNum( numCuts );
for( i = 0; i < numCuts; i++ ) {
cameraCuts[ i ] = parser.ParseInt();
if ( ( cameraCuts[ i ] < 1 ) || ( cameraCuts[ i ] >= numFrames ) ) {
parser.Error( "Invalid camera cut" );
}
}
parser.ExpectTokenString( "}" );
// parse the camera frames
parser.ExpectTokenString( "camera" );
parser.ExpectTokenString( "{" );
camera.SetNum( numFrames );
for( i = 0; i < numFrames; i++ ) {
parser.Parse1DMatrix( 3, camera[ i ].t.ToFloatPtr() );
parser.Parse1DMatrix( 3, camera[ i ].q.ToFloatPtr() );
camera[ i ].fov = parser.ParseFloat();
}
parser.ExpectTokenString( "}" );
}
/*
===============
idCameraAnim::Start
================
*/
void idCameraAnim::Start() {
cycle = spawnArgs.GetInt( "cycle" );
if ( !cycle ) {
cycle = 1;
}
if ( g_debugCinematic.GetBool() ) {
gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() );
}
starttime = gameLocal.time;
gameLocal.SetCamera( this );
BecomeActive( TH_THINK );
// if the player has already created the renderview for this frame, have him update it again so that the camera starts this frame
if ( gameLocal.GetLocalPlayer()->GetRenderView()->time[TIME_GROUP2] == gameLocal.fast.time ) {
gameLocal.GetLocalPlayer()->CalculateRenderView();
}
}
/*
=====================
idCameraAnim::Stop
=====================
*/
void idCameraAnim::Stop() {
if ( gameLocal.GetCamera() == this ) {
if ( g_debugCinematic.GetBool() ) {
gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
}
BecomeInactive( TH_THINK );
gameLocal.SetCamera( NULL );
if ( threadNum ) {
idThread::ObjectMoveDone( threadNum, this );
threadNum = 0;
}
ActivateTargets( activator.GetEntity() );
}
}
/*
=====================
idCameraAnim::Think
=====================
*/
void idCameraAnim::Think() {
}
/*
=====================
idCameraAnim::GetViewParms
=====================
*/
void idCameraAnim::GetViewParms( renderView_t *view ) {
int realFrame;
int frame;
int frameTime;
float lerp;
float invlerp;
cameraFrame_t *camFrame;
int i;
int cut;
idQuat q1, q2, q3;
assert( view );
if ( !view ) {
return;
}
if ( camera.Num() == 0 ) {
// we most likely are in the middle of a restore
// FIXME: it would be better to fix it so this doesn't get called during a restore
return;
}
SetTimeState ts( timeGroup );
frameTime = ( gameLocal.time - starttime ) * frameRate;
frame = frameTime / 1000;
lerp = ( frameTime % 1000 ) * 0.001f;
// skip any frames where camera cuts occur
realFrame = frame;
cut = 0;
for( i = 0; i < cameraCuts.Num(); i++ ) {
if ( frame < cameraCuts[ i ] ) {
break;
}
frame++;
cut++;
}
if ( g_debugCinematic.GetBool() ) {
int prevFrameTime = ( gameLocal.previousTime - starttime ) * frameRate;
int prevFrame = prevFrameTime / 1000;
int prevCut;
prevCut = 0;
for( i = 0; i < cameraCuts.Num(); i++ ) {
if ( prevFrame < cameraCuts[ i ] ) {
break;
}
prevFrame++;
prevCut++;
}
if ( prevCut != cut ) {
gameLocal.Printf( "%d: '%s' cut %d\n", gameLocal.framenum, GetName(), cut );
}
}
// clamp to the first frame. also check if this is a one frame anim. one frame anims would end immediately,
// but since they're mainly used for static cams anyway, just stay on it infinitely.
if ( ( frame < 0 ) || ( camera.Num() < 2 ) ) {
view->viewaxis = camera[ 0 ].q.ToQuat().ToMat3();
view->vieworg = camera[ 0 ].t + offset;
view->fov_x = camera[ 0 ].fov;
} else if ( frame > camera.Num() - 2 ) {
if ( cycle > 0 ) {
cycle--;
}
if ( cycle != 0 ) {
// advance start time so that we loop
starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate;
GetViewParms( view );
return;
}
Stop();
if ( gameLocal.GetCamera() != NULL ) {
// we activated another camera when we stopped, so get it's viewparms instead
gameLocal.GetCamera()->GetViewParms( view );
return;
} else {
// just use our last frame
camFrame = &camera[ camera.Num() - 1 ];
view->viewaxis = camFrame->q.ToQuat().ToMat3();
view->vieworg = camFrame->t + offset;
view->fov_x = camFrame->fov;
}
} else if ( lerp == 0.0f ) {
camFrame = &camera[ frame ];
view->viewaxis = camFrame[ 0 ].q.ToMat3();
view->vieworg = camFrame[ 0 ].t + offset;
view->fov_x = camFrame[ 0 ].fov;
} else {
camFrame = &camera[ frame ];
invlerp = 1.0f - lerp;
q1 = camFrame[ 0 ].q.ToQuat();
q2 = camFrame[ 1 ].q.ToQuat();
q3.Slerp( q1, q2, lerp );
view->viewaxis = q3.ToMat3();
view->vieworg = camFrame[ 0 ].t * invlerp + camFrame[ 1 ].t * lerp + offset;
view->fov_x = camFrame[ 0 ].fov * invlerp + camFrame[ 1 ].fov * lerp;
}
gameLocal.CalcFov( view->fov_x, view->fov_x, view->fov_y );
// setup the pvs for this frame
UpdatePVSAreas( view->vieworg );
#if 0
static int lastFrame = 0;
static idVec3 lastFrameVec( 0.0f, 0.0f, 0.0f );
if ( gameLocal.time != lastFrame ) {
gameRenderWorld->DebugBounds( colorCyan, idBounds( view->vieworg ).Expand( 16.0f ), vec3_origin, 1 );
gameRenderWorld->DebugLine( colorRed, view->vieworg, view->vieworg + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false );
gameRenderWorld->DebugLine( colorCyan, lastFrameVec, view->vieworg, 10000, false );
gameRenderWorld->DebugLine( colorYellow, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 66.0f, 10000, false );
gameRenderWorld->DebugLine( colorOrange, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 64.0f + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false );
lastFrameVec = view->vieworg;
lastFrame = gameLocal.time;
}
#endif
if ( g_showcamerainfo.GetBool() ) {
gameLocal.Printf( "^5Frame: ^7%d/%d\n\n\n", realFrame + 1, camera.Num() - cameraCuts.Num() );
}
}
/*
===============
idCameraAnim::Event_Activate
================
*/
void idCameraAnim::Event_Activate( idEntity *_activator ) {
activator = _activator;
if ( thinkFlags & TH_THINK ) {
Stop();
} else {
Start();
}
}
/*
===============
idCameraAnim::Event_Start
================
*/
void idCameraAnim::Event_Start() {
Start();
}
/*
===============
idCameraAnim::Event_Stop
================
*/
void idCameraAnim::Event_Stop() {
Stop();
}
/*
================
idCameraAnim::Event_SetCallback
================
*/
void idCameraAnim::Event_SetCallback() {
if ( ( gameLocal.GetCamera() == this ) && !threadNum ) {
threadNum = idThread::CurrentThreadNum();
idThread::ReturnInt( true );
} else {
idThread::ReturnInt( false );
}
}

132
neo/d3xp/Camera.h Normal file
View File

@@ -0,0 +1,132 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_CAMERA_H__
#define __GAME_CAMERA_H__
/*
===============================================================================
Camera providing an alternative view of the level.
===============================================================================
*/
class idCamera : public idEntity {
public:
ABSTRACT_PROTOTYPE( idCamera );
void Spawn();
virtual void GetViewParms( renderView_t *view ) = 0;
virtual renderView_t * GetRenderView();
virtual void Stop(){} ;
};
/*
===============================================================================
idCameraView
===============================================================================
*/
class idCameraView : public idCamera {
public:
CLASS_PROTOTYPE( idCameraView );
idCameraView();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn( );
virtual void GetViewParms( renderView_t *view );
virtual void Stop();
protected:
void Event_Activate( idEntity *activator );
void Event_SetAttachments();
void SetAttachment( idEntity **e, const char *p );
float fov;
idEntity *attachedTo;
idEntity *attachedView;
};
/*
===============================================================================
A camera which follows a path defined by an animation.
===============================================================================
*/
typedef struct {
idCQuat q;
idVec3 t;
float fov;
} cameraFrame_t;
class idCameraAnim : public idCamera {
public:
CLASS_PROTOTYPE( idCameraAnim );
idCameraAnim();
~idCameraAnim();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn();
virtual void GetViewParms( renderView_t *view );
private:
int threadNum;
idVec3 offset;
int frameRate;
int starttime;
int cycle;
idList<int> cameraCuts;
idList<cameraFrame_t> camera;
idEntityPtr<idEntity> activator;
void Start();
void Stop();
void Think();
void LoadAnim();
void Event_Start();
void Event_Stop();
void Event_SetCallback();
void Event_Activate( idEntity *activator );
};
#endif /* !__GAME_CAMERA_H__ */

185
neo/d3xp/EndLevel.cpp Normal file
View File

@@ -0,0 +1,185 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
game_endlevel.cpp
This entity is targeted to complete a level, and it also handles
running the stats and moving the camera.
*/
CLASS_DECLARATION( idEntity, idTarget_EndLevel )
EVENT( EV_Activate, idTarget_EndLevel::Event_Trigger )
END_CLASS
/*
================
idTarget_EndLevel::Spawn
================
*/
void idTarget_EndLevel::Spawn( void ) {
idStr guiName;
gui = NULL;
noGui = spawnArgs.GetBool("noGui");
if (!noGui) {
spawnArgs.GetString( "guiName", "guis/EndLevel.gui", guiName );
if (guiName.Length()) {
gui = idUserInterface::FindGui( guiName, true, false, true );
}
}
buttonsReleased = false;
readyToExit = false;
exitCommand = "";
}
/*
================
idTarget_EndLevel::~idTarget_EndLevel()
================
*/
idTarget_EndLevel::~idTarget_EndLevel() {
//FIXME: need to go to smart ptrs for gui allocs or the unique method
//delete gui;
}
/*
================
idTarget_EndLevel::Event_Trigger
================
*/
void idTarget_EndLevel::Event_Trigger( idEntity *activator ) {
if ( gameLocal.endLevel ) {
return;
}
// mark the endLevel, which will modify some game actions
// and pass control to us for drawing the stats and camera position
gameLocal.endLevel = this;
// grab the activating player view position
idPlayer *player = (idPlayer *)(activator);
initialViewOrg = player->GetEyePosition();
initialViewAngles = idVec3( player->viewAngles[0], player->viewAngles[1], player->viewAngles[2] );
// kill all the sounds
gameSoundWorld->StopAllSounds();
if ( noGui ) {
readyToExit = true;
}
}
/*
================
idTarget_EndLevel::Draw
================
*/
void idTarget_EndLevel::Draw() {
if (noGui) {
return;
}
renderView_t renderView;
memset( &renderView, 0, sizeof( renderView ) );
renderView.width = SCREEN_WIDTH;
renderView.height = SCREEN_HEIGHT;
renderView.x = 0;
renderView.y = 0;
renderView.fov_x = 90;
renderView.fov_y = gameLocal.CalcFovY( renderView.fov_x );
renderView.time = gameLocal.time;
#if 0
renderView.vieworg = initialViewOrg;
renderView.viewaxis = idAngles(initialViewAngles).toMat3();
#else
renderView.vieworg = renderEntity.origin;
renderView.viewaxis = renderEntity.axis;
#endif
gameRenderWorld->RenderScene( &renderView );
// draw the gui on top of the 3D view
gui->Redraw(gameLocal.time);
}
/*
================
idTarget_EndLevel::PlayerCommand
================
*/
void idTarget_EndLevel::PlayerCommand( int buttons ) {
if ( !( buttons & BUTTON_ATTACK ) ) {
buttonsReleased = true;
return;
}
if ( !buttonsReleased ) {
return;
}
// we will exit at the end of the next game frame
readyToExit = true;
}
/*
================
idTarget_EndLevel::ExitCommand
================
*/
const char *idTarget_EndLevel::ExitCommand() {
if ( !readyToExit ) {
return NULL;
}
idStr nextMap;
if (spawnArgs.GetString( "nextMap", "", nextMap )) {
sprintf( exitCommand, "map %s", nextMap.c_str() );
} else {
exitCommand = "";
}
return exitCommand;
}

66
neo/d3xp/EndLevel.h Normal file
View File

@@ -0,0 +1,66 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
class idTarget_EndLevel : public idEntity {
public:
CLASS_PROTOTYPE( idTarget_EndLevel );
void Spawn( void );
~idTarget_EndLevel();
void Draw();
// the endLevel will be responsible for drawing the entire screen
// when it is active
void PlayerCommand( int buttons );
// when an endlevel is active, plauer buttons get sent here instead
// of doing anything to the player, which will allow moving to
// the next level
const char *ExitCommand();
// the game will check this each frame, and return it to the
// session when there is something to give
private:
idStr exitCommand;
idVec3 initialViewOrg;
idVec3 initialViewAngles;
// set when the player triggers the exit
idUserInterface *gui;
bool buttonsReleased;
// don't skip out until buttons are released, then pressed
bool readyToExit;
bool noGui;
void Event_Trigger( idEntity *activator );
};

5858
neo/d3xp/Entity.cpp Normal file

File diff suppressed because it is too large Load Diff

711
neo/d3xp/Entity.h Normal file
View File

@@ -0,0 +1,711 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_ENTITY_H__
#define __GAME_ENTITY_H__
/*
===============================================================================
Game entity base class.
===============================================================================
*/
static const int DELAY_DORMANT_TIME = 3000;
extern const idEventDef EV_PostSpawn;
extern const idEventDef EV_FindTargets;
extern const idEventDef EV_Touch;
extern const idEventDef EV_Use;
extern const idEventDef EV_Activate;
extern const idEventDef EV_ActivateTargets;
extern const idEventDef EV_Hide;
extern const idEventDef EV_Show;
extern const idEventDef EV_GetShaderParm;
extern const idEventDef EV_SetShaderParm;
extern const idEventDef EV_SetOwner;
extern const idEventDef EV_GetAngles;
extern const idEventDef EV_SetAngles;
extern const idEventDef EV_SetLinearVelocity;
extern const idEventDef EV_SetAngularVelocity;
extern const idEventDef EV_SetSkin;
extern const idEventDef EV_StartSoundShader;
extern const idEventDef EV_StopSound;
extern const idEventDef EV_CacheSoundShader;
// Think flags
enum {
TH_ALL = -1,
TH_THINK = 1, // run think function each frame
TH_PHYSICS = 2, // run physics each frame
TH_ANIMATE = 4, // update animation each frame
TH_UPDATEVISUALS = 8, // update renderEntity
TH_UPDATEPARTICLES = 16
};
//
// Signals
// make sure to change script/doom_defs.script if you add any, or change their order
//
typedef enum {
SIG_TOUCH, // object was touched
SIG_USE, // object was used
SIG_TRIGGER, // object was activated
SIG_REMOVED, // object was removed from the game
SIG_DAMAGE, // object was damaged
SIG_BLOCKED, // object was blocked
SIG_MOVER_POS1, // mover at position 1 (door closed)
SIG_MOVER_POS2, // mover at position 2 (door open)
SIG_MOVER_1TO2, // mover changing from position 1 to 2
SIG_MOVER_2TO1, // mover changing from position 2 to 1
NUM_SIGNALS
} signalNum_t;
// FIXME: At some point we may want to just limit it to one thread per signal, but
// for now, I'm allowing multiple threads. We should reevaluate this later in the project
#define MAX_SIGNAL_THREADS 16 // probably overkill, but idList uses a granularity of 16
struct signal_t {
int threadnum;
const function_t *function;
};
class signalList_t {
public:
idList<signal_t, TAG_ENTITY> signal[ NUM_SIGNALS ];
};
/*
================================================
idNetEvent
Utility for detecting a bool state change:
-server calls ::Set
-client ::Get will return true (once only)
Useful because:
-Hides client from having to manually declare "last" state and manually checking against it
-using int counter prevents problems w/ dropped snapshots
(ie if we just serialized a bool to true for a single ss, if that ss is dropped,skipped,whatever
the client would never handle it. By incrementing a wrapped counter, we are guaranteed to detect
the state change no matter what happens at the net layer).
================================================
*/
template < int max >
struct idNetEvent {
idNetEvent() : count(0), lastCount(0) { }
void Set() { count = ( ( count + 1 ) % max ); }
bool Get() {
if ( count != lastCount ) {
lastCount = count;
return true;
}
return false;
}
void Serialize( idSerializer &ser ) {
if ( count >= max ) {
idLib::Warning("idNetEvent. count %d > max %d", count, max );
}
ser.SerializeUMax( count, max );
}
public:
static const int Maximum = max;
int count;
int lastCount;
};
typedef idNetEvent< 7 > netBoolEvent_t;
inline void WriteToBitMsg( const netBoolEvent_t & netEvent, idBitMsg & msg ) {
msg.WriteBits( netEvent.count, idMath::BitsForInteger( netBoolEvent_t::Maximum ) );
assert( netEvent.count <= netBoolEvent_t::Maximum );
}
inline void ReadFromBitMsg( netBoolEvent_t & netEvent, const idBitMsg & msg ) {
netEvent.count = msg.ReadBits( idMath::BitsForInteger( netBoolEvent_t::Maximum ) );
assert( netEvent.count <= netBoolEvent_t::Maximum );
}
class idEntity : public idClass {
public:
static const int MAX_PVS_AREAS = 4;
static const uint32 INVALID_PREDICTION_KEY = 0xFFFFFFFF;
int entityNumber; // index into the entity list
int entityDefNumber; // index into the entity def list
idLinkList<idEntity> spawnNode; // for being linked into spawnedEntities list
idLinkList<idEntity> activeNode; // for being linked into activeEntities list
idLinkList<idEntity> aimAssistNode; // linked into gameLocal.aimAssistEntities
idLinkList<idEntity> snapshotNode; // for being linked into snapshotEntities list
int snapshotChanged; // used to detect snapshot state changes
int snapshotBits; // number of bits this entity occupied in the last snapshot
bool snapshotStale; // Set to true if this entity is considered stale in the snapshot
idStr name; // name of entity
idDict spawnArgs; // key/value pairs used to spawn and initialize entity
idScriptObject scriptObject; // contains all script defined data for this entity
int thinkFlags; // TH_? flags
int dormantStart; // time that the entity was first closed off from player
bool cinematic; // during cinematics, entity will only think if cinematic is set
renderView_t * renderView; // for camera views from this entity
idEntity * cameraTarget; // any remoteRenderMap shaders will use this
idList< idEntityPtr<idEntity>, TAG_ENTITY > targets; // when this entity is activated these entities entity are activated
int health; // FIXME: do all objects really need health?
struct entityFlags_s {
bool notarget :1; // if true never attack or target this entity
bool noknockback :1; // if true no knockback from hits
bool takedamage :1; // if true this entity can be damaged
bool hidden :1; // if true this entity is not visible
bool bindOrientated :1; // if true both the master orientation is used for binding
bool solidForTeam :1; // if true this entity is considered solid when a physics team mate pushes entities
bool forcePhysicsUpdate :1; // if true always update from the physics whether the object moved or not
bool selected :1; // if true the entity is selected for editing
bool neverDormant :1; // if true the entity never goes dormant
bool isDormant :1; // if true the entity is dormant
bool hasAwakened :1; // before a monster has been awakened the first time, use full PVS for dormant instead of area-connected
bool networkSync :1; // if true the entity is synchronized over the network
bool grabbed :1; // if true object is currently being grabbed
bool skipReplication :1; // don't replicate this entity over the network.
} fl;
int timeGroup;
bool noGrab;
renderEntity_t xrayEntity;
qhandle_t xrayEntityHandle;
const idDeclSkin * xraySkin;
void DetermineTimeGroup( bool slowmo );
void SetGrabbedState( bool grabbed );
bool IsGrabbed();
public:
ABSTRACT_PROTOTYPE( idEntity );
idEntity();
~idEntity();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
const char * GetEntityDefName() const;
void SetName( const char *name );
const char * GetName() const;
virtual void UpdateChangeableSpawnArgs( const idDict *source );
int GetEntityNumber() const { return entityNumber; }
// clients generate views based on all the player specific options,
// cameras have custom code, and everything else just uses the axis orientation
virtual renderView_t * GetRenderView();
// thinking
virtual void Think();
bool CheckDormant(); // dormant == on the active list, but out of PVS
virtual void DormantBegin(); // called when entity becomes dormant
virtual void DormantEnd(); // called when entity wakes from being dormant
bool IsActive() const;
void BecomeActive( int flags );
void BecomeInactive( int flags );
void UpdatePVSAreas( const idVec3 &pos );
void BecomeReplicated();
// visuals
virtual void Present();
virtual renderEntity_t *GetRenderEntity();
virtual int GetModelDefHandle();
virtual void SetModel( const char *modelname );
void SetSkin( const idDeclSkin *skin );
const idDeclSkin * GetSkin() const;
void SetShaderParm( int parmnum, float value );
virtual void SetColor( float red, float green, float blue );
virtual void SetColor( const idVec3 &color );
virtual void GetColor( idVec3 &out ) const;
virtual void SetColor( const idVec4 &color );
virtual void GetColor( idVec4 &out ) const;
virtual void FreeModelDef();
virtual void FreeLightDef();
virtual void Hide();
virtual void Show();
bool IsHidden() const;
void UpdateVisuals();
void UpdateModel();
void UpdateModelTransform();
virtual void ProjectOverlay( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
int GetNumPVSAreas();
const int * GetPVSAreas();
void ClearPVSAreas();
bool PhysicsTeamInPVS( pvsHandle_t pvsHandle );
// animation
virtual bool UpdateAnimationControllers();
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
virtual idAnimator * GetAnimator(); // returns animator object used by this entity
// sound
virtual bool CanPlayChatterSounds() const;
bool StartSound( const char *soundName, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
bool StartSoundShader( const idSoundShader *shader, const s_channelType channel, int soundShaderFlags, bool broadcast, int *length );
void StopSound( const s_channelType channel, bool broadcast ); // pass SND_CHANNEL_ANY to stop all sounds
void SetSoundVolume( float volume );
void UpdateSound();
int GetListenerId() const;
idSoundEmitter * GetSoundEmitter() const;
void FreeSoundEmitter( bool immediate );
// entity binding
virtual void PreBind();
virtual void PostBind();
virtual void PreUnbind();
virtual void PostUnbind();
void JoinTeam( idEntity *teammember );
void Bind( idEntity *master, bool orientated );
void BindToJoint( idEntity *master, const char *jointname, bool orientated );
void BindToJoint( idEntity *master, jointHandle_t jointnum, bool orientated );
void BindToBody( idEntity *master, int bodyId, bool orientated );
void Unbind();
bool IsBound() const;
bool IsBoundTo( idEntity *master ) const;
idEntity * GetBindMaster() const;
jointHandle_t GetBindJoint() const;
int GetBindBody() const;
idEntity * GetTeamMaster() const;
idEntity * GetNextTeamEntity() const;
void ConvertLocalToWorldTransform( idVec3 &offset, idMat3 &axis );
idVec3 GetLocalVector( const idVec3 &vec ) const;
idVec3 GetLocalCoordinates( const idVec3 &vec ) const;
idVec3 GetWorldVector( const idVec3 &vec ) const;
idVec3 GetWorldCoordinates( const idVec3 &vec ) const;
bool GetMasterPosition( idVec3 &masterOrigin, idMat3 &masterAxis ) const;
void GetWorldVelocities( idVec3 &linearVelocity, idVec3 &angularVelocity ) const;
// physics
// set a new physics object to be used by this entity
void SetPhysics( idPhysics *phys );
// get the physics object used by this entity
idPhysics * GetPhysics() const;
// restore physics pointer for save games
void RestorePhysics( idPhysics *phys );
// run the physics for this entity
bool RunPhysics();
// Interpolates the physics, used on MP clients.
void InterpolatePhysics( const float fraction );
// InterpolatePhysics actually calls evaluate, this version doesn't.
void InterpolatePhysicsOnly( const float fraction, bool updateTeam = false );
// set the origin of the physics object (relative to bindMaster if not NULL)
void SetOrigin( const idVec3 &org );
// set the axis of the physics object (relative to bindMaster if not NULL)
void SetAxis( const idMat3 &axis );
// use angles to set the axis of the physics object (relative to bindMaster if not NULL)
void SetAngles( const idAngles &ang );
// get the floor position underneath the physics object
bool GetFloorPos( float max_dist, idVec3 &floorpos ) const;
// retrieves the transformation going from the physics origin/axis to the visual origin/axis
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
// retrieves the transformation going from the physics origin/axis to the sound origin/axis
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
// called from the physics object when colliding, should return true if the physics simulation should stop
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
// retrieves impact information, 'ent' is the entity retrieving the info
virtual void GetImpactInfo( idEntity *ent, int id, const idVec3 &point, impactInfo_t *info );
// apply an impulse to the physics object, 'ent' is the entity applying the impulse
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
// add a force to the physics object, 'ent' is the entity adding the force
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
// activate the physics object, 'ent' is the entity activating this entity
virtual void ActivatePhysics( idEntity *ent );
// returns true if the physics object is at rest
virtual bool IsAtRest() const;
// returns the time the physics object came to rest
virtual int GetRestStartTime() const;
// add a contact entity
virtual void AddContactEntity( idEntity *ent );
// remove a touching entity
virtual void RemoveContactEntity( idEntity *ent );
// damage
// returns true if this entity can be damaged from the given origin
virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const;
// applies damage to this entity
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
// adds a damage effect like overlays, blood, sparks, debris etc.
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
// callback function for when another entity received damage from this entity. damage can be adjusted and returned to the caller.
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
// notifies this entity that it is in pain
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// notifies this entity that is has been killed
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// scripting
virtual bool ShouldConstructScriptObjectAtSpawn() const;
virtual idThread * ConstructScriptObject();
virtual void DeconstructScriptObject();
void SetSignal( signalNum_t signalnum, idThread *thread, const function_t *function );
void ClearSignal( idThread *thread, signalNum_t signalnum );
void ClearSignalThread( signalNum_t signalnum, idThread *thread );
bool HasSignal( signalNum_t signalnum ) const;
void Signal( signalNum_t signalnum );
void SignalEvent( idThread *thread, signalNum_t signalnum );
// gui
void TriggerGuis();
bool HandleGuiCommands( idEntity *entityGui, const char *cmds );
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
// targets
void FindTargets();
void RemoveNullTargets();
void ActivateTargets( idEntity *activator ) const;
// misc
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
bool TouchTriggers() const;
idCurve_Spline<idVec3> *GetSpline() const;
virtual void ShowEditingDialog();
enum {
EVENT_STARTSOUNDSHADER,
EVENT_STOPSOUNDSHADER,
EVENT_MAXEVENTS
};
// Called on clients in an MP game, does the actual interpolation for the entity.
// This function will eventually replace ClientPredictionThink completely.
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void ClientPredictionThink();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
void ReadFromSnapshot_Ex( const idBitMsg &msg );
virtual void ReadFromSnapshot( const idBitMsg &msg );
virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
void WriteBindToSnapshot( idBitMsg &msg ) const;
void ReadBindFromSnapshot( const idBitMsg &msg );
void WriteColorToSnapshot( idBitMsg &msg ) const;
void ReadColorFromSnapshot( const idBitMsg &msg );
void WriteGUIToSnapshot( idBitMsg &msg ) const;
void ReadGUIFromSnapshot( const idBitMsg &msg );
void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, lobbyUserID_t excluding = lobbyUserID_t() ) const;
void ClientSendEvent( int eventId, const idBitMsg *msg ) const;
void SetUseClientInterpolation( bool use ) { useClientInterpolation = use; }
void SetSkipReplication( const bool skip ) { fl.skipReplication = skip; }
bool GetSkipReplication() const { return fl.skipReplication; }
bool IsReplicated() const { return GetEntityNumber() < ENTITYNUM_FIRST_NON_REPLICATED; }
void CreateDeltasFromOldOriginAndAxis( const idVec3 & oldOrigin, const idMat3 & oldAxis );
void DecayOriginAndAxisDelta();
uint32 GetPredictedKey() { return predictionKey; }
void SetPredictedKey( uint32 key_ ) { predictionKey = key_; }
void FlagNewSnapshot();
idEntity* GetTeamChain() { return teamChain; }
// It is only safe to interpolate if this entity has received two snapshots.
enum interpolationBehavior_t {
USE_NO_INTERPOLATION,
USE_LATEST_SNAP_ONLY,
USE_INTERPOLATION
};
interpolationBehavior_t GetInterpolationBehavior() const { return interpolationBehavior; }
unsigned int GetNumSnapshotsReceived() const { return snapshotsReceived; }
protected:
renderEntity_t renderEntity; // used to present a model to the renderer
int modelDefHandle; // handle to static renderer model
refSound_t refSound; // used to present sound to the audio engine
idVec3 GetOriginDelta() const { return originDelta; }
idMat3 GetAxisDelta() const { return axisDelta; }
private:
idPhysics_Static defaultPhysicsObj; // default physics object
idPhysics * physics; // physics used for this entity
idEntity * bindMaster; // entity bound to if unequal NULL
jointHandle_t bindJoint; // joint bound to if unequal INVALID_JOINT
int bindBody; // body bound to if unequal -1
idEntity * teamMaster; // master of the physics team
idEntity * teamChain; // next entity in physics team
bool useClientInterpolation; // disables interpolation for some objects (handy for weapon world models)
int numPVSAreas; // number of renderer areas the entity covers
int PVSAreas[MAX_PVS_AREAS]; // numbers of the renderer areas the entity covers
signalList_t * signals;
int mpGUIState; // local cache to avoid systematic SetStateInt
uint32 predictionKey; // Unique key used to sync predicted ents (projectiles) in MP.
// Delta values that are set when the server or client disagree on where the render model should be. If this happens,
// they resolve it through DecayOriginAndAxisDelta()
idVec3 originDelta;
idMat3 axisDelta;
interpolationBehavior_t interpolationBehavior;
unsigned int snapshotsReceived;
private:
void FixupLocalizedStrings();
bool DoDormantTests(); // dormant == on the active list, but out of PVS
// physics
// initialize the default physics
void InitDefaultPhysics( const idVec3 &origin, const idMat3 &axis );
// update visual position from the physics
void UpdateFromPhysics( bool moveBack );
// get physics timestep
virtual int GetPhysicsTimeStep() const;
// entity binding
bool InitBind( idEntity *master ); // initialize an entity binding
void FinishBind(); // finish an entity binding
void RemoveBinds(); // deletes any entities bound to this object
void QuitTeam(); // leave the current team
void UpdatePVSAreas();
// events
void Event_GetName();
void Event_SetName( const char *name );
void Event_FindTargets();
void Event_ActivateTargets( idEntity *activator );
void Event_NumTargets();
void Event_GetTarget( float index );
void Event_RandomTarget( const char *ignore );
void Event_Bind( idEntity *master );
void Event_BindPosition( idEntity *master );
void Event_BindToJoint( idEntity *master, const char *jointname, float orientated );
void Event_Unbind();
void Event_RemoveBinds();
void Event_SpawnBind();
void Event_SetOwner( idEntity *owner );
void Event_SetModel( const char *modelname );
void Event_SetSkin( const char *skinname );
void Event_GetShaderParm( int parmnum );
void Event_SetShaderParm( int parmnum, float value );
void Event_SetShaderParms( float parm0, float parm1, float parm2, float parm3 );
void Event_SetColor( float red, float green, float blue );
void Event_GetColor();
void Event_IsHidden();
void Event_Hide();
void Event_Show();
void Event_CacheSoundShader( const char *soundName );
void Event_StartSoundShader( const char *soundName, int channel );
void Event_StopSound( int channel, int netSync );
void Event_StartSound( const char *soundName, int channel, int netSync );
void Event_FadeSound( int channel, float to, float over );
void Event_GetWorldOrigin();
void Event_SetWorldOrigin( idVec3 const &org );
void Event_GetOrigin();
void Event_SetOrigin( const idVec3 &org );
void Event_GetAngles();
void Event_SetAngles( const idAngles &ang );
void Event_SetLinearVelocity( const idVec3 &velocity );
void Event_GetLinearVelocity();
void Event_SetAngularVelocity( const idVec3 &velocity );
void Event_GetAngularVelocity();
void Event_SetSize( const idVec3 &mins, const idVec3 &maxs );
void Event_GetSize();
void Event_GetMins();
void Event_GetMaxs();
void Event_Touches( idEntity *ent );
void Event_SetGuiParm( const char *key, const char *val );
void Event_SetGuiFloat( const char *key, float f );
void Event_GetNextKey( const char *prefix, const char *lastMatch );
void Event_SetKey( const char *key, const char *value );
void Event_GetKey( const char *key );
void Event_GetIntKey( const char *key );
void Event_GetFloatKey( const char *key );
void Event_GetVectorKey( const char *key );
void Event_GetEntityKey( const char *key );
void Event_RestorePosition();
void Event_UpdateCameraTarget();
void Event_DistanceTo( idEntity *ent );
void Event_DistanceToPoint( const idVec3 &point );
void Event_StartFx( const char *fx );
void Event_WaitFrame();
void Event_Wait( float time );
void Event_HasFunction( const char *name );
void Event_CallFunction( const char *name );
void Event_SetNeverDormant( int enable );
void Event_SetGui( int guiNum, const char *guiName);
void Event_PrecacheGui( const char *guiName );
void Event_GetGuiParm(int guiNum, const char *key);
void Event_GetGuiParmFloat(int guiNum, const char *key);
void Event_GuiNamedEvent(int guiNum, const char *event);
};
/*
===============================================================================
Animated entity base class.
===============================================================================
*/
typedef struct damageEffect_s {
jointHandle_t jointNum;
idVec3 localOrigin;
idVec3 localNormal;
int time;
const idDeclParticle* type;
struct damageEffect_s * next;
} damageEffect_t;
class idAnimatedEntity : public idEntity {
public:
CLASS_PROTOTYPE( idAnimatedEntity );
idAnimatedEntity();
~idAnimatedEntity();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void ClientPredictionThink();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void Think();
void UpdateAnimation();
virtual idAnimator * GetAnimator();
virtual void SetModel( const char *modelname );
bool GetJointWorldTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis );
bool GetJointTransformForAnim( jointHandle_t jointHandle, int animNum, int currentTime, idVec3 &offset, idMat3 &axis ) const;
virtual int GetDefaultSurfaceType() const;
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
void AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial );
void UpdateDamageEffects();
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
enum {
EVENT_ADD_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
protected:
idAnimator animator;
damageEffect_t * damageEffects;
private:
void Event_GetJointHandle( const char *jointname );
void Event_ClearAllJoints();
void Event_ClearJoint( jointHandle_t jointnum );
void Event_SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos );
void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles );
void Event_GetJointPos( jointHandle_t jointnum );
void Event_GetJointAngle( jointHandle_t jointnum );
};
class SetTimeState {
bool activated;
bool previousFast;
bool fast;
public:
SetTimeState();
SetTimeState( int timeGroup );
~SetTimeState();
void PushState( int timeGroup );
};
ID_INLINE SetTimeState::SetTimeState() {
activated = false;
}
ID_INLINE SetTimeState::SetTimeState( int timeGroup ) {
activated = false;
PushState( timeGroup );
}
ID_INLINE void SetTimeState::PushState( int timeGroup ) {
// Don't mess with time in Multiplayer
if ( !common->IsMultiplayer() ) {
activated = true;
// determine previous fast setting
if ( gameLocal.time == gameLocal.slow.time ) {
previousFast = false;
} else {
previousFast = true;
}
// determine new fast setting
if ( timeGroup ) {
fast = true;
} else {
fast = false;
}
// set correct time
gameLocal.SelectTimeGroup( timeGroup );
}
}
ID_INLINE SetTimeState::~SetTimeState() {
if ( activated && !common->IsMultiplayer() ) {
// set previous correct time
gameLocal.SelectTimeGroup( previousFast );
}
}
#endif /* !__GAME_ENTITY_H__ */

833
neo/d3xp/Fx.cpp Normal file
View File

@@ -0,0 +1,833 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
===============================================================================
idEntityFx
===============================================================================
*/
const idEventDef EV_Fx_KillFx( "_killfx" );
const idEventDef EV_Fx_Action( "_fxAction", "e" ); // implemented by subclasses
CLASS_DECLARATION( idEntity, idEntityFx )
EVENT( EV_Activate, idEntityFx::Event_Trigger )
EVENT( EV_Fx_KillFx, idEntityFx::Event_ClearFx )
END_CLASS
/*
================
idEntityFx::Save
================
*/
void idEntityFx::Save( idSaveGame *savefile ) const {
int i;
savefile->WriteInt( started );
savefile->WriteInt( nextTriggerTime );
savefile->WriteFX( fxEffect );
savefile->WriteString( systemName );
savefile->WriteInt( actions.Num() );
for ( i = 0; i < actions.Num(); i++ ) {
if ( actions[i].lightDefHandle >= 0 ) {
savefile->WriteBool( true );
savefile->WriteRenderLight( actions[i].renderLight );
} else {
savefile->WriteBool( false );
}
if ( actions[i].modelDefHandle >= 0 ) {
savefile->WriteBool( true );
savefile->WriteRenderEntity( actions[i].renderEntity );
} else {
savefile->WriteBool( false );
}
savefile->WriteFloat( actions[i].delay );
savefile->WriteInt( actions[i].start );
savefile->WriteBool( actions[i].soundStarted );
savefile->WriteBool( actions[i].shakeStarted );
savefile->WriteBool( actions[i].decalDropped );
savefile->WriteBool( actions[i].launched );
}
}
/*
================
idEntityFx::Restore
================
*/
void idEntityFx::Restore( idRestoreGame *savefile ) {
int i;
int num;
bool hasObject;
savefile->ReadInt( started );
savefile->ReadInt( nextTriggerTime );
savefile->ReadFX( fxEffect );
savefile->ReadString( systemName );
savefile->ReadInt( num );
actions.SetNum( num );
for ( i = 0; i < num; i++ ) {
savefile->ReadBool( hasObject );
if ( hasObject ) {
savefile->ReadRenderLight( actions[i].renderLight );
actions[i].lightDefHandle = gameRenderWorld->AddLightDef( &actions[i].renderLight );
} else {
memset( &actions[i].renderLight, 0, sizeof( renderLight_t ) );
actions[i].lightDefHandle = -1;
}
savefile->ReadBool( hasObject );
if ( hasObject ) {
savefile->ReadRenderEntity( actions[i].renderEntity );
actions[i].modelDefHandle = gameRenderWorld->AddEntityDef( &actions[i].renderEntity );
} else {
memset( &actions[i].renderEntity, 0, sizeof( renderEntity_t ) );
actions[i].modelDefHandle = -1;
}
savefile->ReadFloat( actions[i].delay );
// let the FX regenerate the particleSystem
actions[i].particleSystem = -1;
savefile->ReadInt( actions[i].start );
savefile->ReadBool( actions[i].soundStarted );
savefile->ReadBool( actions[i].shakeStarted );
savefile->ReadBool( actions[i].decalDropped );
savefile->ReadBool( actions[i].launched );
}
}
/*
================
idEntityFx::Setup
================
*/
void idEntityFx::Setup( const char *fx ) {
if ( started >= 0 ) {
return; // already started
}
// early during MP Spawn() with no information. wait till we ReadFromSnapshot for more
if ( common->IsClient() && ( !fx || fx[0] == '\0' ) ) {
return;
}
systemName = fx;
started = 0;
fxEffect = static_cast<const idDeclFX *>( declManager->FindType( DECL_FX, systemName.c_str() ) );
if ( fxEffect ) {
idFXLocalAction localAction;
memset( &localAction, 0, sizeof( idFXLocalAction ) );
actions.AssureSize( fxEffect->events.Num(), localAction );
for( int i = 0; i<fxEffect->events.Num(); i++ ) {
const idFXSingleAction& fxaction = fxEffect->events[i];
idFXLocalAction& laction = actions[i];
if ( fxaction.random1 || fxaction.random2 ) {
laction.delay = fxaction.random1 + gameLocal.random.RandomFloat() * ( fxaction.random2 - fxaction.random1 );
} else {
laction.delay = fxaction.delay;
}
laction.start = -1;
laction.lightDefHandle = -1;
laction.modelDefHandle = -1;
laction.particleSystem = -1;
laction.shakeStarted = false;
laction.decalDropped = false;
laction.launched = false;
}
}
}
/*
================
idEntityFx::EffectName
================
*/
const char *idEntityFx::EffectName() {
return fxEffect ? fxEffect->GetName() : NULL;
}
/*
================
idEntityFx::Joint
================
*/
const char *idEntityFx::Joint() {
return fxEffect ? fxEffect->joint.c_str() : NULL;
}
/*
================
idEntityFx::CleanUp
================
*/
void idEntityFx::CleanUp() {
if ( !fxEffect ) {
return;
}
for( int i = 0; i < fxEffect->events.Num(); i++ ) {
const idFXSingleAction& fxaction = fxEffect->events[i];
idFXLocalAction& laction = actions[i];
CleanUpSingleAction( fxaction, laction );
}
}
/*
================
idEntityFx::CleanUpSingleAction
================
*/
void idEntityFx::CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction ) {
if ( laction.lightDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHLIGHT ) {
gameRenderWorld->FreeLightDef( laction.lightDefHandle );
laction.lightDefHandle = -1;
}
if ( laction.modelDefHandle != -1 && fxaction.sibling == -1 && fxaction.type != FX_ATTACHENTITY ) {
gameRenderWorld->FreeEntityDef( laction.modelDefHandle );
laction.modelDefHandle = -1;
}
laction.start = -1;
}
/*
================
idEntityFx::Start
================
*/
void idEntityFx::Start( int time ) {
if ( !fxEffect ) {
return;
}
started = time;
for( int i = 0; i < fxEffect->events.Num(); i++ ) {
idFXLocalAction& laction = actions[i];
laction.start = time;
laction.soundStarted = false;
laction.shakeStarted = false;
laction.particleSystem = -1;
laction.decalDropped = false;
laction.launched = false;
}
}
/*
================
idEntityFx::Stop
================
*/
void idEntityFx::Stop() {
CleanUp();
started = -1;
}
/*
================
idEntityFx::Duration
================
*/
const int idEntityFx::Duration() {
int max = 0;
if ( !fxEffect ) {
return max;
}
for( int i = 0; i < fxEffect->events.Num(); i++ ) {
const idFXSingleAction& fxaction = fxEffect->events[i];
int d = ( fxaction.delay + fxaction.duration ) * 1000.0f;
if ( d > max ) {
max = d;
}
}
return max;
}
/*
================
idEntityFx::Done
================
*/
const bool idEntityFx::Done() {
if (started > 0 && gameLocal.time > started + Duration()) {
return true;
}
return false;
}
/*
================
idEntityFx::ApplyFade
================
*/
void idEntityFx::ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart ) {
if ( fxaction.fadeInTime || fxaction.fadeOutTime ) {
float fadePct = (float)( time - actualStart ) / ( 1000.0f * ( ( fxaction.fadeInTime != 0 ) ? fxaction.fadeInTime : fxaction.fadeOutTime ) );
if (fadePct > 1.0) {
fadePct = 1.0;
}
if ( laction.modelDefHandle != -1 ) {
laction.renderEntity.shaderParms[SHADERPARM_RED] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct;
laction.renderEntity.shaderParms[SHADERPARM_GREEN] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct;
laction.renderEntity.shaderParms[SHADERPARM_BLUE] = (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct;
gameRenderWorld->UpdateEntityDef( laction.modelDefHandle, &laction.renderEntity );
}
if ( laction.lightDefHandle != -1 ) {
laction.renderLight.shaderParms[SHADERPARM_RED] = fxaction.lightColor.x * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct );
laction.renderLight.shaderParms[SHADERPARM_GREEN] = fxaction.lightColor.y * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct );
laction.renderLight.shaderParms[SHADERPARM_BLUE] = fxaction.lightColor.z * ( (fxaction.fadeInTime) ? fadePct : 1.0f - fadePct );
gameRenderWorld->UpdateLightDef( laction.lightDefHandle, &laction.renderLight );
}
}
}
/*
================
idEntityFx::Run
================
*/
void idEntityFx::Run( int time ) {
int ieff, j;
idEntity *ent = NULL;
const idDict *projectileDef = NULL;
idProjectile *projectile = NULL;
if ( !fxEffect ) {
return;
}
for( ieff = 0; ieff < fxEffect->events.Num(); ieff++ ) {
const idFXSingleAction& fxaction = fxEffect->events[ieff];
idFXLocalAction& laction = actions[ieff];
//
// if we're currently done with this one
//
if ( laction.start == -1 ) {
continue;
}
//
// see if it's delayed
//
if ( laction.delay ) {
if ( laction.start + (time - laction.start) < laction.start + (laction.delay * 1000) ) {
continue;
}
}
//
// each event can have it's own delay and restart
//
int actualStart = laction.delay ? laction.start + (int)( laction.delay * 1000 ) : laction.start;
float pct = (float)( time - actualStart ) / (1000 * fxaction.duration );
if ( pct >= 1.0f ) {
laction.start = -1;
float totalDelay = 0.0f;
if ( fxaction.restart ) {
if ( fxaction.random1 || fxaction.random2 ) {
totalDelay = fxaction.random1 + gameLocal.random.RandomFloat() * (fxaction.random2 - fxaction.random1);
} else {
totalDelay = fxaction.delay;
}
laction.delay = totalDelay;
laction.start = time;
}
continue;
}
if ( fxaction.fire.Length() ) {
for( j = 0; j < fxEffect->events.Num(); j++ ) {
if ( fxEffect->events[j].name.Icmp( fxaction.fire ) == 0 ) {
actions[j].delay = 0;
}
}
}
idFXLocalAction *useAction;
if ( fxaction.sibling == -1 ) {
useAction = &laction;
} else {
useAction = &actions[fxaction.sibling];
}
assert( useAction );
switch( fxaction.type ) {
case FX_ATTACHLIGHT:
case FX_LIGHT: {
if ( useAction->lightDefHandle == -1 ) {
if ( fxaction.type == FX_LIGHT ) {
memset( &useAction->renderLight, 0, sizeof( renderLight_t ) );
useAction->renderLight.origin = GetPhysics()->GetOrigin() + fxaction.offset;
useAction->renderLight.axis = GetPhysics()->GetAxis();
useAction->renderLight.lightRadius[0] = fxaction.lightRadius;
useAction->renderLight.lightRadius[1] = fxaction.lightRadius;
useAction->renderLight.lightRadius[2] = fxaction.lightRadius;
useAction->renderLight.shader = declManager->FindMaterial( fxaction.data, false );
useAction->renderLight.shaderParms[ SHADERPARM_RED ] = fxaction.lightColor.x;
useAction->renderLight.shaderParms[ SHADERPARM_GREEN ] = fxaction.lightColor.y;
useAction->renderLight.shaderParms[ SHADERPARM_BLUE ] = fxaction.lightColor.z;
useAction->renderLight.shaderParms[ SHADERPARM_TIMESCALE ] = 1.0f;
useAction->renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time );
useAction->renderLight.referenceSound = refSound.referenceSound;
useAction->renderLight.pointLight = true;
if ( fxaction.noshadows ) {
useAction->renderLight.noShadows = true;
}
useAction->lightDefHandle = gameRenderWorld->AddLightDef( &useAction->renderLight );
}
if ( fxaction.noshadows ) {
for( j = 0; j < fxEffect->events.Num(); j++ ) {
idFXLocalAction& laction2 = actions[j];
if ( laction2.modelDefHandle != -1 ) {
laction2.renderEntity.noShadow = true;
}
}
}
}
ApplyFade( fxaction, *useAction, time, actualStart );
break;
}
case FX_SOUND: {
if ( !useAction->soundStarted ) {
useAction->soundStarted = true;
const idSoundShader *shader = declManager->FindSound(fxaction.data);
StartSoundShader( shader, SND_CHANNEL_ANY, 0, false, NULL );
for( j = 0; j < fxEffect->events.Num(); j++ ) {
idFXLocalAction& laction2 = actions[j];
if ( laction2.lightDefHandle != -1 ) {
laction2.renderLight.referenceSound = refSound.referenceSound;
gameRenderWorld->UpdateLightDef( laction2.lightDefHandle, &laction2.renderLight );
}
}
}
break;
}
case FX_DECAL: {
if ( !useAction->decalDropped ) {
useAction->decalDropped = true;
gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 8.0f, true, fxaction.size, fxaction.data );
}
break;
}
case FX_SHAKE: {
if ( !useAction->shakeStarted ) {
idDict args;
args.Clear();
args.SetFloat( "kick_time", fxaction.shakeTime );
args.SetFloat( "kick_amplitude", fxaction.shakeAmplitude );
for ( j = 0; j < gameLocal.numClients; j++ ) {
idPlayer *player = gameLocal.GetClientByNum( j );
if ( player && ( player->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).LengthSqr() < Square( fxaction.shakeDistance ) ) {
if ( !common->IsMultiplayer() || !fxaction.shakeIgnoreMaster || GetBindMaster() != player ) {
player->playerView.DamageImpulse( fxaction.offset, &args );
}
}
}
if ( fxaction.shakeImpulse != 0.0f && fxaction.shakeDistance != 0.0f ) {
idEntity *ignore_ent = NULL;
if ( common->IsMultiplayer() ) {
ignore_ent = this;
if ( fxaction.shakeIgnoreMaster ) {
ignore_ent = GetBindMaster();
}
}
// lookup the ent we are bound to?
gameLocal.RadiusPush( GetPhysics()->GetOrigin(), fxaction.shakeDistance, fxaction.shakeImpulse, this, ignore_ent, 1.0f, true );
}
useAction->shakeStarted = true;
}
break;
}
case FX_ATTACHENTITY:
case FX_PARTICLE:
case FX_MODEL: {
if ( useAction->modelDefHandle == -1 ) {
memset( &useAction->renderEntity, 0, sizeof( renderEntity_t ) );
useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset;
useAction->renderEntity.axis = (fxaction.explicitAxis) ? fxaction.axis : GetPhysics()->GetAxis();
useAction->renderEntity.hModel = renderModelManager->FindModel( fxaction.data );
useAction->renderEntity.shaderParms[ SHADERPARM_RED ] = 1.0f;
useAction->renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1.0f;
useAction->renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1.0f;
useAction->renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( time );
useAction->renderEntity.shaderParms[3] = 1.0f;
useAction->renderEntity.shaderParms[5] = 0.0f;
if ( useAction->renderEntity.hModel ) {
useAction->renderEntity.bounds = useAction->renderEntity.hModel->Bounds( &useAction->renderEntity );
}
useAction->modelDefHandle = gameRenderWorld->AddEntityDef( &useAction->renderEntity );
} else if ( fxaction.trackOrigin ) {
useAction->renderEntity.origin = GetPhysics()->GetOrigin() + fxaction.offset;
useAction->renderEntity.axis = fxaction.explicitAxis ? fxaction.axis : GetPhysics()->GetAxis();
gameRenderWorld->UpdateEntityDef( useAction->modelDefHandle, &useAction->renderEntity );
}
ApplyFade( fxaction, *useAction, time, actualStart );
break;
}
case FX_LAUNCH: {
if ( common->IsClient() ) {
// client never spawns entities outside of ClientReadSnapshot
useAction->launched = true;
break;
}
if ( !useAction->launched ) {
useAction->launched = true;
projectile = NULL;
// FIXME: may need to cache this if it is slow
projectileDef = gameLocal.FindEntityDefDict( fxaction.data, false );
if ( !projectileDef ) {
gameLocal.Warning( "projectile \'%s\' not found", fxaction.data.c_str() );
} else {
gameLocal.SpawnEntityDef( *projectileDef, &ent, false );
if ( ent && ent->IsType( idProjectile::Type ) ) {
projectile = ( idProjectile * )ent;
projectile->Create( this, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0] );
projectile->Launch( GetPhysics()->GetOrigin(), GetPhysics()->GetAxis()[0], vec3_origin );
}
}
}
break;
}
case FX_SHOCKWAVE: {
if ( common->IsClient() ) {
useAction->shakeStarted = true;
break;
}
if ( !useAction->shakeStarted ) {
idStr shockDefName;
useAction->shakeStarted = true;
shockDefName = fxaction.data;
if ( !shockDefName.Length() ) {
shockDefName = "func_shockwave";
}
projectileDef = gameLocal.FindEntityDefDict( shockDefName, false );
if ( !projectileDef ) {
gameLocal.Warning( "shockwave \'%s\' not found", shockDefName.c_str() );
} else {
gameLocal.SpawnEntityDef( *projectileDef, &ent );
ent->SetOrigin( GetPhysics()->GetOrigin() + fxaction.offset );
ent->PostEventMS( &EV_Remove, ent->spawnArgs.GetInt( "duration" ) );
}
}
break;
}
}
}
}
/*
================
idEntityFx::idEntityFx
================
*/
idEntityFx::idEntityFx() {
fxEffect = NULL;
started = -1;
nextTriggerTime = -1;
fl.networkSync = true;
}
/*
================
idEntityFx::~idEntityFx
================
*/
idEntityFx::~idEntityFx() {
CleanUp();
fxEffect = NULL;
}
/*
================
idEntityFx::Spawn
================
*/
void idEntityFx::Spawn() {
if ( g_skipFX.GetBool() ) {
return;
}
const char *fx;
nextTriggerTime = 0;
fxEffect = NULL;
if ( spawnArgs.GetString( "fx", "", &fx ) ) {
systemName = fx;
}
if ( !spawnArgs.GetBool( "triggered" ) ) {
Setup( fx );
if ( spawnArgs.GetBool( "test" ) || spawnArgs.GetBool( "start" ) || spawnArgs.GetFloat ( "restart" ) ) {
PostEventMS( &EV_Activate, 0, this );
}
}
}
/*
================
idEntityFx::Think
Clears any visual fx started when {item,mob,player} was spawned
================
*/
void idEntityFx::Think() {
if ( g_skipFX.GetBool() ) {
return;
}
if ( thinkFlags & TH_THINK ) {
Run( gameLocal.time );
}
RunPhysics();
Present();
}
/*
================
idEntityFx::Event_ClearFx
Clears any visual fx started when item(mob) was spawned
================
*/
void idEntityFx::Event_ClearFx() {
if ( g_skipFX.GetBool() ) {
return;
}
Stop();
CleanUp();
BecomeInactive( TH_THINK );
if ( spawnArgs.GetBool("test") ) {
PostEventMS( &EV_Activate, 0, this );
} else {
if ( spawnArgs.GetFloat( "restart" ) || !spawnArgs.GetBool( "triggered")) {
float rest = spawnArgs.GetFloat( "restart", "0" );
if ( rest == 0.0f ) {
PostEventSec( &EV_Remove, 0.1f );
} else {
rest *= gameLocal.random.RandomFloat();
PostEventSec( &EV_Activate, rest, this );
}
}
}
}
/*
================
idEntityFx::Event_Trigger
================
*/
void idEntityFx::Event_Trigger( idEntity *activator ) {
if ( g_skipFX.GetBool() ) {
return;
}
float fxActionDelay;
const char *fx;
if ( gameLocal.time < nextTriggerTime ) {
return;
}
if ( spawnArgs.GetString( "fx", "", &fx) ) {
Setup( fx );
Start( gameLocal.time );
PostEventMS( &EV_Fx_KillFx, Duration() );
BecomeActive( TH_THINK );
}
fxActionDelay = spawnArgs.GetFloat( "fxActionDelay" );
if ( fxActionDelay != 0.0f ) {
nextTriggerTime = gameLocal.time + SEC2MS( fxActionDelay );
} else {
// prevent multiple triggers on same frame
nextTriggerTime = gameLocal.time + 1;
}
PostEventSec( &EV_Fx_Action, fxActionDelay, activator );
}
/*
================
idEntityFx::StartFx
================
*/
idEntityFx *idEntityFx::StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind ) {
if ( g_skipFX.GetBool() || !fx || !*fx ) {
return NULL;
}
idDict args;
args.SetBool( "start", true );
args.Set( "fx", fx );
idEntityFx *nfx = static_cast<idEntityFx *>( gameLocal.SpawnEntityType( idEntityFx::Type, &args ) );
if ( nfx->Joint() && *nfx->Joint() ) {
nfx->BindToJoint( ent, nfx->Joint(), true );
nfx->SetOrigin( vec3_origin );
} else {
nfx->SetOrigin( (useOrigin) ? *useOrigin : ent->GetPhysics()->GetOrigin() );
nfx->SetAxis( (useAxis) ? *useAxis : ent->GetPhysics()->GetAxis() );
}
if ( bind ) {
// never bind to world spawn
if ( ent != gameLocal.world ) {
nfx->Bind( ent, true );
}
}
nfx->Show();
return nfx;
}
/*
=================
idEntityFx::WriteToSnapshot
=================
*/
void idEntityFx::WriteToSnapshot( idBitMsg &msg ) const {
GetPhysics()->WriteToSnapshot( msg );
WriteBindToSnapshot( msg );
msg.WriteLong( ( fxEffect != NULL ) ? gameLocal.ServerRemapDecl( -1, DECL_FX, fxEffect->Index() ) : -1 );
msg.WriteLong( started );
}
/*
=================
idEntityFx::ReadFromSnapshot
=================
*/
void idEntityFx::ReadFromSnapshot( const idBitMsg &msg ) {
int fx_index, start_time, max_lapse;
GetPhysics()->ReadFromSnapshot( msg );
ReadBindFromSnapshot( msg );
fx_index = gameLocal.ClientRemapDecl( DECL_FX, msg.ReadLong() );
start_time = msg.ReadLong();
if ( fx_index != -1 && start_time > 0 && !fxEffect && started < 0 ) {
spawnArgs.GetInt( "effect_lapse", "1000", max_lapse );
if ( gameLocal.time - start_time > max_lapse ) {
// too late, skip the effect completely
started = 0;
return;
}
const idDeclFX *fx = static_cast<const idDeclFX *>( declManager->DeclByIndex( DECL_FX, fx_index ) );
if ( !fx ) {
gameLocal.Error( "FX at index %d not found", fx_index );
}
fxEffect = fx;
Setup( fx->GetName() );
Start( start_time );
}
}
/*
=================
idEntityFx::ClientThink
=================
*/
void idEntityFx::ClientThink( const int curTime, const float fraction, const bool predict ) {
if ( gameLocal.isNewFrame ) {
Run( gameLocal.serverTime );
}
InterpolatePhysics( fraction );
Present();
}
/*
=================
idEntityFx::ClientPredictionThink
=================
*/
void idEntityFx::ClientPredictionThink() {
if ( gameLocal.isNewFrame ) {
Run( gameLocal.time );
}
RunPhysics();
Present();
}
/*
===============================================================================
idTeleporter
===============================================================================
*/
CLASS_DECLARATION( idEntityFx, idTeleporter )
EVENT( EV_Fx_Action, idTeleporter::Event_DoAction )
END_CLASS
/*
================
idTeleporter::Event_DoAction
================
*/
void idTeleporter::Event_DoAction( idEntity *activator ) {
float angle;
angle = spawnArgs.GetFloat( "angle" );
idAngles a( 0, spawnArgs.GetFloat( "angle" ), 0 );
activator->Teleport( GetPhysics()->GetOrigin(), a, NULL );
}

107
neo/d3xp/Fx.h Normal file
View File

@@ -0,0 +1,107 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_FX_H__
#define __GAME_FX_H__
/*
===============================================================================
Special effects.
===============================================================================
*/
typedef struct {
renderLight_t renderLight; // light presented to the renderer
qhandle_t lightDefHandle; // handle to renderer light def
renderEntity_t renderEntity; // used to present a model to the renderer
int modelDefHandle; // handle to static renderer model
float delay;
int particleSystem;
int start;
bool soundStarted;
bool shakeStarted;
bool decalDropped;
bool launched;
} idFXLocalAction;
class idEntityFx : public idEntity {
public:
CLASS_PROTOTYPE( idEntityFx );
idEntityFx();
virtual ~idEntityFx();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
void Setup( const char *fx );
void Run( int time );
void Start( int time );
void Stop();
const int Duration();
const char * EffectName();
const char * Joint();
const bool Done();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void ClientPredictionThink();
static idEntityFx * StartFx( const char *fx, const idVec3 *useOrigin, const idMat3 *useAxis, idEntity *ent, bool bind );
protected:
void Event_Trigger( idEntity *activator );
void Event_ClearFx();
void CleanUp();
void CleanUpSingleAction( const idFXSingleAction& fxaction, idFXLocalAction& laction );
void ApplyFade( const idFXSingleAction& fxaction, idFXLocalAction& laction, const int time, const int actualStart );
int started;
int nextTriggerTime;
const idDeclFX * fxEffect; // GetFX() should be called before using fxEffect as a pointer
idList<idFXLocalAction, TAG_FX> actions;
idStr systemName;
};
class idTeleporter : public idEntityFx {
public:
CLASS_PROTOTYPE( idTeleporter );
private:
// teleporters to this location
void Event_DoAction( idEntity *activator );
};
#endif /* !__GAME_FX_H__ */

2
neo/d3xp/Game.def Normal file
View File

@@ -0,0 +1,2 @@
EXPORTS
GetGameAPI

343
neo/d3xp/Game.h Normal file
View File

@@ -0,0 +1,343 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_H__
#define __GAME_H__
/*
===============================================================================
Public game interface with methods to run the game.
===============================================================================
*/
// default scripts
#define SCRIPT_DEFAULTDEFS "script/doom_defs.script"
#define SCRIPT_DEFAULT "script/doom_main.script"
#define SCRIPT_DEFAULTFUNC "doom_main"
struct gameReturn_t {
gameReturn_t() :
syncNextGameFrame( false ),
vibrationLow( 0 ),
vibrationHigh( 0 ) {
}
char sessionCommand[MAX_STRING_CHARS]; // "map", "disconnect", "victory", etc
bool syncNextGameFrame; // used when cinematics are skipped to prevent session from simulating several game frames to
// keep the game time in sync with real time
int vibrationLow;
int vibrationHigh;
};
#define TIME_GROUP1 0
#define TIME_GROUP2 1
class idGame {
public:
virtual ~idGame() {}
// Initialize the game for the first time.
virtual void Init() = 0;
// Shut down the entire game.
virtual void Shutdown() = 0;
// Sets the serverinfo at map loads and when it changes.
virtual void SetServerInfo( const idDict &serverInfo ) = 0;
// Gets the serverinfo, common calls this before saving the game
virtual const idDict & GetServerInfo() = 0;
// Interpolated server time
virtual void SetServerGameTimeMs( const int time ) = 0;
// Interpolated server time
virtual int GetServerGameTimeMs() const = 0;
virtual int GetSSEndTime() const = 0;
virtual int GetSSStartTime() const = 0;
// common calls this before moving the single player game to a new level.
virtual const idDict & GetPersistentPlayerInfo( int clientNum ) = 0;
// common calls this right before a new level is loaded.
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo ) = 0;
// Loads a map and spawns all the entities.
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, int gameMode, int randseed ) = 0;
// Loads a map from a savegame file.
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile, idFile *stringTableFile, int saveGameVersion ) = 0;
// Saves the current game state, common may have written some data to the file already.
virtual void SaveGame( idFile *saveGameFile, idFile *stringTableFile ) = 0;
// Pulls the current player location from the game information
virtual void GetSaveGameDetails( idSaveGameDetails & gameDetails ) = 0;
// Shut down the current map.
virtual void MapShutdown() = 0;
// Caches media referenced from in key/value pairs in the given dictionary.
virtual void CacheDictionaryMedia( const idDict *dict ) = 0;
virtual void Preload( const idPreloadManifest &manifest ) = 0;
// Runs a game frame, may return a session command for level changing, etc
virtual void RunFrame( idUserCmdMgr & cmdMgr, gameReturn_t & gameReturn ) = 0;
// Makes rendering and sound system calls to display for a given clientNum.
virtual bool Draw( int clientNum ) = 0;
virtual bool HandlePlayerGuiEvent( const sysEvent_t * ev ) = 0;
// Writes a snapshot of the server game state.
virtual void ServerWriteSnapshot( idSnapShot & ss ) = 0;
// Processes a reliable message
virtual void ProcessReliableMessage( int clientNum, int type, const idBitMsg &msg ) = 0;
virtual void SetInterpolation( const float fraction, const int serverGameMS, const int ssStartTime, const int ssEndTime ) = 0;
// Reads a snapshot and updates the client game state.
virtual void ClientReadSnapshot( const idSnapShot & ss ) = 0;
// Runs prediction on entities at the client.
virtual void ClientRunFrame( idUserCmdMgr & cmdMgr, bool lastPredictFrame, gameReturn_t & ret ) = 0;
// Used to manage divergent time-lines
virtual int GetTimeGroupTime( int timeGroup ) = 0;
// Returns a list of available multiplayer game modes
virtual int GetMPGameModes( const char *** gameModes, const char *** gameModesDisplay ) = 0;
// Returns a summary of stats for a given client
virtual void GetClientStats( int clientNum, char *data, const int len ) = 0;
virtual bool IsInGame() const = 0;
// Get the player entity number for a network peer.
virtual int MapPeerToClient( int peer ) const = 0;
// Get the player entity number of the local player.
virtual int GetLocalClientNum() const = 0;
// compute an angle offset to be applied to the given client's aim
virtual void GetAimAssistAngles( idAngles & angles ) = 0;
virtual float GetAimAssistSensitivity() = 0;
// Release the mouse when the PDA is open
virtual bool IsPDAOpen() const = 0;
virtual bool IsPlayerChatting() const = 0;
// Creates leaderboards for each map/mode defined.
virtual void Leaderboards_Init() = 0;
virtual void Leaderboards_Shutdown() = 0;
// MAIN MENU FUNCTIONS
virtual bool InhibitControls() = 0;
virtual void Shell_Init( const char * filename, idSoundWorld * sw ) = 0;
virtual void Shell_Cleanup() = 0;
virtual void Shell_CreateMenu( bool inGame ) = 0;
virtual void Shell_ClosePause() = 0;
virtual void Shell_Show( bool show ) = 0;
virtual bool Shell_IsActive() const = 0;
virtual bool Shell_HandleGuiEvent( const sysEvent_t * sev ) = 0;
virtual void Shell_Render() = 0;
virtual void Shell_ResetMenu() = 0;
virtual void Shell_SyncWithSession() = 0;
virtual void Shell_UpdateSavedGames() = 0;
virtual void Shell_SetCanContinue( bool valid ) = 0;
virtual void Shell_UpdateClientCountdown( int countdown ) = 0;
virtual void Shell_UpdateLeaderboard( const idLeaderboardCallback * callback ) = 0;
virtual void Shell_SetGameComplete() = 0;
};
extern idGame * game;
/*
===============================================================================
Public game interface with methods for in-game editing.
===============================================================================
*/
typedef struct {
idSoundEmitter * referenceSound; // this is the interface to the sound system, created
// with idSoundWorld::AllocSoundEmitter() when needed
idVec3 origin;
int listenerId; // SSF_PRIVATE_SOUND only plays if == listenerId from PlaceListener
// no spatialization will be performed if == listenerID
const idSoundShader * shader; // this really shouldn't be here, it is a holdover from single channel behavior
float diversity; // 0.0 to 1.0 value used to select which
// samples in a multi-sample list from the shader are used
bool waitfortrigger; // don't start it at spawn time
soundShaderParms_t parms; // override volume, flags, etc
} refSound_t;
enum {
TEST_PARTICLE_MODEL = 0,
TEST_PARTICLE_IMPACT,
TEST_PARTICLE_MUZZLE,
TEST_PARTICLE_FLIGHT,
TEST_PARTICLE_SELECTED
};
class idEntity;
class idMD5Anim;
// FIXME: this interface needs to be reworked but it properly separates code for the time being
class idGameEdit {
public:
virtual ~idGameEdit() {}
// These are the canonical idDict to parameter parsing routines used by both the game and tools.
virtual void ParseSpawnArgsToRenderLight( const idDict *args, renderLight_t *renderLight );
virtual void ParseSpawnArgsToRenderEntity( const idDict *args, renderEntity_t *renderEntity );
virtual void ParseSpawnArgsToRefSound( const idDict *args, refSound_t *refSound );
// Animation system calls for non-game based skeletal rendering.
virtual idRenderModel * ANIM_GetModelFromEntityDef( const char *classname );
virtual const idVec3 &ANIM_GetModelOffsetFromEntityDef( const char *classname );
virtual idRenderModel * ANIM_GetModelFromEntityDef( const idDict *args );
virtual idRenderModel * ANIM_GetModelFromName( const char *modelName );
virtual const idMD5Anim * ANIM_GetAnimFromEntityDef( const char *classname, const char *animname );
virtual int ANIM_GetNumAnimsFromEntityDef( const idDict *args );
virtual const char * ANIM_GetAnimNameFromEntityDef( const idDict *args, int animNum );
virtual const idMD5Anim * ANIM_GetAnim( const char *fileName );
virtual int ANIM_GetLength( const idMD5Anim *anim );
virtual int ANIM_GetNumFrames( const idMD5Anim *anim );
virtual void ANIM_CreateAnimFrame( const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset );
virtual idRenderModel * ANIM_CreateMeshForAnim( idRenderModel *model, const char *classname, const char *animname, int frame, bool remove_origin_offset );
// Articulated Figure calls for AF editor and Radiant.
virtual bool AF_SpawnEntity( const char *fileName );
virtual void AF_UpdateEntities( const char *fileName );
virtual void AF_UndoChanges();
virtual idRenderModel * AF_CreateMesh( const idDict &args, idVec3 &meshOrigin, idMat3 &meshAxis, bool &poseIsSet );
// Entity selection.
virtual void ClearEntitySelection();
virtual int GetSelectedEntities( idEntity *list[], int max );
virtual void AddSelectedEntity( idEntity *ent );
// Selection methods
virtual void TriggerSelected();
// Entity defs and spawning.
virtual const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const;
virtual void SpawnEntityDef( const idDict &args, idEntity **ent );
virtual idEntity * FindEntity( const char *name ) const;
virtual const char * GetUniqueEntityName( const char *classname ) const;
// Entity methods.
virtual void EntityGetOrigin( idEntity *ent, idVec3 &org ) const;
virtual void EntityGetAxis( idEntity *ent, idMat3 &axis ) const;
virtual void EntitySetOrigin( idEntity *ent, const idVec3 &org );
virtual void EntitySetAxis( idEntity *ent, const idMat3 &axis );
virtual void EntityTranslate( idEntity *ent, const idVec3 &org );
virtual const idDict * EntityGetSpawnArgs( idEntity *ent ) const;
virtual void EntityUpdateChangeableSpawnArgs( idEntity *ent, const idDict *dict );
virtual void EntityChangeSpawnArgs( idEntity *ent, const idDict *newArgs );
virtual void EntityUpdateVisuals( idEntity *ent );
virtual void EntitySetModel( idEntity *ent, const char *val );
virtual void EntityStopSound( idEntity *ent );
virtual void EntityDelete( idEntity *ent );
virtual void EntitySetColor( idEntity *ent, const idVec3 color );
// Player methods.
virtual bool PlayerIsValid() const;
virtual void PlayerGetOrigin( idVec3 &org ) const;
virtual void PlayerGetAxis( idMat3 &axis ) const;
virtual void PlayerGetViewAngles( idAngles &angles ) const;
virtual void PlayerGetEyePosition( idVec3 &org ) const;
// In game map editing support.
virtual const idDict * MapGetEntityDict( const char *name ) const;
virtual void MapSave( const char *path = NULL ) const;
virtual void MapSetEntityKeyVal( const char *name, const char *key, const char *val ) const ;
virtual void MapCopyDictToEntity( const char *name, const idDict *dict ) const;
virtual int MapGetUniqueMatchingKeyVals( const char *key, const char *list[], const int max ) const;
virtual void MapAddEntity( const idDict *dict ) const;
virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const;
virtual void MapRemoveEntity( const char *name ) const;
virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const;
};
extern idGameEdit * gameEdit;
/*
===============================================================================
Game API.
===============================================================================
*/
const int GAME_API_VERSION = 8;
typedef struct {
int version; // API version
idSys * sys; // non-portable system services
idCommon * common; // common
idCmdSystem * cmdSystem; // console command system
idCVarSystem * cvarSystem; // console variable system
idFileSystem * fileSystem; // file system
idRenderSystem * renderSystem; // render system
idSoundSystem * soundSystem; // sound system
idRenderModelManager * renderModelManager; // render model manager
idUserInterfaceManager * uiManager; // user interface manager
idDeclManager * declManager; // declaration manager
idAASFileManager * AASFileManager; // AAS file manager
idCollisionModelManager * collisionModelManager; // collision model manager
} gameImport_t;
typedef struct {
int version; // API version
idGame * game; // interface to run the game
idGameEdit * gameEdit; // interface for in-game editing
} gameExport_t;
extern "C" {
typedef gameExport_t * (*GetGameAPI_t)( gameImport_t *import );
}
#endif /* !__GAME_H__ */

1142
neo/d3xp/GameEdit.cpp Normal file

File diff suppressed because it is too large Load Diff

119
neo/d3xp/GameEdit.h Normal file
View File

@@ -0,0 +1,119 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_EDIT_H__
#define __GAME_EDIT_H__
/*
===============================================================================
Ingame cursor.
===============================================================================
*/
class idCursor3D : public idEntity {
public:
CLASS_PROTOTYPE( idCursor3D );
idCursor3D();
~idCursor3D();
void Spawn();
void Present();
void Think();
idForce_Drag drag;
idVec3 draggedPosition;
};
/*
===============================================================================
Allows entities to be dragged through the world with physics.
===============================================================================
*/
class idDragEntity {
public:
idDragEntity();
~idDragEntity();
void Clear();
void Update( idPlayer *player );
void SetSelected( idEntity *ent );
idEntity * GetSelected() const { return selected.GetEntity(); }
void DeleteSelected();
void BindSelected();
void UnbindSelected();
private:
idEntityPtr<idEntity> dragEnt; // entity being dragged
jointHandle_t joint; // joint being dragged
int id; // id of body being dragged
idVec3 localEntityPoint; // dragged point in entity space
idVec3 localPlayerPoint; // dragged point in player space
idStr bodyName; // name of the body being dragged
idCursor3D * cursor; // cursor entity
idEntityPtr<idEntity> selected; // last dragged entity
void StopDrag();
};
/*
===============================================================================
Handles ingame entity editing.
===============================================================================
*/
typedef struct selectedTypeInfo_s {
idTypeInfo *typeInfo;
idStr textKey;
} selectedTypeInfo_t;
class idEditEntities {
public:
idEditEntities();
bool SelectEntity( const idVec3 &origin, const idVec3 &dir, const idEntity *skip );
void AddSelectedEntity( idEntity *ent );
void RemoveSelectedEntity( idEntity *ent );
void ClearSelectedEntities();
void DisplayEntities();
bool EntityIsSelectable( idEntity *ent, idVec4 *color = NULL, idStr *text = NULL );
private:
int nextSelectTime;
idList<selectedTypeInfo_t> selectableEntityClasses;
idList<idEntity *> selectedEntities;
};
#endif /* !__GAME_EDIT_H__ */

5085
neo/d3xp/Game_local.cpp Normal file

File diff suppressed because it is too large Load Diff

819
neo/d3xp/Game_local.h Normal file
View File

@@ -0,0 +1,819 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_LOCAL_H__
#define __GAME_LOCAL_H__
/*
===============================================================================
Local implementation of the public game interface.
===============================================================================
*/
#ifdef ID_DEBUG_UNINITIALIZED_MEMORY
// This is real evil but allows the code to inspect arbitrary class variables.
#define private public
#define protected public
#endif
extern idRenderWorld * gameRenderWorld;
extern idSoundWorld * gameSoundWorld;
// the "gameversion" client command will print this plus compile date
#define GAME_VERSION "baseDOOM-1"
// classes used by idGameLocal
class idEntity;
class idActor;
class idPlayer;
class idCamera;
class idWorldspawn;
class idTestModel;
class idAAS;
class idAI;
class idSmokeParticles;
class idEntityFx;
class idTypeInfo;
class idProgram;
class idThread;
class idEditEntities;
class idLocationEntity;
class idMenuHandler_Shell;
const int MAX_CLIENTS = MAX_PLAYERS;
const int MAX_CLIENTS_IN_PVS = MAX_CLIENTS >> 3;
const int GENTITYNUM_BITS = 12;
const int MAX_GENTITIES = 1 << GENTITYNUM_BITS;
const int ENTITYNUM_NONE = MAX_GENTITIES - 1;
const int ENTITYNUM_WORLD = MAX_GENTITIES - 2;
const int ENTITYNUM_MAX_NORMAL = MAX_GENTITIES - 2;
const int ENTITYNUM_FIRST_NON_REPLICATED = ENTITYNUM_MAX_NORMAL - 256;
//============================================================================
void gameError( const char *fmt, ... );
#include "gamesys/Event.h"
#include "gamesys/Class.h"
#include "gamesys/SysCvar.h"
#include "gamesys/SysCmds.h"
#include "gamesys/SaveGame.h"
#include "script/Script_Program.h"
#include "anim/Anim.h"
#include "ai/AAS.h"
#include "physics/Clip.h"
#include "physics/Push.h"
#include "Pvs.h"
#include "Leaderboards.h"
#include "MultiplayerGame.h"
class idWeapon;
//============================================================================
const int MAX_GAME_MESSAGE_SIZE = 8192;
const int MAX_ENTITY_STATE_SIZE = 512;
const int ENTITY_PVS_SIZE = ((MAX_GENTITIES+31)>>5);
const int NUM_RENDER_PORTAL_BITS = idMath::BitsForInteger( PS_BLOCK_ALL );
const int MAX_EVENT_PARAM_SIZE = 128;
typedef struct entityNetEvent_s {
int spawnId;
int event;
int time;
int paramsSize;
byte paramsBuf[MAX_EVENT_PARAM_SIZE];
struct entityNetEvent_s *next;
struct entityNetEvent_s *prev;
} entityNetEvent_t;
enum {
GAME_RELIABLE_MESSAGE_SYNCEDCVARS,
GAME_RELIABLE_MESSAGE_SPAWN_PLAYER,
GAME_RELIABLE_MESSAGE_CHAT,
GAME_RELIABLE_MESSAGE_TCHAT,
GAME_RELIABLE_MESSAGE_SOUND_EVENT,
GAME_RELIABLE_MESSAGE_SOUND_INDEX,
GAME_RELIABLE_MESSAGE_DB,
GAME_RELIABLE_MESSAGE_DROPWEAPON,
GAME_RELIABLE_MESSAGE_RESTART,
GAME_RELIABLE_MESSAGE_TOURNEYLINE,
GAME_RELIABLE_MESSAGE_VCHAT,
GAME_RELIABLE_MESSAGE_STARTSTATE,
GAME_RELIABLE_MESSAGE_WARMUPTIME,
GAME_RELIABLE_MESSAGE_SPECTATE,
GAME_RELIABLE_MESSAGE_EVENT,
GAME_RELIABLE_MESSAGE_LOBBY_COUNTDOWN,
GAME_RELIABLE_MESSAGE_RESPAWN_AVAILABLE, // Used just to show clients the respawn text on the hud.
GAME_RELIABLE_MESSAGE_MATCH_STARTED_TIME,
GAME_RELIABLE_MESSAGE_ACHIEVEMENT_UNLOCK,
GAME_RELIABLE_MESSAGE_CLIENT_HITSCAN_HIT
};
typedef enum {
GAMESTATE_UNINITIALIZED, // prior to Init being called
GAMESTATE_NOMAP, // no map loaded
GAMESTATE_STARTUP, // inside InitFromNewMap(). spawning map entities.
GAMESTATE_ACTIVE, // normal gameplay
GAMESTATE_SHUTDOWN // inside MapShutdown(). clearing memory.
} gameState_t;
typedef struct {
idEntity *ent;
int dist;
int team;
} spawnSpot_t;
//============================================================================
class idEventQueue {
public:
typedef enum {
OUTOFORDER_IGNORE,
OUTOFORDER_DROP,
OUTOFORDER_SORT
} outOfOrderBehaviour_t;
idEventQueue() : start( NULL ), end( NULL ) {}
entityNetEvent_t * Alloc();
void Free( entityNetEvent_t *event );
void Shutdown();
void Init();
void Enqueue( entityNetEvent_t* event, outOfOrderBehaviour_t oooBehaviour );
entityNetEvent_t * Dequeue();
entityNetEvent_t * RemoveLast();
entityNetEvent_t * Start() { return start; }
private:
entityNetEvent_t * start;
entityNetEvent_t * end;
idBlockAlloc<entityNetEvent_t,32> eventAllocator;
};
//============================================================================
template< class type >
class idEntityPtr {
public:
idEntityPtr();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
idEntityPtr & operator=( const type * ent );
idEntityPtr & operator=( const idEntityPtr & ep );
bool operator==( const idEntityPtr & ep ) { return spawnId == ep.spawnId; }
type * operator->() const { return GetEntity(); }
operator type * () const { return GetEntity(); }
// synchronize entity pointers over the network
int GetSpawnId() const { return spawnId; }
bool SetSpawnId( int id );
bool UpdateSpawnId();
bool IsValid() const;
type * GetEntity() const;
int GetEntityNum() const;
private:
int spawnId;
};
struct timeState_t {
int time;
int previousTime;
int realClientTime;
void Set( int t, int pt, int rct ) { time = t; previousTime = pt; realClientTime = rct; };
void Get( int & t, int & pt, int & rct ) { t = time; pt = previousTime; rct = realClientTime; };
void Save( idSaveGame *savefile ) const { savefile->WriteInt( time ); savefile->WriteInt( previousTime ); savefile->WriteInt( realClientTime ); }
void Restore( idRestoreGame *savefile ) { savefile->ReadInt( time ); savefile->ReadInt( previousTime ); savefile->ReadInt( realClientTime ); }
};
enum slowmoState_t {
SLOWMO_STATE_OFF,
SLOWMO_STATE_RAMPUP,
SLOWMO_STATE_ON,
SLOWMO_STATE_RAMPDOWN
};
//============================================================================
class idGameLocal : public idGame {
public:
int previousServerTime; // time in msec of last frame on the server
int serverTime; // in msec. ( on the client ) the server time. ( on the server ) the actual game time.
idDict serverInfo; // all the tunable parameters, like numclients, etc
int numClients; // pulled from serverInfo and verified
idArray< lobbyUserID_t, MAX_CLIENTS > lobbyUserIDs; // Maps from a client (player) number to a lobby user
idDict persistentPlayerInfo[MAX_CLIENTS];
idEntity * entities[MAX_GENTITIES];// index to entities
int spawnIds[MAX_GENTITIES];// for use in idEntityPtr
idArray< int, 2 > firstFreeEntityIndex; // first free index in the entities array. [0] for replicated entities, [1] for non-replicated
int num_entities; // current number <= MAX_GENTITIES
idHashIndex entityHash; // hash table to quickly find entities by name
idWorldspawn * world; // world entity
idLinkList<idEntity> spawnedEntities; // all spawned entities
idLinkList<idEntity> activeEntities; // all thinking entities (idEntity::thinkFlags != 0)
idLinkList<idEntity> aimAssistEntities; // all aim Assist entities
int numEntitiesToDeactivate;// number of entities that became inactive in current frame
bool sortPushers; // true if active lists needs to be reordered to place pushers at the front
bool sortTeamMasters; // true if active lists needs to be reordered to place physics team masters before their slaves
idDict persistentLevelInfo; // contains args that are kept around between levels
// can be used to automatically effect every material in the world that references globalParms
float globalShaderParms[ MAX_GLOBAL_SHADER_PARMS ];
idRandom random; // random number generator used throughout the game
idProgram program; // currently loaded script and data space
idThread * frameCommandThread;
idClip clip; // collision detection
idPush push; // geometric pushing
idPVS pvs; // potential visible set
idTestModel * testmodel; // for development testing of models
idEntityFx * testFx; // for development testing of fx
idStr sessionCommand; // a target_sessionCommand can set this to return something to the session
idMultiplayerGame mpGame; // handles rules for standard dm
idSmokeParticles * smokeParticles; // global smoke trails
idEditEntities * editEntities; // in game editing
bool inCinematic; // game is playing cinematic (player controls frozen)
int framenum;
int time; // in msec
int previousTime; // time in msec of last frame
int vacuumAreaNum; // -1 if level doesn't have any outside areas
gameType_t gameType;
idLinkList<idEntity> snapshotEntities; // entities from the last snapshot
int realClientTime; // real client time
bool isNewFrame; // true if this is a new game frame, not a rerun due to prediction
float clientSmoothing; // smoothing of other clients in the view
int entityDefBits; // bits required to store an entity def number
static const char * sufaceTypeNames[ MAX_SURFACE_TYPES ]; // text names for surface types
idEntityPtr<idEntity> lastGUIEnt; // last entity with a GUI, used by Cmd_NextGUI_f
int lastGUI; // last GUI on the lastGUIEnt
idEntityPtr<idPlayer> playerActivateFragChamber; // The player that activated the frag chamber
idEntityPtr<idEntity> portalSkyEnt;
bool portalSkyActive;
void SetPortalSkyEnt( idEntity *ent );
bool IsPortalSkyAcive();
timeState_t fast;
timeState_t slow;
int selectedGroup;
slowmoState_t slowmoState;
float slowmoScale;
bool quickSlowmoReset;
virtual void SelectTimeGroup( int timeGroup );
virtual int GetTimeGroupTime( int timeGroup );
void ComputeSlowScale();
void RunTimeGroup2( idUserCmdMgr & userCmdMgr );
void ResetSlowTimeVars();
void QuickSlowmoReset();
void Tokenize( idStrList &out, const char *in );
// ---------------------- Public idGame Interface -------------------
idGameLocal();
virtual void Init();
virtual void Shutdown();
virtual void SetServerInfo( const idDict &serverInfo );
virtual const idDict & GetServerInfo();
virtual const idDict & GetPersistentPlayerInfo( int clientNum );
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo );
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, int gameType, int randSeed );
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile * saveGameFile, idFile * stringTableFile, int saveGameVersion );
virtual void SaveGame( idFile *saveGameFile, idFile *stringTableFile );
virtual void GetSaveGameDetails( idSaveGameDetails & gameDetails );
virtual void MapShutdown();
virtual void CacheDictionaryMedia( const idDict *dict );
virtual void Preload( const idPreloadManifest &manifest );
virtual void RunFrame( idUserCmdMgr & cmdMgr, gameReturn_t & gameReturn );
void RunAllUserCmdsForPlayer( idUserCmdMgr & cmdMgr, const int playerNumber );
void RunSingleUserCmd( usercmd_t & cmd, idPlayer & player );
void RunEntityThink( idEntity & ent, idUserCmdMgr & userCmdMgr );
virtual bool Draw( int clientNum );
virtual bool HandlePlayerGuiEvent( const sysEvent_t * ev );
virtual void ServerWriteSnapshot( idSnapShot & ss );
virtual void ProcessReliableMessage( int clientNum, int type, const idBitMsg &msg );
virtual void ClientReadSnapshot( const idSnapShot & ss );
virtual void ClientRunFrame( idUserCmdMgr & cmdMgr, bool lastPredictFrame, gameReturn_t & ret );
void BuildReturnValue( gameReturn_t & ret );
virtual int GetMPGameModes( const char *** gameModes, const char *** gameModesDisplay );
virtual void GetClientStats( int clientNum, char *data, const int len );
virtual bool IsInGame() const { return GameState() == GAMESTATE_ACTIVE; }
virtual int MapPeerToClient( int peer ) const;
virtual int GetLocalClientNum() const;
virtual void GetAimAssistAngles( idAngles & angles );
virtual float GetAimAssistSensitivity();
// ---------------------- Public idGameLocal Interface -------------------
void Printf( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
void DPrintf( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
void Warning( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
void DWarning( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
void Error( VERIFY_FORMAT_STRING const char *fmt, ... ) const;
// Initializes all map variables common to both save games and spawned games
void LoadMap( const char *mapName, int randseed );
void LocalMapRestart();
void MapRestart();
static void MapRestart_f( const idCmdArgs &args );
idMapFile * GetLevelMap();
const char * GetMapName() const;
int NumAAS() const;
idAAS * GetAAS( int num ) const;
idAAS * GetAAS( const char *name ) const;
void SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed );
aasHandle_t AddAASObstacle( const idBounds &bounds );
void RemoveAASObstacle( const aasHandle_t handle );
void RemoveAllAASObstacles();
bool CheatsOk( bool requirePlayer = true );
gameState_t GameState() const;
idEntity * SpawnEntityType( const idTypeInfo &classdef, const idDict *args = NULL, bool bIsClientReadSnapshot = false );
bool SpawnEntityDef( const idDict &args, idEntity **ent = NULL, bool setDefaults = true );
int GetSpawnId( const idEntity *ent ) const;
const idDeclEntityDef * FindEntityDef( const char *name, bool makeDefault = true ) const;
const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const;
void RegisterEntity( idEntity *ent, int forceSpawnId, const idDict & spawnArgsToCopy );
void UnregisterEntity( idEntity *ent );
const idDict & GetSpawnArgs() const { return spawnArgs; }
bool RequirementMet( idEntity *activator, const idStr &requires, int removeItem );
void AlertAI( idEntity *ent );
idActor * GetAlertEntity();
bool InPlayerPVS( idEntity *ent ) const;
bool InPlayerConnectedArea( idEntity *ent ) const;
pvsHandle_t GetPlayerPVS() { return playerPVS; };
void SetCamera( idCamera *cam );
idCamera * GetCamera() const;
void CalcFov( float base_fov, float &fov_x, float &fov_y ) const;
void AddEntityToHash( const char *name, idEntity *ent );
bool RemoveEntityFromHash( const char *name, idEntity *ent );
int GetTargets( const idDict &args, idList< idEntityPtr<idEntity> > &list, const char *ref ) const;
// returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player.
idEntity * GetTraceEntity( const trace_t &trace ) const;
static void ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) );
idEntity * FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const;
idEntity * FindEntity( const char *name ) const;
idEntity * FindEntityUsingDef( idEntity *from, const char *match ) const;
int EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const;
void KillBox( idEntity *ent, bool catch_teleport = false );
void RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower = 1.0f );
void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake );
void RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel );
void ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle = 0 );
void BloodSplat( const idVec3 &origin, const idVec3 &dir, float size, const char *material );
void CallFrameCommand( idEntity *ent, const function_t *frameCommand );
void CallObjectFrameCommand( idEntity *ent, const char *frameCommand );
const idVec3 & GetGravity() const;
// added the following to assist licensees with merge issues
int GetFrameNum() const { return framenum; };
int GetTime() const { return time; };
int GetNextClientNum( int current ) const;
idPlayer * GetClientByNum( int current ) const;
idPlayer * GetLocalPlayer() const;
void SpreadLocations();
idLocationEntity * LocationForPoint( const idVec3 &point ); // May return NULL
idEntity * SelectInitialSpawnPoint( idPlayer *player );
void SetPortalState( qhandle_t portal, int blockingBits );
void SaveEntityNetworkEvent( const idEntity *ent, int event, const idBitMsg *msg );
int ServerRemapDecl( int clientNum, declType_t type, int index );
int ClientRemapDecl( declType_t type, int index );
void SyncPlayersWithLobbyUsers( bool initial );
void ServerWriteInitialReliableMessages( int clientNum, lobbyUserID_t lobbyUserID );
void ServerSendNetworkSyncCvars();
virtual void SetInterpolation( const float fraction, const int serverGameMS, const int ssStartTime, const int ssEndTime );
void ServerProcessReliableMessage( int clientNum, int type, const idBitMsg &msg );
void ClientProcessReliableMessage( int type, const idBitMsg &msg );
// Snapshot times - track exactly what times we are interpolating from and to
int GetSSEndTime() const { return netInterpolationInfo.ssEndTime; }
int GetSSStartTime() const { return netInterpolationInfo.ssStartTime; }
virtual void SetServerGameTimeMs( const int time );
virtual int GetServerGameTimeMs() const;
idEntity * FindPredictedEntity( uint32 predictedKey, idTypeInfo * type );
uint32 GeneratePredictionKey( idWeapon * weapon, idPlayer * playerAttacker, int overrideKey );
int GetLastClientUsercmdMilliseconds( int playerIndex ) const { return usercmdLastClientMilliseconds[ playerIndex ]; }
void SetGlobalMaterial( const idMaterial *mat );
const idMaterial * GetGlobalMaterial();
void SetGibTime( int _time ) { nextGibTime = _time; };
int GetGibTime() { return nextGibTime; };
virtual bool InhibitControls();
virtual bool IsPDAOpen() const;
virtual bool IsPlayerChatting() const;
// Creates leaderboards for each map/mode defined.
virtual void Leaderboards_Init();
virtual void Leaderboards_Shutdown();
// MAIN MENU FUNCTIONS
virtual void Shell_Init( const char * filename, idSoundWorld * sw );
virtual void Shell_Cleanup();
virtual void Shell_Show( bool show );
virtual void Shell_ClosePause();
virtual void Shell_CreateMenu( bool inGame );
virtual bool Shell_IsActive() const;
virtual bool Shell_HandleGuiEvent( const sysEvent_t * sev );
virtual void Shell_Render();
virtual void Shell_ResetMenu();
virtual void Shell_SyncWithSession() ;
virtual void Shell_SetCanContinue( bool valid );
virtual void Shell_UpdateSavedGames();
virtual void Shell_UpdateClientCountdown( int countdown );
virtual void Shell_UpdateLeaderboard( const idLeaderboardCallback * callback );
virtual void Shell_SetGameComplete();
void Shell_ClearRepeater();
const char * GetMapFileName() { return mapFileName.c_str(); }
const char * GetMPPlayerDefName() const;
private:
const static int INITIAL_SPAWN_COUNT = 1;
idStr mapFileName; // name of the map, empty string if no map loaded
idMapFile * mapFile; // will be NULL during the game unless in-game editing is used
bool mapCycleLoaded;
int spawnCount;
int mapSpawnCount; // it's handy to know which entities are part of the map
idLocationEntity ** locationEntities; // for location names, etc
idCamera * camera;
const idMaterial * globalMaterial; // for overriding everything
idList<idAAS *> aasList; // area system
idMenuHandler_Shell * shellHandler;
idStrList aasNames;
idEntityPtr<idActor> lastAIAlertEntity;
int lastAIAlertTime;
idDict spawnArgs; // spawn args used during entity spawning FIXME: shouldn't be necessary anymore
pvsHandle_t playerPVS; // merged pvs of all players
pvsHandle_t playerConnectedAreas; // all areas connected to any player area
idVec3 gravity; // global gravity vector
gameState_t gamestate; // keeps track of whether we're spawning, shutting down, or normal gameplay
bool influenceActive; // true when a phantasm is happening
int nextGibTime;
idEventQueue eventQueue;
idEventQueue savedEventQueue;
idStaticList<spawnSpot_t, MAX_GENTITIES> spawnSpots;
idStaticList<idEntity *, MAX_GENTITIES> initialSpots;
int currentInitialSpot;
idStaticList<spawnSpot_t, MAX_GENTITIES> teamSpawnSpots[2];
idStaticList<idEntity *, MAX_GENTITIES> teamInitialSpots[2];
int teamCurrentInitialSpot[2];
struct netInterpolationInfo_t { // Was in GameTimeManager.h in id5, needed common place to put this.
netInterpolationInfo_t()
: pct( 0.0f )
, serverGameMs( 0 )
, previousServerGameMs( 0 )
, ssStartTime( 0 )
, ssEndTime( 0 )
{}
float pct; // % of current interpolation
int serverGameMs; // Interpolated server game time
int previousServerGameMs; // last frame's interpolated server game time
int ssStartTime; // Server time of old snapshot
int ssEndTime; // Server time of next snapshot
};
netInterpolationInfo_t netInterpolationInfo;
idDict newInfo;
idArray< int, MAX_PLAYERS > usercmdLastClientMilliseconds; // The latest client time the server has run.
idArray< int, MAX_PLAYERS > lastCmdRunTimeOnClient;
idArray< int, MAX_PLAYERS > lastCmdRunTimeOnServer;
void Clear();
// returns true if the entity shouldn't be spawned at all in this game type or difficulty level
bool InhibitEntitySpawn( idDict &spawnArgs );
// spawn entities from the map file
void SpawnMapEntities();
// commons used by init, shutdown, and restart
void MapPopulate();
void MapClear( bool clearClients );
pvsHandle_t GetClientPVS( idPlayer *player, pvsType_t type );
void SetupPlayerPVS();
void FreePlayerPVS();
void UpdateGravity();
void SortActiveEntityList();
void ShowTargets();
void RunDebugInfo();
void InitScriptForMap();
void SetScriptFPS( const float com_engineHz );
void SpawnPlayer( int clientNum );
void InitConsoleCommands();
void ShutdownConsoleCommands();
void InitAsyncNetwork();
void ShutdownAsyncNetwork();
void NetworkEventWarning( const entityNetEvent_t *event, VERIFY_FORMAT_STRING const char *fmt, ... );
void ServerProcessEntityNetworkEventQueue();
void ClientProcessEntityNetworkEventQueue();
// call after any change to serverInfo. Will update various quick-access flags
void UpdateServerInfoFlags();
void RandomizeInitialSpawns();
static int sortSpawnPoints( const void *ptr1, const void *ptr2 );
bool SimulateProjectiles();
};
//============================================================================
extern idGameLocal gameLocal;
extern idAnimManager animationLib;
//============================================================================
class idGameError : public idException {
public:
idGameError( const char *text ) : idException( text ) {}
};
//============================================================================
template< class type >
ID_INLINE idEntityPtr<type>::idEntityPtr() {
spawnId = 0;
}
template< class type >
ID_INLINE void idEntityPtr<type>::Save( idSaveGame *savefile ) const {
savefile->WriteInt( spawnId );
}
template< class type >
ID_INLINE void idEntityPtr<type>::Restore( idRestoreGame *savefile ) {
savefile->ReadInt( spawnId );
}
template< class type >
ID_INLINE idEntityPtr<type> &idEntityPtr<type>::operator=( const type *ent ) {
if ( ent == NULL ) {
spawnId = 0;
} else {
spawnId = ( gameLocal.spawnIds[ent->entityNumber] << GENTITYNUM_BITS ) | ent->entityNumber;
}
return *this;
}
template< class type >
ID_INLINE idEntityPtr< type > &idEntityPtr<type>::operator=( const idEntityPtr & ep ) {
spawnId = ep.spawnId;
return *this;
}
template< class type >
ID_INLINE bool idEntityPtr<type>::SetSpawnId( int id ) {
// the reason for this first check is unclear:
// the function returning false may mean the spawnId is already set right, or the entity is missing
if ( id == spawnId ) {
return false;
}
if ( ( id >> GENTITYNUM_BITS ) == gameLocal.spawnIds[ id & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] ) {
spawnId = id;
return true;
}
return false;
}
template< class type >
ID_INLINE bool idEntityPtr<type>::IsValid() const {
return ( gameLocal.spawnIds[ spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) ] == ( spawnId >> GENTITYNUM_BITS ) );
}
template< class type >
ID_INLINE type *idEntityPtr<type>::GetEntity() const {
int entityNum = spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 );
if ( ( gameLocal.spawnIds[ entityNum ] == ( spawnId >> GENTITYNUM_BITS ) ) ) {
return static_cast<type *>( gameLocal.entities[ entityNum ] );
}
return NULL;
}
template< class type >
ID_INLINE int idEntityPtr<type>::GetEntityNum() const {
return ( spawnId & ( ( 1 << GENTITYNUM_BITS ) - 1 ) );
}
// ===========================================================================
//
// these defines work for all startsounds from all entity types
// make sure to change script/doom_defs.script if you add any channels, or change their order
//
typedef enum {
SND_CHANNEL_ANY = SCHANNEL_ANY,
SND_CHANNEL_VOICE = SCHANNEL_ONE,
SND_CHANNEL_VOICE2,
SND_CHANNEL_BODY,
SND_CHANNEL_BODY2,
SND_CHANNEL_BODY3,
SND_CHANNEL_WEAPON,
SND_CHANNEL_ITEM,
SND_CHANNEL_HEART,
SND_CHANNEL_PDA_AUDIO,
SND_CHANNEL_PDA_VIDEO,
SND_CHANNEL_DEMONIC,
SND_CHANNEL_RADIO,
// internal use only. not exposed to script or framecommands.
SND_CHANNEL_AMBIENT,
SND_CHANNEL_DAMAGE
} gameSoundChannel_t;
// content masks
#define MASK_ALL (-1)
#define MASK_SOLID (CONTENTS_SOLID)
#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_BODY)
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY)
#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP)
#define MASK_WATER (CONTENTS_WATER)
#define MASK_OPAQUE (CONTENTS_OPAQUE)
#define MASK_SHOT_RENDERMODEL (CONTENTS_SOLID|CONTENTS_RENDERMODEL)
#define MASK_SHOT_BOUNDINGBOX (CONTENTS_SOLID|CONTENTS_BODY)
const float DEFAULT_GRAVITY = 1066.0f;
#define DEFAULT_GRAVITY_STRING "1066"
const idVec3 DEFAULT_GRAVITY_VEC3( 0, 0, -DEFAULT_GRAVITY );
const int CINEMATIC_SKIP_DELAY = SEC2MS( 2.0f );
//============================================================================
#include "physics/Force.h"
#include "physics/Force_Constant.h"
#include "physics/Force_Drag.h"
#include "physics/Force_Grab.h"
#include "physics/Force_Field.h"
#include "physics/Force_Spring.h"
#include "physics/Physics.h"
#include "physics/Physics_Static.h"
#include "physics/Physics_StaticMulti.h"
#include "physics/Physics_Base.h"
#include "physics/Physics_Actor.h"
#include "physics/Physics_Monster.h"
#include "physics/Physics_Player.h"
#include "physics/Physics_Parametric.h"
#include "physics/Physics_RigidBody.h"
#include "physics/Physics_AF.h"
#include "SmokeParticles.h"
#include "Entity.h"
#include "GameEdit.h"
#include "Grabber.h"
#include "AF.h"
#include "IK.h"
#include "AFEntity.h"
#include "Misc.h"
#include "Actor.h"
#include "Projectile.h"
#include "Weapon.h"
#include "Light.h"
#include "WorldSpawn.h"
#include "Item.h"
#include "PlayerView.h"
#include "PlayerIcon.h"
#include "Achievements.h"
#include "AimAssist.h"
#include "Player.h"
#include "Mover.h"
#include "Camera.h"
#include "Moveable.h"
#include "Target.h"
#include "Trigger.h"
#include "Sound.h"
#include "Fx.h"
#include "SecurityCamera.h"
#include "BrittleFracture.h"
#include "ai/AI.h"
#include "anim/Anim_Testmodel.h"
// menus
#include "menus/MenuWidget.h"
#include "menus/MenuScreen.h"
#include "menus/MenuHandler.h"
#include "script/Script_Compiler.h"
#include "script/Script_Interpreter.h"
#include "script/Script_Thread.h"
#endif /* !__GAME_LOCAL_H__ */

1328
neo/d3xp/Game_network.cpp Normal file

File diff suppressed because it is too large Load Diff

739
neo/d3xp/Grabber.cpp Normal file
View File

@@ -0,0 +1,739 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "Misc.h"
#define MAX_DRAG_TRACE_DISTANCE 384.0f
#define TRACE_BOUNDS_SIZE 3.f
#define HOLD_DISTANCE 72.f
#define FIRING_DELAY 1000.0f
#define DRAG_FAIL_LEN 64.f
#define THROW_SCALE 1000
#define MAX_PICKUP_VELOCITY 1500 * 1500
#define MAX_PICKUP_SIZE 96
/*
===============================================================================
Allows entities to be dragged through the world with physics.
===============================================================================
*/
CLASS_DECLARATION( idEntity, idGrabber )
END_CLASS
/*
==============
idGrabber::idGrabber
==============
*/
idGrabber::idGrabber() {
dragEnt = NULL;
owner = NULL;
beam = NULL;
beamTarget = NULL;
oldImpulseSequence = 0;
shakeForceFlip = false;
holdingAF = false;
endTime = 0;
lastFiredTime = -FIRING_DELAY;
dragFailTime = 0;
startDragTime = 0;
warpId = -1;
dragTraceDist = MAX_DRAG_TRACE_DISTANCE;
}
/*
==============
idGrabber::~idGrabber
==============
*/
idGrabber::~idGrabber() {
StopDrag( true );
if ( beam ) {
delete beam;
}
if ( beamTarget ) {
delete beamTarget;
}
}
/*
==============
idGrabber::Save
==============
*/
void idGrabber::Save( idSaveGame *savefile ) const {
dragEnt.Save( savefile );
savefile->WriteStaticObject( drag );
savefile->WriteVec3( saveGravity );
savefile->WriteInt( id );
savefile->WriteVec3( localPlayerPoint );
owner.Save( savefile );
savefile->WriteBool( holdingAF );
savefile->WriteBool( shakeForceFlip );
savefile->WriteInt( endTime );
savefile->WriteInt( lastFiredTime );
savefile->WriteInt( dragFailTime );
savefile->WriteInt( startDragTime );
savefile->WriteFloat( dragTraceDist );
savefile->WriteInt( savedContents );
savefile->WriteInt( savedClipmask );
savefile->WriteObject( beam );
savefile->WriteObject( beamTarget );
savefile->WriteInt( warpId );
}
/*
==============
idGrabber::Restore
==============
*/
void idGrabber::Restore( idRestoreGame *savefile ) {
//Spawn the beams
Initialize();
dragEnt.Restore( savefile );
savefile->ReadStaticObject( drag );
savefile->ReadVec3( saveGravity );
savefile->ReadInt( id );
// Restore the drag force's physics object
if ( dragEnt.IsValid() ) {
drag.SetPhysics( dragEnt.GetEntity()->GetPhysics(), id, dragEnt.GetEntity()->GetPhysics()->GetOrigin() );
}
savefile->ReadVec3( localPlayerPoint );
owner.Restore( savefile );
savefile->ReadBool( holdingAF );
savefile->ReadBool( shakeForceFlip );
savefile->ReadInt( endTime );
savefile->ReadInt( lastFiredTime );
savefile->ReadInt( dragFailTime );
savefile->ReadInt( startDragTime );
savefile->ReadFloat( dragTraceDist );
savefile->ReadInt( savedContents );
savefile->ReadInt( savedClipmask );
savefile->ReadObject( reinterpret_cast<idClass *&>(beam) );
savefile->ReadObject( reinterpret_cast<idClass *&>(beamTarget) );
savefile->ReadInt( warpId );
}
/*
==============
idGrabber::Initialize
==============
*/
void idGrabber::Initialize() {
if ( !common->IsMultiplayer() ) {
idDict args;
if ( !beamTarget ) {
args.SetVector( "origin", vec3_origin );
args.SetBool( "start_off", true );
beamTarget = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
}
if ( !beam ) {
args.Clear();
args.Set( "target", beamTarget->name.c_str() );
args.SetVector( "origin", vec3_origin );
args.SetBool( "start_off", true );
args.Set( "width", "6" );
args.Set( "skin", "textures/smf/flareSizeable" );
args.Set( "_color", "0.0235 0.843 0.969 0.2" );
beam = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
beam->SetShaderParm( 6, 1.0f );
}
endTime = 0;
dragTraceDist = MAX_DRAG_TRACE_DISTANCE;
}
else {
beam = NULL;
beamTarget = NULL;
endTime = 0;
dragTraceDist = MAX_DRAG_TRACE_DISTANCE;
};
}
/*
==============
idGrabber::SetDragDistance
==============
*/
void idGrabber::SetDragDistance( float dist ) {
dragTraceDist = dist;
}
/*
==============
idGrabber::StartDrag
==============
*/
void idGrabber::StartDrag( idEntity *grabEnt, int id ) {
int clipModelId = id;
idPlayer *thePlayer = owner.GetEntity();
holdingAF = false;
dragFailTime = gameLocal.slow.time;
startDragTime = gameLocal.slow.time;
oldImpulseSequence = thePlayer->usercmd.impulseSequence;
// set grabbed state for networking
grabEnt->SetGrabbedState( true );
// This is the new object to drag around
dragEnt = grabEnt;
// Show the beams!
UpdateBeams();
if ( beam ) {
beam->Show();
}
if ( beamTarget ) {
beamTarget->Show();
}
// Move the object to the fast group (helltime)
grabEnt->timeGroup = TIME_GROUP2;
// Handle specific class types
if ( grabEnt->IsType( idProjectile::Type ) ) {
idProjectile* p = (idProjectile*)grabEnt;
p->CatchProjectile( thePlayer, "_catch" );
// Make the projectile non-solid to other projectiles/enemies (special hack for helltime hunter)
if ( !idStr::Cmp( grabEnt->GetEntityDefName(), "projectile_helltime_killer" ) ) {
savedContents = CONTENTS_PROJECTILE;
savedClipmask = MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE;
} else {
savedContents = grabEnt->GetPhysics()->GetContents();
savedClipmask = grabEnt->GetPhysics()->GetClipMask();
}
grabEnt->GetPhysics()->SetContents( 0 );
grabEnt->GetPhysics()->SetClipMask( CONTENTS_SOLID|CONTENTS_BODY );
} else if ( grabEnt->IsType( idExplodingBarrel::Type ) ) {
idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(grabEnt);
ebarrel->StartBurning();
} else if ( grabEnt->IsType( idAFEntity_Gibbable::Type ) ) {
holdingAF = true;
clipModelId = 0;
if ( grabbableAI( grabEnt->spawnArgs.GetString( "classname" ) ) ) {
idAI *aiEnt = static_cast<idAI*>(grabEnt);
aiEnt->StartRagdoll();
}
} else if ( grabEnt->IsType( idMoveableItem::Type ) ) {
grabEnt->PostEventMS( &EV_Touch, 250, thePlayer, NULL );
}
// Get the current physics object to manipulate
idPhysics *phys = grabEnt->GetPhysics();
// Turn off gravity on object
saveGravity = phys->GetGravity();
phys->SetGravity( vec3_origin );
// hold it directly in front of player
localPlayerPoint = ( thePlayer->firstPersonViewAxis[0] * HOLD_DISTANCE ) * thePlayer->firstPersonViewAxis.Transpose();
// Set the ending time for the hold
endTime = gameLocal.time + g_grabberHoldSeconds.GetFloat() * 1000;
// Start up the Force_Drag to bring it in
drag.Init( g_grabberDamping.GetFloat() );
drag.SetPhysics( phys, clipModelId, thePlayer->firstPersonViewOrigin + localPlayerPoint * thePlayer->firstPersonViewAxis);
// start the screen warp
warpId = thePlayer->playerView.AddWarp( phys->GetOrigin(), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 160, 2000 );
}
/*
==============
idGrabber::StopDrag
==============
*/
void idGrabber::StopDrag( bool dropOnly ) {
idPlayer *thePlayer = owner.GetEntity();
if ( beam ) {
beam->Hide();
}
if ( beamTarget ) {
beamTarget->Hide();
}
if ( dragEnt.IsValid() ) {
idEntity *ent = dragEnt.GetEntity();
// set grabbed state for networking
ent->SetGrabbedState( false );
// If a cinematic has started, allow dropped object to think in cinematics
if ( gameLocal.inCinematic ) {
ent->cinematic = true;
}
// Restore Gravity
ent->GetPhysics()->SetGravity( saveGravity );
// Move the object back to the slow group (helltime)
ent->timeGroup = TIME_GROUP1;
if ( holdingAF ) {
idAFEntity_Gibbable *af = static_cast<idAFEntity_Gibbable *>(ent);
idPhysics_AF *af_Phys = static_cast<idPhysics_AF*>(af->GetPhysics());
if ( grabbableAI( ent->spawnArgs.GetString( "classname" ) ) ) {
idAI *aiEnt = static_cast<idAI*>(ent);
aiEnt->Damage( thePlayer, thePlayer, vec3_origin, "damage_suicide", 1.0f, INVALID_JOINT );
}
af->SetThrown( !dropOnly );
// Reset timers so that it isn't forcibly put to rest in mid-air
af_Phys->PutToRest();
af_Phys->Activate();
af_Phys->SetTimeScaleRamp( MS2SEC(gameLocal.slow.time) - 1.5f, MS2SEC(gameLocal.slow.time) + 1.0f );
}
// If the object isn't near its goal, just drop it in place.
if ( !ent->IsType( idProjectile::Type ) && ( dropOnly || drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) ) {
ent->GetPhysics()->SetLinearVelocity( vec3_origin );
thePlayer->StartSoundShader( declManager->FindSound( "grabber_maindrop" ), SND_CHANNEL_WEAPON, 0, false, NULL );
if ( ent->IsType( idExplodingBarrel::Type ) ) {
idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(ent);
ebarrel->SetStability( true );
ebarrel->StopBurning();
}
} else {
// Shoot the object forward
ent->ApplyImpulse( thePlayer, 0, ent->GetPhysics()->GetOrigin(), thePlayer->firstPersonViewAxis[0] * THROW_SCALE * ent->GetPhysics()->GetMass() );
thePlayer->StartSoundShader( declManager->FindSound( "grabber_release" ), SND_CHANNEL_WEAPON, 0, false, NULL );
// Orient projectiles away from the player
if ( ent->IsType( idProjectile::Type ) ) {
idPlayer *player = owner.GetEntity();
idAngles ang = player->firstPersonViewAxis[0].ToAngles();
ang.pitch += 90.f;
ent->GetPhysics()->SetAxis( ang.ToMat3() );
ent->GetPhysics()->SetAngularVelocity( vec3_origin );
// Restore projectile contents
ent->GetPhysics()->SetContents( savedContents );
ent->GetPhysics()->SetClipMask( savedClipmask );
idProjectile *projectile = static_cast< idProjectile* >( ent );
if ( projectile != NULL ) {
projectile->SetLaunchedFromGrabber( true );
}
} else if ( ent->IsType( idMoveable::Type ) ) {
// Turn on damage for this object
idMoveable *obj = static_cast<idMoveable*>(ent);
obj->EnableDamage( true, 2.5f );
obj->SetAttacker( thePlayer );
if ( ent->IsType( idExplodingBarrel::Type ) ) {
idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(ent);
ebarrel->SetStability( false );
}
} else if ( ent->IsType( idMoveableItem::Type ) ) {
ent->GetPhysics()->SetClipMask( MASK_MONSTERSOLID );
}
}
// Remove the Force_Drag's control of the entity
drag.RemovePhysics( ent->GetPhysics() );
}
if ( warpId != -1 ) {
thePlayer->playerView.FreeWarp( warpId );
warpId = -1;
}
lastFiredTime = gameLocal.time;
dragEnt = NULL;
endTime = 0;
}
/*
==============
idGrabber::Update
==============
*/
int idGrabber::Update( idPlayer *player, bool hide ) {
trace_t trace;
idEntity *newEnt;
// pause before allowing refire
if ( lastFiredTime + FIRING_DELAY > gameLocal.time ) {
return 3;
}
// Dead players release the trigger
if ( hide || player->health <= 0 ) {
StopDrag( true );
if ( hide ) {
lastFiredTime = gameLocal.time - FIRING_DELAY + 250;
}
return 3;
}
// Check if object being held has been removed (dead demon, projectile, etc.)
if ( endTime > gameLocal.time ) {
bool abort = !dragEnt.IsValid();
if ( !abort && dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
idProjectile *proj = (idProjectile *)dragEnt.GetEntity();
if ( proj->GetProjectileState() >= 3 ) {
abort = true;
}
}
if ( !abort && dragEnt.GetEntity() && dragEnt.GetEntity()->IsHidden() ) {
abort = true;
}
// Not in multiplayer :: Pressing "reload" lets you carefully drop an item
if ( !common->IsMultiplayer() && !abort && ( player->usercmd.impulseSequence != oldImpulseSequence ) && (player->usercmd.impulse == IMPULSE_13) ) {
abort = true;
}
if ( abort ) {
StopDrag( true );
return 3;
}
}
owner = player;
// if no entity selected for dragging
if ( !dragEnt.GetEntity() ) {
idBounds bounds;
idVec3 end = player->firstPersonViewOrigin + player->firstPersonViewAxis[0] * dragTraceDist;
bounds.Zero();
bounds.ExpandSelf( TRACE_BOUNDS_SIZE );
gameLocal.clip.TraceBounds( trace, player->firstPersonViewOrigin, end, bounds, MASK_SHOT_RENDERMODEL|CONTENTS_PROJECTILE|CONTENTS_MOVEABLECLIP, player );
// If the trace hit something
if ( trace.fraction < 1.0f ) {
newEnt = gameLocal.entities[ trace.c.entityNum ];
// if entity is already being grabbed then bypass
if ( common->IsMultiplayer() && newEnt && newEnt->IsGrabbed() ) {
return 0;
}
// Check if this is a valid entity to hold
if ( newEnt && ( newEnt->IsType( idMoveable::Type ) ||
newEnt->IsType( idMoveableItem::Type ) ||
newEnt->IsType( idProjectile::Type ) ||
newEnt->IsType( idAFEntity_Gibbable::Type )
) &&
newEnt->noGrab == false &&
newEnt->GetPhysics()->GetBounds().GetRadius() < MAX_PICKUP_SIZE &&
newEnt->GetPhysics()->GetLinearVelocity().LengthSqr() < MAX_PICKUP_VELOCITY ) {
bool validAF = true;
if ( newEnt->IsType( idAFEntity_Gibbable::Type ) ) {
idAFEntity_Gibbable *afEnt = static_cast<idAFEntity_Gibbable*>(newEnt);
if ( grabbableAI( newEnt->spawnArgs.GetString( "classname" ) ) ) {
// Make sure it's also active
if ( !afEnt->IsActive() ) {
validAF = false;
}
} else if ( !afEnt->IsActiveAF() ) {
validAF = false;
}
}
if ( validAF && player->usercmd.buttons & BUTTON_ATTACK ) {
// Grab this entity and start dragging it around
StartDrag( newEnt, trace.c.id );
} else if ( validAF ) {
// A holdable object is ready to be grabbed
return 1;
}
}
}
}
// check backwards server time in multiplayer
bool allow = true;
if ( common->IsMultiplayer() ) {
// if we've marched backwards
if ( gameLocal.slow.time < startDragTime ) {
allow = false;
}
}
// if there is an entity selected for dragging
if ( dragEnt.GetEntity() && allow ) {
idPhysics *entPhys = dragEnt.GetEntity()->GetPhysics();
idVec3 goalPos;
// If the player lets go of attack, or time is up
if ( !( player->usercmd.buttons & BUTTON_ATTACK ) ) {
StopDrag( false );
return 3;
}
if ( gameLocal.time > endTime ) {
StopDrag( true );
return 3;
}
// Check if the player is standing on the object
if ( !holdingAF ) {
idBounds playerBounds;
idBounds objectBounds = entPhys->GetAbsBounds();
idVec3 newPoint = player->GetPhysics()->GetOrigin();
// create a bounds at the players feet
playerBounds.Clear();
playerBounds.AddPoint( newPoint );
newPoint.z -= 1.f;
playerBounds.AddPoint( newPoint );
playerBounds.ExpandSelf( 8.f );
// If it intersects the object bounds, then drop it
if ( playerBounds.IntersectsBounds( objectBounds ) ) {
StopDrag( true );
return 3;
}
}
// Shake the object at the end of the hold
if ( g_grabberEnableShake.GetBool() && !common->IsMultiplayer() ) {
ApplyShake();
}
// Set and evaluate drag force
goalPos = player->firstPersonViewOrigin + localPlayerPoint * player->firstPersonViewAxis;
drag.SetGoalPosition( goalPos );
drag.Evaluate( gameLocal.time );
// If an object is flying too fast toward the player, stop it hard
if ( g_grabberHardStop.GetBool() ) {
idPlane theWall;
idVec3 toPlayerVelocity, objectCenter;
float toPlayerSpeed;
toPlayerVelocity = -player->firstPersonViewAxis[0];
toPlayerSpeed = entPhys->GetLinearVelocity() * toPlayerVelocity;
if ( toPlayerSpeed > 64.f ) {
objectCenter = entPhys->GetAbsBounds().GetCenter();
theWall.SetNormal( player->firstPersonViewAxis[0] );
theWall.FitThroughPoint( goalPos );
if ( theWall.Side( objectCenter, 0.1f ) == PLANESIDE_BACK ) {
int i, num;
num = entPhys->GetNumClipModels();
for ( i=0; i<num; i++ ) {
entPhys->SetLinearVelocity( vec3_origin, i );
}
}
}
// Make sure the object isn't spinning too fast
const float MAX_ROTATION_SPEED = 12.f;
idVec3 angVel = entPhys->GetAngularVelocity();
float rotationSpeed = angVel.LengthFast();
if ( rotationSpeed > MAX_ROTATION_SPEED ) {
angVel.NormalizeFast();
angVel *= MAX_ROTATION_SPEED;
entPhys->SetAngularVelocity( angVel );
}
}
// Orient projectiles away from the player
if ( dragEnt.GetEntity()->IsType( idProjectile::Type ) ) {
idAngles ang = player->firstPersonViewAxis[0].ToAngles();
ang.pitch += 90.f;
entPhys->SetAxis( ang.ToMat3() );
}
// Some kind of effect from gun to object?
UpdateBeams();
// If the object is stuck away from its intended position for more than 500ms, let it go.
if ( drag.GetDistanceToGoal() > DRAG_FAIL_LEN ) {
if ( dragFailTime < (gameLocal.slow.time - 500) ) {
StopDrag( true );
return 3;
}
} else {
dragFailTime = gameLocal.slow.time;
}
// Currently holding an object
return 2;
}
// Not holding, nothing to hold
return 0;
}
/*
======================
idGrabber::UpdateBeams
======================
*/
void idGrabber::UpdateBeams() {
jointHandle_t muzzle_joint;
idVec3 muzzle_origin;
idMat3 muzzle_axis;
renderEntity_t *re;
if ( !beam ) {
return;
}
if ( dragEnt.IsValid() ) {
idPlayer *thePlayer = owner.GetEntity();
if ( beamTarget ) {
beamTarget->SetOrigin( dragEnt.GetEntity()->GetPhysics()->GetAbsBounds().GetCenter() );
}
muzzle_joint = thePlayer->weapon.GetEntity()->GetAnimator()->GetJointHandle( "particle_upper" );
if ( muzzle_joint != INVALID_JOINT ) {
thePlayer->weapon.GetEntity()->GetJointWorldTransform( muzzle_joint, gameLocal.time, muzzle_origin, muzzle_axis );
} else {
muzzle_origin = thePlayer->GetPhysics()->GetOrigin();
}
beam->SetOrigin( muzzle_origin );
re = beam->GetRenderEntity();
re->origin = muzzle_origin;
beam->UpdateVisuals();
beam->Present();
}
}
/*
==============
idGrabber::ApplyShake
==============
*/
void idGrabber::ApplyShake() {
float u = 1 - (float)( endTime - gameLocal.time ) / ( g_grabberHoldSeconds.GetFloat() * 1000 );
if ( u >= 0.8f ) {
idVec3 point, impulse;
float shakeForceMagnitude = 450.f;
float mass = dragEnt.GetEntity()->GetPhysics()->GetMass();
shakeForceFlip = !shakeForceFlip;
// get point to rotate around
point = dragEnt.GetEntity()->GetPhysics()->GetOrigin();
point.y += 1;
// Articulated figures get less violent shake
if ( holdingAF ) {
shakeForceMagnitude = 120.f;
}
// calc impulse
if ( shakeForceFlip ) {
impulse.Set( 0, 0, shakeForceMagnitude * u * mass );
}
else {
impulse.Set( 0, 0, -shakeForceMagnitude * u * mass );
}
dragEnt.GetEntity()->ApplyImpulse( NULL, 0, point, impulse );
}
}
/*
==============
idGrabber::grabbableAI
==============
*/
bool idGrabber::grabbableAI( const char *aiName ) {
// skip "monster_"
aiName += 8;
if (!idStr::Cmpn( aiName, "flying_lostsoul", 15 ) ||
!idStr::Cmpn( aiName, "demon_trite", 11 ) ||
!idStr::Cmp( aiName, "flying_forgotten" ) ||
!idStr::Cmp( aiName, "demon_cherub" ) ||
!idStr::Cmp( aiName, "demon_tick" )) {
return true;
}
return false;
}

84
neo/d3xp/Grabber.h Normal file
View File

@@ -0,0 +1,84 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/*
===============================================================================
Grabber Object - Class to extend idWeapon to include functionality for
manipulating physics objects.
===============================================================================
*/
class idBeam;
class idGrabber : public idEntity {
public:
CLASS_PROTOTYPE( idGrabber );
idGrabber();
~idGrabber();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Initialize();
void SetDragDistance( float dist );
int Update( idPlayer *player, bool hide );
private:
idEntityPtr<idEntity> dragEnt; // entity being dragged
idForce_Grab drag;
idVec3 saveGravity;
int id; // id of body being dragged
idVec3 localPlayerPoint; // dragged point in player space
idEntityPtr<idPlayer> owner;
int oldImpulseSequence;
bool holdingAF;
bool shakeForceFlip;
int endTime;
int lastFiredTime;
int dragFailTime;
int startDragTime;
float dragTraceDist;
int savedContents;
int savedClipmask;
idBeam* beam;
idBeam* beamTarget;
int warpId;
bool grabbableAI( const char *aiName );
void StartDrag( idEntity *grabEnt, int id );
void StopDrag( bool dropOnly );
void UpdateBeams();
void ApplyShake();
};

1128
neo/d3xp/IK.cpp Normal file

File diff suppressed because it is too large Load Diff

182
neo/d3xp/IK.h Normal file
View File

@@ -0,0 +1,182 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_IK_H__
#define __GAME_IK_H__
/*
===============================================================================
IK base class with a simple fast two bone solver.
===============================================================================
*/
#define IK_ANIM "ik_pose"
class idIK {
public:
idIK();
virtual ~idIK();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
bool IsInitialized() const;
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate();
virtual void ClearJointMods();
bool SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos );
float GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis );
protected:
bool initialized;
bool ik_activate;
idEntity * self; // entity using the animated model
idAnimator * animator; // animator on entity
int modifiedAnim; // animation modified by the IK
idVec3 modelOffset;
};
/*
===============================================================================
IK controller for a walking character with an arbitrary number of legs.
===============================================================================
*/
class idIK_Walk : public idIK {
public:
idIK_Walk();
virtual ~idIK_Walk();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate();
virtual void ClearJointMods();
void EnableAll();
void DisableAll();
void EnableLeg( int num );
void DisableLeg( int num );
private:
static const int MAX_LEGS = 8;
idClipModel * footModel;
int numLegs;
int enabledLegs;
jointHandle_t footJoints[MAX_LEGS];
jointHandle_t ankleJoints[MAX_LEGS];
jointHandle_t kneeJoints[MAX_LEGS];
jointHandle_t hipJoints[MAX_LEGS];
jointHandle_t dirJoints[MAX_LEGS];
jointHandle_t waistJoint;
idVec3 hipForward[MAX_LEGS];
idVec3 kneeForward[MAX_LEGS];
float upperLegLength[MAX_LEGS];
float lowerLegLength[MAX_LEGS];
idMat3 upperLegToHipJoint[MAX_LEGS];
idMat3 lowerLegToKneeJoint[MAX_LEGS];
float smoothing;
float waistSmoothing;
float footShift;
float waistShift;
float minWaistFloorDist;
float minWaistAnkleDist;
float footUpTrace;
float footDownTrace;
bool tiltWaist;
bool usePivot;
// state
int pivotFoot;
float pivotYaw;
idVec3 pivotPos;
bool oldHeightsValid;
float oldWaistHeight;
float oldAnkleHeights[MAX_LEGS];
idVec3 waistOffset;
};
/*
===============================================================================
IK controller for reaching a position with an arm or leg.
===============================================================================
*/
class idIK_Reach : public idIK {
public:
idIK_Reach();
virtual ~idIK_Reach();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool Init( idEntity *self, const char *anim, const idVec3 &modelOffset );
virtual void Evaluate();
virtual void ClearJointMods();
private:
static const int MAX_ARMS = 2;
int numArms;
int enabledArms;
jointHandle_t handJoints[MAX_ARMS];
jointHandle_t elbowJoints[MAX_ARMS];
jointHandle_t shoulderJoints[MAX_ARMS];
jointHandle_t dirJoints[MAX_ARMS];
idVec3 shoulderForward[MAX_ARMS];
idVec3 elbowForward[MAX_ARMS];
float upperArmLength[MAX_ARMS];
float lowerArmLength[MAX_ARMS];
idMat3 upperArmToShoulderJoint[MAX_ARMS];
idMat3 lowerArmToElbowJoint[MAX_ARMS];
};
#endif /* !__GAME_IK_H__ */

2138
neo/d3xp/Item.cpp Normal file

File diff suppressed because it is too large Load Diff

324
neo/d3xp/Item.h Normal file
View File

@@ -0,0 +1,324 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_ITEM_H__
#define __GAME_ITEM_H__
/*
===============================================================================
Items the player can pick up or use.
===============================================================================
*/
/*
================================================
These flags are passed to the Give functions
to set their behavior. We need to be able to
separate the feedback from the actual
state modification so that we can hide lag
on MP clients.
For the previous behavior of functions which
take a giveFlags parameter (this is usually
desired on the server too) pass
ITEM_GIVE_FEEDBACK | ITEM_GIVE_UPDATE_STATE.
================================================
*/
enum itemGiveFlags_t {
ITEM_GIVE_FEEDBACK = BIT( 0 ),
ITEM_GIVE_UPDATE_STATE = BIT( 1 ),
ITEM_GIVE_FROM_WEAPON = BIT( 2 ), // indicates this was given via a weapon's launchPowerup (for bloodstone powerups)
};
class idItem : public idEntity {
public:
CLASS_PROTOTYPE( idItem );
idItem();
virtual ~idItem();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
void GetAttributes( idDict &attributes ) const;
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
virtual bool Pickup( idPlayer *player );
virtual void Think();
virtual void Present();
enum {
EVENT_PICKUP = idEntity::EVENT_MAXEVENTS,
EVENT_RESPAWN,
EVENT_RESPAWNFX,
EVENT_TAKEFLAG,
EVENT_DROPFLAG,
EVENT_FLAGRETURN,
EVENT_FLAGCAPTURE,
EVENT_MAXEVENTS
};
void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void ClientPredictionThink();
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
// networking
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
protected:
int GetPredictPickupMilliseconds() const { return clientPredictPickupMilliseconds; }
private:
idVec3 orgOrigin;
bool spin;
bool pulse;
bool canPickUp;
// for item pulse effect
int itemShellHandle;
const idMaterial * shellMaterial;
// used to update the item pulse effect
mutable bool inView;
mutable int inViewTime;
mutable int lastCycle;
mutable int lastRenderViewTime;
// used for prediction in mp
int clientPredictPickupMilliseconds;
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const;
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
void Event_DropToFloor();
void Event_Touch( idEntity *other, trace_t *trace );
void Event_Trigger( idEntity *activator );
void Event_Respawn();
void Event_RespawnFx();
};
class idItemPowerup : public idItem {
public:
CLASS_PROTOTYPE( idItemPowerup );
idItemPowerup();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
private:
int time;
int type;
};
class idObjective : public idItem {
public:
CLASS_PROTOTYPE( idObjective );
idObjective();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
idVec3 playerPos;
const idMaterial * screenshot;
void Event_Trigger( idEntity *activator );
void Event_HideObjective( idEntity *e );
void Event_GetPlayerPos();
};
class idVideoCDItem : public idItem {
public:
CLASS_PROTOTYPE( idVideoCDItem );
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
};
class idPDAItem : public idItem {
public:
CLASS_PROTOTYPE( idPDAItem );
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
};
class idMoveableItem : public idItem {
public:
CLASS_PROTOTYPE( idMoveableItem );
idMoveableItem();
virtual ~idMoveableItem();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Think();
void ClientThink( const int curTime, const float fraction, const bool predict );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual bool Pickup( idPlayer *player );
static void DropItems( idAnimatedEntity *ent, const char *type, idList<idEntity *> *list );
static idEntity * DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay );
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
protected:
idPhysics_RigidBody physicsObj;
idClipModel * trigger;
const idDeclParticle * smoke;
int smokeTime;
int nextSoundTime;
bool repeatSmoke; // never stop updating the particles
void Gib( const idVec3 &dir, const char *damageDefName );
void Event_DropToFloor();
void Event_Gib( const char *damageDefName );
};
class idItemTeam : public idMoveableItem {
public:
CLASS_PROTOTYPE( idItemTeam );
idItemTeam();
virtual ~idItemTeam();
void Spawn();
virtual bool Pickup( idPlayer *player );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
virtual void Think(void );
void Drop( bool death = false ); // was the drop caused by death of carrier?
void Return( idPlayer * player = NULL );
void Capture();
virtual void FreeLightDef();
virtual void Present();
// networking
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
public:
int team;
// TODO : turn this into a state :
bool carried; // is it beeing carried by a player?
bool dropped; // was it dropped?
private:
idVec3 returnOrigin;
idMat3 returnAxis;
int lastDrop;
const idDeclSkin * skinDefault;
const idDeclSkin * skinCarried;
const function_t * scriptTaken;
const function_t * scriptDropped;
const function_t * scriptReturned;
const function_t * scriptCaptured;
renderLight_t itemGlow; // Used by flags when they are picked up
int itemGlowHandle;
int lastNuggetDrop;
const char * nuggetName;
private:
void Event_TakeFlag( idPlayer * player );
void Event_DropFlag( bool death );
void Event_FlagReturn( idPlayer * player = NULL );
void Event_FlagCapture();
void PrivateReturn();
function_t * LoadScript( char * script );
void SpawnNugget( idVec3 pos );
void UpdateGuis();
};
class idMoveablePDAItem : public idMoveableItem {
public:
CLASS_PROTOTYPE( idMoveablePDAItem );
virtual bool GiveToPlayer( idPlayer *player, unsigned int giveFlags );
};
/*
===============================================================================
Item removers.
===============================================================================
*/
class idItemRemover : public idEntity {
public:
CLASS_PROTOTYPE( idItemRemover );
void Spawn();
void RemoveItem( idPlayer *player );
private:
void Event_Trigger( idEntity *activator );
};
class idObjectiveComplete : public idItemRemover {
public:
CLASS_PROTOTYPE( idObjectiveComplete );
idObjectiveComplete();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
idVec3 playerPos;
void Event_Trigger( idEntity *activator );
void Event_HideObjective( idEntity *e );
void Event_GetPlayerPos();
};
#endif /* !__GAME_ITEM_H__ */

332
neo/d3xp/Leaderboards.cpp Normal file
View File

@@ -0,0 +1,332 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "Leaderboards.h"
#include "MultiplayerGame.h"
/*
================================================================================================
Leaderboard stats column definitions - per Game Type.
================================================================================================
*/
static columnDef_t public_Deathmatch[] = {
{ "Frags", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
//{ "Deaths", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
//{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
//{ "Score", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
};
static columnDef_t public_Tourney[] = {
{ "Wins", 64, AGGREGATE_SUM, STATS_COLUMN_DISPLAY_NUMBER },
};
static columnDef_t public_TeamDeathmatch[] = {
{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
};
static columnDef_t public_LastmanStanding[] = {
{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
};
static columnDef_t public_CaptureTheFlag[] = {
{ "Wins", 64, AGGREGATE_MAX, STATS_COLUMN_DISPLAY_NUMBER },
};
// This should match up to the ordering of the gameType_t. ( in MultiplayerGame.h )
const columnGameMode_t gameMode_columnDefs[] = {
{ public_Deathmatch, ARRAY_COUNT( public_Deathmatch ), RANK_GREATEST_FIRST, false, false, "DM" }, // DEATHMATCH
{ public_Tourney, ARRAY_COUNT( public_Tourney ), RANK_GREATEST_FIRST, false, false, "TOURNEY" }, // TOURNEY
{ public_TeamDeathmatch, ARRAY_COUNT( public_TeamDeathmatch ), RANK_GREATEST_FIRST, false, false, "TDM" }, // TEAM DEATHMATCH
{ public_LastmanStanding, ARRAY_COUNT( public_LastmanStanding ), RANK_GREATEST_FIRST, false, false, "LMS" }, // LASTMAN STANDING
{ public_CaptureTheFlag, ARRAY_COUNT( public_CaptureTheFlag ), RANK_GREATEST_FIRST, false, false, "CTF" }, // CAPTURE THE FLAG
};
/*
=====================================
RetreiveLeaderboardID
Each map will move in blocks of n*modes.
ex. map 0 will have 0 - 4 Leaderboard id's blocked out.
map 1 will have 5 - 10 leaderboard id's blocked out.
if gamemode is added it will move in blocks of ARRAY_COUNT( modes )
=====================================
*/
int LeaderboardLocal_GetID( int mapIndex, int gametype ) {
assert( gametype > GAME_RANDOM );
return mapIndex * ARRAY_COUNT( gameMode_columnDefs ) + gametype;
}
/*
=====================================
LeaderboardLocal_Init
=====================================
*/
void LeaderboardLocal_Init() {
const idList< mpMap_t > maps = common->GetMapList();
const char ** gameModes = NULL;
const char ** gameModesDisplay = NULL;
int numModes = game->GetMPGameModes( &gameModes, &gameModesDisplay );
// Iterate through all the available maps, and generate leaderboard Defs, and IDs for each.
for( int mapIdx = 0; mapIdx < maps.Num(); mapIdx++ ) {
for( int modeIdx = 0; modeIdx < numModes; modeIdx++ ) {
// Check the supported modes on the map.
if( maps[ mapIdx ].supportedModes & BIT( modeIdx ) ) {
const columnGameMode_t gamemode = gameMode_columnDefs[ modeIdx ];
// Generate a Leaderboard ID for the map/mode
int boardID = LeaderboardLocal_GetID( mapIdx, modeIdx );
// Create and Register the leaderboard with the sys_stats registered Leaderboards
leaderboardDefinition_t * newLeaderboardDef = Sys_CreateLeaderboardDef( boardID,
gamemode.numColumns,
gamemode.columnDef,
gamemode.rankOrder,
gamemode.supportsAttachments,
gamemode.checkAgainstCurrent );
// Set the leaderboard name.
const char* mapname = idLocalization::GetString( maps[ mapIdx ].mapName );
newLeaderboardDef->boardName.Format( "%s %s", mapname, gamemode.abrevName );
// sanity check.
if( Sys_FindLeaderboardDef( boardID ) != newLeaderboardDef ) {
idLib::Error( "Leaderboards_Init leaderboard creation failed" );
}
}
}
}
}
/*
=====================================
LeaderboardLocal_Shutdown
=====================================
*/
void LeaderboardLocal_Shutdown() {
Sys_DestroyLeaderboardDefs();
}
/*
=====================================
LeaderboardLocal_Upload
=====================================
*/
const static int FRAG_MULTIPLIER = 100;
const static int DEATH_MULTIPLIER = -50;
const static int WINS_MULTIPLIER = 20;
void LeaderboardLocal_Upload( lobbyUserID_t lobbyUserID,int gameType, leaderboardStats_t & stats ) {
assert( gameType > GAME_RANDOM );
int mapIdx = 0;
// Need to figure out What stat columns we want to base rank on. ( for now we'll use wins )
const column_t * gameTypeColumn = NULL;
const column_t defaultStats[] = { stats.wins };
// calculate DM score.
int dmScore = stats.frags * FRAG_MULTIPLIER + stats.deaths * DEATH_MULTIPLIER + stats.wins * WINS_MULTIPLIER ;
// TODO: Once leaderboard menu has correct columns- enable this -> const column_t dmStats[] = { stats.frags, stats.deaths, stats.wins, dmScore };
const column_t dmStats[] = { dmScore };
// Calculate TDM score.
int tdmScore = stats.frags * FRAG_MULTIPLIER + stats.teamfrags * FRAG_MULTIPLIER + stats.deaths * DEATH_MULTIPLIER + stats.wins * WINS_MULTIPLIER ;
const column_t tdmStats[] = { tdmScore };
// Calculate Tourney score.
int tourneyScore = stats.wins;
const column_t tnyStats[] = { tourneyScore };
// Calculate LMS score.
int lmsFrags = stats.frags;
if( lmsFrags < 0 ) {
lmsFrags = 0; // LMS NO LIVES LEFT = -20 on fragCount.
}
int lmsScore = lmsFrags * FRAG_MULTIPLIER + stats.wins * ( WINS_MULTIPLIER * 10 ) ;
const column_t lmsStats[] = { lmsScore };
// Calculate CTF score.
int ctfScore = stats.frags * FRAG_MULTIPLIER + stats.deaths * DEATH_MULTIPLIER + stats.wins * ( WINS_MULTIPLIER * 10 );
const column_t ctfStats[] = { ctfScore };
switch( gameType ) {
case GAME_DM:
gameTypeColumn = dmStats;
break;
case GAME_TDM:
gameTypeColumn = tdmStats;
break;
case GAME_TOURNEY:
gameTypeColumn = tnyStats;
break;
case GAME_LASTMAN:
gameTypeColumn = lmsStats;
break;
case GAME_CTF: {
gameTypeColumn = ctfStats;
break;
}
default:
gameTypeColumn = defaultStats;
}
const idMatchParameters & matchParameters = session->GetActingGameStateLobbyBase().GetMatchParms();
const idList< mpMap_t > maps = common->GetMapList();
// need to find the map Index number
for( mapIdx = 0; mapIdx < maps.Num(); mapIdx++ ) {
if( matchParameters.mapName.Cmp( maps[ mapIdx ].mapFile ) == 0 ) {
break;
}
}
int boardID = LeaderboardLocal_GetID( mapIdx, gameType );
const leaderboardDefinition_t * board = Sys_FindLeaderboardDef( boardID );
if( board ) {
session->LeaderboardUpload( lobbyUserID, board, gameTypeColumn );
} else {
idLib::Warning( "LeaderboardLocal_Upload invalid leaderboard with id of %d", boardID );
}
}
class idLeaderboardCallbackTest : public idLeaderboardCallback {
void Call() {
idLib::Printf( "Leaderboard information retrieved in user callback.\n" );
idLib::Printf( "%d total entries in leaderboard %d.\n", numRowsInLeaderboard, def->id );
for ( int i = 0; i < rows.Num(); i++ ) {
idLib::Printf( "%d: %s rank:%lld", i, rows[i].name.c_str(), rows[i].rank );
for ( int j = 0; j < def->numColumns; j++ ) {
idLib::Printf( ", score[%d]: %lld", j, rows[i].columns[j] );
}
idLib::Printf( "\n" );
}
}
idLeaderboardCallback * Clone() const {
return new (TAG_PSN) idLeaderboardCallbackTest( *this );
}
};
CONSOLE_COMMAND( testLeaderboardDownload, "<id 0 - n > <start = 1> <end = 100>", 0 ) {
idLeaderboardCallbackTest leaderboardCallbackTest;
int leaderboardID = 0;
int start = 1;
int end = 100;
if ( args.Argc() > 1 ) {
leaderboardID = atoi( args.Argv( 1 ) );
}
if ( args.Argc() > 2 ) {
start = atoi( args.Argv( 2 ) );
}
if ( args.Argc() > 3 ) {
end = atoi( args.Argv( 3 ) );
}
const leaderboardDefinition_t * leaderboardDef = Sys_FindLeaderboardDef( leaderboardID );
if( leaderboardDef ) {
session->LeaderboardDownload( 0, leaderboardDef, start, end, leaderboardCallbackTest );
} else {
idLib::Warning( "Sys_FindLeaderboardDef() Unable to find board %d\n", leaderboardID );
}
}
CONSOLE_COMMAND( testLeaderboardUpload, "<gameType 0 - 4 > <frags = 0> <wins = 1>", 0 ) {
idLobbyBase & lobby = session->GetActingGameStateLobbyBase();
lobbyUserID_t user = lobby.GetLobbyUserIdByOrdinal( 0 );
gameType_t gameType = GAME_DM;
int frags = 0;
int wins = 1;
if ( args.Argc() > 1 ) {
gameType = static_cast<gameType_t>( atoi( args.Argv( 1 ) ) );
}
if ( args.Argc() > 2 ) {
frags = atoi( args.Argv( 2 ) );
}
if ( args.Argc() > 3 ) {
wins = atoi( args.Argv( 3 ) );
}
leaderboardStats_t stats = { frags, wins, 0, 0 };
LeaderboardLocal_Upload( user, gameType , stats );
session->LeaderboardFlush();
}
CONSOLE_COMMAND( testLeaderboardUpload_SendToClients, "<gameType 0 - 4 > <frags = 0> <wins = 1>", 0 ) {
for( int playerIdx = 0; playerIdx < gameLocal.numClients; playerIdx++ ) {
leaderboardStats_t stats = { 1, 1, 1, 1 };
LeaderboardLocal_Upload( gameLocal.lobbyUserIDs[ playerIdx ], gameLocal.gameType, stats );
}
// Dont do this more than once.
session->LeaderboardFlush();
}

74
neo/d3xp/Leaderboards.h Normal file
View File

@@ -0,0 +1,74 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __LEADERBOARDS_LOCAL_H__
#define __LEADERBOARDS_LOCAL_H__
struct leaderboardStats_t {
int frags;
int wins;
int teamfrags;
int deaths;
};
struct columnGameMode_t {
columnDef_t * columnDef; // The Column definition for the game mode.
int numColumns;
rankOrder_t rankOrder; // rank ordering of the game mode. ( RANK_GREATEST_FIRST, RANK_LEAST_FIRST )
bool supportsAttachments;
bool checkAgainstCurrent;
const char * abrevName; // Leaderboard Game Mode Abrev.
};
/*
================================================================================================
Leaderboards
================================================================================================
*/
// creates and stores all the leaderboards inside the internal map ( see Sys_FindLeaderboardDef on retrieving definition )
void LeaderboardLocal_Init();
// Destroys any leaderboard definitions allocated by LeaderboardLocal_Init()
void LeaderboardLocal_Shutdown();
// Gets a leaderboard ID with map index and game type.
int LeaderboardLocal_GetID( int mapIndex, int gametype );
// Do it all function. Will create the column_t with the correct stats from the game type, and upload it to the leaderboard system.
void LeaderboardLocal_Upload( lobbyUserID_t lobbyUserID, int gameType, leaderboardStats_t & stats );
extern const columnGameMode_t gameMode_columnDefs[];
#endif // __LEADERBOARDS_LOCAL_H__

1182
neo/d3xp/Light.cpp Normal file

File diff suppressed because it is too large Load Diff

142
neo/d3xp/Light.h Normal file
View File

@@ -0,0 +1,142 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_LIGHT_H__
#define __GAME_LIGHT_H__
/*
===============================================================================
Generic light.
===============================================================================
*/
extern const idEventDef EV_Light_GetLightParm;
extern const idEventDef EV_Light_SetLightParm;
extern const idEventDef EV_Light_SetLightParms;
class idLight : public idEntity {
public:
CLASS_PROTOTYPE( idLight );
idLight();
~idLight();
void Spawn();
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
virtual void UpdateChangeableSpawnArgs( const idDict *source );
virtual void Think();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void FreeLightDef();
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
void Present();
void SaveState( idDict *args );
virtual void SetColor( float red, float green, float blue );
virtual void SetColor( const idVec4 &color );
void SetColor( const idVec3 &color );
virtual void GetColor( idVec3 &out ) const;
virtual void GetColor( idVec4 &out ) const;
const idVec3 & GetBaseColor() const { return baseColor; }
void SetShader( const char *shadername );
void SetLightParm( int parmnum, float value );
void SetLightParms( float parm0, float parm1, float parm2, float parm3 );
void SetRadiusXYZ( float x, float y, float z );
void SetRadius( float radius );
void On();
void Off();
void Fade( const idVec4 &to, float fadeTime );
void FadeOut( float time );
void FadeIn( float time );
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void BecomeBroken( idEntity *activator );
qhandle_t GetLightDefHandle() const { return lightDefHandle; }
void SetLightParent( idEntity *lparent ) { lightParent = lparent; }
void SetLightLevel();
virtual void ShowEditingDialog();
enum {
EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
virtual void ClientPredictionThink();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
private:
renderLight_t renderLight; // light presented to the renderer
idVec3 localLightOrigin; // light origin relative to the physics origin
idMat3 localLightAxis; // light axis relative to physics axis
qhandle_t lightDefHandle; // handle to renderer light def
idStr brokenModel;
int levels;
int currentLevel;
idVec3 baseColor;
// Colors used for client-side interpolation.
idVec3 previousBaseColor;
idVec3 nextBaseColor;
bool breakOnTrigger;
int count;
int triggercount;
idEntity * lightParent;
idVec4 fadeFrom;
idVec4 fadeTo;
int fadeStart;
int fadeEnd;
bool soundWasPlaying;
private:
void PresentLightDefChange();
void PresentModelDefChange();
void Event_SetShader( const char *shadername );
void Event_GetLightParm( int parmnum );
void Event_SetLightParm( int parmnum, float value );
void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 );
void Event_SetRadiusXYZ( float x, float y, float z );
void Event_SetRadius( float radius );
void Event_Hide();
void Event_Show();
void Event_On();
void Event_Off();
void Event_ToggleOnOff( idEntity *activator );
void Event_SetSoundHandles();
void Event_FadeOut( float time );
void Event_FadeIn( float time );
};
#endif /* !__GAME_LIGHT_H__ */

3934
neo/d3xp/Misc.cpp Normal file

File diff suppressed because it is too large Load Diff

928
neo/d3xp/Misc.h Normal file
View File

@@ -0,0 +1,928 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_MISC_H__
#define __GAME_MISC_H__
/*
===============================================================================
idSpawnableEntity
A simple, spawnable entity with a model and no functionable ability of it's own.
For example, it can be used as a placeholder during development, for marking
locations on maps for script, or for simple placed models without any behavior
that can be bound to other entities. Should not be subclassed.
===============================================================================
*/
class idSpawnableEntity : public idEntity {
public:
CLASS_PROTOTYPE( idSpawnableEntity );
void Spawn();
private:
};
/*
===============================================================================
Potential spawning position for players.
The first time a player enters the game, they will be at an 'initial' spot.
Targets will be fired when someone spawns in on them.
When triggered, will cause player to be teleported to spawn spot.
===============================================================================
*/
class idPlayerStart : public idEntity {
public:
CLASS_PROTOTYPE( idPlayerStart );
enum {
EVENT_TELEPORTPLAYER = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
idPlayerStart();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
private:
int teleportStage;
void Event_TeleportPlayer( idEntity *activator );
void Event_TeleportStage( idEntity *player );
void TeleportPlayer( idPlayer *player );
};
/*
===============================================================================
Non-displayed entity used to activate triggers when it touches them.
Bind to a mover to have the mover activate a trigger as it moves.
When target by triggers, activating the trigger will toggle the
activator on and off. Check "start_off" to have it spawn disabled.
===============================================================================
*/
class idActivator : public idEntity {
public:
CLASS_PROTOTYPE( idActivator );
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
private:
bool stay_on;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
Path entities for monsters to follow.
===============================================================================
*/
class idPathCorner : public idEntity {
public:
CLASS_PROTOTYPE( idPathCorner );
void Spawn();
static void DrawDebugInfo();
static idPathCorner *RandomPath( const idEntity *source, const idEntity *ignore );
private:
void Event_RandomPath();
};
/*
===============================================================================
Object that fires targets and changes shader parms when damaged.
===============================================================================
*/
class idDamagable : public idEntity {
public:
CLASS_PROTOTYPE( idDamagable );
idDamagable();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void Hide();
virtual void Show();
private:
int count;
int nextTriggerTime;
void BecomeBroken( idEntity *activator );
void Event_BecomeBroken( idEntity *activator );
void Event_RestoreDamagable();
};
/*
===============================================================================
Hidden object that explodes when activated
===============================================================================
*/
class idExplodable : public idEntity {
public:
CLASS_PROTOTYPE( idExplodable );
void Spawn();
private:
void Event_Explode( idEntity *activator );
};
/*
===============================================================================
idSpring
===============================================================================
*/
class idSpring : public idEntity {
public:
CLASS_PROTOTYPE( idSpring );
void Spawn();
virtual void Think();
private:
idEntity * ent1;
idEntity * ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
void Event_LinkSpring();
};
/*
===============================================================================
idForceField
===============================================================================
*/
class idForceField : public idEntity {
public:
CLASS_PROTOTYPE( idForceField );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Think();
virtual void ClientThink( const int curTime, const float fraction, const bool predict ) ;
private:
idForce_Field forceField;
void Toggle();
void Event_Activate( idEntity *activator );
void Event_Toggle();
void Event_FindTargets();
};
/*
===============================================================================
idAnimated
===============================================================================
*/
class idAnimated : public idAFEntity_Gibbable {
public:
CLASS_PROTOTYPE( idAnimated );
idAnimated();
~idAnimated();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual bool LoadAF();
bool StartRagdoll();
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
private:
int num_anims;
int current_anim_index;
int anim;
int blendFrames;
jointHandle_t soundJoint;
idEntityPtr<idEntity> activator;
bool activated;
int achievement;
void PlayNextAnim();
void Event_Activate( idEntity *activator );
void Event_Start();
void Event_StartRagdoll();
void Event_AnimDone( int animIndex );
void Event_Footstep();
void Event_LaunchMissiles( const char *projectilename, const char *sound, const char *launchjoint, const char *targetjoint, int numshots, int framedelay );
void Event_LaunchMissilesUpdate( int launchjoint, int targetjoint, int numshots, int framedelay );
void Event_SetAnimation( const char *animName );
void Event_GetAnimationLength();
};
/*
===============================================================================
idStaticEntity
===============================================================================
*/
class idStaticEntity : public idEntity {
public:
CLASS_PROTOTYPE( idStaticEntity );
idStaticEntity();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
void ShowEditingDialog();
virtual void Hide();
virtual void Show();
void Fade( const idVec4 &to, float fadeTime );
virtual void Think();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
private:
void Event_Activate( idEntity *activator );
int spawnTime;
bool active;
idVec4 fadeFrom;
idVec4 fadeTo;
int fadeStart;
int fadeEnd;
bool runGui;
};
/*
===============================================================================
idFuncEmitter
===============================================================================
*/
class idFuncEmitter : public idStaticEntity {
public:
CLASS_PROTOTYPE( idFuncEmitter );
idFuncEmitter();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
void Event_Activate( idEntity *activator );
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
private:
bool hidden;
};
/*
===============================================================================
idFuncShootProjectile
===============================================================================
*/
class idFuncShootProjectile : public idStaticEntity {
public:
CLASS_PROTOTYPE( idFuncShootProjectile );
idFuncShootProjectile();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
void Event_Activate( idEntity *activator );
virtual void Think();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
private:
int mRespawnDelay;
int mRespawnTime;
float mShootSpeed;
idVec3 mShootDir;
idStr mEntityDefName;
idEntityPtr< idEntity > mLastProjectile;
};
/*
===============================================================================
idFuncSmoke
===============================================================================
*/
class idFuncSmoke : public idEntity {
public:
CLASS_PROTOTYPE( idFuncSmoke );
idFuncSmoke();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
void Event_Activate( idEntity *activator );
private:
int smokeTime;
const idDeclParticle * smoke;
bool restart;
};
/*
===============================================================================
idFuncSplat
===============================================================================
*/
class idFuncSplat : public idFuncEmitter {
public:
CLASS_PROTOTYPE( idFuncSplat );
idFuncSplat();
void Spawn();
private:
void Event_Activate( idEntity *activator );
void Event_Splat();
};
/*
===============================================================================
idTextEntity
===============================================================================
*/
class idTextEntity : public idEntity {
public:
CLASS_PROTOTYPE( idTextEntity );
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
private:
idStr text;
bool playerOriented;
};
/*
===============================================================================
idLocationEntity
===============================================================================
*/
class idLocationEntity : public idEntity {
public:
CLASS_PROTOTYPE( idLocationEntity );
void Spawn();
const char * GetLocation() const;
private:
};
class idLocationSeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( idLocationSeparatorEntity );
void Spawn();
private:
};
class idVacuumSeparatorEntity : public idEntity {
public:
CLASS_PROTOTYPE( idVacuumSeparatorEntity );
idVacuumSeparatorEntity();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Event_Activate( idEntity *activator );
private:
qhandle_t portal;
};
class idVacuumEntity : public idEntity {
public:
CLASS_PROTOTYPE( idVacuumEntity );
void Spawn();
private:
};
/*
===============================================================================
idBeam
===============================================================================
*/
class idBeam : public idEntity {
public:
CLASS_PROTOTYPE( idBeam );
idBeam();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
void SetMaster( idBeam *masterbeam );
void SetBeamTarget( const idVec3 &origin );
virtual void Show();
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
private:
void Event_MatchTarget();
void Event_Activate( idEntity *activator );
idEntityPtr<idBeam> target;
idEntityPtr<idBeam> master;
};
/*
===============================================================================
idLiquid
===============================================================================
*/
class idRenderModelLiquid;
class idLiquid : public idEntity {
public:
CLASS_PROTOTYPE( idLiquid );
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
void Event_Touch( idEntity *other, trace_t *trace );
idRenderModelLiquid *model;
};
/*
===============================================================================
idShaking
===============================================================================
*/
class idShaking : public idEntity {
public:
CLASS_PROTOTYPE( idShaking );
idShaking();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idPhysics_Parametric physicsObj;
bool active;
void BeginShaking();
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idEarthQuake
===============================================================================
*/
class idEarthQuake : public idEntity {
public:
CLASS_PROTOTYPE( idEarthQuake );
idEarthQuake();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
private:
int nextTriggerTime;
int shakeStopTime;
float wait;
float random;
bool triggered;
bool playerOriented;
bool disabled;
float shakeTime;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncPortal
===============================================================================
*/
class idFuncPortal : public idEntity {
public:
CLASS_PROTOTYPE( idFuncPortal );
idFuncPortal();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
qhandle_t portal;
bool state;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncAASPortal
===============================================================================
*/
class idFuncAASPortal : public idEntity {
public:
CLASS_PROTOTYPE( idFuncAASPortal );
idFuncAASPortal();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
bool state;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncAASObstacle
===============================================================================
*/
class idFuncAASObstacle : public idEntity {
public:
CLASS_PROTOTYPE( idFuncAASObstacle );
idFuncAASObstacle();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
bool state;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idFuncRadioChatter
===============================================================================
*/
class idFuncRadioChatter : public idEntity {
public:
CLASS_PROTOTYPE( idFuncRadioChatter );
idFuncRadioChatter();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
float time;
void Event_Activate( idEntity *activator );
void Event_ResetRadioHud( idEntity *activator );
};
/*
===============================================================================
idPhantomObjects
===============================================================================
*/
class idPhantomObjects : public idEntity {
public:
CLASS_PROTOTYPE( idPhantomObjects );
idPhantomObjects();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
private:
void Event_Activate( idEntity *activator );
void Event_Throw();
void Event_ShakeObject( idEntity *object, int starttime );
int end_time;
float throw_time;
float shake_time;
idVec3 shake_ang;
float speed;
int min_wait;
int max_wait;
idEntityPtr<idActor>target;
idList<int> targetTime;
idList<idVec3> lastTargetPos;
};
/*
===============================================================================
idShockwave
===============================================================================
*/
class idShockwave : public idEntity {
public:
CLASS_PROTOTYPE( idShockwave );
idShockwave();
~idShockwave();
void Spawn();
void Think();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
void Event_Activate( idEntity *activator );
bool isActive;
int startTime;
int duration;
float startSize;
float endSize;
float currentSize;
float magnitude;
float height;
bool playerDamaged;
float playerDamageSize;
};
/*
===============================================================================
idFuncMountedObject
===============================================================================
*/
class idFuncMountedObject : public idEntity {
public:
CLASS_PROTOTYPE( idFuncMountedObject );
idFuncMountedObject();
~idFuncMountedObject();
void Spawn();
void Think();
void GetAngleRestrictions( int &yaw_min, int &yaw_max, int &pitch );
private:
int harc;
int varc;
void Event_Touch( idEntity *other, trace_t *trace );
void Event_Activate( idEntity *activator );
public:
bool isMounted;
function_t * scriptFunction;
idPlayer * mountedPlayer;
};
class idFuncMountedWeapon : public idFuncMountedObject {
public:
CLASS_PROTOTYPE( idFuncMountedWeapon );
idFuncMountedWeapon();
~idFuncMountedWeapon();
void Spawn();
void Think();
private:
// The actual turret that moves with the player's view
idEntity * turret;
// the muzzle bone's position, used for launching projectiles and trailing smoke
idVec3 muzzleOrigin;
idMat3 muzzleAxis;
float weaponLastFireTime;
float weaponFireDelay;
const idDict * projectile;
const idSoundShader *soundFireWeapon;
void Event_PostSpawn();
};
/*
===============================================================================
idPortalSky
===============================================================================
*/
class idPortalSky : public idEntity {
public:
CLASS_PROTOTYPE( idPortalSky );
idPortalSky();
~idPortalSky();
void Spawn();
void Event_PostSpawn();
void Event_Activate( idEntity *activator );
};
#endif /* !__GAME_MISC_H__ */

1355
neo/d3xp/Moveable.cpp Normal file

File diff suppressed because it is too large Load Diff

210
neo/d3xp/Moveable.h Normal file
View File

@@ -0,0 +1,210 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_MOVEABLE_H__
#define __GAME_MOVEABLE_H__
/*
===============================================================================
Entity using rigid body physics.
===============================================================================
*/
extern const idEventDef EV_BecomeNonSolid;
extern const idEventDef EV_IsAtRest;
class idMoveable : public idEntity {
public:
CLASS_PROTOTYPE( idMoveable );
idMoveable();
~idMoveable();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void Hide();
virtual void Show();
bool AllowStep() const;
void EnableDamage( bool enable, float duration );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
void SetAttacker( idEntity *ent );
const idEntity * GetAttacker() { return attacker; }
protected:
idPhysics_RigidBody physicsObj; // physics object
idStr brokenModel; // model set when health drops down to or below zero
idStr damage; // if > 0 apply damage to hit entities
idStr monsterDamage;
idEntity *attacker;
idStr fxCollide; // fx system to start when collides with something
int nextCollideFxTime; // next time it is ok to spawn collision fx
float minDamageVelocity; // minimum velocity before moveable applies damage
float maxDamageVelocity; // velocity at which the maximum damage is applied
idCurve_Spline<idVec3> *initialSpline; // initial spline path the moveable follows
idVec3 initialSplineDir; // initial relative direction along the spline path
bool explode; // entity explodes when health drops down to or below zero
bool unbindOnDeath; // unbind from master when health drops down to or below zero
bool allowStep; // allow monsters to step on the object
bool canDamage; // only apply damage when this is set
int nextDamageTime; // next time the movable can hurt the player
int nextSoundTime; // next time the moveable can make a sound
const idMaterial * GetRenderModelMaterial() const;
void BecomeNonSolid();
void InitInitialSpline( int startTime );
bool FollowInitialSplinePath();
void Event_Activate( idEntity *activator );
void Event_BecomeNonSolid();
void Event_SetOwnerFromSpawnArgs();
void Event_IsAtRest();
void Event_EnableDamage( float enable );
};
/*
===============================================================================
A barrel using rigid body physics. The barrel has special handling of
the view model orientation to make it look like it rolls instead of slides.
===============================================================================
*/
class idBarrel : public idMoveable {
public:
CLASS_PROTOTYPE( idBarrel );
idBarrel();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void BarrelThink();
virtual void Think();
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
private:
float radius; // radius of barrel
int barrelAxis; // one of the coordinate axes the barrel cylinder is parallel to
idVec3 lastOrigin; // origin of the barrel the last think frame
idMat3 lastAxis; // axis of the barrel the last think frame
float additionalRotation; // additional rotation of the barrel about it's axis
idMat3 additionalAxis; // additional rotation axis
};
/*
===============================================================================
A barrel using rigid body physics and special handling of the view model
orientation to make it look like it rolls instead of slides. The barrel
can burn and explode when damaged.
===============================================================================
*/
class idExplodingBarrel : public idBarrel {
public:
CLASS_PROTOTYPE( idExplodingBarrel );
idExplodingBarrel();
~idExplodingBarrel();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
bool IsStable();
void SetStability( bool stability );
void StartBurning();
void StopBurning();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void Think();
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
const char *damageDefName, const float damageScale, const int location );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
enum {
EVENT_EXPLODE = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
private:
typedef enum {
NORMAL = 0,
BURNING,
BURNEXPIRED,
EXPLODING
} explode_state_t;
explode_state_t state;
idVec3 spawnOrigin;
idMat3 spawnAxis;
qhandle_t particleModelDefHandle;
qhandle_t lightDefHandle;
renderEntity_t particleRenderEntity;
renderLight_t light;
int particleTime;
int lightTime;
float time;
bool isStable;
void AddParticles( const char *name, bool burn );
void AddLight( const char *name , bool burn );
void ExplodingEffects();
void UpdateLight();
void Event_Activate( idEntity *activator );
void Event_Respawn();
void Event_Explode();
void Event_TriggerTargets();
};
#endif /* !__GAME_MOVEABLE_H__ */

4852
neo/d3xp/Mover.cpp Normal file

File diff suppressed because it is too large Load Diff

556
neo/d3xp/Mover.h Normal file
View File

@@ -0,0 +1,556 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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<idEntity> splineEnt;
moverCommand_t lastCommand;
float damage;
qhandle_t areaPortal; // 0 = no portal
idList< idEntityPtr<idEntity>, TAG_MOVER > guiTargets;
void VectorForDir( float dir, idVec3 &vec );
idCurve_Spline<idVec3> *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_s, TAG_MOVER> 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<idEntity> 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<idEntity>, 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<idEntity> 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__ */

3188
neo/d3xp/MultiplayerGame.cpp Normal file

File diff suppressed because it is too large Load Diff

357
neo/d3xp/MultiplayerGame.h Normal file
View File

@@ -0,0 +1,357 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __MULTIPLAYERGAME_H__
#define __MULTIPLAYERGAME_H__
/*
===============================================================================
Basic DOOM multiplayer
===============================================================================
*/
class idPlayer;
class idMenuHandler_HUD;
class idMenuHandler_Scoreboard;
class idItemTeam;
enum gameType_t {
GAME_SP = -2,
GAME_RANDOM = -1,
GAME_DM = 0,
GAME_TOURNEY,
GAME_TDM,
GAME_LASTMAN,
GAME_CTF,
GAME_COUNT,
};
// Used by the UI
typedef enum {
FLAGSTATUS_INBASE = 0,
FLAGSTATUS_TAKEN = 1,
FLAGSTATUS_STRAY = 2,
FLAGSTATUS_NONE = 3
} flagStatus_t;
typedef struct mpPlayerState_s {
int ping; // player ping
int fragCount; // kills
int teamFragCount; // team kills
int wins; // wins
bool scoreBoardUp; // toggle based on player scoreboard button, used to activate de-activate the scoreboard gui
int deaths;
} mpPlayerState_t;
const int NUM_CHAT_NOTIFY = 5;
const int CHAT_FADE_TIME = 400;
const int FRAGLIMIT_DELAY = 2000;
const int MP_PLAYER_MINFRAGS = -100;
const int MP_PLAYER_MAXFRAGS = 400; // in CTF frags are player points
const int MP_PLAYER_MAXWINS = 100;
const int MP_PLAYER_MAXPING = 999;
const int MP_CTF_MAXPOINTS = 400;
typedef struct mpChatLine_s {
idStr line;
short fade; // starts high and decreases, line is removed once reached 0
} mpChatLine_t;
typedef enum {
SND_YOUWIN = 0,
SND_YOULOSE,
SND_FIGHT,
SND_THREE,
SND_TWO,
SND_ONE,
SND_SUDDENDEATH,
SND_FLAG_CAPTURED_YOURS,
SND_FLAG_CAPTURED_THEIRS,
SND_FLAG_RETURN,
SND_FLAG_TAKEN_YOURS,
SND_FLAG_TAKEN_THEIRS,
SND_FLAG_DROPPED_YOURS,
SND_FLAG_DROPPED_THEIRS,
SND_COUNT
} snd_evt_t;
class idMultiplayerGame {
public:
idMultiplayerGame();
void Shutdown();
// resets everything and prepares for a match
void Reset();
// setup local data for a new player
void SpawnPlayer( int clientNum );
// checks rules and updates state of the mp game
void Run();
// draws mp hud, scoredboard, etc..
bool Draw( int clientNum );
// updates frag counts and potentially ends the match in sudden death
void PlayerDeath( idPlayer *dead, idPlayer *killer, bool telefrag );
void AddChatLine( VERIFY_FORMAT_STRING const char *fmt, ... );
void WriteToSnapshot( idBitMsg &msg ) const;
void ReadFromSnapshot( const idBitMsg &msg );
// game state
typedef enum {
INACTIVE = 0, // not running
WARMUP, // warming up
COUNTDOWN, // post warmup pre-game
GAMEON, // game is on
SUDDENDEATH, // game is on but in sudden death, first frag wins
GAMEREVIEW, // game is over, scoreboard is up. we wait si_gameReviewPause seconds (which has a min value)
NEXTGAME,
STATE_COUNT
} gameState_t;
static const char *GameStateStrings[ STATE_COUNT ];
idMultiplayerGame::gameState_t GetGameState() const;
static const char *GlobalSoundStrings[ SND_COUNT ];
void PlayGlobalSound( int toPlayerNum, snd_evt_t evt, const char *shader = NULL );
void PlayTeamSound( int toTeam, snd_evt_t evt, const char *shader = NULL ); // sound that's sent only to member of toTeam team
// more compact than a chat line
typedef enum {
MSG_SUICIDE = 0,
MSG_KILLED,
MSG_KILLEDTEAM,
MSG_DIED,
MSG_SUDDENDEATH,
MSG_JOINEDSPEC,
MSG_TIMELIMIT,
MSG_FRAGLIMIT,
MSG_TELEFRAGGED,
MSG_JOINTEAM,
MSG_HOLYSHIT,
MSG_POINTLIMIT,
MSG_FLAGTAKEN,
MSG_FLAGDROP,
MSG_FLAGRETURN,
MSG_FLAGCAPTURE,
MSG_SCOREUPDATE,
MSG_LEFTGAME,
MSG_COUNT
} msg_evt_t;
void PrintMessageEvent( msg_evt_t evt, int parm1 = -1, int parm2 = -1 );
void DisconnectClient( int clientNum );
static void DropWeapon_f( const idCmdArgs &args );
static void MessageMode_f( const idCmdArgs &args );
static void VoiceChat_f( const idCmdArgs &args );
static void VoiceChatTeam_f( const idCmdArgs &args );
int NumActualClients( bool countSpectators, int *teamcount = NULL );
void DropWeapon( int clientNum );
void MapRestart();
void BalanceTeams();
void SwitchToTeam( int clientNum, int oldteam, int newteam );
bool IsPureReady() const;
void ProcessChatMessage( int clientNum, bool team, const char *name, const char *text, const char *sound );
void ProcessVoiceChat( int clientNum, bool team, int index );
bool HandleGuiEvent( const sysEvent_t * sev );
bool IsScoreboardActive();
void SetScoreboardActive( bool active );
void CleanupScoreboard();
void Precache();
void ToggleSpectate();
void GetSpectateText( idPlayer * player, idStr spectatetext[ 2 ], bool scoreboard );
void ClearFrags( int clientNum );
bool CanPlay( idPlayer *p );
bool WantRespawn( idPlayer *p );
void ServerWriteInitialReliableMessages( int clientNum, lobbyUserID_t lobbyUserID );
void ClientReadStartState( const idBitMsg &msg );
void ClientReadWarmupTime( const idBitMsg &msg );
void ClientReadMatchStartedTime( const idBitMsg & msg );
void ClientReadAchievementUnlock( const idBitMsg & msg );
void ServerClientConnect( int clientNum );
int GetFlagPoints( int team ); // Team points in CTF
void SetFlagMsg( bool b ); // allow flag event messages to be sent
bool IsFlagMsgOn(); // should flag event messages go through?
int player_red_flag; // Ent num of red flag carrier for HUD
int player_blue_flag; // Ent num of blue flag carrier for HUD
void PlayerStats( int clientNum, char *data, const int len );
private:
static const char * teamNames[];
static const char * skinNames[];
static const idVec3 skinColors[];
static const int numSkins;
// state vars
gameState_t gameState; // what state the current game is in
gameState_t nextState; // state to switch to when nextStateSwitch is hit
mpPlayerState_t playerState[ MAX_CLIENTS ];
// keep track of clients which are willingly in spectator mode
// time related
int nextStateSwitch; // time next state switch
int warmupEndTime; // warmup till..
int matchStartedTime; // time current match started
// tourney
int currentTourneyPlayer[2];// our current set of players
int lastWinner; // plays again
// warmup
bool one, two, three; // keeps count down voice from repeating
// guis
idMenuHandler_Scoreboard * scoreboardManager;
// chat data
mpChatLine_t chatHistory[ NUM_CHAT_NOTIFY ];
int chatHistoryIndex;
int chatHistorySize; // 0 <= x < NUM_CHAT_NOTIFY
bool chatDataUpdated;
int lastChatLineTime;
// rankings are used by UpdateScoreboard and UpdateHud
int numRankedPlayers; // ranked players, others may be empty slots or spectators
idPlayer * rankedPlayers[MAX_CLIENTS];
bool pureReady; // defaults to false, set to true once server game is running with pure checksums
int fragLimitTimeout;
int voiceChatThrottle;
int startFragLimit; // synchronize to clients in initial state, set on -> GAMEON
idItemTeam * teamFlags[ 2 ];
int teamPoints[ 2 ];
bool flagMsgOn;
private:
void UpdatePlayerRanks();
void GameHasBeenWon();
// updates the passed gui with current score information
void UpdateRankColor( idUserInterface *gui, const char *mask, int i, const idVec3 &vec );
void UpdateScoreboard( idMenuHandler_Scoreboard * scoreboard, idPlayer *owner );
void DrawScoreBoard( idPlayer *player );
void UpdateHud( idPlayer *player, idMenuHandler_HUD * hudManager );
bool Warmup();
idPlayer * FragLimitHit();
idPlayer * FragLeader();
bool TimeLimitHit();
bool PointLimitHit();
// return team with most points
int WinningTeam();
void NewState( gameState_t news, idPlayer *player = NULL );
void UpdateWinsLosses( idPlayer *winner );
// fill any empty tourney slots based on the current tourney ranks
void FillTourneySlots();
void CycleTourneyPlayers();
// walk through the tourneyRank to build a wait list for the clients
void UpdateTourneyLine();
const char * GameTime();
void Clear();
bool EnoughClientsToPlay();
void ClearChatData();
void DrawChat( idPlayer * player );
// go through the clients, and see if they want to be respawned, and if the game allows it
// called during normal gameplay for death -> respawn cycles
// and for a spectator who want back in the game (see param)
void CheckRespawns( idPlayer *spectator = NULL );
// when clients disconnect or join spectate during game, check if we need to end the game
void CheckAbortGame();
void MessageMode( const idCmdArgs &args );
// scores in TDM
void TeamScore( int entityNumber, int team, int delta );
void VoiceChat( const idCmdArgs &args, bool team );
void DumpTourneyLine();
void SuddenRespawn();
void FindTeamFlags();
void NewState_Warmup_ServerAndClient();
void NewState_Countdown_ServerAndClient();
void NewState_GameOn_ServerAndClient();
void NewState_GameReview_ServerAndClient();
public:
const char * GetTeamName( int team ) const;
const char * GetSkinName( int skin ) const;
const idVec3 & GetSkinColor( int skin ) const;
idItemTeam * GetTeamFlag( int team );
flagStatus_t GetFlagStatus( int team );
void TeamScoreCTF( int team, int delta );
void PlayerScoreCTF( int playerIdx, int delta );
// returns entityNum to team flag carrier, -1 if no flag carrier
int GetFlagCarrier( int team );
void UpdateScoreboardFlagStatus();
void ReloadScoreboard();
int GetGameModes( const char *** gameModes, const char *** gameModesDisplay );
bool IsGametypeFlagBased();
bool IsGametypeTeamBased();
};
ID_INLINE idMultiplayerGame::gameState_t idMultiplayerGame::GetGameState() const {
return gameState;
}
ID_INLINE bool idMultiplayerGame::IsPureReady() const {
return pureReady;
}
ID_INLINE void idMultiplayerGame::ClearFrags( int clientNum ) {
playerState[ clientNum ].fragCount = 0;
}
#endif /* !__MULTIPLAYERGAME_H__ */

10742
neo/d3xp/Player.cpp Normal file

File diff suppressed because it is too large Load Diff

924
neo/d3xp/Player.h Normal file
View File

@@ -0,0 +1,924 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_PLAYER_H__
#define __GAME_PLAYER_H__
#include "PredictedValue.h"
/*
===============================================================================
Player entity.
===============================================================================
*/
class idMenuHandler_PDA;
class idMenuHandler_HUD;
class idMenuScreen_HUD;
class idTarget_SetPrimaryObjective;
extern const idEventDef EV_Player_GetButtons;
extern const idEventDef EV_Player_GetMove;
extern const idEventDef EV_Player_GetViewAngles;
extern const idEventDef EV_Player_EnableWeapon;
extern const idEventDef EV_Player_DisableWeapon;
extern const idEventDef EV_Player_ExitTeleporter;
extern const idEventDef EV_Player_SelectWeapon;
extern const idEventDef EV_SpectatorTouch;
const float THIRD_PERSON_FOCUS_DISTANCE = 512.0f;
const int LAND_DEFLECT_TIME = 150;
const int LAND_RETURN_TIME = 300;
const int FOCUS_TIME = 300;
const int FOCUS_GUI_TIME = 500;
const int NUM_QUICK_SLOTS = 4;
const int MAX_WEAPONS = 32;
const int DEAD_HEARTRATE = 0; // fall to as you die
const int LOWHEALTH_HEARTRATE_ADJ = 20; //
const int DYING_HEARTRATE = 30; // used for volumen calc when dying/dead
const int BASE_HEARTRATE = 70; // default
const int ZEROSTAMINA_HEARTRATE = 115; // no stamina
const int MAX_HEARTRATE = 130; // maximum
const int ZERO_VOLUME = -40; // volume at zero
const int DMG_VOLUME = 5; // volume when taking damage
const int DEATH_VOLUME = 15; // volume at death
const int SAVING_THROW_TIME = 5000; // maximum one "saving throw" every five seconds
const int ASYNC_PLAYER_INV_AMMO_BITS = idMath::BitsForInteger( 3000 );
const int ASYNC_PLAYER_INV_CLIP_BITS = -7; // -7 bits to cover the range [-1, 60]
enum gameExpansionType_t {
GAME_BASE,
GAME_D3XP,
GAME_D3LE,
GAME_UNKNOWN
};
struct idObjectiveInfo {
idStr title;
idStr text;
const idMaterial * screenshot;
};
struct idLevelTriggerInfo {
idStr levelName;
idStr triggerName;
};
// powerups - the "type" in item .def must match
enum {
BERSERK = 0,
INVISIBILITY,
MEGAHEALTH,
ADRENALINE,
INVULNERABILITY,
HELLTIME,
ENVIROSUIT,
//HASTE,
ENVIROTIME,
MAX_POWERUPS
};
// powerup modifiers
enum {
SPEED = 0,
PROJECTILE_DAMAGE,
MELEE_DAMAGE,
MELEE_DISTANCE
};
// influence levels
enum {
INFLUENCE_NONE = 0, // none
INFLUENCE_LEVEL1, // no gun or hud
INFLUENCE_LEVEL2, // no gun, hud, movement
INFLUENCE_LEVEL3, // slow player movement
};
typedef struct {
int ammo;
int rechargeTime;
char ammoName[128];
} RechargeAmmo_t;
typedef struct {
char name[64];
idList<int, TAG_IDLIB_LIST_PLAYER> toggleList;
int lastUsed;
} WeaponToggle_t;
class idInventory {
public:
int maxHealth;
int weapons;
int powerups;
int armor;
int maxarmor;
int powerupEndTime[ MAX_POWERUPS ];
RechargeAmmo_t rechargeAmmo[ AMMO_NUMTYPES ];
// mp
int ammoPredictTime; // Unused now but kept for save file compatibility.
int deplete_armor;
float deplete_rate;
int deplete_ammount;
int nextArmorDepleteTime;
int pdasViewed[4]; // 128 bit flags for indicating if a pda has been viewed
int selPDA;
int selEMail;
int selVideo;
int selAudio;
bool pdaOpened;
idList<idDict *> items;
idList<idStr> pdaSecurity;
idList<const idDeclPDA *> pdas;
idList<const idDeclVideo *> videos;
idList<const idDeclEmail *> emails;
bool ammoPulse;
bool weaponPulse;
bool armorPulse;
int lastGiveTime;
idList<idLevelTriggerInfo, TAG_IDLIB_LIST_PLAYER> levelTriggers;
idInventory() { Clear(); }
~idInventory() { Clear(); }
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Clear();
void GivePowerUp( idPlayer *player, int powerup, int msec );
void ClearPowerUps();
void GetPersistantData( idDict &dict );
void RestoreInventory( idPlayer *owner, const idDict &dict );
bool Give( idPlayer *owner, const idDict &spawnArgs, const char *statname, const char *value,
idPredictedValue< int > * idealWeapon, bool updateHud, unsigned int giveFlags );
void Drop( const idDict &spawnArgs, const char *weapon_classname, int weapon_index );
ammo_t AmmoIndexForAmmoClass( const char *ammo_classname ) const;
int MaxAmmoForAmmoClass( const idPlayer *owner, const char *ammo_classname ) const;
int WeaponIndexForAmmoClass( const idDict & spawnArgs, const char *ammo_classname ) const;
ammo_t AmmoIndexForWeaponClass( const char *weapon_classname, int *ammoRequired );
const char * AmmoPickupNameForIndex( ammo_t ammonum ) const;
void AddPickupName( const char * name, idPlayer * owner ); //_D3XP
int HasAmmo( ammo_t type, int amount );
bool UseAmmo( ammo_t type, int amount );
int HasAmmo( const char *weapon_classname, bool includeClip = false, idPlayer* owner = NULL ); // _D3XP
bool HasEmptyClipCannotRefill(const char *weapon_classname, idPlayer* owner);
void UpdateArmor();
void SetInventoryAmmoForType( const int ammoType, const int amount );
void SetClipAmmoForWeapon( const int weapon, const int amount );
int GetInventoryAmmoForType( const int ammoType ) const;
int GetClipAmmoForWeapon( const int weapon ) const;
void WriteAmmoToSnapshot( idBitMsg & msg ) const;
void ReadAmmoFromSnapshot( const idBitMsg & msg, int ownerEntityNumber );
void SetRemoteClientAmmo( const int ownerEntityNumber );
int nextItemPickup;
int nextItemNum;
int onePickupTime;
idList<idStr> pickupItemNames;
idList<idObjectiveInfo> objectiveNames;
void InitRechargeAmmo(idPlayer *owner);
void RechargeAmmo(idPlayer *owner);
bool CanGive( idPlayer *owner, const idDict &spawnArgs, const char *statname, const char *value );
private:
idArray< idPredictedValue< int >, AMMO_NUMTYPES > ammo;
idArray< idPredictedValue< int >, MAX_WEAPONS > clip;
};
typedef struct {
int time;
idVec3 dir; // scaled larger for running
} loggedAccel_t;
typedef struct {
int areaNum;
idVec3 pos;
} aasLocation_t;
class idPlayer : public idActor {
public:
enum {
EVENT_IMPULSE = idEntity::EVENT_MAXEVENTS,
EVENT_EXIT_TELEPORTER,
EVENT_ABORT_TELEPORTER,
EVENT_POWERUP,
EVENT_SPECTATE,
EVENT_PICKUPNAME,
EVENT_FORCE_ORIGIN,
EVENT_KNOCKBACK,
EVENT_MAXEVENTS
};
static const int MAX_PLAYER_PDA = 100;
static const int MAX_PLAYER_VIDEO = 100;
static const int MAX_PLAYER_AUDIO = 100;
static const int MAX_PLAYER_AUDIO_ENTRIES = 2;
usercmd_t oldCmd;
usercmd_t usercmd;
class idPlayerView playerView; // handles damage kicks and effects
renderEntity_t laserSightRenderEntity; // replace crosshair for 3DTV
qhandle_t laserSightHandle;
bool noclip;
bool godmode;
bool spawnAnglesSet; // on first usercmd, we must set deltaAngles
idAngles spawnAngles;
idAngles viewAngles; // player view angles
idAngles cmdAngles; // player cmd angles
float independentWeaponPitchAngle; // viewAngles[PITCH} when head tracking is active
// For interpolating angles between snapshots
idQuat previousViewQuat;
idQuat nextViewQuat;
int buttonMask;
int oldButtons;
int oldImpulseSequence;
int lastHitTime; // last time projectile fired by player hit target
int lastSndHitTime; // MP hit sound - != lastHitTime because we throttle
int lastSavingThrowTime; // for the "free miss" effect
bool pdaHasBeenRead[ MAX_PLAYER_PDA ];
bool videoHasBeenViewed[ MAX_PLAYER_VIDEO ];
bool audioHasBeenHeard[ MAX_PLAYER_AUDIO ][ MAX_PLAYER_AUDIO_ENTRIES ];
idScriptBool AI_FORWARD;
idScriptBool AI_BACKWARD;
idScriptBool AI_STRAFE_LEFT;
idScriptBool AI_STRAFE_RIGHT;
idScriptBool AI_ATTACK_HELD;
idScriptBool AI_WEAPON_FIRED;
idScriptBool AI_JUMP;
idScriptBool AI_CROUCH;
idScriptBool AI_ONGROUND;
idScriptBool AI_ONLADDER;
idScriptBool AI_DEAD;
idScriptBool AI_RUN;
idScriptBool AI_PAIN;
idScriptBool AI_HARDLANDING;
idScriptBool AI_SOFTLANDING;
idScriptBool AI_RELOAD;
idScriptBool AI_TELEPORT;
idScriptBool AI_TURN_LEFT;
idScriptBool AI_TURN_RIGHT;
// inventory
idInventory inventory;
idTarget_SetPrimaryObjective * primaryObjective;
int flashlightBattery;
idEntityPtr<idWeapon> flashlight;
idEntityPtr<idWeapon> weapon;
idMenuHandler_HUD * hudManager;
idMenuScreen_HUD * hud;
idMenuHandler_PDA * pdaMenu;
idSWF * mpMessages;
bool objectiveSystemOpen;
int quickSlot[ NUM_QUICK_SLOTS ];
int weapon_soulcube;
int weapon_pda;
int weapon_fists;
int weapon_flashlight;
int weapon_chainsaw;
int weapon_bloodstone;
int weapon_bloodstone_active1;
int weapon_bloodstone_active2;
int weapon_bloodstone_active3;
bool harvest_lock;
int heartRate;
idInterpolate<float> heartInfo;
int lastHeartAdjust;
int lastHeartBeat;
int lastDmgTime;
int deathClearContentsTime;
bool doingDeathSkin;
int lastArmorPulse; // lastDmgTime if we had armor at time of hit
float stamina;
float healthPool; // amount of health to give over time
int nextHealthPulse;
bool healthPulse;
bool healthTake;
int nextHealthTake;
//-----------------------------------------------------------------
// controller shake parms
//-----------------------------------------------------------------
const static int MAX_SHAKE_BUFFER = 3;
float controllerShakeHighMag[ MAX_SHAKE_BUFFER ]; // magnitude of the high frequency controller shake
float controllerShakeLowMag[ MAX_SHAKE_BUFFER ]; // magnitude of the low frequency controller shake
int controllerShakeHighTime[ MAX_SHAKE_BUFFER ]; // time the controller shake ends for high frequency.
int controllerShakeLowTime[ MAX_SHAKE_BUFFER ]; // time the controller shake ends for low frequency.
int controllerShakeTimeGroup;
bool hiddenWeapon; // if the weapon is hidden ( in noWeapons maps )
idEntityPtr<idProjectile> soulCubeProjectile;
idAimAssist aimAssist;
int spectator;
bool forceScoreBoard;
bool forceRespawn;
bool spectating;
int lastSpectateTeleport;
bool lastHitToggle;
bool wantSpectate; // from userInfo
bool weaponGone; // force stop firing
bool useInitialSpawns; // toggled by a map restart to be active for the first game spawn
int tourneyRank; // for tourney cycling - the higher, the more likely to play next - server
int tourneyLine; // client side - our spot in the wait line. 0 means no info.
int spawnedTime; // when client first enters the game
bool carryingFlag; // is the player carrying the flag?
idEntityPtr<idEntity> teleportEntity; // while being teleported, this is set to the entity we'll use for exit
int teleportKiller; // entity number of an entity killing us at teleporter exit
bool lastManOver; // can't respawn in last man anymore (srv only)
bool lastManPlayAgain; // play again when end game delay is cancelled out before expiring (srv only)
bool lastManPresent; // true when player was in when game started (spectators can't join a running LMS)
bool isLagged; // replicated from server, true if packets haven't been received from client.
int isChatting; // replicated from server, true if the player is chatting.
// timers
int minRespawnTime; // can respawn when time > this, force after g_forcerespawn
int maxRespawnTime; // force respawn after this time
// the first person view values are always calculated, even
// if a third person view is used
idVec3 firstPersonViewOrigin;
idMat3 firstPersonViewAxis;
idDragEntity dragEntity;
idFuncMountedObject * mountedObject;
idEntityPtr<idLight> enviroSuitLight;
bool healthRecharge;
int lastHealthRechargeTime;
int rechargeSpeed;
float new_g_damageScale;
bool bloomEnabled;
float bloomSpeed;
float bloomIntensity;
public:
CLASS_PROTOTYPE( idPlayer );
idPlayer();
virtual ~idPlayer();
void Spawn();
void Think();
void UpdateLaserSight();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
virtual void Hide();
virtual void Show();
void Init();
void PrepareForRestart();
virtual void Restart();
void LinkScriptVariables();
void SetupWeaponEntity();
void SelectInitialSpawnPoint( idVec3 &origin, idAngles &angles );
void SpawnFromSpawnSpot();
void SpawnToPoint( const idVec3 &spawn_origin, const idAngles &spawn_angles );
void SetClipModel(); // spectator mode uses a different bbox size
void SavePersistantInfo();
void RestorePersistantInfo();
void SetLevelTrigger( const char *levelName, const char *triggerName );
void CacheWeapons();
void EnterCinematic();
void ExitCinematic();
void UpdateConditions();
void SetViewAngles( const idAngles &angles );
// Controller Shake
void ControllerShakeFromDamage( int damage );
void SetControllerShake( float highMagnitude, int highDuration, float lowMagnitude, int lowDuration );
void ResetControllerShake();
void GetControllerShake( int & highMagnitude, int & lowMagnitude ) const;
idAimAssist * GetAimAssist() { return &aimAssist; }
// delta view angles to allow movers to rotate the view of the player
void UpdateDeltaViewAngles( const idAngles &angles );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual void GetAASLocation( idAAS *aas, idVec3 &pos, int &areaNum ) const;
virtual void GetAIAimTargets( const idVec3 &lastSightPos, idVec3 &headPos, idVec3 &chestPos );
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
void CalcDamagePoints( idEntity *inflictor, idEntity *attacker, const idDict *damageDef,
const float damageScale, const int location, int *health, int *armor );
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
// New damage path for instant client feedback.
void ServerDealDamage( int damage, idEntity & inflictor, idEntity & attacker, const idVec3 & dir, const char * damageDefName, const int location ); // Actually updates the player's health independent of feedback.
int AdjustDamageAmount( const int inputDamage );
// use exitEntityNum to specify a teleport with private camera view and delayed exit
virtual void Teleport( const idVec3 &origin, const idAngles &angles, idEntity *destination );
void Kill( bool delayRespawn, bool nodamage );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void StartFxOnBone(const char *fx, const char *bone);
renderView_t * GetRenderView();
void CalculateRenderView(); // called every tic by player code
void CalculateFirstPersonView();
void AddChatMessage( int index, int alpha, const idStr & message );
void UpdateSpectatingText();
void ClearChatMessage( int index );
void DrawHUD( idMenuHandler_HUD * hudManager );
void WeaponFireFeedback( const idDict *weaponDef );
float DefaultFov() const;
float CalcFov( bool honorZoom );
void CalculateViewWeaponPos( idVec3 &origin, idMat3 &axis );
idVec3 GetEyePosition() const;
void GetViewPos( idVec3 &origin, idMat3 &axis ) const;
void OffsetThirdPersonView( float angle, float range, float height, bool clip );
bool Give( const char *statname, const char *value, unsigned int giveFlags );
bool GiveItem( idItem *item, unsigned int giveFlags );
void GiveItem( const char *name );
void GiveHealthPool( float amt );
void SetPrimaryObjective( idTarget_SetPrimaryObjective * target ) { primaryObjective = target; }
idTarget_SetPrimaryObjective * GetPrimaryObjective() { return primaryObjective; }
idInventory & GetInventory() { return inventory; }
bool GiveInventoryItem( idDict *item, unsigned int giveFlags );
void RemoveInventoryItem( idDict *item );
bool GiveInventoryItem( const char *name );
void RemoveInventoryItem( const char *name );
idDict * FindInventoryItem( const char *name );
idDict * FindInventoryItem( int index );
int GetNumInventoryItems();
void PlayAudioLog( const idSoundShader * sound );
void EndAudioLog();
void PlayVideoDisk( const idDeclVideo * decl );
void EndVideoDisk();
const idMaterial * GetVideoMaterial() { return pdaVideoMat; }
void SetQuickSlot( int index, int val );
int GetQuickSlot( int index );
void GivePDA( const idDeclPDA * pda, const char * securityItem );
void GiveVideo( const idDeclVideo * video, const char * itemName );
void GiveEmail( const idDeclEmail * email );
void GiveSecurity( const char * security );
void GiveObjective( const char * title, const char * text, const idMaterial * screenshot );
void CompleteObjective( const char * title );
bool GivePowerUp( int powerup, int time, unsigned int giveFlags );
void ClearPowerUps();
bool PowerUpActive( int powerup ) const;
float PowerUpModifier( int type );
int SlotForWeapon( const char *weaponName );
void Reload();
void NextWeapon();
void NextBestWeapon();
void PrevWeapon();
void SetPreviousWeapon( int num ) { previousWeapon = num; }
void SelectWeapon( int num, bool force );
void DropWeapon( bool died ) ;
void StealWeapon( idPlayer *player );
void AddProjectilesFired( int count );
void AddProjectileHits( int count );
void SetLastHitTime( int time );
void LowerWeapon();
void RaiseWeapon();
void WeaponLoweringCallback();
void WeaponRisingCallback();
void RemoveWeapon( const char *weap );
void RemoveAllButEssentialWeapons();
bool CanShowWeaponViewmodel() const;
void AddAIKill();
void SetSoulCubeProjectile( idProjectile *projectile );
void AdjustHeartRate( int target, float timeInSecs, float delay, bool force );
void SetCurrentHeartRate();
int GetBaseHeartRate();
void UpdateAir();
void UpdatePowerupHud();
virtual bool HandleSingleGuiCommand( idEntity *entityGui, idLexer *src );
bool GuiActive() { return focusGUIent != NULL; }
bool HandleGuiEvents( const sysEvent_t * ev );
void PerformImpulse( int impulse );
void Spectate( bool spectate, bool force = false );
void TogglePDA();
void RouteGuiMouse( idUserInterface *gui );
void UpdateHud();
const idDeclPDA * GetPDA() const;
bool GetPDAOpen() const { return objectiveSystemOpen; }
const idDeclVideo * GetVideo( int index );
void SetInfluenceFov( float fov );
void SetInfluenceView( const char *mtr, const char *skinname, float radius, idEntity *ent );
void SetInfluenceLevel( int level );
int GetInfluenceLevel() { return influenceActive; };
void SetPrivateCameraView( idCamera *camView );
idCamera * GetPrivateCameraView() const { return privateCameraView; }
void StartFxFov( float duration );
void UpdateHudWeapon( bool flashWeapon = true );
void UpdateChattingHud();
void UpdateHudStats( idMenuHandler_HUD * hudManager );
void Event_StopAudioLog();
bool IsSoundChannelPlaying( const s_channelType channel = SND_CHANNEL_ANY );
void ShowTip( const char *title, const char *tip, bool autoHide );
void HideTip();
bool IsTipVisible() { return tipUp; };
void HideObjective();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
void WritePlayerStateToSnapshot( idBitMsg &msg ) const;
void ReadPlayerStateFromSnapshot( const idBitMsg &msg );
virtual bool ServerReceiveEvent( int event, int time, const idBitMsg &msg );
virtual bool GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis );
virtual bool GetPhysicsToSoundTransform( idVec3 &origin, idMat3 &axis );
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
bool IsRespawning();
bool IsInTeleport();
int GetSkinIndex() const { return skinIndex; }
idEntity *GetInfluenceEntity() { return influenceEntity; };
const idMaterial *GetInfluenceMaterial() { return influenceMaterial; };
float GetInfluenceRadius() { return influenceRadius; };
// server side work for in/out of spectate. takes care of spawning it into the world as well
void ServerSpectate( bool spectate );
// for very specific usage. != GetPhysics()
idPhysics *GetPlayerPhysics();
void TeleportDeath( int killer );
void SetLeader( bool lead );
bool IsLeader();
void UpdateSkinSetup();
bool OnLadder() const;
virtual void UpdatePlayerIcons();
virtual void DrawPlayerIcons();
virtual void HidePlayerIcons();
bool NeedsIcon();
void StartHealthRecharge(int speed);
void StopHealthRecharge();
idStr GetCurrentWeapon();
int GetCurrentWeaponSlot() { return currentWeapon; }
int GetIdealWeapon() { return idealWeapon.Get(); }
idHashTable<WeaponToggle_t> GetWeaponToggles() const { return weaponToggles; }
bool CanGive( const char *statname, const char *value );
void StopHelltime( bool quick = true );
void PlayHelltimeStopSound();
void DropFlag(); // drop CTF item
void ReturnFlag();
virtual void FreeModelDef();
bool SelfSmooth();
void SetSelfSmooth( bool b );
const idAngles & GetViewBobAngles() { return viewBobAngles; }
const idVec3 & GetViewBob() { return viewBob; }
idAchievementManager & GetAchievementManager() { return achievementManager; }
const idAchievementManager & GetAchievementManager() const { return achievementManager; }
int GetPlayedTime() const { return playedTimeSecs; }
void HandleUserCmds( const usercmd_t & newcmd );
int GetClientFireCount() const { return clientFireCount; }
void IncrementFireCount() { ++clientFireCount; }
void ShowRespawnHudMessage();
void HideRespawnHudMessage();
bool IsLocallyControlled() const { return entityNumber == gameLocal.GetLocalClientNum(); }
gameExpansionType_t GetExpansionType() const;
void AddProjectileKills() { numProjectileKills++; }
int GetProjectileKills() const { return numProjectileKills; }
void ResetProjectileKills() { numProjectileKills = 0; }
private:
// Stats & achievements
idAchievementManager achievementManager;
int playedTimeSecs;
int playedTimeResidual;
jointHandle_t hipJoint;
jointHandle_t chestJoint;
jointHandle_t headJoint;
idPhysics_Player physicsObj; // player physics
idList<aasLocation_t, TAG_IDLIB_LIST_PLAYER> aasLocation; // for AI tracking the player
int bobFoot;
float bobFrac;
float bobfracsin;
int bobCycle; // for view bobbing and footstep generation
float xyspeed;
int stepUpTime;
float stepUpDelta;
float idealLegsYaw;
float legsYaw;
bool legsForward;
float oldViewYaw;
idAngles viewBobAngles;
idVec3 viewBob;
int landChange;
int landTime;
int currentWeapon;
idPredictedValue< int > idealWeapon;
int previousWeapon;
int weaponSwitchTime;
bool weaponEnabled;
int skinIndex;
const idDeclSkin * skin;
const idDeclSkin * powerUpSkin;
int numProjectilesFired; // number of projectiles fired
int numProjectileHits; // number of hits on mobs
int numProjectileKills; // number of kills with a projectile.
bool airless;
int airMsec; // set to pm_airMsec at start, drops in vacuum
int lastAirDamage;
bool gibDeath;
bool gibsLaunched;
idVec3 gibsDir;
idInterpolate<float> zoomFov;
idInterpolate<float> centerView;
bool fxFov;
float influenceFov;
int influenceActive; // level of influence.. 1 == no gun or hud .. 2 == 1 + no movement
idEntity * influenceEntity;
const idMaterial * influenceMaterial;
float influenceRadius;
const idDeclSkin * influenceSkin;
idCamera * privateCameraView;
static const int NUM_LOGGED_VIEW_ANGLES = 64; // for weapon turning angle offsets
idAngles loggedViewAngles[NUM_LOGGED_VIEW_ANGLES]; // [gameLocal.framenum&(LOGGED_VIEW_ANGLES-1)]
static const int NUM_LOGGED_ACCELS = 16; // for weapon turning angle offsets
loggedAccel_t loggedAccel[NUM_LOGGED_ACCELS]; // [currentLoggedAccel & (NUM_LOGGED_ACCELS-1)]
int currentLoggedAccel;
// if there is a focusGUIent, the attack button will be changed into mouse clicks
idEntity * focusGUIent;
idUserInterface * focusUI; // focusGUIent->renderEntity.gui, gui2, or gui3
idAI * focusCharacter;
int talkCursor; // show the state of the focusCharacter (0 == can't talk/dead, 1 == ready to talk, 2 == busy talking)
int focusTime;
idAFEntity_Vehicle * focusVehicle;
idUserInterface * cursor;
// full screen guis track mouse movements directly
int oldMouseX;
int oldMouseY;
const idMaterial * pdaVideoMat;
bool tipUp;
bool objectiveUp;
int lastDamageDef;
idVec3 lastDamageDir;
int lastDamageLocation;
int smoothedFrame;
bool smoothedOriginUpdated;
idVec3 smoothedOrigin;
idAngles smoothedAngles;
idHashTable<WeaponToggle_t> weaponToggles;
int hudPowerup;
int lastHudPowerup;
int hudPowerupDuration;
// mp
bool respawning; // set to true while in SpawnToPoint for telefrag checks
bool leader; // for sudden death situations
int lastSpectateChange;
int lastTeleFX;
bool weaponCatchup; // raise up the weapon silently ( state catchups )
int MPAim; // player num in aim
int lastMPAim;
int lastMPAimTime; // last time the aim changed
int MPAimFadeTime; // for GUI fade
bool MPAimHighlight;
bool isTelefragged; // proper obituaries
int serverOverridePositionTime;
int clientFireCount;
idPlayerIcon playerIcon;
bool selfSmooth;
netBoolEvent_t respawn_netEvent;
void LookAtKiller( idEntity *inflictor, idEntity *attacker );
void StopFiring();
void FireWeapon();
void Weapon_Combat();
void Weapon_NPC();
void Weapon_GUI();
void UpdateWeapon();
void UpdateFlashlight();
void FlashlightOn();
void FlashlightOff();
void UpdateSpectating();
void SpectateFreeFly( bool force ); // ignore the timeout to force when followed spec is no longer valid
void SpectateCycle();
idAngles GunTurningOffset();
idVec3 GunAcceleratingOffset();
void UseObjects();
void CrashLand( const idVec3 &oldOrigin, const idVec3 &oldVelocity );
void BobCycle( const idVec3 &pushVelocity );
void UpdateViewAngles();
void EvaluateControls();
void AdjustSpeed();
void AdjustBodyAngles();
void InitAASLocation();
void SetAASLocation();
void Move();
void Move_Interpolated( float fraction );
void RunPhysics_RemoteClientCorrection();
void UpdatePowerUps();
void UpdateDeathSkin( bool state_hitch );
void ClearPowerup( int i );
void SetSpectateOrigin();
bool AllowClientAuthPhysics();
virtual int GetPhysicsTimeStep() const;
void ClearFocus();
void UpdateFocus();
void UpdateLocation();
idUserInterface * ActiveGui();
// mp
void Respawn_Shared();
bool WeaponAvailable( const char* name );
void UseVehicle();
void Event_GetButtons();
void Event_GetMove();
void Event_GetViewAngles();
void Event_StopFxFov();
void Event_EnableWeapon();
void Event_DisableWeapon();
void Event_GetCurrentWeapon();
void Event_GetPreviousWeapon();
void Event_SelectWeapon( const char *weaponName );
void Event_GetWeaponEntity();
void Event_OpenPDA();
void Event_PDAAvailable();
void Event_InPDA();
void Event_ExitTeleporter();
void Event_HideTip();
void Event_LevelTrigger();
void Event_Gibbed();
void Event_ForceOrigin( idVec3 & origin, idAngles & angles );
void Event_GiveInventoryItem( const char* name );
void Event_RemoveInventoryItem( const char* name );
void Event_GetIdealWeapon();
void Event_WeaponAvailable( const char* name );
void Event_SetPowerupTime( int powerup, int time );
void Event_IsPowerupActive( int powerup );
void Event_StartWarp();
void Event_StopHelltime( int mode );
void Event_ToggleBloom( int on );
void Event_SetBloomParms( float speed, float intensity );
};
ID_INLINE bool idPlayer::IsRespawning() {
return respawning;
}
ID_INLINE idPhysics* idPlayer::GetPlayerPhysics() {
return &physicsObj;
}
ID_INLINE bool idPlayer::IsInTeleport() {
return ( teleportEntity.GetEntity() != NULL );
}
ID_INLINE void idPlayer::SetLeader( bool lead ) {
leader = lead;
}
ID_INLINE bool idPlayer::IsLeader() {
return leader;
}
ID_INLINE bool idPlayer::SelfSmooth() {
return selfSmooth;
}
ID_INLINE void idPlayer::SetSelfSmooth( bool b ) {
selfSmooth = b;
}
extern idCVar g_infiniteAmmo;
#endif /* !__GAME_PLAYER_H__ */

190
neo/d3xp/PlayerIcon.cpp Normal file
View File

@@ -0,0 +1,190 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#include "PlayerIcon.h"
static const char * iconKeys[ ICON_NONE ] = {
"mtr_icon_lag",
"mtr_icon_chat"
,"mtr_icon_redteam",
"mtr_icon_blueteam"
};
/*
===============
idPlayerIcon::idPlayerIcon
===============
*/
idPlayerIcon::idPlayerIcon() {
iconHandle = -1;
iconType = ICON_NONE;
}
/*
===============
idPlayerIcon::~idPlayerIcon
===============
*/
idPlayerIcon::~idPlayerIcon() {
FreeIcon();
}
/*
===============
idPlayerIcon::Draw
===============
*/
void idPlayerIcon::Draw( idPlayer *player, jointHandle_t joint ) {
idVec3 origin;
idMat3 axis;
if ( joint == INVALID_JOINT ) {
FreeIcon();
return;
}
player->GetJointWorldTransform( joint, gameLocal.time, origin, axis );
origin.z += 16.0f;
Draw( player, origin );
}
/*
===============
idPlayerIcon::Draw
===============
*/
void idPlayerIcon::Draw( idPlayer *player, const idVec3 &origin ) {
idPlayer *localPlayer = gameLocal.GetLocalPlayer();
if ( !localPlayer || !localPlayer->GetRenderView() ) {
FreeIcon();
return;
}
idMat3 axis = localPlayer->GetRenderView()->viewaxis;
if ( player->isLagged && !player->spectating ) {
// create the icon if necessary, or update if already created
if ( !CreateIcon( player, ICON_LAG, origin, axis ) ) {
UpdateIcon( player, origin, axis );
}
} else if ( g_CTFArrows.GetBool() && gameLocal.mpGame.IsGametypeFlagBased() && gameLocal.GetLocalPlayer() && player->team == gameLocal.GetLocalPlayer()->team && !player->IsHidden() && !player->AI_DEAD ) {
int icon = ICON_TEAM_RED + player->team;
if ( icon != ICON_TEAM_RED && icon != ICON_TEAM_BLUE )
return;
if ( !CreateIcon( player, ( playerIconType_t )icon, origin, axis ) ) {
UpdateIcon( player, origin, axis );
}
} else {
FreeIcon();
}
}
/*
===============
idPlayerIcon::FreeIcon
===============
*/
void idPlayerIcon::FreeIcon() {
if ( iconHandle != - 1 ) {
gameRenderWorld->FreeEntityDef( iconHandle );
iconHandle = -1;
}
iconType = ICON_NONE;
}
/*
===============
idPlayerIcon::CreateIcon
===============
*/
bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis ) {
assert( type < ICON_NONE );
const char *mtr = player->spawnArgs.GetString( iconKeys[ type ], "_default" );
return CreateIcon( player, type, mtr, origin, axis );
}
/*
===============
idPlayerIcon::CreateIcon
===============
*/
bool idPlayerIcon::CreateIcon( idPlayer *player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis ) {
assert( type != ICON_NONE );
if ( type == iconType ) {
return false;
}
FreeIcon();
memset( &renderEnt, 0, sizeof( renderEnt ) );
renderEnt.origin = origin;
renderEnt.axis = axis;
renderEnt.shaderParms[ SHADERPARM_RED ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_GREEN ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_BLUE ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_ALPHA ] = 1.0f;
renderEnt.shaderParms[ SHADERPARM_SPRITE_WIDTH ] = 16.0f;
renderEnt.shaderParms[ SHADERPARM_SPRITE_HEIGHT ] = 16.0f;
renderEnt.hModel = renderModelManager->FindModel( "_sprite" );
renderEnt.callback = NULL;
renderEnt.numJoints = 0;
renderEnt.joints = NULL;
renderEnt.customSkin = 0;
renderEnt.noShadow = true;
renderEnt.noSelfShadow = true;
renderEnt.customShader = declManager->FindMaterial( mtr );
renderEnt.referenceShader = 0;
renderEnt.bounds = renderEnt.hModel->Bounds( &renderEnt );
iconHandle = gameRenderWorld->AddEntityDef( &renderEnt );
iconType = type;
return true;
}
/*
===============
idPlayerIcon::UpdateIcon
===============
*/
void idPlayerIcon::UpdateIcon( idPlayer *player, const idVec3 &origin, const idMat3 &axis ) {
assert( iconHandle >= 0 );
renderEnt.origin = origin;
renderEnt.axis = axis;
gameRenderWorld->UpdateEntityDef( iconHandle, &renderEnt );
}

65
neo/d3xp/PlayerIcon.h Normal file
View File

@@ -0,0 +1,65 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __PLAYERICON_H__
#define __PLAYERICON_H__
typedef enum {
ICON_LAG,
ICON_CHAT,
ICON_TEAM_RED,
ICON_TEAM_BLUE,
ICON_NONE
} playerIconType_t;
class idPlayerIcon {
public:
public:
idPlayerIcon();
~idPlayerIcon();
void Draw( idPlayer *player, jointHandle_t joint );
void Draw( idPlayer *player, const idVec3 &origin );
public:
playerIconType_t iconType;
renderEntity_t renderEnt;
qhandle_t iconHandle;
public:
void FreeIcon();
bool CreateIcon( idPlayer* player, playerIconType_t type, const char *mtr, const idVec3 &origin, const idMat3 &axis );
bool CreateIcon( idPlayer* player, playerIconType_t type, const idVec3 &origin, const idMat3 &axis );
void UpdateIcon( idPlayer* player, const idVec3 &origin, const idMat3 &axis );
};
#endif /* !_PLAYERICON_H_ */

1749
neo/d3xp/PlayerView.cpp Normal file

File diff suppressed because it is too large Load Diff

417
neo/d3xp/PlayerView.h Normal file
View File

@@ -0,0 +1,417 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_PLAYERVIEW_H__
#define __GAME_PLAYERVIEW_H__
class idMenuHandler_HUD;
/*
===============================================================================
Player view.
===============================================================================
*/
// screenBlob_t are for the on-screen damage claw marks, etc
typedef struct {
const idMaterial * material;
float x, y, w, h;
float s1, t1, s2, t2;
int finishTime;
int startFadeTime;
float driftAmount;
} screenBlob_t;
#define MAX_SCREEN_BLOBS 8
class WarpPolygon_t {
public:
idVec4 outer1;
idVec4 outer2;
idVec4 center;
};
class Warp_t {
public:
int id;
bool active;
int startTime;
float initialRadius;
idVec3 worldOrigin;
idVec2 screenOrigin;
int durationMsec;
idList<WarpPolygon_t, TAG_IDLIB_LIST_PLAYER> polys;
};
class idPlayerView;
class FullscreenFXManager;
/*
==================
FxFader
==================
*/
class FxFader {
enum {
FX_STATE_OFF,
FX_STATE_RAMPUP,
FX_STATE_RAMPDOWN,
FX_STATE_ON
};
int time;
int state;
float alpha;
int msec;
public:
FxFader();
// primary functions
bool SetTriggerState( bool active );
virtual void Save( idSaveGame *savefile );
virtual void Restore( idRestoreGame *savefile );
// fader functions
void SetFadeTime( int t ) { msec = t; };
int GetFadeTime() { return msec; };
// misc functions
float GetAlpha() { return alpha; };
};
/*
==================
FullscreenFX
==================
*/
class FullscreenFX {
protected:
idStr name;
FxFader fader;
FullscreenFXManager *fxman;
public:
FullscreenFX() { fxman = NULL; };
virtual ~FullscreenFX() { };
virtual void Initialize() = 0;
virtual bool Active() = 0;
virtual void HighQuality() = 0;
virtual void LowQuality() { };
virtual void AccumPass( const renderView_t *view ) { };
virtual bool HasAccum() { return false; };
void SetName( idStr n ) { name = n; };
idStr GetName() { return name; };
void SetFXManager( FullscreenFXManager *fx ) { fxman = fx; };
bool SetTriggerState( bool state ) { return fader.SetTriggerState( state ); };
void SetFadeSpeed( int msec ) { fader.SetFadeTime( msec ); };
float GetFadeAlpha() { return fader.GetAlpha(); };
virtual void Save( idSaveGame *savefile );
virtual void Restore( idRestoreGame *savefile );
};
/*
==================
FullscreenFX_Helltime
==================
*/
class FullscreenFX_Helltime : public FullscreenFX {
const idMaterial * initMaterial;
const idMaterial * captureMaterials[3];
const idMaterial * drawMaterial;
bool clearAccumBuffer;
int DetermineLevel();
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
virtual void AccumPass( const renderView_t *view );
virtual bool HasAccum() { return true; };
virtual void Restore( idRestoreGame *savefile );
};
/*
==================
FullscreenFX_Multiplayer
==================
*/
class FullscreenFX_Multiplayer : public FullscreenFX {
const idMaterial * initMaterial;
const idMaterial * captureMaterial;
const idMaterial * drawMaterial;
bool clearAccumBuffer;
int DetermineLevel();
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
virtual void AccumPass( const renderView_t *view );
virtual bool HasAccum() { return true; };
virtual void Restore( idRestoreGame *savefile );
};
/*
==================
FullscreenFX_Warp
==================
*/
class FullscreenFX_Warp : public FullscreenFX {
const idMaterial* material;
bool grabberEnabled;
int startWarpTime;
void DrawWarp( WarpPolygon_t wp, float interp );
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
void EnableGrabber( bool active ) { grabberEnabled = active; startWarpTime = gameLocal.slow.time; };
virtual void Save( idSaveGame *savefile );
virtual void Restore( idRestoreGame *savefile );
};
/*
==================
FullscreenFX_EnviroSuit
==================
*/
class FullscreenFX_EnviroSuit : public FullscreenFX {
const idMaterial* material;
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
};
/*
==================
FullscreenFX_DoubleVision
==================
*/
class FullscreenFX_DoubleVision : public FullscreenFX {
const idMaterial* material;
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
};
/*
==================
FullscreenFX_InfluenceVision
==================
*/
class FullscreenFX_InfluenceVision : public FullscreenFX {
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
};
/*
==================
FullscreenFX_Bloom
==================
*/
class FullscreenFX_Bloom : public FullscreenFX {
const idMaterial* drawMaterial;
const idMaterial* initMaterial;
float currentIntensity;
float targetIntensity;
public:
virtual void Initialize();
virtual bool Active();
virtual void HighQuality();
virtual void Save( idSaveGame *savefile );
virtual void Restore( idRestoreGame *savefile );
};
/*
==================
FullscreenFXManager
==================
*/
class FullscreenFXManager {
idList<FullscreenFX*, TAG_FX> fx;
idPlayerView * playerView;
const idMaterial* blendBackMaterial;
void CreateFX( idStr name, idStr fxtype, int fade );
public:
FullscreenFXManager();
virtual ~FullscreenFXManager();
void Initialize( idPlayerView *pv );
void Process( const renderView_t *view );
void Blendback( float alpha );
idPlayerView* GetPlayerView() { return playerView; };
idPlayer* GetPlayer() { return gameLocal.GetLocalPlayer(); };
int GetNum() { return fx.Num(); };
FullscreenFX* GetFX( int index ) { return fx[index]; };
FullscreenFX* FindFX( idStr name );
void Save( idSaveGame *savefile );
void Restore( idRestoreGame *savefile );
};
class idPlayerView {
public:
idPlayerView();
~idPlayerView();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void SetPlayerEntity( class idPlayer *playerEnt );
void ClearEffects();
void DamageImpulse( idVec3 localKickDir, const idDict *damageDef );
void WeaponFireFeedback( const idDict *weaponDef );
idAngles AngleOffset() const; // returns the current kick angle
idMat3 ShakeAxis() const; // returns the current shake angle
void CalculateShake();
// this may involve rendering to a texture and displaying
// that with a warp model or in double vision mode
void RenderPlayerView( idMenuHandler_HUD * hudManager );
void EmitStereoEyeView( const int eye, idMenuHandler_HUD * hudManager );
void Fade( idVec4 color, int time );
void Flash( idVec4 color, int time );
// temp for view testing
void EnableBFGVision( bool b ) { bfgVision = b; };
private:
void SingleView( const renderView_t *view, idMenuHandler_HUD * hudManager );
void ScreenFade();
screenBlob_t * GetScreenBlob();
screenBlob_t screenBlobs[MAX_SCREEN_BLOBS];
public:
int dvFinishTime; // double vision will be stopped at this time
int kickFinishTime; // view kick will be stopped at this time
idAngles kickAngles;
bool bfgVision; //
const idMaterial * tunnelMaterial; // health tunnel vision
const idMaterial * armorMaterial; // armor damage view effect
const idMaterial * berserkMaterial; // berserk effect
const idMaterial * irGogglesMaterial; // ir effect
const idMaterial * bloodSprayMaterial; // blood spray
const idMaterial * bfgMaterial; // when targeted with BFG
float lastDamageTime; // accentuate the tunnel effect for a while
idVec4 fadeColor; // fade color
idVec4 fadeToColor; // color to fade to
idVec4 fadeFromColor; // color to fade from
float fadeRate; // fade rate
int fadeTime; // fade time
idAngles shakeAng; // from the sound sources
idPlayer * player;
renderView_t view;
FullscreenFXManager *fxManager;
public:
int AddWarp( idVec3 worldOrigin, float centerx, float centery, float initialRadius, float durationMsec );
void FreeWarp( int id );
};
// the crosshair is swapped for a laser sight in stereo rendering
bool IsGameStereoRendered();
#endif /* !__GAME_PLAYERVIEW_H__ */

78
neo/d3xp/PredictedValue.h Normal file
View File

@@ -0,0 +1,78 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 PREDICTED_VALUE_H_
#define PREDICTED_VALUE_H_
#include "Game_local.h"
/*
================================================
A simple class to handle simple predictable values
on multiplayer clients.
The class encapsulates the actual value to be stored
as well as the client frame number on which it is set.
When reading predicted values from a snapshot, the actual
value is only updated if the server has processed the client's
usercmd for the frame in which the client predicted the value.
Got that?
================================================
*/
template< class type_ >
class idPredictedValue {
public:
explicit idPredictedValue();
explicit idPredictedValue( const type_ & value_ );
void Set( const type_ & newValue );
idPredictedValue< type_ > & operator=( const type_ & value );
idPredictedValue< type_ > & operator+=( const type_ & toAdd );
idPredictedValue< type_ > & operator-=( const type_ & toSubtract );
bool UpdateFromSnapshot( const type_ & valueFromSnapshot, int clientNumber );
type_ Get() const { return value; }
private:
// Noncopyable
idPredictedValue( const idPredictedValue< type_ > & other );
idPredictedValue< type_ > & operator=( const idPredictedValue< type_ > & other );
type_ value;
int clientPredictedMilliseconds; // The time in which the client predicted the value.
void UpdatePredictionTime();
};
#endif

View File

@@ -0,0 +1,220 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 PREDICTED_VALUE_IMPL_H_
#define PREDICTED_VALUE_IMPL_H_
#include "PredictedValue.h"
#include "Player.h"
/*
===============
idPredictedValue::idPredictedValue
===============
*/
template< class type_ >
idPredictedValue< type_ >::idPredictedValue() :
value(),
clientPredictedMilliseconds( 0 ) {
}
/*
===============
idPredictedValue::idPredictedValue
===============
*/
template< class type_ >
idPredictedValue< type_ >::idPredictedValue( const type_ & value_ ) :
value( value_ ),
clientPredictedMilliseconds( 0 ) {
}
/*
===============
idPredictedValue::UpdatePredictionTime
===============
*/
template< class type_ >
void idPredictedValue< type_ >::UpdatePredictionTime() {
if ( gameLocal.GetLocalPlayer() != NULL ) {
clientPredictedMilliseconds = gameLocal.GetLocalPlayer()->usercmd.clientGameMilliseconds;
}
}
/*
===============
idPredictedValue::Set
===============
*/
template< class type_ >
void idPredictedValue< type_ >::Set( const type_ & newValue ) {
value = newValue;
UpdatePredictionTime();
}
/*
===============
idPredictedValue::operator=
===============
*/
template< class type_ >
idPredictedValue< type_ > & idPredictedValue< type_ >::operator=( const type_ & newValue ) {
Set( newValue );
return *this;
}
/*
===============
idPredictedValue::operator+=
===============
*/
template< class type_ >
idPredictedValue< type_ > & idPredictedValue< type_ >::operator+=( const type_ & toAdd ) {
Set( value + toAdd );
return *this;
}
/*
===============
idPredictedValue::operator-=
===============
*/
template< class type_ >
idPredictedValue< type_ > & idPredictedValue< type_ >::operator-=( const type_ & toSubtract ) {
Set( value - toSubtract );
return *this;
}
/*
===============
idPredictedValue::UpdateFromSnapshot
Always updates the value for remote clients.
Only updates the actual value if the snapshot usercmd frame is newer than the one in which
the client predicted this value.
Returns true if the value was set, false if not.
===============
*/
template< class type_ >
bool idPredictedValue< type_ >::UpdateFromSnapshot( const type_ & valueFromSnapshot, int clientNumber ) {
if ( clientNumber != gameLocal.GetLocalClientNum() ) {
value = valueFromSnapshot;
return true;
}
if ( gameLocal.GetLastClientUsercmdMilliseconds( clientNumber ) >= clientPredictedMilliseconds ) {
value = valueFromSnapshot;
return true;
}
return false;
}
/*
===============
operator==
Overload for idPredictedValue.
We only care if the values are equal, not the frame number.
===============
*/
template< class firstType_, class secondType_ >
bool operator==( const idPredictedValue< firstType_ > & lhs, const idPredictedValue< secondType_ > & rhs ) {
return lhs.Get() == rhs.Get();
}
/*
===============
operator!=
Overload for idPredictedValue.
We only care if the values are equal, not the frame number.
===============
*/
template< class firstType_, class secondType_ >
bool operator!=( const idPredictedValue< firstType_ > & lhs, const idPredictedValue< secondType_ > & rhs ) {
return lhs.Get() != rhs.Get();
}
/*
===============
operator==
Overload for idPredictedValue.
We only care if the values are equal, not the frame number.
===============
*/
template< class firstType_, class secondType_ >
bool operator==( const idPredictedValue< firstType_ > & lhs, const secondType_ & rhs ) {
return lhs.Get() == rhs;
}
/*
===============
operator==
Overload for idPredictedValue.
We only care if the values are equal, not the frame number.
===============
*/
template< class firstType_, class secondType_ >
bool operator==( const firstType_ lhs, const idPredictedValue< secondType_ > & rhs ) {
return lhs == rhs.Get();
}
/*
===============
operator!=
Overload for idPredictedValue.
We only care if the values are equal, not the frame number.
===============
*/
template< class firstType_, class secondType_ >
bool operator!=( const idPredictedValue< firstType_ > & lhs, const secondType_ & rhs ) {
return lhs.Get() != rhs;
}
/*
===============
operator!=
Overload for idPredictedValue.
We only care if the values are equal, not the frame number.
===============
*/
template< class firstType_, class secondType_ >
bool operator!=( const firstType_ lhs, const idPredictedValue< secondType_ > & rhs ) {
return lhs != rhs.Get();
}
#endif

2989
neo/d3xp/Projectile.cpp Normal file

File diff suppressed because it is too large Load Diff

339
neo/d3xp/Projectile.h Normal file
View File

@@ -0,0 +1,339 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_PROJECTILE_H__
#define __GAME_PROJECTILE_H__
/*
===============================================================================
idProjectile
===============================================================================
*/
extern const idEventDef EV_Explode;
class idProjectile : public idEntity {
public :
CLASS_PROTOTYPE( idProjectile );
idProjectile();
virtual ~idProjectile();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Create( idEntity *owner, const idVec3 &start, const idVec3 &dir );
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
virtual void FreeLightDef();
idEntity * GetOwner() const;
void CatchProjectile( idEntity* o, const char* reflectName );
int GetProjectileState();
void Event_CreateProjectile( idEntity *owner, const idVec3 &start, const idVec3 &dir );
void Event_LaunchProjectile( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity );
void Event_SetGravity( float gravity );
virtual void Think();
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
virtual void Explode( const trace_t &collision, idEntity *ignore );
void Fizzle();
static idVec3 GetVelocity( const idDict *projectile );
static idVec3 GetGravity( const idDict *projectile );
enum {
EVENT_DAMAGE_EFFECT = idEntity::EVENT_MAXEVENTS,
EVENT_MAXEVENTS
};
void SetLaunchedFromGrabber( bool bl ) { launchedFromGrabber = bl; }
bool GetLaunchedFromGrabber() { return launchedFromGrabber; }
static void DefaultDamageEffect( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity );
static bool ClientPredictionCollide( idEntity *soundEnt, const idDict &projectileDef, const trace_t &collision, const idVec3 &velocity, bool addDamageEffect );
virtual void ClientPredictionThink();
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 bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
void QueueToSimulate( int startTime );
virtual void SimulateProjectileFrame( int msec, int endTime );
virtual void PostSimulate( int endTime );
struct simulatedProjectile_t {
simulatedProjectile_t(): projectile( NULL ), startTime( 0 ) {}
idProjectile* projectile;
int startTime;
};
static const int MAX_SIMULATED_PROJECTILES = 64;
// This list is used to "catch up" client projectiles to the current time on the server
static idArray< simulatedProjectile_t, MAX_SIMULATED_PROJECTILES > projectilesToSimulate;
protected:
idEntityPtr<idEntity> owner;
struct projectileFlags_s {
bool detonate_on_world : 1;
bool detonate_on_actor : 1;
bool randomShaderSpin : 1;
bool isTracer : 1;
bool noSplashDamage : 1;
} projectileFlags;
bool launchedFromGrabber;
float thrust;
int thrust_end;
float damagePower;
renderLight_t renderLight;
qhandle_t lightDefHandle; // handle to renderer light def
idVec3 lightOffset;
int lightStartTime;
int lightEndTime;
idVec3 lightColor;
idForce_Constant thruster;
idPhysics_RigidBody physicsObj;
const idDeclParticle * smokeFly;
int smokeFlyTime;
bool mNoExplodeDisappear;
bool mTouchTriggers;
int originalTimeGroup;
typedef enum {
// must update these in script/doom_defs.script if changed
SPAWNED = 0,
CREATED = 1,
LAUNCHED = 2,
FIZZLED = 3,
EXPLODED = 4
} projectileState_t;
projectileState_t state;
private:
idVec3 launchOrigin;
idMat3 launchAxis;
void AddDefaultDamageEffect( const trace_t &collision, const idVec3 &velocity );
void AddParticlesAndLight();
void Event_Explode();
void Event_Fizzle();
void Event_RadiusDamage( idEntity *ignore );
void Event_Touch( idEntity *other, trace_t *trace );
void Event_GetProjectileState();
};
class idGuidedProjectile : public idProjectile {
public :
CLASS_PROTOTYPE( idGuidedProjectile );
idGuidedProjectile();
~idGuidedProjectile();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Think();
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
void SetEnemy( idEntity *ent );
void Event_SetEnemy(idEntity *ent);
protected:
float speed;
idEntityPtr<idEntity> enemy;
virtual void GetSeekPos( idVec3 &out );
private:
idAngles rndScale;
idAngles rndAng;
idAngles angles;
int rndUpdateTime;
float turn_max;
float clamp_dist;
bool burstMode;
bool unGuided;
float burstDist;
float burstVelocity;
};
class idSoulCubeMissile : public idGuidedProjectile {
public:
CLASS_PROTOTYPE ( idSoulCubeMissile );
~idSoulCubeMissile();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Think();
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float power = 1.0f, const float dmgPower = 1.0f );
protected:
virtual void GetSeekPos( idVec3 &out );
void ReturnToOwner();
void KillTarget( const idVec3 &dir );
private:
idVec3 startingVelocity;
idVec3 endingVelocity;
float accelTime;
int launchTime;
bool killPhase;
bool returnPhase;
idVec3 destOrg;
idVec3 orbitOrg;
int orbitTime;
int smokeKillTime;
const idDeclParticle * smokeKill;
};
struct beamTarget_t {
idEntityPtr<idEntity> target;
renderEntity_t renderEntity;
qhandle_t modelDefHandle;
};
class idBFGProjectile : public idProjectile {
public :
CLASS_PROTOTYPE( idBFGProjectile );
idBFGProjectile();
~idBFGProjectile();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Think();
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
virtual void Explode( const trace_t &collision, idEntity *ignore );
private:
idList<beamTarget_t, TAG_PROJECTILE> beamTargets;
renderEntity_t secondModel;
qhandle_t secondModelDefHandle;
int nextDamageTime;
idStr damageFreq;
void FreeBeams();
void Event_RemoveBeams();
void ApplyDamage();
};
class idHomingProjectile : public idProjectile {
public :
CLASS_PROTOTYPE( idHomingProjectile );
idHomingProjectile();
~idHomingProjectile();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Think();
virtual void Launch( const idVec3 &start, const idVec3 &dir, const idVec3 &pushVelocity, const float timeSinceFire = 0.0f, const float launchPower = 1.0f, const float dmgPower = 1.0f );
void SetEnemy( idEntity *ent );
void SetSeekPos( idVec3 pos );
void Event_SetEnemy(idEntity *ent);
protected:
float speed;
idEntityPtr<idEntity> enemy;
idVec3 seekPos;
private:
idAngles rndScale;
idAngles rndAng;
idAngles angles;
float turn_max;
float clamp_dist;
bool burstMode;
bool unGuided;
float burstDist;
float burstVelocity;
};
/*
===============================================================================
idDebris
===============================================================================
*/
class idDebris : public idEntity {
public :
CLASS_PROTOTYPE( idDebris );
idDebris();
~idDebris();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void Spawn();
void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis );
void Launch();
void Think();
void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
void Explode();
void Fizzle();
virtual bool Collide( const trace_t &collision, const idVec3 &velocity );
private:
idEntityPtr<idEntity> owner;
idPhysics_RigidBody physicsObj;
const idDeclParticle * smokeFly;
int smokeFlyTime;
const idSoundShader * sndBounce;
void Event_Explode();
void Event_Fizzle();
};
#endif /* !__GAME_PROJECTILE_H__ */

1421
neo/d3xp/Pvs.cpp Normal file

File diff suppressed because it is too large Load Diff

126
neo/d3xp/Pvs.h Normal file
View File

@@ -0,0 +1,126 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_PVS_H__
#define __GAME_PVS_H__
/*
===================================================================================
PVS
Note: mirrors and other special view portals are not taken into account
===================================================================================
*/
typedef struct pvsHandle_s {
int i; // index to current pvs
unsigned int h; // handle for current pvs
} pvsHandle_t;
typedef struct pvsCurrent_s {
pvsHandle_t handle; // current pvs handle
byte * pvs; // current pvs bit string
} pvsCurrent_t;
#define MAX_CURRENT_PVS 64 // must be a power of 2
typedef enum {
PVS_NORMAL = 0, // PVS through portals taking portal states into account
PVS_ALL_PORTALS_OPEN = 1, // PVS through portals assuming all portals are open
PVS_CONNECTED_AREAS = 2 // PVS considering all topologically connected areas visible
} pvsType_t;
class idPVS {
public:
idPVS();
~idPVS();
// setup for the current map
void Init();
void Shutdown();
// get the area(s) the source is in
int GetPVSArea( const idVec3 &point ) const; // returns the area number
int GetPVSAreas( const idBounds &bounds, int *areas, int maxAreas ) const; // returns number of areas
// setup current PVS for the source
pvsHandle_t SetupCurrentPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const;
pvsHandle_t SetupCurrentPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const;
pvsHandle_t SetupCurrentPVS( const int sourceArea, const pvsType_t type = PVS_NORMAL ) const;
pvsHandle_t SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type = PVS_NORMAL ) const;
pvsHandle_t MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const;
void FreeCurrentPVS( pvsHandle_t handle ) const;
// returns true if the target is within the current PVS
bool InCurrentPVS( const pvsHandle_t handle, const idVec3 &target ) const;
bool InCurrentPVS( const pvsHandle_t handle, const idBounds &target ) const;
bool InCurrentPVS( const pvsHandle_t handle, const int targetArea ) const;
bool InCurrentPVS( const pvsHandle_t handle, const int *targetAreas, int numTargetAreas ) const;
// draw all portals that are within the PVS of the source
void DrawPVS( const idVec3 &source, const pvsType_t type = PVS_NORMAL ) const;
void DrawPVS( const idBounds &source, const pvsType_t type = PVS_NORMAL ) const;
// visualize the PVS the handle points to
void DrawCurrentPVS( const pvsHandle_t handle, const idVec3 &source ) const;
bool CheckAreasForPortalSky( const pvsHandle_t handle, const idVec3 &origin );
private:
int numAreas;
int numPortals;
bool * connectedAreas;
int * areaQueue;
byte * areaPVS;
// current PVS for a specific source possibly taking portal states (open/closed) into account
mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS];
// used to create PVS
int portalVisBytes;
int portalVisLongs;
int areaVisBytes;
int areaVisLongs;
struct pvsPortal_s *pvsPortals;
struct pvsArea_s * pvsAreas;
private:
int GetPortalCount() const;
void CreatePVSData();
void DestroyPVSData();
void CopyPortalPVSToMightSee() const;
void FloodFrontPortalPVS_r( struct pvsPortal_s *portal, int areaNum ) const;
void FrontPortalPVS() const;
struct pvsStack_s * FloodPassagePVS_r( struct pvsPortal_s *source, const struct pvsPortal_s *portal, struct pvsStack_s *prevStack ) const;
void PassagePVS() const;
void AddPassageBoundaries( const idWinding &source, const idWinding &pass, bool flipClip, idPlane *bounds, int &numBounds, int maxBounds ) const;
void CreatePassages() const;
void DestroyPassages() const;
int AreaPVSFromPortalPVS() const;
void GetConnectedAreas( int srcArea, bool *connectedAreas ) const;
pvsHandle_t AllocCurrentPVS( unsigned int h ) const;
};
#endif /* !__GAME_PVS_H__ */

587
neo/d3xp/SecurityCamera.cpp Normal file
View File

@@ -0,0 +1,587 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/*
SecurityCamera.cpp
Security camera that triggers targets when player is in view
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/***********************************************************************
idSecurityCamera
***********************************************************************/
const idEventDef EV_SecurityCam_ReverseSweep( "<reverseSweep>" );
const idEventDef EV_SecurityCam_ContinueSweep( "<continueSweep>" );
const idEventDef EV_SecurityCam_Pause( "<pause>" );
const idEventDef EV_SecurityCam_Alert( "<alert>" );
const idEventDef EV_SecurityCam_AddLight( "<addLight>" );
CLASS_DECLARATION( idEntity, idSecurityCamera )
EVENT( EV_SecurityCam_ReverseSweep, idSecurityCamera::Event_ReverseSweep )
EVENT( EV_SecurityCam_ContinueSweep, idSecurityCamera::Event_ContinueSweep )
EVENT( EV_SecurityCam_Pause, idSecurityCamera::Event_Pause )
EVENT( EV_SecurityCam_Alert, idSecurityCamera::Event_Alert )
EVENT( EV_SecurityCam_AddLight, idSecurityCamera::Event_AddLight )
END_CLASS
/*
================
idSecurityCamera::Save
================
*/
void idSecurityCamera::Save( idSaveGame *savefile ) const {
savefile->WriteFloat( angle );
savefile->WriteFloat( sweepAngle );
savefile->WriteInt( modelAxis );
savefile->WriteBool( flipAxis );
savefile->WriteFloat( scanDist );
savefile->WriteFloat( scanFov );
savefile->WriteFloat( sweepStart );
savefile->WriteFloat( sweepEnd );
savefile->WriteBool( negativeSweep );
savefile->WriteBool( sweeping );
savefile->WriteInt( alertMode );
savefile->WriteFloat( stopSweeping );
savefile->WriteFloat( scanFovCos );
savefile->WriteVec3( viewOffset );
savefile->WriteInt( pvsArea );
savefile->WriteStaticObject( physicsObj );
savefile->WriteTraceModel( trm );
}
/*
================
idSecurityCamera::Restore
================
*/
void idSecurityCamera::Restore( idRestoreGame *savefile ) {
savefile->ReadFloat( angle );
savefile->ReadFloat( sweepAngle );
savefile->ReadInt( modelAxis );
savefile->ReadBool( flipAxis );
savefile->ReadFloat( scanDist );
savefile->ReadFloat( scanFov );
savefile->ReadFloat( sweepStart );
savefile->ReadFloat( sweepEnd );
savefile->ReadBool( negativeSweep );
savefile->ReadBool( sweeping );
savefile->ReadInt( alertMode );
savefile->ReadFloat( stopSweeping );
savefile->ReadFloat( scanFovCos );
savefile->ReadVec3( viewOffset );
savefile->ReadInt( pvsArea );
savefile->ReadStaticObject( physicsObj );
savefile->ReadTraceModel( trm );
}
/*
================
idSecurityCamera::Spawn
================
*/
void idSecurityCamera::Spawn() {
idStr str;
sweepAngle = spawnArgs.GetFloat( "sweepAngle", "90" );
health = spawnArgs.GetInt( "health", "100" );
scanFov = spawnArgs.GetFloat( "scanFov", "90" );
scanDist = spawnArgs.GetFloat( "scanDist", "200" );
flipAxis = spawnArgs.GetBool( "flipAxis" );
modelAxis = spawnArgs.GetInt( "modelAxis" );
if ( modelAxis < 0 || modelAxis > 2 ) {
modelAxis = 0;
}
spawnArgs.GetVector( "viewOffset", "0 0 0", viewOffset );
if ( spawnArgs.GetBool( "spotLight" ) ) {
PostEventMS( &EV_SecurityCam_AddLight, 0 );
}
negativeSweep = ( sweepAngle < 0 ) ? true : false;
sweepAngle = abs( sweepAngle );
scanFovCos = cos( scanFov * idMath::PI / 360.0f );
angle = GetPhysics()->GetAxis().ToAngles().yaw;
StartSweep();
SetAlertMode( SCANNING );
BecomeActive( TH_THINK );
if ( health ) {
fl.takedamage = true;
}
pvsArea = gameLocal.pvs.GetPVSArea( GetPhysics()->GetOrigin() );
// if no target specified use ourself
str = spawnArgs.GetString( "cameraTarget" );
if ( str.Length() == 0 ) {
spawnArgs.Set( "cameraTarget", spawnArgs.GetString( "name" ) );
}
// check if a clip model is set
spawnArgs.GetString( "clipmodel", "", str );
if ( !str[0] ) {
str = spawnArgs.GetString( "model" ); // use the visual model
}
if ( !collisionModelManager->TrmFromModel( str, trm ) ) {
gameLocal.Error( "idSecurityCamera '%s': cannot load collision model %s", name.c_str(), str.c_str() );
return;
}
GetPhysics()->SetContents( CONTENTS_SOLID );
GetPhysics()->SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP );
// setup the physics
UpdateChangeableSpawnArgs( NULL );
}
/*
================
idSecurityCamera::Event_AddLight
================
*/
void idSecurityCamera::Event_AddLight() {
idDict args;
idVec3 right, up, target, temp;
idVec3 dir;
float radius;
idVec3 lightOffset;
idLight *spotLight;
dir = GetAxis();
dir.NormalVectors( right, up );
target = GetPhysics()->GetOrigin() + dir * scanDist;
radius = tan( scanFov * idMath::PI / 360.0f );
up = dir + up * radius;
up.Normalize();
up = GetPhysics()->GetOrigin() + up * scanDist;
up -= target;
right = dir + right * radius;
right.Normalize();
right = GetPhysics()->GetOrigin() + right * scanDist;
right -= target;
spawnArgs.GetVector( "lightOffset", "0 0 0", lightOffset );
args.Set( "origin", ( GetPhysics()->GetOrigin() + lightOffset ).ToString() );
args.Set( "light_target", target.ToString() );
args.Set( "light_right", right.ToString() );
args.Set( "light_up", up.ToString() );
args.SetFloat( "angle", GetPhysics()->GetAxis()[0].ToYaw() );
spotLight = static_cast<idLight *>( gameLocal.SpawnEntityType( idLight::Type, &args ) );
spotLight->Bind( this, true );
spotLight->UpdateVisuals();
}
/*
================
idSecurityCamera::DrawFov
================
*/
void idSecurityCamera::DrawFov() {
int i;
float radius, a, s, c, halfRadius;
idVec3 right, up;
idVec4 color(1, 0, 0, 1), color2(0, 0, 1, 1);
idVec3 lastPoint, point, lastHalfPoint, halfPoint, center;
idVec3 dir = GetAxis();
dir.NormalVectors( right, up );
radius = tan( scanFov * idMath::PI / 360.0f );
halfRadius = radius * 0.5f;
lastPoint = dir + up * radius;
lastPoint.Normalize();
lastPoint = GetPhysics()->GetOrigin() + lastPoint * scanDist;
lastHalfPoint = dir + up * halfRadius;
lastHalfPoint.Normalize();
lastHalfPoint = GetPhysics()->GetOrigin() + lastHalfPoint * scanDist;
center = GetPhysics()->GetOrigin() + dir * scanDist;
for ( i = 1; i < 12; i++ ) {
a = idMath::TWO_PI * i / 12.0f;
idMath::SinCos( a, s, c );
point = dir + right * s * radius + up * c * radius;
point.Normalize();
point = GetPhysics()->GetOrigin() + point * scanDist;
gameRenderWorld->DebugLine( color, lastPoint, point );
gameRenderWorld->DebugLine( color, GetPhysics()->GetOrigin(), point );
lastPoint = point;
halfPoint = dir + right * s * halfRadius + up * c * halfRadius;
halfPoint.Normalize();
halfPoint = GetPhysics()->GetOrigin() + halfPoint * scanDist;
gameRenderWorld->DebugLine( color2, point, halfPoint );
gameRenderWorld->DebugLine( color2, lastHalfPoint, halfPoint );
lastHalfPoint = halfPoint;
gameRenderWorld->DebugLine( color2, halfPoint, center );
}
}
/*
================
idSecurityCamera::GetRenderView
================
*/
renderView_t *idSecurityCamera::GetRenderView() {
renderView_t *rv = idEntity::GetRenderView();
rv->fov_x = scanFov;
rv->fov_y = scanFov;
rv->viewaxis = GetAxis().ToAngles().ToMat3();
rv->vieworg = GetPhysics()->GetOrigin() + viewOffset;
return rv;
}
/*
================
idSecurityCamera::CanSeePlayer
================
*/
bool idSecurityCamera::CanSeePlayer() {
int i;
float dist;
idPlayer *ent;
trace_t tr;
idVec3 dir;
pvsHandle_t handle;
handle = gameLocal.pvs.SetupCurrentPVS( pvsArea );
for ( i = 0; i < gameLocal.numClients; i++ ) {
ent = static_cast<idPlayer*>(gameLocal.entities[ i ]);
if ( !ent || ( ent->fl.notarget ) ) {
continue;
}
// if there is no way we can see this player
if ( !gameLocal.pvs.InCurrentPVS( handle, ent->GetPVSAreas(), ent->GetNumPVSAreas() ) ) {
continue;
}
dir = ent->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin();
dist = dir.Normalize();
if ( dist > scanDist ) {
continue;
}
if ( dir * GetAxis() < scanFovCos ) {
continue;
}
idVec3 eye;
eye = ent->EyeOffset();
gameLocal.clip.TracePoint( tr, GetPhysics()->GetOrigin(), ent->GetPhysics()->GetOrigin() + eye, MASK_OPAQUE, this );
if ( tr.fraction == 1.0 || ( gameLocal.GetTraceEntity( tr ) == ent ) ) {
gameLocal.pvs.FreeCurrentPVS( handle );
return true;
}
}
gameLocal.pvs.FreeCurrentPVS( handle );
return false;
}
/*
================
idSecurityCamera::SetAlertMode
================
*/
void idSecurityCamera::SetAlertMode( int alert ) {
if (alert >= SCANNING && alert <= ACTIVATED) {
alertMode = alert;
}
renderEntity.shaderParms[ SHADERPARM_MODE ] = alertMode;
UpdateVisuals();
}
/*
================
idSecurityCamera::Think
================
*/
void idSecurityCamera::Think() {
float pct;
float travel;
if ( thinkFlags & TH_THINK ) {
if ( g_showEntityInfo.GetBool() ) {
DrawFov();
}
if (health <= 0) {
BecomeInactive( TH_THINK );
return;
}
}
// run physics
RunPhysics();
if ( thinkFlags & TH_THINK ) {
if (CanSeePlayer()) {
if (alertMode == SCANNING) {
float sightTime;
SetAlertMode(ALERT);
stopSweeping = gameLocal.time;
if (sweeping) {
CancelEvents( &EV_SecurityCam_Pause );
} else {
CancelEvents( &EV_SecurityCam_ReverseSweep );
}
sweeping = false;
StopSound( SND_CHANNEL_ANY, false );
StartSound( "snd_sight", SND_CHANNEL_BODY, 0, false, NULL );
sightTime = spawnArgs.GetFloat( "sightTime", "5" );
PostEventSec(&EV_SecurityCam_Alert, sightTime);
}
} else {
if (alertMode == ALERT) {
float sightResume;
SetAlertMode(LOSINGINTEREST);
CancelEvents( &EV_SecurityCam_Alert );
sightResume = spawnArgs.GetFloat( "sightResume", "1.5" );
PostEventSec( &EV_SecurityCam_ContinueSweep, sightResume );
}
if ( sweeping ) {
idAngles a = GetPhysics()->GetAxis().ToAngles();
pct = ( gameLocal.time - sweepStart ) / ( sweepEnd - sweepStart );
travel = pct * sweepAngle;
if ( negativeSweep ) {
a.yaw = angle + travel;
} else {
a.yaw = angle - travel;
}
SetAngles( a );
}
}
}
Present();
}
/*
================
idSecurityCamera::GetAxis
================
*/
const idVec3 idSecurityCamera::GetAxis() const {
return (flipAxis) ? -GetPhysics()->GetAxis()[modelAxis] : GetPhysics()->GetAxis()[modelAxis];
};
/*
================
idSecurityCamera::SweepSpeed
================
*/
float idSecurityCamera::SweepSpeed() const {
return spawnArgs.GetFloat( "sweepSpeed", "5" );
}
/*
================
idSecurityCamera::StartSweep
================
*/
void idSecurityCamera::StartSweep() {
int speed;
sweeping = true;
sweepStart = gameLocal.time;
speed = SEC2MS( SweepSpeed() );
sweepEnd = sweepStart + speed;
PostEventMS( &EV_SecurityCam_Pause, speed );
StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL );
}
/*
================
idSecurityCamera::Event_ContinueSweep
================
*/
void idSecurityCamera::Event_ContinueSweep() {
float pct = (stopSweeping - sweepStart) / (sweepEnd - sweepStart);
float f = gameLocal.time - (sweepEnd - sweepStart) * pct;
int speed;
sweepStart = f;
speed = MS2SEC( SweepSpeed() );
sweepEnd = sweepStart + speed;
PostEventMS( &EV_SecurityCam_Pause, speed * (1.0 - pct));
StartSound( "snd_moving", SND_CHANNEL_BODY, 0, false, NULL );
SetAlertMode(SCANNING);
sweeping = true;
}
/*
================
idSecurityCamera::Event_Alert
================
*/
void idSecurityCamera::Event_Alert() {
float wait;
SetAlertMode(ACTIVATED);
StopSound( SND_CHANNEL_ANY, false );
StartSound( "snd_activate", SND_CHANNEL_BODY, 0, false, NULL );
ActivateTargets(this);
CancelEvents( &EV_SecurityCam_ContinueSweep );
wait = spawnArgs.GetFloat( "wait", "20" );
PostEventSec( &EV_SecurityCam_ContinueSweep, wait );
}
/*
================
idSecurityCamera::Event_ReverseSweep
================
*/
void idSecurityCamera::Event_ReverseSweep() {
angle = GetPhysics()->GetAxis().ToAngles().yaw;
negativeSweep = !negativeSweep;
StartSweep();
}
/*
================
idSecurityCamera::Event_Pause
================
*/
void idSecurityCamera::Event_Pause() {
float sweepWait;
sweepWait = spawnArgs.GetFloat( "sweepWait", "0.5" );
sweeping = false;
StopSound( SND_CHANNEL_ANY, false );
StartSound( "snd_stop", SND_CHANNEL_BODY, 0, false, NULL );
PostEventSec( &EV_SecurityCam_ReverseSweep, sweepWait );
}
/*
============
idSecurityCamera::Killed
============
*/
void idSecurityCamera::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
sweeping = false;
StopSound( SND_CHANNEL_ANY, false );
const char *fx = spawnArgs.GetString( "fx_destroyed" );
if ( fx[0] != '\0' ) {
idEntityFx::StartFx( fx, NULL, NULL, this, true );
}
physicsObj.SetSelf( this );
physicsObj.SetClipModel( new (TAG_PHYSICS_CLIP_ENTITY) idClipModel( trm ), 0.02f );
physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
physicsObj.SetAxis( GetPhysics()->GetAxis() );
physicsObj.SetBouncyness( 0.2f );
physicsObj.SetFriction( 0.6f, 0.6f, 0.2f );
physicsObj.SetGravity( gameLocal.GetGravity() );
physicsObj.SetContents( CONTENTS_SOLID );
physicsObj.SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP );
SetPhysics( &physicsObj );
physicsObj.DropToFloor();
}
/*
============
idSecurityCamera::Pain
============
*/
bool idSecurityCamera::Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
const char *fx = spawnArgs.GetString( "fx_damage" );
if ( fx[0] != '\0' ) {
idEntityFx::StartFx( fx, NULL, NULL, this, true );
}
return true;
}
/*
================
idSecurityCamera::Present
Present is called to allow entities to generate refEntities, lights, etc for the renderer.
================
*/
void idSecurityCamera::Present() {
// don't present to the renderer if the entity hasn't changed
if ( !( thinkFlags & TH_UPDATEVISUALS ) ) {
return;
}
BecomeInactive( TH_UPDATEVISUALS );
// camera target for remote render views
if ( cameraTarget ) {
renderEntity.remoteRenderView = cameraTarget->GetRenderView();
}
// if set to invisible, skip
if ( !renderEntity.hModel || IsHidden() ) {
return;
}
// add to refresh list
if ( modelDefHandle == -1 ) {
modelDefHandle = gameRenderWorld->AddEntityDef( &renderEntity );
} else {
gameRenderWorld->UpdateEntityDef( modelDefHandle, &renderEntity );
}
}

97
neo/d3xp/SecurityCamera.h Normal file
View File

@@ -0,0 +1,97 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_SECURITYCAMERA_H__
#define __GAME_SECURITYCAMERA_H__
/*
===================================================================================
Security camera
===================================================================================
*/
class idSecurityCamera : public idEntity {
public:
CLASS_PROTOTYPE( idSecurityCamera );
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Think();
virtual renderView_t * GetRenderView();
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void Present();
private:
enum { SCANNING, LOSINGINTEREST, ALERT, ACTIVATED };
float angle;
float sweepAngle;
int modelAxis;
bool flipAxis;
float scanDist;
float scanFov;
float sweepStart;
float sweepEnd;
bool negativeSweep;
bool sweeping;
int alertMode;
float stopSweeping;
float scanFovCos;
idVec3 viewOffset;
int pvsArea;
idPhysics_RigidBody physicsObj;
idTraceModel trm;
void StartSweep();
bool CanSeePlayer();
void SetAlertMode( int status );
void DrawFov();
const idVec3 GetAxis() const;
float SweepSpeed() const;
void Event_ReverseSweep();
void Event_ContinueSweep();
void Event_Pause();
void Event_Alert();
void Event_AddLight();
};
#endif /* !__GAME_SECURITYCAMERA_H__ */

438
neo/d3xp/SmokeParticles.cpp Normal file
View File

@@ -0,0 +1,438 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
static const char *smokeParticle_SnapshotName = "_SmokeParticle_Snapshot_";
/*
================
idSmokeParticles::idSmokeParticles
================
*/
idSmokeParticles::idSmokeParticles() {
initialized = false;
memset( &renderEntity, 0, sizeof( renderEntity ) );
renderEntityHandle = -1;
memset( smokes, 0, sizeof( smokes ) );
freeSmokes = NULL;
numActiveSmokes = 0;
currentParticleTime = -1;
}
/*
================
idSmokeParticles::Init
================
*/
void idSmokeParticles::Init() {
if ( initialized ) {
Shutdown();
}
// set up the free list
for ( int i = 0; i < MAX_SMOKE_PARTICLES-1; i++ ) {
smokes[i].next = &smokes[i+1];
}
smokes[MAX_SMOKE_PARTICLES-1].next = NULL;
freeSmokes = &smokes[0];
numActiveSmokes = 0;
activeStages.Clear();
memset( &renderEntity, 0, sizeof( renderEntity ) );
renderEntity.bounds.Clear();
renderEntity.axis = mat3_identity;
renderEntity.shaderParms[ SHADERPARM_RED ] = 1;
renderEntity.shaderParms[ SHADERPARM_GREEN ] = 1;
renderEntity.shaderParms[ SHADERPARM_BLUE ] = 1;
renderEntity.shaderParms[3] = 1;
renderEntity.hModel = renderModelManager->AllocModel();
renderEntity.hModel->InitEmpty( smokeParticle_SnapshotName );
// we certainly don't want particle shadows
renderEntity.noShadow = 1;
// huge bounds, so it will be present in every world area
renderEntity.bounds.AddPoint( idVec3(-100000, -100000, -100000) );
renderEntity.bounds.AddPoint( idVec3( 100000, 100000, 100000) );
renderEntity.callback = idSmokeParticles::ModelCallback;
// add to renderer list
renderEntityHandle = gameRenderWorld->AddEntityDef( &renderEntity );
currentParticleTime = -1;
initialized = true;
}
/*
================
idSmokeParticles::Shutdown
================
*/
void idSmokeParticles::Shutdown() {
// make sure the render entity is freed before the model is freed
if ( renderEntityHandle != -1 ) {
gameRenderWorld->FreeEntityDef( renderEntityHandle );
renderEntityHandle = -1;
}
if ( renderEntity.hModel != NULL ) {
renderModelManager->FreeModel( renderEntity.hModel );
renderEntity.hModel = NULL;
}
initialized = false;
}
/*
================
idSmokeParticles::FreeSmokes
================
*/
void idSmokeParticles::FreeSmokes() {
for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) {
singleSmoke_t *smoke, *next, *last;
activeSmokeStage_t *active = &activeStages[activeStageNum];
const idParticleStage *stage = active->stage;
for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) {
next = smoke->next;
float frac;
if ( smoke->timeGroup ) {
frac = (float)( gameLocal.fast.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 );
}
else {
frac = (float)( gameLocal.slow.time - smoke->privateStartTime ) / ( stage->particleLife * 1000 );
}
if ( frac >= 1.0f ) {
// remove the particle from the stage list
if ( last != NULL ) {
last->next = smoke->next;
} else {
active->smokes = smoke->next;
}
// put the particle on the free list
smoke->next = freeSmokes;
freeSmokes = smoke;
numActiveSmokes--;
continue;
}
last = smoke;
}
if ( !active->smokes ) {
// remove this from the activeStages list
activeStages.RemoveIndex( activeStageNum );
activeStageNum--;
}
}
}
/*
================
idSmokeParticles::EmitSmoke
Called by game code to drop another particle into the list
================
*/
bool idSmokeParticles::EmitSmoke( const idDeclParticle *smoke, const int systemStartTime, const float diversity, const idVec3 &origin, const idMat3 &axis, int timeGroup /*_D3XP*/ ) {
bool continues = false;
SetTimeState ts( timeGroup );
if ( !smoke ) {
return false;
}
if ( !gameLocal.isNewFrame ) {
return false;
}
// dedicated doesn't smoke. No UpdateRenderEntity, so they would not be freed
if ( gameLocal.GetLocalClientNum() < 0 ) {
return false;
}
assert( gameLocal.time == 0 || systemStartTime <= gameLocal.time );
if ( systemStartTime > gameLocal.time ) {
return false;
}
idRandom steppingRandom( 0xffff * diversity );
// for each stage in the smoke that is still emitting particles, emit a new singleSmoke_t
for ( int stageNum = 0; stageNum < smoke->stages.Num(); stageNum++ ) {
const idParticleStage *stage = smoke->stages[stageNum];
if ( !stage->cycleMsec ) {
continue;
}
if ( !stage->material ) {
continue;
}
if ( stage->particleLife <= 0 ) {
continue;
}
// see how many particles we should emit this tic
// FIXME: smoke.privateStartTime += stage->timeOffset;
int finalParticleTime = stage->cycleMsec * stage->spawnBunching;
int deltaMsec = gameLocal.time - systemStartTime;
int nowCount = 0, prevCount = 0;
if ( finalParticleTime == 0 ) {
// if spawnBunching is 0, they will all come out at once
if ( gameLocal.time == systemStartTime ) {
prevCount = -1;
nowCount = stage->totalParticles-1;
} else {
prevCount = stage->totalParticles;
}
} else {
nowCount = floor( ( (float)deltaMsec / finalParticleTime ) * stage->totalParticles );
if ( nowCount >= stage->totalParticles ) {
nowCount = stage->totalParticles-1;
}
prevCount = floor( ((float)( deltaMsec - ( gameLocal.time - gameLocal.previousTime ) ) / finalParticleTime) * stage->totalParticles );
if ( prevCount < -1 ) {
prevCount = -1;
}
}
if ( prevCount >= stage->totalParticles ) {
// no more particles from this stage
continue;
}
if ( nowCount < stage->totalParticles-1 ) {
// the system will need to emit particles next frame as well
continues = true;
}
// find an activeSmokeStage that matches this
activeSmokeStage_t *active = NULL;
int i;
for ( i = 0 ; i < activeStages.Num() ; i++ ) {
active = &activeStages[i];
if ( active->stage == stage ) {
break;
}
}
if ( i == activeStages.Num() ) {
// add a new one
activeSmokeStage_t newActive;
newActive.smokes = NULL;
newActive.stage = stage;
i = activeStages.Append( newActive );
active = &activeStages[i];
}
// add all the required particles
for ( prevCount++ ; prevCount <= nowCount && active != NULL ; prevCount++ ) {
if ( !freeSmokes ) {
gameLocal.Printf( "idSmokeParticles::EmitSmoke: no free smokes with %d active stages\n", activeStages.Num() );
return true;
}
singleSmoke_t *newSmoke = freeSmokes;
freeSmokes = freeSmokes->next;
numActiveSmokes++;
newSmoke->timeGroup = timeGroup;
newSmoke->index = prevCount;
newSmoke->axis = axis;
newSmoke->origin = origin;
newSmoke->random = steppingRandom;
newSmoke->privateStartTime = systemStartTime + prevCount * finalParticleTime / stage->totalParticles;
newSmoke->next = active->smokes;
active->smokes = newSmoke;
steppingRandom.RandomInt(); // advance the random
}
}
return continues;
}
/*
================
idSmokeParticles::UpdateRenderEntity
================
*/
bool idSmokeParticles::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) {
// this may be triggered by a model trace or other non-view related source,
// to which we should look like an empty model
if ( !renderView ) {
// FIXME: re-use model surfaces
renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName );
return false;
}
// don't regenerate it if it is current
if ( renderView->time[renderEntity->timeGroup] == currentParticleTime && !renderView->forceUpdate ) {
return false;
}
// FIXME: re-use model surfaces
renderEntity->hModel->InitEmpty( smokeParticle_SnapshotName );
currentParticleTime = renderView->time[renderEntity->timeGroup];
particleGen_t g;
g.renderEnt = renderEntity;
g.renderView = renderView;
for ( int activeStageNum = 0; activeStageNum < activeStages.Num(); activeStageNum++ ) {
singleSmoke_t *smoke, *next, *last;
activeSmokeStage_t *active = &activeStages[activeStageNum];
const idParticleStage *stage = active->stage;
if ( !stage->material ) {
continue;
}
// allocate a srfTriangles that can hold all the particles
int count = 0;
for ( smoke = active->smokes; smoke; smoke = smoke->next ) {
count++;
}
int quads = count * stage->NumQuadsPerParticle();
srfTriangles_t *tri = renderEntity->hModel->AllocSurfaceTriangles( quads * 4, quads * 6 );
tri->numIndexes = quads * 6;
tri->numVerts = quads * 4;
// just always draw the particles
tri->bounds[0][0] =
tri->bounds[0][1] =
tri->bounds[0][2] = -99999;
tri->bounds[1][0] =
tri->bounds[1][1] =
tri->bounds[1][2] = 99999;
tri->numVerts = 0;
for ( last = NULL, smoke = active->smokes; smoke; smoke = next ) {
next = smoke->next;
if ( smoke->timeGroup ) {
g.frac = (float)( gameLocal.fast.time - smoke->privateStartTime ) / (stage->particleLife * 1000);
}
else {
g.frac = (float)( gameLocal.time - smoke->privateStartTime ) / (stage->particleLife * 1000);
}
if ( g.frac >= 1.0f ) {
// remove the particle from the stage list
if ( last != NULL ) {
last->next = smoke->next;
} else {
active->smokes = smoke->next;
}
// put the particle on the free list
smoke->next = freeSmokes;
freeSmokes = smoke;
numActiveSmokes--;
continue;
}
g.index = smoke->index;
g.random = smoke->random;
g.origin = smoke->origin;
g.axis = smoke->axis;
g.originalRandom = g.random;
g.age = g.frac * stage->particleLife;
tri->numVerts += stage->CreateParticle( &g, tri->verts + tri->numVerts );
last = smoke;
}
if ( tri->numVerts > quads * 4 ) {
gameLocal.Error( "idSmokeParticles::UpdateRenderEntity: miscounted verts" );
}
if ( tri->numVerts == 0 ) {
// they were all removed
renderEntity->hModel->FreeSurfaceTriangles( tri );
if ( !active->smokes ) {
// remove this from the activeStages list
activeStages.RemoveIndex( activeStageNum );
activeStageNum--;
}
} else {
// build the index list
int indexes = 0;
for ( int i = 0 ; i < tri->numVerts ; i += 4 ) {
tri->indexes[indexes+0] = i;
tri->indexes[indexes+1] = i+2;
tri->indexes[indexes+2] = i+3;
tri->indexes[indexes+3] = i;
tri->indexes[indexes+4] = i+3;
tri->indexes[indexes+5] = i+1;
indexes += 6;
}
tri->numIndexes = indexes;
modelSurface_t surf;
surf.geometry = tri;
surf.shader = stage->material;
surf.id = 0;
renderEntity->hModel->AddSurface( surf );
}
}
return true;
}
/*
================
idSmokeParticles::ModelCallback
================
*/
bool idSmokeParticles::ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView ) {
// update the particles
if ( gameLocal.smokeParticles ) {
return gameLocal.smokeParticles->UpdateRenderEntity( renderEntity, renderView );
}
return true;
}

103
neo/d3xp/SmokeParticles.h Normal file
View File

@@ -0,0 +1,103 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __SMOKEPARTICLES_H__
#define __SMOKEPARTICLES_H__
/*
===============================================================================
Smoke systems are for particles that are emitted off of things that are
constantly changing position and orientation, like muzzle smoke coming
from a bone on a weapon, blood spurting from a wound, or particles
trailing from a monster limb.
The smoke particles are always evaluated and rendered each tic, so there
is a performance cost with using them for continuous effects. The general
particle systems are completely parametric, and have no performance
overhead when not in view.
All smoke systems share the same shaderparms, so any coloration must be
done in the particle definition.
Each particle model has its own shaderparms, which can be used by the
particle materials.
===============================================================================
*/
typedef struct singleSmoke_s {
struct singleSmoke_s * next;
int privateStartTime; // start time for this particular particle
int index; // particle index in system, 0 <= index < stage->totalParticles
idRandom random;
idVec3 origin;
idMat3 axis;
int timeGroup;
} singleSmoke_t;
typedef struct {
const idParticleStage * stage;
singleSmoke_t * smokes;
} activeSmokeStage_t;
class idSmokeParticles {
public:
idSmokeParticles();
// creats an entity covering the entire world that will call back each rendering
void Init();
void Shutdown();
// spits out a particle, returning false if the system will not emit any more particles in the future
bool EmitSmoke( const idDeclParticle *smoke, const int startTime, const float diversity,
const idVec3 &origin, const idMat3 &axis, int timeGroup /*_D3XP*/ );
// free old smokes
void FreeSmokes();
private:
bool initialized;
renderEntity_t renderEntity; // used to present a model to the renderer
int renderEntityHandle; // handle to static renderer model
static const int MAX_SMOKE_PARTICLES = 10000;
singleSmoke_t smokes[MAX_SMOKE_PARTICLES];
idList<activeSmokeStage_t, TAG_PARTICLE> activeStages;
singleSmoke_t * freeSmokes;
int numActiveSmokes;
int currentParticleTime; // don't need to recalculate if == view time
bool UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView );
static bool ModelCallback( renderEntity_s *renderEntity, const renderView_t *renderView );
};
#endif /* !__SMOKEPARTICLES_H__ */

304
neo/d3xp/Sound.cpp Normal file
View File

@@ -0,0 +1,304 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
===============================================================================
SOUND
===============================================================================
*/
const idEventDef EV_Speaker_On( "On", NULL );
const idEventDef EV_Speaker_Off( "Off", NULL );
const idEventDef EV_Speaker_Timer( "<timer>", NULL );
CLASS_DECLARATION( idEntity, idSound )
EVENT( EV_Activate, idSound::Event_Trigger )
EVENT( EV_Speaker_On, idSound::Event_On )
EVENT( EV_Speaker_Off, idSound::Event_Off )
EVENT( EV_Speaker_Timer, idSound::Event_Timer )
END_CLASS
/*
================
idSound::idSound
================
*/
idSound::idSound() {
lastSoundVol = 0.0f;
soundVol = 0.0f;
shakeTranslate.Zero();
shakeRotate.Zero();
random = 0.0f;
wait = 0.0f;
timerOn = false;
playingUntilTime = 0;
}
/*
================
idSound::Save
================
*/
void idSound::Save( idSaveGame *savefile ) const {
savefile->WriteFloat( lastSoundVol );
savefile->WriteFloat( soundVol );
savefile->WriteFloat( random );
savefile->WriteFloat( wait );
savefile->WriteBool( timerOn );
savefile->WriteVec3( shakeTranslate );
savefile->WriteAngles( shakeRotate );
savefile->WriteInt( playingUntilTime );
}
/*
================
idSound::Restore
================
*/
void idSound::Restore( idRestoreGame *savefile ) {
savefile->ReadFloat( lastSoundVol );
savefile->ReadFloat( soundVol );
savefile->ReadFloat( random );
savefile->ReadFloat( wait );
savefile->ReadBool( timerOn );
savefile->ReadVec3( shakeTranslate );
savefile->ReadAngles( shakeRotate );
savefile->ReadInt( playingUntilTime );
}
/*
================
idSound::Spawn
================
*/
void idSound::Spawn() {
spawnArgs.GetVector( "move", "0 0 0", shakeTranslate );
spawnArgs.GetAngles( "rotate", "0 0 0", shakeRotate );
spawnArgs.GetFloat( "random", "0", random );
spawnArgs.GetFloat( "wait", "0", wait );
if ( ( wait > 0.0f ) && ( random >= wait ) ) {
random = wait - 0.001;
gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
soundVol = 0.0f;
lastSoundVol = 0.0f;
if ( ( shakeRotate != ang_zero ) || ( shakeTranslate != vec3_zero ) ) {
BecomeActive( TH_THINK );
}
if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) {
timerOn = true;
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
} else {
timerOn = false;
}
}
/*
================
idSound::Event_Trigger
this will toggle the idle idSound on and off
================
*/
void idSound::Event_Trigger( idEntity *activator ) {
if ( wait > 0.0f ) {
if ( timerOn ) {
timerOn = false;
CancelEvents( &EV_Speaker_Timer );
} else {
timerOn = true;
DoSound( true );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
} else {
if ( common->IsMultiplayer() ) {
if ( refSound.referenceSound && ( gameLocal.time < playingUntilTime ) ) {
DoSound( false );
} else {
DoSound( true );
}
} else {
if ( refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) {
DoSound( false );
} else {
DoSound( true );
}
}
}
}
/*
================
idSound::Event_Timer
================
*/
void idSound::Event_Timer() {
DoSound( true );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
/*
================
idSound::Think
================
*/
void idSound::Think() {
idAngles ang;
// run physics
RunPhysics();
// clear out our update visuals think flag since we never call Present
BecomeInactive( TH_UPDATEVISUALS );
}
/*
===============
idSound::UpdateChangableSpawnArgs
===============
*/
void idSound::UpdateChangeableSpawnArgs( const idDict *source ) {
idEntity::UpdateChangeableSpawnArgs( source );
if ( source ) {
FreeSoundEmitter( true );
spawnArgs.Copy( *source );
idSoundEmitter *saveRef = refSound.referenceSound;
gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound );
refSound.referenceSound = saveRef;
idVec3 origin;
idMat3 axis;
if ( GetPhysicsToSoundTransform( origin, axis ) ) {
refSound.origin = GetPhysics()->GetOrigin() + origin * axis;
} else {
refSound.origin = GetPhysics()->GetOrigin();
}
spawnArgs.GetFloat( "random", "0", random );
spawnArgs.GetFloat( "wait", "0", wait );
if ( ( wait > 0.0f ) && ( random >= wait ) ) {
random = wait - 0.001;
gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) {
timerOn = true;
DoSound( false );
CancelEvents( &EV_Speaker_Timer );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
} else if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) {
// start it if it isn't already playing, and we aren't waitForTrigger
DoSound( true );
timerOn = false;
}
}
}
/*
===============
idSound::SetSound
===============
*/
void idSound::SetSound( const char *sound, int channel ) {
const idSoundShader *shader = declManager->FindSound( sound );
if ( shader != refSound.shader ) {
FreeSoundEmitter( true );
}
gameEdit->ParseSpawnArgsToRefSound(&spawnArgs, &refSound);
refSound.shader = shader;
// start it if it isn't already playing, and we aren't waitForTrigger
if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) {
DoSound( true );
}
}
/*
================
idSound::DoSound
================
*/
void idSound::DoSound( bool play ) {
if ( play ) {
StartSoundShader( refSound.shader, SND_CHANNEL_ANY, refSound.parms.soundShaderFlags, true, &playingUntilTime );
playingUntilTime += gameLocal.time;
} else {
StopSound( SND_CHANNEL_ANY, true );
playingUntilTime = 0;
}
}
/*
================
idSound::Event_On
================
*/
void idSound::Event_On() {
if ( wait > 0.0f ) {
timerOn = true;
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
DoSound( true );
}
/*
================
idSound::Event_Off
================
*/
void idSound::Event_Off() {
if ( timerOn ) {
timerOn = false;
CancelEvents( &EV_Speaker_Timer );
}
DoSound( false );
}
/*
===============
idSound::ShowEditingDialog
===============
*/
void idSound::ShowEditingDialog() {
}

76
neo/d3xp/Sound.h Normal file
View File

@@ -0,0 +1,76 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_SOUND_H__
#define __GAME_SOUND_H__
/*
===============================================================================
Generic sound emitter.
===============================================================================
*/
class idSound : public idEntity {
public:
CLASS_PROTOTYPE( idSound );
idSound();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void UpdateChangeableSpawnArgs( const idDict *source );
void Spawn();
void ToggleOnOff( idEntity *other, idEntity *activator );
void Think();
void SetSound( const char *sound, int channel = SND_CHANNEL_ANY );
virtual void ShowEditingDialog();
private:
float lastSoundVol;
float soundVol;
float random;
float wait;
bool timerOn;
idVec3 shakeTranslate;
idAngles shakeRotate;
int playingUntilTime;
void Event_Trigger( idEntity *activator );
void Event_Timer();
void Event_On();
void Event_Off();
void DoSound( bool play );
};
#endif /* !__GAME_SOUND_H__ */

1921
neo/d3xp/Target.cpp Normal file

File diff suppressed because it is too large Load Diff

615
neo/d3xp/Target.h Normal file
View File

@@ -0,0 +1,615 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_TARGET_H__
#define __GAME_TARGET_H__
/*
===============================================================================
idTarget
===============================================================================
*/
class idTarget : public idEntity {
public:
CLASS_PROTOTYPE( idTarget );
};
/*
===============================================================================
idTarget_Remove
===============================================================================
*/
class idTarget_Remove : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Remove );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_Show
===============================================================================
*/
class idTarget_Show : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Show );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_Damage
===============================================================================
*/
class idTarget_Damage : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Damage );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SessionCommand
===============================================================================
*/
class idTarget_SessionCommand : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SessionCommand );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_EndLevel
===============================================================================
*/
class idTarget_EndLevel : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_EndLevel );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_WaitForButton
===============================================================================
*/
class idTarget_WaitForButton : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_WaitForButton );
void Think();
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetGlobalShaderTime
===============================================================================
*/
class idTarget_SetGlobalShaderTime : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetGlobalShaderTime );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetShaderParm
===============================================================================
*/
class idTarget_SetShaderParm : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetShaderParm );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetShaderTime
===============================================================================
*/
class idTarget_SetShaderTime : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetShaderTime );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_FadeEntity
===============================================================================
*/
class idTarget_FadeEntity : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_FadeEntity );
idTarget_FadeEntity();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Think();
private:
idVec4 fadeFrom;
int fadeStart;
int fadeEnd;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_LightFadeIn
===============================================================================
*/
class idTarget_LightFadeIn : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_LightFadeIn );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_LightFadeOut
===============================================================================
*/
class idTarget_LightFadeOut : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_LightFadeOut );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_Give
===============================================================================
*/
class idTarget_Give : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Give );
void Spawn();
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_GiveEmail
===============================================================================
*/
class idTarget_GiveEmail : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_GiveEmail );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetModel
===============================================================================
*/
class idTarget_SetModel : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetModel );
void Spawn();
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetInfluence
===============================================================================
*/
typedef struct SavedGui_s {
SavedGui_s() {memset(gui, 0, sizeof(idUserInterface*)*MAX_RENDERENTITY_GUI); };
idUserInterface* gui[MAX_RENDERENTITY_GUI];
} SavedGui_t;
class idTarget_SetInfluence : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetInfluence );
idTarget_SetInfluence();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
void Event_Activate( idEntity *activator );
void Event_RestoreInfluence();
void Event_GatherEntities();
void Event_Flash( float flash, int out );
void Event_ClearFlash( float flash );
void Think();
idList<int, TAG_TARGET> lightList;
idList<int, TAG_TARGET> guiList;
idList<int, TAG_TARGET> soundList;
idList<int, TAG_TARGET> genericList;
float flashIn;
float flashOut;
float delay;
idStr flashInSound;
idStr flashOutSound;
idEntity * switchToCamera;
idInterpolate<float>fovSetting;
bool soundFaded;
bool restoreOnTrigger;
idList<SavedGui_t, TAG_TARGET> savedGuiList;
};
/*
===============================================================================
idTarget_SetKeyVal
===============================================================================
*/
class idTarget_SetKeyVal : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetKeyVal );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetFov
===============================================================================
*/
class idTarget_SetFov : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetFov );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Think();
private:
idInterpolate<float> fovSetting;
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_SetPrimaryObjective
===============================================================================
*/
class idTarget_SetPrimaryObjective : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_SetPrimaryObjective );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_LockDoor
===============================================================================
*/
class idTarget_LockDoor: public idTarget {
public:
CLASS_PROTOTYPE( idTarget_LockDoor );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_CallObjectFunction
===============================================================================
*/
class idTarget_CallObjectFunction : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_CallObjectFunction );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_LockDoor
===============================================================================
*/
class idTarget_EnableLevelWeapons : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_EnableLevelWeapons );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_Tip
===============================================================================
*/
class idTarget_Tip : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Tip );
idTarget_Tip();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
private:
idVec3 playerPos;
void Event_Activate( idEntity *activator );
void Event_TipOff();
void Event_GetPlayerPos();
};
/*
===============================================================================
idTarget_GiveSecurity
===============================================================================
*/
class idTarget_GiveSecurity : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_GiveSecurity );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_RemoveWeapons
===============================================================================
*/
class idTarget_RemoveWeapons : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_RemoveWeapons );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_LevelTrigger
===============================================================================
*/
class idTarget_LevelTrigger : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_LevelTrigger );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_Checkpoint
===============================================================================
*/
class idTarget_Checkpoint : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Checkpoint );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_EnableStamina
===============================================================================
*/
class idTarget_EnableStamina : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_EnableStamina );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_FadeSoundClass
===============================================================================
*/
class idTarget_FadeSoundClass : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_FadeSoundClass );
private:
void Event_Activate( idEntity *activator );
void Event_RestoreVolume();
};
/*
===============================================================================
idTarget_RumbleJoystick
===============================================================================
*/
class idTarget_RumbleJoystick : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_RumbleJoystick );
private:
void Event_Activate( idEntity *activator );
};
/*
===============================================================================
idTarget_Achievement
===============================================================================
*/
class idTarget_Achievement : public idTarget {
public:
CLASS_PROTOTYPE( idTarget_Achievement );
private:
void Event_Activate( idEntity *activator );
};
#endif /* !__GAME_TARGET_H__ */

1357
neo/d3xp/Trigger.cpp Normal file

File diff suppressed because it is too large Load Diff

312
neo/d3xp/Trigger.h Normal file
View File

@@ -0,0 +1,312 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_TRIGGER_H__
#define __GAME_TRIGGER_H__
extern const idEventDef EV_Enable;
extern const idEventDef EV_Disable;
/*
===============================================================================
Trigger base.
===============================================================================
*/
class idTrigger : public idEntity {
public:
CLASS_PROTOTYPE( idTrigger );
static void DrawDebugInfo();
idTrigger();
void Spawn();
const function_t * GetScriptFunction() const;
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
virtual void Enable();
virtual void Disable();
protected:
void CallScript() const;
void Event_Enable();
void Event_Disable();
const function_t * scriptFunction;
};
/*
===============================================================================
Trigger which can be activated multiple times.
===============================================================================
*/
class idTrigger_Multi : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Multi );
idTrigger_Multi();
void Spawn();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
protected:
float wait;
float random;
float delay;
float random_delay;
int nextTriggerTime;
idStr requires;
int removeItem;
bool touchClient;
bool touchOther;
bool triggerFirst;
bool triggerWithSelf;
bool CheckFacing( idEntity *activator );
void TriggerAction( idEntity *activator );
void Event_TriggerAction( idEntity *activator );
void Event_Trigger( idEntity *activator );
void Event_Touch( idEntity *other, trace_t *trace );
};
/*
===============================================================================
Trigger which can only be activated by an entity with a specific name.
===============================================================================
*/
class idTrigger_EntityName : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_EntityName );
idTrigger_EntityName();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
float wait;
float random;
float delay;
float random_delay;
int nextTriggerTime;
bool triggerFirst;
idStr entityName;
bool testPartialName;
void TriggerAction( idEntity *activator );
void Event_TriggerAction( idEntity *activator );
void Event_Trigger( idEntity *activator );
void Event_Touch( idEntity *other, trace_t *trace );
};
/*
===============================================================================
Trigger which repeatedly fires targets.
===============================================================================
*/
class idTrigger_Timer : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Timer );
idTrigger_Timer();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
virtual void Enable();
virtual void Disable();
private:
float random;
float wait;
bool on;
float delay;
idStr onName;
idStr offName;
void Event_Timer();
void Event_Use( idEntity *activator );
};
/*
===============================================================================
Trigger which fires targets after being activated a specific number of times.
===============================================================================
*/
class idTrigger_Count : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Count );
idTrigger_Count();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
int goal;
int count;
float delay;
void Event_Trigger( idEntity *activator );
void Event_TriggerAction( idEntity *activator );
};
/*
===============================================================================
Trigger which hurts touching entities.
===============================================================================
*/
class idTrigger_Hurt : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Hurt );
idTrigger_Hurt();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
private:
bool on;
float delay;
int nextTime;
void Event_Touch( idEntity *other, trace_t *trace );
void Event_Toggle( idEntity *activator );
};
/*
===============================================================================
Trigger which fades the player view.
===============================================================================
*/
class idTrigger_Fade : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Fade );
private:
void Event_Trigger( idEntity *activator );
};
/*
===============================================================================
Trigger which continuously tests whether other entities are touching it.
===============================================================================
*/
class idTrigger_Touch : public idTrigger {
public:
CLASS_PROTOTYPE( idTrigger_Touch );
idTrigger_Touch();
void Spawn();
virtual void Think();
void Save( idSaveGame *savefile );
void Restore( idRestoreGame *savefile );
virtual void Enable();
virtual void Disable();
void TouchEntities();
private:
idClipModel * clipModel;
void Event_Trigger( idEntity *activator );
};
/*
===============================================================================
Trigger that responces to CTF flags
===============================================================================
*/
class idTrigger_Flag : public idTrigger_Multi {
public:
CLASS_PROTOTYPE( idTrigger_Flag );
idTrigger_Flag();
void Spawn();
private:
int team;
bool player; // flag must be attached/carried by player
const idEventDef * eventFlag;
void Event_Touch( idEntity *other, trace_t *trace );
};
#endif /* !__GAME_TRIGGER_H__ */

4195
neo/d3xp/Weapon.cpp Normal file

File diff suppressed because it is too large Load Diff

447
neo/d3xp/Weapon.h Normal file
View File

@@ -0,0 +1,447 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_WEAPON_H__
#define __GAME_WEAPON_H__
#include "PredictedValue.h"
/*
===============================================================================
Player Weapon
===============================================================================
*/
extern const idEventDef EV_Weapon_State;
typedef enum {
WP_READY,
WP_OUTOFAMMO,
WP_RELOAD,
WP_HOLSTERED,
WP_RISING,
WP_LOWERING
} weaponStatus_t;
typedef int ammo_t;
static const int AMMO_NUMTYPES = 16;
class idPlayer;
static const int LIGHTID_WORLD_MUZZLE_FLASH = 1;
static const int LIGHTID_VIEW_MUZZLE_FLASH = 100;
class idMoveableItem;
typedef struct {
char name[64];
char particlename[128];
bool active;
int startTime;
jointHandle_t joint; //The joint on which to attach the particle
bool smoke; //Is this a smoke particle
const idDeclParticle* particle; //Used for smoke particles
idFuncEmitter* emitter; //Used for non-smoke particles
} WeaponParticle_t;
typedef struct {
char name[64];
bool active;
int startTime;
jointHandle_t joint;
int lightHandle;
renderLight_t light;
} WeaponLight_t;
class idWeapon : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idWeapon );
idWeapon();
virtual ~idWeapon();
// Init
void Spawn();
void SetOwner( idPlayer *owner );
idPlayer* GetOwner();
virtual bool ShouldConstructScriptObjectAtSpawn() const;
void SetFlashlightOwner( idPlayer *owner );
static void CacheWeapon( const char *weaponName );
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
// Weapon definition management
void Clear();
void GetWeaponDef( const char *objectname, int ammoinclip );
bool IsLinked();
bool IsWorldModelReady();
// GUIs
const char * Icon() const;
void UpdateGUI();
const char * PdaIcon() const;
const char * DisplayName() const;
const char * Description() const;
virtual void SetModel( const char *modelname );
bool GetGlobalJointTransform( bool viewModel, const jointHandle_t jointHandle, idVec3 &offset, idMat3 &axis );
void SetPushVelocity( const idVec3 &pushVelocity );
bool UpdateSkin();
// State control/player interface
void Think();
void Raise();
void PutAway();
void Reload();
void LowerWeapon();
void RaiseWeapon();
void HideWeapon();
void ShowWeapon();
void HideWorldModel();
void ShowWorldModel();
void OwnerDied();
void BeginAttack();
void EndAttack();
bool IsReady() const;
bool IsReloading() const;
bool IsHolstered() const;
bool ShowCrosshair() const;
idEntity * DropItem( const idVec3 &velocity, int activateDelay, int removeDelay, bool died );
bool CanDrop() const;
void WeaponStolen();
void ForceAmmoInClip();
weaponStatus_t GetStatus() { return status; };
// Script state management
virtual idThread * ConstructScriptObject();
virtual void DeconstructScriptObject();
void SetState( const char *statename, int blendFrames );
void UpdateScript();
void EnterCinematic();
void ExitCinematic();
void NetCatchup();
// Visual presentation
void PresentWeapon( bool showViewModel );
int GetZoomFov();
void GetWeaponAngleOffsets( int *average, float *scale, float *max );
void GetWeaponTimeOffsets( float *time, float *scale );
bool BloodSplat( float size );
void SetIsPlayerFlashlight( bool bl ) { isPlayerFlashlight = bl; }
void FlashlightOn();
void FlashlightOff();
// Ammo
static ammo_t GetAmmoNumForName( const char *ammoname );
static const char *GetAmmoNameForNum( ammo_t ammonum );
static const char *GetAmmoPickupNameForNum( ammo_t ammonum );
ammo_t GetAmmoType() const;
int AmmoAvailable() const;
int AmmoInClip() const;
void ResetAmmoClip();
int ClipSize() const;
int LowAmmo() const;
int AmmoRequired() const;
int AmmoCount() const;
int GetGrabberState() const;
// Flashlight
idAnimatedEntity * GetWorldModel() { return worldModel.GetEntity(); }
virtual void WriteToSnapshot( idBitMsg &msg ) const;
virtual void ReadFromSnapshot( const idBitMsg &msg );
enum {
EVENT_RELOAD = idEntity::EVENT_MAXEVENTS,
EVENT_ENDRELOAD,
EVENT_CHANGESKIN,
EVENT_MAXEVENTS
};
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
virtual void ClientPredictionThink();
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
void MuzzleFlashLight();
void RemoveMuzzleFlashlight();
// Get a global origin and axis suitable for the laser sight or bullet tracing
// Returns false for hands, grenades, and chainsaw.
// Can't be const because a frame may need to be created.
bool GetMuzzlePositionWithHacks( idVec3 & origin, idMat3 & axis );
void GetProjectileLaunchOriginAndAxis( idVec3 & origin, idMat3 & axis );
const idDeclEntityDef * GetDeclEntityDef() { return weaponDef; }
friend class idPlayer;
private:
// script control
idScriptBool WEAPON_ATTACK;
idScriptBool WEAPON_RELOAD;
idScriptBool WEAPON_NETRELOAD;
idScriptBool WEAPON_NETENDRELOAD;
idScriptBool WEAPON_NETFIRING;
idScriptBool WEAPON_RAISEWEAPON;
idScriptBool WEAPON_LOWERWEAPON;
weaponStatus_t status;
idThread * thread;
idStr state;
idStr idealState;
int animBlendFrames;
int animDoneTime;
bool isLinked;
bool isPlayerFlashlight;
// precreated projectile
idEntity *projectileEnt;
idPlayer * owner;
idEntityPtr<idAnimatedEntity> worldModel;
// hiding (for GUIs and NPCs)
int hideTime;
float hideDistance;
int hideStartTime;
float hideStart;
float hideEnd;
float hideOffset;
bool hide;
bool disabled;
// berserk
int berserk;
// these are the player render view parms, which include bobbing
idVec3 playerViewOrigin;
idMat3 playerViewAxis;
// the view weapon render entity parms
idVec3 viewWeaponOrigin;
idMat3 viewWeaponAxis;
// the muzzle bone's position, used for launching projectiles and trailing smoke
idVec3 muzzleOrigin;
idMat3 muzzleAxis;
idVec3 pushVelocity;
// weapon definition
// we maintain local copies of the projectile and brass dictionaries so they
// do not have to be copied across the DLL boundary when entities are spawned
const idDeclEntityDef * weaponDef;
const idDeclEntityDef * meleeDef;
idDict projectileDict;
float meleeDistance;
idStr meleeDefName;
idDict brassDict;
int brassDelay;
idStr icon;
idStr pdaIcon;
idStr displayName;
idStr itemDesc;
// view weapon gui light
renderLight_t guiLight;
int guiLightHandle;
// muzzle flash
renderLight_t muzzleFlash; // positioned on view weapon bone
int muzzleFlashHandle;
renderLight_t worldMuzzleFlash; // positioned on world weapon bone
int worldMuzzleFlashHandle;
float fraccos;
float fraccos2;
idVec3 flashColor;
int muzzleFlashEnd;
int flashTime;
bool lightOn;
bool silent_fire;
bool allowDrop;
// effects
bool hasBloodSplat;
// weapon kick
int kick_endtime;
int muzzle_kick_time;
int muzzle_kick_maxtime;
idAngles muzzle_kick_angles;
idVec3 muzzle_kick_offset;
// ammo management
ammo_t ammoType;
int ammoRequired; // amount of ammo to use each shot. 0 means weapon doesn't need ammo.
int clipSize; // 0 means no reload
idPredictedValue< int > ammoClip;
int lowAmmo; // if ammo in clip hits this threshold, snd_
bool powerAmmo; // true if the clip reduction is a factor of the power setting when
// a projectile is launched
// mp client
bool isFiring;
// zoom
int zoomFov; // variable zoom fov per weapon
// joints from models
jointHandle_t barrelJointView;
jointHandle_t flashJointView;
jointHandle_t ejectJointView;
jointHandle_t guiLightJointView;
jointHandle_t ventLightJointView;
jointHandle_t flashJointWorld;
jointHandle_t barrelJointWorld;
jointHandle_t ejectJointWorld;
jointHandle_t smokeJointView;
idHashTable<WeaponParticle_t> weaponParticles;
idHashTable<WeaponLight_t> weaponLights;
// sound
const idSoundShader * sndHum;
// new style muzzle smokes
const idDeclParticle * weaponSmoke; // null if it doesn't smoke
int weaponSmokeStartTime; // set to gameLocal.time every weapon fire
bool continuousSmoke; // if smoke is continuous ( chainsaw )
const idDeclParticle * strikeSmoke; // striking something in melee
int strikeSmokeStartTime; // timing
idVec3 strikePos; // position of last melee strike
idMat3 strikeAxis; // axis of last melee strike
int nextStrikeFx; // used for sound and decal ( may use for strike smoke too )
// nozzle effects
bool nozzleFx; // does this use nozzle effects ( parm5 at rest, parm6 firing )
// this also assumes a nozzle light atm
int nozzleFxFade; // time it takes to fade between the effects
int lastAttack; // last time an attack occured
renderLight_t nozzleGlow; // nozzle light
int nozzleGlowHandle; // handle for nozzle light
idVec3 nozzleGlowColor; // color of the nozzle glow
const idMaterial * nozzleGlowShader; // shader for glow light
float nozzleGlowRadius; // radius of glow light
// weighting for viewmodel angles
int weaponAngleOffsetAverages;
float weaponAngleOffsetScale;
float weaponAngleOffsetMax;
float weaponOffsetTime;
float weaponOffsetScale;
// flashlight
void AlertMonsters();
// Visual presentation
void InitWorldModel( const idDeclEntityDef *def );
void MuzzleRise( idVec3 &origin, idMat3 &axis );
void UpdateNozzleFx();
void UpdateFlashPosition();
// script events
void Event_Clear();
void Event_GetOwner();
void Event_WeaponState( const char *statename, int blendFrames );
void Event_SetWeaponStatus( float newStatus );
void Event_WeaponReady();
void Event_WeaponOutOfAmmo();
void Event_WeaponReloading();
void Event_WeaponHolstered();
void Event_WeaponRising();
void Event_WeaponLowering();
void Event_UseAmmo( int amount );
void Event_AddToClip( int amount );
void Event_AmmoInClip();
void Event_AmmoAvailable();
void Event_TotalAmmoCount();
void Event_ClipSize();
void Event_PlayAnim( int channel, const char *animname );
void Event_PlayCycle( int channel, const char *animname );
void Event_AnimDone( int channel, int blendFrames );
void Event_SetBlendFrames( int channel, int blendFrames );
void Event_GetBlendFrames( int channel );
void Event_Next();
void Event_SetSkin( const char *skinname );
void Event_Flashlight( int enable );
void Event_GetLightParm( int parmnum );
void Event_SetLightParm( int parmnum, float value );
void Event_SetLightParms( float parm0, float parm1, float parm2, float parm3 );
void Event_LaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower );
void Event_CreateProjectile();
void Event_EjectBrass();
void Event_Melee();
void Event_GetWorldModel();
void Event_AllowDrop( int allow );
void Event_AutoReload();
void Event_NetReload();
void Event_IsInvisible();
void Event_NetEndReload();
idGrabber grabber;
int grabberState;
void Event_Grabber( int enable );
void Event_GrabberHasTarget();
void Event_GrabberSetGrabDistance( float dist );
void Event_LaunchProjectilesEllipse( int num_projectiles, float spreada, float spreadb, float fuseOffset, float power );
void Event_LaunchPowerup( const char* powerup, float duration, int useAmmo );
void Event_StartWeaponSmoke();
void Event_StopWeaponSmoke();
void Event_StartWeaponParticle( const char* name);
void Event_StopWeaponParticle( const char* name);
void Event_StartWeaponLight( const char* name);
void Event_StopWeaponLight( const char* name);
};
ID_INLINE bool idWeapon::IsLinked() {
return isLinked;
}
ID_INLINE bool idWeapon::IsWorldModelReady() {
return ( worldModel.GetEntity() != NULL );
}
ID_INLINE idPlayer* idWeapon::GetOwner() {
return owner;
}
#endif /* !__GAME_WEAPON_H__ */

143
neo/d3xp/WorldSpawn.cpp Normal file
View File

@@ -0,0 +1,143 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/*
game_worldspawn.cpp
Worldspawn class. Each map has one worldspawn which handles global spawnargs.
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
/*
================
idWorldspawn
Every map should have exactly one worldspawn.
================
*/
CLASS_DECLARATION( idEntity, idWorldspawn )
EVENT( EV_Remove, idWorldspawn::Event_Remove )
EVENT( EV_SafeRemove, idWorldspawn::Event_Remove )
END_CLASS
/*
================
idWorldspawn::Spawn
================
*/
void idWorldspawn::Spawn() {
idStr scriptname;
idThread *thread;
const function_t *func;
const idKeyValue *kv;
assert( gameLocal.world == NULL );
gameLocal.world = this;
g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) );
// disable stamina on hell levels
if ( spawnArgs.GetBool( "no_stamina" ) ) {
pm_stamina.SetFloat( 0.0f );
}
// load script
scriptname = gameLocal.GetMapName();
scriptname.SetFileExtension( ".script" );
if ( fileSystem->ReadFile( scriptname, NULL, NULL ) > 0 ) {
gameLocal.program.CompileFile( scriptname );
// call the main function by default
func = gameLocal.program.FindFunction( "main" );
if ( func != NULL ) {
thread = new idThread( func );
thread->DelayedStart( 0 );
}
}
// call any functions specified in worldspawn
kv = spawnArgs.MatchPrefix( "call" );
while( kv != NULL ) {
func = gameLocal.program.FindFunction( kv->GetValue() );
if ( func == NULL ) {
gameLocal.Error( "Function '%s' not found in script for '%s' key on worldspawn", kv->GetValue().c_str(), kv->GetKey().c_str() );
}
thread = new idThread( func );
thread->DelayedStart( 0 );
kv = spawnArgs.MatchPrefix( "call", kv );
}
}
/*
=================
idWorldspawn::Save
=================
*/
void idWorldspawn::Save( idSaveGame *savefile ) {
}
/*
=================
idWorldspawn::Restore
=================
*/
void idWorldspawn::Restore( idRestoreGame *savefile ) {
assert( gameLocal.world == this );
g_gravity.SetFloat( spawnArgs.GetFloat( "gravity", va( "%f", DEFAULT_GRAVITY ) ) );
// disable stamina on hell levels
if ( spawnArgs.GetBool( "no_stamina" ) ) {
pm_stamina.SetFloat( 0.0f );
}
}
/*
================
idWorldspawn::~idWorldspawn
================
*/
idWorldspawn::~idWorldspawn() {
if ( gameLocal.world == this ) {
gameLocal.world = NULL;
}
}
/*
================
idWorldspawn::Event_Remove
================
*/
void idWorldspawn::Event_Remove() {
gameLocal.Error( "Tried to remove world" );
}

55
neo/d3xp/WorldSpawn.h Normal file
View File

@@ -0,0 +1,55 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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_WORLDSPAWN_H__
#define __GAME_WORLDSPAWN_H__
/*
===============================================================================
World entity.
===============================================================================
*/
class idWorldspawn : public idEntity {
public:
CLASS_PROTOTYPE( idWorldspawn );
~idWorldspawn();
void Spawn();
void Save( idSaveGame *savefile );
void Restore( idRestoreGame *savefile );
private:
void Event_Remove();
};
#endif /* !__GAME_WORLDSPAWN_H__ */

276
neo/d3xp/ai/AAS.cpp Normal file
View File

@@ -0,0 +1,276 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#pragma hdrstop
#include "../../idlib/precompiled.h"
#include "AAS_local.h"
/*
============
idAAS::Alloc
============
*/
idAAS *idAAS::Alloc() {
return new (TAG_AAS) idAASLocal;
}
/*
============
idAAS::idAAS
============
*/
idAAS::~idAAS() {
}
/*
============
idAASLocal::idAASLocal
============
*/
idAASLocal::idAASLocal() {
file = NULL;
}
/*
============
idAASLocal::~idAASLocal
============
*/
idAASLocal::~idAASLocal() {
Shutdown();
}
/*
============
idAASLocal::Init
============
*/
bool idAASLocal::Init( const idStr &mapName, unsigned int mapFileCRC ) {
if ( file && mapName.Icmp( file->GetName() ) == 0 && mapFileCRC == file->GetCRC() ) {
common->Printf( "Keeping %s\n", file->GetName() );
RemoveAllObstacles();
}
else {
Shutdown();
file = AASFileManager->LoadAAS( mapName, mapFileCRC );
if ( !file ) {
common->DWarning( "Couldn't load AAS file: '%s'", mapName.c_str() );
return false;
}
SetupRouting();
}
return true;
}
/*
============
idAASLocal::Shutdown
============
*/
void idAASLocal::Shutdown() {
if ( file ) {
ShutdownRouting();
RemoveAllObstacles();
AASFileManager->FreeAAS( file );
file = NULL;
}
}
/*
============
idAASLocal::Stats
============
*/
void idAASLocal::Stats() const {
if ( !file ) {
return;
}
common->Printf( "[%s]\n", file->GetName() );
file->PrintInfo();
RoutingStats();
}
/*
============
idAASLocal::GetSettings
============
*/
const idAASSettings *idAASLocal::GetSettings() const {
if ( !file ) {
return NULL;
}
return &file->GetSettings();
}
/*
============
idAASLocal::PointAreaNum
============
*/
int idAASLocal::PointAreaNum( const idVec3 &origin ) const {
if ( !file ) {
return 0;
}
return file->PointAreaNum( origin );
}
/*
============
idAASLocal::PointReachableAreaNum
============
*/
int idAASLocal::PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const {
if ( !file ) {
return 0;
}
return file->PointReachableAreaNum( origin, searchBounds, areaFlags, TFL_INVALID );
}
/*
============
idAASLocal::BoundsReachableAreaNum
============
*/
int idAASLocal::BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const {
if ( !file ) {
return 0;
}
return file->BoundsReachableAreaNum( bounds, areaFlags, TFL_INVALID );
}
/*
============
idAASLocal::PushPointIntoAreaNum
============
*/
void idAASLocal::PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const {
if ( !file ) {
return;
}
file->PushPointIntoAreaNum( areaNum, origin );
}
/*
============
idAASLocal::AreaCenter
============
*/
idVec3 idAASLocal::AreaCenter( int areaNum ) const {
if ( !file ) {
return vec3_origin;
}
return file->GetArea( areaNum ).center;
}
/*
============
idAASLocal::AreaFlags
============
*/
int idAASLocal::AreaFlags( int areaNum ) const {
if ( !file ) {
return 0;
}
return file->GetArea( areaNum ).flags;
}
/*
============
idAASLocal::AreaTravelFlags
============
*/
int idAASLocal::AreaTravelFlags( int areaNum ) const {
if ( !file ) {
return 0;
}
return file->GetArea( areaNum ).travelFlags;
}
/*
============
idAASLocal::Trace
============
*/
bool idAASLocal::Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const {
if ( !file ) {
trace.fraction = 0.0f;
trace.lastAreaNum = 0;
trace.numAreas = 0;
return true;
}
return file->Trace( trace, start, end );
}
/*
============
idAASLocal::GetPlane
============
*/
const idPlane &idAASLocal::GetPlane( int planeNum ) const {
if ( !file ) {
static idPlane dummy;
return dummy;
}
return file->GetPlane( planeNum );
}
/*
============
idAASLocal::GetEdgeVertexNumbers
============
*/
void idAASLocal::GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const {
if ( !file ) {
verts[0] = verts[1] = 0;
return;
}
const int *v = file->GetEdge( abs(edgeNum) ).vertexNum;
verts[0] = v[INT32_SIGNBITSET(edgeNum)];
verts[1] = v[INT32_SIGNBITNOTSET(edgeNum)];
}
/*
============
idAASLocal::GetEdge
============
*/
void idAASLocal::GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const {
if ( !file ) {
start.Zero();
end.Zero();
return;
}
const int *v = file->GetEdge( abs(edgeNum) ).vertexNum;
start = file->GetVertex( v[INT32_SIGNBITSET(edgeNum)] );
end = file->GetVertex( v[INT32_SIGNBITNOTSET(edgeNum)] );
}

141
neo/d3xp/ai/AAS.h Normal file
View File

@@ -0,0 +1,141 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __AAS_H__
#define __AAS_H__
/*
===============================================================================
Area Awareness System
===============================================================================
*/
enum {
PATHTYPE_WALK,
PATHTYPE_WALKOFFLEDGE,
PATHTYPE_BARRIERJUMP,
PATHTYPE_JUMP
};
typedef struct aasPath_s {
int type; // path type
idVec3 moveGoal; // point the AI should move towards
int moveAreaNum; // number of the area the AI should move towards
idVec3 secondaryGoal; // secondary move goal for complex navigation
const idReachability * reachability; // reachability used for navigation
} aasPath_t;
typedef struct aasGoal_s {
int areaNum; // area the goal is in
idVec3 origin; // position of goal
} aasGoal_t;
typedef struct aasObstacle_s {
idBounds absBounds; // absolute bounds of obstacle
idBounds expAbsBounds; // expanded absolute bounds of obstacle
} aasObstacle_t;
class idAASCallback {
public:
virtual ~idAASCallback() {};
virtual bool TestArea( const class idAAS *aas, int areaNum ) = 0;
};
typedef int aasHandle_t;
class idAAS {
public:
static idAAS * Alloc();
virtual ~idAAS() = 0;
// Initialize for the given map.
virtual bool Init( const idStr &mapName, unsigned int mapFileCRC ) = 0;
// Print AAS stats.
virtual void Stats() const = 0;
// Test from the given origin.
virtual void Test( const idVec3 &origin ) = 0;
// Get the AAS settings.
virtual const idAASSettings *GetSettings() const = 0;
// Returns the number of the area the origin is in.
virtual int PointAreaNum( const idVec3 &origin ) const = 0;
// Returns the number of the nearest reachable area for the given point.
virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &bounds, const int areaFlags ) const = 0;
// Returns the number of the first reachable area in or touching the bounds.
virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const = 0;
// Push the point into the area.
virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const = 0;
// Returns a reachable point inside the given area.
virtual idVec3 AreaCenter( int areaNum ) const = 0;
// Returns the area flags.
virtual int AreaFlags( int areaNum ) const = 0;
// Returns the travel flags for traveling through the area.
virtual int AreaTravelFlags( int areaNum ) const = 0;
// Trace through the areas and report the first collision.
virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0;
// Get a plane for a trace.
virtual const idPlane & GetPlane( int planeNum ) const = 0;
// Get wall edges.
virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const = 0;
// Sort the wall edges to create continuous sequences of walls.
virtual void SortWallEdges( int *edges, int numEdges ) const = 0;
// Get the vertex numbers for an edge.
virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const = 0;
// Get an edge.
virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const = 0;
// Find all areas within or touching the bounds with the given contents and disable/enable them for routing.
virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled ) = 0;
// Add an obstacle to the routing system.
virtual aasHandle_t AddObstacle( const idBounds &bounds ) = 0;
// Remove an obstacle from the routing system.
virtual void RemoveObstacle( const aasHandle_t handle ) = 0;
// Remove all obstacles from the routing system.
virtual void RemoveAllObstacles() = 0;
// Returns the travel time towards the goal area in 100th of a second.
virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags ) const = 0;
// Get the travel time and first reachability to be used towards the goal, returns true if there is a path.
virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach ) const = 0;
// Creates a walk path towards the goal.
virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const = 0;
// Returns true if one can walk along a straight line from the origin to the goal origin.
virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const = 0;
// Creates a fly path towards the goal.
virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const = 0;
// Returns true if one can fly along a straight line from the origin to the goal origin.
virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const = 0;
// Show the walk path from the origin towards the area.
virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0;
// Show the fly path from the origin towards the area.
virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const = 0;
// Find the nearest goal which satisfies the callback.
virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const = 0;
};
#endif /* !__AAS_H__ */

508
neo/d3xp/ai/AAS_debug.cpp Normal file
View File

@@ -0,0 +1,508 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#pragma hdrstop
#include "../../idlib/precompiled.h"
#include "AAS_local.h"
#include "../Game_local.h" // for cvars and debug drawing
/*
============
idAASLocal::DrawCone
============
*/
void idAASLocal::DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const {
int i;
idMat3 axis;
idVec3 center, top, p, lastp;
axis[2] = dir;
axis[2].NormalVectors( axis[0], axis[1] );
axis[1] = -axis[1];
center = origin + dir;
top = center + dir * (3.0f * radius);
lastp = center + radius * axis[1];
for ( i = 20; i <= 360; i += 20 ) {
p = center + sin( DEG2RAD(i) ) * radius * axis[0] + cos( DEG2RAD(i) ) * radius * axis[1];
gameRenderWorld->DebugLine( color, lastp, p, 0 );
gameRenderWorld->DebugLine( color, p, top, 0 );
lastp = p;
}
}
/*
============
idAASLocal::DrawReachability
============
*/
void idAASLocal::DrawReachability( const idReachability *reach ) const {
gameRenderWorld->DebugArrow( colorCyan, reach->start, reach->end, 2 );
if ( gameLocal.GetLocalPlayer() ) {
gameRenderWorld->DrawText( va( "%d", reach->edgeNum ), ( reach->start + reach->end ) * 0.5f, 0.1f, colorWhite, gameLocal.GetLocalPlayer()->viewAxis );
}
switch( reach->travelType ) {
case TFL_WALK: {
//const idReachability_Walk *walk = static_cast<const idReachability_Walk *>(reach);
break;
}
default: {
break;
}
}
}
/*
============
idAASLocal::DrawEdge
============
*/
void idAASLocal::DrawEdge( int edgeNum, bool arrow ) const {
const aasEdge_t *edge;
idVec4 *color;
if ( !file ) {
return;
}
edge = &file->GetEdge( edgeNum );
color = &colorRed;
if ( arrow ) {
gameRenderWorld->DebugArrow( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ), 1 );
} else {
gameRenderWorld->DebugLine( *color, file->GetVertex( edge->vertexNum[0] ), file->GetVertex( edge->vertexNum[1] ) );
}
if ( gameLocal.GetLocalPlayer() ) {
gameRenderWorld->DrawText( va( "%d", edgeNum ), ( file->GetVertex( edge->vertexNum[0] ) + file->GetVertex( edge->vertexNum[1] ) ) * 0.5f + idVec3(0,0,4), 0.1f, colorRed, gameLocal.GetLocalPlayer()->viewAxis );
}
}
/*
============
idAASLocal::DrawFace
============
*/
void idAASLocal::DrawFace( int faceNum, bool side ) const {
int i, j, numEdges, firstEdge;
const aasFace_t *face;
idVec3 mid, end;
if ( !file ) {
return;
}
face = &file->GetFace( faceNum );
numEdges = face->numEdges;
firstEdge = face->firstEdge;
mid = vec3_origin;
for ( i = 0; i < numEdges; i++ ) {
DrawEdge( abs( file->GetEdgeIndex( firstEdge + i ) ), ( face->flags & FACE_FLOOR ) != 0 );
j = file->GetEdgeIndex( firstEdge + i );
mid += file->GetVertex( file->GetEdge( abs( j ) ).vertexNum[ j < 0 ] );
}
mid /= numEdges;
if ( side ) {
end = mid - 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal();
} else {
end = mid + 5.0f * file->GetPlane( file->GetFace( faceNum ).planeNum ).Normal();
}
gameRenderWorld->DebugArrow( colorGreen, mid, end, 1 );
}
/*
============
idAASLocal::DrawArea
============
*/
void idAASLocal::DrawArea( int areaNum ) const {
int i, numFaces, firstFace;
const aasArea_t *area;
idReachability *reach;
if ( !file ) {
return;
}
area = &file->GetArea( areaNum );
numFaces = area->numFaces;
firstFace = area->firstFace;
for ( i = 0; i < numFaces; i++ ) {
DrawFace( abs( file->GetFaceIndex( firstFace + i ) ), file->GetFaceIndex( firstFace + i ) < 0 );
}
for ( reach = area->reach; reach; reach = reach->next ) {
DrawReachability( reach );
}
}
/*
============
idAASLocal::DefaultSearchBounds
============
*/
const idBounds &idAASLocal::DefaultSearchBounds() const {
return file->GetSettings().boundingBoxes[0];
}
/*
============
idAASLocal::ShowArea
============
*/
void idAASLocal::ShowArea( const idVec3 &origin ) const {
static int lastAreaNum;
int areaNum;
const aasArea_t *area;
idVec3 org;
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
org = origin;
PushPointIntoAreaNum( areaNum, org );
if ( aas_goalArea.GetInteger() ) {
int travelTime;
idReachability *reach;
RouteToGoalArea( areaNum, org, aas_goalArea.GetInteger(), TFL_WALK|TFL_AIR, travelTime, &reach );
gameLocal.Printf( "\rtt = %4d", travelTime );
if ( reach ) {
gameLocal.Printf( " to area %4d", reach->toAreaNum );
DrawArea( reach->toAreaNum );
}
}
if ( areaNum != lastAreaNum ) {
area = &file->GetArea( areaNum );
gameLocal.Printf( "area %d: ", areaNum );
if ( area->flags & AREA_LEDGE ) {
gameLocal.Printf( "AREA_LEDGE " );
}
if ( area->flags & AREA_REACHABLE_WALK ) {
gameLocal.Printf( "AREA_REACHABLE_WALK " );
}
if ( area->flags & AREA_REACHABLE_FLY ) {
gameLocal.Printf( "AREA_REACHABLE_FLY " );
}
if ( area->contents & AREACONTENTS_CLUSTERPORTAL ) {
gameLocal.Printf( "AREACONTENTS_CLUSTERPORTAL " );
}
if ( area->contents & AREACONTENTS_OBSTACLE ) {
gameLocal.Printf( "AREACONTENTS_OBSTACLE " );
}
gameLocal.Printf( "\n" );
lastAreaNum = areaNum;
}
if ( org != origin ) {
idBounds bnds = file->GetSettings().boundingBoxes[ 0 ];
bnds[ 1 ].z = bnds[ 0 ].z;
gameRenderWorld->DebugBounds( colorYellow, bnds, org );
}
DrawArea( areaNum );
}
/*
============
idAASLocal::ShowWalkPath
============
*/
void idAASLocal::ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const {
int i, areaNum, curAreaNum, travelTime;
idReachability *reach;
idVec3 org, areaCenter;
aasPath_t path;
if ( !file ) {
return;
}
org = origin;
areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_WALK );
PushPointIntoAreaNum( areaNum, org );
curAreaNum = areaNum;
for ( i = 0; i < 100; i++ ) {
if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_AIR, travelTime, &reach ) ) {
break;
}
if ( !reach ) {
break;
}
gameRenderWorld->DebugArrow( colorGreen, org, reach->start, 2 );
DrawReachability( reach );
if ( reach->toAreaNum == goalAreaNum ) {
break;
}
curAreaNum = reach->toAreaNum;
org = reach->end;
}
if ( WalkPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_AIR ) ) {
gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 2 );
}
}
/*
============
idAASLocal::ShowFlyPath
============
*/
void idAASLocal::ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const {
int i, areaNum, curAreaNum, travelTime;
idReachability *reach;
idVec3 org, areaCenter;
aasPath_t path;
if ( !file ) {
return;
}
org = origin;
areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AREA_REACHABLE_FLY );
PushPointIntoAreaNum( areaNum, org );
curAreaNum = areaNum;
for ( i = 0; i < 100; i++ ) {
if ( !RouteToGoalArea( curAreaNum, org, goalAreaNum, TFL_WALK|TFL_FLY|TFL_AIR, travelTime, &reach ) ) {
break;
}
if ( !reach ) {
break;
}
gameRenderWorld->DebugArrow( colorPurple, org, reach->start, 2 );
DrawReachability( reach );
if ( reach->toAreaNum == goalAreaNum ) {
break;
}
curAreaNum = reach->toAreaNum;
org = reach->end;
}
if ( FlyPathToGoal( path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_FLY|TFL_AIR ) ) {
gameRenderWorld->DebugArrow( colorBlue, origin, path.moveGoal, 2 );
}
}
/*
============
idAASLocal::ShowWallEdges
============
*/
void idAASLocal::ShowWallEdges( const idVec3 &origin ) const {
int i, areaNum, numEdges, edges[1024];
idVec3 start, end;
idPlayer *player;
player = gameLocal.GetLocalPlayer();
if ( !player ) {
return;
}
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( 256.0f ), TFL_WALK, edges, 1024 );
for ( i = 0; i < numEdges; i++ ) {
GetEdge( edges[i], start, end );
gameRenderWorld->DebugLine( colorRed, start, end );
gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, 0.1f, colorWhite, player->viewAxis );
}
}
/*
============
idAASLocal::ShowHideArea
============
*/
void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) const {
int areaNum, numObstacles;
idVec3 target;
aasGoal_t goal;
aasObstacle_t obstacles[10];
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
target = AreaCenter( targetAreaNum );
// consider the target an obstacle
obstacles[0].absBounds = idBounds( target ).Expand( 16 );
numObstacles = 1;
DrawCone( target, idVec3(0,0,1), 16.0f, colorYellow );
idAASFindCover findCover( target );
if ( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK|TFL_AIR, obstacles, numObstacles, findCover ) ) {
DrawArea( goal.areaNum );
ShowWalkPath( origin, goal.areaNum, goal.origin );
DrawCone( goal.origin, idVec3(0,0,1), 16.0f, colorWhite );
}
}
/*
============
idAASLocal::PullPlayer
============
*/
bool idAASLocal::PullPlayer( const idVec3 &origin, int toAreaNum ) const {
int areaNum;
idVec3 areaCenter, dir, vel;
idAngles delta;
aasPath_t path;
idPlayer *player;
player = gameLocal.GetLocalPlayer();
if ( !player ) {
return true;
}
idPhysics *physics = player->GetPhysics();
if ( !physics ) {
return true;
}
if ( !toAreaNum ) {
return false;
}
areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
areaCenter = AreaCenter( toAreaNum );
if ( player->GetPhysics()->GetAbsBounds().Expand( 8 ).ContainsPoint( areaCenter ) ) {
return false;
}
if ( WalkPathToGoal( path, areaNum, origin, toAreaNum, areaCenter, TFL_WALK|TFL_AIR ) ) {
dir = path.moveGoal - origin;
dir[2] *= 0.5f;
dir.Normalize();
delta = dir.ToAngles() - player->cmdAngles - player->GetDeltaViewAngles();
delta.Normalize180();
player->SetDeltaViewAngles( player->GetDeltaViewAngles() + delta * 0.1f );
dir[2] = 0.0f;
dir.Normalize();
dir *= 100.0f;
vel = physics->GetLinearVelocity();
dir[2] = vel[2];
physics->SetLinearVelocity( dir );
return true;
}
else {
return false;
}
}
/*
============
idAASLocal::RandomPullPlayer
============
*/
void idAASLocal::RandomPullPlayer( const idVec3 &origin ) const {
int rnd, i, n;
if ( !PullPlayer( origin, aas_pullPlayer.GetInteger() ) ) {
rnd = gameLocal.random.RandomFloat() * file->GetNumAreas();
for ( i = 0; i < file->GetNumAreas(); i++ ) {
n = (rnd + i) % file->GetNumAreas();
if ( file->GetArea( n ).flags & (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) ) {
aas_pullPlayer.SetInteger( n );
}
}
} else {
ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) );
}
}
/*
============
idAASLocal::ShowPushIntoArea
============
*/
void idAASLocal::ShowPushIntoArea( const idVec3 &origin ) const {
int areaNum;
idVec3 target;
target = origin;
areaNum = PointReachableAreaNum( target, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
PushPointIntoAreaNum( areaNum, target );
gameRenderWorld->DebugArrow( colorGreen, origin, target, 1 );
}
/*
============
idAASLocal::Test
============
*/
void idAASLocal::Test( const idVec3 &origin ) {
if ( !file ) {
return;
}
if ( aas_randomPullPlayer.GetBool() ) {
RandomPullPlayer( origin );
}
if ( ( aas_pullPlayer.GetInteger() > 0 ) && ( aas_pullPlayer.GetInteger() < file->GetNumAreas() ) ) {
ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) );
PullPlayer( origin, aas_pullPlayer.GetInteger() );
}
if ( ( aas_showPath.GetInteger() > 0 ) && ( aas_showPath.GetInteger() < file->GetNumAreas() ) ) {
ShowWalkPath( origin, aas_showPath.GetInteger(), AreaCenter( aas_showPath.GetInteger() ) );
}
if ( ( aas_showFlyPath.GetInteger() > 0 ) && ( aas_showFlyPath.GetInteger() < file->GetNumAreas() ) ) {
ShowFlyPath( origin, aas_showFlyPath.GetInteger(), AreaCenter( aas_showFlyPath.GetInteger() ) );
}
if ( ( aas_showHideArea.GetInteger() > 0 ) && ( aas_showHideArea.GetInteger() < file->GetNumAreas() ) ) {
ShowHideArea( origin, aas_showHideArea.GetInteger() );
}
if ( aas_showAreas.GetBool() ) {
ShowArea( origin );
}
if ( aas_showWallEdges.GetBool() ) {
ShowWallEdges( origin );
}
if ( aas_showPushIntoArea.GetBool() ) {
ShowPushIntoArea( origin );
}
}

189
neo/d3xp/ai/AAS_local.h Normal file
View File

@@ -0,0 +1,189 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __AAS_LOCAL_H__
#define __AAS_LOCAL_H__
#include "AAS.h"
#include "../Pvs.h"
class idRoutingCache {
friend class idAASLocal;
public:
idRoutingCache( int size );
~idRoutingCache();
int Size() const;
private:
int type; // portal or area cache
int size; // size of cache
int cluster; // cluster of the cache
int areaNum; // area of the cache
int travelFlags; // combinations of the travel flags
idRoutingCache * next; // next in list
idRoutingCache * prev; // previous in list
idRoutingCache * time_next; // next in time based list
idRoutingCache * time_prev; // previous in time based list
unsigned short startTravelTime; // travel time to start with
unsigned char * reachabilities; // reachabilities used for routing
unsigned short * travelTimes; // travel time for every area
};
class idRoutingUpdate {
friend class idAASLocal;
private:
int cluster; // cluster number of this update
int areaNum; // area number of this update
unsigned short tmpTravelTime; // temporary travel time
unsigned short * areaTravelTimes; // travel times within the area
idVec3 start; // start point into area
idRoutingUpdate * next; // next in list
idRoutingUpdate * prev; // prev in list
bool isInList; // true if the update is in the list
};
class idRoutingObstacle {
friend class idAASLocal;
idRoutingObstacle() { }
private:
idBounds bounds; // obstacle bounds
idList<int, TAG_AAS> areas; // areas the bounds are in
};
class idAASLocal : public idAAS {
public:
idAASLocal();
virtual ~idAASLocal();
virtual bool Init( const idStr &mapName, unsigned int mapFileCRC );
virtual void Shutdown();
virtual void Stats() const;
virtual void Test( const idVec3 &origin );
virtual const idAASSettings *GetSettings() const;
virtual int PointAreaNum( const idVec3 &origin ) const;
virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags ) const;
virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags ) const;
virtual void PushPointIntoAreaNum( int areaNum, idVec3 &origin ) const;
virtual idVec3 AreaCenter( int areaNum ) const;
virtual int AreaFlags( int areaNum ) const;
virtual int AreaTravelFlags( int areaNum ) const;
virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const;
virtual const idPlane & GetPlane( int planeNum ) const;
virtual int GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const;
virtual void SortWallEdges( int *edges, int numEdges ) const;
virtual void GetEdgeVertexNumbers( int edgeNum, int verts[2] ) const;
virtual void GetEdge( int edgeNum, idVec3 &start, idVec3 &end ) const;
virtual bool SetAreaState( const idBounds &bounds, const int areaContents, bool disabled );
virtual aasHandle_t AddObstacle( const idBounds &bounds );
virtual void RemoveObstacle( const aasHandle_t handle );
virtual void RemoveAllObstacles();
virtual int TravelTimeToGoalArea( int areaNum, const idVec3 &origin, int goalAreaNum, int travelFlags ) const;
virtual bool RouteToGoalArea( int areaNum, const idVec3 origin, int goalAreaNum, int travelFlags, int &travelTime, idReachability **reach ) const;
virtual bool WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const;
virtual bool WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const;
virtual bool FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const;
virtual bool FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const;
virtual void ShowWalkPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
virtual void ShowFlyPath( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
virtual bool FindNearestGoal( aasGoal_t &goal, int areaNum, const idVec3 origin, const idVec3 &target, int travelFlags, aasObstacle_t *obstacles, int numObstacles, idAASCallback &callback ) const;
private:
idAASFile * file;
idStr name;
private: // routing data
idRoutingCache *** areaCacheIndex; // for each area in each cluster the travel times to all other areas in the cluster
int areaCacheIndexSize; // number of area cache entries
idRoutingCache ** portalCacheIndex; // for each area in the world the travel times from each portal
int portalCacheIndexSize; // number of portal cache entries
idRoutingUpdate * areaUpdate; // memory used to update the area routing cache
idRoutingUpdate * portalUpdate; // memory used to update the portal routing cache
unsigned short * goalAreaTravelTimes; // travel times to goal areas
unsigned short * areaTravelTimes; // travel times through the areas
int numAreaTravelTimes; // number of area travel times
mutable idRoutingCache * cacheListStart; // start of list with cache sorted from oldest to newest
mutable idRoutingCache * cacheListEnd; // end of list with cache sorted from oldest to newest
mutable int totalCacheMemory; // total cache memory used
idList<idRoutingObstacle *, TAG_AAS> obstacleList; // list with obstacles
private: // routing
bool SetupRouting();
void ShutdownRouting();
unsigned short AreaTravelTime( int areaNum, const idVec3 &start, const idVec3 &end ) const;
void CalculateAreaTravelTimes();
void DeleteAreaTravelTimes();
void SetupRoutingCache();
void DeleteClusterCache( int clusterNum );
void DeletePortalCache();
void ShutdownRoutingCache();
void RoutingStats() const;
void LinkCache( idRoutingCache *cache ) const;
void UnlinkCache( idRoutingCache *cache ) const;
void DeleteOldestCache() const;
idReachability * GetAreaReachability( int areaNum, int reachabilityNum ) const;
int ClusterAreaNum( int clusterNum, int areaNum ) const;
void UpdateAreaRoutingCache( idRoutingCache *areaCache ) const;
idRoutingCache * GetAreaRoutingCache( int clusterNum, int areaNum, int travelFlags ) const;
void UpdatePortalRoutingCache( idRoutingCache *portalCache ) const;
idRoutingCache * GetPortalRoutingCache( int clusterNum, int areaNum, int travelFlags ) const;
void RemoveRoutingCacheUsingArea( int areaNum );
void DisableArea( int areaNum );
void EnableArea( int areaNum );
bool SetAreaState_r( int nodeNum, const idBounds &bounds, const int areaContents, bool disabled );
void GetBoundsAreas_r( int nodeNum, const idBounds &bounds, idList<int> &areas ) const;
void SetObstacleState( const idRoutingObstacle *obstacle, bool enable );
private: // pathing
bool EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const;
bool FloorEdgeSplitPoint( idVec3 &split, int areaNum, const idPlane &splitPlane, const idPlane &frontPlane, bool closest ) const;
idVec3 SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const;
idVec3 SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const;
private: // debug
const idBounds & DefaultSearchBounds() const;
void DrawCone( const idVec3 &origin, const idVec3 &dir, float radius, const idVec4 &color ) const;
void DrawArea( int areaNum ) const;
void DrawFace( int faceNum, bool side ) const;
void DrawEdge( int edgeNum, bool arrow ) const;
void DrawReachability( const idReachability *reach ) const;
void ShowArea( const idVec3 &origin ) const;
void ShowWallEdges( const idVec3 &origin ) const;
void ShowHideArea( const idVec3 &origin, int targerAreaNum ) const;
bool PullPlayer( const idVec3 &origin, int toAreaNum ) const;
void RandomPullPlayer( const idVec3 &origin ) const;
void ShowPushIntoArea( const idVec3 &origin ) const;
};
#endif /* !__AAS_LOCAL_H__ */

717
neo/d3xp/ai/AAS_pathing.cpp Normal file
View File

@@ -0,0 +1,717 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#pragma hdrstop
#include "../../idlib/precompiled.h"
#include "AAS_local.h"
#define SUBSAMPLE_WALK_PATH 1
#define SUBSAMPLE_FLY_PATH 0
const int maxWalkPathIterations = 10;
const float maxWalkPathDistance = 500.0f;
const float walkPathSampleDistance = 8.0f;
const int maxFlyPathIterations = 10;
const float maxFlyPathDistance = 500.0f;
const float flyPathSampleDistance = 8.0f;
/*
============
idAASLocal::EdgeSplitPoint
calculates split point of the edge with the plane
returns true if the split point is between the edge vertices
============
*/
bool idAASLocal::EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const {
const aasEdge_t *edge;
idVec3 v1, v2;
float d1, d2;
edge = &file->GetEdge( edgeNum );
v1 = file->GetVertex( edge->vertexNum[0] );
v2 = file->GetVertex( edge->vertexNum[1] );
d1 = v1 * plane.Normal() - plane.Dist();
d2 = v2 * plane.Normal() - plane.Dist();
//if ( (d1 < CM_CLIP_EPSILON && d2 < CM_CLIP_EPSILON) || (d1 > -CM_CLIP_EPSILON && d2 > -CM_CLIP_EPSILON) ) {
if ( IEEE_FLT_SIGNBITSET( d1 ) == IEEE_FLT_SIGNBITSET( d2 ) ) {
return false;
}
split = v1 + (d1 / (d1 - d2)) * (v2 - v1);
return true;
}
/*
============
idAASLocal::FloorEdgeSplitPoint
calculates either the closest or furthest point on the floor of the area which also lies on the pathPlane
the point has to be on the front side of the frontPlane to be valid
============
*/
bool idAASLocal::FloorEdgeSplitPoint( idVec3 &bestSplit, int areaNum, const idPlane &pathPlane, const idPlane &frontPlane, bool closest ) const {
int i, j, faceNum, edgeNum;
const aasArea_t *area;
const aasFace_t *face;
idVec3 split;
float dist, bestDist;
if ( closest ) {
bestDist = maxWalkPathDistance;
} else {
bestDist = -0.1f;
}
area = &file->GetArea( areaNum );
for ( i = 0; i < area->numFaces; i++ ) {
faceNum = file->GetFaceIndex( area->firstFace + i );
face = &file->GetFace( abs(faceNum) );
if ( !(face->flags & FACE_FLOOR ) ) {
continue;
}
for ( j = 0; j < face->numEdges; j++ ) {
edgeNum = file->GetEdgeIndex( face->firstEdge + j );
if ( !EdgeSplitPoint( split, abs( edgeNum ), pathPlane ) ) {
continue;
}
dist = frontPlane.Distance( split );
if ( closest ) {
if ( dist >= -0.1f && dist < bestDist ) {
bestDist = dist;
bestSplit = split;
}
} else {
if ( dist > bestDist ) {
bestDist = dist;
bestSplit = split;
}
}
}
}
if ( closest ) {
return ( bestDist < maxWalkPathDistance );
} else {
return ( bestDist > -0.1f );
}
}
/*
============
idAASLocal::WalkPathValid
returns true if one can walk in a straight line between origin and goalOrigin
============
*/
bool idAASLocal::WalkPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const {
int curAreaNum, lastAreaNum, lastAreas[4], lastAreaIndex;
idPlane pathPlane, frontPlane, farPlane;
idReachability *reach;
const aasArea_t *area;
idVec3 p, dir;
if ( file == NULL ) {
endPos = goalOrigin;
endAreaNum = 0;
return true;
}
lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum;
lastAreaIndex = 0;
pathPlane.SetNormal( (goalOrigin - origin).Cross( file->GetSettings().gravityDir ) );
pathPlane.Normalize();
pathPlane.FitThroughPoint( origin );
frontPlane.SetNormal( goalOrigin - origin );
frontPlane.Normalize();
frontPlane.FitThroughPoint( origin );
farPlane.SetNormal( frontPlane.Normal() );
farPlane.FitThroughPoint( goalOrigin );
curAreaNum = areaNum;
lastAreaNum = curAreaNum;
while ( 1 ) {
// find the furthest floor face split point on the path
if ( !FloorEdgeSplitPoint( endPos, curAreaNum, pathPlane, frontPlane, false ) ) {
endPos = origin;
}
// if we found a point near or further than the goal we're done
if ( farPlane.Distance( endPos ) > -0.5f ) {
break;
}
// if we reached the goal area we're done
if ( curAreaNum == goalAreaNum ) {
break;
}
frontPlane.SetDist( frontPlane.Normal() * endPos );
area = &file->GetArea( curAreaNum );
for ( reach = area->reach; reach; reach = reach->next ) {
if ( reach->travelType != TFL_WALK ) {
continue;
}
// if the reachability goes back to a previous area
if ( reach->toAreaNum == lastAreas[0] || reach->toAreaNum == lastAreas[1] ||
reach->toAreaNum == lastAreas[2] || reach->toAreaNum == lastAreas[3] ) {
continue;
}
// if undesired travel flags are required to travel through the area
if ( file->GetArea( reach->toAreaNum ).travelFlags & ~travelFlags ) {
continue;
}
// don't optimize through an area near a ledge
if ( file->GetArea( reach->toAreaNum ).flags & AREA_LEDGE ) {
continue;
}
// find the closest floor face split point on the path
if ( !FloorEdgeSplitPoint( p, reach->toAreaNum, pathPlane, frontPlane, true ) ) {
continue;
}
// direction parallel to gravity
dir = ( file->GetSettings().gravityDir * endPos * file->GetSettings().gravityDir ) -
( file->GetSettings().gravityDir * p * file->GetSettings().gravityDir );
if ( dir.LengthSqr() > Square( file->GetSettings().maxStepHeight ) ) {
continue;
}
// direction orthogonal to gravity
dir = endPos - p - dir;
if ( dir.LengthSqr() > Square( 0.2f ) ) {
continue;
}
break;
}
if ( !reach ) {
return false;
}
lastAreas[lastAreaIndex] = curAreaNum;
lastAreaIndex = ( lastAreaIndex + 1 ) & 3;
curAreaNum = reach->toAreaNum;
}
endAreaNum = curAreaNum;
return true;
}
/*
============
idAASLocal::SubSampleWalkPath
============
*/
idVec3 idAASLocal::SubSampleWalkPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const {
int i, numSamples, curAreaNum;
idVec3 dir, point, nextPoint, endPos;
dir = end - start;
numSamples = (int) (dir.Length() / walkPathSampleDistance) + 1;
point = start;
for ( i = 1; i < numSamples; i++ ) {
nextPoint = start + dir * ((float) i / numSamples);
if ( (point - nextPoint).LengthSqr() > Square( maxWalkPathDistance ) ) {
return point;
}
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum ) ) {
return point;
}
point = nextPoint;
endAreaNum = curAreaNum;
}
return point;
}
/*
============
idAASLocal::WalkPathToGoal
FIXME: don't stop optimizing on first failure ?
============
*/
bool idAASLocal::WalkPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const {
int i, travelTime, curAreaNum, lastAreas[4], lastAreaIndex, endAreaNum;
idReachability * reach = NULL;
idVec3 endPos;
path.type = PATHTYPE_WALK;
path.moveGoal = origin;
path.moveAreaNum = areaNum;
path.secondaryGoal = origin;
path.reachability = NULL;
if ( file == NULL || areaNum == goalAreaNum ) {
path.moveGoal = goalOrigin;
return true;
}
lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum;
lastAreaIndex = 0;
curAreaNum = areaNum;
for ( i = 0; i < maxWalkPathIterations; i++ ) {
if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach ) ) {
break;
}
if ( !reach ) {
return false;
}
// no need to check through the first area
if ( areaNum != curAreaNum ) {
// only optimize a limited distance ahead
if ( (reach->start - origin).LengthSqr() > Square( maxWalkPathDistance ) ) {
#if SUBSAMPLE_WALK_PATH
path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
#endif
return true;
}
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum ) ) {
#if SUBSAMPLE_WALK_PATH
path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
#endif
return true;
}
}
path.moveGoal = reach->start;
path.moveAreaNum = curAreaNum;
if ( reach->travelType != TFL_WALK ) {
break;
}
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum ) ) {
return true;
}
path.moveGoal = reach->end;
path.moveAreaNum = reach->toAreaNum;
if ( reach->toAreaNum == goalAreaNum ) {
if ( !idAASLocal::WalkPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum ) ) {
#if SUBSAMPLE_WALK_PATH
path.moveGoal = SubSampleWalkPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum );
#endif
return true;
}
path.moveGoal = goalOrigin;
path.moveAreaNum = goalAreaNum;
return true;
}
lastAreas[lastAreaIndex] = curAreaNum;
lastAreaIndex = ( lastAreaIndex + 1 ) & 3;
curAreaNum = reach->toAreaNum;
if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] ||
curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) {
common->Warning( "idAASLocal::WalkPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum );
break;
}
}
if ( reach == NULL ) {
return false;
}
switch( reach->travelType ) {
case TFL_WALKOFFLEDGE:
path.type = PATHTYPE_WALKOFFLEDGE;
path.secondaryGoal = reach->end;
path.reachability = reach;
break;
case TFL_BARRIERJUMP:
path.type |= PATHTYPE_BARRIERJUMP;
path.secondaryGoal = reach->end;
path.reachability = reach;
break;
case TFL_JUMP:
path.type |= PATHTYPE_JUMP;
path.secondaryGoal = reach->end;
path.reachability = reach;
break;
default:
break;
}
return true;
}
/*
============
idAASLocal::FlyPathValid
returns true if one can fly in a straight line between origin and goalOrigin
============
*/
bool idAASLocal::FlyPathValid( int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags, idVec3 &endPos, int &endAreaNum ) const {
aasTrace_t trace;
if ( file == NULL ) {
endPos = goalOrigin;
endAreaNum = 0;
return true;
}
file->Trace( trace, origin, goalOrigin );
endPos = trace.endpos;
endAreaNum = trace.lastAreaNum;
if ( trace.fraction >= 1.0f ) {
return true;
}
return false;
}
/*
============
idAASLocal::SubSampleFlyPath
============
*/
idVec3 idAASLocal::SubSampleFlyPath( int areaNum, const idVec3 &origin, const idVec3 &start, const idVec3 &end, int travelFlags, int &endAreaNum ) const {
int i, numSamples, curAreaNum;
idVec3 dir, point, nextPoint, endPos;
dir = end - start;
numSamples = (int) (dir.Length() / flyPathSampleDistance) + 1;
point = start;
for ( i = 1; i < numSamples; i++ ) {
nextPoint = start + dir * ((float) i / numSamples);
if ( (point - nextPoint).LengthSqr() > Square( maxFlyPathDistance ) ) {
return point;
}
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, nextPoint, travelFlags, endPos, curAreaNum ) ) {
return point;
}
point = nextPoint;
endAreaNum = curAreaNum;
}
return point;
}
/*
============
idAASLocal::FlyPathToGoal
FIXME: don't stop optimizing on first failure ?
============
*/
bool idAASLocal::FlyPathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int travelFlags ) const {
int i, travelTime, curAreaNum, lastAreas[4], lastAreaIndex, endAreaNum;
idReachability *reach = NULL;
idVec3 endPos;
path.type = PATHTYPE_WALK;
path.moveGoal = origin;
path.moveAreaNum = areaNum;
path.secondaryGoal = origin;
path.reachability = NULL;
if ( file == NULL || areaNum == goalAreaNum ) {
path.moveGoal = goalOrigin;
return true;
}
lastAreas[0] = lastAreas[1] = lastAreas[2] = lastAreas[3] = areaNum;
lastAreaIndex = 0;
curAreaNum = areaNum;
for ( i = 0; i < maxFlyPathIterations; i++ ) {
if ( !idAASLocal::RouteToGoalArea( curAreaNum, path.moveGoal, goalAreaNum, travelFlags, travelTime, &reach ) ) {
break;
}
if ( !reach ) {
return false;
}
// no need to check through the first area
if ( areaNum != curAreaNum ) {
if ( (reach->start - origin).LengthSqr() > Square( maxFlyPathDistance ) ) {
#if SUBSAMPLE_FLY_PATH
path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
#endif
return true;
}
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->start, travelFlags, endPos, endAreaNum ) ) {
#if SUBSAMPLE_FLY_PATH
path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, reach->start, travelFlags, path.moveAreaNum );
#endif
return true;
}
}
path.moveGoal = reach->start;
path.moveAreaNum = curAreaNum;
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, reach->end, travelFlags, endPos, endAreaNum ) ) {
return true;
}
path.moveGoal = reach->end;
path.moveAreaNum = reach->toAreaNum;
if ( reach->toAreaNum == goalAreaNum ) {
if ( !idAASLocal::FlyPathValid( areaNum, origin, 0, goalOrigin, travelFlags, endPos, endAreaNum ) ) {
#if SUBSAMPLE_FLY_PATH
path.moveGoal = SubSampleFlyPath( areaNum, origin, path.moveGoal, goalOrigin, travelFlags, path.moveAreaNum );
#endif
return true;
}
path.moveGoal = goalOrigin;
path.moveAreaNum = goalAreaNum;
return true;
}
lastAreas[lastAreaIndex] = curAreaNum;
lastAreaIndex = ( lastAreaIndex + 1 ) & 3;
curAreaNum = reach->toAreaNum;
if ( curAreaNum == lastAreas[0] || curAreaNum == lastAreas[1] ||
curAreaNum == lastAreas[2] || curAreaNum == lastAreas[3] ) {
common->Warning( "idAASLocal::FlyPathToGoal: local routing minimum going from area %d to area %d", areaNum, goalAreaNum );
break;
}
}
if ( reach == NULL ) {
return false;
}
return true;
}
typedef struct wallEdge_s {
int edgeNum;
int verts[2];
struct wallEdge_s * next;
} wallEdge_t;
/*
============
idAASLocal::SortWallEdges
============
*/
void idAASLocal::SortWallEdges( int *edges, int numEdges ) const {
int i, j, k, numSequences;
wallEdge_t **sequenceFirst, **sequenceLast, *wallEdges, *wallEdge;
wallEdges = (wallEdge_t *) _alloca16( numEdges * sizeof( wallEdge_t ) );
sequenceFirst = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) );
sequenceLast = (wallEdge_t **)_alloca16( numEdges * sizeof( wallEdge_t * ) );
for ( i = 0; i < numEdges; i++ ) {
wallEdges[i].edgeNum = edges[i];
GetEdgeVertexNumbers( edges[i], wallEdges[i].verts );
wallEdges[i].next = NULL;
sequenceFirst[i] = &wallEdges[i];
sequenceLast[i] = &wallEdges[i];
}
numSequences = numEdges;
for ( i = 0; i < numSequences; i++ ) {
for ( j = i+1; j < numSequences; j++ ) {
if ( sequenceFirst[i]->verts[0] == sequenceLast[j]->verts[1] ) {
sequenceLast[j]->next = sequenceFirst[i];
sequenceFirst[i] = sequenceFirst[j];
break;
}
if ( sequenceLast[i]->verts[1] == sequenceFirst[j]->verts[0] ) {
sequenceLast[i]->next = sequenceFirst[j];
break;
}
}
if ( j < numSequences ) {
numSequences--;
for ( k = j; k < numSequences; k++ ) {
sequenceFirst[k] = sequenceFirst[k+1];
sequenceLast[k] = sequenceLast[k+1];
}
i = -1;
}
}
k = 0;
for ( i = 0; i < numSequences; i++ ) {
for ( wallEdge = sequenceFirst[i]; wallEdge; wallEdge = wallEdge->next ) {
edges[k++] = wallEdge->edgeNum;
}
}
}
/*
============
idAASLocal::GetWallEdges
============
*/
int idAASLocal::GetWallEdges( int areaNum, const idBounds &bounds, int travelFlags, int *edges, int maxEdges ) const {
int i, j, k, l, face1Num, face2Num, edge1Num, edge2Num, numEdges, absEdge1Num;
int *areaQueue, curArea, queueStart, queueEnd;
byte *areasVisited;
const aasArea_t *area;
const aasFace_t *face1, *face2;
idReachability *reach;
if ( !file ) {
return 0;
}
numEdges = 0;
areasVisited = (byte *) _alloca16( file->GetNumAreas() );
memset( areasVisited, 0, file->GetNumAreas() * sizeof( byte ) );
areaQueue = (int *) _alloca16( file->GetNumAreas() * sizeof( int ) );
queueStart = -1;
queueEnd = 0;
areaQueue[0] = areaNum;
areasVisited[areaNum] = true;
for ( curArea = areaNum; queueStart < queueEnd; curArea = areaQueue[++queueStart] ) {
area = &file->GetArea( curArea );
for ( i = 0; i < area->numFaces; i++ ) {
face1Num = file->GetFaceIndex( area->firstFace + i );
face1 = &file->GetFace( abs(face1Num) );
if ( !(face1->flags & FACE_FLOOR ) ) {
continue;
}
for ( j = 0; j < face1->numEdges; j++ ) {
edge1Num = file->GetEdgeIndex( face1->firstEdge + j );
absEdge1Num = abs( edge1Num );
// test if the edge is shared by another floor face of this area
for ( k = 0; k < area->numFaces; k++ ) {
if ( k == i ) {
continue;
}
face2Num = file->GetFaceIndex( area->firstFace + k );
face2 = &file->GetFace( abs(face2Num) );
if ( !(face2->flags & FACE_FLOOR ) ) {
continue;
}
for ( l = 0; l < face2->numEdges; l++ ) {
edge2Num = abs( file->GetEdgeIndex( face2->firstEdge + l ) );
if ( edge2Num == absEdge1Num ) {
break;
}
}
if ( l < face2->numEdges ) {
break;
}
}
if ( k < area->numFaces ) {
continue;
}
// test if the edge is used by a reachability
for ( reach = area->reach; reach; reach = reach->next ) {
if ( reach->travelType & travelFlags ) {
if ( reach->edgeNum == absEdge1Num ) {
break;
}
}
}
if ( reach ) {
continue;
}
// test if the edge is already in the list
for ( k = 0; k < numEdges; k++ ) {
if ( edge1Num == edges[k] ) {
break;
}
}
if ( k < numEdges ) {
continue;
}
// add the edge to the list
edges[numEdges++] = edge1Num;
if ( numEdges >= maxEdges ) {
return numEdges;
}
}
}
// add new areas to the queue
for ( reach = area->reach; reach; reach = reach->next ) {
if ( reach->travelType & travelFlags ) {
// if the area the reachability leads to hasn't been visited yet and the area bounds touch the search bounds
if ( !areasVisited[reach->toAreaNum] && bounds.IntersectsBounds( file->GetArea( reach->toAreaNum ).bounds ) ) {
areaQueue[queueEnd++] = reach->toAreaNum;
areasVisited[reach->toAreaNum] = true;
}
}
}
}
return numEdges;
}

1350
neo/d3xp/ai/AAS_routing.cpp Normal file

File diff suppressed because it is too large Load Diff

5337
neo/d3xp/ai/AI.cpp Normal file

File diff suppressed because it is too large Load Diff

731
neo/d3xp/ai/AI.h Normal file
View File

@@ -0,0 +1,731 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __AI_H__
#define __AI_H__
/*
===============================================================================
idAI
===============================================================================
*/
const float SQUARE_ROOT_OF_2 = 1.414213562f;
const float AI_TURN_PREDICTION = 0.2f;
const float AI_TURN_SCALE = 60.0f;
const float AI_SEEK_PREDICTION = 0.3f;
const float AI_FLY_DAMPENING = 0.15f;
const float AI_HEARING_RANGE = 2048.0f;
const int DEFAULT_FLY_OFFSET = 68;
#define ATTACK_IGNORE 0
#define ATTACK_ON_DAMAGE 1
#define ATTACK_ON_ACTIVATE 2
#define ATTACK_ON_SIGHT 4
typedef struct ballistics_s {
float angle; // angle in degrees in the range [-180, 180]
float time; // time it takes before the projectile arrives
} ballistics_t;
extern int Ballistics( const idVec3 &start, const idVec3 &end, float speed, float gravity, ballistics_t bal[2] );
// defined in script/ai_base.script. please keep them up to date.
typedef enum {
MOVETYPE_DEAD,
MOVETYPE_ANIM,
MOVETYPE_SLIDE,
MOVETYPE_FLY,
MOVETYPE_STATIC,
NUM_MOVETYPES
} moveType_t;
typedef enum {
MOVE_NONE,
MOVE_FACE_ENEMY,
MOVE_FACE_ENTITY,
// commands < NUM_NONMOVING_COMMANDS don't cause a change in position
NUM_NONMOVING_COMMANDS,
MOVE_TO_ENEMY = NUM_NONMOVING_COMMANDS,
MOVE_TO_ENEMYHEIGHT,
MOVE_TO_ENTITY,
MOVE_OUT_OF_RANGE,
MOVE_TO_ATTACK_POSITION,
MOVE_TO_COVER,
MOVE_TO_POSITION,
MOVE_TO_POSITION_DIRECT,
MOVE_SLIDE_TO_POSITION,
MOVE_WANDER,
NUM_MOVE_COMMANDS
} moveCommand_t;
typedef enum {
TALK_NEVER,
TALK_DEAD,
TALK_OK,
TALK_BUSY,
NUM_TALK_STATES
} talkState_t;
//
// status results from move commands
// make sure to change script/doom_defs.script if you add any, or change their order
//
typedef enum {
MOVE_STATUS_DONE,
MOVE_STATUS_MOVING,
MOVE_STATUS_WAITING,
MOVE_STATUS_DEST_NOT_FOUND,
MOVE_STATUS_DEST_UNREACHABLE,
MOVE_STATUS_BLOCKED_BY_WALL,
MOVE_STATUS_BLOCKED_BY_OBJECT,
MOVE_STATUS_BLOCKED_BY_ENEMY,
MOVE_STATUS_BLOCKED_BY_MONSTER
} moveStatus_t;
#define DI_NODIR -1
// obstacle avoidance
typedef struct obstaclePath_s {
idVec3 seekPos; // seek position avoiding obstacles
idEntity * firstObstacle; // if != NULL the first obstacle along the path
idVec3 startPosOutsideObstacles; // start position outside obstacles
idEntity * startPosObstacle; // if != NULL the obstacle containing the start position
idVec3 seekPosOutsideObstacles; // seek position outside obstacles
idEntity * seekPosObstacle; // if != NULL the obstacle containing the seek position
} obstaclePath_t;
// path prediction
typedef enum {
SE_BLOCKED = BIT(0),
SE_ENTER_LEDGE_AREA = BIT(1),
SE_ENTER_OBSTACLE = BIT(2),
SE_FALL = BIT(3),
SE_LAND = BIT(4)
} stopEvent_t;
typedef struct predictedPath_s {
idVec3 endPos; // final position
idVec3 endVelocity; // velocity at end position
idVec3 endNormal; // normal of blocking surface
int endTime; // time predicted
int endEvent; // event that stopped the prediction
const idEntity * blockingEntity; // entity that blocks the movement
} predictedPath_t;
//
// events
//
extern const idEventDef AI_BeginAttack;
extern const idEventDef AI_EndAttack;
extern const idEventDef AI_MuzzleFlash;
extern const idEventDef AI_CreateMissile;
extern const idEventDef AI_AttackMissile;
extern const idEventDef AI_FireMissileAtTarget;
extern const idEventDef AI_LaunchProjectile;
extern const idEventDef AI_TriggerFX;
extern const idEventDef AI_StartEmitter;
extern const idEventDef AI_StopEmitter;
extern const idEventDef AI_AttackMelee;
extern const idEventDef AI_DirectDamage;
extern const idEventDef AI_JumpFrame;
extern const idEventDef AI_EnableClip;
extern const idEventDef AI_DisableClip;
extern const idEventDef AI_EnableGravity;
extern const idEventDef AI_DisableGravity;
extern const idEventDef AI_TriggerParticles;
extern const idEventDef AI_RandomPath;
class idPathCorner;
typedef struct particleEmitter_s {
particleEmitter_s() {
particle = NULL;
time = 0;
joint = INVALID_JOINT;
};
const idDeclParticle *particle;
int time;
jointHandle_t joint;
} particleEmitter_t;
typedef struct funcEmitter_s {
char name[64];
idFuncEmitter* particle;
jointHandle_t joint;
} funcEmitter_t;
class idMoveState {
public:
idMoveState();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
moveType_t moveType;
moveCommand_t moveCommand;
moveStatus_t moveStatus;
idVec3 moveDest;
idVec3 moveDir; // used for wandering and slide moves
idEntityPtr<idEntity> goalEntity;
idVec3 goalEntityOrigin; // move to entity uses this to avoid checking the floor position every frame
int toAreaNum;
int startTime;
int duration;
float speed; // only used by flying creatures
float range;
float wanderYaw;
int nextWanderTime;
int blockTime;
idEntityPtr<idEntity> obstacle;
idVec3 lastMoveOrigin;
int lastMoveTime;
int anim;
};
class idAASFindCover : public idAASCallback {
public:
idAASFindCover( const idVec3 &hideFromPos );
~idAASFindCover();
virtual bool TestArea( const idAAS *aas, int areaNum );
private:
pvsHandle_t hidePVS;
int PVSAreas[ idEntity::MAX_PVS_AREAS ];
};
class idAASFindAreaOutOfRange : public idAASCallback {
public:
idAASFindAreaOutOfRange( const idVec3 &targetPos, float maxDist );
virtual bool TestArea( const idAAS *aas, int areaNum );
private:
idVec3 targetPos;
float maxDistSqr;
};
class idAASFindAttackPosition : public idAASCallback {
public:
idAASFindAttackPosition( const idAI *self, const idMat3 &gravityAxis, idEntity *target, const idVec3 &targetPos, const idVec3 &fireOffset );
~idAASFindAttackPosition();
virtual bool TestArea( const idAAS *aas, int areaNum );
private:
const idAI *self;
idEntity *target;
idBounds excludeBounds;
idVec3 targetPos;
idVec3 fireOffset;
idMat3 gravityAxis;
pvsHandle_t targetPVS;
int PVSAreas[ idEntity::MAX_PVS_AREAS ];
};
class idAI : public idActor {
public:
CLASS_PROTOTYPE( idAI );
idAI();
~idAI();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
void HeardSound( idEntity *ent, const char *action );
idActor *GetEnemy() const;
void TalkTo( idActor *actor );
talkState_t GetTalkState() const;
bool GetAimDir( const idVec3 &firePos, idEntity *aimAtEnt, const idEntity *ignore, idVec3 &aimDir ) const;
void TouchedByFlashlight( idActor *flashlight_owner );
// Outputs a list of all monsters to the console.
static void List_f( const idCmdArgs &args );
// Finds a path around dynamic obstacles.
static bool FindPathAroundObstacles( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path );
// Frees any nodes used for the dynamic obstacle avoidance.
static void FreeObstacleAvoidanceNodes();
// Predicts movement, returns true if a stop event was triggered.
static bool PredictPath( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path );
// Return true if the trajectory of the clip model is collision free.
static bool TestTrajectory( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime );
// Finds the best collision free trajectory for a clip model.
static bool PredictTrajectory( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir );
virtual void Gib( const idVec3 &dir, const char *damageDefName );
protected:
// navigation
idAAS * aas;
int travelFlags;
idMoveState move;
idMoveState savedMove;
float kickForce;
bool ignore_obstacles;
float blockedRadius;
int blockedMoveTime;
int blockedAttackTime;
// turning
float ideal_yaw;
float current_yaw;
float turnRate;
float turnVel;
float anim_turn_yaw;
float anim_turn_amount;
float anim_turn_angles;
// physics
idPhysics_Monster physicsObj;
// flying
jointHandle_t flyTiltJoint;
float fly_speed;
float fly_bob_strength;
float fly_bob_vert;
float fly_bob_horz;
int fly_offset; // prefered offset from player's view
float fly_seek_scale;
float fly_roll_scale;
float fly_roll_max;
float fly_roll;
float fly_pitch_scale;
float fly_pitch_max;
float fly_pitch;
bool allowMove; // disables any animation movement
bool allowHiddenMovement; // allows character to still move around while hidden
bool disableGravity; // disables gravity and allows vertical movement by the animation
bool af_push_moveables; // allow the articulated figure to push moveable objects
// weapon/attack vars
bool lastHitCheckResult;
int lastHitCheckTime;
int lastAttackTime;
float melee_range;
float projectile_height_to_distance_ratio; // calculates the maximum height a projectile can be thrown
idList<idVec3, TAG_AI> missileLaunchOffset;
const idDict * projectileDef;
mutable idClipModel *projectileClipModel;
float projectileRadius;
float projectileSpeed;
idVec3 projectileVelocity;
idVec3 projectileGravity;
idEntityPtr<idProjectile> projectile;
idStr attack;
idVec3 homingMissileGoal;
// chatter/talking
const idSoundShader *chat_snd;
int chat_min;
int chat_max;
int chat_time;
talkState_t talk_state;
idEntityPtr<idActor> talkTarget;
// cinematics
int num_cinematics;
int current_cinematic;
bool allowJointMod;
idEntityPtr<idEntity> focusEntity;
idVec3 currentFocusPos;
int focusTime;
int alignHeadTime;
int forceAlignHeadTime;
idAngles eyeAng;
idAngles lookAng;
idAngles destLookAng;
idAngles lookMin;
idAngles lookMax;
idList<jointHandle_t, TAG_AI> lookJoints;
idList<idAngles, TAG_AI> lookJointAngles;
float eyeVerticalOffset;
float eyeHorizontalOffset;
float eyeFocusRate;
float headFocusRate;
int focusAlignTime;
// special fx
bool restartParticles; // should smoke emissions restart
bool useBoneAxis; // use the bone vs the model axis
idList<particleEmitter_t, TAG_AI> particles; // particle data
renderLight_t worldMuzzleFlash; // positioned on world weapon bone
int worldMuzzleFlashHandle;
jointHandle_t flashJointWorld;
int muzzleFlashEnd;
int flashTime;
// joint controllers
idAngles eyeMin;
idAngles eyeMax;
jointHandle_t focusJoint;
jointHandle_t orientationJoint;
// enemy variables
idEntityPtr<idActor> enemy;
idVec3 lastVisibleEnemyPos;
idVec3 lastVisibleEnemyEyeOffset;
idVec3 lastVisibleReachableEnemyPos;
idVec3 lastReachableEnemyPos;
bool wakeOnFlashlight;
bool spawnClearMoveables;
idHashTable<funcEmitter_t> funcEmitters;
idEntityPtr<idHarvestable> harvestEnt;
// script variables
idScriptBool AI_TALK;
idScriptBool AI_DAMAGE;
idScriptBool AI_PAIN;
idScriptFloat AI_SPECIAL_DAMAGE;
idScriptBool AI_DEAD;
idScriptBool AI_ENEMY_VISIBLE;
idScriptBool AI_ENEMY_IN_FOV;
idScriptBool AI_ENEMY_DEAD;
idScriptBool AI_MOVE_DONE;
idScriptBool AI_ONGROUND;
idScriptBool AI_ACTIVATED;
idScriptBool AI_FORWARD;
idScriptBool AI_JUMP;
idScriptBool AI_ENEMY_REACHABLE;
idScriptBool AI_BLOCKED;
idScriptBool AI_OBSTACLE_IN_PATH;
idScriptBool AI_DEST_UNREACHABLE;
idScriptBool AI_HIT_ENEMY;
idScriptBool AI_PUSHED;
//
// ai/ai.cpp
//
void SetAAS();
virtual void DormantBegin(); // called when entity becomes dormant
virtual void DormantEnd(); // called when entity wakes from being dormant
void Think();
void Activate( idEntity *activator );
public:
int ReactionTo( const idEntity *ent );
protected:
bool CheckForEnemy();
void EnemyDead();
virtual bool CanPlayChatterSounds() const;
void SetChatSound();
void PlayChatter();
virtual void Hide();
virtual void Show();
idVec3 FirstVisiblePointOnPath( const idVec3 origin, const idVec3 &target, int travelFlags ) const;
void CalculateAttackOffsets();
void PlayCinematic();
// movement
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
void GetMoveDelta( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta );
void CheckObstacleAvoidance( const idVec3 &goalPos, idVec3 &newPos );
void DeadMove();
void AnimMove();
void SlideMove();
void AdjustFlyingAngles();
void AddFlyBob( idVec3 &vel );
void AdjustFlyHeight( idVec3 &vel, const idVec3 &goalPos );
void FlySeekGoal( idVec3 &vel, idVec3 &goalPos );
void AdjustFlySpeed( idVec3 &vel );
void FlyTurn();
void FlyMove();
void StaticMove();
// damage
virtual bool Pain( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
// navigation
void KickObstacles( const idVec3 &dir, float force, idEntity *alwaysKick );
bool ReachedPos( const idVec3 &pos, const moveCommand_t moveCommand ) const;
float TravelDistance( const idVec3 &start, const idVec3 &end ) const;
int PointReachableAreaNum( const idVec3 &pos, const float boundsScale = 2.0f ) const;
bool PathToGoal( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
void DrawRoute() const;
bool GetMovePos( idVec3 &seekPos );
bool MoveDone() const;
bool EntityCanSeePos( idActor *actor, const idVec3 &actorOrigin, const idVec3 &pos );
void BlockedFailSafe();
// movement control
void StopMove( moveStatus_t status );
bool FaceEnemy();
bool FaceEntity( idEntity *ent );
bool DirectMoveToPosition( const idVec3 &pos );
bool MoveToEnemyHeight();
bool MoveOutOfRange( idEntity *entity, float range );
bool MoveToAttackPosition( idEntity *ent, int attack_anim );
bool MoveToEnemy();
bool MoveToEntity( idEntity *ent );
bool MoveToPosition( const idVec3 &pos );
bool MoveToCover( idEntity *entity, const idVec3 &pos );
bool SlideToPosition( const idVec3 &pos, float time );
bool WanderAround();
bool StepDirection( float dir );
bool NewWanderDir( const idVec3 &dest );
// effects
const idDeclParticle *SpawnParticlesOnJoint( particleEmitter_t &pe, const char *particleName, const char *jointName );
void SpawnParticles( const char *keyName );
bool ParticlesActive();
// turning
bool FacingIdeal();
void Turn();
bool TurnToward( float yaw );
bool TurnToward( const idVec3 &pos );
// enemy management
void ClearEnemy();
bool EnemyPositionValid() const;
void SetEnemyPosition();
void UpdateEnemyPosition();
void SetEnemy( idActor *newEnemy );
// attacks
void CreateProjectileClipModel() const;
idProjectile *CreateProjectile( const idVec3 &pos, const idVec3 &dir );
void RemoveProjectile();
idProjectile *LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone );
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
void DirectDamage( const char *meleeDefName, idEntity *ent );
bool TestMelee() const;
bool AttackMelee( const char *meleeDefName );
void BeginAttack( const char *name );
void EndAttack();
void PushWithAF();
// special effects
void GetMuzzle( const char *jointname, idVec3 &muzzle, idMat3 &axis );
void InitMuzzleFlash();
void TriggerWeaponEffects( const idVec3 &muzzle );
void UpdateMuzzleFlash();
virtual bool UpdateAnimationControllers();
void UpdateParticles();
void TriggerParticles( const char *jointName );
void TriggerFX( const char* joint, const char* fx );
idEntity* StartEmitter( const char* name, const char* joint, const char* particle );
idEntity* GetEmitter( const char* name );
void StopEmitter( const char* name );
// AI script state management
void LinkScriptVariables();
void UpdateAIScript();
//
// ai/ai_events.cpp
//
void Event_Activate( idEntity *activator );
void Event_Touch( idEntity *other, trace_t *trace );
void Event_FindEnemy( int useFOV );
void Event_FindEnemyAI( int useFOV );
void Event_FindEnemyInCombatNodes();
void Event_ClosestReachableEnemyOfEntity( idEntity *team_mate );
void Event_HeardSound( int ignore_team );
void Event_SetEnemy( idEntity *ent );
void Event_ClearEnemy();
void Event_MuzzleFlash( const char *jointname );
void Event_CreateMissile( const char *jointname );
void Event_AttackMissile( const char *jointname );
void Event_FireMissileAtTarget( const char *jointname, const char *targetname );
void Event_LaunchMissile( const idVec3 &muzzle, const idAngles &ang );
void Event_LaunchHomingMissile();
void Event_SetHomingMissileGoal();
void Event_LaunchProjectile( const char *entityDefName );
void Event_AttackMelee( const char *meleeDefName );
void Event_DirectDamage( idEntity *damageTarget, const char *damageDefName );
void Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName );
void Event_BeginAttack( const char *name );
void Event_EndAttack();
void Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName );
void Event_RandomPath();
void Event_CanBecomeSolid();
void Event_BecomeSolid();
void Event_BecomeNonSolid();
void Event_BecomeRagdoll();
void Event_StopRagdoll();
void Event_SetHealth( float newHealth );
void Event_GetHealth();
void Event_AllowDamage();
void Event_IgnoreDamage();
void Event_GetCurrentYaw();
void Event_TurnTo( float angle );
void Event_TurnToPos( const idVec3 &pos );
void Event_TurnToEntity( idEntity *ent );
void Event_MoveStatus();
void Event_StopMove();
void Event_MoveToCover();
void Event_MoveToEnemy();
void Event_MoveToEnemyHeight();
void Event_MoveOutOfRange( idEntity *entity, float range );
void Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim );
void Event_MoveToEntity( idEntity *ent );
void Event_MoveToPosition( const idVec3 &pos );
void Event_SlideTo( const idVec3 &pos, float time );
void Event_Wander();
void Event_FacingIdeal();
void Event_FaceEnemy();
void Event_FaceEntity( idEntity *ent );
void Event_WaitAction( const char *waitForState );
void Event_GetCombatNode();
void Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location );
void Event_WaitMove();
void Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height );
void Event_EntityInAttackCone( idEntity *ent );
void Event_CanSeeEntity( idEntity *ent );
void Event_SetTalkTarget( idEntity *target );
void Event_GetTalkTarget();
void Event_SetTalkState( int state );
void Event_EnemyRange();
void Event_EnemyRange2D();
void Event_GetEnemy();
void Event_GetEnemyPos();
void Event_GetEnemyEyePos();
void Event_PredictEnemyPos( float time );
void Event_CanHitEnemy();
void Event_CanHitEnemyFromAnim( const char *animname );
void Event_CanHitEnemyFromJoint( const char *jointname );
void Event_EnemyPositionValid();
void Event_ChargeAttack( const char *damageDef );
void Event_TestChargeAttack();
void Event_TestAnimMoveTowardEnemy( const char *animname );
void Event_TestAnimMove( const char *animname );
void Event_TestMoveToPosition( const idVec3 &position );
void Event_TestMeleeAttack();
void Event_TestAnimAttack( const char *animname );
void Event_Burn();
void Event_PreBurn();
void Event_ClearBurn();
void Event_SetSmokeVisibility( int num, int on );
void Event_NumSmokeEmitters();
void Event_StopThinking();
void Event_GetTurnDelta();
void Event_GetMoveType();
void Event_SetMoveType( int moveType );
void Event_SaveMove();
void Event_RestoreMove();
void Event_AllowMovement( float flag );
void Event_JumpFrame();
void Event_EnableClip();
void Event_DisableClip();
void Event_EnableGravity();
void Event_DisableGravity();
void Event_EnableAFPush();
void Event_DisableAFPush();
void Event_SetFlySpeed( float speed );
void Event_SetFlyOffset( int offset );
void Event_ClearFlyOffset();
void Event_GetClosestHiddenTarget( const char *type );
void Event_GetRandomTarget( const char *type );
void Event_TravelDistanceToPoint( const idVec3 &pos );
void Event_TravelDistanceToEntity( idEntity *ent );
void Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest );
void Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest );
void Event_LookAtEntity( idEntity *ent, float duration );
void Event_LookAtEnemy( float duration );
void Event_SetJointMod( int allowJointMod );
void Event_ThrowMoveable();
void Event_ThrowAF();
void Event_SetAngles( idAngles const &ang );
void Event_GetAngles();
void Event_GetTrajectoryToPlayer();
void Event_RealKill();
void Event_Kill();
void Event_WakeOnFlashlight( int enable );
void Event_LocateEnemy();
void Event_KickObstacles( idEntity *kickEnt, float force );
void Event_GetObstacle();
void Event_PushPointIntoAAS( const idVec3 &pos );
void Event_GetTurnRate();
void Event_SetTurnRate( float rate );
void Event_AnimTurn( float angles );
void Event_AllowHiddenMovement( int enable );
void Event_TriggerParticles( const char *jointName );
void Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs );
void Event_CanReachPosition( const idVec3 &pos );
void Event_CanReachEntity( idEntity *ent );
void Event_CanReachEnemy();
void Event_GetReachableEntityPosition( idEntity *ent );
void Event_MoveToPositionDirect( const idVec3 &pos );
void Event_AvoidObstacles( int ignore);
void Event_TriggerFX( const char* joint, const char* fx );
void Event_StartEmitter( const char* name, const char* joint, const char* particle );
void Event_GetEmitter( const char* name );
void Event_StopEmitter( const char* name );
};
class idCombatNode : public idEntity {
public:
CLASS_PROTOTYPE( idCombatNode );
idCombatNode();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Spawn();
bool IsDisabled() const;
bool EntityInView( idActor *actor, const idVec3 &pos );
static void DrawDebugInfo();
private:
float min_dist;
float max_dist;
float cone_dist;
float min_height;
float max_height;
idVec3 cone_left;
idVec3 cone_right;
idVec3 offset;
bool disabled;
void Event_Activate( idEntity *activator );
void Event_MarkUsed();
};
#endif /* !__AI_H__ */

149
neo/d3xp/ai/AI_Vagary.cpp Normal file
View File

@@ -0,0 +1,149 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/***********************************************************************
game/ai/AI_Vagary.cpp
Vagary specific AI code
***********************************************************************/
#pragma hdrstop
#include "../../idlib/precompiled.h"
#include "../Game_local.h"
class idAI_Vagary : public idAI {
public:
CLASS_PROTOTYPE( idAI_Vagary );
private:
void Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset );
void Event_ThrowObjectAtEnemy( idEntity *ent, float speed );
};
const idEventDef AI_Vagary_ChooseObjectToThrow( "vagary_ChooseObjectToThrow", "vvfff", 'e' );
const idEventDef AI_Vagary_ThrowObjectAtEnemy( "vagary_ThrowObjectAtEnemy", "ef" );
CLASS_DECLARATION( idAI, idAI_Vagary )
EVENT( AI_Vagary_ChooseObjectToThrow, idAI_Vagary::Event_ChooseObjectToThrow )
EVENT( AI_Vagary_ThrowObjectAtEnemy, idAI_Vagary::Event_ThrowObjectAtEnemy )
END_CLASS
/*
================
idAI_Vagary::Event_ChooseObjectToThrow
================
*/
void idAI_Vagary::Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset ) {
idEntity * ent;
idEntity * entityList[ MAX_GENTITIES ];
int numListedEntities;
int i, index;
float dist;
idVec3 vel;
idVec3 offsetVec( 0, 0, offset );
idEntity *enemyEnt = enemy.GetEntity();
if ( !enemyEnt ) {
idThread::ReturnEntity( NULL );
return;
}
idVec3 enemyEyePos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset;
const idBounds &myBounds = physicsObj.GetAbsBounds();
idBounds checkBounds( mins, maxs );
checkBounds.TranslateSelf( physicsObj.GetOrigin() );
numListedEntities = gameLocal.clip.EntitiesTouchingBounds( checkBounds, -1, entityList, MAX_GENTITIES );
index = gameLocal.random.RandomInt( numListedEntities );
for ( i = 0; i < numListedEntities; i++, index++ ) {
if ( index >= numListedEntities ) {
index = 0;
}
ent = entityList[ index ];
if ( !ent->IsType( idMoveable::Type ) ) {
continue;
}
if ( ent->fl.hidden ) {
// don't throw hidden objects
continue;
}
idPhysics *entPhys = ent->GetPhysics();
const idVec3 &entOrg = entPhys->GetOrigin();
dist = ( entOrg - enemyEyePos ).LengthFast();
if ( dist < minDist ) {
continue;
}
idBounds expandedBounds = myBounds.Expand( entPhys->GetBounds().GetRadius() );
if ( expandedBounds.LineIntersection( entOrg, enemyEyePos ) ) {
// ignore objects that are behind us
continue;
}
if ( PredictTrajectory( entPhys->GetOrigin() + offsetVec, enemyEyePos, speed, entPhys->GetGravity(),
entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel ) ) {
idThread::ReturnEntity( ent );
return;
}
}
idThread::ReturnEntity( NULL );
}
/*
================
idAI_Vagary::Event_ThrowObjectAtEnemy
================
*/
void idAI_Vagary::Event_ThrowObjectAtEnemy( idEntity *ent, float speed ) {
idVec3 vel;
idEntity *enemyEnt;
idPhysics *entPhys;
entPhys = ent->GetPhysics();
enemyEnt = enemy.GetEntity();
if ( !enemyEnt ) {
vel = ( viewAxis[ 0 ] * physicsObj.GetGravityAxis() ) * speed;
} else {
PredictTrajectory( entPhys->GetOrigin(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, speed, entPhys->GetGravity(),
entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel );
vel *= speed;
}
entPhys->SetLinearVelocity( vel );
if ( ent->IsType( idMoveable::Type ) ) {
idMoveable *ment = static_cast<idMoveable*>( ent );
ment->EnableDamage( true, 2.5f );
}
}

2986
neo/d3xp/ai/AI_events.cpp Normal file

File diff suppressed because it is too large Load Diff

1535
neo/d3xp/ai/AI_pathing.cpp Normal file

File diff suppressed because it is too large Load Diff

1177
neo/d3xp/anim/Anim.cpp Normal file

File diff suppressed because it is too large Load Diff

598
neo/d3xp/anim/Anim.h Normal file
View File

@@ -0,0 +1,598 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __ANIM_H__
#define __ANIM_H__
//
// animation channels
// these can be changed by modmakers and licensees to be whatever they need.
const int ANIM_NumAnimChannels = 5;
const int ANIM_MaxAnimsPerChannel = 3;
const int ANIM_MaxSyncedAnims = 3;
//
// animation channels. make sure to change script/doom_defs.script if you add any channels, or change their order
//
const int ANIMCHANNEL_ALL = 0;
const int ANIMCHANNEL_TORSO = 1;
const int ANIMCHANNEL_LEGS = 2;
const int ANIMCHANNEL_HEAD = 3;
const int ANIMCHANNEL_EYELIDS = 4;
// for converting from 24 frames per second to milliseconds
ID_INLINE int FRAME2MS( int framenum ) {
return ( framenum * 1000 ) / 24;
}
class idRenderModel;
class idAnimator;
class idAnimBlend;
class function_t;
class idEntity;
class idSaveGame;
class idRestoreGame;
typedef struct {
int cycleCount; // how many times the anim has wrapped to the begining (0 for clamped anims)
int frame1;
int frame2;
float frontlerp;
float backlerp;
} frameBlend_t;
typedef struct {
int nameIndex;
int parentNum;
int animBits;
int firstComponent;
} jointAnimInfo_t;
typedef struct {
jointHandle_t num;
jointHandle_t parentNum;
int channel;
} jointInfo_t;
//
// joint modifier modes. make sure to change script/doom_defs.script if you add any, or change their order.
//
typedef enum {
JOINTMOD_NONE, // no modification
JOINTMOD_LOCAL, // modifies the joint's position or orientation in joint local space
JOINTMOD_LOCAL_OVERRIDE, // sets the joint's position or orientation in joint local space
JOINTMOD_WORLD, // modifies joint's position or orientation in model space
JOINTMOD_WORLD_OVERRIDE // sets the joint's position or orientation in model space
} jointModTransform_t;
typedef struct {
jointHandle_t jointnum;
idMat3 mat;
idVec3 pos;
jointModTransform_t transform_pos;
jointModTransform_t transform_axis;
} jointMod_t;
#define ANIM_BIT_TX 0
#define ANIM_BIT_TY 1
#define ANIM_BIT_TZ 2
#define ANIM_BIT_QX 3
#define ANIM_BIT_QY 4
#define ANIM_BIT_QZ 5
#define ANIM_TX BIT( ANIM_BIT_TX )
#define ANIM_TY BIT( ANIM_BIT_TY )
#define ANIM_TZ BIT( ANIM_BIT_TZ )
#define ANIM_QX BIT( ANIM_BIT_QX )
#define ANIM_QY BIT( ANIM_BIT_QY )
#define ANIM_QZ BIT( ANIM_BIT_QZ )
typedef enum {
FC_SCRIPTFUNCTION,
FC_SCRIPTFUNCTIONOBJECT,
FC_EVENTFUNCTION,
FC_SOUND,
FC_SOUND_VOICE,
FC_SOUND_VOICE2,
FC_SOUND_BODY,
FC_SOUND_BODY2,
FC_SOUND_BODY3,
FC_SOUND_WEAPON,
FC_SOUND_ITEM,
FC_SOUND_GLOBAL,
FC_SOUND_CHATTER,
FC_SKIN,
FC_TRIGGER,
FC_TRIGGER_SMOKE_PARTICLE,
FC_MELEE,
FC_DIRECTDAMAGE,
FC_BEGINATTACK,
FC_ENDATTACK,
FC_MUZZLEFLASH,
FC_CREATEMISSILE,
FC_LAUNCHMISSILE,
FC_FIREMISSILEATTARGET,
FC_FOOTSTEP,
FC_LEFTFOOT,
FC_RIGHTFOOT,
FC_ENABLE_EYE_FOCUS,
FC_DISABLE_EYE_FOCUS,
FC_FX,
FC_DISABLE_GRAVITY,
FC_ENABLE_GRAVITY,
FC_JUMP,
FC_ENABLE_CLIP,
FC_DISABLE_CLIP,
FC_ENABLE_WALK_IK,
FC_DISABLE_WALK_IK,
FC_ENABLE_LEG_IK,
FC_DISABLE_LEG_IK,
FC_RECORDDEMO,
FC_AVIGAME
, FC_LAUNCH_PROJECTILE,
FC_TRIGGER_FX,
FC_START_EMITTER,
FC_STOP_EMITTER,
} frameCommandType_t;
typedef struct {
int num;
int firstCommand;
} frameLookup_t;
typedef struct {
frameCommandType_t type;
idStr *string;
union {
const idSoundShader *soundShader;
const function_t *function;
const idDeclSkin *skin;
int index;
};
} frameCommand_t;
typedef struct {
bool prevent_idle_override : 1;
bool random_cycle_start : 1;
bool ai_no_turn : 1;
bool anim_turn : 1;
} animFlags_t;
/*
==============================================================================================
idMD5Anim
==============================================================================================
*/
class idMD5Anim {
private:
int numFrames;
int frameRate;
int animLength;
int numJoints;
int numAnimatedComponents;
idList<idBounds, TAG_MD5_ANIM> bounds;
idList<jointAnimInfo_t, TAG_MD5_ANIM> jointInfo;
idList<idJointQuat, TAG_MD5_ANIM> baseFrame;
idList<float, TAG_MD5_ANIM> componentFrames;
idStr name;
idVec3 totaldelta;
mutable int ref_count;
public:
idMD5Anim();
~idMD5Anim();
void Free();
bool Reload();
size_t Allocated() const;
size_t Size() const { return sizeof( *this ) + Allocated(); };
bool LoadAnim( const char *filename );
bool LoadBinary( idFile * file, ID_TIME_T sourceTimeStamp );
void WriteBinary( idFile * file, ID_TIME_T sourceTimeStamp );
void IncreaseRefs() const;
void DecreaseRefs() const;
int NumRefs() const;
void CheckModelHierarchy( const idRenderModel *model ) const;
void GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const;
void GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const;
int Length() const;
int NumFrames() const;
int NumJoints() const;
const idVec3 &TotalMovementDelta() const;
const char *Name() const;
void GetFrameBlend( int framenum, frameBlend_t &frame ) const; // frame 1 is first frame
void ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const;
void GetOrigin( idVec3 &offset, int currentTime, int cyclecount ) const;
void GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const;
void GetBounds( idBounds &bounds, int currentTime, int cyclecount ) const;
};
/*
==============================================================================================
idAnim
==============================================================================================
*/
class idAnim {
private:
const class idDeclModelDef *modelDef;
const idMD5Anim *anims[ ANIM_MaxSyncedAnims ];
int numAnims;
idStr name;
idStr realname;
idList<frameLookup_t, TAG_ANIM> frameLookup;
idList<frameCommand_t, TAG_ANIM> frameCommands;
animFlags_t flags;
public:
idAnim();
idAnim( const idDeclModelDef *modelDef, const idAnim *anim );
~idAnim();
void SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] );
const char *Name() const;
const char *FullName() const;
const idMD5Anim *MD5Anim( int num ) const;
const idDeclModelDef *ModelDef() const;
int Length() const;
int NumFrames() const;
int NumAnims() const;
const idVec3 &TotalMovementDelta() const;
bool GetOrigin( idVec3 &offset, int animNum, int time, int cyclecount ) const;
bool GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const;
bool GetBounds( idBounds &bounds, int animNum, int time, int cyclecount ) const;
const char *AddFrameCommand( const class idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def );
void CallFrameCommands( idEntity *ent, int from, int to ) const;
bool HasFrameCommands() const;
// returns first frame (zero based) that command occurs. returns -1 if not found.
int FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const;
void SetAnimFlags( const animFlags_t &animflags );
const animFlags_t &GetAnimFlags() const;
};
/*
==============================================================================================
idDeclModelDef
==============================================================================================
*/
class idDeclModelDef : public idDecl {
public:
idDeclModelDef();
~idDeclModelDef();
virtual size_t Size() const;
virtual const char * DefaultDefinition() const;
virtual bool Parse( const char *text, const int textLength, bool allowBinaryVersion );
virtual void FreeData();
void Touch() const;
const idDeclSkin * GetDefaultSkin() const;
const idJointQuat * GetDefaultPose() const;
void SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const;
idRenderModel * ModelHandle() const;
void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const;
const jointInfo_t * FindJoint( const char *name ) const;
int NumAnims() const;
const idAnim * GetAnim( int index ) const;
int GetSpecificAnim( const char *name ) const;
int GetAnim( const char *name ) const;
bool HasAnim( const char *name ) const;
const idDeclSkin * GetSkin() const;
const char * GetModelName() const;
const idList<jointInfo_t> & Joints() const;
const int * JointParents() const;
int NumJoints() const;
const jointInfo_t * GetJoint( int jointHandle ) const;
const char * GetJointName( int jointHandle ) const;
int NumJointsOnChannel( int channel ) const;
const int * GetChannelJoints( int channel ) const;
const idVec3 & GetVisualOffset() const;
private:
void CopyDecl( const idDeclModelDef *decl );
bool ParseAnim( idLexer &src, int numDefaultAnims );
private:
idVec3 offset;
idList<jointInfo_t, TAG_ANIM> joints;
idList<int, TAG_ANIM> jointParents;
idList<int, TAG_ANIM> channelJoints[ ANIM_NumAnimChannels ];
idRenderModel * modelHandle;
idList<idAnim *, TAG_ANIM> anims;
const idDeclSkin * skin;
};
/*
==============================================================================================
idAnimBlend
==============================================================================================
*/
class idAnimBlend {
private:
const class idDeclModelDef *modelDef;
int starttime;
int endtime;
int timeOffset;
float rate;
int blendStartTime;
int blendDuration;
float blendStartValue;
float blendEndValue;
float animWeights[ ANIM_MaxSyncedAnims ];
short cycle;
short frame;
short animNum;
bool allowMove;
bool allowFrameCommands;
friend class idAnimator;
void Reset( const idDeclModelDef *_modelDef );
void CallFrameCommands( idEntity *ent, int fromtime, int totime ) const;
void SetFrame( const idDeclModelDef *modelDef, int animnum, int frame, int currenttime, int blendtime );
void CycleAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime );
void PlayAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime );
bool BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOrigin, bool overrideBlend, bool printInfo ) const;
void BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const;
void BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const;
void BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const;
bool AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const;
public:
idAnimBlend();
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef );
const char *AnimName() const;
const char *AnimFullName() const;
float GetWeight( int currenttime ) const;
float GetFinalWeight() const;
void SetWeight( float newweight, int currenttime, int blendtime );
int NumSyncedAnims() const;
bool SetSyncedAnimWeight( int num, float weight );
void Clear( int currentTime, int clearTime );
bool IsDone( int currentTime ) const;
bool FrameHasChanged( int currentTime ) const;
int GetCycleCount() const;
void SetCycleCount( int count );
void SetPlaybackRate( int currentTime, float newRate );
float GetPlaybackRate() const;
void SetStartTime( int startTime );
int GetStartTime() const;
int GetEndTime() const;
int GetFrameNumber( int currenttime ) const;
int AnimTime( int currenttime ) const;
int NumFrames() const;
int Length() const;
int PlayLength() const;
void AllowMovement( bool allow );
void AllowFrameCommands( bool allow );
const idAnim *Anim() const;
int AnimNum() const;
};
/*
==============================================================================================
idAFPoseJointMod
==============================================================================================
*/
typedef enum {
AF_JOINTMOD_AXIS,
AF_JOINTMOD_ORIGIN,
AF_JOINTMOD_BOTH
} AFJointModType_t;
class idAFPoseJointMod {
public:
idAFPoseJointMod();
AFJointModType_t mod;
idMat3 axis;
idVec3 origin;
};
ID_INLINE idAFPoseJointMod::idAFPoseJointMod() {
mod = AF_JOINTMOD_AXIS;
axis.Identity();
origin.Zero();
}
/*
==============================================================================================
idAnimator
==============================================================================================
*/
class idAnimator {
public:
idAnimator();
~idAnimator();
size_t Allocated() const;
size_t Size() const;
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
void SetEntity( idEntity *ent );
idEntity *GetEntity() const ;
void RemoveOriginOffset( bool remove );
bool RemoveOrigin() const;
void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const;
int NumAnims() const;
const idAnim *GetAnim( int index ) const;
int GetAnim( const char *name ) const;
bool HasAnim( const char *name ) const;
void ServiceAnims( int fromtime, int totime );
bool IsAnimating( int currentTime ) const;
void GetJoints( int *numJoints, idJointMat **jointsPtr );
int NumJoints() const;
jointHandle_t GetFirstChild( jointHandle_t jointnum ) const;
jointHandle_t GetFirstChild( const char *name ) const;
idRenderModel *SetModel( const char *modelname );
idRenderModel *ModelHandle() const;
const idDeclModelDef *ModelDef() const;
void ForceUpdate();
void ClearForceUpdate();
bool CreateFrame( int animtime, bool force );
bool FrameHasChanged( int animtime ) const;
void GetDelta( int fromtime, int totime, idVec3 &delta ) const;
bool GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const;
void GetOrigin( int currentTime, idVec3 &pos ) const;
bool GetBounds( int currentTime, idBounds &bounds );
idAnimBlend *CurrentAnim( int channelNum );
void Clear( int channelNum, int currentTime, int cleartime );
void SetFrame( int channelNum, int animnum, int frame, int currenttime, int blendtime );
void CycleAnim( int channelNum, int animnum, int currenttime, int blendtime );
void PlayAnim( int channelNum, int animnum, int currenttime, int blendTime );
// copies the current anim from fromChannelNum to channelNum.
// the copied anim will have frame commands disabled to avoid executing them twice.
void SyncAnimChannels( int channelNum, int fromChannelNum, int currenttime, int blendTime );
void SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos );
void SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat );
void ClearJoint( jointHandle_t jointnum );
void ClearAllJoints();
void InitAFPose();
void SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin );
void FinishAFPose( int animnum, const idBounds &bounds, const int time );
void SetAFPoseBlendWeight( float blendWeight );
bool BlendAFPose( idJointQuat *blendFrame ) const;
void ClearAFPose();
void ClearAllAnims( int currentTime, int cleartime );
jointHandle_t GetJointHandle( const char *name ) const;
const char * GetJointName( jointHandle_t handle ) const;
int GetChannelForJoint( jointHandle_t joint ) const;
bool GetJointTransform( jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis );
bool GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis );
const animFlags_t GetAnimFlags( int animnum ) const;
int NumFrames( int animnum ) const;
int NumSyncedAnims( int animnum ) const;
const char *AnimName( int animnum ) const;
const char *AnimFullName( int animnum ) const;
int AnimLength( int animnum ) const;
const idVec3 &TotalMovementDelta( int animnum ) const;
private:
void FreeData();
void PushAnims( int channel, int currentTime, int blendTime );
private:
const idDeclModelDef * modelDef;
idEntity * entity;
idAnimBlend channels[ ANIM_NumAnimChannels ][ ANIM_MaxAnimsPerChannel ];
idList<jointMod_t *, TAG_ANIM> jointMods;
int numJoints;
idJointMat * joints;
mutable int lastTransformTime; // mutable because the value is updated in CreateFrame
mutable bool stoppedAnimatingUpdate;
bool removeOriginOffset;
bool forceUpdate;
idBounds frameBounds;
float AFPoseBlendWeight;
idList<int, TAG_ANIM> AFPoseJoints;
idList<idAFPoseJointMod, TAG_ANIM> AFPoseJointMods;
idList<idJointQuat, TAG_ANIM> AFPoseJointFrame;
idBounds AFPoseBounds;
int AFPoseTime;
};
/*
==============================================================================================
idAnimManager
==============================================================================================
*/
class idAnimManager {
public:
idAnimManager();
~idAnimManager();
static bool forceExport;
void Shutdown();
idMD5Anim * GetAnim( const char *name );
void Preload( const idPreloadManifest &manifest );
void ReloadAnims();
void ListAnims() const;
int JointIndex( const char *name );
const char * JointName( int index ) const;
void ClearAnimsInUse();
void FlushUnusedAnims();
private:
idHashTable<idMD5Anim *> animations;
idStrList jointnames;
idHashIndex jointnamesHash;
};
#endif /* !__ANIM_H__ */

5114
neo/d3xp/anim/Anim_Blend.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,901 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/*
=============================================================================
MODEL TESTING
Model viewing can begin with either "testmodel <modelname>"
The names must be the full pathname after the basedir, like
"models/weapons/v_launch/tris.md3" or "players/male/tris.md3"
Extension will default to ".ase" if not specified.
Testmodel will create a fake entity 100 units in front of the current view
position, directly facing the viewer. It will remain immobile, so you can
move around it to view it from different angles.
g_testModelRotate
g_testModelAnimate
g_testModelBlend
=============================================================================
*/
#pragma hdrstop
#include "../../idlib/precompiled.h"
#include "../Game_local.h"
CLASS_DECLARATION( idAnimatedEntity, idTestModel )
EVENT( EV_FootstepLeft, idTestModel::Event_Footstep )
EVENT( EV_FootstepRight, idTestModel::Event_Footstep )
END_CLASS
/*
================
idTestModel::idTestModel
================
*/
idTestModel::idTestModel() {
head = NULL;
headAnimator = NULL;
anim = 0;
headAnim = 0;
starttime = 0;
animtime = 0;
mode = 0;
frame = 0;
}
/*
================
idTestModel::Save
================
*/
void idTestModel::Save( idSaveGame *savefile ) {
}
/*
================
idTestModel::Restore
================
*/
void idTestModel::Restore( idRestoreGame *savefile ) {
// FIXME: one day we may actually want to save/restore test models, but for now we'll just delete them
delete this;
}
/*
================
idTestModel::Spawn
================
*/
void idTestModel::Spawn() {
idVec3 size;
idBounds bounds;
const char *headModel;
jointHandle_t joint;
idStr jointName;
idVec3 origin, modelOffset;
idMat3 axis;
const idKeyValue *kv;
copyJoints_t copyJoint;
if ( renderEntity.hModel && renderEntity.hModel->IsDefaultModel() && !animator.ModelDef() ) {
gameLocal.Warning( "Unable to create testmodel for '%s' : model defaulted", spawnArgs.GetString( "model" ) );
PostEventMS( &EV_Remove, 0 );
return;
}
mode = g_testModelAnimate.GetInteger();
animator.RemoveOriginOffset( g_testModelAnimate.GetInteger() == 1 );
physicsObj.SetSelf( this );
physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
physicsObj.SetAxis( GetPhysics()->GetAxis() );
if ( spawnArgs.GetVector( "mins", NULL, bounds[0] ) ) {
spawnArgs.GetVector( "maxs", NULL, bounds[1] );
physicsObj.SetClipBox( bounds, 1.0f );
physicsObj.SetContents( 0 );
} else if ( spawnArgs.GetVector( "size", NULL, size ) ) {
bounds[ 0 ].Set( size.x * -0.5f, size.y * -0.5f, 0.0f );
bounds[ 1 ].Set( size.x * 0.5f, size.y * 0.5f, size.z );
physicsObj.SetClipBox( bounds, 1.0f );
physicsObj.SetContents( 0 );
}
spawnArgs.GetVector( "offsetModel", "0 0 0", modelOffset );
// add the head model if it has one
headModel = spawnArgs.GetString( "def_head", "" );
if ( headModel[ 0 ] ) {
jointName = spawnArgs.GetString( "head_joint" );
joint = animator.GetJointHandle( jointName );
if ( joint == INVALID_JOINT ) {
gameLocal.Warning( "Joint '%s' not found for 'head_joint'", jointName.c_str() );
} else {
// copy any sounds in case we have frame commands on the head
idDict args;
const idKeyValue *sndKV = spawnArgs.MatchPrefix( "snd_", NULL );
while( sndKV ) {
args.Set( sndKV->GetKey(), sndKV->GetValue() );
sndKV = spawnArgs.MatchPrefix( "snd_", sndKV );
}
head = gameLocal.SpawnEntityType( idAnimatedEntity::Type, &args );
animator.GetJointTransform( joint, gameLocal.time, origin, axis );
origin = GetPhysics()->GetOrigin() + ( origin + modelOffset ) * GetPhysics()->GetAxis();
head.GetEntity()->SetModel( headModel );
head.GetEntity()->SetOrigin( origin );
head.GetEntity()->SetAxis( GetPhysics()->GetAxis() );
head.GetEntity()->BindToJoint( this, animator.GetJointName( joint ), true );
headAnimator = head.GetEntity()->GetAnimator();
// set up the list of joints to copy to the head
for( kv = spawnArgs.MatchPrefix( "copy_joint", NULL ); kv != NULL; kv = spawnArgs.MatchPrefix( "copy_joint", kv ) ) {
jointName = kv->GetKey();
if ( jointName.StripLeadingOnce( "copy_joint_world " ) ) {
copyJoint.mod = JOINTMOD_WORLD_OVERRIDE;
} else {
jointName.StripLeadingOnce( "copy_joint " );
copyJoint.mod = JOINTMOD_LOCAL_OVERRIDE;
}
copyJoint.from = animator.GetJointHandle( jointName );
if ( copyJoint.from == INVALID_JOINT ) {
gameLocal.Warning( "Unknown copy_joint '%s'", jointName.c_str() );
continue;
}
copyJoint.to = headAnimator->GetJointHandle( jointName );
if ( copyJoint.to == INVALID_JOINT ) {
gameLocal.Warning( "Unknown copy_joint '%s' on head", jointName.c_str() );
continue;
}
copyJoints.Append( copyJoint );
}
}
}
// start any shader effects based off of the spawn time
renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );
SetPhysics( &physicsObj );
gameLocal.Printf( "Added testmodel at origin = '%s', angles = '%s'\n", GetPhysics()->GetOrigin().ToString(), GetPhysics()->GetAxis().ToAngles().ToString() );
BecomeActive( TH_THINK );
}
/*
================
idTestModel::~idTestModel
================
*/
idTestModel::~idTestModel() {
StopSound( SND_CHANNEL_ANY, false );
if ( renderEntity.hModel ) {
gameLocal.Printf( "Removing testmodel %s\n", renderEntity.hModel->Name() );
} else {
gameLocal.Printf( "Removing testmodel\n" );
}
if ( gameLocal.testmodel == this ) {
gameLocal.testmodel = NULL;
}
if ( head.GetEntity() ) {
head.GetEntity()->StopSound( SND_CHANNEL_ANY, false );
head.GetEntity()->PostEventMS( &EV_Remove, 0 );
}
}
/*
===============
idTestModel::Event_Footstep
===============
*/
void idTestModel::Event_Footstep() {
StartSound( "snd_footstep", SND_CHANNEL_BODY, 0, false, NULL );
}
/*
================
idTestModel::ShouldConstructScriptObjectAtSpawn
Called during idEntity::Spawn to see if it should construct the script object or not.
Overridden by subclasses that need to spawn the script object themselves.
================
*/
bool idTestModel::ShouldConstructScriptObjectAtSpawn() const {
return false;
}
/*
================
idTestModel::Think
================
*/
void idTestModel::Think() {
idVec3 pos;
idMat3 axis;
idAngles ang;
int i;
if ( thinkFlags & TH_THINK ) {
if ( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) ) {
StopSound( SND_CHANNEL_ANY, false );
if ( head.GetEntity() ) {
head.GetEntity()->StopSound( SND_CHANNEL_ANY, false );
}
switch( g_testModelAnimate.GetInteger() ) {
default:
case 0:
// cycle anim with origin reset
if ( animator.NumFrames( anim ) <= 1 ) {
// single frame animations end immediately, so just cycle it since it's the same result
animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
if ( headAnim ) {
headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
}
} else {
animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
if ( headAnim ) {
headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) {
// loop the body anim when the head anim is longer
animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
}
}
}
animator.RemoveOriginOffset( false );
break;
case 1:
// cycle anim with fixed origin
animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
animator.RemoveOriginOffset( true );
if ( headAnim ) {
headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
}
break;
case 2:
// cycle anim with continuous origin
animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
animator.RemoveOriginOffset( false );
if ( headAnim ) {
headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
}
break;
case 3:
// frame by frame with continuous origin
animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
animator.RemoveOriginOffset( false );
if ( headAnim ) {
headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
}
break;
case 4:
// play anim once
animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
animator.RemoveOriginOffset( false );
if ( headAnim ) {
headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
}
break;
case 5:
// frame by frame with fixed origin
animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
animator.RemoveOriginOffset( true );
if ( headAnim ) {
headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
}
break;
}
mode = g_testModelAnimate.GetInteger();
}
if ( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) ) {
starttime = gameLocal.time;
StopSound( SND_CHANNEL_ANY, false );
animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
if ( headAnim ) {
headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
if ( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) {
// loop the body anim when the head anim is longer
animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
}
}
}
if ( headAnimator ) {
// copy the animation from the body to the head
for( i = 0; i < copyJoints.Num(); i++ ) {
if ( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) {
idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose();
GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
pos -= head.GetEntity()->GetPhysics()->GetOrigin();
headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat );
headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat );
} else {
animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos );
headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis );
}
}
}
// update rotation
RunPhysics();
physicsObj.GetAngles( ang );
physicsObj.SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero );
idClipModel *clip = physicsObj.GetClipModel();
if ( clip != NULL && animator.ModelDef() ) {
idVec3 neworigin;
idMat3 axis;
jointHandle_t joint;
joint = animator.GetJointHandle( "origin" );
animator.GetJointTransform( joint, gameLocal.time, neworigin, axis );
neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin();
clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() );
}
}
UpdateAnimation();
Present();
if ( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim ) {
gameLocal.Printf( "^5 Anim: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
if ( headAnim ) {
gameLocal.Printf( "^5 Head: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
} else {
gameLocal.Printf( "\n\n" );
}
}
}
/*
================
idTestModel::NextAnim
================
*/
void idTestModel::NextAnim( const idCmdArgs &args ) {
if ( !animator.NumAnims() ) {
return;
}
anim++;
if ( anim >= animator.NumAnims() ) {
// anim 0 is no anim
anim = 1;
}
starttime = gameLocal.time;
animtime = animator.AnimLength( anim );
animname = animator.AnimFullName( anim );
headAnim = 0;
if ( headAnimator ) {
headAnimator->ClearAllAnims( gameLocal.time, 0 );
headAnim = headAnimator->GetAnim( animname );
if ( !headAnim ) {
headAnim = headAnimator->GetAnim( "idle" );
}
if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) {
animtime = headAnimator->AnimLength( headAnim );
}
}
gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) );
if ( headAnim ) {
gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) );
}
// reset the anim
mode = -1;
frame = 1;
}
/*
================
idTestModel::PrevAnim
================
*/
void idTestModel::PrevAnim( const idCmdArgs &args ) {
if ( !animator.NumAnims() ) {
return;
}
anim--;
if ( anim < 0 ) {
anim = animator.NumAnims() - 1;
}
starttime = gameLocal.time;
animtime = animator.AnimLength( anim );
animname = animator.AnimFullName( anim );
headAnim = 0;
if ( headAnimator ) {
headAnimator->ClearAllAnims( gameLocal.time, 0 );
headAnim = headAnimator->GetAnim( animname );
if ( !headAnim ) {
headAnim = headAnimator->GetAnim( "idle" );
}
if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) {
animtime = headAnimator->AnimLength( headAnim );
}
}
gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) );
if ( headAnim ) {
gameLocal.Printf( "head '%s', %d.%03d seconds, %d frames\n", headAnimator->AnimFullName( headAnim ), headAnimator->AnimLength( headAnim ) / 1000, headAnimator->AnimLength( headAnim ) % 1000, headAnimator->NumFrames( headAnim ) );
}
// reset the anim
mode = -1;
frame = 1;
}
/*
================
idTestModel::NextFrame
================
*/
void idTestModel::NextFrame( const idCmdArgs &args ) {
if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) {
return;
}
frame++;
if ( frame > animator.NumFrames( anim ) ) {
frame = 1;
}
gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) );
// reset the anim
mode = -1;
}
/*
================
idTestModel::PrevFrame
================
*/
void idTestModel::PrevFrame( const idCmdArgs &args ) {
if ( !anim || ( ( g_testModelAnimate.GetInteger() != 3 ) && ( g_testModelAnimate.GetInteger() != 5 ) ) ) {
return;
}
frame--;
if ( frame < 1 ) {
frame = animator.NumFrames( anim );
}
gameLocal.Printf( "^5 Anim: ^7%s\n^5Frame: ^7%d/%d\n\n", animator.AnimFullName( anim ), frame, animator.NumFrames( anim ) );
// reset the anim
mode = -1;
}
/*
================
idTestModel::TestAnim
================
*/
void idTestModel::TestAnim( const idCmdArgs &args ) {
idStr name;
int animNum;
const idAnim *newanim;
if ( args.Argc() < 2 ) {
gameLocal.Printf( "usage: testanim <animname>\n" );
return;
}
newanim = NULL;
name = args.Argv( 1 );
animNum = animator.GetAnim( name );
if ( !animNum ) {
gameLocal.Printf( "Animation '%s' not found.\n", name.c_str() );
return;
}
anim = animNum;
starttime = gameLocal.time;
animtime = animator.AnimLength( anim );
headAnim = 0;
if ( headAnimator ) {
headAnimator->ClearAllAnims( gameLocal.time, 0 );
headAnim = headAnimator->GetAnim( animname );
if ( !headAnim ) {
headAnim = headAnimator->GetAnim( "idle" );
if ( !headAnim ) {
gameLocal.Printf( "Missing 'idle' anim for head.\n" );
}
}
if ( headAnim && ( headAnimator->AnimLength( headAnim ) > animtime ) ) {
animtime = headAnimator->AnimLength( headAnim );
}
}
animname = name;
gameLocal.Printf( "anim '%s', %d.%03d seconds, %d frames\n", animname.c_str(), animator.AnimLength( anim ) / 1000, animator.AnimLength( anim ) % 1000, animator.NumFrames( anim ) );
// reset the anim
mode = -1;
}
/*
=====================
idTestModel::BlendAnim
=====================
*/
void idTestModel::BlendAnim( const idCmdArgs &args ) {
int anim1;
int anim2;
if ( args.Argc() < 4 ) {
gameLocal.Printf( "usage: testblend <anim1> <anim2> <frames>\n" );
return;
}
anim1 = gameLocal.testmodel->animator.GetAnim( args.Argv( 1 ) );
if ( !anim1 ) {
gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 1 ) );
return;
}
anim2 = gameLocal.testmodel->animator.GetAnim( args.Argv( 2 ) );
if ( !anim2 ) {
gameLocal.Printf( "Animation '%s' not found.\n", args.Argv( 2 ) );
return;
}
animname = args.Argv( 2 );
animator.CycleAnim( ANIMCHANNEL_ALL, anim1, gameLocal.time, 0 );
animator.CycleAnim( ANIMCHANNEL_ALL, anim2, gameLocal.time, FRAME2MS( atoi( args.Argv( 3 ) ) ) );
anim = anim2;
headAnim = 0;
}
/***********************************************************************
Testmodel console commands
***********************************************************************/
/*
=================
idTestModel::KeepTestModel_f
Makes the current test model permanent, allowing you to place
multiple test models
=================
*/
void idTestModel::KeepTestModel_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No active testModel.\n" );
return;
}
gameLocal.Printf( "modelDef %p kept\n", gameLocal.testmodel->renderEntity.hModel );
gameLocal.testmodel = NULL;
}
/*
=================
idTestModel::TestSkin_f
Sets a skin on an existing testModel
=================
*/
void idTestModel::TestSkin_f( const idCmdArgs &args ) {
idVec3 offset;
idStr name;
idPlayer * player;
idDict dict;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
// delete the testModel if active
if ( !gameLocal.testmodel ) {
common->Printf( "No active testModel\n" );
return;
}
if ( args.Argc() < 2 ) {
common->Printf( "removing testSkin.\n" );
gameLocal.testmodel->SetSkin( NULL );
return;
}
name = args.Argv( 1 );
gameLocal.testmodel->SetSkin( declManager->FindSkin( name ) );
}
/*
=================
idTestModel::TestShaderParm_f
Sets a shaderParm on an existing testModel
=================
*/
void idTestModel::TestShaderParm_f( const idCmdArgs &args ) {
idVec3 offset;
idStr name;
idPlayer * player;
idDict dict;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
// delete the testModel if active
if ( !gameLocal.testmodel ) {
common->Printf( "No active testModel\n" );
return;
}
if ( args.Argc() != 3 ) {
common->Printf( "USAGE: testShaderParm <parmNum> <float | \"time\">\n" );
return;
}
int parm = atoi( args.Argv( 1 ) );
if ( parm < 0 || parm >= MAX_ENTITY_SHADER_PARMS ) {
common->Printf( "parmNum %i out of range\n", parm );
return;
}
float value;
if ( !idStr::Icmp( args.Argv( 2 ), "time" ) ) {
value = gameLocal.time * -0.001;
} else {
value = atof( args.Argv( 2 ) );
}
gameLocal.testmodel->SetShaderParm( parm, value );
}
/*
=================
idTestModel::TestModel_f
Creates a static modelDef in front of the current position, which
can then be moved around
=================
*/
void idTestModel::TestModel_f( const idCmdArgs &args ) {
idVec3 offset;
idStr name;
idPlayer * player;
const idDict * entityDef;
idDict dict;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
// delete the testModel if active
if ( gameLocal.testmodel ) {
delete gameLocal.testmodel;
gameLocal.testmodel = NULL;
}
if ( args.Argc() < 2 ) {
return;
}
name = args.Argv( 1 );
entityDef = gameLocal.FindEntityDefDict( name, false );
if ( entityDef ) {
dict = *entityDef;
} else {
if ( declManager->FindType( DECL_MODELDEF, name, false ) ) {
dict.Set( "model", name );
} else {
// allow map models with underscore prefixes to be tested during development
// without appending an ase
if ( name[ 0 ] != '_' ) {
name.DefaultFileExtension( ".ase" );
}
if ( !renderModelManager->CheckModel( name ) ) {
gameLocal.Printf( "Can't register model\n" );
return;
}
dict.Set( "model", name );
}
}
offset = player->GetPhysics()->GetOrigin() + player->viewAngles.ToForward() * 100.0f;
dict.Set( "origin", offset.ToString() );
dict.Set( "angle", va( "%f", player->viewAngles.yaw + 180.0f ) );
gameLocal.testmodel = ( idTestModel * )gameLocal.SpawnEntityType( idTestModel::Type, &dict );
gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_TIMEOFFSET] = -MS2SEC( gameLocal.time );
}
/*
=====================
idTestModel::ArgCompletion_TestModel
=====================
*/
void idTestModel::ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) ) {
int i, num;
num = declManager->GetNumDecls( DECL_ENTITYDEF );
for ( i = 0; i < num; i++ ) {
callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_ENTITYDEF, i , false )->GetName() );
}
num = declManager->GetNumDecls( DECL_MODELDEF );
for ( i = 0; i < num; i++ ) {
callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( DECL_MODELDEF, i , false )->GetName() );
}
cmdSystem->ArgCompletion_FolderExtension( args, callback, "models/", false, ".lwo", ".ase", ".md5mesh", ".ma", ".mb", NULL );
}
/*
=====================
idTestModel::TestParticleStopTime_f
=====================
*/
void idTestModel::TestParticleStopTime_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->renderEntity.shaderParms[SHADERPARM_PARTICLE_STOPTIME] = MS2SEC( gameLocal.time );
gameLocal.testmodel->UpdateVisuals();
}
/*
=====================
idTestModel::TestAnim_f
=====================
*/
void idTestModel::TestAnim_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->TestAnim( args );
}
/*
=====================
idTestModel::ArgCompletion_TestAnim
=====================
*/
void idTestModel::ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) ) {
if ( gameLocal.testmodel ) {
idAnimator *animator = gameLocal.testmodel->GetAnimator();
for( int i = 0; i < animator->NumAnims(); i++ ) {
callback( va( "%s %s", args.Argv( 0 ), animator->AnimFullName( i ) ) );
}
}
}
/*
=====================
idTestModel::TestBlend_f
=====================
*/
void idTestModel::TestBlend_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->BlendAnim( args );
}
/*
=====================
idTestModel::TestModelNextAnim_f
=====================
*/
void idTestModel::TestModelNextAnim_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->NextAnim( args );
}
/*
=====================
idTestModel::TestModelPrevAnim_f
=====================
*/
void idTestModel::TestModelPrevAnim_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->PrevAnim( args );
}
/*
=====================
idTestModel::TestModelNextFrame_f
=====================
*/
void idTestModel::TestModelNextFrame_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->NextFrame( args );
}
/*
=====================
idTestModel::TestModelPrevFrame_f
=====================
*/
void idTestModel::TestModelPrevFrame_f( const idCmdArgs &args ) {
if ( !gameLocal.testmodel ) {
gameLocal.Printf( "No testModel active.\n" );
return;
}
gameLocal.testmodel->PrevFrame( args );
}

View File

@@ -0,0 +1,95 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __ANIM_TESTMODEL_H__
#define __ANIM_TESTMODEL_H__
/*
==============================================================================================
idTestModel
==============================================================================================
*/
class idTestModel : public idAnimatedEntity {
public:
CLASS_PROTOTYPE( idTestModel );
idTestModel();
~idTestModel();
void Save( idSaveGame *savefile );
void Restore( idRestoreGame *savefile );
void Spawn();
virtual bool ShouldConstructScriptObjectAtSpawn() const;
void NextAnim( const idCmdArgs &args );
void PrevAnim( const idCmdArgs &args );
void NextFrame( const idCmdArgs &args );
void PrevFrame( const idCmdArgs &args );
void TestAnim( const idCmdArgs &args );
void BlendAnim( const idCmdArgs &args );
static void KeepTestModel_f( const idCmdArgs &args );
static void TestModel_f( const idCmdArgs &args );
static void ArgCompletion_TestModel( const idCmdArgs &args, void(*callback)( const char *s ) );
static void TestSkin_f( const idCmdArgs &args );
static void TestShaderParm_f( const idCmdArgs &args );
static void TestParticleStopTime_f( const idCmdArgs &args );
static void TestAnim_f( const idCmdArgs &args );
static void ArgCompletion_TestAnim( const idCmdArgs &args, void(*callback)( const char *s ) );
static void TestBlend_f( const idCmdArgs &args );
static void TestModelNextAnim_f( const idCmdArgs &args );
static void TestModelPrevAnim_f( const idCmdArgs &args );
static void TestModelNextFrame_f( const idCmdArgs &args );
static void TestModelPrevFrame_f( const idCmdArgs &args );
private:
idEntityPtr<idEntity> head;
idAnimator *headAnimator;
idAnim customAnim;
idPhysics_Parametric physicsObj;
idStr animname;
int anim;
int headAnim;
int mode;
int frame;
int starttime;
int animtime;
idList<copyJoints_t> copyJoints;
virtual void Think();
void Event_Footstep();
};
#endif /* !__ANIM_TESTMODEL_H__*/

File diff suppressed because it is too large Load Diff

1025
neo/d3xp/gamesys/Class.cpp Normal file

File diff suppressed because it is too large Load Diff

349
neo/d3xp/gamesys/Class.h Normal file
View File

@@ -0,0 +1,349 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/*
Base class for all game objects. Provides fast run-time type checking and run-time
instancing of objects.
*/
#ifndef __SYS_CLASS_H__
#define __SYS_CLASS_H__
class idClass;
class idTypeInfo;
extern const idEventDef EV_Remove;
extern const idEventDef EV_SafeRemove;
typedef void ( idClass::*eventCallback_t )();
template< class Type >
struct idEventFunc {
const idEventDef *event;
eventCallback_t function;
};
// added & so gcc could compile this
#define EVENT( event, function ) { &( event ), ( void ( idClass::* )() )( &function ) },
#define END_CLASS { NULL, NULL } };
class idEventArg {
public:
int type;
int value;
idEventArg() { type = D_EVENT_INTEGER; value = 0; };
idEventArg( int data ) { type = D_EVENT_INTEGER; value = data; };
idEventArg( float data ) { type = D_EVENT_FLOAT; value = *reinterpret_cast<int *>( &data ); };
idEventArg( idVec3 &data ) { type = D_EVENT_VECTOR; value = reinterpret_cast<int>( &data ); };
idEventArg( const idStr &data ) { type = D_EVENT_STRING; value = reinterpret_cast<int>( data.c_str() ); };
idEventArg( const char *data ) { type = D_EVENT_STRING; value = reinterpret_cast<int>( data ); };
idEventArg( const class idEntity *data ) { type = D_EVENT_ENTITY; value = reinterpret_cast<int>( data ); };
idEventArg( const struct trace_s *data ) { type = D_EVENT_TRACE; value = reinterpret_cast<int>( data ); };
};
class idAllocError : public idException {
public:
idAllocError( const char *text = "" ) : idException( text ) {}
};
/***********************************************************************
idClass
***********************************************************************/
/*
================
CLASS_PROTOTYPE
This macro must be included in the definition of any subclass of idClass.
It prototypes variables used in class instanciation and type checking.
Use this on single inheritance concrete classes only.
================
*/
#define CLASS_PROTOTYPE( nameofclass ) \
public: \
static idTypeInfo Type; \
static idClass *CreateInstance(); \
virtual idTypeInfo *GetType() const; \
static idEventFunc<nameofclass> eventCallbacks[]
/*
================
CLASS_DECLARATION
This macro must be included in the code to properly initialize variables
used in type checking and run-time instanciation. It also defines the list
of events that the class responds to. Take special care to ensure that the
proper superclass is indicated or the run-time type information will be
incorrect. Use this on concrete classes only.
================
*/
#define CLASS_DECLARATION( nameofsuperclass, nameofclass ) \
idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \
( idEventFunc<idClass> * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )() )&nameofclass::Spawn, \
( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \
idClass *nameofclass::CreateInstance() { \
try { \
nameofclass *ptr = new nameofclass; \
ptr->FindUninitializedMemory(); \
return ptr; \
} \
catch( idAllocError & ) { \
return NULL; \
} \
} \
idTypeInfo *nameofclass::GetType() const { \
return &( nameofclass::Type ); \
} \
idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
/*
================
ABSTRACT_PROTOTYPE
This macro must be included in the definition of any abstract subclass of idClass.
It prototypes variables used in class instanciation and type checking.
Use this on single inheritance abstract classes only.
================
*/
#define ABSTRACT_PROTOTYPE( nameofclass ) \
public: \
static idTypeInfo Type; \
static idClass *CreateInstance(); \
virtual idTypeInfo *GetType() const; \
static idEventFunc<nameofclass> eventCallbacks[]
/*
================
ABSTRACT_DECLARATION
This macro must be included in the code to properly initialize variables
used in type checking. It also defines the list of events that the class
responds to. Take special care to ensure that the proper superclass is
indicated or the run-time tyep information will be incorrect. Use this
on abstract classes only.
================
*/
#define ABSTRACT_DECLARATION( nameofsuperclass, nameofclass ) \
idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass, \
( idEventFunc<idClass> * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )() )&nameofclass::Spawn, \
( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore ); \
idClass *nameofclass::CreateInstance() { \
gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass ); \
return NULL; \
} \
idTypeInfo *nameofclass::GetType() const { \
return &( nameofclass::Type ); \
} \
idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
typedef void ( idClass::*classSpawnFunc_t )();
class idSaveGame;
class idRestoreGame;
class idClass {
public:
ABSTRACT_PROTOTYPE( idClass );
void * operator new( size_t );
void operator delete( void * );
virtual ~idClass();
void Spawn();
void CallSpawn();
bool IsType( const idTypeInfo &c ) const;
const char * GetClassname() const;
const char * GetSuperclass() const;
void FindUninitializedMemory();
void Save( idSaveGame *savefile ) const {};
void Restore( idRestoreGame *savefile ) {};
bool RespondsTo( const idEventDef &ev ) const;
bool PostEventMS( const idEventDef *ev, int time );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
bool PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
bool PostEventSec( const idEventDef *ev, float time );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
bool PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
bool ProcessEvent( const idEventDef *ev );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
bool ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
bool ProcessEventArgPtr( const idEventDef *ev, int *data );
void CancelEvents( const idEventDef *ev );
void Event_Remove();
// Static functions
static void Init();
static void Shutdown();
static idTypeInfo * GetClass( const char *name );
static void DisplayInfo_f( const idCmdArgs &args );
static void ListClasses_f( const idCmdArgs &args );
static idClass * CreateInstance( const char *name );
static int GetNumTypes() { return types.Num(); }
static int GetTypeNumBits() { return typeNumBits; }
static idTypeInfo * GetType( int num );
private:
classSpawnFunc_t CallSpawnFunc( idTypeInfo *cls );
bool PostEventArgs( const idEventDef *ev, int time, int numargs, ... );
bool ProcessEventArgs( const idEventDef *ev, int numargs, ... );
void Event_SafeRemove();
static bool initialized;
static idList<idTypeInfo *, TAG_IDCLASS> types;
static idList<idTypeInfo *, TAG_IDCLASS> typenums;
static int typeNumBits;
static int memused;
static int numobjects;
};
/***********************************************************************
idTypeInfo
***********************************************************************/
class idTypeInfo {
public:
const char * classname;
const char * superclass;
idClass * ( *CreateInstance )();
void ( idClass::*Spawn )();
void ( idClass::*Save )( idSaveGame *savefile ) const;
void ( idClass::*Restore )( idRestoreGame *savefile );
idEventFunc<idClass> * eventCallbacks;
eventCallback_t * eventMap;
idTypeInfo * super;
idTypeInfo * next;
bool freeEventMap;
int typeNum;
int lastChild;
idHierarchy<idTypeInfo> node;
idTypeInfo( const char *classname, const char *superclass,
idEventFunc<idClass> *eventCallbacks, idClass *( *CreateInstance )(), void ( idClass::*Spawn )(),
void ( idClass::*Save )( idSaveGame *savefile ) const, void ( idClass::*Restore )( idRestoreGame *savefile ) );
~idTypeInfo();
void Init();
void Shutdown();
bool IsType( const idTypeInfo &superclass ) const;
bool RespondsTo( const idEventDef &ev ) const;
};
/*
================
idTypeInfo::IsType
Checks if the object's class is a subclass of the class defined by the
passed in idTypeInfo.
================
*/
ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const {
return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) );
}
/*
================
idTypeInfo::RespondsTo
================
*/
ID_INLINE bool idTypeInfo::RespondsTo( const idEventDef &ev ) const {
assert( idEvent::initialized );
if ( !eventMap[ ev.GetEventNum() ] ) {
// we don't respond to this event
return false;
}
return true;
}
/*
================
idClass::IsType
Checks if the object's class is a subclass of the class defined by the
passed in idTypeInfo.
================
*/
ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const {
idTypeInfo *subclass;
subclass = GetType();
return subclass->IsType( superclass );
}
/*
================
idClass::RespondsTo
================
*/
ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const {
const idTypeInfo *c;
assert( idEvent::initialized );
c = GetType();
return c->RespondsTo( ev );
}
#endif /* !__SYS_CLASS_H__ */

1062
neo/d3xp/gamesys/Event.cpp Normal file

File diff suppressed because it is too large Load Diff

210
neo/d3xp/gamesys/Event.h Normal file
View File

@@ -0,0 +1,210 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
/*
sys_event.h
Event are used for scheduling tasks and for linking script commands.
*/
#ifndef __SYS_EVENT_H__
#define __SYS_EVENT_H__
#define D_EVENT_MAXARGS 8 // if changed, enable the CREATE_EVENT_CODE define in Event.cpp to generate switch statement for idClass::ProcessEventArgPtr.
// running the game will then generate c:\doom\base\events.txt, the contents of which should be copied into the switch statement.
#define D_EVENT_VOID ( ( char )0 )
#define D_EVENT_INTEGER 'd'
#define D_EVENT_FLOAT 'f'
#define D_EVENT_VECTOR 'v'
#define D_EVENT_STRING 's'
#define D_EVENT_ENTITY 'e'
#define D_EVENT_ENTITY_NULL 'E' // event can handle NULL entity pointers
#define D_EVENT_TRACE 't'
#define MAX_EVENTS 4096
class idClass;
class idTypeInfo;
class idEventDef {
private:
const char *name;
const char *formatspec;
unsigned int formatspecIndex;
int returnType;
int numargs;
size_t argsize;
int argOffset[ D_EVENT_MAXARGS ];
int eventnum;
const idEventDef * next;
static idEventDef * eventDefList[MAX_EVENTS];
static int numEventDefs;
public:
idEventDef( const char *command, const char *formatspec = NULL, char returnType = 0 );
const char *GetName() const;
const char *GetArgFormat() const;
unsigned int GetFormatspecIndex() const;
char GetReturnType() const;
int GetEventNum() const;
int GetNumArgs() const;
size_t GetArgSize() const;
int GetArgOffset( int arg ) const;
static int NumEventCommands();
static const idEventDef *GetEventCommand( int eventnum );
static const idEventDef *FindEvent( const char *name );
};
class idSaveGame;
class idRestoreGame;
class idEvent {
private:
const idEventDef *eventdef;
byte *data;
int time;
idClass *object;
const idTypeInfo *typeinfo;
idLinkList<idEvent> eventNode;
static idDynamicBlockAlloc<byte, 16 * 1024, 256> eventDataAllocator;
public:
static bool initialized;
~idEvent();
static idEvent *Alloc( const idEventDef *evdef, int numargs, va_list args );
static void CopyArgs( const idEventDef *evdef, int numargs, va_list args, int data[ D_EVENT_MAXARGS ] );
void Free();
void Schedule( idClass *object, const idTypeInfo *cls, int time );
byte *GetData();
static void CancelEvents( const idClass *obj, const idEventDef *evdef = NULL );
static void ClearEventList();
static void ServiceEvents();
static void ServiceFastEvents();
static void Init();
static void Shutdown();
// save games
static void Save( idSaveGame *savefile ); // archives object for save game file
static void Restore( idRestoreGame *savefile ); // unarchives object from save game file
static void SaveTrace( idSaveGame *savefile, const trace_t &trace );
static void RestoreTrace( idRestoreGame *savefile, trace_t &trace );
};
/*
================
idEvent::GetData
================
*/
ID_INLINE byte *idEvent::GetData() {
return data;
}
/*
================
idEventDef::GetName
================
*/
ID_INLINE const char *idEventDef::GetName() const {
return name;
}
/*
================
idEventDef::GetArgFormat
================
*/
ID_INLINE const char *idEventDef::GetArgFormat() const {
return formatspec;
}
/*
================
idEventDef::GetFormatspecIndex
================
*/
ID_INLINE unsigned int idEventDef::GetFormatspecIndex() const {
return formatspecIndex;
}
/*
================
idEventDef::GetReturnType
================
*/
ID_INLINE char idEventDef::GetReturnType() const {
return returnType;
}
/*
================
idEventDef::GetNumArgs
================
*/
ID_INLINE int idEventDef::GetNumArgs() const {
return numargs;
}
/*
================
idEventDef::GetArgSize
================
*/
ID_INLINE size_t idEventDef::GetArgSize() const {
return argsize;
}
/*
================
idEventDef::GetArgOffset
================
*/
ID_INLINE int idEventDef::GetArgOffset( int arg ) const {
assert( ( arg >= 0 ) && ( arg < D_EVENT_MAXARGS ) );
return argOffset[ arg ];
}
/*
================
idEventDef::GetEventNum
================
*/
ID_INLINE int idEventDef::GetEventNum() const {
return eventnum;
}
#endif /* !__SYS_EVENT_H__ */

File diff suppressed because it is too large Load Diff

182
neo/d3xp/gamesys/SaveGame.h Normal file
View File

@@ -0,0 +1,182 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __SAVEGAME_H__
#define __SAVEGAME_H__
/*
Save game related helper classes.
*/
class idSaveGame {
public:
idSaveGame( idFile *savefile, idFile *stringFile, int inVersion );
~idSaveGame();
void Close();
void WriteDecls();
void AddObject( const idClass *obj );
void Resize( const int count ) { objects.Resize( count ); }
void WriteObjectList();
void Write( const void *buffer, int len );
void WriteInt( const int value );
void WriteJoint( const jointHandle_t value );
void WriteShort( const short value );
void WriteByte( const byte value );
void WriteSignedChar( const signed char value );
void WriteFloat( const float value );
void WriteBool( const bool value );
void WriteString( const char *string );
void WriteVec2( const idVec2 &vec );
void WriteVec3( const idVec3 &vec );
void WriteVec4( const idVec4 &vec );
void WriteVec6( const idVec6 &vec );
void WriteWinding( const idWinding &winding );
void WriteBounds( const idBounds &bounds );
void WriteMat3( const idMat3 &mat );
void WriteAngles( const idAngles &angles );
void WriteObject( const idClass *obj );
void WriteStaticObject( const idClass &obj );
void WriteDict( const idDict *dict );
void WriteMaterial( const idMaterial *material );
void WriteSkin( const idDeclSkin *skin );
void WriteParticle( const idDeclParticle *particle );
void WriteFX( const idDeclFX *fx );
void WriteSoundShader( const idSoundShader *shader );
void WriteModelDef( const class idDeclModelDef *modelDef );
void WriteModel( const idRenderModel *model );
void WriteUserInterface( const idUserInterface *ui, bool unique );
void WriteRenderEntity( const renderEntity_t &renderEntity );
void WriteRenderLight( const renderLight_t &renderLight );
void WriteRefSound( const refSound_t &refSound );
void WriteRenderView( const renderView_t &view );
void WriteUsercmd( const usercmd_t &usercmd );
void WriteContactInfo( const contactInfo_t &contactInfo );
void WriteTrace( const trace_t &trace );
void WriteTraceModel( const idTraceModel &trace );
void WriteClipModel( const class idClipModel *clipModel );
void WriteSoundCommands();
void WriteBuildNumber( const int value );
int GetBuildNumber() const { return version; }
int GetCurrentSaveSize() const { return file->Length(); }
private:
idFile * file;
idFile * stringFile;
idCompressor * compressor;
idList<const idClass *> objects;
int version;
void CallSave_r( const idTypeInfo *cls, const idClass *obj );
struct stringTableIndex_s {
idStr string;
int offset;
};
idHashIndex stringHash;
idList< stringTableIndex_s > stringTable;
int curStringTableOffset;
};
class idRestoreGame {
public:
idRestoreGame( idFile * savefile, idFile * stringTableFile, int saveVersion );
~idRestoreGame();
void ReadDecls();
void CreateObjects();
void RestoreObjects();
void DeleteObjects();
void Error( VERIFY_FORMAT_STRING const char *fmt, ... );
void Read( void *buffer, int len );
void ReadInt( int &value );
void ReadJoint( jointHandle_t &value );
void ReadShort( short &value );
void ReadByte( byte &value );
void ReadSignedChar( signed char &value );
void ReadFloat( float &value );
void ReadBool( bool &value );
void ReadString( idStr &string );
void ReadVec2( idVec2 &vec );
void ReadVec3( idVec3 &vec );
void ReadVec4( idVec4 &vec );
void ReadVec6( idVec6 &vec );
void ReadWinding( idWinding &winding );
void ReadBounds( idBounds &bounds );
void ReadMat3( idMat3 &mat );
void ReadAngles( idAngles &angles );
void ReadObject( idClass *&obj );
void ReadStaticObject( idClass &obj );
void ReadDict( idDict *dict );
void ReadMaterial( const idMaterial *&material );
void ReadSkin( const idDeclSkin *&skin );
void ReadParticle( const idDeclParticle *&particle );
void ReadFX( const idDeclFX *&fx );
void ReadSoundShader( const idSoundShader *&shader );
void ReadModelDef( const idDeclModelDef *&modelDef );
void ReadModel( idRenderModel *&model );
void ReadUserInterface( idUserInterface *&ui );
void ReadRenderEntity( renderEntity_t &renderEntity );
void ReadRenderLight( renderLight_t &renderLight );
void ReadRefSound( refSound_t &refSound );
void ReadRenderView( renderView_t &view );
void ReadUsercmd( usercmd_t &usercmd );
void ReadContactInfo( contactInfo_t &contactInfo );
void ReadTrace( trace_t &trace );
void ReadTraceModel( idTraceModel &trace );
void ReadClipModel( idClipModel *&clipModel );
void ReadSoundCommands();
// Used to retrieve the saved game buildNumber from within class Restore methods
int GetBuildNumber() const { return version; }
private:
idFile * file;
idFile * stringFile;
idList<idClass *, TAG_SAVEGAMES> objects;
int version;
int stringTableOffset;
void CallRestore_r( const idTypeInfo *cls, idClass *obj );
};
#endif /* !__SAVEGAME_H__*/

2397
neo/d3xp/gamesys/SysCmds.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __SYS_CMDS_H__
#define __SYS_CMDS_H__
void D_DrawDebugLines();
#endif /* !__SYS_CMDS_H__ */

View File

@@ -0,0 +1,323 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#pragma hdrstop
#include "../../idlib/precompiled.h"
#include "../Game_local.h"
#if defined( _DEBUG )
#define BUILD_DEBUG "-debug"
#else
#define BUILD_DEBUG "-release"
#endif
/*
All game cvars should be defined here.
*/
struct gameVersion_s {
gameVersion_s() { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); }
char string[256];
} gameVersion;
// noset vars
idCVar gamename( "gamename", GAME_VERSION, CVAR_GAME | CVAR_ROM, "" );
idCVar gamedate( "gamedate", __DATE__, CVAR_GAME | CVAR_ROM, "" );
idCVar si_map( "si_map", "-1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "default map choice for profile" );
idCVar si_mode( "si_mode", "-1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "default mode choice for profile", -1, GAME_COUNT - 1 );
idCVar si_fragLimit( "si_fragLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "frag limit", 1, MP_PLAYER_MAXFRAGS );
idCVar si_timeLimit( "si_timeLimit", "10", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "time limit in minutes", 0, 60 );
idCVar si_teamDamage( "si_teamDamage", "0", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "enable team damage" );
idCVar si_spectators( "si_spectators", "1", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_BOOL, "allow spectators or require all clients to play" );
//idCVar si_pointLimit( "si_pointlimit", "8", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "team points limit to win in CTF" );
idCVar si_flagDropTimeLimit( "si_flagDropTimeLimit", "30", CVAR_GAME | CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_INTEGER, "seconds before a dropped CTF flag is returned" );
idCVar si_midnight( "si_midnight", "0", CVAR_GAME | CVAR_INTEGER | CVAR_SERVERINFO, "Start the game up in midnight CTF (completely dark)" );
// change anytime vars
idCVar developer( "developer", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_cinematic( "g_cinematic", "1", CVAR_GAME | CVAR_BOOL, "skips updating entities that aren't marked 'cinematic' '1' during cinematics" );
idCVar g_cinematicMaxSkipTime( "g_cinematicMaxSkipTime", "600", CVAR_GAME | CVAR_FLOAT, "# of seconds to allow game to run when skipping cinematic. prevents lock-up when cinematic doesn't end.", 0, 3600 );
idCVar g_muzzleFlash( "g_muzzleFlash", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show muzzle flashes" );
idCVar g_projectileLights( "g_projectileLights", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show dynamic lights on projectiles" );
idCVar g_bloodEffects( "g_bloodEffects", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show blood splats, sprays and gibs" );
idCVar g_monsters( "g_monsters", "1", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_decals( "g_decals", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "show decals such as bullet holes" );
idCVar g_knockback( "g_knockback", "1000", CVAR_GAME | CVAR_INTEGER, "" );
idCVar g_skill( "g_skill", "1", CVAR_GAME | CVAR_INTEGER, "" );
idCVar g_nightmare( "g_nightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed" );
idCVar g_roeNightmare( "g_roeNightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed for roe" );
idCVar g_leNightmare( "g_leNightmare", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "if nightmare mode is allowed for le" );
idCVar g_gravity( "g_gravity", DEFAULT_GRAVITY_STRING, CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_skipFX( "g_skipFX", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_disasm( "g_disasm", "0", CVAR_GAME | CVAR_BOOL, "disassemble script into base/script/disasm.txt on the local drive when script is compiled" );
idCVar g_debugBounds( "g_debugBounds", "0", CVAR_GAME | CVAR_BOOL, "checks for models with bounds > 2048" );
idCVar g_debugAnim( "g_debugAnim", "-1", CVAR_GAME | CVAR_INTEGER, "displays information on which animations are playing on the specified entity number. set to -1 to disable." );
idCVar g_debugMove( "g_debugMove", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_debugDamage( "g_debugDamage", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_debugWeapon( "g_debugWeapon", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_debugScript( "g_debugScript", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_debugMover( "g_debugMover", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_debugTriggers( "g_debugTriggers", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_debugCinematic( "g_debugCinematic", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_stopTime( "g_stopTime", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_damageScale( "g_damageScale", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "scale final damage on player by this factor" );
idCVar g_armorProtection( "g_armorProtection", "0.3", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage" );
idCVar g_armorProtectionMP( "g_armorProtectionMP", "0.6", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage in mp" );
idCVar g_useDynamicProtection( "g_useDynamicProtection", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "scale damage and armor dynamically to keep the player alive more often" );
idCVar g_healthTakeTime( "g_healthTakeTime", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how often to take health in nightmare mode" );
idCVar g_healthTakeAmt( "g_healthTakeAmt", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how much health to take in nightmare mode" );
idCVar g_healthTakeLimit( "g_healthTakeLimit", "25", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how low can health get taken in nightmare mode" );
idCVar g_showPVS( "g_showPVS", "0", CVAR_GAME | CVAR_INTEGER, "", 0, 2 );
idCVar g_showTargets( "g_showTargets", "0", CVAR_GAME | CVAR_BOOL, "draws entities and thier targets. hidden entities are drawn grey." );
idCVar g_showTriggers( "g_showTriggers", "0", CVAR_GAME | CVAR_BOOL, "draws trigger entities (orange) and thier targets (green). disabled triggers are drawn grey." );
idCVar g_showCollisionWorld( "g_showCollisionWorld", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_showCollisionModels( "g_showCollisionModels", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_showCollisionTraces( "g_showCollisionTraces", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_maxShowDistance( "g_maxShowDistance", "128", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_showEntityInfo( "g_showEntityInfo", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_showviewpos( "g_showviewpos", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_showcamerainfo( "g_showcamerainfo", "0", CVAR_GAME | CVAR_ARCHIVE, "displays the current frame # for the camera when playing cinematics" );
idCVar g_showTestModelFrame( "g_showTestModelFrame", "0", CVAR_GAME | CVAR_BOOL, "displays the current animation and frame # for testmodels" );
idCVar g_showActiveEntities( "g_showActiveEntities", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around thinking entities. dormant entities (outside of pvs) are drawn yellow. non-dormant are green." );
idCVar g_showEnemies( "g_showEnemies", "0", CVAR_GAME | CVAR_BOOL, "draws boxes around monsters that have targeted the the player" );
idCVar g_frametime( "g_frametime", "0", CVAR_GAME | CVAR_BOOL, "displays timing information for each game frame" );
idCVar g_timeentities( "g_timeEntities", "0", CVAR_GAME | CVAR_FLOAT, "when non-zero, shows entities whose think functions exceeded the # of milliseconds specified" );
idCVar g_debugShockwave( "g_debugShockwave", "0", CVAR_GAME | CVAR_BOOL, "Debug the shockwave" );
idCVar g_enableSlowmo( "g_enableSlowmo", "0", CVAR_GAME | CVAR_BOOL, "for testing purposes only" );
idCVar g_slowmoStepRate( "g_slowmoStepRate", "0.02", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_enablePortalSky( "g_enablePortalSky", "1", CVAR_GAME | CVAR_BOOL, "enables the portal sky" );
idCVar g_testFullscreenFX( "g_testFullscreenFX", "-1", CVAR_GAME | CVAR_INTEGER, "index will activate specific fx, -2 is for all on, -1 is off" );
idCVar g_testHelltimeFX( "g_testHelltimeFX", "-1", CVAR_GAME | CVAR_INTEGER, "set to 0, 1, 2 to test helltime, -1 is off" );
idCVar g_testMultiplayerFX( "g_testMultiplayerFX", "-1", CVAR_GAME | CVAR_INTEGER, "set to 0, 1, 2 to test multiplayer, -1 is off" );
idCVar g_moveableDamageScale( "g_moveableDamageScale", "0.1", CVAR_GAME | CVAR_FLOAT, "scales damage wrt mass of object in multiplayer" );
idCVar g_testBloomIntensity( "g_testBloomIntensity", "-0.01", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_testBloomNumPasses( "g_testBloomNumPasses", "30", CVAR_GAME | CVAR_INTEGER, "" );
idCVar ai_debugScript( "ai_debugScript", "-1", CVAR_GAME | CVAR_INTEGER, "displays script calls for the specified monster entity number" );
idCVar ai_debugMove( "ai_debugMove", "0", CVAR_GAME | CVAR_BOOL, "draws movement information for monsters" );
idCVar ai_debugTrajectory( "ai_debugTrajectory", "0", CVAR_GAME | CVAR_BOOL, "draws trajectory tests for monsters" );
idCVar ai_testPredictPath( "ai_testPredictPath", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar ai_showCombatNodes( "ai_showCombatNodes", "0", CVAR_GAME | CVAR_BOOL, "draws attack cones for monsters" );
idCVar ai_showPaths( "ai_showPaths", "0", CVAR_GAME | CVAR_BOOL, "draws path_* entities" );
idCVar ai_showObstacleAvoidance( "ai_showObstacleAvoidance", "0", CVAR_GAME | CVAR_INTEGER, "draws obstacle avoidance information for monsters. if 2, draws obstacles for player, as well", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
idCVar ai_blockedFailSafe( "ai_blockedFailSafe", "1", CVAR_GAME | CVAR_BOOL, "enable blocked fail safe handling" );
idCVar ai_showHealth( "ai_showHealth", "0", CVAR_GAME | CVAR_BOOL, "Draws the AI's health above its head" );
idCVar g_dvTime( "g_dvTime", "1", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_dvAmplitude( "g_dvAmplitude", "0.001", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_dvFrequency( "g_dvFrequency", "0.5", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_kickTime( "g_kickTime", "1", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_kickAmplitude( "g_kickAmplitude", "0.0001", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_blobTime( "g_blobTime", "1", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_blobSize( "g_blobSize", "1", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_testHealthVision( "g_testHealthVision", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_editEntityMode( "g_editEntityMode", "0", CVAR_GAME | CVAR_INTEGER, "0 = off\n"
"1 = lights\n"
"2 = sounds\n"
"3 = articulated figures\n"
"4 = particle systems\n"
"5 = monsters\n"
"6 = entity names\n"
"7 = entity models", 0, 7, idCmdSystem::ArgCompletion_Integer<0,7> );
idCVar g_dragEntity( "g_dragEntity", "0", CVAR_GAME | CVAR_BOOL, "allows dragging physics objects around by placing the crosshair over them and holding the fire button" );
idCVar g_dragDamping( "g_dragDamping", "0.5", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_dragShowSelection( "g_dragShowSelection", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_dropItemRotation( "g_dropItemRotation", "", CVAR_GAME, "" );
// Note: These cvars do not necessarily need to be in the shipping game.
idCVar g_flagAttachJoint( "g_flagAttachJoint", "Chest", CVAR_GAME | CVAR_CHEAT, "player joint to attach CTF flag to" );
idCVar g_flagAttachOffsetX( "g_flagAttachOffsetX", "8", CVAR_GAME | CVAR_CHEAT, "X offset of CTF flag when carried" );
idCVar g_flagAttachOffsetY( "g_flagAttachOffsetY", "4", CVAR_GAME | CVAR_CHEAT, "Y offset of CTF flag when carried" );
idCVar g_flagAttachOffsetZ( "g_flagAttachOffsetZ", "-12", CVAR_GAME | CVAR_CHEAT, "Z offset of CTF flag when carried" );
idCVar g_flagAttachAngleX( "g_flagAttachAngleX", "90", CVAR_GAME | CVAR_CHEAT, "X angle of CTF flag when carried" );
idCVar g_flagAttachAngleY( "g_flagAttachAngleY", "25", CVAR_GAME | CVAR_CHEAT, "Y angle of CTF flag when carried" );
idCVar g_flagAttachAngleZ( "g_flagAttachAngleZ", "-90", CVAR_GAME | CVAR_CHEAT, "Z angle of CTF flag when carried" );
idCVar g_vehicleVelocity( "g_vehicleVelocity", "1000", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleForce( "g_vehicleForce", "50000", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleSuspensionUp( "g_vehicleSuspensionUp", "32", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleSuspensionDown( "g_vehicleSuspensionDown", "20", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleSuspensionKCompress("g_vehicleSuspensionKCompress","200", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleSuspensionDamping( "g_vehicleSuspensionDamping","400", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleTireFriction( "g_vehicleTireFriction", "0.8", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_vehicleDebug( "g_vehicleDebug", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar ik_enable( "ik_enable", "1", CVAR_GAME | CVAR_BOOL, "enable IK" );
idCVar ik_debug( "ik_debug", "0", CVAR_GAME | CVAR_BOOL, "show IK debug lines" );
idCVar af_useLinearTime( "af_useLinearTime", "1", CVAR_GAME | CVAR_BOOL, "use linear time algorithm for tree-like structures" );
idCVar af_useImpulseFriction( "af_useImpulseFriction", "0", CVAR_GAME | CVAR_BOOL, "use impulse based contact friction" );
idCVar af_useJointImpulseFriction( "af_useJointImpulseFriction","0", CVAR_GAME | CVAR_BOOL, "use impulse based joint friction" );
idCVar af_useSymmetry( "af_useSymmetry", "1", CVAR_GAME | CVAR_BOOL, "use constraint matrix symmetry" );
idCVar af_skipSelfCollision( "af_skipSelfCollision", "0", CVAR_GAME | CVAR_BOOL, "skip self collision detection" );
idCVar af_skipLimits( "af_skipLimits", "0", CVAR_GAME | CVAR_BOOL, "skip joint limits" );
idCVar af_skipFriction( "af_skipFriction", "0", CVAR_GAME | CVAR_BOOL, "skip friction" );
idCVar af_forceFriction( "af_forceFriction", "-1", CVAR_GAME | CVAR_FLOAT, "force the given friction value" );
idCVar af_maxLinearVelocity( "af_maxLinearVelocity", "128", CVAR_GAME | CVAR_FLOAT, "maximum linear velocity" );
idCVar af_maxAngularVelocity( "af_maxAngularVelocity", "1.57", CVAR_GAME | CVAR_FLOAT, "maximum angular velocity" );
idCVar af_timeScale( "af_timeScale", "1", CVAR_GAME | CVAR_FLOAT, "scales the time" );
idCVar af_jointFrictionScale( "af_jointFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the joint friction" );
idCVar af_contactFrictionScale( "af_contactFrictionScale", "0", CVAR_GAME | CVAR_FLOAT, "scales the contact friction" );
idCVar af_highlightBody( "af_highlightBody", "", CVAR_GAME, "name of the body to highlight" );
idCVar af_highlightConstraint( "af_highlightConstraint", "", CVAR_GAME, "name of the constraint to highlight" );
idCVar af_showTimings( "af_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show articulated figure cpu usage" );
idCVar af_showConstraints( "af_showConstraints", "0", CVAR_GAME | CVAR_BOOL, "show constraints" );
idCVar af_showConstraintNames( "af_showConstraintNames", "0", CVAR_GAME | CVAR_BOOL, "show constraint names" );
idCVar af_showConstrainedBodies( "af_showConstrainedBodies", "0", CVAR_GAME | CVAR_BOOL, "show the two bodies contrained by the highlighted constraint" );
idCVar af_showPrimaryOnly( "af_showPrimaryOnly", "0", CVAR_GAME | CVAR_BOOL, "show primary constraints only" );
idCVar af_showTrees( "af_showTrees", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures" );
idCVar af_showLimits( "af_showLimits", "0", CVAR_GAME | CVAR_BOOL, "show joint limits" );
idCVar af_showBodies( "af_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show bodies" );
idCVar af_showBodyNames( "af_showBodyNames", "0", CVAR_GAME | CVAR_BOOL, "show body names" );
idCVar af_showMass( "af_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each body" );
idCVar af_showTotalMass( "af_showTotalMass", "0", CVAR_GAME | CVAR_BOOL, "show the total mass of each articulated figure" );
idCVar af_showInertia( "af_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each body" );
idCVar af_showVelocity( "af_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each body" );
idCVar af_showActive( "af_showActive", "0", CVAR_GAME | CVAR_BOOL, "show tree-like structures of articulated figures not at rest" );
idCVar af_testSolid( "af_testSolid", "1", CVAR_GAME | CVAR_BOOL, "test for bodies initially stuck in solid" );
idCVar rb_showTimings( "rb_showTimings", "0", CVAR_GAME | CVAR_BOOL, "show rigid body cpu usage" );
idCVar rb_showBodies( "rb_showBodies", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies" );
idCVar rb_showMass( "rb_showMass", "0", CVAR_GAME | CVAR_BOOL, "show the mass of each rigid body" );
idCVar rb_showInertia( "rb_showInertia", "0", CVAR_GAME | CVAR_BOOL, "show the inertia tensor of each rigid body" );
idCVar rb_showVelocity( "rb_showVelocity", "0", CVAR_GAME | CVAR_BOOL, "show the velocity of each rigid body" );
idCVar rb_showActive( "rb_showActive", "0", CVAR_GAME | CVAR_BOOL, "show rigid bodies that are not at rest" );
// The default values for player movement cvars are set in def/player.def
idCVar pm_jumpheight( "pm_jumpheight", "48", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "approximate hieght the player can jump" );
idCVar pm_stepsize( "pm_stepsize", "16", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "maximum height the player can step up without jumping" );
idCVar pm_crouchspeed( "pm_crouchspeed", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while crouched" );
idCVar pm_walkspeed( "pm_walkspeed", "140", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while walking" );
idCVar pm_runspeed( "pm_runspeed", "220", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while running" );
idCVar pm_noclipspeed( "pm_noclipspeed", "200", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while in noclip" );
idCVar pm_spectatespeed( "pm_spectatespeed", "450", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "speed the player can move while spectating" );
idCVar pm_spectatebbox( "pm_spectatebbox", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "size of the spectator bounding box" );
idCVar pm_usecylinder( "pm_usecylinder", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "use a cylinder approximation instead of a bounding box for player collision detection" );
idCVar pm_minviewpitch( "pm_minviewpitch", "-89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look up (negative values are up)" );
idCVar pm_maxviewpitch( "pm_maxviewpitch", "89", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "amount player's view can look down" );
idCVar pm_stamina( "pm_stamina", "24", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "length of time player can run" );
idCVar pm_staminathreshold( "pm_staminathreshold", "45", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "when stamina drops below this value, player gradually slows to a walk" );
idCVar pm_staminarate( "pm_staminarate", "0.75", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "rate that player regains stamina. divide pm_stamina by this value to determine how long it takes to fully recharge." );
idCVar pm_crouchheight( "pm_crouchheight", "38", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while crouched" );
idCVar pm_crouchviewheight( "pm_crouchviewheight", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while crouched" );
idCVar pm_normalheight( "pm_normalheight", "74", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while standing" );
idCVar pm_normalviewheight( "pm_normalviewheight", "68", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while standing" );
idCVar pm_deadheight( "pm_deadheight", "20", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's bounding box while dead" );
idCVar pm_deadviewheight( "pm_deadviewheight", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of player's view while dead" );
idCVar pm_crouchrate( "pm_crouchrate", "0.87", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "time it takes for player's view to change from standing to crouching" );
idCVar pm_bboxwidth( "pm_bboxwidth", "32", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "x/y size of player's bounding box" );
idCVar pm_crouchbob( "pm_crouchbob", "0.5", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob much faster when crouched" );
idCVar pm_walkbob( "pm_walkbob", "0.3", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob slowly when walking" );
idCVar pm_runbob( "pm_runbob", "0.4", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "bob faster when running" );
idCVar pm_runpitch( "pm_runpitch", "0.002", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
idCVar pm_runroll( "pm_runroll", "0.005", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
idCVar pm_bobup( "pm_bobup", "0.005", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
idCVar pm_bobpitch( "pm_bobpitch", "0.002", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
idCVar pm_bobroll( "pm_bobroll", "0.002", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "" );
idCVar pm_thirdPersonRange( "pm_thirdPersonRange", "80", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "camera distance from player in 3rd person" );
idCVar pm_thirdPersonHeight( "pm_thirdPersonHeight", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "height of camera from normal view height in 3rd person" );
idCVar pm_thirdPersonAngle( "pm_thirdPersonAngle", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT, "direction of camera from player in 3rd person in degrees (0 = behind player, 180 = in front)" );
idCVar pm_thirdPersonClip( "pm_thirdPersonClip", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "clip third person view into world space" );
idCVar pm_thirdPerson( "pm_thirdPerson", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view" );
idCVar pm_thirdPersonDeath( "pm_thirdPersonDeath", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "enables third person view when player dies" );
idCVar pm_modelView( "pm_modelView", "0", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "draws camera from POV of player model (1 = always, 2 = when dead)", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
idCVar pm_airMsec( "pm_air", "30000", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER, "how long in milliseconds the player can go without air before he starts taking damage" );
idCVar g_showPlayerShadow( "g_showPlayerShadow", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables shadow of player model" );
idCVar g_showHud( "g_showHud", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "" );
idCVar g_showProjectilePct( "g_showProjectilePct", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables display of player hit percentage" );
idCVar g_showBrass( "g_showBrass", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL, "enables ejected shells from weapon" );
idCVar g_gun_x( "g_gunX", "3", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
idCVar g_gun_y( "g_gunY", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
idCVar g_gun_z( "g_gunZ", "0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
idCVar g_gunScale( "g_gunScale", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT, "" );
idCVar g_viewNodalX( "g_viewNodalX", "3", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_viewNodalZ( "g_viewNodalZ", "6", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_fov( "g_fov", "80", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "" );
idCVar g_skipViewEffects( "g_skipViewEffects", "0", CVAR_GAME | CVAR_BOOL, "skip damage and other view effects" );
idCVar g_mpWeaponAngleScale( "g_mpWeaponAngleScale", "0", CVAR_GAME | CVAR_FLOAT, "Control the weapon sway in MP" );
idCVar g_testParticle( "g_testParticle", "0", CVAR_GAME | CVAR_INTEGER, "test particle visualation, set by the particle editor" );
idCVar g_testParticleName( "g_testParticleName", "", CVAR_GAME, "name of the particle being tested by the particle editor" );
idCVar g_testModelRotate( "g_testModelRotate", "0", CVAR_GAME, "test model rotation speed" );
idCVar g_testPostProcess( "g_testPostProcess", "", CVAR_GAME, "name of material to draw over screen" );
idCVar g_testModelAnimate( "g_testModelAnimate", "0", CVAR_GAME | CVAR_INTEGER, "test model animation,\n"
"0 = cycle anim with origin reset\n"
"1 = cycle anim with fixed origin\n"
"2 = cycle anim with continuous origin\n"
"3 = frame by frame with continuous origin\n"
"4 = play anim once", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> );
idCVar g_testModelBlend( "g_testModelBlend", "0", CVAR_GAME | CVAR_INTEGER, "number of frames to blend" );
idCVar g_testDeath( "g_testDeath", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_flushSave( "g_flushSave", "0", CVAR_GAME | CVAR_BOOL, "1 = don't buffer file writing for save games." );
idCVar aas_test( "aas_test", "0", CVAR_GAME | CVAR_INTEGER, "" );
idCVar aas_showAreas( "aas_showAreas", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar aas_showPath( "aas_showPath", "0", CVAR_GAME | CVAR_INTEGER, "" );
idCVar aas_showFlyPath( "aas_showFlyPath", "0", CVAR_GAME | CVAR_INTEGER, "" );
idCVar aas_showWallEdges( "aas_showWallEdges", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar aas_showHideArea( "aas_showHideArea", "0", CVAR_GAME | CVAR_INTEGER, "" );
idCVar aas_pullPlayer( "aas_pullPlayer", "0", CVAR_GAME | CVAR_INTEGER, "" );
idCVar aas_randomPullPlayer( "aas_randomPullPlayer", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar aas_goalArea( "aas_goalArea", "0", CVAR_GAME | CVAR_INTEGER, "" );
idCVar aas_showPushIntoArea( "aas_showPushIntoArea", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_countDown( "g_countDown", "15", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "pregame countdown in seconds", 4, 3600 );
idCVar g_gameReviewPause( "g_gameReviewPause", "10", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_INTEGER | CVAR_ARCHIVE, "scores review time in seconds (at end game)", 2, 3600 );
idCVar g_CTFArrows( "g_CTFArrows", "1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_BOOL, "draw arrows over teammates in CTF" );
idCVar net_clientPredictGUI( "net_clientPredictGUI", "1", CVAR_GAME | CVAR_BOOL, "test guis in networking without prediction" );
idCVar g_grabberHoldSeconds( "g_grabberHoldSeconds", "3", CVAR_GAME | CVAR_FLOAT | CVAR_CHEAT, "number of seconds to hold object" );
idCVar g_grabberEnableShake( "g_grabberEnableShake", "1", CVAR_GAME | CVAR_BOOL | CVAR_CHEAT, "enable the grabber shake" );
idCVar g_grabberRandomMotion( "g_grabberRandomMotion", "1", CVAR_GAME | CVAR_BOOL | CVAR_CHEAT, "enable random motion on the grabbed object" );
idCVar g_grabberHardStop( "g_grabberHardStop", "1", CVAR_GAME | CVAR_BOOL | CVAR_CHEAT, "hard stops object if too fast" );
idCVar g_grabberDamping( "g_grabberDamping", "0.5", CVAR_GAME | CVAR_FLOAT | CVAR_CHEAT, "damping of grabber" );
idCVar g_xp_bind_run_once( "g_xp_bind_run_once", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Rebind all controls once for D3XP." );

274
neo/d3xp/gamesys/SysCvar.h Normal file
View File

@@ -0,0 +1,274 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __SYS_CVAR_H__
#define __SYS_CVAR_H__
extern idCVar developer;
extern idCVar g_cinematic;
extern idCVar g_cinematicMaxSkipTime;
extern idCVar g_monsters;
extern idCVar g_decals;
extern idCVar g_knockback;
extern idCVar g_skill;
extern idCVar g_gravity;
extern idCVar g_skipFX;
extern idCVar g_bloodEffects;
extern idCVar g_projectileLights;
extern idCVar g_muzzleFlash;
extern idCVar g_disasm;
extern idCVar g_debugBounds;
extern idCVar g_debugAnim;
extern idCVar g_debugMove;
extern idCVar g_debugDamage;
extern idCVar g_debugWeapon;
extern idCVar g_debugScript;
extern idCVar g_debugMover;
extern idCVar g_debugTriggers;
extern idCVar g_debugCinematic;
extern idCVar g_stopTime;
extern idCVar g_armorProtection;
extern idCVar g_armorProtectionMP;
extern idCVar g_damageScale;
extern idCVar g_useDynamicProtection;
extern idCVar g_healthTakeTime;
extern idCVar g_healthTakeAmt;
extern idCVar g_healthTakeLimit;
extern idCVar g_showPVS;
extern idCVar g_showTargets;
extern idCVar g_showTriggers;
extern idCVar g_showCollisionWorld;
extern idCVar g_showCollisionModels;
extern idCVar g_showCollisionTraces;
extern idCVar g_maxShowDistance;
extern idCVar g_showEntityInfo;
extern idCVar g_showviewpos;
extern idCVar g_showcamerainfo;
extern idCVar g_showTestModelFrame;
extern idCVar g_showActiveEntities;
extern idCVar g_showEnemies;
extern idCVar g_frametime;
extern idCVar g_timeentities;
extern idCVar ai_debugScript;
extern idCVar ai_debugMove;
extern idCVar ai_debugTrajectory;
extern idCVar ai_testPredictPath;
extern idCVar ai_showCombatNodes;
extern idCVar ai_showPaths;
extern idCVar ai_showObstacleAvoidance;
extern idCVar ai_blockedFailSafe;
extern idCVar ai_showHealth;
extern idCVar g_dvTime;
extern idCVar g_dvAmplitude;
extern idCVar g_dvFrequency;
extern idCVar g_kickTime;
extern idCVar g_kickAmplitude;
extern idCVar g_blobTime;
extern idCVar g_blobSize;
extern idCVar g_testHealthVision;
extern idCVar g_editEntityMode;
extern idCVar g_dragEntity;
extern idCVar g_dragDamping;
extern idCVar g_dragShowSelection;
extern idCVar g_dropItemRotation;
extern idCVar g_vehicleVelocity;
extern idCVar g_vehicleForce;
extern idCVar g_vehicleSuspensionUp;
extern idCVar g_vehicleSuspensionDown;
extern idCVar g_vehicleSuspensionKCompress;
extern idCVar g_vehicleSuspensionDamping;
extern idCVar g_vehicleTireFriction;
extern idCVar g_vehicleDebug;
extern idCVar g_debugShockwave;
extern idCVar g_enablePortalSky;
extern idCVar ik_enable;
extern idCVar ik_debug;
extern idCVar af_useLinearTime;
extern idCVar af_useImpulseFriction;
extern idCVar af_useJointImpulseFriction;
extern idCVar af_useSymmetry;
extern idCVar af_skipSelfCollision;
extern idCVar af_skipLimits;
extern idCVar af_skipFriction;
extern idCVar af_forceFriction;
extern idCVar af_maxLinearVelocity;
extern idCVar af_maxAngularVelocity;
extern idCVar af_timeScale;
extern idCVar af_jointFrictionScale;
extern idCVar af_contactFrictionScale;
extern idCVar af_highlightBody;
extern idCVar af_highlightConstraint;
extern idCVar af_showTimings;
extern idCVar af_showConstraints;
extern idCVar af_showConstraintNames;
extern idCVar af_showConstrainedBodies;
extern idCVar af_showPrimaryOnly;
extern idCVar af_showTrees;
extern idCVar af_showLimits;
extern idCVar af_showBodies;
extern idCVar af_showBodyNames;
extern idCVar af_showMass;
extern idCVar af_showTotalMass;
extern idCVar af_showInertia;
extern idCVar af_showVelocity;
extern idCVar af_showActive;
extern idCVar af_testSolid;
extern idCVar rb_showTimings;
extern idCVar rb_showBodies;
extern idCVar rb_showMass;
extern idCVar rb_showInertia;
extern idCVar rb_showVelocity;
extern idCVar rb_showActive;
extern idCVar pm_jumpheight;
extern idCVar pm_stepsize;
extern idCVar pm_crouchspeed;
extern idCVar pm_walkspeed;
extern idCVar pm_runspeed;
extern idCVar pm_noclipspeed;
extern idCVar pm_spectatespeed;
extern idCVar pm_spectatebbox;
extern idCVar pm_usecylinder;
extern idCVar pm_minviewpitch;
extern idCVar pm_maxviewpitch;
extern idCVar pm_stamina;
extern idCVar pm_staminathreshold;
extern idCVar pm_staminarate;
extern idCVar pm_crouchheight;
extern idCVar pm_crouchviewheight;
extern idCVar pm_normalheight;
extern idCVar pm_normalviewheight;
extern idCVar pm_deadheight;
extern idCVar pm_deadviewheight;
extern idCVar pm_crouchrate;
extern idCVar pm_bboxwidth;
extern idCVar pm_crouchbob;
extern idCVar pm_walkbob;
extern idCVar pm_runbob;
extern idCVar pm_runpitch;
extern idCVar pm_runroll;
extern idCVar pm_bobup;
extern idCVar pm_bobpitch;
extern idCVar pm_bobroll;
extern idCVar pm_thirdPersonRange;
extern idCVar pm_thirdPersonHeight;
extern idCVar pm_thirdPersonAngle;
extern idCVar pm_thirdPersonClip;
extern idCVar pm_thirdPerson;
extern idCVar pm_thirdPersonDeath;
extern idCVar pm_modelView;
extern idCVar pm_airMsec;
extern idCVar g_showPlayerShadow;
extern idCVar g_showHud;
extern idCVar g_showProjectilePct;
extern idCVar g_showBrass;
extern idCVar g_gun_x;
extern idCVar g_gun_y;
extern idCVar g_gun_z;
extern idCVar g_gunScale;
extern idCVar g_viewNodalX;
extern idCVar g_viewNodalZ;
extern idCVar g_fov;
extern idCVar g_testDeath;
extern idCVar g_skipViewEffects;
extern idCVar g_mpWeaponAngleScale;
extern idCVar g_testParticle;
extern idCVar g_testParticleName;
extern idCVar g_testPostProcess;
extern idCVar g_testModelRotate;
extern idCVar g_testModelAnimate;
extern idCVar g_testModelBlend;
extern idCVar g_flushSave;
extern idCVar g_enableSlowmo;
extern idCVar g_slowmoStepRate;
extern idCVar g_testFullscreenFX;
extern idCVar g_testHelltimeFX;
extern idCVar g_testMultiplayerFX;
extern idCVar g_moveableDamageScale;
extern idCVar g_testBloomIntensity;
extern idCVar g_testBloomNumPasses;
extern idCVar g_grabberHoldSeconds;
extern idCVar g_grabberEnableShake;
extern idCVar g_grabberRandomMotion;
extern idCVar g_grabberHardStop;
extern idCVar g_grabberDamping;
extern idCVar g_xp_bind_run_once;
extern idCVar aas_test;
extern idCVar aas_showAreas;
extern idCVar aas_showPath;
extern idCVar aas_showFlyPath;
extern idCVar aas_showWallEdges;
extern idCVar aas_showHideArea;
extern idCVar aas_pullPlayer;
extern idCVar aas_randomPullPlayer;
extern idCVar aas_goalArea;
extern idCVar aas_showPushIntoArea;
extern idCVar net_clientPredictGUI;
extern idCVar si_timeLimit;
extern idCVar si_fragLimit;
extern idCVar si_spectators;
extern idCVar si_flagDropTimeLimit;
extern idCVar si_midnight;
extern idCVar g_flagAttachJoint;
extern idCVar g_flagAttachOffsetX;
extern idCVar g_flagAttachOffsetY;
extern idCVar g_flagAttachOffsetZ;
extern idCVar g_flagAttachAngleX;
extern idCVar g_flagAttachAngleY;
extern idCVar g_flagAttachAngleZ;
extern idCVar g_CTFArrows;
extern idCVar net_clientSelfSmoothing;
#endif /* !__SYS_CVAR_H__ */

View File

@@ -0,0 +1,449 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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.
===========================================================================
*/
#pragma hdrstop
#include "../../idLib/precompiled.h"
#include "../Game_local.h"
extern idCVar in_useJoystick;
/*
================================================
idMenuHandler::~idMenuHandler
================================================
*/
idMenuHandler::idMenuHandler() {
scrollingMenu = false;
scrollCounter = 0;
activeScreen = -1;
nextScreen = -1;
transition = -1;
platform = 0;
gui = NULL;
cmdBar = NULL;
for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
menuScreens[ index ] = NULL;
}
sounds.SetNum( NUM_GUI_SOUNDS );
}
/*
================================================
idMenuHandler::~idMenuHandler
================================================
*/
idMenuHandler::~idMenuHandler() {
Cleanup();
}
/*
================================================
idMenuHandler::Initialize
================================================
*/
void idMenuHandler::Initialize( const char * swfFile, idSoundWorld * sw ) {
Cleanup();
gui = new idSWF( swfFile, sw );
platform = 2;
}
/*
================================================
idMenuHandler::AddChild
================================================
*/
void idMenuHandler::AddChild( idMenuWidget * widget ) {
widget->SetSWFObj( gui );
widget->SetHandlerIsParent( true );
children.Append( widget );
widget->AddRef();
}
/*
================================================
idMenuHandler::GetChildFromIndex
================================================
*/
idMenuWidget * idMenuHandler::GetChildFromIndex( int index ) {
if ( children.Num() == 0 ) {
return NULL;
}
if ( index > children.Num() ) {
return NULL;
}
return children[ index ];
}
/*
================================================
idMenuHandler::GetPlatform
================================================
*/
int idMenuHandler::GetPlatform( bool realPlatform ) {
if ( platform == 2 && in_useJoystick.GetBool() && !realPlatform ) {
return 0;
}
return platform;
}
/*
================================================
idMenuHandler::GetPlatform
================================================
*/
void idMenuHandler::PlaySound( menuSounds_t type, int channel ) {
if ( gui == NULL ) {
return;
}
if ( type >= sounds.Num() ) {
return;
}
if ( sounds[ type ].IsEmpty() ) {
return;
}
int c = SCHANNEL_ANY;
if ( channel != -1 ) {
c = channel;
}
gui->PlaySound( sounds[ type ], c );
}
/*
================================================
idMenuHandler::StopSound
================================================
*/
void idMenuHandler::StopSound( int channel ) {
gui->StopSound();
}
/*
================================================
idMenuHandler::Cleanup
================================================
*/
void idMenuHandler::Cleanup() {
for ( int index = 0; index < children.Num(); ++index ) {
assert( children[ index ]->GetRefCount() > 0 );
children[ index ]->Release();
}
children.Clear();
for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
if ( menuScreens[ index ] != NULL ) {
menuScreens[ index ]->Release();
}
}
delete gui;
gui = NULL;
}
/*
================================================
idMenuHandler::TriggerMenu
================================================
*/
void idMenuHandler::TriggerMenu() {
}
/*
================================================
idMenuHandler::IsActive
================================================
*/
bool idMenuHandler::IsActive() {
if ( gui == NULL ) {
return false;
}
return gui->IsActive();
}
/*
================================================
idMenuHandler::ActivateMenu
================================================
*/
void idMenuHandler::ActivateMenu( bool show ) {
if ( gui == NULL ) {
return;
}
if ( !show ) {
gui->Activate( show );
return;
}
class idSWFScriptFunction_updateMenuDisplay : public idSWFScriptFunction_RefCounted {
public:
idSWFScriptFunction_updateMenuDisplay( idSWF * _gui, idMenuHandler * _handler ) {
gui = _gui;
handler = _handler;
}
idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
if ( handler != NULL ) {
int screen = parms[0].ToInteger();
handler->UpdateMenuDisplay( screen );
}
return idSWFScriptVar();
}
private:
idSWF * gui;
idMenuHandler * handler;
};
class idSWFScriptFunction_activateMenu : public idSWFScriptFunction_RefCounted {
public:
idSWFScriptFunction_activateMenu( idMenuHandler * _handler ) {
handler = _handler;
}
idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
if ( handler != NULL ) {
handler->TriggerMenu();
}
return idSWFScriptVar();
}
private:
idMenuHandler * handler;
};
gui->SetGlobal( "updateMenuDisplay", new (TAG_SWF) idSWFScriptFunction_updateMenuDisplay( gui, this ) );
gui->SetGlobal( "activateMenus", new (TAG_SWF) idSWFScriptFunction_activateMenu( this ) );
gui->Activate( show );
}
/*
================================================
idMenuHandler::Update
================================================
*/
void idMenuHandler::Update() {
PumpWidgetActionRepeater();
if ( gui != NULL && gui->IsActive() ) {
gui->Render( renderSystem, Sys_Milliseconds() );
}
}
/*
================================================
idMenuHandler::UpdateChildren
================================================
*/
void idMenuHandler::UpdateChildren() {
for ( int index = 0; index < children.Num(); ++index ) {
if ( children[ index ] != NULL ) {
children[index]->Update();
}
}
}
/*
================================================
idMenuHandler::UpdateMenuDisplay
================================================
*/
void idMenuHandler::UpdateMenuDisplay( int menu ) {
if ( menuScreens[ menu ] != NULL ) {
menuScreens[ menu ]->Update();
}
UpdateChildren();
}
/*
================================================
idMenuHandler::Update
================================================
*/
bool idMenuHandler::HandleGuiEvent( const sysEvent_t * sev ) {
if ( gui != NULL && activeScreen != -1 ) {
return gui->HandleEvent( sev );
}
return false;
}
/*
================================================
idMenuHandler::Update
================================================
*/
bool idMenuHandler::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
widgetAction_t actionType = action.GetType();
const idSWFParmList & parms = action.GetParms();
switch ( actionType ) {
case WIDGET_ACTION_ADJUST_FIELD: {
if ( widget != NULL && widget->GetDataSource() != NULL ) {
widget->GetDataSource()->AdjustField( widget->GetDataSourceFieldIndex(), parms[ 0 ].ToInteger() );
widget->Update();
}
return true;
}
case WIDGET_ACTION_FUNCTION: {
if ( verify( action.GetScriptFunction() != NULL ) ) {
action.GetScriptFunction()->Call( event.thisObject, event.parms );
}
return true;
}
case WIDGET_ACTION_PRESS_FOCUSED: {
idMenuScreen * const screen = menuScreens[ activeScreen ];
if ( screen != NULL ) {
idWidgetEvent pressEvent( WIDGET_EVENT_PRESS, 0, event.thisObject, idSWFParmList() );
screen->ReceiveEvent( pressEvent );
}
return true;
}
case WIDGET_ACTION_START_REPEATER: {
idWidgetAction repeatAction;
widgetAction_t repeatActionType = static_cast< widgetAction_t >( parms[ 0 ].ToInteger() );
assert( parms.Num() >= 2 );
int repeatDelay = DEFAULT_REPEAT_TIME;
if ( parms.Num() >= 3 ) {
repeatDelay = parms[2].ToInteger();
}
repeatAction.Set( repeatActionType, parms[ 1 ], repeatDelay );
StartWidgetActionRepeater( widget, repeatAction, event );
return true;
}
case WIDGET_ACTION_STOP_REPEATER: {
ClearWidgetActionRepeater();
return true;
}
}
if ( !widget->GetHandlerIsParent() ) {
for ( int index = 0; index < children.Num(); ++index ) {
if ( children[index] != NULL ) {
if ( children[index]->HandleAction( action, event, widget, forceHandled ) ) {
return true;
}
}
}
}
return false;
}
/*
========================
idMenuHandler::StartWidgetActionRepeater
========================
*/
void idMenuHandler::StartWidgetActionRepeater( idMenuWidget * widget, const idWidgetAction & action, const idWidgetEvent & event ) {
if ( actionRepeater.isActive && actionRepeater.action == action ) {
return; // don't attempt to reactivate an already active repeater
}
actionRepeater.isActive = true;
actionRepeater.action = action;
actionRepeater.widget = widget;
actionRepeater.event = event;
actionRepeater.numRepetitions = 0;
actionRepeater.nextRepeatTime = 0;
actionRepeater.screenIndex = activeScreen; // repeaters are cleared between screens
if ( action.GetParms().Num() == 2 ) {
actionRepeater.repeatDelay = action.GetParms()[ 1 ].ToInteger();
} else {
actionRepeater.repeatDelay = DEFAULT_REPEAT_TIME;
}
// do the first event immediately
PumpWidgetActionRepeater();
}
/*
========================
idMenuHandler::PumpWidgetActionRepeater
========================
*/
void idMenuHandler::PumpWidgetActionRepeater() {
if ( !actionRepeater.isActive ) {
return;
}
if ( activeScreen != actionRepeater.screenIndex || nextScreen != activeScreen ) { // || common->IsDialogActive() ) {
actionRepeater.isActive = false;
return;
}
if ( actionRepeater.nextRepeatTime > Sys_Milliseconds() ) {
return;
}
// need to hold down longer on the first iteration before we continue to scroll
if ( actionRepeater.numRepetitions == 0 ) {
actionRepeater.nextRepeatTime = Sys_Milliseconds() + 400;
} else {
actionRepeater.nextRepeatTime = Sys_Milliseconds() + actionRepeater.repeatDelay;
}
if ( verify( actionRepeater.widget != NULL ) ) {
actionRepeater.widget->HandleAction( actionRepeater.action, actionRepeater.event, actionRepeater.widget );
actionRepeater.numRepetitions++;
}
}
/*
========================
idMenuHandler::ClearWidgetActionRepeater
========================
*/
void idMenuHandler::ClearWidgetActionRepeater() {
actionRepeater.isActive = false;
}

View File

@@ -0,0 +1,516 @@
/*
===========================================================================
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 <http://www.gnu.org/licenses/>.
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 __MENUDATA_H__
#define __MENUDATA_H__
enum shellAreas_t {
SHELL_AREA_INVALID = -1,
SHELL_AREA_START,
SHELL_AREA_ROOT,
SHELL_AREA_DEV,
SHELL_AREA_CAMPAIGN,
SHELL_AREA_LOAD,
SHELL_AREA_SAVE,
SHELL_AREA_NEW_GAME,
SHELL_AREA_GAME_OPTIONS,
SHELL_AREA_SYSTEM_OPTIONS,
SHELL_AREA_MULTIPLAYER,
SHELL_AREA_GAME_LOBBY,
SHELL_AREA_STEREOSCOPICS,
SHELL_AREA_PARTY_LOBBY,
SHELL_AREA_SETTINGS,
SHELL_AREA_AUDIO,
SHELL_AREA_VIDEO,
SHELL_AREA_KEYBOARD,
SHELL_AREA_CONTROLS,
SHELL_AREA_CONTROLLER_LAYOUT,
SHELL_AREA_GAMEPAD,
SHELL_AREA_PAUSE,
SHELL_AREA_LEADERBOARDS,
SHELL_AREA_PLAYSTATION,
SHELL_AREA_DIFFICULTY,
SHELL_AREA_RESOLUTION,
SHELL_AREA_MATCH_SETTINGS,
SHELL_AREA_MODE_SELECT,
SHELL_AREA_BROWSER,
SHELL_AREA_CREDITS,
SHELL_NUM_AREAS
};
enum shellState_t {
SHELL_STATE_INVALID = -1,
SHELL_STATE_PRESS_START,
SHELL_STATE_IDLE,
SHELL_STATE_PARTY_LOBBY,
SHELL_STATE_GAME_LOBBY,
SHELL_STATE_PAUSED,
SHELL_STATE_CONNECTING,
SHELL_STATE_SEARCHING,
SHELL_STATE_LOADING,
SHELL_STATE_BUSY,
SHELL_STATE_IN_GAME
};
enum pdaAreas_t {
PDA_AREA_INVALID = -1,
PDA_AREA_USER_DATA,
PDA_AREA_USER_EMAIL,
PDA_AREA_VIDEO_DISKS,
PDA_AREA_INVENTORY,
PDA_NUM_AREAS
};
enum hudArea_t {
HUD_AREA_INVALID = -1,
HUD_AREA_PLAYING,
HUD_NUM_AREAS
};
enum scoreboardArea_t {
SCOREBOARD_AREA_INVALID = -1,
SCOREBOARD_AREA_DEFAULT,
SCOREBOARD_AREA_TEAM,
SCOREBOARD_AREA_CTF,
SCOREBOARD_NUM_AREAS
};
enum pdaHandlerWidgets_t {
PDA_WIDGET_NAV_BAR,
PDA_WIDGET_PDA_LIST,
PDA_WIDGET_PDA_LIST_SCROLLBAR,
PDA_WIDGET_CMD_BAR
};
enum scoreboardHandlerWidgets_t {
SCOREBOARD_WIDGET_CMD_BAR,
};
enum menuSounds_t {
GUI_SOUND_MUSIC,
GUI_SOUND_SCROLL,
GUI_SOUND_ADVANCE,
GUI_SOUND_BACK,
GUI_SOUND_BUILD_ON,
GUI_SOUND_BUILD_OFF,
GUI_SOUND_FOCUS,
GUI_SOUND_ROLL_OVER,
GUI_SOUND_ROLL_OUT,
NUM_GUI_SOUNDS,
};
static const int MAX_SCREEN_AREAS = 32;
static const int DEFAULT_REPEAT_TIME = 150;
static const int WAIT_START_TIME_LONG = 30000;
static const int WAIT_START_TIME_SHORT = 5000;
struct actionRepeater_t {
actionRepeater_t() :
widget( NULL ),
numRepetitions( 0 ),
nextRepeatTime( 0 ),
screenIndex( -1 ),
repeatDelay( DEFAULT_REPEAT_TIME ),
isActive( false ) {
}
idMenuWidget * widget;
idWidgetEvent event;
idWidgetAction action;
int numRepetitions;
int nextRepeatTime;
int repeatDelay;
int screenIndex;
bool isActive;
};
class mpScoreboardInfo{
public:
mpScoreboardInfo() :
voiceState( VOICECHAT_DISPLAY_NONE ),
score( 0 ),
wins( 0 ),
ping( 0 ),
team( -1 ),
playerNum( 0 ) {
}
mpScoreboardInfo( const mpScoreboardInfo & src ) {
voiceState = src.voiceState;
score = src.score;
wins = src.wins;
ping = src.ping;
spectateData = src.spectateData;
name = src.name;
team = src.team;
playerNum = src.playerNum;
}
void operator=( const mpScoreboardInfo & src ) {
voiceState = src.voiceState;
score = src.score;
wins = src.wins;
ping = src.ping;
spectateData = src.spectateData;
name = src.name;
team = src.team;
playerNum = src.playerNum;
}
bool operator!=( const mpScoreboardInfo & otherInfo ) const {
if ( otherInfo.score != score || otherInfo.wins != wins || otherInfo.ping != ping ||
otherInfo.spectateData != spectateData || otherInfo.name != name || otherInfo.team != team ||
otherInfo.playerNum != playerNum || otherInfo.voiceState != voiceState ) {
return true;
}
return false;
}
bool operator==( const mpScoreboardInfo & otherInfo ) const {
if ( otherInfo.score != score || otherInfo.wins != wins || otherInfo.ping != ping ||
otherInfo.spectateData != spectateData || otherInfo.name != name || otherInfo.team != team ||
otherInfo.playerNum != playerNum || otherInfo.voiceState != voiceState ) {
return false;
}
return true;
}
voiceStateDisplay_t voiceState;
int score;
int wins;
int ping;
int team;
int playerNum;
idStr spectateData;
idStr name;
};
/*
================================================
idMenuHandler
================================================
*/
class idMenuHandler {
public:
idMenuHandler();
virtual ~idMenuHandler();
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
virtual void Cleanup();
virtual void Update();
virtual void UpdateChildren();
virtual void UpdateMenuDisplay( int menu );
virtual bool HandleGuiEvent( const sysEvent_t * sev );
virtual bool IsActive();
virtual void ActivateMenu( bool show );
virtual void TriggerMenu();
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
virtual int ActiveScreen() { return activeScreen; }
virtual int NextScreen() { return nextScreen; }
virtual int MenuTransition() { return transition; }
virtual idMenuScreen * GetMenuScreen( int index ) { return NULL; }
virtual void SetNextScreen( int screen, int trans ) { nextScreen = screen; transition = trans; }
virtual void StartWidgetActionRepeater( idMenuWidget * widget, const idWidgetAction & action, const idWidgetEvent & event );
virtual void PumpWidgetActionRepeater();
virtual void ClearWidgetActionRepeater();
virtual idSWF * GetGUI() { return gui; }
virtual void AddChild( idMenuWidget * widget );
virtual idMenuWidget * GetChildFromIndex( int index );
virtual int GetPlatform( bool realPlatform = false );
virtual void PlaySound( menuSounds_t type, int channel = -1 );
virtual void StopSound( int channel = SCHANNEL_ANY );
idMenuWidget_CommandBar * GetCmdBar() { return cmdBar; }
protected:
bool scrollingMenu;
int scrollCounter;
int activeScreen;
int nextScreen;
int transition;
int platform;
idSWF * gui;
actionRepeater_t actionRepeater;
idMenuScreen * menuScreens[MAX_SCREEN_AREAS];
idList< idMenuWidget *, TAG_IDLIB_LIST_MENU> children;
idStaticList< idStr, NUM_GUI_SOUNDS > sounds;
idMenuWidget_CommandBar * cmdBar;
};
/*
================================================
lobbyPlayerInfo_t
================================================
*/
struct lobbyPlayerInfo_t {
lobbyPlayerInfo_t() :
partyToken( 0 ),
voiceState( VOICECHAT_DISPLAY_NONE ) {
}
idStr name;
int partyToken;
voiceStateDisplay_t voiceState;
};
/*
================================================
idMenuHandler_Shell
================================================
*/
class idMenuHandler_Shell : public idMenuHandler {
public:
idMenuHandler_Shell() :
state( SHELL_STATE_INVALID ),
nextState( SHELL_STATE_INVALID ),
smallFrameShowing( false ),
largeFrameShowing( false ),
bgShowing( true ),
nextPeerUpdateMs( 0 ),
inGame( false ),
waitForBinding( false ),
waitBind( NULL ),
newGameType( 0 ),
menuBar( NULL ),
pacifier( NULL ),
showingIntro( false ),
introGui( NULL ),
doom3Intro( NULL ),
roeIntro( NULL ),
lmIntro( NULL ),
typeSoundShader( NULL ),
continueWaitForEnumerate( false ),
gameComplete( false ),
marsRotation( NULL ) {
}
virtual void Update();
virtual void ActivateMenu( bool show );
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
virtual void Cleanup();
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
virtual idMenuScreen * GetMenuScreen( int index );
virtual bool HandleGuiEvent( const sysEvent_t * sev );
void UpdateSavedGames();
void ShowSmallFrame( bool show );
void ShowMPFrame( bool show );
void ShowLogo( bool show );
void SetShellState( shellState_t s ) { nextState = s; }
bool IsSmallFrameShowing() { return smallFrameShowing; }
void UpdateBGState();
void GetMapName( int index, idStr & name );
void GetModeName( int index, idStr & name );
idMenuWidget * GetPacifier() { return pacifier; }
idMenuWidget_MenuBar * GetMenuBar() { return menuBar; }
bool IsPacifierVisible() const { return ( pacifier != NULL && pacifier->GetSprite() != NULL ) ? pacifier->GetSprite()->IsVisible() : false; }
void ShowPacifier( const idStr & msg );
void HidePacifier();
void SetTimeRemaining( int time ) { timeRemaining = time; }
int GetTimeRemaining() { return timeRemaining; }
void SetNewGameType( int type ) { newGameType = type; }
int GetNewGameType() { return newGameType; }
void SetInGame( bool val ) { inGame = val; }
bool GetInGame() { return inGame; }
void HandleExitGameBtn();
void SetupPCOptions();
void SetWaitForBinding( const char * bind ) { waitForBinding = true; waitBind = bind; }
void ClearWaitForBinding() { waitForBinding = false; }
void UpdateLeaderboard( const idLeaderboardCallback * callback );
void UpdateLobby( idMenuWidget_LobbyList * lobbyList );
void ShowDoomIntro();
void ShowROEIntro();
void ShowLEIntro();
void StartGame( int index );
void SetContinueWaitForEnumerate( bool wait ) { continueWaitForEnumerate = wait; }
void SetCanContinue( bool valid );
void SetGameComplete() { gameComplete = true; }
bool GetGameComplete() { return gameComplete; }
private:
shellState_t state;
shellState_t nextState;
bool smallFrameShowing;
bool largeFrameShowing;
bool bgShowing;
bool waitForBinding;
const char * waitBind;
//idSysSignal deviceRequestedSignal;
idList<const char *, TAG_IDLIB_LIST_MENU> mpGameModes;
idList<mpMap_t, TAG_IDLIB_LIST_MENU> mpGameMaps;
idMenuWidget_MenuBar * menuBar;
idMenuWidget * pacifier;
int timeRemaining;
int nextPeerUpdateMs;
int newGameType;
bool inGame;
bool showingIntro;
bool continueWaitForEnumerate;
bool gameComplete;
idSWF * introGui;
const idSoundShader * typeSoundShader;
const idMaterial * doom3Intro;
const idMaterial * roeIntro;
const idMaterial * lmIntro;
const idMaterial * marsRotation;
idList< idStr, TAG_IDLIB_LIST_MENU> navOptions;
};
/*
================================================
idMenuHandler_PDA
================================================
*/
class idMenuHandler_PDA : public idMenuHandler {
public:
idMenuHandler_PDA() :
audioLogPlaying( false ),
videoPlaying( false ),
audioFile( NULL ) {
}
virtual ~idMenuHandler_PDA();
virtual void Update();
virtual void ActivateMenu( bool show );
virtual void TriggerMenu();
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
virtual idMenuScreen * GetMenuScreen( int index );
void UpdateAudioLogPlaying( bool playing );
void UdpateVideoPlaying( bool playing );
void ClearVideoPlaying() { videoPlaying = false; }
bool PlayPDAAudioLog( int pdaIndex, int audioIndex );
virtual void Cleanup();
protected:
bool audioLogPlaying;
bool videoPlaying;
idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > pdaNames;
idList< idStr, TAG_IDLIB_LIST_MENU > navOptions;
const idDeclAudio * audioFile;
idMenuWidget_ScrollBar pdaScrollBar;
idMenuWidget_DynamicList pdaList;
idMenuWidget_NavBar navBar;
idMenuWidget_CommandBar commandBarWidget;
};
/*
================================================
idMenuHandler_PDA
================================================
*/
class idMenuHandler_HUD : public idMenuHandler {
public:
idMenuHandler_HUD() :
autoHideTip( true ),
tipStartTime( 0 ),
hiding( false ),
radioMessage( false ) {
}
virtual void Update();
virtual void ActivateMenu( bool show );
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
virtual idMenuScreen * GetMenuScreen( int index );
idMenuScreen_HUD * GetHud();
void ShowTip( const char * title, const char * tip, bool autoHide );
void HideTip();
void SetRadioMessage( bool show ) { radioMessage = show; }
protected:
bool autoHideTip;
int tipStartTime;
bool hiding;
bool radioMessage;
};
/*
================================================
idMenuHandler_Scoreboard
================================================
*/
class idMenuHandler_Scoreboard : public idMenuHandler {
public:
idMenuHandler_Scoreboard() :
redScore( 0 ),
blueScore( 0 ),
activationScreen( SCOREBOARD_AREA_INVALID ) {
}
virtual void Update();
virtual void TriggerMenu();
virtual void ActivateMenu( bool show );
virtual void Initialize( const char * swfFile, idSoundWorld * sw );
virtual idMenuScreen * GetMenuScreen( int index );
virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false );
void AddPlayerInfo( int index, voiceStateDisplay_t voiceState, int team, idStr name, int score, int wins, int ping, idStr spectateData );
void UpdateScoreboard( idList< mpScoreboardInfo > & data, idStr gameInfo );
void UpdateVoiceStates();
void UpdateSpectating( idStr spectate, idStr follow );
void SetTeamScores( int r, int b );
int GetNumPlayers( int team );
void SetActivationScreen( int screen, int trans );
void ViewPlayerProfile( int slot );
void MutePlayer( int slot );
void GetUserID( int slot, lobbyUserID_t & luid );
void UpdateScoreboardSelection();
protected:
int redScore;
int blueScore;
int activationScreen;
idList< mpScoreboardInfo > scoreboardInfo;
idList< scoreboardInfo_t, TAG_IDLIB_LIST_MENU > redInfo;
idList< scoreboardInfo_t, TAG_IDLIB_LIST_MENU> blueInfo;
};
#endif //__MENUDATA_H__

Some files were not shown because too many files have changed in this diff Show More