Ive done three todo items:
authorblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 2 Dec 2004 14:25:48 +0000 (14:25 +0000)
committerblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 2 Dec 2004 14:25:48 +0000 (14:25 +0000)
-Added support for ' strings in Com_ParseToken.
-Added support for " and ' as end tokens in Com_ParseToken.
-Added the NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN extensions.
The last needs to be tested though. Hopefully it works.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4819 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
common.c
host_cmd.c
pr_cmds.c
pr_edict.c
progdefs.h
server.h
sv_main.c
sv_user.c
todo

index d1d5fc6..c90bec3 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1274,7 +1274,7 @@ CL_Init
 =================
 */
 //VorteX: cvars for GAME_NETHERWORLD
-cvar_t cl_playermodel = {CVAR_SAVE, "cl_playermodel", "ranger"}; 
+cvar_t __cl_playermodel = {CVAR_SAVE, "cl_playermodel", "ranger"}; 
 cvar_t cl_footsteps = {CVAR_SAVE, "cl_footsteps", "1"}; 
 cvar_t cl_weapon_ofs = {CVAR_SAVE, "cl_weapon_ofs", "0 0 0"}; 
 cvar_t cl_weapon_bstep = {CVAR_SAVE, "cl_weapon_bstep", "100 0 0"}; 
@@ -1371,7 +1371,7 @@ void CL_Init (void)
 
        if (gamemode == GAME_NETHERWORLD)
        {
-               Cvar_RegisterVariable (&cl_playermodel); 
+               Cvar_RegisterVariable (&__cl_playermodel); 
                Cvar_RegisterVariable (&cl_footsteps); 
                Cvar_RegisterVariable (&cl_weapon_ofs); 
                Cvar_RegisterVariable (&cl_weapon_bstep); 
index a6dca4e..1414e31 100644 (file)
--- a/common.c
+++ b/common.c
@@ -682,7 +682,26 @@ skipwhite:
                com_token[len] = 0;
                *datapointer = data+1;
                return true;
-       }
+       } 
+       else if (*data == '\'')
+       {
+               // quoted string
+               for (data++;*data != '\'';data++)
+               {
+                       if (*data == '\\' && data[1] == '\'' )
+                               data++;
+                       if (!*data || len >= (int)sizeof(com_token) - 1)
+                       {
+                               com_token[0] = 0;
+                               *datapointer = NULL;
+                               return false;
+                       }
+                       com_token[len++] = *data;
+               }
+               com_token[len] = 0;
+               *datapointer = data+1;
+               return true;
+       }       
        else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == '\'' || *data == ':' || *data == ',' || *data == ';')
        {
                // single character
@@ -694,7 +713,7 @@ skipwhite:
        else
        {
                // regular word
-               for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';';data++)
+               for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';' && *data != '\'' && *data != '"';data++)
                {
                        if (len >= (int)sizeof(com_token) - 1)
                        {
index 80b62d1..6272c14 100644 (file)
@@ -764,6 +764,126 @@ void Host_Name_f (void)
        }
 }
 
