as released 2003-11-05

This commit is contained in:
archive 2003-11-05 00:00:00 +00:00
commit 1134707c06
367 changed files with 298005 additions and 0 deletions

37
EF2-game.dsw Normal file
View file

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "game"=".\dlls\game\game.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/Code/DLLs/game", NEDAAAAA
.\dlls\game
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/EF2/Code", QJDAAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
EF2-game.ncb Normal file

Binary file not shown.

BIN
EF2-game.opt Normal file

Binary file not shown.

129
EF2.dsw Normal file
View file

@ -0,0 +1,129 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "EF2"=".\Executable\EF2.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/EF2/Code/Executable", UJDAAAAA
.\executable
end source code control
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name renderer
End Project Dependency
Begin Project Dependency
Project_Dep_Name uilib
End Project Dependency
Begin Project Dependency
Project_Dep_Name cgame
End Project Dependency
Begin Project Dependency
Project_Dep_Name game
End Project Dependency
}}}
###############################################################################
Project: "bspc"=".\Executable\bspc\bspc.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/EF2/Code/Executable/bspc", RTEAAAAA
.\Executable\bspc
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "cgame"=".\dlls\cgame\cgame.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/Code/DLLs/cgame", LEDAAAAA
.\dlls\cgame
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "game"=".\dlls\game\game.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/Code/DLLs/game", NEDAAAAA
.\dlls\game
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "renderer"=".\Libs\renderer\renderer.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/Code/Libs/renderer", MEDAAAAA
.\libs\renderer
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "uilib"=".\Libs\uilib\uilib.dsp" - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/Code/Libs/uilib", REDAAAAA
.\libs\uilib
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/EF2/Code", QJDAAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

13
Executable/gamedefs.h Normal file
View file

@ -0,0 +1,13 @@
//------------------------------------------------
// gamename.h -- Defines the name of the game.
//
// This file is included by q_shared.h, which happens
// to be in the game dll directory. However, we want
// the name of the game to be unique to each executable.
// Hence, it is part of the Executable directory structure,
// but lives at the executable dsp level.
//------------------------------------------------
#define GAME_NAME "Elite Force II"
#define GAME_EXE_VERSION "1.10"

View file

@ -0,0 +1,187 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/executable/win32/win_bounds.cpp $
// $Revision:: 4 $
// $Date:: 9/29/02 10:46a $
//
// Copyright (C) 1999 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Bounds checks all new's and delete's
//
extern "C"
{
void *b_malloc ( unsigned int size );
void b_free ( void * );
}
//////////////////////////
// Bounds checking
//
// #define DISABLE_BOUNDS to disable checking a compiler
// warning will happen if checking is enabled
//
// #define BOUNDS_ENDOFPAGE to check for overflowed, don't
// define it to check for underflows
//
// functions:
// void *b_malloc ( unsigned );
// Does a bounds-malloc, or just a normal one if checking's
// disabled
// void b_free ( void * );
// Frees a bounds pointer, or just a normal free if no
// checking
//
// void *operator new ( size_t ), operator new[] ( size )
// For C++ new's and new []'s, bounds checked
// void operator delete ( void * ), operator delete[] ( void * )
// For C++ delete's and delete []'s, bounds checked
//////////////////////////
#define DISABLE_BOUNDS
#if defined(GAME_DLL) || defined(CGAME_DLL)
#define DISABLE_BOUNDS
#endif
//#define BOUNDS_ENDOFPAGE
/////////////////////////
// If bounds are disabled
/////////////////////////
#ifdef DISABLE_BOUNDS
#include <malloc.h>
void *b_malloc ( unsigned int size )
{
return malloc ( size );
}
void b_free ( void *what )
{
free ( what );
}
///////////////////////////
// If bounds are enabled
///////////////////////////
#else
#pragma message ("win_bounds.cpp: Warning - Bounds checking is enabled\n" )
#include <stdio.h>
#include <windows.h>
typedef struct
{
unsigned int header;
int size;
void *returned;
} bounds_type_t;
#define PAGE_SIZE ( 4096 )
#define NORMAL_HEADER 0xdeadbeef
#define ARRAY_HEADER 0xdeadbabe
static unsigned int bounds_numpages ( unsigned int size )
{
unsigned int ret;
ret = size / PAGE_SIZE + 3;
if ( size % PAGE_SIZE )
ret++;
return ret;
}
void *bounds_malloc ( unsigned int size, unsigned head = NORMAL_HEADER )
{
bounds_type_t *where;
unsigned int num_pages;
void *mainaddress;
num_pages = bounds_numpages ( size );
mainaddress = VirtualAlloc ( NULL, num_pages * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS );
VirtualAlloc ( mainaddress, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE );
VirtualAlloc ( (char *) mainaddress + PAGE_SIZE * 2, ( num_pages - 3 ) * PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE );
where = (bounds_type_t *) mainaddress;
where->header = head;
where->size = size;
#ifdef BOUNDS_ENDOFPAGE
where->returned = (char *) mainaddress + ( num_pages - 1 ) * PAGE_SIZE - size;
#else
where->returned = (char *) mainaddress + PAGE_SIZE * 2;
#endif
memset ( where->returned, 0xdc, size );
return where->returned;
}
void bounds_free ( void *address, unsigned head = NORMAL_HEADER )
{
bounds_type_t *where;
unsigned int num_pages;
void *mainaddress;
mainaddress = (char *) address - PAGE_SIZE * 2;
#ifdef BOUNDS_ENDOFPAGE
mainaddress = (char *) mainaddress - ( (unsigned int) mainaddress % 4096 );
#endif
where = (bounds_type_t *) mainaddress;
if ( where->header != head || where->returned != address )
{
__asm int 3 // Breakpoint
}
num_pages = bounds_numpages ( where->size );
// All pages must be in the same state to be MEM_RELEASED
VirtualFree ( mainaddress, PAGE_SIZE, MEM_DECOMMIT );
VirtualFree ( (char *) mainaddress + PAGE_SIZE * 2, (num_pages - 3 ) * PAGE_SIZE, MEM_DECOMMIT );
VirtualFree ( mainaddress, 0, MEM_RELEASE );
}
void *b_malloc ( unsigned int size )
{
return bounds_malloc ( size );
}
void b_free ( void *what )
{
bounds_free ( what );
}
void *operator new[] ( size_t size )
{
return bounds_malloc ( size, ARRAY_HEADER );
}
void *operator new ( size_t size )
{
return bounds_malloc ( size );
}
void operator delete [] ( void *what )
{
if ( what )
bounds_free ( what, ARRAY_HEADER );
}
void operator delete ( void *what )
{
if ( what )
bounds_free ( what );
}
#endif /* !DISABLE_BOUNDS */

117
Shared/qcommon/alias.h Normal file
View file

@ -0,0 +1,117 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/Shared/qcommon/alias.h $
// $Revision:: 5 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Generic alias system for files.
//
#ifndef __ALIAS_H__
#define __ALIAS_H__
#ifdef __cplusplus
extern "C" {
#endif
//
// public implementation
//
const char * Alias_Find( const char * alias );
qboolean Alias_Add( const char * alias, const char * name, const char * parameters );
qboolean Alias_Delete( const char * alias );
const char * Alias_FindRandom( const char * alias );
void Alias_Dump( void );
void Alias_Clear( void );
//
// private implementation
//
#define MAX_ALIAS_NAME_LENGTH 32
#define MAX_REAL_NAME_LENGTH 128
#define MAX_ANIM_NAME_LENGTH 128
#define MAX_ALIASLIST_NAME_LENGTH MAX_QPATH
typedef struct AliasActorNode_s
{
int actor_number;
int number_of_times_played;
byte been_played_this_loop;
int last_time_played;
struct AliasActorNode_s * next;
} AliasActorNode_t;
typedef struct AliasListNode_s
{
char alias_name[MAX_ALIAS_NAME_LENGTH];
char real_name[MAX_REAL_NAME_LENGTH];
char anim_name[MAX_ANIM_NAME_LENGTH];
float weight;
qboolean loop_anim;
// Static alias info
byte global_flag;
byte stop_flag;
float timeout;
int maximum_use;
// Global alias info
int number_of_times_played;
byte been_played_this_loop;
int last_time_played;
// Actor infos
AliasActorNode_t *actor_list;
struct AliasListNode_s * next;
} AliasListNode_t;
typedef struct AliasList_s
{
char name[ MAX_ALIASLIST_NAME_LENGTH ];
qboolean dirty;
int num_in_list;
AliasListNode_t ** sorted_list;
AliasListNode_t * data_list;
} AliasList_t;
void Alias_ListClearActors( const AliasList_t * list );
AliasList_t * AliasList_New( const char * name );
const char * Alias_ListFind( AliasList_t * list, const char * alias );
AliasListNode_t *Alias_ListFindNode( AliasList_t * list, const char * alias );
qboolean Alias_ListAdd( AliasList_t * list, const char * alias, const char * name, const char * parameters );
const char * Alias_ListFindRandom( AliasList_t * list, const char * alias );
void Alias_ListDump( AliasList_t * list );
void Alias_ListClear( AliasList_t * list );
void Alias_ListDelete( AliasList_t * list );
void Alias_ListSort( AliasList_t * list );
int Alias_IsGlobal( const AliasListNode_t *node, int actor_number );
AliasActorNode_t *Alias_FindActor( const AliasListNode_t *node, int actor_number );
void Alias_ListFindRandomRange( AliasList_t * list, const char * alias, int *min_index, int *max_index, float *total_weight );
const char * Alias_ListFindDialog( AliasList_t * list, const char * alias, int random, int actor_number);
const char* Alias_ListFindSpecificAnim( const AliasList_t *list, const char *name );
qboolean Alias_ListCheckLoopAnim( const AliasList_t *list, const char *name );
void Alias_ListUpdateDialog( AliasList_t * list, const char * alias, int number_of_times_played, byte been_played_this_loop, int last_time_played );
void Alias_ListAddActorDialog( AliasList_t * list, const char * alias, int actor_number, int number_of_times_played, byte been_played_this_loop, int last_time_played );
float randweight( void );
#ifdef __cplusplus
}
#endif
#endif /* alias.h */

115
Shared/qcommon/cm_public.h Normal file
View file

@ -0,0 +1,115 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/Shared/qcommon/cm_public.h $
// $Revision:: 16 $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 1999 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
//
#ifndef __CM_PUBLIC_H__
#define __CM_PUBLIC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "qfiles.h"
void CM_LoadMap( const char *name, qboolean clientload, int *checksum);
clipHandle_t CM_InlineModel( int index ); // 0 = world, 1 + are bmodels
clipHandle_t CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, int contents );
void CM_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs );
int CM_NumClusters (void);
int CM_NumInlineModels( void );
char *CM_EntityString (void);
// returns an ORed contents mask
int CM_PointContents( const vec3_t p, clipHandle_t model );
int CM_PointBrushNum( const vec3_t p, clipHandle_t model );
int CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin, const vec3_t angles );
void CM_BoxTrace ( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask, qboolean cylinder);
void CM_BoxTraceEx ( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask, qboolean cylinder, const unsigned int traceExFlags );
void CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask,
const vec3_t origin, const vec3_t angles, qboolean cylinder, qboolean force_rotation );
byte *CM_ClusterPVS (int cluster);
int CM_PointLeafnum( const vec3_t p );
void CM_Clear( void );
// only returns non-solid leafs
// overflow if return listsize and if *lastLeaf != list[listsize-1]
int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list,
int listsize, int *lastLeaf );
int CM_LeafCluster (int leafnum);
int CM_LeafArea (int leafnum);
void CM_AdjustAreaPortalState( int area1, int area2, qboolean open );
qboolean CM_AreasConnected( int area1, int area2 );
void CM_ResetAreaPortals( void );
void CM_WritePortalState( fileHandle_t );
void CM_ReadPortalState( fileHandle_t );
int CM_WriteAreaBits( byte *buffer, int area );
byte *CM_VisibilityPointer( void );
int CM_GetLightingGroup( const char *group_name );
// cm_tag.c
void CM_LerpTag( orientation_t *tag, clipHandle_t model, int startFrame, int endFrame,
float frac, const char *tagName );
// cm_marks.c
int CM_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer, float max_dist, qboolean test_normal );
// cm_patch.c
void CM_DrawDebugSurface( void (*drawPoly)(int color, int numPoints, float *points) );
void CM_DrawDebugTerrain( void (*drawPoly)(unsigned int color, int numPoints, float *points) );
// ToolServer wrapper functions
void ToolServerInit( void );
void ToolServerShutdown( void );
void ToolServerProcessCommands( void );
void* ToolServerGetData( void );
unsigned int ToolServerGetNumClients();
// GameplayManager functions
void CreateGameplayManager( void );
void ShutdownGameplayManager( void );
// LoadSaveGameManager functions
void CreateLoadSaveGameManager( void );
void DeleteLoadSaveGameManager( void );
//Arena Controller functions
void CreateArenaController( void );
void DeleteArenaController( void );
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,296 @@
// GameplayDatabase.h: interface for the GameplayDatabase class.
//
//////////////////////////////////////////////////////////////////////
class GameplayDatabase;
class GameplayObject;
class GameplayProperty;
#ifndef __GAMEPLAYDATABASE_H__
#define __GAMEPLAYDATABASE_H__
#ifdef GAME_DLL
#include <game/g_local.h>
#include <game/script.h>
#endif // GAME_DLL
// Select a parser to use. We wouldn't have to do this part
// if the system didn't have 10000 parsers.
#ifdef GAME_DLL
#define Parser Script
#else
#define Parser TikiScript
#endif // GAME_DLL
#define HASH_SIZE 256
#include <game/class.h>
#include <game/listener.h>
#include <game/str.h>
#include <game/container.h>
#include <qcommon/tiki_script.h>
typedef enum GameplayValueType
{
VALUE_FLOAT,
VALUE_STRING,
VALUE_VECTOR,
GAMEPLAY_VALUE_UNSPECIFIED
};
//------------------------ CLASS -------------------------------
//
// Name: PendingDelta
// Base Class: None
//
// Description: This class stores a database delta. When
// a game is saved, all the changes to the database
// are stored in the save game file. When this
// file is loaded, these changes are made back to
// the gameplay database.
//
// However, the changes are made before the client
// has had a chance to initialize. We store off
// all these changes until then. When the server
// learns the player is fully initialized, the
// GameplayManager will ask for this list of
// pending deltas. It will then send them all
// to the client.
//-------------------------------------------------------------
class PendingDelta
{
private:
str _objName ;
str _propName ;
str _stringValue ;
float _floatValue ;
Vector _vectorValue ;
GameplayValueType _type ;
public:
PendingDelta() : _type( GAMEPLAY_VALUE_UNSPECIFIED ) { }
PendingDelta( const str &objName, const str &propName, float floatValue )
: _objName( objName ), _propName( propName ), _floatValue( floatValue ), _type( VALUE_FLOAT ) { }
PendingDelta( const str &objName, const str &propName, const str &stringValue )
: _objName( objName ), _propName( propName ), _stringValue( stringValue ), _type( VALUE_STRING ) { }
PendingDelta( const str &objName, const str &propName, const Vector &vectorValue )
: _objName( objName ), _propName( propName ), _vectorValue( vectorValue ), _type( VALUE_VECTOR ) { }
float getFloatValue() { return _floatValue ; }
const str& getStringValue() { return _stringValue ; }
const Vector& getVectorValue() { return _vectorValue ; }
const str& getObjectName() { return _objName ; }
const str& getPropertyName() { return _propName ; }
GameplayValueType getGameplayValueType() { return _type ; }
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayProperty
// Base Class: Class
//
// Description: Object that has a key and a value which can be
// a string or a float
//
// Method of Use: Used in GameplayObject's
//
//--------------------------------------------------------------
class GameplayProperty : public Class
{
private:
str _name;
str _valuestr;
float _valuefloat;
Vector _valuevector;
bool _modified;
GameplayValueType _type;
public:
CLASS_PROTOTYPE( GameplayProperty );
GameplayProperty()
: _name(""),
_valuestr(""),
_valuefloat(1.0f),
_modified(false),
_type(VALUE_FLOAT),
_valuevector(vec_zero)
{}
virtual ~GameplayProperty() {}
// Parsing
bool parseProperty(Parser &gameplayFile, const str& type);
bool isModified( void ) { return _modified ; }
// Accessors -- Gets
const str& getName() { return _name; }
const str& getStringValue() { return _valuestr; }
float getFloatValue() { return _valuefloat; }
const Vector& getVectorValue() { return _valuevector; }
bool getModified() { return _modified; }
GameplayValueType getType() { return _type; }
const str getFloatValueStr();
// Accessors -- Sets
void setName(const str& name);
void setModified(bool modified) { _modified = modified; }
void setType(GameplayValueType type) { _type = type; }
bool setStringValue(const str& valuestr);
bool setFloatValue(float valuefloat);
bool setVectorValue(const Vector& vector);
#ifdef GAME_DLL
public:
void Archive(Archiver &arc);
#endif // GAME_DLL
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayObject
// Base Class: Class
//
// Description: Object that has a name, and a container of
// GameplayProperty's.
//
// Method of Use: Used in GameplayDatabase
//
//--------------------------------------------------------------
class GameplayObject : public Class
{
private:
str _name;
str _category;
str _fullScopeName;
int _depth;
bool _modified ;
GameplayObject* _baseObject;
GameplayObject* _nextHashObject;
Container<GameplayProperty *> _propertyList;
Container<GameplayObject *> _subObjectList;
public:
CLASS_PROTOTYPE( GameplayObject );
GameplayObject();
GameplayObject(int depth);
virtual ~GameplayObject();
// Parsing
bool parseObject(Parser &gameplayFile, const str& name);
//Queries
bool hasProperty(const str& propname, bool localonly = false);
bool isModified( void ) { return _modified ; }
// Accessors -- Gets
const str& getName() { return _name; }
const str& getCategory() { return _category; }
const str& getFullScopeName() { return _fullScopeName; }
const Container<GameplayObject *>& getSubObjectList() { return _subObjectList; };
const Container<GameplayProperty *>& getPropertyList() { return _propertyList; };
GameplayObject* getBaseObject() { return _baseObject; }
GameplayObject* getNextObject() { return _nextHashObject; }
GameplayObject* getSubObject(const str& subobjname);
GameplayProperty* getProperty(const str& propname);
float getPropertyFloatValue(const str& propname);
const str getPropertyStringValue(const str& propname);
bool getModified(const str& propname);
int getNumberOfModifiedProperties( void );
// Accessors -- Sets
void setModified( bool modified ) { _modified = modified ; }
void setName(const str& name) { _name = name; }
void setCategory(const str& category) { _category = category; }
void setFullScopeName(const str& fullscope) { _fullScopeName = fullscope; }
void setBaseObject(GameplayObject* baseObject) { _baseObject = baseObject; }
void setNextObject(GameplayObject *nextObject) { _nextHashObject = nextObject; }
bool setFloatValue(const str& propname, float value, bool create = false);
bool setStringValue(const str& propname, const str& valuestr, bool create = false);
bool setVectorValue( const str& propname, const Vector& valuevector, bool create = false );
// Deletion
bool removeProperty(const str& propname);
#ifdef GAME_DLL
public:
void Archive(Archiver &arc);
#endif // GAME_DLL
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayDatabase
// Base Class: Listener
//
// Description: Database of GameplayObjects. Queries are made
// to this database to retrieve the data
//
// Method of Use: Used by the GameplayManager
//
//--------------------------------------------------------------
class GameplayDatabase : public Listener
{
private:
Container<PendingDelta> _pendingDeltaList ;
Container<GameplayObject *> _objectList;
GameplayObject* _hashTable[HASH_SIZE];
// Saved off last object reference
GameplayObject *_lastObj;
str _lastObjName;
// Private Functions
void _linkSubObjectsToBase();
void _linkToBase(GameplayObject *object);
GameplayObject* _createFromScope(const str& scope);
bool _addToHashTable(GameplayObject *object);
void _buildHashTable();
public:
CLASS_PROTOTYPE( GameplayDatabase );
GameplayDatabase();
virtual ~GameplayDatabase();
// Parsing
bool parseFile(const str& filename);
// Queries
bool hasObject(const str& objname);
// Accessors -- Gets
GameplayObject* getObject(const str& objname);
GameplayObject* getRootObject(const str& objname);
GameplayObject* getSubObject(const str& objname, const str& subobjname);
int getNumberOfModifiedObjects( void );
float getFloatValue(const str& objname, const str& propname);
const str getStringValue(const str& objname, const str& propname);
Container<PendingDelta>& getPendingDeltaList() { return _pendingDeltaList ; }
// Accessors -- Sets
bool setFloatValue(const str& objname, const str& propname, float value, bool create = false);
bool setStringValue(const str& objname, const str& propname, const str& valuestr, bool create = false);
bool setVectorValue( const str& objname, const str& propname, const Vector& valuevalue, bool create = false );
bool setBase(const str& objname, const str& baseobj);
bool clearPropertyOverrides(const str& objname);
void clearPendingDeltaList() { _pendingDeltaList.FreeObjectList(); }
#ifdef GAME_DLL
public:
void Archive(Archiver &arc);
#endif // GAME_DLL
};
#endif

View file

@ -0,0 +1,499 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/Shared/qcommon/gameplayformulamanager.cpp $
// $Revision:: 4 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// GameplayFormulaManager.cpp: implementation of the GameplayFormulaManager class.
//
//////////////////////////////////////////////////////////////////////
#ifdef GAME_DLL
#include "gameplayformulamanager.h"
#include "gameplaymanager.h"
////////////////////////////////////////////////////////////////
//
// GameplayFormulaData CLASS
//
////////////////////////////////////////////////////////////////
//--------------------------------------------------------------
//
// Name: GameplayFormulaData
// Class: GameplayFormulaData
//
// Description: Constructor
//
// Parameters: Entity *primary -- Default 0
// Entity *secondary -- Default 0
// Entity *weapon -- Default 0
// const str& attackType -- Default ""
//
// Returns:
//
//--------------------------------------------------------------
GameplayFormulaData::GameplayFormulaData( Entity *pPrimary, Entity *pSecondary, Entity *pWeapon, const str& pAttackType )
{
primary = pPrimary;
secondary = pSecondary;
weapon = pWeapon;
attackType = pAttackType;
}
////////////////////////////////////////////////////////////////
//
// GameplayFormulaVariable CLASS
//
////////////////////////////////////////////////////////////////
//--------------------------------------------------------------
//
// Name: GameplayFormulaVariable
// Class: GameplayFormulaVariable
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayFormulaVariable::GameplayFormulaVariable()
{
_categoryList.ClearObjectList();
}
//--------------------------------------------------------------
//
// Name: ~GameplayFormulaVariable
// Class: GameplayFormulaVariable
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayFormulaVariable::~GameplayFormulaVariable()
{
}
////////////////////////////////////////////////////////////////
//
// GameplayFormulaOperand CLASS
//
////////////////////////////////////////////////////////////////
//--------------------------------------------------------------
//
// Name: getResult
// Class: GameplayFormulaOperand
//
// Description: Gets the result of the operand given the data
//
// Parameters: const GameplayFormulaData& formulaData -- Data to use
//
// Returns: float -- The result, or 1.0 if there's a problem
//
//--------------------------------------------------------------
float GameplayFormulaOperand::getResult(const GameplayFormulaData& formulaData)
{
float finalResult = _constant; // Constant is factored in here.
str name;
GameplayManager *gpm = GameplayManager::getTheGameplayManager();
char firstobj[255], *sptr;
strcpy(firstobj, _object.c_str());
sptr = strchr(firstobj, '.');
sptr = 0;
// Defines are a special case
if ( !strcmp(firstobj,"Defines") )
{
finalResult *= gpm->getFloatValue(_property, "value");
return finalResult;
}
if ( !strcmp(firstobj, "Primary") && formulaData.primary )
name = formulaData.primary->getArchetype();
if ( !strcmp(firstobj, "Secondary") && formulaData.secondary )
name = formulaData.secondary->getArchetype();
if ( !strcmp(firstobj, "Weapon") && formulaData.weapon )
name = formulaData.weapon->getArchetype();
if ( !strcmp(firstobj, "AttackType") )
name = formulaData.attackType;
// The object was not one of the code-keywords, check the database
// itself for the object and property.
if ( !name.length() )
{
finalResult *= gpm->getFloatValue(_object, _property);
return finalResult;
}
if ( _inverse )
finalResult *= (1.0f / gpm->getFloatValue(name, _property));
else
finalResult *= gpm->getFloatValue(name, _property);
return finalResult;
}
//--------------------------------------------------------------
//
// Name: paraseOperand
// Class: GameplayFormulaOperand
//
// Description: Parses the operand
//
// Parameters: Script &formulaFile -- The file to parse
// const str& token -- The first token
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayFormulaOperand::parseOperand(Script &formulaFile, const str& constant)
{
const char *token;
_constant = (float)atof(constant);
if ( !formulaFile.TokenAvailable(false) )
return false;
token = formulaFile.GetToken(false);
if ( token[0] == '/' )
_inverse = true;
if ( !formulaFile.TokenAvailable(false) )
return false;
token = formulaFile.GetToken(false);
char *sptr, tmpstr[255];
strcpy(tmpstr, token);
sptr = strrchr(tmpstr,'.');
if ( sptr )
{
*sptr = 0;
sptr++;
}
_object = tmpstr;
_property = sptr;
return true;
}
////////////////////////////////////////////////////////////////
//
// GameplayFormula CLASS
//
////////////////////////////////////////////////////////////////
//--------------------------------------------------------------
//
// Name: GameplayFormula
// Class: GameplayFormula
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayFormula::GameplayFormula()
{
_operandList.ClearObjectList();
}
//--------------------------------------------------------------
//
// Name: ~GameplayFormula
// Class: GameplayFormula
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayFormula::~GameplayFormula()
{
int i;
for ( i=1; i<=_operandList.NumObjects(); i++ )
{
GameplayFormulaOperand *gpfo = _operandList.ObjectAt(i);
delete gpfo;
}
_operandList.ClearObjectList();
}
//--------------------------------------------------------------
//
// Name: getResult
// Class: GameplayFormula
//
// Description: Gets the result of a formula given it's the data
//
// Parameters: const GameplayFormulaData& formulaData -- Data to use
//
// Returns: float -- The result, or 1.0 if there's a problem
//
//--------------------------------------------------------------
float GameplayFormula::getResult(const GameplayFormulaData& formulaData)
{
float finalResult = 1.0f;
int i;
for ( i=1; i<=_operandList.NumObjects(); i++ )
{
GameplayFormulaOperand *gpfo = _operandList.ObjectAt(i);
finalResult *= gpfo->getResult(formulaData);
}
return finalResult;
}
//--------------------------------------------------------------
//
// Name: paraseFormula
// Class: GameplayFormula
//
// Description: Parses the formula
//
// Parameters: Script &formulaFile -- The file to parse
// const str& name -- The token
//
// Returns:
//
//--------------------------------------------------------------
bool GameplayFormula::parseFormula(Script &formulaFile, const str& name)
{
const char *token;
GameplayFormulaOperand *gpfo;
if ( name != "FORMULA" )
return false;
if ( !formulaFile.TokenAvailable(false) )
return false;
token = formulaFile.GetToken(false);
setName(token);
// Get the open brace
token = formulaFile.GetToken(true);
if ( token[0] != '{' )
assert(0);
while (formulaFile.TokenAvailable(true))
{
token = formulaFile.GetToken(true);
// If we have a close brace, we're done.
if ( token[0] == '}' )
return true;
gpfo = new GameplayFormulaOperand();
if ( gpfo->parseOperand(formulaFile, token) )
_operandList.AddObject(gpfo);
else
{
delete gpfo;
return false;
}
}
// Premature end of file, missing close brace.
return false;
}
////////////////////////////////////////////////////////////////
//
// GameplayFormulaManager CLASS
//
////////////////////////////////////////////////////////////////
//--------------------------------------------------------------
//
// Name: GameplayFormulaManager
// Class: GameplayFormulaManager
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayFormulaManager::GameplayFormulaManager()
{
_variableList.ClearObjectList();
_formulaList.ClearObjectList();
}
//--------------------------------------------------------------
//
// Name: ~GameplayFormulaManager
// Class: GameplayFormulaManager
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayFormulaManager::~GameplayFormulaManager()
{
int i;
for ( i=1; i<=_variableList.NumObjects(); i++ )
{
GameplayFormulaVariable *gpfv = _variableList.ObjectAt(i);
delete gpfv;
}
for ( i=1; i<=_formulaList.NumObjects(); i++ )
{
GameplayFormula *gpf = _formulaList.ObjectAt(i);
delete gpf;
}
_variableList.FreeObjectList();
_formulaList.FreeObjectList();
}
//--------------------------------------------------------------
//
// Name: getFormulaResult
// Class: GameplayFormulaManager
//
// Description: Gets the result of a formula given it's name and the data
//
// Parameters: const str& formulaName -- Name of the formula to use
// const GameplayFormulaData& formulaData -- Data to use
//
// Returns: float -- The result, or 1.0 if there's a problem
//
//--------------------------------------------------------------
float GameplayFormulaManager::getFormulaResult(const str& formulaName, const GameplayFormulaData& formulaData)
{
float finalResult = 1.0f;
int i;
for ( i=1; i<=_formulaList.NumObjects(); i++ )
{
GameplayFormula *gpf = _formulaList.ObjectAt(i);
if ( gpf->getName() == formulaName )
{
// Found the matching formula, get the result.
finalResult = gpf->getResult(formulaData);
return finalResult;
}
}
return finalResult;
}
//--------------------------------------------------------------
//
// Name: parseFile
// Class: GameplayFormulaManager
//
// Description: Reads and parses the formula file
//
// Parameters: const str& filename -- Name of the file
//
// Returns: bool -- sucessful parse or not
//
//--------------------------------------------------------------
bool GameplayFormulaManager::parseFile(const str& filename)
{
Script formulaFile;
const char *token;
GameplayFormula *gpformula;
if ( !gi.FS_Exists(filename.c_str()) )
return false;
formulaFile.LoadFile(filename.c_str());
while (formulaFile.TokenAvailable(true))
{
token = formulaFile.GetToken(false);
// If the first token isn't a formula, there's a problem
if ( strcmp(token, "FORMULA") )
return false;
gpformula = new GameplayFormula();
if ( gpformula->parseFormula(formulaFile, token) )
_formulaList.AddObject(gpformula);
else
{
delete gpformula;
return false;
}
}
return true;
}
//--------------------------------------------------------------
//
// Name: hasFormula
// Class: GameplayFormulaManager
//
// Description: Checks to see if the formula exists
//
// Parameters: const str& formulaName
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayFormulaManager::hasFormula(const str& formulaName)
{
int i;
for ( i=1; i<=_formulaList.NumObjects(); i++ )
{
GameplayFormula *gpf = _formulaList.ObjectAt(i);
if ( gpf->getName() == formulaName )
return true;
}
return false;
}
#endif // GAME_DLL

View file

@ -0,0 +1,196 @@
// GameplayFormulaManager.h: interface for the GameplayFormulaManager class.
//
//////////////////////////////////////////////////////////////////////
#ifdef GAME_DLL
class GameplayFormulaManager;
class GameplayFormula;
class GameplayFormulaVariable;
class GameplayFormulaData;
class GameplayFormulaOperand;
#ifndef __GAMEPLAY_FORMULA_MANAGER_H__
#define __GAMEPLAY_FORMULA_MANAGER_H__
#include <game/g_local.h>
#include <game/actor.h>
#include <game/weapon.h>
#include <game/entity.h>
#include <game/player.h>
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaData
// Base Class: Class
//
// Description: Utility class to the GameplayFormulaManager
//
// Method of Use: The user will build on of these objects to pass
// into the GameplayManager query functions.
//
//--------------------------------------------------------------
class GameplayFormulaData : public Class
{
public:
GameplayFormulaData( Entity *pPrimary = 0,
Entity *pSecondary = 0,
Entity *pWeapon = 0,
const str& pAttackType = "");
Entity *primary;
Entity *secondary;
Entity *weapon;
str attackType;;
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaVariable
// Base Class: Class
//
// Description: Variable that contains the list of categories that
// are specific to a variable type.
//
// Method of Use: GameplayFormula uses this class
//
//--------------------------------------------------------------
class GameplayFormulaVariable : public Class
{
private:
str _name;
Container<str> _categoryList;
public:
GameplayFormulaVariable();
virtual ~GameplayFormulaVariable();
// Accessors
const str& getName() { return _name; }
void setName(const str& name) { _name = name; }
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaOperand
// Base Class: Class
//
// Description: A operand in a formula
//
// Method of Use: GameplayFormula has a list of these to multiply together
//
//--------------------------------------------------------------
class GameplayFormulaOperand : public Class
{
private:
float _constant;
str _object;
str _property;
bool _inverse;
public:
GameplayFormulaOperand()
: _constant(1.0f),
_inverse(false)
{}
virtual ~GameplayFormulaOperand() {}
// Accessors
const str& getObjectName() { return _object; }
void setObjectName(const str& object) { _object = object; }
const str& getPropertyName() { return _property; }
void setPropertyName(const str& property) { _property = property; }
float getConstant() { return _constant; }
void setConstant(float constant) { _constant = constant; }
bool getInverseFlag() { return _inverse; }
void setInverseFlag(bool inverse) { _inverse = inverse; }
// Queries
float getResult(const GameplayFormulaData& formulaData);
// Parsing
bool parseOperand(Script &formulaFile, const str& constant);
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormula
// Base Class: Class
//
// Description: A formula in the for the GameplayManager
//
// Method of Use: GameplayFormulaManager requests data from this class
//
//--------------------------------------------------------------
class GameplayFormula : public Class
{
private:
str _name;
Container<GameplayFormulaOperand *> _operandList;
public:
GameplayFormula();
virtual ~GameplayFormula();
// Accessors
const str& getName() { return _name; }
void setName(const str& name) { _name = name; }
// Queries
float getResult(const GameplayFormulaData& formulaData );
// Parsing
bool parseFormula(Script &formulaFile, const str& name);
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaManager
// Base Class: Class
//
// Description: The manager for all the formulas. Accessed
// by the GameplayManager
//
// Method of Use: GameplayManager uses this class to access formulas
//
//--------------------------------------------------------------
class GameplayFormulaManager : public Class
{
private:
Container<GameplayFormulaVariable *> _variableList;
Container<GameplayFormula *> _formulaList;
public:
GameplayFormulaManager();
virtual ~GameplayFormulaManager();
// Queries
float getFormulaResult(const str& formulaName, const GameplayFormulaData& formulaData);
bool hasFormula(const str& formulaName);
// Parsing
bool parseFile(const str& filename);
};
#endif // __GAMEPLAY_FORMULA_MANAGER_H__
#endif // GAME_DLL

View file

@ -0,0 +1,850 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/Shared/qcommon/gameplaymanager.cpp $
// $Revision:: 14 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// GameplayManager.cpp: implementation of the GameplayManager class.
//
//////////////////////////////////////////////////////////////////////
#include "gameplaymanager.h"
#include <assert.h>
//#include <qcommon/qcommon.h>
// The Singleton
GameplayManager *GameplayManager::_theGameplayManager = 0;
//--------------------------------------------------------------
//
// Name: GameplayManager
// Class: GameplayManager
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayManager::GameplayManager()
{
}
//--------------------------------------------------------------
//
// Name: ~GameplayManager
// Class: GameplayManager
//
// Description: Destructor.
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
GameplayManager::~GameplayManager()
{
}
//--------------------------------------------------------------
// Name: Shutdown (static)
// Class: GameplayManager
//
// Description: Destroys the GPM variable
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
void GameplayManager::shutdown()
{
if ( _theGameplayManager )
{
delete _theGameplayManager;
_theGameplayManager = 0;
}
}
//--------------------------------------------------------------
// Name: IsReady (static)
// Class: GameplayManager
//
// Description: Determines if the GPM variable has been created yet
//
// Parameters: None
//
// Returns: bool -- Is ready or not
//
//--------------------------------------------------------------
bool GameplayManager::isReady()
{
if ( _theGameplayManager )
return true;
return false;
}
//--------------------------------------------------------------
// Name: getTheGameplayManager (static)
// Class: GameplayManager
//
// Description: Interface function to the GameplayManager singleton
//
// Parameters: None
//
// Returns: Pointer to the GameplayManager singleton
//
//--------------------------------------------------------------
GameplayManager* GameplayManager::getTheGameplayManager()
{
if ( _theGameplayManager )
return _theGameplayManager;
assert(0); // Something called this function before create();
return 0;
}
//--------------------------------------------------------------
// Name: Create (static)
// Class: GameplayManager
//
// Description: Creates the GPM singleton.
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
void GameplayManager::create()
{
if ( _theGameplayManager )
shutdown();
_theGameplayManager = new GameplayManager;
if (!_theGameplayManager)
{
// This probably won't happen unless we're out of memory
assert(0);
}
if ( !_theGameplayManager->_gameplayDatabase.parseFile("global/gameplay.gdb") )
{
// Parsing the database file failed!
assert(0);
Com_Error (ERR_DROP, "GameplayDatabase: Parsing failed. Contact programmer regarding this error.");
}
#ifdef GAME_DLL
if ( !_theGameplayManager->_gameplayFormulaManager.parseFile("global/gameplay.gpf") )
{
// Parsing the formula file failed!
assert(0);
gi.Error(ERR_DROP, "GameplayFormulas: Parsing failed. Contact programmer regarding this error.");
}
#endif // GAME_DLL
}
//--------------------------------------------------------------
//
// Name: hasObject
// Class: GameplayManager
//
// Description: Checks to see if an object is in the database
//
// Parameters: const str& objname -- Name of the object
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayManager::hasObject(const str& objname)
{
if ( !objname.length() )
return false;
return _gameplayDatabase.hasObject(objname);
}
//--------------------------------------------------------------
//
// Name: isDefined
// Class: GameplayManager
//
// Description: Checks to see if the specified property
// exists as a define in the database.
//
// Parameters: const str& propname -- Property to find
//
// Returns: bool -- True if exists
//
//--------------------------------------------------------------
bool GameplayManager::isDefined(const str& propname)
{
GameplayObject *gpobject = _gameplayDatabase.getObject(propname);
if ( !gpobject )
return false;
if ( gpobject->hasProperty("value") )
return true;
return false;
}
//--------------------------------------------------------------
//
// Name: getDefine
// Class: GameplayManager
//
// Description: Returns the define as a string
//
// Parameters: const str& propname -- Property to find
//
// Returns: const str& -- the define as a string
//
//--------------------------------------------------------------
const str GameplayManager::getDefine(const str& propname)
{
GameplayObject *gpobject = _gameplayDatabase.getObject(propname);
if ( !gpobject )
return ""; // Should never happen since we go through isDefined first
str value = gpobject->getPropertyStringValue("value");
if ( value == "" )
{
float floatval;
char tmpstr[16];
floatval = gpobject->getPropertyFloatValue("value");
sprintf(tmpstr, "%g", floatval);
value = tmpstr;
}
return value;
}
//--------------------------------------------------------------
//
// Name: setFloatValue
// Class: GameplayManager
//
// Description: Sets float value of a property.
//
// Parameters: const str& objname -- Object name
// const str& propname -- Property name
// float value -- value
// bool create -- whether or not to create properties that are not found
//
// Returns: None
//
//--------------------------------------------------------------
void GameplayManager::setFloatValue(const str& objname, const str& propname, float value, bool create)
{
#ifdef GAME_DLL
bool valueChanged = _gameplayDatabase.setFloatValue(objname, propname, value, create);
if ( valueChanged )
{
char message[256] ;
sprintf( message, "gdb_setfloatproperty %s %s %g\n", objname.c_str(), propname.c_str(), value );
G_SendCommandToAllPlayers( message );
}
#else
_gameplayDatabase.setFloatValue(objname, propname, value, create);
#endif // GAME_DLL
}
//--------------------------------------------------------------
//
// Name: setStringValue
// Class: GameplayManager
//
// Description: Sets float value of a property.
//
// Parameters: const str& objname -- Object name
// const str& propname -- Property name
// const str& value -- string value
// bool create -- whether or not to create properties that are not found
//
// Returns: None
//
//--------------------------------------------------------------
void GameplayManager::setStringValue(const str& objname, const str& propname, const str& valuestr, bool create)
{
#ifdef GAME_DLL
bool valueChanged = _gameplayDatabase.setStringValue(objname, propname, valuestr, create);
if ( valueChanged )
{
char message[256] ;
sprintf( message, "gdb_setstringproperty %s %s %s\n", objname.c_str(), propname.c_str(), valuestr.c_str() );
G_SendCommandToAllPlayers( message );
}
#else
_gameplayDatabase.setStringValue(objname, propname, valuestr, create);
#endif // GAME_DLL
}
//--------------------------------------------------------------
//
// Name: getFloatValue
// Class: GameplayManager
//
// Description: Gets the float value of the property.
//
// Parameters: const str& objname -- Object to retrieve the property from, supports scoping
// via the . symbol, example: "Object1.SubObject"
//
// Returns: float -- Float value of the property or 1.0
//
//--------------------------------------------------------------
float GameplayManager::getFloatValue(const str& objname, const str& propname)
{
if ( !hasObject(objname) )
return 1.0f;
GameplayObject *gpobject = 0;
gpobject = _gameplayDatabase.getObject(objname);
return gpobject->getPropertyFloatValue(propname);
}
//--------------------------------------------------------------
//
// Name: getStringValue
// Class: GameplayManager
//
// Description: Gets the string value of the property.
//
// Parameters: const str& objname -- Object to retrieve the property from, supports scoping
// via the . symbol, example: "Object1.SubObject"
//
// Returns: const str -- String value of the property or ""
//
//--------------------------------------------------------------
const str GameplayManager::getStringValue(const str& objname, const str& propname)
{
if ( !hasObject(objname) )
return "";
GameplayObject *gpobject = 0;
gpobject = _gameplayDatabase.getObject(objname);
return gpobject->getPropertyStringValue(propname);
}
//--------------------------------------------------------------
//
// Name: hasProperty
// Class: GameplayManager
//
// Description: Checks to see if the property exists in the object
//
// Parameters: const str& objname -- Object to find
// const str& propname -- Property name to check for
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayManager::hasProperty(const str& objname, const str& propname)
{
if ( !hasObject(objname) )
return false;
GameplayObject *gpobject = _gameplayDatabase.getObject(objname);
return gpobject->hasProperty(propname);
}
//--------------------------------------------------------------
//
// Name: hasSubObject
// Class: GameplayManager
//
// Description: Checks to see if the specified object has the subobject
//
// Parameters: const str& objname -- Object name
// const str& subobject -- Subobject to look for
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayManager::hasSubObject(const str& objname, const str& subobject)
{
if ( !objname.length() || !subobject.length())
return false;
GameplayObject *gpobject = 0;
gpobject = _gameplayDatabase.getObject(objname);
if ( !gpobject )
return false;
if ( !gpobject->getSubObject(subobject) )
return false;
return true;
}
#ifdef GAME_DLL
//--------------------------------------------------------------
// F O R M U L A S T U F F
//--------------------------------------------------------------
//--------------------------------------------------------------
//
// Name: hasFormula
// Class: GameplayManager
//
// Description: Checks to see if the formula is in the database
//
// Parameters: const str& formulaName -- Formula to check for
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayManager::hasFormula(const str& formulaName)
{
return _gameplayFormulaManager.hasFormula(formulaName);
}
//--------------------------------------------------------------
//
// Name: calculate
// Class: GameplayManager
//
// Description: Queries the FormulaManager for the result given the formula
// name and some data.
//
// Parameters: const str& formulaName -- Name of the formula
// const GameplayFormulaData& formulaData -- Formula Data
// float multiplier -- optional multiplier that defaults to 1.0
//
// Returns: flaot
//
//--------------------------------------------------------------
float GameplayManager::calculate(const str& formulaName, const GameplayFormulaData& formulaData, float multiplier)
{
float result = _gameplayFormulaManager.getFormulaResult(formulaName, formulaData) * multiplier;
return result;
}
//--------------------------------------------------------------
//
// Name: setBase
// Class: GameplayManager
//
// Description: Sets the base object of objname to be baseobj.
//
// Parameters: const str& objname -- Object on which to set the base
// const str& baseobj -- Base object to reference
//
// Returns: bool
//
//--------------------------------------------------------------
bool GameplayManager::setBase(const str& objname, const str& baseobj)
{
return _gameplayDatabase.setBase(objname, baseobj);
}
//--------------------------------------------------------------
//
// Name: clearPropertyOverrides
// Class: GameplayManager
//
// Description: Clears all properties in this object that override
// properties in the base object.
//
// Parameters: const str& objname -- Object to clear the properties for
//
// Returns: bool - successful or not
//
//--------------------------------------------------------------
bool GameplayManager::clearPropertyOverrides(const str& objname)
{
return _gameplayDatabase.clearPropertyOverrides(objname);
}
//===============================================================
// Name: processPendingMessages
// Class: GameplayManager
//
// Description: Sends all messages that haven't been sent about
// deltas in the database to the client.
//
// Parameters: None
//
// Returns: None
//
//===============================================================
void GameplayManager::processPendingMessages( void )
{
char message[256] ;
Container<PendingDelta> &pendingDeltaList = _gameplayDatabase.getPendingDeltaList();
for ( int pendingDeltaIdx = 1; pendingDeltaIdx <= pendingDeltaList.NumObjects(); pendingDeltaIdx++ )
{
PendingDelta pendingDelta = pendingDeltaList.ObjectAt( pendingDeltaIdx );
Vector vectorValue ;
float floatValue = 0.0f ;
str objName = pendingDelta.getObjectName();
str propName = pendingDelta.getPropertyName();
str stringValue ;
switch ( pendingDelta.getGameplayValueType() )
{
case VALUE_FLOAT:
floatValue = pendingDelta.getFloatValue();
sprintf( message, "gdb_setfloatproperty %s %s %g\n", objName.c_str(), propName.c_str(), floatValue );
break ;
case VALUE_STRING:
stringValue = pendingDelta.getStringValue();
sprintf( message, "gdb_setstringproperty %s %s %s\n", objName.c_str(), propName.c_str(), stringValue.c_str() );
break ;
case VALUE_VECTOR:
vectorValue = pendingDelta.getVectorValue();
sprintf( message, "gdb_setvectorproperty %s %s %g %g %g\n", objName.c_str(), propName.c_str(), vectorValue.x, vectorValue.y, vectorValue.z );
break ;
default:
break ;
}
G_SendCommandToAllPlayers( message );
}
_gameplayDatabase.clearPendingDeltaList();
}
//--------------------------------------------------------------
//
// Name: Archive
// Class: GameplayDatabase
//
// Description: Archive function.
//
// Parameters: Archiver &arc -- Archive reference
//
// Returns: None
//
//--------------------------------------------------------------
void GameplayManager::Archive(Archiver &arc)
{
_gameplayDatabase.Archive(arc);
}
#else
//----------------------------------------------------------------
// E X T E R N A L "C" A P I
//----------------------------------------------------------------
//-----------------------------------------------------
//
// Name: HasProperty
// Class: None
//
// Description: Checks if a property exists.
//
// Parameters: objectName - The object name
// propertyName - The property name
//
// Returns: If found, true is returned, otherwise false.
//-----------------------------------------------------
extern "C" qboolean HasGameplayProperty(const char* objectName, const char* propertyName)
{
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if(gpm == 0)
return 0;
if(gpm->hasProperty(objectName, propertyName))
return qtrue;
return qfalse;
}
//-----------------------------------------------------
//
// Name: GetGameplayStringProperty
// Class: None
//
// Description: Gets the string property in the gameplay database
//
// Parameters: objectName - The object name
// propertyName - The property name
//
// Returns: If found, the property string is returned, otherwise 0
//-----------------------------------------------------
extern "C" void GetGameplayStringProperty(const char* objectName, const char* propertyName, char* buffer, int length)
{
if(buffer == 0 || length <= 0)
return;
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if(gpm == 0)
return;
str stringValue = gpm->getStringValue(objectName, propertyName);
strncpy(buffer, stringValue.c_str(), length);
}
//-----------------------------------------------------
//
// Name: SetGameplayStringProperty
// Class: None
//
// Description: Sets the string property in the gameplay database
//
// Parameters: objname - The object name
// propname - The property name
// valuestr - The value of the property.
// create - If true, it creates the property if the property does not exist
//
// Returns: None
//-----------------------------------------------------
extern "C" void SetGameplayStringProperty(const char* objectName, const char* propertyName, const char* stringValue, qboolean create)
{
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if(gpm == 0)
return;
//Convert the qboolean to boolean
bool createProperty = false;
if(create)
createProperty = true;
gpm->setStringValue(objectName, propertyName, stringValue, createProperty);
}
//-----------------------------------------------------
//
// Name: GetGameplayFloatProperty
// Class: None
//
// Description: Gets a float property from the gameplay datbase
//
// Parameters: objectName - the object name
// propertyName - the property name
//
// Returns: The found value.
//-----------------------------------------------------
extern "C" float GetGameplayFloatProperty(const char* objectName, const char* propertyName)
{
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if(gpm == 0)
return 1.0f;
return gpm->getFloatValue(objectName, propertyName);
}
//-----------------------------------------------------
//
// Name: GetGameplayFloatPropertyCmd
// Class: None
//
// Description: Gets a float property from the gameplay datbase
// and prints it to the console.
//
// Parameters:
//
// Returns: The found value.
//-----------------------------------------------------
void GetGameplayFloatPropertyCmd( void )
{
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if ( gpm )
{
const char *objectName = Cmd_Argv( 1 );
const char *propertyName = Cmd_Argv( 2 );
float floatValue = gpm->getFloatValue( objectName, propertyName );
Com_Printf( "%s.%s: %g\n", objectName, propertyName, floatValue );
}
}
//-----------------------------------------------------
//
// Name: GetGameplayStringPropertyCmd
// Class: None
//
// Description: Gets a string property from the gameplay datbase
// and prints it to the console.
//
// Parameters:
//
// Returns: The found value.
//-----------------------------------------------------
void GetGameplayStringPropertyCmd( void )
{
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if( gpm )
{
const char *objectName = Cmd_Argv( 1 );
const char *propertyName = Cmd_Argv( 2 );
str stringValue = gpm->getStringValue( objectName, propertyName );
Com_Printf( "%s.%s: %s\n", objectName, propertyName, stringValue.c_str() );
}
}
//-----------------------------------------------------
//
// Name: SetGameplayFloatProperty
// Class: None
//
// Description: Sets a float property in the gameplay database
//
// Parameters: objectName - the object name
// propertyName - the property name
// value - the new float value
// create - If true, the value is created, otherwise the value is set.
//
// Returns: None
//-----------------------------------------------------
extern "C" void SetGameplayFloatProperty(const char* objectName, const char* propertyName, float value, qboolean create)
{
GameplayManager* gpm = GameplayManager::getTheGameplayManager();
if(gpm == 0)
return;
//Convert the qboolean to boolean.
bool createProperty = false;
if(create)
createProperty = true;
gpm->setFloatValue(objectName, propertyName, value, createProperty);
}
//===============================================================
// Name: SetGameplayStringProperty
// Class: None
//
// Description: Sets a string property in the gameplay database.
//
// Parameters: None
//
// Returns: None
//
//===============================================================
void SetGameplayStringProperty( void )
{
if ( Cmd_Argc() != 4 )
{
Com_Printf( "Syntax: gdb_setstringproperty <objname> <propname> <stringvalue>\n" );
return ;
}
const char *objectName = Cmd_Argv( 1 );
const char *propertyName = Cmd_Argv( 2 );
const char *stringValue = Cmd_Argv( 3 );
GameplayManager *gpm = GameplayManager::getTheGameplayManager();
if ( !gpm ) return ;
gpm->setStringValue( objectName, propertyName, stringValue, true );
}
//===============================================================
// Name: SetGameplayFloatProperty
// Class: None
//
// Description: Sets a float property in the gameplay database.
//
// Parameters: None
//
// Returns: None
//
//===============================================================
void SetGameplayFloatProperty( void )
{
if ( Cmd_Argc() != 4 )
{
Com_Printf( "Syntax: gdb_setfloatproperty <objname> <propname> <floatvalue>\n" );
return ;
}
const char *objectName = Cmd_Argv( 1 );
const char *propertyName = Cmd_Argv( 2 );
const char *floatStringValue = Cmd_Argv( 3 );
GameplayManager *gpm = GameplayManager::getTheGameplayManager();
if ( !gpm ) return ;
float floatValue = atof( floatStringValue );
gpm->setFloatValue( objectName, propertyName, floatValue, true );
}
//===============================================================
// Name: CreateGameplayManager
// Class: None
//
// Description: Creates the GameplayManager. This loads the
// Gameplay Database from disk.
//
// Parameters: None
//
// Returns: None
//
//===============================================================
extern "C" void CreateGameplayManager( void )
{
GameplayManager::create();
Cmd_AddCommand( "gdb_setfloatproperty", SetGameplayFloatProperty );
Cmd_AddCommand( "gdb_setstringproperty", SetGameplayStringProperty );
Cmd_AddCommand( "gdb_getfloatproperty", GetGameplayFloatPropertyCmd );
Cmd_AddCommand( "gdb_getstringproperty", GetGameplayStringPropertyCmd );
}
//===============================================================
// Name: ShutdownGameplayManager
// Class: None
//
// Description: Shuts down (destroys) the GameplayManager.
//
// Parameters: None
//
// Returns: None
//
//===============================================================
extern "C" void ShutdownGameplayManager( void )
{
Cmd_RemoveCommand( "gdb_setfloatproperty" );
Cmd_RemoveCommand( "gdb_setstringproperty" );
Cmd_RemoveCommand( "gdb_getfloatproperty" );
Cmd_RemoveCommand( "gdb_getstringproperty" );
GameplayManager::shutdown();
}
#endif // GAME_DLL

View file

@ -0,0 +1,88 @@
// GameplayManager.h: interface for the GameplayManager class.
//
//////////////////////////////////////////////////////////////////////
class GameplayManager;
#ifndef __GAMEPLAYMANAGER_H__
#define __GAMEPLAYMANAGER_H__
#ifdef GAME_DLL
#include <game/g_local.h>
#include <game/actor.h>
#include <game/weapon.h>
#include <game/player.h>
#include <game/gamecmds.h>
#include "gameplayformulamanager.h"
#endif // GAME_DLL
#ifdef CGAME_DLL
#include "cg_local.h"
#endif // CGAME_DLL
#include "gameplaydatabase.h"
//------------------------- CLASS ------------------------------
//
// Name: GameplayManager
// Base Class: Listener
//
// Description: Singlton class that handles gameplay elements
//
// Method of Use: Use in game code when things need to be resolved
//
//--------------------------------------------------------------
class GameplayManager : public Listener
{
//-----------------------------------------------------------
// D A T A B A S E S T U F F
//-----------------------------------------------------------
public:
// Static Member functions
static GameplayManager* getTheGameplayManager();
static void shutdown();
static bool isReady();
static void create();
// Queries
bool hasProperty(const str& objname, const str& propname);
bool hasObject(const str& objname);
bool hasSubObject(const str& objname, const str& subobject);
bool isDefined(const str& propname);
// Accessors
const str getDefine(const str& propname);
float getFloatValue(const str& objname, const str& propname);
const str getStringValue(const str& objname, const str& propname);
// Mutators NOTE: These functions can only set values on root level objects!
void setFloatValue(const str& objname, const str& propname, float value, bool create = false);
void setStringValue(const str& objname, const str& propname, const str& valuestr, bool create = false);
bool setBase(const str& objname, const str& baseobj);
bool clearPropertyOverrides(const str& objname);
protected:
GameplayManager();
virtual ~GameplayManager();
private:
static GameplayManager *_theGameplayManager; // singleton
GameplayDatabase _gameplayDatabase;
#ifdef GAME_DLL
//------------------------------------------------------------
// F O R M U L A S T U F F
//------------------------------------------------------------
public:
bool hasFormula(const str& formulaName);
float calculate(const str& formulaName, const GameplayFormulaData& formulaData, float multiplier = 1.0f);
void processPendingMessages();
void Archive(Archiver &arc);
private:
GameplayFormulaManager _gameplayFormulaManager;
#endif // GAME_DLL
};
#endif

942
Shared/qcommon/output.cpp Normal file
View file

@ -0,0 +1,942 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/Shared/qcommon/output.cpp $
// $Revision:: 14 $
// $Author:: Steven $
// $Date:: 10/06/02 7:10p $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
#include "output.h"
#include <game/str.h> // Was uilib/str.h
//================================================================
// Name: DocFileOutput
// Class: DocFileOutput
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
DocFileOutput::DocFileOutput()
{
typeFlag = 0;
fileptr = NULL;
classCount = 0;
eventCount = 0;
}
//================================================================
// Name: ~DocFileOutput
// Class: DocFileOutput
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
DocFileOutput::~DocFileOutput()
{
}
//================================================================
// Name: OutputClasses
// Class: DocFileOutput
//
// Description: Loops through all the classes and calls OutputClass on each
// (which will usually be a derived classes' version of it).
//
// Parameters: ClassDef *classlist -- The list of classes to loop through
//
// Returns: None
//
//================================================================
void DocFileOutput::OutputClasses(ClassDef *classlist)
{
ClassDef *c;
int num = 0;
for( c = classlist->next; c != classlist; c = c->next )
{
if ( num < MAX_CLASSES )
{
OutputClass(c);
num++;
}
}
}
//================================================================
// Name: OutputClass
// Class: DocFileOutput
//
// Description: This function is normally overriden by a subclass.
// The subclass's OutputClass will call this function
// when its done with its own version.
//
// Parameters: ClassDef *in_class -- The class to output
//
// Returns: None
//
//================================================================
void DocFileOutput::OutputClass(ClassDef *in_class)
{
OutputEvents(in_class);
classCount++;
}
//================================================================
// Name: OutputEvents
// Class: DocFileOutput
//
// Description: Loops through all the events and calls OutputEvent on each
// (which will usually be a derived classes' version of it).
// This function also filters out the events based on the typeFlag
//
// Parameters: ClassDef in_class -- The class whose events we will loop through
//
// Returns: None
//
//================================================================
void DocFileOutput::OutputEvents(ClassDef *in_class)
{
ResponseDef<Class> *r;
int ev, i, num;
Event **events;
num = Event::NumEventCommands();
events = new Event *[num];
memset( events, 0, sizeof( Event * ) * num );
// gather event responses for this class
r = in_class->responses;
if ( r )
{
for( i = 0; r[i].event != NULL; i++ )
{
ev = ( int )*r[i].event;
if ( r[i].response )
{
events[ev] = r[i].event;
}
}
}
for( i = 1; i < num; i++ )
{
int index;
index = Event::MapSortedEventIndex( i );
if ( events[index] )
{
// Filtering
if ( events[index]->GetFlags() != 0 )
{
// Event is not default
if ( ( events[index]->GetFlags() & EV_TIKIONLY ) && typeFlag == EVENT_SCRIPT_ONLY && !( events[index]->GetFlags() & EV_SCRIPTONLY ) )
continue;
if ( ( events[index]->GetFlags() & EV_SCRIPTONLY ) && typeFlag == EVENT_TIKI_ONLY && !( events[index]->GetFlags() & EV_TIKIONLY ) )
continue;
if ( ( events[index]->GetFlags() & EV_CODEONLY ) && ( typeFlag == EVENT_TIKI_ONLY || typeFlag == EVENT_SCRIPT_ONLY ) )
continue;
if ( ( events[index]->GetFlags() & EV_CHEAT ) && ( typeFlag == EVENT_TIKI_ONLY ) && !( events[index]->GetFlags() & EV_TIKIONLY ) )
continue;
if ( ( events[index]->GetFlags() & EV_CHEAT ) && ( typeFlag == EVENT_SCRIPT_ONLY ) && !( events[index]->GetFlags() & EV_SCRIPTONLY ) )
continue;
if ( ( events[index]->GetFlags() & EV_CONSOLE ) && ( typeFlag == EVENT_TIKI_ONLY || typeFlag == EVENT_SCRIPT_ONLY ) )
continue;
}
OutputEvent( events[index] );
}
}
delete[] events;
}
//================================================================
// Name: OutputEvent
// Class: DocFileOutput
//
// Description: This function is normally overriden by a subclass.
// The subclass's OutputEvent will call this function
// when its done with its own version.
//
// Parameters: Event *ev -- The event to output
//
// Returns: None
//
//================================================================
void DocFileOutput::OutputEvent(Event *ev)
{
OutputArguments(ev);
eventCount++;
}
//================================================================
// Name: OutputArguments
// Class: DocFileOutput
//
// Description: Loops through all the args and calls OutputArgument on each
// (which will usually be a derived classes' version of it).
//
// Parameters: Event *ev -- The event whose arguments we will loop through
//
// Returns: None
//
//================================================================
void DocFileOutput::OutputArguments(Event *ev)
{
int i;
for( i = 1; i <= ev->getNumArgDefs(); i++ )
{
EventArgDef *evarg = ev->getArgDef(i);
OutputArgument(evarg);
}
}
//================================================================
// Name: OutputArgument
// Class: DocFileOutput
//
// Description: This function is normally overriden by a subclass.
// The subclass's OutputArgument will call this function
// when its done with its own version.
//
//
// Parameters: None
//
// Returns: None
//
//================================================================
void DocFileOutput::OutputArgument(EventArgDef *evarg)
{
// Function does nothing. This is the last level of nesting, and there
// is nothing else to go print from here.
}
//================================================================
// Name: Write
// Class: DocFileOutput
//
// Description: Writes the file to disk
//
// Parameters: char *filename -- the filename to create
//
// Returns: None
//
//================================================================
void DocFileOutput::Write(const char *filename, ClassDef *classlist, int ptypeFlag)
{
char realname[255];
sprintf(realname,"%s.%s",filename,GetExtension());
fileptr = fopen(realname,"w");
if ( !fileptr )
return;
// Store the type flag privately so we don't have to pass it around
typeFlag = ptypeFlag;
// Start the writing process
OutputClasses(classlist);
fclose(fileptr);
}
// ************************************************************************
// * *
// * *
// * HTMLDocFileOutput Class *
// * *
// * *
// ************************************************************************
//================================================================
// Name: HTMLDocFileOutput
// Class: HTMLDocFileOutput
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
HTMLDocFileOutput::HTMLDocFileOutput()
{
}
//================================================================
// Name: HTMLDocFileOutput
// Class: ~HTMLDocFileOutput
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
HTMLDocFileOutput::~HTMLDocFileOutput()
{
}
//================================================================
// Name: OutputClasses
// Class: HTMLDocFileOutput
//
// Description: Override of the base class version. We do this
// so we can print header and footer information.
//
// Parameters: None
//
// Returns: None
//
//================================================================
void HTMLDocFileOutput::OutputClasses(ClassDef *classlist)
{
str class_title;
#if defined( GAME_DLL )
class_title = "Game Module";
#elif defined( CGAME_DLL )
class_title = "Client Game Module";
#else
class_title = "Client Module";
#endif
// Header Info
fprintf(fileptr, "<HTML>\n");
fprintf(fileptr, "<HEAD>\n");
fprintf(fileptr, "<Title>%s Classes</Title>\n", class_title.c_str() );
fprintf(fileptr, "</HEAD>\n");
fprintf(fileptr, "<BODY>\n");
fprintf(fileptr, "<H1>\n");
fprintf(fileptr, "<center>%s Classes</center>\n", class_title.c_str() );
fprintf(fileptr, "</H1>\n");
#if defined( GAME_DLL )
fprintf(fileptr, "<h2>" );
fprintf(fileptr, "<a href=\"#Actor\">Actor</a>, " );
fprintf(fileptr, "<a href=\"#Animate\">Animate</a>, " );
fprintf(fileptr, "<a href=\"#Entity\">Entity</a>, " );
fprintf(fileptr, "<a href=\"#ScriptSlave\">ScriptSlave</a>, " );
fprintf(fileptr, "<a href=\"#Sentient\">Sentient</a>, " );
fprintf(fileptr, "<a href=\"#Trigger\">Trigger</a>, " );
fprintf(fileptr, "<a href=\"#World\">World</a>" );
fprintf(fileptr, "</h2>" );
#endif
// Print the body
DocFileOutput::OutputClasses(classlist);
// Footer
fprintf(fileptr, "<H2>\n");
fprintf(fileptr, "%d %s Classes.<BR>%d Events.\n", classCount, class_title.c_str(), eventCount );
fprintf(fileptr, "</H2>\n");
fprintf(fileptr, "</BODY>\n");
fprintf(fileptr, "</HTML>\n");
}
//================================================================
// Name: OutputClass
// Class: HTMLDocFileOutput
//
// Description: Write the class output for this type of file
//
// Parameters: ClassDef *in_class -- Class to write out
//
// Returns: None
//
//================================================================
void HTMLDocFileOutput::OutputClass(ClassDef *in_class)
{
ClassDef *savedClass;
savedClass = in_class;
fprintf(fileptr, "\n");
if ( in_class->classID[ 0 ] )
{
fprintf(fileptr, "<h2> <a name=\"%s\">%s (<i>%s</i>)</a>", in_class->classname, in_class->classname, in_class->classID );
}
else
{
fprintf(fileptr, "<h2> <a name=\"%s\">%s</a>", in_class->classname, in_class->classname );
}
// print out lineage
for( in_class = in_class->super; in_class != NULL; in_class = in_class->super )
{
fprintf(fileptr, " -> <a href=\"#%s\">%s</a>", in_class->classname, in_class->classname );
}
fprintf(fileptr, "</h2>\n");
fprintf(fileptr, "<BLOCKQUOTE>\n");
// Events
DocFileOutput::OutputClass(savedClass);
fprintf(fileptr, "</BLOCKQUOTE>\n");
}
//================================================================
// Name: OutputEvent
// Class: HTMLDocFileOutput
//
// Description: Write the event output for this type of file
//
// Parameters: Event *ev -- Event to write out
//
// Returns: None
//
//================================================================
void HTMLDocFileOutput::OutputEvent(Event *ev)
{
int numargs;
const char *text;
fprintf(fileptr, "\n<P><tt><B>%s</B>", ev->getName() );
numargs = ev->getNumArgDefs();
if ( numargs )
{
fprintf(fileptr, "( <i>" );
DocFileOutput::OutputEvent(ev);
fprintf(fileptr, " </i>)</tt><BR>\n" );
}
else
{
// No arguments, do not call base class OutputEvent
fprintf(fileptr, "</tt><BR>\n" );
}
text = ev->GetDocumentation();
// Build a new documentation string, replaces the newlines with <BR>\n
if ( text )
{
char new_doc[1024];
int old_index;
int new_index = 0;
for ( old_index = 0 ; old_index < strlen ( text ) ; old_index++ )
{
if ( text[old_index] == '\n' )
{
new_doc[new_index ] = '<';
new_doc[new_index + 1] = 'B';
new_doc[new_index + 2] = 'R';
new_doc[new_index + 3] = '>';
new_doc[new_index + 4] = '\n';
new_index += 5;
}
else
{
new_doc[new_index] = text[old_index];
new_index++;
}
}
new_doc[new_index] = 0;
fprintf(fileptr, "<ul>%s</ul>\n", new_doc );
}
}
//================================================================
// Name: OutputArgument
// Class: HTMLDocFileOutput
//
// Description: Write the argument output for this type of file
//
// Parameters: EventArgDef *evarg -- EventArgs to write out
//
// Returns: None
//
//================================================================
void HTMLDocFileOutput::OutputArgument(EventArgDef *evarg)
{
if ( evarg->isOptional() )
{
fprintf(fileptr, "[ " );
}
switch( evarg->getType() )
{
case IS_ENTITY:
fprintf(fileptr, "Entity " );
break;
case IS_VECTOR:
fprintf(fileptr, "Vector " );
break;
case IS_INTEGER:
fprintf(fileptr, "Integer " );
break;
case IS_FLOAT:
fprintf(fileptr, "Float " );
break;
case IS_STRING:
fprintf(fileptr, "String " );
break;
case IS_BOOLEAN:
fprintf(fileptr, "Boolean " );
break;
}
fprintf(fileptr, "%s", evarg->getName() );
// print the range of the argument
OutputRange(evarg);
if ( evarg->isOptional() )
{
fprintf(fileptr, " ]" );
}
DocFileOutput::OutputArgument(evarg);
}
//================================================================
// Name: OutputRange
// Class: HTMLDocFileOutput
//
// Description: Writes the range of the event arg passed if any
//
// Parameters: EventArgDef *evarg -- Argument to check for a range
//
// Returns: None
//
//================================================================
void HTMLDocFileOutput::OutputRange(EventArgDef *evarg)
{
qboolean integer, single;
int numRanges, i;
single = false;
integer = true;
numRanges = 1;
switch( evarg->getType() )
{
case IS_VECTOR:
integer = false;
numRanges = 3;
break;
case IS_FLOAT:
integer = false;
break;
case IS_STRING:
single = true;
break;
}
for( i = 0; i < numRanges; i++ )
{
if ( single )
{
if ( !evarg->GetMinRangeDefault(i) )
{
if ( integer )
{
fprintf(fileptr, "<%d>", ( int )evarg->GetMinRange(i) );
}
else
{
fprintf(fileptr, "<%.2f>", evarg->GetMinRange(i) );
}
}
}
else
{
// both non-default
if ( !evarg->GetMinRangeDefault(i) && !evarg->GetMaxRangeDefault(i) )
{
if ( integer )
{
fprintf(fileptr, "<%d...%d>", ( int )evarg->GetMinRange(i), ( int )evarg->GetMaxRange(i) );
}
else
{
fprintf(fileptr, "<%.2f...%.2f>", evarg->GetMinRange(i), evarg->GetMaxRange(i) );
}
}
// max default
else if ( !evarg->GetMinRangeDefault(i) && evarg->GetMaxRangeDefault(i) )
{
if ( integer )
{
fprintf(fileptr, "<%d...max_integer>", ( int )evarg->GetMinRange(i) );
}
else
{
fprintf(fileptr, "<%.2f...max_float>", evarg->GetMinRange(i) );
}
}
// min default
else if ( evarg->GetMinRangeDefault(i) && !evarg->GetMaxRangeDefault(i) )
{
if ( integer )
{
fprintf(fileptr, "<min_integer...%d>", ( int )evarg->GetMaxRange(i) );
}
else
{
fprintf(fileptr, "<min_float...%.2f>", evarg->GetMaxRange(i) );
}
}
}
}
}
// ************************************************************************
// * *
// * *
// * ToolDocFileOutput Class *
// * *
// * *
// ************************************************************************
//================================================================
// Name: ToolDocFileOutput
// Class: ToolDocFileOutput
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
ToolDocFileOutput::ToolDocFileOutput()
{
randFlag = false;
colorFlag = false;
}
//================================================================
// Name: ToolDocFileOutput
// Class: ~ToolDocFileOutput
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
ToolDocFileOutput::~ToolDocFileOutput()
{
}
//================================================================
// Name: OutputClass
// Class: ToolDocFileOutput
//
// Description: Write the class output for this type of file
//
// Parameters: ClassDef *in_class -- Class to write out
//
// Returns: None
//
//================================================================
void ToolDocFileOutput::OutputClass(ClassDef *in_class)
{
ClassDef *savedClass;
savedClass = in_class;
fprintf(fileptr, "\n");
fprintf(fileptr, "%s\n", in_class->classname );
fprintf(fileptr, "{\n");
// Events
DocFileOutput::OutputClass(savedClass);
if ( in_class->super != NULL )
fprintf(fileptr, "\n\tincludes %s\n",in_class->super->classname);
fprintf(fileptr, "}\n");
}
//================================================================
// Name: OutputEvent
// Class: ToolDocFileOutput
//
// Description: Write the event output for this type of file
//
// Parameters: Event *ev -- Event to write out
//
// Returns: None
//
//================================================================
void ToolDocFileOutput::OutputEvent(Event *ev)
{
int numargs;
const char *text;
int i;
fprintf(fileptr, "\n");
fprintf(fileptr, "\t%s\n", ev->getName() );
fprintf(fileptr, "\t{\n");
numargs = ev->getNumArgDefs();
if ( numargs )
{
DocFileOutput::OutputEvent(ev);
}
fprintf(fileptr, "\n\t\thelp\t\t\"");
text = ev->GetDocumentation();
for ( i=0; i<strlen(text); i++ )
{
if ( text[i] == '\n' )
fprintf(fileptr, "\n\t\t\t\t");
else
fprintf(fileptr, "%c", text[i]);
}
fprintf(fileptr, "\"\n");
fprintf(fileptr, "\t}\n");
text = ev->GetDocumentation();
}
//================================================================
// Name: OutputArgument
// Class: ToolDocFileOutput
//
// Description: Write the argument output for this type of file
//
// Parameters: EventArgDef *evarg -- EventArgs to write out
//
// Returns: None
//
//================================================================
void ToolDocFileOutput::OutputArgument(EventArgDef *evarg)
{
// Check for Randoms. If there is one, print out the "random" keyword
// and set the random flag, so next next time this function is called,
// it is assumed to be the random parameter's name.
if ( !strcmp(evarg->getName(), "[randomtype]") )
{
fprintf(fileptr, "\t\trandom");
randFlag = true; // Set the random flag
return;
}
// If the random flag is set, we assume the previous call to this function
// was a [randomtype] parameter. We now output the name of the random parameter,
// which is assumed to be a float. (All randoms ARE floats, correct?)
if ( randFlag )
{
fprintf(fileptr, "\t\t%s\t\"%s\"\n",evarg->getName(), evarg->getName());
randFlag = false;
return;
}
// If it's a vector that's supposed to specify a color, we directly print it here
if ( strstr(evarg->getName(), "color_") && evarg->getType() == IS_VECTOR )
{
fprintf(fileptr, "\t\trgb\t\t%s\t\"%s\"\n",evarg->getName(), evarg->getName());
return;
}
// If the event takes an RGB color (three floats), we must do special casing to
// output a single color parameter.
// If we find color_red, we ASSUME it's the start of an RGB set.
if ( strstr(evarg->getName(), "color_red") && evarg->getType() != IS_VECTOR )
{
char tmpstr[25], *sptr;
strcpy(tmpstr,evarg->getName());
sptr = strtok(tmpstr,"_"); // color
sptr = strtok(NULL,"_"); // red
sptr = strtok(NULL,"_"); // potential name or NULL
colorFlag = true;
if ( sptr == NULL )
fprintf(fileptr, "\t\trgb\t\tcolor\t\"color\"\n");
else
fprintf(fileptr, "\t\trgb\t\t%s\t\"%s\"\n", sptr, sptr);
return;
}
// If we find color_blue, we ASSUME is the end of an RGB set
if ( colorFlag && strstr(evarg->getName(), "color_blue") )
{
colorFlag = false;
return;
}
// If the colorFlag is still set by the time we get here, we are in
// the process of ignoring parameters until the color is done.
if ( colorFlag )
return;
// If we reach this point it is assumed that it is not one of the special case parameters
// listed above.
if ( evarg->isOptional() )
fprintf(fileptr, "\t\t|" );
else
fprintf(fileptr, "\t\t");
switch( evarg->getType() )
{
case IS_ENTITY:
fprintf(fileptr, "string\t\t" );
break;
case IS_VECTOR:
fprintf(fileptr, "xyz\t\t" );
break;
case IS_INTEGER:
fprintf(fileptr, "int\t\t" );
break;
case IS_FLOAT:
fprintf(fileptr, "float\t\t" );
break;
case IS_STRING:
fprintf(fileptr, "string\t\t" );
break;
case IS_BOOLEAN:
fprintf(fileptr, "boolean\t\t" );
break;
}
fprintf(fileptr, "%s\t", evarg->getName() );
fprintf(fileptr, "\"%s\"\t", evarg->getName() );
// print the range of the argument
OutputRange(evarg);
fprintf(fileptr, "\n");
DocFileOutput::OutputArgument(evarg);
}
//================================================================
// Name: OutputRange
// Class: ToolDocFileOutput
//
// Description: Writes the range of the event arg passed if any
//
// Parameters: EventArgDef *evarg -- Argument to check for a range
//
// Returns: None
//
//================================================================
void ToolDocFileOutput::OutputRange(EventArgDef *evarg)
{
int i;
// Event type is a vector
if ( evarg->getType() == IS_VECTOR )
{
for ( i=0; i<3; i++ )
{
if ( evarg->GetMinRangeDefault(i) || evarg->GetMaxRangeDefault(i) )
return;
}
fprintf(fileptr, "%.2f %.2f %.2f %.2f %.2f %.2f\n",
evarg->GetMinRange(0), evarg->GetMinRange(1), evarg->GetMinRange(2),
evarg->GetMaxRange(0), evarg->GetMaxRange(1), evarg->GetMaxRange(2) );
return;
}
// Event type is a string
if ( evarg->getType() == IS_STRING )
{
if ( !evarg->GetMinRangeDefault(0) )
{
fprintf(fileptr, "%d", ( int )evarg->GetMinRange(0) );
}
return;
}
// Default checks
if ( !evarg->GetMinRangeDefault(0) && !evarg->GetMaxRangeDefault(0) )
{
if ( evarg->getType() == IS_FLOAT )
fprintf(fileptr, "%.2f %.2f", evarg->GetMinRange(0), evarg->GetMaxRange(0) );
else
fprintf(fileptr, "%d %d", ( int )evarg->GetMinRange(0), ( int )evarg->GetMaxRange(0) );
}
}
//================================================================
// Name: PrintSubClasses (private)
// Class: ToolDocFileOutput
//
// Description: Recursive function that prints all the passed classes
// subclasses.
//
// Parameters: ClassDef *in_class -- the class to print the subclasses of
//
// Returns: None
//
//================================================================
void ToolDocFileOutput::PrintSubClasses(ClassDef *in_class, ClassDef *classlist)
{
ClassDef *c;
OutputClass(in_class);
for( c = classlist->next; c != classlist; c = c->next )
{
if ( c->super == in_class )
PrintSubClasses(c, classlist);
}
}
//================================================================
// Name: OutputClasses
// Class: ToolDocFileOutput
//
// Description: Override of the base class version. This is a special
// fuctions that loops through the classes in a specific way.
// For each root node, we recursively print all it's children.
// This way, all classes' super classes are printed first
//
// Parameters: ClassDef *classlist -- The list of classes to loop through
//
// Returns: None
//
//================================================================
void ToolDocFileOutput::OutputClasses(ClassDef *classlist)
{
ClassDef *c;
// Make a container of all the root class names
for( c = classlist->next; c != classlist; c = c->next )
{
if ( c->super == NULL )
PrintSubClasses(c, classlist);
}
}

105
Shared/qcommon/output.h Normal file
View file

@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/Shared/qcommon/output.h $
// $Revision:: 10 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
class DocFileOutput;
#ifndef __DOCFILEOUTPUT_H__
#define __DOCFILEOUTPUT_H__
#if defined ( GAME_DLL )
// class.h behaves different when the GAME_DLL define is set, so
// we need to act differently to. If we simply include class.h here,
// it includes g_local.h, which then includes game.h which fails to
// compile because class.h isn't fully read yet. To prevent this,
// we include g_local.h first, so that it can include things in the
// right order.
#include <game/g_local.h>
#else
#include <game/listener.h>
#include <game/class.h>
#endif
// Base Class
class DocFileOutput
{
protected:
FILE *fileptr;
int typeFlag;
int classCount;
int eventCount;
public:
DocFileOutput();
virtual ~DocFileOutput();
virtual void OutputClasses(ClassDef *classlist);
virtual void OutputClass(ClassDef *in_class);
virtual void OutputEvents(ClassDef *in_class);
virtual void OutputEvent(Event *ev);
virtual void OutputArguments(Event *ev);
virtual void OutputArgument(EventArgDef *evarg);
virtual const char *GetExtension() { return "txt"; }
void Write(const char *filename, ClassDef *classlist, int ptypeFlag);
};
// HTML Output
class HTMLDocFileOutput : public DocFileOutput
{
public:
HTMLDocFileOutput();
~HTMLDocFileOutput();
// Virtual Function Implementation
void OutputClass(ClassDef *in_class);
void OutputEvent(Event *ev);
void OutputArgument(EventArgDef *evarg);
// Special override
void OutputClasses(ClassDef *classlist);
void OutputRange(EventArgDef *evarg);
const char *GetExtension() { return "html"; }
};
// Tool Output -- Output to the specific parser format that
// the tools use.
class ToolDocFileOutput : public DocFileOutput
{
private:
void PrintSubClasses(ClassDef *in_class, ClassDef *classlist); // recursive
bool randFlag;
bool colorFlag;
public:
ToolDocFileOutput();
~ToolDocFileOutput();
// Virtual Function Implementation
void OutputClass(ClassDef *in_class);
void OutputEvent(Event *ev);
void OutputArgument(EventArgDef *evarg);
// Special override
void OutputClasses(ClassDef *classlist);
void OutputRange(EventArgDef *evarg);
const char *GetExtension() { return "txt"; }
};
#endif // #ifndef __DOCFILEOUTPUT_H__

10
Shared/qcommon/platform.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef PLATFORM_H
#define PLATFORM_H
#ifdef LINUX
#define __declspec(x)
#define __cdecl
#define __stdcall
#endif
#endif //PLATFORM_H

1264
Shared/qcommon/qfiles.h Normal file

File diff suppressed because it is too large Load diff

776
Shared/qcommon/quaternion.h Normal file
View file

@ -0,0 +1,776 @@
//-----------------------------------------------------------------------------
// Quaternion.h
//
// Author: Squirrel Eiserloh
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
// Header for (and inline implementation of) a basic Quaternion class.
// This should ultimately be part of a yet-to-be-written general-purpose
// Rotation class at some point, time-permitting.
//
#ifndef _QUATERNION_H_
#define _QUATERNION_H_
#include <math.h>
#include "vector.h"
//#include "Matrix.h"
#define UNUSED_ARG (void)
//---------------------------------------------------------------------------
// Quaternion
//
// ...in the form (x, y, z, w) such that q = xi + yj + zk + w, where:
//
// i x i = -1 i x j = k j x i = -k
// j x j = -1 and j x k = i and k x j = -i
// k = k = -1 k x i = j i x k = -j
//
// Note that i, j, and k are each imaginary numbers of different "flavors"
// representing mutually perpendicular unit vectors defining 3 of the
// 4 axes in quaternion 4-space. (The fourth axis is the real unit, 1.)
//
// In vector form, the quaternion would look like (s, v), where s is a
// scalar (equal to w) and v is a vector (x, y, z) in quaternion 4-space
// (giving position along the base unit axis vectors i, j, and k,
// respectively).
//
// The most useful quaternions are those that are of unit length
// (|q| = 1, or x*x + y*y + z*z + w*w = 1). This defines a set
// of points which make up a 4-dimensional "unit hypersphere",
// across the surface of which we will be interpolating.
//
// Note that Quaternion multiplication involves the vector cross
// product (v1 x v2), so it is NOT COMMUTATIVE. This means that
// q1 x q2 != q2 x q1. (Then again, matrix multiplication isn't
// commutative either, so suck it down.)
//
// "lhs" and "rhs" mean "left hand side" and "right hand side" for
// operator arguments, respectively.
//---------------------------------------------------------------------------
class Quaternion
{
//---------------------------------------------------------------------------
// Member variables
//---------------------------------------------------------------------------
private:
float _x; // coefficient for the i imaginary term
float _y; // coefficient for the j imaginary term
float _z; // coefficient for the k imaginary term
float _w; // coefficient for the real term
//---------------------------------------------------------------------------
// Accessors / Mutators
//---------------------------------------------------------------------------
protected:
//---------------------------------------------------------------------------
// Implementation Methods
//---------------------------------------------------------------------------
private:
//---------------------------------------------------------------------------
// Construction / Destruction
//---------------------------------------------------------------------------
public:
~Quaternion();
explicit Quaternion(); // default constructor
Quaternion( const Quaternion& rhs ); // copy constructor
explicit Quaternion( const float x, const float y, const float z, const float w );
explicit Quaternion( const float w, const Vector& vec );
explicit Quaternion( const Vector& eulerAngles );
// explicit Quaternion( const Matrix3x3& rotationMatrix );
// explicit Quaternion( const Matrix4x4& transformMatrix );
//---------------------------------------------------------------------------
// Interface Methods
//---------------------------------------------------------------------------
public:
float CalcLength( void ) const;
float CalcLengthSquared( void ) const;
float Normalize( void );
void SetFromSV( const float w, const Vector& vec );
void SetFromXYZW( const float x, const float y, const float z, const float w );
void SetFromEuler( const Vector& eulerAngles );
// void SetFromMatrix3x3( const Matrix3x3& rotationMatrix );
// void SetFromMatrix4x4( const Matrix4x4& transformMatrix );
void GetToSV( float& w, Vector& vec ) const;
void GetToXYZW( float& x, float& y, float& z, float& w ) const;
void GetToEuler( Vector& eulerAngles ) const;
// void GetToMatrix3x3( Matrix3x3& rotationMatrix ) const;
// void GetToMatrix4x4( Matrix4x4& transformMatrix ) const;
/// Self-modifying operators
const Quaternion& operator = ( const Quaternion& rhs );
const Quaternion& operator += ( const Quaternion& rhs );
const Quaternion& operator -= ( const Quaternion& rhs );
const Quaternion& operator *= ( const float scale );
const Quaternion& operator *= ( const Quaternion& rhs );
const Quaternion& operator /= ( const float invScale );
const Quaternion operator - () const;
/// Construction operators
const Quaternion operator + ( const Quaternion& rhs ) const;
const Quaternion operator - ( const Quaternion& rhs ) const;
bool operator == ( const Quaternion& rhs ) const;
bool operator != ( const Quaternion& rhs ) const;
private:
const Quaternion operator * ( const float scale ) const; // multiply-by-right-scalar forbidden; use (float, Quaternion&) version instead
};
//---------------------------------------------------------------------------
// External Operators & Functions
//---------------------------------------------------------------------------
const Quaternion operator * ( const Quaternion& lhs, const Quaternion& rhs );
const Quaternion operator * ( const float scale, const Quaternion& rhs );
const Quaternion operator / ( const Quaternion& lhs, const float invScale );
const Quaternion CalcSlerp( const Quaternion& q1, const Quaternion& q2, const float fraction );
const Quaternion CalcLerp( const Quaternion& q1, const Quaternion& q2, const float q2Fraction );
const Quaternion CalcNoLerp( const Quaternion& q1, const Quaternion& q2, const float q2Fraction );
float QuaternionDotProduct( const Quaternion& q1, const Quaternion& q2 );
//---------------------------------------------------------------------------
// Destructor
//---------------------------------------------------------------------------
inline Quaternion::~Quaternion()
{
}
//---------------------------------------------------------------------------
// Default constructor
//---------------------------------------------------------------------------
inline Quaternion::Quaternion()
{
// Do nothing; this should be used only by static array declarations
}
//---------------------------------------------------------------------------
// Copy Constructor( Quaternion )
//---------------------------------------------------------------------------
inline Quaternion::Quaternion( const Quaternion& rhs )
{
SetFromXYZW( rhs._x, rhs._y, rhs._z, rhs._w );
}
//---------------------------------------------------------------------------
// Constructor( float, float, float, float )
//---------------------------------------------------------------------------
inline Quaternion::Quaternion( const float x, const float y, const float z, const float w )
{
SetFromXYZW( x, y, z, w );
}
//---------------------------------------------------------------------------
// Constructor( float, Vector )
//---------------------------------------------------------------------------
inline Quaternion::Quaternion( const float w, const Vector& vec )
{
SetFromSV( w, vec );
}
//---------------------------------------------------------------------------
// Constructor( Vector )
//---------------------------------------------------------------------------
inline Quaternion::Quaternion( const Vector& eulerAngles )
{
SetFromEuler( eulerAngles );
}
//---------------------------------------------------------------------------
// Constructor( Matrix3x3 )
//---------------------------------------------------------------------------
/*
inline Quaternion::Quaternion( const Matrix3x3& rotationMatrix )
{
SetFromMatrix3x3( rotationMatrix );
}
*/
//---------------------------------------------------------------------------
// Constructor( Matrix4x4 )
//---------------------------------------------------------------------------
/*
inline Quaternion::Quaternion( const Matrix4x4& transformMatrix )
{
SetFromMatrix4x4( transformMatrix );
}
*/
//---------------------------------------------------------------------------
// CalcLength()
//---------------------------------------------------------------------------
inline float Quaternion::CalcLength( void ) const
{
float length = (float) sqrt( CalcLengthSquared() );
return( length );
}
//---------------------------------------------------------------------------
// CalcLengthSquared()
//---------------------------------------------------------------------------
inline float Quaternion::CalcLengthSquared( void ) const
{
float lengthSquared;
lengthSquared = (_x * _x) + (_y * _y) + (_z * _z) + (_w * _w);
return( lengthSquared );
}
//---------------------------------------------------------------------------
// Normalize
//---------------------------------------------------------------------------
inline float Quaternion::Normalize( void )
{
/// Get the length of the quaternion 4d vector
float length = CalcLength();
if( !length )
return( 0.0f );
/// Divide each component by <length>
*this /= length;
return( length );
}
//---------------------------------------------------------------------------
// SetFromSV
//---------------------------------------------------------------------------
inline void Quaternion::SetFromSV( const float w, const Vector& vec )
{
SetFromXYZW( vec.x, vec.y, vec.z, w );
}
//---------------------------------------------------------------------------
// SetFromXYZW
//---------------------------------------------------------------------------
inline void Quaternion::SetFromXYZW( const float x, const float y, const float z, const float w )
{
_x = x;
_y = y;
_z = z;
_w = w;
}
//---------------------------------------------------------------------------
// SetFromEuler
//---------------------------------------------------------------------------
inline void Quaternion::SetFromEuler( const Vector& eulerAngles )
{
// FIXME: THIS IS TEMPORARY HACKED STUFF FOR PROOF OF CONCEPT ONLY!!!
float quat[ 4 ];
vec3_t eulerAng;
eulerAngles.copyTo( eulerAng );
EulerToQuat( eulerAng, quat );
_x = quat[ 0 ];
_y = quat[ 1 ];
_z = quat[ 2 ];
_w = quat[ 3 ];
}
//---------------------------------------------------------------------------
// SetFromMatrix3x3
//---------------------------------------------------------------------------
/*
inline void Quaternion::SetFromMatrix3x3( const Matrix3x3& rotationMatrix )
{
// FIXME: stub
UNUSED_ARG rotationMatrix;
}
*/
//---------------------------------------------------------------------------
// SetFromMatrix4x4
//---------------------------------------------------------------------------
/*
inline void Quaternion::SetFromMatrix4x4( const Matrix4x4& transformMatrix )
{
// FIXME: stub
UNUSED_ARG transformMatrix;
}
*/
//---------------------------------------------------------------------------
// GetToSV
//---------------------------------------------------------------------------
inline void Quaternion::GetToSV( float& w, Vector& vec ) const
{
GetToXYZW( vec.x, vec.y, vec.z, w );
}
//---------------------------------------------------------------------------
// GetToXYZW
//---------------------------------------------------------------------------
inline void Quaternion::GetToXYZW( float& x, float& y, float& z, float& w ) const
{
x = _x;
y = _y;
z = _z;
w = _w;
}
//---------------------------------------------------------------------------
// GetToEuler
//---------------------------------------------------------------------------
inline void Quaternion::GetToEuler( Vector& eulerAngles ) const
{
// FIXME: THIS IS TEMPORARY HACKED STUFF FOR PROOF OF CONCEPT ONLY!!!
float matrix[ 3 ][ 3 ];
float quat[ 4 ];
vec3_t eulerAng;
quat[ 0 ] = _x;
quat[ 1 ] = _y;
quat[ 2 ] = _z;
quat[ 3 ] = _w;
QuatToMat( quat, matrix );
MatrixToEulerAngles( matrix, eulerAng );
eulerAngles.setXYZ( eulerAng[0], eulerAng[1], eulerAng[2] );
}
//---------------------------------------------------------------------------
// GetToMatrix3x3
//---------------------------------------------------------------------------
/*
inline void Quaternion::GetToMatrix3x3( Matrix3x3& rotationMatrix ) const
{
// FIXME: stub
UNUSED_ARG rotationMatrix;
}
*/
//---------------------------------------------------------------------------
// GetToMatrix4x4
//---------------------------------------------------------------------------
/*
inline void Quaternion::GetToMatrix4x4( Matrix4x4& transformMatrix ) const
{
// FIXME: stub
UNUSED_ARG transformMatrix;
}
*/
//---------------------------------------------------------------------------
// operator = (Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion& Quaternion::operator = ( const Quaternion& rhs )
{
if( this == &rhs )
return *this;
_x = rhs._x;
_y = rhs._y;
_z = rhs._z;
_w = rhs._w;
return *this;
}
//---------------------------------------------------------------------------
// operator += (Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion& Quaternion::operator += ( const Quaternion& rhs )
{
_x += rhs._x;
_y += rhs._y;
_z += rhs._z;
_w += rhs._w;
return *this;
}
//---------------------------------------------------------------------------
// operator -= (Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion& Quaternion::operator -= ( const Quaternion& rhs )
{
_x -= rhs._x;
_y -= rhs._y;
_z -= rhs._z;
_w -= rhs._w;
return *this;
}
//---------------------------------------------------------------------------
// operator *= (float)
//---------------------------------------------------------------------------
inline const Quaternion& Quaternion::operator *= ( const float scale )
{
_x *= scale;
_y *= scale;
_z *= scale;
_w *= scale;
return *this;
}
//---------------------------------------------------------------------------
// operator *= (Quaternion)
//
// Quaternion multiplication is NOT COMMUTATIVE, and is defined as
// follows, where "s" is the scalar component (w) and "v" is the vector
// component (x,y,z) (and 'x' means "3d vector cross product", '|' means
// "3d vector dot product"):
//
// q1 * q2 = q3 = (s3, v3) != q2 * q1
//
// s3 = (s1 * s2) - (v1 | v2)
// v3 = (s1 * v2) + (s2 * v1) + (v1 x v2)
//
// i.e. Q(s1, v1) * Q(s2, v2) = Q(s3, v3)
//---------------------------------------------------------------------------
inline const Quaternion& Quaternion::operator *= ( const Quaternion& rhs )
{
float s1, s2, s3; // see above comment
Vector v1, v2, v3; // see above comment
/// Get both quaternions into (s,v) form
GetToSV( s1, v1 );
rhs.GetToSV( s2, v2 );
/// Calculate the new scalar term (s3)
s3 = (s1 * s2) - Vector::Dot( v1, v2 );
/// Calculate the new vector term (v3)
Vector v1CrossV2; // temp variable for cross-product result, since our Vector class sucks
v1CrossV2.CrossProduct( v1, v2 ); // our vector class sucks
v3 = (s1 * v2) + (s2 * v1) + v1CrossV2;
/// Set the new scalar and vector terms and return this
SetFromSV( s3, v3 );
return *this;
}
//---------------------------------------------------------------------------
// operator /= (float)
//---------------------------------------------------------------------------
inline const Quaternion& Quaternion::operator /= ( const float invScale )
{
if( invScale )
{
_x /= invScale;
_y /= invScale;
_z /= invScale;
_w /= invScale;
}
else
{
SetFromXYZW( 0.0f, 0.0f, 0.0f, 0.0f );
}
return *this;
}
//---------------------------------------------------------------------------
// operator - (Quaternion) : unary minus
//---------------------------------------------------------------------------
inline const Quaternion Quaternion::operator - () const
{
return Quaternion( -_x, -_y, -_z, -_w );
}
//---------------------------------------------------------------------------
// operator == (Quaternion, Quaternion)
//---------------------------------------------------------------------------
//inline bool operator == ( const Quaternion& lhs, const Quaternion& rhs )
inline bool Quaternion::operator == ( const Quaternion& rhs ) const
{
if( _x != rhs._x )
return false;
if( _y != rhs._y )
return false;
if( _z != rhs._z )
return false;
if( _w != rhs._w )
return false;
return true;
}
//---------------------------------------------------------------------------
// operator != (Quaternion, Quaternion)
//---------------------------------------------------------------------------
inline bool Quaternion::operator != ( const Quaternion& rhs ) const
{
return( !(*this == rhs) );
}
//---------------------------------------------------------------------------
// operator - (Quaternion, Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion Quaternion::operator - ( const Quaternion& rhs ) const
{
Quaternion difference( *this );
difference -= rhs;
return( difference );
}
//---------------------------------------------------------------------------
// operator + (Quaternion, Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion Quaternion::operator + ( const Quaternion& rhs ) const
//Quaternion Quaternion::operator + ( const Quaternion& rhs ) const
{
Quaternion sum( *this );
sum += rhs;
return( sum );
}
//---------------------------------------------------------------------------
// general operator * (Quaternion, Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion operator * ( const Quaternion& lhs, const Quaternion& rhs )
{
Quaternion product( lhs );
product *= rhs;
return product;
}
//---------------------------------------------------------------------------
// general operator * (float, Quaternion)
//---------------------------------------------------------------------------
inline const Quaternion operator * ( const float scale, const Quaternion& rhs )
{
Quaternion scaled( rhs );
scaled *= scale;
return scaled;
}
//---------------------------------------------------------------------------
// general operator / (Quaternion, float)
//---------------------------------------------------------------------------
inline const Quaternion operator / ( const Quaternion& lhs, const float invScale )
{
Quaternion scaled( lhs );
if( invScale )
{
scaled /= invScale;
}
else
{
scaled *= 0.0f;
}
return scaled;
}
//---------------------------------------------------------------------------
// general CalcLerp (Quaternion, Quaternion, float)
//
// Performs a hypervector linear interpolation - or "lerp" - of two
// Quaternions and returns the resulting (newly constructed) Quaternion.
//
// <q2Fraction> is a value in the range [0,1] representing how much of
// <q2> to use in the interpolation; q1Fraction = 1-<q2Fraction> is the
// weighting given to <q1>.
//
// NOTE: This interpolation is faster, but less accurate, than CalcSlerp().
// Use CalcSlerp() if the error incurred from CalcLerp() is noticeable.
//
// For optimization purposes, CalcLerp() assumes <q1> and <q2> are
// already normalized.
//---------------------------------------------------------------------------
inline const Quaternion CalcLerp( const Quaternion& q1, const Quaternion& q2, const float q2Fraction )
{
const float q1Fraction = 1.0f - q2Fraction;
/// Check if <q1> and <q2> are the same quaternion
if( &q1 == &q2 )
return Quaternion( q1 );
/// Check if <q1> and <q2> are data-identical
if( q1 == q2 )
return Quaternion( q1 );
/// Check if <q2Fraction> is at (or beyond) a boundary condition
if( q2Fraction <= 0.0f )
return Quaternion( q1 );
if( q2Fraction >= 1.0f )
return Quaternion( q2 );
/// Create a new quaternion which represents the weighted average of <q1> and <q2>
Quaternion lerped( (q1Fraction * q1) + (q2Fraction * q2) );
float lerpedLength = lerped.Normalize();
/// Check if the 4d vectors added up to 0.0 (degenerate case!)
if( !lerpedLength )
{
/// Return whichever of <q1> or <q2> the parameter is currently closest to
return CalcNoLerp( q1, q2, q2Fraction );
}
return lerped;
}
//---------------------------------------------------------------------------
// general CalcSlerp (Quaternion, Quaternion, float)
//
// Performs a (hyper)spherical linear interpolation - or "slerp" - of two
// Quaternions and returns the resulting (newly constructed) Quaternion.
//
// <q2Fraction> is a value in the range [0,1] representing how much of
// <q2> to use in the interpolation; q1Fraction = 1-<q2Fraction> is the
// weighting given to <q1>.
//
// For optimization purposes, CalcSlerp() assumes <q1> and <q2> are
// already normalized.
//---------------------------------------------------------------------------
inline const Quaternion CalcSlerp( const Quaternion& q1, const Quaternion& q2, const float q2Fraction )
{
static const float SIN_OMEGA_EPSILON = 0.00001f;
const float q1Fraction = 1.0f - q2Fraction;
/// Check if <q1> and <q2> are one and the same
if( &q1 == &q2 )
return Quaternion( q1 );
/// Check if <q1> and <q2> are data-identical
if( q1 == q2 )
return Quaternion( q1 );
/// Check if <q2Fraction> is at (or beyond) a boundary condition
if( q2Fraction <= 0.0f )
return Quaternion( q1 );
if( q2Fraction >= 1.0f )
return Quaternion( q2 );
/// Calculate <cosOmega>, the dot product (cosine) of the angle between the two 4d hypervectors
float cosOmega = QuaternionDotProduct( q1, q2 );
/// Create a copy of q2 and invert it if <cosOmega> is negative (i.e. it's on the opposite side of the hypersphere)
Quaternion q2copy( q2 );
if( cosOmega < 0.0f )
{
/// Mirror the hypervector (and, therefore, the dot product) to be on the same side of the hypersphere as <q1>
cosOmega = -cosOmega;
q2copy *= -1.0f;
}
/// Check if either <q1> or <q2> was not normalized
if( cosOmega > 1.0f )
{
/// FIXME: One or both of <q1> or <q2> were evidently not normalized; this should be an error condition!
/// Return whichever of <q1> or <q2> the parameter is currently closest to
return CalcNoLerp( q1, q2, q2Fraction );
}
/// Check if <q1> and <q2> are close enough to use linear interpolation instead
if( (1.0f - cosOmega) > SIN_OMEGA_EPSILON )
{
return CalcLerp( q1, q2, q2Fraction );
}
/// Check if <q1> and <q2> are nearly opposite on the hypersphere
if( (cosOmega + 1.0) < SIN_OMEGA_EPSILON )
{
// FIXME: how should this case be handled?
// Watt & Watt does some voodoo-math which is clearly incorrect...
return CalcNoLerp( q1, q2, q2Fraction );
}
/// Calculate <omega>, the angle between <q1> and <q2>, based on the dot product (cosine) between <q1> and <q2>
const float omega = acos( cosOmega );
const float sinOmega = sin( omega );
/// Check if <sinOmega> is prohibitively small (since it will end up in the denominator later)
if( (sinOmega > -SIN_OMEGA_EPSILON) && (sinOmega < SIN_OMEGA_EPSILON) )
{
/// Return whichever of <q1> or <q2> the parameter is currently closest to
return CalcNoLerp( q1, q2, q2Fraction );
}
/// Build a new quaternion, <slerped>, which uses normal (hyper)spherical linear interpolation
Quaternion slerped;
float scale1 = sin( q1Fraction * omega ) / sinOmega;
float scale2 = sin( q2Fraction * omega ) / sinOmega;
slerped = (scale1 * q1) + (scale2 * q2);
// FIXME: does <slerped> need to be renormalized at this point??
// (yes, but only because of floating-point drift, and it's the caller's reponsibility to do this)
return slerped;
}
//---------------------------------------------------------------------------
// general CalcNoLerp (Quaternion, Quaternion, float)
//
// This is a fake / stub quaternion interpolation function; it simply
// returns a copy of <q1> or <q2> based on which one <q2Fraction>
// indicates it is closer to.
//---------------------------------------------------------------------------
inline const Quaternion CalcNoLerp( const Quaternion& q1, const Quaternion& q2, const float q2Fraction )
{
if( q2Fraction < 0.5f )
{
return Quaternion( q1 );
}
else
{
return Quaternion( q2 );
}
}
//---------------------------------------------------------------------------
// QuaternionDotProduct
//
// Calculates the dot product of <q1> and <q2> where both quaternions are
// taken as (probably unit) vectors in fourspace.
//---------------------------------------------------------------------------
inline float QuaternionDotProduct( const Quaternion& q1, const Quaternion& q2 )
{
float x1, y1, z1, w1;
float x2, y2, z2, w2;
q1.GetToXYZW( x1, y1, z1, w1 );
q2.GetToXYZW( x2, y2, z2, w2 );
float dotProduct = (x1*x2) + (y1*y2) + (z1*z2) + (w1*w1);
return dotProduct;
}
#endif // _QUATERNION_H_

View file

@ -0,0 +1,119 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/uilib/console.h $
// $Revision:: 2 $
// $Author:: Steven $
// $Date:: 10/10/01 10:29a $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// String resource system
#ifndef STRING_RESOURCE_HPP
#define STRING_RESOURCE_HPP
#include <game/q_shared.h>
//#include "qcommon.h"
#include <game/container.h>
#include <game/str.h>
//#include <cgame/cg_local.h>
//#include <cgame/cg_commands.h>
//The map types of the string.
//Global - this is a global string and is used for every level
//Level - this is a string specific for the level and therefore loaded when the level is loaded.
typedef enum StringType { GLOBAL, LEVEL };
#define STRING_HASH_SIZE 1024
//-------------------------- CLASS ----------------------------------
//
// Name: StringMapEntry
// Base Class: None
//
// Description: This is the map entry that the String Resource contains.
// The StringMapEntry stores the string, id and the type of string
// that is used.
//
// Method Of Use: This is used internally by the String Resource class.
//
//-------------------------------------------------------------------
class StringEntry
{
public:
StringEntry() { }
~StringEntry() { }
str& getString(void) { return _string; }
str& getStringId(void) { return _stringId; }
StringType getType(void) { return _type; }
StringEntry* getNext(void) { return _next; }
void setString(const str& string) { _string = string; }
void setStringId(const str& stringId){ _stringId = stringId; }
void setType(StringType type) { _type = type; }
void setNext(StringEntry* next) { _next = next; }
private:
str _string;
str _stringId;
StringType _type;
StringEntry* _next;
};
//-------------------------- CLASS ----------------------------------
//
// Name: StringResource
// Base Class: None
//
// Description: The String Resource is a system that loads a list of strings. Each of these strings
// are paired with an identifier.
//
// Method Of Use: This is used internally by the print statements, mainly center print.
//
//-------------------------------------------------------------------
class StringResource
{
public:
static void createInstance(void);
static void deleteInstance(void);
static StringResource* getInstance(void) { if(_instance == 0) createInstance(); return _instance; }
str& getStringResource(const str& stringId);
void convertStringResourceIds(str& string);
void parseStringId(str& stringId);
void loadGlobalStrings(void);
void loadLevelStrings(const str& levelName);
void clearAllStrings(void);
void clearLevelStrings(void);
bool addStringEntry(StringEntry* stringEntry);
bool loadStrings(const str& fileName, StringType stringType);
void parseStringValue(str& stringValue);
protected:
int getHashValue(const str& stringId);
private:
StringResource();
~StringResource();
static StringResource* _instance;
StringEntry* _stringHashTable[STRING_HASH_SIZE];
str _notFoundString;
str _loadedLevel;
bool _globalLoaded;
bool _overwrite;
cvar_t* _languageCvar;
};
#endif

View file

@ -0,0 +1,108 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/Shared/qcommon/tiki_script.h $
// $Revision:: 10 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// C++ implementaion of tokenizing text interpretation. Class accepts filename
// to load or pointer to preloaded text data. Standard tokenizing operations
// such as skip white-space, get string, get integer, get float, get token,
// and skip line are implemented.
//
// Note: all '//', '#', and ';' are treated as comments. Probably should
// make this behaviour toggleable.
//
#ifndef __TIKI_SCRIPT_H__
#define __TIKI_SCRIPT_H__
#if !defined( QERADIANT ) && !defined( UTILS )
#define MAXTOKEN 256
#endif
#define MAXMACROS 384 // was 256, increased for ef2 weapon lists
typedef struct
{
char name[ MAXTOKEN ];
char macro[ MAXTOKEN ];
} tiki_macro_t;
class TikiScript
{
public:
~TikiScript();
TikiScript();
char* buffer;
int length;
void Close();
const char* Filename();
int GetLineNumber();
void Reset();
qboolean TokenAvailable( qboolean crossline );
void UnGetToken();
const char* GetToken( qboolean crossline );
const char* GetLine( qboolean crossline );
const char* GetRaw();
const char* GetString( qboolean crossline );
qboolean GetSpecific( const char *string );
int GetInteger( qboolean crossline );
double GetDouble( qboolean crossline );
float GetFloat( qboolean crossline );
void GetVector( qboolean crossline, vec3_t vec );
int LinesInFile();
void Parse( char *data, int length, const char *name );
qboolean LoadFile( const char *name, qboolean quiet = qfalse );
qboolean LoadFileFromTS( const char *name, const char * tikidata, qboolean quiet = qfalse );
const char* Token();
float EvaluateMacroMath(float value, float newval, char oper);
char* EvaluateMacroString(const char *theMacroString);
const char* GetMacroString(const char *theMacroName);
protected:
qboolean error;
qboolean tokenready;
TikiScript* include;
TikiScript* parent;
char filename[ MAXTOKEN ];
const char* script_p;
const char* end_p;
tiki_macro_t macros[ MAXMACROS ];
int nummacros;
int line;
char token[ MAXTOKEN ];
qboolean releaseBuffer;
qboolean AtComment();
qboolean AtExtendedComment();
qboolean AtCommand();
qboolean AtString( qboolean crossline );
qboolean ProcessCommand( qboolean crossline );
qboolean Completed();
void CheckOverflow();
void Uninclude();
const char* FindMacro( const char * macro );
void AddMacro( const char *macro, const char *expansion );
qboolean SkipToEOL();
void SkipWhiteSpace( qboolean crossline );
void SkipNonToken( qboolean crossline );
qboolean CommentAvailable( qboolean crossline );
void SkipExtendedComment();
};
#endif

801
dlls/game/CameraPath.cpp Normal file
View file

@ -0,0 +1,801 @@
//-----------------------------------------------------------------------------
// CameraPath.cpp
//
// Author: Squirrel Eiserloh
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
// Implementation file for the following camera-related classes:
//
// CameraPath Describes a single camera path through time -
// including camera orientation, position,
// and field-of-view - using either many simple
// reference keyframes or a few bspline nodes.
// Also owns the coordinate system through which
// all positions and orientations are transformed
// (for scripts with relative playback locales).
//
// CameraKeyFramePath The innards of a CameraPath object implemented
// using keyframes (as opposed to bspline nodes).
// Does not know about relative locales.
//
// CameraKeyFrame A single key frame item in a CameraKeyFramePath.
// Stores a time index / frame number, the camera'a
// position (as a Vector), orientation (as a
// Quaternion), and field-of-fiew (as a Scalar).
//
#include "_pch_cpp.h"
#include "CameraPath.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CameraKeyFrame
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CLASS_DECLARATION( Class, CameraKeyFrame, NULL )
{
{ NULL, NULL }
};
//-----------------------------------------------------------------------------------------------
// Name: CameraKeyFrame
// Class: CameraKeyFrame
//
// Description: Default Constructor
//
// Parameters: None
//
// Returns: N/a
//
//-----------------------------------------------------------------------------------------------
CameraKeyFrame::CameraKeyFrame()
:
_position( Vector( 0.0f, 0.0f, 0.0f ) ),
_orientation( Quaternion( 0.0f, 0.0f, 0.0f, 1.0f ) ),
_fovDegrees( 90.0f ),
_seconds( 0.0f )
{
}
//-----------------------------------------------------------------------------------------------
// Name: CameraKeyFrame
// Class: CameraKeyFrame
//
// Description: Constructor( Vector, Quaternion, float )
//
// Parameters: position XYZ coordinates of camera
// orientation camera orientation as a quaternion
// fovDegrees horizontal fov of camera, in degrees
//
// Returns: n/a
//
//-----------------------------------------------------------------------------------------------
CameraKeyFrame::CameraKeyFrame( const Vector& position, const Quaternion& orientation, const float fovDegrees, const float seconds )
:
_position( position ),
_orientation( orientation ),
_fovDegrees( fovDegrees ),
_seconds( seconds )
{
}
//-----------------------------------------------------------------------------------------------
// Name: ParseFrameInfo
// Class: CameraKeyFrame
//
// Description: Starting with the keyword "Frame", parses one single frame entry from a .KFC
// buffer (using a Script object) in its entirety.
//
// Parameters: int frameNumber, Script& cameraPathFile
//
// Returns: bool - true upon success
//
//-----------------------------------------------------------------------------------------------
bool CameraKeyFrame::ParseFrameInfo( int frameNumber, Script& cameraPathFile, float& totalPathTime )
{
const char* token;
/// Read in the Frame number
token = cameraPathFile.GetToken( true );
if( !stricmp( token, "Frame" ) )
{
/// Make sure the frame number is the same as <frameNumber>, as expected
int actualFrame = cameraPathFile.GetInteger( false );
if( actualFrame != frameNumber )
{
cameraPathFile.error( "CameraKeyFrame::ParseFrameInfo", "Incorrect Frame number (found %d, expecting %d)\n", frameNumber, actualFrame );
return( false );
}
}
else // bad identifier
{
gi.Printf( "Unexpected token %s in camera path file (expecting \"Frame\").\n", token );
cameraPathFile.error( "CameraKeyFrame::ParseFrameInfo", "Unexpected token %s in camera path file (expecting \"Frame\").\n", token );
return( false );
}
return( ParseFrameInfoBlock( cameraPathFile, totalPathTime ) );
}
//-----------------------------------------------------------------------------------------------
// Name: ParseFrameInfoBlock
// Class: CameraKeyFrame
//
// Description: Parse in a single camera key frame from a .KFC file, from '{' to '}'
//
// Parameters: Script& cameraPathFile - parse object for .KFC file
//
// Returns: bool - true upon success
//
//-----------------------------------------------------------------------------------------------
bool CameraKeyFrame::ParseFrameInfoBlock( Script& cameraPathFile, float& totalPathTime )
{
const char* token;
float frameTimeInSeconds = DEFAULT_KEY_FRAME_LENGTH_SECONDS;
/// Read the opening bracket
token = cameraPathFile.GetToken( true );
if( *token != '{' )
{
cameraPathFile.error( "CameraKeyFrame::ParseFrameInfoBlock", "Expected '{', found \"%s\"\n", token );
return( false );
}
/// Read each entry in the Path info block
token = cameraPathFile.GetToken( true );
while( *token != '}' )
{
if( !stricmp( token, "fov" ) )
{
/// Read in the horizontal field of view (fov) for this camera key frame
_fovDegrees = cameraPathFile.GetFloat( false );
}
else if( !stricmp( token, "position" ) )
{
/// Read in the position vector for this camera key frame
_position = cameraPathFile.GetVector( false );
}
else if( !stricmp( token, "quaternion" ) )
{
/// Read in the orientation of the camera as a quaternion
float x = cameraPathFile.GetFloat( false );
float y = cameraPathFile.GetFloat( false );
float z = cameraPathFile.GetFloat( false );
float w = cameraPathFile.GetFloat( false );
_orientation.SetFromXYZW( x, y, z, w );
}
else // unknown token
{
gi.Printf( "Unexpected token %s in camera path file.\n", token );
cameraPathFile.error( "CameraKeyFrame::ParseFrameInfoBlock", "Unexpected token %s in camera path file.\n", token );
return( false );
}
token = cameraPathFile.GetToken( true );
}
_seconds = totalPathTime;
totalPathTime += frameTimeInSeconds;
return( true );
}
//-----------------------------------------------------------------------------------------------
// Name: Interpolate
// Class: CameraKeyFrame
//
// Description: Sets the position, orientation, and fov values in the current CameraKeyFrame
// object (this) to be a weighted average of two other key frames: <before> and
// <after>, where <fraction> represents the weighting of the <after> frame (and
// 1 - fraction is the weighting of the <before> frame).
//
// Parameters: const CameraKeyFrame& before - key frame being approached as fraction -> 0
// const CameraKeyFrame& after - key frame being approached as fraction -> 1
// const float fraction - in the range [0,1]; the fraction of <after> to be used
//
// Returns: const CameraKeyFrame&
//
//-----------------------------------------------------------------------------------------------
const CameraKeyFrame& CameraKeyFrame::Interpolate( const CameraKeyFrame& before, const CameraKeyFrame& after, const float fraction, const bool normalizeQuaternion )
{
/// Set up some convenience references
const Vector& pos1 = before.GetPosition();
const Vector& pos2 = after.GetPosition();
const Quaternion& quat1 = before.GetOrientation();
const Quaternion& quat2 = after.GetOrientation();
float fov1 = before.GetFOV();
float fov2 = after.GetFOV();
/// Calculate interpolated position, orientation, and fov values for this new frame
_position = pos1 + ( pos2 - pos1 ) * fraction; // linear componentwise interpolation
_orientation = CalcSlerp( quat1, quat2, (double) fraction ); // (hyper)spherical linear interpolation
_fovDegrees = fov1 + (fraction * (fov2 - fov1) ); // linear float interpolation
/// Check if the caller has requested the quaternion to be renormalized after interpolation (a good idea, but costly)
if( normalizeQuaternion )
_orientation.Normalize();
return( *this );
}
//-----------------------------------------------------------------------------------------------
// Name: GetEulerAngles
// Class: CameraKeyFrame
//
// Description: Returns the orientation of the key frame in Euler angles (pitch, yaw, roll).
// Note that orientations are internally stored as quaternions, and this function
// is mainly provided as a interface useful to the surrounding Euler-centric
// Quake / Fakk / Tiki code.
//
// Parameters:
//
// Returns: const Vector
//
//-----------------------------------------------------------------------------------------------
const Vector CameraKeyFrame::GetEulerAngles( void ) const
{
Vector eulerAngles;
_orientation.GetToEuler( eulerAngles );
return eulerAngles;
}
//-----------------------------------------------------------------------------------------------
// Name: TransformToPlaybackOffsets
// Class: CameraKeyFrame
//
// Description: Transforms a CameraKeyFrame object by (1) rotating it <yawOffsetDegrees> degrees
// (including orientations and positions) and then (2) translating it by
// <originOffset> world-units.
//
// Parameters: const float yawOffset - the amount of (yaw) rotation to apply
// const Vector& originOffset - the amount of translation to apply
//
// Returns: const CameraKeyFrame& - returns *this, now transformed
//
// NOTE: Because q_math.c is a C file and was written long ago, we use vec3_t and euler
// angles instead of Vector and Quaternion.
//-----------------------------------------------------------------------------------------------
const CameraKeyFrame& CameraKeyFrame::TransformToPlaybackOffsets( const float yawOffsetDegrees, const Vector& originOffset )
{
/// Rotate <_position> about the Z axis by <yawOffsetDegrees>
vec3_t zNormal = { 0.0f, 0.0f, 1.0f };
vec3_t point;
vec3_t rotated;
_position.copyTo( point ); // Don't blame me for this. Our math library was written in C.
RotatePointAroundVector( rotated, zNormal, point, yawOffsetDegrees );
_position = rotated;
/// Rotate <_orientation> in a like manner
Vector eulerOrientation;
_orientation.GetToEuler( eulerOrientation );
eulerOrientation.y += yawOffsetDegrees;
_orientation.SetFromEuler( eulerOrientation );
_orientation.Normalize();
/// Translate <_position> by <originOffset>
_position += originOffset; // see how easy things can be in C++?
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CameraKeyFramePath
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CLASS_DECLARATION( Class, CameraKeyFramePath, NULL )
{
{ NULL, NULL }
};
//-----------------------------------------------------------------------------------------------
// Name: CameraKeyFramePath
// Class: CameraKeyFramePath
//
// Description: Default Constructor
//
// Parameters: None
//
// Returns: n/a
//
//-----------------------------------------------------------------------------------------------
CameraKeyFramePath::CameraKeyFramePath()
:
_isLoaded( false ),
_numKeyFrames( 0 ),
_keyFrameArray( NULL ),
_totalSeconds( 0.0f )
{
}
//-----------------------------------------------------------------------------------------------
// Name: Unload
// Class: CameraKeyFramePath
//
// Description: Destroys the key-framed camera path data and
// marks the object as dirty (_isLoaded = false).
//
// Parameters: void
//
// Returns: void
//
//-----------------------------------------------------------------------------------------------
void CameraKeyFramePath::Unload( void )
{
if( IsLoaded() )
{
delete [] _keyFrameArray;
_keyFrameArray = NULL;
}
_totalSeconds = 0.0f;
_isLoaded = false;
}
//-----------------------------------------------------------------------------------------------
// Name: CreateFrames
// Class: CameraKeyFramePath
//
// Description: Allocates <numberOfFrames> CameraKeyFrame objects
// in a dynamic array. Previous data, if any, is
// deleted.
//
// Parameters: numberOfFrames - The number of key frames to be allocated.
//
// Returns: bool - true upon success
//
//-----------------------------------------------------------------------------------------------
bool CameraKeyFramePath::CreateFrames( const int numberOfFrames )
{
/// Unload the previous data (if any)
Unload();
/// Allocte <numberOFFrames> CameraKeyFrame objects
_keyFrameArray = new CameraKeyFrame[ numberOfFrames ];
if( !_keyFrameArray )
return( false );
/// Set internal dependents
_numKeyFrames = numberOfFrames;
return( true );
}
//-----------------------------------------------------------------------------------------------
// Name: ParsePathInfo
// Class: CameraKeyFramePath
//
// Description: Parses a "Path" entry and all subsequent "Frame" entries for that path.
// Parsing begins at the '{' following the "Path" keyword (already parsed).
//
// Parameters: Script& cameraPathFile - parsing object; keeps track of parse-offset, etc.
//
// Returns: bool - true upon success
//
//-----------------------------------------------------------------------------------------------
bool CameraKeyFramePath::ParsePathInfo( Script& cameraPathFile )
{
const char* token;
/// Read the opening bracket
token = cameraPathFile.GetToken( true );
if( *token != '{' )
{
cameraPathFile.error( "CameraKeyFramePath::ParsePathInfo", "Expected '{', found \"%s\"\n", token );
return( false );
}
/// Read each entry in the Path info block
token = cameraPathFile.GetToken( true );
while( *token != '}' )
{
if( !stricmp( token, "frameCount" ) )
{
/// Read in the number of frames in the path
_numKeyFrames = cameraPathFile.GetInteger( false );
assert( _numKeyFrames > 0 );
}
else // unknown token
{
gi.Printf( "Unexpected token %s in camera path file.\n", token );
cameraPathFile.error( "CameraKeyFramePath::ParsePathInfo", "Unexpected token %s in camera path file.\n", token );
return( false );
}
token = cameraPathFile.GetToken( true );
}
/// Allocate an array of CameraKeyFrame objects equal in number to what "frameCount" specified
CreateFrames( _numKeyFrames );
/// Loop through each key frame and let it parse itself
for( int i = 0; i < _numKeyFrames; i ++ )
{
/// Tell each frame to parse itself
CameraKeyFrame& keyFrame = _keyFrameArray[ i ];
bool success = keyFrame.ParseFrameInfo( i, cameraPathFile, _totalSeconds );
if( !success )
return( false );
}
/// Inform the object that it has been successfully loaded and is ready for use
_isLoaded = true;
return( true );
}
//-----------------------------------------------------------------------------------------------
// Name: GetClosestFramesForTime
// Class: CameraKeyFramePath
//
// Description: Sets <before> and <after> pointers to the camera key frames closest in time
// to <seconds>. Both pointers are guaranteed to always be set, though they
// may be identical (especially in cases where <seconds> matches a frame exactly,
// or where <seconds> is out of the time bounds of the path).
//
// Parameters: CameraKeyFrame*& before - pointer (by reference) to be set to the closest
// frame at or before <seconds>
//
// CameraKeyFrame*& after - pointer (by reference) to be set to the closest
// frame at or after <seconds>
//
// const float seconds - the time offset, in seconds, from the beginning of the
// camera path, around which the search for closest frames is centered
//
// Returns: void
//
//-----------------------------------------------------------------------------------------------
void CameraKeyFramePath::GetClosestFramesForTime( CameraKeyFrame*& before, CameraKeyFrame*& after, const float seconds )
{
int i;
/// Find the frame closest to - but no greater than - <seconds>
before = &_keyFrameArray[ 0 ];
for( i = 0; i < _numKeyFrames; i ++ )
{
CameraKeyFrame& frame = _keyFrameArray[ i ];
if( frame.GetSeconds() > seconds )
break;
before = &frame;
}
/// Find the frame closest to - but no less than - <seconds>
after = &_keyFrameArray[ _numKeyFrames - 1 ];
for( i = _numKeyFrames - 1; i >= 0; i -- )
{
CameraKeyFrame& frame = _keyFrameArray[ i ];
if( frame.GetSeconds() < seconds )
break;
after = &frame;
}
}
//-----------------------------------------------------------------------------------------------
// Name: CreateInterpolatedFrameForTime
// Class: CameraKeyFramePath
//
// Description: Creates a new CameraKeyFrame object based on the best interpolated-approximation
// of the CameraKeyFramePath when evaluated at <seconds> time.
//
// Parameters: const float seconds - time at which to evaluate the camera path
//
// Returns: const CameraKeyFrame - a new key frame, created by interpolating (if necessary)
// between the key frames in the camera path closest to <seconds>.
//
//-----------------------------------------------------------------------------------------------
const CameraKeyFrame CameraKeyFramePath::CreateInterpolatedFrameForTime( const float seconds )
{
/// Check if <seconds> is out-of-bounds for this camera path
if( seconds < 0.0f )
{
/// Return a copy of the first key frame
return( _keyFrameArray[ 0 ] );
}
else if( seconds > _totalSeconds )
{
/// Return a copy of the last key frame
return( _keyFrameArray[ _numKeyFrames - 1 ] );
}
/// Get the two closest frames in time to <seconds>; one just before and one just after
CameraKeyFrame* closestFrameBefore = NULL;
CameraKeyFrame* closestFrameAfter = NULL;
GetClosestFramesForTime( closestFrameBefore, closestFrameAfter, seconds );
assert( closestFrameBefore );
assert( closestFrameAfter );
/// Check if both frames are identical; if so, simply return a copy of it / them
if( closestFrameBefore == closestFrameAfter )
return( *closestFrameBefore );
/// Generate an interpolated frame based on where <seconds> falls between those two frames
return( CreateInterpolatedFrame( *closestFrameBefore, *closestFrameAfter, seconds ) );
}
//-----------------------------------------------------------------------------------------------
// Name: CreateInterpolatedFrame
// Class: CameraKeyFramePath
//
// Description: Creates a new CameraKeyFrame object based on the best interpolated-approximation
// of the CameraKeyFramePath when evaluated at <seconds> time. NOTE: This method
// is called by CreateInterpolatedFrameForTime(), above, and does all the real
// interpolation work.
//
// Parameters: const CameraKeyFrame& before - closest frame shy of <seconds>
// const CameraKeyFrame& after - closest frame past <seconds>
// const float seconds - time index used to interpolate between <before> and <after>
//
// Returns: const CameraKeyFrame - new, interpolated key frame
//
//-----------------------------------------------------------------------------------------------
const CameraKeyFrame CameraKeyFramePath::CreateInterpolatedFrame( const CameraKeyFrame& before, const CameraKeyFrame& after, const float seconds )
{
/// Calculate the amount of time between the two reference frames
const float startTime = before.GetSeconds();
const float endTime = after.GetSeconds();
const float timeSpan = endTime - startTime;
assert( timeSpan >= 0.0f );
assert( seconds >= startTime );
assert( seconds <= endTime );
/// Calculation the interpolation fraction
float fraction;
if( timeSpan )
{
fraction = (seconds - startTime) / timeSpan;
}
else
{
fraction = 0.0f;
}
/// Create a new frame with interpolated values
CameraKeyFrame lerped;
lerped.Interpolate( before, after, fraction, true );
return( lerped );
}
//-----------------------------------------------------------------------------------------------
// Name: GetPathLengthInSeconds
// Class: CameraKeyFramePath
//
// Description: Returns the total length of the camera path, in seconds.
//
// Parameters: void
//
// Returns: float - the total length of the camera path, in seconds.
//
//-----------------------------------------------------------------------------------------------
float CameraKeyFramePath::GetPathLengthInSeconds( void )
{
return( _totalSeconds );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CameraPath
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CLASS_DECLARATION( Class, CameraPath, NULL )
{
{ NULL, NULL }
};
//-----------------------------------------------------------------------------------------------
// Name: CameraPath
// Class: CameraPath
//
// Description: Construct from .KFC file
//
// Parameters: fileName Name of the .KFC file to parse on construction of this object.
//
// Returns: n/a
//
//-----------------------------------------------------------------------------------------------
CameraPath::CameraPath( const str& fileName )
:
_fileName( str( "" ) ),
_isLoaded( false ),
_keyFramePath( NULL ),
_yawPlaybackOffsetDegrees( 0.0f ),
_originPlaybackOffset( Vector( 0.0f, 0.0f, 0.0f ) )
{
LoadKeyFramedCameraFile( fileName );
}
//-----------------------------------------------------------------------------------------------
// Name: LoadKeyFramedCameraFile
// Class: CameraPath
//
// Description: Loads a .KFC file and builds a dynamic array of camera key frames.
// Any previously loaded data in this object is destroyed.
//
// Parameters: fileName - Name of the .KFC file to load and parse.
//
// Returns: bool - true upon success
//
//-----------------------------------------------------------------------------------------------
bool CameraPath::LoadKeyFramedCameraFile( const str& fileName )
{
Script cameraPathFile;
const char* token;
bool success; // generic parsing return-value variable
str filePathName;
/// Unload the previous data (if any)
Unload();
/// Store the filename in the object for duplicate-load later on
_fileName = fileName;
/// Build the new file path name
filePathName = "cams/";
filePathName += fileName;
filePathName += ".kfc";
/// Load the file into a buffer (in the Script object)
cameraPathFile.LoadFile( filePathName.c_str() );
/// Parse each token in turn until no more remain
while( cameraPathFile.TokenAvailable( true ) )
{
/// Read the next token-word and take the appropriate action
token = cameraPathFile.GetToken( true );
if( !stricmp( token, "Path" ) )
{
/// Read in the path info and its subsequent key frame data
success = ParsePathInfo( cameraPathFile );
if( !success )
return( false );
}
else // unknown token
{
gi.Printf( "Unexpected token %s in camera path file %s.\n", token, _fileName.c_str() );
cameraPathFile.error( "CameraPath::LoadKeyFramedCameraFile", "Unexpected token %s in camera path file %s.\n", token, _fileName.c_str() );
return( false );
}
}
/// Inform the object that it has been successfully loaded and is ready for use
_isLoaded = true;
return( true );
}
//-----------------------------------------------------------------------------------------------
// Name: Unload
// Class: CameraPath
//
// Description: Destroys the camera path data and marks the object as dirty (_isLoaded = false).
//
// Parameters: void
//
// Returns: void
//
//-----------------------------------------------------------------------------------------------
void CameraPath::Unload( void )
{
if( IsLoaded() )
{
_isLoaded = false;
delete _keyFramePath;
_keyFramePath = NULL;
}
}
//-----------------------------------------------------------------------------------------------
// Name: ParsePathInfo
// Class: CameraPath
//
// Description: Parses the Path #, allocates a new path object, and passes parsing duties onto it.
//
// Parameters: Script& cameraPathFile - parsing object
//
// Returns: bool - true upon success
//
//-----------------------------------------------------------------------------------------------
bool CameraPath::ParsePathInfo( Script& cameraPathFile )
{
/// Read the path number
int pathNumber = cameraPathFile.GetInteger( false );
assert( pathNumber == 0 ); // FIXME: this is only temporary, until we allow more than one path per .kfc
/// Create a new key frame camera path and pass parsing duties on to it
_keyFramePath = new CameraKeyFramePath;
bool success = _keyFramePath->ParsePathInfo( cameraPathFile );
return( success );
}
//-----------------------------------------------------------------------------------------------
// Name: GetInterpolatedFrameForTime
// Class: CameraPath
//
// Description: Returns a newly created temporary object; the resulting camera key frame when
// the CameraPath is evaluated at <seconds>.
//
// Parameters: const float seconds - time index at which to evaluate the camera path
//
// Returns: const CameraKeyFrame - key frame created as a result of interpolation / evaluation
//
//-----------------------------------------------------------------------------------------------
const CameraKeyFrame CameraPath::GetInterpolatedFrameForTime( const float seconds )
{
CameraKeyFrame transformedKeyFrame( _keyFramePath->CreateInterpolatedFrameForTime( seconds ) );
transformedKeyFrame.TransformToPlaybackOffsets( _yawPlaybackOffsetDegrees, _originPlaybackOffset );
return( transformedKeyFrame );
}
//-----------------------------------------------------------------------------------------------
// Name: SetPlaybackOffsets
// Class: CameraPath
//
// Description: Tells a CameraPath object what offsets to use when reporting interpolations /
// evaluations. <yawOffset> is applied first to all positions and orientations;
// <originOffset> is applied last (to positions only).
//
// Parameters: const float yawOffsetDegrees - yaw rotation to apply to all positions & orientations
// const Vector& originOffset - offset translation applied to all positions, post-rotation
//
// Returns: void
//
//-----------------------------------------------------------------------------------------------
void CameraPath::SetPlaybackOffsets( const float yawOffsetDegrees, const Vector& originOffset )
{
_yawPlaybackOffsetDegrees = yawOffsetDegrees;
_originPlaybackOffset = originOffset;
}
//-----------------------------------------------------------------------------------------------
// Name: GetPathLengthInSeconds
// Class: CameraPath
//
// Description: Returns the total length of the camera path, in seconds.
//
// Parameters: void
//
// Returns: float - the total length of the camera path, in seconds
//
//-----------------------------------------------------------------------------------------------
float CameraPath::GetPathLengthInSeconds( void )
{
return( _keyFramePath->GetPathLengthInSeconds() );
}

293
dlls/game/CameraPath.h Normal file
View file

@ -0,0 +1,293 @@
//-----------------------------------------------------------------------------
// CameraPath.h
//
// Author: Squirrel Eiserloh
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
// Header file for the following camera-related classes:
//
// CameraPath Describes a single camera path through time -
// including camera orientation, position,
// and field-of-view - using either many simple
// reference keyframes or a few bspline nodes.
// Also owns the coordinate system through which
// all positions and orientations are transformed
// (for scripts with relative playback locales).
//
// CameraKeyFramePath The innards of a CameraPath object implemented
// using keyframes (as opposed to bspline nodes).
// Does not know about relative locales.
//
// CameraKeyFrame A single key frame item in a CameraKeyFramePath.
// Stores a time index / frame number, the camera'a
// position (as a Vector), orientation (as a
// Quaternion), and field-of-fiew (as a Scalar).
//
#ifndef _CAMERA_PATH_H_
#define _CAMERA_PATH_H_
/// Included headers
#include "class.h"
#include <qcommon/quaternion.h>
/// forward class declarations
class CameraPath;
class CameraKeyFramePath;
class CameraKeyFrame;
const float DEFAULT_KEY_FRAME_LENGTH_SECONDS = 0.05f;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CameraKeyFrame
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CameraKeyFrame : public Class
{
/// Member variables
private:
Vector _position; // the camera's position in xyz coordinates
Quaternion _orientation; // the camera's orientation, as a quaternion
float _fovDegrees; // the camera's horizontal field of view
float _seconds; // time (path start = 0) at which the key frame occurs
/// Accessors / Mutators
public:
inline const Vector& GetPosition( void ) const { return _position; }
inline const Quaternion& GetOrientation( void ) const { return _orientation; }
inline const float GetFOV( void ) const { return _fovDegrees; }
inline const float GetSeconds( void ) const { return _seconds; }
/// Construction / Destruction
public:
CLASS_PROTOTYPE( CameraKeyFrame );
CameraKeyFrame(); // default constructor
CameraKeyFrame( const Vector& position, const Quaternion& orientation, const float fovDegrees, const float seconds );
/// Interface methods
public:
bool ParseFrameInfo( int frameNumber, Script& cameraPathFile, float& frameLengthInSeconds );
const CameraKeyFrame& Interpolate( const CameraKeyFrame& before, const CameraKeyFrame& after, const float fraction, const bool normalizeQuaternion );
const Vector GetEulerAngles( void ) const;
const CameraKeyFrame& TransformToPlaybackOffsets( const float yawOffsetDegrees, const Vector& originOffset );
void Archive( Archiver &arc );
/// Implementation methods
private:
bool ParseFrameInfoBlock( Script& cameraPathFile, float& frameLengthInSeconds );
};
//===============================================================
// Name: Archive
// Class: CameraKeyFrame
//
// Description: Archives the data of a single camera key frame.
//
// Parameters: Archiver& -- reference to archive object for storing data.
//
// Returns: None
//
//===============================================================
inline void CameraKeyFrame::Archive
(
Archiver &arc
)
{
Class::Archive( arc );
float x = 0.0f ;
float y = 0.0f ;
float z = 0.0f ;
float w = 0.0f ;
arc.ArchiveVector( &_position );
if ( arc.Saving() )
{
_orientation.GetToXYZW( x, y, z, w );
}
arc.ArchiveFloat( &x );
arc.ArchiveFloat( &y );
arc.ArchiveFloat( &z );
arc.ArchiveFloat( &w );
if ( arc.Loading() )
{
_orientation.SetFromXYZW( x, y, z, w );
}
arc.ArchiveFloat( &_fovDegrees );
arc.ArchiveFloat( &_seconds );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CameraKeyFramePath
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CameraKeyFramePath : public Class
{
/// Member variables
private:
bool _isLoaded;
int _numKeyFrames;
CameraKeyFrame* _keyFrameArray;
float _totalSeconds;
/// Accessors / Mutators
public:
inline const bool IsLoaded( void ) const { return _isLoaded; }
private:
inline const int GetNumKeyFrames( void ) const { return _numKeyFrames; }
/// Construction / Destruction
public:
CLASS_PROTOTYPE( CameraKeyFramePath );
CameraKeyFramePath(); // default constructor
/// Interface methods
public:
void Unload( void );
bool ParsePathInfo( Script& cameraPathFile );
const CameraKeyFrame CreateInterpolatedFrameForTime( const float seconds );
float GetPathLengthInSeconds( void );
void Archive( Archiver &arc );
/// Implementation methods
private:
void GetClosestFramesForTime( CameraKeyFrame*& before, CameraKeyFrame*& after, const float seconds );
bool CreateFrames( const int numberOfFrames );
const CameraKeyFrame CreateInterpolatedFrame( const CameraKeyFrame& before, const CameraKeyFrame& after, const float seconds );
};
//===============================================================
// Name: Archive
// Class: CameraKeyFramePath
//
// Description: Archives the data of a archive key frame path.
//
// Parameters: Archiver& -- reference to the archive object
//
// Returns: None
//
//===============================================================
inline void CameraKeyFramePath::Archive
(
Archiver &arc
)
{
Class::Archive( arc );
arc.ArchiveBool( &_isLoaded );
arc.ArchiveInteger( &_numKeyFrames );
if ( arc.Loading() )
{
_keyFrameArray = new CameraKeyFrame[ _numKeyFrames ];
}
for ( int frameIdx = 0; frameIdx < _numKeyFrames; ++frameIdx )
{
arc.ArchiveObject( &_keyFrameArray[ frameIdx ] );
}
arc.ArchiveFloat( &_totalSeconds );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CameraPath
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CameraPath : public Class
{
/// Member variables
private:
bool _isLoaded;
str _fileName;
CameraKeyFramePath* _keyFramePath;
float _yawPlaybackOffsetDegrees;
Vector _originPlaybackOffset;
/// Accessors / Mutators
public:
inline const bool IsLoaded( void ) const { return _isLoaded; }
/// Construction / Destruction
public:
CLASS_PROTOTYPE( CameraPath );
CameraPath( const str& fileName );
CameraPath() : _isLoaded( false ), _keyFramePath( 0 ), _yawPlaybackOffsetDegrees( 0 ) { };
/// Interface methods
public:
void Unload( void );
bool Reload( void );
const CameraKeyFrame GetInterpolatedFrameForTime( const float seconds );
void SetPlaybackOffsets( const float yawOffsetDegrees, const Vector& originOffset );
float GetPathLengthInSeconds( void );
void Archive( Archiver &arc );
/// Implementation methods
private:
bool LoadKeyFramedCameraFile( const str& fileName );
bool ParsePathInfo( Script& cameraPathFile );
};
//===============================================================
// Name: Archive
// Class: CameraPath
//
// Description: Archives the data of the camera path.
//
// Parameters: Archiver& -- reference to archiver storing data.
//
// Returns: None
//
//===============================================================
inline void CameraPath::Archive
(
Archiver &arc
)
{
Class::Archive( arc );
arc.ArchiveBool( &_isLoaded );
arc.ArchiveString( &_fileName );
//arc.ArchiveObjectPointer( (Class**)&_keyFramePath );
if ( arc.Loading() )
{
_keyFramePath = ( CameraKeyFramePath*)arc.ReadObject();
}
else
{
arc.ArchiveObject( _keyFramePath );
}
arc.ArchiveFloat( &_yawPlaybackOffsetDegrees );
arc.ArchiveVector( &_originPlaybackOffset );
}
#endif // _CAMERA_PATH_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,765 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/CinematicArmature.h $
// $Revision:: 24 $
// $Author:: Steven $
// $Date:: 5/16/03 8:27p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION: Classes related to supporting Cinematic Armature. The
// CinematicArmature itself is a singleton that governs
// the loading, cacheing, playing, and stopping of
// cinematics. The Cinematic class represents a single
// cinematic with actors, cameras, objects, and associated
// events.
//
// Forward declarations
class Cinematic ;
class CinematicArmature ;
class CinematicActor ;
class CinematicCamera ;
#ifndef __CINEMATIC_ARMATURE_H_
#define __CINEMATIC_ARMATURE_H_
#include "g_local.h"
#include "actor.h"
#include "container.h"
extern CinematicArmature theCinematicArmature ;
extern Event EV_Cinematic_CinematicThink;
extern Event EV_Cinematic_Start ;
extern Event EV_Cinematic_Stop ;
extern Event EV_Cinematic_Loop ;
extern Event EV_Cinematic_Pause ;
extern Event EV_Cinematic_Continue ;
typedef SafePtr<Cinematic> CinematicPtr;
//-----------------------------------------------------------------
// CinematicActor -- Represents an actor in a cinematic. This
// stores data about the actor participating in
// the cinematic, including their name, tiki,
// origin at the start of the cinematic, etc.
// It also stores a pointer to the Actor class
// once the cinematic begins.
//-----------------------------------------------------------------
class CinematicActor : public Listener
{
public:
typedef enum
{
CINEMATIC_ACTOR_STATE_INACTIVE,
CINEMATIC_ACTOR_STATE_MOVING,
CINEMATIC_ACTOR_STATE_TURNING,
CINEMATIC_ACTOR_STATE_PLAYING,
CINEMATIC_ACTOR_STATE_FINISHED
} CinematicActorState ;
typedef enum
{
CINEMATIC_ACTOR_AFTER_BEHAVIOR_REMOVE_FROM_GAME,
CINEMATIC_ACTOR_AFTER_BEHAVIOR_LEAVE_WITH_AI,
CINEMATIC_ACTOR_AFTER_BEHAVIOR_LEAVE_NO_AI,
CINEMATIC_ACTOR_AFTER_BEHAVIOR_LEAVE_FREEZE,
CINEMATIC_ACTOR_AFTER_BEHAVIOR_KILL,
NUM_CINEMATIC_ACTOR_AFTER_BEHAVIORS
} CinematicActorAfterBehavior ;
CLASS_PROTOTYPE( CinematicActor );
CinematicActor();
~CinematicActor() { }
bool isAtSpot( void ) { return _isAtSpot ; }
bool isAnimDone( void ) { return _isAnimDone ; }
bool isRootActor( void ) { return _rootActor ; }
bool doesSnapToSpot( void ) { return _snapToSpot ; }
bool doesIgnorePain( void ) { return _ignorePain ; }
bool doesIgnoreSight( void ) { return _ignoreSight ; }
bool doesIgnoreSound( void ) { return _ignoreSound ; }
bool doesRemoveAfterCinematic( void ) { return _removeAfter ; }
const str& getName() { return _name ; }
const str& getTiki() { return _tiki ; }
const str& getAnim() { return _anim ; }
const str& getMoveAnim() { return _moveAnim ; }
Vector getOrigin() { return _origin ; }
ActorPtr getActor() { return _actor ; }
CinematicActorAfterBehavior getAfterBehavior() { return _afterBehavior ; }
void setName( const str &name) { _name = name ; }
void setTiki( const str &tiki) { _tiki = tiki ; }
void setMoveAnim( const str &anim) { _moveAnim = anim ; }
void setOriginOffset( const Vector &off) { _originOffset = off ; }
void setYawOffset( float yawOffset ) { _yawOffset = yawOffset ; }
void setSnapToSpot( bool snapToSpot ) { _snapToSpot = snapToSpot ; }
void setIgnorePain( bool ignorePain ) { _ignorePain = ignorePain ; }
void setIgnoreSight( bool ignoreSight ) { _ignoreSight = ignoreSight ; }
void setIgnoreSound( bool ignoreSound ) { _ignoreSound = ignoreSound ; }
void setRemoveAfter( bool removeAfter ) { _removeAfter = removeAfter ; }
void setRootActor( bool rootActor ) { _rootActor = rootActor ; }
void setAlwaysSpawn( bool alwaysSpawn ) { _alwaysSpawn = alwaysSpawn ; }
void setAfterBehavior( const str &s );
void setAnim( const str &anim);
bool parse( Script &cinematicFile );
void getToPosition( void );
void takeControlOfActor( const Vector &origin=Vector( 0.0f, 0.0f, 0.0f ), float yaw=0.0f );
void releaseControlOfActor( void );
void playAnimation( void );
void reset( void );
void debug( void );
void Archive( Archiver &arc );
// Event handlers
void actorControlLostEvent( Event *ev );
void actorBehaviorFinishedEvent( Event *ev );
protected:
void _spawn();
void _turnActor( bool useAnims );
void _locateActor();
private:
str _name ;
str _tiki ;
str _anim ;
str _moveAnim ;
Vector _origin ;
Vector _originOffset ;
ActorPtr _actor ;
float _yaw ;
float _yawOffset ;
bool _snapToSpot ;
bool _ignorePain ;
bool _ignoreSight ;
bool _ignoreSound ;
bool _isAtSpot ;
bool _isAnimDone ;
bool _hasActorControl ;
bool _rootActor ;
bool _removeAfter ;
bool _alwaysSpawn ;
CinematicActorAfterBehavior _afterBehavior ;
CinematicActorState _state ;
};
//===============================================================
// Name: Archive
// Class: CinematicActor
//
// Description: Archives (loads or saves) data of a Cinematic actor.
//
// Parameters: Archiver& -- reference to archiver object to store the data.
//
// Returns: None
//
//===============================================================
inline void CinematicActor::Archive
(
Archiver &arc
)
{
Listener::Archive( arc );
arc.ArchiveString( &_name );
arc.ArchiveString( &_tiki );
arc.ArchiveString( &_anim );
arc.ArchiveString( &_moveAnim );
arc.ArchiveVector( &_origin );
arc.ArchiveVector( &_originOffset );
// Archive safe pointer to the actor ( actor is already archived as an entity)
arc.ArchiveSafePointer( &_actor );
arc.ArchiveFloat( &_yaw );
arc.ArchiveFloat( &_yawOffset );
arc.ArchiveBool( &_snapToSpot );
arc.ArchiveBool( &_ignorePain );
arc.ArchiveBool( &_ignoreSight );
arc.ArchiveBool( &_ignoreSound );
arc.ArchiveBool( &_isAtSpot );
arc.ArchiveBool( &_isAnimDone );
arc.ArchiveBool( &_hasActorControl );
arc.ArchiveBool( &_rootActor );
arc.ArchiveBool( &_removeAfter );
arc.ArchiveBool( &_alwaysSpawn );
// Enumerations
ArchiveEnum( _afterBehavior, CinematicActorAfterBehavior );
ArchiveEnum( _state, CinematicActorState );
}
//-----------------------------------------------------------------
// CinematicCamera -- Represents a single cinematic camera. This is
// a wrapper around a regular camera. The cinematic
// camera is given stage directions, including when
// to cut to the next camera. It is also usually
// instantiated at load time, and delays actual
// instantiation of the real camera until the
// cinematic begins.
//-----------------------------------------------------------------
class CinematicCamera : public Listener
{
public:
typedef enum
{
CAMERA_MOVE_TYPE_STATIC,
CAMERA_MOVE_TYPE_FOLLOW_ANIM,
CAMERA_MOVE_TYPE_FOLLOW_PLAYER,
CAMERA_MOVE_TYPE_FOLLOW_ACTOR,
} CameraMoveType ;
typedef enum
{
CAMERA_LOOK_TYPE_WATCH_ANIM,
CAMERA_LOOK_TYPE_WATCH_PLAYER,
CAMERA_LOOK_TYPE_WATCH_ACTOR,
} CameraLookType ;
CLASS_PROTOTYPE( CinematicCamera );
CinematicCamera();
~CinematicCamera() { }
bool isAnimDone() { return !_playing ; }
bool isSelfRemoving( void ) { return _selfRemoving ; }
const str& getName( void ) { return _name ; }
const str& getCamFIle( void ) { return _camFile ; }
const str& getMoveActor( void ) { return _moveActor ; }
const str& getLookActor( void ) { return _lookActor ; }
void getToPosition( void );
void setName( const str &name ) { _name = name ; }
void setCamFile( const str &camFile ) { _camFile = camFile ; }
void setOriginOffset( const Vector &originOffset ) { _originOffset = originOffset ; }
void setYawOffset( float yawOffset ) { _yawOffset = yawOffset ; }
void setMoveActor( const str &moveActor ) { _moveActor = moveActor ; }
void setLookActor( const str &lookActor ) { _lookActor = lookActor ; }
void setMoveType( CameraMoveType moveType ) { _moveType = moveType ; }
void setLookType( CameraLookType lookType ) { _lookType = lookType ; }
void setSelfRemovingFlag( bool selfRemoving ) { _selfRemoving = selfRemoving ; }
void setMoveType( const str &moveType );
void setLookType( const str &lookType );
void start( void );
void cut( void );
void takeControlOfCamera( const Vector &origin=Vector( 0.0f, 0.0f, 0.0f ), float yaw=0.0f );
void releaseControlOfCamera();
bool parse( Script &cinematicFile );
void reset( void );
void debug( void ) { }
void Archive( Archiver &arc );
protected:
void _locateCamera( void );
void _spawn( void );
void _handleStopPlayingEvent( Event *ev );
private:
CameraMoveType _moveType ;
CameraLookType _lookType ;
CameraPtr _camera ;
Vector _originOffset ;
float _yawOffset ;
bool _playing ;
bool _selfRemoving ;
str _name ;
str _camFile ;
str _moveActor ;
str _lookActor ;
};
//===============================================================
// Name: Archive
// Class: CinematicCut
//
// Description: Archives (loads or saves) the data of a Cinematic Camera
//
// Parameters: Archiver& -- reference to Archiver that stores the data.
//
// Returns: None
//
//===============================================================
inline void CinematicCamera::Archive
(
Archiver &arc
)
{
Listener::Archive( arc );
// Enumerations
ArchiveEnum( _moveType, CameraMoveType );
ArchiveEnum( _lookType, CameraLookType );
// Archive off pointer to the camera (camera is archived as normal entity
arc.ArchiveSafePointer( &_camera );
arc.ArchiveVector( &_originOffset );
arc.ArchiveFloat( &_yawOffset );
arc.ArchiveBool( &_playing );
arc.ArchiveBool( &_selfRemoving );
arc.ArchiveString( &_name );
arc.ArchiveString( &_camFile );
arc.ArchiveString( &_moveActor );
arc.ArchiveString( &_lookActor );
}
//-----------------------------------------------------------------
// CinematicCut -- Represents a single cinematic camera cut.
//-----------------------------------------------------------------
class CinematicCut : public Listener
{
public:
CLASS_PROTOTYPE( CinematicCut );
CinematicCut();
~CinematicCut() { }
bool doesLerp( void ) { return _lerpFlag ; }
CinematicCamera *getCinematicCamera( void ) { return _cinematicCamera ; }
const str &getCameraName( void ) { return _cameraName ; }
int getFrame( void ) { return _frame ; }
int getFadeOut( void ) { return _fadeOut ; }
int getFadeIn( void ) { return _fadeIn ; }
void setCinematicCamera( CinematicCamera *camera ) { _cinematicCamera = camera ; }
void setCameraName( const str &name ) { _cameraName = name ; }
void setFrame( unsigned int frame ) { _frame = frame ; }
void setFadeOut( unsigned int fadeOut ) { _fadeOut = fadeOut ; }
void setFadeIn( unsigned int fadeIn ) { _fadeIn = fadeIn ; }
void setLerpFlag( bool lerpFlag ) { _lerpFlag = lerpFlag ; }
void postEvents( void );
bool parse( Script &cinematicFile );
void reset( void );
void stop( void );
void debug( void ) { }
void Archive( Archiver &arc );
protected:
void _locateCamera( void );
void _spawn( void );
void _handleFadeOutEvent( Event *event );
void _handleCutEvent( Event *event );
private:
CinematicCamera *_cinematicCamera ;
bool _lerpFlag ;
int _frame ;
int _fadeOut ;
int _fadeIn ;
str _cameraName ;
};
//===============================================================
// Name: Archive
// Class: CinematicCut
//
// Description: Archives (loads or saves) a Cinematic Cut's data.
//
// Parameters: Archiver& -- reference to object archiving the data.
//
// Returns: None
//
//===============================================================
inline void CinematicCut::Archive
(
Archiver &arc
)
{
Listener::Archive( arc );
arc.ArchiveObjectPointer( ( Class**) &_cinematicCamera );
arc.ArchiveBool( &_lerpFlag );
arc.ArchiveInteger( &_frame );
arc.ArchiveInteger( &_fadeOut );
arc.ArchiveInteger( &_fadeIn );
arc.ArchiveString( &_cameraName );
}
//------------------------------------------------------------------
// CinematicOrigin -- Specifies an origin for a given cinematic.
// This enables the cinematic to be played
// relative to this origin, rather than in
// absolute coordinates on a map.
//------------------------------------------------------------------
class CinematicOrigin : public Listener
{
public:
CLASS_PROTOTYPE( CinematicOrigin );
CinematicOrigin();
~CinematicOrigin() { }
Vector getOrigin( void ) { return _origin ; }
const str& getName( void ) { return _name ; }
float getYaw( void ) { return _yaw ; }
void setOrigin( const Vector origin ) { _origin = origin ; }
void setYaw( float yaw ) { _yaw = yaw ; }
void setName( const str &name ) { _name = name ; }
bool parse( Script &cinematicFile );
void debug( void );
void Archive( Archiver &arc );
private:
Vector _origin ;
str _name ;
float _yaw ;
};
//===============================================================
// Name: Archive
// Class: CinematicOrigin
//
// Description: Arhives (loads or saves) a cinematic origin.
//
// Parameters: Archiver& -- reference to archive object.
//
// Returns: None
//
//===============================================================
inline void CinematicOrigin::Archive
(
Archiver &arc
)
{
Listener::Archive( arc );
arc.ArchiveVector( &_origin );
arc.ArchiveString( &_name );
arc.ArchiveFloat( &_yaw );
}
//-----------------------------------------------------------------
// Cinematic -- Represents a single cinematic. A cinematic is made
// up of actors, cameras, and other objects. The
// cinematic is responsible for coordinating these
// entities working together to recreate the cinematic
// in the game. The data for the cinematic is read
// from a text file when the Cinematic object is
// instantiated by the CinematicArmature (the coordinator
// of all cinematics).
//-----------------------------------------------------------------
class Cinematic : public Entity
{
public:
CLASS_PROTOTYPE( Cinematic );
typedef enum
{
CINEMATIC_STAGE_UNLOADED,
CINEMATIC_STAGE_READY,
CINEMATIC_STAGE_WAITING_FOR_ACTORS,
CINEMATIC_STAGE_ANIMATING,
CINEMATIC_STAGE_FINISHED,
} CinematicStage ;
Cinematic();
Cinematic( const str &filename );
virtual ~Cinematic();
bool doesResetCamera( void ) { return _resetCamera ; }
str& getStartThread( void ) { return _startThread ; }
str& getStopThread( void ) { return _stopThread ; }
str& getFilename( void ) { return _filename ; }
void setResetCameraFlag( bool resetCamera ) { _resetCamera = resetCamera ; }
void setLooping( bool looping ) { _looping = looping ; }
void setFilename( const str &filename ) { _filename = filename ; }
void setStartThread( const str &startThread ) { _startThread = startThread ; }
void setStopThread( const str &stopThread ) { _stopThread = stopThread ; }
void setStartThreadEvent( Event *ev );
void setStopThreadEvent( Event *ev );
void debug( void );
bool load( void );
void start( bool callStartThread = true );
void stop( bool callEndThread = true );
void reset( void );
void startAtNamedOrigin( const str &originName, bool callStartThread = true );
void startAtOrigin( const Vector& origin=Vector( 0.0f, 0.0f, 0.0f ), float yaw=0.0f, bool callStartThread = true );
void Think();
virtual void Archive( Archiver &arc );
protected:
CinematicActor *getCinematicActorByName( const str &name );
CinematicCamera *getCinematicCameraByName( const str &cameraName );
CinematicOrigin *getCinematicOriginByName( const str &originName );
void handleBeginEvent( Event *ev );
void handleBeginAtEvent( Event *ev );
void handleEndEvent( Event *ev );
void handleSetBeginThreadEvent( Event *ev );
void handleSetEndThreadEvent( Event *ev );
void init();
bool parseActors( Script &cinematicFile );
bool parseActor( Script &cinematicFile );
bool parseCameras( Script &cinematicFile );
bool parseCamera( Script &cinematicFile );
bool parseCut( Script &cinematicFile );
bool parseObjects( Script &cinematicFile );
bool parseObject( Script &cinematicFile );
bool parseOrigins( Script &cinematicFile );
bool parseOrigin( Script &cinematicFile );
bool parseOpenBlock( Script &cinematicFile, const str &blockName, const str &openToken="{" );
bool parseCloseBlock( Script &cinematicFile, const str &blockName, const str &closeToken="}" );
bool areActorsAtTheirPlaces();
bool checkForCompletion();
void _startAnimation();
void _endAnimation();
private:
Container<CinematicActor*> _actorList ;
Container<CinematicCamera*> _cameraList ;
Container<CinematicCut*> _cutList ;
Container<CinematicOrigin*> _originList ;
str _filename ;
str _startThread;
str _stopThread ;
bool _looping ;
bool _playing ;
bool _callStartThreadFlag ;
bool _resetCamera ;
CinematicStage _stage ;
};
//===============================================================
// Name: Archive
// Class: Cinematic
//
// Description: Archives (loads or saves) a cinematic's data.
//
// Parameters: Archiver& -- reference to object archiving data.
//
// Returns: None
//
//===============================================================
inline void Cinematic::Archive
(
Archiver &arc
)
{
Entity::Archive( arc );
// Archive actors
int numActors = _actorList.NumObjects();
arc.ArchiveInteger( &numActors );
if ( arc.Loading() )
{
_actorList.Resize( numActors );
for ( int actorIdx = 1; actorIdx <= numActors; ++actorIdx )
{
CinematicActor *actor = 0 ;
_actorList.AddObject( actor );
CinematicActor **actorPtr = &_actorList.ObjectAt( actorIdx );
*actorPtr = (CinematicActor*)arc.ReadObject();
}
}
else
{
for ( int actorIdx = 1; actorIdx <= numActors; ++actorIdx )
{
CinematicActor *actor = _actorList.ObjectAt( actorIdx );
arc.ArchiveObject( actor );
}
}
// Archive cameras
int numCameras = _cameraList.NumObjects();
arc.ArchiveInteger( &numCameras );
if ( arc.Loading() )
{
_cameraList.Resize( numCameras );
for ( int cameraIdx = 1; cameraIdx <= numCameras; ++cameraIdx )
{
CinematicCamera *camera = 0 ;
_cameraList.AddObject( camera );
CinematicCamera **cameraPtr = &_cameraList.ObjectAt( cameraIdx );
*cameraPtr = (CinematicCamera*)arc.ReadObject();
}
}
else
{
for ( int cameraIdx = 1; cameraIdx <= numCameras; ++cameraIdx )
{
CinematicCamera *camera = _cameraList.ObjectAt( cameraIdx );
arc.ArchiveObject( camera );
}
}
// Archive cuts
int numCuts = _cutList.NumObjects();
arc.ArchiveInteger( &numCuts );
if ( arc.Loading() )
{
_cutList.Resize( numCuts );
for ( int cutIdx = 1; cutIdx <= numCuts; ++cutIdx )
{
CinematicCut *cut = 0 ;
_cutList.AddObject( cut );
CinematicCut **cutPtr = &_cutList.ObjectAt( cutIdx );
*cutPtr = (CinematicCut*)arc.ReadObject();
}
}
else
{
for ( int cutIdx = 1; cutIdx <= numCuts; ++cutIdx )
{
CinematicCut *cut = _cutList.ObjectAt( cutIdx );
arc.ArchiveObject( cut );
}
}
// Archive origins
int numOrigins = _originList.NumObjects();
arc.ArchiveInteger( &numOrigins );
if ( arc.Loading() )
{
_cameraList.Resize( numCameras );
for ( int originIdx = 1; originIdx <= numOrigins; ++originIdx )
{
CinematicOrigin *origin = 0 ;
_originList.AddObject( origin );
CinematicOrigin **originPtr = &_originList.ObjectAt( originIdx );
*originPtr = (CinematicOrigin*)arc.ReadObject();
}
}
else
{
for ( int originIdx = 1; originIdx <= numOrigins; ++originIdx )
{
CinematicOrigin *origin = _originList.ObjectAt( originIdx );
arc.ArchiveObject( origin );
}
}
// Archive private members
arc.ArchiveString( &_filename );
arc.ArchiveString( &_startThread );
arc.ArchiveString( &_stopThread );
arc.ArchiveBool( &_playing );
arc.ArchiveBool( &_looping );
arc.ArchiveBool( &_callStartThreadFlag );
arc.ArchiveBool( &_resetCamera );
// Enumerations
ArchiveEnum( _stage, CinematicStage );
}
//----------------------------------------------------------------
// CinematicArmature -- Coordinates the creation, playing, and
// removal of cinematics.
//----------------------------------------------------------------
class CinematicArmature : public Listener
{
public:
CLASS_PROTOTYPE(CinematicArmature );
CinematicArmature();
~CinematicArmature();
static bool isInDebugMode( void ) { return _debug ; }
virtual void Archive( Archiver &arc );
void clearCinematicsList();
Cinematic* createCinematic( const str &cinematicName );
void deleteAllCinematics();
protected:
Cinematic* getCinematicByName( const str &cinematicName );
void setStartThread( Event *ev );
void setStopThread( Event *ev );
void debugCinematics( Event *ev );
void playCinematic( Event *ev );
void playCinematicAt( Event *ev );
void loadCinematic( Event *ev );
bool loadCinematic( const str &cinematicName );
private:
Container<CinematicPtr> _cinematicList ;
Cinematic *_cinematic ;
static bool _debug ;
};
inline void CinematicArmature::Archive
(
Archiver &arc
)
{
Listener::Archive( arc );
int numCinematics = _cinematicList.NumObjects();
arc.ArchiveInteger( &numCinematics );
if ( arc.Loading() )
{
_cinematicList.Resize( numCinematics );
for ( int cinematicIdx = 1; cinematicIdx <= numCinematics; ++cinematicIdx )
{
Cinematic *cinematic = 0 ;
CinematicPtr *cinematicPtr = 0 ;
_cinematicList.AddObject( cinematic );
cinematicPtr = &_cinematicList.ObjectAt( cinematicIdx );
arc.ArchiveSafePointer( cinematicPtr );
}
}
else
{
for ( int cinematicIdx = 1; cinematicIdx <= numCinematics; ++cinematicIdx )
{
CinematicPtr *cinematic = &_cinematicList.ObjectAt( cinematicIdx );
arc.ArchiveSafePointer( cinematic );
}
}
arc.ArchiveObjectPointer( (Class**) &_cinematic );
arc.ArchiveBool( &_debug );
}
#endif /* _CINEMATIC_ARMATURE_H_ */

View file

@ -0,0 +1,526 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/DamageModification.cpp $
// $Revision:: 13 $
// $Date:: 10/10/02 2:39p $
//
// Copyright (C) 1999 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DamageModification.cpp: implementation of the DamageModification class.
//
//////////////////////////////////////////////////////////////////////
#include "_pch_cpp.h"
#include "DamageModification.hpp"
#include "actor.h"
// ------------ DamageModificationSystem -----------------------------
//--------------------------------------------------------------
//
// Name: DamageModificationSystem
// Class: DamageModificationSystem
//
// Description: Constructor / Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
DamageModificationSystem::DamageModificationSystem()
{
damageModifiers.ClearObjectList();
}
DamageModificationSystem::~DamageModificationSystem()
{
int i;
for ( i=1; i<=damageModifiers.NumObjects(); i++ )
{
DamageModifier *damMod = damageModifiers.ObjectAt(i);
delete damMod;
}
damageModifiers.FreeObjectList();
}
//--------------------------------------------------------------
//
// Name: AddDamageModifier
// Class: DamageModificationSystem
//
// Description: Adds a new damage modifier to the internal
// list.
//
// Parameters: const str &damagemodtype -- String version of the DamageModifierType
// const str &value -- String value to be determined by the type
// float multiplier -- the multiplier to this damage mod.
//
// Returns: None
//
//--------------------------------------------------------------
void DamageModificationSystem::addDamageModifier( const str &damagemodtype, const str &value, float multiplier,
float chance, float painBaseLine )
{
DamageModifier *newMod = 0;
if ( damagemodtype == "tikiname" )
newMod = new DamageModifierTikiName(TIKI_NAME, value, multiplier, chance, painBaseLine );
else if ( damagemodtype == "name" )
newMod = new DamageModifierName(NAME, value, multiplier, chance, painBaseLine );
else if ( damagemodtype == "group" )
{
int groupVal = atoi(value);
newMod = new DamageModifierGroup(GROUP, groupVal, multiplier, chance, painBaseLine );
}
else if ( damagemodtype == "actortype" )
{
int actortype = Actor::ActorTypeStringToInt(value);
newMod = new DamageModifierActorType(ACTOR_TYPE, actortype, multiplier, chance, painBaseLine );
}
else if ( damagemodtype == "targetname" )
newMod = new DamageModifierTargetName(TARGETNAME, value, multiplier, chance, painBaseLine );
else if ( damagemodtype == "damagetype" )
{
int damagetypeVal = MOD_NameToNum(value);
newMod = new DamageModifierDamageType(GROUP, damagetypeVal, multiplier, chance, painBaseLine );
}
damageModifiers.AddObject(newMod);
}
//--------------------------------------------------------------
//
// Name: AddDamageModifier
// Class: DamageModificationSystem
//
// Description: Directly adds a premade DamageModifier object to the list
// (this is currently only called from archive loading)
//
// Parameters: DamageModifier *newModifier -- Modifier to add to the list
//
// Returns: None
//
//--------------------------------------------------------------
void DamageModificationSystem::addDamageModifier(DamageModifier *newModifier)
{
if ( newModifier )
damageModifiers.AddObject(newModifier);
}
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModificationSystem
//
// Description: The main damage resolving function
//
// Parameters: Damage &damage -- The damage class to resolve
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModificationSystem::resolveDamage(Damage &damage)
{
int i;
for ( i=1; i<=damageModifiers.NumObjects(); i++ )
{
DamageModifier *damageMod = damageModifiers.ObjectAt( i );
damageMod->resolveDamage(damage);
}
damage.showPain = false;
for ( i=1; i<=damageModifiers.NumObjects(); i++ )
{
DamageModifier *damageMod = damageModifiers.ObjectAt( i );
damageMod->resolvePain(damage);
}
}
// ------------ Damage -----------------------------------------
//--------------------------------------------------------------
//
// Name: Damage
// Class: Damage
//
// Description: Constructor / Destructor
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
Damage::Damage()
{
damage = 0.0f;
inflictor = 0;
attacker = 0;
position = vec_zero;
direction = vec_zero;
normal = vec_zero;
knockback = 0;
dflags = 0;
meansofdeath = -1;
surfaceNumber = -1;
boneNumber = -1;
showPain = false;
weapon = 0;
}
// Constructor that takes the typical damage event as the initializer
Damage::Damage( Event *ev )
{
damage = ev->GetFloat ( 1 );
inflictor = ev->GetEntity ( 2 );
attacker = ev->GetEntity ( 3 );
position = ev->GetVector ( 4 );
direction = ev->GetVector ( 5 );
normal = ev->GetVector ( 6 );
knockback = ev->GetInteger( 7 );
dflags = ev->GetInteger( 8 );
meansofdeath = ev->GetInteger( 9 );
if ( ev->NumArgs() > 9 )
surfaceNumber = ev->GetInteger( 10 );
else
surfaceNumber = -1;
if ( ev->NumArgs() > 10 )
boneNumber = ev->GetInteger( 11 );
else
boneNumber = -1;
if ( ev->NumArgs() > 11 )
weapon = ev->GetEntity( 12 );
else
weapon = 0;
}
Damage::~Damage()
{
}
// ------------ DamageModifierTikiName -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierTikiName
//
// Description: Resolve damage for tiki name type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTikiName::resolveDamage(Damage &damage)
{
if ( damage.attacker->model == _tikiName )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierTikiName
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTikiName::resolvePain(Damage &damage)
{
if ( damage.attacker->model == _tikiName )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
// ------------ DamageModifierName -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierName
//
// Description: Resolve damage for name type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierName::resolveDamage(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->name == _name )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierName
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierName::resolvePain(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->name == _name )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
}
// ------------ DamageModifierGroup -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierGroup
//
// Description: Resolve damage for group type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierGroup::resolveDamage(Damage &damage)
{
if ( damage.attacker->GetGroupID() == _group )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierGroup
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierGroup::resolvePain(Damage &damage)
{
if ( damage.attacker->GetGroupID() == _group )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
// ------------ DamageModifierActorType -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierActorType
//
// Description: Resolve damage for ActorType type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierActorType::resolveDamage(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->actortype == _actortype )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierActorType
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierActorType::resolvePain(Damage &damage)
{
if ( damage.attacker->isSubclassOf( Actor ) )
{
Actor *act = (Actor *)damage.attacker;
if ( act->actortype == _actortype )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
}
// ------------ DamageModifierTargetName -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierTargetName
//
// Description: Resolve damage for TargetName type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTargetName::resolveDamage(Damage &damage)
{
if ( damage.attacker->targetname == _targetname )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierTargetName
//
// Description: Resolve pain for this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierTargetName::resolvePain(Damage &damage)
{
if ( damage.attacker->targetname == _targetname )
{
if ( G_Random() <= (damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}
// ------------ DamageModifierDamageType -------------------------
//--------------------------------------------------------------
//
// Name: resolveDamage
// Class: DamageModifierDamageType
//
// Description: Resolve damage for DamageType type modifiers
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierDamageType::resolveDamage(Damage &damage)
{
if ( damage.meansofdeath == _damagetype )
{
float rand = G_Random();
if ( rand < getChance() )
damage.damage *= getMultiplier();
else
damage.damage = 0.0f;
}
}
//--------------------------------------------------------------
//
// Name: resolvePain
// Class: DamageModifierDamageType
//
// Description: Resolve pain from this damage
//
// Parameters: Damage &damage -- Damage reference to modify
//
// Returns: None (reference above)
//
//--------------------------------------------------------------
void DamageModifierDamageType::resolvePain(Damage &damage)
{
if ( damage.meansofdeath == _damagetype )
{
if ( G_Random() <= ( damage.damage / getPainBaseLine() ) )
damage.showPain = true;
}
}

View file

@ -0,0 +1,381 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: $
// $Revision:: $
// $Date:: $
//
// Copyright (C) 1999 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DamageModification.hpp: interface for the Damage Modification System
//
//////////////////////////////////////////////////////////////////////
class DamageModificationSystem;
class Damage;
class DamageModifier;
class DamageModifierTikiName;
class DamageModifierName;
class DamageModifierGroup;
class DamageModifierActorType;
class DamageModifierTargetName;
class DamageModifierDamageType;
#ifndef __DAMAGEMODIFICATION_H__
#define __DAMAGEMODIFICATION_H__
#include "g_local.h"
// Damage Types enumeration
typedef enum
{
UNDEFINED = 0,
TIKI_NAME,
NAME,
GROUP,
ACTOR_TYPE,
TARGETNAME,
DAMAGE_TYPE // MOD values
} DamageModifierType;
//------------------------- CLASS ------------------------------
//
// Name: DamageModificationSystem
// Base Class: Class
//
// Description: The main system for damage modification
//
// Method of Use: Used in the damage system
//--------------------------------------------------------------
class DamageModificationSystem : public Class
{
private:
Container<DamageModifier *> damageModifiers;
public:
DamageModificationSystem();
virtual ~DamageModificationSystem();
void addDamageModifier(const str &damagemodtype, const str &value, float multiplier, float chance, float painBaseLine );
void addDamageModifier(DamageModifier *newModifier);
void resolveDamage(Damage &damage);
Container<DamageModifier *>& getModifierList() { return damageModifiers; }
};
//------------------------- CLASS ------------------------------
//
// Name: Damage
// Base Class: Class
//
// Description: The actual damage information that's passed around
//
// Method of Use: Used as a parameter to resolveDamage on the main
// DamageModificationSystem class.
//--------------------------------------------------------------
class Damage : public Class
{
public:
float damage;
Entity *inflictor;
Entity *attacker;
Vector position;
Vector direction;
Vector normal;
int knockback;
int dflags;
int meansofdeath;
int surfaceNumber;
int boneNumber;
bool showPain;
Entity *weapon;
Damage();
Damage( Event *ev );
virtual ~Damage();
};
//------------------------- CLASS ------------------------------
//
// Name: DamageModifier
// Base Class: Class
//
// Description: DamageModifier information (type, resistance, etc)
//
// Method of Use: There is a container of this class in DamageModificationSystem
//--------------------------------------------------------------
class DamageModifier : public Class
{
friend class DamageModificationSystem;
private:
float _multiplier;
float _chance;
float _painBaseLine;
protected:
DamageModifierType _type;
virtual void resolveDamage(Damage &damage) = 0;
virtual void resolvePain(Damage &damage) = 0;
public:
DamageModifier()
: _type(UNDEFINED),
_multiplier(0.0f)
{ }
DamageModifier(DamageModifierType type, float multiplier, float chance, float painBaseLine )
: _type(type),
_multiplier(multiplier),
_chance(chance),
_painBaseLine(painBaseLine)
{ }
virtual ~DamageModifier() { }
DamageModifierType getType() { return _type; }
float getMultiplier() { return _multiplier; }
float getPainBaseLine() { return _painBaseLine; }
float getChance() { return _chance; }
void Archive( Archiver &arc );
};
inline void DamageModifier::Archive(Archiver &arc)
{
Class::Archive(arc);
// _type is archived by the caller of this function
//DamageModifierType _type;
arc.ArchiveFloat( &_multiplier );
arc.ArchiveFloat( &_chance );
arc.ArchiveFloat( &_painBaseLine );
}
//------------------------- CLASS ------------------------------
//
// Name: DamageModifierTikiName
// Base Class: DamageModifier
//
// Description: Sub-class to resolve damage modification
// of tiki name type.
//
// Method of Use:
//--------------------------------------------------------------
class DamageModifierTikiName : public DamageModifier
{
private:
str _tikiName;
protected:
/*virtual*/ void resolveDamage(Damage &damage);
/*virtual*/ void resolvePain(Damage &damage);
public:
DamageModifierTikiName() { _type = TIKI_NAME; }
DamageModifierTikiName(DamageModifierType type, const str &tikiname, float multiplier, float chance, float painBaseLine )
: DamageModifier(type, multiplier, chance, painBaseLine ),
_tikiName(tikiname)
{ }
virtual ~DamageModifierTikiName() { }
void Archive( Archiver &arc );
};
inline void DamageModifierTikiName::Archive(Archiver &arc)
{
DamageModifier::Archive(arc);
arc.ArchiveString( &_tikiName );
}
//------------------------- CLASS ------------------------------
//
// Name: DamageModifierName
// Base Class: DamageModifier
//
// Description: Sub-class to resolve damage modification
// of name type.
//
// Method of Use:
//--------------------------------------------------------------
class DamageModifierName : public DamageModifier
{
private:
str _name;
protected:
/*virtual*/ void resolveDamage(Damage &damage);
/*virtual*/ void resolvePain(Damage &damage);
public:
DamageModifierName() { _type = NAME; }
DamageModifierName(DamageModifierType type, const str &name, float multiplier, float chance, float painBaseLine )
: DamageModifier(type, multiplier, chance, painBaseLine ),
_name(name)
{ }
virtual ~DamageModifierName() { }
void Archive( Archiver &arc );
};
inline void DamageModifierName::Archive(Archiver &arc)
{
DamageModifier::Archive(arc);
arc.ArchiveString( &_name );
}
//------------------------- CLASS ------------------------------
//
// Name: DamageModifierGroup
// Base Class: DamageModifier
//
// Description: Sub-class to resolve damage modification
// of group type.
//
// Method of Use:
//--------------------------------------------------------------
class DamageModifierGroup : public DamageModifier
{
private:
int _group;
protected:
/*virtual*/ void resolveDamage(Damage &damage);
/*virtual*/ void resolvePain(Damage &damage);
public:
DamageModifierGroup() { _type = GROUP; }
DamageModifierGroup(DamageModifierType type, int group, float multiplier, float chance, float painBaseLine )
: DamageModifier(type, multiplier, chance, painBaseLine ),
_group(group)
{ }
virtual ~DamageModifierGroup() { }
void Archive( Archiver &arc );
};
inline void DamageModifierGroup::Archive(Archiver &arc)
{
DamageModifier::Archive(arc);
arc.ArchiveInteger( &_group );
}
//------------------------- CLASS ------------------------------
//
// Name: DamageModifierActorType
// Base Class: DamageModifier
//
// Description: Sub-class to resolve damage modification
// of actortype type.
//
// Method of Use:
//--------------------------------------------------------------
class DamageModifierActorType : public DamageModifier
{
private:
int _actortype;
protected:
/*virtual*/ void resolveDamage(Damage &damage);
/*virtual*/ void resolvePain(Damage &damage);
public:
DamageModifierActorType() { _type = ACTOR_TYPE; }
DamageModifierActorType(DamageModifierType type, int actortype, float multiplier, float chance, float painBaseLine)
: DamageModifier(type, multiplier, chance, painBaseLine ),
_actortype(actortype)
{ }
virtual ~DamageModifierActorType() { }
void Archive( Archiver &arc );
};
inline void DamageModifierActorType::Archive(Archiver &arc)
{
DamageModifier::Archive(arc);
arc.ArchiveInteger( &_actortype );
}
//------------------------- CLASS ------------------------------
//
// Name: DamageModifierTargetName
// Base Class: DamageModifier
//
// Description: Sub-class to resolve damage modification
// of targetname type.
//
// Method of Use:
//--------------------------------------------------------------
class DamageModifierTargetName : public DamageModifier
{
private:
str _targetname;
protected:
/*virtual*/ void resolveDamage(Damage &damage);
/*virtual*/ void resolvePain(Damage &damage);
public:
DamageModifierTargetName() { _type = TARGETNAME; }
DamageModifierTargetName(DamageModifierType type, const str &targetname, float multiplier, float chance, float painBaseLine)
: DamageModifier(type, multiplier, chance, painBaseLine ),
_targetname(targetname)
{ }
virtual ~DamageModifierTargetName() { }
void Archive( Archiver &arc );
};
inline void DamageModifierTargetName::Archive(Archiver &arc)
{
DamageModifier::Archive(arc);
arc.ArchiveString( &_targetname );
}
//------------------------- CLASS ------------------------------
//
// Name: DamageModifierDamageType
// Base Class: DamageModifier
//
// Description: Sub-class to resolve damage modification
// of targetname type.
//
// Method of Use:
//--------------------------------------------------------------
class DamageModifierDamageType : public DamageModifier
{
private:
int _damagetype;
protected:
/*virtual*/ void resolveDamage(Damage &damage);
/*virtual*/ void resolvePain(Damage &damage);
public:
DamageModifierDamageType() { _type = DAMAGE_TYPE; }
DamageModifierDamageType(DamageModifierType type, int damagetype, float multiplier, float chance, float painBaseLine)
: DamageModifier(type, multiplier, chance, painBaseLine ),
_damagetype(damagetype)
{ }
virtual ~DamageModifierDamageType() { }
void Archive( Archiver &arc );
};
inline void DamageModifierDamageType::Archive(Archiver &arc)
{
DamageModifier::Archive(arc);
arc.ArchiveInteger( &_damagetype );
}
#endif // !defined(__DAMAGEMODIFICATION_H__)

1389
dlls/game/FollowPath.cpp Normal file

File diff suppressed because it is too large Load diff

267
dlls/game/FollowPath.h Normal file
View file

@ -0,0 +1,267 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/FollowPath.h $
// $Revision:: 20 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// Provides base functionality for path following with avoidance
//
#ifndef __FOLLOW_PATH_H__
#define __FOLLOW_PATH_H__
#include "g_local.h"
#include "entity.h"
#include "path.h"
#include "steering.h"
class Actor;
//------------------------- CLASS ------------------------------
//
// Name: FollowNode
// Base Class: Class
//
// Description: FollowNodes are a lightweight class meant to
// store translation information for the FollowNodePath class
//
// Method of Use: FollowNodes should only be created by
// FollowNodePaths but other classes my need access a node's
// translation.
//
//--------------------------------------------------------------
class FollowNode : public Class
{
public:
CLASS_PROTOTYPE( FollowNode );
FollowNode( void );
FollowNode( const Vector &position, const bool isTemporary=false, const bool isJumpNode=false, const float jumpAngle=45.0f );
Vector const & GetPosition( void ) const { return _position; }
const bool GetIsTemporary( void ) const { return _isTemporary; }
const bool GetIsJumpNode( void ) const { return _isJumpNode; }
void SetIsJumpNode( const bool isJumpNode ) { _isJumpNode = isJumpNode; }
const float GetJumpAngle( void ) const { return _jumpAngle; }
void SetJumpAngle( const float jumpAngle )
{
_jumpAngle = jumpAngle;
}
virtual void Archive( Archiver &arc );
private:
Vector _position;
bool _isTemporary;
bool _isJumpNode;
float _jumpAngle;
};
inline void FollowNode::Archive( Archiver &arc )
{
Class::Archive( arc );
arc.ArchiveVector( &_position );
arc.ArchiveBool( &_isTemporary );
arc.ArchiveBool( &_isJumpNode );
arc.ArchiveFloat( &_jumpAngle );
}
typedef SafePtr<FollowNode> FollowNodePtr;
//------------------------- CLASS ------------------------------
//
// Name: FollowNodePath
// Base Class: Class
//
// Description: FollowNodePaths are simple paths that support the
// concept of temporary path nodes (allowing temporary insertion
// nodes into the path).
//
// Method of Use: FollowNodePaths should primarily be used by
// FollowPath classes, although other classes may need access to
// most of the members of the class
//
//--------------------------------------------------------------
enum PathCreationReturnCodes
{
PATH_CREATION_SUCCESS,
PATH_CREATION_FAILED_DEGENERATE_PATH,
PATH_CREATION_FAILED_NODES_NOT_CONNECTED,
PATH_CREATION_FAILED_START_NODE_NOT_FOUND,
PATH_CREATION_FAILED_END_NODE_NOT_FOUND,
};
class FollowNodePath : public Class
{
public:
CLASS_PROTOTYPE( FollowNodePath );
FollowNodePath();
~FollowNodePath() { Clear(); }
void AddNode(FollowNodePtr node) { _nodes.AddObject(node); }
void RemoveNode(FollowNodePtr node);
void InsertNode(FollowNodePtr node, const int index);
FollowNodePtr GetPreviousNode(const FollowNodePtr node) const;
FollowNodePtr GetNextNode(const FollowNodePtr node) const;
const Steering::ReturnValue Evaluate( Actor &self, const Vector &goalPosition );
unsigned int const SetPath( Actor &self, const Vector &from, const Vector &to );
void Clear();
void Draw( void ) const;
void SetCurrentNode(FollowNodePtr node) { _currentNode = node; }
FollowNodePtr GetCurrentNode(void) const { return _currentNode; }
int GetCurrentNodeIndex(void) const { return GetNodeIndex( GetCurrentNode() ); }
FollowNodePtr GetNodeAt(const int index) const { return _nodes.ObjectAt(index); }
int const GetNodeIndex(const FollowNodePtr node) const { return _nodes.IndexOfObject(node); }
FollowNodePtr FirstNode(void) const { return _nodes.ObjectAt(1); }
FollowNodePtr LastNode(void) const { return _nodes.ObjectAt(NumNodes()); }
int const NumNodes(void) const { return _nodes.NumObjects(); }
virtual void Archive( Archiver &arc );
private:
void BuildFromPathNodes(Path *path, const Actor &self);
const bool FindNewCurrentNode( const Actor &self );
const Steering::ReturnValue AdvanceCurrentNode( const Actor &self );
const Steering::ReturnValue RetreatCurrentNode( Actor &self, const Vector &goalPosition );
Container<FollowNode *> _nodes;
FollowNodePtr _currentNode;
};
inline void FollowNodePath::Archive( Archiver &arc )
{
Class::Archive( arc );
int i;
int num;
FollowNode *followNode;
if ( arc.Saving() )
{
num = _nodes.NumObjects();
arc.ArchiveInteger( &num );
for( i = 1 ; i <= num ; i++ )
{
followNode = _nodes.ObjectAt( i );
arc.ArchiveObject( followNode );
}
}
else
{
arc.ArchiveInteger( &num );
_nodes.ClearObjectList();
_nodes.Resize( num );
for( i = 1 ; i <= num ; i++ )
{
followNode = new FollowNode;
_nodes.AddObject( followNode );
arc.ArchiveObject( followNode );
}
}
arc.ArchiveSafePointer( &_currentNode );
}
//------------------------- CLASS ------------------------------
//
// Name: FollowPath
// Base Class: Steering
//
// Description: FollowPath is the base class for and Steering
// classes that need to navigate any significant distance through
// the level.
//
// Method of Use: Never instantiate an object of type FollowPath.
// If the TikiEngine architecture allowed, this cless would be an
// interface class. If you need FollowPath behavior either use an
// existing FollowPath subclass or derive a new class from a
// FollowPath class.
//
//--------------------------------------------------------------
class FollowPath : public Steering
{
public:
CLASS_PROTOTYPE( FollowPath );
FollowPath();
virtual ~FollowPath() { DeleteTemporaryPathNodes(); }
virtual const Vector & GetGoalPosition(void) const { assert (false); return vec_zero; }
virtual const float GetGoalRadius(void) const { assert (false); return 0.0f; }
virtual FollowNodePath & GetPath(void) { return _path; }
virtual const float GetRadius (void) const { return _radius; }
virtual void SetRadius (const float radius) { _radius = radius; }
virtual const float GetAvoidanceDistance (void) const { return _avoidanceDistance; }
virtual void SetAvoidanceDistance (const float avoidanceDistance) { _avoidanceDistance = avoidanceDistance; }
virtual void SetSteeringForceAndDesiredHeading( Actor &self, const Vector &steeringForce );
virtual void Begin( Actor &self );
virtual const ReturnValue Evaluate( Actor &self );
virtual void ShowInfo( Actor &self );
virtual void Archive( Archiver &arc );
protected:
virtual void DeleteTemporaryPathNodes(void);
virtual const bool ClearTraceToGoal( Actor &self, const trace_t &traceToGoal, const float radius ) const;
virtual const bool DoneTurning( Actor &self ) const;
virtual const ReturnValue GotoCurrentNode( Actor &self );
virtual const ReturnValue GotoGoal( Actor &self );
virtual const bool BuildAvoidancePath(Actor &self, const bool passOnTheLeft, const Vector &obstaclePosition, const float avoidanceRadius, const bool pursueGoal );
virtual const ReturnValue AvoidObstacle( Actor &self, const trace_t & trace, const bool pursueGoal=false );
virtual const bool TraceBlockedByEntity(Actor &self, const trace_t & trace ) const;
virtual const bool CheckBlocked(Actor &self);
virtual const ReturnValue ReturnBlockingObject(const trace_t &trace) const;
virtual const bool AtDestination(Actor &self) const;
virtual void SteerToCurrentNode(Actor &self);
virtual void SteerToGoal( Actor &self );
virtual void FreePath( void ) { _path.Clear(); }
virtual void AddPathNode(FollowNodePtr node) { GetPath().AddNode( node ); }
virtual void InsertPathNode(FollowNodePtr node, const int index) { GetPath().InsertNode(node, index); SetCurrentNode(node); }
virtual FollowNodePtr GetCurrentNode(void) const { return _path.GetCurrentNode(); }
virtual void SetCurrentNode(FollowNodePtr node) { _path.SetCurrentNode(node); }
private:
float _radius;
FollowNodePath _path;
float _avoidanceDistance;
Vector _desiredHeading;
Jump _jump;
qboolean _jumping;
str _oldAnim;
};
inline void FollowPath::Archive
(
Archiver &arc
)
{
Steering::Archive( arc );
arc.ArchiveFloat( &_radius );
arc.ArchiveObject( &_path );
arc.ArchiveFloat( &_avoidanceDistance );
arc.ArchiveVector( &_desiredHeading );
arc.ArchiveObject( &_jump );
arc.ArchiveBoolean( &_jumping );
arc.ArchiveString( &_oldAnim );
}
#endif // FollowPath

View file

@ -0,0 +1,133 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/FollowPathToEntity.cpp $
// $Revision:: 12 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// Specialization of FollowPath used to follow moving entities
//
#include "_pch_cpp.h"
#include "actor.h"
#include "FollowPathToEntity.h"
//------------------------- CLASS ------------------------------
//
// Name: FollowPathToEntity
// Base Class: FollowPath
//
// Description: FollowPathToEntity is a specialization of
// FollowPath used when the Actor must move to a moving Entity
//
// Method of Use: Behaviors Aggregate FollowPath classes to
// handle long term motion to a goal
//
//--------------------------------------------------------------
CLASS_DECLARATION( FollowPath, FollowPathToEntity, NULL )
{
{ NULL, NULL }
};
//----------------------------------------------------------------
// Name: FollowPathToEntity
// Class: FollowPathToEntity
//
// Description: default constructor
//
// Parameters: None
//
// Returns: None
//----------------------------------------------------------------
FollowPathToEntity::FollowPathToEntity():
_targetEntity(NULL),
_oldGoalPosition(0,0,0)
{
}
//----------------------------------------------------------------
// Name: SetGoal
// Class: FollowPathToEntity
//
// Description: sets goal entity and creates a path to it
//
// Parameters:
// Entity entity - goal entity
// float radius - how close actor needs to get to goal
// Actor self - the Actor trying to get to the goal
//
// Returns: None
//----------------------------------------------------------------
void FollowPathToEntity::SetGoal(Entity *entity, const float radius, Actor &self)
{
SetRadius(radius);
if (
( _targetEntity == NULL ) ||
( _targetEntity->entnum != entity->entnum)
)
{
_targetEntity = entity;
_oldGoalPosition = GetGoalPosition();
GetPath().SetPath(self, self.origin, GetGoalPosition());
}
}
//----------------------------------------------------------------
// Name: ClearTraceToGoal
// Class: FollowPathToEntity
//
// Description: test to determine if Actor can move directly
// to the goal
//
// Parameters:
// Actor self - the Actor trying to get to the goal
// trace_t trace - trace that travels from the
// Actor to the goal
//
// Returns: bool that is true if the trace reaches the goal
//----------------------------------------------------------------
const bool FollowPathToEntity::ClearTraceToGoal( Actor &self, const trace_t &traceToGoal, const float radius ) const
{
assert (_targetEntity != NULL);
// Path is only obstructed by the goal object itself
bool traceHitGoal = (
(_targetEntity->entnum == traceToGoal.entityNum) &&
(traceToGoal.entityNum != ENTITYNUM_NONE)
);
return ( FollowPath::ClearTraceToGoal( self, traceToGoal, radius ) || (!traceToGoal.startsolid && traceHitGoal ) );
}
//----------------------------------------------------------------
// Name: Evaluate
// Class: FollowPathToEntity
//
// Description: attempts to move the Actor to the goal position
//
// Parameters:
// Actor self - the actor following the path
//
// Returns: Steering::ReturnValue returns reason for failure
//----------------------------------------------------------------
const Steering::ReturnValue FollowPathToEntity::Evaluate( Actor &self)
{
if (Vector::Distance( _oldGoalPosition, GetGoalPosition()) > GetAvoidanceDistance() )
{
_oldGoalPosition = GetGoalPosition();
GetPath().SetPath(self, self.origin, GetGoalPosition() );
}
return FollowPath::Evaluate( self);
}

View file

@ -0,0 +1,67 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/FollowPathToEntity.h $
// $Revision:: 7 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// Specialization of FollowPath used to follow moving entities
//
#ifndef __FOLLOW_PATH_TO_ENTITY_H__
#define __FOLLOW_PATH_TO_ENTITY_H__
#include "FollowPath.h"
class Actor;
//------------------------- CLASS ------------------------------
//
// Name: FollowPathToEntity
// Base Class: FollowPath
//
// Description: FollowPathToEntity is a specialization of
// FollowPath used when the Actor must move to a moving Entity
//
// Method of Use: Behaviors Aggregate FollowPath classes to
// handle long term motion to a goal
//
//--------------------------------------------------------------
class FollowPathToEntity : public FollowPath
{
public:
CLASS_PROTOTYPE( FollowPathToEntity );
FollowPathToEntity();
virtual void SetGoal( Entity *ent, const float radius, Actor &self );
virtual const Vector & GetGoalPosition(void) const { assert (_targetEntity != NULL); return _targetEntity->origin; }
virtual const float GetGoalRadius(void) const { return Vector(_targetEntity->mins).lengthXY(); }
virtual const ReturnValue Evaluate( Actor &self );
virtual void Archive( Archiver &arc );
protected:
virtual const bool ClearTraceToGoal( Actor &self, const trace_t &traceToGoal, const float radius ) const;
private:
EntityPtr _targetEntity;
Vector _oldGoalPosition;
};
inline void FollowPathToEntity::Archive( Archiver &arc )
{
FollowPath::Archive( arc );
arc.ArchiveSafePointer( &_targetEntity );
arc.ArchiveVector( &_oldGoalPosition );
}
#endif // FollowPathToEntity.h

View file

@ -0,0 +1,76 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/FollowPathToPoint.cpp $
// $Revision:: 9 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// Specialization of FollowPath used to follow moving entities
//
#include "_pch_cpp.h"
#include "FollowPathToPoint.h"
#include "actor.h"
//------------------------- CLASS ------------------------------
//
// Name: FollowPathToPoint
// Base Class: FollowPath
//
// Description: FollowPathToEntity is a specialization of
// FollowPath used when the Actor must move to a stationary point
//
// Method of Use: Behaviors Aggregate FollowPath classes to
// handle long term motion to a goal
//
//--------------------------------------------------------------
CLASS_DECLARATION( FollowPath, FollowPathToPoint, NULL )
{
{ NULL, NULL }
};
//----------------------------------------------------------------
// Name: FollowPathToPoint
// Class: FollowPathToPoint
//
// Description: default constructor
//
// Parameters: None
//
// Returns: None
//----------------------------------------------------------------
FollowPathToPoint::FollowPathToPoint():_targetPoint(0,0,0)
{
}
//----------------------------------------------------------------
// Name: SetGoal
// Class: FollowPathToPoint
//
// Description: sets goal point and creates a path to it
//
// Parameters:
// Vector targetPoint - goal position
// float radius - how close actor needs to get to goal
// Actor self - the Actor trying to get to the goal
//
// Returns: None
//----------------------------------------------------------------
void FollowPathToPoint::SetGoal(const Vector &targetPoint, const float radius, Actor &self)
{
SetRadius(radius);
if (!Vector::CloseEnough(_targetPoint, targetPoint, 1.0f))
{
_targetPoint = targetPoint;
GetPath().SetPath(self, self.origin, GetGoalPosition());
}
}

View file

@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/FollowPathToPoint.h $
// $Revision:: 6 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Specialization of FollowPath used to follow a path to a static point
//
#ifndef __FOLLOW_PATH_TO_POINT_H__
#define __FOLLOW_PATH_TO_POINT_H__
#include "FollowPath.h"
//------------------------- CLASS ------------------------------
//
// Name: FollowPathToPoint
// Base Class: FollowPath
//
// Description: FollowPathToEntity is a specialization of
// FollowPath used when the Actor must move to a stationary point
//
// Method of Use: Behaviors Aggregate FollowPath classes to
// handle long term motion to a goal
//
//--------------------------------------------------------------
class FollowPathToPoint : public FollowPath
{
public:
CLASS_PROTOTYPE( FollowPathToPoint );
FollowPathToPoint();
virtual void SetGoal( const Vector &targetPoint, const float radius, Actor &self );
virtual const Vector & GetGoalPosition( void ) const { return _targetPoint; }
virtual const float GetGoalRadius(void) const { return 16.0f; }
virtual void Archive( Archiver &arc );
private:
Vector _targetPoint;
};
inline void FollowPathToPoint::Archive( Archiver &arc )
{
FollowPath::Archive( arc );
arc.ArchiveVector( &_targetPoint );
}
#endif // FollowPathToPoint.h

View file

@ -0,0 +1,192 @@
// GameplayDatabase.h: interface for the GameplayDatabase class.
//
//////////////////////////////////////////////////////////////////////
class GameplayDatabase;
class GameplayObject;
class GameplayProperty;
#ifndef __GAMEPLAYDATABASE_H__
#define __GAMEPLAYDATABASE_H__
#ifdef GAME_DLL
#include "g_local.h"
#endif // GAME_DLL
//------------------------- CLASS ------------------------------
//
// Name: GameplayProperty
// Base Class: Class
//
// Description: Object that has a key and a value which can be
// a string or a float
//
// Method of Use: Used in GameplayObject's
//
//--------------------------------------------------------------
class GameplayProperty : public Class
{
private:
str _name;
str _valuestr;
float _valuefloat;
bool _modified;
public:
GameplayProperty()
: _name(""),
_valuestr(""),
_valuefloat(1.0f),
_modified(false)
{}
virtual ~GameplayProperty() {}
// Parsing
bool parseProperty(Script &gameplayFile, const str& name);
// Accessors -- Gets
const str& getName() { return _name; }
const str& getStringValue() { return _valuestr; }
float getFloatValue() { return _valuefloat; }
bool getModified() { return _modified; }
const str getFloatValueStr();
// Accessors -- Sets
void setName(const str& name) { _name = name; }
void setModified(bool modified) { _modified = modified; }
bool setStringValue(const str& valuestr);
bool setFloatValue(float valuefloat);
// Archiving
void Archive(Archiver &arc);
};
inline void GameplayProperty::Archive(Archiver &arc)
{
arc.ArchiveString(&_name);
arc.ArchiveString(&_valuestr);
arc.ArchiveFloat(&_valuefloat);
arc.ArchiveBool(&_modified);
}
//------------------------- CLASS ------------------------------
//
// Name: GameplayObject
// Base Class: Class
//
// Description: Object that has a name, and a container of
// GameplayProperty's.
//
// Method of Use: Used in GameplayDatabase
//
//--------------------------------------------------------------
class GameplayObject : public Class
{
private:
str _name;
str _category;
int _depth;
GameplayObject* _baseObject;
Container<GameplayProperty *> _propertyList;
Container<GameplayObject *> _subObjectList;
public:
GameplayObject();
GameplayObject(int depth);
virtual ~GameplayObject();
// Parsing
bool parseObject(Script &gameplayFile, const str& name);
//Queries
bool hasProperty(const str& propname);
// Accessors -- Gets
const str& getName() { return _name; }
const str& getCategory() { return _category; }
const Container<GameplayObject *>& getSubObjectList() { return _subObjectList; };
GameplayObject* getBaseObject() { return _baseObject; }
GameplayObject* getSubObject(const str& subobjname);
GameplayProperty* getProperty(const str& propname);
float getPropertyFloatValue(const str& propname);
const str getPropertyStringValue(const str& propname);
bool getModified(const str& propname);
// Accessors -- Sets
void setName(const str& name) { _name = name; }
void setCategory(const str& category) { _category = category; }
void setBaseObject(GameplayObject* baseObject) { _baseObject = baseObject; }
bool setFloatValue(const str& propname, float value, bool create = false);
bool setStringValue(const str& propname, const str& valuestr, bool create = false);
// Archiving
void Archive(Archiver &arc);
};
inline void GameplayObject::Archive(Archiver &arc)
{
// TODO: Archive the container of GameplayProperties
// TODO: Archive the container of GameplayObjects
}
//------------------------- CLASS ------------------------------
//
// Name: GameplayDatabase
// Base Class: Listener
//
// Description: Database of GameplayObjects. Queries are made
// to this database to retrieve the data
//
// Method of Use: Used by the GameplayManager
//
//--------------------------------------------------------------
class GameplayDatabase : public Listener
{
private:
Container<GameplayObject *> _objectList;
GameplayObject *_lastObj;
str _lastObjName; // Full scope for quick compare
// Private Functions
void linkSubObjectsToBase();
GameplayObject* createFromScope(const str& scope);
public:
GameplayDatabase();
virtual ~GameplayDatabase();
// Parsing
bool parseFile(const str& filename);
// Queries
bool hasObject(const str& objname);
// Accessors -- Gets
GameplayObject* getObject(const str& objname);
GameplayObject* getRootObject(const str& objname);
GameplayObject* getSubObject(const str& objname, const str& subobjname);
float getFloatValue(const str& objname, const str& propname);
const str getStringValue(const str& objname, const str& propname);
// Accessors -- Sets
bool setFloatValue(const str& objname, const str& propname, float value, bool create = false);
bool setStringValue(const str& objname, const str& propname, const str& valuestr, bool create = false);
// Archiving
void Archive(Archiver &arc);
};
inline void GameplayDatabase::Archive(Archiver &arc)
{
// TODO: Archive the container of GameplayObjects
}
#endif

View file

@ -0,0 +1,193 @@
// GameplayFormulaManager.h: interface for the GameplayFormulaManager class.
//
//////////////////////////////////////////////////////////////////////
class GameplayFormulaManager;
class GameplayFormula;
class GameplayFormulaVariable;
class GameplayFormulaData;
class GameplayFormulaOperand;
#ifndef __GAMEPLAY_FORMULA_MANAGER_H__
#define __GAMEPLAY_FORMULA_MANAGER_H__
#include "g_local.h"
#include "actor.h"
#include "weapon.h"
#include "entity.h"
#include "player.h"
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaData
// Base Class: Class
//
// Description: Utility class to the GameplayFormulaManager
//
// Method of Use: The user will build on of these objects to pass
// into the GameplayManager query functions.
//
//--------------------------------------------------------------
class GameplayFormulaData : public Class
{
public:
GameplayFormulaData( Entity *pPrimary = 0,
Entity *pSecondary = 0,
Entity *pWeapon = 0,
const str& pAttackType = "");
Entity *primary;
Entity *secondary;
Entity *weapon;
str attackType;;
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaVariable
// Base Class: Class
//
// Description: Variable that contains the list of categories that
// are specific to a variable type.
//
// Method of Use: GameplayFormula uses this class
//
//--------------------------------------------------------------
class GameplayFormulaVariable : public Class
{
private:
str _name;
Container<str> _categoryList;
public:
GameplayFormulaVariable();
virtual ~GameplayFormulaVariable();
// Accessors
const str& getName() { return _name; }
void setName(const str& name) { _name = name; }
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaOperand
// Base Class: Class
//
// Description: A operand in a formula
//
// Method of Use: GameplayFormula has a list of these to multiply together
//
//--------------------------------------------------------------
class GameplayFormulaOperand : public Class
{
private:
float _constant;
str _object;
str _property;
bool _inverse;
public:
GameplayFormulaOperand()
: _constant(1.0f),
_inverse(false)
{}
virtual ~GameplayFormulaOperand() {}
// Accessors
const str& getObjectName() { return _object; }
void setObjectName(const str& object) { _object = object; }
const str& getPropertyName() { return _property; }
void setPropertyName(const str& property) { _property = property; }
float getConstant() { return _constant; }
void setConstant(float constant) { _constant = constant; }
bool getInverseFlag() { return _inverse; }
void setInverseFlag(bool inverse) { _inverse = inverse; }
// Queries
float getResult(const GameplayFormulaData& formulaData);
// Parsing
bool parseOperand(Script &formulaFile, const str& constant);
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormula
// Base Class: Class
//
// Description: A formula in the for the GameplayManager
//
// Method of Use: GameplayFormulaManager requests data from this class
//
//--------------------------------------------------------------
class GameplayFormula : public Class
{
private:
str _name;
Container<GameplayFormulaOperand *> _operandList;
public:
GameplayFormula();
virtual ~GameplayFormula();
// Accessors
const str& getName() { return _name; }
void setName(const str& name) { _name = name; }
// Queries
float getResult(const GameplayFormulaData& formulaData );
// Parsing
bool parseFormula(Script &formulaFile, const str& name);
};
//------------------------- CLASS ------------------------------
//
// Name: GameplayFormulaManager
// Base Class: Class
//
// Description: The manager for all the formulas. Accessed
// by the GameplayManager
//
// Method of Use: GameplayManager uses this class to access formulas
//
//--------------------------------------------------------------
class GameplayFormulaManager : public Class
{
private:
Container<GameplayFormulaVariable *> _variableList;
Container<GameplayFormula *> _formulaList;
public:
GameplayFormulaManager();
virtual ~GameplayFormulaManager();
// Queries
float getFormulaResult(const str& formulaName, const GameplayFormulaData& formulaData);
bool hasFormula(const str& formulaName);
// Parsing
bool parseFile(const str& filename);
};
#endif

View file

@ -0,0 +1,84 @@
// GameplayManager.h: interface for the GameplayManager class.
//
//////////////////////////////////////////////////////////////////////
class GameplayManager;
#ifndef __GAMEPLAYMANAGER_H__
#define __GAMEPLAYMANAGER_H__
#ifdef GAME_DLL
#include "g_local.h"
#include "actor.h"
#include "weapon.h"
#include "player.h"
#include "GameplayFormulaManager.h"
#endif // GAME_DLL
#ifdef CGAME_DLL
#include "cg_local.h"
#endif // CGAME_DLL
#include "GameplayDatabase.h"
//------------------------- CLASS ------------------------------
//
// Name: GameplayManager
// Base Class: Listener
//
// Description: Singlton class that handles gameplay elements
//
// Method of Use: Use in game code when things need to be resolved
//
//--------------------------------------------------------------
class GameplayManager : public Listener
{
//-----------------------------------------------------------
// D A T A B A S E S T U F F
//-----------------------------------------------------------
public:
// Static Member functions
static GameplayManager* getTheGameplayManager();
static void shutdown();
static bool isReady();
static void create();
// Queries
bool hasProperty(const str& objname, const str& propname);
bool hasObject(const str& objname);
bool hasSubObject(const str& objname, const str& subobject);
bool isDefined(const str& propname);
// Accessors
const str getDefine(const str& propname);
float getFloatValue(const str& objname, const str& propname);
const str getStringValue(const str& objname, const str& propname);
GameplayObject *getObject(const str& objname);
// Mutators NOTE: These functions can only set values on root level objects!
void setFloatValue(const str& objname, const str& propname, float value, bool create = false);
void setStringValue(const str& objname, const str& propname, const str& valuestr, bool create = false);
protected:
GameplayManager();
virtual ~GameplayManager();
private:
static GameplayManager *_theGameplayManager; // singleton
GameplayDatabase _gameplayDatabase;
#ifdef GAME_DLL
//------------------------------------------------------------
// F O R M U L A S T U F F
//------------------------------------------------------------
public:
bool hasFormula(const str& formulaName);
float calculate(const str& formulaName, const GameplayFormulaData& formulaData, float multiplier = 1.0f);
private:
GameplayFormulaManager _gameplayFormulaManager;
#endif // GAME_DLL
};
#endif

View file

@ -0,0 +1,142 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/GoDirectlyToPoint.cpp $
// $Revision:: 6 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
#include "_pch_cpp.h"
#include "actor.h"
#include "GoDirectlyToPoint.h"
//------------------------- CLASS ------------------------------
//
// Name: GoDirectlyToPoint
// Base Class: Class
//
// Description: Simple Steering class that moves directly to the
// desired point without any regard for obstacle or world
// avoidance.
//
// Method of Use: This is an appropiate steering method iff
// some guarentee is made that the Actor will not collide with
// anything while travelling to the target point.
//
//--------------------------------------------------------------
CLASS_DECLARATION( Steering, GoDirectlyToPoint, NULL )
{
{ NULL, NULL }
};
//----------------------------------------------------------------
// Name: GoDirectlyToPoint
// Class: GoDirectlyToPoint
//
// Description: default constructor
//
// Parameters: None
//
// Returns: None
//----------------------------------------------------------------
GoDirectlyToPoint::GoDirectlyToPoint()
{
}
//----------------------------------------------------------------
// Name: Begin
// Class: GoDirectlyToPoint
//
// Description: Initializes variables necessary to Evaluate
//
// Parameters:
// Actor self - the actor moving to a point
//
// Returns: None
//----------------------------------------------------------------
void GoDirectlyToPoint::Begin(Actor &self)
{
}
//----------------------------------------------------------------
// Name: Evaluate
// Class: GoDirectlyToPoint
//
// Description: attempts to move the Actor to the goal position
//
// Parameters:
// Actor self - the actor following the path
//
// Returns: Steering::ReturnValue returns reason for failure
//----------------------------------------------------------------
const Steering::ReturnValue GoDirectlyToPoint::Evaluate( Actor &self )
{
ResetForces();
if (AtDestination( self ))
{
return Steering::SUCCESS;
}
Vector newSteeringForce = self.movementSubsystem->SteerTowardsPoint
(
_destination,
vec_zero,
self.movementSubsystem->getMoveDir(),
self.movementSubsystem->getMoveSpeed()
);
self.movementSubsystem->Accelerate( newSteeringForce );
return Steering::EVALUATING ;
}
//----------------------------------------------------------------
// Name: ShowInfo
// Class: GoDirectlyToPoint
//
// Description: prints out useful debug info for the class
//
// Parameters:
// Actor self - the actor following the path
//
// Returns: None
//----------------------------------------------------------------
void GoDirectlyToPoint::ShowInfo( Actor &self )
{
Steering::ShowInfo( self );
gi.Printf( "\n destination : ( %f, %f, %f ) \n", _destination.x, _destination.y, _destination.z );
}
//----------------------------------------------------------------
// Name: AtDestination
// Class: GoDirectlyToPoint
//
// Description: test that determines if the Actor is close to
// the goal
//
// Parameters:
// Actor self - the actor following the path
//
// Returns: bool that is true if the Actor is at the goal
//----------------------------------------------------------------
const bool GoDirectlyToPoint::AtDestination(const Actor &self) const
{
//Check if we are in range
if ((Vector::DistanceXY( _destination, self.origin ) ) <= _radius )
{
return true;
}
return false;
}

View file

@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/GoDirectlyToPoint.h $
// $Revision:: 4 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Simple Steering class that moves directly to the desired point
// without any regard for obstacle or world avoidance
//
#ifndef __GO_DIRECTLY_TO_POINT__
#define __GO_DIRECTLY_TO_POINT__
#include "g_local.h"
#include "steering.h"
class Actor;
//------------------------- CLASS ------------------------------
//
// Name: GoDirectlyToPoint
// Base Class: Class
//
// Description: Simple Steering class that moves directly to the
// desired point without any regard for obstacle or world
// avoidance.
//
// Method of Use: This is an appropiate steering method iff
// some guarentee is made that the Actor will not collide with
// anything while travelling to the target point.
//
//--------------------------------------------------------------
class GoDirectlyToPoint : public Steering
{
public:
CLASS_PROTOTYPE( GoDirectlyToPoint );
GoDirectlyToPoint();
virtual ~GoDirectlyToPoint() { }
virtual void Begin( Actor &self );
virtual const ReturnValue Evaluate( Actor &self );
virtual void ShowInfo( Actor &self );
void SetDestination( const Vector &destination ) { _destination = destination; }
void SetRadius( const float radius ) { _radius = radius; }
virtual void Archive( Archiver &arc );
const bool AtDestination( const Actor &self ) const;
private:
Vector _destination;
float _radius;
};
inline void GoDirectlyToPoint::Archive( Archiver &arc )
{
Steering::Archive( arc );
arc.ArchiveVector( &_destination );
arc.ArchiveFloat( &_radius );
}
#endif // GoDirectlyToPoint

118
dlls/game/Linklist.h Normal file
View file

@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/Linklist.h $
// $Revision:: 3 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
//
// WARNING: This file is shared between game, cgame and possibly the user interface.
// It is instanced in each one of these directories because of the way that SourceSafe works.
//
#ifndef __linklist_h
#define __linklist_h
#ifdef __cplusplus
extern "C" {
#endif
#define NewNode(type) ((type *)Z_Malloc(sizeof(type)))
#define LL_New(rootnode,type,next,prev) \
{ \
(rootnode) = NewNode(type); \
(rootnode)->prev = (rootnode); \
(rootnode)->next = (rootnode); \
}
#define LL_Add(rootnode, newnode, next, prev) \
{ \
(newnode)->next = (rootnode); \
(newnode)->prev = (rootnode)->prev; \
(rootnode)->prev->next = (newnode); \
(rootnode)->prev = (newnode); \
}
//MED
#define LL_AddFirst(rootnode, newnode, next, prev) \
{ \
(newnode)->prev = (rootnode); \
(newnode)->next = (rootnode)->next; \
(rootnode)->next->prev = (newnode); \
(rootnode)->next = (newnode); \
}
#define LL_Transfer(oldroot,newroot,next,prev) \
{ \
if (oldroot->prev != oldroot) \
{ \
oldroot->prev->next = newroot; \
oldroot->next->prev = newroot->prev; \
newroot->prev->next = oldroot->next; \
newroot->prev = oldroot->prev; \
oldroot->next = oldroot; \
oldroot->prev = oldroot; \
} \
}
#define LL_Reverse(root,type,next,prev) \
{ \
type *newend,*trav,*tprev; \
\
newend = root->next; \
for(trav = root->prev; trav != newend; trav = tprev) \
{ \
tprev = trav->prev; \
LL_Move(trav,newend,next,prev); \
} \
}
#define LL_Remove(node,next,prev) \
{ \
node->prev->next = node->next; \
node->next->prev = node->prev; \
node->next = node; \
node->prev = node; \
}
#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \
{ \
type *hoya; \
\
hoya = rootnode->next; \
while((hoya != rootnode) && (insertnode->sortparm > hoya->sortparm)) \
{ \
hoya = hoya->next; \
} \
LL_Add(hoya,insertnode,next,prev); \
}
#define LL_Move(node,newroot,next,prev) \
{ \
LL_Remove(node,next,prev); \
LL_Add(newroot,node,next,prev); \
}
#define LL_Empty(list,next,prev) \
( \
((list)->next == (list)) && \
((list)->prev == (list)) \
)
#define LL_Free(list) Z_Free(list)
#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list)
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,434 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/MoveRandomDirection.cpp $
// $Revision:: 6 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// MoveRandomDirection Implementation
//
// PARAMETERS:
//
// ANIMATIONS:
//--------------------------------------------------------------------------------
#include "actor.h"
#include "MoveRandomDirection.hpp"
#include <qcommon/gameplaymanager.h>
//--------------------------------------------------------------
//
// Class Declaration and Event Registration
//
//--------------------------------------------------------------
CLASS_DECLARATION( Behavior, MoveRandomDirection, NULL )
{
{ &EV_Behavior_Args, &MoveRandomDirection::SetArgs },
{ NULL, NULL }
};
MoveRandomDirection::MoveRandomDirection()
{
anim = "";
_forever = false;
_faceEnemy = false;
_dist = 1024.0f;
_minDistance = MIN_RANDOM_DIRECTION_DESTINATION;
_mode = RANDOM_MOVE_ANYWHERE;
_forever = false;
_faceEnemy = false;
}
MoveRandomDirection::~MoveRandomDirection()
{
}
//--------------------------------------------------------------
//
// Name: SetArgs()
// Class: MoveRandomDirection
//
// Description: Sets Parameters
//
// Parameters: Event *ev -- Event containing the string
//
// Returns: None
//
//--------------------------------------------------------------
void MoveRandomDirection::SetArgs( Event *ev )
{
int parmCount = ev->NumArgs();
if ( parmCount > 0 ) anim = ev->GetString( 1 );
if ( parmCount > 1 ) SetDistance( ev->GetFloat( 2 ) );
if ( parmCount > 2 ) SetMinDistance( ev->GetFloat( 3 ) );
if ( parmCount > 3 ) SetMode( ev->GetInteger( 4 ) );
if ( parmCount > 4 ) _forever = ev->GetBoolean( 5 );
if ( parmCount > 5 ) _faceEnemy = ev->GetBoolean( 6 );
}
//--------------------------------------------------------------
//
// Name: Begin()
// Class: MoveRandomDirection
//
// Description: Initializes the behavior
//
// Parameters: Actor &self -- The actor executing this behavior
//
// Returns: None
//
//--------------------------------------------------------------
void MoveRandomDirection::Begin( Actor &self )
{
findDestination( self );
if ( _foundGoodDestination )
{
float radius = 16.0f;
if ( _faceEnemy )
self.movementSubsystem->setFaceEnemy( true );
setLegAnim( self );
_chase.SetDistance( radius );
_chase.SetPoint( _destination );
_chase.SetAnim( anim );
_chase.Begin( self );
//Setup Torso Anim if appropriate
if ( !self.torsoBehavior )
setTorsoAnim( self );
}
}
//--------------------------------------------------------------
//
// Name: Evaluate()
// Class: MoveRandomDirection
//
// Description: Update for this behavior -- called every server frame
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: BehaviorReturnCode_t
//
//--------------------------------------------------------------
BehaviorReturnCode_t MoveRandomDirection::Evaluate( Actor &self )
{
BehaviorReturnCode_t result;
if ( !_foundGoodDestination )
{
self.SetAnim( "idle" , NULL , legs );
if ( _forever )
Begin( self );
else
return BEHAVIOR_FAILED;
}
result = _chase.Evaluate( self );
if ( result == BEHAVIOR_SUCCESS )
{
if ( _forever )
Begin( self );
else
return BEHAVIOR_SUCCESS;
}
if ( result != BEHAVIOR_EVALUATING )
{
if ( _forever )
Begin( self );
else
return BEHAVIOR_FAILED;
}
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
//
// Name: End()
// Class: MoveRandomDirection
//
// Description: Ends this behavior -- cleans things up
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: None
//
//--------------------------------------------------------------
void MoveRandomDirection::End(Actor &self)
{
self.SetAnim( "idle" , NULL , legs );
if ( _faceEnemy )
self.movementSubsystem->setFaceEnemy( false );
self.movementSubsystem->setMovingBackwards( false );
}
//--------------------------------------------------------------
// Name: _chooseRandomDirection()
// Class: MoveRandomDirection
//
// Description: Picks a random position Vector based on
// the _mode
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: Vector
//--------------------------------------------------------------
Vector MoveRandomDirection::_chooseRandomDirection(Actor &self)
{
float yaw;
Vector destination;
Vector start;
trace_t trace;
switch ( _mode )
{
case RANDOM_MOVE_IN_FRONT:
yaw = G_Random( 90.0f ) - 45.0f;
break;
case RANDOM_MOVE_IN_BACK:
yaw = G_Random( 90.0f ) - 45.0f;
yaw = AngleNormalize180( yaw + 180);
break;
default:
yaw = G_Random(360.0f);
break;
}
start = self.origin;
start.z += 16.0f;
destination = self.angles;
destination[YAW] = AngleNormalize180(destination[YAW]);
destination[YAW] += yaw;
destination.AngleVectors( &destination );
Vector debug;
debug = self.angles;
debug.AngleVectors ( &debug );
debug *= 296.0f;
debug.z = start.z;
debug += start;
destination *= _dist;
destination += start;
destination.z = start.z;
trace = G_Trace( start , self.mins, self.maxs, destination, &self, self.edict->clipmask, false, "MoveRandomDirection: _chooseRandomDirection" );
Vector size1 = self.mins;
Vector size2 = self.maxs;
Vector actorSize;
size1.z = 0;
size2.z = 0;
actorSize = size2 - size1;
float mungeValue = actorSize.length();
Vector startToDest = trace.endpos - start;
float dist = startToDest.length();
dist-= mungeValue;
startToDest.normalize();
startToDest *= dist;
startToDest = startToDest + start;
//destination = trace.endpos;
destination = startToDest;
//G_DebugLine( start , destination , 1.0 , 1.0 , 1.0 , 1.0);
return destination;
}
//--------------------------------------------------------------
// Name: _getDistanceToDestination()
// Class: MoveRandomDirection
//
// Description: Returns the the distance to the destination
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: float
//--------------------------------------------------------------
float MoveRandomDirection::_getDistanceToDestination(Actor &self)
{
Vector selfToDestination;
selfToDestination = _destination - self.origin;
return selfToDestination.length();
}
//--------------------------------------------------------------
// Name: SetDistance()
// Class: MoveRandomDirection
//
// Description: Mutator
//
// Parameters: float dist
//
// Returns: None
//--------------------------------------------------------------
void MoveRandomDirection::SetDistance( float dist )
{
_dist = dist;
}
//--------------------------------------------------------------
// Name: SetAnim()
// Class: MoveRandomDirection
//
// Description: Mutator
//
// Parameters: const str &moveAnim
//
// Returns: None
//--------------------------------------------------------------
void MoveRandomDirection::SetAnim( const str &moveAnim )
{
anim = moveAnim;
}
//--------------------------------------------------------------
// Name: SetMode()
// Class: MoveRandomDirection
//
// Description: Mutator
//
// Parameters: unsigned int mode
//
// Returns: None
//--------------------------------------------------------------
void MoveRandomDirection::SetMode( unsigned int mode )
{
_mode = mode;
}
//--------------------------------------------------------------
// Name: SetMinDistance()
// Class: MoveRandomDirection
//
// Description: Mutator
//
// Parameters: float dist
//
// Returns: None
//--------------------------------------------------------------
void MoveRandomDirection::SetMinDistance( float dist )
{
_minDistance = dist;
}
void MoveRandomDirection::findDestination( Actor &self )
{
int attempts;
_destination = _chooseRandomDirection(self);
attempts = 0;
_foundGoodDestination = true;
while ( _getDistanceToDestination(self) < _minDistance && attempts < 5 )
{
_destination = _chooseRandomDirection(self);
_foundGoodDestination = false;
attempts += 1;
if ( _getDistanceToDestination(self) > _minDistance )
_foundGoodDestination = true;
}
}
void MoveRandomDirection::setLegAnim( Actor &self )
{
str newAnim;
if ( _faceEnemy )
{
Vector selfToDestinationAngles = _destination - self.origin;
Vector animAngles = self.movementSubsystem->getAnimDir();
float yawDiff;
selfToDestinationAngles = selfToDestinationAngles.toAngles();
animAngles = animAngles.toAngles();
yawDiff = AngleNormalize180(selfToDestinationAngles[YAW] - animAngles[YAW] );
if ( yawDiff >= -25.0 && yawDiff <= 25.0 )
{
newAnim = self.combatSubsystem->GetAnimForMyWeapon( "CombatWalk" );
}
if ( yawDiff >= -135.0 && yawDiff <= -25.0 )
{
newAnim = self.combatSubsystem->GetAnimForMyWeapon( "CombatRStrafe" );
}
if ( yawDiff >= 25.0 && yawDiff <= 135.0f )
{
newAnim = self.combatSubsystem->GetAnimForMyWeapon( "CombatLStrafe" );
}
if ( yawDiff >= 135.0 && yawDiff <= 180.0f )
{
newAnim = self.combatSubsystem->GetAnimForMyWeapon( "CombatBackpedal" );
self.movementSubsystem->setMovingBackwards( true );
}
if ( yawDiff <= -135.0 && yawDiff >= -180.0 )
{
newAnim = self.combatSubsystem->GetAnimForMyWeapon( "CombatBackpedal" );
self.movementSubsystem->setMovingBackwards( true );
}
}
if ( newAnim.length() )
anim = newAnim;
}
void MoveRandomDirection::setTorsoAnim( Actor &self )
{
if ( self.enemyManager->HasEnemy() )
_torsoAnim = self.combatSubsystem->GetAnimForMyWeapon( "CombatGunIdle" );
else
_torsoAnim = self.combatSubsystem->GetAnimForMyWeapon( "IdleGunIdle" );
if ( _torsoAnim.length() )
{
self.SetAnim( _torsoAnim, NULL , torso );
}
}

View file

@ -0,0 +1,123 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/MoveRandomDirection.hpp $
// $Revision:: 169 $
// $Author:: sketcher $
// $Date:: 4/26/02 2:22p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// MoveRandomDirection Behavior Definition
//
//--------------------------------------------------------------------------------
//==============================
// Forward Declarations
//==============================
class MoveRandomDirection;
#ifndef __MOVE_RANDOM_DIRECTION___
#define __MOVE_RANDOM_DIRECTION___
#include "behavior.h"
#include "behaviors_general.h"
#define MIN_RANDOM_DIRECTION_DESTINATION 64.0f
//------------------------- CLASS ------------------------------
//
// Name: MoveRandomDirection
// Base Class: Behavior
//
// Description: A replacement for Wander -- Utilizes fewer traces
//
// Method of Use: Called From State Machine
//--------------------------------------------------------------
class MoveRandomDirection : public Behavior
{
public:
typedef enum
{
RANDOM_MOVE_ANYWHERE,
RANDOM_MOVE_IN_FRONT,
RANDOM_MOVE_IN_BACK,
} randomMoveModes_t;
private: // Parameters
str anim;
protected:
Vector _chooseRandomDirection ( Actor &self );
float _getDistanceToDestination ( Actor &self );
void findDestination ( Actor &self );
void setLegAnim ( Actor &self );
void setTorsoAnim ( Actor &self );
public:
CLASS_PROTOTYPE( MoveRandomDirection );
MoveRandomDirection();
~MoveRandomDirection();
void SetArgs( Event *ev );
void Begin( Actor &self );
BehaviorReturnCode_t Evaluate( Actor &self );
void End( Actor &self );
virtual void Archive( Archiver &arc );
// Accessors
void SetDistance( float dist );
void SetMinDistance( float dist );
void SetAnim( const str &moveAnim );
void SetMode( unsigned int mode );
private:
GotoPoint _chase;
Vector _destination;
unsigned int _mode;
float _dist;
float _minDistance;
float _nextChangeTime;
bool _foundGoodDestination;
bool _forever;
bool _faceEnemy;
str _torsoAnim;
};
inline void MoveRandomDirection::Archive( Archiver &arc )
{
Behavior::Archive( arc );
// Archive Parameters
arc.ArchiveString( &anim );
// Archive Components
arc.ArchiveObject( &_chase );
// Archive Member Vars
arc.ArchiveVector( &_destination );
arc.ArchiveUnsigned( &_mode );
arc.ArchiveFloat( &_dist );
arc.ArchiveFloat( &_minDistance );
arc.ArchiveFloat( &_nextChangeTime );
arc.ArchiveBool( &_foundGoodDestination );
arc.ArchiveBool( &_forever );
arc.ArchiveBool( &_faceEnemy );
arc.ArchiveString( &_torsoAnim );
}
#endif /* __MOVE_RANDOM_DIRECTION___ */

442
dlls/game/PlayAnim.cpp Normal file
View file

@ -0,0 +1,442 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/PlayAnim.cpp $
// $Revision:: 7 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// PlayAnim Implementation
//
// PARAMETERS:
//
//
// ANIMATIONS:
//
//--------------------------------------------------------------------------------
#include "actor.h"
#include "PlayAnim.hpp"
//--------------------------------------------------------------
//
// Class Declaration and Event Registration
//
//--------------------------------------------------------------
CLASS_DECLARATION( Behavior, PlayAnim, NULL )
{
{ &EV_Behavior_Args, &PlayAnim::SetArgs },
{ NULL, NULL }
};
//--------------------------------------------------------------
// Name: PlayAnim()
// Class: PlayAnim
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
PlayAnim::PlayAnim()
{
_legAnim = "idle";
_torsoAnim = "";
_minTime = 0.0f;
_maxTime = 0.0f;
_endTime = 0.0f;
}
//--------------------------------------------------------------
// Name: ~PlayAnim()
// Class: PlayAnim
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
PlayAnim::~PlayAnim()
{
}
//--------------------------------------------------------------
//
// Name: SetArgs()
// Class: PlayAnim
//
// Description:
//
// Parameters: Event *ev -- Event containing the string
//
// Returns: None
//
//--------------------------------------------------------------
void PlayAnim::SetArgs( Event *ev )
{
_legAnim = ev->GetString( 1 );
if ( ev->NumArgs() > 1 ) _torsoAnim = ev->GetString( 2 );
if ( ev->NumArgs() > 2 ) _minTime = ev->GetFloat( 3 );
if ( ev->NumArgs() > 3 ) _maxTime = ev->GetFloat( 4 );
}
//--------------------------------------------------------------
//
// Name: Begin()
// Class: PlayAnim
//
// Description: Initializes the behavior
//
// Parameters: Actor &self -- The actor executing this behavior
//
// Returns: None
//
//--------------------------------------------------------------
void PlayAnim::Begin( Actor &self )
{
init( self );
}
//--------------------------------------------------------------
//
// Name: Evaluate()
// Class: PlayAnim
//
// Description: Update for this behavior -- called every server frame
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: BehaviorReturnCode_t
//
//--------------------------------------------------------------
BehaviorReturnCode_t PlayAnim::Evaluate( Actor &self )
{
BehaviorReturnCode_t stateResult;
think();
switch ( _state )
{
//---------------------------------------------------------------------
case PLAYANIM_SETUP:
//---------------------------------------------------------------------
stateResult = evaluateStateSetup();
if ( stateResult == BEHAVIOR_SUCCESS )
transitionToState( PLAYANIM_ANIMATE );
break;
//---------------------------------------------------------------------
case PLAYANIM_ANIMATE:
//---------------------------------------------------------------------
stateResult = evaluateStateAnimate();
if ( stateResult == BEHAVIOR_SUCCESS )
transitionToState( PLAYANIM_SUCCESS );
break;
//---------------------------------------------------------------------
case PLAYANIM_SUCCESS:
//---------------------------------------------------------------------
return BEHAVIOR_SUCCESS;
break;
//---------------------------------------------------------------------
case PLAYANIM_FAILED:
//---------------------------------------------------------------------
return BEHAVIOR_FAILED;
break;
}
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
//
// Name: End()
// Class: PlayAnim
//
// Description: Ends this behavior -- cleans things up
//
// Parameters: Actor &self -- Actor executing this behavior
//
// Returns: None
//
//--------------------------------------------------------------
void PlayAnim::End(Actor &self)
{
self.RemoveAnimDoneEvent();
}
//--------------------------------------------------------------
// Name: transitionToState()
// Class: CloseInOnEnemy
//
// Description: Transitions the behaviors state
//
// Parameters: coverCombatStates_t state -- The state to transition to
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::transitionToState( PlayAnimStates_t state )
{
switch( state )
{
case PLAYANIM_SETUP:
setInternalState( state , "PLAYANIM_SETUP" );
setupStateSetup();
break;
case PLAYANIM_ANIMATE:
setInternalState( state , "PLAYANIM_ANIMATE" );
setupStateAnimate();
break;
case PLAYANIM_SUCCESS:
setInternalState( state , "PLAYANIM_SUCCESS" );
break;
case PLAYANIM_FAILED:
setInternalState( state , "PLAYANIM_FAILED" );
break;
}
}
//--------------------------------------------------------------
// Name: setInternalState()
// Class: PlayAnim
//
// Description: Sets the internal state of the behavior
//
// Parameters: unsigned int state
// const str &stateName
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::setInternalState( PlayAnimStates_t state , const str &stateName )
{
_state = state;
SetInternalStateName( stateName );
}
//--------------------------------------------------------------
// Name: init()
// Class: PlayAnim
//
// Description: Initializes the behavior
//
// Parameters: Actor &self
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::init( Actor &self )
{
str legAnim, torsoAnim;
ScriptVariable *var = NULL;
//Check for State Var's first
legAnim = self.GetStateVar( _legAnim );
if ( legAnim.length() )
_legAnim = legAnim;
torsoAnim = self.GetStateVar( _torsoAnim );
if ( torsoAnim.length() )
_torsoAnim = torsoAnim;
var = self.entityVars.GetVariable( _legAnim );
if ( var )
{
legAnim = var->stringValue();
if ( legAnim.length() )
_legAnim = legAnim;
}
var = self.entityVars.GetVariable( _torsoAnim );
if ( var )
{
torsoAnim = var->stringValue();
if ( torsoAnim.length() )
_torsoAnim = torsoAnim;
}
transitionToState(PLAYANIM_SETUP);
}
//--------------------------------------------------------------
// Name: think()
// Class: PlayAnim
//
// Description: Does any processing required before evaluating states
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::think()
{
}
//--------------------------------------------------------------
// Name: setupStateSetup()
// Class: PlayAnim
//
// Description: Sets up State
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::setupStateSetup()
{
if ( _minTime )
_endTime = level.time + _minTime;
if ( _maxTime )
_endTime = _endTime + G_Random( _maxTime - _minTime );
if ( _legAnim.length() )
{
if ( !_endTime )
{
if ( !GetSelf()->SetAnim( _legAnim, EV_Actor_EndBehavior ) )
{
GetSelf()->PostEvent( EV_Actor_EndBehavior, 0.0f );
}
}
else
{
if ( !GetSelf()->SetAnim( _legAnim, NULL ) )
{
GetSelf()->PostEvent( EV_Actor_EndBehavior, 0.0f );
}
}
GetSelf()->ClearTorsoAnim();
}
if ( _torsoAnim.length() )
{
if ( !_endTime )
{
if ( !GetSelf()->SetAnim( _torsoAnim, EV_Actor_EndBehavior ) )
{
GetSelf()->PostEvent( EV_Actor_EndBehavior, 0.0f );
}
}
else
{
if ( !GetSelf()->SetAnim( _torsoAnim, NULL ) )
{
GetSelf()->PostEvent( EV_Actor_EndBehavior, 0.0f );
}
}
}
}
//--------------------------------------------------------------
// Name: evaluateStateApproach()
// Class: PlayAnim
//
// Description: Evaluates State
//
// Parameters: None
//
// Returns: BehaviorReturnCode_t
//--------------------------------------------------------------
BehaviorReturnCode_t PlayAnim::evaluateStateSetup()
{
return BEHAVIOR_SUCCESS;
}
//--------------------------------------------------------------
// Name: failureStateApproach()
// Class: PlayAnim
//
// Description: Failure Handler for State
//
// Parameters: const str &failureReason
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::failureStateSetup( const str& failureReason )
{
}
//--------------------------------------------------------------
// Name: setupStateSetup()
// Class: PlayAnim
//
// Description: Sets up State
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::setupStateAnimate()
{
}
//--------------------------------------------------------------
// Name: evaluateStateApproach()
// Class: PlayAnim
//
// Description: Evaluates State
//
// Parameters: None
//
// Returns: BehaviorReturnCode_t
//--------------------------------------------------------------
BehaviorReturnCode_t PlayAnim::evaluateStateAnimate()
{
if ( _endTime )
{
if ( level.time >= _endTime )
return BEHAVIOR_SUCCESS;
}
return BEHAVIOR_EVALUATING;
}
//--------------------------------------------------------------
// Name: failureStateApproach()
// Class: PlayAnim
//
// Description: Failure Handler for State
//
// Parameters: const str &failureReason
//
// Returns: None
//--------------------------------------------------------------
void PlayAnim::failureStateAnimate( const str& failureReason )
{
}

137
dlls/game/PlayAnim.hpp Normal file
View file

@ -0,0 +1,137 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/PlayAnim.hpp $
// $Revision:: 169 $
// $Author:: sketcher $
// $Date:: 4/26/02 2:22p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// CloseInOnEnemyWhileFiringWeapon Behavior Definition
//
//--------------------------------------------------------------------------------
//==============================
// Forward Declarations
//==============================
class PlayAnim;
#ifndef __PLAY_ANIM_HPP__
#define __PLAY_ANIM_HPP__
#include "behavior.h"
#include "behaviors_general.h"
//------------------------- CLASS ------------------------------
//
// Name: CloseInOnEnemyWhileFiringWeapon
// Base Class: Behavior
//
// Description: Makes the actor move closer to its current enemy
//
// Method of Use: Called From State Machine
//--------------------------------------------------------------
class PlayAnim : public Behavior
{
//------------------------------------
// States
//------------------------------------
public:
typedef enum
{
PLAYANIM_SETUP,
PLAYANIM_ANIMATE,
PLAYANIM_SUCCESS,
PLAYANIM_FAILED
} PlayAnimStates_t;
//------------------------------------
// Parameters
//------------------------------------
private:
str _legAnim;
str _torsoAnim;
float _minTime;
float _maxTime;
//-------------------------------------
// Internal Functionality
//-------------------------------------
protected:
void transitionToState ( PlayAnimStates_t state );
void setInternalState ( PlayAnimStates_t state , const str &stateName );
void init ( Actor &self );
void think ();
void setupStateSetup ();
BehaviorReturnCode_t evaluateStateSetup ();
void failureStateSetup ( const str& failureReason );
void setupStateAnimate ();
BehaviorReturnCode_t evaluateStateAnimate ();
void failureStateAnimate ( const str& failureReason );
//-------------------------------------
// Public Interface
//-------------------------------------
public:
CLASS_PROTOTYPE( PlayAnim );
PlayAnim();
~PlayAnim();
void SetArgs ( Event *ev );
void Begin ( Actor &self );
BehaviorReturnCode_t Evaluate ( Actor &self );
void End ( Actor &self );
virtual void Archive ( Archiver &arc );
void setAnim ( const str &animName ) { _legAnim = animName; }
void setTorsoAnim( const str &animName ) { _torsoAnim = animName; }
void setMinTime ( float minTime ) { _minTime = minTime; }
void setMaxTime ( float maxTime ) { _maxTime = maxTime; }
//-------------------------------------
// Components
//-------------------------------------
//-------------------------------------
// Member Variables
//-------------------------------------
private:
PlayAnimStates_t _state;
float _endTime;
};
inline void PlayAnim::Archive( Archiver &arc )
{
Behavior::Archive( arc );
// Archive Parameters
arc.ArchiveString ( &_legAnim );
arc.ArchiveString ( &_torsoAnim );
arc.ArchiveFloat ( &_minTime );
arc.ArchiveFloat ( &_maxTime);
// Archive Components
// Archive Member Variables
ArchiveEnum ( _state, PlayAnimStates_t );
arc.ArchiveFloat ( &_endTime );
}
#endif /* __PLAY_ANIM_HPP__ */

122
dlls/game/PlayerStart.cpp Normal file
View file

@ -0,0 +1,122 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/PlayerStart.cpp $
// $Revision:: 7 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Player start location entity declarations
//
#include "_pch_cpp.h"
#include "entity.h"
#include "trigger.h"
#include "PlayerStart.h"
/*****************************************************************************/
/*QUAKED info_player_start (0.75 0.75 0) (-16 -16 0) (16 16 96)
The normal starting point for a level.
"angle" - the direction the player should face
"thread" - the thread that should be called when spawned at this position
******************************************************************************/
Event EV_PlayerStart_SetThread
(
"thread",
EV_SCRIPTONLY,
"s",
"thread",
"Set the thread to execute when this player start is used"
);
CLASS_DECLARATION( Entity, PlayerStart, "info_player_start" )
{
{ &EV_SetAngle, &PlayerStart::SetAngle },
{ &EV_PlayerStart_SetThread, &PlayerStart::SetThread },
{ NULL, NULL }
};
void PlayerStart::SetAngle( Event *ev )
{
angles = Vector( 0.0f, ev->GetFloat( 1 ), 0.0f );
}
void PlayerStart::SetThread( Event *ev )
{
thread = ev->GetString( 1 );
}
str PlayerStart::getThread( void )
{
return thread;
}
/*****************************************************************************/
/* saved out by quaked in region mode
******************************************************************************/
CLASS_DECLARATION( PlayerStart, TestPlayerStart, "testplayerstart" )
{
{ NULL, NULL }
};
/*****************************************************************************/
/*QUAKED info_player_deathmatch (0.75 0.75 1) (-16 -16 0) (16 16 96)
potential spawning position for deathmatch games
"angle" - the direction the player should face
"thread" - the thread that should be called when spawned at this position
"spawnpoint_type" - the named type of this spawnpoint
******************************************************************************/
Event EV_PlayerDeathmatchStart_SetType
(
"spawnpoint_type",
EV_DEFAULT,
"s",
"spawnpointType",
"Sets the named type of this spawnpoint"
);
CLASS_DECLARATION( PlayerStart, PlayerDeathmatchStart, "info_player_deathmatch" )
{
{ &EV_PlayerDeathmatchStart_SetType, &PlayerDeathmatchStart::SetType },
{ NULL, NULL }
};
void PlayerDeathmatchStart::SetType( Event *ev )
{
_type = ev->GetString( 1 );
}
/*****************************************************************************/
/*QUAKED info_player_intermission (0.75 0.75 0) (-16 -16 0) (16 16 96)
viewing point in between deathmatch levels
******************************************************************************/
CLASS_DECLARATION( Camera, PlayerIntermission, "info_player_intermission" )
{
{ NULL, NULL }
};
PlayerIntermission::PlayerIntermission()
{
currentstate.watch.watchPath = false;
}

74
dlls/game/PlayerStart.h Normal file
View file

@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/PlayerStart.h $
// $Revision:: 4 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Player start location entity declarations
//
#ifndef __PLAYERSTART_H__
#define __PLAYERSTART_H__
#include "g_local.h"
#include "entity.h"
#include "camera.h"
#include "navigate.h"
class PlayerStart : public Entity
{
private:
str thread;
public:
CLASS_PROTOTYPE( PlayerStart );
void SetAngle( Event *ev );
void SetThread( Event *ev );
str getThread( void );
virtual void Archive(Archiver &arc);
};
inline void PlayerStart::Archive (Archiver &arc)
{
Entity::Archive( arc );
arc.ArchiveString(&thread);
}
class TestPlayerStart : public PlayerStart
{
public:
CLASS_PROTOTYPE( TestPlayerStart );
};
class PlayerDeathmatchStart : public PlayerStart
{
private:
void SetType( Event *ev );
public:
str _type;
PlayerDeathmatchStart() {};
CLASS_PROTOTYPE( PlayerDeathmatchStart );
};
class PlayerIntermission : public Camera
{
public:
CLASS_PROTOTYPE( PlayerIntermission );
PlayerIntermission();
};
#endif /* PlayerStart.h */

1169
dlls/game/RageAI.cpp Normal file

File diff suppressed because it is too large Load diff

245
dlls/game/RageAI.h Normal file
View file

@ -0,0 +1,245 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/RageAI.h $
// $Revision:: 30 $
// $Author:: Steven $
// $Date:: 10/13/03 8:54a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// The Rage AI System, will house several components that will make the AI function
// such as the Strategos, Personality, etc...
//
//============================
// Forward Declarations
//============================
class Strategos;
class DefaultStrategos;
class PackageManager;
class Personality;
#ifndef __RAGE_AI_H__
#define __RAGE_AI_H__
#include "actor.h"
#include "actorincludes.h"
#include "characterstate.h"
#include "script.h"
//============================
// Global Functions
//============================
void FillBehaviorPackageList( void );
void ClearBehaviorPackageList( void );
//============================
// Class Strategos
//============================
//
// Handles all strategic thinking for the actor
// This will get more complicated as the AI gets more
// sophisticated
//
class Strategos
{
public:
Strategos() { }
Strategos( Actor *act ) { }
virtual ~Strategos() { }
virtual void Evaluate() { }
virtual void NotifySightStatusChanged ( Entity *enemy , qboolean canSee ) { }
virtual void NotifyDamageChanged( Entity *enemy , float damage ) { }
virtual void Attack ( Entity *enemy ) { }
virtual void DoArchive( Archiver &arc , Actor *act );
/* virtual */ void Archive( Archiver &arc );
virtual void SetBehaviorPackage( const str &packageName ) { }
virtual float GetCheckYawMin() { assert( 0 ); return 0; }
virtual float GetCheckYawMax() { assert( 0 ); return 0; }
virtual float GetCheckInConeDistMax() { assert( 0 ); return 0; }
virtual void SetCheckInConeDistMax( float distance ) { assert( 0 ); }
//Accessors and Mutators
void SetEvaluateInterval( float interval ) { _evaluateInterval = interval; }
float GetEvaluateInterval() { return _evaluateInterval; }
void SetNextEvaluateTime( float time ) { _nextEvaluateTime = time; }
float GetNextEvaluateTime() { return _nextEvaluateTime; }
void SetSightBasedHate( float hate ) { _sightBasedHate = hate; }
float GetSightBasedHate() { return _sightBasedHate; }
private:
float _sightBasedHate;
float _nextEvaluateTime;
float _evaluateInterval;
};
//============================
// Class DefaultStrategos
//============================
//
// The Strategos supplied by default. All actors get this
// in construction. As additional subclasses are added
// events will be put into place in Actor that will allow
// the specification of the strategos to use from the TIKI file
//
class DefaultStrategos : public Strategos
{
public:
DefaultStrategos();
DefaultStrategos( Actor *act );
~DefaultStrategos();
void Evaluate();
void NotifySightStatusChanged ( Entity *enemy , qboolean canSee );
void NotifyDamageChanged( Entity *enemy, float damage );
void SetBehaviorPackage( const str &packageName );
float GetCheckYawMin();
float GetCheckYawMax();
float GetCheckInConeDistMax();
void SetCheckInConeDistMax( float distance );
void Attack ( Entity *enemy );
void DoArchive ( Archiver &arc, Actor *actor );
/* virtual */ void Archive( Archiver &arc );
private: // Functions
void _EvaluateEnemies();
void _EvaluatePackages();
void _EvaluateWorld();
void _CheckForInTheWay();
void _CheckForInConeOfFire();
private: // Member Variables
Actor *act;
float _checkYawMin;
float _checkYawMax;
float _checkInConeDistMax;
};
//============================
// PackageManager
//============================
//
// Handles behavior packages. It should be noted that, if an
// actor has a statemap, but no fuzzyengine, then it will just execute
// the specified statemap. A fuzzyengine MUST be supplied if the actor
// is going to take advantage of the PackageManager.
//
class PackageManager
{
public:
PackageManager();
PackageManager( Actor *actor );
~PackageManager();
void RegisterPackage( const str &packageName );
void UnregisterPackage( const str &packageName );
void EvaluatePackages( FuzzyEngine *fEngine );
int GetHighestScoringPackage();
int GetCurrentFVarIndex();
float GetCurrentFVarLastExecuteTime();
void SetLastExecutionTime(int packageIndex);
void UpdateCurrentPackageIndex( int packageIndex );
int GetPackageIndex( const str &packageName );
str GetCurrentPackageName();
void DoArchive( Archiver &arc , Actor *actor );
private: // Member Variables
Actor *act;
Container<BehaviorPackageEntry_t> _BehaviorPackages;
int _currentFVarIndex;
float _currentFVarLastExecuteTime;
int _currentPackageIndex;
};
//============================
// Class Personality
//============================
//
// Stores Personality Measures. Now, you maybe asking why am I making
// a full blown class if all I'm doing is storing data. Well, I'm setting
// this up for future expansion, so when I realize I need this class do something
// to the data its storing, it won't be a huge pain to make that happen
//
class Personality
{
public:
Personality();
Personality( Actor *actor );
~Personality();
void SetBehaviorTendency( const str& packageName , float tendency );
void SetTendency ( const str& tendencyName , float tendencyValue );
qboolean WantsToExecuteCurrentPackage(float interval);
qboolean ExecutedPackageInLastTimeFrame(float interval);
void SetAggressiveness( float aggressiveness );
float GetAggressiveness();
void SetTalkiness( float talkiness );
float GetTalkiness();
float GetTendency( const str& tendencyName );
virtual void Archive( Archiver &arc );
void DoArchive ( Archiver &arc, Actor *actor );
protected: // Member Functions
float _clampValue( float value );
qboolean _wantsToExecutePackage(PackageTendency_t *tendency);
private: // Emotions and Tendencies
float _aggressiveness;
float _talkiness;
float _anger;
float _fear;
// Package Tendencies
Container<PackageTendency_t> _PackageTendencies;
Container<Tendency_t> _Tendencies;
private: // Member Variables
Actor *act;
};
#endif /* __RAGE_AI_H__ */

43
dlls/game/UseData.cpp Normal file
View file

@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/UseData.cpp $
// $Revision:: 4 $
// $Author:: Steven $
// $Date:: 5/20/02 3:53p $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// UseDataObject
//
#include "_pch_cpp.h"
//#include "g_local.h"
#include "UseData.h"
//--------------------------------------------------------------
//
// Name: useMe
// Class: UseData
//
// Description: Local notification that this entity has been
// used. Needed to decrement use counter.
//
// Parameters: None
//
// Returns: None
//
//--------------------------------------------------------------
void UseData::useMe()
{
if ( _useCount == -1 )
return;
_useCount--;
}

96
dlls/game/UseData.h Normal file
View file

@ -0,0 +1,96 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/UseData.h $
// $Revision:: 5 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// UseDataObject
//
// UseData.h: interface for the UseData class.
//
//////////////////////////////////////////////////////////////////////
class UseData;
#ifndef __USEDATA_H__
#define __USEDATA_H__
#include "g_local.h"
//------------------------- CLASS ------------------------------
//
// Name: UseData
// Base Class: Class
//
// Description: Stores information about how to use this entity
//
// Method of Use: There is a pointer to this class in Entity,
// NULL by default. If this class is allocated,
// it is assumed that this entity can be "used"
// When used, it plays _useAnim on the player,
// calls _useThread in the script. Displays
// _useType icon in the HUD.
//--------------------------------------------------------------
class UseData : public Class
{
private:
str _useAnim;
str _useThread;
str _useType;
float _useMaxDist;
int _useCount;
public:
UseData::UseData()
:_useAnim(""),
_useType(""),
_useThread(""),
_useMaxDist(64.0f),
_useCount(-1)
{ }
~UseData() { }
const str& getUseAnim() { return _useAnim; }
const str& getUseThread() { return _useThread; }
const str& getUseType() { return _useType; }
float getUseMaxDist() { return _useMaxDist; }
int getUseCount() { return _useCount; }
void setUseAnim(const str& newanim) { _useAnim = newanim; }
void setUseThread(const str& newthread) { _useThread = newthread; }
void setUseType(const str& newtype) { _useType = newtype; }
void setUseMaxDist(float newdist) { _useMaxDist = newdist; }
void setUseCount(float newcount) { _useCount = (int)newcount; }
void useMe();
void Archive(Archiver &arc);
};
inline void UseData::Archive(Archiver &arc)
{
Class::Archive( arc );
arc.ArchiveString( &_useAnim );
arc.ArchiveString( &_useThread );
arc.ArchiveString( &_useType );
arc.ArchiveFloat( &_useMaxDist );
arc.ArchiveInteger( &_useCount );
}
#endif // __USEDATA_H__

View file

@ -0,0 +1,145 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/WeaponDualWield.cpp $
// $Revision:: 6 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
#include "WeaponDualWield.h"
#include <qcommon/gameplaymanager.h>
CLASS_DECLARATION( Weapon, WeaponDualWield, NULL )
{
{ &EV_Anim, &WeaponDualWield::PassToAnimate },
{ &EV_NewAnim, &WeaponDualWield::PassToAnimate },
{ NULL, NULL }
};
WeaponDualWield::WeaponDualWield()
: _leftweapon(0),
_rightweapon(0)
{
}
WeaponDualWield::~WeaponDualWield()
{
}
//--------------------------------------------------------------
//
// Name: AttachToOwner
// Class: WeaponDualWield
//
// Description: Attach to the owner.
//
// Parameters: weaponhand_t hand -- hand
//
// Returns: None
//
//--------------------------------------------------------------
void WeaponDualWield::AttachToOwner( weaponhand_t hand )
{
_leftweapon->SetOwner(owner);
_rightweapon->SetOwner(owner);
_leftweapon->AttachGun( WEAPON_LEFT );
_rightweapon->AttachGun( WEAPON_RIGHT );
_rightweapon->ForceIdle();
_leftweapon->ForceIdle();
}
//--------------------------------------------------------------
//
// Name: processGameplayData
// Class: WeaponDualWield
//
// Description: Process gameplay data
//
// Parameters: Event *ev -- not used
//
// Returns: None
//
//--------------------------------------------------------------
void WeaponDualWield::processGameplayData( Event *ev )
{
ClassDef *cls;
GameplayManager *gpm = GameplayManager::getTheGameplayManager();
if ( !gpm->hasObject(getArchetype()) )
return;
str leftmodel = gpm->getStringValue(getArchetype(), "leftmodel");
str rightmodel = gpm->getStringValue(getArchetype(), "rightmodel");
if ( !_leftweapon )
{
cls = getClass( leftmodel );
if ( !cls )
{
SpawnArgs args;
args.setArg( "model", leftmodel );
cls = args.getClassDef();
if ( !cls )
return;
}
_leftweapon = ( Weapon * )cls->newInstance();
_leftweapon->setModel( leftmodel );
_leftweapon->ProcessPendingEvents();
_leftweapon->hideModel();
}
if ( !_rightweapon )
{
cls = getClass( rightmodel );
if ( !cls )
{
SpawnArgs args;
args.setArg( "model", rightmodel );
cls = args.getClassDef();
if ( !cls )
return;
}
_rightweapon = ( Weapon * )cls->newInstance();
_rightweapon->setModel( rightmodel );
_rightweapon->ProcessPendingEvents();
_rightweapon->hideModel();
}
// Process gameplay data on myself.
Weapon::processGameplayData( NULL );
}
//===============================================================
// Name: PassToAnimate
// Class: WeaponDualWield
//
// Description: Passes animation events on to both the left
// and right weapons.
//
// Parameters: Event* -- the event to pass on.
//
// Returns: None
//
//===============================================================
void WeaponDualWield::PassToAnimate( Event *ev )
{
if ( _leftweapon )
{
Event *leftEvent = new Event( ev );
_leftweapon->ProcessEvent( leftEvent );
}
if ( _rightweapon )
{
Event *rightEvent = new Event( ev );
_rightweapon->ProcessEvent( rightEvent );
}
}

View file

@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/WeaponDualWield.h $
// $Revision:: 5 $
// $Author:: Steven $
// $Date:: 10/11/02 4:05a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
class WeaponDualWield;
#ifndef __WEAPONDUALWIELD_H__
#define __WEAPONDUALWIELD_H__
#include "g_local.h"
#include "item.h"
#include "ammo.h"
#include "sentient.h"
#include "weapon.h"
class WeaponDualWield : public Weapon
{
private:
Weapon *_leftweapon;
Weapon *_rightweapon;
protected:
void PassToAnimate( Event *ev );
public:
CLASS_PROTOTYPE( WeaponDualWield );
WeaponDualWield();
~WeaponDualWield();
Weapon* getRightWeapon() { return _rightweapon; }
Weapon* getLeftWeapon() { return _leftweapon; }
void processGameplayData( Event *ev );
virtual void AttachToOwner( weaponhand_t hand );
void Archive( Archiver &arc );
};
inline void WeaponDualWield::Archive( Archiver &arc )
{
Weapon::Archive( arc );
arc.ArchiveObjectPointer( (Class **)&_leftweapon );
arc.ArchiveObjectPointer( (Class **)&_rightweapon );
}
#endif

22
dlls/game/_pch_cpp.cpp Normal file
View file

@ -0,0 +1,22 @@
//---------------------------------------------------------------------------
// _pch_cpp.cpp
//
// Precompiled header prototype source file for Game module.
//
// NOTE: Precompiled headers may not mix C with C++ files; this
// is the CPP version for the module.
//
// In this module's Project Settings -> C++ -> Precompiled Headers,
// the file _PCH_CPP.C should be set to:
// Create precompiled header file (.pch)
// Through header: _pch_cpp.h
//
// All other C++ files in the project should be set to:
// Use precompiled header file (.pch)
// Through header: _pch_cpp.h
//---------------------------------------------------------------------------
#include "_pch_cpp.h"

25
dlls/game/_pch_cpp.h Normal file
View file

@ -0,0 +1,25 @@
//---------------------------------------------------------------------------
// _pch_cpp.h
//
// Precompiled header for Game module.
//
// NOTE: Precompiled headers may not mix C with C++ files; this
// is the CPP version for the module.
//
// In this module's Project Settings -> C++ -> Precompiled Headers,
// the file _PCH_CPP.C should be set to:
// Create precompiled header file (.pch)
// Through header: _pch_cpp.h
//
// All other C++ files in the project should be set to:
// Use precompiled header file (.pch)
// Through header: _pch_cpp.h
//---------------------------------------------------------------------------
#include "g_local.h"
#include "actor.h"
#include "player.h"
#include "entity.h"
#include "object.h"

19685
dlls/game/actor.cpp Normal file

File diff suppressed because it is too large Load diff

1531
dlls/game/actor.h Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_combatsubsystem.h $
// $Revision:: 21 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Combat Related Classes
//
class CombatSubsystem;
#ifndef __ACTOR_COMBAT_SUBSYSTEM_H__
#define __ACTOR_COMBAT_SUBSYSTEM_H__
#include "actor.h"
#include "actorincludes.h"
#include "weapon.h"
//============================
// Class CombatSubsystem
//============================
//
// Encapsulates combat related data and functionality for the actor
//
class CombatSubsystem
{
public:
CombatSubsystem();
CombatSubsystem( Actor *actor );
~CombatSubsystem();
bool CanAttackTarget ( Entity *target );
bool CanAttackTargetFrom ( Entity *target , const Vector &startPos );
bool IsTargetInWeaponRange ( Entity *target );
bool UsingWeaponNamed ( const str &weaponName );
bool WeaponIsFireType ( firetype_t fire_type );
bool HaveWeapon ();
bool CanAttackEnemy ();
void UseActorWeapon (const str &weaponName , weaponhand_t hand );
void SetTraceInterval ( float interval );
void FireWeapon ();
void StopFireWeapon ();
void AimWeaponTag (Entity *target);
void AimWeaponTag (const Vector &targetPos);
void ClearAim ();
void GetGunPositionData ( Vector *pos , Vector *forward = NULL, Vector *right = NULL, Vector *up = NULL );
float GetAimGunYaw ( const Vector &target );
float GetAimGunPitch ( const Vector &target );
WeaponPtr GetBestAvailableWeapon ( Entity *target );
float GetActiveWeaponPowerRating ( Entity *target );
str GetActiveWeaponName ();
str GetActiveWeaponArchetype();
bool GetProjectileLaunchAngles( Vector &launchAngles, const Vector &launchPoint, const float initialSpeed, const float gravity , const bool useHighTrajectory = false ) const;
bool shouldArcProjectile();
float GetLowArcRange();
void OverrideSpread ( float spreadX , float spreadY );
const str GetAnimForMyWeapon( const str& property );
float GetDataForMyWeapon( const str& property );
Vector GetLeadingTargetPos( float projSpeed , Vector originalTargetPos , Entity *target );
// Archiving
void DoArchive ( Archiver &arc , Actor *actor );
virtual void Archive ( Archiver &arc );
protected:
void _init();
bool _traceHitTarget ( Entity *target , const Vector &startPos );
float getModifiedPowerRating ( Entity *target , Weapon *weapon );
private:
ActiveWeapon _activeWeapon;
float _nextTimeTracedToTarget;
float _traceInterval;
bool _canShootTarget;
float _yawDiff;
Actor *act;
};
#endif /* __ACTOR_COMBAT_SUBSYSTEM_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,120 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_enemymanager.h $
// $Revision:: 16 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// EnemyManager class for Actors -- Handles all the hatelist management
//
class EnemyManager;
#ifndef __ACTOR_ENEMYMANAGER_H__
#define __ACTOR_ENEMYMANAGER_H__
#include "actor.h"
#include "actorincludes.h"
#include "weapon.h"
//============================
// Class EnemyManager
//============================
//
// Class used to handle all enemy management by actors.
//
// Notes:
// _currentEnemy and _alternateTarget -- _currentEnemy should always be used to
// house the Sentient ( i.e. Actor or Player ) at the top of the hatelist.
// _alternateTarget should be used for "non-living" things ( Like ThrowObjects or
// ExplodingObjects... things like that.
//
// As behaviors get used, and proves necessary, we can add a flag that will allow the
// state machine to set and use the _alternateTarget
class EnemyManager
{
public:
EnemyManager();
EnemyManager( Actor *actor );
~EnemyManager();
void FindHighestHateEnemy();
void FindNextEnemy();
void FindClosestEnemy();
void ClearCurrentEnemy();
void ClearHateList();
qboolean Hates( Entity *ent );
qboolean Likes( Entity *ent );
qboolean CanAttack( Entity *ent );
qboolean CanAttackAnyEnemy();
EntityPtr GetCurrentEnemy();
void SetCurrentEnemy( Entity *enemy );
bool CanGetToEntity(Entity *enemy);
EntityPtr GetAlternateTarget();
void SetAlternateTarget( Entity *target );
void TryToAddToHateList( Entity *enemy );
qboolean IsInHateList( Entity *enemy );
qboolean IsLastInHateList( Entity* enemy );
void AdjustHate( Entity *enemy , float adjustment );
void AdjustDamageCaused( Entity *enemy, float adjustment );
void TrivialUpdate();
void Update();
void UpdateDistance( HateListEntry_t *listIndex );
void UpdateCanSee( HateListEntry_t *listIndex );
void UpdateAttackers( HateListEntry_t *listIndex );
void LockOnCurrentEnemy( qboolean lock );
qboolean IsLockedOnCurrentEnemy();
Vector GetAwayFromEnemies();
qboolean InEnemyLineOfFire();
float GetDistanceFromEnemy();
void TrySleep( void );
bool HasEnemy();
// Utility Functions
qboolean IsValidEnemy( Entity *enemy );
bool IsAnyEnemyInRange( float range );
float getEnemyCount();
// Archiving
virtual void Archive( Archiver &arc );
void DoArchive ( Archiver &arc , Actor *actor );
protected: //Member Functions
void _AddToHateList( Entity *enemy );
int _findEntityInHateList( Entity *searchEnt );
private: //Member Variables
Container<HateListEntry_t> _hateList;
EntityPtr _currentEnemy;
EntityPtr _lastEnemy;
EntityPtr _alternateTarget;
qboolean _lockedOnCurrentEnemy;
float _currentEnemyHate;
Actor *act;
};
#endif /* __ACTOR_ENEMYMANAGER_H__ */

View file

@ -0,0 +1,365 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_headwatcher.cpp $
// $Revision:: 21 $
// $Author:: Sketcher $
// $Date:: 5/04/03 5:49p $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
#include "_pch_cpp.h"
#include "actor_enemymanager.h"
#include "player.h"
#include "object.h"
HeadWatcher::HeadWatcher()
{
// Should always use other constructor
gi.Error( ERR_FATAL, "HeadWatcher::HeadWatcher -- Default Constructor Called" );
}
HeadWatcher::HeadWatcher( Actor *actor )
{
//Initialize our Actor
if ( actor )
act = actor;
else
gi.Error( ERR_DROP, "HeadWatcher::HeadWatcher -- actor is NULL" );
_init();
}
HeadWatcher::~HeadWatcher()
{
}
void HeadWatcher::_init()
{
act->SetControllerTag( ACTOR_HEAD_TAG, gi.Tag_NumForName( act->edict->s.modelindex, "Bip01 Head" ) );
_currentHeadAngles = act->GetControllerAngles( ACTOR_HEAD_TAG );
_watchTarget = NULL;
// Numbers here for testing, should come from events so they can be set via tiki or script
_maxHeadTurnSpeed = 30.0f;
_turnThreshold = 0.0f;
_maxHeadYaw = 60.0f;
_maxHeadPitch = 45.0f;
_twitchHead = false;
_nextTwitchHeadTime = 0.0f;
_maxDistance = -1.0;
_explicitSet = false;
_ignoreWatchTarget = false;
}
void HeadWatcher::SetWatchTarget( Entity *ent )
{
_watchTarget = ent;
_explicitSet = true;
}
void HeadWatcher::SetWatchTarget( const str &targetName )
{
TargetList *tlist;
int numObjects;
tlist = world->GetTargetList( targetName );
numObjects = tlist->list.NumObjects();
if ( numObjects == 0 )
{
//Hey, No targets with that name
gi.WDPrintf( "No target with target name %s specified\n", targetName.c_str() );
return;
}
else if ( numObjects > 1 )
{
//Uh Oh... We have more than one target... Let's throw up an error
gi.WDPrintf( "More than one target with target name %s specified, grabbing first one\n", targetName.c_str() );
}
_watchTarget = tlist->list.ObjectAt( 1 );
_explicitSet = true;
}
void HeadWatcher::SetWatchSpeed( float speed )
{
_maxHeadTurnSpeed = speed;
}
void HeadWatcher::ClearWatchTarget()
{
_watchTarget = NULL;
_explicitSet = false;
}
Entity *HeadWatcher::GetWatchTarget()
{
return _watchTarget;
}
void HeadWatcher::HeadWatchTarget()
{
int tagNum;
Vector tagPos;
Vector watchPosition;
Actor *actTarget;
actTarget = NULL;
tagNum = gi.Tag_NumForName( act->edict->s.modelindex, "Bip01 Head" );
if ( tagNum < 0 )
return;
//Check if we even have an animation set yet
if ( act->animate->CurrentAnim(legs) < 0 )
return;
act->GetTag( "Bip01 Head", &tagPos );
if ( !_watchTarget || _ignoreWatchTarget )
{
if ( _twitchHead )
{
twitchHead();
return;
}
else
{
LerpHeadBySpeed( vec_zero , false );
return;
}
}
if (act->GetActorFlag( ACTOR_FLAG_DIALOG_PLAYING ) && act->GetActorFlag(ACTOR_FLAG_USING_HUD) )
{
LerpHeadBySpeed( vec_zero , false );
return;
}
// Check if our _watchTarget is within distance )
if ( _maxDistance > 0 )
{
Vector selfToTarget = _watchTarget->origin - act->origin;
float dist = selfToTarget.length();
if ( dist > _maxDistance )
{
LerpHeadBySpeed( vec_zero , false );
return;
}
}
if ( _watchTarget->isSubclassOf( Actor ) )
{
actTarget = (Actor *)(Entity *)_watchTarget;
// Don't watch if the target is dead.
if ( !actTarget->isThinkOn() )
{
_watchTarget = NULL;
actTarget = NULL;
return;
}
}
if ( actTarget && ( actTarget->watch_offset != vec_zero ) )
{
MatrixTransformVector( actTarget->watch_offset, _watchTarget->orientation, watchPosition );
watchPosition += _watchTarget->origin;
}
else
{
tagNum = gi.Tag_NumForName( _watchTarget->edict->s.modelindex, "Bip01 Head" );
if ( tagNum < 0 )
watchPosition = _watchTarget->centroid;
else
{
_watchTarget->GetTag( "Bip01 Head", &watchPosition );
}
}
AdjustHeadAngles( tagPos , watchPosition );
}
void HeadWatcher::AdjustHeadAngles( const Vector &tagPos , const Vector &watchPosition )
{
Vector dir;
Vector angles;
Vector anglesDiff;
float yawChange;
float pitchChange;
dir = watchPosition - tagPos;
angles = dir.toAngles();
anglesDiff = angles - act->angles;
anglesDiff[YAW] = AngleNormalize180( anglesDiff[YAW] );
anglesDiff[PITCH] = AngleNormalize180( anglesDiff[PITCH] );
yawChange = anglesDiff[YAW];
pitchChange = anglesDiff[PITCH];
if ( _turnThreshold && ( yawChange < _turnThreshold ) && ( yawChange > -_turnThreshold ) && ( pitchChange < _turnThreshold ) && ( pitchChange > -_turnThreshold ) )
{
return;
}
// Make sure we don't turn neck too far
if ( anglesDiff[YAW] < -_maxHeadYaw )
anglesDiff[YAW] = -_maxHeadYaw;
else if ( anglesDiff[YAW] > _maxHeadYaw )
anglesDiff[YAW] = _maxHeadYaw;
if ( anglesDiff[PITCH] < -_maxHeadPitch )
anglesDiff[PITCH] = -_maxHeadPitch;
else if ( anglesDiff[PITCH] > _maxHeadPitch )
anglesDiff[PITCH] = _maxHeadPitch;
anglesDiff[ROLL] = 0.0f;
LerpHeadBySpeed( anglesDiff );
}
void HeadWatcher::LerpHeadBySpeed( const Vector &angleDelta , bool useTorsoAngles )
{
Vector anglesDiff;
Vector change;
Vector finalAngles;
Vector currentTorsoAngles;
anglesDiff = angleDelta;
// Get our Torso Angles
act->SetControllerTag( ACTOR_TORSO_TAG , gi.Tag_NumForName( act->edict->s.modelindex, "Bip01 Spine1" ) );
currentTorsoAngles = act->GetControllerAngles( ACTOR_TORSO_TAG );
//Reset our Controller Tag
act->SetControllerTag( ACTOR_HEAD_TAG, gi.Tag_NumForName( act->edict->s.modelindex, "Bip01 Head" ) );
// Make sure we don't change our head angles too much at once
change = anglesDiff - _currentHeadAngles;
if ( change[YAW] > _maxHeadTurnSpeed )
anglesDiff[YAW] = _currentHeadAngles[YAW] + _maxHeadTurnSpeed;
else if ( change[YAW] < -_maxHeadTurnSpeed )
anglesDiff[YAW] = _currentHeadAngles[YAW] - _maxHeadTurnSpeed;
if ( change[PITCH] > _maxHeadTurnSpeed )
anglesDiff[PITCH] = _currentHeadAngles[PITCH] + _maxHeadTurnSpeed;
else if ( change[PITCH] < -_maxHeadTurnSpeed )
anglesDiff[PITCH] = _currentHeadAngles[PITCH] - _maxHeadTurnSpeed;
if ( change[ROLL] > _maxHeadTurnSpeed )
anglesDiff[ROLL] = _currentHeadAngles[ROLL] + _maxHeadTurnSpeed;
else if ( change[ROLL] < -_maxHeadTurnSpeed )
anglesDiff[ROLL] = _currentHeadAngles[ROLL] - _maxHeadTurnSpeed;
finalAngles = anglesDiff;
if ( useTorsoAngles )
finalAngles[YAW] = anglesDiff[YAW] - currentTorsoAngles[YAW];
else
finalAngles[YAW] = anglesDiff[YAW];
act->SetControllerAngles( ACTOR_HEAD_TAG, finalAngles );
act->real_head_pitch = anglesDiff[PITCH];
_currentHeadAngles = anglesDiff;
}
void HeadWatcher::setHeadTwitch( bool twitchHead )
{
_twitchHead = twitchHead;
if ( _twitchHead )
{
_nextTwitchHeadTime = 0.0f;
}
}
void HeadWatcher::twitchHead( void )
{
Vector headAngles;
float oldMaxHeadTurnSpeed;
if ( level.time > _nextTwitchHeadTime )
{
_headTwitchAngles = Vector( G_CRandom( 4.0f ), G_CRandom( 4.0f ), G_CRandom( 4.0f ) );
_nextTwitchHeadTime = level.time + 1.0f + G_CRandom( 0.5f );
}
oldMaxHeadTurnSpeed = _maxHeadTurnSpeed;
_maxHeadTurnSpeed = 0.25f;
LerpHeadBySpeed( _headTwitchAngles, false );
_maxHeadTurnSpeed = oldMaxHeadTurnSpeed;
}
//
// Name: DoArchive()
// Parameters: Archiver &arc
// Actor *actor
// Description: Sets the Actor Pointer and Calls Archive()
//
void HeadWatcher::DoArchive( Archiver &arc , Actor *actor )
{
Archive( arc );
if ( actor )
act = actor;
else
gi.Error( ERR_FATAL, "HeadWatcher::DoArchive -- actor is NULL" );
}
//
// Name: Archive()
// Parameters: Archiver &arc
// Description: Archives Class Data
//
void HeadWatcher::Archive( Archiver &arc )
{
arc.ArchiveSafePointer( &_watchTarget );
arc.ArchiveVector( &_currentHeadAngles );
arc.ArchiveFloat( &_maxHeadTurnSpeed );
arc.ArchiveFloat( &_turnThreshold );
arc.ArchiveBoolean( &_explicitSet );
arc.ArchiveFloat( &_maxHeadYaw );
arc.ArchiveFloat( &_maxHeadPitch );
arc.ArchiveBool( &_twitchHead );
arc.ArchiveFloat( &_nextTwitchHeadTime );
arc.ArchiveVector( &_headTwitchAngles );
arc.ArchiveFloat( &_maxDistance );
arc.ArchiveBool( &_ignoreWatchTarget );
}

View file

@ -0,0 +1,101 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_headwatcher.h $
// $Revision:: 10 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Head Watcher Class
//
#ifndef __ACTOR_HEADWATCHER_H__
#define __ACTOR_HEADWATCHER_H__
#include "actor.h"
#include "actorincludes.h"
#include "weapon.h"
//============================
// Class HeadWatcher
//============================
class HeadWatcher
{
public:
HeadWatcher();
HeadWatcher( Actor *actor );
~HeadWatcher();
void SetWatchTarget( Entity *ent );
void SetWatchTarget( const str &targetName );
void SetWatchSpeed ( float speed );
void SetMaxHeadYaw ( float max );
void SetMaxHeadPitch ( float max );
void SetMaxDistance( float distance );
void SetIgnoreWatchTarget( bool ignore );
Entity* GetWatchTarget();
void ClearWatchTarget();
void HeadWatchTarget();
void AdjustHeadAngles( const Vector &tagPos , const Vector &watchPosition );
void LerpHeadBySpeed( const Vector &angleDelta , bool useTorsoAngles = true );
void setHeadTwitch( bool twitchHead );
void twitchHead( void );
// Archiving
virtual void Archive( Archiver &arc );
void DoArchive( Archiver &arc , Actor *actor );
protected:
void _init();
private:
EntityPtr _watchTarget;
Vector _currentHeadAngles;
float _maxHeadTurnSpeed;
float _turnThreshold;
qboolean _explicitSet;
float _maxHeadYaw;
float _maxHeadPitch;
bool _twitchHead;
float _nextTwitchHeadTime;
Vector _headTwitchAngles;
float _maxDistance;
bool _ignoreWatchTarget;
Actor *act;
};
inline void HeadWatcher::SetMaxHeadPitch( float max )
{
_maxHeadPitch = max;
}
inline void HeadWatcher::SetMaxHeadYaw( float max )
{
_maxHeadYaw = max;
}
inline void HeadWatcher::SetMaxDistance( float distance )
{
_maxDistance = distance;
}
inline void HeadWatcher::SetIgnoreWatchTarget( bool ignore )
{
_ignoreWatchTarget = ignore;
}
#endif /* __ACTOR_HEADWATCHER_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,217 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_locomotion.h $
// $Revision:: 22 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Motion and Movement Related Classes
//
class MovementSubsystem;
class LocomotionController;
#ifndef __ACTOR_LOCOMOTION_H__
#define __ACTOR_LOCOMOTION_H__
#include "actor.h"
#include "actorincludes.h"
#include "weapon.h"
#include "path.h"
#include "steering.h"
class LocomotionController
{
public:
LocomotionController();
LocomotionController( Actor *actor );
~LocomotionController();
void Begin();
void Evaluate();
void End();
// Accessors & Mutators
void SetMovementStyle( MovementStyle style );
MovementStyle GetMovementStyle();
// Archiving
virtual void Archive( Archiver &arc );
void DoArchive( Archiver &arc , Actor *actor );
protected:
void _init();
private:
Actor *act;
MovementStyle _movementStyle;
FollowPath _chase;
};
//============================
// Class MovementSubsystem
//============================
//
// Encapsulates movement related data and functionality for the actor
//
class MovementSubsystem
{
public:
MovementSubsystem();
MovementSubsystem( Actor *actor );
~MovementSubsystem();
qboolean CanMoveTo( const Vector &pos );
bool CanWalkTowardsPoint( const Vector &goalPoint, const int mask = -1);
qboolean CanWalkTo( const Vector &pos, float bounding_box_extra = 0, int entnum = ENTITYNUM_NONE, const int mask = -1 );
qboolean CanWalkToFrom( const Vector &origin, const Vector &pos, float bounding_box_extra = 0, int entnum = ENTITYNUM_NONE, const int mask = -1 );
void Accelerate( const Vector &steering );
void CalcMove( void );
stepmoveresult_t WaterMove( void );
stepmoveresult_t AirMove( void );
stepmoveresult_t IsMoveValid( trace_t &horizontalTrace, trace_t &verticalTrace, const Vector &moveBegin, const Vector &moveEnd );
stepmoveresult_t TryMove( void );
stepmoveresult_t SimpleMove( const bool stickToGround );
qboolean Push( const Vector &dir );
void CheckWater( void );
float JumpTo( PathNode * goal, const Angle angle = 45.0f );
float JumpTo( Entity * goal, const Angle angle = 45.0f );
float JumpTo( const Vector &targ, const Angle angle = 45.0f );
const Vector SteerTowardsPoint(const Vector &targetPosition, const Vector &targetVelocity, const Vector &moveDirection, const float maxSpeed=1.0f, const bool adjustSpeed = false);
// Archiving
virtual void Archive( Archiver &arc );
void DoArchive( Archiver &arc , Actor *actor );
// Accessors and Mutators
void setStep( const Vector &step );
const Vector & getStep() const;
void setLastMove( stepmoveresult_t lastMove );
stepmoveresult_t getLastMove();
void setMove( const Vector &move );
Vector getMove();
void setMoveDir( const Vector &moveDir );
Vector getMoveDir();
void setMoveVelocity( const Vector &moveVelocity );
Vector getMoveVelocity();
void setAnimDir( const Vector &animDir );
Vector getAnimDir();
void setDiveDir( const Vector &diveDir );
Vector getDiveDir();
void setStartPos( const Vector &startPos );
Vector getStartPos();
void setTotalLen( float totalLen );
float getTotalLen();
void setTurnSpeed( float turnSpeed );
float getTurnSpeed();
void setForwardSpeed( float forwardSpeed );
float getForwardSpeed();
void setMoveSpeed( float moveSpeed );
float getMoveSpeed();
void setPath( Path* path );
Path* getPath();
void setFlipLegs( qboolean flip );
qboolean getFlipLegs();
void flipLegs();
void setMovingBackwards( qboolean backwards );
qboolean getMovingBackwards();
void setFaceEnemy ( bool faceEnemy );
bool getFaceEnemy ();
void setAdjustAnimDir( bool adjustAnimDir );
bool getAdjustAnimDir();
void setMovementType( MovementType_t mType );
MovementType_t getMovementType();
void SetStickToGround( const bool stick );
const bool GetStickToGround( void ) const;
void setUseCodeDrivenSpeed( bool useCode );
bool getUseCodeDrivenSpeed();
Entity* getBlockingEntity();
void clearBlockingEntity();
protected: // Functions
Vector _getRealDestinationPosition( const Vector &pos ) const;
stepmoveresult_t _noGravityTryMove( const Vector &oldorg, trace_t &verticalTrace ) const;
trace_t _feetWidthTrace( const Vector &currentLoc , const Vector &bottom , const Vector &endPos, const int mask ) const;
float _getTraceStep() const;
void _saveGroundInformation(trace_t &trace);
qboolean _isBlockedByDoor(trace_t &trace ) const;
qboolean _canMoveSimplePath(const Vector &mins, const Vector &maxs, const Vector &pos ) const;
qboolean _isBlockedByFall(trace_t &trace ) const;
qboolean _allowFall() const;
qboolean _shouldTryMove() const;
qboolean _checkHaveGroundEachStep( const Vector &start, const Vector &end, const Vector &test_mins , const Vector &test_maxs, const int mask = -1 ) const;
void _init();
private: // Member Variables
static Vector _step;
stepmoveresult_t _lastmove;
float _forwardspeed;
PathPtr _path;
Vector _move;
Vector _movedir;
float _movespeed;
Vector _movevelocity;
float _totallen;
float _turnspeed;
Vector _animdir;
Vector _divedir;
Vector _startpos;
qboolean _fliplegs;
qboolean _movingBackwards;
bool _faceEnemy;
bool _adjustAnimDir;
MovementType_t _movementType;
bool _stickToGround;
bool _useCodeDrivenSpeed;
Actor *act;
EntityPtr _blockingEntity;
};
inline void MovementSubsystem::setUseCodeDrivenSpeed( bool useCode )
{
_useCodeDrivenSpeed = useCode;
}
inline bool MovementSubsystem::getUseCodeDrivenSpeed()
{
return _useCodeDrivenSpeed;
}
#endif /* __ACTOR_LOCOMOTION_H__ */

View file

@ -0,0 +1,308 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_posturecontroller.cpp $
// $Revision:: 8 $
// $Author:: Steven $
// $Date:: 5/04/03 2:02p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//-----------------------------------------------------------------------------
#include "_pch_cpp.h"
#include "actor_posturecontroller.hpp"
extern Event EV_Actor_SetPostureStateMap;
//--------------------------------------------------------------
// Name: PostureController()
// Class: PostureController
//
// Description: Constructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
PostureController::PostureController()
{
// Should always use other constructor
gi.Error( ERR_FATAL, "PostureController::PostureController -- Default Constructor Called" );
}
//--------------------------------------------------------------
// Name: PostureController()
// Class: PostureController
//
// Description: Constructor
//
// Parameters: Actor *actor
//
// Returns: None
//--------------------------------------------------------------
PostureController::PostureController( Actor *actor )
{
if ( actor )
act = actor;
else
gi.Error( ERR_DROP, "PostureController::PostureController -- actor is NULL" );
init();
}
//--------------------------------------------------------------
// Name: ~PostureController()
// Class: PostureController
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
PostureController::~PostureController()
{
act->freeConditionals( _postureConditionals );
}
//--------------------------------------------------------------
// Name: DoArchive()
// Class: PostureController
//
// Description: Archives our Actor and Calls our Archive Function
//
// Parameters: Archiver &arc -- The Archiver Object
// Actor *actor -- The pointer to our actor
//
// Returns: None
//--------------------------------------------------------------
void PostureController::DoArchive( Archiver &arc, Actor *actor )
{
Archive( arc );
if ( actor )
act = actor;
else
gi.Error( ERR_FATAL, "PostureController::DoArchive -- actor is NULL" );
}
//--------------------------------------------------------------
// Name: Archive()
// Class: PostureController
//
// Description: Archives the class
//
// Parameters: Archiver &arc
//
// Returns: None
//--------------------------------------------------------------
void PostureController::Archive( Archiver &arc )
{
arc.ArchiveString( &_postureStateMap_Name );
arc.ArchiveString( &_currentPostureState_Name );
arc.ArchiveString( &_requestedPostureState_Name );
arc.ArchiveSafePointer ( &_requestor );
if ( !arc.Saving() )
{
if ( _postureStateMap_Name.length() )
{
Event *event;
event = new Event( EV_Actor_SetPostureStateMap );
event->AddString( _postureStateMap_Name );
event->AddInteger( 1 );
act->ProcessEvent ( event );
_currentPostureState = _postureStateMap->FindState( _currentPostureState_Name.c_str() );
_requestedPostureState = _postureStateMap->FindState(_requestedPostureState_Name.c_str() );
}
}
}
//--------------------------------------------------------------
// Name: init()
// Class: PostureController
//
// Description: Initializes the class
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void PostureController::init()
{
_postureStateMap = NULL;
_postureStateMap_Name = "";
_currentPostureState = NULL;
_currentPostureState_Name = "";
_requestedPostureState = NULL;
_requestedPostureState_Name = "";
_requestor = NULL;
}
//--------------------------------------------------------------
// Name: evaluate()
// Class: PostureController
//
// Description: Evaluation Routine, Called Every Frame
//
// Parameters: None
//
// Returns: None
//--------------------------------------------------------------
void PostureController::evaluate()
{
int count;
State *laststate = NULL;
str currentanim;
str stateLegAnim;
stateLegAnim = act->animname;
count = 0;
if ( !_postureStateMap )
return;
if ( act->deadflag || !_currentPostureState )
return;
do
{
// Since we could get into an infinite loop here, do a check to make sure we don't.
count++;
if ( count > 10 )
{
gi.WDPrintf( "Possible infinite loop in posture state '%s'\n", _currentPostureState->getName() );
if ( count > 50 )
{
gi.Error( ERR_DROP, "Stopping due to possible infinite state loop\n" );
break;
}
}
// Determine the next state to go to
laststate = _currentPostureState;
_currentPostureState = _currentPostureState->Evaluate( *act, &_postureConditionals );
if ( !_currentPostureState )
return;
_currentPostureState_Name = _currentPostureState->getName();
// Change the behavior if the state has changed
if ( laststate != _currentPostureState )
{
// Initialize some stuff for changing states
act->SetActorFlag( ACTOR_FLAG_POSTURE_ANIM_DONE, false );
}
if ( _currentPostureState == _requestedPostureState )
{
if ( _requestor )
_requestor->ProcessEvent( EV_PostureChanged_Completed );
}
// Change the animation if it has changed
currentanim = _currentPostureState->getLegAnim( *act, &_postureConditionals );
if ( currentanim.length() && ( stricmp( stateLegAnim , currentanim.c_str() ) != 0 ) )
{
act->SetAnim( currentanim, EV_Posture_Anim_Done, legs );
stateLegAnim = currentanim;
}
}
while( laststate != _currentPostureState );
}
//--------------------------------------------------------------
// Name: requestPosture()
// Class: PostureController
//
// Description: Request Handler for a specific Posture
//
// Parameters: PostureStates_t postureState
//
// Returns: true -- if the posture is viable
// false -- if the posture in not viable
//--------------------------------------------------------------
bool PostureController::requestPosture( const str &postureState , Listener *requestor )
{
if ( !_postureStateMap )
return false;
_requestedPostureState = _postureStateMap->FindState( postureState.c_str() );
if ( _requestedPostureState )
{
_requestor = requestor;
_requestedPostureState_Name = postureState;
return true;
}
return false;
}
void PostureController::setPostureStateMap( const str &stateMap , bool loading )
{
str animName;
// Load the new state map
_postureStateMap_Name = stateMap;
//_postureConditionals.FreeObjectList();
act->freeConditionals( _postureConditionals );
_postureStateMap = GetStatemap( _postureStateMap_Name, ( Condition<Class> * )act->Conditions, &_postureConditionals, false );
// Set the first state
_currentPostureState_Name = "START";
// Initialize the actors first animation
if ( !loading )
setPostureState( _currentPostureState_Name.c_str() );
}
void PostureController::setPostureState( const str &postureState )
{
if ( !_postureStateMap )
return;
if ( act->deadflag )
return;
_currentPostureState = _postureStateMap->FindState( postureState.c_str() );
}
void PostureController::setPostureState( const str &postureState, const str &requestedState )
{
if ( !_postureStateMap )
return;
if ( act->deadflag )
return;
_currentPostureState = _postureStateMap->FindState( postureState.c_str() );
_requestedPostureState = _postureStateMap->FindState( requestedState.c_str() );
_requestedPostureState_Name = requestedState.c_str();
}

View file

@ -0,0 +1,93 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_posturecontroller.h $
// $Revision:: 15 $
// $Author:: Sketcher $
// $Date:: 5/20/02 3:55p $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//-----------------------------------------------------------------------------
class PostureController;
#ifndef __ACTOR_POSTURECONTROLLER_HPP__
#define __ACTOR_POSTURECONTROLLER_HPP__
#include "actor.h"
#include "actorincludes.h"
extern Event EV_Posture_Anim_Done;
extern Event EV_PostureChanged_Completed;
//------------------------- CLASS ------------------------------
//
// Name: PostureController
// Base Class: None
//
// Description: This class will control the posture of the Actor. It will maintain
// an enum of the current posture and will have methods for changing
// posture via Animations... Eventually, these will need to be modified
// to call functions on some type of animation manager
//
// Method of Use: Instantiated by the Actor
//
//--------------------------------------------------------------
class PostureController
{
public:
PostureController();
PostureController( Actor *actor );
~PostureController();
virtual void Archive( Archiver &arc );
void DoArchive( Archiver &arc , Actor *actor );
void evaluate();
bool requestPosture( const str &postureState , Listener *requestor );
const str& getRequestedPostureName();
const str& getCurrentPostureName();
void setPostureStateMap( const str &stateMap , bool loading );
void setPostureState( const str &postureState );
void setPostureState( const str &postureState , const str &requestedState );
protected:
void init();
private:
StateMap *_postureStateMap;
str _postureStateMap_Name;
State *_currentPostureState;
str _currentPostureState_Name;
State *_requestedPostureState;
str _requestedPostureState_Name;
SafePtr<Listener> _requestor;
Container<Conditional*> _postureConditionals;
Actor *act;
};
inline const str& PostureController::getRequestedPostureName()
{
return _requestedPostureState_Name;
}
inline const str& PostureController::getCurrentPostureName()
{
return _currentPostureState_Name;
}
#endif /* __ACTOR_POSTURECONTROLLER_HPP__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,131 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actor_sensoryperception.h $
// $Revision:: 7 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
// SensoryPerception class for Actors -- Handles all the sensory related funtionality
//
class SensoryPerception;
#ifndef __ACTOR_SENSORYPERCEPTION_H__
#define __ACTOR_SENSORYPERCEPTION_H__
#include "actor.h"
#include "actorincludes.h"
#include "weapon.h"
//============================
// Class SensoryPerception
//============================
//
// Class used to handle all sensory perception by actors.
//
class SensoryPerception
{
public:
SensoryPerception();
SensoryPerception(Actor *actor );
~SensoryPerception();
// Sense functions
void SenseEnemies();
void SearchForEnemies();
// Stimuli functions
void Stimuli( int stimuli );
void Stimuli( int stimuli, Entity *ent );
void Stimuli( int stimuli, const Vector &pos );
void Stimuli( int stimuli, const Vector &pos, int sound_Type );
void RespondTo( const str &stimuli_name , qboolean respond );
void RespondTo( int stimuli, qboolean respond );
void PermanentlyRespondTo( const str &stimuli_name , qboolean respond );
qboolean ShouldRespondToStimuli( int new_stimuli );
// Vision functions
qboolean WithinVisionDistance( const Entity *ent );
qboolean WithinVisionDistance( const Vector &pos );
qboolean InFOV( const Vector &pos, float check_fov, float check_fovdot );
qboolean InFOV( const Vector &pos );
qboolean InFOV( const Entity *ent );
// New Vision Functions -- Simplified Vision
qboolean CanSeeEntity( Entity *start , const Entity *target, qboolean useFOV, qboolean useVisionDistance );
qboolean CanSeeEntity( const Vector &start , const Entity *target, qboolean useFOV, qboolean useVisionDistance );
// New Vision Functions -- More Sophisticated Vision
qboolean CanSeeEntityComplex( Entity *start , Entity *target, qboolean useFOV, qboolean useVisionDistance );
qboolean CanSeeEntityComplex( Vector &start , Entity *target, qboolean useFOV, qboolean useVisionDistance );
qboolean CanSeePosition( const Vector &start, const Vector &position, qboolean useFOV, qboolean useVisionDistance );
qboolean isInLineOfSight( const Vector &position , const int entNum );
qboolean checkInLineOfSight( const Vector &position , const int entNum );
// Debugging Functions
void ShowInfo();
// Accessors and Mutators
void SetNoisePosition( const Vector &pos );
Vector GetNoisePosition();
void SetLastSoundType( int soundtype );
int GetLastSoundType();
void SetNoiseTime( float noisetime );
float GetNoiseTime();
void SetFOV( float fov );
float GetFOV();
void SetFOVdot( float fov_dot );
float GetFOVdot();
void SetVisionDistance( float vision_distance );
float GetVisionDistance();
// Archiving
virtual void Archive( Archiver &arc );
void DoArchive( Archiver &arc , Actor *actor );
private: //Functions
qboolean _CanSeeComplex( Vector &start , Entity *target , qboolean useFOV , qboolean useVisionDistance );
qboolean _SenseEntity( Entity *ent );
void _init();
private: //Member Variables
// Stimuli Variables
int _stimuli;
int _permanent_stimuli;
// Hearing Variables
Vector _noise_position;
int _last_soundType;
float _noise_time;
// Vision Stuff for "seeing"
float _fov;
float _fovdot;
float _vision_distance;
float _nextSenseTime;
LineOfSight_t _lineOfSight;
Actor *act;
};
#endif /* __ACTOR_SENSORYPERCEPTION_H__ */

View file

@ -0,0 +1,143 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actorgamecomponents.cpp $
// $Revision:: 18 $
// $Author:: Steven $
// $Date:: 10/11/02 3:34a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// What I am trying to do here, is encapsulate any game specific pieces for actor. Each game will
// subclass off of the base class, then the Actor class will point to the component class it will
// use. I am hoping this will make life much easier for mod makers as well
//
#include "_pch_cpp.h"
#include "actorgamecomponents.h"
#include "player.h"
//
// Name: CLASS_DECLARATION
// Parameters: Listener -- Parent Class
// ActorGameComponent -- This class
// String -- Name
// Description: Macro
//
CLASS_DECLARATION( Listener , ActorGameComponent, "actor_game_component" )
{
{ NULL, NULL }
};
//=========================================
// EFGameComponent Implementation
//=========================================
//
// Name: CLASS_DECLARATION
// Parameters: ActorGameComponent -- Parent Class
// EFGameComponent -- This class
// String -- Name
// Description: Macro
//
CLASS_DECLARATION( ActorGameComponent, EFGameComponent, "ef_game_component" )
{
{ NULL, NULL }
};
//
// Name: EFGameComponent()
// Parameters: None
// Description: Constructor
//
EFGameComponent::EFGameComponent()
{
// Should always use other constructor
gi.Error( ERR_FATAL, "EFGameComponent::EFGameComponent -- Default Constructor Called" );
}
//
// Name: EFGameComponent()
// Parameters: Actor *actor
// Description: Constructor
//
EFGameComponent::EFGameComponent( const Actor *actor )
{
if ( actor )
act = (Actor *)actor;
}
void EFGameComponent::DoArchive( Archiver &arc , const Actor *actor )
{
if ( actor )
act = (Actor *)actor;
else
gi.Error( ERR_FATAL, "EFGameComponnet::DoArchive -- actor is NULL" );
}
//
// Name: HandleDeath()
// Parameters: Entity *ent
// Description: Custom Game Death Handler
//
void EFGameComponent::HandleDeath( const Entity *ent )
{
}
//
// Name: HandleArmorDamage()
// Parameters: Event *ev
// Description: Custom Game Armor Damage Handler
//
void EFGameComponent::HandleArmorDamage( Event *ev )
{
}
//
// Name: HandleThink()
// Parameters: None
// Description: Custom Game Think Handler
//
void EFGameComponent::HandleThink()
{
}
//
// Name: HandleEvent()
// Parameters: Event *ev
// Description: Event Handler
//
void EFGameComponent::HandleEvent( Event *ev )
{
Event *new_event;
new_event = new Event( ev );
ProcessEvent(new_event);
}
//
// Name: DoCheck()
// Parameters: Conditional &condition
// Description: Custom Game conditional check handler
//
qboolean EFGameComponent::DoCheck ( const Conditional &condition )
{
return false;
}

View file

@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actorgamecomponents.h $
// $Revision:: 12 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// What I am trying to do here, is encapsulate any game specific pieces for actor. Each game will
// subclass off of the base class, then the Actor class will point to the component class it will
// use. I am hoping this will make life much easier for mod makers as well
//
//============================
// Forward Declarations
//============================
class ActorGameComponent;
class RedemptionGameComponent;
#ifndef __ACTORGAMECOMPONENTS_H__
#define __ACTORGAMECOMPONENTS_H__
#include "actor.h"
//============================
// Class ActorGameComponent
//============================
//
// Base class from which all Actor Game Components are derived.
//
class ActorGameComponent : public Listener
{
public:
CLASS_PROTOTYPE( ActorGameComponent );
ActorGameComponent() {}
virtual void HandleEvent( Event *ev ) {}
virtual void HandleArmorDamage( Event *ev ) {}
virtual void HandleDeath( const Entity *ent ) {}
virtual void HandleThink() {}
virtual qboolean DoCheck( const Conditional &condition ) { return false; }
virtual void DoArchive( Archiver &arc, const Actor *act ) {}
};
/*
EF Specific Stuff
*/
//============================
// Class EFGameComponent
//============================
class EFGameComponent : public ActorGameComponent
{
public:
CLASS_PROTOTYPE( EFGameComponent );
EFGameComponent();
EFGameComponent( const Actor *actor );
void HandleEvent( Event *ev );
void HandleArmorDamage( Event *ev );
void HandleDeath( const Entity *ent);
void HandleThink();
qboolean DoCheck( const Conditional &condition );
void DoArchive( Archiver &arc , const Actor *act );
private:
Actor *act;
};
#endif /*__ACTORGAMECOMPONENTS_H__*/

537
dlls/game/actorincludes.h Normal file
View file

@ -0,0 +1,537 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actorincludes.h $
// $Revision:: 84 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// Centralized repository for externs, defines, enums, and structs that are required
// by actor and all of actor's helper classes, like sensoryPerception, thinkStrategy, etc...
//
#ifndef __ACTORINCLUDES_H__
#define __ACTORINCLUDES_H__
//=========================================
// External Events
//=========================================
extern Event EV_Actor_Start;
extern Event EV_Actor_Dead;
extern Event EV_Actor_LookAt;
extern Event EV_Actor_TurnTo;
extern Event EV_Actor_BehaviorFinished ;
extern Event EV_Actor_ControlLost ;
extern Event EV_Actor_EndBehavior;
extern Event EV_Actor_EndHeadBehavior;
extern Event EV_Actor_EndEyeBehavior;
extern Event EV_Actor_NotifyBehavior;
extern Event EV_Actor_NotifyTorsoBehavior;
extern Event EV_Actor_NotifyHeadBehavior;
extern Event EV_Actor_NotifyEyeBehavior;
extern Event EV_Actor_FinishedMove;
extern Event EV_Actor_FinishedAnim;
extern Event EV_Actor_WalkTo;
extern Event EV_Actor_FallToDeath;
extern Event EV_Actor_RunTo;
extern Event EV_Actor_Anim;
extern Event EV_Actor_AttackFinished;
extern Event EV_Actor_Attack;
extern Event EV_Actor_AttackPlayer;
extern Event EV_Actor_AIOn;
extern Event EV_Actor_AIOff;
extern Event EV_Actor_AIDeaf;
extern Event EV_Actor_AIDumb;
extern Event EV_Actor_RespondTo;
extern Event EV_Actor_PermanentlyRespondTo;
extern Event EV_ActorIncomingProjectile;
extern Event EV_Anim_Done;
extern Event EV_ActorOnlyShootable;
extern Event EV_Actor_BounceOff;
extern Event EV_Actor_Push;
extern Event EV_Actor_Statemap;
extern Event EV_Actor_SetTargetable;
extern Event EV_Sentient_StopFire;
extern Event EV_Sentient_Attack;
extern Event EV_Actor_SetUseGravity ;
extern Event EV_Actor_SetSimplifiedThink ;
extern Event EV_Actor_SetStickToGround ;
extern Event EV_Actor_SetMovementMode ;
//========================================
// General Defines
//========================================
#define MAX_ALIAS_NAME_LENGTH 32
#define MAX_INACTIVE_TIME 30.0
#define DEFAULT_FOV 150
#define DEFAULT_VISION_DISTANCE 1536
#define MIN_SIGHT_DELAY 2
#define RANDOM_SIGHT_DELAY 1.5
#define DEFAULT_INITIAL_HATE 100
#define TURN_SPEED 60 //Used to be 25
#define HELPER_NODE_MAX_DISTANCE 96.0
#define HELPER_NODE_ARRIVAL_DISTANCE 24.0
#define HACK_PATH_CHECK 1.0
//========================================
// Stimuli types
//========================================
#define STIMULI_ALL -1
#define STIMULI_NONE 0
#define STIMULI_SIGHT (1<<0)
#define STIMULI_SOUND (1<<1)
#define STIMULI_PAIN (1<<2)
#define STIMULI_SCRIPT (1<<3)
//========================================
// Bones used by actor
//========================================
#define ACTOR_MOUTH_TAG 0
#define ACTOR_HEAD_TAG 1
#define ACTOR_TORSO_TAG 2
#define ACTOR_LEYE_TAG 3
#define ACTOR_REYE_TAG 4
//========================================
// Dialog stuff
//========================================
#define MAX_DIALOG_PARAMETERS_LENGTH 100
#define MAX_DIALOG_PARM_LENGTH 64
#define MAX_DIALOG_PARMS 10
#define DIALOG_PARM_TYPE_NONE 0
#define DIALOG_PARM_TYPE_PLAYERHAS 1
#define DIALOG_PARM_TYPE_PLAYERHASNOT 2
#define DIALOG_PARM_TYPE_HAS 3
#define DIALOG_PARM_TYPE_HASNOT 4
#define DIALOG_PARM_TYPE_DEPENDS 5
#define DIALOG_PARM_TYPE_DEPENDSNOT 6
#define DIALOG_PARM_TYPE_DEPENDSINT 7
#define DIALOG_PARM_TYPE_CONTEXT_INITIATOR 8
#define DIALOG_PARM_TYPE_CONTEXT_RESPONSE 9
//========================================
// State flags
//========================================
#define STATE_FLAG_IN_PAIN ( 1<<0 )
#define STATE_FLAG_MELEE_HIT ( 1<<1 )
#define STATE_FLAG_TOUCHED ( 1<<2 )
#define STATE_FLAG_ACTIVATED ( 1<<3 )
#define STATE_FLAG_USED ( 1<<4 )
#define STATE_FLAG_TWITCH ( 1<<5 )
#define STATE_FLAG_BLOCKED_HIT ( 1<<6 )
#define STATE_FLAG_SMALL_PAIN ( 1<<7 )
#define STATE_FLAG_OTHER_DIED ( 1<<8 )
#define STATE_FLAG_STUCK ( 1<<9 )
#define STATE_FLAG_NO_PATH ( 1<<10 )
#define STATE_FLAG_TOUCHED_BY_PLAYER ( 1<<11 )
#define STATE_FLAG_CHANGED_WEAPON ( 1<<12 )
#define STATE_FLAG_DAMAGE_THRESHOLD_EXCEEDED ( 1<<13 )
#define STATE_FLAG_ATTACKED ( 1<<14 )
#define STATE_FLAG_ATTACKED_BY_PLAYER ( 1<<15 )
#define STATE_FLAG_SHOW_PAIN ( 1<<16 )
#define STATE_FLAG_IN_THE_WAY ( 1<<17 )
#define STATE_FLAG_STEERING_FAILED ( 1<<18 )
#define STATE_FLAG_BLOCKED_BY_ENTITY ( 1<<19 )
#define STATE_FLAG_ENEMY_PROJECTILE_CLOSE ( 1<<20 )
//========================================
// Combat Subsystem Defines
//========================================
#define DEFAULT_TRACE_INTERVAL .05f
#define DEFAULT_PATH_TO_ENEMY_INTERVAL .05f
//========================================
// Actor modes
//========================================
#define ACTOR_MODE_NONE 0
#define ACTOR_MODE_IDLE 1
#define ACTOR_MODE_AI 2
#define ACTOR_MODE_SCRIPT 3
#define ACTOR_MODE_TALK 4
//=======================================
// Pain types
//=======================================
#define PAIN_SMALL 0
#define PAIN_BIG 1
//========================================
// Save Flags
//========================================
#define SAVE_FLAG_NEW_ANIM (1<<0)
#define SAVE_FLAG_FORWARD_SPEED (1<<1)
#define SAVE_FLAG_BEHAVIOR (1<<2)
#define SAVE_FLAG_PATH (1<<3)
#define SAVE_FLAG_NOISE (1<<4)
#define SAVE_FLAG_SCRIPT_THREAD (1<<5)
#define SAVE_FLAG_ACTOR_THREAD (1<<6)
#define SAVE_FLAG_KILL_THREAD (1<<7)
#define SAVE_FLAG_STATE (1<<8)
#define SAVE_FLAG_IDLE_THREAD (1<<7)
#define SAVE_FLAG_PARTS (1<<10)
#define SAVE_FLAG_TRIGGER (1<<11)
#define SAVE_FLAG_STATE_FLAGS (1<<12)
#define SAVE_FLAG_COMMAND (1<<13)
#define SAVE_FLAG_STAGE (1<<14)
#define SAVE_FLAG_NUM_OF_SPAWNS (1<<15)
#define SAVE_FLAG_SPAWN_PARENT (1<<16)
#define SAVE_FLAG_DIALOG (1<<17)
#define SAVE_FLAG_SAVED_STUFF (1<<18)
#define SAVE_FLAG_LAST_ANIM_EVENT (1<<19)
#define SAVE_FLAG_PICKUP_ENT (1<<20)
#define SAVE_FLAG_PAIN (1<<21)
#define SAVE_FLAG_SPAWN_ITEMS (1<<22)
//=======================================
// Rage AI System
//=======================================
#define DEFAULT_EVALUATE_INTERVAL .05f // Was 10.0f
#define DEFAULT_SIGHT_BASED_HATE 5.0f
//=======================================
// Structures
//=======================================
//DialogParm_t -- Structure for Dialog Parameters
typedef struct
{
byte type;
char parm[ MAX_DIALOG_PARM_LENGTH ];
char parm2[ MAX_DIALOG_PARM_LENGTH ];
} DialogParm_t;
typedef enum
{
DIALOG_TYPE_NORMAL,
DIALOG_TYPE_RADIUS,
DIALOG_TYPE_GREETING,
DIALOG_TYPE_COMBAT,
DIALOG_TYPE_CONTEXT_INITIATOR,
DIALOG_TYPE_CONTEXT_RESPONSE
} DialogType_t;
//DialogNode_t -- Structure for Dialog Nodes
typedef struct DialogNode_s
{
char alias_name[ MAX_ALIAS_NAME_LENGTH ];
int random_flag;
int number_of_parms;
float random_percent;
DialogType_t dType;
DialogParm_t parms[ MAX_DIALOG_PARMS ];
struct DialogNode_s *next;
} DialogNode_t;
typedef struct
{
int entNum;
float time;
qboolean inLineOfSight;
} LineOfSight_t;
//HateListEntry_t -- Structure for the hate list
typedef struct
{
// Information that will need to be persistant, or accesses
// frequently should be placed in this structure
EntityPtr enemy; //Pointer to the entity
float lastSightTime; //Last time I tried to see this entity
float nextSightTime; //Next time I try and see this entity
qboolean canSee; //Can I see the enemy ( based on last time I tried )
float damageCaused; //total damage that entity has done to me
float hate; //how much hate I have for this entiy
float lastDistance;
} HateListEntry_t;
typedef struct
{
str packageName;
str stateFile;
} BehaviorPackageType_t;
// Helper Node Data
typedef struct
{
HelperNodePtr node;
int mask;
int nodeID;
} CurrentHelperNodeData_t;
typedef struct
{
HelperNodePtr node;
int mask;
int nodeID;
} IgnoreHelperNodeData_t;
// Follow Target Data
typedef struct
{
EntityPtr currentFollowTarget;
EntityPtr specifiedFollowTarget;
float maxRangeIdle;
float minRangeIdle;
float maxRangeCombat;
float minRangeCombat;
} FollowTargetData_t;
typedef struct
{
int packageIndex;
float currentScore;
float lastScore;
float lastTimeExecuted;
float priority;
} BehaviorPackageEntry_t;
typedef struct
{
int packageIndex;
float tendency;
float lastTendencyCheck;
} PackageTendency_t;
// We need to modify PackageTendency_t to do
// what struct is going to do, however, I'm 2 days from a
// milestone, so I'm not changing anything right now
typedef struct
{
str tendencyName;
float tendencyValue;
} Tendency_t;
// StateVar -- Structure for holding StateVars
typedef struct
{
str varName;
str varValue;
float varTime;
} StateVar;
// part_t -- Part stuff
typedef struct
{
EntityPtr ent;
unsigned int state_flags;
} part_t;
// threadlist_t -- A Key/Value pair for all the custom threading stuff we're doing
// we will eventually need to convert all those errant actor threads into this.
typedef struct
{
str threadType;
str threadName;
} threadlist_t;
//===========================================
// Enumerations
//===========================================
typedef enum{
MOVEMENT_TYPE_NORMAL,
MOVEMENT_TYPE_ANIM
} MovementType_t;
//DialogMode_t -- Enumeration of Dialog Modes
typedef enum{
DIALOG_MODE_ANXIOUS,
DIALOG_MODE_NORMAL,
DIALOG_MODE_IGNORE
} DialogMode_t;
// actortype_t -- Enumeration of possible actor types
typedef enum
{
IS_INANIMATE,
IS_MONSTER,
IS_ENEMY,
IS_CIVILIAN,
IS_FRIEND,
IS_ANIMAL,
IS_TEAMMATE,
NUM_ACTORTYPES
} actortype_t;
// targetType_t -- Enumeration of possible target types
typedef enum
{
ATTACK_ANY,
ATTACK_PLAYER_ONLY,
ATTACK_ACTORS_ONLY,
ATTACK_SCRIPTED_ONLY,
ATTACK_LEVEL_INTERACTION
} targetType_t;
typedef enum
{
DEBUG_NONE,
DEBUG_STATES_ONLY,
DEBUG_STATES_BEHAVIORS,
DEBUG_ALL,
MAX_DEBUG_TYPES
} stateDebugType_t;
typedef enum
{
TALK_TURNTO,
TALK_HEADWATCH,
TALK_IGNORE
} talkModeStates_t;
// actorflags -- Enumeration of Actor flags
typedef enum{
ACTOR_FLAG_NOISE_HEARD,
ACTOR_FLAG_INVESTIGATING,
ACTOR_FLAG_DEATHGIB,
ACTOR_FLAG_DEATHFADE,
ACTOR_FLAG_NOCHATTER,
ACTOR_FLAG_INACTIVE,
ACTOR_FLAG_ANIM_DONE,
ACTOR_FLAG_STATE_DONE_TIME_VALID,
ACTOR_FLAG_MASTER_STATE_DONE_TIME_VALID,
ACTOR_FLAG_AI_ON,
ACTOR_FLAG_LAST_CANSEEENEMY,
ACTOR_FLAG_LAST_CANSEEENEMY_NOFOV,
ACTOR_FLAG_DIALOG_PLAYING,
ACTOR_FLAG_RADIUS_DIALOG_PLAYING,
ACTOR_FLAG_ALLOW_TALK,
ACTOR_FLAG_DAMAGE_ONCE_ON,
ACTOR_FLAG_DAMAGE_ONCE_DAMAGED,
ACTOR_FLAG_BOUNCE_OFF,
ACTOR_FLAG_NOTIFY_OTHERS_AT_DEATH,
ACTOR_FLAG_HAS_THING1,
ACTOR_FLAG_HAS_THING2,
ACTOR_FLAG_HAS_THING3,
ACTOR_FLAG_HAS_THING4,
ACTOR_FLAG_LAST_ATTACK_HIT,
ACTOR_FLAG_STARTED,
ACTOR_FLAG_ALLOW_HANGBACK,
ACTOR_FLAG_USE_GRAVITY,
ACTOR_FLAG_SPAWN_FAILED,
ACTOR_FLAG_FADING_OUT,
ACTOR_FLAG_DEATHSHRINK,
ACTOR_FLAG_DEATHSINK,
ACTOR_FLAG_STAYSOLID,
ACTOR_FLAG_STUNNED,
ACTOR_FLAG_ALLOW_FALL,
ACTOR_FLAG_FINISHED,
ACTOR_FLAG_IN_LIMBO,
ACTOR_FLAG_CAN_WALK_ON_OTHERS,
ACTOR_FLAG_PUSHABLE,
ACTOR_FLAG_LAST_TRY_TALK,
ACTOR_FLAG_TARGETABLE,
ACTOR_FLAG_IMMORTAL,
ACTOR_FLAG_TURNING_HEAD,
ACTOR_FLAG_MOVING_EYES,
ACTOR_FLAG_DIE_COMPLETELY,
ACTOR_FLAG_BLEED_AFTER_DEATH,
ACTOR_FLAG_IGNORE_STUCK_WARNING,
ACTOR_FLAG_IGNORE_OFF_GROUND_WARNING,
ACTOR_FLAG_ALLOWED_TO_KILL,
ACTOR_FLAG_TOUCH_TRIGGERS,
ACTOR_FLAG_IGNORE_WATER,
ACTOR_FLAG_NEVER_IGNORE_SOUNDS,
ACTOR_FLAG_SIMPLE_PATHFINDING,
ACTOR_FLAG_HAVE_MOVED,
ACTOR_FLAG_NO_PAIN_SOUNDS,
ACTOR_FLAG_UPDATE_BOSS_HEALTH,
ACTOR_FLAG_IGNORE_PAIN_FROM_ACTORS,
ACTOR_FLAG_DAMAGE_ALLOWED,
ACTOR_FLAG_AT_COVER_NODE,
ACTOR_FLAG_WAIT_FOR_NEW_ENEMY,
ACTOR_FLAG_TAKE_DAMAGE,
ACTOR_FLAG_USE_DAMAGESKINS,
ACTOR_FLAG_CAPTURED,
ACTOR_FLAG_TURRET_MODE,
ACTOR_FLAG_INCOMING_HITSCAN,
ACTOR_FLAG_RESPONDING_TO_HITSCAN,
ACTOR_FLAG_MELEE_HIT_WORLD,
ACTOR_FLAG_TORSO_ANIM_DONE,
ACTOR_FLAG_WEAPON_READY,
ACTOR_FLAG_DISABLED,
ACTOR_FLAG_IN_ALCOVE,
ACTOR_FLAG_IN_CONE_OF_FIRE,
ACTOR_FLAG_IN_PLAYER_CONE_OF_FIRE,
ACTOR_FLAG_PLAYER_IN_CALL_VOLUME,
ACTOR_FLAG_IN_CALL_VOLUME,
ACTOR_FLAG_OUT_OF_TORSO_RANGE,
ACTOR_FLAG_DUCKED,
ACTOR_FLAG_PRONE,
ACTOR_FLAG_SHOULD_BLINK,
ACTOR_FLAG_CRIPPLED,
ACTOR_FLAG_RETREATING,
ACTOR_FLAG_HIDDEN,
ACTOR_FLAG_FOLLOWING_IN_FORMATION,
ACTOR_FLAG_DISPLAYING_FAILURE_FX,
ACTOR_FLAG_GROUPMEMBER_INJURED,
ACTOR_FLAG_CAN_HEAL_OTHER,
ACTOR_FLAG_STRICTLY_FOLLOW_PATHS,
ACTOR_FLAG_POSTURE_ANIM_DONE,
ACTOR_FLAG_ATTACKING_ENEMY,
ACTOR_FLAG_UPDATE_HATE_WITH_ATTACKERS,
ACTOR_FLAG_LAST_CANSEEPLAYER,
ACTOR_FLAG_LAST_CANSEEPLAYER_NOFOV,
ACTOR_FLAG_MELEE_ALLOWED,
ACTOR_FLAG_PLAYING_DIALOG_ANIM,
ACTOR_FLAG_USING_HUD,
ACTOR_FLAG_FORCE_LIFEBAR,
ACTOR_FLAG_UPDATE_ACTION_LEVEL,
ACTOR_FLAG_CAN_CHANGE_ANIM,
ACTOR_FLAG_USE_FOLLOWRANGE_FOR_NODES,
ACTOR_FLAG_IMMEDIATE_ACTIVATE,
ACTOR_FLAG_CANNOT_DISINTEGRATE,
ACTOR_FLAG_CANNOT_USE,
ACTOR_FLAG_CANNOT_FREEZE,
ACTOR_FLAG_MAX
} ActorFlags;
typedef enum {
NOTIFY_FLAG_DAMAGED,
NOTIFY_FLAG_KILLED,
NOTIFY_FLAG_SPOTTED_ENEMY,
NOTIFY_FLAG_MAX
} NotifyFlags;
typedef enum {
MOVEMENT_STYLE_NONE,
MOVEMENT_STYLE_WALK,
MOVEMENT_STYLE_RUN,
MOVEMENT_STYLE_MAX
} MovementStyle;
//========================================
// Global Lists
//========================================
extern Container<Actor *> SleepList;
extern Container<Actor *> ActiveList;
extern Container<Sentient *> TeamMateList;
extern Container<BehaviorPackageType_t *> PackageList;
#endif /* __ACTORINCLUDES_H__ */

View file

@ -0,0 +1,580 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/actorstrategies.cpp $
// $Revision:: 46 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:35p $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// I am replacing the old way that Actor::Think was done by implementing a group of strategies for it
// instead. This will form the foundation for new flexiblility within the actor class.
//
// What I am trying to achieve is a specialized "think" for different types of actors. A Boss, for instance,
// would use BossThink, an Non-Attacking-NPC could use NPCThink. Using the event system we already have inplace
// it will be easy to change thinking modalities on the fly, allowing us to make a cowardly NPC turn into a
// roaring death machine if he gets shot.
//
#include "_pch_cpp.h"
#include "actorstrategies.h"
#include "actor.h"
#include "entity.h"
extern cvar_t *ai_showfailure;
//------------------------- CLASS ------------------------------
//
// Name: ActorThink
// Base Class: None
//
// Description: Base class from which all Actor Think Strategies
// are derived.
//
// Method of Use:
// Deriving a new class from ActorThink is a good
// to allow Actor to exhibit new behavior.
//
//--------------------------------------------------------------
//----------------------------------------------------------------
// Name: DoArchive
// Class: ActorThink
//
// Description: Archives this instance of ActorThink
//
// Parameters:
// Archiver the class that receives/supplies
// archival info
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::DoArchive( Archiver &arc )
{
}
//----------------------------------------------------------------
// Name: ProcessBehaviors
// Class: ActorThink
//
// Description: Processes all the Actors Behaviors
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::ProcessBehaviors( Actor &actor )
{
bool showFailure;
showFailure = ( ai_showfailure->integer != 0 );
// Do the state machine for this creature
actor.ProcessMasterStateMachine();
actor.ProcessActorStateMachine();
// Process the current behavior
if ( actor.behavior )
{
actor.behaviorCode = actor.behavior->Evaluate( actor );
if ( actor.behaviorCode == BEHAVIOR_FAILED )
{
actor.behaviorFailureReason = actor.behavior->GetFailureReason();
}
if ( actor.behaviorCode != BEHAVIOR_EVALUATING )
{
if ( stricmp( actor.behavior->getClassname(), "Talk" ) == 0 )
{
actor.EndBehavior();
actor.EndMode();
}
else
{
actor.EndBehavior();
}
}
// Process state machine again because the behavior finished
actor.ProcessActorStateMachine();
}
// Process the current head behavior
if ( actor.headBehavior )
{
actor.headBehaviorCode = actor.headBehavior->Evaluate( actor );
if ( actor.headBehaviorCode != BEHAVIOR_EVALUATING )
{
actor.EndHeadBehavior();
}
// Process state machine again because the behavior finished
actor.ProcessActorStateMachine();
}
// Process the current eye behavior
if ( actor.eyeBehavior )
{
actor.eyeBehaviorCode = actor.eyeBehavior->Evaluate( actor );
if ( actor.eyeBehaviorCode != BEHAVIOR_EVALUATING )
{
actor.EndEyeBehavior();
}
// Process state machine again because the behavior finished
actor.ProcessActorStateMachine();
}
// Process the current torso behavior
if ( actor.torsoBehavior )
{
actor.torsoBehaviorCode = actor.torsoBehavior->Evaluate( actor );
if ( actor.torsoBehaviorCode != BEHAVIOR_EVALUATING )
{
actor.EndTorsoBehavior();
}
// Process state machine again because the behavior finished
actor.ProcessActorStateMachine();
}
// Reset the animation is done flag
actor.SetActorFlag( ACTOR_FLAG_ANIM_DONE, false );
actor.SetActorFlag( ACTOR_FLAG_TORSO_ANIM_DONE, false );
// Change the animation if necessary
if ( ( actor.newanimnum != -1 ) || ( actor.newTorsoAnimNum != -1 ) )
actor.ChangeAnim();
if ( !showFailure )
return;
if ( actor.behaviorCode == BEHAVIOR_FAILED && !actor.GetActorFlag(ACTOR_FLAG_DISPLAYING_FAILURE_FX) )
{
Event* event;
event = new Event( EV_DisplayEffect );
event->AddString( "electric" );
actor.ProcessEvent( event );
actor.SetActorFlag( ACTOR_FLAG_DISPLAYING_FAILURE_FX , true );
return;
}
else if ( actor.behaviorCode != BEHAVIOR_FAILED && actor.GetActorFlag(ACTOR_FLAG_DISPLAYING_FAILURE_FX) )
{
Event* event;
event = new Event( EV_DisplayEffect );
event->AddString( "noelectric" );
actor.ProcessEvent( event );
actor.SetActorFlag( ACTOR_FLAG_DISPLAYING_FAILURE_FX , false );
return;
}
}
//----------------------------------------------------------------
// Name: DoMove
// Class: ActorThink
//
// Description: Does Movement Stuff for Actor
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::DoMove( Actor &actor )
{
if ( ( actor.flags & FL_IMMOBILE ) || ( actor.flags & FL_PARTIAL_IMMOBILE ) )
{
actor.animate->StopAnimating();
return;
}
actor.movementSubsystem->CalcMove();
actor.movementSubsystem->setLastMove( STEPMOVE_STUCK );
stepmoveresult_t lastMove;
if ( actor.flags & FL_SWIM )
lastMove = actor.movementSubsystem->WaterMove();
else if ( actor.flags & FL_FLY )
lastMove = actor.movementSubsystem->AirMove();
else
lastMove = actor.movementSubsystem->TryMove();
actor.movementSubsystem->setLastMove( lastMove );
if (
( actor.movetype != MOVETYPE_NONE ) &&
( actor.movetype != MOVETYPE_STATIONARY ) &&
actor.GetActorFlag( ACTOR_FLAG_TOUCH_TRIGGERS ) &&
actor.GetActorFlag( ACTOR_FLAG_HAVE_MOVED )
)
G_TouchTriggers( &actor );
if ( actor.groundentity && ( actor.groundentity->entity != world ) && !M_CheckBottom( &actor ) )
actor.flags |= FL_PARTIALGROUND;
}
//----------------------------------------------------------------
// Name: UpdateBossHealth
// Class: ActorThink
//
// Description: Handles Boss Specific behavior
//
// Parameters:
// Actor that is the boss in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::UpdateBossHealth( Actor &actor )
{
char bosshealth_string[20];
sprintf( bosshealth_string, "%.5f", actor.health / actor.max_boss_health );
gi.cvar_set( "bosshealth", bosshealth_string );
gi.cvar_set( "bossname", actor.getName() );
}
//----------------------------------------------------------------
// Name: CheckGround
// Class: ActorThink
//
// Description: Checks that the actor is on the ground, and does
// Falling Damage if necessary
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::CheckGround( Actor &actor )
{
if ( actor.GetActorFlag( ACTOR_FLAG_HAVE_MOVED ) ||
( actor.groundentity && actor.groundentity->entity && ( actor.groundentity->entity->entnum != ENTITYNUM_WORLD ) ) )
actor.CheckGround();
// Add Fall Damage if necessary
if ( actor.groundentity )
{
if ( !actor.Immune( MOD_FALLING ) && !( actor.flags & FL_FLY ) && ( actor.origin.z + 1000.0f < actor.last_ground_z ) )
actor.Damage( world, world, 1000.0f, actor.origin, vec_zero, vec_zero, 0, DAMAGE_NO_ARMOR, MOD_FALLING );
actor.last_ground_z = actor.origin.z;
}
}
//----------------------------------------------------------------
// Name: InanimateObject
// Class: ActorThink
//
// Description: Handles behavior ending, if the Actor is an
// InanimateObject
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::InanimateObject( Actor &actor )
{
if ( actor.behavior && actor.behavior->Evaluate( actor ) != BEHAVIOR_EVALUATING )
{
actor.EndBehavior();
// stop thinking
actor.turnThinkOff();
ActiveList.RemoveObject( &actor );
}
if ( actor.headBehavior && actor.headBehavior->Evaluate( actor ) != BEHAVIOR_EVALUATING )
{
actor.EndHeadBehavior();
// stop thinking
actor.turnThinkOff();
ActiveList.RemoveObject( &actor );
}
if ( actor.eyeBehavior && actor.eyeBehavior->Evaluate( actor ) != BEHAVIOR_EVALUATING )
{
actor.EndEyeBehavior();
// stop thinking
actor.turnThinkOff();
ActiveList.RemoveObject( &actor );
}
if ( actor.torsoBehavior && actor.torsoBehavior->Evaluate( actor ) != BEHAVIOR_EVALUATING )
{
actor.EndTorsoBehavior();
// stop thinking
actor.turnThinkOff();
ActiveList.RemoveObject( &actor );
}
}
//----------------------------------------------------------------
// Name: TryDrown
// Class: ActorThink
//
// Description: Damages the Actor if they are drowning
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::TryDrown( Actor &actor )
{
if ( actor.waterlevel == 3 && !( actor.flags & FL_SWIM ) )
{
// if out of air, start drowning
if ( actor.air_finished < level.time )
{
// we may have been in a water brush when we spawned, so check our water level again to be sure
actor.movementSubsystem->CheckWater();
if ( actor.waterlevel < 3 )
{
// we're ok, so reset our air
actor.air_finished = level.time + 5.0f;
}
else if ( ( actor.next_drown_time < level.time ) && ( actor.health > 0 ) )
{
// drown!
actor.next_drown_time = level.time + 1.0f;
//Sound( "snd_uwchoke", CHAN_VOICE );
actor.BroadcastSound();
actor.Damage( world, world, 15.0f, actor.origin, vec_zero, vec_zero, 0, DAMAGE_NO_ARMOR, MOD_DROWN );
}
}
}
else
{
actor.air_finished = level.time + 5.0f;
}
}
//----------------------------------------------------------------
// Name: ActorStateUpdate
// Class: ActorThink
//
// Description: Updates miscellaneous actor state variables
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void ActorThink::ActorStateUpdate( Actor &actor )
{
// Update move status
if ( actor.last_origin != actor.origin )
actor.SetActorFlag( ACTOR_FLAG_HAVE_MOVED, true );
else
actor.SetActorFlag( ACTOR_FLAG_HAVE_MOVED, false );
// Set Origins;
actor.last_origin = actor.origin;
// Check for the ground
if ( !( actor.flags & FL_SWIM ) && !( actor.flags & FL_FLY ) && actor.GetStickToGround() )
CheckGround( actor );
if ( !actor.deadflag )
{
// Check to see if stunned
actor.CheckStun();
// Handle Game Specific Stuff
actor.gameComponent->HandleThink();
// See if can talk to the player
if(actor.DialogMode == DIALOG_MODE_ANXIOUS)
actor.TryTalkToPlayer();
// Blink -- Emotions
if ( actor.GetActorFlag( ACTOR_FLAG_SHOULD_BLINK ) )
actor.TryBlink();
if ( actor.getHeadWatchAllowed() )
actor.headWatcher->HeadWatchTarget();
//Update Eyeposition
actor.eyeposition[ 2 ] = actor.maxs[ 2 ] + actor.eyeoffset[ 2 ];
// See if we should damage the actor because of waterlevel
TryDrown( actor );
if ( actor.groundentity && ( actor.groundentity->entity != world ) && !M_CheckBottom( &actor ) )
actor.flags |= FL_PARTIALGROUND;
}
}
//------------------------- CLASS ------------------------------
//
// Name: DefaultThink
// Base Class: ActorThink
//
// Description:
// Think class instantiated by most actors -- and
// instantiated in ALL actors by default
//
// Method of Use:
// This is the default behavior for Actor, nothing
// special need be done to use this class
//
//--------------------------------------------------------------
//----------------------------------------------------------------
// Name: Think
// Class: DefaultThink
//
// Description: Main Think Function for Actor
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void DefaultThink::Think( Actor &actor )
{
if ( actor.flags & FL_IMMOBILE )
{
// Update boss health if necessary
if ( (actor.GetActorFlag( ACTOR_FLAG_UPDATE_BOSS_HEALTH ) && actor.max_boss_health && ( actor.mode == ACTOR_MODE_AI )) || actor.GetActorFlag(ACTOR_FLAG_FORCE_LIFEBAR) )
UpdateBossHealth( actor );
if ( actor.statemap )
{
actor.last_time_active = level.time;
return;
}
}
// Update boss health if necessary
if ( (actor.GetActorFlag( ACTOR_FLAG_UPDATE_BOSS_HEALTH ) && actor.max_boss_health && ( actor.mode == ACTOR_MODE_AI )) || actor.GetActorFlag(ACTOR_FLAG_FORCE_LIFEBAR) )
UpdateBossHealth( actor );
if ( actor.postureController )
actor.postureController->evaluate();
ActorStateUpdate( actor );
if ( !actor.deadflag )
{
// Update the hate list
actor.enemyManager->Update();
// Do the movement
DoMove( actor );
if ( actor.actortype == IS_INANIMATE )
{
InanimateObject( actor );
return;
}
//Process our behaviors
ProcessBehaviors( actor );
}
}
//------------------------- CLASS ------------------------------
//
// Name: SimplifiedThink
// Base Class: ActorThink
//
// Description:
// This is a light weight version of Default Think
// The purpose of this class is to allow Actors that
// move, have behaviors and accept messages without
// the CPU overhead of doing DefaultThink
//
// Method of Use:
// Actors can be given this method of updating via
// the script command "setsimplifiedthink"
//
//--------------------------------------------------------------
SimplifiedThink::SimplifiedThink( Actor *actor ) :
_actor( actor ),
_previousContents( actor->getContents() )
{
actor->setContents( 0 );
}
SimplifiedThink::~SimplifiedThink( void )
{
_actor->setContents( _previousContents );
}
//----------------------------------------------------------------
// Name: DoMove
// Class: SimplifiedThink
//
// Description: Does Movement Stuff for Actor
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void SimplifiedThink::DoMove( Actor &actor )
{
actor.last_origin = actor.origin;
actor.movementSubsystem->CalcMove();
actor.movementSubsystem->setLastMove( actor.movementSubsystem->SimpleMove( actor.GetStickToGround() ) );
}
void SimplifiedThink::DoArchive( Archiver &arc )
{
ActorThink::DoArchive( arc );
arc.ArchiveInteger ( &_previousContents );
arc.ArchiveSafePointer( &_actor );
}
//----------------------------------------------------------------
// Name: Think
// Class: SimplifiedThink
//
// Description: Main Think Function for Actor
//
// Parameters:
// Actor in question
//
// Returns: None
//----------------------------------------------------------------
void SimplifiedThink::Think( Actor &actor )
{
// Update the hate list
actor.enemyManager->TrivialUpdate();
if ( actor.GetActorFlag( ACTOR_FLAG_SHOULD_BLINK ) )
actor.TryBlink();
//Process our behaviors
ProcessBehaviors( actor );
// Do the movement
DoMove( actor );
}

128
dlls/game/actorstrategies.h Normal file
View file

@ -0,0 +1,128 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actorstrategies.h $
// $Revision:: 19 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// I am replacing the old way that Actor::Think was done by implementing a group of strategies for it
// instead. This will form the foundation for new flexiblility within the actor class.
//
// What I am trying to achieve is a specialized "think" for different types of actors. A Boss, for instance,
// would use BossThink, an Non-Attacking-NPC could use NPCThink. Using the event system we already have in place
// it will be easy to change thinking modalities on the fly, allowing us to make a cowardly NPC turn into a
// roaring death machine if he gets shot.
//
#ifndef __ACTORSTRATEGIES_H__
#define __ACTORSTRATEGIES_H__
//============================
// Forward Declarations
//============================
class Actor;
class Entity;
class Archiver;
typedef SafePtr<Actor> ActorPtr;
//------------------------- CLASS ------------------------------
//
// Name: ActorThink
// Base Class: None
//
// Description: Base class from which all Actor Think Strategies
// are derived.
//
// Method of Use:
// Deriving a new class from ActorThink is a good
// to allow Actor to exhibit new behavior.
//
//--------------------------------------------------------------
class ActorThink
{
public:
virtual ~ActorThink() { }
virtual void DoArchive( Archiver &arc );
virtual void Think( Actor & ) = 0;
virtual bool isSimple( void ) { return false; }
protected:
virtual void ProcessBehaviors( Actor &actor );
virtual void DoMove( Actor &actor );
virtual void UpdateBossHealth( Actor &actor );
virtual void CheckGround( Actor &actor );
virtual void InanimateObject( Actor &actor );
virtual void TryDrown( Actor &actor );
virtual void ActorStateUpdate( Actor &actor );
};
//------------------------- CLASS ------------------------------
//
// Name: DefaultThink
// Base Class: ActorThink
//
// Description:
// Think class instantiated by most actors -- and
// instantiated in ALL actors by default
//
// Method of Use:
// This is the default behavior for Actor, nothing
// special need be done to use this class
//
//--------------------------------------------------------------
class DefaultThink : public ActorThink
{
public:
virtual void Think( Actor &actor );
};
//------------------------- CLASS ------------------------------
//
// Name: SimplifiedThink
// Base Class: ActorThink
//
// Description:
// This is a light weight version of Default Think
// The purpose of this class is to allow Actors that
// move, have behaviors and accept messages without
// the CPU overhead of doing DefaultThink
//
// Method of Use:
// Actors can be given this method of updating via
// the script command "setsimplifiedthink"
//
//--------------------------------------------------------------
class SimplifiedThink : public ActorThink
{
public:
SimplifiedThink( Actor *actor );
~SimplifiedThink( void );
virtual void Think( Actor &actor );
virtual void DoArchive( Archiver &arc );
virtual bool isSimple( void ) { return true; }
protected:
virtual void DoMove( Actor &actor );
private:
const SimplifiedThink & operator=( const SimplifiedThink & );
ActorPtr _actor;
int _previousContents;
};
#endif /* __ACTORSTRATEGIES_H__ */

195
dlls/game/actorutil.cpp Normal file
View file

@ -0,0 +1,195 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actorutil.cpp $
// $Revision:: 44 $
// $Author:: Steven $
// $Date:: 10/11/02 3:27a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// These classes will be used to help simplify the Actor class, and move some of the large subsystems it contained into
// these smaller classes.
//
#include "_pch_cpp.h"
#include "actorutil.h"
#include "actor_sensoryperception.h"
#include "actor_enemymanager.h"
#include "player.h"
#include "object.h"
//===============================================================
//
// Movement Utility Functions
//
//===============================================================
qboolean FindMovement::validpath( PathNode *node, int i )
{
if ( !StandardMovement::validpath( node, i ) )
return false;
return true;
}
qboolean FindMovement::done( PathNode *node , const PathNode *end )
{
if ( node == end )
return true;
return false;
}
qboolean FindCoverMovement::validpath( PathNode *node, int i )
{
PathNodeConnection *path;
PathNode *n;
path = &node->GetConnection( i );
if ( !StandardMovement::validpath( node, i ) )
{
return false;
}
n = thePathManager.GetNode( path->targetNodeIndex );;
if ( !n || self->CloseToEnemy( n->origin, 128.0f ) )
{
return false;
}
return true;
}
qboolean FindCoverMovement::done( PathNode *node , const PathNode *end )
{
// Get our current enemy
Entity *currentEnemy;
currentEnemy = self->enemyManager->GetCurrentEnemy();
if ( !currentEnemy )
return true;
if ( node == end )
{
return true;
}
if ( !( node->nodeflags & ( AI_DUCK | AI_COVER ) ) )
{
return false;
}
if ( self )
{
return true;
}
return false;
}
qboolean FindFleeMovement::validpath( PathNode *node , int i )
{
PathNodeConnection *path;
PathNode *n;
path = &node->GetConnection( i );
if ( !StandardMovement::validpath( node, i ) )
{
return false;
}
n = thePathManager.GetNode( path->targetNodeIndex );;
if ( !n || self->CloseToEnemy( n->origin, 128.0f ) )
{
return false;
}
return true;
}
qboolean FindFleeMovement::done( PathNode *node , const PathNode *end )
{
// Get our current enemy
Entity *currentEnemy;
currentEnemy = self->enemyManager->GetCurrentEnemy();
if ( !currentEnemy )
return true;
if ( node == end )
{
return true;
}
if ( !( node->nodeflags & AI_FLEE ) )
{
return false;
}
if ( self )
{
return true;
}
return false;
}
qboolean FindEnemyMovement::done( PathNode *node , const PathNode *end )
{
if ( node == end )
{
return true;
}
if ( self )
{
return !true;
}
return false;
}
//======================================
// Global Functions
//======================================
qboolean EntityIsValidTarget( const Entity *ent )
{
if ( ent && ( ent->flags & FL_NOTARGET ) )
return false;
if ( ent && ( ent->entnum == ENTITYNUM_WORLD ) )
return false;
return true;
}

102
dlls/game/actorutil.h Normal file
View file

@ -0,0 +1,102 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/actorutil.h $
// $Revision:: 28 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
//
// DESCRIPTION:
// Utility Functions and classes for Actor
class FindCoverMovement;
class FindFleeMovement;
class FindEnemyMovement;
#ifndef __ACTORUTIL_H__
#define __ACTORUTIL_H__
#include "actor.h"
#include "actorincludes.h"
#include "weapon.h"
//============================
// Global Functions
//============================
qboolean EntityIsValidTarget( const Entity *ent );
//============================
// Class FindMovement
//============================
//
// Standard Movement, finds a path from the starting position to the ending position
//
class FindMovement : public StandardMovement
{
public:
Actor *self;
qboolean validpath ( PathNode *node, int i );
qboolean done ( PathNode *node, const PathNode *end );
};
//============================
// Class FindCoverMovement
//============================
//
// Set destination to node with duck or cover set. Class will find a path to that node, or a closer one.
//
class FindCoverMovement : public StandardMovement
{
public:
Actor *self;
qboolean validpath ( PathNode *node, int i );
qboolean done ( PathNode *node, const PathNode *end );
};
//============================
// Class FindFleeMovement
//============================
//
// Set destination to node with flee set. Class will find a path to that node, or a closer one.
//
class FindFleeMovement : public StandardMovement
{
public:
Actor *self;
qboolean validpath ( PathNode *node, int i );
qboolean done ( PathNode *node, const PathNode *end );
};
//============================
// Class FindEnemyMovement
//============================
//
// Not sure what this is for at the moment.
//
class FindEnemyMovement : public StandardMovement
{
public:
Actor *self;
qboolean done ( PathNode *node, const PathNode *end );
};
#endif /* __ACTORUTIL_H__ */

1276
dlls/game/ai_chat.cpp Normal file

File diff suppressed because it is too large Load diff

45
dlls/game/ai_chat.h Normal file
View file

@ -0,0 +1,45 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_chat.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_chat.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 7/25/02 11:48a $
* $Date: 7/30/02 1:10p $
*
*****************************************************************************/
//
int BotChat_EnterGame(bot_state_t *bs);
//
int BotChat_ExitGame(bot_state_t *bs);
//
int BotChat_StartLevel(bot_state_t *bs);
//
int BotChat_EndLevel(bot_state_t *bs);
//
int BotChat_HitTalking(bot_state_t *bs);
//
int BotChat_HitNoDeath(bot_state_t *bs);
//
int BotChat_HitNoKill(bot_state_t *bs);
//
int BotChat_Death(bot_state_t *bs);
//
int BotChat_Kill(bot_state_t *bs);
//
int BotChat_EnemySuicide(bot_state_t *bs);
//
int BotChat_Random(bot_state_t *bs);
// time the selected chat takes to type in
float BotChatTime(bot_state_t *bs);
// returns true if the bot can chat at the current position
int BotValidChatPosition(bot_state_t *bs);
// test the initial bot chats
void BotChatTest(bot_state_t *bs);

1976
dlls/game/ai_cmd.cpp Normal file

File diff suppressed because it is too large Load diff

21
dlls/game/ai_cmd.h Normal file
View file

@ -0,0 +1,21 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_cmd.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_cmd.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 7/25/02 11:48a $
* $Date: 7/30/02 1:10p $
*
*****************************************************************************/
extern int notleader[MAX_CLIENTS];
int BotMatchMessage(bot_state_t *bs, char *message);
void BotPrintTeamGoal(bot_state_t *bs);

2605
dlls/game/ai_dmnet.cpp Normal file

File diff suppressed because it is too large Load diff

45
dlls/game/ai_dmnet.h Normal file
View file

@ -0,0 +1,45 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_dmnet.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_dmnet.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 7/25/02 11:48a $
* $Date: 7/30/02 1:10p $
*
*****************************************************************************/
#define MAX_NODESWITCHES 50
void AIEnter_Intermission(bot_state_t *bs, char *s);
void AIEnter_Observer(bot_state_t *bs, char *s);
void AIEnter_Respawn(bot_state_t *bs, char *s);
void AIEnter_Stand(bot_state_t *bs, char *s);
void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s);
void AIEnter_Seek_NBG(bot_state_t *bs, char *s);
void AIEnter_Seek_LTG(bot_state_t *bs, char *s);
void AIEnter_Seek_Camp(bot_state_t *bs, char *s);
void AIEnter_Battle_Fight(bot_state_t *bs, char *s);
void AIEnter_Battle_Chase(bot_state_t *bs, char *s);
void AIEnter_Battle_Retreat(bot_state_t *bs, char *s);
void AIEnter_Battle_NBG(bot_state_t *bs, char *s);
int AINode_Intermission(bot_state_t *bs);
int AINode_Observer(bot_state_t *bs);
int AINode_Respawn(bot_state_t *bs);
int AINode_Stand(bot_state_t *bs);
int AINode_Seek_ActivateEntity(bot_state_t *bs);
int AINode_Seek_NBG(bot_state_t *bs);
int AINode_Seek_LTG(bot_state_t *bs);
int AINode_Battle_Fight(bot_state_t *bs);
int AINode_Battle_Chase(bot_state_t *bs);
int AINode_Battle_Retreat(bot_state_t *bs);
int AINode_Battle_NBG(bot_state_t *bs);
void BotResetNodeSwitches(void);
void BotDumpNodeSwitches(bot_state_t *bs);

5673
dlls/game/ai_dmq3.cpp Normal file

File diff suppressed because it is too large Load diff

191
dlls/game/ai_dmq3.h Normal file
View file

@ -0,0 +1,191 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_dmq3.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_dmq3.h $
* $Author: Jwaters $
* $Revision: 2 $
* $Modtime: 8/25/02 1:03p $
* $Date: 8/25/02 6:26p $
*
*****************************************************************************/
//setup the deathmatch AI
void BotSetupDeathmatchAI(void);
//shutdown the deathmatch AI
void BotShutdownDeathmatchAI(void);
//let the bot live within it's deathmatch AI net
void BotDeathmatchAI(bot_state_t *bs, float thinktime);
//free waypoints
void BotFreeWaypoints(bot_waypoint_t *wp);
//choose a weapon
void BotChooseWeapon(bot_state_t *bs);
//setup movement stuff
void BotSetupForMovement(bot_state_t *bs);
//update the inventory
void BotUpdateInventory(bot_state_t *bs);
//update the inventory during battle
void BotUpdateBattleInventory(bot_state_t *bs, int enemy);
//use holdable items during battle
void BotBattleUseItems(bot_state_t *bs);
//return true if the bot is dead
qboolean BotIsDead(bot_state_t *bs);
//returns true if the bot is in observer mode
qboolean BotIsObserver(bot_state_t *bs);
//returns true if the bot is in the intermission
qboolean BotIntermission(bot_state_t *bs);
//returns true if the bot is in lava or slime
qboolean BotInLavaOrSlime(bot_state_t *bs);
//returns true if the entity is dead
qboolean EntityIsDead(aas_entityinfo_t *entinfo);
//returns true if the entity is invisible
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo);
//returns true if the entity is shooting
qboolean EntityIsShooting(aas_entityinfo_t *entinfo);
#ifdef MISSIONPACK
//returns true if this entity has the kamikaze
qboolean EntityHasKamikaze(aas_entityinfo_t *entinfo);
#endif
// set a user info key/value pair
void BotSetUserInfo(bot_state_t *bs, char *key, char *value);
// set the team status (offense, defense etc.)
void BotSetTeamStatus(bot_state_t *bs);
//returns the name of the client
char *ClientName(int client, char *name, int size);
//returns an simplyfied client name
char *EasyClientName(int client, char *name, int size);
//returns the skin used by the client
char *ClientSkin(int client, char *skin, int size);
// returns the appropriate synonym context for the current game type and situation
int BotSynonymContext(bot_state_t *bs);
// set last ordered task
int BotSetLastOrderedTask(bot_state_t *bs);
// selection of goals for teamplay
void BotTeamGoals(bot_state_t *bs, int retreat);
//returns the aggression of the bot in the range [0, 100]
float BotAggression(bot_state_t *bs);
//returns how bad the bot feels
float BotFeelingBad(bot_state_t *bs);
//returns true if the bot wants to retreat
int BotWantsToRetreat(bot_state_t *bs);
//returns true if the bot wants to chase
int BotWantsToChase(bot_state_t *bs);
//returns true if the bot wants to help
int BotWantsToHelp(bot_state_t *bs);
//returns true if the bot can and wants to rocketjump
int BotCanAndWantsToRocketJump(bot_state_t *bs);
// returns true if the bot has a persistant powerup and a weapon
int BotHasPersistantPowerupAndWeapon(bot_state_t *bs);
//returns true if the bot wants to and goes camping
int BotWantsToCamp(bot_state_t *bs);
//the bot will perform attack movements
bot_moveresult_t BotAttackMove(bot_state_t *bs, int tfl);
//returns true if the bot and the entity are in the same team
int BotSameTeam(bot_state_t *bs, int entnum);
//returns true if teamplay is on
int TeamPlayIsOn(void);
// returns the client number of the team mate flag carrier (-1 if none)
int BotTeamFlagCarrier(bot_state_t *bs);
//returns visible team mate flag carrier if available
int BotTeamFlagCarrierVisible(bot_state_t *bs);
//returns visible enemy flag carrier if available
int BotEnemyFlagCarrierVisible(bot_state_t *bs);
//get the number of visible teammates and enemies
void BotVisibleTeamMatesAndEnemies(bot_state_t *bs, int *teammates, int *enemies, float range);
//returns true if within the field of vision for the given angles
qboolean InFieldOfVision(vec3_t viewangles, float fov, vec3_t angles);
//returns true and sets the .enemy field when an enemy is found
int BotFindEnemy(bot_state_t *bs, int curenemy);
//returns a roam goal
void BotRoamGoal(bot_state_t *bs, vec3_t goal);
//returns entity visibility in the range [0, 1]
float BotEntityVisible(int viewer, vec3_t eye, vec3_t viewangles, float fov, int ent);
//the bot will aim at the current enemy
void BotAimAtEnemy(bot_state_t *bs);
//check if the bot should attack
void BotCheckAttack(bot_state_t *bs);
//AI when the bot is blocked
void BotAIBlocked(bot_state_t *bs, bot_moveresult_t *moveresult, int activate);
//AI to predict obstacles
int BotAIPredictObstacles(bot_state_t *bs, bot_goal_t *goal);
//enable or disable the areas the blocking entity is in
void BotEnableActivateGoalAreas(bot_activategoal_t *activategoal, int enable);
//pop an activate goal from the stack
int BotPopFromActivateGoalStack(bot_state_t *bs);
//clear the activate goal stack
void BotClearActivateGoalStack(bot_state_t *bs);
//returns the team the bot is in
int BotTeam(bot_state_t *bs);
//retuns the opposite team of the bot
int BotOppositeTeam(bot_state_t *bs);
//returns the flag the bot is carrying (CTFFLAG_?)
int BotCTFCarryingFlag(bot_state_t *bs);
//remember the last ordered task
void BotRememberLastOrderedTask(bot_state_t *bs);
//set ctf goals (defend base, get enemy flag) during seek
void BotCTFSeekGoals(bot_state_t *bs);
//set ctf goals (defend base, get enemy flag) during retreat
void BotCTFRetreatGoals(bot_state_t *bs);
//
#ifdef MISSIONPACK
int Bot1FCTFCarryingFlag(bot_state_t *bs);
int BotHarvesterCarryingCubes(bot_state_t *bs);
void Bot1FCTFSeekGoals(bot_state_t *bs);
void Bot1FCTFRetreatGoals(bot_state_t *bs);
void BotObeliskSeekGoals(bot_state_t *bs);
void BotObeliskRetreatGoals(bot_state_t *bs);
void BotGoHarvest(bot_state_t *bs);
void BotHarvesterSeekGoals(bot_state_t *bs);
void BotHarvesterRetreatGoals(bot_state_t *bs);
int BotTeamCubeCarrierVisible(bot_state_t *bs);
int BotEnemyCubeCarrierVisible(bot_state_t *bs);
#endif
//get a random alternate route goal towards the given base
int BotGetAlternateRouteGoal(bot_state_t *bs, int base);
//returns either the alternate route goal or the given goal
bot_goal_t *BotAlternateRoute(bot_state_t *bs, bot_goal_t *goal);
//create a new waypoint
bot_waypoint_t *BotCreateWayPoint(char *name, vec3_t origin, int areanum);
//find a waypoint with the given name
bot_waypoint_t *BotFindWayPoint(bot_waypoint_t *waypoints, char *name);
//strstr but case insensitive
char *stristr(char *str, char *charset);
//returns the number of the client with the given name
int ClientFromName(char *name);
int ClientOnSameTeamFromName(bot_state_t *bs, char *name);
//
int BotPointAreaNum(vec3_t origin);
//
void BotMapScripts(bot_state_t *bs);
//ctf flags
#define CTF_FLAG_NONE 0
#define CTF_FLAG_RED 1
#define CTF_FLAG_BLUE 2
//CTF skins
#define CTF_SKIN_REDTEAM "red"
#define CTF_SKIN_BLUETEAM "blue"
extern int gametype; //game type
//extern int maxclients; //maximum number of clients
extern vmCvar_t bot_grapple;
extern vmCvar_t bot_rocketjump;
extern vmCvar_t bot_fastchat;
extern vmCvar_t bot_nochat;
extern vmCvar_t bot_testrchat;
extern vmCvar_t bot_challenge;
extern vmCvar_t bot_showstates;
extern bot_goal_t ctf_redflag;
extern bot_goal_t ctf_blueflag;
#ifdef MISSIONPACK
extern bot_goal_t ctf_neutralflag;
extern bot_goal_t redobelisk;
extern bot_goal_t blueobelisk;
extern bot_goal_t neutralobelisk;
#endif

1747
dlls/game/ai_main.cpp Normal file

File diff suppressed because it is too large Load diff

286
dlls/game/ai_main.h Normal file
View file

@ -0,0 +1,286 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_main.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_main.h $
* $Author: Jwaters $
* $Revision: 2 $
* $Modtime: 8/05/02 5:51p $
* $Date: 8/06/02 6:28p $
*
*****************************************************************************/
#ifndef __AI_MAIN__
#define __AI_MAIN__
//#define DEBUG
#define CTF
//#define MAX_ITEMS 256 // already in q_shared.h
//bot flags
#define BFL_STRAFERIGHT 1 //strafe to the right
#define BFL_ATTACKED 2 //bot has attacked last ai frame
#define BFL_ATTACKJUMPED 4 //bot jumped during attack last frame
#define BFL_AIMATENEMY 8 //bot aimed at the enemy this frame
#define BFL_AVOIDRIGHT 16 //avoid obstacles by going to the right
#define BFL_IDEALVIEWSET 32 //bot has ideal view angles set
#define BFL_FIGHTSUICIDAL 64 //bot is in a suicidal fight
//long term goal types
#define LTG_TEAMHELP 1 //help a team mate
#define LTG_TEAMACCOMPANY 2 //accompany a team mate
#define LTG_DEFENDKEYAREA 3 //defend a key area
#define LTG_GETFLAG 4 //get the enemy flag
#define LTG_RUSHBASE 5 //rush to the base
#define LTG_RETURNFLAG 6 //return the flag
#define LTG_CAMP 7 //camp somewhere
#define LTG_CAMPORDER 8 //ordered to camp somewhere
#define LTG_PATROL 9 //patrol
#define LTG_GETITEM 10 //get an item
#define LTG_KILL 11 //kill someone
#define LTG_HARVEST 12 //harvest skulls
#define LTG_ATTACKENEMYBASE 13 //attack the enemy base
#define LTG_MAKELOVE_UNDER 14
#define LTG_MAKELOVE_ONTOP 15
//some goal dedication times
#define TEAM_HELP_TIME 60 //1 minute teamplay help time
#define TEAM_ACCOMPANY_TIME 600 //10 minutes teamplay accompany time
#define TEAM_DEFENDKEYAREA_TIME 600 //10 minutes ctf defend base time
#define TEAM_CAMP_TIME 600 //10 minutes camping time
#define TEAM_PATROL_TIME 600 //10 minutes patrolling time
#define TEAM_LEAD_TIME 600 //10 minutes taking the lead
#define TEAM_GETITEM_TIME 60 //1 minute
#define TEAM_KILL_SOMEONE 180 //3 minute to kill someone
#define TEAM_ATTACKENEMYBASE_TIME 600 //10 minutes
#define TEAM_HARVEST_TIME 120 //2 minutes
#define CTF_GETFLAG_TIME 600 //10 minutes ctf get flag time
#define CTF_RUSHBASE_TIME 120 //2 minutes ctf rush base time
#define CTF_RETURNFLAG_TIME 180 //3 minutes to return the flag
#define CTF_ROAM_TIME 60 //1 minute ctf roam time
//patrol flags
#define PATROL_LOOP 1
#define PATROL_REVERSE 2
#define PATROL_BACK 4
//teamplay task preference
#define TEAMTP_DEFENDER 1
#define TEAMTP_ATTACKER 2
//CTF strategy
#define CTFS_AGRESSIVE 1
//copied from the aas file header
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//
#define MAX_PROXMINES 64
//check points
typedef struct bot_waypoint_s
{
int inuse;
char name[32];
bot_goal_t goal;
struct bot_waypoint_s *next, *prev;
} bot_waypoint_t;
#define MAX_ACTIVATESTACK 8
#define MAX_ACTIVATEAREAS 32
typedef struct bot_activategoal_s
{
int inuse;
bot_goal_t goal; //goal to activate (buttons etc.)
float time; //time to activate something
float start_time; //time starting to activate something
float justused_time; //time the goal was used
int shoot; //true if bot has to shoot to activate
int weapon; //weapon to be used for activation
vec3_t target; //target to shoot at to activate something
vec3_t origin; //origin of the blocking entity to activate
int areas[MAX_ACTIVATEAREAS]; //routing areas disabled by blocking entity
int numareas; //number of disabled routing areas
int areasdisabled; //true if the areas are disabled for the routing
struct bot_activategoal_s *next; //next activate goal on stack
} bot_activategoal_t;
//bot state
typedef struct bot_state_s
{
int inuse; //true if this state is used by a bot client
int botthink_residual; //residual for the bot thinks
int client; //client number of the bot
int entitynum; //entity number of the bot
playerState_t cur_ps; //current player state
int last_eFlags; //last ps flags
usercmd_t lastucmd; //usercmd from last frame
int entityeventTime[1024]; //last entity event time
//
bot_settings_t settings; //several bot settings
int (*ainode)(struct bot_state_s *bs); //current AI node
float thinktime; //time the bot thinks this frame
vec3_t origin; //origin of the bot
vec3_t velocity; //velocity of the bot
int presencetype; //presence type of the bot
vec3_t eye; //eye coordinates of the bot
int areanum; //the number of the area the bot is in
int inventory[256]; // was MAX_INVENTORY, but they have different defs in bot code FIXME //string with items amounts the bot has
int tfl; //the travel flags the bot uses
int flags; //several flags
int respawn_wait; //wait until respawned
int lasthealth; //health value previous frame
int lastkilledplayer; //last killed player
int lastkilledby; //player that last killed this bot
int botdeathtype; //the death type of the bot
int enemydeathtype; //the death type of the enemy
int botsuicide; //true when the bot suicides
int enemysuicide; //true when the enemy of the bot suicides
int setupcount; //true when the bot has just been setup
int map_restart; //true when the map is being restarted
int entergamechat; //true when the bot used an enter game chat
int num_deaths; //number of time this bot died
int num_kills; //number of kills of this bot
int revenge_enemy; //the revenge enemy
int revenge_kills; //number of kills the enemy made
int lastframe_health; //health value the last frame
int lasthitcount; //number of hits last frame
int chatto; //chat to all or team
float walker; //walker charactertic
float ltime; //local bot time
float entergame_time; //time the bot entered the game
float ltg_time; //long term goal time
float nbg_time; //nearby goal time
float respawn_time; //time the bot takes to respawn
float respawnchat_time; //time the bot started a chat during respawn
float chase_time; //time the bot will chase the enemy
float enemyvisible_time; //time the enemy was last visible
float check_time; //time to check for nearby items
float stand_time; //time the bot is standing still
float lastchat_time; //time the bot last selected a chat
float kamikaze_time; //time to check for kamikaze usage
float invulnerability_time; //time to check for invulnerability usage
float standfindenemy_time; //time to find enemy while standing
float attackstrafe_time; //time the bot is strafing in one dir
float attackcrouch_time; //time the bot will stop crouching
float attackchase_time; //time the bot chases during actual attack
float attackjump_time; //time the bot jumped during attack
float enemysight_time; //time before reacting to enemy
float enemydeath_time; //time the enemy died
float enemyposition_time; //time the position and velocity of the enemy were stored
float defendaway_time; //time away while defending
float defendaway_range; //max travel time away from defend area
float rushbaseaway_time; //time away from rushing to the base
float attackaway_time; //time away from attacking the enemy base
float harvestaway_time; //time away from harvesting
float ctfroam_time; //time the bot is roaming in ctf
float killedenemy_time; //time the bot killed the enemy
float arrive_time; //time arrived (at companion)
float lastair_time; //last time the bot had air
float teleport_time; //last time the bot teleported
float camp_time; //last time camped
float camp_range; //camp range
float weaponchange_time; //time the bot started changing weapons
float firethrottlewait_time; //amount of time to wait
float firethrottleshoot_time; //amount of time to shoot
float notblocked_time; //last time the bot was not blocked
float blockedbyavoidspot_time; //time blocked by an avoid spot
float predictobstacles_time; //last time the bot predicted obstacles
int predictobstacles_goalareanum; //last goal areanum the bot predicted obstacles for
vec3_t aimtarget;
vec3_t enemyvelocity; //enemy velocity 0.5 secs ago during battle
vec3_t enemyorigin; //enemy origin 0.5 secs ago during battle
//
int kamikazebody; //kamikaze body
int proxmines[MAX_PROXMINES];
int numproxmines;
//
int character; //the bot character
int ms; //move state of the bot
int gs; //goal state of the bot
int cs; //chat state of the bot
int ws; //weapon state of the bot
//
int enemy; //enemy entity number
int lastenemyareanum; //last reachability area the enemy was in
vec3_t lastenemyorigin; //last origin of the enemy in the reachability area
int weaponnum; //current weapon number
vec3_t viewangles; //current view angles
vec3_t ideal_viewangles; //ideal view angles
vec3_t viewanglespeed;
//
int ltgtype; //long term goal type
// team goals
int teammate; //team mate involved in this team goal
int decisionmaker; //player who decided to go for this goal
int ordered; //true if ordered to do something
float order_time; //time ordered to do something
int owndecision_time; //time the bot made it's own decision
bot_goal_t teamgoal; //the team goal
bot_goal_t altroutegoal; //alternative route goal
float reachedaltroutegoal_time; //time the bot reached the alt route goal
float teammessage_time; //time to message team mates what the bot is doing
float teamgoal_time; //time to stop helping team mate
float teammatevisible_time; //last time the team mate was NOT visible
int teamtaskpreference; //team task preference
// last ordered team goal
int lastgoal_decisionmaker;
int lastgoal_ltgtype;
int lastgoal_teammate;
bot_goal_t lastgoal_teamgoal;
// for leading team mates
int lead_teammate; //team mate the bot is leading
bot_goal_t lead_teamgoal; //team goal while leading
float lead_time; //time leading someone
float leadvisible_time; //last time the team mate was visible
float leadmessage_time; //last time a messaged was sent to the team mate
float leadbackup_time; //time backing up towards team mate
//
char teamleader[32]; //netname of the team leader
float askteamleader_time; //time asked for team leader
float becometeamleader_time; //time the bot will become the team leader
float teamgiveorders_time; //time to give team orders
float lastflagcapture_time; //last time a flag was captured
int numteammates; //number of team mates
int redflagstatus; //0 = at base, 1 = not at base
int blueflagstatus; //0 = at base, 1 = not at base
int neutralflagstatus; //0 = at base, 1 = our team has flag, 2 = enemy team has flag, 3 = enemy team dropped the flag
int flagstatuschanged; //flag status changed
int forceorders; //true if forced to give orders
int flagcarrier; //team mate carrying the enemy flag
int ctfstrategy; //ctf strategy
char subteam[32]; //sub team name
float formation_dist; //formation team mate intervening space
char formation_teammate[16]; //netname of the team mate the bot uses for relative positioning
float formation_angle; //angle relative to the formation team mate
vec3_t formation_dir; //the direction the formation is moving in
vec3_t formation_origin; //origin the bot uses for relative positioning
bot_goal_t formation_goal; //formation goal
bot_activategoal_t *activatestack; //first activate goal on the stack
bot_activategoal_t activategoalheap[MAX_ACTIVATESTACK]; //activate goal heap
bot_waypoint_t *checkpoints; //check points
bot_waypoint_t *patrolpoints; //patrol points
bot_waypoint_t *curpatrolpoint; //current patrol point the bot is going for
int patrolflags; //patrol flags
} bot_state_t;
//resets the whole bot state
void BotResetState(bot_state_t *bs);
//returns the number of bots in the game
int NumBots(void);
//returns info about the entity
void BotEntityInfo(int entnum, aas_entityinfo_t *info);
extern float floattime;
#define FloatTime() level.time
// from the game source
void QDECL BotAI_Print(int type, char *fmt, ...);
void QDECL QDECL BotAI_BotInitialChat( bot_state_t *bs, char *type, ... );
void BotAI_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
int BotAI_GetClientState( int clientNum, playerState_t *state );
int BotAI_GetEntityState( int entityNum, entityState_t *state );
int BotAI_GetSnapshotEntity( int clientNum, int sequence, entityState_t *state );
int BotTeamLeader(bot_state_t *bs);
#endif // __AI_MAIN__

2087
dlls/game/ai_team.cpp Normal file

File diff suppressed because it is too large Load diff

23
dlls/game/ai_team.h Normal file
View file

@ -0,0 +1,23 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_team.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_team.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 7/25/02 11:48a $
* $Date: 7/30/02 1:10p $
*
*****************************************************************************/
void BotTeamAI(bot_state_t *bs);
int BotGetTeamMateTaskPreference(bot_state_t *bs, int teammate);
void BotSetTeamMateTaskPreference(bot_state_t *bs, int teammate, int preference);
void BotVoiceChat(bot_state_t *bs, int toclient, char *voicechat);
void BotVoiceChatOnly(bot_state_t *bs, int toclient, char *voicechat);

532
dlls/game/ai_vcmd.cpp Normal file
View file

@ -0,0 +1,532 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_vcmd.c
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_vcmd.cpp $
* $Author: Singlis $
* $Revision: 3 $
* $Modtime: 9/13/02 1:22p $
* $Date: 9/13/02 4:32p $
*
*****************************************************************************/
#include "g_local.h"
#include "botlib.h"
#include "be_aas.h"
#include "be_ea.h"
#include "be_ai_char.h"
#include "be_ai_chat.h"
#include "be_ai_gen.h"
#include "be_ai_goal.h"
#include "be_ai_move.h"
#include "be_ai_weap.h"
//
#include "ai_main.h"
#include "ai_dmq3.h"
#include "ai_chat.h"
#include "ai_cmd.h"
#include "ai_dmnet.h"
#include "ai_team.h"
#include "ai_vcmd.h"
//
#include "chars.h" //characteristics
#include "inv.h" //indexes into the inventory
#include "syn.h" //synonyms
#include "match.h" //string matching types and vars
// for the voice chats
#include "botmenudef.h"
typedef struct voiceCommand_s
{
char *cmd;
void (*func)(bot_state_t *bs, int client, int mode);
} voiceCommand_t;
/*
==================
BotVoiceChat_GetFlag
==================
*/
void BotVoiceChat_GetFlag(bot_state_t *bs, int client, int mode) {
//
if (gametype == GT_CTF) {
if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
return;
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum)
return;
}
#endif
else {
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_GETFLAG;
//set the team goal time
bs->teamgoal_time = FloatTime() + CTF_GETFLAG_TIME;
// get an alternate route in ctf
if (gametype == GT_CTF) {
//get an alternative route goal towards the enemy base
BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
}
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_Offense
==================
*/
void BotVoiceChat_Offense(bot_state_t *bs, int client, int mode) {
if ( gametype == GT_CTF
#ifdef MISSIONPACK
|| gametype == GT_1FCTF
#endif
) {
BotVoiceChat_GetFlag(bs, client, mode);
return;
}
#ifdef MISSIONPACK
if (gametype == GT_HARVESTER) {
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_HARVEST;
//set the team goal time
bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
bs->harvestaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
}
else
#endif
{
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_ATTACKENEMYBASE;
//set the team goal time
bs->teamgoal_time = FloatTime() + TEAM_ATTACKENEMYBASE_TIME;
bs->attackaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
}
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_Defend
==================
*/
void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode) {
#ifdef MISSIONPACK
if ( gametype == GT_OBELISK || gametype == GT_HARVESTER) {
//
switch(BotTeam(bs)) {
case TEAM_RED: memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t)); break;
case TEAM_BLUE: memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t)); break;
default: return;
}
}
else
#endif
if (gametype == GT_CTF
#ifdef MISSIONPACK
|| gametype == GT_1FCTF
#endif
) {
//
switch(BotTeam(bs)) {
case TEAM_RED: memcpy(&bs->teamgoal, &ctf_redflag, sizeof(bot_goal_t)); break;
case TEAM_BLUE: memcpy(&bs->teamgoal, &ctf_blueflag, sizeof(bot_goal_t)); break;
default: return;
}
}
else {
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_DEFENDKEYAREA;
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME;
//away from defending
bs->defendaway_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_DefendFlag
==================
*/
void BotVoiceChat_DefendFlag(bot_state_t *bs, int client, int mode) {
BotVoiceChat_Defend(bs, client, mode);
}
/*
==================
BotVoiceChat_Patrol
==================
*/
void BotVoiceChat_Patrol(bot_state_t *bs, int client, int mode) {
//
bs->decisionmaker = client;
//
bs->ltgtype = 0;
bs->lead_time = 0;
bs->lastgoal_ltgtype = 0;
//
BotAI_BotInitialChat(bs, "dismissed", NULL);
gi.BotEnterChat(bs->cs, client, CHAT_TELL);
BotVoiceChatOnly(bs, -1, VOICECHAT_ONPATROL);
//
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_Camp
==================
*/
void BotVoiceChat_Camp(bot_state_t *bs, int client, int mode) {
int areanum;
aas_entityinfo_t entinfo;
char netname[MAX_NETNAME];
//
bs->teamgoal.entitynum = -1;
BotEntityInfo(client, &entinfo);
//if info is valid (in PVS)
if (entinfo.valid) {
areanum = BotPointAreaNum(entinfo.origin);
if (areanum) { // && gi.AAS_AreaReachability(areanum)) {
//NOTE: just assume the bot knows where the person is
//if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, client)) {
bs->teamgoal.entitynum = client;
bs->teamgoal.areanum = areanum;
VectorCopy(entinfo.origin, bs->teamgoal.origin);
VectorSet(bs->teamgoal.mins, -8, -8, -8);
VectorSet(bs->teamgoal.maxs, 8, 8, 8);
//}
}
}
//if the other is not visible
if (bs->teamgoal.entitynum < 0) {
BotAI_BotInitialChat(bs, "whereareyou", EasyClientName(client, netname, sizeof(netname)), NULL);
gi.BotEnterChat(bs->cs, client, CHAT_TELL);
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_CAMPORDER;
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_CAMP_TIME;
//the teammate that requested the camping
bs->teammate = client;
//not arrived yet
bs->arrive_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_FollowMe
==================
*/
void BotVoiceChat_FollowMe(bot_state_t *bs, int client, int mode) {
int areanum;
aas_entityinfo_t entinfo;
char netname[MAX_NETNAME];
bs->teamgoal.entitynum = -1;
BotEntityInfo(client, &entinfo);
//if info is valid (in PVS)
if (entinfo.valid) {
areanum = BotPointAreaNum(entinfo.origin);
if (areanum) { // && gi.AAS_AreaReachability(areanum)) {
bs->teamgoal.entitynum = client;
bs->teamgoal.areanum = areanum;
VectorCopy(entinfo.origin, bs->teamgoal.origin);
VectorSet(bs->teamgoal.mins, -8, -8, -8);
VectorSet(bs->teamgoal.maxs, 8, 8, 8);
}
}
//if the other is not visible
if (bs->teamgoal.entitynum < 0) {
BotAI_BotInitialChat(bs, "whereareyou", EasyClientName(client, netname, sizeof(netname)), NULL);
gi.BotEnterChat(bs->cs, client, CHAT_TELL);
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//the team mate
bs->teammate = client;
//last time the team mate was assumed visible
bs->teammatevisible_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME;
//set the ltg type
bs->ltgtype = LTG_TEAMACCOMPANY;
bs->formation_dist = 3.5 * 32; //3.5 meter
bs->arrive_time = 0;
//
BotSetTeamStatus(bs);
// remember last ordered task
BotRememberLastOrderedTask(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_FollowFlagCarrier
==================
*/
void BotVoiceChat_FollowFlagCarrier(bot_state_t *bs, int client, int mode) {
int carrier;
carrier = BotTeamFlagCarrier(bs);
if (carrier >= 0)
BotVoiceChat_FollowMe(bs, carrier, mode);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_ReturnFlag
==================
*/
void BotVoiceChat_ReturnFlag(bot_state_t *bs, int client, int mode) {
//if not in CTF mode
if (
gametype != GT_CTF
#ifdef MISSIONPACK
&& gametype != GT_1FCTF
#endif
) {
return;
}
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_RETURNFLAG;
//set the team goal time
bs->teamgoal_time = FloatTime() + CTF_RETURNFLAG_TIME;
bs->rushbaseaway_time = 0;
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotVoiceChat_StartLeader
==================
*/
void BotVoiceChat_StartLeader(bot_state_t *bs, int client, int mode) {
ClientName(client, bs->teamleader, sizeof(bs->teamleader));
}
/*
==================
BotVoiceChat_StopLeader
==================
*/
void BotVoiceChat_StopLeader(bot_state_t *bs, int client, int mode) {
char netname[MAX_MESSAGE_SIZE];
if (!Q_stricmp(bs->teamleader, ClientName(client, netname, sizeof(netname)))) {
bs->teamleader[0] = '\0';
notleader[client] = qtrue;
}
}
/*
==================
BotVoiceChat_WhoIsLeader
==================
*/
void BotVoiceChat_WhoIsLeader(bot_state_t *bs, int client, int mode) {
char netname[MAX_MESSAGE_SIZE];
if (!TeamPlayIsOn()) return;
ClientName(bs->client, netname, sizeof(netname));
//if this bot IS the team leader
if (!Q_stricmp(netname, bs->teamleader)) {
BotAI_BotInitialChat(bs, "iamteamleader", NULL);
gi.BotEnterChat(bs->cs, 0, CHAT_TEAM);
BotVoiceChatOnly(bs, -1, VOICECHAT_STARTLEADER);
}
}
/*
==================
BotVoiceChat_WantOnDefense
==================
*/
void BotVoiceChat_WantOnDefense(bot_state_t *bs, int client, int mode) {
char netname[MAX_NETNAME];
int preference;
preference = BotGetTeamMateTaskPreference(bs, client);
preference &= ~TEAMTP_ATTACKER;
preference |= TEAMTP_DEFENDER;
BotSetTeamMateTaskPreference(bs, client, preference);
//
EasyClientName(client, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
gi.BotEnterChat(bs->cs, client, CHAT_TELL);
BotVoiceChatOnly(bs, client, VOICECHAT_YES);
gi.EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
/*
==================
BotVoiceChat_WantOnOffense
==================
*/
void BotVoiceChat_WantOnOffense(bot_state_t *bs, int client, int mode) {
char netname[MAX_NETNAME];
int preference;
preference = BotGetTeamMateTaskPreference(bs, client);
preference &= ~TEAMTP_DEFENDER;
preference |= TEAMTP_ATTACKER;
BotSetTeamMateTaskPreference(bs, client, preference);
//
EasyClientName(client, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
gi.BotEnterChat(bs->cs, client, CHAT_TELL);
BotVoiceChatOnly(bs, client, VOICECHAT_YES);
gi.EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
void BotVoiceChat_Dummy(bot_state_t *bs, int client, int mode) {
}
voiceCommand_t voiceCommands[] = {
{VOICECHAT_GETFLAG, BotVoiceChat_GetFlag},
{VOICECHAT_OFFENSE, BotVoiceChat_Offense },
{VOICECHAT_DEFEND, BotVoiceChat_Defend },
{VOICECHAT_DEFENDFLAG, BotVoiceChat_DefendFlag },
{VOICECHAT_PATROL, BotVoiceChat_Patrol },
{VOICECHAT_CAMP, BotVoiceChat_Camp },
{VOICECHAT_FOLLOWME, BotVoiceChat_FollowMe },
{VOICECHAT_FOLLOWFLAGCARRIER, BotVoiceChat_FollowFlagCarrier },
{VOICECHAT_RETURNFLAG, BotVoiceChat_ReturnFlag },
{VOICECHAT_STARTLEADER, BotVoiceChat_StartLeader },
{VOICECHAT_STOPLEADER, BotVoiceChat_StopLeader },
{VOICECHAT_WHOISLEADER, BotVoiceChat_WhoIsLeader },
{VOICECHAT_WANTONDEFENSE, BotVoiceChat_WantOnDefense },
{VOICECHAT_WANTONOFFENSE, BotVoiceChat_WantOnOffense },
{NULL, BotVoiceChat_Dummy}
};
int BotVoiceChatCommand(bot_state_t *bs, int mode, char *voiceChat) {
int i, clientNum;
char *ptr, buf[MAX_MESSAGE_SIZE], *cmd,*cmd2;
if (!TeamPlayIsOn()) {
return qfalse;
}
if ( mode == SAY_ALL ) {
return qfalse;
}
Q_strncpyz(buf, voiceChat, sizeof(buf));
cmd = buf;
ptr = strchr(buf,' ');
*ptr++ = 0;
clientNum = atoi(ptr);
cmd2 = ptr+2;
ptr = strchr(cmd2,' ');
*ptr = 0;
if (!BotSameTeam(bs, clientNum)) {
return qfalse;
}
for (i = 0; voiceCommands[i].cmd; i++) {
if (!Q_stricmp(cmd2, voiceCommands[i].cmd)) {
voiceCommands[i].func(bs, clientNum, mode);
return qtrue;
}
}
return qfalse;
}

20
dlls/game/ai_vcmd.h Normal file
View file

@ -0,0 +1,20 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: ai_vcmd.h
*
* desc: Quake3 bot AI
*
* $Archive: /Code/DLLs/game/ai_vcmd.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 7/25/02 11:48a $
* $Date: 7/30/02 1:10p $
*
*****************************************************************************/
int BotVoiceChatCommand(bot_state_t *bs, int mode, char *voicechat);
void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode);

175
dlls/game/ammo.cpp Normal file
View file

@ -0,0 +1,175 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/ammo.cpp $
// $Revision:: 15 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:35p $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Base class for all ammunition for entities derived from the Weapon class.
//
// AmmoEntity is the Class which represents ammo that the player "sees" and "
// picks up" in the game
//
// Ammo is the Class which is used to keep track of how much ammo a player has
// in his inventory
#include "_pch_cpp.h"
#include "ammo.h"
#include "player.h"
CLASS_DECLARATION( Item, AmmoEntity, NULL )
{
{ NULL, NULL }
};
AmmoEntity::AmmoEntity()
{
if ( LoadingSavegame )
{
// all data will be setup by the archive function
return;
}
setName( "UnknownAmmo" );
amount = 0;
_lastPrintTime = 0.0f;
}
Item *AmmoEntity::ItemPickup( Entity *other, qboolean add_to_inventory, qboolean )
{
Sentient *player;
str realname;
int amountUsed;
if ( !other->isSubclassOf( Player ) )
return NULL;
if ( !Pickupable( other ) )
return NULL;
player = ( Sentient * )other;
// Give the ammo to the player
amountUsed = player->GiveAmmo( item_name, (int) amount, true );
if ( amountUsed == 0 )
{
if ( level.time > _lastPrintTime + 1.0f )
{
_lastPrintTime = level.time;
((Player *)other)->setItemText( getIcon(), va( "$$CouldNotPickUp$$ $$Ammo-%s$$ $$FullAmmo$$", item_name.c_str() ) );
//gi.centerprintf ( other->edict, CENTERPRINT_IMPORTANCE_NORMAL, "$$CouldNotPickUp$$ %s $$FullAmmo$$", item_name.c_str() );
}
return NULL;
}
// Play pickup sound
realname = GetRandomAlias( "snd_pickup" );
if ( realname.length() > 1 )
player->Sound( realname, CHAN_ITEM );
// Cancel some events
CancelEventsOfType( EV_Item_DropToFloor );
CancelEventsOfType( EV_Item_Respawn );
CancelEventsOfType( EV_FadeOut );
// Hide the model
setSolidType( SOLID_NOT );
if ( _missingSkin )
{
ChangeSkin( _missingSkin, true );
}
else
{
hideModel();
}
// Respawn?
if ( !Respawnable() )
PostEvent( EV_Remove, FRAMETIME );
else
PostEvent( EV_Item_Respawn, RespawnTime() );
// fire off any pickup_thread's
if ( pickup_thread.length() )
{
ExecuteThread( pickup_thread );
}
return NULL; // This doesn't create any items
}
void AmmoEntity::cacheStrings( void )
{
G_FindConfigstringIndex( va( "$$CouldNotPickUp$$ $$Ammo-%s$$ $$FullAmmo$$", item_name.c_str() ), CS_GENERAL_STRINGS, MAX_GENERAL_STRINGS, true );
G_FindConfigstringIndex( va( "$$PickedUp$$ %d $$Ammo-%s$$\n", (int)amount, item_name.c_str() ), CS_GENERAL_STRINGS, MAX_GENERAL_STRINGS, true );
}
// This is the Class that is used to keep track of ammo in the player's inventory.
// It is not an entity, just a name and an amount.
CLASS_DECLARATION( Class, Ammo, NULL )
{
{NULL, NULL}
};
Ammo::Ammo()
{
if ( LoadingSavegame )
{
// all data will be setup by the archive function
return;
}
setName( "UnknownAmmo" );
setAmount( 0 );
setMaxAmount( 100 );
}
void Ammo::setAmount( int a )
{
amount = a;
if ( ( maxamount > 0 ) && ( amount > maxamount ) )
amount = maxamount;
}
int Ammo::getAmount( void )
{
return amount;
}
void Ammo::setMaxAmount( int a )
{
maxamount = a;
}
int Ammo::getMaxAmount( void )
{
return maxamount;
}
void Ammo::setName( const str &n )
{
name = n;
name_index = gi.itemindex( name );
}
str Ammo::getName( void )
{
return name;
}
int Ammo::getIndex( void )
{
return name_index;
}

89
dlls/game/ammo.h Normal file
View file

@ -0,0 +1,89 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/ammo.h $
// $Revision:: 6 $
// $Author:: Steven $
// $Date:: 2/14/03 5:37p $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
// Base class for all ammunition for entities derived from the Weapon class.
//
#ifndef __AMMO_H__
#define __AMMO_H__
#include "g_local.h"
#include "item.h"
class AmmoEntity : public Item
{
private:
float _lastPrintTime;
public:
CLASS_PROTOTYPE( AmmoEntity );
AmmoEntity();
/* virtual */ Item * ItemPickup( Entity *other, qboolean add_to_inventory, qboolean );
/* virtual */ void cacheStrings( void );
/* virtual */ void Archive( Archiver &arc );
};
inline void AmmoEntity::Archive( Archiver &arc )
{
Item::Archive( arc );
arc.ArchiveFloat( &_lastPrintTime );
}
class Ammo : public Class
{
int amount;
int maxamount;
str name;
int name_index;
public:
CLASS_PROTOTYPE( Ammo );
Ammo();
Ammo(const str &name, int amount, int name_index );
void setAmount( int a );
int getAmount( void );
void setMaxAmount( int a );
int getMaxAmount( void );
void setName( const str &name );
str getName( void );
int getIndex( void );
virtual void Archive( Archiver &arc );
};
inline void Ammo::Archive
(
Archiver &arc
)
{
Class::Archive( arc );
arc.ArchiveInteger( &amount );
arc.ArchiveInteger( &maxamount );
arc.ArchiveString( &name );
//
// name_index not archived, because it is auto-generated by gi.itemindex
//
if ( arc.Loading() )
{
setName( name );
}
}
#endif /* ammo.h */

1010
dlls/game/animate.cpp Normal file

File diff suppressed because it is too large Load diff

330
dlls/game/animate.h Normal file
View file

@ -0,0 +1,330 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/animate.h $
// $Revision:: 10 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Animate class
//
#ifndef __ANIMATE_H__
#define __ANIMATE_H__
#include "g_local.h"
#ifndef __ENTITY_H__
#include "entity.h"
#endif
extern Event EV_SetFrame;
extern Event EV_StopAnimating;
extern Event EV_Torso_StopAnimating;
#define MINIMUM_DELTA_MOVEMENT 8.0f
#define MINIMUM_DELTA_MOVEMENT_PER_FRAME ( MINIMUM_DELTA_MOVEMENT / 20.0f )
class Animate;
class Entity;
typedef SafePtr<Animate> AnimatePtr;
class Animate : public Listener
{
private:
Event *animDoneEvent;
Event *torso_animDoneEvent;
float legs_animtime;
float torso_animtime;
float legs_starttime;
float torso_starttime;
float legs_frametime;
float torso_frametime;
int legs_numframes;
int torso_numframes;
str currentAnim;
float oldAnimationRate;
Entity *self;
void FrameDeltaEvent( Event *ev );
void EndAnim( bodypart_t part );
void Legs_AnimDoneEvent( Event *ev );
void Legs_AnimEvent( Event *ev );
void Legs_SetFrameEvent( Event *ev );
void Legs_StopAnimating( Event *ev );
void Torso_AnimDoneEvent( Event *ev );
void Torso_AnimEvent( Event *ev );
void Torso_SetFrameEvent( Event *ev );
void Torso_StopAnimating( Event *ev );
void NewAnimEvent( Event *ev );
public:
// Animation variables
Vector frame_delta; // current movement from this frame
CLASS_PROTOTYPE( Animate );
Animate();
Animate( Entity * ent );
~Animate();
void RandomAnimate( const char *animname, Event *endevent = NULL, bodypart_t part = legs );
void RandomAnimate( const char *animname, const Event &endevent, bodypart_t part = legs );
void SetAnimationRate( const float animationRate );
void RestoreAnimationRate( void );
void NewAnim( int animnum, bodypart_t part = legs );
void NewAnim( int animnum, Event *endevent, bodypart_t part = legs );
void NewAnim( int animnum, Event &endevent, bodypart_t part = legs );
void SetFrame( int framenum, bodypart_t part = legs, int anim = -1 );
qboolean HasAnim( const char *animname );
Event *AnimDoneEvent( bodypart_t part = legs );
void SetAnimDoneEvent( const Event &event, bodypart_t part = legs );
void SetAnimDoneEvent( Event *event, bodypart_t part = legs );
int NumFrames( bodypart_t part = legs );
int NumAnims( void );
const char *AnimName( bodypart_t part = legs );
float AnimTime( bodypart_t part = legs );
str GetName();
void ClearLegsAnim( void );
void ClearTorsoAnim( void );
virtual void StopAnimating( bodypart_t part = legs );
virtual void StopAnimatingAtEnd( bodypart_t part = legs );
virtual int CurrentAnim( bodypart_t part = legs );
virtual int CurrentFrame( bodypart_t part = legs );
virtual void AddEffectAnim( const char *animName );
virtual void RemoveEffectAnim( const char *animName );
virtual void ClearAllEffectAnims( void );
virtual void Archive( Archiver &arc );
};
inline void Animate::RandomAnimate
(
const char *animname,
const Event &endevent,
bodypart_t part
)
{
Event *ev;
ev = new Event( endevent );
RandomAnimate( animname, ev, part );
}
inline int Animate::CurrentAnim
(
bodypart_t part
)
{
switch( part )
{
case legs:
if ( self->edict->s.anim & ANIM_BLEND )
return self->edict->s.anim & ANIM_MASK;
else
return -1;
break;
case torso:
if ( self->edict->s.torso_anim & ANIM_BLEND )
return self->edict->s.torso_anim & ANIM_MASK;
else
return -1;
break;
default:
warning( "CurrentAnim", "Unknown body part %d", part );
return -1;
break;
}
}
inline int Animate::CurrentFrame
(
bodypart_t part
)
{
int frame;
switch( part )
{
case legs:
if ( self->edict->s.frame & FRAME_EXPLICIT )
{
frame = self->edict->s.frame & FRAME_MASK;
}
else
{
if ( legs_numframes )
{
frame = ( int )( ( float )( ( level.time - legs_starttime ) * legs_numframes ) / legs_animtime + 0.5f );
while ( frame >= legs_numframes )
frame -= legs_numframes;
}
else
{
frame = 0;
}
}
break;
case torso:
if ( self->edict->s.torso_frame & FRAME_EXPLICIT )
{
frame = self->edict->s.torso_frame & FRAME_MASK;
}
else
{
if ( torso_numframes )
{
frame = ( int )( ( float )( ( level.time - torso_starttime ) * torso_numframes ) / torso_animtime + 0.5f );
while ( frame >= torso_numframes )
frame -= torso_numframes;
}
else
{
frame = 0;
}
}
break;
default:
warning( "CurrentFrame", "Unknown body part %d", part );
frame = 0;
break;
}
return frame;
}
inline int Animate::NumFrames
(
bodypart_t part
)
{
switch( part )
{
case legs:
return legs_numframes;
break;
case torso:
return torso_numframes;
break;
default:
warning( "NumFrames", "Unknown body part %d", part );
return 0;
break;
}
}
inline float Animate::AnimTime
(
bodypart_t part
)
{
switch( part )
{
case legs:
return legs_animtime;
break;
case torso:
return torso_animtime;
break;
default:
warning( "AnimTime", "Unknown body part %d", part );
return 0;
break;
}
}
inline int Animate::NumAnims
(
void
)
{
return gi.NumAnims( self->edict->s.modelindex );
}
inline const char *Animate::AnimName
(
bodypart_t part
)
{
switch( part )
{
case legs:
return gi.Anim_NameForNum( self->edict->s.modelindex, CurrentAnim( part ) );
break;
case torso:
return gi.Anim_NameForNum( self->edict->s.modelindex, CurrentAnim( part ) );
break;
default:
warning( "AnimName", "Unknown body part %d", part );
return NULL;
break;
}
}
inline Event * Animate::AnimDoneEvent
(
bodypart_t part
)
{
switch( part )
{
case legs:
if ( animDoneEvent )
return new Event( animDoneEvent );
else
return NULL;
break;
case torso:
if ( torso_animDoneEvent )
return new Event( torso_animDoneEvent );
else
return NULL;
break;
default:
warning( "AnimDoneEvent", "Unknown body part %d", part );
return NULL;
break;
}
}
inline void Animate::Archive( Archiver &arc )
{
Listener::Archive( arc );
arc.ArchiveEventPointer( &animDoneEvent );
arc.ArchiveEventPointer( &torso_animDoneEvent );
arc.ArchiveFloat( &legs_animtime );
arc.ArchiveFloat( &torso_animtime );
arc.ArchiveFloat( &legs_starttime );
arc.ArchiveFloat( &torso_starttime );
arc.ArchiveFloat( &legs_frametime );
arc.ArchiveFloat( &torso_frametime );
arc.ArchiveInteger( &legs_numframes );
arc.ArchiveInteger( &torso_numframes );
arc.ArchiveString( &currentAnim );
arc.ArchiveFloat( &oldAnimationRate );
arc.ArchiveVector( &frame_delta );
}
#endif /* animate.h */

1027
dlls/game/archive.cpp Normal file

File diff suppressed because it is too large Load diff

489
dlls/game/archive.h Normal file
View file

@ -0,0 +1,489 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/archive.h $
// $Revision:: 5 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Class for archiving objects
//
#ifndef __ARCHIVE_H__
#define __ARCHIVE_H__
#include "g_local.h"
#include "class.h"
#include "str.h"
#define ARCHIVE_NULL_POINTER ( -654321 )
#define ARCHIVE_POINTER_VALID ( 0 )
#define ARCHIVE_POINTER_NULL ( ARCHIVE_NULL_POINTER )
#define ARCHIVE_POINTER_SELF_REFERENTIAL ( -123456 )
#define ARCHIVE_WRITE 0
#define ARCHIVE_READ 1
typedef SafePtr<Entity> EntityPtr;
enum
{
pointer_fixup_normal,
pointer_fixup_safe
};
typedef struct
{
void **ptr;
int index;
int type;
} pointer_fixup_t;
class FileRead : public Class
{
protected:
str filename;
size_t length;
byte *buffer;
byte *pos;
public:
CLASS_PROTOTYPE( FileRead );
FileRead();
~FileRead();
void Close( void );
const char *Filename( void );
size_t Length( void );
size_t Pos( void );
qboolean Seek( size_t newpos );
qboolean Open( const char *name );
qboolean Read( void *dest, size_t size );
};
class Archiver : public Class
{
private:
Container<Class *> classpointerList;
Container<pointer_fixup_t *> fixupList;
protected:
str filename;
qboolean fileerror;
fileHandle_t file;
FileRead readfile;
int archivemode;
int numclassespos;
qboolean harderror;
void CheckRead( void );
void CheckType( int type );
int ReadType( void );
size_t ReadSize( void );
void CheckSize( int type, size_t size );
void ArchiveData( int type, void *data, size_t size );
void CheckWrite( void );
void WriteType( int type );
void WriteSize( size_t size );
public:
CLASS_PROTOTYPE( Archiver );
Archiver();
~Archiver();
void FileError( const char *fmt, ... );
void Close( void );
qboolean Read( const str &name, qboolean file_harderror = true );
qboolean Read( const char *name, qboolean file_harderror = true );
Class *ReadObject( void );
qboolean Create( const str &name, qboolean file_harderror = true );
qboolean Create( const char *name, qboolean file_harderror = true );
qboolean Loading( void );
qboolean Saving( void );
qboolean NoErrors( void );
void ArchiveVector( Vector * vec );
void ArchiveQuat( Quat * quat );
void ArchiveInteger( int * num );
void ArchiveUnsigned( unsigned * unum);
void ArchiveByte( byte * num );
void ArchiveChar( char * ch );
void ArchiveShort( short * num );
void ArchiveUnsignedShort( unsigned short * num );
void ArchiveFloat( float * num );
void ArchiveDouble( double * num );
void ArchiveBoolean( qboolean * boolean );
void ArchiveString( str * string );
void ArchiveObjectPointer( Class ** ptr );
void ArchiveSafePointer( SafePtrBase * ptr );
void ArchiveEvent( Event * ev );
void ArchiveEventPointer( Event ** ev );
void ArchiveBool( bool * boolean );
void ArchiveVec3( vec3_t vec );
void ArchiveVec4( vec4_t vec );
void ArchiveRaw( void *data, size_t size );
void ArchiveObject( Class *obj );
};
inline qboolean Archiver::Read
(
const str &name,
qboolean file_harderror
)
{
return Read( name.c_str(), file_harderror );
}
inline qboolean Archiver::Create
(
const str &name,
qboolean file_harderror
)
{
return Create( name.c_str(), file_harderror );
}
inline qboolean Archiver::Loading
(
void
)
{
return ( archivemode == ARCHIVE_READ );
}
inline qboolean Archiver::Saving
(
void
)
{
return ( archivemode == ARCHIVE_WRITE );
}
inline qboolean Archiver::NoErrors
(
void
)
{
return ( !fileerror );
}
inline void Container<str>::Archive
(
Archiver &arc
)
{
int i, num;
if ( arc.Loading() )
{
ClearObjectList();
arc.ArchiveInteger( &num );
Resize( num );
}
else
{
num = numobjects;
arc.ArchiveInteger( &num );
}
for( i = 1; i <= num; i++ )
{
arc.ArchiveString( AddressOfObjectAt( i ) );
}
}
inline void Container<Vector>::Archive
(
Archiver &arc
)
{
int i, num;
if ( arc.Loading() )
{
ClearObjectList();
arc.ArchiveInteger( &num );
Resize( num );
}
else
{
num = numobjects;
arc.ArchiveInteger( &num );
}
for( i = 1; i <= num; i++ )
{
arc.ArchiveVector( AddressOfObjectAt( i ) );
}
}
inline void Container<int>::Archive
(
Archiver &arc
)
{
int i, num;
if ( arc.Loading() )
{
ClearObjectList();
arc.ArchiveInteger( &num );
Resize( num );
}
else
{
num = numobjects;
arc.ArchiveInteger( &num );
}
for( i = 1; i <= num; i++ )
{
arc.ArchiveInteger( AddressOfObjectAt( i ) );
}
}
inline void Container<float>::Archive
(
Archiver &arc
)
{
int i, num;
if ( arc.Loading() )
{
ClearObjectList();
arc.ArchiveInteger( &num );
Resize( num );
}
else
{
num = numobjects;
arc.ArchiveInteger( &num );
}
for( i = 1; i <= num; i++ )
{
arc.ArchiveFloat( AddressOfObjectAt( i ) );
}
}
//===============================================================
// Name: Archive
// Class: Container<Class*>
//
// Description: Archive function for a container of Class pointers.
// Note that if the container contains objects deriving
// from Entity, then the Container<Entity*> function
// will get called instead. This will only get called
// if the pointers are to Class or Listener objects.
//
// Parameters: Archiver& -- holds the archive data
//
// Returns: None
//
//===============================================================
inline void Container<Class*>::Archive
(
Archiver &arc
)
{
int numObjects = numobjects ;
arc.ArchiveInteger( &numObjects );
if ( arc.Loading() )
Resize( numObjects );
for ( int objectIdx = 1; objectIdx <= numObjects; ++objectIdx )
{
arc.ArchiveObjectPointer( AddressOfObjectAt( objectIdx ) );
arc.ArchiveObject( ObjectAt( objectIdx ) );
}
}
//===============================================================
// Name: Archive
// Class: Container<Class>
//
// Description: Archive function for a contianer of Class objects
//
// Parameters: Archiver& -- holds the archive data
//
// Returns: None
//
//===============================================================
inline void Container<Class>::Archive
(
Archiver &arc
)
{
int numObjects = numobjects ;
arc.ArchiveInteger( &numObjects );
if ( arc.Loading() )
Resize( numObjects );
for ( int objectIdx = 1; objectIdx <= numObjects; ++objectIdx )
{
arc.ArchiveObject( AddressOfObjectAt( objectIdx ) );
}
}
/*
//===============================================================
// Name: Archive
// Class: Container<SafePtr>
//
// Description: Archive function for a container of Safe pointers.
//
// Parameters: Archiver& -- holds the archive data
//
// Returns: None
//
//===============================================================
inline void Container< SafePtr<Class*> >::Archive
(
Archiver &arc
)
{
int numObjects = numobjects ;
arc.ArchiveInteger( &numObjects );
if ( arc.Loading() )
Resize( numObjects );
for ( int objectIdx = 1; objectIdx <= numObjects; ++objectIdx )
{
SafePtr<Class*> *safePtr = AddressOfObjectAt( objectIdx );
arc.ArchiveSafePointer( ObjectAt( objectIdx ) );
arc.ArchiveObject( ObjectAt( objectIdx ) );
}
}
*/
//===============================================================
// Name: Archive
// Class: Container<Entity*>
//
// Description: Archive function for a container of Entity pointers.
//
// Parameters: Archiver& -- holds the archive data
//
// Returns: None
//
//===============================================================
inline void Container<Entity*>::Archive
(
Archiver &arc
)
{
int numObjects = numobjects ;
arc.ArchiveInteger( &numObjects );
if ( arc.Loading() )
Resize( numObjects );
for ( int objectIdx = 1; objectIdx <= numObjects; ++objectIdx )
{
Entity** entity = AddressOfObjectAt( objectIdx );
arc.ArchiveObjectPointer( (Class**)entity );
}
}
inline void Container<EntityPtr>::Archive
(
Archiver &arc
)
{
int i;
int numEntries;
EntityPtr eptr;
EntityPtr *eptrptr;
if ( arc.Saving() )
{
numEntries = NumObjects();
arc.ArchiveInteger( &numEntries );
for ( i = 1 ; i <= numEntries ; i++ )
{
eptr = ObjectAt( i );
arc.ArchiveSafePointer( &eptr );
}
}
else
{
arc.ArchiveInteger( &numEntries );
ClearObjectList();
Resize( numEntries );
for ( i = 1 ; i <= numEntries ; i++ )
{
AddObject( eptr );
eptrptr = &ObjectAt( i );
arc.ArchiveSafePointer( eptrptr );
}
}
}
/*
//===============================================================
// Name: Archive
// Class: Container<Entity>
//
// Description: Archive function for a container of Entity objects.
//
// Parameters: Archiver& -- holds the archive data
//
// Returns: None
//
//===============================================================
inline void Container<Entity>::Archive
(
Archiver &arc
)
{
int numObjects = numobjects ;
arc.ArchiveInteger( &numObjects );
if ( arc.Loading() )
Resize( numObjects );
for ( int objectIdx = 1; objectIdx <= numObjects; ++objectIdx )
{
arc.ArchiveObject( AddressOfObjectAt( objectIdx ) );
}
}
*/
#define ArchiveEnum( thing, type ) \
{ \
int tempInt; \
\
tempInt = ( int )( thing ); \
arc.ArchiveInteger( &tempInt ); \
( thing ) = ( type )tempInt; \
}
#endif /* archive.h */

1077
dlls/game/armor.cpp Normal file

File diff suppressed because it is too large Load diff

317
dlls/game/armor.h Normal file
View file

@ -0,0 +1,317 @@
//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/armor.h $
// $Revision:: 38 $
// $Author:: Sketcher $
// $Date:: 2/21/03 6:01p $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// Standard armor that prevents a percentage of damage per hit.
//
#ifndef __ARMOR_H__
#define __ARMOR_H__
#include "item.h"
//
// Defines
//
#define ADAPTION_LIMIT 200
#define FX_CHANGE_DELTA 25
//
// Stucture Name: MODHitCounter
//
// Description: Holds mapping of MODs and counts of hits
//
typedef struct
{
int MODIndex;
float damage;
bool adapted;
} MODHitCounter;
//
// Class Name: ArmorEntity
// Base Class: Item
//
// Description: Base Class for all Armor Items
//
class Armor : public Item
{
public:
CLASS_PROTOTYPE( Armor );
Armor();
~Armor();
virtual Item *ItemPickup( Entity *other, qboolean add_to_inventory, qboolean );
virtual float ResolveDamage( float damage , int meansOfDeath , const Vector &direction , const Vector &position , Entity *attacker );
virtual void Archive( Archiver &arc );
virtual bool CanBeDamagedBy( int meansOfDeath );
protected:
virtual qboolean _needThisArmor( Sentient *sentient );
virtual void _pickupArmor( Sentient *sentient );
};
inline void Armor::Archive( Archiver &arc )
{
Item::Archive( arc );
}
//
// Class Name: AdaptiveArmor
// Base Class: ArmorEntity
//
// Description: Armor that adapts to MOD's
//
class AdaptiveArmor : public Armor
{
public:
CLASS_PROTOTYPE( AdaptiveArmor );
AdaptiveArmor();
~AdaptiveArmor();
float ResolveDamage ( float damage , int meansOfDeath , const Vector &direction , const Vector &position , Entity *attacker );
void SetAdaptionFX ( Event *ev );
void SetAdaptionFX ( const str &fxName );
bool CanBeDamagedBy ( int meansOfDeath );
void Archive ( Archiver &arc );
void SetFXLife ( Event *ev );
static void ClearAdaptionList ();
//Game Var Support Functions
void AddGameVar( const str &name , float value );
void UpdateGameVar( const str &name , float value );
void LoadAdaptionData( const str &name );
void LoadDataFromGameVars( Event *ev );
void LoadDataFromGameVars();
protected:
void _AddAdaption ( int MeansOfDeath , float damage );
void _UpdateAdaption ( int MeansOfDeath , float damage );
qboolean _AdaptionInList ( int MeansOfDeath );
float _GetDamageTotal ( int MeansOfDeath );
void _PlayAdaptionFX ( const Vector &direction , const Vector &position );
void _AddMODToCannotAdaptList ( int MOD );
qboolean _CanAdaptTo ( int MOD );
void _changeFX();
private:
static Container<MODHitCounter*> _AdaptionList;
static Container<int> _CannotAdaptToList;
static Container<str> _fxList;
int _currentFXIndex;
str _AdaptionFX;
Vector _currentFXPosition;
float _fxTime;
float _fxTimeNormal;
float _fxTimeExplosive;
float _adaptionLimit;
};
inline void AdaptiveArmor::Archive( Archiver &arc )
{
int num;
MODHitCounter* modHitCounter;
int i;
Armor::Archive( arc );
if ( arc.Loading() )
{
ClearAdaptionList();
_CannotAdaptToList.ClearObjectList();
_fxList.ClearObjectList();
}
if ( arc.Saving() )
{
num = _AdaptionList.NumObjects();
arc.ArchiveInteger( &num );
for( i = 1 ; i <= num ; i++ )
{
modHitCounter = _AdaptionList.ObjectAt( i );
arc.ArchiveInteger( &modHitCounter->MODIndex );
arc.ArchiveFloat( &modHitCounter->damage );
arc.ArchiveBool( &modHitCounter->adapted );
}
}
else
{
arc.ArchiveInteger( &num );
for( i = 1 ; i <= num ; i++ )
{
modHitCounter = new MODHitCounter;
arc.ArchiveInteger( &modHitCounter->MODIndex );
arc.ArchiveFloat( &modHitCounter->damage );
arc.ArchiveBool( &modHitCounter->adapted );
_AdaptionList.AddObject( modHitCounter );
}
}
_CannotAdaptToList.Archive( arc );
_fxList.Archive( arc );
arc.ArchiveInteger (&_currentFXIndex );
arc.ArchiveString (&_AdaptionFX );
arc.ArchiveVector (&_currentFXPosition);
arc.ArchiveFloat (&_fxTime );
arc.ArchiveFloat (&_fxTimeNormal );
arc.ArchiveFloat (&_fxTimeExplosive );
arc.ArchiveFloat (&_adaptionLimit );
}
//
// Class Name: BasicArmor
// Base Class: Item
//
// Description: Basic armor
//
class BasicArmor : public Armor
{
protected:
static const float _maxAmount;
static const float _normalMaxAmount;
static const float _lossRate;
static const float _highRangeCutoffSinglePlayer;
static const float _midRangeCutoffSinglePlayer;
static const float _highRangeCutoffMultiplayer;
static const float _midRangeCutoffMultiplayer;
static const float _highRangePercent;
static const float _midRangePercent;
static const float _lowRangePercent;
float _lastAddTime;
virtual qboolean _needThisArmor( Sentient *sentient );
/* virtual */ void Think( void );
public:
CLASS_PROTOTYPE( BasicArmor );
BasicArmor();
virtual float ResolveDamage( float damage , int meansOfDeath , const Vector &direction , const Vector &position , Entity *attacker );
virtual bool CanBeDamagedBy( int meansOfDeath );
/* virtual */ void Add( int num );
/* virtual */ void cacheStrings( void );
void Archive ( Archiver &arc );
};
inline void BasicArmor::Archive( Archiver &arc )
{
Armor::Archive( arc );
arc.ArchiveFloat( &_lastAddTime );
}
//
// Class Name: ShieldArmor
// Base Class: Item
//
// Description: Shield armor that can take a specified amount of damage
//
class ShieldArmor : public Armor
{
public:
CLASS_PROTOTYPE ( ShieldArmor );
ShieldArmor();
void SetActiveStatus( Event *ev );
void SetMultiplier( Event *ev );
void AddMODToNoProtectionList( Event *ev );
void AddMODToNoProtectionList( const str &MODName );
void SetShieldDirection( Event *ev );
void SetShieldDirection( float minAngle, float maxAngle );
bool CanBeUsed();
virtual float ResolveDamage( float damage, int meansOfDeath, const Vector &direction, const Vector &position , Entity *attacker );
virtual bool CanBeDamagedBy ( int meansOfDeath );
void Archive ( Archiver &arc );
private:
bool _active;
float _multiplier;
float _directionMin;
float _directionMax;
bool _useDirection;
Container<unsigned int> _noProtectionList;
};
inline void ShieldArmor::Archive( Archiver &arc )
{
Armor::Archive( arc );
arc.ArchiveBool( &_active );
arc.ArchiveFloat( &_multiplier );
arc.ArchiveFloat( &_directionMin);
arc.ArchiveFloat( &_directionMax );
arc.ArchiveBool( &_useDirection );
int num , i;
if ( arc.Saving() )
{
num = _noProtectionList.NumObjects();
arc.ArchiveInteger( &num );
for( i = 1 ; i <= num ; i++ )
{
arc.ArchiveUnsigned ( &_noProtectionList.ObjectAt( i ) );
}
}
else
{
arc.ArchiveInteger( &num );
for( i = 1 ; i <= num ; i++ )
{
unsigned int theMod;
arc.ArchiveUnsigned( &theMod );
_noProtectionList.AddObject( theMod );
}
}
}
typedef SafePtr<Armor> ArmorPtr;
#endif /* armor.h */

210
dlls/game/be_aas.h Normal file
View file

@ -0,0 +1,210 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_aas.h
*
* desc: Area Awareness System, stuff exported to the AI
*
* $Archive: /Code/DLLs/game/be_aas.h $
* $Author: Steven $
* $Revision: 2 $
* $Modtime: 10/13/03 9:01a $
* $Date: 10/13/03 9:11a $
*
*****************************************************************************/
#ifndef MAX_STRINGFIELD
#define MAX_STRINGFIELD 80
#endif
//travel flags
#define TFL_INVALID 0x00000001 //traveling temporary not possible
#define TFL_WALK 0x00000002 //walking
#define TFL_CROUCH 0x00000004 //crouching
#define TFL_BARRIERJUMP 0x00000008 //jumping onto a barrier
#define TFL_JUMP 0x00000010 //jumping
#define TFL_LADDER 0x00000020 //climbing a ladder
#define TFL_WALKOFFLEDGE 0x00000080 //walking of a ledge
#define TFL_SWIM 0x00000100 //swimming
#define TFL_WATERJUMP 0x00000200 //jumping out of the water
#define TFL_TELEPORT 0x00000400 //teleporting
#define TFL_ELEVATOR 0x00000800 //elevator
#define TFL_ROCKETJUMP 0x00001000 //rocket jumping
#define TFL_BFGJUMP 0x00002000 //bfg jumping
#define TFL_GRAPPLEHOOK 0x00004000 //grappling hook
#define TFL_DOUBLEJUMP 0x00008000 //double jump
#define TFL_RAMPJUMP 0x00010000 //ramp jump
#define TFL_STRAFEJUMP 0x00020000 //strafe jump
#define TFL_JUMPPAD 0x00040000 //jump pad
#define TFL_AIR 0x00080000 //travel through air
#define TFL_WATER 0x00100000 //travel through water
#define TFL_SLIME 0x00200000 //travel through slime
#define TFL_LAVA 0x00400000 //travel through lava
#define TFL_DONOTENTER 0x00800000 //travel through donotenter area
#define TFL_FUNCBOB 0x01000000 //func bobbing
#define TFL_FLIGHT 0x02000000 //flight
#define TFL_BRIDGE 0x04000000 //move over a bridge
//
#define TFL_NOTTEAM1 0x08000000 //not team 1
#define TFL_NOTTEAM2 0x10000000 //not team 2
//default travel flags
#define TFL_DEFAULT TFL_WALK|TFL_CROUCH|TFL_BARRIERJUMP|\
TFL_JUMP|TFL_LADDER|\
TFL_WALKOFFLEDGE|TFL_SWIM|TFL_WATERJUMP|\
TFL_TELEPORT|TFL_ELEVATOR|\
TFL_AIR|TFL_WATER|TFL_JUMPPAD|TFL_FUNCBOB
// already defined in g_public.h in tiki tech, moved to l_util.h so the botlib stuff compiles but the gamecode also compiles
/*
typedef enum
{
SOLID_NOT, // no interaction with other objects
SOLID_TRIGGER, // only touch when inside, after moving
SOLID_BBOX, // touch on edge
SOLID_BSP // bsp clip, touch on edge
} solid_t;
*/
//a trace is returned when a box is swept through the AAS world
typedef struct aas_trace_s
{
qboolean startsolid; // if true, the initial point was in a solid area
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
int ent; // entity blocking the trace
int lastarea; // last area the trace was in (zero if none)
int area; // area blocking the trace (zero if none)
int planenum; // number of the plane that was hit
} aas_trace_t;
// Defined in botlib.h
//bsp_trace_t hit surface
/*
typedef struct bsp_surface_s
{
char name[16];
int flags;
int value;
} bsp_surface_t;
//a trace is returned when a box is swept through the BSP world
typedef struct bsp_trace_s
{
qboolean allsolid; // if true, plane is not valid
qboolean startsolid; // if true, the initial point was in a solid area
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
cplane_t plane; // surface normal at impact
float exp_dist; // expanded plane distance
int sidenum; // number of the brush side hit
bsp_surface_t surface; // hit surface
int contents; // contents on other side of surface hit
int ent; // number of entity hit
} bsp_trace_t;
*/
//
//entity info
typedef struct aas_entityinfo_s
{
int valid; // true if updated this frame
int type; // entity type
int flags; // entity flags
float ltime; // local time
float update_time; // time between last and current update
int number; // number of the entity
vec3_t origin; // origin of the entity
vec3_t angles; // angles of the model
vec3_t old_origin; // for lerping
vec3_t lastvisorigin; // last visible origin
vec3_t mins; // bounding box minimums
vec3_t maxs; // bounding box maximums
int groundent; // ground entity
int solid; // solid type
int modelindex; // model used
int modelindex2; // weapons, CTF flags, etc
int frame; // model frame number
int event; // impulse events -- muzzle flashes, footsteps, etc
int eventParm; // even parameter
int powerups; // bit flags
int weapon; // determines weapon and flash model, etc
int legsAnim; // mask off ANIM_TOGGLEBIT
int torsoAnim; // mask off ANIM_TOGGLEBIT
} aas_entityinfo_t;
// area info
typedef struct aas_areainfo_s
{
int contents;
int flags;
int presencetype;
int cluster;
vec3_t mins;
vec3_t maxs;
vec3_t center;
} aas_areainfo_t;
// client movement prediction stop events, stop as soon as:
#define SE_NONE 0
#define SE_HITGROUND 1 // the ground is hit
#define SE_LEAVEGROUND 2 // there's no ground
#define SE_ENTERWATER 4 // water is entered
#define SE_ENTERSLIME 8 // slime is entered
#define SE_ENTERLAVA 16 // lava is entered
#define SE_HITGROUNDDAMAGE 32 // the ground is hit with damage
#define SE_GAP 64 // there's a gap
#define SE_TOUCHJUMPPAD 128 // touching a jump pad area
#define SE_TOUCHTELEPORTER 256 // touching teleporter
#define SE_ENTERAREA 512 // the given stoparea is entered
#define SE_HITGROUNDAREA 1024 // a ground face in the area is hit
#define SE_HITBOUNDINGBOX 2048 // hit the specified bounding box
#define SE_TOUCHCLUSTERPORTAL 4096 // touching a cluster portal
typedef struct aas_clientmove_s
{
vec3_t endpos; //position at the end of movement prediction
int endarea; //area at end of movement prediction
vec3_t velocity; //velocity at the end of movement prediction
aas_trace_t trace; //last trace
int presencetype; //presence type at end of movement prediction
int stopevent; //event that made the prediction stop
int endcontents; //contents at the end of movement prediction
float time; //time predicted ahead
int frames; //number of frames predicted ahead
} aas_clientmove_t;
// alternate route goals
#define ALTROUTEGOAL_ALL 1
#define ALTROUTEGOAL_CLUSTERPORTALS 2
#define ALTROUTEGOAL_VIEWPORTALS 4
typedef struct aas_altroutegoal_s
{
vec3_t origin;
int areanum;
unsigned short starttraveltime;
unsigned short goaltraveltime;
unsigned short extratraveltime;
} aas_altroutegoal_t;
// route prediction stop events
#define RSE_NONE 0
#define RSE_NOROUTE 1 //no route to goal
#define RSE_USETRAVELTYPE 2 //stop as soon as on of the given travel types is used
#define RSE_ENTERCONTENTS 4 //stop when entering the given contents
#define RSE_ENTERAREA 8 //stop when entering the given area
typedef struct aas_predictroute_s
{
vec3_t endpos; //position at the end of movement prediction
int endarea; //area at end of movement prediction
int stopevent; //event that made the prediction stop
int endcontents; //contents at the end of movement prediction
int endtravelflags; //end travel flags
int numareas; //number of areas predicted ahead
int time; //time predicted ahead (in hundreth of a sec)
} aas_predictroute_t;

32
dlls/game/be_ai_char.h Normal file
View file

@ -0,0 +1,32 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_char.h
*
* desc: bot characters
*
* $Archive: /Code/DLLs/game/be_ai_char.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 5/17/02 11:35a $
* $Date: 7/31/02 10:45a $
*
*****************************************************************************/
//loads a bot character from a file
int BotLoadCharacter(char *charfile, float skill);
//frees a bot character
void BotFreeCharacter(int character);
//returns a float characteristic
float Characteristic_Float(int character, int index);
//returns a bounded float characteristic
float Characteristic_BFloat(int character, int index, float min, float max);
//returns an integer characteristic
int Characteristic_Integer(int character, int index);
//returns a bounded integer characteristic
int Characteristic_BInteger(int character, int index, int min, int max);
//returns a string characteristic
void Characteristic_String(int character, int index, char *buf, int size);
//free cached bot characters
void BotShutdownCharacters(void);

97
dlls/game/be_ai_chat.h Normal file
View file

@ -0,0 +1,97 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_chat.h
*
* desc: char AI
*
* $Archive: /Code/DLLs/game/be_ai_chat.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 5/17/02 11:35a $
* $Date: 7/31/02 10:45a $
*
*****************************************************************************/
#define MAX_MESSAGE_SIZE 256
#define MAX_CHATTYPE_NAME 32
#define MAX_MATCHVARIABLES 8
#define CHAT_GENDERLESS 0
#define CHAT_GENDERFEMALE 1
#define CHAT_GENDERMALE 2
#define CHAT_ALL 0
#define CHAT_TEAM 1
#define CHAT_TELL 2
//a console message
typedef struct bot_consolemessage_s
{
int handle;
float time; //message time
int type; //message type
char message[MAX_MESSAGE_SIZE]; //message
struct bot_consolemessage_s *prev, *next; //prev and next in list
} bot_consolemessage_t;
//match variable
typedef struct bot_matchvariable_s
{
char offset;
int length;
} bot_matchvariable_t;
//returned to AI when a match is found
typedef struct bot_match_s
{
char string[MAX_MESSAGE_SIZE];
int type;
int subtype;
bot_matchvariable_t variables[MAX_MATCHVARIABLES];
} bot_match_t;
//setup the chat AI
int BotSetupChatAI(void);
//shutdown the chat AI
void BotShutdownChatAI(void);
//returns the handle to a newly allocated chat state
int BotAllocChatState(void);
//frees the chatstate
void BotFreeChatState(int handle);
//adds a console message to the chat state
void BotQueueConsoleMessage(int chatstate, int type, char *message);
//removes the console message from the chat state
void BotRemoveConsoleMessage(int chatstate, int handle);
//returns the next console message from the state
int BotNextConsoleMessage(int chatstate, bot_consolemessage_t *cm);
//returns the number of console messages currently stored in the state
int BotNumConsoleMessages(int chatstate);
//selects a chat message of the given type
void BotInitialChat(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
//returns the number of initial chat messages of the given type
int BotNumInitialChats(int chatstate, char *type);
//find and select a reply for the given message
int BotReplyChat(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
//returns the length of the currently selected chat message
int BotChatLength(int chatstate);
//enters the selected chat message
void BotEnterChat(int chatstate, int clientto, int sendto);
//get the chat message ready to be output
void BotGetChatMessage(int chatstate, char *buf, int size);
//checks if the first string contains the second one, returns index into first string or -1 if not found
int StringContains(char *str1, char *str2, int casesensitive);
//finds a match for the given string using the match templates
int BotFindMatch(char *str, bot_match_t *match, unsigned long int context);
//returns a variable from a match
void BotMatchVariable(bot_match_t *match, int variable, char *buf, int size);
//unify all the white spaces in the string
void UnifyWhiteSpaces(char *string);
//replace all the context related synonyms in the string
void BotReplaceSynonyms(char *string, unsigned long int context);
//loads a chat file for the chat state
int BotLoadChatFile(int chatstate, char *chatfile, char *chatname);
//store the gender of the bot in the chat state
void BotSetChatGender(int chatstate, int gender);
//store the bot name in the chat state
void BotSetChatName(int chatstate, char *name, int client);

17
dlls/game/be_ai_gen.h Normal file
View file

@ -0,0 +1,17 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_gen.h
*
* desc: genetic selection
*
* $Archive: /Code/DLLs/game/be_ai_gen.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 5/17/02 11:35a $
* $Date: 7/31/02 10:45a $
*
*****************************************************************************/
int GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child);

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