Reworked source tree so it compiles

This commit is contained in:
L 2023-01-29 20:59:31 +01:00
parent 19e33444e7
commit 8ef16a91f2
164 changed files with 3183 additions and 20134 deletions

View file

@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "simpleactor.h"
#include "actorenemy.h"
#include "level.h"
#include "game.h"
#include <gamescript.h>
#include <scriptmaster.h>
#include "grenadehint.h"

1287
code/game/archive.cpp Normal file

File diff suppressed because it is too large Load diff

415
code/game/archive.h Normal file
View file

@ -0,0 +1,415 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// archive.h: OpenMoHAA Archiver
#ifndef __ARCHIVE_H__
#define __ARCHIVE_H__
#include "glb_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_USE_TYPES
#define ARCHIVE_WRITE 0
#define ARCHIVE_READ 1
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( bool bDoCompression = false );
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;
size_t m_iNumBytesIO;
qboolean silent;
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( str &name, qboolean harderror = true );
qboolean Read( const char *name, qboolean harderror = true );
Class *ReadObject( void );
qboolean Create( str &name, qboolean harderror = true );
qboolean Create( const char *name, qboolean 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 ArchiveSize( long * 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 ArchiveConfigString( int cs );
void ArchiveObjectPointer( Class ** ptr );
void ArchiveObjectPosition( void *obj );
void ArchiveSafePointer( SafePtrBase * ptr );
void ArchiveEventPointer( Event ** ev );
void ArchiveBool( bool * boolean );
void ArchivePosition( int * pos );
void ArchiveSvsTime( int * time );
void ArchiveVec2( vec2_t vec );
void ArchiveVec3( vec3_t vec );
void ArchiveVec4( vec4_t vec );
void ArchiveRaw( void *data, size_t size );
void ArchiveObject( Class *obj );
qboolean ObjectPositionExists( void * obj );
void SetSilent( bool bSilent );
};
inline qboolean Archiver::Read
(
str &name,
qboolean harderror
)
{
return Read( name.c_str(), harderror );
}
inline qboolean Archiver::Create
(
str &name,
qboolean harderror
)
{
return Create( name.c_str(), 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 );
}
template< class Type >
inline void Container<Type>::Archive
(
Archiver& arc,
void( *ArchiveFunc )( Archiver& arc, Type *obj )
)
{
int num;
int i;
if( arc.Loading() )
{
arc.ArchiveInteger( &num );
Resize( num );
}
else
{
num = numobjects;
arc.ArchiveInteger( &num );
}
for( i = 1; i <= num; i++ )
{
if( num > numobjects ) {
numobjects = num;
}
ArchiveFunc( arc, &objlist[ i ] );
}
}
template<>
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 ) );
}
}
template<>
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 ) );
}
}
template<>
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 ) );
}
}
template<>
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 ) );
}
}
template< typename c >
inline void ArchiveClass
(
Archiver& arc,
c *obj
)
{
arc.ArchiveObject( obj );
}
#ifndef NO_ARCHIVE
template< typename key, typename value >
void con_set< key, value >::Archive
(
Archiver& arc
)
{
Entry< key, value > *e;
int hash;
int i;
arc.ArchiveUnsigned( &tableLength );
arc.ArchiveUnsigned( &threshold );
arc.ArchiveUnsigned( &count );
arc.ArchiveUnsignedShort( &tableLengthIndex );
if( arc.Loading() )
{
if( tableLength != 1 )
{
table = new Entry< key, value > *[ tableLength ]();
memset( table, 0, tableLength * sizeof( Entry< key, value > * ) );
}
for( i = 0; i < count; i++ )
{
e = new Entry< key, value >;
e->Archive( arc );
hash = HashCode< key >( e->key ) % tableLength;
e->index = i;
e->next = table[ hash ];
table[ hash ] = e;
}
}
else
{
for( i = tableLength - 1; i >= 0; i-- )
{
for( e = table[ i ]; e != NULL; e = e->next )
{
e->Archive( arc );
}
}
}
}
template< typename key, typename value >
void con_map< key, value >::Archive
(
Archiver& arc
)
{
m_con_set.Archive( arc );
}
#endif
#define ArchiveEnum( thing, type ) \
{ \
int tempInt; \
\
tempInt = ( int )( thing ); \
arc.ArchiveInteger( &tempInt ); \
( thing ) = ( type )tempInt; \
}
#endif // __ARCHIVE_H__

View file

