as released 2003-11-05
This commit is contained in:
commit
1134707c06
367 changed files with 298005 additions and 0 deletions
37
EF2-game.dsw
Normal file
37
EF2-game.dsw
Normal 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
BIN
EF2-game.ncb
Normal file
Binary file not shown.
BIN
EF2-game.opt
Normal file
BIN
EF2-game.opt
Normal file
Binary file not shown.
129
EF2.dsw
Normal file
129
EF2.dsw
Normal 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
13
Executable/gamedefs.h
Normal 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"
|
187
Executable/win32/win_bounds.cpp
Normal file
187
Executable/win32/win_bounds.cpp
Normal 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
117
Shared/qcommon/alias.h
Normal 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
115
Shared/qcommon/cm_public.h
Normal 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
|
1570
Shared/qcommon/gameplaydatabase.cpp
Normal file
1570
Shared/qcommon/gameplaydatabase.cpp
Normal file
File diff suppressed because it is too large
Load diff
296
Shared/qcommon/gameplaydatabase.h
Normal file
296
Shared/qcommon/gameplaydatabase.h
Normal 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
|
499
Shared/qcommon/gameplayformulamanager.cpp
Normal file
499
Shared/qcommon/gameplayformulamanager.cpp
Normal 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
|
||||||
|
|
||||||
|
|
196
Shared/qcommon/gameplayformulamanager.h
Normal file
196
Shared/qcommon/gameplayformulamanager.h
Normal 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
|
850
Shared/qcommon/gameplaymanager.cpp
Normal file
850
Shared/qcommon/gameplaymanager.cpp
Normal 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
|
88
Shared/qcommon/gameplaymanager.h
Normal file
88
Shared/qcommon/gameplaymanager.h
Normal 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
942
Shared/qcommon/output.cpp
Normal 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
105
Shared/qcommon/output.h
Normal 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
10
Shared/qcommon/platform.h
Normal 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
1264
Shared/qcommon/qfiles.h
Normal file
File diff suppressed because it is too large
Load diff
776
Shared/qcommon/quaternion.h
Normal file
776
Shared/qcommon/quaternion.h
Normal 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_
|
119
Shared/qcommon/stringresource.hpp
Normal file
119
Shared/qcommon/stringresource.hpp
Normal 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
|
108
Shared/qcommon/tiki_script.h
Normal file
108
Shared/qcommon/tiki_script.h
Normal 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
801
dlls/game/CameraPath.cpp
Normal 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
293
dlls/game/CameraPath.h
Normal 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_
|
2830
dlls/game/CinematicArmature.cpp
Normal file
2830
dlls/game/CinematicArmature.cpp
Normal file
File diff suppressed because it is too large
Load diff
765
dlls/game/CinematicArmature.h
Normal file
765
dlls/game/CinematicArmature.h
Normal 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_ */
|
526
dlls/game/DamageModification.cpp
Normal file
526
dlls/game/DamageModification.cpp
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
381
dlls/game/DamageModification.hpp
Normal file
381
dlls/game/DamageModification.hpp
Normal 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
1389
dlls/game/FollowPath.cpp
Normal file
File diff suppressed because it is too large
Load diff
267
dlls/game/FollowPath.h
Normal file
267
dlls/game/FollowPath.h
Normal 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
|
133
dlls/game/FollowPathToEntity.cpp
Normal file
133
dlls/game/FollowPathToEntity.cpp
Normal 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);
|
||||||
|
}
|
67
dlls/game/FollowPathToEntity.h
Normal file
67
dlls/game/FollowPathToEntity.h
Normal 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
|
76
dlls/game/FollowPathToPoint.cpp
Normal file
76
dlls/game/FollowPathToPoint.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
58
dlls/game/FollowPathToPoint.h
Normal file
58
dlls/game/FollowPathToPoint.h
Normal 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
|
192
dlls/game/GameplayDatabase.h
Normal file
192
dlls/game/GameplayDatabase.h
Normal 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
|
193
dlls/game/GameplayFormulaManager.h
Normal file
193
dlls/game/GameplayFormulaManager.h
Normal 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
|
||||||
|
|
84
dlls/game/GameplayManager.h
Normal file
84
dlls/game/GameplayManager.h
Normal 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
|
142
dlls/game/GoDirectlyToPoint.cpp
Normal file
142
dlls/game/GoDirectlyToPoint.cpp
Normal 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;
|
||||||
|
}
|
73
dlls/game/GoDirectlyToPoint.h
Normal file
73
dlls/game/GoDirectlyToPoint.h
Normal 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
118
dlls/game/Linklist.h
Normal 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
|
434
dlls/game/MoveRandomDirection.cpp
Normal file
434
dlls/game/MoveRandomDirection.cpp
Normal 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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
123
dlls/game/MoveRandomDirection.hpp
Normal file
123
dlls/game/MoveRandomDirection.hpp
Normal 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
442
dlls/game/PlayAnim.cpp
Normal 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
137
dlls/game/PlayAnim.hpp
Normal 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
122
dlls/game/PlayerStart.cpp
Normal 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
74
dlls/game/PlayerStart.h
Normal 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
1169
dlls/game/RageAI.cpp
Normal file
File diff suppressed because it is too large
Load diff
245
dlls/game/RageAI.h
Normal file
245
dlls/game/RageAI.h
Normal 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
43
dlls/game/UseData.cpp
Normal 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
96
dlls/game/UseData.h
Normal 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__
|
145
dlls/game/WeaponDualWield.cpp
Normal file
145
dlls/game/WeaponDualWield.cpp
Normal 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 );
|
||||||
|
}
|
||||||
|
}
|
58
dlls/game/WeaponDualWield.h
Normal file
58
dlls/game/WeaponDualWield.h
Normal 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
22
dlls/game/_pch_cpp.cpp
Normal 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
25
dlls/game/_pch_cpp.h
Normal 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
19685
dlls/game/actor.cpp
Normal file
File diff suppressed because it is too large
Load diff
1531
dlls/game/actor.h
Normal file
1531
dlls/game/actor.h
Normal file
File diff suppressed because it is too large
Load diff
1002
dlls/game/actor_combatsubsystem.cpp
Normal file
1002
dlls/game/actor_combatsubsystem.cpp
Normal file
File diff suppressed because it is too large
Load diff
97
dlls/game/actor_combatsubsystem.h
Normal file
97
dlls/game/actor_combatsubsystem.h
Normal 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__ */
|
1074
dlls/game/actor_enemymanager.cpp
Normal file
1074
dlls/game/actor_enemymanager.cpp
Normal file
File diff suppressed because it is too large
Load diff
120
dlls/game/actor_enemymanager.h
Normal file
120
dlls/game/actor_enemymanager.h
Normal 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__ */
|
365
dlls/game/actor_headwatcher.cpp
Normal file
365
dlls/game/actor_headwatcher.cpp
Normal 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 );
|
||||||
|
}
|
101
dlls/game/actor_headwatcher.h
Normal file
101
dlls/game/actor_headwatcher.h
Normal 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__ */
|
2178
dlls/game/actor_locomotion.cpp
Normal file
2178
dlls/game/actor_locomotion.cpp
Normal file
File diff suppressed because it is too large
Load diff
217
dlls/game/actor_locomotion.h
Normal file
217
dlls/game/actor_locomotion.h
Normal 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 ¤tLoc , 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__ */
|
308
dlls/game/actor_posturecontroller.cpp
Normal file
308
dlls/game/actor_posturecontroller.cpp
Normal 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();
|
||||||
|
}
|
93
dlls/game/actor_posturecontroller.hpp
Normal file
93
dlls/game/actor_posturecontroller.hpp
Normal 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__ */
|
||||||
|
|
1085
dlls/game/actor_sensoryperception.cpp
Normal file
1085
dlls/game/actor_sensoryperception.cpp
Normal file
File diff suppressed because it is too large
Load diff
131
dlls/game/actor_sensoryperception.h
Normal file
131
dlls/game/actor_sensoryperception.h
Normal 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__ */
|
143
dlls/game/actorgamecomponents.cpp
Normal file
143
dlls/game/actorgamecomponents.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
79
dlls/game/actorgamecomponents.h
Normal file
79
dlls/game/actorgamecomponents.h
Normal 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
537
dlls/game/actorincludes.h
Normal 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__ */
|
580
dlls/game/actorstrategies.cpp
Normal file
580
dlls/game/actorstrategies.cpp
Normal 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
128
dlls/game/actorstrategies.h
Normal 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
195
dlls/game/actorutil.cpp
Normal 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
102
dlls/game/actorutil.h
Normal 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
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
45
dlls/game/ai_chat.h
Normal 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
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
21
dlls/game/ai_cmd.h
Normal 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
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
45
dlls/game/ai_dmnet.h
Normal 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
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
191
dlls/game/ai_dmq3.h
Normal 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
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
286
dlls/game/ai_main.h
Normal 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
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
23
dlls/game/ai_team.h
Normal 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
532
dlls/game/ai_vcmd.cpp
Normal 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
20
dlls/game/ai_vcmd.h
Normal 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
175
dlls/game/ammo.cpp
Normal 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
89
dlls/game/ammo.h
Normal 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
1010
dlls/game/animate.cpp
Normal file
File diff suppressed because it is too large
Load diff
330
dlls/game/animate.h
Normal file
330
dlls/game/animate.h
Normal 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( ¤tAnim );
|
||||||
|
arc.ArchiveFloat( &oldAnimationRate );
|
||||||
|
arc.ArchiveVector( &frame_delta );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* animate.h */
|
1027
dlls/game/archive.cpp
Normal file
1027
dlls/game/archive.cpp
Normal file
File diff suppressed because it is too large
Load diff
489
dlls/game/archive.h
Normal file
489
dlls/game/archive.h
Normal 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
1077
dlls/game/armor.cpp
Normal file
File diff suppressed because it is too large
Load diff
317
dlls/game/armor.h
Normal file
317
dlls/game/armor.h
Normal 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
210
dlls/game/be_aas.h
Normal 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
32
dlls/game/be_ai_char.h
Normal 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
97
dlls/game/be_ai_chat.h
Normal 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
17
dlls/game/be_ai_gen.h
Normal 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
Loading…
Reference in a new issue