+/*
+======================
+Host_Playermodel_f
+======================
+*/
+cvar_t cl_playermodel = {CVAR_SAVE, "_cl_playermodel", ""}; 
+// the old cl_playermodel in cl_main has been renamed to __cl_playermodel
+void Host_Playermodel_f (void)
+{
+       int i, j;
+       char newPath[sizeof(host_client->playermodel)];
+
+       if (Cmd_Argc () == 1)
+       {
+               Con_Printf("\"playermodel\" is \"%s\"\n", cl_playermodel.string);
+               return;
+       }
+
+       if (Cmd_Argc () == 2)
+               strlcpy (newPath, Cmd_Argv(1), sizeof (newPath));
+       else
+               strlcpy (newPath, Cmd_Args(), sizeof (newPath));
+
+       for (i = 0, j = 0;newPath[i];i++)
+               if (newPath[i] != '\r' && newPath[i] != '\n')
+                       newPath[j++] = newPath[i];
+       newPath[j] = 0;
+
+       if (cmd_source == src_command)
+       {
+               Cvar_Set ("_cl_playermodel", newPath);
+               if (cls.state == ca_connected)
+                       Cmd_ForwardToServer ();
+               return;
+       }
+
+       /*
+       if (sv.time < host_client->nametime)
+       {
+               SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n");
+               return;
+       }
+       
+       host_client->nametime = sv.time + 5;
+       */
+
+       // point the string back at updateclient->name to keep it safe
+       strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
+       host_client->edict->v->playermodel = PR_SetString(host_client->playermodel);
+       if (strcmp(host_client->old_model, host_client->playermodel))
+       {
+               if (host_client->spawned)
+                       SV_BroadcastPrintf("%s changed model to %s\n", host_client->old_model, host_client->playermodel);
+               strcpy(host_client->old_model, host_client->playermodel);
+               /*// send notification to all clients
+               MSG_WriteByte (&sv.reliable_datagram, svc_updatepmodel);
+               MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
+               MSG_WriteString (&sv.reliable_datagram, host_client->playermodel);*/
+       }
+}
+
+/*
+======================
+Host_Playerskin_f
+======================
+*/
+cvar_t cl_playerskin = {CVAR_SAVE, "_cl_playerskin", ""};
+void Host_Playerskin_f (void)
+{
+       int i, j;
+       char newPath[sizeof(host_client->playerskin)];
+
+       if (Cmd_Argc () == 1)
+       {
+               Con_Printf("\"playerskin\" is \"%s\"\n", cl_playerskin.string);
+               return;
+       }
+
+       if (Cmd_Argc () == 2)
+               strlcpy (newPath, Cmd_Argv(1), sizeof (newPath));
+       else
+               strlcpy (newPath, Cmd_Args(), sizeof (newPath));
+
+       for (i = 0, j = 0;newPath[i];i++)
+               if (newPath[i] != '\r' && newPath[i] != '\n')
+                       newPath[j++] = newPath[i];
+       newPath[j] = 0;
+
+       if (cmd_source == src_command)
+       {
+               Cvar_Set ("_cl_playerskin", newPath);
+               if (cls.state == ca_connected)
+                       Cmd_ForwardToServer ();
+               return;
+       }
+
+       /*
+       if (sv.time < host_client->nametime)
+       {
+               SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n");
+               return;
+       }
+       
+       host_client->nametime = sv.time + 5;
+       */
+
+       // point the string back at updateclient->name to keep it safe
+       strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
+       host_client->edict->v->playerskin = PR_SetString(host_client->playerskin);
+       if (strcmp(host_client->old_skin, host_client->playerskin))
+       {
+               if (host_client->spawned)
+                       SV_BroadcastPrintf("%s changed skin to %s\n", host_client->old_skin, host_client->playerskin);
+               strcpy(host_client->old_skin, host_client->playerskin);
+               /*// send notification to all clients
+               MSG_WriteByte (&sv.reliable_datagram, svc_updatepskin);
+               MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
+               MSG_WriteString (&sv.reliable_datagram, host_client->playerskin);*/
+       }
+}
 
 void Host_Version_f (void)
 {
@@ -1806,6 +1926,15 @@ void Host_InitCommands (void)
                Cvar_RegisterVariable (&cl_pmodel);
                Cmd_AddCommand ("pmodel", Host_PModel_f);
        }
+       // FIXME: Do this only for GAME_NEXUIZ?
+       else if (gamemode == GAME_NEXUIZ) 
+       {
+               Cvar_RegisterVariable (&cl_playermodel);
+               Cmd_AddCommand ("playermodel", Host_Playermodel_f);
+               Cvar_RegisterVariable (&cl_playerskin);
+               Cmd_AddCommand ("playerskin", Host_Playerskin_f);
+       }
+
        Cmd_AddCommand ("prespawn", Host_PreSpawn_f);
        Cmd_AddCommand ("spawn", Host_Spawn_f);
        Cmd_AddCommand ("begin", Host_Begin_f);
index 5214f33..6de3550 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -170,6 +170,8 @@ char *ENGINE_EXTENSIONS =
 "PRYDON_CLIENTCURSOR "
 "TENEBRAE_GFX_DLIGHTS "
 "TW_SV_STEPCONTROL "
+"NEXUIZ_PLAYERMODEL "
+"NEXUIZ_PLAYERSKIN "
 ;
 
 qboolean checkextension(char *name)
index 3e20a98..884bff1 100644 (file)
@@ -235,6 +235,9 @@ void ED_ClearEdict (edict_t *e)
                e->v->netname = PR_SetString(svs.clients[num].name);
                if ((val = GETEDICTFIELDVALUE(e, eval_clientcolors)))
                        val->_float = svs.clients[num].colors;
+               // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
+               e->v->playermodel = PR_SetString(svs.clients[num].playermodel);
+               e->v->playerskin = PR_SetString(svs.clients[num].playerskin);
        }
 }
 
@@ -1269,7 +1272,9 @@ dpfield_t dpfields[] =
        {ev_vector, "cursor_trace_endpos"},
        {ev_vector, "cursor_trace_start"},
        {ev_vector, "movement"},