@ -1,487 +0,0 @@
//
// b_files.c
//
#include "b_local.h"
#if 0
//
// parse support routines
//
static qboolean Nav_ParseLiteral( char **data, const char *string ) {
char *token;
token = COM_ParseExt( data, qtrue );
if ( token[0] == 0 ) {
gi.Printf( ERROR "unexpected EOF\n" );
return qtrue;
}
if ( Q_stricmp( token, string ) ) {
gi.Printf( ERROR "required string '%s' missing\n", string );
return qtrue;
}
return qfalse;
}
static qboolean Nav_ParseString( char **data, char **s ) {
*s = COM_ParseExt( data, qfalse );
if ( s[0] == 0 ) {
gi.Printf( ERROR "unexpected EOF\n" );
return qtrue;
}
return qfalse;
}
static qboolean Nav_ParseInt( char **data, int *i ) {
char *token;
token = COM_ParseExt( data, qfalse );
if ( token[0] == 0 ) {
gi.Printf( ERROR "unexpected EOF\n" );
return qtrue;
}
*i = atoi( token );
return qfalse;
}
//
// bot parameters file : scripts/bots.cfg
//
char botParms[0x10000];
static int MethodNameToNumber( const char *name ) {
if ( !Q_stricmp( name, "EXPONENTIAL" ) ) {
return METHOD_EXPONENTIAL;
}
if ( !Q_stricmp( name, "LINEAR" ) ) {
return METHOD_LINEAR;
}
if ( !Q_stricmp( name, "LOGRITHMIC" ) ) {
return METHOD_LOGRITHMIC;
}
if ( !Q_stricmp( name, "ALWAYS" ) ) {
return METHOD_ALWAYS;
}
if ( !Q_stricmp( name, "NEVER" ) ) {
return METHOD_NEVER;
}
return -1;
}
static int ItemNameToNumber( const char *name, int itemType ) {
int n;
for ( n = 0; n < bg_numItems; n++ ) {
if ( bg_itemlist[n].type != itemType ) {
continue;
}
if ( Q_stricmp( bg_itemlist[n].classname, name ) == 0 ) {
return bg_itemlist[n].tag;
}
}
return -1;
}
void Bot_ParseParms( const char *botName, gentity_t *bot, char *userinfo ) {
char *token;
char *value;
char *p;
int n;
int count;
if ( !botName || !botName[0]) {
botName = "Player";
}
strcpy( userinfo, "\\name\\" );
strcat( userinfo, botName );
// fill in defaults
bot->bot->reactions = 3;
bot->bot->aim = 3;
bot->bot->move = 3;
bot->bot->aggression = 3;
bot->bot->intelligence = 3;
bot->bot->hfov = 90 / 2;
bot->bot->vfov = 68 / 2;
bot->bot->healthMethod = METHOD_LOGRITHMIC;
bot->bot->armorMethod = METHOD_LINEAR;
bot->bot->ammoMethod = METHOD_EXPONENTIAL;
bot->bot->allWeaponOrder[0] = WP_BFG;
bot->bot->allWeaponOrder[1] = WP_ROCKET_LAUNCHER;
bot->bot->allWeaponOrder[2] = WP_RAILGUN;
bot->bot->allWeaponOrder[3] = WP_PLASMAGUN;
bot->bot->allWeaponOrder[4] = WP_GRENADE_LAUNCHER;
bot->bot->allWeaponOrder[5] = WP_SHOTGUN;
bot->bot->allWeaponOrder[6] = WP_MACHINEGUN;
bot->bot->allWeaponOrder[7] = WP_NONE;
p = botParms;
COM_BeginParseSession();
// look for the right bot
while ( p ) {
token = COM_ParseExt( &p, qtrue );
if ( token[0] == 0 )
return;
if ( !Q_stricmp( token, botName ) ) {
break;
}
SkipBracedSection( &p );
}
if ( !p ) {
return;
}
if ( Nav_ParseLiteral( &p, "{" ) ) {
return;
}
// parse the bot info block
while ( 1 ) {
token = COM_ParseExt( &p, qtrue );
if ( !token[0] ) {
gi.Printf( "ERROR: unexpected EOF while parsing '%s'\n", botName );
return;
}
if ( !Q_stricmp( token, "}" ) ) {
break;
}
// model
if ( !Q_stricmp( token, "model" ) ) {
if ( Nav_ParseString( &p, &value ) ) {
continue;
}
strcat ( userinfo, "\\model\\" );
strcat ( userinfo, value );
continue;
}
// reactions
if ( !Q_stricmp( token, "reactions" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 1 || n > 5 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->reactions = n;
continue;
}
// aim
if ( !Q_stricmp( token, "aim" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 1 || n > 5 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->aim = n;
continue;
}
// move
if ( !Q_stricmp( token, "move" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 1 || n > 5 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->move = n;
continue;
}
// aggression
if ( !Q_stricmp( token, "aggression" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 1 || n > 5 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->aggression = n;
continue;
}
// intelligence
if ( !Q_stricmp( token, "intelligence" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 1 || n > 5 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->intelligence = n;
continue;
}
// hfov
if ( !Q_stricmp( token, "hfov" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 30 || n > 180 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->hfov = n / 2;
continue;
}
// vfov
if ( !Q_stricmp( token, "vfov" ) ) {
if ( Nav_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 30 || n > 180 ) {
gi.Printf( WARNING "bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->vfov = n / 2;
continue;
}
// healthMethod
if ( !Q_stricmp( token, "healthMethod" ) ) {
if ( Nav_ParseString( &p, &value ) ) {
continue;
}
n = MethodNameToNumber( value );
if ( n == -1 ) {
gi.Printf( "WARNING: bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->healthMethod = n;
continue;
}
// armorMethod
if ( !Q_stricmp( token, "armorMethod" ) ) {
if ( Nav_ParseString( &p, &value ) ) {
continue;
}
n = MethodNameToNumber( value );
if ( n == -1 ) {
gi.Printf( "WARNING: bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->armorMethod = n;
continue;
}
// ammoMethod
if ( !Q_stricmp( token, "ammoMethod" ) ) {
if ( Nav_ParseString( &p, &value ) ) {
continue;
}
n = MethodNameToNumber( value );
if ( n == -1 ) {
gi.Printf( "WARNING: bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->ammoMethod = n;
continue;
}
// weapons
if ( !Q_stricmp( token, "weapons" ) ) {
for ( count = 0; count < MAX_WEAPONS; count++ ) {
if ( Nav_ParseString( &p, &value ) ) {
break;
}
if ( *value == 0 ) {
break;
}
n = ItemNameToNumber( value, IT_WEAPON );
if ( n == -1 ) {
gi.Printf( "WARNING: bad %s in bot '%s'\n", token, botName );
continue;
}
bot->bot->allWeaponOrder[count] = n;
}
if ( count < MAX_WEAPONS ) {
bot->bot->allWeaponOrder[count] = WP_NONE;
}
continue;
}
// snd
if ( !Q_stricmp( token, "snd" ) ) {
if ( Nav_ParseString( &p, &value ) ) {
continue;
}
strcat( userinfo, "\\snd\\" );
strcat( userinfo, value );
continue;
}
gi.Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, botName );
SkipRestOfLine( &p );
}
}
void Bot_LoadParms( void ) {
int len;
char filename[MAX_QPATH];
char *buffer;
sprintf( filename, "scripts/bots.cfg" );
gi.Printf( "Parsing %s\n", filename );
len = gi.FS_ReadFile( filename, &buffer, qtrue );
if ( len == -1 ) {
gi.Printf( "file not found\n" );
}
if ( len >= sizeof( botParms ) ) {
gi.Error( ERR_DROP, "scripts/bots.cfg is too large" );
}
strncpy( botParms, buffer, sizeof( botParms ) - 1 );
gi.FS_FreeFile( buffer );
}
#endif
//
// navigation data : maps/*.nav
//
void Nav_LoadRoutes( void ) {
int len;
navheader_t *header;
int value;
int n;
str filename;
Swap_Init();
surfaceCount = 0;
surface = NULL;
neighborCount = 0;
neighbor = NULL;
// load the file
filename = "maps/";
filename += level.mapname + ".nav";
gi.Printf( "Loading %s\n", filename.c_str() );
len = gi.FS_ReadFile( filename.c_str(), ( void ** )&navFileData, qtrue );
if ( len == -1 ) {
gi.Printf( WARNING "no navigation data\n" );
return;
}
if ( len < sizeof( navheader_t ) ) {
gi.Printf( ERROR "no nav file header\n" );
goto cleanup;
}
// process the header
header = (navheader_t *)navFileData;
header->id = LittleLong( header->id );
header->version = LittleLong( header->version );
header->surfaceCount = LittleLong( header->surfaceCount );
header->neighborCount = LittleLong( header->neighborCount );
// validate the header fields
if ( header->id != NAVFILE_ID ) {
gi.Printf( ERROR "incorrect nav file id\n" );
goto cleanup;
}
if ( header->version != NAVFILE_VERSION ) {
gi.Printf( ERROR "incorrect nav file version (%i, should be %i)\n", header->version, NAVFILE_VERSION );
goto cleanup;
}
value = /* header */ sizeof( navheader_t ) +
/* surfaces */ header->surfaceCount * sizeof( nsurface_t ) +
/* neighbors */ header->neighborCount * sizeof( nneighbor_t ) +
/* routes */ header->surfaceCount * header->surfaceCount * sizeof( byte );
if ( value != len ) {
gi.Printf( ERROR "incorrect nav file length (%i, should be %i)\n", len, value );
goto cleanup;
}
surfaceCount = header->surfaceCount;
neighborCount = header->neighborCount;
// process surfaces
surface = (nsurface_t *)(navFileData + sizeof( navheader_t ) );
for ( n = 0; n < surfaceCount; n++ ) {
surface[n].origin[0] = LittleFloat( surface[n].origin[0] );
surface[n].origin[1] = LittleFloat( surface[n].origin[1] );
surface[n].origin[2] = LittleFloat( surface[n].origin[2] );
surface[n].absmin[0] = LittleFloat( surface[n].absmin[0] );
surface[n].absmin[1] = LittleFloat( surface[n].absmin[1] );
surface[n].absmax[0] = LittleFloat( surface[n].absmax[0] );
surface[n].absmax[1] = LittleFloat( surface[n].absmax[1] );
surface[n].flags = LittleLong( surface[n].flags );
surface[n].neighborCount = LittleLong( surface[n].neighborCount );
surface[n].neighborIndex = LittleLong( surface[n].neighborIndex );
surface[n].parm = LittleLong( surface[n].parm );
}
// process neighbors
neighbor = (nneighbor_t *)((byte *)surface + surfaceCount * sizeof( nsurface_t ));
for ( n = 0; n < neighborCount; n++ ) {
neighbor[n].origin[0] = LittleFloat( neighbor[n].origin[0] );
neighbor[n].origin[1] = LittleFloat( neighbor[n].origin[1] );
neighbor[n].origin[2] = LittleFloat( neighbor[n].origin[2] );
neighbor[n].absmin[0] = LittleFloat( neighbor[n].absmin[0] );
neighbor[n].absmin[1] = LittleFloat( neighbor[n].absmin[1] );
neighbor[n].absmax[0] = LittleFloat( neighbor[n].absmax[0] );
neighbor[n].absmax[1] = LittleFloat( neighbor[n].absmax[1] );
neighbor[n].surfaceNum = LittleLong( neighbor[n].surfaceNum );
neighbor[n].flags = LittleLong( neighbor[n].flags );
neighbor[n].cost = LittleLong( neighbor[n].cost );
neighbor[n].filler = LittleLong( neighbor[n].filler );
}
// process routes
route = (byte *)neighbor + neighborCount * sizeof( nneighbor_t );
gi.Printf( "...loaded %i surfaces and %i neighbors\n", surfaceCount, neighborCount );
return;
cleanup:
gi.FS_FreeFile ( navFileData );
navFileData = NULL;
}

View file

@ -1,167 +0,0 @@
#ifndef __B_LOCAL_H__
#define __B_LOCAL_H__
#include "g_local.h"
//
// This section should be moved to QFILES.H
//
#define NAVFILE_ID (('I')+('N'<<8)+('A'<<16)+('V'<<24))
#define NAVFILE_VERSION 2
typedef struct {
unsigned id;
unsigned version;
unsigned surfaceCount;
unsigned neighborCount;
} navheader_t;
#define MAX_SURFACES 4096
#define SF_PUSH 0x00000001
#define SF_WATERLEVEL1 0x00000002
#define SF_WATERLEVEL2 0x00000004
#define SF_WATER_NOAIR 0x00000008
#define SF_DUCK 0x00000010
#define SF_PAIN 0x00000020
#define SF_TELEPORTER 0x00000040
#define SF_PLATHIGH 0x00000080
#define SF_PLATLOW 0x00000100
typedef struct {
vec3_t origin;
vec2_t absmin;
vec2_t absmax;
int parm;
unsigned flags;
unsigned neighborCount;
unsigned neighborIndex;
} nsurface_t;
#define MAX_NEIGHBORS 16384
#define NF_JUMP 0x00000001
#define NF_DUCK 0x00000002
#define NF_PLAT 0x00000004
#define NF_FALL1 0x00000008
#define NF_FALL2 0x00000010
typedef struct {
vec3_t origin;
vec2_t absmin; // region within this surface that is the portal to the other surface
vec2_t absmax;
int surfaceNum;
unsigned flags; // jump, prerequisite button, will take falling damage, etc...
float cost;
unsigned filler; // to be used as a "string index" into an array of targetnames for buttons, etc
} nneighbor_t;
#define WARNING "\033" "3" "WARNING: "
#define ERROR "\033" "1" "ERROR: "
// file buffers
extern char botParms[0x10000];
extern char *navFileData;
//
// Navigation susbsystem
//
#define NAVF_DUCK 0x00000001
#define NAVF_JUMP 0x00000002
#define NAVF_HOLD 0x00000004
#define NAVF_SLOW 0x00000008
#define METHOD_EXPONENTIAL 1
#define METHOD_LINEAR 2
#define METHOD_LOGRITHMIC 3
#define METHOD_ALWAYS 4
#define METHOD_NEVER 5
// combat maneuvers
#define CM_NONE 0
#define CM_CLOSE_DISTANCE 1
#define CM_OPEN_DISTANCE 2
#define CM_HOLD_DISTANCE 3
#define CM_GET_ITEM 4
#define CM_RUN_AWAY 5
#define CM_CIRCLE 6
#define CM_DUCK 7
typedef enum {SPOT_ORIGIN, SPOT_HEAD, SPOT_WEAPON, SPOT_LEGS, SPOT_GROUND} spot_t;
#define BOT_TIME_TO_LOSE_SIGHT 2000
#define SF_FROMMAPFILE 0x80000000
#define DEBUG_LEVEL_DETAIL 4
#define DEBUG_LEVEL_INFO 3
#define DEBUG_LEVEL_WARNING 2
#define DEBUG_LEVEL_ERROR 1
#define DEBUG_LEVEL_NONE 0
//
// b_main.c
//
void Debug_Printf( cvar_t *cv, int level, char *fmt, ... );
void Debug_BotPrintf( gentity_t *bot, cvar_t *cv, int debugLevel, char *fmt, ... );
//
// b_ai.c
//
extern cvar_t *debugBotAI;
extern cvar_t *debugBotFreeze;
void Bot_InitAI( void );
void Bot_Pain( gentity_t *bot, gentity_t *other, int damage );
void Bot_Touch( gentity_t *bot, gentity_t *other, trace_t *trace );
void BotSpawn( gentity_t *bot );
void Bot_Fetch_f( void );
//
// b_nav.c
//
extern char *navFileData;
extern int surfaceCount;
extern nsurface_t *surface;
extern int neighborCount;
extern nneighbor_t *neighbor;
extern byte *route;
void Nav_InitPreSpawn( void );
void Nav_InitPostSpawn( void );
void Nav_Shutdown( void );
void Nav_ShowPath( gentity_t *bot );
int Nav_GroundSurfaceNumber( gentity_t *ent );
int Nav_ItemSurfaceNumber( gentity_t *ent );
int Nav_EntitySurfaceNumber( gentity_t *ent );
int Nav_MoveToGoal( gentity_t *bot, vec3_t dir, int *flags );
//
// b_items.c
//
void Nav_InitRoamList( void );
qboolean WeaponIsOnLevel( int weapon );
gentity_t *Nav_ChooseRoamGoal( void );
//
// b_files.c
//
void Bot_ParseParms( const char *botName, gentity_t *bot, char *userinfo );
void Bot_LoadParms( void );
void Nav_LoadRoutes( void );
void Nav_SaveRoutes( void );
#endif

View file

@ -1,632 +0,0 @@
//
// b_nav.c
//
//FIXME make botInfo, etc visible here too and get rid of all the mutliple dereferences like bot->bot->
#include "b_local.h"
#define NAVF_EDGEZONE 0x00000001
#define INFINITE 1000000
#define BOTAI_PUSHED (1<<0)
cvar_t *nav_showsectors;
char *navFileData;
int surfaceCount;
nsurface_t *surface;
int neighborCount;
nneighbor_t *neighbor;
byte *route;
//#if 0
static int spawnpadModelIndex;
int Nav_SurfaceUnderPlayer( gentity_t *player ) {
vec3_t start;
vec3_t end;
vec3_t p;
trace_t tr;
float bestDist;
int bestSurf;
vec3_t v;
int n;
float dist;
VectorCopy( player->s.origin, start );
VectorCopy( player->s.origin, end );
end[2] -= 4096;
gi.trace ( &tr, start, player->mins, player->maxs, end, player->s.number, MASK_DEADSOLID, true );
// p[0] = ((int)tr.endpos[0] + 8) & (~16);
// p[1] = ((int)tr.endpos[1] + 8) & (~16);
p[0] = tr.endpos[0];
p[1] = tr.endpos[1];
p[2] = floor(tr.endpos[2]+player->mins[2]);
bestDist = INFINITE;
bestSurf = -1;
for ( n = 0; n < surfaceCount; n++ ) {
if ( Q_fabs( surface[n].origin[2] - p[2] ) > 24 ) {
continue;
}
VectorSubtract( p, surface[n].origin, v );
dist = VectorLength( v );
if ( dist < bestDist ) {
bestDist = dist;
bestSurf = n;
}
if ( surface[n].origin[2] != p[2] ) {
continue;
}
if ( surface[n].absmin[0] > p[0] ) {
continue;
}
if ( surface[n].absmax[0] < p[0] ) {
continue;
}
if ( surface[n].absmin[1] > p[1] ) {
continue;
}
if ( surface[n].absmax[1] < p[1] ) {
continue;
}
return n;
}
// gi.Printf( "guess for %s at %s\n", ent->classname, vtos( p ) );
return bestSurf;
}
/*
=============
Nav_GroundSurfaceNumber
Returns the surface number for where an entity is currently located.
If the entity is not on the ground, it returns -1.
FIXME we can make this more efficient
right now surfaces are in Z sorted order
we could make a Z index and binary search it to get to right z group fast
=============
*/
int Nav_GroundSurfaceNumber( gentity_t *ent ) {
vec3_t p;
vec3_t v;
int n;
float dist;
float bestDist;
int bestSurf;
gentity_t *groundEntity;
// if ent is not on the ground it is not on a surface
if ( ent->s.groundEntityNum == -1 ) {
return -1;
}
// p[0] = ((int)ent->s.origin[0] + 8) & (~16);
// p[1] = ((int)ent->s.origin[1] + 8) & (~16);
p[0] = ent->s.origin[0];
p[1] = ent->s.origin[1];
p[2] = floor(ent->s.origin[2]+ent->mins[2]);
// if ground is not the world we need to handle it differently.
if ( ent->s.groundEntityNum != ENTITYNUM_WORLD ) {
groundEntity = &g_entities[ent->s.groundEntityNum];
// check for sitting on a spawn pad
if ( !groundEntity->bmodel && groundEntity->s.modelindex == spawnpadModelIndex ) {
p[2] -= 8.0;
}
// check for plats
/* else if ( groundEntity->bmodel && Q_stricmp( groundEntity->classname, "func_plat" ) == 0 ) {
// if at the top the return PLATHIGH surface number, otherwise return PLATLOW surface number
if ( VectorCompare( groundEntity->currentOrigin, groundEntity->pos2 ) ) {
return surface[groundEntity->navSurfaceNum].parm;
}
return groundEntity->navSurfaceNum;
} */
}
bestDist = INFINITE;
bestSurf = -1;
for ( n = 0; n < surfaceCount; n++ ) {
if ( Q_fabs( surface[n].origin[2] - p[2] ) > 24 ) {
continue;
}
VectorSubtract( p, surface[n].origin, v );
dist = VectorLength( v );
if ( dist < bestDist ) {
bestDist = dist;
bestSurf = n;
}
if ( surface[n].origin[2] != p[2] ) {
continue;
}
if ( surface[n].absmin[0] > p[0] ) {
continue;
}
if ( surface[n].absmax[0] < p[0] ) {
continue;
}
if ( surface[n].absmin[1] > p[1] ) {
continue;
}
if ( surface[n].absmax[1] < p[1] ) {
continue;
}
return n;
}
// gi.Printf( "guess for %s at %s\n", ent->classname, vtos( p ) );
return bestSurf;
}
/*
=============
Nav_ItemSurfaceNumber
Returns the surface number for where an item entity is currently located.
If the entity is not on the ground, it returns -1. This is a specialized
copy of Nav_GroundSurfaceNumber for items that caches the result.
=============
*/
int Nav_ItemSurfaceNumber( gentity_t *ent ) {
if ( !VectorCompare( ent->s.origin, ent->navOrigin ) && level.time > ent->navTime ) {
VectorCopy( ent->s.origin, ent->navOrigin );
ent->navTime = level.time;
ent->navSurfaceNum = Nav_GroundSurfaceNumber( ent );
}
return ent->navSurfaceNum;
}
/*
=============
Nav_EntitySurfaceNumber
=============
*/
int Nav_EntitySurfaceNumber( gentity_t *ent ) {
if ( ent->s.eType == ET_ITEM ) {
return Nav_ItemSurfaceNumber( ent );
}
/*if ( ent->classname&& strcmp( ent->classname, "bot_goal" ) == 0 ) {
return Nav_SurfaceUnderPlayer( ent );
}*/
return Nav_GroundSurfaceNumber( ent );
}
/*
=============
PathEdge
=============
*/
static nneighbor_t *PathEdge( int sourceSurfNum, int destSurfNum ) {
int base;
int n;
base = surface[sourceSurfNum].neighborIndex;
for ( n = 0; n < surface[sourceSurfNum].neighborCount; n++ ) {
if ( neighbor[base+n].surfaceNum == destSurfNum ) {
return &neighbor[base+n];
}
}
return NULL;
}
/*
=============
PointIsInEdgeRegion
=============
*/
static qboolean PointIsInEdgeRegion( vec3_t p, nneighbor_t *n ) {
if ( p[0] < n->absmin[0] ) {
return qfalse;
}
if ( p[0] > n->absmax[0] ) {
return qfalse;
}
if ( p[1] < n->absmin[1] ) {
return qfalse;
}
if ( p[1] > n->absmax[1] ) {
return qfalse;
}
return qtrue;
}
/*
=============
Nav_MoveToGoal
=============
*/
int Nav_MoveToGoal( gentity_t *bot, vec3_t dir, int *flags ) {
int currentSurf;
int nextSurf;
int thirdSurf;
int goalSurf;
int routeIndex;
nneighbor_t *edge;
nneighbor_t *nextEdge;
//gentity_t *ent;
//float dist;
*flags = 0;
VectorCopy( bot->navDir, dir );
currentSurf = bot->currentSurface;
// if bot is airborne, just keep heading the same
if ( currentSurf == -1 ) {
if ( bot->aiFlags & BOTAI_PUSHED ) {
//gi.Printf( "bot was bounced\n" );
*flags |= NAVF_HOLD;
}
//gi.Printf( "not on ground\n" );
return 0;
}
if ( bot->pushedTime < level.time ) {
bot->aiFlags &= ~BOTAI_PUSHED;
}
if ( !bot->goalEntity ) {
// gi.Printf( ERROR "Nav_MoveToGoal called with no goalEntity set\n" );
return -1;
}
goalSurf = Nav_EntitySurfaceNumber( bot->goalEntity );
if ( goalSurf == -1 ) {
return -1;
}
// if we've changed surfaces, the surface to surface navigation flags and timer need to be cleared
if ( currentSurf != bot->lastSurface ) {
bot->navFlags = 0;
bot->navTime = 0;
//gi.Printf( "surface changed from %i to %i\n", bot->bot->lastSurface, bot->bot->currentSurface );
}
if ( currentSurf == goalSurf ) {
//gi.Printf( "On target surface\n" );
VectorSubtract( bot->goalEntity->s.origin, bot->s.origin, dir );
//VectorCopy( dir, bot->bot->navDir );
VectorCopy( dir, bot->navDir );
return 0;
}
routeIndex = route[currentSurf * surfaceCount + goalSurf];
if ( routeIndex == 255 ) {
//gi.Printf( "Nav_MoveToGoal - no known route from %i to %i\n", currentSurf, goalSurf );
return -1;
}
if ( routeIndex >= surface[currentSurf].neighborCount ) {
gi.Printf( ERROR "Nav_MoveToGoal - bad routeIndex\n" );
return -1;
}
nextSurf = neighbor[surface[currentSurf].neighborIndex + routeIndex].surfaceNum;
edge = PathEdge( currentSurf, nextSurf );
if ( !edge ) {
gi.Printf( ERROR "Nav_MoveToGoal - %i does not have %i as a neighbor\n", currentSurf, nextSurf );
VectorClear( dir );
return -1;
}
if ( ! ( bot->navFlags & NAVF_EDGEZONE ) ) {
if ( PointIsInEdgeRegion( bot->s.origin, edge ) ) {
//gi.Printf( "hit edge\n" );
bot->navFlags |= NAVF_EDGEZONE;
bot->navTime = level.time;
}
}
// if we are in the edge zone
if ( bot->navFlags & NAVF_EDGEZONE ) {
// if we're trying to get onto a plat, we must make sure it's there
/*if ( surface[nextSurf].flags & SF_PLATLOW ) {
ent = &g_entities[surface[surface[nextSurf].parm].parm]; //FIXME this works for now, but I don't like it
if ( VectorCompare( ent->currentOrigin, ent->pos1 ) == 0 ) {
*flags |= NAVF_HOLD;
//gi.Printf(" wait for plat2\n" );
}
}*/
// if we're riding up on a plat, we don't need to move
if ( surface[nextSurf].flags & SF_PLATHIGH ) {
*flags |= NAVF_HOLD;
//gi.Printf(" hold on plat\n" );
}
// if the next surface contains the goalEntity, head towards it
if ( nextSurf == goalSurf ) {
//gi.Printf( "next surf has goal - targeting directly\n" );
VectorSubtract( bot->goalEntity->s.origin, bot->s.origin, dir );
//VectorCopy( dir, bot->bot->navDir );
VectorCopy( dir, bot->navDir );
}
// start heading towards the next edge
else {
routeIndex = route[nextSurf * surfaceCount + goalSurf];
if ( routeIndex == 255 ) {
gi.Printf( ERROR "Nav_MoveToGoal - no known route from %i to %i\n", nextSurf, goalSurf );
return -1;
}
if ( routeIndex >= surface[nextSurf].neighborCount ) {
gi.Printf( ERROR "Nav_MoveToGoal - bad routeIndex\n" );
return -1;
}
thirdSurf = neighbor[surface[nextSurf].neighborIndex + routeIndex].surfaceNum;
nextEdge = PathEdge( nextSurf, thirdSurf );
if ( !nextEdge ) {
gi.Printf( ERROR "Nav_MoveToGoal - %i does not have %i as a neighbor\n", nextSurf, thirdSurf );
VectorClear( dir );
return -1;
}
//gi.Printf( "targeting next edge\n" );
if ( surface[nextSurf].flags & SF_PLATHIGH ) {
VectorSubtract( nextEdge->origin, surface[nextSurf].origin, dir );
}
else {
VectorSubtract( nextEdge->origin, bot->s.origin, dir );
}
//VectorCopy( dir, bot->bot->navDir );
VectorCopy( dir, bot->navDir );
}
if ( edge->flags & NF_DUCK ) {
*flags |= NAVF_DUCK;
}
if ( edge->flags & NF_JUMP ) {
*flags |= NAVF_JUMP;
}
}
else {
VectorSubtract( edge->origin, bot->s.origin, dir );
//VectorCopy( dir, bot->bot->navDir );
VectorCopy( dir, bot->navDir );
/*if ( surface[nextSurf].flags & SF_PLATLOW ) {
ent = &g_entities[surface[surface[nextSurf].parm].parm]; //FIXME this works for now, but I don't like it
if ( VectorCompare( ent->currentOrigin, ent->pos1 ) == 0 ) {
dist = VectorLength( dir );
if ( dist > 64 ) {
*flags |= NAVF_SLOW;
//gi.Printf(" slow for plat\n" );
}
else {
*flags |= NAVF_HOLD;
//gi.Printf(" wait for plat\n" );
}
}
}*/
}
return 0;
}
void Nav_ShowPath( gentity_t *bot ) {
#if 0
gentity_t *tent;
int m, n;
if ( !bot->bot->goalEntity ) {
return;
}
tent = G_TempEntity( bot->s.origin, EV_DEBUG_LINE );
VectorCopy( bot->bot->currentWaypoint->s.origin, tent->s.origin2 );
m = bot->bot->currentWaypoint->count;
for (;;) {
if ( m == bot->bot->finalWaypoint->count ) {
break;
}
n = route[m*maxwaypoints+bot->bot->finalWaypoint->count];
if ( n == -1 ) {
break;
}
tent = G_TempEntity( rents[m]->s.origin, EV_DEBUG_LINE );
VectorCopy( rents[n]->s.origin, tent->s.origin2 );
m = n;
}
if ( bot->bot->finalWaypoint != bot->bot->goalEntity ) {
tent = G_TempEntity( bot->bot->finalWaypoint->s.origin, EV_DEBUG_LINE );
VectorCopy( bot->bot->goalEntity->s.origin, tent->s.origin2 );
}
#endif
/* gentity_t *tent;
int m, n;
gentity_t *player;
int pSurf;
player = &g_entities[1];
pSurf = Nav_GroundSurfaceNumber( player );
tent = G_TempEntity( player->s.origin, EV_DEBUG_LINE );
VectorCopy( surface[pSurf].origin, tent->s.origin2 ); */
}
//#endif
/*
// Init and Shutdown
//
//
*/
static void Nav_Cleanup( void ) {
if ( navFileData ) {
gi.FS_FreeFile ( navFileData );
navFileData = NULL;
}
surfaceCount = 0;
neighborCount = 0;
}
void Nav_InitPreSpawn( void ) {
nav_showsectors = gi.cvar( "nav_showsectors", "0", 0 );
Nav_Cleanup();
Nav_LoadRoutes();
}
void Nav_InitPostSpawn( void ) {
#if 0
int n;
nsurface_t *s;
gentity_t *ent;
// FIXME resolve targetnames here (like button needed to open a door)
// get the modelindex for the spawnpad model so we can use it for surface determination
spawnpadModelIndex = G_ModelIndex( "models/objects/dmspot.md3" );
// set the navSurface for plats
for ( n = 0; n < surfaceCount; n++ ) {
s = &surface[n];
if ( s->flags & SF_PLATLOW ) {
ent = &g_entities[surface[s->parm].parm]; //FIXME this works for now, but I don't like it
ent->navSurfaceNum = n;
}
}
#endif
}
void Nav_Shutdown ( void ) {
Nav_Cleanup();
}
void Nav_Test_f( void ) {
#if 0
gentity_t *player;
gentity_t *goal;
char *goalname;
int pSurf;
int gSurf;
int cSurf;
int n;
gentity_t *tent;
player = &g_entities[0];
pSurf = Nav_GroundSurfaceNumber( player );
goalname = gi.argv(2);
if ( !goalname[0] ) {
gi.Printf( "Player1 is at (%f, %f, %f) on surface %i\n", player->s.origin[0], player->s.origin[1], player->s.origin[2] + player->mins[2], pSurf );
return;
}
goal = NULL;
goal = G_Find( goal, FOFS( classname ), goalname );
if ( !goal ) {
gi.Printf( "no %s on level\n", goalname );
return;
}
gSurf = Nav_EntitySurfaceNumber( goal );
cSurf = pSurf;
while ( cSurf != gSurf ) {
n = route[cSurf * surfaceCount + gSurf];
if ( n == 255 ) {
//gi.Printf( "no known route from %i to %i\n", cSurf, gSurf );
return;
}
if ( n >= surface[cSurf].neighborCount ) {
gi.Printf( ERROR "bad routeIndex\n" );
return;
}
n = neighbor[surface[cSurf].neighborIndex + n].surfaceNum;
if ( cSurf == pSurf ) {
tent = G_TempEntity( player->s.origin, EV_DEBUG_LINE );
}
else {
tent = G_TempEntity( surface[cSurf].origin, EV_DEBUG_LINE );
}
if ( n == gSurf ) {
VectorCopy( goal->s.origin, tent->s.origin2 );
}
else {
VectorCopy( surface[n].origin, tent->s.origin2 );
}
cSurf = n;
}
#endif
}
void Nav_Gen_f( void );
void Cmd_Nav_f( void )
{
char *cmd;
cmd = gi.argv(1);
if ( Q_stricmp ( cmd, "gen" ) == 0 ) {
Nav_Gen_f();
Nav_InitPreSpawn();
}
else if ( Q_stricmp ( cmd, "test" ) == 0 ) {
Nav_Test_f();
}
else {
gi.Printf("Unknown nav command '%s'\n", cmd);
}
}
void Nav_ShowStuff
(
void
)
{
int i;
nsurface_t *surf;
if ( !nav_showsectors->integer )
{
return;
}
G_Color4f( 1, 1, 0, 1 );
for( i = 0; i < surfaceCount; i++ )
{
surf = &surface[ i ];
G_BeginLine();
G_Vertex( Vector( surf->absmin[ 0 ], surf->absmin[ 1 ], surf->origin[ 2 ] ) );
G_Vertex( Vector( surf->absmin[ 0 ], surf->absmax[ 1 ], surf->origin[ 2 ] ) );
G_Vertex( Vector( surf->absmax[ 0 ], surf->absmax[ 1 ], surf->origin[ 2 ] ) );
G_Vertex( Vector( surf->absmax[ 0 ], surf->absmin[ 1 ], surf->origin[ 2 ] ) );
G_Vertex( Vector( surf->absmin[ 0 ], surf->absmin[ 1 ], surf->origin[ 2 ] ) );
G_EndLine();
}
}

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "barrels.h"
#include "weaputils.h"
#include "level.h"
/*****************************************************************************
/*QUAKED func_barrel (0 0.25 0.5) ? INDESTRUCTABLE

90
code/game/baseimp.h Normal file
View file

@ -0,0 +1,90 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __BASEIMP_H__
#define __BASEIMP_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct aliasListNode_s aliasListNode_t;
typedef struct cvar_s cvar_t;
typedef struct baseImport_s
{
void ( *Printf )( const char *format, ... );
void ( *DPrintf )( const char *format, ... );
const char * ( *LV_ConvertString )( const char *string );
cvar_t * ( *Cvar_Get )( const char *varName, const char *varValue, int varFlags );
void( *Cvar_Set )( const char *varName, const char *varValue );
int( *FS_ReadFile )( const char *qpath, void **buffer, qboolean quiet );
void( *FS_FreeFile )( void *buffer );
size_t( *FS_WriteFile )( const char *qpath, const void *buffer, size_t size );
fileHandle_t( *FS_FOpenFileWrite )( const char *fileName );
fileHandle_t( *FS_FOpenFileAppend )( const char *fileName );
fileHandle_t( *FS_FOpenFile )( const char *fileName );
const char *( *FS_PrepFileWrite )( const char *fileName );
size_t( *FS_Write )( const void *buffer, size_t len, fileHandle_t fileHandle );
size_t( *FS_Read )( void *buffer, size_t len, fileHandle_t fileHandle );
void( *FS_FCloseFile )( fileHandle_t fileHandle );
int( *FS_Tell )( fileHandle_t fileHandle );
int( *FS_Seek )( fileHandle_t fileHandle, long int offset, fsOrigin_t origin );
void( *FS_Flush )( fileHandle_t fileHandle );
int( *FS_FileNewer )( const char *source, const char *destination );
void( *FS_CanonicalFilename )( char *fileName );
char **( *FS_ListFiles )( const char *qpath, const char *extension, qboolean wantSubs, int *numFiles );
void( *FS_FreeFileList )( char **list );
int( *Milliseconds )( );
double( *MillisecondsDbl )( );
void( *Error )( int errortype, const char *format, ... );
void *( *Malloc )( size_t size );
void( *Free )( void *ptr );
int( *Key_StringToKeynum )( const char *str );
char * ( *Key_KeynumToBindString )( int keyNum );
void( *Key_GetKeysForCommand )( const char *command, int *key1, int *key2 );
void( *SendConsoleCommand )( const char *text );
void( *SendServerCommand )( int client, const char *format, ... );
qboolean( *GlobalAlias_Add )( const char *alias, const char *name, const char *parameters );
char * ( *GlobalAlias_FindRandom )( const char *alias, aliasListNode_t **ret );
void( *GlobalAlias_Dump )( );
void( *GlobalAlias_Clear )( );
void( *SetConfigstring )( int index, const char *val );
char *( *GetConfigstring )( int index );
void( *AddSvsTimeFixup )( int *piTime );
} baseImport_t;
extern baseImport_t bi;
extern cvar_t *developer;
extern cvar_t *precache;
extern cvar_t *sv_scriptfiles;
extern cvar_t *g_scriptcheck;
extern cvar_t *g_showopcodes;
void CacheResource( const char *name );
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,210 +0,0 @@
// 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;

View file

@ -1,32 +0,0 @@
// 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);

View file

@ -1,97 +0,0 @@
// 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);

View file

@ -1,17 +0,0 @@
// 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);

View file

@ -1,102 +0,0 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_goal.h
*
* desc: goal AI
*
* $Archive: /Code/DLLs/game/be_ai_goal.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 5/17/02 11:35a $
* $Date: 7/31/02 10:45a $
*
*****************************************************************************/
#define MAX_AVOIDGOALS 256
#define MAX_GOALSTACK 8
#define GFL_NONE 0
#define GFL_ITEM 1
#define GFL_ROAM 2
#define GFL_DROPPED 4
//a bot goal
typedef struct bot_goal_s
{
vec3_t origin; //origin of the goal
int areanum; //area number of the goal
vec3_t mins, maxs; //mins and maxs of the goal
int entitynum; //number of the goal entity
int number; //goal number
int flags; //goal flags
int iteminfo; //item information
} bot_goal_t;
//reset the whole goal state, but keep the item weights
void BotResetGoalState(int goalstate);
//reset avoid goals
void BotResetAvoidGoals(int goalstate);
//remove the goal with the given number from the avoid goals
void BotRemoveFromAvoidGoals(int goalstate, int number);
//push a goal onto the goal stack
void BotPushGoal(int goalstate, bot_goal_t *goal);
//pop a goal from the goal stack
void BotPopGoal(int goalstate);
//empty the bot's goal stack
void BotEmptyGoalStack(int goalstate);
//dump the avoid goals
void BotDumpAvoidGoals(int goalstate);
//dump the goal stack
void BotDumpGoalStack(int goalstate);
//get the name name of the goal with the given number
void BotGoalName(int number, char *name, int size);
//get the top goal from the stack
int BotGetTopGoal(int goalstate, bot_goal_t *goal);
//get the second goal on the stack
int BotGetSecondGoal(int goalstate, bot_goal_t *goal);
//choose the best long term goal item for the bot
int BotChooseLTGItem(int goalstate, vec3_t origin, int *inventory, int travelflags);
//choose the best nearby goal item for the bot
//the item may not be further away from the current bot position than maxtime
//also the travel time from the nearby goal towards the long term goal may not
//be larger than the travel time towards the long term goal from the current bot position
int BotChooseNBGItem(int goalstate, vec3_t origin, int *inventory, int travelflags,
bot_goal_t *ltg, float maxtime);
//returns true if the bot touches the goal
int BotTouchingGoal(vec3_t origin, bot_goal_t *goal);
//returns true if the goal should be visible but isn't
int BotItemGoalInVisButNotVisible(int viewer, vec3_t eye, vec3_t viewangles, bot_goal_t *goal);
//search for a goal for the given classname, the index can be used
//as a start point for the search when multiple goals are available with that same classname
int BotGetLevelItemGoal(int index, char *classname, bot_goal_t *goal);
//get the next camp spot in the map
int BotGetNextCampSpotGoal(int num, bot_goal_t *goal);
//get the map location with the given name
int BotGetMapLocationGoal(char *name, bot_goal_t *goal);
//returns the avoid goal time
float BotAvoidGoalTime(int goalstate, int number);
//set the avoid goal time
void BotSetAvoidGoalTime(int goalstate, int number, float avoidtime);
//initializes the items in the level
void BotInitLevelItems(void);
//regularly update dynamic entity items (dropped weapons, flags etc.)
void BotUpdateEntityItems(void);
//interbreed the goal fuzzy logic
void BotInterbreedGoalFuzzyLogic(int parent1, int parent2, int child);
//save the goal fuzzy logic to disk
void BotSaveGoalFuzzyLogic(int goalstate, char *filename);
//mutate the goal fuzzy logic
void BotMutateGoalFuzzyLogic(int goalstate, float range);
//loads item weights for the bot
int BotLoadItemWeights(int goalstate, char *filename);
//frees the item weights of the bot
void BotFreeItemWeights(int goalstate);
//returns the handle of a newly allocated goal state
int BotAllocGoalState(int client);
//free the given goal state
void BotFreeGoalState(int handle);
//setup the goal AI
int BotSetupGoalAI(void);
//shut down the goal AI
void BotShutdownGoalAI(void);

View file

@ -1,126 +0,0 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_move.h
*
* desc: movement AI
*
* $Archive: /Code/DLLs/game/be_ai_move.h $
* $Author: Jwaters $
* $Revision: 1 $
* $Modtime: 5/17/02 11:35a $
* $Date: 7/31/02 10:45a $
*
*****************************************************************************/
//movement types
#define MOVE_WALK 1
#define MOVE_CROUCH 2
#define MOVE_JUMP 4
#define MOVE_GRAPPLE 8
#define MOVE_ROCKETJUMP 16
#define MOVE_BFGJUMP 32
//move flags
#define MFL_BARRIERJUMP 1 //bot is performing a barrier jump
#define MFL_ONGROUND 2 //bot is in the ground
#define MFL_SWIMMING 4 //bot is swimming
#define MFL_AGAINSTLADDER 8 //bot is against a ladder
#define MFL_WATERJUMP 16 //bot is waterjumping
#define MFL_TELEPORTED 32 //bot is being teleported
#define MFL_GRAPPLEPULL 64 //bot is being pulled by the grapple
#define MFL_ACTIVEGRAPPLE 128 //bot is using the grapple hook
#define MFL_GRAPPLERESET 256 //bot has reset the grapple
#define MFL_WALK 512 //bot should walk slowly
// move result flags
#define MOVERESULT_MOVEMENTVIEW 1 //bot uses view for movement
#define MOVERESULT_SWIMVIEW 2 //bot uses view for swimming
#define MOVERESULT_WAITING 4 //bot is waiting for something
#define MOVERESULT_MOVEMENTVIEWSET 8 //bot has set the view in movement code
#define MOVERESULT_MOVEMENTWEAPON 16 //bot uses weapon for movement
#define MOVERESULT_ONTOPOFOBSTACLE 32 //bot is ontop of obstacle
#define MOVERESULT_ONTOPOF_FUNCBOB 64 //bot is ontop of a func_bobbing
#define MOVERESULT_ONTOPOF_ELEVATOR 128 //bot is ontop of an elevator (func_plat)
#define MOVERESULT_BLOCKEDBYAVOIDSPOT 256 //bot is blocked by an avoid spot
//
#define MAX_AVOIDREACH 1
#define MAX_AVOIDSPOTS 32
// avoid spot types
#define AVOID_CLEAR 0 //clear all avoid spots
#define AVOID_ALWAYS 1 //avoid always
#define AVOID_DONTBLOCK 2 //never totally block
// restult types
#define RESULTTYPE_ELEVATORUP 1 //elevator is up
#define RESULTTYPE_WAITFORFUNCBOBBING 2 //waiting for func bobbing to arrive
#define RESULTTYPE_BADGRAPPLEPATH 4 //grapple path is obstructed
#define RESULTTYPE_INSOLIDAREA 8 //stuck in solid area, this is bad
//structure used to initialize the movement state
//the or_moveflags MFL_ONGROUND, MFL_TELEPORTED and MFL_WATERJUMP come from the playerstate
typedef struct bot_initmove_s
{
vec3_t origin; //origin of the bot
vec3_t velocity; //velocity of the bot
vec3_t viewoffset; //view offset
int entitynum; //entity number of the bot
int client; //client number of the bot
float thinktime; //time the bot thinks
int presencetype; //presencetype of the bot
vec3_t viewangles; //view angles of the bot
int or_moveflags; //values ored to the movement flags
} bot_initmove_t;
//NOTE: the ideal_viewangles are only valid if MFL_MOVEMENTVIEW is set
typedef struct bot_moveresult_s
{
int failure; //true if movement failed all together
int type; //failure or blocked type
int blocked; //true if blocked by an entity
int blockentity; //entity blocking the bot
int traveltype; //last executed travel type
int flags; //result flags
int weapon; //weapon used for movement
vec3_t movedir; //movement direction
vec3_t ideal_viewangles; //ideal viewangles for the movement
} bot_moveresult_t;
// bk001204: from code/botlib/be_ai_move.c
// TTimo 04/12/2001 was moved here to avoid dup defines
typedef struct bot_avoidspot_s
{
vec3_t origin;
float radius;
int type;
} bot_avoidspot_t;
//resets the whole move state
void BotResetMoveState(int movestate);
//moves the bot to the given goal
void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, int travelflags);
//moves the bot in the specified direction using the specified type of movement
int BotMoveInDirection(int movestate, vec3_t dir, float speed, int type);
//reset avoid reachability
void BotResetAvoidReach(int movestate);
//resets the last avoid reachability
void BotResetLastAvoidReach(int movestate);
//returns a reachability area if the origin is in one
int BotReachabilityArea(vec3_t origin, int client);
//view target based on movement
int BotMovementViewTarget(int movestate, bot_goal_t *goal, int travelflags, float lookahead, vec3_t target);
//predict the position of a player based on movement towards a goal
int BotPredictVisiblePosition(vec3_t origin, int areanum, bot_goal_t *goal, int travelflags, vec3_t target);
//returns the handle of a newly allocated movestate
int BotAllocMoveState(void);
//frees the movestate with the given handle
void BotFreeMoveState(int handle);
//initialize movement state before performing any movement
void BotInitMoveState(int handle, bot_initmove_t *initmove);
//add a spot to avoid (if type == AVOID_CLEAR all spots are removed)
void BotAddAvoidSpot(int movestate, vec3_t origin, float radius, int type);
//must be called every map change
void BotSetBrushModelTypes(void);
//setup movement AI
int BotSetupMoveAI(void);
//shutdown movement AI
void BotShutdownMoveAI(void);

View file

@ -1,90 +0,0 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ai_weap.h
*
* desc: weapon AI
*
* $Archive: /Code/DLLs/game/be_ai_weap.h $
* $Author: Jwaters $
* $Revision: 4 $
* $Modtime: 8/19/02 3:51p $
* $Date: 8/19/02 4:08p $
*
*****************************************************************************/
//projectile flags
#define PFL_WINDOWDAMAGE 1 //projectile damages through window
#define PFL_RETURN 2 //set when projectile returns to owner
//weapon flags
#define WFL_FIRERELEASED 1 //set when projectile is fired with key-up event
//damage types
#define DAMAGETYPE_IMPACT 1 //damage on impact
#define DAMAGETYPE_RADIAL 2 //radial damage
#define DAMAGETYPE_VISIBLE 4 //damage to all entities visible to the projectile
typedef struct projectileinfo_s
{
char name[MAX_STRINGFIELD];
char model[MAX_STRINGFIELD];
int flags;
float gravity;
int damage;
float radius;
int visdamage;
int damagetype;
int healthinc;
float push;
float detonation;
float bounce;
float bouncefric;
float bouncestop;
} projectileinfo_t;
typedef struct weaponinfo_s
{
int valid; //true if the weapon info is valid
int number; //number of the weapon
char name[MAX_STRINGFIELD];
char model[MAX_STRINGFIELD];
int level;
int weaponindex;
int flags;
char projectile[MAX_STRINGFIELD];
int numprojectiles;
float hspread;
float vspread;
float speed;
float acceleration;
vec3_t recoil;
vec3_t offset;
vec3_t angleoffset;
float extrazvelocity;
int ammoamount;
int ammoindex;
float activate;
float reload;
float spinup;
float spindown;
int primarydangerous; // if primary and/or alternate fire are REALLY DANGEROUS
int altdangerous;
projectileinfo_t proj; //pointer to the used projectile
} weaponinfo_t;
//setup the weapon AI
int BotSetupWeaponAI(void);
//shut down the weapon AI
void BotShutdownWeaponAI(void);
//returns the best weapon to fight with
int BotChooseBestFightWeapon(int weaponstate, int *inventory);
//returns the information of the current weapon
void BotGetWeaponInfo(int weaponstate, int weapon, weaponinfo_t *weaponinfo);
//loads the weapon weights
int BotLoadWeaponWeights(int weaponstate, char *filename);
//returns a handle to a newly allocated weapon state
int BotAllocWeaponState(void);
//frees the weapon state
void BotFreeWeaponState(int weaponstate);
//resets the whole weapon state
void BotResetWeaponState(int weaponstate);

View file

@ -1,51 +0,0 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
/*****************************************************************************
* name: be_ea.h
*
* desc: elementary actions
*
* $Archive: /Code/DLLs/game/be_ea.h $
* $Author: Jwaters $
* $Revision: 2 $
* $Modtime: 8/08/02 12:17p $
* $Date: 8/08/02 1:38p $
*
*****************************************************************************/
//ClientCommand elementary actions
void EA_Say(int client, char *str);
void EA_SayTeam(int client, char *str);
void EA_Command(int client, const char *command );
void EA_Action(int client, int action);
void EA_Crouch(int client);
void EA_Walk(int client);
void EA_MoveUp(int client);
void EA_MoveDown(int client);
void EA_MoveForward(int client);
void EA_MoveBack(int client);
void EA_MoveLeft(int client);
void EA_MoveRight(int client);
void EA_ToggleFireState(int client);
void EA_Attack(int client, int primarydangerous, int altdangerous);
void EA_Respawn(int client);
void EA_Talk(int client);
void EA_Gesture(int client);
void EA_Use(int client);
//regular elementary actions
void EA_SelectWeapon(int client, int weapon);
void EA_Jump(int client);
void EA_DelayedJump(int client);
void EA_Move(int client, vec3_t dir, float speed);
void EA_View(int client, vec3_t viewangles);
//send regular input to the server
void EA_EndRegular(int client, float thinktime);
void EA_GetInput(int client, float thinktime, bot_input_t *input);
void EA_ResetInput(int client);
//setup and shutdown routines
int EA_Setup(void);
void EA_Shutdown(void);

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "beam.h"
#include "../qcommon/qfiles.h"
#include "game.h"
/*****************************************************************************/
/*QUAKED func_beam (0 0.25 .5) (-8 -8 -8) (8 8 8) START_ON PERSIST WAVE NOISE

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "BSpline.h"
#include "game.h"
void BSpline::Set
(

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entity.h"
#include "bspline.h"
#include "container.h"
#include "level.h"
#define CAMERA_SWITCHTIME 0.5f

1949
code/game/compiler.cpp Normal file

File diff suppressed because it is too large Load diff

177
code/game/compiler.h Normal file
View file

@ -0,0 +1,177 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// compiler.h: Script Compiler
#ifndef __COMPILER_H__
#define __COMPILER_H__
#include "glb_local.h"
#include <scriptopcodes.h>
#include <gamescript.h>
#include <parser/parsetree.h>
enum
{
method_game,
method_level,
method_local,
method_parm,
method_self,
method_group,
method_owner,
method_field,
method_array,
};
typedef struct scriptmacro {
str name;
str parameters;
} scriptmacro_t;
#define BREAK_JUMP_LOCATION_COUNT 100
#define CONTINUE_JUMP_LOCATION_COUNT 100
class ScriptCompiler
{
public:
unsigned char *code_pos;
unsigned char *code_ptr;
unsigned char *prog_ptr;
unsigned char *prog_end_ptr;
GameScript *script;
StateScript *stateScript;
bool bCanBreak;
bool bCanContinue;
opcode_info_t prev_opcodes[ 100 ];
unsigned int prev_opcode_pos;
int m_iVarStackOffset;
int m_iInternalMaxVarStackOffset;
int m_iMaxExternalVarStackOffset;
int m_iMaxCallStackOffset;
int m_iHasExternal;
unsigned char *apucBreakJumpLocations[ BREAK_JUMP_LOCATION_COUNT ];
int iBreakJumpLocCount;
unsigned char *apucContinueJumpLocations[ CONTINUE_JUMP_LOCATION_COUNT ];
int iContinueJumpLocCount;
bool compileSuccess;
static int current_label;
public:
ScriptCompiler();
void Reset();
unsigned char PrevOpcode();
char PrevVarStackOffset();
void AbsorbPrevOpcode();
void ClearPrevOpcode();
void AddBreakJumpLocation( unsigned char *pos );
void AddContinueJumpLocation( unsigned char *pos );
void AddJumpLocation( unsigned char *pos );
void AddJumpBackLocation( unsigned char *pos );
void AddJumpToLocation( unsigned char *pos );
bool BuiltinReadVariable( unsigned int sourcePos, int type, int eventnum );
bool BuiltinWriteVariable( unsigned int sourcePos, int type, int eventnum );
void EmitAssignmentStatement( sval_t lhs, unsigned int sourcePos );
void EmitBoolJumpFalse( unsigned int sourcePos );
void EmitBoolJumpTrue( unsigned int sourcePos );
void EmitBoolNot( unsigned int sourcePos );
void EmitBoolToVar( unsigned int sourcePos );
void EmitBreak( unsigned int sourcePos );
void EmitCatch( sval_t val, unsigned char *try_begin_code_pos, unsigned int sourcePos );
void EmitConstArray( sval_t lhs, sval_t rhs, unsigned int sourcePos );
void EmitConstArrayOpcode( int iCount );
void EmitContinue( unsigned int sourcePos );
void EmitDoWhileJump( sval_t while_stmt, sval_t while_expr, unsigned int sourcePos );
void EmitEof( unsigned int sourcePos );
void EmitField( sval_t listener_val, sval_t field_val, unsigned int sourcePos );
void EmitFloat( float value, unsigned int sourcePos );
void EmitFunc1( int opcode, unsigned int sourcePos );
void EmitFunction( int iParamCount, sval_t val, unsigned int sourcePos );
void EmitIfElseJump( sval_t if_stmt, sval_t else_stmt, unsigned int sourcePos );
void EmitIfJump( sval_t if_stmt, unsigned int sourcePos );
void EmitInteger( unsigned int value, unsigned int sourcePos );
void EmitJump( unsigned char *pos, unsigned int sourcePos );
void EmitJumpBack( unsigned char *pos, unsigned int sourcePos );
void EmitLabel( str name, unsigned int sourcePos );
void EmitLabelParameterList( sval_t parameter_list, unsigned int sourcePos );
void EmitLabelPrivate( str name, unsigned int sourcePos );
void EmitLogicJump( sval_t logic_stmt, bool isOr, unsigned int sourcePos );
void EmitMakeArray( sval_t val );
void EmitMethodExpression( int iParamCount, int eventnum, unsigned int sourcePos );
void EmitNil( unsigned int sourcePos );
void EmitNop();
int EmitNot( unsigned int sourcePos );
void EmitOpcode( int opcode, unsigned int sourcePos );
void EmitParameter( sval_u lhs, unsigned int sourcePos );
int EmitParameterList( sval_t event_parameter_list );
void EmitRef( sval_t val, unsigned int sourcePos );
void EmitStatementList( sval_t val );
void EmitString( str value, unsigned int sourcePos );
void EmitSwitch( sval_t val, unsigned int sourcePos );
void EmitValue( sval_t val );
void EmitValue( ScriptVariable& var, unsigned int sourcePos );
void EmitVarToBool( unsigned int sourcePos );
void EmitWhileJump( sval_t while_expr, sval_t while_stmt, sval_t inc_stmt, unsigned int sourcePos );
bool EvalPrevValue( ScriptVariable& var );
void OptimizeInstructions( unsigned char *code, unsigned char *op1, unsigned char *op2 );
int OptimizeValue( int val1, int val2, unsigned char opcode );
void ProcessBreakJumpLocations( int iStartBreakJumpLocCount );
void ProcessContinueJumpLocations( int iStartContinueJumpLocCount );
unsigned char *GetPosition();
// compile
void CompileError( unsigned int sourcePos, const char *format, ... );
scriptmacro_t *GetMacro( char *sourceLine );
char *Preprocess( char *sourceBuffer );
void Preclean( char *processedBuffer );
size_t Parse( GameScript *m_GameScript, char *sourceBuffer );
size_t Compile( GameScript *m_GameScript, unsigned char *progBuffer );
void Optimize( unsigned char *progBuffer );
static str GetLine( str content, int line );
};
extern ScriptCompiler Compiler;
void CompileAssemble( const char *filename, const char *outputfile );
bool GetCompiledScript( GameScript *scr );
#endif

View file

@ -0,0 +1,87 @@
#include "consoleevent.h"
#include "g_local.h"
//===============================
// ConsoleEvent
//===============================
MEM_BlockAlloc< ConsoleEvent, MEM_BLOCKSIZE > ConsoleEvent_allocator;
CLASS_DECLARATION(Event, ConsoleEvent, NULL)
{
{ NULL, NULL }
};
/*
=======================
new ConsoleEvent
=======================
*/
void* ConsoleEvent::operator new(size_t size)
{
return ConsoleEvent_allocator.Alloc();
}
/*
=======================
delete ptr
=======================
*/
void ConsoleEvent::operator delete(void* ptr)
{
ConsoleEvent_allocator.Free(ptr);
}
/*
=======================
ConsoleEvent
=======================
*/
ConsoleEvent::ConsoleEvent(void)
{
m_consoleedict = NULL;
}
/*
=======================
SetConsoleEdict
=======================
*/
void ConsoleEvent::SetConsoleEdict(gentity_t* edict)
{
m_consoleedict = edict;
}
/*
=======================
GetConsoleEdict
=======================
*/
gentity_t* ConsoleEvent::GetConsoleEdict(void)
{
if (m_consoleedict)
return m_consoleedict;
return g_entities;
}
/*
=======================
ErrorInternal
=======================
*/
void ConsoleEvent::ErrorInternal(Listener* l, str text)
{
gentity_t* edict = GetConsoleEdict();
str eventname = getName();
gi.DPrintf("^~^~^ Game ( Event '%s', Client '%s' ) : %s\n",
eventname.c_str(),
edict->client ? edict->client->pers.netname : "",
text.c_str());
gi.SendServerCommand(GetConsoleEdict() - g_entities,
"print \"Console: '%s' : %s\n\"",
eventname.c_str(),
text.c_str());
}

27
code/game/consoleevent.h Normal file
View file

@ -0,0 +1,27 @@
#pragma once
#include <listener.h>
#include <mem_blockalloc.h>
#include "g_public.h"
class ConsoleEvent : public Event
{
private:
gentity_t* m_consoleedict;
public:
CLASS_PROTOTYPE(ConsoleEvent);
void* operator new(size_t size);
void operator delete(void* ptr);
ConsoleEvent();
ConsoleEvent(str name) : Event(name) { m_consoleedict = NULL; }
void SetConsoleEdict(gentity_t* edict);
gentity_t* GetConsoleEdict(void);
virtual void ErrorInternal(Listener* l, str text);
};
extern MEM_BlockAlloc< ConsoleEvent, MEM_BLOCKSIZE > ConsoleEvent_allocator;

88
code/game/crc32.h Normal file
View file

@ -0,0 +1,88 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// crc32.h: CRC32 Encryption (used by the Archiver)
#ifndef __CRC32_H__
#define __CRC32_H8_
static unsigned int crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
inline
unsigned int crc32( unsigned int crc, const void *buf, size_t size )
{
const unsigned char *p;
p = ( const unsigned char * )buf;
crc = crc ^ ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}
#endif // __CRC32_H__

286
code/game/dbgheap.cpp Normal file
View file

@ -0,0 +1,286 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// dbgheap.cpp: Heap Debugger.
#include <glb_local.h>
#include <dbgheap.h>
DbgHeap m_Heap;
refptr_t *DbgHeap::hashTable[ DBG_HEAP_HASHSIZE ];
#ifdef WIN32
extern "C" {
typedef struct _SYMBOL_INFO {
unsigned long SizeOfStruct;
unsigned long TypeIndex;
unsigned __int64 Reserved[ 2 ];
unsigned long Index;
unsigned long Size;
unsigned __int64 ModBase;
unsigned long Flags;
unsigned __int64 Value;
unsigned __int64 Address;
unsigned long Register;
unsigned long Scope;
unsigned long Tag;
unsigned long NameLen;
unsigned long MaxNameLen;
char Name[ 1 ];
} SYMBOL_INFO, *PSYMBOL_INFO;
unsigned short __stdcall RtlCaptureStackBackTrace
(
unsigned long FramesToSkip,
unsigned long FramesToCapture,
void *BackTrace,
unsigned long *BackTraceHash
);
void * __stdcall GetCurrentProcess
(
void
);
unsigned int __stdcall SymInitialize
(
void *hProcess,
const char *UserSearchPath,
int fInvadeProcess
);
unsigned int __stdcall SymFromAddr
(
void *hProcess,
unsigned long long Address,
unsigned long long *Displacement,
PSYMBOL_INFO Symbol
);
}
#endif
DbgHeap::DbgHeap()
{
}
DbgHeap::~DbgHeap()
{
/*
refptr_t *rootptr;
refptr_t *ref;
refptr_t *next;
for( int i = 0; i < DBG_HEAP_HASHSIZE; i++ )
{
rootptr = hashTable[ i ];
for( ref = rootptr; ref != NULL; ref = next )
{
next = ref->next;
free( ref );
}
}
rootptr = NULL;
*/
}
refptr_t *DbgHeap::FindReference
(
void *ptr
)
{
refptr_t *ref;
refptr_t *rootptr;
rootptr = hashTable[ ( ( size_t )ptr / 8 ) % DBG_HEAP_HASHSIZE ];
for( ref = rootptr; ref != NULL; ref = ref->next )
{
if( ref->ptr == ptr )
return ref;
}
return NULL;
}
void DbgHeap::ReferencePointer
(
void *ptr
)
{
return;
refptr_t *ref = FindReference( ptr );
refptr_t **rootptr;
if( !ref )
{
ref = ( refptr_t * )malloc( sizeof( refptr_t ) );
ref->ptr = ptr;
ref->refcount = 0;
ref->next = NULL;
#ifdef WIN32
RtlCaptureStackBackTrace( 1, DBG_HEAP_MAX_CALLSTACK, ref->callstack, NULL );
#endif
rootptr = &hashTable[ ( ( size_t )ptr / 8 ) % DBG_HEAP_HASHSIZE ];
if( !*rootptr )
{
*rootptr = ref;
}
else
{
ref->next = *rootptr;
*rootptr = ref;
}
}
// Increase the reference count
ref->refcount++;
}
void DbgHeap::DereferencePointer
(
void *ptr
)
{
return;
refptr_t *ref = FindReference( ptr );
assert( ref );
if( !ref )
{
// Trying to dereference a non-existing pointer
exit( EXIT_FAILURE );
return;
}
assert( ref->refcount > 0 );
if( !ref->refcount )
{
// Trying to dereference an unreferenced pointer
exit( EXIT_FAILURE );
return;
}
ref->refcount--;
/*
if( !ref->refcount )
{
refptr_t *r;
refptr_t *rootptr;
rootptr = hashTable[ ( ( size_t )ptr / 8 ) % DBG_HEAP_HASHSIZE ];
if( ref != rootptr )
{
for( r = rootptr; r != NULL; r = r->next )
{
if( r->ptr == ptr )
{
ref->next = r->next;
break;
}
ref = r;
}
}
else
{
hashTable[ ( ( size_t )ptr / 8 ) % DBG_HEAP_HASHSIZE ] = ref->next;
}
}
*/
#ifdef WIN32
RtlCaptureStackBackTrace( 1, DBG_HEAP_MAX_CALLSTACK, ref->callstack, NULL );
#endif
}
/*
void *operator new( size_t size )
{
void *ptr = malloc( size );
m_Heap.ReferencePointer( ptr );
return ptr;
}
void *operator new[]( size_t size )
{
void *ptr = malloc( size );
m_Heap.ReferencePointer( ptr );
return ptr;
}
void operator delete( void *ptr )
{
m_Heap.DereferencePointer( ptr );
free( ptr );
}
void operator delete[]( void *ptr )
{
m_Heap.DereferencePointer( ptr );
free( ptr );
}
*/
#ifdef _DEBUG_MEM
#undef new
void *operator new( size_t size, const char* file, int line )
{
return _malloc_dbg( size, _NORMAL_BLOCK, file, line );
}
void *operator new[]( size_t size, const char* file, int line )
{
return _malloc_dbg( size, _NORMAL_BLOCK, file, line );
}
void operator delete( void *ptr, const char* file, int line )
{
return _free_dbg( ptr, _NORMAL_BLOCK );
}
void operator delete[]( void *ptr, const char* file, int line )
{
return _free_dbg( ptr, _NORMAL_BLOCK );
}
#endif

75
code/game/dbgheap.h Normal file
View file

@ -0,0 +1,75 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// dbgheap.h: Heap Debugger.
#ifndef __DBGHEAP_H__
#define __DBGHEAP_H__
#include <stdio.h>
#include <stdlib.h>
#define DBG_HEAP_HASHSIZE 4096
#define DBG_HEAP_MAX_CALLSTACK 16
typedef struct refptr {
void *ptr;
unsigned char refcount;
void *callstack[ DBG_HEAP_MAX_CALLSTACK ];
struct refptr *next;
} refptr_t;
class DbgHeap
{
private:
static refptr_t *hashTable[ DBG_HEAP_HASHSIZE ];
private:
refptr_t *FindReference( void *ptr );
public:
DbgHeap();
~DbgHeap();
void ReferencePointer( void *ptr );
void DereferencePointer( void *ptr );
};
extern void *operator new( size_t size );
extern void *operator new[]( size_t size );
extern void operator delete( void *ptr );
extern void operator delete[]( void *ptr );
#ifdef _DEBUG_MEM
extern void *operator new( size_t size, const char* file, int line );
extern void *operator new[]( size_t size, const char* file, int line );
extern void operator delete( void *ptr, const char* file, int line );
extern void operator delete[]( void *ptr, const char* file, int line );
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
#endif
extern DbgHeap m_Heap;
#endif /* dbgheap.h */

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
#include "debuglines.h"
#include "game.h"
#define NUM_CIRCLE_SEGMENTS 24

View file

@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// decals.cpp: Decal entities
#include "decals.h"
#include "level.h"
CLASS_DECLARATION( Entity, Decal, NULL )
{

View file

@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "earthquake.h"
#include "weapon.h"
#include "sentient.h"
#include "level.h"
/*****************************************************************************/
/*QUAKED func_viewjitter (0 0.25 0.5) (-8 -8 -8) (8 8 8)

View file

@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "entity.h"
#include "game.h"
// FIXME: OLD Q3 CODE
#if 0

View file

@ -1464,11 +1464,8 @@ GetGameAPI
Gets game imports and returns game exports
================
*/
#ifndef WIN32
extern "C"
__attribute__((visibility("default")))
#endif
gameExport_t* GetGameAPI( gameImport_t *import )
gameExport_t * GetGameAPI(gameImport_t * import)
{
gi = *import;

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "entity.h"
#include "game.h"
typedef struct {
qboolean validGroundTrace;

View file

@ -23,6 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// g_public.h -- game module information visible to server
#pragma once
#include "bg_public.h"
#define GAME_API_VERSION 12
// entity->svFlags
@ -807,6 +811,14 @@ typedef struct gameExport_s {
#ifdef __cplusplus
extern "C"
#endif
#ifdef GAME_DLL
#ifdef WIN32
__declspec(dllexport)
#else
__attribute__((visibility("default")))
#endif
#endif
gameExport_t* GetGameAPI( gameImport_t *import );
#if 0

View file

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//
#include "g_local.h"
#include "game.h"
/*

1409
code/game/g_spawn.cpp Normal file

File diff suppressed because it is too large Load diff

81
code/game/g_spawn.h Normal file
View file

@ -0,0 +1,81 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// g_spawn.h : spawner for scripts.
#ifndef __G_SPAWN_H__
#define __G_SPAWN_H__
#include "glb_local.h"
// spawnflags
// these are set with checkboxes on each entity in the map editor
#define SPAWNFLAG_NOT_EASY 0x00000100
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
#define SPAWNFLAG_NOT_HARD 0x00000400
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
#define SPAWNFLAG_DEVELOPMENT 0x00002000
#define SPAWNFLAG_DETAIL 0x00004000
#define SPAWNFLAG_NOCONSOLE 0x00008000
#define SPAWNFLAG_NOPC 0x00010000
class Listener;
class SpawnArgs : public Class
{
private:
Container<str> keyList;
Container<str> valueList;
public:
CLASS_PROTOTYPE( SpawnArgs );
SpawnArgs();
SpawnArgs( SpawnArgs &arglist );
void Clear( void );
char *Parse( char *data, bool bAllowUtils = false );
const char *getArg( const char *key, const char *defaultValue = NULL );
void setArg( const char *key, const char *value );
int NumArgs( void );
const char *getKey( int index );
const char *getValue( int index );
void operator=( SpawnArgs &a );
ClassDef *getClassDef( qboolean *tikiWasStatic = NULL );
Listener *Spawn( void );
Listener *SpawnInternal( void );
virtual void Archive( Archiver &arc );
};
extern Container< SafePtr< Listener > > g_spawnlist;
ClassDef *FindClass( const char *name, qboolean *isModel );
#ifdef GAME_DLL
void G_InitClientPersistant( gclient_t *client );
#endif
#endif

View file

@ -26,12 +26,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "scriptmaster.h"
#include "world.h"
#ifdef GAME_DLL
#include "../game/camera.h"
#include "../game/entity.h"
#include "../game/player.h"
#include "../game/dm_manager.h"
#endif
#include "camera.h"
#include "entity.h"
#include "player.h"
#include "dm_manager.h"
Game game;

View file

@ -22,12 +22,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// game.h: General Game Info
#ifndef __GAME_H__
#define __GAME_H__
#pragma once
#include "glb_local.h"
#include "listener.h"
#include "level.h"
#include "listener.h"
#include "g_public.h"
class Game : public Listener
{
@ -46,6 +45,8 @@ public:
~Game();
};
class SimpleArchivedEntity;
/*
* Functions prototypes
*/
@ -238,5 +239,3 @@ void G_TouchTriggers(
);
extern Game game;
#endif /* __GAME_H__ */

View file

@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "player.h"
#include <compiler.h>
#include "playerbot.h"
#include "consoleevent.h"
typedef struct
{

1195
code/game/gamescript.cpp Normal file

File diff suppressed because it is too large Load diff

197
code/game/gamescript.h Normal file
View file

@ -0,0 +1,197 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// gamescript.h: Subclass of script that preprocesses labels
#ifndef __GAMESCRIPT_H__
#define __GAMESCRIPT_H__
#include "class.h"
#include "script.h"
#include "archive.h"
class Listener;
class ScriptThread;
class GameScript;
typedef struct {
byte *codepos; // code position pointer
const_str key; // label name
bool isprivate; // new script engine implementation
} script_label_t;
typedef struct {
unsigned int sourcePos;
int column;
int line;
} sourceinfo_t;
class AbstractScript {
public:
// File variables
const_str m_Filename;
char *m_SourceBuffer;
size_t m_SourceLength;
// Developper variable
con_set< uchar *, sourceinfo_t > *m_ProgToSource;
public:
AbstractScript();
str& Filename( void );
const_str ConstFilename( void );
bool GetSourceAt( size_t sourcePos, str &sourceLine, int &column, int &line );
void PrintSourcePos( sourceinfo_t *sourcePos, bool dev );
void PrintSourcePos( size_t sourcePos, bool dev );
void PrintSourcePos( unsigned char *m_pCodePos, bool dev );
void PrintSourcePos( str sourceLine, int column, int line, bool dev );
};
class StateScript : public Class
{
friend class GameScript;
private:
// Label list
con_set< const_str, script_label_t > label_list;
Container< script_label_t * > reverse_label_list;
public:
// Parent gamescript
GameScript *m_Parent;
public:
StateScript();
virtual void Archive( Archiver& arc );
bool AddLabel( str label, unsigned char *pos, bool private_section = false );
bool AddLabel( const_str label, unsigned char *pos, bool private_section = false );
unsigned char *FindLabel( str label );
unsigned char *FindLabel( const_str label );
const_str NearestLabel( unsigned char *pos );
};
class CatchBlock {
public:
// program variable
StateScript m_StateScript;
// code position variables
unsigned char *m_TryStartCodePos;
unsigned char *m_TryEndCodePos;
};
class GameScript : public AbstractScript {
protected:
// try/throw variable
Container<CatchBlock *> m_CatchBlocks;
public:
// program variables
StateScript m_State;
unsigned char *m_ProgBuffer;
size_t m_ProgLength;
// compile variables
bool successCompile;
bool m_bPrecompiled;
// stack variables
unsigned int requiredStackSize;
public:
GameScript();
GameScript( const char *filename );
~GameScript();
virtual void Archive( Archiver& arc );
static void Archive( Archiver& arc, GameScript *&scr );
void ArchiveCodePos( Archiver& arc, unsigned char **codePos );
void Close( void );
void Load( const void *sourceBuffer, size_t sourceLength );
bool GetCodePos( unsigned char *codePos, str& filename, int& pos );
bool SetCodePos( unsigned char *&codePos, str& filename, int pos );
unsigned int GetRequiredStackSize( void );
qboolean labelExists( const char *name );
StateScript *CreateCatchStateScript( unsigned char *try_begin_code_pos, unsigned char *try_end_code_pos );
StateScript *CreateSwitchStateScript( void );
StateScript *GetCatchStateScript( unsigned char *in, unsigned char *&out );
bool ScriptCheck( void );
};
class ScriptThreadLabel {
private:
GameScript *m_Script;
const_str m_Label;
public:
ScriptThreadLabel();
ScriptThread *Create( Listener *listener );
void Execute( Listener *listener = NULL );
void Execute( Listener *listener, Event &ev );
void Execute( Listener *listener, Event *ev );
void Set( const char *label );
void SetScript( const ScriptVariable& label );
void SetScript( const char *label );
void SetThread( const ScriptVariable& label );
bool TrySet( const_str label );
bool TrySet( const char *label );
bool TrySetScript( const_str label );
bool TrySetScript( const char *label );
bool IsSet(void);
bool IsFile(const_str filename);
void GetScriptValue(ScriptVariable *var);
void Archive( Archiver& arc );
friend bool operator==(const ScriptThreadLabel& a, const ScriptThreadLabel& b);
};
inline bool operator==
(
const ScriptThreadLabel& a,
const ScriptThreadLabel& b
)
{
return a.m_Label == b.m_Label && a.m_Script == b.m_Script;
}
#endif

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "gibs.h"
#include "decals.h"
#include "level.h"
Event EV_ThrowGib
(

83
code/game/glb_local.h Normal file
View file

@ -0,0 +1,83 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __GLB_LOCAL_H__
#define __GLB_LOCAL_H__
#if defined( GAME_DLL )
#define glbs gi
#include "g_local.h"
#include "qcommon.h"
#else
#if defined( CGAME_DLL )
#define glbs cgi
#else
#define glbs bi
#endif
#include "../qcommon/q_shared.h"
#include <linklist.h>
#include <mem_blockalloc.h>
#include <vector.h>
#include <str.h>
#include <container.h>
#include <const_str.h>
#include <short3.h>
#include <con_set.h>
#include <con_arrayset.h>
#include <scriptexception.h>
#include <class.h>
#include <containerclass.h>
#include <stack.h>
#include <listener.h>
#include <script.h>
#include "../qcommon/qcommon.h"
#if defined ( CGAME_DLL )
#if defined ( CGAME_HOOK )
#include "../cgame_hook/cgamex86.h"
#endif
#else
#define glbs bi
#include "baseimp.h"
#endif
#endif
#endif /* glb_local.h */

1938
code/game/hud.cpp Normal file

File diff suppressed because it is too large Load diff

212
code/game/hud.h Normal file
View file

@ -0,0 +1,212 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// hud.h: New HUD handler for MoHAA
//
#ifndef __HUD_H__
#define __HUD_H__
#include "listener.h"
#include "container.h"
#define TIMER_ACTIVE (1<<0)
#define TIMER_UP (1<<1)
typedef enum hudAlign_s
{
HUD_LEFT = 0,
HUD_CENTER = 1,
HUD_RIGHT = 2,
HUD_TOP = 0,
HUD_BOTTOM = 2,
HUD_INVALID = 3
} hudAlign_t;
class Hud : public Listener
{
private:
unsigned int number; // auto-assigned number
#ifdef GAME_DLL
char clientnum; // assigned client number
#else
fontHeader_t *font;
qhandle_t shaderHandle;
#endif
hudAlign_t alignX, alignY;
float x, y;
float width, height;
Vector color;
float alpha;
str fontName;
str shader;
str text;
bool virtualSize;
bool isDimensional;
bool fade_alpha;
bool fade_move;
bool fade_scale;
int fade_timer_flags;
bool fade_alpha_first;
int fade_move_x_first;
int fade_move_y_first;
float fade_alpha_current;
float fade_move_current;
float fade_scale_current;
float fade_time_current;
float fade_alpha_time;
float fade_move_time;
float fade_scale_time;
float fade_time;
float fade_out_time;
float fade_alpha_start;
float fade_move_x_start;
float fade_move_y_start;
float fade_scale_w_start;
float fade_scale_h_start;
float fade_time_alpha_start;
float fade_alpha_target;
float fade_move_x_target;
float fade_move_y_target;
float fade_scale_w_target;
float fade_scale_h_target;
float fade_time_target;
Vector org;
Vector lastOrg;
qboolean always_show;
qboolean depth;
int enttarget;
#ifdef GAME_DLL
void SetBroadcast( int clientNumber = -1 ); // Broadcast to someone or everyone
#endif
private:
#ifdef GAME_DLL
void WriteNumber();
#endif
public:
CLASS_PROTOTYPE( Hud );
virtual void Archive( Archiver &arc );
static Hud *Find( int index );
static Hud *FindOrCreate( int index );
static int GetFreeNumber( void );
static void ProcessThink( void );
static int Sort( const void *elem1, const void *elem2 );
#ifdef CGAME_DLL
static void ArchiveFunction( Archiver &arc );
#endif
#ifdef GAME_DLL
Hud( int client = -1 );
#else
Hud( int index = -1 );
#endif
~Hud( void );
#ifdef CGAME_DLL
void Draw3D( void );
#endif
void FadeThink( void );
void MoveThink( void );
void ScaleThink( void );
void TimerThink( void );
void Think( void );
void FadeOverTime( float time );
void MoveOverTime( float time );
void ScaleOverTime( float time, short width, short height );
void Refresh( int clientNumber = -1 );
#ifdef GAME_DLL
int GetClient( void );
#endif
void Set3D( Vector vector_or_offset, qboolean always_show, qboolean depth, int entnum = -1 );
void SetNon3D( void );
void SetAlignX( hudAlign_t align );
void SetAlignY( hudAlign_t align );
void SetAlpha( float alpha );
void SetClient( int clientnum, qboolean clears = false );
void SetColor( Vector color );
void SetFont( const char * font );
void SetRectX( short x );
void SetRectY( short y );
void SetRectHeight( short height );
void SetRectWidth( short height );
void SetShader( const char * shader, float width, float height );
void SetText( const char * text );
void SetTimer( float time, float fade_at_time = -1.0f );
void SetTimerUp( float time, float fade_at_time = -1.0f );
void SetVirtualSize( qboolean virtualSize );
// Events
void EventGetAlignX( Event * ev );
void EventGetAlignY( Event * ev );
void EventGetAlpha( Event * ev );
void EventGetColor( Event * ev );
void EventGetFont( Event * ev );
void EventGetHeight( Event *ev );
void EventGetRectX( Event * ev );
void EventGetRectY( Event * ev );
void EventGetTime( Event *ev );
void EventGetWidth( Event *ev );
void EventFadeDone( Event * ev );
void EventFadeOverTime( Event * ev );
void EventMoveDone( Event * ev );
void EventMoveOverTime( Event * ev );
void EventRefresh( Event * ev );
void EventScaleOverTime( Event * ev );
void EventSet3D( Event *ev );
void EventSetNon3D( Event *ev );
void EventSetAlignX( Event * ev );
void EventSetAlignY( Event * ev );
void EventSetAlpha( Event * ev );
void EventSetColor( Event * ev );
void EventSetFont( Event * ev );
void EventSetPlayer( Event * ev );
void EventSetRectX( Event * ev );
void EventSetRectY( Event * ev );
void EventSetShader( Event * ev );
void EventSetText( Event * ev );
void EventSetTimer( Event *ev );
void EventSetTimerUp( Event *ev );
void EventSetVirtualSize( Event * ev );
};
extern Container< Hud * > hudElements;
#endif /* __HUD_H__ */

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "inventoryitem.h"
#include "weaputils.h"
#include "level.h"
Event EV_InventoryItem_Shoot
(

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "inventoryitem.h"
#include "scriptmaster.h"
#include "health.h"
#include "game.h"
typedef struct {
str name;

View file

@ -22,10 +22,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// level.h: General Level Info
#ifndef __LEVEL_H__
#define __LEVEL_H__
#pragma once
#include "listener.h"
#include "g_public.h"
#define MAX_HEAD_SENTIENTS 2
#define MAX_EARTHQUAKES 10
@ -290,5 +290,3 @@ qboolean Level::Reborn
{
return reborn;
}
#endif

381
code/game/md5.cpp Normal file
View file

@ -0,0 +1,381 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#include "md5.h"
#include <string.h>
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define BYTE_ORDER 0
#endif
#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
const md5_word_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes)
{
const md5_byte_t *p = data;
size_t left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

91
code/game/md5.h Normal file
View file

@ -0,0 +1,91 @@
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef md5_INCLUDED
# define md5_INCLUDED
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef size_t md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialize the algorithm. */
void md5_init(md5_state_t *pms);
/* Append a string to the message. */
void md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes);
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* md5_INCLUDED */

View file

@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entity.h"
#include "trigger.h"
#include "mover.h"
#include "level.h"
#define MOVE_ANGLES 1
#define MOVE_ORIGIN 2

View file

@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "stack.h"
#include "container.h"
#include "doors.h"
#include "sentient.h"
#include "../qcommon/qfiles.h"

34
code/game/object.cpp Normal file
View file

@ -0,0 +1,34 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// object.cpp : Object (used by common TIKIs)
#include "object.h"
#if defined ( GAME_DLL ) || defined ( CGAME_DLL )
CLASS_DECLARATION( Animate, Object, NULL )
#else
CLASS_DECLARATION( SimpleEntity, Object, NULL )
#endif
{
{ NULL, NULL }
};

48
code/game/object.h Normal file
View file

@ -0,0 +1,48 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// object.h: Object (used by common TIKIs)
#ifndef __OBJECT_H__
#define __OBJECT_H__
#if defined ( GAME_DLL ) || defined ( CGAME_DLL )
#include "animate.h"
class Object : public Animate {
public:
CLASS_PROTOTYPE( Object );
};
#else
#include "simpleentity.h"
class Object : public SimpleEntity {
public:
CLASS_PROTOTYPE( Object );
};
#endif
#endif /* __OBJECT_H__ */

91
code/game/parm.cpp Normal file
View file

@ -0,0 +1,91 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// parm.cpp : Event parameters
#include "glb_local.h"
#include "parm.h"
#include "scriptmaster.h"
#include "scriptvm.h"
Parm parm;
Event EV_Parm_GetOther
(
"other",
EV_DEFAULT,
NULL,
NULL,
"other",
EV_GETTER
);
Event EV_Parm_GetOwner
(
"owner",
EV_DEFAULT,
NULL,
NULL,
"owner",
EV_GETTER
);
Event EV_Parm_GetPreviousThread
(
"previousthread",
EV_DEFAULT,
NULL,
NULL,
"previousthread",
EV_GETTER
);
void Parm::Archive( Archiver& arc )
{
Listener::Archive( arc );
arc.ArchiveSafePointer( &other );
arc.ArchiveSafePointer( &owner );
}
void Parm::GetOther( Event *ev )
{
ev->AddListener( other );
}
void Parm::GetOwner( Event *ev )
{
ev->AddListener( owner );
}
void Parm::GetPreviousThread( Event *ev )
{
ev->AddListener( Director.PreviousThread() );
}
CLASS_DECLARATION( Listener, Parm, NULL )
{
{ &EV_Parm_GetOther, &Parm::GetOther },
{ &EV_Parm_GetOwner, &Parm::GetOwner },
{ &EV_Parm_GetPreviousThread, &Parm::GetPreviousThread },
{ NULL, NULL }
};

55
code/game/parm.h Normal file
View file

@ -0,0 +1,55 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// parm.h: Event parameters
#ifndef __PARM_H__
#define __PARM_H__
#include "listener.h"
class Parm : public Listener {
public:
// General trigger variables
SafePtr< Listener > other;
SafePtr< Listener > owner;
// Failure variables
qboolean movedone;
qboolean movefail;
qboolean motionfail;
qboolean upperfail;
qboolean sayfail;
public:
CLASS_PROTOTYPE( Parm );
virtual void Archive( Archiver& arc );
void GetOther( Event *ev );
void GetOwner( Event *ev );
void GetPreviousThread( Event *ev );
};
extern Parm parm;
#endif /* __PARM_H__ */

View file

@ -0,0 +1,334 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// parsetree.cpp: Abstract Syntax Layer for Lexer/Parser
#include "glb_local.h"
#include "parsetree.h"
#include <mem_tempalloc.h>
MEM_TempAlloc parsetree_allocator;
yyparsedata parsedata;
sval_u node_none = { 0 };
char *str_replace( char *orig, char *rep, char *with ) {
char *result; // the return string
char *ins; // the next insert point
char *tmp; // varies
size_t len_rep; // length of rep
size_t len_with; // length of with
size_t len_front; // distance between rep and end of last rep
int count; // number of replacements
if( !orig )
return NULL;
if( !rep )
rep = "";
len_rep = strlen( rep );
if( !with )
with = "";
len_with = strlen( with );
ins = orig;
for( count = 0; tmp = strstr( ins, rep ); ++count ) {
ins = tmp + len_rep;
}
// first time through the loop, all the variable are set correctly
// from here on,
// tmp points to the end of the result string
// ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep"
tmp = result = ( char * )parsetree_allocator.Alloc( strlen( orig ) + ( len_with - len_rep ) * count + 1 );
if( !result )
return NULL;
while( count-- ) {
ins = strstr( orig, rep );
len_front = ins - orig;
tmp = strncpy( tmp, orig, len_front ) + len_front;
tmp = strcpy( tmp, with ) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy( tmp, orig );
return result;
}
void parsetree_freeall()
{
parsetree_allocator.FreeAll();
if( showopcodes->integer )
{
glbs.DPrintf( "%d bytes freed\n", parsedata.total_length );
}
}
void parsetree_init()
{
parsedata.total_length = 0;
}
size_t parsetree_length()
{
return parsedata.total_length;
}
#if 0
char *parsetree_string( const char *string )
{
//char *pszString = ( char * )parsetree_allocator.Alloc( strlen( string ) + 1 );
//strcpy( pszString, string );
char *buffer = str_replace( ( char * )string, "\\\"", "\"" );
if( buffer )
{
char *ptr = buffer;
if( ptr[ 0 ] == '"' )
{
ptr++;
}
int len = strlen( buffer );
if( buffer[ len - 1 ] == '"' )
{
buffer[ len - 1 ] = 0;
}
buffer = ptr;
}
return buffer;
}
#endif
extern size_t yyleng;
extern size_t prev_yyleng;
char *parsetree_malloc( size_t s )
{
parsedata.total_length += s;
return ( char * )parsetree_allocator.Alloc( s );
}
sval_u append_lists( sval_u val1, sval_u val2 )
{
val1.node[ 1 ].node[ 1 ] = val2.node[ 0 ];
val1.node[ 1 ] = val2.node[ 1 ];
return val1;
}
sval_u append_node( sval_u val1, sval_u val2 )
{
sval_u *node;
node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 2 );
node[ 1 ].node = NULL;
node[ 0 ] = val2;
val1.node[ 1 ].node[ 1 ].node = node;
val1.node[ 1 ].node = node;
return val1;
}
sval_u prepend_node( sval_u val1, sval_u val2 )
{
sval_u *node;
node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 2 );
node[ 0 ] = val1;
node[ 1 ] = val2;
val2.node = node;
return val2;
}
sval_u linked_list_end( sval_u val )
{
sval_u *node;
sval_u end;
node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 2 );
node[ 0 ] = val;
node[ 1 ].node = NULL;
end.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 2 );
end.node[ 0 ].node = node;
end.node[ 1 ].node = node;
return end;
}
sval_u node1_( int val1 )
{
sval_u val;
val.intValue = val1;
return val;
}
sval_u node1b( int val1 )
{
sval_u val;
val.byteValue = val1;
return val;
}
sval_u node_pos( unsigned int pos )
{
sval_u val;
val.sourcePosValue = pos;
return val;
}
sval_u node_string( char *text )
{
sval_u val;
val.stringValue = text;
return val;
}
sval_u node0( int type )
{
sval_u val;
if( type == sval_none )
{
// memory optimization
val.node = &node_none;
}
else
{
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 1 );
val.node[ 0 ].node = NULL;
val.node[ 0 ].type = type;
}
return val;
}
sval_u node1( int type, sval_u val1 )
{
sval_u val;
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 2 );
val.node[ 0 ].type = type;
val.node[ 1 ] = val1;
return val;
}
sval_u node2( int type, sval_u val1, sval_u val2 )
{
sval_u val;
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 3 );
val.node[ 0 ].type = type;
val.node[ 1 ] = val1;
val.node[ 2 ] = val2;
return val;
}
sval_u node3( int type, sval_u val1, sval_u val2, sval_u val3 )
{
sval_u val;
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 4 );
val.node[ 0 ].type = type;
val.node[ 1 ] = val1;
val.node[ 2 ] = val2;
val.node[ 3 ] = val3;
return val;
}
sval_u node4( int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4 )
{
sval_u val;
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 5 );
val.node[ 0 ].type = type;
val.node[ 1 ] = val1;
val.node[ 2 ] = val2;
val.node[ 3 ] = val3;
val.node[ 4 ] = val4;
return val;
}
sval_u node5( int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5 )
{
sval_u val;
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 6 );
val.node[ 0 ].type = type;
val.node[ 1 ] = val1;
val.node[ 2 ] = val2;
val.node[ 3 ] = val3;
val.node[ 4 ] = val4;
val.node[ 5 ] = val5;
return val;
}
sval_u node6( int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5, sval_u val6 )
{
sval_u val;
val.node = ( sval_u * )parsetree_malloc( sizeof( sval_u ) * 7 );
val.node[ 0 ].type = type;
val.node[ 1 ] = val1;
val.node[ 2 ] = val2;
val.node[ 3 ] = val3;
val.node[ 4 ] = val4;
val.node[ 5 ] = val5;
val.node[ 6 ] = val6;
return val;
}

View file

@ -0,0 +1,147 @@
/*
===========================================================================
Copyright (C) 2008 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// parsetree.h: Abstract Syntax Layer for Lexer/Parser
#ifndef __PARSETREE_H__
#define __PARSETREE_H__
#if defined ( GAME_DLL )
#define showopcodes g_showopcodes
#elif defined( CGAME_DLL )
#define showopcodes cg_showopcodes
#else
#define showopcodes g_showopcodes
#endif
typedef enum
{
sval_none,
sval_next,
sval_statement_list,
sval_label,
sval_case,
sval_negative,
sval_assignment,
sval_if,
sval_ifelse,
sval_while,
sval_and,
sval_or,
sval_cmd_method,
sval_cmd_method_ret,
sval_cmd,
sval_cmd_default_ret,
sval_field,
sval_store_method,
sval_store_string,
sval_store_integer,
sval_store_float,
sval_calc_vector,
sval_store_null,
sval_store_nil,
sval_func1,
sval_operation,
sval_not,
sval_array,
sval_constarray,
sval_makearray,
sval_catch,
sval_switch,
sval_break,
sval_continue,
sval_do,
sval_privatelabel,
sval_define
} sval_type_e;
typedef union sval_u {
int type;
char *stringValue;
float floatValue;
int intValue;
char charValue;
unsigned char byteValue;
unsigned char *posValue;
int MaxVarStackOffset;
int HasExternal;
union sval_u *node;
unsigned int sourcePosValue;
} sval_t;
typedef struct {
sval_t val;
unsigned int sourcePos;
} stype_t;
void parsetree_freeall();
void parsetree_init();
size_t parsetree_length();
char *parsetree_malloc( size_t s );
sval_u append_lists( sval_u val1, sval_u val2 );
sval_u append_node( sval_u val1, sval_u val2 );
sval_u prepend_node( sval_u val1, sval_u val2 );
sval_u linked_list_end( sval_u val );
sval_u node1_( int val1 );
sval_u node1b( int val1 );
sval_u node_pos( unsigned int pos );
sval_u node_string( char *text );
sval_u node0( int type );
sval_u node1( int type, sval_u val1 );
sval_u node2( int type, sval_u val1, sval_u val2 );
sval_u node3( int type, sval_u val1, sval_u val2, sval_u val3 );
sval_u node4( int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4 );
sval_u node5( int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5 );
sval_u node6( int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5, sval_u val6 );
struct yyexception {
int yylineno;
str yytext;
str yytoken;
yyexception() { yylineno = 0; }
};
struct yyparsedata {
size_t total_length;
int braces_count;
int line_count;
unsigned int pos;
sval_t val;
char *sourceBuffer;
class GameScript *gameScript;
yyexception exc;
yyparsedata() { total_length = 0, braces_count = 0, line_count = 0, pos = 0; val = sval_t(); sourceBuffer = NULL; gameScript = NULL; }
};
extern yyparsedata parsedata;
#endif

2766
code/game/parser/yyLexer.cpp Normal file

File diff suppressed because it is too large Load diff

408
code/game/parser/yyLexer.h Normal file
View file

@ -0,0 +1,408 @@
#ifndef yyHEADER_H
#define yyHEADER_H 1
#define yyIN_HEADER 1
#line 5 "../../../code/globalcpp/parser/yyLexer.h"
#line 7 "../../../code/globalcpp/parser/yyLexer.h"
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
#define YY_FLEX_SUBMINOR_VERSION 3
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
#define yy_create_buffer yy_create_buffer
#define yy_delete_buffer yy_delete_buffer
#define yy_scan_buffer yy_scan_buffer
#define yy_scan_string yy_scan_string
#define yy_scan_bytes yy_scan_bytes
#define yy_init_buffer yy_init_buffer
#define yy_flush_buffer yy_flush_buffer
#define yy_load_buffer_state yy_load_buffer_state
#define yy_switch_to_buffer yy_switch_to_buffer
#define yypush_buffer_state yypush_buffer_state
#define yypop_buffer_state yypop_buffer_state
#define yyensure_buffer_stack yyensure_buffer_stack
#define yylex yylex
#define yyrestart yyrestart
#define yylex_init yylex_init
#define yylex_init_extra yylex_init_extra
#define yylex_destroy yylex_destroy
#define yyget_debug yyget_debug
#define yyset_debug yyset_debug
#define yyget_extra yyget_extra
#define yyset_extra yyset_extra
#define yyget_in yyget_in
#define yyset_in yyset_in
#define yyget_out yyget_out
#define yyset_out yyset_out
#define yyget_leng yyget_leng
#define yyget_text yyget_text
#define yyget_lineno yyget_lineno
#define yyset_lineno yyset_lineno
#define yywrap yywrap
#define yyalloc yyalloc
#define yyrealloc yyrealloc
#define yyfree yyfree
#define yytext yytext
#define yyleng yyleng
#define yyin yyin
#define yyout yyout
#define yy_flex_debug yy_flex_debug
#define yylineno yylineno
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* end standard C headers. */
/* flex integer type definitions */
#ifndef FLEXINT_H
#define FLEXINT_H
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN (-128)
#endif
#ifndef INT16_MIN
#define INT16_MIN (-32767-1)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT8_MAX
#define INT8_MAX (127)
#endif
#ifndef INT16_MAX
#define INT16_MAX (32767)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (255U)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (65535U)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
/* TODO: this is always defined, so inline it */
#define yyconst const
#if defined(__GNUC__) && __GNUC__ >= 3
#define yynoreturn __attribute__((__noreturn__))
#else
#define yynoreturn
#endif
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k.
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
* Ditto for the __ia64__ case accordingly.
*/
#define YY_BUF_SIZE 32768
#else
#define YY_BUF_SIZE 16384
#endif /* __ia64__ */
#endif
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
extern int yyleng;
extern FILE *yyin, *yyout;
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
void yyrestart ( FILE *input_file );
void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
void yy_delete_buffer ( YY_BUFFER_STATE b );
void yy_flush_buffer ( YY_BUFFER_STATE b );
void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
void yypop_buffer_state ( void );
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
void *yyalloc ( yy_size_t );
void *yyrealloc ( void *, yy_size_t );
void yyfree ( void * );
/* Begin user sect3 */
#define yywrap() (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
extern int yylineno;
extern char *yytext;
#ifdef yytext_ptr
#undef yytext_ptr
#endif
#define yytext_ptr yytext
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
#define INITIAL 0
#define C_COMMENT 1
#define C_LINE_COMMENT 2
#define VARIABLES 3
#define IDENTIFIER 4
#endif
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
* down here because we want the user's section 1 to have been scanned first.
* The user has a chance to override it with an option.
*/
#include <unistd.h>
#endif
#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
#endif
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
int yylex_destroy ( void );
int yyget_debug ( void );
void yyset_debug ( int debug_flag );
YY_EXTRA_TYPE yyget_extra ( void );
void yyset_extra ( YY_EXTRA_TYPE user_defined );
FILE *yyget_in ( void );
void yyset_in ( FILE * _in_str );
FILE *yyget_out ( void );
void yyset_out ( FILE * _out_str );
int yyget_leng ( void );
char *yyget_text ( void );
int yyget_lineno ( void );
void yyset_lineno ( int _line_number );
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int yywrap ( void );
#else
extern int yywrap ( void );
#endif
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy ( char *, const char *, int );
#endif
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen ( const char * );
#endif
#ifndef YY_NO_INPUT
#endif
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k */
#define YY_READ_BUF_SIZE 16384
#else
#define YY_READ_BUF_SIZE 8192
#endif /* __ia64__ */
#endif
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
extern int yylex (void);
#define YY_DECL int yylex (void)
#endif /* !YY_DECL */
/* yy_get_previous_state - get the state just before the EOB char was reached */
#undef YY_NEW_FILE
#undef YY_FLUSH_BUFFER
#undef yy_set_bol
#undef yy_new_buffer
#undef yy_set_interactive
#undef YY_DO_BEFORE_ACTION
#ifdef YY_DECL_IS_OURS
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
#line 285 "..\\..\\..\\code\\globalcpp\\parser\\yyLexer.l"
#line 406 "../../../code/globalcpp/parser/yyLexer.h"
#undef yyIN_HEADER
#endif /* yyHEADER_H */

285
code/game/parser/yyLexer.l Normal file
View file

@ -0,0 +1,285 @@
%{
/*
* ===========================================================================
* Copyright (C) 2015 the OpenMoHAA team
*
* This file is part of OpenMoHAA source code.
*
* OpenMoHAA source code is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* OpenMoHAA source code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenMoHAA source code; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ===========================================================================
*
*
* yyLexer.*: FLEX Lexical grammar for MoHScript.
*/
#include "compiler.h"
#include "yyParser.h"
#include <stdio.h>
void fprintf2( FILE *f, const char *format, ... )
{
va_list va;
static char buffer[ 4200 ];
va_start( va, format );
vsprintf( buffer, format, va );
va_end( va );
glbs.Printf( buffer );
}
#define fprintf fprintf2
int prev_yylex = 0;
extern yyparsedata parsedata;
#define YYLLOCSET { yylval.s.sourcePos = parsedata.pos - yyleng; }
#define YYLEX(n) { prev_yylex = n; return n; }
#define YY_USER_ACTION parsedata.pos; parsedata.pos += yyleng;
#define YY_FATAL_ERROR( n ) yylexerror( n )
void yylexerror( const char *msg )
{
glbs.Printf( "%s\n%s", msg, yytext );
assert( 0 );
}
static void TextEscapeValue( char *str, size_t len )
{
char *to = parsetree_malloc( len + 1 );
yylval.s.val.stringValue = to;
while( len )
{
if( *str == '\\' )
{
len--;
if( !len )
break;
str++;
if( *str == 'n' )
{
*to = '\n';
}
else if( *str == 't' )
{
*to = '\t';
}
else if( *str == '"' )
{
*to = '\"';
}
else
{
*to = *str;
}
}
else
{
*to = *str;
}
len--;
str++;
to++;
}
*to = 0;
}
static void TextValue( char *str, size_t len )
{
yylval.s.val.stringValue = parsetree_malloc( len + 1 );
strncpy( yylval.s.val.stringValue, str, len );
yylval.s.val.stringValue[ len ] = 0;
}
static bool UseField( void )
{
//return prev_yylex == TOKEN_PERIOD || prev_yylex == TOKEN_DOLLAR;
return ( !strncmp( yytext, "game.", 5 ) ||
!strncmp( yytext, "group.", 6 ) ||
!strncmp( yytext, "level.", 6 ) ||
!strncmp( yytext, "local.", 6 ) ||
!strncmp( yytext, "parm.", 5 ) ||
!strncmp( yytext, "owner.", 6 ) ||
!strncmp( yytext, "self.", 5 ) ||
*yytext == '$' || *yytext == '-' || *yytext == '/' );
}
%}
/*%option debug*/
%option outfile="../../../code/globalcpp/parser/yyLexer.cpp" header-file="../../../code/globalcpp/parser/yyLexer.h"
%option warn nodefault
%option noyywrap never-interactive
%option yylineno
%x C_COMMENT
%x C_LINE_COMMENT
%x VARIABLES
%x IDENTIFIER
%%
"/*" { BEGIN( C_COMMENT ); }
<C_COMMENT>"*/" { BEGIN( INITIAL ); }
<C_COMMENT>\n { ; }
<C_COMMENT>. { ; }
"*/" { Compiler.CompileError( parsedata.pos - yyleng, "'*/' found outside of comment" ); }
\\[\r\n]+ { ; }
"//"[^\r\n]* { if( prev_yylex != TOKEN_EOL ) YYLEX( TOKEN_EOL ); }
<VARIABLES>[\r\n]* { BEGIN( INITIAL ); YYLEX( TOKEN_EOL ); }
<VARIABLES>"size" { YYLEX( TOKEN_SIZE ); }
<VARIABLES>"." { YYLEX( TOKEN_PERIOD ); }
<VARIABLES>\"([^\\\"]|\\.)*\" { YYLLOCSET; TextEscapeValue( yytext + 1, strlen( yytext ) - 2 ); YYLEX( TOKEN_STRING ); }
<VARIABLES>[a-zA-Z0-9_\"]+ { YYLLOCSET; TextValue( yytext, strlen( yytext ) ); YYLEX( TOKEN_IDENTIFIER ); }
<VARIABLES>. {
for ( int i = yyleng - 1; i >= 0; --i )
unput( yytext[ i ] );
parsedata.pos -= yyleng;
BEGIN( INITIAL );
}
[\r\n]* { if( prev_yylex != TOKEN_EOL ) YYLEX( TOKEN_EOL ); }
[ \t]* { ; }
\"([^\\\"]|\\.)*\" { YYLLOCSET; TextEscapeValue( yytext + 1, strlen( yytext ) - 2 ); YYLEX( TOKEN_STRING ); }
"?" { YYLEX( TOKEN_TERNARY ); }
"if" { YYLEX( TOKEN_IF ); }
"else" { YYLEX( TOKEN_ELSE ); }
"while" { YYLEX( TOKEN_WHILE ); }
"for" { YYLEX( TOKEN_FOR ); }
"do" { YYLEX( TOKEN_DO ); }
"game"? { BEGIN( VARIABLES ); yylval.s.val = node1_( method_game ); YYLEX( TOKEN_LISTENER ); }
"group" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_group ); YYLEX( TOKEN_LISTENER ); }
"level" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_level ); YYLEX( TOKEN_LISTENER ); }
"local" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_local ); YYLEX( TOKEN_LISTENER ); }
"parm" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_parm ); YYLEX( TOKEN_LISTENER ); }
"owner" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_owner ); YYLEX( TOKEN_LISTENER ); }
"self" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_self ); YYLEX( TOKEN_LISTENER ); }
"{" { parsedata.braces_count++; YYLEX( TOKEN_LBRACKET ); }
"}" { parsedata.braces_count--; YYLEX( TOKEN_RBRACKET ); }
"(" { YYLLOCSET; YYLEX( TOKEN_LPAREN ); }
")" { BEGIN( VARIABLES ); YYLLOCSET; YYLEX( TOKEN_RPAREN ); }
"[" { YYLEX( TOKEN_LSQUARE ); }
"]" { BEGIN( VARIABLES ); YYLEX( TOKEN_RSQUARE ); }
"=" { YYLEX( TOKEN_ASSIGNMENT ); }
":" { YYLEX( TOKEN_COLON ); }
"::" { YYLEX( TOKEN_DOUBLE_COLON ); }
";" { YYLEX( TOKEN_SEMICOLON ); }
"==" { YYLEX( TOKEN_EQUALITY ); }
"||" { YYLEX( TOKEN_LOGICAL_OR ); }
"&&" { YYLEX( TOKEN_LOGICAL_AND ); }
"|" { YYLEX( TOKEN_BITWISE_OR ); }
"^" { YYLEX( TOKEN_BITWISE_EXCL_OR ); }
"&" { YYLEX( TOKEN_BITWISE_AND ); }
"!=" { YYLEX( TOKEN_INEQUALITY ); }
"<" { YYLEX( TOKEN_LESS_THAN ); }
">" { YYLEX( TOKEN_GREATER_THAN ); }
"<=" { YYLEX( TOKEN_LESS_THAN_OR_EQUAL ); }
">=" { YYLEX( TOKEN_GREATER_THAN_OR_EQUAL ); }
[ ]"-" { YYLEX( TOKEN_NEG ); }
"+" { YYLEX( TOKEN_PLUS ); }
"+=" { YYLEX( TOKEN_PLUS_EQUALS ); }
"++"|[ ]"++" { YYLEX( TOKEN_INCREMENT ); }
"-"|"-"[ ]|[ ]"-"[ ] { YYLEX( TOKEN_MINUS ); }
"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
[ ]"-=" { YYLEX( TOKEN_MINUS_EQUALS ); }
"--"|[ ]"--" { YYLEX( TOKEN_DECREMENT ); }
"*" { YYLEX( TOKEN_MULTIPLY ); }
"*=" { YYLEX( TOKEN_MULTIPLY_EQUALS ); }
"/" { YYLEX( TOKEN_DIVIDE ); }
"/=" { YYLEX( TOKEN_DIVIDE_EQUALS ); }
"%" { YYLEX( TOKEN_MODULUS ); }
"%=" { YYLEX( TOKEN_MODULUS_EQUALS ); }
"<<" { YYLEX( TOKEN_SHIFT_LEFT ); }
"<<=" { YYLEX( TOKEN_SHIFT_LEFT_EQUALS ); }
">>" { YYLEX( TOKEN_SHIFT_RIGHT ); }
">>=" { YYLEX( TOKEN_SHIFT_RIGHT_EQUALS ); }
"&=" { YYLEX( TOKEN_AND_EQUALS ); }
"^=" { YYLEX( TOKEN_EXCL_OR_EQUALS ); }
"|=" { YYLEX( TOKEN_OR_EQUALS ); }
"$" { BEGIN( VARIABLES ); YYLEX( TOKEN_DOLLAR ); }
"!" { YYLEX( TOKEN_NOT ); }
"~" { YYLEX( TOKEN_COMPLEMENT ); }
"." { YYLEX( TOKEN_PERIOD ); }
"," { YYLEX( TOKEN_COMMA ); }
"#" { YYLEX( TOKEN_NUMBER ); }
"NULL" { YYLEX( TOKEN_NULL ); }
"NIL" { YYLEX( TOKEN_NIL ); }
[0-9]+ { YYLLOCSET; sscanf( yytext, "%d", &yylval.s.val.intValue ); YYLEX( TOKEN_INTEGER ); }
[0-9\.]+|[0-9\.]+("e+"|"e-")+[0-9\.] { YYLLOCSET; sscanf( yytext, "%f", &yylval.s.val.floatValue ); YYLEX( TOKEN_FLOAT ); }
"try" { YYLEX( TOKEN_TRY ); }
"catch" { YYLEX( TOKEN_CATCH ); }
"switch" { YYLEX( TOKEN_SWITCH ); }
"case" { YYLEX( TOKEN_CASE ); }
"break" { YYLEX( TOKEN_BREAK ); }
"continue" { YYLEX( TOKEN_CONTINUE ); }
"makearray"|"makeArray" { YYLEX( TOKEN_MAKEARRAY ); }
"endarray"|"endArray" { YYLEX( TOKEN_ENDARRAY ); }
[a-zA-Z0-9_\./\\-]+ {
if( UseField() )
{
parsedata.pos -= yyleng;
REJECT;
}
else
{
YYLLOCSET;
TextEscapeValue( yytext, yyleng );
YYLEX( TOKEN_IDENTIFIER );
}
}
. { yylexerror( "bad token:\n" ); }
%{
#undef fprintf
%}
%%

