11 Jan 2009

This commit is contained in:
g-cont 2009-01-11 00:00:00 +03:00 committed by Alibek Omarov
parent df6f03c2ba
commit dff851cc74
15 changed files with 287 additions and 157 deletions

View File

@ -629,6 +629,8 @@ public:
// user messages
int _cdecl MsgFunc_Damage( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf);
int _cdecl MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf );

View File

@ -22,10 +22,12 @@
// CHud message handlers
DECLARE_HUDMESSAGE( HUDColor );
DECLARE_HUDMESSAGE( SetFog );
DECLARE_HUDMESSAGE( RoomType );
DECLARE_HUDMESSAGE( SetSky );
DECLARE_HUDMESSAGE( RainData );
DECLARE_HUDMESSAGE( SetBody );
DECLARE_HUDMESSAGE( SetSkin );
DECLARE_HUDMESSAGE( ScreenFade );
DECLARE_HUDMESSAGE( WeaponAnim );
DECLARE_HUDMESSAGE( ResetHUD );
DECLARE_HUDMESSAGE( InitHUD );
@ -51,6 +53,7 @@ int CHud :: InitMessages( void )
HOOK_MESSAGE( InitHUD );
HOOK_MESSAGE( ViewMode );
HOOK_MESSAGE( Concuss );
HOOK_MESSAGE( RoomType );
HOOK_MESSAGE( HUDColor );
HOOK_MESSAGE( Particle );
HOOK_MESSAGE( TempEntity );
@ -64,6 +67,7 @@ int CHud :: InitMessages( void )
HOOK_MESSAGE( AddMirror);
HOOK_MESSAGE( AddScreen );
HOOK_MESSAGE( AddPortal );
HOOK_MESSAGE( ScreenFade );
HOOK_MESSAGE( ScreenShake );
viewEntityIndex = 0; // trigger_viewset stuff
@ -389,6 +393,18 @@ int CHud::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
return 1;
}
int CHud :: MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf )
{
// FIXME: needs callback to sound engine
return 1;
}
int CHud :: MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf )
{
// FIXME: implement
return 1;
}
int CHud::MsgFunc_ScreenShake( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );

View File

@ -219,6 +219,7 @@ typedef struct
DLL_FUNCTIONS dllFuncs; // dll exported funcs
byte *mempool; // edicts pool
byte *private; // server.dll private pool
byte *temppool; // for parse, save and restore edicts
// library exports table
word *ordinals;
@ -384,6 +385,7 @@ void SV_CopyTraceToGlobal( trace_t *trace );
void SV_CopyTraceResult( TraceResult *out, trace_t trace );
float SV_AngleMod( float ideal, float current, float speed );
void SV_SpawnEntities( const char *mapname, script_t *entities );
edict_t* SV_AllocPrivateData( edict_t *ent, string_t className );
string_t SV_AllocString( const char *szValue );
const char *SV_GetString( string_t iString );

View File

