string autocvar_sv_quickmenu_file;
bool autocvar_sv_servermodelsonly;
bool autocvar_sv_showspectators;
-int autocvar_sv_spectate;
+bool autocvar_sv_spectate;
bool autocvar_sv_teamnagger;
float autocvar_sv_player_scale;
.int spectatee_status;
.bool zoomstate;
+/// > 0 is a team index, if wants_join == -1 the player can't have the team they selected (conflict)
+.int team_selected;
.bool just_joined;
+/// > 0 is a team index, -1 means team selection is deferred until Join()
+.int wants_join;
.int pressedkeys;
void ClientState_attach(entity this);
-IntrusiveList g_players;
-STATIC_INIT(g_players) { g_players = IL_NEW(); }
-
CLASS(Client, Object)
/** Client name */
ATTRIB(Client, netname, string, this.netname);
ATTRIB(Client, teamkill_soundsource, entity, this.teamkill_soundsource);
ATTRIB(Client, usekeypressed, bool, this.usekeypressed);
ATTRIB(Client, jointime, float, this.jointime);
+ ATTRIB(Client, wants_join, int, this.wants_join);
ATTRIB(Client, spectatortime, float, this.spectatortime);
ATTRIB(Client, startplaytime, float, this.startplaytime);
ATTRIB(Client, version_nagtime, float, this.version_nagtime);
ATTRIB(Client, cvar_cl_pokenade_type, string, this.cvar_cl_pokenade_type);
ATTRIB(Client, cvar_cl_spawn_near_teammate, bool, this.cvar_cl_spawn_near_teammate);
ATTRIB(Client, cvar_cl_gunalign, int, this.cvar_cl_gunalign);
- ATTRIB(Client, cvar_cl_handicap, float, this.cvar_cl_handicap);
+ ATTRIB(Client, cvar_cl_handicap_damage_given, float, this.cvar_cl_handicap_damage_given);
+ ATTRIB(Client, cvar_cl_handicap_damage_taken, float, this.cvar_cl_handicap_damage_taken);
ATTRIB(Client, cvar_cl_clippedspectating, bool, this.cvar_cl_clippedspectating);
ATTRIB(Client, cvar_cl_autoscreenshot, int, this.cvar_cl_autoscreenshot);
ATTRIB(Client, cvar_cl_jetpack_jump, bool, this.cvar_cl_jetpack_jump);
INIT(Player) {
this.classname = STR_PLAYER;
- IL_PUSH(g_players, this);
}
DESTRUCTOR(Player) {
- IL_REMOVE(g_players, this);
}
ENDCLASS(Player)
.int killcount;
-//flood fields
-.float nickspamtime; // time of last nick change
-.float nickspamcount;
-
void SendWelcomeMessage(entity this, int msg_type);
// respawning
const int RESPAWN_SILENT = BIT(1);
const int RESPAWN_DENY = BIT(2);
-float blockSpectators; // if set, new or existing spectators or observers will be removed unless they become a player within g_maxplayers_spectator_blocktime seconds
.float spectatortime; // point in time since the client is spectating or observing
.bool player_blocked;
void ClientData_Touch(entity e);
-int nJoinAllowed(entity this, entity ignore);
-
void PlayerUseKey(entity this);
void FixClientCvars(entity e);
.void(entity this, entity player) init_for_player;
IntrusiveList g_initforplayer;
-STATIC_INIT(g_initforplayer) { g_initforplayer = IL_NEW(); }
+IntrusiveList g_observepoints;
+STATIC_INIT(client_lists)
+{
+ g_initforplayer = IL_NEW();
+ g_observepoints = IL_NEW();
+}
void play_countdown(entity this, float finished, Sound samp);
void player_powerups_remove_all(entity this);
int GetPlayerLimit();
const int MIN_SPEC_TIME = 1;
-bool joinAllowed(entity this);
-void Join(entity this);
+void Join(entity this, bool queued_join);
+int nJoinAllowed(entity this, entity ignore);
+bool joinAllowed(entity this, int team_index);
+
+void PlayerFrame (entity this);
#define SPECTATE_COPY() ACCUMULATE void SpectateCopy(entity this, entity spectatee)
#define SPECTATE_COPYFIELD(fld) SPECTATE_COPY() { this.(fld) = spectatee.(fld); }