File diff suppressed because it is too large Load diff

159
code/game/parser/yyParser.h Normal file
View file

@ -0,0 +1,159 @@
/* A Bison parser, made by GNU Bison 2.7. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_CODE_GLOBALCPP_PARSER_YYPARSER_H_INCLUDED
# define YY_YY_CODE_GLOBALCPP_PARSER_YYPARSER_H_INCLUDED
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
END = 0,
TOKEN_EOL = 258,
TOKEN_COMMA = 259,
TOKEN_TERNARY = 260,
TOKEN_SHIFT_RIGHT_EQUALS = 261,
TOKEN_SHIFT_LEFT_EQUALS = 262,
TOKEN_OR_EQUALS = 263,
TOKEN_EXCL_OR_EQUALS = 264,
TOKEN_AND_EQUALS = 265,
TOKEN_MODULUS_EQUALS = 266,
TOKEN_DIVIDE_EQUALS = 267,
TOKEN_MULTIPLY_EQUALS = 268,
TOKEN_MINUS_EQUALS = 269,
TOKEN_PLUS_EQUALS = 270,
TOKEN_ASSIGNMENT = 271,
TOKEN_LOGICAL_OR = 272,
TOKEN_LOGICAL_AND = 273,
TOKEN_BITWISE_OR = 274,
TOKEN_BITWISE_EXCL_OR = 275,
TOKEN_BITWISE_AND = 276,
TOKEN_INEQUALITY = 277,
TOKEN_EQUALITY = 278,
TOKEN_GREATER_THAN_OR_EQUAL = 279,
TOKEN_GREATER_THAN = 280,
TOKEN_LESS_THAN_OR_EQUAL = 281,
TOKEN_LESS_THAN = 282,
TOKEN_SHIFT_RIGHT = 283,
TOKEN_SHIFT_LEFT = 284,
TOKEN_MINUS = 285,
TOKEN_PLUS = 286,
TOKEN_MODULUS = 287,
TOKEN_DIVIDE = 288,
TOKEN_MULTIPLY = 289,
TOKEN_LISTENER = 290,
TOKEN_COMPLEMENT = 291,
TOKEN_NOT = 292,
TOKEN_NEG = 293,
TOKEN_FLOAT = 294,
TOKEN_INTEGER = 295,
TOKEN_IDENTIFIER = 296,
TOKEN_STRING = 297,
TOKEN_NIL = 298,
TOKEN_NULL = 299,
TOKEN_LBRACKET = 300,
TOKEN_RBRACKET = 301,
TOKEN_COLON = 302,
TOKEN_SEMICOLON = 303,
TOKEN_DOLLAR = 304,
TOKEN_DOUBLE_COLON = 305,
TOKEN_NUMBER = 306,
TOKEN_PERIOD = 307,
TOKEN_DECREMENT = 308,
TOKEN_INCREMENT = 309,
TOKEN_RPAREN = 310,
TOKEN_LPAREN = 311,
TOKEN_RSQUARE = 312,
TOKEN_LSQUARE = 313,
TOKEN_MAKEARRAY = 314,
TOKEN_ENDARRAY = 315,
TOKEN_CATCH = 316,
TOKEN_TRY = 317,
TOKEN_DO = 318,
TOKEN_FOR = 319,
TOKEN_IF = 320,
TOKEN_ELSE = 321,
TOKEN_SWITCH = 322,
TOKEN_WHILE = 323,
TOKEN_BREAK = 324,
TOKEN_CASE = 325,
TOKEN_CONTINUE = 326,
TOKEN_SIZE = 327,
TOKEN_END = 328,
TOKEN_RETURN = 329
};
#endif
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2058 of yacc.c */
#line 53 "..\\..\\..\\code\\globalcpp\\parser\\yyParser.yy"
stype_t s;
/* Line 2058 of yacc.c */
#line 137 "../../../code/globalcpp/parser/yyParser.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_YY_CODE_GLOBALCPP_PARSER_YYPARSER_H_INCLUDED */