@ -557,8 +557,11 @@ void SV_SetModel( edict_t *ent, const char *name )
break;
}
Matrix3x3_FromAngles( angles, ent->v.m_pmatrix );
Matrix3x3_Transpose( ent->v.m_pmatrix, ent->v.m_pmatrix );
if( !sv.loadgame )
{
Matrix3x3_FromAngles( angles, ent->v.m_pmatrix );
Matrix3x3_Transpose( ent->v.m_pmatrix, ent->v.m_pmatrix );
}
SV_CreatePhysBody( ent );
}
@ -696,6 +699,39 @@ edict_t *SV_AllocEdict( void )
return pEdict;
}
edict_t* SV_AllocPrivateData( edict_t *ent, string_t className )
{
const char *pszClassName;
LINK_ENTITY_FUNC SpawnEdict;
pszClassName = STRING( className );
if( !ent ) ent = SV_AllocEdict();
else if( ent->free ) SV_InitEdict( ent ); // FIXME
ent->v.classname = className;
ent->v.pContainingEntity = ent; // re-link
// allocate edict private memory (passed by dlls)
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName );
if( !SpawnEdict )
{
// attempt to create custom entity
if( svgame.dllFuncs.pfnCreate( ent, pszClassName ) == -1 )
{
ent->v.flags |= FL_KILLME;
MsgDev( D_ERROR, "No spawn function for %s\n", pszClassName );
return ent; // this edict will be removed from map
}
}
else SpawnEdict( &ent->v );
Com_Assert( ent->pvServerData == NULL )
// also register classname to send for client
ent->pvServerData->s.classname = SV_ClassIndex( pszClassName );
return ent;
}
void SV_FreeEdicts( void )
{
int i;
@ -1265,31 +1301,7 @@ pfnCreateNamedEntity
*/
edict_t* pfnCreateNamedEntity( string_t className )
{
edict_t *ent;
const char *pszClassName;
LINK_ENTITY_FUNC SpawnEdict;
pszClassName = STRING( className );
ent = pfnCreateEntity();
ent->v.classname = className;
// allocate edict private memory (passed by dlls)
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName );
if( !SpawnEdict )
{
// attempt to create custom entity
if( svgame.dllFuncs.pfnCreate( ent, pszClassName ) == -1 )
{
MsgDev( D_ERROR, "No spawn function for %s\n", pszClassName );
return ent; // this edict needs to be alloced pvPrivateData
}
}
else SpawnEdict( &ent->v );
// also register classname to send for client
ent->pvServerData->s.classname = SV_ClassIndex( pszClassName );
return ent;
return SV_AllocPrivateData( NULL, className );
}
/*
@ -2818,11 +2830,9 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
KeyValueData pkvd[256]; // per one entity
int i, numpairs = 0;
const char *classname = NULL;
LINK_ENTITY_FUNC SpawnEdict;
byte *tempstr;
token_t token;
tempstr = Mem_AllocPool( "SV Temp Strings" );
svgame.temppool = Mem_AllocPool( "SV Temp Strings" );
// go through all the dictionary pairs
while( 1 )
@ -2848,8 +2858,8 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
// create keyvalue strings
pkvd[numpairs].szClassName = (char *)classname; // unknown at this moment
pkvd[numpairs].szKeyName = com.stralloc( tempstr, keyname, __FILE__, __LINE__ );
pkvd[numpairs].szValue = com.stralloc( tempstr, token.string, __FILE__, __LINE__ );
pkvd[numpairs].szKeyName = com.stralloc( svgame.temppool, keyname, __FILE__, __LINE__ );
pkvd[numpairs].szValue = com.stralloc( svgame.temppool, token.string, __FILE__, __LINE__ );
pkvd[numpairs].fHandled = false;
if( !com.strcmp( keyname, "classname" ) && classname == NULL )
@ -2857,33 +2867,15 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
if( ++numpairs >= 256 ) break;
}
// allocate edict private memory (passed by dlls)
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, classname );
if( !SpawnEdict )
{
// attempt to create custom entity
if( svgame.dllFuncs.pfnCreate( ent, classname ) == -1 )
{
MsgDev( D_ERROR, "No spawn function for %s\n", classname );
Mem_FreePool( &tempstr );
return false;
}
}
else
{
ent->v.classname = MAKE_STRING( classname );
SpawnEdict( &ent->v );
}
ent = SV_AllocPrivateData( ent, MAKE_STRING( classname ));
// apply classname to keyvalue containers and parse fields
ent->pvServerData->s.classname = SV_ClassIndex( classname );
for( i = 0; i < numpairs; i++ )
{
if( pkvd[i].fHandled ) continue;
pkvd[i].szClassName = (char *)classname;
svgame.dllFuncs.pfnKeyValue( ent, &pkvd[i] );
}
Mem_FreePool( &tempstr );
Mem_FreePool( &svgame.temppool );
return true;
}

View File

@ -57,40 +57,51 @@ static TYPEDESCRIPTION gETable[] =
DEFINE_FIELD( ENTITYTABLE, classname, FIELD_STRING ),
};
// TEST
uint HashString( const char *pszToken )
// FIXME: implement _rotr into Xash::stdlib
static uint SV_HashString( const char *pszToken )
{
uint hash = 0;
uint hash = 0;
while( *pszToken )
hash = _rotr( hash, 4 ) ^ *pszToken++;
return hash;
}
word TokenHash( const char *pszToken, const char **pTokens, uint tokenCount )
static word SV_TokenHash( const char *pszToken )
{
word hash = (word)(HashString( pszToken ) % (uint)tokenCount );
int i, index;
word hash;
int i, index;
for( i = 0; i < tokenCount; i++ )
// only valid if SAVERESTOREDATA have been initialized
if( !svgame.SaveData.pTokens || !svgame.SaveData.tokenCount ) return 0;
hash = (word)(SV_HashString( pszToken ) % (uint)svgame.SaveData.tokenCount );
for( i = 0; i < svgame.SaveData.tokenCount; i++ )
{
index = hash + i;
if( index >= tokenCount )
index -= tokenCount;
if( index >= svgame.SaveData.tokenCount )
index -= svgame.SaveData.tokenCount;
if( !pTokens[index] || !com.strcmp( pszToken, pTokens[index] ))
if( !svgame.SaveData.pTokens[index] || !com.strcmp( pszToken, svgame.SaveData.pTokens[index] ))
{
pTokens[index] = (char *)pszToken;
svgame.SaveData.pTokens[index] = (char *)pszToken;
return index;
}
}
// Token hash table full!!!
// [Consider doing overflow table(s) after the main table & limiting linear hash table search]
MsgDev( D_ERROR, "CSaveRestoreBuffer :: TokenHash() is COMPLETELY FULL!" );
// consider doing overflow table(s) after the main table & limiting linear hash table search
MsgDev( D_ERROR, "SV_TokenHash is completely full!\n" );
return 0;
}
static void SV_UpdateTokens( const TYPEDESCRIPTION *fields, int fieldCount )
{
int i;
for( i = 0; i < fieldCount; i++, fields++ )
SV_TokenHash( fields->fieldName );
}
static void SV_AddSaveLump( wfile_t *f, const char *lumpname, void *data, size_t len, bool compress )
{
if( f ) WAD_Write( f, lumpname, data, len, TYPE_BINDATA, ( compress ? CMP_ZLIB : CMP_NONE ));
@ -104,6 +115,26 @@ static void SV_SetPair( const char *name, const char *value, dkeyvalue_t *cvars,
(*numpairs)++; // increase epairs
}
static void SV_SaveBuffer( wfile_t *f, const char *lumpname, bool compress )
{
// write result into lump
SV_AddSaveLump( f, lumpname, svgame.SaveData.pBaseData, svgame.SaveData.size, compress );
// clear buffer after writing
Mem_Set( svgame.SaveData.pBaseData, 0, svgame.SaveData.bufferSize );
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
svgame.SaveData.size = 0; // reset current bufSize
}
static void SV_ReadBuffer( wfile_t *f, const char *lumpname )
{
// an older pointer will automatically free memory when calling WAD_Close
// so we don't need to care about it
svgame.SaveData.pBaseData = WAD_Read( f, lumpname, &svgame.SaveData.bufferSize, TYPE_BINDATA );
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
svgame.SaveData.size = 0; // reset current bufSize
}
static void SV_SaveEngineData( wfile_t *f )
{
byte *portalstate = NULL;
@ -130,22 +161,22 @@ static void SV_SaveEngineData( wfile_t *f )
static void SV_SaveServerData( wfile_t *f )
{
SAVERESTOREDATA *pSaveData;
byte *savepool;
string_t hash_strings[4095];
int i, numstrings;
ENTITYTABLE *pTable;
save_header_t shdr;
game_header_t ghdr;
int i;
// initialize local mempool
savepool = Mem_AllocPool( "Save Pool" );
svgame.temppool = Mem_AllocPool( "Save Pool" );
// initialize SAVERESTOREDATA
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
svgame.SaveData.bufferSize = 0x80000; // reserve 512K for now
svgame.SaveData.pBaseData = Mem_Alloc( savepool, svgame.SaveData.bufferSize );
svgame.SaveData.pBaseData = Mem_Alloc( svgame.temppool, svgame.SaveData.bufferSize );
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
svgame.SaveData.tokenCount = 0xFFF; // assume a maximum of 4K-1 symbol table entries
svgame.SaveData.pTokens = Mem_Alloc( savepool, svgame.SaveData.tokenCount * sizeof( char* ));
svgame.SaveData.pTokens = Mem_Alloc( svgame.temppool, svgame.SaveData.tokenCount * sizeof( char* ));
svgame.SaveData.time = svgame.globals->time;
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
@ -165,7 +196,7 @@ static void SV_SaveServerData( wfile_t *f )
// initialize ENTITYTABLE
pSaveData->tableCount = svgame.globals->numEntities;
pSaveData->pTable = Mem_Alloc( savepool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
pSaveData->pTable = Mem_Alloc( svgame.temppool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
for( i = 0; i < svgame.globals->numEntities; i++ )
{
@ -173,7 +204,6 @@ static void SV_SaveServerData( wfile_t *f )
pTable = &pSaveData->pTable[i];
pTable->id = pent->serialnumber;
if( pent->free ) pTable->flags |= FENTTABLE_REMOVED;
pTable->pent = pent;
// setup some flags
@ -191,16 +221,20 @@ static void SV_SaveServerData( wfile_t *f )
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "ADJACENCY", pList, gAdjacency, ARRAYSIZE( gAdjacency ));
}
SV_SaveBuffer( f, LUMP_ADJACENCY, false );
// write entity descriptions
for( i = 0; i < svgame.globals->numEntities; i++ )
{
edict_t *pent = EDICT_NUM( i );
if( pent->free ) continue;
svgame.dllFuncs.pfnSave( pent, pSaveData );
if( !pent->free && pent->v.classname )
svgame.dllFuncs.pfnSave( pent, pSaveData );
pSaveData->currentIndex++; // move pointer
}
SV_SaveBuffer( f, LUMP_ENTITIES, false );
// write entity table
for( i = 0; i < pSaveData->tableCount; i++ )
{
@ -209,12 +243,7 @@ static void SV_SaveServerData( wfile_t *f )
}
// write result into lump
SV_AddSaveLump( f, LUMP_ENTITIES, pSaveData->pBaseData, pSaveData->size, false );
// clear buffer for global lump
Mem_Set( pSaveData->pBaseData, 0, pSaveData->size );
pSaveData->pCurrentData = pSaveData->pBaseData;
pSaveData->size = 0;
SV_SaveBuffer( f, LUMP_ENTTABLE, false );
// write game header
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "Game Header", &ghdr, gGameHeader, ARRAYSIZE( gGameHeader ));
@ -223,12 +252,23 @@ static void SV_SaveServerData( wfile_t *f )
svgame.dllFuncs.pfnSaveGlobalState( pSaveData );
// write result into lump
SV_AddSaveLump( f, LUMP_GLOBALS, pSaveData->pBaseData, pSaveData->size, false );
SV_SaveBuffer( f, LUMP_GLOBALS, false );
// save used hash strings
for( i = numstrings = 0; i < svgame.SaveData.tokenCount; i++ )
{
if( !svgame.SaveData.pTokens[i] ) continue;
hash_strings[numstrings] = StringTable_SetString( svgame.hStringTable, svgame.SaveData.pTokens[i] );
numstrings++;
}
// save hash table
SV_AddSaveLump( f, LUMP_HASHTABLE, hash_strings, numstrings * sizeof( string_t ), true );
// do cleanup operations
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
svgame.globals->pSaveData = NULL;
Mem_FreePool( &savepool );
Mem_FreePool( &svgame.temppool );
}
/*
@ -268,7 +308,7 @@ void SV_WriteSaveFile( const char *name, bool autosave )
// write lumps
SV_SaveEngineData( savfile );
SV_SaveServerData( savfile );
StringTable_Save( svgame.hStringTable, savfile );
StringTable_Save( svgame.hStringTable, savfile ); // must be last
WAD_Close( savfile );
@ -279,29 +319,35 @@ void SV_ReadComment( wfile_t *l )
{
SAVERESTOREDATA *pSaveData;
game_header_t ghdr;
int i;
// initialize SAVERESTOREDATA
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
svgame.SaveData.pBaseData = WAD_Read( l, LUMP_GLOBALS, &svgame.SaveData.bufferSize, TYPE_BINDATA );
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
svgame.SaveData.tokenCount = 0xFFF; // assume a maximum of 4K-1 symbol table entries
svgame.SaveData.pTokens = (char **)Z_Malloc( svgame.SaveData.tokenCount * sizeof( char* ));
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
SV_ReadBuffer( l, LUMP_GLOBALS );
// TEST: tokenize strings
for( i = 0; i < ARRAYSIZE( gGameHeader ); i++ )
TokenHash( gGameHeader[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
SV_UpdateTokens( gGameHeader, ARRAYSIZE( gGameHeader ));
// read game header
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "Game Header", &ghdr, gGameHeader, ARRAYSIZE( gGameHeader ));
com.strncpy( svs.comment, ghdr.comment, CS_SIZE );
if( svgame.SaveData.pTokens ) Mem_Free( svgame.SaveData.pTokens );
if( svgame.SaveData.pBaseData ) Mem_Free( svgame.SaveData.pBaseData );
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
}
void SV_ReadHashTable( wfile_t *l )
{
string_t *in_table;
int i, hash_size;
in_table = (string_t *)WAD_Read( l, LUMP_HASHTABLE, &hash_size, TYPE_BINDATA );
for( i = 0; i < hash_size / sizeof( string_t ); i++, in_table++ )
SV_TokenHash( STRING( *in_table ));
}
void SV_ReadCvars( wfile_t *l )
{
dkeyvalue_t *in;
@ -346,24 +392,19 @@ void SV_ReadAreaPortals( wfile_t *l )
void SV_ReadGlobals( wfile_t *l )
{
SAVERESTOREDATA *pSaveData;
byte *restorepool;
game_header_t ghdr;
int i;
// initialize local mempool
// restorepool = Mem_AllocPool( "Restore Pool" );
svgame.temppool = Mem_AllocPool( "Restore Pool" );
// initialize SAVERESTOREDATA
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
svgame.SaveData.pBaseData = WAD_Read( l, LUMP_GLOBALS, &svgame.SaveData.bufferSize, TYPE_BINDATA );
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
svgame.SaveData.tokenCount = 0xFFF; // assume a maximum of 4K-1 symbol table entries
svgame.SaveData.pTokens = Mem_Alloc( svgame.mempool, svgame.SaveData.tokenCount * sizeof( char* ));
svgame.SaveData.pTokens = Mem_Alloc( svgame.temppool, svgame.SaveData.tokenCount * sizeof( char* ));
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
SV_ReadBuffer( l, LUMP_GLOBALS );
// TEST: tokenize strings
for( i = 0; i < ARRAYSIZE( gGameHeader ); i++ )
TokenHash( gGameHeader[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
SV_ReadHashTable( l );
// read the game header
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "Game Header", &ghdr, gGameHeader, ARRAYSIZE( gGameHeader ));
@ -376,49 +417,50 @@ void SV_ReadGlobals( wfile_t *l )
svgame.dllFuncs.pfnRestoreGlobalState( pSaveData );
svgame.dllFuncs.pfnServerDeactivate();
//Mem_FreePool( &restorepool );
// leave pool unfreed, because we have partially filled hash tokens
}
void SV_RestoreEdict( edict_t *ent )
{
SV_SetPhysForce( ent ); // restore forces ...
SV_SetMassCentre( ent ); // and mass force
}
void SV_ReadEntities( wfile_t *l )
{
SAVERESTOREDATA *pSaveData;
byte *restorepool;
ENTITYTABLE *pTable;
LEVELLIST *pList;
save_header_t shdr;
int i;
// initialize local mempool
//restorepool = Mem_AllocPool( "Restore Pool" );
// SAVERESTOREDATA partially initialized, continue filling
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
svgame.SaveData.pBaseData = WAD_Read( l, LUMP_ENTITIES, &svgame.SaveData.bufferSize, TYPE_BINDATA );
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
svgame.SaveData.size = 0;
SV_ReadBuffer( l, LUMP_ADJACENCY );
// TEST: tokenize strings
for( i = 0; i < ARRAYSIZE( gSaveHeader ); i++ )
TokenHash( gSaveHeader[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
// read save header
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "Save Header", &shdr, gSaveHeader, ARRAYSIZE( gSaveHeader ));
SV_ConfigString( CS_MAXCLIENTS, va("%i", Host_MaxClients()));
SV_ConfigString( CS_MAXCLIENTS, va( "%i", Host_MaxClients( )));
com.strncpy( sv.name, shdr.mapName, MAX_STRING );
svgame.globals->mapname = MAKE_STRING( sv.name );
svgame.globals->time = sv.time = shdr.time;
pSaveData->connectionCount = shdr.numConnections;
// read ADJACENCY sections
for( i = 0; i < pSaveData->connectionCount; i++ )
{
pList = &pSaveData->levelList[i];
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "ADJACENCY", pList, gAdjacency, ARRAYSIZE( gAdjacency ));
}
// initialize ENTITYTABLE
pSaveData->tableCount = shdr.numEntities;
pSaveData->pTable = Mem_Alloc( svgame.mempool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
pSaveData->pTable = Mem_Alloc( svgame.temppool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
while( svgame.globals->numEntities < shdr.numEntities ) SV_AllocEdict(); // allocate edicts
// TEST: tokenize strings
for( i = 0; i < ARRAYSIZE( gETable ); i++ )
TokenHash( gETable[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
SV_ReadBuffer( l, LUMP_ENTTABLE );
// read entity table
for( i = 0; i < pSaveData->tableCount; i++ )
{
@ -430,20 +472,13 @@ void SV_ReadEntities( wfile_t *l )
if( pTable->id != pent->serialnumber )
MsgDev( D_ERROR, "ETABLE id( %i ) != edict->id( %i )\n", pTable->id, pent->serialnumber );
if( pTable->flags & FENTTABLE_REMOVED ) SV_FreeEdict( pent );
else pent = SV_AllocPrivateData( pent, pTable->classname );
pTable->pent = pent;
}
// TEST: tokenize strings
for( i = 0; i < ARRAYSIZE( gAdjacency ); i++ )
TokenHash( gAdjacency[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
SV_ReadBuffer( l, LUMP_ENTITIES );
pSaveData->fUseLandmark = true;
// read ADJACENCY sections
for( i = 0; i < pSaveData->connectionCount; i++ )
{
pList = &pSaveData->levelList[i];
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "ADJACENCY", pList, gAdjacency, ARRAYSIZE( gAdjacency ));
}
Com_Assert( 1 );
// and read entities ...
for( i = 0; i < pSaveData->tableCount; i++ )
{
@ -451,14 +486,18 @@ void SV_ReadEntities( wfile_t *l )
pTable = &pSaveData->pTable[i];
// ignore removed edicts
if( pTable->flags & FENTTABLE_REMOVED ) continue;
svgame.dllFuncs.pfnRestore( pent, pSaveData, (pTable->flags & FENTTABLE_GLOBAL));
if( !pent->free && pTable->classname )
{
svgame.dllFuncs.pfnRestore( pent, pSaveData, false );
SV_RestoreEdict( pent );
}
pSaveData->currentIndex++;
}
// do cleanup operations
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
svgame.globals->pSaveData = NULL;
//Mem_FreePool( &restorepool );
Mem_FreePool( &svgame.temppool );
}
/*
@ -544,13 +583,4 @@ bool SV_GetComment( char *comment, int savenum )
WAD_Close( savfile );
return true;
}
void SV_RestoreEdict( edict_t *ent )
{
// link it into the bsp tree
SV_LinkEdict( ent );
SV_CreatePhysBody( ent );
SV_SetPhysForce( ent ); // restore forces ...
SV_SetMassCentre( ent ); // and mass force
}

View File

@ -289,7 +289,7 @@ int StringTable_CreateNewSystem( const char *name, size_t max_strings )
{
// found free slot
dstring[i] = Mem_Alloc( Sys.basepool, sizeof( stringtable_t ));
dstring[i]->mempool = Mem_AllocPool( va( "StringTable_%s", name ));
dstring[i]->mempool = Mem_AllocPool( va( "StringTable_%s", name ));
com.strncpy( dstring[i]->name, name, MAX_STRING );
dstring[i]->maxdatasize = max_strings * 8;
dstring[i]->maxstrings = max_strings;
@ -393,13 +393,22 @@ bool StringTable_SaveSystem( int h, wfile_t *wad )
int StringTable_LoadSystem( wfile_t *wad, const char *name )
{
int datasize, table_size;
int h = StringTable_CreateNewSystem( name, 0x10000 ); // 65535 unique strings
int datasize, numstrings;
char *data = (char *)W_LoadLump( wad, "stringdata", &datasize, TYPE_STRDATA );
int *table = (int *)W_LoadLump( wad, "stringtable", &table_size, TYPE_STRDATA );
dstring[h]->data = W_LoadLump( wad, "stringdata", &datasize, TYPE_STRDATA );
dstring[h]->table = (int *)W_LoadLump( wad, "stringtable", &numstrings, TYPE_STRDATA );
if(( datasize > dstring[h]->maxdatasize ) || ((table_size / sizeof( int )) > dstring[h]->maxstrings ))
Sys_Error( "Too small StringTable for loading\n" );
#ifndef ST_STATIC_ALLOCATE
dstring[h]->data = Mem_Realloc( dstring[handle]->mempool, dstring[handle]->data, datasize );
dstring[h]->table = Mem_Realloc( dstring[handle]->mempool, dstring[handle]->table, table_size );
#endif
Mem_Copy( dstring[h]->data, data, datasize );
Mem_Copy( dstring[h]->table, table, table_size );
dstring[h]->datasize = datasize;
dstring[h]->numstrings = numstrings / sizeof(int);
dstring[h]->numstrings = table_size / sizeof( int );
return h;
}

View File

@ -903,9 +903,12 @@ included global, and both (client & server) pent list
*/
#define LUMP_CFGSTRING "configstrings"
#define LUMP_AREASTATE "areaportals"
#define LUMP_ENTITIES "entities"
#define LUMP_GLOBALS "global_data"
#define LUMP_ENTITIES "entities" // entvars + CBase->fields
#define LUMP_ENTTABLE "enttable" // entity transition table
#define LUMP_ADJACENCY "adjacency" // Save Header + ADJACENCY
#define LUMP_GLOBALS "global_data" // Game Header + Global State
#define LUMP_GAMECVARS "latched_cvars"
#define LUMP_HASHTABLE "hashtable" // contains string_t only for used hash-values
#define LUMP_SNAPSHOT "saveshot" // currently not implemented
#define DENT_KEY 0

