From 57a5521ab909e321deef5e56ee807cf5df12476b Mon Sep 17 00:00:00 2001 From: terencehill Date: Thu, 8 Jun 2023 18:07:18 +0200 Subject: [PATCH] Survival: refactor survival status networking to avoid sending hunter statuses to survivors --- qcsrc/common/ent_cs.qc | 5 -- .../gamemode/survival/cl_survival.qc | 46 +++++++++++++---- .../gamemodes/gamemode/survival/survival.qc | 1 + .../gamemode/survival/sv_survival.qc | 50 +++++++++++++++++++ 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/qcsrc/common/ent_cs.qc b/qcsrc/common/ent_cs.qc index b84a98ca6..85119de08 100644 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@ -157,11 +157,6 @@ ENTCS_PROP(SOLID, true, sv_solid, solid, ENTCS_SET_NORMAL, { WriteByte(chan, ent.sv_solid); }, { ent.sv_solid = ReadByte(); }) -// gamemode specific player survival status (independent of score and frags) -ENTCS_PROP(SURVIVAL_STATUS, true, survival_status, survival_status, ENTCS_SET_NORMAL, - { WriteShort(chan, ent.survival_status); }, - { ent.survival_status = ReadShort(); }) - #ifdef SVQC int ENTCS_PUBLICMASK = 0, ENTCS_PRIVATEMASK = 0; diff --git a/qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc b/qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc index 02d0907ab..72f4b83e0 100644 --- a/qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc +++ b/qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc @@ -3,14 +3,47 @@ #include #include +NET_HANDLE(ENT_CLIENT_SURVIVALSTATUSES, bool isnew) +{ + make_pure(this); + int sf = 0; + serialize(byte, 0, sf); + if (sf & BIT(1)) + { + for (int j = 0; j < maxclients; ++j) + if (playerslots[j]) + playerslots[j].survival_status = SURV_STATUS_PREY; + } + if (sf & BIT(0)) + { + for (int i = 1; i <= maxclients; i += 8) + { + int f = 0; + serialize(byte, 0, f); + for (int b = 0; b < 8; ++b) + { + if (!(f & BIT(b))) continue; + int j = i - 1 + b; + if (playerslots[j]) + playerslots[j].survival_status = SURV_STATUS_HUNTER; + } + } + } + return true; +} + void HUD_Mod_Survival(vector pos, vector mySize) { mod_active = 1; // survival should always show the mod HUD - int mystatus = entcs_receiver(player_localnum).survival_status; + int mystatus = playerslots[player_localnum].survival_status; string player_text = ""; vector player_color = '1 1 1'; //string player_icon = ""; + + if(STAT(GAMESTARTTIME) > time || STAT(ROUNDSTARTTIME) > time || entcs_IsSpectating(player_localnum)) + return; + if(mystatus == SURV_STATUS_HUNTER) { player_text = _("Hunter"); @@ -23,11 +56,6 @@ void HUD_Mod_Survival(vector pos, vector mySize) player_color = '0 1 0'; //player_icon = "player_neutral"; } - else - { - // if the player has no valid status, don't draw anything - return; - } drawstring_aspect(pos, player_text, vec2(mySize.x, mySize.y), player_color, panel_fg_alpha, DRAWFLAG_NORMAL); } @@ -40,9 +68,9 @@ MUTATOR_HOOKFUNCTION(cl_surv, ForcePlayercolors_Skip, CBC_ORDER_LAST) return false; entity player = M_ARGV(0, entity); - entity e = entcs_receiver(player.entnum - 1); - int surv_status = ((e) ? e.survival_status : 0); - int mystatus = entcs_receiver(player_localnum).survival_status; + entity e = playerslots[player.entnum - 1]; + int surv_status = ((e) ? e.survival_status : SURV_COLOR_PREY); + int mystatus = playerslots[player_localnum].survival_status; int plcolor = SURV_COLOR_PREY; // default to survivor if((mystatus == SURV_STATUS_HUNTER || intermission || STAT(GAME_STOPPED)) && surv_status == SURV_STATUS_HUNTER) diff --git a/qcsrc/common/gamemodes/gamemode/survival/survival.qc b/qcsrc/common/gamemodes/gamemode/survival/survival.qc index 1f2d14402..a8a67ad44 100644 --- a/qcsrc/common/gamemodes/gamemode/survival/survival.qc +++ b/qcsrc/common/gamemodes/gamemode/survival/survival.qc @@ -1 +1,2 @@ #include "survival.qh" +REGISTER_NET_LINKED(ENT_CLIENT_SURVIVALSTATUSES) diff --git a/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc b/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc index 223aa0787..83817ac8e 100644 --- a/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc +++ b/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc @@ -8,6 +8,53 @@ bool autocvar_g_survival_reward_survival = true; void nades_Clear(entity player); +entity survivalStatuses; +void SurvivalStatuses_Init(); + +void SurvivalStatuses_Send() +{ + // SendFlags can be set to anything != 0, SurvivalStatuses_SendEntity won't use its value + survivalStatuses.SendFlags = 1; +} + +bool SurvivalStatuses_SendEntity(entity this, entity dest, float sendflags) +{ + Stream out = MSG_ENTITY; + WriteHeader(out, ENT_CLIENT_SURVIVALSTATUSES); + + sendflags = BIT(0) | BIT(1); + + // send hunter statuses only to hunters + bool send_hunter_statuses = (dest.survival_status == SURV_STATUS_HUNTER || STAT(GAME_STOPPED)); + if (!send_hunter_statuses) + sendflags &= !BIT(0); + + serialize(byte, out, sendflags); + if (sendflags & BIT(0)) { + for (int i = 1; i <= maxclients; i += 8) { + int f = 0; + entity e = edict_num(i); + for (int b = 0; b < 8; ++b, e = nextent(e)) { + bool is_hunter = (IS_PLAYER(e) && e.survival_status == SURV_STATUS_HUNTER); + if (is_hunter) + f |= BIT(b); + } + serialize(byte, out, f); + } + } + return true; +} + +void SurvivalStatuses_Init() +{ + if(survivalStatuses) + { + backtrace("Can't spawn survivalStatuses again!"); + return; + } + Net_LinkEntity(survivalStatuses = new_pure(survivalStatuses), false, 0, SurvivalStatuses_SendEntity); +} + void Surv_UpdateScores(bool timed_out) { // give players their hard-earned kills now that the round is over @@ -119,6 +166,7 @@ void Surv_RoundStart() total_hunters++; it.survival_status = SURV_STATUS_HUNTER; }); + SurvivalStatuses_Send(); FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), { @@ -181,6 +229,7 @@ void surv_Initialize() // run at the start of a match, initiates game mode round_handler_Spawn(Surv_CheckPlayers, Surv_CheckWinner, Surv_RoundStart); round_handler_Init(5, autocvar_g_survival_warmup, autocvar_g_survival_round_timelimit); EliminatedPlayers_Init(surv_isEliminated); + SurvivalStatuses_Init(); } @@ -276,6 +325,7 @@ MUTATOR_HOOKFUNCTION(surv, reset_map_players) } }); bot_relinkplayerlist(); + SurvivalStatuses_Send(); return true; } -- 2.39.2