View file

@ -0,0 +1,269 @@
%{
/*
* ===========================================================================
* Copyright (C) 2015 the OpenMoHAA team
*
* This file is part of OpenMoHAA source code.
*
* OpenMoHAA source code is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* OpenMoHAA source code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenMoHAA source code; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ===========================================================================
*
*
* yyParser.*: BISON Parser for MoHScript.
*/
#include "compiler.h"
#include "yyParser.h"
#include "yyLexer.h"
int yyerror( const char *msg );
extern int prev_yylex;
extern yyparsedata parsedata;
#define YYLLOC node_pos( parsedata.pos - yyleng )
%}
%output "../../../code/globalcpp/parser/yyParser.cpp"
%defines "../../../code/globalcpp/parser/yyParser.h"
%error-verbose
%expect 306
%token END 0
%token TOKEN_EOL
%left TOKEN_COMMA
%union {
stype_t s;
}
%right TOKEN_ASSIGNMENT
TOKEN_PLUS_EQUALS TOKEN_MINUS_EQUALS TOKEN_MULTIPLY_EQUALS TOKEN_DIVIDE_EQUALS TOKEN_MODULUS_EQUALS
TOKEN_AND_EQUALS TOKEN_EXCL_OR_EQUALS TOKEN_OR_EQUALS
TOKEN_SHIFT_LEFT_EQUALS TOKEN_SHIFT_RIGHT_EQUALS
TOKEN_TERNARY
%left TOKEN_LOGICAL_OR
%left TOKEN_LOGICAL_AND
%left TOKEN_BITWISE_OR
%left TOKEN_BITWISE_EXCL_OR
%left TOKEN_BITWISE_AND
%left TOKEN_EQUALITY TOKEN_INEQUALITY
%left TOKEN_LESS_THAN TOKEN_LESS_THAN_OR_EQUAL TOKEN_GREATER_THAN TOKEN_GREATER_THAN_OR_EQUAL
%left TOKEN_SHIFT_LEFT TOKEN_SHIFT_RIGHT
%left TOKEN_PLUS TOKEN_MINUS
%left TOKEN_MULTIPLY TOKEN_DIVIDE TOKEN_MODULUS
%token <s> TOKEN_LISTENER
%right TOKEN_NEG TOKEN_NOT TOKEN_COMPLEMENT
%token <s> TOKEN_FLOAT TOKEN_INTEGER TOKEN_IDENTIFIER TOKEN_STRING TOKEN_NIL TOKEN_NULL
%token TOKEN_LBRACKET TOKEN_RBRACKET
%token TOKEN_COLON TOKEN_SEMICOLON TOKEN_DOLLAR TOKEN_DOUBLE_COLON TOKEN_NUMBER
%left <s> TOKEN_LSQUARE TOKEN_RSQUARE TOKEN_LPAREN TOKEN_RPAREN TOKEN_INCREMENT TOKEN_DECREMENT TOKEN_PERIOD
%token TOKEN_MAKEARRAY TOKEN_ENDARRAY
TOKEN_CATCH TOKEN_TRY
TOKEN_DO TOKEN_FOR TOKEN_IF TOKEN_ELSE TOKEN_SWITCH TOKEN_WHILE
TOKEN_BREAK TOKEN_CASE TOKEN_CONTINUE
TOKEN_SIZE
TOKEN_END TOKEN_RETURN
%type <s.val> event_parameter_list event_parameter_list_need
%type <s.val> statement_list statement makearray_statement_list makearray_statement
%type <s.val> compound_statement
%type <s.val> expr
%type <s.val> func_prim_expr
%type <s.val> prim_expr
%type <s.val> nonident_prim_expr
%type <s.val> number
%type <s> identifier_prim
%start program
%%
program:
newline statement_list { parsedata.val = node1( sval_statement_list, $2 ); }
;
statement_list:
statement_list statement newline { $$ = append_node( $1, $2 ); }
//| statement_list error TOKEN_EOL { yyerrok; }
| statement newline { $$ = linked_list_end( $1 ); }
| newline { $$ = node0( sval_none ); }
;
statement:
TOKEN_IDENTIFIER event_parameter_list TOKEN_COLON { $$ = node3( sval_label, $1.val, $2, YYLLOC ); }
| TOKEN_PLUS TOKEN_IDENTIFIER event_parameter_list TOKEN_COLON { $$ = node3( sval_label, $2.val, $3, YYLLOC ); }
| TOKEN_MINUS TOKEN_IDENTIFIER event_parameter_list TOKEN_COLON { $$ = node3( sval_privatelabel, $2.val, $3, YYLLOC ); }
| TOKEN_CASE prim_expr event_parameter_list TOKEN_COLON { $$ = node3( sval_case, $2, $3, YYLLOC ); }
| compound_statement
| TOKEN_IF prim_expr newline statement[S] newline { $$ = node3( sval_if, $2, $S, YYLLOC ); }
| TOKEN_IF prim_expr newline statement[S1] newline TOKEN_ELSE newline statement[S2] { $$ = node4( sval_ifelse, $2, $S1, $S2, YYLLOC ); }
| TOKEN_WHILE prim_expr newline statement { $$ = node4( sval_while, $2, $4, node0( sval_none ), YYLLOC ); }
| TOKEN_FOR TOKEN_LPAREN statement[SINIT] TOKEN_SEMICOLON expr[E] TOKEN_SEMICOLON statement_list[INC] TOKEN_RPAREN newline statement[S]
{
sval_u while_stmt = node4( sval_while, $E, $S, node1( sval_statement_list, $INC ), YYLLOC );
$$ = node1( sval_statement_list, append_node( linked_list_end( $SINIT ), while_stmt ) );
}
| TOKEN_FOR TOKEN_LPAREN TOKEN_SEMICOLON expr[E] TOKEN_SEMICOLON statement_list[INC] TOKEN_RPAREN newline statement[S]
{
$$ = node4( sval_while, $E, $S, node1( sval_statement_list, $INC ), YYLLOC );
}
| TOKEN_DO newline statement[S] newline TOKEN_WHILE prim_expr[E] { $$ = node3( sval_do, $S, $E, YYLLOC ); }
| TOKEN_TRY newline compound_statement newline TOKEN_CATCH newline compound_statement { $$ = node3( sval_catch, $3, $7, YYLLOC ); }
| TOKEN_SWITCH prim_expr newline compound_statement { $$ = node3( sval_switch, $2, $4, YYLLOC ); }
| TOKEN_BREAK { $$ = node1( sval_break, YYLLOC ); }
| TOKEN_CONTINUE { $$ = node1( sval_continue, YYLLOC ); }
| TOKEN_IDENTIFIER event_parameter_list { $$ = node3( sval_cmd, $1.val, node1( sval_none, $2 ), node_pos( $1.sourcePos ) ); }
//| TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node3( sval_cmd, node_string( parsetree_string( str( $1.stringValue ) + "::" + $3.stringValue ) ), node1( sval_none, $4 ), $1.sourcePos ); }
| nonident_prim_expr TOKEN_IDENTIFIER event_parameter_list { $$ = node4( sval_cmd_method, $1, $2.val, node1( sval_none, $3 ), node_pos( $2.sourcePos ) ); }
//| nonident_prim_expr TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node4( sval_cmd_method, $1, node_string( parsetree_string( str( $2.stringValue ) + "::" + $4.stringValue ) ), node1( sval_none, $5 ), $2.sourcePos ); }
| nonident_prim_expr TOKEN_ASSIGNMENT expr { $$ = node3( sval_assignment, $1, $3, YYLLOC ); }
| nonident_prim_expr TOKEN_PLUS_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_PLUS ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_MINUS_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_MINUS ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_MULTIPLY_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_MULTIPLY ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_DIVIDE_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_DIVIDE ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_MODULUS_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_PERCENTAGE ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_AND_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_BITWISE_AND ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_EXCL_OR_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_BITWISE_EXCL_OR ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_OR_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_BITWISE_OR ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_SHIFT_LEFT_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_SHIFT_LEFT ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_SHIFT_RIGHT_EQUALS expr { $$ = node3( sval_assignment, $1, node4( sval_operation, node1b( OP_BIN_SHIFT_RIGHT ), $1, $3, YYLLOC ), YYLLOC ); }
| nonident_prim_expr TOKEN_INCREMENT { $$ = node3( sval_assignment, $1, node2( sval_func1, node1b( OP_UN_INC ), $1 ), YYLLOC ); }
| nonident_prim_expr TOKEN_DECREMENT { $$ = node3( sval_assignment, $1, node2( sval_func1, node1b( OP_UN_DEC ), $1 ), YYLLOC ); }
| statement TOKEN_SEMICOLON
;
compound_statement:
TOKEN_LBRACKET newline statement_list newline TOKEN_RBRACKET { $$ = node1( sval_statement_list, $3 ); }
;
expr:
expr TOKEN_LOGICAL_AND newline expr { $$ = node3( sval_and, $1, $4, YYLLOC ); }
| expr TOKEN_LOGICAL_OR newline expr { $$ = node3( sval_or, $1, $4, YYLLOC ); }
| expr TOKEN_BITWISE_AND newline expr { $$ = node4( sval_operation, node1b( OP_BIN_BITWISE_AND ), $1, $4, YYLLOC ); }
| expr TOKEN_BITWISE_EXCL_OR newline expr { $$ = node4( sval_operation, node1b( OP_BIN_BITWISE_EXCL_OR ), $1, $4, YYLLOC ); }
| expr TOKEN_BITWISE_OR newline expr { $$ = node4( sval_operation, node1b( OP_BIN_BITWISE_OR ), $1, $4, YYLLOC ); }
| expr TOKEN_EQUALITY newline expr { $$ = node4( sval_operation, node1b( OP_BIN_EQUALITY ), $1, $4, YYLLOC ); }
| expr TOKEN_INEQUALITY newline expr { $$ = node4( sval_operation, node1b( OP_BIN_INEQUALITY ), $1, $4, YYLLOC ); }
| expr TOKEN_LESS_THAN newline expr { $$ = node4( sval_operation, node1b( OP_BIN_LESS_THAN ), $1, $4, YYLLOC ); }
| expr TOKEN_GREATER_THAN newline expr { $$ = node4( sval_operation, node1b( OP_BIN_GREATER_THAN ), $1, $4, YYLLOC ); }
| expr TOKEN_LESS_THAN_OR_EQUAL newline expr { $$ = node4( sval_operation, node1b( OP_BIN_LESS_THAN_OR_EQUAL ), $1, $4, YYLLOC ); }
| expr TOKEN_GREATER_THAN_OR_EQUAL newline expr { $$ = node4( sval_operation, node1b( OP_BIN_GREATER_THAN_OR_EQUAL ), $1, $4, YYLLOC ); }
| expr TOKEN_PLUS newline expr { $$ = node4( sval_operation, node1b( OP_BIN_PLUS ), $1, $4, YYLLOC ); }
| expr TOKEN_MINUS newline expr { $$ = node4( sval_operation, node1b( OP_BIN_MINUS ), $1, $4, YYLLOC ); }
| expr TOKEN_MULTIPLY newline expr { $$ = node4( sval_operation, node1b( OP_BIN_MULTIPLY ), $1, $4, YYLLOC ); }
| expr TOKEN_DIVIDE newline expr { $$ = node4( sval_operation, node1b( OP_BIN_DIVIDE ), $1, $4, YYLLOC ); }
| expr TOKEN_MODULUS newline expr { $$ = node4( sval_operation, node1b( OP_BIN_PERCENTAGE ), $1, $4, YYLLOC ); }
| expr TOKEN_SHIFT_LEFT newline expr { $$ = node4( sval_operation, node1b( OP_BIN_SHIFT_LEFT ), $1, $4, YYLLOC ); }
| expr TOKEN_SHIFT_RIGHT newline expr { $$ = node4( sval_operation, node1b( OP_BIN_SHIFT_RIGHT ), $1, $4, YYLLOC ); }
| expr TOKEN_TERNARY expr TOKEN_COLON expr { $$ = node4( sval_ifelse, $1, $3, $5, YYLLOC ); }
| nonident_prim_expr
| func_prim_expr
| identifier_prim { $$ = node1( sval_store_string, $1.val ); }
;
func_prim_expr:
TOKEN_IDENTIFIER event_parameter_list_need { $$ = node3( sval_cmd_default_ret, $1.val, node1( sval_none, $2 ), node_pos( $1.sourcePos ) ); }
//| TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list_need { $$ = node3( sval_cmd_default_ret, node_string( parsetree_string( str( $1.val.stringValue ) + "::" + $3.val.stringValue ) ), node1( sval_none, $4 ), $1.sourcePos ); }
| nonident_prim_expr TOKEN_IDENTIFIER event_parameter_list { $$ = node4( sval_cmd_method_ret, $1, $2.val, node1( sval_none, $3 ), node_pos( $2.sourcePos ) ); }
//| nonident_prim_expr TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON TOKEN_IDENTIFIER event_parameter_list { $$ = node4( sval_cmd_method_ret, $1, node_string( parsetree_string( str( $2.val.stringValue ) + "::" + $4.val.stringValue ) ), node1( sval_none, $5 ), $2.sourcePos ); }
| TOKEN_NEG func_prim_expr { $$ = node3( sval_func1, node1b( OP_UN_MINUS ), $2, YYLLOC ); }
| TOKEN_COMPLEMENT func_prim_expr { $$ = node3( sval_func1, node1b( OP_UN_COMPLEMENT ), $2, YYLLOC ); }
| TOKEN_NOT func_prim_expr { $$ = node2( sval_not, $2, YYLLOC ); }
| TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON prim_expr { $$ = node3( sval_constarray, node2( sval_store_string, $1.val, node_pos( $1.sourcePos ) ), $3, YYLLOC ); }
| nonident_prim_expr TOKEN_DOUBLE_COLON prim_expr { $$ = node3( sval_constarray, $1, $3, YYLLOC ); }
| TOKEN_MAKEARRAY newline makearray_statement_list newline TOKEN_ENDARRAY { $$ = node1( sval_makearray, $3 ); }
;
event_parameter_list:
{ $$ = node0( sval_none ); }
| event_parameter_list prim_expr { $$ = append_node( $1, $2 ); }
| prim_expr { $$ = linked_list_end( $1 ); }
;
event_parameter_list_need:
event_parameter_list_need prim_expr { $$ = append_node( $1, $2 ); }
| prim_expr { $$ = linked_list_end( $1 ); }
;
prim_expr:
nonident_prim_expr
| identifier_prim { $$ = node1( sval_store_string, $1.val ); }
| prim_expr TOKEN_DOUBLE_COLON prim_expr { $$ = node3( sval_constarray, $1, $3, YYLLOC ); }
;
nonident_prim_expr:
TOKEN_DOLLAR TOKEN_LPAREN expr TOKEN_RPAREN { $$ = node3( sval_func1, node1b( OP_UN_TARGETNAME ), $3, YYLLOC ); }
| TOKEN_DOLLAR TOKEN_IDENTIFIER { $$ = node3( sval_func1, node1b( OP_UN_TARGETNAME ), node1( sval_store_string, $2.val ), YYLLOC ); }
| TOKEN_DOLLAR TOKEN_STRING { $$ = node3( sval_func1, node1b( OP_UN_TARGETNAME ), node1( sval_store_string, $2.val ), YYLLOC ); }
| nonident_prim_expr TOKEN_PERIOD TOKEN_IDENTIFIER { $$ = node3( sval_field, $1, $3.val, node_pos( $3.sourcePos ) ); }
| nonident_prim_expr TOKEN_PERIOD TOKEN_STRING { $$ = node3( sval_field, $1, $3.val, node_pos( $3.sourcePos ) ); }
| nonident_prim_expr TOKEN_PERIOD TOKEN_SIZE { $$ = node3( sval_func1, node1b( OP_UN_SIZE ), $1, YYLLOC ); }
| nonident_prim_expr TOKEN_LSQUARE expr TOKEN_RSQUARE { $$ = node3( sval_array, $1, $3, $1 ); }
| TOKEN_STRING { $$ = node1( sval_store_string, $1.val ); }
| number
| TOKEN_LPAREN expr expr expr TOKEN_RPAREN { $$ = node4( sval_calc_vector, $2, $3, $4, YYLLOC ); }
| TOKEN_LISTENER { $$ = node2( sval_store_method, $1.val, YYLLOC ); }
| TOKEN_LPAREN expr TOKEN_RPAREN { $$ = $2; }
| TOKEN_LPAREN TOKEN_RPAREN { $$ = node0( sval_none ); }
| TOKEN_NEG nonident_prim_expr { $$ = node3( sval_func1, node1b( OP_UN_MINUS ), $2, YYLLOC ); }
| TOKEN_COMPLEMENT nonident_prim_expr { $$ = node3( sval_func1, node1b( OP_UN_COMPLEMENT ), $2, YYLLOC ); }
| TOKEN_NOT nonident_prim_expr { $$ = node2( sval_not, $2, YYLLOC ); }
| TOKEN_NULL { $$ = node1( sval_store_null, YYLLOC ); }
| TOKEN_NIL { $$ = node1( sval_store_nil, YYLLOC ); }
;
number:
TOKEN_FLOAT { $$ = node1( sval_store_float, $1.val ); }
| TOKEN_INTEGER { $$ = node1( sval_store_integer, $1.val ); }
;
identifier_prim:
TOKEN_IDENTIFIER
;
makearray_statement_list:
{ $$ = node0( sval_none ); }
| makearray_statement_list makearray_statement newline { $$ = append_node( $1, node1( sval_makearray, $2 ) ); }
| makearray_statement newline { $$ = linked_list_end( node1( sval_makearray, $1 ) ); }
;
makearray_statement:
prim_expr { $$ = linked_list_end( $1 ); }
| makearray_statement prim_expr { $$ = append_node( $1, $2 ); }
;
newline:
{}
| TOKEN_EOL
;
%%

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "actor.h"
#include "playerbot.h"
#include "consoleevent.h"
// We assume that we have limited access to the server-side
// and that most logic come from the playerstate_s structure

