#include "main.qh"
-#include <common/effects/qc/all.qh>
-#include "hud/all.qh"
+#include "defs.qh"
+#include <common/ent_cs.qh>
+#include "miscfunctions.qh"
+#include <common/effects/effect.qh>
+#include <common/effects/qc/_mod.qh>
+#include <common/effects/all.qh>
+#include <common/effects/all.inc>
+#include "hud/_mod.qh"
#include "mapvoting.qh"
#include "mutators/events.qh"
+#include "hud/panel/scoreboard.qh"
#include "hud/panel/quickmenu.qh"
-#include "scoreboard.qh"
#include "shownames.qh"
#include <common/t_items.qh>
#include "wall.qh"
#include "weapons/projectile.qh"
#include <common/deathtypes/all.qh>
-#include <common/items/all.qh>
+#include <common/items/_mod.qh>
#include <common/mapinfo.qh>
#include <common/minigames/cl_minigames.qh>
#include <common/minigames/cl_minigames_hud.qh>
+#include <common/net_linked.qh>
#include <common/net_notice.qh>
+#include <common/scores.qh>
#include <common/triggers/include.qh>
#include <common/vehicles/all.qh>
#include <lib/csqcmodel/cl_model.qh>
void draw_cursor(vector pos, vector ofs, string img, vector col, float a)
{
- ofs = eX * (ofs.x * SIZE_CURSOR.x) + eY * (ofs.y * SIZE_CURSOR.y);
+ ofs = vec2(ofs.x * SIZE_CURSOR.x, ofs.y * SIZE_CURSOR.y);
drawpic(pos - ofs, strcat(draw_currentSkin, img), SIZE_CURSOR, col, a, DRAWFLAG_NORMAL);
}
prvm_language = strzone(cvar_string("prvm_language"));
#ifdef WATERMARK
- LOG_INFOF("^4CSQC Build information: ^1%s\n", WATERMARK);
+ LOG_INFOF("^4CSQC Build information: ^1%s", WATERMARK);
#endif
{
binddb = db_create();
tempdb = db_create();
ClientProgsDB = db_load("client.db");
- compressShortVector_init();
draw_endBoldFont();
registercvar("cl_spawn_near_teammate", "1");
- gametype = 0;
+ if(autocvar_cl_lockview)
+ cvar_set("cl_lockview", "0");
- // hud_fields uses strunzone on the titles!
- for(int i = 0; i < MAX_HUD_FIELDS; ++i)
- hud_title[i] = strzone("(null)");
-
- Cmd_HUD_SetFields(0);
+ gametype = NULL;
postinit = false;
GetTeam(NUM_SPECTATOR, true); // add specs first
+ for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
+ weapon_accuracy[w] = -1;
+
// precaches
if(autocvar_cl_reticle)
localcmd("\ncl_hook_gameend\n");
}
+ localcmd("\ncl_hook_shutdown\n");
+
deactivate_minigame();
HUD_MinigameMenu_Close(NULL, NULL, NULL);
}
default:
if(GetTeam(Team, false) == NULL)
{
- LOG_TRACEF("trying to switch to unsupported team %d\n", Team);
+ LOG_TRACEF("trying to switch to unsupported team %d", Team);
Team = NUM_SPECTATOR;
}
break;
default:
if(GetTeam(Team, false) == NULL)
{
- LOG_TRACEF("trying to switch to unsupported team %d\n", Team);
+ LOG_TRACEF("trying to switch to unsupported team %d", Team);
Team = NUM_SPECTATOR;
}
break;
e.ping_movementloss = 0;
//e.gotscores = 0; // we might already have the scores...
int t = entcs_GetScoreTeam(i);
- if (t) SetTeam(e, t); // will not hurt; later updates come with HUD_UpdatePlayerTeams
+ if (t) SetTeam(e, t); // will not hurt; later updates come with Scoreboard_UpdatePlayerTeams
RegisterPlayer(e);
- HUD_UpdatePlayerPos(e);
+ Scoreboard_UpdatePlayerPos(e);
}
}
}
if(this.owner) {
SetTeam(this.owner, -1);
this.owner.gotscores = 0;
- for(int i = 0; i < MAX_SCORE; ++i) {
- this.owner.(scores[i]) = 0; // clear all scores
- }
+ FOREACH(Scores, true, {
+ this.owner.(scores(it)) = 0; // clear all scores
+ });
}
}
NET_HANDLE(ENT_CLIENT_SCORES, bool isnew)
{
make_pure(this);
- int i, n;
- bool isNew;
entity o;
// damnit -.- don't want to go change every single .sv_entnum in hud.qc AGAIN
// (no I've never heard of M-x replace-string, sed, or anything like that)
- isNew = !this.owner; // workaround for DP bug
- n = ReadByte()-1;
+ bool isNew = !this.owner; // workaround for DP bug
+ int n = ReadByte()-1;
#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
if(!isNew && n != this.sv_entnum)
{
//print("A CSQC entity changed its owner!\n");
- LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", etof(this), this.classname);
+ LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)", etof(this), this.classname);
isNew = true;
Ent_Remove(this);
}
// RegisterPlayer(o);
//playerchecker will do this for us later, if it has not already done so
- int sf, lf;
-#if MAX_SCORE <= 8
- sf = ReadByte();
- lf = ReadByte();
-#else
- sf = ReadShort();
- lf = ReadShort();
-#endif
- int p;
- for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
- if(sf & p)
+ int sf = ReadShort();
+ int lf = ReadShort();
+ FOREACH(Scores, true, {
+ int p = 1 << (i % 16);
+ if (sf & p)
{
- if(lf & p)
- o.(scores[i]) = ReadInt24_t();
+ if (lf & p)
+ o.(scores(it)) = ReadInt24_t();
else
- o.(scores[i]) = ReadChar();
+ o.(scores(it)) = ReadChar();
}
+ });
return = true;
if(o.sort_prev)
- HUD_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
+ Scoreboard_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
this.entremove = Ent_RemovePlayerScore;
}
{
make_pure(this);
int i;
- entity o;
this.team = ReadByte();
- o = this.owner = GetTeam(this.team, true); // these team numbers can always be trusted
+ entity o = this.owner = GetTeam(this.team, true); // these team numbers can always be trusted
- int sf, lf;
#if MAX_TEAMSCORE <= 8
- sf = ReadByte();
- lf = ReadByte();
+ int sf = ReadByte();
+ int lf = ReadByte();
#else
- sf = ReadShort();
- lf = ReadShort();
+ int sf = ReadShort();
+ int lf = ReadShort();
#endif
- int p;
- for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
- if(sf & p)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
+ if(sf & BIT(i))
{
- if(lf & p)
- o.(teamscores[i]) = ReadInt24_t();
+ if(lf & BIT(i))
+ o.(teamscores(i)) = ReadInt24_t();
else
- o.(teamscores[i]) = ReadChar();
+ o.(teamscores(i)) = ReadChar();
}
return = true;
- HUD_UpdateTeamPos(o);
+ Scoreboard_UpdateTeamPos(o);
}
NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
make_pure(this);
float newspectatee_status;
- int f = ReadByte();
+ int f = ReadByte();
- scoreboard_showscores_force = (f & 1);
+ scoreboard_showscores_force = (f & BIT(0));
- if(f & 2)
+ if(f & BIT(1))
{
newspectatee_status = ReadByte();
if(newspectatee_status == player_localnum + 1)
else
newspectatee_status = 0;
- spectatorbutton_zoom = (f & 4);
+ spectatorbutton_zoom = (f & BIT(2));
- if(f & 8)
+ if(f & BIT(4))
{
- angles_held_status = 1;
- angles_held.x = ReadAngle();
- angles_held.y = ReadAngle();
- angles_held.z = 0;
+ num_spectators = ReadByte();
+
+ float i, slot;
+
+ for(i = 0; i < MAX_SPECTATORS; ++i)
+ spectatorlist[i] = 0; // reset list first
+
+ for(i = 0; i < num_spectators; ++i)
+ {
+ slot = ReadByte();
+ spectatorlist[i] = slot - 1;
+ }
}
- else
- angles_held_status = 0;
return = true;
NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
{
make_pure(this);
- int i, j, b, f;
+ int i, j, b, f;
- int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
+ int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
if(!(nags & BIT(2)))
{
{
if(vote_called_vote)
strunzone(vote_called_vote);
- vote_called_vote = strzone(ColorTranslateRGB(ReadString()));
+ vote_called_vote = strzone(ReadString());
}
if(nags & 1)
for(i = 1; i <= maxclients; i += 8)
{
f = ReadByte();
- for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+ for(j = i-1, b = BIT(0); b < BIT(8); b <<= 1, ++j)
if (!(f & b))
if(playerslots[j])
playerslots[j].ready = 0;
NET_HANDLE(ENT_CLIENT_ELIMINATEDPLAYERS, bool isnew)
{
make_pure(this);
- int i, j, b, f;
-
- int sf = ReadByte();
- if(sf & 1)
- {
- for(j = 0; j < maxclients; ++j)
- if(playerslots[j])
+ int sf = 0;
+ serialize(byte, 0, sf);
+ if (sf & 1) {
+ for (int j = 0; j < maxclients; ++j) {
+ if (playerslots[j]) {
playerslots[j].eliminated = 1;
- for(i = 1; i <= maxclients; i += 8)
- {
- f = ReadByte();
- for(j = i-1, b = 1; b < 256; b *= 2, ++j)
- if (!(f & b))
- if(playerslots[j])
- playerslots[j].eliminated = 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].eliminated = 0;
+ }
+ }
}
}
return true;
NET_HANDLE(ENT_CLIENT_ACCURACY, bool isnew)
{
make_pure(this);
- int sf = ReadInt24_t();
+ int sf = ReadInt24_t();
if (sf == 0) {
for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
weapon_accuracy[w] = -1;
int f = 1;
for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
if (sf & f) {
- int b = ReadByte();
+ int b = ReadByte();
if (b == 0)
weapon_accuracy[w] = -1;
else if (b == 255)
void Spawn_Draw(entity this)
{
+ if(this.alpha <= 0)
+ return;
+
__pointparticles(this.cnt, this.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1));
}
float alph;
vector org = getpropertyvec(VF_ORIGIN);
if(this.fade_start)
- alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+ {
+ if(vdist(org - this.origin, >, this.fade_end))
+ alph = 0; // save on some processing
+ else if(vdist(org - this.origin, <, this.fade_start))
+ alph = 1; // more processing saved
+ else
+ alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+ }
else
alph = 1;
//printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
}*/
if(autocvar_cl_spawn_point_particles)
{
- if((serverflags & SERVERFLAG_TEAMPLAY))
+ if(teamplay)
{
switch(teamnum)
{
localcmd("-zoom\n");
button_zoom = false;
}
+ HUD_Radar_Hide_Maximized();
}
- HUD_Radar_Hide_Maximized();
//printf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(this.origin), entnum, player_localentnum);
}
{
if (t != this.enttype || isnew)
{
- LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", etof(this), this.entnum, this.enttype, t);
+ LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)", etof(this), this.entnum, this.enttype, t);
Ent_Remove(this);
clearentity(this);
isnew = true;
{
if (!isnew)
{
- LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", etof(this), this.entnum, t);
+ LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)", etof(this), this.entnum, t);
isnew = true;
}
}
FOREACH(LinkedEntities, it.m_id == t, {
if (isnew) this.classname = it.netname;
if (autocvar_developer_csqcentities)
- LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
+ LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
done = it.m_read(this, NULL, isnew);
MUTATOR_CALLHOOK(Ent_Update, this, isnew);
break;
time = savetime;
if (!done)
{
- LOG_FATALF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
+ LOG_FATALF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
}
}
if(this.snd_looping > 0)
{
- sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = 0;
}
// CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed. Essentially call remove(this) as well.
void CSQC_Ent_Remove(entity this)
{
- if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}\n", this, this.entnum, this.enttype);
+ if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}", this, this.entnum, this.enttype);
if (wasfreed(this))
{
- LOG_WARNING("CSQC_Ent_Remove called for already removed entity. Packet loss?\n");
+ LOG_WARN("CSQC_Ent_Remove called for already removed entity. Packet loss?");
return;
}
if (this.enttype) Ent_Remove(this);
// CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided. To execute standard behavior, simply execute localcmd with the string.
void CSQC_Parse_StuffCmd(string strMessage)
{
- if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage);
+ if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")", strMessage);
localcmd(strMessage);
}
// CSQC_Parse_Print : Provides the print string in the first parameter that the server provided. To execute standard behavior, simply execute print with the string.
void CSQC_Parse_Print(string strMessage)
{
- if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")\n", strMessage);
+ if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")", strMessage);
print(ColorTranslateRGB(strMessage));
}
// CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided.
void CSQC_Parse_CenterPrint(string strMessage)
{
- if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage);
+ if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")", strMessage);
centerprint_hud(strMessage);
}
FOREACH(TempEntities, it.m_id == nTEID, {
if (autocvar_developer_csqcentities)
- LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)\n", it.netname, nTEID);
+ LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)", it.netname, nTEID);
return it.m_read(NULL, NULL, true);
});
if (autocvar_developer_csqcentities)
- LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID);
+ LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d", nTEID);
// No special logic for this temporary entity; return 0 so the engine can handle it
return false;
NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
{
make_pure(this);
- gametype = ReadInt24_t();
+ gametype = ReadRegistered(Gametypes);
+ teamplay = _MapInfo_GetTeamPlayBool(gametype);
HUD_ModIcons_SetFunc();
- for (int i = 0; i < MAX_SCORE; ++i)
- {
- if (scores_label[i]) strunzone(scores_label[i]);
- scores_label[i] = strzone(ReadString());
- scores_flags[i] = ReadByte();
- }
+ FOREACH(Scores, true, {
+ if (scores_label(it)) strunzone(scores_label(it));
+ scores_label(it) = strzone(ReadString());
+ scores_flags(it) = ReadByte();
+ });
for (int i = 0; i < MAX_TEAMSCORE; ++i)
{
- if (teamscores_label[i]) strunzone(teamscores_label[i]);
- teamscores_label[i] = strzone(ReadString());
- teamscores_flags[i] = ReadByte();
+ if (teamscores_label(i)) strunzone(teamscores_label(i));
+ teamscores_label(i) = strzone(ReadString());
+ teamscores_flags(i) = ReadByte();
}
return = true;
- HUD_InitScores();
+ Scoreboard_InitScores();
Gamemode_Init();
}
forcefog = strzone(ReadString());
armorblockpercent = ReadByte() / 255.0;
+ damagepush_speedfactor = ReadByte() / 255.0;
serverflags = ReadByte();
race_checkpoint = ReadByte();
race_time = ReadInt24_t();
race_previousbesttime = ReadInt24_t();
+ race_mypreviousbesttime = ReadInt24_t();
if(race_previousbestname)
strunzone(race_previousbestname);
- race_previousbestname = strzone(ColorTranslateRGB(ReadString()));
+ string pbestname = ReadString();
+ if(autocvar_cl_race_cptimes_onlyself)
+ {
+ race_previousbesttime = race_mypreviousbesttime;
+ race_mypreviousbesttime = 0;
+ race_previousbestname = strzone("");
+ }
+ else
+ race_previousbestname = strzone(pbestname);
race_checkpointtime = time;
race_penaltyaccumulator = 0;
race_laptime = time; // valid
}
-
break;
case RACE_NET_CHECKPOINT_CLEAR:
race_nextcheckpoint = ReadByte();
race_nextbesttime = ReadInt24_t();
+ if(b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING) // not while spectating (matches server)
+ race_mybesttime = ReadInt24_t();
if(race_nextbestname)
strunzone(race_nextbestname);
- race_nextbestname = strzone(ColorTranslateRGB(ReadString()));
+ string newname = ReadString();
+ if(autocvar_cl_race_cptimes_onlyself && b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING)
+ {
+ race_nextbesttime = race_mybesttime;
+ race_mybesttime = 0;
+ race_nextbestname = strzone("");
+ }
+ else
+ race_nextbestname = strzone(newname);
break;
case RACE_NET_CHECKPOINT_HIT_RACE:
race_mycheckpointlapsdelta -= 256;
if(race_mycheckpointenemy)
strunzone(race_mycheckpointenemy);
- race_mycheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+ int who = ReadByte();
+ if(who)
+ race_mycheckpointenemy = strzone(entcs_GetName(who - 1));
+ else
+ race_mycheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
break;
case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
race_othercheckpointlapsdelta -= 256;
if(race_othercheckpointenemy)
strunzone(race_othercheckpointenemy);
- race_othercheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+ int what = ReadByte();
+ if(what)
+ race_othercheckpointenemy = strzone(entcs_GetName(what - 1));
+ else
+ race_othercheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
break;
case RACE_NET_PENALTY_RACE:
strunzone(grecordholder[pos-1]);
grecordholder[pos-1] = strzone(ReadString());
grecordtime[pos-1] = ReadInt24_t();
- if(grecordholder[pos-1] == entcs_GetName(player_localnum))
+ if(strdecolorize(grecordholder[pos-1]) == strdecolorize(entcs_GetName(player_localnum)))
race_myrank = pos;
break;
case RACE_NET_SERVER_STATUS:
keys = db_get(binddb, command);
if (keys == "")
{
- bool joy_detected = cvar("joy_detected");
+ bool joy_active = cvar("joy_active");
n = tokenize(findkeysforcommand(command, 0)); // uses '...' strings
for(j = 0; j < n; ++j)
{
if(k != -1)
{
string key = keynumtostring(k);
- if(!joy_detected && substring(key, 0, 3) == "JOY")
+ if(!joy_active && substring(key, 0, 3) == "JOY")
continue;
if (keys == "")