#define PHYS_INPUT_BUTTON_ZOOM(s) PHYS_INPUT_BUTTON_BUTTON4(s)
#define PHYS_INPUT_BUTTON_CROUCH(s) PHYS_INPUT_BUTTON_BUTTON5(s)
#define PHYS_INPUT_BUTTON_HOOK(s) PHYS_INPUT_BUTTON_BUTTON6(s)
+
+#ifdef CSQC
+STATIC_INIT(PHYS_INPUT_BUTTON_HOOK)
+{
+ localcmd("alias +hook +button6\n");
+ localcmd("alias -hook -button6\n");
+}
+#endif
+
#define PHYS_INPUT_BUTTON_INFO(s) PHYS_INPUT_BUTTON_BUTTON7(s)
#define PHYS_INPUT_BUTTON_DRAG(s) PHYS_INPUT_BUTTON_BUTTON8(s)
#define PHYS_INPUT_BUTTON_USE(s) PHYS_INPUT_BUTTON_BUTTON_USE(s)
#define PHYS_INPUT_BUTTON_ZOOMSCRIPT(s) PHYS_INPUT_BUTTON_BUTTON9(s)
#define PHYS_INPUT_BUTTON_JETPACK(s) PHYS_INPUT_BUTTON_BUTTON10(s)
+#ifdef CSQC
+STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
+{
+ localcmd("alias +jetpack +button10\n");
+ localcmd("alias -jetpack -button10\n");
+}
+#endif
+
// if more buttons are needed, start using impulse bits as buttons
#define PHYS_INPUT_BUTTON_BACKWARD(s) (PHYS_INPUT_MOVEVALUES(s).x < 0)
PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; }
#endif
+void Inventory_new(entity this);
+void Inventory_delete(entity this);
+
+// TODO: renew on death
+
void PlayerState_attach(entity this)
{
- // TODO: dynamic
- // this._ps = NEW(PlayerState, this);
+ this._ps = NEW(PlayerState, this);
+
+ Inventory_new(this);
}
void PlayerState_detach(entity this)
{
- // TODO: dynamic
- // if (!PS(this)) return; // initial connect
- // remove(PS(this));
- // this._ps = NULL;
+ if (!PS(this)) return; // initial connect
+ remove(PS(this));
+ this._ps = NULL;
+
+ Inventory_delete(self);
}
/**
ClientState CS(entity this) { assert(IS_CLIENT(this)); assert(this._cs); return this._cs; }
#endif
+void GetCvars(int);
+void DecodeLevelParms(entity this);
+void PlayerScore_Attach(entity this);
+void ClientData_Attach(entity this);
+void accuracy_init(entity this);
+void entcs_attach(entity this);
+void playerdemo_init(entity this);
+void anticheat_init(entity this);
+void W_HitPlotOpen(entity this);
+void bot_clientconnect(entity this);
+
void ClientState_attach(entity this)
{
this._cs = NEW(ClientState, this);
- this._ps = NEW(PlayerState, this); // TODO: dynamic
+
+ GetCvars(0); // get other cvars from player
+
+ // TODO: xonstat elo.txt support, until then just 404s
+ if (false && IS_REAL_CLIENT(this)) { PlayerStats_PlayerBasic_CheckUpdate(this); }
+
+ // TODO: fold all of these into ClientState
+
+ DecodeLevelParms(this);
+
+ PlayerScore_Attach(this);
+ ClientData_Attach(this);
+ accuracy_init(this);
+ entcs_attach(this);
+ playerdemo_init(this);
+ anticheat_init(this);
+ W_HitPlotOpen(this);
+
+ bot_clientconnect(this);
}
+void bot_clientdisconnect();
+void W_HitPlotClose(entity this);
+void anticheat_report();
+void playerdemo_shutdown();
+void entcs_detach(entity this);
+void accuracy_free(entity this);
+void ClientData_Detach(entity this);
+void PlayerScore_Detach(entity this);
+
void ClientState_detach(entity this)
{
remove(CS(this));
this._cs = NULL;
- this._ps = NULL; // TODO: dynamic
+
+ GetCvars(-1); // free cvars
+
+ bot_clientdisconnect();
+
+ W_HitPlotClose(this);
+ anticheat_report();
+ playerdemo_shutdown();
+ entcs_detach(this);
+ accuracy_free(self);
+ ClientData_Detach(this);
+ PlayerScore_Detach(self);
}
setsize (self, STAT(PL_CROUCH_MIN, NULL), STAT(PL_CROUCH_MAX, NULL)); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
- PS(self).m_weapon = WEP_Null;
self.weaponname = "";
- PS(self).m_switchingweapon = WEP_Null;
self.weaponmodel = "";
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
#endif
this.version_nagtime = time + 10 + random() * 10;
- // TODO: xonstat elo.txt support, until then just 404s
- if (false && IS_REAL_CLIENT(this)) { PlayerStats_PlayerBasic_CheckUpdate(this); }
-
ClientState_attach(this);
- // TODO: fold all of these into ClientState
- DecodeLevelParms(this);
- PlayerScore_Attach(this);
- ClientData_Attach(this);
- accuracy_init(this);
- Inventory_new(this);
- playerdemo_init(this);
- anticheat_init(this);
- entcs_attach(this);
- W_HitPlotOpen(this);
-
- bot_clientconnect(this);
// identify the right forced team
if (autocvar_g_campaign)
FixClientCvars(this);
- // Grappling hook
- stuffcmd(this, "alias +hook +button6\n");
- stuffcmd(this, "alias -hook -button6\n");
-
- // Jetpack binds
- stuffcmd(this, "alias +jetpack +button10\n");
- stuffcmd(this, "alias -jetpack -button10\n");
-
// get version info from player
stuffcmd(this, "cmd clientversion $gameversion\n");
- // get other cvars from player
- GetCvars(0);
-
// notify about available teams
if (teamplay)
{
*/
.entity chatbubbleentity;
void ReadyCount();
-void ClientDisconnect ()
+void ClientDisconnect()
{
SELFPARAM();
- ClientState_detach(this);
- if(self.vehicle)
- vehicles_exit(VHEF_RELEASE);
+ assert(IS_CLIENT(this), return);
- if (!IS_CLIENT(self))
- {
- LOG_INFO("Warning: ClientDisconnect without ClientConnect\n");
- return;
- }
-
- PlayerStats_GameReport_FinalizePlayer(self);
-
- if ( self.active_minigame )
- part_minigame(self);
-
- if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); }
+ PlayerStats_GameReport_FinalizePlayer(this);
+ if (this.vehicle) vehicles_exit(VHEF_RELEASE);
+ if (this.active_minigame) part_minigame(this);
+ if (IS_PLAYER(this)) Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1);
- CheatShutdownClient();
-
- W_HitPlotClose(self);
-
- anticheat_report();
- anticheat_shutdown();
-
- playerdemo_shutdown();
-
- bot_clientdisconnect();
-
- entcs_detach(self);
+ if (autocvar_sv_eventlog)
+ GameLogEcho(strcat(":part:", ftos(this.playerid)));
- if(autocvar_sv_eventlog)
- GameLogEcho(strcat(":part:", ftos(self.playerid)));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, this.netname);
- Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
+ MUTATOR_CALLHOOK(ClientDisconnect);
- MUTATOR_CALLHOOK(ClientDisconnect);
+ ClientState_detach(this);
Portal_ClearAll(self);
self.flags &= ~FL_CLIENT;
- if (self.chatbubbleentity)
- remove (self.chatbubbleentity);
-
- if (self.killindicator)
- remove (self.killindicator);
+ if (this.chatbubbleentity) remove(this.chatbubbleentity);
+ if (this.killindicator) remove(this.killindicator);
WaypointSprite_PlayerGone();
bot_relinkplayerlist();
- accuracy_free(self);
- Inventory_delete(self);
- ClientData_Detach(this);
- PlayerScore_Detach(self);
-
- if(self.netname_previous)
- strunzone(self.netname_previous);
- if(self.clientstatus)
- strunzone(self.clientstatus);
- if(self.weaponorder_byimpulse)
- strunzone(self.weaponorder_byimpulse);
+ if (self.netname_previous) strunzone(self.netname_previous);
+ if (self.clientstatus) strunzone(self.clientstatus);
+ if (self.weaponorder_byimpulse) strunzone(self.weaponorder_byimpulse);
+ if (self.personal) remove(self.personal);
- if(self.personal)
- remove(self.personal);
-
- self.playerid = 0;
+ this.playerid = 0;
ReadyCount();
- if(vote_called)
- if(IS_REAL_CLIENT(self))
- VoteCount(false);
-
- // free cvars
- GetCvars(-1);
+ if (vote_called && IS_REAL_CLIENT(this)) VoteCount(false);
}
void ChatBubbleThink()