View file

@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// portal.cpp: Portals - surfaces that are mirrors or cameras
#include "portal.h"
#include "game.h"
/*QUAKED portal_surface (1 0 1) (-8 -8 -8) (8 8 8)
The portal surface nearest this entity will show a view from the targeted portal_camera, or a mirror view if untargeted.

9420
code/game/scriptmaster.cpp Normal file

File diff suppressed because it is too large Load diff

601
code/game/scriptmaster.h Normal file
View file

@ -0,0 +1,601 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// scriptmaster.h: Handle events, parse scripts, spawn at the beginning of the map
#ifndef __SCRIPTMASTER_H__
#define __SCRIPTMASTER_H__
#include "class.h"
#include "listener.h"
#include "scriptvm.h"
#include <con_timer.h>
#define MAX_COMMANDS 20
#define MAX_EXECUTION_TIME 3000
void Showmenu( str name, qboolean bForce );
void Hidemenu( str name, qboolean bForce );
#define MAX_VAR_STACK 1024
#define MAX_FASTEVENT 10
class ScriptMaster : public Listener
{
public:
// VM recursions
int stackCount;
// Global stack (not needed anymore)
#if 0
ScriptVariable avar_Stack[ MAX_VAR_STACK+1 ]; // Global variables stack
Event fastEvent[ MAX_FASTEVENT+1 ]; // Event that will be executed
ScriptVariable *pTop; // Top variable on the stack
#endif
// Command variables
unsigned int cmdCount; // cmd count
int cmdTime; // Elapsed VM execution time
int maxTime; // Maximum VM execution time
// Thread variables
SafePtr<ScriptThread> m_PreviousThread; // parm.previousthread
SafePtr<ScriptThread> m_CurrentThread; // current running thread
con_map< const_str, GameScript * > m_GameScripts; // compiled gamescripts
// Miscellaneous
Container< str > m_menus; // Script menus
con_timer timerList; // waiting threads list
con_arrayset< str, str > StringDict; // const strings (improve performance)
int iPaused; // num times paused
// Context switch variables
bool m_bAllowContextSwitch;
Container< SafePtr< ScriptThread > > m_contextSwitches; // Threads to be prepared for context switching
protected:
static const char *ConstStrings[];
private:
GameScript *GetGameScriptInternal( str& filename );
void InitConstStrings( void );
public:
CLASS_PROTOTYPE( ScriptMaster );
virtual ~ScriptMaster();
virtual void Archive( Archiver &arc );
void ArchiveString( Archiver& arc, const_str& s );
void AddContextSwitch( ScriptThread *thread );
const_str AddString( const char *s );
const_str AddString( str& s );
const_str GetString( const char *s );
const_str GetString( str s );
str& GetString( const_str s );
void AddTiming( ScriptThread *thread, float time );
void RemoveTiming( ScriptThread *thread );
void AddMenu( str name );
void RemoveMenu( str name );
void LoadMenus( void );
ScriptThread *CreateScriptThread( GameScript *scr, Listener *self, const_str label );
ScriptThread *CreateScriptThread( GameScript *scr, Listener *self, str label );
ScriptThread *CreateScriptThread( ScriptClass *scriptClass, const_str label );
ScriptThread *CreateScriptThread( ScriptClass *scriptClass, str label );
ScriptThread *CreateScriptThread( ScriptClass *scriptClass, unsigned char *m_pCodePos );
ScriptThread *CreateThread( GameScript *scr, str label, Listener *self = NULL );
ScriptThread *CreateThread( str filename, str label, Listener *self = NULL );
ScriptClass *CurrentScriptClass( void );
ScriptThread *CurrentThread( void );
ScriptThread *PreviousThread( void );
void ExecuteThread( GameScript *scr, str label = "" );
void ExecuteThread( str filename, str label = "" );
void ExecuteThread( GameScript *scr, str label, Event &parms );
void ExecuteThread( str filename, str label, Event &parms );
GameScript *GetTempScript( const char *data );
GameScript *GetGameScript( str filename, qboolean recompile = false );
GameScript *GetGameScript( const_str filename, qboolean recompile = false );
GameScript *GetScript( str filename, qboolean recompile = false );
GameScript *GetScript( const_str filename, qboolean recompile = false );
void CloseGameScript();
void Reset( qboolean samemap = false );
void Init();
void ExecuteRunning();
void SetTime( int time );
void PrintStatus( void );
void PrintThread( int iThreadNum );
//
// Events
//
void RegisterAliasInternal( Event *ev, bool bCache = false );
void RegisterAlias( Event *ev );
void RegisterAliasAndCache( Event *ev );
void Cache( Event *ev );
};
class ScriptThread : public Listener
{
friend class Flag;
friend class EndOn;
friend class Listener;
friend class ScriptMaster;
private:
ScriptVM *m_ScriptVM;
SafePtr< ScriptThread > m_WaitingContext;
private:
void ScriptExecuteInternal( ScriptVariable *data = NULL, int dataSize = 0 );
public:
CLASS_PROTOTYPE( ScriptThread );
#ifndef _DEBUG_MEM
void *operator new( size_t size );
void operator delete( void *ptr );
#endif
virtual void Archive( Archiver &arc ) override;
void ArchiveInternal( Archiver& arc );
virtual void StartedWaitFor( void ) override;
virtual void StoppedNotify( void ) override;
virtual void StoppedWaitFor( const_str name, bool bDeleting ) override;
virtual ScriptThread *CreateThreadInternal(const ScriptVariable& label) override;
virtual ScriptThread *CreateScriptInternal(const ScriptVariable& label) override;
ScriptThread();
ScriptThread( ScriptClass *scriptClass, unsigned char *pCodePos );
virtual ~ScriptThread();
void Execute( Event &ev );
void Execute( Event *ev = NULL );
void Execute(ScriptVariable *data, int dataSize);
void DelayExecute( Event& ev );
void DelayExecute( Event *ev = NULL );
void AllowContextSwitch( bool allow = true );
ScriptClass *GetScriptClass( void );
str ScriptThread::FileName(void);
int GetThreadState( void );
ScriptThread *GetWaitingContext( void );
void SetWaitingContext( ScriptThread *thread );
void HandleContextSwitch( ScriptThread *childThread );
void Pause( void );
void ScriptExecute( ScriptVariable *data, int dataSize, ScriptVariable &returnValue );
void Stop( void );
void Wait( float time );
void StartTiming( float time );
void StartTiming( void );
void CanSwitchTeams( Event *ev );
bool CanScriptTracePrint( void );
void CharToInt( Event *ev );
void Conprintf( Event *ev );
void CreateHUD( Event *ev );
void Earthquake( Event *ev );
void FadeSound( Event *ev );
void FileOpen( Event *ev );
void FileWrite( Event *ev );
void FileRead( Event *ev );
void FileClose( Event *ev );
void FileEof( Event *ev );
void FileSeek( Event *ev );
void FileTell( Event *ev );
void FileRewind( Event *ev );
void FilePutc( Event *ev );
void FilePuts( Event *ev );
void FileGetc( Event *ev );
void FileGets( Event *ev );
void FileError( Event *ev );
void FileFlush( Event *ev );
void FileExists( Event *ev );
void FileReadAll( Event *ev );
void FileSaveAll( Event *ev );
void FileRemove( Event *ev );
void FileRename( Event *ev );
void FileCopy( Event *ev );
void FileReadPak( Event *ev );
void FileList( Event *ev );
void FileNewDirectory( Event *ev );
void FileRemoveDirectory( Event *ev );
void FlagClear( Event *ev );
void FlagInit( Event *ev );
void FlagSet( Event *ev );
void FlagWait( Event *ev );
void Lock( Event *ev );
void UnLock( Event *ev );
void GetAreaEntities( Event *ev );
void GetArrayKeys( Event *ev );
void GetArrayValues( Event *ev );
void GetEntArray( Event *ev );
void GetPlayerNetname( Event *ev );
void GetPlayerIP( Event *ev );
void GetPlayerPing( Event *ev );
void GetPlayerClientNum( Event *ev );
void GetTime( Event *ev );
void GetDate( Event *ev );
void GetTimeZone( Event *ev );
void PregMatch( Event *ev );
void EventHudDraw3d( Event *ev );
void EventHudDrawTimer( Event *ev );
void EventHudDrawShader( Event *ev );
void EventHudDrawAlign( Event *ev );
void EventHudDrawRect( Event *ev );
void EventHudDrawVirtualSize( Event *ev );
void EventHudDrawColor( Event *ev );
void EventHudDrawAlpha( Event *ev );
void EventHudDrawString( Event *ev );
void EventHudDrawFont( Event *ev );
void EventIHudDraw3d( Event *ev );
void EventIHudDrawShader( Event *ev );
void EventIHudDrawAlign( Event *ev );
void EventIHudDrawRect( Event *ev );
void EventIHudDrawVirtualSize( Event *ev );
void EventIHudDrawColor( Event *ev );
void EventIHudDrawAlpha( Event *ev );
void EventIHudDrawString( Event *ev );
void EventIHudDrawFont( Event *ev );
void EventIHudDrawTimer( Event *ev );
void EventIsArray( Event *ev );
void EventIsDefined( Event *ev );
void EventIsOnGround( Event *ev );
void EventIsOutOfBounds( Event *ev );
void GetEntity( Event *ev );
void MathCos( Event *ev );
void MathSin( Event *ev );
void MathTan( Event *ev );
void MathACos( Event *ev );
void MathASin( Event *ev );
void MathATan( Event *ev );
void MathATan2( Event *ev );
void MathCosH( Event *ev );
void MathSinH( Event *ev );
void MathTanH( Event *ev );
void MathExp( Event *ev );
void MathFrexp( Event *ev );
void MathLdexp( Event *ev );
void MathLog( Event *ev );
void MathLog10( Event *ev );
void MathModf( Event *ev );
void MathPow( Event *ev );
void MathSqrt( Event *ev );
void MathCeil( Event *ev );
void MathFloor( Event *ev );
void MathFmod( Event *ev );
void StringBytesCopy( Event *ev );
void Md5File( Event *ev );
void Md5String( Event *ev );
void RegisterEvent( Event *ev );
void RestoreSound( Event *ev );
void RemoveArchivedClass( Event *ev );
void ServerStufftext( Event *ev );
void SetTimer( Event *ev );
void TeamGetScore( Event *ev );
void TeamSetScore( Event *ev );
void TeamSwitchDelay( Event *ev );
void TraceDetails( Event *ev );
void TypeOfVariable( Event *ev );
void UnregisterEvent( Event *ev );
void VisionGetNaked( Event *ev );
void VisionSetNaked( Event *ev );
void CancelWaiting( Event *ev );
void GetAbs( Event *ev );
void AddObjective( Event *ev );
void AddObjective( int index, int status, str text, Vector location );
void ClearObjectiveLocation( Event *ev );
void ClearObjectiveLocation( void );
void SetObjectiveLocation( Event *ev );
void SetObjectiveLocation( Vector vLocation );
void SetCurrentObjective( Event *ev );
void SetCurrentObjective( int iObjective );
void AllAIOff( Event *ev );
void AllAIOn( Event *ev );
void EventTeamWin( Event *ev );
void Angles_PointAt( Event *ev );
void Angles_ToForward( Event *ev );
void Angles_ToLeft( Event *ev );
void Angles_ToUp( Event *ev );
void Assert( Event *ev );
void Cache( Event *ev );
void CastBoolean( Event *ev );
void CastEntity( Event *ev );
void CastFloat( Event *ev );
void CastInt( Event *ev );
void CastString( Event *ev );
void CreateReturnThread( Event *ev );
void CreateThread( Event *ev );
void ExecuteReturnScript( Event *ev );
void ExecuteScript( Event *ev );
void EventCreateListener( Event *ev );
void EventDelayThrow( Event *ev );
void EventEnd( Event *ev );
void EventTimeout( Event *ev );
void EventError( Event *ev );
void EventGoto( Event *ev );
void EventRegisterCommand( Event *ev );
void EventGetCvar( Event *ev );
void EventSetCvar( Event *ev );
void EventSightTrace( Event *ev );
void EventTrace( Event *ev );
void EventThrow( Event *ev );
void EventWait( Event *ev );
void EventWaitFrame( Event *ev );
void EventIsAlive( Event *ev );
void EventEarthquake( Event *ev );
void MapEvent( Event *ev );
void CueCamera( Event *ev );
void CuePlayer( Event *ev );
void FreezePlayer( Event *ev );
void ReleasePlayer( Event *ev );
void EventDrawHud( Event *ev );
void EventRadiusDamage( Event *ev );
void GetSelf( Event *ev );
void IPrintln( Event *ev );
void IPrintln_NoLoc( Event *ev );
void IPrintlnBold( Event *ev );
void IPrintlnBold_NoLoc( Event *ev );
void Println( Event *ev );
void Print( Event *ev );
void MPrintln( Event *ev );
void MPrint( Event *ev );
void EventPrint3D( Event *ev );
void EventBspTransition( Event *ev );
void EventLevelTransition( Event *ev );
void EventMissionTransition( Event *ev );
void EventGetBoundKey1( Event *ev );
void EventGetBoundKey2( Event *ev );
void EventLocConvertString( Event *ev );
void RandomFloat( Event *ev );
void RandomInt( Event *ev );
void Spawn( Event *ev );
Listener *SpawnInternal( Event *ev );
void SpawnReturn( Event *ev );
void ForceMusicEvent( Event *ev );
void SoundtrackEvent( Event *ev );
void RestoreSoundtrackEvent( Event *ev );
void EventVectorAdd( Event *ev );
void EventVectorCloser( Event *ev );
void EventVectorCross( Event *ev );
void EventVectorDot( Event *ev );
void EventVectorLength( Event *ev );
void EventVectorNormalize( Event *ev );
void EventVectorScale( Event *ev );
void EventVectorSubtract( Event *ev );
void EventVectorToAngles( Event *ev );
void EventVectorWithin( Event *ev );
void FadeIn( Event *ev );
void FadeOut( Event *ev );
void ClearFade( Event *ev );
void Letterbox( Event *ev );
void ClearLetterbox( Event *ev );
void MusicEvent( Event *ev );
void MusicVolumeEvent( Event *ev );
void RestoreMusicVolumeEvent( Event *ev );
void SetCinematic( Event *ev );
void SetNonCinematic( Event *ev );
void StuffCommand( Event *ev );
void KillEnt( Event *ev );
void RemoveEnt( Event *ev );
void KillClass( Event *ev );
void RemoveClass( Event *ev );
void CameraCommand( Event *ev );
void SetLightStyle( Event *ev );
void CenterPrint( Event *ev );
void LocationPrint( Event *ev );
void TriggerEvent( Event *ev );
void ServerEvent( Event *ev );
void MissionFailed( Event *ev );
};
extern qboolean disable_team_change;
extern qboolean disable_team_spectate;
extern str vision_current;
extern Event EV_ScriptThread_Trace;
extern Event EV_ScriptThread_SightTrace;
extern Event EV_ScriptThread_VisionSetNaked;
extern Event EV_ScriptThread_CancelWaiting;
extern con_set< str, ScriptThreadLabel > m_scriptCmds;
extern ScriptMaster Director;
class LightStyleClass : public Class
{
private:
CLASS_PROTOTYPE( LightStyleClass );
str styles[ MAX_LIGHTSTYLES ];
public:
void SetLightStyle( int index, str style );
void Archive( Archiver &arc );
};
extern LightStyleClass lightStyles;
typedef enum scriptedEvType_e
{
SE_DEFAULT,
SE_CONNECTED,
SE_DISCONNECTED,
SE_SPAWN,
SE_DAMAGE,
SE_KILL,
SE_KEYPRESS,
SE_INTERMISSION,
SE_SERVERCOMMAND,
SE_CHANGETEAM,
SE_MAX
} scriptedEvType_t;
class ScriptEvent : public Class
{
public:
ScriptThreadLabel label;
public:
CLASS_PROTOTYPE( ScriptEvent );
virtual void Archive( Archiver& arc );
bool IsRegistered( void );
void Trigger( Event *ev );
};
inline void ScriptEvent::Archive
(
Archiver& arc
)
{
label.Archive( arc );
}
inline bool ScriptEvent::IsRegistered
(
void
)
{
return label.IsSet();
}
inline void ScriptEvent::Trigger
(
Event *ev
)
{
if( label.IsSet() )
{
label.Execute( NULL, ev );
}
delete ev;
}
extern ScriptEvent scriptedEvents[];
typedef struct mutex_thread_list_s {
SafePtr< ScriptThread > m_pThread;
struct mutex_thread_list_s *next;
struct mutex_thread_list_s *prev;
} mutex_thread_list_t;
class ScriptMutex : public Listener {
public:
SafePtr< ScriptThread > m_pLockThread;
int m_iLockCount;
mutex_thread_list_t m_list;
private:
void setOwner( ScriptThread *pThread );
void Lock( mutex_thread_list_t *pList );
public:
CLASS_PROTOTYPE( ScriptMutex );
ScriptMutex();
~ScriptMutex();
virtual void StoppedNotify( void );
void Lock( void );
void Unlock( void );
};
class Flag
{
public:
char flagName[MAX_QPATH];
qboolean bSignaled;
private:
Container< ScriptVM * > m_WaitList;
public:
Flag();
~Flag();
void Reset(void);
void Set(void);
void Wait(ScriptThread *Thread);
};
class FlagList
{
friend class Flag;
private:
void AddFlag(Flag *flag);
void RemoveFlag(Flag *flag);
public:
Container< Flag * > m_Flags;
Flag *FindFlag(const char * name);
};
extern FlagList flags;
#endif /* scriptmaster.h */