View File

@ -228,7 +228,7 @@ typedef struct
} ENTITYTABLE;
#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore
#define MAX_LEVEL_CONNECTIONS 32 // These are encoded in the lower 16bits of ENTITYTABLE->flags
#define MAX_LEVEL_CONNECTIONS 16 // These are encoded in the lower 16bits of ENTITYTABLE->flags
#define FENTTABLE_GLOBAL 0x10000000
#define FENTTABLE_MOVEABLE 0x20000000
@ -300,6 +300,7 @@ typedef struct
#define DEFINE_FIELD( type, name, fieldtype ) _FIELD( type, name, fieldtype, 1, 0 )
#define DEFINE_ARRAY( type, name, fieldtype, count ) _FIELD( type, name, fieldtype, count, 0 )
#define DEFINE_ENTITY_FIELD( name, fieldtype ) _FIELD( entvars_t, name, fieldtype, 1, 0 )
#define DEFINE_ENTITY_FIELD_ARRAY( name, fieldtype, count ) _FIELD( entvars_t, name, fieldtype, count, 0 )
#define DEFINE_ENTITY_GLOBAL_FIELD( name, fieldtype ) _FIELD( entvars_t, name, fieldtype, 1, FTYPEDESC_GLOBAL )
#define DEFINE_GLOBAL_FIELD( type, name, fieldtype ) _FIELD( type, name, fieldtype, 1, FTYPEDESC_GLOBAL )

