// --------------------------------------------------------------------------
// BEGIN OPTIONAL CSQC FUNCTIONS
-
+.int survival_status;
void Ent_RemovePlayerScore(entity this)
{
if(this.owner) {
FOREACH(Scores, true, {
this.owner.(scores(it)) = 0; // clear all scores
});
+ this.owner.colormap = 0;
+ // TODO add a hook to reset this Survival field
+ this.owner.survival_status = 0;
}
}
make_pure(this);
int sf = 0;
serialize(byte, 0, sf);
- if (sf & BIT(1)) // make all players survivors
+ if (sf & BIT(0)) // make all players survivors
{
for (int j = 0; j < maxclients; ++j)
if (playerslots[j])
playerslots[j].survival_status = SURV_STATUS_PREY;
}
- if (sf & BIT(0)) // reveal hunters (to hunters)
+ if (sf & BIT(1)) // receive hunter statuses
{
for (int i = 1; i <= maxclients; i += 8)
{
}
}
- // we could check STAT(GAME_STOPPED) instead of this dedicated flag,
- // unfortunately STAT(GAME_STOPPED) is still false right when we receive this
- bool reveal_hunters_to_survivors = (sf & BIT(2)); // when a round ends
-
- int mystatus = playerslots[player_localnum].survival_status;
+ // color all players
for (int i = 1; i <= maxclients; ++i)
{
entity e = playerslots[i - 1];
if (!e) continue;
- int plcolor = SURV_COLOR_PREY;
- if(e.survival_status == SURV_STATUS_HUNTER && (mystatus == SURV_STATUS_HUNTER || reveal_hunters_to_survivors))
+ int plcolor = SURV_COLOR_PREY; // default color
+ if(e.survival_status == SURV_STATUS_HUNTER) // if client knows this hunter
plcolor = SURV_COLOR_HUNTER;
e.colormap = 1024 + plcolor; // override scoreboard and player model colors
return true;
}
+MUTATOR_HOOKFUNCTION(cl_surv, DrawScoreboard)
+{
+ if(!ISGAMETYPE(SURVIVAL))
+ return false;
+
+ // initialize colors of new players
+ for(entity pl = players.sort_next; pl; pl = pl.sort_next)
+ if(pl.gotscores && pl.colormap == 0)
+ pl.colormap = 1024 + SURV_COLOR_PREY;
+ return false;
+}
+
MUTATOR_HOOKFUNCTION(cl_surv, DrawScoreboard_Force)
{
// show the scoreboard when the round ends, so players can see who the hunter was
void SurvivalStatuses_Send()
{
// SendFlags can be set to anything != 0, SurvivalStatuses_SendEntity won't use its value
+ // Dr. Jaska: this was a lie, the flags were not reset until now
survivalStatuses.SendFlags = 1;
- survivalStatuses.nextthink = 0; // clear delayed send
-}
-
-void SurvivalStatuses_Send_Delayed()
-{
- survivalStatuses.think = SurvivalStatuses_Send;
- survivalStatuses.nextthink = time + 0.2;
}
bool SurvivalStatuses_SendEntity(entity this, entity dest, float sendflags)
Stream out = MSG_ENTITY;
WriteHeader(out, ENT_CLIENT_SURVIVALSTATUSES);
- sendflags |= BIT(1); // make all players survivors
-
- if (dest.survival_status == SURV_STATUS_HUNTER);
- sendflags |= BIT(0); // send hunter statuses
+ // TODO: optimize this instead of always setting it on
+ sendflags = BIT(0); // reset all flags and make all players survivors
- if (round_handler_AwaitingNextRound())
- sendflags |= (BIT(0) | BIT(2)); // send hunter statuses and reveal hunters to survivors
+ if ((dest.survival_status == SURV_STATUS_HUNTER) || round_handler_AwaitingNextRound())
+ sendflags |= BIT(1); // send hunter statuses
serialize(byte, out, sendflags);
- if (sendflags & BIT(0)) {
+ if (sendflags & BIT(1)) {
for (int i = 1; i <= maxclients; i += 8) {
int f = 0;
entity e = edict_num(i);
serialize(byte, out, f);
}
}
+ //print(sprintf("sent flags %f to %s\n", sendflags, dest.netname));
return true;
}
if (!warmup_stage)
eliminatedPlayers.SendFlags |= 1;
- // send statuses with a small delay to make sure a playerslot exists, otherwise
- // personal colors for this player won't be overriden
- // it also reduces network traffic when multiple clients join the server at once (at map start)
- SurvivalStatuses_Send_Delayed();
}
MUTATOR_HOOKFUNCTION(surv, reset_map_players)
}
});
bot_relinkplayerlist();
- // this will also clear scheduled SurvivalStatuses_Send set by PutClientInServer
SurvivalStatuses_Send();
return true;
}