diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index dff1c2965..0e1ff9cfe 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1647,6 +1647,10 @@ void CLQ2_ParseServerData (void) // if ((*str && (!fs_gamedirvar->string || !*fs_gamedirvar->string || strcmp(fs_gamedirvar->string, str))) || (!*str && (fs_gamedirvar->string || *fs_gamedirvar->string))) // Cvar_Set("game", str); + Cvar_Get("timescale", "1", 0, "Q2Admin hacks"); //Q2Admin will kick players who have a timescale set to something other than 1 + //FTE doesn't actually have a timescale cvar, so create one to fool q2admin. + //I can't really blame q2admin for rejecting engines that don't have this cvar, as it could have been renamed via a hex-edit. + CL_ClearState (); cl.minpitch = -89; cl.maxpitch = 89; @@ -1661,6 +1665,9 @@ void CLQ2_ParseServerData (void) CL_RegisterSplitCommands(); cl.spectator = false; + cl.numq2visibleweapons = 1; //give it a default. + cl.q2visibleweapons[0] = "weapon.md2"; + // get the full level name str = MSG_ReadString (); Q_strncpyz (cl.levelname, str, sizeof(cl.levelname)); @@ -2268,7 +2275,17 @@ void CLQ2_ParseConfigString (void) // if (cl.refresh_prepped) { Q_strncpyz(cl.model_name[i-Q2CS_MODELS], s, MAX_QPATH); - cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], false); + if (cl.model_name[i-Q2CS_MODELS][0] == '#') + { + if (cl.numq2visibleweapons < Q2MAX_VISIBLE_WEAPONS) + { + cl.q2visibleweapons[cl.numq2visibleweapons] = cl.model_name[i-Q2CS_MODELS]+1; + cl.numq2visibleweapons++; + } + cl.model_precache[i-Q2CS_MODELS] = NULL; + } + else + cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], false); } } else if (i >= Q2CS_SOUNDS && i < Q2CS_SOUNDS+Q2MAX_MODELS) @@ -2574,6 +2591,19 @@ void CLQ2_ParseStartSoundPacket(void) if (!cl.sound_precache[sound_num]) return; + if (cl.sound_precache[sound_num]->name[0] == '*' && ent > 0 && ent <= MAX_CLIENTS) + { //a 'sexed' sound + char *model = Info_ValueForKey(cl.players[ent-1].userinfo, "skin"); + char *skin; + skin = strchr(model, '/'); + if (skin) + *skin = '\0'; + if (*model) + { + S_StartSound (ent, channel, S_PrecacheSound(va("players/%s/%s", model, cl.sound_precache[sound_num]->name+1)), pos, volume, attenuation); + return; + } + } S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume, attenuation); } #endif diff --git a/engine/client/client.h b/engine/client/client.h index f9830abc3..fa110223e 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -501,7 +501,11 @@ typedef struct float punchangle[MAX_SPLITS]; // temporar yview kick from weapon firing int intermission; // don't change view angle, full screen, etc - int completed_time; // latched ffrom time at intermission start + float completed_time; // latched ffrom time at intermission start + +#define Q2MAX_VISIBLE_WEAPONS 32 //q2 has about 20. + int numq2visibleweapons; //q2 sends out visible-on-model weapons in a wierd gender-nutral way. + char *q2visibleweapons[Q2MAX_VISIBLE_WEAPONS];//model names beginning with a # are considered 'sexed', and are loaded on a per-client basis. yay. :( // // information that is static for the entire time connected to a server diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index b6a76a8fc..b24fc9868 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1533,7 +1533,9 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) if (s1->number == cl.playernum[0]+1) //woo! this is us! { - ent.flags |= Q2RF_EXTERNALMODEL; // only draw from mirrors +// VectorCopy(cl.predicted_origin, ent.origin); +// VectorCopy(cl.predicted_origin, ent.oldorigin); +// ent.flags |= Q2RF_EXTERNALMODEL; // only draw from mirrors if (effects & Q2EF_FLAG1) V_AddLight (ent.origin, 225, 0.2, 0.05, 0.05); @@ -1645,7 +1647,18 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) { if (s1->modelindex2 == 255) { // custom weapon + char *modelname = "male"; + char *skin; ent.model=NULL; + + player = &cl.players[(s1->skinnum&0xff)%MAX_CLIENTS]; + modelname = Info_ValueForKey(player->userinfo, "skin"); + skin = strchr(modelname, '/'); + if (skin) *skin = '\0'; + + i = (s1->skinnum >> 8); // 0 is default weapon model + if (i >= 0 && i < cl.numq2visibleweapons) + ent.model = Mod_ForName(va("players/%s/%s", modelname, cl.q2visibleweapons[i]), false); /* ci = &cl.clientinfo[s1->skinnum & 0xff]; i = (s1->skinnum >> 8); // 0 is default weapon model @@ -1868,6 +1881,9 @@ void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops) if (!r_drawviewmodel.value) return; + if (!Cam_DrawViewModel(0)) + return; + // don't draw gun if in wide angle view if (ps->fov > 90) return;