236
code/game/scriptopcodes.cpp Normal file
View file

@ -0,0 +1,236 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// scriptopcodes.cpp
#include "glb_local.h"
#include "scriptopcodes.h"
static opcode_t OpcodeInfo[] =
{
{ "OPCODE_EOF", 0, 0, 0 },
{ "OPCODE_BOOL_JUMP_FALSE4", 5, -1, 0 },
{ "OPCODE_BOOL_JUMP_TRUE4", 5, -1, 0 },
{ "OPCODE_VAR_JUMP_FALSE4", 5, -1, 0 },
{ "OPCODE_VAR_JUMP_TRUE4", 5, -1, 0 },
{ "OPCODE_BOOL_LOGICAL_AND", 5, -1, 0 },
{ "OPCODE_BOOL_LOGICAL_OR", 5, -1, 0 },
{ "OPCODE_VAR_LOGICAL_AND", 5, -1, 0 },
{ "OPCODE_VAR_LOGICAL_OR", 5, -1, 0 },
{ "OPCODE_BOOL_TO_VAR", 0, 0, 0 },
{ "OPCODE_JUMP4", 1 + sizeof( unsigned int ), 0, 0 },
{ "OPCODE_JUMP_BACK4", 1 + sizeof( unsigned int ), 0, 0 },
{ "OPCODE_STORE_INT0", 1, 1, 0 },
{ "OPCODE_STORE_INT1", 1 + sizeof( char ), 1, 0 },
{ "OPCODE_STORE_INT2", 1 + sizeof( short ), 1, 0 },
{ "OPCODE_STORE_INT3", 1 + sizeof( short3 ), 1, 0 },
{ "OPCODE_STORE_INT4", 1 + sizeof( int ), 1, 0 },
{ "OPCODE_BOOL_STORE_FALSE", 1, 1, 0 },
{ "OPCODE_BOOL_STORE_TRUE", 1, 1, 0 },
{ "OPCODE_STORE_STRING", 1 + sizeof( unsigned int ), 1, 0 },
{ "OPCODE_STORE_FLOAT", 1 + sizeof( float ), 1, 0 },
{ "OPCODE_STORE_VECTOR", 1 + sizeof( Vector ), 1, 0 },
{ "OPCODE_CALC_VECTOR", 1, -2, 0 },
{ "OPCODE_STORE_NULL", 1, 1, 0 },
{ "OPCODE_STORE_NIL", 1, 1, 0 },
{ "OPCODE_EXEC_CMD0", 5, 0, 1 },
{ "OPCODE_EXEC_CMD1", 5, -1, 1 },
{ "OPCODE_EXEC_CMD2", 5, -2, 1 },
{ "OPCODE_EXEC_CMD3", 5, -3, 1 },
{ "OPCODE_EXEC_CMD4", 5, -4, 1 },
{ "OPCODE_EXEC_CMD5", 5, -5, 1 },
{ "OPCODE_EXEC_CMD_COUNT1", 6, -128, 1 },
{ "OPCODE_EXEC_CMD_METHOD0", 5, -1, 1 },
{ "OPCODE_EXEC_CMD_METHOD1", 5, -2, 1 },
{ "OPCODE_EXEC_CMD_METHOD2", 5, -3, 1 },
{ "OPCODE_EXEC_CMD_METHOD3", 5, -4, 1 },
{ "OPCODE_EXEC_CMD_METHOD4", 5, -5, 1 },
{ "OPCODE_EXEC_CMD_METHOD5", 5, -6, 1 },
{ "OPCODE_EXEC_CMD_METHOD_COUNT1", 6, -128, 1 },
{ "OPCODE_EXEC_METHOD0", 5, 0, 1 },
{ "OPCODE_EXEC_METHOD1", 5, -1, 1 },
{ "OPCODE_EXEC_METHOD2", 5, -2, 1 },
{ "OPCODE_EXEC_METHOD3", 5, -3, 1 },
{ "OPCODE_EXEC_METHOD4", 5, -4, 1 },
{ "OPCODE_EXEC_METHOD5", 5, -5, 1 },
{ "OPCODE_EXEC_METHOD_COUNT1", 6, -128, 1 },
{ "OPCODE_LOAD_GAME_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_LEVEL_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_LOCAL_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_PARM_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_SELF_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_GROUP_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_OWNER_VAR", 5, -1, 0 },
{ "OPCODE_LOAD_FIELD_VAR", 5, -2, 0 },
{ "OPCODE_LOAD_ARRAY_VAR", 1, -3, 0 },
{ "OPCODE_LOAD_CONST_ARRAY1", 2, -128, 0 },
{ "OPCODE_STORE_FIELD_REF", 5, 0, 0 },
{ "OPCODE_STORE_ARRAY_REF", 1, -1, 0 },
{ "OPCODE_MARK_STACK_POS", 1, 0, 0 },
{ "OPCODE_STORE_PARAM", 1, 1, 0 },
{ "OPCODE_RESTORE_STACK_POS", 1, 0, 0 },
{ "OPCODE_LOAD_STORE_GAME_VAR", 5, 0, 0 },
{ "OPCODE_LOAD_STORE_LEVEL_VAR", 5, 0, 0 },
{ "OPCODE_LOAD_STORE_LOCAL_VAR", 5, 0, 0 },
{ "OPCODE_LOAD_STORE_PARM_VAR", 5, 0, 0 },
{ "OPCODE_LOAD_STORE_SELF_VAR", 5, 0, 0 },
{ "OPCODE_LOAD_STORE_GROUP_VAR", 5, 0, 0 },
{ "OPCODE_LOAD_STORE_OWNER_VAR", 5, 0, 0 },
{ "OPCODE_STORE_GAME_VAR", 5, 1, 0 },
{ "OPCODE_STORE_LEVEL_VAR", 5, 1, 0 },
{ "OPCODE_STORE_LOCAL_VAR", 5, 1, 0 },
{ "OPCODE_STORE_PARM_VAR", 5, 1, 0 },
{ "OPCODE_STORE_SELF_VAR", 5, 1, 0 },
{ "OPCODE_STORE_GROUP_VAR", 5, 1, 0 },
{ "OPCODE_STORE_OWNER_VAR", 5, 1, 0 },
{ "OPCODE_STORE_FIELD", 5, 0, 1 },
{ "OPCODE_STORE_ARRAY", 1, -1, 0 },
{ "OPCODE_STORE_GAME", 1, 1, 0 },
{ "OPCODE_STORE_LEVEL", 1, 1, 0 },
{ "OPCODE_STORE_LOCAL", 1, 1, 0 },
{ "OPCODE_STORE_PARM", 1, 1, 0 },
{ "OPCODE_STORE_SELF", 1, 1, 0 },
{ "OPCODE_STORE_GROUP", 1, 1, 0 },
{ "OPCODE_STORE_OWNER", 1, 1, 0 },
{ "OPCODE_BIN_BITWISE_AND", 1, -1, 0 },
{ "OPCODE_BIN_BITWISE_OR", 1, -1, 0 },
{ "OPCODE_BIN_BITWISE_EXCL_OR", 1, -1, 0 },
{ "OPCODE_BIN_EQUALITY", 1, -1, 0 },
{ "OPCODE_BIN_INEQUALITY", 1, -1, 0 },
{ "OPCODE_BIN_LESS_THAN", 1, -1, 0 },
{ "OPCODE_BIN_GREATER_THAN", 1, -1, 0 },
{ "OPCODE_BIN_LESS_THAN_OR_EQUAL", 1, -1, 0 },
{ "OPCODE_BIN_GREATER_THAN_OR_EQUAL", 1, -1, 0 },
{ "OPCODE_BIN_PLUS", 1, -1, 0 },
{ "OPCODE_BIN_MINUS", 1, -1, 0 },
{ "OPCODE_BIN_MULTIPLY", 1, -1, 0 },
{ "OPCODE_BIN_DIVIDE", 1, -1, 0 },
{ "OPCODE_BIN_PERCENTAGE", 1, -1, 0 },
{ "OPCODE_UN_MINUS", 1, 0, 0 },
{ "OPCODE_UN_COMPLEMENT", 1, 0, 0 },
{ "OPCODE_UN_TARGETNAME", 1, 0, 0 },
{ "OPCODE_BOOL_UN_NOT", 1, 0, 0 },
{ "OPCODE_VAR_UN_NOT", 1, 0, 0 },
{ "OPCODE_UN_CAST_BOOLEAN", 1, 0, 0 },
{ "OPCODE_UN_INC", 1, 0, 0 },
{ "OPCODE_UN_DEC", 1, 0, 0 },
{ "OPCODE_UN_SIZE", 1, 0, 0 },
{ "OPCODE_SWITCH", 5, -1, 0 },
{ "OPCODE_FUNC", 11, -128, 1 },
{ "OPCODE_NOP", 1, 0, 0 },
{ "OPCODE_BIN_SHIFT_LEFT", 1, -1, 0 },
{ "OPCODE_BIN_SHIFT_RIGHT", 1, -1, 0 },
{ "OPCODE_END", 1, -1, 0 },
{ "OPCODE_RETURN", 1, -1, 0 },
};
static const char *aszVarGroupNames[] =
{
"game",
"level",
"local",
"parm",
"self"
};
/*
====================
VarGroupName
====================
*/
const char *VarGroupName( int iVarGroup )
{
return aszVarGroupNames[ iVarGroup ];
}
/*
====================
OpcodeName
====================
*/
const char *OpcodeName( int opcode )
{
return OpcodeInfo[ opcode ].opcodename;
}
/*
====================
OpcodeLength
====================
*/
int OpcodeLength( int opcode )
{
return OpcodeInfo[ opcode ].opcodelength;
}
/*
====================
OpcodeVarStackOffset
====================
*/
int OpcodeVarStackOffset( int opcode )
{
return OpcodeInfo[ opcode ].opcodestackoffset;
}
/*
====================
SetOpcodeVarStackOffset
====================
*/
void SetOpcodeVarStackOffset( int opcode, int iVarStackOffset )
{
OpcodeInfo[ opcode ].opcodestackoffset = iVarStackOffset;
}
/*
====================
IsExternalOpcode
====================
*/
bool IsExternalOpcode( int opcode )
{
return OpcodeInfo[ opcode ].isexternal ? true : false;
}

186
code/game/scriptopcodes.h Normal file
View file

@ -0,0 +1,186 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// scriptopcodes.h
typedef struct {
const char *opcodename;
int opcodelength;
short opcodestackoffset;
char isexternal;
} opcode_t;
typedef struct {
unsigned char opcode;
char VarStackOffset;
} opcode_info_t;
typedef enum
{
OP_DONE,
OP_BOOL_JUMP_FALSE4,
OP_BOOL_JUMP_TRUE4,
OP_VAR_JUMP_FALSE4,
OP_VAR_JUMP_TRUE4,
OP_BOOL_LOGICAL_AND,
OP_BOOL_LOGICAL_OR,
OP_VAR_LOGICAL_AND,
OP_VAR_LOGICAL_OR,
OP_BOOL_TO_VAR,
OP_JUMP4,
OP_JUMP_BACK4,
OP_STORE_INT0,
OP_STORE_INT1,
OP_STORE_INT2,
OP_STORE_INT3,
OP_STORE_INT4,
OP_BOOL_STORE_FALSE,
OP_BOOL_STORE_TRUE,
OP_STORE_STRING,
OP_STORE_FLOAT,
OP_STORE_VECTOR,
OP_CALC_VECTOR,
OP_STORE_NULL,
OP_STORE_NIL,
OP_EXEC_CMD0, // exec normal
OP_EXEC_CMD1,
OP_EXEC_CMD2,
OP_EXEC_CMD3,
OP_EXEC_CMD4,
OP_EXEC_CMD5,
OP_EXEC_CMD_COUNT1,
OP_EXEC_CMD_METHOD0, // exec from listener
OP_EXEC_CMD_METHOD1,
OP_EXEC_CMD_METHOD2,
OP_EXEC_CMD_METHOD3,
OP_EXEC_CMD_METHOD4,
OP_EXEC_CMD_METHOD5,
OP_EXEC_CMD_METHOD_COUNT1,
OP_EXEC_METHOD0, // exec from listener with return
OP_EXEC_METHOD1,
OP_EXEC_METHOD2,
OP_EXEC_METHOD3,
OP_EXEC_METHOD4,
OP_EXEC_METHOD5,
OP_EXEC_METHOD_COUNT1,
OP_LOAD_GAME_VAR,
OP_LOAD_LEVEL_VAR,
OP_LOAD_LOCAL_VAR,
OP_LOAD_PARM_VAR,
OP_LOAD_SELF_VAR,
OP_LOAD_GROUP_VAR,
OP_LOAD_OWNER_VAR,
OP_LOAD_FIELD_VAR,
OP_LOAD_ARRAY_VAR,
OP_LOAD_CONST_ARRAY1,
OP_STORE_FIELD_REF,
OP_STORE_ARRAY_REF,
OP_MARK_STACK_POS,
OP_STORE_PARAM,
OP_RESTORE_STACK_POS,
OP_LOAD_STORE_GAME_VAR,
OP_LOAD_STORE_LEVEL_VAR,
OP_LOAD_STORE_LOCAL_VAR,
OP_LOAD_STORE_PARM_VAR,
OP_LOAD_STORE_SELF_VAR,
OP_LOAD_STORE_GROUP_VAR,
OP_LOAD_STORE_OWNER_VAR,
OP_STORE_GAME_VAR,
OP_STORE_LEVEL_VAR,
OP_STORE_LOCAL_VAR,
OP_STORE_PARM_VAR,
OP_STORE_SELF_VAR,
OP_STORE_GROUP_VAR,
OP_STORE_OWNER_VAR,
OP_STORE_FIELD,
OP_STORE_ARRAY,
OP_STORE_GAME,
OP_STORE_LEVEL,
OP_STORE_LOCAL,
OP_STORE_PARM,
OP_STORE_SELF,
OP_STORE_GROUP,
OP_STORE_OWNER,
OP_BIN_BITWISE_AND,
OP_BIN_BITWISE_OR,
OP_BIN_BITWISE_EXCL_OR,
OP_BIN_EQUALITY,
OP_BIN_INEQUALITY,
OP_BIN_LESS_THAN,
OP_BIN_GREATER_THAN,
OP_BIN_LESS_THAN_OR_EQUAL,
OP_BIN_GREATER_THAN_OR_EQUAL,
OP_BIN_PLUS,
OP_BIN_MINUS,
OP_BIN_MULTIPLY,
OP_BIN_DIVIDE,
OP_BIN_PERCENTAGE,
OP_UN_MINUS,
OP_UN_COMPLEMENT,
OP_UN_TARGETNAME,
OP_BOOL_UN_NOT,
OP_VAR_UN_NOT,
OP_UN_CAST_BOOLEAN,
OP_UN_INC,
OP_UN_DEC,
OP_UN_SIZE,
OP_SWITCH,
OP_FUNC,
OP_NOP,
OP_BIN_SHIFT_LEFT,
OP_BIN_SHIFT_RIGHT,
OP_END,
OP_RETURN,
OP_PREVIOUS,
OP_MAX = OP_PREVIOUS
} opcode_e;
const char *VarGroupName( int iVarGroup );
const char *OpcodeName( int opcode );
int OpcodeLength( int opcode );
int OpcodeVarStackOffset( int opcode );
void SetOpcodeVarStackOffset( int opcode, int iVarStackOffset );
bool IsExternalOpcode( int opcode );

View file

@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "weapon.h"
#include "gibs.h"
#include "explosion.h"
#include "game.h"
/*****************************************************************************/
/*QUAKED script_object (0 0.5 1) ? NOT_SOLID

277
code/game/scripttimer.cpp Normal file
View file

@ -0,0 +1,277 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// scripttimer.cpp: Scripted Timer & Fader
//
#include "ScriptTimer.h"
#include "level.h"
#if defined(GAME_DLL)
#include "archive.h"
#endif
Event EV_ScriptTimer_Think
(
"scripttimer_think",
EV_CODEONLY,
NULL,
NULL,
"Internal event",
EV_NORMAL
);
Container< ScriptTimer * > m_scriptTimers;
/*void ScriptTimer::HandleTimer( float frametime )
{
ScriptTimer *timer;
for( int i = 0; i < m_scriptTimers.NumObjects(); i++ )
{
timer = m_scriptTimers[ i ];
if( timer->isEnabled() && timer->GetTime() > 0.0f ) {
timer->Think( frametime );
}
}
}*/
ScriptTimer::ScriptTimer( timertype_e type )
{
Reset();
bEnabled = false;
setType( type );
m_scriptTimers.AddObject( this );
}
ScriptTimer::~ScriptTimer()
{
Disable();
if( m_scriptTimers.IndexOfObject( this ) )
{
m_scriptTimers.RemoveObject( this );
}
}
void ScriptTimer::Archive( Archiver &arc )
{
Listener::Archive( arc );
#ifdef CGAME_DLL
arc.ArchiveFloat( &targetTime );
arc.ArchiveFloat( &currentTime );
arc.ArchiveFloat( &realTime );
arc.ArchiveFloat( &glideRatio );
arc.ArchiveInteger( ( int * )&timerType );
arc.ArchiveBool( &bEnabled );
if( arc.Loading() && bEnabled ) {
Enable();
}
#endif
}
void ScriptTimer::GlideRefresh()
{
if( timerType != TIMER_GLIDE ) {
return;
}
if( targetTime <= 0.0f ){
return;
}
float r = realTime / ( targetTime * 0.5f );
if( r > 1.0f )
{
glideRatio = 2.0f - 2.0f * ( r - 1.0f );
if( glideRatio < 0.0f ) {
glideRatio = 0.0f;
}
}
else
{
glideRatio = 2.0f * r;
if( glideRatio > 2.0f ) {
glideRatio = 2.0f;
}
}
}
void ScriptTimer::Think( Event *ev )
{
if( !bEnabled ) {
return;
}
#ifdef CGAME_DLL
float frametime = ( float )cg->frametime;
#else
float frametime = level.frametime;
#endif
GlideRefresh();
if( currentTime < targetTime )
{
realTime += frametime;
if( timerType == TIMER_GLIDE ) {
currentTime += frametime * glideRatio;
} else {
currentTime += frametime;
}
}
else
{
currentTime = targetTime;
realTime = targetTime;
bEnabled = false;
CancelEventsOfType( &EV_ScriptTimer_Think );
return;
}
CancelEventsOfType( &EV_ScriptTimer_Think );
PostEvent( EV_ScriptTimer_Think, level.frametime );
}
void ScriptTimer::Disable()
{
bEnabled = false;
CancelEventsOfType( &EV_ScriptTimer_Think );
}
void ScriptTimer::Enable()
{
bEnabled = true;
CancelEventsOfType( &EV_ScriptTimer_Think );
Event *ev = new Event( &EV_ScriptTimer_Think );
ProcessEvent( ev );
}
qboolean ScriptTimer::Done()
{
return ( currentTime >= targetTime );
}
float ScriptTimer::GetCurrentTime()
{
return realTime;
}
float ScriptTimer::GetRatio()
{
float ratio;
if( targetTime <= 0.0f ) {
return 1.0f;
}
ratio = ( currentTime / targetTime );
// ratio must not go below 0.0 and above 1.0
return ( ratio < 0.0f ? 0.0f : ratio > 1.0f ? 1.0f : ratio );
}
float ScriptTimer::GetTime()
{
return targetTime;
}
float ScriptTimer::LerpValue( float start, float end )
{
return start + ( end - start ) * GetRatio();
}
Vector ScriptTimer::LerpValue( Vector start, Vector end )
{
return start + ( end - start ) * GetRatio();
}
void ScriptTimer::Reset()
{
currentTime = 0.f;
realTime = 0.f;
glideRatio = 0.f;
}
void ScriptTimer::SetCurrentTime( float time )
{
realTime = time * 1000.0f;
if( timerType == TIMER_GLIDE )
{
GlideRefresh();
currentTime = time * 1000.0f * glideRatio;
}
else
{
currentTime = time * 1000.0f;
}
}
void ScriptTimer::SetPhase( float phase )
{
float t = targetTime * ( phase / 2.0f ) / 1000.0f;
SetCurrentTime( t );
}
void ScriptTimer::SetTime( float time )
{
Reset();
targetTime = time * 1000.0f;
}
bool ScriptTimer::isEnabled()
{
return bEnabled;
}
void ScriptTimer::setType( timertype_e type )
{
timerType = type;
}
CLASS_DECLARATION( Listener, ScriptTimer, NULL )
{
{ &EV_ScriptTimer_Think, &ScriptTimer::Think },
{ NULL, NULL }
};

85
code/game/scripttimer.h Normal file
View file

@ -0,0 +1,85 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// ScriptTimer.cpp: Scripted Timer & Fader
//
#ifndef __SCRIPTTIMER_H__
#define __SCRIPTTIMER_H__
#include "listener.h"
typedef enum timertype_s {
TIMER_NORMAL,
TIMER_GLIDE
} timertype_e;
class ScriptTimer : public Listener
{
private:
float targetTime;
float currentTime;
float realTime;
float glideRatio;
timertype_e timerType;
bool bEnabled;
private:
void GlideRefresh();
public:
CLASS_PROTOTYPE( ScriptTimer );
ScriptTimer( timertype_e type = TIMER_NORMAL );
~ScriptTimer();
#if defined(ARCHIVE_SUPPORTED)
void Archive( Archiver &arc ) override;
#endif
void Think( Event *ev );
void Disable();
void Enable();
qboolean Done();
float GetCurrentTime();
float GetRatio();
float GetTime();
float LerpValue( float start, float end );
Vector LerpValue( Vector start, Vector end );
void Reset();
void SetCurrentTime( float time );
void SetPhase( float phase );
void SetTime( float time );
bool isEnabled();
void setType( timertype_e type );
};
#endif /* __SCRIPTTIMER_H__ */

2353
code/game/scriptvm.cpp Normal file

File diff suppressed because it is too large Load diff

333
code/game/scriptvm.h Normal file
View file

