From 8447342b7b182b4d73d19fbec3f8746361aed400 Mon Sep 17 00:00:00 2001 From: black Date: Thu, 17 Jan 2008 13:39:55 +0000 Subject: [PATCH] Add support for a clientcamera sqc field that automatically updates the view entity on the clients. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7972 d7cf8633-e32d-0410-b094-e92efae38249 --- progsvm.h | 1 + prvm_edict.c | 1 + server.h | 3 +++ sv_main.c | 25 ++++++++++++++++++++++--- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/progsvm.h b/progsvm.h index 341f64cf..8b412bca 100644 --- a/progsvm.h +++ b/progsvm.h @@ -213,6 +213,7 @@ typedef struct prvm_prog_fieldoffsets_s int viewmodelforclient; // ssqc int viewzoom; // ssqc int yaw_speed; // ssqc / csqc + int clientcamera; // ssqc } prvm_prog_fieldoffsets_t; diff --git a/prvm_edict.c b/prvm_edict.c index f017e2de..8d982791 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -1421,6 +1421,7 @@ void PRVM_FindOffsets(void) prog->fieldoffsets.viewmodelforclient = PRVM_ED_FindFieldOffset("viewmodelforclient"); prog->fieldoffsets.viewzoom = PRVM_ED_FindFieldOffset("viewzoom"); prog->fieldoffsets.yaw_speed = PRVM_ED_FindFieldOffset("yaw_speed"); + prog->fieldoffsets.clientcamera = PRVM_ED_FindFieldOffset("clientcamera"); 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"); diff --git a/server.h b/server.h index 33099d38..ac5e1edf 100644 --- a/server.h +++ b/server.h @@ -228,6 +228,9 @@ typedef struct client_s char weaponmodel[MAX_QPATH]; int weaponmodelindex; + // clientcamera (entity to use as camera) + int clientcamera; + entityframe_database_t *entitydatabase; entityframe4_database_t *entitydatabase4; entityframe5_database_t *entitydatabase5; diff --git a/sv_main.c b/sv_main.c index e177b8a4..c471ff35 100644 --- a/sv_main.c +++ b/sv_main.c @@ -790,9 +790,11 @@ void SV_SendServerinfo (client_t *client) MSG_WriteByte (&client->netconnection->message, (int)prog->edicts->fields.server->sounds); // set view +// store this in clientcamera, too + client->clientcamera = PRVM_NUM_FOR_EDICT(client->edict); MSG_WriteByte (&client->netconnection->message, svc_setview); - MSG_WriteShort (&client->netconnection->message, PRVM_NUM_FOR_EDICT(client->edict)); - + MSG_WriteShort (&client->netconnection->message, client->clientcamera); + MSG_WriteByte (&client->netconnection->message, svc_signonnum); MSG_WriteByte (&client->netconnection->message, 1); @@ -1323,6 +1325,7 @@ void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t * { int i, numsendstates; entity_state_t *s; + prvm_edict_t *camera; // if there isn't enough space to accomplish anything, skip it if (msg->cursize + 25 > msg->maxsize) @@ -1338,7 +1341,8 @@ void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t * // find the client's PVS // the real place being tested from - VectorAdd(clent->fields.server->origin, clent->fields.server->view_ofs, sv.writeentitiestoclient_testeye); + camera = PRVM_EDICT_NUM( client->clientcamera ); + VectorAdd(camera->fields.server->origin, clent->fields.server->view_ofs, sv.writeentitiestoclient_testeye); sv.writeentitiestoclient_pvsbytes = 0; if (sv.worldmodel && sv.worldmodel->brush.FatPVS) sv.writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, sv.writeentitiestoclient_testeye, 8, sv.writeentitiestoclient_pvs, sizeof(sv.writeentitiestoclient_pvs), false); @@ -1937,6 +1941,21 @@ static void SV_UpdateToReliableMessages (void) PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(host_client->playerskin); } + // TODO: add an extension name for this [1/17/2008 Black] + if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcamera)) && val->edict > 0 ) { + int oldclientcamera = host_client->clientcamera; + if( val->edict >= prog->max_edicts || PRVM_EDICT_NUM( val->edict )->priv.required->free ) { + val->edict = host_client->clientcamera = PRVM_NUM_FOR_EDICT( host_client->edict ); + } else { + host_client->clientcamera = val->edict; + } + + if( oldclientcamera != host_client->clientcamera ) { + MSG_WriteByte (&sv.reliable_datagram, svc_setview ); + MSG_WriteShort (&host_client->netconnection->message, host_client->clientcamera); + } + } + // frags host_client->frags = (int)host_client->edict->fields.server->frags; if(gamemode == GAME_NEXUIZ) -- 2.39.2