#include "main.qh"
#include <common/effects/qc/all.qh>
-#include "hud/all.qh"
+#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>
binddb = db_create();
tempdb = db_create();
ClientProgsDB = db_load("client.db");
- compressShortVector_init();
draw_endBoldFont();
registercvar("cl_spawn_near_teammate", "1");
- gametype = 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;
{
WarpZone_Shutdown();
- remove(teams);
- remove(players);
+ delete(teams);
+ delete(players);
db_close(binddb);
db_close(tempdb);
if(autocvar_cl_db_saveasdump)
case NUM_TEAM_4:
break;
default:
- if(GetTeam(Team, false) == world)
+ 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;
case 0:
break;
default:
- if(GetTeam(Team, false) == world)
+ 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;
// player disconnected
SetTeam(e, -1);
RemovePlayer(e);
- e.sort_prev = world;
+ e.sort_prev = NULL;
//e.gotscores = 0;
}
}
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)
//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)
+ 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;
}
if(sf & p)
{
if(lf & p)
- o.(teamscores[i]) = ReadInt24_t();
+ 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)
else
angles_held_status = 0;
+ if(f & 16)
+ {
+ 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;
+ }
+ }
+
return = true;
if(newspectatee_status != spectatee_status)
spn_origin.y = ReadCoord();
spn_origin.z = ReadCoord();
+ this.team = (teamnum + 1);
+
//if(is_new)
//{
this.origin = spn_origin;
precache_model(this.mdl);
setmodel(this, this.mdl);
this.drawmask = MASK_NORMAL;
- //this.movetype = MOVETYPE_NOCLIP;
+ //this.move_movetype = MOVETYPE_NOCLIP;
//this.draw = Spawn_Draw;
+ IL_PUSH(g_drawables, this);
}*/
if(autocvar_cl_spawn_point_particles)
{
- if((serverflags & SERVERFLAG_TEAMPLAY))
+ if(teamplay)
{
switch(teamnum)
{
else { this.cnt = particleeffectnum(EFFECT_SPAWNPOINT_NEUTRAL); }
this.draw = Spawn_Draw;
+ if (is_new) IL_PUSH(g_drawables, this);
setpredraw(this, Spawn_PreDraw);
this.fade_start = autocvar_cl_spawn_point_dist_min;
this.fade_end = autocvar_cl_spawn_point_dist_max;
// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
-void CSQC_Ent_Update(bool isnew)
+void CSQC_Ent_Update(entity this, bool isnew)
{
- SELFPARAM(); // needed for engine functions
this.sourceLoc = __FILE__ ":" STR(__LINE__);
int t = ReadByte();
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);
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);
}
}
// TODO possibly set more stuff to defaults
}
// 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()
+void CSQC_Ent_Remove(entity this)
{
- SELFPARAM(); // needed for engine functions
if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}\n", 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);
- remove(this);
+ delete(this);
}
void Gamemode_Init()
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();
}
if (!postinit) PostInit();
}
+float GetSpeedUnitFactor(int speed_unit)
+{
+ switch(speed_unit)
+ {
+ default:
+ case 1:
+ return 1.0;
+ case 2:
+ return 0.0254;
+ case 3:
+ return 0.0254 * 3.6;
+ case 4:
+ return 0.0254 * 3.6 * 0.6213711922;
+ case 5:
+ return 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
+ }
+}
+
+string GetSpeedUnit(int speed_unit)
+{
+ switch(speed_unit)
+ {
+ default:
+ case 1:
+ return _(" qu/s");
+ case 2:
+ return _(" m/s");
+ case 3:
+ return _(" km/h");
+ case 4:
+ return _(" mph");
+ case 5:
+ return _(" knots");
+ }
+}
+
NET_HANDLE(TE_CSQC_RACE, bool isNew)
{
int b = ReadByte();
race_server_record = ReadInt24_t();
break;
case RACE_NET_SPEED_AWARD:
- race_speedaward = ReadInt24_t();
+ race_speedaward = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
if(race_speedaward_holder)
strunzone(race_speedaward_holder);
race_speedaward_holder = strzone(ReadString());
+ if(race_speedaward_unit)
+ strunzone(race_speedaward_unit);
+ race_speedaward_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
break;
case RACE_NET_SPEED_AWARD_BEST:
- race_speedaward_alltimebest = ReadInt24_t();
+ race_speedaward_alltimebest = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
if(race_speedaward_alltimebest_holder)
strunzone(race_speedaward_alltimebest_holder);
race_speedaward_alltimebest_holder = strzone(ReadString());
+ if(race_speedaward_alltimebest_unit)
+ strunzone(race_speedaward_alltimebest_unit);
+ race_speedaward_alltimebest_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
break;
case RACE_NET_SERVER_RANKINGS:
float prevpos, del;
}
}
-string getcommandkey(string text, string command)
+string _getcommandkey(string cmd_name, string command, bool forcename)
{
string keys;
float n, j, k, l = 0;
if (!autocvar_hud_showbinds)
- return text;
+ return cmd_name;
keys = db_get(binddb, command);
if (keys == "")
if (keys == "NO_KEY") {
if (autocvar_hud_showbinds > 1)
- return sprintf(_("%s (not bound)"), text);
+ return sprintf(_("%s (not bound)"), cmd_name);
else
- return text;
+ return cmd_name;
}
- else if (autocvar_hud_showbinds > 1)
- return sprintf("%s (%s)", text, keys);
+ else if (autocvar_hud_showbinds > 1 || forcename)
+ return sprintf("%s (%s)", cmd_name, keys);
else
return keys;
}