@ -0,0 +1,333 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// scriptvm.h: Script virtual machine interpreter.
#ifndef __SCRIPTVM_H__
#define __SCRIPTVM_H__
#include "listener.h"
#include <gamescript.h>
#include "scriptvariable.h"
#include "con_set.h"
#define MAX_STACK_DEPTH 20 // 9 in mohaa
//#define LOCALSTACK_SIZE 255 // pre-allocated localstack size for each VM
#define MAX_SCRIPTCYCLES 9999 // max cmds
#define STATE_RUNNING 0 // Running
#define STATE_SUSPENDED 1 // Suspended
#define STATE_WAITING 2 // Waiting for something
#define STATE_EXECUTION 3 // Resume to execution
#define STATE_DESTROYED 4 // Pending deletion
#define THREAD_RUNNING 0 // Running
#define THREAD_WAITING 1 // Waiting
#define THREAD_SUSPENDED 2 // Suspended
#define THREAD_CONTEXT_SWITCH 3 // Resume from context switch
// Ley0k: That's the old OpenMOHAA script stuff
// not needed anymore
//
/****************************************************************************************************************************************************************
// IneQuation: MoHAA server-side scripting
// TODO: work on it, it's a stub
// variables
typedef enum {
SVT_INTEGER,
SVT_FLOAT,
SVT_VECTOR,
SVT_STRING,
SVT_ENTITY,
SVT_LISTENER, // for compatibility with the bare Listener MoHAA object which is basically just a data container
SVT_ARRAY
} scriptVariableType_t;
typedef union {
int i;
float f;
char *s;
gentity_t *e;
struct scriptStack_s *l; // for compatibility with the bare Listener MoHAA object which is basically just a data container
struct scriptArray_s *a;
} scriptVariableData_t;
typedef struct scriptArrayElement_s {
scriptVariableData_t data;
struct scriptArrayElement_s *next;
struct scriptArrayElement_s *prev;
} scriptArrayElement_t;
typedef struct scriptArray_s {
int size;
scriptArrayElement_t *first;
} scriptArray_t;
typedef struct scriptVariable_s {
qboolean readonly;
scriptVariableType_t type;
scriptVariableData_t data;
} scriptVariable_t;
// script stack
typedef struct scriptStackVariable_s {
scriptVariable_t var;
struct scriptStackVariable_s *prev;
struct scriptStackVariable_s *next;
} scriptStackVariable_t;
typedef struct scriptStack_s {
int size;
scriptVariable_t *top;
} scriptStack_t;
// compiled script
typedef enum { // what code gets translated into the given instruction
SI_STARTTHREAD, // thread, waitthread, exec, waitexec
SI_TERMINATETHREAD, // end
SI_WAIT, // wait, waitframe
SI_JUMP, // goto, break and continue
SI_CONDITIONALJUMP, // if, for, while, switch
SI_INCR, // ++
SI_DECR, // --
SI_ASSIGN,
SI_EVENT // TODO: this possibly needs expanding into a separate instruction for each event (entity command), need to think the design through
} scriptInstruction_t;
typedef struct scriptStatement_s {
scriptInstruction_t inst;
int numParams;
scriptVariableData_t *params; // malloced at script compilation time
} scriptStatement_t;
typedef struct scriptCompiled_s {
scriptStack_t level;
scriptStack_t parm;
int numStats;
scriptStatement_t *stat;
} scriptCompiled_t;
// script threads
typedef struct scriptThread_s {
scriptVariableData_t object;
scriptStack_t stack;
int pos; // index of the statement we should be executing at this frame
int resumeTime; // execution of thread will stop until level.time >= resumeTime
struct scriptThread_s *next;
struct scriptThread_s *prev;
} scriptThread_t;
typedef struct scriptThreadGroup_s {
scriptStack_t group;
int count;
scriptThread_t *first;
} scriptThreadGroup_t;
****************************************************************************************************************************************************************/
//
//
// End of the old OpenMOHAA script stuff
class ScriptThread;
class ScriptVM;
class ScriptClass : public Listener
{
friend class GameScript;
friend class StateScript;
public:
// script variable
GameScript *m_Script; // current game script
// listener variable
SafePtr<Listener> m_Self; // self
// thread variable
ScriptVM *m_Threads; // threads list
public:
CLASS_PROTOTYPE( ScriptClass );
#ifndef _DEBUG_MEM
void *operator new( size_t size );
void operator delete( void *ptr );
#endif
ScriptClass( GameScript *gameScript, Listener *self );
ScriptClass();
virtual ~ScriptClass();
virtual void Archive( Archiver& arc );
void ArchiveInternal( Archiver& arc );
static void ArchiveScript( Archiver& arc, ScriptClass **obj );
void ArchiveCodePos( Archiver& arc, unsigned char **codePos );
virtual ScriptThread *CreateThreadInternal( const ScriptVariable& label );
virtual ScriptThread *CreateScriptInternal( const ScriptVariable& label );
void AddThread( ScriptVM * m_ScriptVM );
void KillThreads( void );
void RemoveThread( ScriptVM * m_ScriptVM );
str Filename();
unsigned char *FindLabel( str label );
unsigned char *FindLabel( const_str label );
const_str NearestLabel( unsigned char *pos );
StateScript *GetCatchStateScript( unsigned char *in, unsigned char *&out );
GameScript *GetScript();
Listener *GetSelf();
};
class ScriptCallStack {
public:
// opcode variable
unsigned char *codePos; // opcode will be restored once a DONE was hit
// stack variables
ScriptVariable *localStack;
ScriptVariable *pTop;
// return variable
ScriptVariable returnValue;
// OLD self value
SafePtr< Listener > m_Self;
};
// Ley0k: I'm unsure about this class, MOHAA use it
class ScriptStack
{
public:
ScriptVariable *m_Array;
int m_Count;
};
class ScriptVM
{
friend class ScriptThread;
public:
// important thread variables
ScriptVM *next; // next VM in the current ScriptClass
ScriptThread *m_Thread; // script thread
ScriptClass *m_ScriptClass; // current group of threads
public:
// return variables
ScriptStack *m_Stack; // Currently unused
ScriptVariable m_ReturnValue; // VM return value
// opcode variables
unsigned char *m_PrevCodePos; // previous opcode, for use with script exceptions
unsigned char *m_CodePos; // check compiler.h for the list of all opcodes
public:
// states
unsigned char state; // current VM state
unsigned char m_ThreadState; // current thread state
// stack variables
Container< ScriptCallStack * > callStack; // thread's call stack
ScriptVariable *localStack; // thread's local stack
int localStackSize; // dynamically allocated at initialization
ScriptVariable *pTop; // top stack from the local stack
ScriptVariable *m_StackPos; // marked stack position
// parameters variables
ScriptVariable *m_pOldData; // old fastEvent data, to cleanup
int m_OldDataSize;
bool m_bMarkStack; // changed by OP_MARK_STACK_POS and OP_RESTORE_STACK_POS
Event fastEvent; // parameter list, set when the VM is executed
// miscellaneous
bool m_bAllowContextSwitch; // allow parallel VM executions [experimental feature]
private:
void error( const char *format, ... );
void executeCommand( Listener *listener, int iParamCount, int eventnum, bool bReturn = false );
bool executeGetter( Listener *listener, str& name );
bool executeSetter( Listener *listener, str& name );
void jump( int offset );
void jumpBool( int offset, bool value );
void loadTop( Listener *listener, bool noTop = false );
void storeTop( Listener *listener, bool noTop = false );
void SetFastData( ScriptVariable *data, int dataSize );
bool Switch( StateScript *stateScript, ScriptVariable &var );
unsigned char *ProgBuffer();
void HandleScriptException( ScriptException& exc );
public:
#ifndef _DEBUG_MEM
void *operator new( size_t size );
void operator delete( void *ptr );
#endif
ScriptVM( ScriptClass *scriptClass, unsigned char *pCodePos, ScriptThread *thread );
~ScriptVM();
void Archive( Archiver& arc );
void EnterFunction( Event *ev );
void LeaveFunction();
void End( const ScriptVariable& returnValue );
void End( void );
void Execute( ScriptVariable *data = NULL, int dataSize = 0, str label = "" );
void NotifyDelete( void );
void Resume( qboolean bForce = false );
void Suspend( void );
str Filename( void );
str Label( void );
ScriptClass *GetScriptClass( void );
bool IsSuspended( void );
int State( void );
int ThreadState( void );
void EventGoto( Event *ev );
bool EventThrow( Event *ev );
void AllowContextSwitch( bool allow = true );
void RequestContextSwitch();
bool CanScriptTracePrint( void );
};
extern MEM_BlockAlloc< ScriptClass, MEM_BLOCKSIZE > ScriptClass_allocator;
#endif

View file

@ -114,7 +114,6 @@ inline ActiveWeapon::ActiveWeapon
)
{
weapon = NULL;
hand = WEAPON_ERROR;
}
@ -394,7 +393,7 @@ inline void Sentient::ClearNewActiveWeapon
)
{
newActiveWeapon.weapon = NULL;
newActiveWeapon.weapon.Clear();
newActiveWeapon.hand = WEAPON_ERROR;
}

606
code/game/simpleentity.cpp Normal file
View file

@ -0,0 +1,606 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// simpleentity.cpp : Simple entity
#include "glb_local.h"
#include "simpleentity.h"
#include "world.h"
#include "level.h"
Event EV_SimpleEntity_GetAngle
(
"angle",
EV_DEFAULT,
NULL,
NULL,
"get the angles of the entity using just one value.\n"
"Gets the yaw of the entity or an up and down\n"
"direction if newAngle is[ 0 - 359 ] or - 1 or - 2",
EV_GETTER
);
Event EV_SetAngle
(
"angle",
EV_DEFAULT,
"f",
"newAngle",
"set the angles of the entity using just one value.\n"
"Sets the yaw of the entity or an up and down\n"
"direction if newAngle is[ 0 - 359 ] or - 1 or - 2",
EV_NORMAL
);
Event EV_SimpleEntity_SetterAngle
(
"angle",
EV_DEFAULT,
"f",
"newAngle",
"set the angles of the entity using just one value.\n"
"Sets the yaw of the entity or an up and down\n"
"direction if newAngle is[ 0 - 359 ] or - 1 or - 2",
EV_SETTER
);
Event EV_SimpleEntity_GetAngles
(
"angles",
EV_DEFAULT,
NULL,
NULL,
"get the angles of the entity.",
EV_GETTER
);
Event EV_SetAngles
(
"angles",
EV_DEFAULT,
"v[0,360][0,360][0,360]",
"newAngles",
"Set the angles of the entity to newAngles.",
EV_NORMAL
);
Event EV_SimpleEntity_SetterAngles
(
"angles",
EV_DEFAULT,
"v[0,360][0,360][0,360]",
"newAngles",
"Set the angles of the entity to newAngles.",
EV_SETTER
);
Event EV_SimpleEntity_GetOrigin
(
"origin",
EV_DEFAULT,
NULL,
NULL,
"entity's origin",
EV_GETTER
);
Event EV_SetOrigin
(
"origin",
EV_DEFAULT,
"v",
"newOrigin",
"Set the origin of the entity to newOrigin.",
EV_NORMAL
);
Event EV_SimpleEntity_SetterOrigin
(
"origin",
EV_DEFAULT,
"v",
"newOrigin",
"Set the origin of the entity to newOrigin.",
EV_SETTER
);
Event EV_SimpleEntity_GetTargetname
(
"targetname",
EV_DEFAULT,
NULL,
NULL,
"entity's targetname",
EV_GETTER
);
Event EV_SimpleEntity_SetTargetname
(
"targetname",
EV_DEFAULT,
"s",
"targetName",
"set the targetname of the entity to targetName.",
EV_NORMAL
);
Event EV_SimpleEntity_SetterTargetname
(
"targetname",
EV_DEFAULT,
"s",
"targetName",
"set the targetname of the entity to targetName.",
EV_SETTER
);
Event EV_SimpleEntity_GetTarget
(
"target",
EV_DEFAULT,
NULL,
NULL,
"entity's target",
EV_GETTER
);
Event EV_SimpleEntity_SetTarget
(
"target",
EV_DEFAULT,
"s",
"targetname_to_target",
"target another entity with targetname_to_target.",
EV_NORMAL
);
Event EV_SimpleEntity_SetterTarget
(
"target",
EV_DEFAULT,
"s",
"targetname_to_target",
"target another entity with targetname_to_target.",
EV_SETTER
);
Event EV_SimpleEntity_Centroid
(
"centroid",
EV_DEFAULT,
NULL,
NULL,
"entity's centroid",
EV_GETTER
);
Event EV_SimpleEntity_ForwardVector
(
"forwardvector",
EV_DEFAULT,
NULL,
NULL,
"get the forward vector of angles",
EV_GETTER
);
Event EV_SimpleEntity_LeftVector
(
"leftvector",
EV_DEFAULT,
NULL,
NULL,
"get the left vector of angles",
EV_GETTER
);
Event EV_SimpleEntity_RightVector
(
"rightvector",
EV_DEFAULT,
NULL,
NULL,
"get the right vector of angles",
EV_GETTER
);
Event EV_SimpleEntity_UpVector
(
"upvector",
EV_DEFAULT,
NULL,
NULL,
"get the up vector of angles",
EV_GETTER
);
void SimpleEntity::SimpleArchive( Archiver& arc )
{
int index;
Listener::Archive( arc );
arc.ArchiveVector( &angles );
arc.ArchiveString( &target );
arc.ArchiveString( &targetname );
if( targetname.length() )
{
if( arc.Loading() )
{
arc.ArchiveInteger( &index );
world->AddTargetEntityAt( this, index );
}
else
{
index = world->GetTargetnameIndex( this );
arc.ArchiveInteger( &index );
}
}
}
void SimpleEntity::Archive( Archiver& arc )
{
SimpleEntity::SimpleArchive( arc );
arc.ArchiveVector( &origin );
arc.ArchiveVector( &centroid );
}
void SimpleEntity::setOrigin( Vector origin )
{
this->origin = origin;
this->centroid = origin;
}
void SimpleEntity::setOriginEvent( Vector origin )
{
setOrigin( origin );
}
void SimpleEntity::setAngles( Vector angles )
{
this->angles = angles.AnglesMod();
}
SimpleEntity::SimpleEntity()
{
entflags = 0;
}
SimpleEntity::~SimpleEntity()
{
if( world ) {
world->RemoveTargetEntity( this );
}
}
void SimpleEntity::SetTarget( str target )
{
this->target = target;
}
void SimpleEntity::SetTargetName( str targetname )
{
world->RemoveTargetEntity( this );
this->targetname = targetname;
world->AddTargetEntity( this );
}
str& SimpleEntity::Target()
{
return target;
}
str& SimpleEntity::TargetName()
{
return targetname;
}
SimpleEntity *SimpleEntity::Next( void )
{
SimpleEntity *ent = world->GetTarget( target, true );
if( !ent || !ent->isSubclassOf( SimpleEntity ) )
{
return NULL;
}
else
{
return ent;
}
}
void SimpleEntity::EventGetAngle( Event *ev )
{
ev->AddFloat( angles[ 1 ] );
}
void SimpleEntity::EventGetAngles( Event *ev )
{
ev->AddVector( angles );
}
void SimpleEntity::EventGetOrigin( Event *ev )
{
ev->AddVector( origin );
}
void SimpleEntity::EventGetTargetname( Event *ev )
{
ev->AddString( TargetName() );
}
void SimpleEntity::EventGetTarget( Event *ev )
{
ev->AddString( Target() );
}
void SimpleEntity::EventSetAngle( Event *ev )
{
Vector dir;
float angle = ev->GetFloat( 1 );
dir = G_GetMovedir( angle );
dir.toAngles();
setAngles( dir );
}
void SimpleEntity::EventSetAngles( Event *ev )
{
Vector angles;
if( ev->NumArgs() == 1 )
{
angles = ev->GetVector( 1 );
}
else
{
angles = Vector( ev->GetFloat( 1 ), ev->GetFloat( 2 ), ev->GetFloat( 3 ) );
}
setAngles( angles );
}
void SimpleEntity::EventSetOrigin( Event *ev )
{
setOriginEvent( ev->GetVector( 1 ) );
}
void SimpleEntity::EventSetTargetname( Event *ev )
{
SetTargetName( ev->GetString( 1 ) );
}
void SimpleEntity::EventSetTarget( Event *ev )
{
SetTarget( ev->GetString( 1 ) );
}
void SimpleEntity::GetCentroid( Event *ev )
{
ev->AddVector( centroid );
}
void SimpleEntity::GetForwardVector( Event *ev )
{
Vector fwd;
AngleVectorsLeft( angles, fwd, NULL, NULL );
ev->AddVector( fwd );
}
void SimpleEntity::GetLeftVector( Event *ev )
{
Vector left;
AngleVectorsLeft( angles, NULL, left, NULL );
ev->AddVector( left );
}
void SimpleEntity::GetRightVector( Event *ev )
{
Vector right;
AngleVectors( angles, NULL, right, NULL );
ev->AddVector( right );
}
void SimpleEntity::GetUpVector( Event *ev )
{
Vector up;
AngleVectorsLeft( angles, NULL, NULL, up );
ev->AddVector( up );
}
void SimpleEntity::MPrintf( const char *fmt, ... )
{
va_list argptr;
char msg[MAXPRINTMSG];
if (*g_monitor->string == NULL)
{
return;
}
if (targetname == g_monitor->string)
{
va_start(argptr, fmt);
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr);
Com_Printf("%s", msg);
}
}
int SimpleEntity::IsSubclassOfEntity( void ) const
{
return ( entflags & EF_ENTITY );
}
int SimpleEntity::IsSubclassOfAnimate( void ) const
{
return ( entflags & EF_ANIMATE );
}
int SimpleEntity::IsSubclassOfSentient( void ) const
{
return ( entflags & EF_SENTIENT );
}
int SimpleEntity::IsSubclassOfPlayer( void ) const
{
return ( entflags & EF_PLAYER );
}
int SimpleEntity::IsSubclassOfActor( void ) const
{
return ( entflags & EF_ACTOR );
}
int SimpleEntity::IsSubclassOfItem( void ) const
{
return ( entflags & EF_ITEM );
}
int SimpleEntity::IsSubclassOfInventoryItem( void ) const
{
return ( entflags & EF_INVENTORYITEM );
}
int SimpleEntity::IsSubclassOfWeapon( void ) const
{
return ( entflags & EF_WEAPON );
}
int SimpleEntity::IsSubclassOfProjectile( void ) const
{
return ( entflags & EF_PROJECTILE );
}
int SimpleEntity::IsSubclassOfDoor( void ) const
{
return ( entflags & EF_DOOR );
}
int SimpleEntity::IsSubclassOfCamera( void ) const
{
return ( entflags & EF_CAMERA );
}
int SimpleEntity::IsSubclassOfVehicle( void ) const
{
return ( entflags & EF_VEHICLE );
}
int SimpleEntity::IsSubclassOfVehicleTank( void ) const
{
return ( entflags & EF_VEHICLETANK );
}
int SimpleEntity::IsSubclassOfVehicleTurretGun( void ) const
{
return ( entflags & EF_VEHICLETURRET );
}
int SimpleEntity::IsSubclassOfTurretGun( void ) const
{
return ( entflags & EF_TURRET );
}
int SimpleEntity::IsSubclassOfPathNode( void ) const
{
return ( entflags & EF_PATHNODE );
}
int SimpleEntity::IsSubclassOfWaypoint( void ) const
{
return ( entflags & EF_WAYPOINT );
}
int SimpleEntity::IsSubclassOfTempWaypoint( void ) const
{
return ( entflags & EF_TEMPWAYPOINT );
}
int SimpleEntity::IsSubclassOfVehiclePoint( void ) const
{
return ( entflags & EF_VEHICLEPOINT );
}
int SimpleEntity::IsSubclassOfSplinePath( void ) const
{
return ( entflags & EF_SPLINEPATH );
}
int SimpleEntity::IsSubclassOfCrateObject( void ) const
{
return ( entflags & EF_CRATEOBJECT );
}
int SimpleEntity::IsSubclassOfBot( void ) const
{
return ( entflags & EF_BOT );
}
CLASS_DECLARATION( Listener, SimpleEntity, NULL )
{
{ &EV_SimpleEntity_GetAngle, &SimpleEntity::EventGetAngle },
{ &EV_SimpleEntity_GetAngles, &SimpleEntity::EventGetAngles },
{ &EV_SimpleEntity_GetOrigin, &SimpleEntity::EventGetOrigin },
{ &EV_SimpleEntity_GetTargetname, &SimpleEntity::EventGetTargetname },
{ &EV_SimpleEntity_GetTarget, &SimpleEntity::EventGetTarget },
{ &EV_SimpleEntity_SetterAngle, &SimpleEntity::EventSetAngle },
{ &EV_SimpleEntity_SetterAngles, &SimpleEntity::EventSetAngles },
{ &EV_SimpleEntity_SetterOrigin, &SimpleEntity::EventSetOrigin },
{ &EV_SimpleEntity_SetterTargetname, &SimpleEntity::EventSetTargetname },
{ &EV_SimpleEntity_SetterTarget, &SimpleEntity::EventSetTarget },
{ &EV_SetAngle, &SimpleEntity::EventSetAngle },
{ &EV_SetAngles, &SimpleEntity::EventSetAngles },
{ &EV_SetOrigin, &SimpleEntity::EventSetOrigin },
{ &EV_SimpleEntity_SetTargetname, &SimpleEntity::EventSetTargetname },
{ &EV_SimpleEntity_SetTarget, &SimpleEntity::EventSetTarget },
{ &EV_SimpleEntity_Centroid, &SimpleEntity::GetCentroid },
{ &EV_SimpleEntity_ForwardVector, &SimpleEntity::GetForwardVector },
{ &EV_SimpleEntity_LeftVector, &SimpleEntity::GetLeftVector },
{ &EV_SimpleEntity_RightVector, &SimpleEntity::GetRightVector },
{ &EV_SimpleEntity_UpVector, &SimpleEntity::GetUpVector },
{ NULL, NULL }
};
SimpleArchivedEntity::SimpleArchivedEntity()
{
level.m_SimpleArchivedEntities.AddObject( this );
}
SimpleArchivedEntity::~SimpleArchivedEntity()
{
level.m_SimpleArchivedEntities.RemoveObject( this );
}
CLASS_DECLARATION( SimpleEntity, SimpleArchivedEntity, NULL )
{
{ NULL, NULL }
};

130
code/game/simpleentity.h Normal file
View file

@ -0,0 +1,130 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// simpleentity.h: Simple entity.
#ifndef __SIMPLEENTITY_H__
#define __SIMPLEENTITY_H__
#include "listener.h"
extern Event EV_SetAngles;
extern Event EV_SetAngle;
extern Event EV_SetOrigin;
typedef int entflags_t;
class SimpleEntity;
typedef SafePtr< SimpleEntity > SimpleEntityPtr;
class SimpleEntity : public Listener
{
public:
// Base coord variable
Vector origin;
Vector angles;
// Flag (used to set a class flag)
entflags_t entflags;
// Used by scripts
str target;
str targetname;
// Centered origin based on mins/maxs
Vector centroid;
public:
CLASS_PROTOTYPE( SimpleEntity );
SimpleEntity();
virtual ~SimpleEntity();
void SimpleArchive( Archiver& arc );
virtual void Archive( Archiver& arc );
virtual void setOrigin( Vector origin );
virtual void setOriginEvent( Vector origin );
virtual void setAngles( Vector angles );
void SetTarget( str target );
void SetTargetName( str targetname );
str& Target();
str& TargetName();
SimpleEntity *Next( void );
int IsSubclassOfEntity( void ) const;
int IsSubclassOfAnimate( void ) const;
int IsSubclassOfSentient( void ) const;
int IsSubclassOfPlayer( void ) const;
int IsSubclassOfActor( void ) const;
int IsSubclassOfItem( void ) const;
int IsSubclassOfInventoryItem( void ) const;
int IsSubclassOfWeapon( void ) const;
int IsSubclassOfProjectile( void ) const;
int IsSubclassOfDoor( void ) const;
int IsSubclassOfCamera( void ) const;
int IsSubclassOfVehicle( void ) const;
int IsSubclassOfVehicleTank( void ) const;
int IsSubclassOfVehicleTurretGun( void ) const;
int IsSubclassOfTurretGun( void ) const;
int IsSubclassOfPathNode( void ) const;
int IsSubclassOfWaypoint( void ) const;
int IsSubclassOfTempWaypoint( void ) const;
int IsSubclassOfVehiclePoint( void ) const;
int IsSubclassOfSplinePath( void ) const;
int IsSubclassOfCrateObject( void ) const;
int IsSubclassOfBot( void ) const;
void EventGetAngle( Event *ev );
void EventGetAngles( Event *ev );
void EventGetOrigin( Event *ev );
void EventGetTargetname( Event *ev );
void EventGetTarget( Event *ev );
void EventSetAngle( Event *ev );
void EventSetAngles( Event *ev );
void EventSetOrigin( Event *ev );
void EventSetTargetname( Event *ev );
void EventSetTarget( Event *ev );
void GetCentroid( Event *ev );
void GetForwardVector( Event *ev );
void GetLeftVector( Event *ev );
void GetRightVector( Event *ev );
void GetUpVector( Event *ev );
void MPrintf( const char *msg, ... );
};
class SimpleArchivedEntity : public SimpleEntity
{
public:
CLASS_PROTOTYPE( SimpleArchivedEntity );
SimpleArchivedEntity();
virtual ~SimpleArchivedEntity();
};
#endif

442
code/game/slre.c Normal file
View file