-       {ev_vector, "punchvector"}
+       {ev_vector, "punchvector"},
+       {ev_string, "playermodel"},
+       {ev_string, "playerskin"}
 };
 
 /*
index 14e2e91..82b589d 100644 (file)
@@ -161,6 +161,8 @@ typedef struct
        string_t        noise1;
        string_t        noise2;
        string_t        noise3;
+       string_t        playermodel;
+       string_t        playerskin;
 } entvars_t;
 
 #define PROGHEADER_CRC 5927
index f42c67e..70a8348 100644 (file)
--- a/server.h
+++ b/server.h
@@ -160,6 +160,8 @@ typedef struct client_s
        char name[64], old_name[64];
        int colors, old_colors;
        int frags, old_frags;
+       char playermodel[MAX_QPATH], old_model[MAX_QPATH];
+       char playerskin[MAX_QPATH], old_skin[MAX_QPATH];
 
        // visibility state
        float visibletime[MAX_EDICTS];
index 833129f..b7d9a8e 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -1119,6 +1119,8 @@ void SV_UpdateToReliableMessages (void)
        client_t *client;
        eval_t *val;
        char *name;
+       char *model;
+       char *skin;
 
 // check for changes to be sent over the reliable streams
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
@@ -1157,6 +1159,22 @@ void SV_UpdateToReliableMessages (void)
                        MSG_WriteByte (&sv.reliable_datagram, host_client->colors);
                }
 
+               // NEXUIZ_PLAYERMODEL
+               model = PR_GetString(host_client->edict->v->playermodel);
+               if (model == NULL)
+                       model = "";
+               // always point the string back at host_client->name to keep it safe
+               strlcpy (host_client->playermodel, model, sizeof (host_client->playermodel));
+               host_client->edict->v->playermodel = PR_SetString(host_client->playermodel);
+
+               // NEXUIZ_PLAYERSKIN
+               skin = PR_GetString(host_client->edict->v->playerskin);
+               if (skin == NULL)
+                       skin = "";
+               // always point the string back at host_client->name to keep it safe
+               strlcpy (host_client->playerskin, skin, sizeof (host_client->playerskin));
+               host_client->edict->v->playerskin = PR_SetString(host_client->playerskin);
+
                // frags
                host_client->frags = (int)host_client->edict->v->frags;
                if (host_client->old_frags != host_client->frags)
index 4d76775..63c54c6 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -788,6 +788,8 @@ void SV_ReadClientMessage(void)
                         || strncasecmp(s, "ban", 3) == 0
                         || strncasecmp(s, "pmodel", 6) == 0
                         || strncasecmp(s, "rate", 4) == 0
+                        || strncasecmp(s, "playermodel", 11) == 0
+                        || strncasecmp(s, "playerskin", 10) == 00
                         || (gamemode == GAME_NEHAHRA && (strncasecmp(s, "max", 3) == 0 || strncasecmp(s, "monster", 7) == 0 || strncasecmp(s, "scrag", 5) == 0 || strncasecmp(s, "gimme", 5) == 0 || strncasecmp(s, "wraith", 6) == 0))
                         || (gamemode != GAME_NEHAHRA && (strncasecmp(s, "god", 3) == 0 || strncasecmp(s, "notarget", 8) == 0 || strncasecmp(s, "fly", 3) == 0 || strncasecmp(s, "give", 4) == 0 || strncasecmp(s, "noclip", 6) == 0)))
                                Cmd_ExecuteString (s, src_client);
diff --git a/todo b/todo
index f4a7385..4ada1f6 100644 (file)
--- a/todo
+++ b/todo
 0 darkplaces optimize: put patches on a delayed queue in q3bsp collision code so the trace is first clipped by brushes
 0 darkplaces optimize: remove the loop unrolling in Image_Resample32LerpLine and Image_Resample24LerpLine and related functions, as the loop is really too long to get much benefit, and it might even not fit in the L1 instruction cache on Pentium1 (fuh)
 0 darkplaces optimize: support GL_ATI_separate_stencil since ATI does not support GL_EXT_stencil_two_side yet (romi)
-0 darkplaces parse: support " as an end token for words in Com_Parse
-0 darkplaces parse: support ' quoted strings
+d darkplaces parse: support " as an end token for words in Com_Parse
+d darkplaces parse: support ' quoted strings
 0 darkplaces physics: figure out why monsters keep making fall pain sound after they've landed in dpmod (Cruaich)
 0 darkplaces physics: q3bsp collisions are still glitchy, particularly gunshots hitting thin air near brushes, even with mod_q3bsp_optimizedtraceline 0, test in dpdm2r by shooting down through gaps in the architecture around the top platform (Vermeulen)
 0 darkplaces physics: test TecnoX and find the frikbot crash in SV_Physics (KrimZon)
-0 darkplaces protocol: GAME_NEXUIZ: add a NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN extension which would add playermodel and playerskin commands and set them up like the Host_Name_f stuff works, this means a command for each, saved _cl_playermodel and _cl_playerskin cvars, playermodel and playerskin fields in the client_t struct, and quakec fields to allow access to these similarly to .clientcolors (Vermeulen, Black, VorteX)
+d darkplaces protocol: GAME_NEXUIZ: add a NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN extension which would add playermodel and playerskin commands and set them up like the Host_Name_f stuff works, this means a command for each, saved _cl_playermodel and _cl_playerskin cvars, playermodel and playerskin fields in the client_t struct, and quakec fields to allow access to these similarly to .clientcolors (Vermeulen, Black, VorteX)
 0 darkplaces protocol: PRYDON_CLIENTCURSOR should use a stat and .prydoncursor field instead of the cl_prydoncursor cvar, because stuffcmd is a bit icky (FrikaC)
 0 darkplaces protocol: add DP_GFX_QUAKE3MODELTAGS_ATTACHMENTTYPE extension to allow attachments to affect only origin or only orientation, and enable/disable client camera turning while attached (Urre)
 0 darkplaces protocol: add DP_SENSITIVITYSCALE extension which scales sensitivity on client like viewzoom does, but without affecting fov, note if this is non-zero it overrides viewzoom sensitivity entirely, it does not scale it (Urre)