View File

@ -71,5 +71,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
quake.exe -game tmpQuArK -dev 3 -log +map dm_knot
quake.exe -game tmpQuArK -dev 3 -log +map qctest
:done

View File

@ -891,7 +891,10 @@ int CBaseEntity :: Restore( CRestore &restore )
status = restore.ReadEntVars( "ENTVARS", pev );
if( status ) status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE( m_SaveData ));
if( pev->modelindex != 0 && !FStringNull( pev->model ))
// restore edict class here
SetObjectClass( m_iClassType );
if( pev->modelindex != 0 && !FStringNull( pev->model ))
{
Vector mins = pev->mins, maxs = pev->maxs; // Set model is about to destroy these

View File

@ -1,6 +1,6 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// logicentity.cpp - all entities with prefix "logic_"
// logicentity.cpp - all entities with prefix "logic_"
// additional entities for smart system
//=======================================================================

59
server/ents/basephys.cpp Normal file
View File

@ -0,0 +1,59 @@
//=======================================================================
// Copyright (C) XashXT Group 2008
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "client.h"
class CPhysEntity : public CBaseEntity
{
public:
void Precache( void )
{
UTIL_PrecacheModel( pev->model, (char *)Model() );
}
void Spawn( void )
{
Precache();
pev->movetype = MOVETYPE_PHYSIC;
pev->solid = SolidType();
pev->owner = ENT( pev ); // g-cont. i'm forget what for needs this stuff :)
UTIL_SetOrigin( this, pev->origin );
UTIL_SetModel( ENT( pev ), pev->model, (char *)Model() );
SetObjectClass( ED_RIGIDBODY );
}
virtual const char *Model( void ){ return NULL; }
virtual int SolidType( void ){ return SOLID_MESH; } // generic but slow
void PostActivate( void ) { } // stub
};
LINK_ENTITY_TO_CLASS( func_physbox, CPhysEntity );
// some rigid bodies for Xash3D 0.56 beta
class CPhysSphere : public CPhysEntity
{
public:
virtual const char *Model( void ){ return "models/props/nexplode.mdl"; }
virtual int SolidType( void ){ return SOLID_SPHERE; }
};
LINK_ENTITY_TO_CLASS( misc_sphere, CPhysSphere );
class CPhysBarrel : public CPhysEntity
{
public:
virtual const char *Model( void ){ return "models/props/barrel2.mdl"; }
virtual int SolidType( void ){ return SOLID_CYLINDER; }
};
LINK_ENTITY_TO_CLASS( misc_barrel, CPhysBarrel );
class CPhysBox : public CPhysEntity
{
public:
virtual const char *Model( void ){ return "models/props/box.mdl"; }
virtual int SolidType( void ){ return SOLID_BOX; }
};
LINK_ENTITY_TO_CLASS( misc_physbox, CPhysBox );

View File

@ -239,11 +239,12 @@ int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if ( pEntity && pSaveData )
if( pEntity && pSaveData )
{
entvars_t tmpVars;
Vector oldOffset;
ALERT( at_console, "DispatchRestore( %s )\n", STRING( pent->v.classname ));
CRestore restoreHelper( pSaveData );
if ( globalEntity )
{

View File

@ -95,7 +95,17 @@ TYPEDESCRIPTION gEntvarsDescription[] =
DEFINE_ENTITY_FIELD( spawnflags, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( flags, FIELD_INTEGER64 ),
#if 0
DEFINE_ENTITY_FIELD_ARRAY( m_pmatrix, FIELD_VECTOR, 3 ),
DEFINE_ENTITY_FIELD_ARRAY( m_pcentre, FIELD_VECTOR, 3 ),
#else
DEFINE_ENTITY_FIELD( m_pmatrix[0], FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( m_pmatrix[1], FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( m_pmatrix[2], FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( m_pcentre[0], FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( m_pcentre[1], FIELD_VECTOR ),
DEFINE_ENTITY_FIELD( m_pcentre[2], FIELD_VECTOR ),
#endif
DEFINE_ENTITY_FIELD( colormap, FIELD_INTEGER ),
DEFINE_ENTITY_FIELD( team, FIELD_INTEGER ),
@ -988,8 +998,6 @@ void CRestore::BufferReadHeader( HEADER *pheader )
pheader->token = ReadShort(); // Read field name token
pheader->pData = BufferPointer(); // Field Data is next
BufferSkipBytes( pheader->size ); // Advance to next field
ALERT( at_console, "header.token is %i\n", pheader->token );
}

View File

@ -185,6 +185,10 @@ SOURCE=.\ents\basepath.cpp
# End Source File
# Begin Source File
SOURCE=.\ents\basephys.cpp
# End Source File
# Begin Source File
SOURCE=.\ents\baserockets.cpp
# End Source File
# Begin Source File