@ -0,0 +1,442 @@
/*
* Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
* Copyright (c) 2013 Cesanta Software Limited
* All rights reserved
*
* This library is dual-licensed: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. For the terms of this
* license, see <http://www.gnu.org/licenses/>.
*
* You are free to use this library under the terms of the GNU General
* Public License, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* Alternatively, you can license this library under a commercial
* license, as set out in <http://cesanta.com/products.html>.
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "slre.h"
#define MAX_BRANCHES 100
#define MAX_BRACKETS 100
#define FAIL_IF(condition, error_code) if (condition) return (error_code)
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof((ar)[0]))
#endif
#ifdef SLRE_DEBUG
#define DBG(x) printf x
#else
#define DBG(x)
#endif
struct bracket_pair {
const char *ptr; /* Points to the first char after '(' in regex */
size_t len; /* Length of the text between '(' and ')' */
int branches; /* Index in the branches array for this pair */
unsigned int num_branches; /* Number of '|' in this bracket pair */
};
struct branch {
int bracket_index; /* index for 'struct bracket_pair brackets' */
/* array defined below */
const char *schlong; /* points to the '|' character in the regex */
};
struct regex_info {
/*
* Describes all bracket pairs in the regular expression.
* First entry is always present, and grabs the whole regex.
*/
struct bracket_pair brackets[MAX_BRACKETS];
int num_brackets;
/*
* Describes alternations ('|' operators) in the regular expression.
* Each branch falls into a specific branch pair.
*/
struct branch branches[MAX_BRANCHES];
int num_branches;
/* Array of captures provided by the user */
struct slre_cap *caps;
int num_caps;
/* E.g. SLRE_IGNORE_CASE. See enum below */
int flags;
};
static int is_metacharacter(const unsigned char *s) {
static const char *metacharacters = "^$().[]*+?|\\Ssdbfnrtv";
return strchr(metacharacters, *s) != NULL;
}
static int op_len(const char *re) {
return re[0] == '\\' && re[1] == 'x' ? 4 : re[0] == '\\' ? 2 : 1;
}
static size_t set_len(const char *re, size_t re_len) {
size_t len = 0;
while (len < re_len && re[len] != ']') {
len += op_len(re + len);
}
return len <= re_len ? len + 1 : -1;
}
static size_t get_op_len(const char *re, size_t re_len) {
return re[0] == '[' ? set_len(re + 1, re_len - 1) + 1 : op_len(re);
}
static int is_quantifier(const char *re) {
return re[0] == '*' || re[0] == '+' || re[0] == '?';
}
static int toi(int x) {
return isdigit(x) ? x - '0' : x - 'W';
}
static int hextoi(const unsigned char *s) {
return (toi(tolower(s[0])) << 4) | toi(tolower(s[1]));
}
static int match_op(const unsigned char *re, const unsigned char *s,
struct regex_info *info) {
int result = 0;
switch (*re) {
case '\\':
/* Metacharacters */
switch (re[1]) {
case 'S': FAIL_IF(isspace(*s), SLRE_NO_MATCH); result++; break;
case 's': FAIL_IF(!isspace(*s), SLRE_NO_MATCH); result++; break;
case 'd': FAIL_IF(!isdigit(*s), SLRE_NO_MATCH); result++; break;
case 'b': FAIL_IF(*s != '\b', SLRE_NO_MATCH); result++; break;
case 'f': FAIL_IF(*s != '\f', SLRE_NO_MATCH); result++; break;
case 'n': FAIL_IF(*s != '\n', SLRE_NO_MATCH); result++; break;
case 'r': FAIL_IF(*s != '\r', SLRE_NO_MATCH); result++; break;
case 't': FAIL_IF(*s != '\t', SLRE_NO_MATCH); result++; break;
case 'v': FAIL_IF(*s != '\v', SLRE_NO_MATCH); result++; break;
case 'x':
/* Match byte, \xHH where HH is hexadecimal byte representaion */
FAIL_IF(hextoi(re + 2) != *s, SLRE_NO_MATCH);
result++;
break;
default:
/* Valid metacharacter check is done in bar() */
FAIL_IF(re[1] != s[0], SLRE_NO_MATCH);
result++;
break;
}
break;
case '|': FAIL_IF(1, SLRE_INTERNAL_ERROR); break;
case '$': FAIL_IF(1, SLRE_NO_MATCH); break;
case '.': result++; break;
default:
if (info->flags & SLRE_IGNORE_CASE) {
FAIL_IF(tolower(*re) != tolower(*s), SLRE_NO_MATCH);
} else {
FAIL_IF(*re != *s, SLRE_NO_MATCH);
}
result++;
break;
}
return result;
}
static int match_set(const char *re, size_t re_len, const char *s,
struct regex_info *info) {
size_t len = 0;
int result = -1, invert = re[0] == '^';
if (invert) re++, re_len--;
while (len <= re_len && re[len] != ']' && result <= 0) {
/* Support character range */
if (re[len] != '-' && re[len + 1] == '-' && re[len + 2] != ']' &&
re[len + 2] != '\0') {
result = info->flags & SLRE_IGNORE_CASE ?
tolower(*s) >= tolower(re[len]) && tolower(*s) <= tolower(re[len + 2]) :
*s >= re[len] && *s <= re[len + 2];
len += 3;
} else {
result = match_op((unsigned char *) re + len, (unsigned char *) s, info);
len += op_len(re + len);
}
}
return (!invert && result > 0) || (invert && result <= 0) ? 1 : -1;
}
static size_t doh(const char *s, size_t s_len, struct regex_info *info, int bi);
static size_t bar(const char *re, size_t re_len, const char *s, size_t s_len,
struct regex_info *info, int bi) {
/* i is offset in re, j is offset in s, bi is brackets index */
size_t i, j, n, step;
for (i = j = 0; i < re_len && j <= s_len; i += step) {
/* Handle quantifiers. Get the length of the chunk. */
step = re[i] == '(' ? info->brackets[bi + 1].len + 2 :
get_op_len(re + i, re_len - i);
DBG(("%s [%.*s] [%.*s] re_len=%d step=%d i=%d j=%d\n", __func__,
re_len - i, re + i, s_len - j, s + j, re_len, step, i, j));
FAIL_IF(is_quantifier(&re[i]), SLRE_UNEXPECTED_QUANTIFIER);
FAIL_IF(step <= 0, SLRE_INVALID_CHARACTER_SET);
if (i + step < re_len && is_quantifier(re + i + step)) {
DBG(("QUANTIFIER: [%.*s]%c [%.*s]\n", step, re + i,
re[i + step], s_len - j, s + j));
if (re[i + step] == '?') {
size_t result = bar(re + i, step, s + j, s_len - j, info, bi);
j += result > 0 ? result : 0;
i++;
} else if (re[i + step] == '+' || re[i + step] == '*') {
size_t j2 = j, nj = j, n1, n2 = -1, ni, non_greedy = 0;
/* Points to the regexp code after the quantifier */
ni = i + step + 1;
if (ni < re_len && re[ni] == '?') {
non_greedy = 1;
ni++;
}
do {
if ((n1 = bar(re + i, step, s + j2, s_len - j2, info, bi)) > 0) {
j2 += n1;
}
if (re[i + step] == '+' && n1 < 0) break;
if (ni >= re_len) {
/* After quantifier, there is nothing */
nj = j2;
} else if ((n2 = bar(re + ni, re_len - ni, s + j2,
s_len - j2, info, bi)) >= 0) {
/* Regex after quantifier matched */
nj = j2 + n2;
}
if (nj > j && non_greedy) break;
} while (n1 > 0);
/*
* Even if we found one or more pattern, this branch will be executed,
* changing the next captures.
*/
if (n1 < 0 && n2 < 0 && re[i + step] == '*' &&
(n2 = bar(re + ni, re_len - ni, s + j, s_len - j, info, bi)) > 0) {
nj = j + n2;
}
DBG(("STAR/PLUS END: %d %d %d %d %d\n", j, nj, re_len - ni, n1, n2));
FAIL_IF(re[i + step] == '+' && nj == j, SLRE_NO_MATCH);
/* If while loop body above was not executed for the * quantifier, */
/* make sure the rest of the regex matches */
FAIL_IF(nj == j && ni < re_len && n2 < 0, SLRE_NO_MATCH);
/* Returning here cause we've matched the rest of RE already */
return nj;
}
continue;
}
if (re[i] == '[') {
n = match_set(re + i + 1, re_len - (i + 2), s + j, info);
DBG(("SET %.*s [%.*s] -> %d\n", step, re + i, s_len - j, s + j, n));
FAIL_IF(n <= 0, SLRE_NO_MATCH);
j += n;
} else if (re[i] == '(') {
n = SLRE_NO_MATCH;
bi++;
FAIL_IF(bi >= info->num_brackets, SLRE_INTERNAL_ERROR);
DBG(("CAPTURING [%.*s] [%.*s] [%s]\n",
step, re + i, s_len - j, s + j, re + i + step));
if (re_len - (i + step) <= 0) {
/* Nothing follows brackets */
n = doh(s + j, s_len - j, info, bi);
} else {
size_t j2;
for (j2 = 0; j2 <= s_len - j; j2++) {
if ((n = doh(s + j, s_len - (j + j2), info, bi)) >= 0 &&
bar(re + i + step, re_len - (i + step),
s + j + n, s_len - (j + n), info, bi) >= 0) break;
}
}
DBG(("CAPTURED [%.*s] [%.*s]:%d\n", step, re + i, s_len - j, s + j, n));
FAIL_IF(n < 0, n);
if (info->caps != NULL && n > 0) {
info->caps[bi - 1].ptr = s + j;
info->caps[bi - 1].len = n;
}
j += n;
} else if (re[i] == '^') {
FAIL_IF(j != 0, SLRE_NO_MATCH);
} else if (re[i] == '$') {
FAIL_IF(j != s_len, SLRE_NO_MATCH);
} else {
FAIL_IF(j >= s_len, SLRE_NO_MATCH);
n = match_op((unsigned char *) (re + i), (unsigned char *) (s + j), info);
FAIL_IF(n <= 0, n);
j += n;
}
}
return j;
}
/* Process branch points */
static size_t doh(const char *s, size_t s_len, struct regex_info *info, int bi) {
const struct bracket_pair *b = &info->brackets[bi];
size_t i = 0, len, result;
const char *p;
do {
p = i == 0 ? b->ptr : info->branches[b->branches + i - 1].schlong + 1;
len = b->num_branches == 0 ? b->len :
i == b->num_branches ? (b->ptr + b->len - p) :
(info->branches[b->branches + i].schlong - p);
DBG(("%s %d %d [%.*s] [%.*s]\n", __func__, bi, i, len, p, s_len, s));
result = bar(p, len, s, s_len, info, bi);
DBG(("%s <- %d\n", __func__, result));
} while (result <= 0 && i++ < b->num_branches); /* At least 1 iteration */
return result;
}
static size_t baz(const char *s, size_t s_len, struct regex_info *info) {
size_t i;
int is_anchored = info->brackets[0].ptr[0] == '^';
size_t result = -1;
for (i = 0; i <= s_len; i++) {
result = doh(s + i, s_len - i, info, 0);
if (result >= 0) {
result += i;
break;
}
if (is_anchored) break;
}
return result;
}
static void setup_branch_points(struct regex_info *info) {
int i, j;
struct branch tmp;
/* First, sort branches. Must be stable, no qsort. Use bubble algo. */
for (i = 0; i < info->num_branches; i++) {
for (j = i + 1; j < info->num_branches; j++) {
if (info->branches[i].bracket_index > info->branches[j].bracket_index) {
tmp = info->branches[i];
info->branches[i] = info->branches[j];
info->branches[j] = tmp;
}
}
}
/*
* For each bracket, set their branch points. This way, for every bracket
* (i.e. every chunk of regex) we know all branch points before matching.
*/
for (i = j = 0; i < info->num_brackets; i++) {
info->brackets[i].num_branches = 0;
info->brackets[i].branches = j;
while (j < info->num_branches && info->branches[j].bracket_index == i) {
info->brackets[i].num_branches++;
j++;
}
}
}
static size_t foo(const char *re, size_t re_len, const char *s, size_t s_len,
struct regex_info *info) {
size_t i;
size_t step;
int depth = 0;
/* First bracket captures everything */
info->brackets[0].ptr = re;
info->brackets[0].len = re_len;
info->num_brackets = 1;
/* Make a single pass over regex string, memorize brackets and branches */
for (i = 0; i < re_len; i += step) {
step = get_op_len(re + i, re_len - i);
if (re[i] == '|') {
FAIL_IF(info->num_branches >= (int) ARRAY_SIZE(info->branches),
SLRE_TOO_MANY_BRANCHES);
info->branches[info->num_branches].bracket_index =
info->brackets[info->num_brackets - 1].len == -1 ?
info->num_brackets - 1 : depth;
info->branches[info->num_branches].schlong = &re[i];
info->num_branches++;
} else if (re[i] == '\\') {
FAIL_IF(i >= re_len - 1, SLRE_INVALID_METACHARACTER);
if (re[i + 1] == 'x') {
/* Hex digit specification must follow */
FAIL_IF(re[i + 1] == 'x' && i >= re_len - 3,
SLRE_INVALID_METACHARACTER);
FAIL_IF(re[i + 1] == 'x' && !(isxdigit(re[i + 2]) &&
isxdigit(re[i + 3])), SLRE_INVALID_METACHARACTER);
} else {
FAIL_IF(!is_metacharacter((unsigned char *) re + i + 1),
SLRE_INVALID_METACHARACTER);
}
} else if (re[i] == '(') {
FAIL_IF(info->num_brackets >= (int) ARRAY_SIZE(info->brackets),
SLRE_TOO_MANY_BRACKETS);
depth++; /* Order is important here. Depth increments first. */
info->brackets[info->num_brackets].ptr = re + i + 1;
info->brackets[info->num_brackets].len = -1;
info->num_brackets++;
FAIL_IF(info->num_caps > 0 && info->num_brackets - 1 > info->num_caps,
SLRE_CAPS_ARRAY_TOO_SMALL);
} else if (re[i] == ')') {
int ind = info->brackets[info->num_brackets - 1].len == -1 ?
info->num_brackets - 1 : depth;
info->brackets[ind].len = (int) (&re[i] - info->brackets[ind].ptr);
DBG(("SETTING BRACKET %d [%.*s]\n",
ind, info->brackets[ind].len, info->brackets[ind].ptr));
depth--;
FAIL_IF(depth < 0, SLRE_UNBALANCED_BRACKETS);
FAIL_IF(i > 0 && re[i - 1] == '(', SLRE_NO_MATCH);
}
}
FAIL_IF(depth != 0, SLRE_UNBALANCED_BRACKETS);
setup_branch_points(info);
return baz(s, s_len, info);
}
size_t slre_match(const char *regexp, const char *s, size_t s_len,
struct slre_cap *caps, int num_caps, int flags) {
struct regex_info info;
/* Initialize info structure */
info.flags = flags;
info.num_brackets = info.num_branches = 0;
info.num_caps = num_caps;
info.caps = caps;
DBG(("========================> [%s] [%.*s]\n", regexp, s_len, s));
return foo(regexp, strlen(regexp), s, s_len, &info);
}

60
code/game/slre.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
* Copyright (c) 2013 Cesanta Software Limited
* All rights reserved
*
* This library is dual-licensed: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. For the terms of this
* license, see <http://www.gnu.org/licenses/>.
*
* You are free to use this library under the terms of the GNU General
* Public License, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* Alternatively, you can license this library under a commercial
* license, as set out in <http://cesanta.com/products.html>.
*/
/*
* This is a regular expression library that implements a subset of Perl RE.
* Please refer to README.md for a detailed reference.
*/
#ifndef SLRE_HEADER_DEFINED
#define SLRE_HEADER_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
struct slre_cap {
const char *ptr;
size_t len;
};
size_t slre_match(const char *regexp, const char *buf, size_t buf_len,
struct slre_cap *caps, int num_caps, int flags);
/* Possible flags for slre_match() */
enum { SLRE_IGNORE_CASE = 1 };
/* slre_match() failure codes */
#define SLRE_NO_MATCH -1
#define SLRE_UNEXPECTED_QUANTIFIER -2
#define SLRE_UNBALANCED_BRACKETS -3
#define SLRE_INTERNAL_ERROR -4
#define SLRE_INVALID_CHARACTER_SET -5
#define SLRE_INVALID_METACHARACTER -6
#define SLRE_CAPS_ARRAY_TOO_SMALL -7
#define SLRE_TOO_MANY_BRANCHES -8
#define SLRE_TOO_MANY_BRACKETS -9
#ifdef __cplusplus
}
#endif
#endif /* SLRE_HEADER_DEFINED */

View file

@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#include "spawners.h"
#include "game.h"
Event EV_Spawn_ModelName
(

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "specialfx.h"
#include "level.h"
/*****************************************************************************/
/*QUAKED func_fulcrum (0 0 1) ? X_AXIS_ONLY Y_AXIS_ONLY

View file

@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "animate.h"
#include "viewthing.h"
#include "game.h"
#include "level.h"
Event EV_ViewThing_Think
(

View file

@ -39,6 +39,7 @@ extern Event EV_Projectile_Explode;
extern Event EV_Projectile_UpdateBeam;
class Weapon;
class Sentient;
class Projectile : public Animate
{

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
#include "windows.h"
#include "game.h"
Event EV_Window_Setup
(

609
code/game/world.cpp Normal file
View file

@ -0,0 +1,609 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// world.cpp : Holds the target list, and general info (fog and such).
#include "world.h"
#include "level.h"
#include <scriptmaster.h>
#ifdef GAME_DLL
#include "../game/soundman.h"
#endif
WorldPtr world;
Event EV_World_MapTime
(
"map_time",
EV_DEFAULT,
"i",
"version",
"Internal usage."
);
Event EV_World_SetSoundtrack
(
"soundtrack",
EV_DEFAULT,
"s",
"MusicFile",
"Set music soundtrack for this level."
);
Event EV_World_SetGravity
(
"gravity",
EV_DEFAULT,
"f",
"worldGravity",
"Set the gravity for the whole world."
);
Event EV_World_SetNextMap
(
"nextmap",
EV_DEFAULT,
"s",
"nextMap",
"Set the next map to change to"
);
Event EV_World_SetMessage
(
"message",
EV_DEFAULT,
"s",
"worldMessage",
"Set a message for the world"
);
Event EV_World_SetWaterColor
(
"watercolor",
EV_DEFAULT,
"v",
"waterColor",
"Set the watercolor screen blend"
);
Event EV_World_SetWaterAlpha
(
"wateralpha",
EV_DEFAULT,
"f",
"waterAlpha",
"Set the alpha of the water screen blend"
);
Event EV_World_SetLavaColor
(
"lavacolor",
EV_DEFAULT,
"v",
"lavaColor",
"Set the color of lava screen blend"
);
Event EV_World_SetLavaAlpha
(
"lavaalpha",
EV_DEFAULT,
"f",
"lavaAlpha",
"Set the alpha of lava screen blend"
);
Event EV_World_SetFarPlane_Color
(
"farplane_color",
EV_DEFAULT,
"v",
"farplaneColor",
"Set the color of the far clipping plane fog"
);
Event EV_World_SetFarPlane_Cull
(
"farplane_cull",
EV_DEFAULT,
"b",
"farplaneCull",
"Whether or not the far clipping plane should cull things out of the world"
);
Event EV_World_SetFarPlane
(
"farplane",
EV_DEFAULT,
"f",
"farplaneDistance",
"Set the distance of the far clipping plane"
);
Event EV_World_SetAmbientLight
(
"ambientlight",
EV_DEFAULT,
"b",
"ambientLight",
"Set whether or not ambient light should be used"
);
Event EV_World_SetAmbientIntensity
(
"ambient",
EV_DEFAULT,
"f",
"ambientIntensity",
"Set the intensity of the ambient light"
);
Event EV_World_SetSunColor
(
"suncolor",
EV_DEFAULT,
"v",
"sunColor",
"Set the color of the sun"
);
Event EV_World_SetSunLight
(
"sunlight",
EV_DEFAULT,
"b",
"sunlight",
"Set whether or not there should be sunlight"
);
Event EV_World_SetSunDirection
(
"sundirection",
EV_DEFAULT,
"v",
"sunlightDirection",
"Set the direction of the sunlight"
);
Event EV_World_LightmapDensity
(
"lightmapdensity",
EV_DEFAULT,
"f",
"density",
"Set the default lightmap density for all world surfaces"
);
Event EV_World_SunFlare
(
"sunflare",
EV_DEFAULT,
"v",
"position_of_sun",
"Set the position of the sun for the purposes of the sunflare"
);
Event EV_World_SunFlareInPortalSky
(
"sunflare_inportalsky",
EV_DEFAULT,
NULL,
NULL,
"Let the renderer know that the sun is in the portal sky"
);
Event EV_World_SetSkyAlpha
(
"skyalpha",
EV_DEFAULT,
"f",
"newAlphaForPortalSky",
"Set the alpha on the sky"
);
Event EV_World_SetSkyPortal
(
"skyportal",
EV_DEFAULT,
"b",
"newSkyPortalState",
"Whether or not to use the sky portal at all"
);
Event EV_World_SetNorthYaw
(
"northyaw",
EV_DEFAULT,
"f",
"yaw",
"Sets the yaw direction that is considered to be north"
);
Event EV_World_SetSunDiffuse
(
"sundiffuse",
EV_DEFAULT,
"f",
"factor",
"Sets the fraction of the sunlight to use for diffuse sun"
);
Event EV_World_SetSunDiffuseColor
(
"sundiffusecolor",
EV_DEFAULT,
"v",
"diffusecolor",
"Sets an alternate sun color to use for clcing diffuse sun"
);
void World::AddTargetEntity( SimpleEntity *ent )
{
str targetname = ent->TargetName();
if( !targetname.length() )
{
return;
}
ConSimple* list = GetTargetList( targetname );
list->AddObject( ent );
}
void World::AddTargetEntityAt( SimpleEntity *ent, int index )
{
str targetname = ent->TargetName();
if( !targetname.length() )
{
return;
}
ConSimple* list = GetTargetList( targetname );
list->AddObjectAt( index, ent );
}
void World::RemoveTargetEntity( SimpleEntity *ent )
{
str targetname = ent->TargetName();
if( !targetname.length() )
{
return;
}
ConSimple* list = GetExistingTargetList( targetname );
if( list )
{
list->RemoveObject( ent );
if( list->NumObjects() <= 0 )
{
m_targetList.remove( Director.AddString( targetname ) );
}
}
}
void World::FreeTargetList()
{
m_targetList.clear();
}
SimpleEntity *World::GetNextEntity( str targetname, SimpleEntity *ent )
{
return GetNextEntity( Director.AddString( targetname ), ent );
}
SimpleEntity *World::GetNextEntity( const_str targetname, SimpleEntity *ent )
{
ConSimple* list = GetTargetList( targetname );
int index;
if( ent )
{
index = list->IndexOfObject( ent ) + 1;
}
else
{
index = 1;
}
if( list->NumObjects() >= index )
{
return list->ObjectAt( index );
}
else
{
return NULL;
}
}
SimpleEntity *World::GetScriptTarget( str targetname )
{
return GetScriptTarget( Director.AddString( targetname ) );
}
SimpleEntity *World::GetScriptTarget( const_str targetname )
{
ConSimple* list = GetTargetList( targetname );
if( list->NumObjects() == 1 )
{
return list->ObjectAt( 1 );
}
else if( list->NumObjects() > 1 )
{
ScriptError( "There are %d entities with targetname '%s'. You are using a command that requires exactly one.", list->NumObjects(), Director.GetString( targetname ).c_str() );
}
return NULL;
}
SimpleEntity *World::GetTarget( str targetname, bool quiet )
{
return GetTarget( Director.AddString( targetname ), quiet );
}
SimpleEntity *World::GetTarget( const_str targetname, bool quiet )
{
ConSimple* list = GetTargetList( targetname );
if( list->NumObjects() == 1 )
{
return list->ObjectAt( 1 );
}
else if( list->NumObjects() > 1 )
{
if( !quiet ) {
warning( "World::GetTarget", "There are %d entities with targetname '%s'. You are using a command that requires exactly one.", list->NumObjects(), Director.GetString( targetname ).c_str() );
}
}
return NULL;
}
int World::GetTargetnameIndex( SimpleEntity *ent )
{
ConSimple* list = GetTargetList( ent->TargetName() );
return list->IndexOfObject( ent );
}
ConSimple *World::GetExistingTargetList( const str& targetname )
{
return GetExistingTargetList( Director.AddString( targetname ) );
}
ConSimple *World::GetExistingTargetList( const_str targetname )
{
return m_targetList.findKeyValue( targetname );
}
ConSimple *World::GetTargetList( str& targetname )
{
return GetTargetList( Director.AddString( targetname ) );
}
ConSimple *World::GetTargetList( const_str targetname )
{
return &m_targetList.addKeyValue( targetname );
}
#ifdef GAME_DLL
World::World()
{
world = this;
world_dying = qfalse;
// Anything that modifies configstrings, or spawns things is ignored when loading savegames
if( LoadingSavegame )
{
return;
}
assert( entnum == ENTITYNUM_WORLD );
setMoveType( MOVETYPE_NONE );
setSolidType( SOLID_BSP );
// world model is always index 1
edict->s.modelindex = 1;
model = "*1";
UpdateConfigStrings();
// clear out the soundtrack from the last level
ChangeSoundtrack( "" );
// set the default gravity
gi.Cvar_Set( "sv_gravity", "800" );
// set the default farplane parameters
farplane_distance = 0;
farplane_color = "0 0 0";
farplane_cull = qtrue;
UpdateFog();
sky_portal = qtrue;
UpdateSky();
m_fAIVisionDistance = 2048.0f;
level.cinematic = spawnflags & WORLD_CINEMATIC;
if( level.cinematic )
gi.Cvar_Set( "sv_cinematic", "1" );
else
gi.Cvar_Set( "sv_cinematic", "0" );
level.nextmap = "";
level.level_name = level.mapname;
SoundMan.Load();
// Set the color for the blends.
level.water_color = Vector( 0, 0, 1 );
level.water_alpha = 0.1f;
level.lava_color = Vector( 1.0f, 0.3f, 0 );
level.lava_alpha = 0.6f;
//
// set the targetname of the world
//
SetTargetName( "world" );
m_fNorth = 0;
}
void World::UpdateConfigStrings( void )
{
//
// make some data visible to connecting client
//
gi.SetConfigstring( CS_GAME_VERSION, GAME_VERSION );
gi.SetConfigstring( CS_LEVEL_START_TIME, va( "%i", level.svsStartTime ) );
// make some data visible to the server
gi.SetConfigstring( CS_MESSAGE, level.level_name.c_str() );
};
void World::UpdateFog( void )
{
gi.SetFarPlane( farplane_distance );
gi.SetConfigstring( CS_FOGINFO, va( "%d %.0f %.4f %.4f %.4f", farplane_cull, farplane_distance, farplane_color.x, farplane_color.y, farplane_color.z ) );
}
void World::UpdateSky( void )
{
gi.SetSkyPortal( sky_portal );
gi.SetConfigstring( CS_SKYINFO, va( "%.4f %d", sky_alpha, sky_portal ) );
}
void World::SetSoundtrack( Event *ev )
{
const char *text;
text = ev->GetString( 1 );
ChangeSoundtrack( text );
}
void World::SetGravity( Event *ev )
{
gi.Cvar_Set( "sv_gravity", ev->GetString( 1 ) );
}
void World::SetFarPlane( Event *ev )
{
farplane_distance = ev->GetFloat( 1 );
UpdateFog();
}
void World::SetFarPlane_Color( Event *ev )
{
farplane_color = ev->GetVector( 1 );
UpdateFog();
}
void World::SetFarPlane_Cull( Event *ev )
{
farplane_cull = ev->GetBoolean( 1 );
UpdateFog();
}
void World::SetSkyAlpha( Event *ev )
{
sky_alpha = ev->GetFloat( 1 );
UpdateSky();
}
void World::SetSkyPortal( Event *ev )
{
sky_portal = ev->GetBoolean( 1 );
UpdateSky();
}
void World::SetNextMap( Event *ev )
{
level.nextmap = ev->GetString( 1 );
}
void World::SetMessage( Event *ev )
{
const char *text;
text = ev->GetString( 1 );
level.level_name = text;
gi.SetConfigstring( CS_MESSAGE, text );
}
void World::SetWaterColor( Event *ev )
{
level.water_color = ev->GetVector( 1 );
}
void World::SetWaterAlpha( Event *ev )
{
level.water_alpha = ev->GetFloat( 1 );
}
void World::SetLavaColor( Event *ev )
{
level.lava_color = ev->GetVector( 1 );
}
void World::SetLavaAlpha( Event *ev )
{
level.lava_alpha = ev->GetFloat( 1 );
}
void World::SetNorthYaw( Event *ev )
{
m_fNorth = anglemod( ev->GetFloat( 1 ) );
}
CLASS_DECLARATION( Entity, World, "worldspawn" )
{
{ &EV_World_SetSoundtrack, &World::SetSoundtrack },
{ &EV_World_SetGravity, &World::SetGravity },
{ &EV_World_SetNextMap, &World::SetNextMap },
{ &EV_World_SetMessage, &World::SetMessage },
{ &EV_World_SetWaterColor, &World::SetWaterColor },
{ &EV_World_SetWaterAlpha, &World::SetWaterAlpha },
{ &EV_World_SetLavaColor, &World::SetLavaColor },
{ &EV_World_SetLavaAlpha, &World::SetLavaAlpha },
{ &EV_World_SetFarPlane_Color, &World::SetFarPlane_Color },
{ &EV_World_SetFarPlane_Cull, &World::SetFarPlane_Cull },
{ &EV_World_SetFarPlane, &World::SetFarPlane },
{ &EV_World_SetSkyAlpha, &World::SetSkyAlpha },
{ &EV_World_SetSkyPortal, &World::SetSkyPortal },
{ &EV_World_SetNorthYaw, &World::SetNorthYaw },
{ &EV_World_SetAmbientLight, NULL },
{ &EV_World_SetAmbientIntensity, NULL },
{ &EV_World_SetSunColor, NULL },
{ &EV_World_SetSunLight, NULL },
{ &EV_World_SetSunDirection, NULL },
{ &EV_World_LightmapDensity, NULL },
{ &EV_World_SunFlare, NULL },
{ &EV_World_SunFlareInPortalSky, NULL },
{ &EV_World_SetSunDiffuse, NULL },
{ &EV_World_SetSunDiffuseColor, NULL },
{ NULL, NULL }
};
#else
World::World()
{
world = this;
world_dying = qfalse;
}
CLASS_DECLARATION( SimpleEntity, World, "worldspawn" )
{
{ NULL, NULL }
};
#endif

111
code/game/world.h Normal file
View file

@ -0,0 +1,111 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// world.h: Global world information (fog and such).
#ifndef __WORLD_H__
#define __WORLD_H__
#if defined ( CGAME_DLL )
#include "../cgame_hook/script/centity.h"
#elif defined ( GAME_DLL )
#include "entity.h"
#else
#include "glb_local.h"
#include "simpleentity.h"
#endif
#include <gamescript.h>
#define WORLD_CINEMATIC 1
typedef Container< SafePtr< SimpleEntity > > ConSimple;
#if defined ( GAME_DLL ) || defined ( CGAME_DLL )
class World : public Entity {
#else
class World : public SimpleEntity {
#endif
con_set < const_str, ConSimple > m_targetList; // moh could have used con_set instead of TargetList
qboolean world_dying;
public:
// farplane variables
float farplane_distance;
Vector farplane_color;
qboolean farplane_cull;
// sky variables
float sky_alpha;
qboolean sky_portal;
// orientation variables
float m_fAIVisionDistance;
float m_fNorth;
public:
CLASS_PROTOTYPE( World );
World();
void AddTargetEntity( SimpleEntity *ent );
void AddTargetEntityAt( SimpleEntity *ent, int index );
void RemoveTargetEntity( SimpleEntity *ent );
void FreeTargetList();
SimpleEntity *GetNextEntity( str targetname, SimpleEntity *ent );
SimpleEntity *GetNextEntity( const_str targetname, SimpleEntity *ent );
SimpleEntity *GetScriptTarget( str targetname );
SimpleEntity *GetScriptTarget( const_str targetname );
SimpleEntity *GetTarget( str targetname, bool quiet );
SimpleEntity *GetTarget( const_str targetname, bool quiet );
int GetTargetnameIndex( SimpleEntity *ent );
ConSimple *GetExistingTargetList( const str& targetname );
ConSimple *GetExistingTargetList( const_str targetname );
ConSimple *GetTargetList( str& targetname );
ConSimple *GetTargetList( const_str targetname );
void SetSoundtrack( Event *ev );
void SetGravity( Event *ev );
void SetNextMap( Event *ev );
void SetMessage( Event *ev );
void SetWaterColor( Event *ev );
void SetWaterAlpha( Event *ev );
void SetLavaColor( Event *ev );
void SetLavaAlpha( Event *ev );
void SetFarPlane_Color( Event *ev );
void SetFarPlane_Cull( Event *ev );
void SetFarPlane( Event *ev );
void SetSkyAlpha( Event *ev );
void SetSkyPortal( Event *ev );
void SetNorthYaw( Event *ev );
void UpdateConfigStrings( void );
void UpdateFog( void );
void UpdateSky( void );
};
typedef SafePtr< World > WorldPtr;
extern WorldPtr world;
#endif /* __WORLD_H__ */