From 8a1bae9e4de4dbb479679b2c77765beb689e33b8 Mon Sep 17 00:00:00 2001 From: black Date: Thu, 2 Dec 2004 14:25:48 +0000 Subject: [PATCH] Ive done three todo items: -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 | 4 +- common.c | 23 +++++++++- host_cmd.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++ pr_cmds.c | 2 + pr_edict.c | 7 ++- progdefs.h | 2 + server.h | 2 + sv_main.c | 18 ++++++++ sv_user.c | 2 + todo | 6 +-- 10 files changed, 187 insertions(+), 8 deletions(-) diff --git a/cl_main.c b/cl_main.c index d1d5fc60..c90bec3a 100644 --- 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); diff --git a/common.c b/common.c index a6dca4ea..1414e31f 100644 --- 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) { diff --git a/host_cmd.c b/host_cmd.c index 80b62d1c..6272c143 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -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); diff --git a/pr_cmds.c b/pr_cmds.c index 5214f332..6de3550b 100644 --- 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) diff --git a/pr_edict.c b/pr_edict.c index 3e20a98d..884bff1a 100644 --- a/pr_edict.c +++ b/pr_edict.c @@ -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"} }; /* diff --git a/progdefs.h b/progdefs.h index 14e2e919..82b589d6 100644 --- a/progdefs.h +++ b/progdefs.h @@ -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 diff --git a/server.h b/server.h index f42c67ed..70a8348b 100644 --- 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]; diff --git a/sv_main.c b/sv_main.c index 833129f5..b7d9a8ee 100644 --- 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) diff --git a/sv_user.c b/sv_user.c index 4d767753..63c54c69 100644 --- 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 f4a7385a..4ada1f6c 100644 --- a/todo +++ b/todo @@ -56,12 +56,12 @@ 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) -- 2.39.2