diff --git a/src/pr2_cmds.c b/src/pr2_cmds.c index 698d064f..064b2899 100644 --- a/src/pr2_cmds.c +++ b/src/pr2_cmds.c @@ -1423,6 +1423,14 @@ void PF2_makestatic(edict_t *ent) VectorCopy(ent->v->angles, s->angles); #ifdef FTE_PEXT_TRANS s->trans = ent->xv.alpha >= 1.0f ? 0 : bound(0, (byte)(ent->xv.alpha * 254.0), 254); +#endif +#ifdef FTE_PEXT_COLOURMOD + if (ent->xv.colourmod[0] != 1.0f && ent->xv.colourmod[1] != 1.0f && ent->xv.colourmod[2] != 1.0f) + { + s->colourmod[0] = bound(0, ent->xv.colourmod[0] * (256.0f / 8.0f), 255); + s->colourmod[1] = bound(0, ent->xv.colourmod[1] * (256.0f / 8.0f), 255); + s->colourmod[2] = bound(0, ent->xv.colourmod[2] * (256.0f / 8.0f), 255); + } #endif ++sv.static_entity_count; @@ -2049,6 +2057,10 @@ static intptr_t EXT_MapExtFieldPtr(intptr_t *args) { return offsetof(ext_entvars_t, alpha) | GetExtFieldCookie(); } + if (!strcmp(key, "colormod")) + { + return offsetof(ext_entvars_t, colourmod) | GetExtFieldCookie(); + } } return 0; diff --git a/src/pr_cmds.c b/src/pr_cmds.c index ee186a97..5bcf6646 100644 --- a/src/pr_cmds.c +++ b/src/pr_cmds.c @@ -2230,6 +2230,14 @@ void PF_makestatic (void) VectorCopy(ent->v->angles, s->angles); #ifdef FTE_PEXT_TRANS s->trans = ent->xv.alpha >= 1.0f ? 0 : bound(0, (byte)(ent->xv.alpha * 254.0), 254); +#endif +#ifdef FTE_PEXT_COLOURMOD + if (ent->xv.colourmod[0] != 1.0f && ent->xv.colourmod[1] != 1.0f && ent->xv.colourmod[2] != 1.0f) + { + s->colourmod[0] = bound(0, ent->xv.colourmod[0] * (256.0f / 8.0f), 255); + s->colourmod[1] = bound(0, ent->xv.colourmod[1] * (256.0f / 8.0f), 255); + s->colourmod[2] = bound(0, ent->xv.colourmod[2] * (256.0f / 8.0f), 255); + } #endif ++sv.static_entity_count; diff --git a/src/pr_edict.c b/src/pr_edict.c index 228ab322..66c42c9d 100644 --- a/src/pr_edict.c +++ b/src/pr_edict.c @@ -928,6 +928,19 @@ const char *ED_ParseEdict (const char *data, edict_t *ent) ent->xv.alpha = bound(0.0f, atof (com_token), 1.0f); continue; } + if (!strcmp(keyname, "colormod")) + { + float v[3]; + int ret = sscanf(com_token, "%f %f %f", &v[0], &v[1], &v[2]); + if (ret == 3 && v[0] > 0.0f && v[1] > 0.0f && v[2] > 0.0f) + { + ent->xv.colourmod[0] = max(0.0f, v[0]); + ent->xv.colourmod[1] = max(0.0f, v[1]); + ent->xv.colourmod[2] = max(0.0f, v[2]); + } + continue; + } + key = ED_FindField (keyname); if (!key) { diff --git a/src/progs.h b/src/progs.h index 5b1306a4..17928f7d 100644 --- a/src/progs.h +++ b/src/progs.h @@ -66,6 +66,7 @@ typedef struct sv_edict_s typedef struct { float alpha; // 0 = opaque, 1 = opaque, 0 < x < 1 translucent + float colourmod[3]; // r,g,b [0.0 .. 1.0], > 1 overbright } ext_entvars_t; typedef struct edict_s diff --git a/src/sv_ents.c b/src/sv_ents.c index d8c72d23..63eb8d03 100644 --- a/src/sv_ents.c +++ b/src/sv_ents.c @@ -215,6 +215,13 @@ void SV_WriteDelta(client_t* client, entity_state_t *from, entity_state_t *to, s evenmorebits |= U_FTE_TRANS; #endif +#ifdef U_FTE_COLOURMOD + if ((to->colourmod[0] != from->colourmod[0] || + to->colourmod[1] != from->colourmod[1] || + to->colourmod[2] != from->colourmod[2]) && (fte_extensions & FTE_PEXT_COLOURMOD)) + evenmorebits |= U_FTE_COLOURMOD; +#endif + if (evenmorebits&0xff00) evenmorebits |= U_FTE_YETMORE; if (evenmorebits&0x00ff) @@ -299,6 +306,15 @@ void SV_WriteDelta(client_t* client, entity_state_t *from, entity_state_t *to, s if (evenmorebits & U_FTE_TRANS) MSG_WriteByte (msg, to->trans); #endif + +#ifdef U_FTE_COLOURMOD + if (evenmorebits & U_FTE_COLOURMOD) + { + MSG_WriteByte (msg, to->colourmod[0]); + MSG_WriteByte (msg, to->colourmod[1]); + MSG_WriteByte (msg, to->colourmod[2]); + } +#endif } /* @@ -628,6 +644,14 @@ static void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, by pflags |= PF_TRANS_Z; } #endif +#ifdef FTE_PEXT_COLOURMOD + if (client->fteprotocolextensions & FTE_PEXT_COLOURMOD && + (ent->xv.colourmod[0] > 0.0f && ent->xv.colourmod[1] > 0.0f && ent->xv.colourmod[2] > 0.0f) && + !(ent->xv.colourmod[0] == 1.0f && ent->xv.colourmod[1] == 1.0f && ent->xv.colourmod[2] == 1.0f)) + { + pflags |= PF_COLOURMOD; + } +#endif // Z_EXT_PM_TYPE protocol extension // encode pm_type and jump_held into pm_code @@ -680,8 +704,8 @@ static void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, by MSG_WriteByte (msg, svc_playerinfo); MSG_WriteByte (msg, j); -#ifdef FTE_PEXT_TRANS - if (client->fteprotocolextensions & FTE_PEXT_TRANS) +#if defined(FTE_PEXT_TRANS) && defined(FTE_PEXT_COLOURMOD) + if (client->fteprotocolextensions & (FTE_PEXT_TRANS | FTE_PEXT_COLOURMOD)) { if (pflags & 0xff0000) { @@ -775,6 +799,14 @@ static void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, by { MSG_WriteByte (msg, bound(1, (byte)(ent->xv.alpha * 254.0f), 254)); } +#endif +#ifdef FTE_PEXT_COLOURMOD + if (pflags & PF_COLOURMOD) + { + MSG_WriteByte(msg, bound(0, ent->xv.colourmod[0] * (256.0f / 8.0f), 255)); + MSG_WriteByte(msg, bound(0, ent->xv.colourmod[1] * (256.0f / 8.0f), 255)); + MSG_WriteByte(msg, bound(0, ent->xv.colourmod[2] * (256.0f / 8.0f), 255)); + } #endif } } @@ -1003,6 +1035,14 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qbool recorder) state->effects = TranslateEffects(ent); #ifdef FTE_PEXT_TRANS state->trans = ent->xv.alpha >= 1.0f ? 0 : bound(0, (byte)(ent->xv.alpha * 254.0f), 254); +#endif +#ifdef FTE_PEXT_COLOURMOD + if (ent->xv.colourmod[0] != 1.0f && ent->xv.colourmod[1] != 1.0f && ent->xv.colourmod[2] != 1.0f) + { + state->colourmod[0] = bound(0, ent->xv.colourmod[0] * (256.0f / 8.0f), 255); + state->colourmod[1] = bound(0, ent->xv.colourmod[1] * (256.0f / 8.0f), 255); + state->colourmod[2] = bound(0, ent->xv.colourmod[2] * (256.0f / 8.0f), 255); + } #endif } } // server flash diff --git a/src/sv_main.c b/src/sv_main.c index 31ebd4c6..7bf151f0 100644 --- a/src/sv_main.c +++ b/src/sv_main.c @@ -3573,6 +3573,9 @@ void SV_InitLocal (void) #ifdef FTE_PEXT_TRANS svs.fteprotocolextensions |= FTE_PEXT_TRANS; #endif +#ifdef FTE_PEXT_COLOURMOD + svs.fteprotocolextensions |= FTE_PEXT_COLOURMOD; +#endif #ifdef FTE_PEXT2_VOICECHAT svs.fteprotocolextensions2 |= FTE_PEXT2_VOICECHAT; #endif