From 02b8f1e24bce4b4a9b641b7dd97d134a9ff9a6c4 Mon Sep 17 00:00:00 2001 From: black Date: Fri, 1 Feb 2008 16:21:37 +0000 Subject: [PATCH] Rewrite CSQC's setmodel a bit. Add support for CSQC_Ent_Spawn to csqc. A function that is called when a entity packet from the server arrives that requires a new entity. entity( float entnum ) CSQC_Ent_Spawn; CSQC_Ent_Spawn needs to spawn a new entity and set its .entnum field accordingly or simply return another existing entity or world if it wants to ignore that server entity. Subsequent CSQC_Ent_Update calls are routed to that entity (or CSQC_Ent_Spawn is called again when .Version increases). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8063 d7cf8633-e32d-0410-b094-e92efae38249 --- clvm_cmds.c | 39 ++++++++++++++++++++++----------------- csprogs.c | 31 +++++++++++++++++++++++-------- progsvm.h | 6 ++++-- prvm_edict.c | 5 +++-- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/clvm_cmds.c b/clvm_cmds.c index b566f052..4f962739 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -83,39 +83,44 @@ void VM_CL_setmodel (void) VM_SAFEPARMCOUNT(2, VM_CL_setmodel); e = PRVM_G_EDICT(OFS_PARM0); + e->fields.client->modelindex = 0; + e->fields.client->model = 0; + m = PRVM_G_STRING(OFS_PARM1); + mod = NULL; for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++) { if (!strcmp(cl.csqc_model_precache[i]->name, m)) { - e->fields.client->model = PRVM_SetEngineString(cl.csqc_model_precache[i]->name); + mod = cl.csqc_model_precache[i]; + e->fields.client->model = PRVM_SetEngineString(mod->name); e->fields.client->modelindex = -(i+1); - return; + break; } } - for (i = 0;i < MAX_MODELS;i++) - { - mod = cl.model_precache[i]; - if (mod && !strcmp(mod->name, m)) + if( !mod ) { + for (i = 0;i < MAX_MODELS;i++) { - e->fields.client->model = PRVM_SetEngineString(mod->name); - e->fields.client->modelindex = i; - return; + mod = cl.model_precache[i]; + if (mod && !strcmp(mod->name, m)) + { + e->fields.client->model = PRVM_SetEngineString(mod->name); + e->fields.client->modelindex = i; + break; + } } } - e->fields.client->modelindex = 0; - e->fields.client->model = 0; - VM_Warning ("setmodel: model '%s' not precached\n", m); - - // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black] - if (mod) - { + if( mod ) { + // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black] SetMinMaxSize (e, mod->normalmins, mod->normalmaxs); - } + } else + { SetMinMaxSize (e, vec3_origin, vec3_origin); + VM_Warning ("setmodel: model '%s' not precached\n", m); + } } // #4 void(entity e, vector min, vector max) setsize diff --git a/csprogs.c b/csprogs.c index 6175e450..c6b38b15 100644 --- a/csprogs.c +++ b/csprogs.c @@ -554,21 +554,36 @@ void CSQC_ReadEntities (void) cl.csqc_server2csqcentitynumber[realentnum] = 0; } else - Con_Printf("Smth bad happens in csqc...\n"); //[515]: never happens ? + Con_Printf("Bad csqc_server2csqcentitynumber map\n"); //[515]: never happens ? } else { if(!prog->globals.client->self) { - prvm_edict_t *ed; - ed = PRVM_ED_Alloc(); - ed->fields.client->entnum = realentnum; - prog->globals.client->self = cl.csqc_server2csqcentitynumber[realentnum] = PRVM_EDICT_TO_PROG(ed); - PRVM_G_FLOAT(OFS_PARM0) = 1; + if(!prog->funcoffsets.CSQC_Ent_Spawn) + { + prvm_edict_t *ed; + ed = PRVM_ED_Alloc(); + ed->fields.client->entnum = realentnum; + prog->globals.client->self = cl.csqc_server2csqcentitynumber[realentnum] = PRVM_EDICT_TO_PROG(ed); + PRVM_G_FLOAT(OFS_PARM0) = 1; + PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Update, "QC function CSQC_Ent_Update is missing"); + } + else + { + // entity( float entnum ) CSQC_Ent_Spawn; + // the qc function should set entnum, too (this way it also can return world [2/1/2008 Andreas] + PRVM_G_FLOAT(OFS_PARM0) = (float) realentnum; + // make sure no one gets wrong ideas + prog->globals.client->self = 0; + PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Spawn, "QC function CSQC_Ent_Spawn is missing"); + cl.csqc_server2csqcentitynumber[realentnum] = PRVM_EDICT( PRVM_G_INT( OFS_RETURN ) ); + } } - else + else { PRVM_G_FLOAT(OFS_PARM0) = 0; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Update, "QC function CSQC_Ent_Update is missing"); + PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Update, "QC function CSQC_Ent_Update is missing"); + } } } prog->globals.client->self = oldself; diff --git a/progsvm.h b/progsvm.h index 3a6028b1..e5dd2d00 100644 --- a/progsvm.h +++ b/progsvm.h @@ -258,6 +258,7 @@ typedef struct prvm_prog_funcoffsets_s { func_t CSQC_ConsoleCommand; // csqc func_t CSQC_Ent_Remove; // csqc + func_t CSQC_Ent_Spawn; // csqc DP_CSQC_ENT_SPAWN extension (BlackHC - TODO: needs to be added to dpextensions.qc) func_t CSQC_Ent_Update; // csqc func_t CSQC_Event; // csqc [515]: engine call this for its own needs so csqc can do some things according to what engine it's running on. example: to say about edicts increase, whatever... func_t CSQC_Event_Sound; // csqc : called by engine when an incoming sound packet arrives so CSQC can act on it @@ -515,8 +516,9 @@ void PRVM_ED_ParseGlobals (const char *data); void PRVM_ED_LoadFromFile (const char *data); -prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline); -#define PRVM_EDICT_NUM(n) (((unsigned)(n) < (unsigned int)prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__)) +unsigned PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline); +#define PRVM_EDICT(n) (((unsigned)(n) < (unsigned int)prog->max_edicts) ? n : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__)) +#define PRVM_EDICT_NUM(n) (prog->edicts + PRVM_EDICT(n)) //int NUM_FOR_EDICT_ERROR(prvm_edict_t *e); #define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts)) diff --git a/prvm_edict.c b/prvm_edict.c index 9e85cfc7..600e8495 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -1425,6 +1425,7 @@ void PRVM_FindOffsets(void) prog->funcoffsets.CSQC_ConsoleCommand = PRVM_ED_FindFunctionOffset("CSQC_ConsoleCommand"); prog->funcoffsets.CSQC_Ent_Remove = PRVM_ED_FindFunctionOffset("CSQC_Ent_Remove"); prog->funcoffsets.CSQC_Ent_Update = PRVM_ED_FindFunctionOffset("CSQC_Ent_Update"); + prog->funcoffsets.CSQC_Ent_Spawn = PRVM_ED_FindFunctionOffset("CSQC_Ent_Spawn"); prog->funcoffsets.CSQC_Event = PRVM_ED_FindFunctionOffset("CSQC_Event"); prog->funcoffsets.CSQC_Event_Sound = PRVM_ED_FindFunctionOffset("CSQC_Event_Sound"); prog->funcoffsets.CSQC_Init = PRVM_ED_FindFunctionOffset("CSQC_Init"); @@ -2106,10 +2107,10 @@ void _PRVM_FreeAll(const char *filename, int fileline) } // LordHavoc: turned PRVM_EDICT_NUM into a #define for speed reasons -prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline) +unsigned PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline) { PRVM_ERROR ("PRVM_EDICT_NUM: %s: bad number %i (called at %s:%i)", PRVM_NAME, n, filename, fileline); - return NULL; + return 0; } /* -- 2.39.2