Xonotic
client.qc File Reference
#include "client.qh"
#include <common/csqcmodel_settings.qh>
#include <common/deathtypes/all.qh>
#include <common/effects/all.qh>
#include <common/effects/qc/globalsound.qh>
#include <common/ent_cs.qh>
#include <common/gamemodes/_mod.qh>
#include <common/gamemodes/gamemode/nexball/sv_nexball.qh>
#include <common/items/_mod.qh>
#include <common/items/inventory.qh>
#include <common/mapobjects/func/conveyor.qh>
#include <common/mapobjects/func/ladder.qh>
#include <common/mapobjects/subs.qh>
#include <common/mapobjects/target/spawnpoint.qh>
#include <common/mapobjects/teleporters.qh>
#include <common/mapobjects/trigger/counter.qh>
#include <common/mapobjects/trigger/secret.qh>
#include <common/mapobjects/trigger/swamp.qh>
#include <common/mapobjects/triggers.qh>
#include <common/minigames/sv_minigames.qh>
#include <common/monsters/sv_monsters.qh>
#include <common/mutators/mutator/instagib/sv_instagib.qh>
#include <common/mutators/mutator/nades/nades.qh>
#include <common/mutators/mutator/overkill/oknex.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
#include <common/mutators/mutator/waypoints/all.qh>
#include <common/net_linked.qh>
#include <common/net_notice.qh>
#include <common/notifications/all.qh>
#include <common/physics/player.qh>
#include <common/playerstats.qh>
#include <common/resources/sv_resources.qh>
#include <common/state.qh>
#include <common/stats.qh>
#include <common/vehicles/all.qh>
#include <common/vehicles/sv_vehicles.qh>
#include <common/viewloc.qh>
#include <common/weapons/_all.qh>
#include <common/weapons/weapon/vortex.qh>
#include <common/wepent.qh>
#include <lib/csqcmodel/sv_model.qh>
#include <lib/warpzone/common.qh>
#include <lib/warpzone/server.qh>
#include <server/anticheat.qh>
#include <server/antilag.qh>
#include <server/bot/api.qh>
#include <server/bot/default/cvars.qh>
#include <server/campaign.qh>
#include <server/chat.qh>
#include <server/cheats.qh>
#include <server/clientkill.qh>
#include <server/command/common.qh>
#include <server/command/vote.qh>
#include <server/compat/quake3.qh>
#include <server/damage.qh>
#include <server/gamelog.qh>
#include <server/handicap.qh>
#include <server/hook.qh>
#include <server/impulse.qh>
#include <server/intermission.qh>
#include <server/ipban.qh>
#include <server/main.qh>
#include <server/mutators/_mod.qh>
#include <server/player.qh>
#include <server/portals.qh>
#include <server/race.qh>
#include <server/scores.qh>
#include <server/scores_rules.qh>
#include <server/spawnpoints.qh>
#include <server/teamplay.qh>
#include <server/weapons/accuracy.qh>
#include <server/weapons/common.qh>
#include <server/weapons/hitplot.qh>
#include <server/weapons/selection.qh>
#include <server/weapons/tracing.qh>
#include <server/weapons/weaponsystem.qh>
#include <server/world.qh>
+ Include dependency graph for client.qc:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

float CalcRegen (float current, float stable, float regenfactor, float regenframetime)
 
float CalcRot (float current, float stable, float rotfactor, float rotframetime)
 
void calculate_player_respawn_time (entity this)
 
void ChatBubbleThink (entity this)
 
string CheckPlayerModel (string plyermodel)
 
void ClientConnect (entity this)
 

ClientConnect More...

 
void ClientData_Attach (entity this)
 
void ClientData_Detach (entity this)
 
bool ClientData_Send (entity this, entity to, int sf)
 
void ClientData_Touch (entity e)
 
 ClientDisconnect (this)
 
void ClientDisconnect (entity this)
 
void ClientInit_CheckUpdate (entity this)
 
void ClientInit_misc (entity this)
 
bool ClientInit_SendEntity (entity this, entity to, int sf)
 
void ClientInit_Spawn ()
 
int CountSpectators (entity player, entity to)
 
void DecodeLevelParms (entity this)
 
void DrownPlayer (entity this)
 
bool findinlist_abbrev (string tofind, string list)
 
void FixClientCvars (entity e)
 
void FixPlayermodel (entity player)
 
string GetClientVersionMessage (entity this)
 
int GetPlayerLimit ()
 
void GetPressedKeys (entity this)
 
string getwelcomemessage (entity this)
 
void Join (entity this)
 
bool joinAllowed (entity this)
 
 NET_HANDLE (fpsreport, bool)
 
int nJoinAllowed (entity this, entity ignore)
 Determines whether the player is allowed to join. More...
 
void ObserverOrSpectatorThink (entity this)
 
void play_countdown (entity this, float finished, Sound samp)
 
int player_getspecies (entity this)
 
void Player_Physics (entity this)
 
void player_powerups (entity this)
 
void player_powerups_remove_all (entity this)
 
void player_regen (entity this)
 
bool PlayerInIDList (entity p, string idlist)
 
bool PlayerInIPList (entity p, string iplist)
 
bool PlayerInList (entity player, string list)
 
void PlayerPostThink (entity this)
 
void PlayerPreThink (entity this)
 
bool PlayerThink (entity this)
 
void PlayerUseKey (entity this)
 
void PM_UpdateButtons (entity this, entity store)
 
void PrintWelcomeMessage (entity this)
 
 PutClientInServer (this)
 
void PutClientInServer (entity this)
 Called when a client spawns in the server. More...
 
void PutObserverInServer (entity this, bool is_forced, bool use_spawnpoint)
 putting a client as observer in the server More...
 
void PutPlayerInServer (entity this)
 
void respawn (entity this)
 
void RotRegen (entity this, Resource res, float limit_mod, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime)
 
void send_CSQC_teamnagger ()
 
void SetChangeParms (entity this)
 
void SetNewParms ()
 
void setplayermodel (entity e, string modelname)
 
void SetSpectatee (entity this, entity spectatee)
 
void SetSpectatee_status (entity this, int spectatee_num)
 
void SetZoomState (entity this, float newzoom)
 
void ShowRespawnCountdown (entity this)
 
bool ShowTeamSelection (entity this)
 
bool Spectate (entity this, entity pl)
 
void SpectateCopy (entity this, entity spectatee)
 
bool SpectateNext (entity this)
 
bool SpectatePrev (entity this)
 
bool SpectateSet (entity this)
 
bool SpectateUpdate (entity this)
 
 TRANSMUTE (Player, this)
 
void UpdateChatBubble (entity this)
 
void WriteSpectators (entity player, entity to)
 

Variables

entity chatbubbleentity
 
bool dualwielding_prev
 
string FallbackPlayerModel
 
this frame = 12
 
float last_vehiclecheck
 
float model_randomizer
 
bool move_qcphysics
 
string shootfromfixedorigin
 
this team = _team
 
bool team_selected
 
bool would_spectate
 
bool zoomstate_set
 

Function Documentation

◆ CalcRegen()

float CalcRegen ( float  current,
float  stable,
float  regenfactor,
float  regenframetime 
)

Definition at line 1550 of file client.qc.

References min().

Referenced by RotRegen().

1551 {
1552  if(current > stable)
1553  return current;
1554  else if(current > stable - 0.25) // when close enough, "snap"
1555  return stable;
1556  else
1557  return min(stable, current + (stable - current) * regenfactor * regenframetime);
1558 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CalcRot()

float CalcRot ( float  current,
float  stable,
float  rotfactor,
float  rotframetime 
)

Definition at line 1560 of file client.qc.

References max().

Referenced by RotRegen().

1561 {
1562  if(current < stable)
1563  return current;
1564  else if(current < stable + 0.25) // when close enough, "snap"
1565  return stable;
1566  else
1567  return max(stable, current + (stable - current) * rotfactor * rotframetime);
1568 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculate_player_respawn_time()

void calculate_player_respawn_time ( entity  this)

Definition at line 1315 of file client.qc.

References autocvar_g_forced_respawn, ceil(), FOREACH_CLIENT, GAMETYPE_DEFAULTED_SETTING, IS_INDEPENDENT_PLAYER, IS_PLAYER, MUTATOR_CALLHOOK, respawn_countdown, respawn_flags, RESPAWN_FORCE, respawn_time, respawn_time_max, teamplay, and time.

Referenced by PlayerDamage().

1316 {
1317  if(MUTATOR_CALLHOOK(CalculateRespawnTime, this))
1318  return;
1319 
1320  float gametype_setting_tmp;
1321  float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max);
1322  float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small);
1323  float sdelay_large = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large);
1324  float sdelay_small_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small_count);
1325  float sdelay_large_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large_count);
1326  float waves = GAMETYPE_DEFAULTED_SETTING(respawn_waves);
1327 
1328  float pcount = 1; // Include myself whether or not team is already set right and I'm a "player".
1329  if (teamplay)
1330  {
1331  FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
1332  if(it.team == this.team)
1333  ++pcount;
1334  });
1335  if (sdelay_small_count == 0)
1336  sdelay_small_count = 1;
1337  if (sdelay_large_count == 0)
1338  sdelay_large_count = 1;
1339  }
1340  else
1341  {
1342  FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
1343  ++pcount;
1344  });
1345  if (sdelay_small_count == 0)
1346  {
1347  if (IS_INDEPENDENT_PLAYER(this))
1348  {
1349  // Players play independently. No point in requiring enemies.
1350  sdelay_small_count = 1;
1351  }
1352  else
1353  {
1354  // Players play AGAINST each other. Enemies required.
1355  sdelay_small_count = 2;
1356  }
1357  }
1358  if (sdelay_large_count == 0)
1359  {
1360  if (IS_INDEPENDENT_PLAYER(this))
1361  {
1362  // Players play independently. No point in requiring enemies.
1363  sdelay_large_count = 1;
1364  }
1365  else
1366  {
1367  // Players play AGAINST each other. Enemies required.
1368  sdelay_large_count = 2;
1369  }
1370  }
1371  }
1372 
1373  float sdelay;
1374 
1375  if (pcount <= sdelay_small_count)
1376  sdelay = sdelay_small;
1377  else if (pcount >= sdelay_large_count)
1378  sdelay = sdelay_large;
1379  else // NOTE: this case implies sdelay_large_count > sdelay_small_count.
1380  sdelay = sdelay_small + (sdelay_large - sdelay_small) * (pcount - sdelay_small_count) / (sdelay_large_count - sdelay_small_count);
1381 
1382  if(waves)
1383  this.respawn_time = ceil((time + sdelay) / waves) * waves;
1384  else
1385  this.respawn_time = time + sdelay;
1386 
1387  if(sdelay < sdelay_max)
1388  this.respawn_time_max = time + sdelay_max;
1389  else
1390  this.respawn_time_max = this.respawn_time;
1391 
1392  if((sdelay + waves >= 5.0) && (this.respawn_time - time > 1.75))
1393  this.respawn_countdown = 10; // first number to count down from is 10
1394  else
1395  this.respawn_countdown = -1; // do not count down
1396 
1399 }
const int RESPAWN_FORCE
Definition: client.qh:330
float respawn_countdown
Definition: client.qh:328
int respawn_flags
Definition: client.qh:324
float respawn_time
Definition: client.qh:325
#define IS_INDEPENDENT_PLAYER(e)
Definition: client.qh:314
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
bool autocvar_g_forced_respawn
Definition: client.qh:42
float respawn_time_max
Definition: client.qh:326
float teamplay
Definition: progsdefs.qc:31
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
#define GAMETYPE_DEFAULTED_SETTING(str)
Definition: client.qh:352
float time
Definition: csprogsdefs.qc:16
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ChatBubbleThink()

void ChatBubbleThink ( entity  this)

Definition at line 1267 of file client.qc.

References CS(), IS_DEAD, IS_PLAYER, model, nextthink, NULL, owner, PHYS_INPUT_BUTTON_CHAT, PHYS_INPUT_BUTTON_MINIGAME, and time.

Referenced by UpdateChatBubble().

1268 {
1269  this.nextthink = time;
1270  if ((this.owner.alpha < 0) || this.owner.chatbubbleentity != this)
1271  {
1272  if(this.owner) // but why can that ever be NULL?
1273  this.owner.chatbubbleentity = NULL;
1274  delete(this);
1275  return;
1276  }
1277 
1278  this.mdl = "";
1279 
1280  if ( !IS_DEAD(this.owner) && IS_PLAYER(this.owner) )
1281  {
1282  if ( CS(this.owner).active_minigame && PHYS_INPUT_BUTTON_MINIGAME(this.owner) )
1283  this.mdl = "models/sprites/minigame_busy.iqm";
1284  else if (PHYS_INPUT_BUTTON_CHAT(this.owner))
1285  this.mdl = "models/misc/chatbubble.spr";
1286  }
1287 
1288  if ( this.model != this.mdl )
1289  _setmodel(this, this.mdl);
1290 
1291 }
#define PHYS_INPUT_BUTTON_CHAT(s)
Definition: player.qh:155
ClientState CS(Client this)
Definition: state.qh:47
entity owner
Definition: main.qh:73
string model
Definition: csprogsdefs.qc:108
#define NULL
Definition: post.qh:17
#define IS_DEAD(s)
Definition: utils.qh:26
float nextthink
Definition: csprogsdefs.qc:121
float time
Definition: csprogsdefs.qc:16
#define PHYS_INPUT_BUTTON_MINIGAME(s)
Definition: player.qh:160
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckPlayerModel()

string CheckPlayerModel ( string  plyermodel)

Definition at line 194 of file client.qc.

References autocvar_sv_servermodelsonly, cvar_defstring(), FallbackPlayerModel, fexists(), strzone(), and substring().

Referenced by FixPlayermodel().

194  {
195  if(FallbackPlayerModel != cvar_defstring("_cl_playermodel"))
196  {
197  // note: we cannot summon Don Strunzone here, some player may
198  // still have the model string set. In case anyone manages how
199  // to change a cvar default, we'll have a small leak here.
200  FallbackPlayerModel = strzone(cvar_defstring("_cl_playermodel"));
201  }
202  // only in right path
203  if(substring(plyermodel, 0, 14) != "models/player/")
204  return FallbackPlayerModel;
205  // only good file extensions
206  if(substring(plyermodel, -4, 4) != ".iqm"
207  && substring(plyermodel, -4, 4) != ".zym"
208  && substring(plyermodel, -4, 4) != ".dpm"
209  && substring(plyermodel, -4, 4) != ".md3"
210  && substring(plyermodel, -4, 4) != ".psk")
211  {
212  return FallbackPlayerModel;
213  }
214  // forbid the LOD models
215  if(substring(plyermodel, -9, 5) == "_lod1" || substring(plyermodel, -9, 5) == "_lod2")
216  return FallbackPlayerModel;
217  if(plyermodel != strtolower(plyermodel))
218  return FallbackPlayerModel;
219  // also, restrict to server models
221  {
222  if(!fexists(plyermodel))
223  return FallbackPlayerModel;
224  }
225  return plyermodel;
226 }
string FallbackPlayerModel
Definition: client.qc:193
bool autocvar_sv_servermodelsonly
Definition: client.qh:53
ERASEABLE bool fexists(string f)
Definition: file.qh:4
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientConnect()

void ClientConnect ( entity  this)


ClientConnect

Called when a client connects to the server

Definition at line 1096 of file client.qc.

References assert, autocvar_bot_vs_human, autocvar_g_campaign, autocvar_g_maxplayers_spectator_blocktime, autocvar_sv_eventlog, autocvar_sv_foginterval, autocvar_sv_teamnagger, autocvar_sv_timeout_number, AvailableTeams(), Ban_MaybeEnforceBanOnce(), blockSpectators, bot_clientconnect(), bot_relinkplayerlist(), clientstuff, CS(), entity(), etof(), FixClientCvars(), FL_CLIENT, flags, ftos(), g_initforplayer, g_weaponarena_weapons, GameLog_ProcessIP(), GameLogEcho(), getwelcomemessage(), Handicap_Initialize(), IL_EACH, IS_BOT_CLIENT, IS_CLIENT, IS_PLAYER, IS_REAL_CLIENT, move_qcphysics, MUTATOR_CALLHOOK, netaddress, netname, NULL, player_count, Player_DetermineForcedTeam(), playerid, random(), send_CSQC_teamnagger(), strcat(), stuffcmd, team, TeamBalance_CheckAllowedTeams(), TeamBalance_Destroy(), TeamBalance_GetAllowedTeams(), teamplay, time, TRANSMUTE(), WEPSET, and world.

Referenced by bot_spawn(), and Item_ItemsTime_Allow().

1097 {
1098  if (Ban_MaybeEnforceBanOnce(this)) return;
1099  assert(!IS_CLIENT(this), return);
1100  this.flags |= FL_CLIENT;
1101  assert(player_count >= 0, player_count = 0);
1102 
1103  TRANSMUTE(Client, this);
1104  CS(this).version_nagtime = time + 10 + random() * 10;
1105 
1106  Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_JOIN_CONNECT, this.netname);
1107 
1108  bot_clientconnect(this);
1109 
1111 
1112  TRANSMUTE(Observer, this);
1113 
1114  PlayerStats_GameReport_AddEvent(sprintf("kills-%d", this.playerid));
1115 
1116  // always track bots, don't ask for cl_allow_uidtracking
1117  if (IS_BOT_CLIENT(this))
1118  PlayerStats_GameReport_AddPlayer(this);
1119  else
1120  CS(this).allowed_timeouts = autocvar_sv_timeout_number;
1121 
1123  GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? GameLog_ProcessIP(this.netaddress) : "bot"), ":", playername(this.netname, this.team, false)));
1124 
1125  CS(this).just_joined = true; // stop spamming the eventlog with additional lines when the client connects
1126 
1127  stuffcmd(this, clientstuff, "\n");
1128  stuffcmd(this, "cl_particles_reloadeffects\n"); // TODO do we still need this?
1129 
1130  FixClientCvars(this);
1131 
1132  // get version info from player
1133  stuffcmd(this, "cmd clientversion $gameversion\n");
1134 
1135  // notify about available teams
1136  if (teamplay)
1137  {
1138  entity balance = TeamBalance_CheckAllowedTeams(this);
1139  int t = TeamBalance_GetAllowedTeams(balance);
1140  TeamBalance_Destroy(balance);
1141  stuffcmd(this, sprintf("set _teams_available %d\n", t));
1142  }
1143  else
1144  {
1145  stuffcmd(this, "set _teams_available 0\n");
1146  }
1147 
1149 
1150  CS(this).spectatortime = time;
1151  if (blockSpectators)
1152  {
1153  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
1154  }
1155 
1156  CS(this).jointime = time;
1157 
1158  if (IS_REAL_CLIENT(this))
1159  {
1160  if (g_weaponarena_weapons == WEPSET(TUBA))
1161  stuffcmd(this, "cl_cmd settemp chase_active 1\n");
1162  }
1163 
1164  if (!autocvar_sv_foginterval && world.fog != "")
1165  stuffcmd(this, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
1166 
1168  if(!MUTATOR_CALLHOOK(HideTeamNagger, this))
1170 
1171  CSQCMODEL_AUTOINIT(this);
1172 
1173  CS(this).model_randomizer = random();
1174 
1175  if (IS_REAL_CLIENT(this))
1176  sv_notice_join(this);
1177 
1178  this.move_qcphysics = autocvar_sv_qcphysics;
1179 
1180  // update physics stats (players can spawn before physics runs)
1181  Physics_UpdateStats(this);
1182 
1183  IL_EACH(g_initforplayer, it.init_for_player, {
1184  it.init_for_player(it, this);
1185  });
1186 
1187  Handicap_Initialize(this);
1188 
1190 
1191  if (IS_REAL_CLIENT(this))
1192  {
1193  if (!autocvar_g_campaign && !IS_PLAYER(this))
1194  {
1195  CS(this).motd_actived_time = -1;
1196  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
1197  }
1198  }
1199 }
#define WEPSET(id)
Definition: all.qh:37
string getwelcomemessage(entity this)
Definition: client.qc:1036
#define assert(expr,...)
Definition: log.qh:8
#define IL_EACH(this, cond, body)
entity world
Definition: csprogsdefs.qc:15
TRANSMUTE(Player, this)
void ClientConnect(entity this)
ClientConnect
Definition: client.qc:1096
void bot_relinkplayerlist()
Definition: bot.qc:381
float blockSpectators
Definition: client.qh:334
#define IS_CLIENT(v)
Definition: utils.qh:13
void TeamBalance_Destroy(entity balance)
Destroy the team balance entity.
Definition: teamplay.qc:627
entity() spawn
int player_count
Definition: api.qh:103
int playerid
Definition: client.qh:78
ClientState CS(Client this)
Definition: state.qh:47
string netname
Definition: powerups.qc:20
int autocvar_bot_vs_human
Definition: cvars.qh:70
bool move_qcphysics
Definition: client.qc:2627
void bot_clientconnect(entity this)
Definition: bot.qc:426
IntrusiveList g_initforplayer
Definition: client.qh:373
string clientstuff
Definition: world.qh:55
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
bool autocvar_sv_teamnagger
Definition: client.qh:55
this team
Definition: client.qc:86
int TeamBalance_GetAllowedTeams(entity balance)
Returns the bitmask of allowed teams.
Definition: teamplay.qc:640
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
int autocvar_sv_timeout_number
Definition: common.qh:8
void send_CSQC_teamnagger()
Definition: client.qc:97
#define NULL
Definition: post.qh:17
string netaddress
bool Ban_MaybeEnforceBanOnce(entity client)
Definition: ipban.qc:471
Definition: client.qh:88
int AvailableTeams()
Definition: scores_rules.qc:22
void GameLogEcho(string s)
Definition: gamelog.qc:12
float teamplay
Definition: progsdefs.qc:31
#define stuffcmd(cl,...)
Definition: progsdefs.qh:23
string GameLog_ProcessIP(string s)
Definition: gamelog.qc:5
float autocvar_sv_foginterval
Definition: client.qh:35
float flags
Definition: csprogsdefs.qc:129
float autocvar_g_maxplayers_spectator_blocktime
Definition: client.qh:44
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition: utils.qh:15
void Player_DetermineForcedTeam(entity player)
Determines the forced team of the player using current global config.
Definition: teamplay.qc:376
bool autocvar_g_campaign
Definition: campaign.qh:6
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings...
Definition: teamplay.qc:487
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
void Handicap_Initialize(entity player)
Initializes handicap to its default value.
Definition: handicap.qc:13
float time
Definition: csprogsdefs.qc:16
WepSet g_weaponarena_weapons
Definition: world.qh:77
#define IS_PLAYER(v)
Definition: utils.qh:9
void FixClientCvars(entity e)
Definition: client.qc:947
float FL_CLIENT
Definition: progsdefs.qc:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientData_Attach()

void ClientData_Attach ( entity  this)

Definition at line 158 of file client.qc.

References clientdata, ClientData_Send(), CS(), and new_pure.

Referenced by ClientState_attach(), and PlayerState_detach().

159 {
160  Net_LinkEntity(CS(this).clientdata = new_pure(clientdata), false, 0, ClientData_Send);
161  CS(this).clientdata.drawonlytoclient = this;
162  CS(this).clientdata.owner = this;
163 }
ClientState CS(Client this)
Definition: state.qh:47
entity clientdata
Definition: client.qh:62
bool ClientData_Send(entity this, entity to, int sf)
Definition: client.qc:129
#define new_pure(class)
purely logical entities (.origin doesn&#39;t work)
Definition: oo.qh:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientData_Detach()

void ClientData_Detach ( entity  this)

Definition at line 165 of file client.qc.

References CS(), and NULL.

Referenced by ClientState_attach(), and ClientState_detach().

166 {
167  delete(CS(this).clientdata);
168  CS(this).clientdata = NULL;
169 }
ClientState CS(Client this)
Definition: state.qh:47
#define NULL
Definition: post.qh:17
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientData_Send()

bool ClientData_Send ( entity  this,
entity  to,
int  sf 
)

Definition at line 129 of file client.qc.

References assert, autocvar_sv_showspectators, BIT, CountSpectators(), CS(), entity(), IS_SPEC, owner, race_completed, spectatee_status, to, WriteByte(), WriteSpectators(), and zoomstate.

Referenced by ClientData_Attach().

130 {
131  assert(to == this.owner, return false);
132 
133  entity e = to;
134  if (IS_SPEC(e)) e = e.enemy;
135 
136  sf = 0;
137  if (CS(e).race_completed) sf |= BIT(0); // forced scoreboard
138  if (CS(to).spectatee_status) sf |= BIT(1); // spectator ent number follows
139  if (CS(e).zoomstate) sf |= BIT(2); // zoomed
140  if (autocvar_sv_showspectators) sf |= BIT(4); // show spectators
141 
142  WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
143  WriteByte(MSG_ENTITY, sf);
144 
145  if (sf & BIT(1))
146  WriteByte(MSG_ENTITY, CS(to).spectatee_status);
147 
148  if(sf & BIT(4))
149  {
150  float specs = CountSpectators(e, to);
151  WriteByte(MSG_ENTITY, specs);
152  WriteSpectators(e, to);
153  }
154 
155  return true;
156 }
#define assert(expr,...)
Definition: log.qh:8
bool zoomstate
Definition: client.qh:72
entity() spawn
ClientState CS(Client this)
Definition: state.qh:47
entity to
Definition: self.qh:96
entity owner
Definition: main.qh:73
#define IS_SPEC(v)
Definition: utils.qh:10
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition: bits.qh:8
bool autocvar_sv_showspectators
Definition: client.qh:57
void WriteSpectators(entity player, entity to)
Definition: client.qc:115
float spectatee_status
Definition: main.qh:166
float race_completed
Definition: race.qh:25
int CountSpectators(entity player, entity to)
Definition: client.qc:101
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientData_Touch()

void ClientData_Touch ( entity  e)

Definition at line 171 of file client.qc.

References CS(), entity(), FOREACH_CLIENT, IS_REAL_CLIENT, and IS_SPEC.

Referenced by race_AbandonRaceCheck(), race_SendTime(), SetSpectatee(), SetSpectatee_status(), SetZoomState(), and SpectateSet().

172 {
173  entity cd = CS(e).clientdata;
174  if (cd) { cd.SendFlags = 1; }
175 
176  // make it spectatable
177  FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != e && IS_SPEC(it) && it.enemy == e,
178  {
179  entity cd = CS(it).clientdata;
180  if (cd) { cd.SendFlags = 1; }
181  });
182 }
entity() spawn
ClientState CS(Client this)
Definition: state.qh:47
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
#define IS_SPEC(v)
Definition: utils.qh:10
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientDisconnect() [1/2]

ClientDisconnect ( this  )

Referenced by ClientDisconnect().

+ Here is the caller graph for this function:

◆ ClientDisconnect() [2/2]

void ClientDisconnect ( entity  this)

Definition at line 1210 of file client.qc.

References active_minigame, assert, autocvar_sv_eventlog, bot_relinkplayerlist(), chatbubbleentity, ClientDisconnect(), ClientState_detach(), clientstatus, CS(), CS_CVAR, FL_CLIENT, flags, ftos(), GameLogEcho(), IL_EACH, IS_CLIENT, IS_PLAYER, IS_REAL_CLIENT, IS_SPEC, killindicator, MUTATOR_CALLHOOK, netname, NULL, ONREMOVE(), origin, part_minigame(), personal, player_powerups_remove_all(), playerid, Portal_ClearAll(), ReadyCount(), RemoveGrapplingHooks(), SetSpectatee(), strcat(), strfree, Unfreeze(), vehicle, vehicles_exit(), vote_called, VoteCount(), and weaponorder_byimpulse.

1211 {
1212  assert(IS_CLIENT(this), return);
1213 
1214  PlayerStats_GameReport_FinalizePlayer(this);
1215  if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
1216  if (CS(this).active_minigame) part_minigame(this);
1217  if (IS_PLAYER(this)) Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1);
1218 
1220  GameLogEcho(strcat(":part:", ftos(this.playerid)));
1221 
1222  Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_DISCONNECT, this.netname);
1223 
1224  if(IS_SPEC(this))
1225  SetSpectatee(this, NULL);
1226 
1228 
1229  strfree(CS(this).netname_previous); // needs to be before the CS entity is removed!
1231  ClientState_detach(this);
1232 
1233  Portal_ClearAll(this);
1234 
1235  Unfreeze(this, false);
1236 
1237  RemoveGrapplingHooks(this);
1238 
1239  // Here, everything has been done that requires this player to be a client.
1240 
1241  this.flags &= ~FL_CLIENT;
1242 
1243  if (this.chatbubbleentity) delete(this.chatbubbleentity);
1244  if (this.killindicator) delete(this.killindicator);
1245 
1246  IL_EACH(g_counters, it.realowner == this,
1247  {
1248  delete(it);
1249  });
1250 
1251  WaypointSprite_PlayerGone(this);
1252 
1254 
1255  strfree(this.clientstatus);
1256  if (this.personal) delete(this.personal);
1257 
1258  this.playerid = 0;
1259  ReadyCount();
1260  if (vote_called && IS_REAL_CLIENT(this)) VoteCount(false);
1261 
1262  player_powerups_remove_all(this); // stop powerup sound
1263 
1264  ONREMOVE(this);
1265 }
#define assert(expr,...)
Definition: log.qh:8
#define IL_EACH(this, cond, body)
void ReadyCount()
Definition: vote.qc:498
void bot_relinkplayerlist()
Definition: bot.qc:381
#define IS_CLIENT(v)
Definition: utils.qh:13
int playerid
Definition: client.qh:78
ClientState CS(Client this)
Definition: state.qh:47
void part_minigame(entity player)
#define CS_CVAR(this)
Definition: state.qh:51
string netname
Definition: powerups.qc:20
float vote_called
Definition: vote.qh:43
origin
Definition: ent_cs.qc:114
ClientDisconnect(this)
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
void Unfreeze(entity targ, bool reset_health)
Definition: damage.qc:546
#define IS_SPEC(v)
Definition: utils.qh:10
entity personal
Definition: cheats.qh:23
entity active_minigame
Definition: cl_minigames.qh:85
void Portal_ClearAll(entity own)
Definition: portals.qc:587
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define NULL
Definition: post.qh:17
void GameLogEcho(string s)
Definition: gamelog.qc:12
void SetSpectatee(entity this, entity spectatee)
Definition: client.qc:1836
void RemoveGrapplingHooks(entity pl)
Definition: hook.qc:78
string clientstatus
entity killindicator
Definition: clientkill.qh:7
float flags
Definition: csprogsdefs.qc:129
void ONREMOVE(entity this)
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
#define strfree(this)
Definition: string.qh:56
void vehicles_exit(entity vehic, bool eject)
Definition: sv_vehicles.qc:788
void VoteCount(float first_count)
Definition: vote.qc:207
entity vehicle
Definition: impulse.qc:21
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
void ClientState_detach(entity this)
Definition: state.qc:73
string weaponorder_byimpulse
Definition: client.qh:60
#define IS_PLAYER(v)
Definition: utils.qh:9
entity chatbubbleentity
Definition: client.qc:1207
void player_powerups_remove_all(entity this)
Definition: client.qc:1457
float FL_CLIENT
Definition: progsdefs.qc:234
+ Here is the call graph for this function:

◆ ClientInit_CheckUpdate()

void ClientInit_CheckUpdate ( entity  this)

Definition at line 879 of file client.qc.

References autocvar_g_balance_armor_blockpercent, autocvar_g_balance_damagepush_speedfactor, cnt, count, nextthink, and time.

Referenced by ClientInit_Spawn().

880 {
881  this.nextthink = time;
883  {
885  this.SendFlags |= 1;
886  }
888  {
890  this.SendFlags |= 1;
891  }
892 }
float cnt
Definition: powerups.qc:24
float nextthink
Definition: csprogsdefs.qc:121
float autocvar_g_balance_damagepush_speedfactor
Definition: damage.qh:18
float count
Definition: powerups.qc:22
float autocvar_g_balance_armor_blockpercent
Definition: damage.qh:21
float time
Definition: csprogsdefs.qc:16
+ Here is the caller graph for this function:

◆ ClientInit_misc()

void ClientInit_misc ( entity  this)

Definition at line 855 of file client.qc.

References autocvar_g_trueaim_minrange, autocvar_sv_foginterval, cnt, compressShotOrigin(), count, g_nexball_meter_period, hook_shotorigin, MSG_ONE, serverflags, world, WriteByte(), WriteCoord(), and WriteString().

Referenced by ClientInit_SendEntity(), and STATIC_INIT().

856 {
857  int channel = MSG_ONE;
858  WriteHeader(channel, ENT_CLIENT_INIT);
859  WriteByte(channel, g_nexball_meter_period * 32);
860  WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[0]));
861  WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[1]));
862  WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[2]));
863  WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[3]));
864  WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[0]));
865  WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[1]));
866  WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[2]));
867  WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[3]));
868 
869  if(autocvar_sv_foginterval && world.fog != "")
870  WriteString(channel, world.fog);
871  else
872  WriteString(channel, "");
873  WriteByte(channel, this.count * 255.0); // g_balance_armor_blockpercent
874  WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor
875  WriteByte(channel, serverflags);
877 }
int serverflags
Definition: main.qh:184
entity world
Definition: csprogsdefs.qc:15
float g_nexball_meter_period
Definition: sv_nexball.qh:54
vector hook_shotorigin[4]
Definition: main.qh:177
float compressShotOrigin(vector v)
Definition: util.qc:1121
float autocvar_g_trueaim_minrange
Definition: tracing.qh:16
float cnt
Definition: powerups.qc:24
float autocvar_sv_foginterval
Definition: client.qh:35
float count
Definition: powerups.qc:22
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientInit_SendEntity()

bool ClientInit_SendEntity ( entity  this,
entity  to,
int  sf 
)

Definition at line 843 of file client.qc.

References ClientInit_misc(), msg_entity, MSG_ONE, MUTATOR_CALLHOOK, Registry_send_all(), and to.

Referenced by ClientInit_Spawn().

844 {
845  WriteHeader(MSG_ENTITY, _ENT_CLIENT_INIT);
846  return = true;
847  msg_entity = to;
848  // MSG_INIT replacement
849  // TODO: make easier to use
851  W_PROP_reload(MSG_ONE, to);
852  ClientInit_misc(this);
853  MUTATOR_CALLHOOK(Ent_Init);
854 }
entity to
Definition: self.qh:96
entity msg_entity
Definition: progsdefs.qc:63
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
ERASEABLE ACCUMULATE void Registry_send_all()
Definition: registry.qh:167
void ClientInit_misc(entity this)
Definition: client.qc:855
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientInit_Spawn()

void ClientInit_Spawn ( )

Definition at line 894 of file client.qc.

References ClientInit_CheckUpdate(), ClientInit_SendEntity(), entity(), new_pure, and setthink.

Referenced by spawnfunc(), and STATIC_INIT().

895 {
896  entity e = new_pure(clientinit);
898  Net_LinkEntity(e, false, 0, ClientInit_SendEntity);
899 
901 }
void ClientInit_CheckUpdate(entity this)
Definition: client.qc:879
entity() spawn
#define new_pure(class)
purely logical entities (.origin doesn&#39;t work)
Definition: oo.qh:62
#define setthink(e, f)
bool ClientInit_SendEntity(entity this, entity to, int sf)
Definition: client.qc:843
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CountSpectators()

int CountSpectators ( entity  player,
entity  to 
)

Definition at line 101 of file client.qc.

References FOREACH_CLIENT, IS_REAL_CLIENT, and IS_SPEC.

Referenced by ClientData_Send().

102 {
103  if(!player) { return 0; } // not sure how, but best to be safe
104 
105  int spec_count = 0;
106 
107  FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_SPEC(it) && it != to && it.enemy == player,
108  {
109  spec_count++;
110  });
111 
112  return spec_count;
113 }
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
entity to
Definition: self.qh:96
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
#define IS_SPEC(v)
Definition: utils.qh:10
+ Here is the caller graph for this function:

◆ DecodeLevelParms()

void DecodeLevelParms ( entity  this)

Definition at line 934 of file client.qc.

References autocvar_sv_maxidle, CS(), max(), MUTATOR_CALLHOOK, parm1, and time.

Referenced by ClientState_attach(), and PlayerState_detach().

935 {
936  // load parms
937  CS(this).parm_idlesince = parm1;
938  if (CS(this).parm_idlesince == -(86400 * 366))
939  CS(this).parm_idlesince = time;
940 
941  // whatever happens, allow 60 seconds of idling directly after connect for map loading
942  CS(this).parm_idlesince = max(CS(this).parm_idlesince, time - autocvar_sv_maxidle + 60);
943 
945 }
float autocvar_sv_maxidle
Definition: client.qh:36
ClientState CS(Client this)
Definition: state.qh:47
void DecodeLevelParms(entity this)
Definition: client.qc:934
float parm1
Definition: progsdefs.qc:45
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DrownPlayer()

void DrownPlayer ( entity  this)

Definition at line 2597 of file client.qc.

References autocvar_g_balance_contents_damagerate, autocvar_g_balance_contents_drowndelay, autocvar_g_balance_contents_playerdamage_drowning, CH_PLAYER, CONTENT_WATER, Damage(), DMG_NOWEP, IS_DEAD, NULL, pain_finished, time, vehicle, VOICETYPE_PLAYERSOUND, VOL_BASE, waterlevel, WATERLEVEL_SUBMERGED, and watertype.

Referenced by PlayerPostThink().

2598 {
2599  if(IS_DEAD(this) || game_stopped || time < game_starttime || this.vehicle
2600  || STAT(FROZEN, this) || this.watertype != CONTENT_WATER)
2601  {
2602  STAT(AIR_FINISHED, this) = 0;
2603  return;
2604  }
2605 
2606  if (this.waterlevel != WATERLEVEL_SUBMERGED)
2607  {
2608  if(STAT(AIR_FINISHED, this) && STAT(AIR_FINISHED, this) < time)
2609  PlayerSound(this, playersound_gasp, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
2610  STAT(AIR_FINISHED, this) = 0;
2611  }
2612  else
2613  {
2614  if (!STAT(AIR_FINISHED, this))
2615  STAT(AIR_FINISHED, this) = time + autocvar_g_balance_contents_drowndelay;
2616  if (STAT(AIR_FINISHED, this) < time)
2617  { // drown!
2618  if (this.pain_finished < time)
2619  {
2621  this.pain_finished = time + 0.5;
2622  }
2623  }
2624  }
2625 }
float watertype
Definition: progsdefs.qc:182
const int WATERLEVEL_SUBMERGED
Definition: movetypes.qh:14
float autocvar_g_balance_contents_damagerate
Definition: main.qh:3
float autocvar_g_balance_contents_drowndelay
Definition: main.qh:4
const int VOICETYPE_PLAYERSOUND
Definition: globalsound.qh:64
float waterlevel
Definition: progsdefs.qc:181
#define DMG_NOWEP
Definition: damage.qh:126
const float CONTENT_WATER
Definition: csprogsdefs.qc:238
#define NULL
Definition: post.qh:17
const float VOL_BASE
Definition: sound.qh:36
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition: damage.qc:583
#define IS_DEAD(s)
Definition: utils.qh:26
float pain_finished
int autocvar_g_balance_contents_playerdamage_drowning
Definition: main.qh:5
const int CH_PLAYER
Definition: sound.qh:20
entity vehicle
Definition: impulse.qc:21
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ findinlist_abbrev()

bool findinlist_abbrev ( string  tofind,
string  list 
)

Definition at line 963 of file client.qc.

References FOREACH_WORD, strlen(), and substring().

Referenced by PlayerInIDList(), and PlayerInIPList().

964 {
965  if(list == "" || tofind == "")
966  return false; // empty list or search, just return
967 
968  // this function allows abbreviated strings!
969  FOREACH_WORD(list, it == substring(tofind, 0, strlen(it)),
970  {
971  return true;
972  });
973 
974  return false;
975 }
#define FOREACH_WORD(words, cond, body)
Definition: iter.qh:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FixClientCvars()

void FixClientCvars ( entity  e)

Definition at line 947 of file client.qc.

References autocvar_g_antilag, FixClientCvars(), MUTATOR_CALLHOOK, and stuffcmd.

Referenced by ClientConnect(), FixClientCvars(), and MapVote_Finished().

948 {
949  // send prediction settings to the client
950  if(autocvar_g_antilag == 3) // client side hitscan
951  stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
952  if(autocvar_sv_gentle)
953  stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
954 
955  stuffcmd(e, sprintf("\ncl_jumpspeedcap_min \"%s\"\n", autocvar_sv_jumpspeedcap_min));
956  stuffcmd(e, sprintf("\ncl_jumpspeedcap_max \"%s\"\n", autocvar_sv_jumpspeedcap_max));
957 
958  stuffcmd(e, sprintf("\ncl_shootfromfixedorigin \"%s\"\n", autocvar_g_shootfromfixedorigin));
959 
961 }
int autocvar_g_antilag
Definition: antilag.qh:3
#define stuffcmd(cl,...)
Definition: progsdefs.qh:23
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
void FixClientCvars(entity e)
Definition: client.qc:947
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FixPlayermodel()

void FixPlayermodel ( entity  player)

Definition at line 423 of file client.qc.

References argv(), autocvar_sv_defaultcharacter, autocvar_sv_defaultcharacterskin, autocvar_sv_defaultplayercolors, autocvar_sv_defaultplayermodel, autocvar_sv_defaultplayermodel_blue, autocvar_sv_defaultplayermodel_pink, autocvar_sv_defaultplayermodel_red, autocvar_sv_defaultplayermodel_yellow, autocvar_sv_defaultplayerskin, autocvar_sv_defaultplayerskin_blue, autocvar_sv_defaultplayerskin_pink, autocvar_sv_defaultplayerskin_red, autocvar_sv_defaultplayerskin_yellow, CheckPlayerModel(), CS(), FixPlayermodel(), floor(), M_ARGV, model_randomizer, MUTATOR_CALLHOOK, NUM_TEAM_1, NUM_TEAM_2, NUM_TEAM_3, NUM_TEAM_4, oldskin, player_getspecies(), setcolor, setplayermodel(), stof(), strcat(), strlen(), strstrofs, substring(), teamplay, tokenize_console, UpdatePlayerSounds(), and vector().

Referenced by FixPlayermodel(), PlayerThink(), PutObserverInServer(), PutPlayerInServer(), and STATIC_INIT().

424 {
425  string defaultmodel = "";
426  int defaultskin = 0;
428  {
429  if(teamplay)
430  {
431  switch(player.team)
432  {
433  case NUM_TEAM_1: defaultmodel = autocvar_sv_defaultplayermodel_red; defaultskin = autocvar_sv_defaultplayerskin_red; break;
434  case NUM_TEAM_2: defaultmodel = autocvar_sv_defaultplayermodel_blue; defaultskin = autocvar_sv_defaultplayerskin_blue; break;
436  case NUM_TEAM_4: defaultmodel = autocvar_sv_defaultplayermodel_pink; defaultskin = autocvar_sv_defaultplayerskin_pink; break;
437  }
438  }
439 
440  if(defaultmodel == "")
441  {
442  defaultmodel = autocvar_sv_defaultplayermodel;
443  defaultskin = autocvar_sv_defaultplayerskin;
444  }
445 
446  int n = tokenize_console(defaultmodel);
447  if(n > 0)
448  {
449  defaultmodel = argv(floor(n * CS(player).model_randomizer));
450  // However, do NOT randomize if the player-selected model is in the list.
451  for (int i = 0; i < n; ++i)
452  if ((argv(i) == player.playermodel && defaultskin == stof(player.playerskin)) || argv(i) == strcat(player.playermodel, ":", player.playerskin))
453  defaultmodel = argv(i);
454  }
455 
456  int i = strstrofs(defaultmodel, ":", 0);
457  if(i >= 0)
458  {
459  defaultskin = stof(substring(defaultmodel, i+1, -1));
460  defaultmodel = substring(defaultmodel, 0, i);
461  }
462  }
463  if(autocvar_sv_defaultcharacterskin && !defaultskin)
464  {
465  if(teamplay)
466  {
467  switch(player.team)
468  {
469  case NUM_TEAM_1: defaultskin = autocvar_sv_defaultplayerskin_red; break;
470  case NUM_TEAM_2: defaultskin = autocvar_sv_defaultplayerskin_blue; break;
471  case NUM_TEAM_3: defaultskin = autocvar_sv_defaultplayerskin_yellow; break;
472  case NUM_TEAM_4: defaultskin = autocvar_sv_defaultplayerskin_pink; break;
473  }
474  }
475 
476  if(!defaultskin)
477  defaultskin = autocvar_sv_defaultplayerskin;
478  }
479 
480  MUTATOR_CALLHOOK(FixPlayermodel, defaultmodel, defaultskin, player);
481  defaultmodel = M_ARGV(0, string);
482  defaultskin = M_ARGV(1, int);
483 
484  bool chmdl = false;
485  int oldskin;
486  if(defaultmodel != "")
487  {
488  if (defaultmodel != player.model)
489  {
490  vector m1 = player.mins;
491  vector m2 = player.maxs;
492  setplayermodel (player, defaultmodel);
493  setsize (player, m1, m2);
494  chmdl = true;
495  }
496 
497  oldskin = player.skin;
498  player.skin = defaultskin;
499  } else {
500  if (player.playermodel != player.model || player.playermodel == "")
501  {
502  player.playermodel = CheckPlayerModel(player.playermodel); // this is never "", so no endless loop
503  vector m1 = player.mins;
504  vector m2 = player.maxs;
505  setplayermodel (player, player.playermodel);
506  setsize (player, m1, m2);
507  chmdl = true;
508  }
509 
511  {
512  oldskin = player.skin;
513  player.skin = stof(player.playerskin);
514  }
515  else
516  {
517  oldskin = player.skin;
518  player.skin = defaultskin;
519  }
520  }
521 
522  if(chmdl || oldskin != player.skin) // model or skin has changed
523  {
524  player.species = player_getspecies(player); // update species
525  if(!autocvar_g_debug_globalsounds)
526  UpdatePlayerSounds(player); // update skin sounds
527  }
528 
529  if(!teamplay)
531  if(player.clientcolors != stof(autocvar_sv_defaultplayercolors))
533 }
float model_randomizer
Definition: client.qc:422
int autocvar_sv_defaultplayerskin_pink
Definition: player.qh:9
const int NUM_TEAM_2
Definition: teams.qh:19
int autocvar_sv_defaultplayerskin_blue
Definition: player.qh:8
int autocvar_sv_defaultplayerskin_red
Definition: player.qh:10
ClientState CS(Client this)
Definition: state.qh:47
bool autocvar_sv_defaultcharacterskin
Definition: player.qh:7
string autocvar_sv_defaultplayermodel
Definition: player.qh:13
void UpdatePlayerSounds(entity this)
Definition: globalsound.qc:300
string autocvar_sv_defaultplayermodel_blue
Definition: player.qh:14
int autocvar_sv_defaultplayerskin
Definition: player.qh:18
string autocvar_sv_defaultplayercolors
Definition: player.qh:12
string autocvar_sv_defaultplayermodel_yellow
Definition: player.qh:17
string CheckPlayerModel(string plyermodel)
Definition: client.qc:194
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
int autocvar_sv_defaultplayerskin_yellow
Definition: player.qh:11
int player_getspecies(entity this)
Definition: client.qc:413
#define strstrofs
Definition: dpextensions.qh:42
bool autocvar_sv_defaultcharacter
Definition: player.qh:6
#define setcolor
Definition: pre.qh:11
float teamplay
Definition: progsdefs.qc:31
#define M_ARGV(x, type)
Definition: events.qh:17
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define tokenize_console
Definition: dpextensions.qh:24
const int NUM_TEAM_4
Definition: teams.qh:21
string autocvar_sv_defaultplayermodel_red
Definition: player.qh:16
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
void FixPlayermodel(entity player)
Definition: client.qc:423
void setplayermodel(entity e, string modelname)
Definition: client.qc:228
const int NUM_TEAM_1
Definition: teams.qh:18
int oldskin
Definition: sv_monsters.qh:56
string autocvar_sv_defaultplayermodel_pink
Definition: player.qh:15
const int NUM_TEAM_3
Definition: teams.qh:20
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetClientVersionMessage()

string GetClientVersionMessage ( entity  this)

Definition at line 1021 of file client.qc.

References autocvar_g_xonoticversion, autocvar_gameversion, CS(), and strcat().

Referenced by getwelcomemessage().

1022 {
1023  if (CS(this).version_mismatch) {
1024  if(CS(this).version < autocvar_gameversion) {
1025  return strcat("This is Xonotic ", autocvar_g_xonoticversion,
1026  "\n^3Your client version is outdated.\n\n\n### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###\n\n\nPlease update!!!^8");
1027  } else {
1028  return strcat("This is Xonotic ", autocvar_g_xonoticversion,
1029  "\n^3This server is using an outdated Xonotic version.\n\n\n ### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###.^8");
1030  }
1031  } else {
1032  return strcat("Welcome to Xonotic ", autocvar_g_xonoticversion);
1033  }
1034 }
ClientState CS(Client this)
Definition: state.qh:47
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
float autocvar_gameversion
Definition: client.qh:46
string autocvar_g_xonoticversion
Definition: client.qh:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetPlayerLimit()

int GetPlayerLimit ( )

Definition at line 1990 of file client.qc.

References autocvar_g_maxplayers, g_duel, GetPlayerLimit(), M_ARGV, and MUTATOR_CALLHOOK.

Referenced by bot_fixcount(), GetPlayerLimit(), MapHasRightSize(), nJoinAllowed(), and STATIC_INIT().

1991 {
1992  if(g_duel)
1993  return 2; // TODO: this workaround is needed since the mutator hook from duel can't be activated before the gametype is loaded (e.g. switching modes via gametype vote screen)
1994  int player_limit = autocvar_g_maxplayers;
1995  MUTATOR_CALLHOOK(GetPlayerLimit, player_limit);
1996  player_limit = M_ARGV(0, int);
1997  return player_limit;
1998 }
int GetPlayerLimit()
Definition: client.qc:1990
#define M_ARGV(x, type)
Definition: events.qh:17
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
int autocvar_g_maxplayers
Definition: client.qh:43
#define g_duel
Definition: duel.qh:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetPressedKeys()

void GetPressedKeys ( entity  this)

Definition at line 1681 of file client.qc.

References BITSET, CS(), IS_DUCKED, movement, MUTATOR_CALLHOOK, PHYS_INPUT_BUTTON_ATCK, PHYS_INPUT_BUTTON_ATCK2, and PHYS_INPUT_BUTTON_JUMP.

Referenced by MUTATOR_HOOKFUNCTION(), and PlayerPostThink().

1682 {
1684  if (game_stopped)
1685  {
1686  CS(this).pressedkeys = 0;
1687  STAT(PRESSED_KEYS, this) = 0;
1688  return;
1689  }
1690 
1691  // NOTE: GetPressedKeys and PM_dodging_GetPressedKeys use similar code
1692  int keys = STAT(PRESSED_KEYS, this);
1693  keys = BITSET(keys, KEY_FORWARD, CS(this).movement.x > 0);
1694  keys = BITSET(keys, KEY_BACKWARD, CS(this).movement.x < 0);
1695  keys = BITSET(keys, KEY_RIGHT, CS(this).movement.y > 0);
1696  keys = BITSET(keys, KEY_LEFT, CS(this).movement.y < 0);
1697 
1698  keys = BITSET(keys, KEY_JUMP, PHYS_INPUT_BUTTON_JUMP(this));
1699  keys = BITSET(keys, KEY_CROUCH, IS_DUCKED(this)); // workaround: player can't un-crouch until their path is clear, so we keep the button held here
1700  keys = BITSET(keys, KEY_ATCK, PHYS_INPUT_BUTTON_ATCK(this));
1701  keys = BITSET(keys, KEY_ATCK2, PHYS_INPUT_BUTTON_ATCK2(this));
1702  CS(this).pressedkeys = keys; // store for other users
1703 
1704  STAT(PRESSED_KEYS, this) = keys;
1705 }
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition: player.qh:148
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition: player.qh:147
#define IS_DUCKED(s)
Definition: player.qh:206
ClientState CS(Client this)
Definition: state.qh:47
void GetPressedKeys(entity this)
Definition: client.qc:1681
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition: player.qh:146
#define BITSET(var, mask, flag)
Definition: bits.qh:11
vector movement
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getwelcomemessage()

string getwelcomemessage ( entity  this)

Definition at line 1036 of file client.qc.

References autocvar_g_jetpack, autocvar_g_mutatormsg, autocvar_hostname, autocvar_sv_motd, cache_lastmutatormsg, cache_mutatormsg, cvar(), cvar_defstring(), ftos(), g_cts, g_weapon_stay, g_weaponarena, g_weaponarena_list, g_weaponarena_random, gamemode_name, GetClientVersionMessage(), M_ARGV, MUTATOR_CALLHOOK, stof(), strcat(), strcpy, strlen(), and substring().

Referenced by ClientConnect(), and PrintWelcomeMessage().

1037 {
1038  MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
1039  string modifications = M_ARGV(0, string);
1040 
1041  if(g_weaponarena)
1042  {
1044  modifications = strcat(modifications, ", ", ftos(g_weaponarena_random), " of ", g_weaponarena_list, " Arena");
1045  else
1046  modifications = strcat(modifications, ", ", g_weaponarena_list, " Arena");
1047  }
1048  else if(cvar("g_balance_blaster_weaponstartoverride") == 0)
1049  modifications = strcat(modifications, ", No start weapons");
1050  if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")))
1051  modifications = strcat(modifications, ", Low gravity");
1052  if(g_weapon_stay && !g_cts)
1053  modifications = strcat(modifications, ", Weapons stay");
1054  if(autocvar_g_jetpack)
1055  modifications = strcat(modifications, ", Jet pack");
1056  modifications = substring(modifications, 2, strlen(modifications) - 2);
1057 
1058  string versionmessage = GetClientVersionMessage(this);
1059  string s = strcat(versionmessage, "^8\n^8\nserver is ^9", autocvar_hostname, "^8\n");
1060 
1061  s = strcat(s, "^8\nmatch type is ^1", gamemode_name, "^8\n");
1062 
1063  if(modifications != "")
1064  s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
1065 
1067  {
1070  }
1071 
1072  if (cache_mutatormsg != "") {
1073  s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg);
1074  }
1075 
1076  string mutator_msg = "";
1077  MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
1078  mutator_msg = M_ARGV(0, string);
1079 
1080  s = strcat(s, mutator_msg); // trust that the mutator will do proper formatting
1081 
1082  string motd = autocvar_sv_motd;
1083  if (motd != "") {
1084  s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
1085  }
1086  return s;
1087 }
string autocvar_sv_motd
Definition: client.qh:51
string autocvar_g_mutatormsg
Definition: client.qh:34
string g_weaponarena_list
Definition: world.qh:79
float g_weaponarena_random
Definition: world.qh:78
string GetClientVersionMessage(entity this)
Definition: client.qc:1021
#define strcpy(this, s)
Definition: string.qh:49
#define g_cts
Definition: cts.qh:36
string autocvar_hostname
Definition: client.qh:49
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define M_ARGV(x, type)
Definition: events.qh:17
float g_weapon_stay
Definition: world.qh:112
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
bool autocvar_g_jetpack
Definition: world.qh:8
string cache_mutatormsg
Definition: world.qh:63
string gamemode_name
Definition: world.qh:47
string cache_lastmutatormsg
Definition: world.qh:64
float g_weaponarena
Definition: world.qh:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Join()

void Join ( entity  this)

Definition at line 1966 of file client.qc.

References autocvar_g_balance_teams, autocvar_g_campaign, campaign_bots_may_start, IS_PLAYER, netname, NULL, PutClientInServer(), team, team_selected, TeamBalance_JoinBestTeam(), teamplay, and TRANSMUTE().

Referenced by ClientCommand_join(), ObserverOrSpectatorThink(), and PlayerPreThink().

1967 {
1968  TRANSMUTE(Player, this);
1969 
1970  if(!this.team_selected)
1973 
1975  campaign_bots_may_start = true;
1976 
1977  Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_PREVENT_JOIN);
1978 
1979  PutClientInServer(this);
1980 
1981  if(IS_PLAYER(this))
1982  if(teamplay && this.team != -1)
1983  {
1984  }
1985  else
1986  Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_JOIN_PLAY, this.netname);
1987  this.team_selected = false;
1988 }
TRANSMUTE(Player, this)
string netname
Definition: powerups.qc:20
bool team_selected
Definition: client.qc:1958
void TeamBalance_JoinBestTeam(entity player)
Assigns the given player to a team that will make the game most balanced.
Definition: teamplay.qc:451
this team
Definition: client.qc:86
#define NULL
Definition: post.qh:17
float teamplay
Definition: progsdefs.qc:31
bool campaign_bots_may_start
campaign mode: bots shall spawn but wait for the player to spawn before they do anything in other gam...
Definition: campaign.qh:27
bool autocvar_g_balance_teams
Definition: teamplay.qh:8
PutClientInServer(this)
bool autocvar_g_campaign
Definition: campaign.qh:6
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ joinAllowed()

bool joinAllowed ( entity  this)

Definition at line 2108 of file client.qc.

References CS(), jointime, lockteams, MIN_SPEC_TIME, MUTATOR_CALLHOOK, nJoinAllowed(), ShowTeamSelection(), teamplay, and time.

Referenced by ClientCommand_join(), ObserverOrSpectatorThink(), and PlayerPreThink().

2109 {
2110  if (CS(this).version_mismatch) return false;
2111  if (time < CS(this).jointime + MIN_SPEC_TIME) return false;
2112  if (!nJoinAllowed(this, this)) return false;
2113  if (teamplay && lockteams) return false;
2114  if (MUTATOR_CALLHOOK(ForbidSpawn, this)) return false;
2115  if (ShowTeamSelection(this)) return false;
2116  return true;
2117 }
ClientState CS(Client this)
Definition: state.qh:47
bool ShowTeamSelection(entity this)
Definition: client.qc:1959
float jointime
Definition: client.qh:64
float teamplay
Definition: progsdefs.qc:31
bool lockteams
Definition: teamplay.qh:13
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
int nJoinAllowed(entity this, entity ignore)
Determines whether the player is allowed to join.
Definition: client.qc:2006
const int MIN_SPEC_TIME
Definition: client.qh:399
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ NET_HANDLE()

NET_HANDLE ( fpsreport  ,
bool   
)

Definition at line 2818 of file client.qc.

References PlayerScore_Set().

2819 {
2820  int fps = ReadShort();
2821  PlayerScore_Set(sender, SP_FPS, fps);
2822  return true;
2823 }
float PlayerScore_Set(entity player, PlayerScoreField scorefield, float score)
Sets the player&#39;s score to the score parameter.
Definition: scores.qc:368
+ Here is the call graph for this function:

◆ nJoinAllowed()

int nJoinAllowed ( entity  this,
entity  ignore 
)

Determines whether the player is allowed to join.

This depends on cvar g_maxplayers, if it isn't used this function always return true, otherwise it checks whether the number of currently playing players exceeds g_maxplayers.

Returns
int number of free slots for players, 0 if none

Definition at line 2006 of file client.qc.

References autocvar_g_forced_team_otherwise, FOREACH_CLIENT, GetPlayerLimit(), INGAME, IS_PLAYER, IS_REAL_CLIENT, maxclients, min(), Player_GetForcedTeamIndex(), TEAM_FORCE_SPECTATOR, and time.

Referenced by joinAllowed(), and WinningConditionHelper().

2007 {
2008  if(!ignore)
2009  // this is called that way when checking if anyone may be able to join (to build qcstatus)
2010  // so report 0 free slots if restricted
2011  {
2012  if(autocvar_g_forced_team_otherwise == "spectate")
2013  return 0;
2014  if(autocvar_g_forced_team_otherwise == "spectator")
2015  return 0;
2016  }
2017 
2018  if(this && (Player_GetForcedTeamIndex(this) == TEAM_FORCE_SPECTATOR))
2019  return 0; // forced spectators can never join
2020 
2021  // TODO simplify this
2022  int totalClients = 0;
2023  int currentlyPlaying = 0;
2024  FOREACH_CLIENT(true, {
2025  if(it != ignore)
2026  ++totalClients;
2027  if(IS_REAL_CLIENT(it) && (IS_PLAYER(it) || INGAME(it)))
2028  ++currentlyPlaying;
2029  });
2030 
2031  int player_limit = GetPlayerLimit();
2032 
2033  int free_slots = 0;
2034  if (!player_limit)
2035  free_slots = maxclients - totalClients;
2036  else if(player_limit > 0 && currentlyPlaying < player_limit)
2037  free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying);
2038 
2039  static float msg_time = 0;
2040  if(this && !INGAME(this) && ignore && !free_slots && time > msg_time)
2041  {
2042  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_PREVENT);
2043  msg_time = time + 0.5;
2044  }
2045 
2046  return free_slots;
2047 }
#define INGAME(it)
Definition: sv_rules.qh:20
string autocvar_g_forced_team_otherwise
Definition: teamplay.qh:11
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
int GetPlayerLimit()
Definition: client.qc:1990
float maxclients
Definition: csprogsdefs.qc:21
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
Force the player to spectator team.
Definition: teamplay.qh:137
int Player_GetForcedTeamIndex(entity player)
Returns the index of the forced team of the given player.
Definition: teamplay.qc:346
float time
Definition: csprogsdefs.qc:16
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ObserverOrSpectatorThink()

void ObserverOrSpectatorThink ( entity  this)

Definition at line 2267 of file client.qc.

References CS(), CS_CVAR, FL_CLIENT, FL_JUMPRELEASED, FL_NOTARGET, flags, impulse, IS_SPEC, Join(), joinAllowed(), jointime, MIN_SPEC_TIME, MinigameImpulse(), MOVETYPE_FLY_WORLDONLY, MOVETYPE_NOCLIP, PHYS_INPUT_BUTTON_ATCK, PHYS_INPUT_BUTTON_ATCK2, PHYS_INPUT_BUTTON_JUMP, PHYS_INPUT_BUTTON_USE, PutClientInServer(), PutObserverInServer(), set_movetype(), SpectateNext(), SpectatePrev(), SpectateUpdate(), time, TRANSMUTE(), and would_spectate.

Referenced by PlayerPreThink().

2268 {
2269  bool is_spec = IS_SPEC(this);
2270  if ( CS(this).impulse )
2271  {
2272  int r = MinigameImpulse(this, CS(this).impulse);
2273  if (!is_spec || r)
2274  CS(this).impulse = 0;
2275 
2276  if (is_spec && CS(this).impulse == IMP_weapon_drop.impulse)
2277  {
2278  STAT(CAMERA_SPECTATOR, this) = (STAT(CAMERA_SPECTATOR, this) + 1) % 3;
2279  CS(this).impulse = 0;
2280  return;
2281  }
2282  }
2283 
2284  if (this.flags & FL_JUMPRELEASED) {
2285  if (PHYS_INPUT_BUTTON_JUMP(this) && (joinAllowed(this) || time < CS(this).jointime + MIN_SPEC_TIME)) {
2286  this.flags &= ~FL_JUMPRELEASED;
2287  this.flags |= FL_SPAWNING;
2288  } else if((is_spec && (PHYS_INPUT_BUTTON_ATCK(this) || CS(this).impulse == 10 || CS(this).impulse == 15 || CS(this).impulse == 18 || (CS(this).impulse >= 200 && CS(this).impulse <= 209)))
2289  || (!is_spec && ((PHYS_INPUT_BUTTON_ATCK(this) && !CS(this).version_mismatch) || this.would_spectate))) {
2290  this.flags &= ~FL_JUMPRELEASED;
2291  if(SpectateNext(this)) {
2292  TRANSMUTE(Spectator, this);
2293  } else if (is_spec) {
2294  TRANSMUTE(Observer, this);
2295  PutClientInServer(this);
2296  }
2297  else
2298  this.would_spectate = false; // unable to spectate anyone
2299  if (is_spec)
2300  CS(this).impulse = 0;
2301  } else if (is_spec) {
2302  if(CS(this).impulse == 12 || CS(this).impulse == 16 || CS(this).impulse == 19 || (CS(this).impulse >= 220 && CS(this).impulse <= 229)) {
2303  this.flags &= ~FL_JUMPRELEASED;
2304  if(SpectatePrev(this)) {
2305  TRANSMUTE(Spectator, this);
2306  } else {
2307  TRANSMUTE(Observer, this);
2308  PutClientInServer(this);
2309  }
2310  CS(this).impulse = 0;
2311  } else if(PHYS_INPUT_BUTTON_ATCK2(this)) {
2312  this.would_spectate = false;
2313  this.flags &= ~FL_JUMPRELEASED;
2314  TRANSMUTE(Observer, this);
2315  PutClientInServer(this);
2316  } else if(!SpectateUpdate(this) && !SpectateNext(this)) {
2317  PutObserverInServer(this, false, true);
2318  this.would_spectate = true;
2319  }
2320  }
2321  else {
2322  bool wouldclip = CS_CVAR(this).cvar_cl_clippedspectating;
2323  if (PHYS_INPUT_BUTTON_USE(this))
2324  wouldclip = !wouldclip;
2325  int preferred_movetype = (wouldclip ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP);
2326  set_movetype(this, preferred_movetype);
2327  }
2328  } else { // jump pressed
2329  if ((is_spec && !(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this)))
2330  || (!is_spec && !(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this)))) {
2331  this.flags |= FL_JUMPRELEASED;
2332  if(this.flags & FL_SPAWNING)
2333  {
2334  this.flags &= ~FL_SPAWNING;
2335  if(joinAllowed(this))
2336  Join(this);
2337  else if(time < CS(this).jointime + MIN_SPEC_TIME)
2338  CS(this).autojoin_checked = -1;
2339  return;
2340  }
2341  }
2342  if(is_spec && !SpectateUpdate(this))
2343  PutObserverInServer(this, false, true);
2344  }
2345  if (is_spec)
2346  this.flags |= FL_CLIENT | FL_NOTARGET;
2347 }
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition: player.qh:148
bool would_spectate
Definition: client.qc:2265
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition: player.qh:147
TRANSMUTE(Player, this)
ClientState CS(Client this)
Definition: state.qh:47
#define CS_CVAR(this)
Definition: state.qh:51
bool SpectateUpdate(entity this)
Definition: client.qc:1784
float impulse
Definition: progsdefs.qc:158
#define IS_SPEC(v)
Definition: utils.qh:10
bool SpectateNext(entity this)
Definition: client.qc:1883
bool MinigameImpulse(entity this, int imp)
#define PHYS_INPUT_BUTTON_USE(s)
Definition: player.qh:154
bool joinAllowed(entity this)
Definition: client.qc:2108
float MOVETYPE_FLY_WORLDONLY
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
putting a client as observer in the server
Definition: client.qc:238
float FL_JUMPRELEASED
Definition: progsdefs.qc:243
float jointime
Definition: client.qh:64
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition: player.qh:146
float MOVETYPE_NOCLIP
Definition: progsdefs.qc:254
float flags
Definition: csprogsdefs.qc:129
PutClientInServer(this)
float FL_NOTARGET
Definition: progsdefs.qc:238
const int MIN_SPEC_TIME
Definition: client.qh:399
float time
Definition: csprogsdefs.qc:16
void Join(entity this)
Definition: client.qc:1966
void set_movetype(entity this, int mt)
float FL_CLIENT
Definition: progsdefs.qc:234
bool SpectatePrev(entity this)
Definition: client.qc:1897
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ play_countdown()

void play_countdown ( entity  this,
float  finished,
Sound  samp 
)

Definition at line 1447 of file client.qc.

References ATTEN_NORM, CH_INFO, floor(), frametime, IS_REAL_CLIENT, sound, TC, time, and VOL_BASE.

Referenced by player_powerups(), and STATIC_INIT().

1448 {
1449  TC(Sound, samp);
1450  if(IS_REAL_CLIENT(this))
1451  if(floor(finished - time - frametime) != floor(finished - time))
1452  if(finished - time < 6)
1453  sound (this, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
1454 }
const int CH_INFO
Definition: sound.qh:6
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
float frametime
Definition: csprogsdefs.qc:17
const float VOL_BASE
Definition: sound.qh:36
#define TC(T, sym)
Definition: _all.inc:82
Definition: sound.qh:119
const float ATTEN_NORM
Definition: sound.qh:30
#define sound(e, c, s, v, a)
Definition: sound.qh:52
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ player_getspecies()

int player_getspecies ( entity  this)

Definition at line 413 of file client.qc.

References get_model_parameters(), get_model_parameters_species, model, skin, SPECIES_HUMAN, and string_null.

Referenced by FixPlayermodel().

414 {
415  get_model_parameters(this.model, this.skin);
418  if (s < 0) return SPECIES_HUMAN;
419  return s;
420 }
string string_null
Definition: nil.qh:9
const int SPECIES_HUMAN
Definition: constants.qh:20
skin
Definition: ent_cs.qc:143
float get_model_parameters(string m, float sk)
Definition: util.qc:1258
string model
Definition: csprogsdefs.qc:108
float get_model_parameters_species
Definition: util.qh:140
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Player_Physics()

void Player_Physics ( entity  this)

Definition at line 2629 of file client.qc.

References CS(), frametime, move_movetype, move_qcphysics, movetype, Movetype_Physics_NoMatchTicrate(), and MOVETYPE_QCPLAYER.

Referenced by PlayerPostThink().

2630 {
2631  this.movetype = (this.move_qcphysics) ? MOVETYPE_QCPLAYER : this.move_movetype;
2632 
2633  if(!this.move_qcphysics)
2634  return;
2635 
2636  if(!frametime && !CS(this).pm_frametime)
2637  return;
2638 
2639  Movetype_Physics_NoMatchTicrate(this, CS(this).pm_frametime, true);
2640 
2641  CS(this).pm_frametime = 0;
2642 }
ClientState CS(Client this)
Definition: state.qh:47
void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient)
Definition: movetypes.qc:813
bool move_qcphysics
Definition: client.qc:2627
float move_movetype
Definition: movetypes.qh:76
float frametime
Definition: csprogsdefs.qc:17
const int MOVETYPE_QCPLAYER
Definition: movetypes.qh:151
float movetype
Definition: csprogsdefs.qc:98
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ player_powerups()

void player_powerups ( entity  this)

Definition at line 1470 of file client.qc.

References alpha, autocvar_g_fullbrightplayers, autocvar_g_nodepthtestplayers, EF_FULLBRIGHT, EF_NODEPTHTEST, effects, g_cts, IS_DEAD, items, MF_ROCKET, modelflags, MUTATOR_CALLHOOK, MUTATOR_IS_ENABLED, netname, NULL, play_countdown(), player_powerups_remove_all(), STATUSEFFECT_REMOVE_CLEAR, STATUSEFFECT_REMOVE_NORMAL, STATUSEFFECT_REMOVE_TIMEOUT, time, vehicle, and WEPSET_SUPERWEAPONS.

Referenced by PlayerThink().

1471 {
1472  if((this.items & IT_USING_JETPACK) && !IS_DEAD(this) && !game_stopped)
1473  this.modelflags |= MF_ROCKET;
1474  else
1475  this.modelflags &= ~MF_ROCKET;
1476 
1477  this.effects &= ~EF_NODEPTHTEST;
1478 
1479  if (IS_DEAD(this))
1481 
1482  if((this.alpha < 0 || IS_DEAD(this)) && !this.vehicle) // don't apply the flags if the player is gibbed
1483  return;
1484 
1485  // add a way to see what the items were BEFORE all of these checks for the mutator hook
1486  int items_prev = this.items;
1487 
1488  if (!MUTATOR_IS_ENABLED(mutator_instagib))
1489  {
1490  // NOTE: superweapons are a special case and as such are handled here instead of the status effects system
1491  if (this.items & IT_SUPERWEAPON)
1492  {
1493  if (!(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
1494  {
1495  StatusEffects_remove(STATUSEFFECT_Superweapons, this, STATUSEFFECT_REMOVE_NORMAL);
1496  this.items = this.items - (this.items & IT_SUPERWEAPON);
1497  //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_SUPERWEAPON_LOST, this.netname);
1498  Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
1499  }
1500  else if (this.items & IT_UNLIMITED_SUPERWEAPONS)
1501  {
1502  // don't let them run out
1503  }
1504  else
1505  {
1506  play_countdown(this, StatusEffects_gettime(STATUSEFFECT_Superweapons, this), SND_POWEROFF);
1507  if (time > StatusEffects_gettime(STATUSEFFECT_Superweapons, this))
1508  {
1509  this.items = this.items - (this.items & IT_SUPERWEAPON);
1510  STAT(WEAPONS, this) &= ~WEPSET_SUPERWEAPONS;
1511  //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_SUPERWEAPON_BROKEN, this.netname);
1512  Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_SUPERWEAPON_BROKEN);
1513  }
1514  }
1515  }
1516  else if(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)
1517  {
1518  if (time < StatusEffects_gettime(STATUSEFFECT_Superweapons, this) || (this.items & IT_UNLIMITED_SUPERWEAPONS))
1519  {
1520  this.items = this.items | IT_SUPERWEAPON;
1521  if(!(this.items & IT_UNLIMITED_SUPERWEAPONS))
1522  {
1523  if(!g_cts)
1524  Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_SUPERWEAPON_PICKUP, this.netname);
1525  Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_SUPERWEAPON_PICKUP);
1526  }
1527  }
1528  else
1529  {
1530  if(StatusEffects_active(STATUSEFFECT_Superweapons, this))
1531  StatusEffects_remove(STATUSEFFECT_Superweapons, this, STATUSEFFECT_REMOVE_TIMEOUT);
1532  STAT(WEAPONS, this) &= ~WEPSET_SUPERWEAPONS;
1533  }
1534  }
1535  else if(StatusEffects_active(STATUSEFFECT_Superweapons, this)) // cheaper to check than to update each frame!
1536  {
1537  StatusEffects_remove(STATUSEFFECT_Superweapons, this, STATUSEFFECT_REMOVE_CLEAR);
1538  }
1539  }
1540 
1542  this.effects = this.effects | EF_NODEPTHTEST;
1543 
1545  this.effects = this.effects | EF_FULLBRIGHT;
1546 
1547  MUTATOR_CALLHOOK(PlayerPowerups, this, items_prev);
1548 }
WepSet WEPSET_SUPERWEAPONS
Definition: all.qh:307
float alpha
Definition: items.qc:14
void play_countdown(entity this, float finished, Sound samp)
Definition: client.qc:1447
bool autocvar_g_nodepthtestplayers
Definition: client.qh:33
const int MF_ROCKET
string netname
Definition: powerups.qc:20
Effect is being removed by a function, calls regular removal mechanics.
Definition: all.qh:25
const float EF_NODEPTHTEST
Definition: csprogsdefs.qc:304
float effects
Definition: csprogsdefs.qc:111
int modelflags
#define MUTATOR_IS_ENABLED(this)
Definition: base.qh:176
const float EF_FULLBRIGHT
Definition: csprogsdefs.qc:303
Effect is being forcibly removed without calling any additional mechanics.
Definition: all.qh:27
#define g_cts
Definition: cts.qh:36
#define NULL
Definition: post.qh:17
#define IS_DEAD(s)
Definition: utils.qh:26
bool autocvar_g_fullbrightplayers
Definition: client.qh:16
float items
Definition: progsdefs.qc:145
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
entity vehicle
Definition: impulse.qc:21
float time
Definition: csprogsdefs.qc:16
void player_powerups_remove_all(entity this)
Definition: client.qc:1457
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ player_powerups_remove_all()

void player_powerups_remove_all ( entity  this)

Definition at line 1457 of file client.qc.

References ATTEN_NORM, CH_INFO, CH_TRIGGER_SINGLE, IS_CLIENT, items, sound, time, and VOL_BASE.

Referenced by ClientDisconnect(), player_powerups(), PutObserverInServer(), reset_map(), and STATIC_INIT().

1458 {
1459  if (this.items & (IT_SUPERWEAPON | IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS))
1460  {
1461  // don't play the poweroff sound when the game restarts or the player disconnects
1462  if (time > game_starttime + 1 && IS_CLIENT(this))
1463  sound(this, CH_INFO, SND_POWEROFF, VOL_BASE, ATTEN_NORM);
1464  if (this.items & (IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS))
1465  stopsound(this, CH_TRIGGER_SINGLE); // get rid of the pickup sound
1466  this.items -= (this.items & (IT_SUPERWEAPON | IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS));
1467  }
1468 }
#define IS_CLIENT(v)
Definition: utils.qh:13
const int CH_INFO
Definition: sound.qh:6
const float VOL_BASE
Definition: sound.qh:36
const float ATTEN_NORM
Definition: sound.qh:30
const int CH_TRIGGER_SINGLE
Definition: sound.qh:13
float items
Definition: progsdefs.qc:145
#define sound(e, c, s, v, a)
Definition: sound.qh:52
float time
Definition: csprogsdefs.qc:16
+ Here is the caller graph for this function:

◆ player_regen()

void player_regen ( entity  this)

Definition at line 1601 of file client.qc.

References autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, autocvar_g_balance_armor_regenstable, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear, autocvar_g_balance_armor_rotstable, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, autocvar_g_balance_fuel_regenstable, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, autocvar_g_balance_fuel_rotstable, autocvar_g_balance_health_regen, autocvar_g_balance_health_regenlinear, autocvar_g_balance_health_regenstable, autocvar_g_balance_health_rot, autocvar_g_balance_health_rotlinear, autocvar_g_balance_health_rotstable, DMG_NOWEP, frametime, GetResource(), items, M_ARGV, MUTATOR_CALLHOOK, pauseregen_finished, pauserotarmor_finished, pauserotfuel_finished, pauserothealth_finished, RES_HEALTH, RotRegen(), time, vehicle, and vehicles_exit().

Referenced by PlayerThink().

1602 {
1603  float max_mod, regen_mod, rot_mod, limit_mod;
1604  max_mod = regen_mod = rot_mod = limit_mod = 1;
1605 
1606  float regen_health = autocvar_g_balance_health_regen;
1607  float regen_health_linear = autocvar_g_balance_health_regenlinear;
1608  float regen_health_rot = autocvar_g_balance_health_rot;
1609  float regen_health_rotlinear = autocvar_g_balance_health_rotlinear;
1610  float regen_health_stable = autocvar_g_balance_health_regenstable;
1611  float regen_health_rotstable = autocvar_g_balance_health_rotstable;
1612  bool mutator_returnvalue = MUTATOR_CALLHOOK(PlayerRegen, this, max_mod, regen_mod, rot_mod, limit_mod, regen_health, regen_health_linear, regen_health_rot,
1613  regen_health_rotlinear, regen_health_stable, regen_health_rotstable);
1614  max_mod = M_ARGV(1, float);
1615  regen_mod = M_ARGV(2, float);
1616  rot_mod = M_ARGV(3, float);
1617  limit_mod = M_ARGV(4, float);
1618  regen_health = M_ARGV(5, float);
1619  regen_health_linear = M_ARGV(6, float);
1620  regen_health_rot = M_ARGV(7, float);
1621  regen_health_rotlinear = M_ARGV(8, float);
1622  regen_health_stable = M_ARGV(9, float);
1623  regen_health_rotstable = M_ARGV(10, float);
1624 
1625  float rotstable, regenstable, rotframetime, regenframetime;
1626 
1627  if(!mutator_returnvalue)
1628  if(!STAT(FROZEN, this))
1629  {
1632  regenframetime = (time > this.pauseregen_finished) ? (regen_mod * frametime) : 0;
1633  rotframetime = (time > this.pauserotarmor_finished) ? (rot_mod * frametime) : 0;
1634  RotRegen(this, RES_ARMOR, limit_mod,
1637 
1638  // NOTE: max_mod is only applied to health
1639  regenstable = regen_health_stable * max_mod;
1640  rotstable = regen_health_rotstable * max_mod;
1641  regenframetime = (time > this.pauseregen_finished) ? (regen_mod * frametime) : 0;
1642  rotframetime = (time > this.pauserothealth_finished) ? (rot_mod * frametime) : 0;
1643  RotRegen(this, RES_HEALTH, limit_mod,
1644  regenstable, regen_health, regen_health_linear, regenframetime,
1645  rotstable, regen_health_rot, regen_health_rotlinear, rotframetime);
1646  }
1647 
1648  // if player rotted to death... die!
1649  // check this outside above checks, as player may still be able to rot to death
1650  if(GetResource(this, RES_HEALTH) < 1)
1651  {
1652  if(this.vehicle)
1653  vehicles_exit(this.vehicle, VHEF_RELEASE);
1654  if(this.event_damage)
1655  this.event_damage(this, this, this, 1, DEATH_ROT.m_id, DMG_NOWEP, this.origin, '0 0 0');
1656  }
1657 
1658  if (!(this.items & IT_UNLIMITED_AMMO))
1659  {
1662  regenframetime = ((time > this.pauseregen_finished) && (this.items & ITEM_JetpackRegen.m_itemid)) ? frametime : 0;
1663  rotframetime = (time > this.pauserotfuel_finished) ? frametime : 0;
1664  RotRegen(this, RES_FUEL, 1,
1667  }
1668 }
float autocvar_g_balance_armor_rotlinear
Definition: sv_resources.qh:18
float autocvar_g_balance_health_rot
Definition: sv_resources.qh:29
int autocvar_g_balance_fuel_rotstable
Definition: sv_resources.qh:25
float autocvar_g_balance_armor_regenlinear
Definition: sv_resources.qh:15
float autocvar_g_balance_fuel_rotlinear
Definition: sv_resources.qh:24
#define DMG_NOWEP
Definition: damage.qh:126
float autocvar_g_balance_fuel_rot
Definition: sv_resources.qh:23
void RotRegen(entity this, Resource res, float limit_mod, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime)
Definition: client.qc:1570
float autocvar_g_balance_health_rotlinear
Definition: sv_resources.qh:30
float autocvar_g_balance_armor_rot
Definition: sv_resources.qh:17
RES_HEALTH
Definition: ent_cs.qc:126
float autocvar_g_balance_health_regenstable
Definition: sv_resources.qh:28
int autocvar_g_balance_armor_regenstable
Definition: sv_resources.qh:16
float autocvar_g_balance_fuel_regen
Definition: sv_resources.qh:20
float pauserothealth_finished
Definition: client.qh:343
int autocvar_g_balance_armor_rotstable
Definition: sv_resources.qh:19
float autocvar_g_balance_fuel_regenlinear
Definition: sv_resources.qh:21
float pauserotfuel_finished
Definition: client.qh:345
float frametime
Definition: csprogsdefs.qc:17
float pauserotarmor_finished
Definition: client.qh:344
#define M_ARGV(x, type)
Definition: events.qh:17
int autocvar_g_balance_fuel_regenstable
Definition: sv_resources.qh:22
float autocvar_g_balance_health_regen
Definition: sv_resources.qh:26
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
float items
Definition: progsdefs.qc:145
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
float pauseregen_finished
Definition: client.qh:342
void vehicles_exit(entity vehic, bool eject)
Definition: sv_vehicles.qc:788
float autocvar_g_balance_health_regenlinear
Definition: sv_resources.qh:27
entity vehicle
Definition: impulse.qc:21
float autocvar_g_balance_armor_regen
Definition: sv_resources.qh:14
float autocvar_g_balance_health_rotstable
Definition: sv_resources.qh:31
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerInIDList()

bool PlayerInIDList ( entity  p,
string  idlist 
)

Definition at line 986 of file client.qc.

References findinlist_abbrev().

Referenced by PlayerInList().

987 {
988  // NOTE: we do NOT check crypto_idfp_signed here, an unsigned ID is fine too for this
989  if(!p.crypto_idfp)
990  return false;
991 
992  return findinlist_abbrev(p.crypto_idfp, idlist);
993 }
bool findinlist_abbrev(string tofind, string list)
Definition: client.qc:963
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerInIPList()

bool PlayerInIPList ( entity  p,
string  iplist 
)

Definition at line 977 of file client.qc.

References findinlist_abbrev(), and IS_REAL_CLIENT.

Referenced by PlayerInList().

978 {
979  // some safety checks (never allow local?)
980  if(p.netaddress == "local" || p.netaddress == "" || !IS_REAL_CLIENT(p))
981  return false;
982 
983  return findinlist_abbrev(p.netaddress, iplist);
984 }
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
bool findinlist_abbrev(string tofind, string list)
Definition: client.qc:963
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerInList()

bool PlayerInList ( entity  player,
string  list 
)

Definition at line 995 of file client.qc.

References autocvar_sv_eventlog, boolean, entity(), etof(), GameLogEcho(), IS_REAL_CLIENT, netaddress, playerid, PlayerInIDList(), and PlayerInIPList().

Referenced by Player_DetermineForcedTeam().

996 {
997  return boolean(PlayerInIDList(player, list) || PlayerInIPList(player, list));
998 }
bool PlayerInIPList(entity p, string iplist)
Definition: client.qc:977
#define boolean(value)
Definition: bool.qh:9
bool PlayerInIDList(entity p, string idlist)
Definition: client.qc:986
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerPostThink()

void PlayerPostThink ( entity  this)

Definition at line 2651 of file client.qc.

References autocvar_g_balance_armor_blockpercent, autocvar_sv_maxidle, autocvar_sv_maxidle_alsokickspectators, autocvar_sv_maxidle_minplayers, autocvar_sv_maxidle_playertospectator, autocvar_sv_maxidle_slots, autocvar_sv_maxidle_slots_countbots, ceil(), CheatFrame(), CPID_IDLING, CS(), DAMAGE_NO, death_time, dropclient_schedule(), DrownPlayer(), FOREACH_CLIENT, frametime, GetPressedKeys(), GetResource(), impulse, ImpulseCommands(), intermission_running, IS_DEAD, IS_OBSERVER, IS_PLAYER, IS_REAL_CLIENT, max(), maxclients, maxs, min(), mins, MOVETYPE_NONE, netname, NULL, Player_Physics(), PutObserverInServer(), RES_HEALTH, server_is_dedicated, set_movetype(), SND, solid, SOLID_NOT, takedamage, time, and UpdateChatBubble().

Referenced by StartFrame().

2652 {
2653  Player_Physics(this);
2654 
2656  if (frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
2657  if (IS_REAL_CLIENT(this))
2659  if (!intermission_running) // NextLevel() kills all centerprints after setting this true
2660  {
2661  int totalClients = 0;
2663  {
2664  // maxidle disabled in local matches by not counting clients (totalClients 0)
2665  if (server_is_dedicated)
2666  {
2668  {
2669  ++totalClients;
2670  });
2671  if (maxclients - totalClients > autocvar_sv_maxidle_slots)
2672  totalClients = 0;
2673  }
2674  }
2675  else if (IS_PLAYER(this) && autocvar_sv_maxidle_playertospectator > 0)
2676  {
2678  {
2679  ++totalClients;
2680  });
2681  }
2682 
2683  if (totalClients < autocvar_sv_maxidle_minplayers)
2684  {
2685  // idle kick disabled
2686  CS(this).parm_idlesince = time;
2687  }
2688  else if (time - CS(this).parm_idlesince < 1) // instead of (time == this.parm_idlesince) to support sv_maxidle <= 10
2689  {
2690  if (CS(this).idlekick_lasttimeleft)
2691  {
2692  CS(this).idlekick_lasttimeleft = 0;
2693  Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_IDLING);
2694  }
2695  }
2696  else
2697  {
2698  float maxidle_time = autocvar_sv_maxidle;
2701  float timeleft = ceil(maxidle_time - (time - CS(this).parm_idlesince));
2702  float countdown_time = max(min(10, maxidle_time - 1), ceil(maxidle_time * 0.33)); // - 1 to support maxidle_time <= 10
2703  if (timeleft == countdown_time && !CS(this).idlekick_lasttimeleft)
2704  {
2706  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOVETOSPEC_IDLING, timeleft);
2707  else
2708  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_DISCONNECT_IDLING, timeleft);
2709  }
2710  if (timeleft <= 0) {
2712  {
2713  Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MOVETOSPEC_IDLING, this.netname, maxidle_time);
2714  PutObserverInServer(this, true, true);
2715  }
2716  else
2717  {
2718  if (dropclient_schedule(this))
2719  Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_IDLING, this.netname, maxidle_time);
2720  }
2721  return;
2722  }
2723  else if (timeleft <= countdown_time) {
2724  if (timeleft != CS(this).idlekick_lasttimeleft)
2725  play2(this, SND(TALK2));
2726  CS(this).idlekick_lasttimeleft = timeleft;
2727  }
2728  }
2729  }
2730 
2731  CheatFrame(this);
2732 
2733  if (game_stopped)
2734  {
2735  this.solid = SOLID_NOT;
2736  this.takedamage = DAMAGE_NO;
2737  set_movetype(this, MOVETYPE_NONE);
2738  CS(this).teamkill_complain = 0;
2739  CS(this).teamkill_soundtime = 0;
2740  CS(this).teamkill_soundsource = NULL;
2741  }
2742 
2743  if (IS_PLAYER(this)) {
2744  if(this.death_time == time && IS_DEAD(this))
2745  {
2746  // player's bbox gets resized now, instead of in the damage event that killed the player,
2747  // once all the damage events of this frame have been processed with normal size
2748  this.maxs.z = 5;
2749  setsize(this, this.mins, this.maxs);
2750  }
2751  DrownPlayer(this);
2752  UpdateChatBubble(this);
2753  if (CS(this).impulse) ImpulseCommands(this);
2754  GetPressedKeys(this);
2755  if (game_stopped)
2756  {
2757  CSQCMODEL_AUTOUPDATE(this);
2758  return;
2759  }
2760  }
2761  else if (IS_OBSERVER(this) && STAT(PRESSED_KEYS, this))
2762  {
2763  CS(this).pressedkeys = 0;
2764  STAT(PRESSED_KEYS, this) = 0;
2765  }
2766 
2767  if (this.waypointsprite_attachedforcarrier) {
2768  float hp = healtharmor_maxdamage(GetResource(this, RES_HEALTH), GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x;
2769  WaypointSprite_UpdateHealth(this.waypointsprite_attachedforcarrier, hp);
2770  }
2771 
2772  CSQCMODEL_AUTOUPDATE(this);
2773 }
const float SOLID_NOT
Definition: csprogsdefs.qc:244
float MOVETYPE_NONE
Definition: progsdefs.qc:246
#define SND(id)
Definition: all.qh:35
float autocvar_sv_maxidle
Definition: client.qh:36
int autocvar_sv_maxidle_minplayers
Definition: client.qh:37
ClientState CS(Client this)
Definition: state.qh:47
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
vector maxs
Definition: csprogsdefs.qc:113
#define IS_OBSERVER(v)
Definition: utils.qh:11
string netname
Definition: powerups.qc:20
float maxclients
Definition: csprogsdefs.qc:21
bool dropclient_schedule(entity this)
Schedules dropclient for a player and returns true; if dropclient is already scheduled (for that play...
Definition: main.qc:42
float impulse
Definition: progsdefs.qc:158
void UpdateChatBubble(entity this)
Definition: client.qc:1293
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
int autocvar_sv_maxidle_slots
Definition: client.qh:40
RES_HEALTH
Definition: ent_cs.qc:126
bool autocvar_sv_maxidle_slots_countbots
Definition: client.qh:41
vector mins
Definition: csprogsdefs.qc:113
bool autocvar_sv_maxidle_alsokickspectators
Definition: client.qh:39
void GetPressedKeys(entity this)
Definition: client.qc:1681
float CheatFrame(entity this)
Definition: cheats.qc:703
float autocvar_sv_maxidle_playertospectator
Definition: client.qh:38
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
putting a client as observer in the server
Definition: client.qc:238
#define NULL
Definition: post.qh:17
float frametime
Definition: csprogsdefs.qc:17
float takedamage
Definition: progsdefs.qc:147
#define IS_DEAD(s)
Definition: utils.qh:26
void DrownPlayer(entity this)
Definition: client.qc:2597
void Player_Physics(entity this)
Definition: client.qc:2629
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 CPID_IDLING
Definition: all.inc:654
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
bool intermission_running
Definition: intermission.qh:9
float autocvar_g_balance_armor_blockpercent
Definition: damage.qh:21
float time
Definition: csprogsdefs.qc:16
float death_time
float DAMAGE_NO
Definition: progsdefs.qc:282
bool server_is_dedicated
Definition: world.qh:37
void set_movetype(entity this, int mt)
#define IS_PLAYER(v)
Definition: utils.qh:9
float solid
Definition: csprogsdefs.qc:99
void ImpulseCommands(entity this)
Definition: impulse.qc:372
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerPreThink()

void PlayerPreThink ( entity  this)

Definition at line 2402 of file client.qc.

References anticheat_prethink(), autocvar_g_balance_teams, autocvar_g_campaign, autocvar_g_maxplayers_spectator_blocktime, autocvar_g_xonoticversion, autocvar_sv_eventlog, autocvar_sv_name_maxlength, autocvar_sv_spectate, blockSpectators, bound(), campaign_bots_may_start, CH_VOICE, CS(), CS_CVAR, DAMAGE_NO, DMG_NOWEP, dropclient_schedule(), entity(), error(), FL_GODMODE, flags, frametime, frozen_by, FROZEN_TEMP_DYING, FROZEN_TEMP_REVIVING, ftos(), GameLogEcho(), GetResource(), iceblock, INGAME, intermission_running, IntermissionThink(), IS_DEAD, IS_INDEPENDENT_PLAYER, IS_OBSERVER, IS_PLAYER, IS_REAL_CLIENT, IS_SPEC, IS_VEHICLE, isInvisibleString(), Join(), joinAllowed(), jointime, last_vehiclecheck, max(), max_armorvalue, MAX_WEAPONSLOTS, MIN_SPEC_TIME, MUTATOR_CALLHOOK, netname, ObserverOrSpectatorThink(), origin, PHYS_INPUT_BUTTON_USE, PHYS_INPUT_BUTTON_ZOOM, PHYS_INPUT_BUTTON_ZOOMSCRIPT, Player_GetForcedTeamIndex(), playerid, PlayerThink(), PlayerUseKey(), PrintWelcomeMessage(), RES_HEALTH, revive_speed, SAME_TEAM, SetResourceExplicit(), SetZoomState(), spectatortime, sprint(), start_health, strcat(), strcpy, strstrofs, strzone(), substring(), taunt_soundtime, team, TEAM_FORCE_SPECTATOR, teamkill_soundtime, teamplay, textLengthUpToLength(), time, Unfreeze(), vehicle, vehicles_exit(), vercmp(), VHF_MULTISLOT, VOICETYPE_AUTOTAUNT, VOICETYPE_LASTATTACKER_ONLY, VOL_BASEVOICE, and weaponentities.

Referenced by StartFrame().

2403 {
2404  STAT(GUNALIGN, this) = CS_CVAR(this).cvar_cl_gunalign; // TODO
2405  STAT(MOVEVARS_CL_TRACK_CANJUMP, this) = CS_CVAR(this).cvar_cl_movement_track_canjump;
2406 
2407  WarpZone_PlayerPhysics_FixVAngle(this);
2408 
2409  if (frametime) {
2410  // physics frames: update anticheat stuff
2411  anticheat_prethink(this);
2412 
2413  // WORKAROUND: only use dropclient in server frames (frametime set).
2414  // Never use it in cl_movement frames (frametime zero).
2415  if (blockSpectators && IS_REAL_CLIENT(this)
2416  && (IS_SPEC(this) || IS_OBSERVER(this)) && !INGAME(this)
2418  {
2419  if (dropclient_schedule(this))
2420  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
2421  }
2422  }
2423 
2424  zoomstate_set = false;
2425 
2426  // Check for nameless players
2427  if (this.netname == "" || this.netname != CS(this).netname_previous)
2428  {
2429  bool assume_unchanged = (CS(this).netname_previous == "");
2430  if (autocvar_sv_name_maxlength > 0 && strlennocol(this.netname) > autocvar_sv_name_maxlength)
2431  {
2432  int new_length = textLengthUpToLength(this.netname, autocvar_sv_name_maxlength, strlennocol);
2433  this.netname = strzone(strcat(substring(this.netname, 0, new_length), "^7"));
2434  sprint(this, sprintf("Warning: your name is longer than %d characters, it has been truncated.\n", autocvar_sv_name_maxlength));
2435  assume_unchanged = false;
2436  // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
2437  }
2438  if (isInvisibleString(this.netname))
2439  {
2440  this.netname = strzone(sprintf("Player#%d", this.playerid));
2441  sprint(this, "Warning: invisible names are not allowed.\n");
2442  assume_unchanged = false;
2443  // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
2444  }
2445  if (!assume_unchanged && autocvar_sv_eventlog)
2446  GameLogEcho(strcat(":name:", ftos(this.playerid), ":", playername(this.netname, this.team, false)));
2447  strcpy(CS(this).netname_previous, this.netname);
2448  }
2449 
2450  // version nagging
2451  if (CS(this).version_nagtime && CS_CVAR(this).cvar_g_xonoticversion && time > CS(this).version_nagtime) {
2452  CS(this).version_nagtime = 0;
2453  if (strstrofs(CS_CVAR(this).cvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(CS_CVAR(this).cvar_g_xonoticversion, "autobuild", 0) >= 0) {
2454  // git client
2455  } else if (strstrofs(autocvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(autocvar_g_xonoticversion, "autobuild", 0) >= 0) {
2456  // git server
2457  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
2458  } else {
2459  int r = vercmp(CS_CVAR(this).cvar_g_xonoticversion, autocvar_g_xonoticversion);
2460  if (r < 0) { // old client
2461  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
2462  } else if (r > 0) { // old server
2463  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
2464  }
2465  }
2466  }
2467 
2468  // GOD MODE info
2469  if (!(this.flags & FL_GODMODE) && this.max_armorvalue)
2470  {
2471  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_GODMODE_OFF, this.max_armorvalue);
2472  this.max_armorvalue = 0;
2473  }
2474 
2475  if (frametime && IS_PLAYER(this) && time >= game_starttime)
2476  {
2477  if (STAT(FROZEN, this) == FROZEN_TEMP_REVIVING)
2478  {
2479  STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) + frametime * this.revive_speed, 1);
2480  SetResourceExplicit(this, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, this) * start_health));
2481  if (this.iceblock)
2482  this.iceblock.alpha = bound(0.2, 1 - STAT(REVIVE_PROGRESS, this), 1);
2483 
2484  if (STAT(REVIVE_PROGRESS, this) >= 1)
2485  Unfreeze(this, false);
2486  }
2487  else if (STAT(FROZEN, this) == FROZEN_TEMP_DYING)
2488  {
2489  STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) - frametime * this.revive_speed, 1);
2490  SetResourceExplicit(this, RES_HEALTH, max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * STAT(REVIVE_PROGRESS, this)));
2491 
2492  if (GetResource(this, RES_HEALTH) < 1)
2493  {
2494  if (this.vehicle)
2495  vehicles_exit(this.vehicle, VHEF_RELEASE);
2496  if(this.event_damage)
2497  this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, DMG_NOWEP, this.origin, '0 0 0');
2498  }
2499  else if (STAT(REVIVE_PROGRESS, this) <= 0)
2500  Unfreeze(this, false);
2501  }
2502  }
2503 
2505 
2506  if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !game_stopped && !this.vehicle)
2507  if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this) && !IS_INDEPENDENT_PLAYER(this))
2508  {
2509  FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it) && !IS_DEAD(it) && it.takedamage != DAMAGE_NO,
2510  {
2511  if(!it.owner)
2512  {
2513  if(!it.team || SAME_TEAM(this, it))
2514  Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER);
2515  else if(autocvar_g_vehicles_steal)
2516  Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
2517  }
2518  else if((it.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(it.owner, this))
2519  {
2520  Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER);
2521  }
2522  });
2523 
2524  this.last_vehiclecheck = time + 1;
2525  }
2526 
2527  if(PHYS_INPUT_BUTTON_USE(this) && !CS(this).usekeypressed)
2528  PlayerUseKey(this);
2529  CS(this).usekeypressed = PHYS_INPUT_BUTTON_USE(this);
2530 
2531  if (IS_REAL_CLIENT(this))
2532  PrintWelcomeMessage(this);
2533 
2534  if (IS_PLAYER(this)) {
2535  if (IS_REAL_CLIENT(this) && time < CS(this).jointime + MIN_SPEC_TIME)
2536  error("Client can't be spawned as player on connection!");
2537  if(!PlayerThink(this))
2538  return;
2539  }
2540  else if (game_stopped || intermission_running) {
2542  IntermissionThink(this);
2543  return;
2544  }
2545  else if (IS_REAL_CLIENT(this) && CS(this).autojoin_checked <= 0 && time >= CS(this).jointime + MIN_SPEC_TIME)
2546  {
2547  bool early_join_requested = (CS(this).autojoin_checked < 0);
2548  CS(this).autojoin_checked = 1;
2549  // don't do this in ClientConnect
2550  // many things can go wrong if a client is spawned as player on connection
2551  if (early_join_requested || MUTATOR_CALLHOOK(AutoJoinOnConnection, this)
2554  {
2555  campaign_bots_may_start = true;
2556  if(joinAllowed(this))
2557  Join(this);
2558  return;
2559  }
2560  }
2561  else if (IS_OBSERVER(this) || IS_SPEC(this)) {
2563  }
2564 
2565  // WEAPONTODO: Add weapon request for this
2566  if (!zoomstate_set) {
2567  bool wep_zoomed = false;
2568  for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
2569  {
2570  .entity weaponentity = weaponentities[slot];
2571  Weapon thiswep = this.(weaponentity).m_weapon;
2572  if(thiswep != WEP_Null && thiswep.wr_zoom)
2573  wep_zoomed += thiswep.wr_zoom(thiswep, this);
2574  }
2575  SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
2576  }
2577 
2578  if (CS(this).teamkill_soundtime && time > CS(this).teamkill_soundtime)
2579  {
2580  CS(this).teamkill_soundtime = 0;
2581 
2582  entity e = CS(this).teamkill_soundsource;
2583  entity oldpusher = e.pusher;
2584  e.pusher = this;
2585  PlayerSound(e, playersound_teamshoot, CH_VOICE, VOL_BASEVOICE, VOICETYPE_LASTATTACKER_ONLY);
2586  e.pusher = oldpusher;
2587  }
2588 
2589  if (CS(this).taunt_soundtime && time > CS(this).taunt_soundtime) {
2590  CS(this).taunt_soundtime = 0;
2591  PlayerSound(this, playersound_taunt, CH_VOICE, VOL_BASEVOICE, VOICETYPE_AUTOTAUNT);
2592  }
2593 
2594  target_voicescript_next(this);
2595 }
#define INGAME(it)
Definition: sv_rules.qh:20
const int CH_VOICE
Definition: sound.qh:10
int autocvar_sv_name_maxlength
Definition: client.qh:52
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
Definition: cl_resources.qc:15
float blockSpectators
Definition: client.qh:334
#define IS_INDEPENDENT_PLAYER(e)
Definition: client.qh:314
float last_vehiclecheck
Definition: client.qc:2401
entity() spawn
int playerid
Definition: client.qh:78
ClientState CS(Client this)
Definition: state.qh:47
void PrintWelcomeMessage(entity this)
Definition: client.qc:2049
#define PHYS_INPUT_BUTTON_ZOOM(s)
Definition: player.qh:149
#define IS_OBSERVER(v)
Definition: utils.qh:11
#define CS_CVAR(this)
Definition: state.qh:51
string netname
Definition: powerups.qc:20
entity iceblock
Definition: damage.qh:116
const int VOICETYPE_AUTOTAUNT
Definition: globalsound.qh:68
origin
Definition: ent_cs.qc:114
float FL_GODMODE
Definition: progsdefs.qc:237
bool zoomstate_set
Definition: client.qc:1670
bool dropclient_schedule(entity this)
Schedules dropclient for a player and returns true; if dropclient is already scheduled (for that play...
Definition: main.qc:42
void PlayerPreThink(entity this)
Definition: client.qc:2402
float taunt_soundtime
Definition: damage.qh:62
#define DMG_NOWEP
Definition: damage.qh:126
void SetZoomState(entity this, float newzoom)
Definition: client.qc:1671
void anticheat_prethink(entity this)
Definition: anticheat.qc:157
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
entity frozen_by
Definition: damage.qh:117
#define strcpy(this, s)
Definition: string.qh:49
RES_HEALTH
Definition: ent_cs.qc:126
this team
Definition: client.qc:86
void Unfreeze(entity targ, bool reset_health)
Definition: damage.qc:546
#define IS_SPEC(v)
Definition: utils.qh:10
Force the player to spectator team.
Definition: teamplay.qh:137
void IntermissionThink(entity this)
float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t w)
Definition: util.qc:809
int Player_GetForcedTeamIndex(entity player)
Returns the index of the forced team of the given player.
Definition: teamplay.qc:346
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const int MAX_WEAPONSLOTS
Definition: weapon.qh:13
#define PHYS_INPUT_BUTTON_USE(s)
Definition: player.qh:154
void PlayerUseKey(entity this)
Definition: client.qc:2349
bool joinAllowed(entity this)
Definition: client.qc:2108
ERASEABLE int vercmp(string v1, string v2)
Definition: string.qh:488
float teamkill_soundtime
Definition: damage.qh:58
float frametime
Definition: csprogsdefs.qc:17
float spectatortime
Definition: client.qh:335
int autocvar_sv_spectate
Definition: client.qh:54
#define PHYS_INPUT_BUTTON_ZOOMSCRIPT(s)
Definition: player.qh:157
float jointime
Definition: client.qh:64
#define strstrofs
Definition: dpextensions.qh:42
float max_armorvalue
Definition: items.qh:31
void GameLogEcho(string s)
Definition: gamelog.qc:12
#define SAME_TEAM(a, b)
Definition: teams.qh:239
float teamplay
Definition: progsdefs.qc:31
#define IS_DEAD(s)
Definition: utils.qh:26
bool campaign_bots_may_start
campaign mode: bots shall spawn but wait for the player to spawn before they do anything in other gam...
Definition: campaign.qh:27
#define IS_VEHICLE(v)
Definition: utils.qh:22
const int FROZEN_TEMP_REVIVING
Definition: damage.qh:110
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
const int VHF_MULTISLOT
Add random head angles each frame if health < 50%.
Definition: vehicle.qh:75
float start_health
Definition: world.qh:98
float flags
Definition: csprogsdefs.qc:129
float autocvar_g_maxplayers_spectator_blocktime
Definition: client.qh:44
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
bool PlayerThink(entity this)
Definition: client.qc:2121
entity weaponentities[MAX_WEAPONSLOTS]
Definition: weapon.qh:14
bool autocvar_g_balance_teams
Definition: teamplay.qh:8
const float VOL_BASEVOICE
Definition: sound.qh:37
bool intermission_running
Definition: intermission.qh:9
void vehicles_exit(entity vehic, bool eject)
Definition: sv_vehicles.qc:788
bool autocvar_g_campaign
Definition: campaign.qh:6
const int MIN_SPEC_TIME
Definition: client.qh:399
entity vehicle
Definition: impulse.qc:21
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition: weapon.qh:41
float time
Definition: csprogsdefs.qc:16
float revive_speed
Definition: damage.qh:114
ERASEABLE bool isInvisibleString(string s)
Definition: string.qh:369
void ObserverOrSpectatorThink(entity this)
Definition: client.qc:2267
const int FROZEN_TEMP_DYING
Definition: damage.qh:111
const int VOICETYPE_LASTATTACKER_ONLY
Definition: globalsound.qh:67
float DAMAGE_NO
Definition: progsdefs.qc:282
void Join(entity this)
Definition: client.qc:1966
#define IS_PLAYER(v)
Definition: utils.qh:9
string autocvar_g_xonoticversion
Definition: client.qh:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerThink()

bool PlayerThink ( entity  this)

Definition at line 2121 of file client.qc.

References angles, autocvar_g_teamdamage_resetspeed, bound(), CS(), CS_CVAR, DEAD_DEAD, DEAD_DYING, DEAD_RESPAWNABLE, DEAD_RESPAWNING, deadflag, dmg_team, dualwielding_prev, fixangle, FixPlayermodel(), frametime, g_race_qualifying, intermission_running, IntermissionThink(), IS_DEAD, lastV_angle, max(), MAX_WEAPONSLOTS, MF_ROCKET, modelflags, monsters_setstatus(), personal, PHYS_INPUT_BUTTON_ATCK, PHYS_INPUT_BUTTON_ATCK2, PHYS_INPUT_BUTTON_HOOK, PHYS_INPUT_BUTTON_JUMP, PHYS_INPUT_BUTTON_USE, player_anim(), player_powerups(), player_regen(), respawn(), RESPAWN_DENY, respawn_flags, RESPAWN_FORCE, RESPAWN_SILENT, respawn_time, respawn_time_max, shootfromfixedorigin, ShowRespawnCountdown(), stuffcmd, time, TIMEOUT_ACTIVE, v_angle, vortex_charge, W_DualWielding(), W_ResetGunAlign(), W_TICSPERFRAME, W_WeaponFrame(), weaponentities, and WEP_CVAR.

Referenced by PlayerPreThink().

2122 {
2123  if (game_stopped || intermission_running) {
2124  this.modelflags &= ~MF_ROCKET;
2126  IntermissionThink(this);
2127  return false;
2128  }
2129 
2130  if (timeout_status == TIMEOUT_ACTIVE) {
2131  // don't allow the player to turn around while game is paused
2132  // FIXME turn this into CSQC stuff
2133  this.v_angle = this.lastV_angle;
2134  this.angles = this.lastV_angle;
2135  this.fixangle = true;
2136  }
2137 
2138  if (frametime) player_powerups(this);
2139 
2140  if (IS_DEAD(this)) {
2141  if (this.personal && g_race_qualifying) {
2142  if (time > this.respawn_time) {
2143  STAT(RESPAWN_TIME, this) = this.respawn_time = time + 1; // only retry once a second
2144  respawn(this);
2145  CS(this).impulse = CHIMPULSE_SPEEDRUN.impulse;
2146  }
2147  } else {
2148  if (frametime) player_anim(this);
2149 
2150  if (this.respawn_flags & RESPAWN_DENY)
2151  {
2152  STAT(RESPAWN_TIME, this) = 0;
2153  return false;
2154  }
2155 
2156  bool button_pressed = (PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_ATCK2(this) || PHYS_INPUT_BUTTON_HOOK(this) || PHYS_INPUT_BUTTON_USE(this));
2157 
2158  switch(this.deadflag)
2159  {
2160  case DEAD_DYING:
2161  {
2162  if ((this.respawn_flags & RESPAWN_FORCE) && !(this.respawn_time < this.respawn_time_max))
2163  this.deadflag = DEAD_RESPAWNING;
2164  else if (!button_pressed || (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE)))
2165  this.deadflag = DEAD_DEAD;
2166  break;
2167  }
2168  case DEAD_DEAD:
2169  {
2170  if (button_pressed)
2171  this.deadflag = DEAD_RESPAWNABLE;
2172  else if (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE))
2173  this.deadflag = DEAD_RESPAWNING;
2174  break;
2175  }
2176  case DEAD_RESPAWNABLE:
2177  {
2178  if (!button_pressed || (this.respawn_flags & RESPAWN_FORCE))
2179  this.deadflag = DEAD_RESPAWNING;
2180  break;
2181  }
2182  case DEAD_RESPAWNING:
2183  {
2184  if (time > this.respawn_time)
2185  {
2186  this.respawn_time = time + 1; // only retry once a second
2187  this.respawn_time_max = this.respawn_time;
2188  respawn(this);
2189  }
2190  break;
2191  }
2192  }
2193 
2194  ShowRespawnCountdown(this);
2195 
2196  if (this.respawn_flags & RESPAWN_SILENT)
2197  STAT(RESPAWN_TIME, this) = 0;
2198  else if ((this.respawn_flags & RESPAWN_FORCE) && this.respawn_time < this.respawn_time_max)
2199  {
2200  if (time < this.respawn_time)
2201  STAT(RESPAWN_TIME, this) = this.respawn_time;
2202  else if (this.deadflag != DEAD_RESPAWNING)
2203  STAT(RESPAWN_TIME, this) = -this.respawn_time_max;
2204  }
2205  else
2206  STAT(RESPAWN_TIME, this) = this.respawn_time;
2207  }
2208 
2209  // if respawning, invert stat_respawn_time to indicate this, the client translates it
2210  if (this.deadflag == DEAD_RESPAWNING && STAT(RESPAWN_TIME, this) > 0)
2211  STAT(RESPAWN_TIME, this) *= -1;
2212 
2213  return false;
2214  }
2215 
2216  FixPlayermodel(this);
2217 
2218  if (this.shootfromfixedorigin != autocvar_g_shootfromfixedorigin) {
2219  this.shootfromfixedorigin = autocvar_g_shootfromfixedorigin;
2220  stuffcmd(this, sprintf("\ncl_shootfromfixedorigin \"%s\"\n", autocvar_g_shootfromfixedorigin));
2221  }
2222 
2223  // reset gun alignment when dual wielding status changes
2224  // to ensure guns are always aligned right and left
2225  bool dualwielding = W_DualWielding(this);
2226  if(this.dualwielding_prev != dualwielding)
2227  {
2228  W_ResetGunAlign(this, CS_CVAR(this).cvar_cl_gunalign);
2229  this.dualwielding_prev = dualwielding;
2230  }
2231 
2232  // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers
2233  //if(frametime)
2234  {
2235  for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
2236  {
2237  .entity weaponentity = weaponentities[slot];
2238  if(WEP_CVAR(vortex, charge_always))
2239  W_Vortex_Charge(this, weaponentity, frametime);
2240  W_WeaponFrame(this, weaponentity);
2241  }
2242  }
2243 
2244  if (frametime)
2245  {
2246  // WEAPONTODO: Add a weapon request for this
2247  // rot vortex charge to the charge limit
2248  for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
2249  {
2250  .entity weaponentity = weaponentities[slot];
2251  if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
2252  this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
2253  }
2254 
2255  player_regen(this);
2256  player_anim(this);
2258  }
2259 
2260  monsters_setstatus(this);
2261 
2262  return true;
2263 }
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition: player.qh:148
float DEAD_DYING
Definition: progsdefs.qc:275
void respawn(entity this)
Definition: client.qc:1417
const int RESPAWN_FORCE
Definition: client.qh:330
#define PHYS_INPUT_BUTTON_JUMP(s)
Definition: player.qh:147
const int RESPAWN_DENY
Definition: client.qh:332
#define PHYS_INPUT_BUTTON_HOOK(s)
Definition: player.qh:151
const int MF_ROCKET
void W_WeaponFrame(Player actor,.entity weaponentity)
void player_regen(entity this)
Definition: client.qc:1601
int respawn_flags
Definition: client.qh:324
float respawn_time
Definition: client.qh:325
ClientState CS(Client this)
Definition: state.qh:47
vector v_angle
Definition: progsdefs.qc:161
#define CS_CVAR(this)
Definition: state.qh:51
void player_powerups(entity this)
Definition: client.qc:1470
#define WEP_CVAR(wepname, name)
Definition: all.qh:299
void W_ResetGunAlign(entity player, int preferred_alignment)
float dmg_team
Definition: damage.qh:56
string shootfromfixedorigin
Definition: client.qc:2119
const float TIMEOUT_ACTIVE
Definition: common.qh:49
bool g_race_qualifying
Definition: race.qh:12
int modelflags
float DEAD_DEAD
Definition: progsdefs.qc:276
float respawn_time_max
Definition: client.qh:326
void IntermissionThink(entity this)
entity personal
Definition: cheats.qh:23
bool W_DualWielding(entity player)
Definition: common.qc:20
const int MAX_WEAPONSLOTS
Definition: weapon.qh:13
void monsters_setstatus(entity this)
Definition: sv_monsters.qc:33
#define PHYS_INPUT_BUTTON_USE(s)
Definition: player.qh:154
void player_anim(entity this)
Definition: player.qc:152
float fixangle
Definition: progsdefs.qc:160
float frametime
Definition: csprogsdefs.qc:17
void ShowRespawnCountdown(entity this)
Definition: client.qc:1939
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition: player.qh:146
#define IS_DEAD(s)
Definition: utils.qh:26
float DEAD_RESPAWNING
Definition: progsdefs.qc:278
#define stuffcmd(cl,...)
Definition: progsdefs.qh:23
bool dualwielding_prev
Definition: client.qc:2120
float deadflag
Definition: progsdefs.qc:149
void FixPlayermodel(entity player)
Definition: client.qc:423
entity weaponentities[MAX_WEAPONSLOTS]
Definition: weapon.qh:14
bool intermission_running
Definition: intermission.qh:9
float vortex_charge
Definition: wepent.qh:6
vector angles
Definition: csprogsdefs.qc:104
vector lastV_angle
Definition: common.qh:62
float autocvar_g_teamdamage_resetspeed
Definition: damage.qh:22
float time
Definition: csprogsdefs.qc:16
float DEAD_RESPAWNABLE
Definition: progsdefs.qc:277
const int RESPAWN_SILENT
Definition: client.qh:331
const int W_TICSPERFRAME
Definition: weaponsystem.qh:14
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PlayerUseKey()

void PlayerUseKey ( entity  this)

Definition at line 2349 of file client.qc.

References DAMAGE_NO, entity(), IS_DEAD, IS_INDEPENDENT_PLAYER, IS_PLAYER, IS_VEHICLE, MUTATOR_CALLHOOK, NULL, origin, PlayerUseKey(), SAME_TEAM, vehicle, vehicles_enter(), vehicles_exit(), VHF_MULTISLOT, vlen2, and WarpZone_FindRadius().

Referenced by IMPULSE(), PlayerPreThink(), and PlayerUseKey().

2350 {
2351  if (!IS_PLAYER(this))
2352  return;
2353 
2354  if(this.vehicle)
2355  {
2356  if(!game_stopped)
2357  {
2358  vehicles_exit(this.vehicle, VHEF_NORMAL);
2359  return;
2360  }
2361  }
2362  else if(autocvar_g_vehicles_enter)
2363  {
2364  if(!game_stopped && !STAT(FROZEN, this) && !IS_DEAD(this) && !IS_INDEPENDENT_PLAYER(this))
2365  {
2366  entity head, closest_target = NULL;
2367  head = WarpZone_FindRadius(this.origin, autocvar_g_vehicles_enter_radius, true);
2368 
2369  while(head) // find the closest acceptable target to enter
2370  {
2371  if(IS_VEHICLE(head) && !IS_DEAD(head) && head.takedamage != DAMAGE_NO)
2372  if(!head.owner || ((head.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(head.owner, this)))
2373  {
2374  if(closest_target)
2375  {
2376  if(vlen2(this.origin - head.origin) < vlen2(this.origin - closest_target.origin))
2377  { closest_target = head; }
2378  }
2379  else { closest_target = head; }
2380  }
2381 
2382  head = head.chain;
2383  }
2384 
2385  if(closest_target) { vehicles_enter(this, closest_target); return; }
2386  }
2387  }
2388 
2389  // a use key was pressed; call handlers
2391 }
#define IS_INDEPENDENT_PLAYER(e)
Definition: client.qh:314
entity() spawn
origin
Definition: ent_cs.qc:114
void vehicles_enter(entity pl, entity veh)
Definition: sv_vehicles.qc:939
#define vlen2(v)
Definition: vector.qh:4
void PlayerUseKey(entity this)
Definition: client.qc:2349
#define NULL
Definition: post.qh:17
#define SAME_TEAM(a, b)
Definition: teams.qh:239
#define IS_DEAD(s)
Definition: utils.qh:26
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition: common.qc:669
#define IS_VEHICLE(v)
Definition: utils.qh:22
const int VHF_MULTISLOT
Add random head angles each frame if health < 50%.
Definition: vehicle.qh:75
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
void vehicles_exit(entity vehic, bool eject)
Definition: sv_vehicles.qc:788
entity vehicle
Definition: impulse.qc:21
float DAMAGE_NO
Definition: progsdefs.qc:282
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PM_UpdateButtons()

void PM_UpdateButtons ( entity  this,
entity  store 
)

Definition at line 2776 of file client.qc.

References button0, button10, button11, button12, button13, button14, button15, button16, button2, button3, button4, button5, button6, button7, button8, button9, buttonchat, buttonuse, cursor_active, cursor_screen, cursor_trace_endpos, cursor_trace_ent, cursor_trace_start, impulse, movement, ping, ping_movementloss, ping_packetloss, and v_angle.

Referenced by IsFlying().

2777 {
2778  if(this.impulse)
2779  store.impulse = this.impulse;
2780  this.impulse = 0;
2781 
2782  bool typing = this.buttonchat || this.button12;
2783 
2784  store.button0 = (typing) ? 0 : this.button0;
2785  //button1?!
2786  store.button2 = (typing) ? 0 : this.button2;
2787  store.button3 = (typing) ? 0 : this.button3;
2788  store.button4 = this.button4;
2789  store.button5 = (typing) ? 0 : this.button5;
2790  store.button6 = this.button6;
2791  store.button7 = this.button7;
2792  store.button8 = this.button8;
2793  store.button9 = this.button9;
2794  store.button10 = this.button10;
2795  store.button11 = this.button11;
2796  store.button12 = this.button12;
2797  store.button13 = this.button13;
2798  store.button14 = this.button14;
2799  store.button15 = this.button15;
2800  store.button16 = this.button16;
2801  store.buttonuse = this.buttonuse;
2802  store.buttonchat = this.buttonchat;
2803 
2804  store.cursor_active = this.cursor_active;
2805  store.cursor_screen = this.cursor_screen;
2806  store.cursor_trace_start = this.cursor_trace_start;
2807  store.cursor_trace_endpos = this.cursor_trace_endpos;
2808  store.cursor_trace_ent = this.cursor_trace_ent;
2809 
2810  store.ping = this.ping;
2811  store.ping_packetloss = this.ping_packetloss;
2812  store.ping_movementloss = this.ping_movementloss;
2813 
2814  store.v_angle = this.v_angle;
2815  store.movement = this.movement;
2816 }
float button3
float button12
float buttonchat
Definition: dpextensions.qc:36
vector cursor_screen
vector v_angle
Definition: progsdefs.qc:161
float button6
float ping
Definition: main.qh:138
vector cursor_trace_start
vector cursor_trace_endpos
float impulse
Definition: progsdefs.qc:158
float button8
float button5
float button10
int cursor_active
Definition: view.qh:108
float ping_packetloss
Definition: main.qh:138
float button4
float button7
vector movement
entity cursor_trace_ent
float button13
float button16
float button0
Definition: progsdefs.qc:154
float button2
Definition: progsdefs.qc:156
float ping_movementloss
Definition: main.qh:138
float button14
float button15
float button9
float buttonuse
Definition: dpextensions.qc:44
float button11
+ Here is the caller graph for this function:

◆ PrintWelcomeMessage()

void PrintWelcomeMessage ( entity  this)

Definition at line 2049 of file client.qc.

References autocvar_g_campaign, Campaign_GetLevelNum(), Campaign_GetMessage(), CPID_CAMPAIGN_MESSAGE, CS(), floor(), getwelcomemessage(), IS_PLAYER, IS_SPEC, motd_actived_time, PHYS_INPUT_BUTTON_INFO, random(), and time.

Referenced by PlayerPreThink().

2050 {
2051  if(CS(this).motd_actived_time == 0)
2052  {
2053  if (autocvar_g_campaign) {
2054  if ((IS_PLAYER(this) && PHYS_INPUT_BUTTON_INFO(this)) || (!IS_PLAYER(this))) {
2055  CS(this).motd_actived_time = time;
2056  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_CAMPAIGN_MESSAGE, Campaign_GetMessage(), Campaign_GetLevelNum());
2057  }
2058  } else {
2059  if (PHYS_INPUT_BUTTON_INFO(this)) {
2060  CS(this).motd_actived_time = time;
2061  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
2062  }
2063  }
2064  }
2065  else if(CS(this).motd_actived_time > 0) // showing MOTD or campaign message
2066  {
2067  if (autocvar_g_campaign) {
2068  if (PHYS_INPUT_BUTTON_INFO(this))
2069  CS(this).motd_actived_time = time;
2070  else if ((time - CS(this).motd_actived_time > 2) && IS_PLAYER(this)) { // hide it some seconds after BUTTON_INFO has been released
2071  CS(this).motd_actived_time = 0;
2072  Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
2073  }
2074  } else {
2075  if (PHYS_INPUT_BUTTON_INFO(this))
2076  CS(this).motd_actived_time = time;
2077  else if (time - CS(this).motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
2078  CS(this).motd_actived_time = 0;
2079  Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
2080  }
2081  }
2082  }
2083  else //if(CS(this).motd_actived_time < 0) // just connected, motd is active
2084  {
2085  if(PHYS_INPUT_BUTTON_INFO(this)) // BUTTON_INFO hides initial MOTD
2086  CS(this).motd_actived_time = -2; // wait until BUTTON_INFO gets released
2087  else if (CS(this).motd_actived_time == -2)
2088  {
2089  // instantly hide MOTD
2090  CS(this).motd_actived_time = 0;
2091  if (autocvar_g_campaign)
2092  Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
2093  else
2094  Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
2095  }
2096  else if (IS_PLAYER(this) || IS_SPEC(this))
2097  {
2098  // FIXME occasionally for some reason MOTD never goes away
2099  // delay MOTD removal a little bit in the hope it fixes this bug
2100  if (CS(this).motd_actived_time == -1) // MOTD marked to fade away as soon as client becomes player or spectator
2101  CS(this).motd_actived_time = -(5 + floor(random() * 10)); // add small delay
2102  else //if (CS(this).motd_actived_time < -2)
2103  CS(this).motd_actived_time++;
2104  }
2105  }
2106 }
string getwelcomemessage(entity this)
Definition: client.qc:1036
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 CPID_CAMPAIGN_MESSAGE
Definition: all.inc:715
ClientState CS(Client this)
Definition: state.qh:47
int Campaign_GetLevelNum()
Definition: campaign.qc:44
#define IS_SPEC(v)
Definition: utils.qh:10
float motd_actived_time
Definition: client.qh:67
bool autocvar_g_campaign
Definition: campaign.qh:6
float time
Definition: csprogsdefs.qc:16
string Campaign_GetMessage()
Definition: campaign.qc:49
#define PHYS_INPUT_BUTTON_INFO(s)
Definition: player.qh:152
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PutClientInServer() [1/2]

PutClientInServer ( this  )
Initial value:
{
TRANSMUTE(Player, this)

Referenced by bot_spawn(), Join(), MUTATOR_HOOKFUNCTION(), ObserverOrSpectatorThink(), PutClientInServer(), reset_map(), and respawn().

+ Here is the caller graph for this function:

◆ PutClientInServer() [2/2]

void PutClientInServer ( entity  this)

Called when a client spawns in the server.

Definition at line 811 of file client.qc.

References bot_relinkplayerlist(), enemy, IS_BOT_CLIENT, IS_OBSERVER, IS_PLAYER, IS_REAL_CLIENT, msg_entity, MSG_ONE, MUTATOR_CALLHOOK, NULL, PS, PutClientInServer(), PutObserverInServer(), PutPlayerInServer(), SetSpectatee(), SVC_SETVIEW, TRANSMUTE(), WriteByte(), and WriteEntity().

812 {
813  if (IS_BOT_CLIENT(this)) {
814  TRANSMUTE(Player, this);
815  } else if (IS_REAL_CLIENT(this)) {
816  msg_entity = this;
818  WriteEntity(MSG_ONE, this);
819  }
820  if (game_stopped)
821  TRANSMUTE(Observer, this);
822 
823  bool use_spawnpoint = (!this.enemy); // check this.enemy here since SetSpectatee will clear it
824  SetSpectatee(this, NULL);
825 
826  // reset player keys
827  if(PS(this))
828  PS(this).itemkeys = 0;
829 
831 
832  if (IS_OBSERVER(this)) {
833  PutObserverInServer(this, false, use_spawnpoint);
834  } else if (IS_PLAYER(this)) {
835  PutPlayerInServer(this);
836  }
837 
839 }
TRANSMUTE(Player, this)
void bot_relinkplayerlist()
Definition: bot.qc:381
#define IS_OBSERVER(v)
Definition: utils.qh:11
#define PS(this)
Definition: state.qh:18
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
entity enemy
Definition: sv_ctf.qh:143
entity msg_entity
Definition: progsdefs.qc:63
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
putting a client as observer in the server
Definition: client.qc:238
#define NULL
Definition: post.qh:17
void SetSpectatee(entity this, entity spectatee)
Definition: client.qc:1836
const int SVC_SETVIEW
Definition: client.qh:339
void PutPlayerInServer(entity this)
Definition: client.qc:535
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition: utils.qh:15
PutClientInServer(this)
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:

◆ PutObserverInServer()

void PutObserverInServer ( entity  this,
bool  is_forced,
bool  use_spawnpoint 
)

putting a client as observer in the server

Definition at line 238 of file client.qc.

References accuracy_resend(), alivetime, alpha, angles, autocvar_g_balance_armor_start, autocvar_g_playerclip_collisions, AuxiliaryXhair, avelocity, bot_attack, bot_relinkplayerlist(), CHAT_NOSPECTATORS, CS(), DAMAGE_NO, damagedbycontents, damageforcescale, DEAD_NO, deadflag, death_time, DPCONTENTS_PLAYERCLIP, DPCONTENTS_SOLID, dphitcontentsmask, drag_undraggable(), drawonlytoclient, effects, entity(), etof(), fade_time, fixangle, FixPlayermodel(), FL_CLIENT, FL_NOTARGET, flags, frags, FRAGS_SPECTATOR, func_null(), g_bot_targets, g_damagedbycontents, g_monster_targets, GetResource(), IL_REMOVE(), IS_PLAYER, IS_REAL_CLIENT, iscreature, istypefrag, items, just_joined, killcount, LOG_FATAL, MAX_AXH, MAX_WEAPONSLOTS, model, monster_attack, MOVETYPE_FLY_WORLDONLY, msg_entity, MSG_ONE, MUTATOR_CALLHOOK, nextthink, NULL, oldvelocity, origin, pain_finished, pauseregen_finished, pauserotarmor_finished, pauserothealth_finished, player_powerups_remove_all(), PlayerState_detach(), Portal_ClearAll(), punchangle, punchvector, pushltime, ready, ReadyCount(), RemoveGrapplingHooks(), RES_HEALTH, respawn_flags, respawn_time, revival_time, scale, SelectSpawnPoint(), set_movetype(), setmodel, setorigin(), SetPlayerTeam(), SetResourceExplicit(), SetSpectatee(), SetSpectatee_status(), setthink, solid, SOLID_NOT, SVC_SETVIEW, takedamage, TEAM_CHANGE_SPECTATOR, TELEPORT_SIMPLE, teleportable, time, TRANSMUTE(), Unfreeze(), UNSET_DUCKED, vec2, vehicle, vehicles_exit(), velocity, view_ofs, viewloc, vote_called, VoteCount(), warmup_stage, weaponentities, weaponmodel, WriteByte(), and WriteEntity().

Referenced by ClientKill_Now_TeamChange(), GameCommand_allspec(), GameCommand_moveplayer(), minigame_addplayer(), ObserverOrSpectatorThink(), PlayerPostThink(), PutClientInServer(), SpectateSet(), and STATIC_INIT().

239 {
240  bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver, this, is_forced);
241  bool recount_ready = false;
242  PlayerState_detach(this);
243 
244  if (IS_PLAYER(this))
245  {
246  if(GetResource(this, RES_HEALTH) >= 1)
247  {
248  // despawn effect
249  Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1);
250  }
251 
252  // was a player, recount votes and ready status
253  if(IS_REAL_CLIENT(this))
254  {
255  if (vote_called) { VoteCount(false); }
256  this.ready = false;
257  recount_ready = true;
258  }
259  entcs_update_players(this);
260  }
261 
262  if (use_spawnpoint)
263  {
264  entity spot = SelectSpawnPoint(this, true);
265  if (!spot) LOG_FATAL("No spawnpoints for observers?!?");
266  this.angles = vec2(spot.angles);
267  // offset it so that the spectator spawns higher off the ground, looks better this way
268  setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this));
269  }
270  else // change origin to restore previous view origin
271  setorigin(this, this.origin + STAT(PL_VIEW_OFS, this) - STAT(PL_CROUCH_VIEW_OFS, this));
272  this.fixangle = true;
273 
274  if (IS_REAL_CLIENT(this))
275  {
276  msg_entity = this;
278  WriteEntity(MSG_ONE, this);
279  }
280  // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
281  // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
282  if(!autocvar_g_debug_globalsounds)
283  {
284  // needed for player sounds
285  this.model = "";
286  FixPlayermodel(this);
287  }
288  setmodel(this, MDL_Null);
289  setsize(this, STAT(PL_CROUCH_MIN, this), STAT(PL_CROUCH_MAX, this));
290  this.view_ofs = '0 0 0';
291 
292  RemoveGrapplingHooks(this);
293  Portal_ClearAll(this);
294  Unfreeze(this, false);
295  SetSpectatee(this, NULL);
296 
297  if (this.alivetime)
298  {
299  if (!warmup_stage)
300  PlayerStats_GameReport_Event_Player(this, PLAYERSTATS_ALIVETIME, time - this.alivetime);
301  this.alivetime = 0;
302  }
303 
304  if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
305 
306  TRANSMUTE(Observer, this);
307 
308  if(recount_ready) ReadyCount();
309 
310  WaypointSprite_PlayerDead(this);
311  accuracy_resend(this);
312 
313  if (CS(this).killcount != FRAGS_SPECTATOR && !game_stopped && CHAT_NOSPECTATORS())
314  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
315 
316  CS(this).spectatortime = time;
317  if(this.bot_attack)
318  IL_REMOVE(g_bot_targets, this);
319  this.bot_attack = false;
320  if(this.monster_attack)
322  this.monster_attack = false;
323  STAT(HUD, this) = HUD_NORMAL;
324  this.iscreature = false;
326  if(this.damagedbycontents)
328  this.damagedbycontents = false;
330  SetSpectatee_status(this, etof(this));
331  this.takedamage = DAMAGE_NO;
332  this.solid = SOLID_NOT;
333  set_movetype(this, MOVETYPE_FLY_WORLDONLY); // user preference is controlled by playerprethink
334  this.flags = FL_CLIENT | FL_NOTARGET;
335  this.effects = 0;
336  SetResourceExplicit(this, RES_ARMOR, autocvar_g_balance_armor_start); // was 666?!
337  this.pauserotarmor_finished = 0;
338  this.pauserothealth_finished = 0;
339  this.pauseregen_finished = 0;
340  this.damageforcescale = 0;
341  this.death_time = 0;
342  this.respawn_flags = 0;
343  this.respawn_time = 0;
344  STAT(RESPAWN_TIME, this) = 0;
345  this.alpha = 0;
346  this.scale = 0;
347  this.fade_time = 0;
348  this.pain_finished = 0;
349  STAT(AIR_FINISHED, this) = 0;
350  //this.dphitcontentsmask = 0;
354  this.pushltime = 0;
355  this.istypefrag = 0;
356  setthink(this, func_null);
357  this.nextthink = 0;
358  this.deadflag = DEAD_NO;
359  UNSET_DUCKED(this);
360  STAT(REVIVE_PROGRESS, this) = 0;
361  this.revival_time = 0;
362  this.draggable = drag_undraggable;
363 
365  this.items = 0;
366  STAT(WEAPONS, this) = '0 0 0';
367  this.drawonlytoclient = this;
368 
369  this.viewloc = NULL;
370 
371  //this.spawnpoint_targ = NULL; // keep it so they can return to where they were?
372 
373  this.weaponmodel = "";
374  for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
375  {
376  this.weaponentities[slot] = NULL;
377  }
378  this.exteriorweaponentity = NULL;
379  CS(this).killcount = FRAGS_SPECTATOR;
380  this.velocity = '0 0 0';
381  this.avelocity = '0 0 0';
382  this.punchangle = '0 0 0';
383  this.punchvector = '0 0 0';
384  this.oldvelocity = this.velocity;
385  this.event_damage = func_null;
386  this.event_heal = func_null;
387 
388  for(int slot = 0; slot < MAX_AXH; ++slot)
389  {
390  entity axh = this.(AuxiliaryXhair[slot]);
391  this.(AuxiliaryXhair[slot]) = NULL;
392 
393  if(axh.owner == this && axh != NULL && !wasfreed(axh))
394  delete(axh);
395  }
396 
397  if (mutator_returnvalue)
398  {
399  // mutator prevents resetting teams+score
400  }
401  else
402  {
404  this.frags = FRAGS_SPECTATOR;
405  }
406 
408 
409  if (CS(this).just_joined)
410  CS(this).just_joined = false;
411 }
const float SOLID_NOT
Definition: csprogsdefs.qc:244
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
entity SelectSpawnPoint(entity this, bool anypoint)
Definition: spawnpoints.qc:329
void ReadyCount()
Definition: vote.qc:498
float alpha
Definition: items.qc:14
bool monster_attack
Definition: sv_monsters.qh:62
IntrusiveList g_monster_targets
Definition: sv_monsters.qh:147
bool SetPlayerTeam(entity player, int team_index, int type)
Sets the team of the player.
Definition: teamplay.qc:237
TRANSMUTE(Player, this)
vector view_ofs
Definition: progsdefs.qc:151
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
Definition: cl_resources.qc:15
int respawn_flags
Definition: client.qh:324
const int TELEPORT_SIMPLE
Definition: teleporters.qh:27
bool iscreature
Definition: main.qh:42
void bot_relinkplayerlist()
Definition: bot.qc:381
float respawn_time
Definition: client.qh:325
float damageforcescale
Definition: damage.qh:137
IntrusiveList g_damagedbycontents
Definition: damage.qh:155
entity() spawn
float bot_attack
Definition: api.qh:38
ClientState CS(Client this)
Definition: state.qh:47
int autocvar_g_balance_armor_start
Definition: client.qh:10
bool warmup_stage
Definition: main.qh:103
bool ready
Definition: main.qh:74
float pushltime
Definition: jumppads.qh:10
float DPCONTENTS_PLAYERCLIP
float vote_called
Definition: vote.qh:43
origin
Definition: ent_cs.qc:114
#define UNSET_DUCKED(s)
Definition: player.qh:208
vector punchangle
vector oldvelocity
Definition: main.qh:38
vector avelocity
Definition: csprogsdefs.qc:105
int killcount
Definition: client.qh:317
const int MAX_AXH
Definition: cl_vehicles.qh:23
float effects
Definition: csprogsdefs.qc:111
string model
Definition: csprogsdefs.qc:108
IntrusiveList g_bot_targets
Definition: api.qh:149
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
#define setmodel(this, m)
Definition: model.qh:26
RES_HEALTH
Definition: ent_cs.qc:126
#define CHAT_NOSPECTATORS()
Definition: chat.qh:27
void Unfreeze(entity targ, bool reset_health)
Definition: damage.qc:546
string weaponmodel
Definition: progsdefs.qc:140
Player is joining spectators. //TODO: Remove?
Definition: teamplay.qh:113
entity msg_entity
Definition: progsdefs.qc:63
vector punchvector
entity AuxiliaryXhair[MAX_AXH]
Definition: cl_vehicles.qh:24
void Portal_ClearAll(entity own)
Definition: portals.qc:587
float damagedbycontents
Definition: damage.qh:48
const int MAX_WEAPONSLOTS
Definition: weapon.qh:13
bool just_joined
Definition: client.qh:74
float pauserothealth_finished
Definition: client.qh:343
float fixangle
Definition: progsdefs.qc:160
float MOVETYPE_FLY_WORLDONLY
#define NULL
Definition: post.qh:17
float DPCONTENTS_SOLID
float pauserotarmor_finished
Definition: client.qh:344
frags
Definition: ent_cs.qc:151
float takedamage
Definition: progsdefs.qc:147
void SetSpectatee(entity this, entity spectatee)
Definition: client.qc:1836
float alivetime
Definition: client.qh:66
float nextthink
Definition: csprogsdefs.qc:121
float scale
Definition: projectile.qc:14
void RemoveGrapplingHooks(entity pl)
Definition: hook.qc:78
void SetSpectatee_status(entity this, int spectatee_num)
Definition: client.qc:1819
entity viewloc
Definition: viewloc.qh:13
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
float deadflag
Definition: progsdefs.qc:149
float pain_finished
float flags
Definition: csprogsdefs.qc:129
entity drawonlytoclient
bool istypefrag
Definition: jumppads.qh:11
float fade_time
Definition: common.qh:22
const int SVC_SETVIEW
Definition: client.qh:339
float items
Definition: progsdefs.qc:145
const int FRAGS_SPECTATOR
Definition: constants.qh:4
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
bool drag_undraggable(entity draggee, entity dragger)
Definition: cheats.qc:897
void FixPlayermodel(entity player)
Definition: client.qc:423
#define vec2(...)
Definition: vector.qh:90
entity weaponentities[MAX_WEAPONSLOTS]
Definition: weapon.qh:14
float teleportable
Definition: teleporters.qh:24
setorigin(ent, v)
float dphitcontentsmask
float DEAD_NO
Definition: progsdefs.qc:274
float pauseregen_finished
Definition: client.qh:342
#define setthink(e, f)
vector angles
Definition: csprogsdefs.qc:104
void vehicles_exit(entity vehic, bool eject)
Definition: sv_vehicles.qc:788
float FL_NOTARGET
Definition: progsdefs.qc:238
void PlayerState_detach(entity this)
Definition: state.qc:22
void VoteCount(float first_count)
Definition: vote.qc:207
entity vehicle
Definition: impulse.qc:21
bool autocvar_g_playerclip_collisions
Definition: client.qh:17
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
#define LOG_FATAL(...)
Definition: log.qh:58
float death_time
void accuracy_resend(entity e)
Definition: accuracy.qc:74
float DAMAGE_NO
Definition: progsdefs.qc:282
float revival_time
Definition: damage.qh:113
void set_movetype(entity this, int mt)
#define IS_PLAYER(v)
Definition: utils.qh:9
var void func_null()
void player_powerups_remove_all(entity this)
Definition: client.qc:1457
float FL_CLIENT
Definition: progsdefs.qc:234
float solid
Definition: csprogsdefs.qc:99
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ PutPlayerInServer()

void PutPlayerInServer ( entity  this)

Definition at line 535 of file client.qc.

References accuracy_resend(), alivetime, alpha, angles, antilag_clear(), autocvar__notarget, autocvar_g_balance_pause_armor_rot_spawn, autocvar_g_balance_pause_fuel_rot_spawn, autocvar_g_balance_pause_health_regen_spawn, autocvar_g_balance_pause_health_rot_spawn, autocvar_g_balance_superweapons_time, autocvar_g_ballistics_density_player, autocvar_g_botclip_collisions, autocvar_g_player_brightness, autocvar_g_player_damageforcescale, autocvar_g_playerclip_collisions, autocvar_g_random_start_weapons, autocvar_g_spawnshieldtime, autocvar_g_weaponswitch_debug, autocvar_spawn_debug, autocvar_sv_player_scale, autocvar_sv_q3compat_changehitbox, AuxiliaryXhair, avelocity, bot_aim_reset(), bot_attack, CH_PLAYER_SINGLE, CL_SpawnWeaponentity(), colormod, CONTENT_EMPTY, conveyor, CS(), CS_CVAR, DAMAGE_AIM, damagedbycontents, damageforcescale, DEAD_NO, deadflag, death_time, default_player_alpha, default_weapon_alpha, dmg_team, DPCONTENTS_BODY, DPCONTENTS_BOTCLIP, DPCONTENTS_PLAYERCLIP, DPCONTENTS_SOLID, dphitcontentsmask, drawonlytoclient, EF_RESTARTANIM_BIT, EF_TELEPORT_BIT, effects, entity(), fade_time, fixangle, FixPlayermodel(), FL_CLIENT, FL_NOTARGET, flags, FOREACH, frags, FRAGS_PLAYER, FRAGS_SPECTATOR, fragsfilter_cnt, func_null(), g_assault, g_bot_targets, g_conveyed, g_damagedbycontents, g_ladderents, g_monster_targets, g_race, GiveRandomWeapons(), IL_EACH, IL_PUSH(), IL_REMOVE(), impulse, ImpulseCommands(), INDEPENDENT_PLAYERS, IS_BOT_CLIENT, iscreature, items, killcount, ladder_entity, MAKE_INDEPENDENT_PLAYER, MAX_AXH, MAX_WEAPONSLOTS, model, monster_attack, MOVETYPE_WALK, MUTATOR_CALLHOOK, navigation_dynamicgoal_init(), new_pure, nextthink, NULL, oldorigin, oldvelocity, origin, pain_finished, pauseregen_finished, pauserotarmor_finished, pauserotfuel_finished, pauserothealth_finished, PHYS_INPUT_BUTTON_ATCK, PHYS_INPUT_BUTTON_ATCK2, PHYS_INPUT_BUTTON_JUMP, PlayerDamage(), PlayerHeal(), PlayerScore_Clear(), PlayerState_attach(), PS, punchangle, punchvector, pushltime, q3compat, random_start_ammo, random_start_weapons_count, RES_HEALTH, respawn_flags, respawn_time, revival_time, scale, SelectSpawnPoint(), set_movetype(), setorigin(), SetResource(), SetSpectatee_status(), setthink, solid, SOLID_SLIDEBOX, SpawnEvent_Send(), speedrunning, sprint(), start_ammo_cells, start_ammo_fuel, start_ammo_nails, start_ammo_plasma, start_ammo_rockets, start_ammo_shells, start_armorvalue, start_health, start_items, start_weapons, strcat(), string_null, SUB_UseTargets(), sv_ready_restart_after_countdown, takedamage, team, TeamBalance_JoinBestTeam(), TELEPORT_NORMAL, teleportable, time, TRANSMUTE(), Unfreeze(), UNSET_DUCKED, v_angle, vehicle, vehicles_exit(), velocity, view_ofs, viewloc, vtos(), w_getbestweapon, W_ResetGunAlign(), W_WeaponFrame(), warmup_stage, warmup_start_ammo_cells, warmup_start_ammo_fuel, warmup_start_ammo_nails, warmup_start_ammo_plasma, warmup_start_ammo_rockets, warmup_start_ammo_shells, warmup_start_armorvalue, warmup_start_health, WARMUP_START_WEAPONS, waterlevel, WATERLEVEL_NONE, watertype, weapon_load, weaponentities, WEP_FLAG_RELOADABLE, and WEPSET_SUPERWEAPONS.

Referenced by PutClientInServer().

536 {
537  if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
538 
539  PlayerState_attach(this);
540  accuracy_resend(this);
541 
542  if (this.team < 0)
544 
545  entity spot = SelectSpawnPoint(this, false);
546  if (!spot) {
547  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
548  return; // spawn failed
549  }
550 
551  TRANSMUTE(Player, this);
552 
553  CS(this).wasplayer = true;
554  this.iscreature = true;
556  if(!this.damagedbycontents)
558  this.damagedbycontents = true;
560  this.solid = SOLID_SLIDEBOX;
566  this.frags = FRAGS_PLAYER;
568  this.flags = FL_CLIENT | FL_PICKUPITEMS;
569  if (autocvar__notarget)
570  this.flags |= FL_NOTARGET;
571  this.takedamage = DAMAGE_AIM;
573 
574  if (warmup_stage) {
575  SetResource(this, RES_SHELLS, warmup_start_ammo_shells);
576  SetResource(this, RES_BULLETS, warmup_start_ammo_nails);
577  SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets);
578  SetResource(this, RES_CELLS, warmup_start_ammo_cells);
579  SetResource(this, RES_PLASMA, warmup_start_ammo_plasma);
580  SetResource(this, RES_FUEL, warmup_start_ammo_fuel);
582  SetResource(this, RES_ARMOR, warmup_start_armorvalue);
583  STAT(WEAPONS, this) = WARMUP_START_WEAPONS;
584  } else {
585  SetResource(this, RES_SHELLS, start_ammo_shells);
586  SetResource(this, RES_BULLETS, start_ammo_nails);
587  SetResource(this, RES_ROCKETS, start_ammo_rockets);
588  SetResource(this, RES_CELLS, start_ammo_cells);
589  SetResource(this, RES_PLASMA, start_ammo_plasma);
590  SetResource(this, RES_FUEL, start_ammo_fuel);
592  SetResource(this, RES_ARMOR, start_armorvalue);
593  STAT(WEAPONS, this) = start_weapons;
594  if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false)
595  {
598  }
599  }
600  SetSpectatee_status(this, 0);
601 
602  PS(this).dual_weapons = '0 0 0';
603 
604  if(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)
605  StatusEffects_apply(STATUSEFFECT_Superweapons, this, time + autocvar_g_balance_superweapons_time, 0);
606 
607  this.items = start_items;
608 
609  float shieldtime = time + autocvar_g_spawnshieldtime;
610 
615  if (!sv_ready_restart_after_countdown && time < game_starttime)
616  {
617  float f = game_starttime - time;
618  shieldtime += f;
619  this.pauserotarmor_finished += f;
620  this.pauserothealth_finished += f;
621  this.pauseregen_finished += f;
622  }
623 
624  StatusEffects_apply(STATUSEFFECT_SpawnShield, this, shieldtime, 0);
625 
627  this.death_time = 0;
628  this.respawn_flags = 0;
629  this.respawn_time = 0;
630  STAT(RESPAWN_TIME, this) = 0;
632  this.fade_time = 0;
633  this.pain_finished = 0;
634  this.pushltime = 0;
635  setthink(this, func_null); // players have no think function
636  this.nextthink = 0;
637  this.dmg_team = 0;
638  PS(this).ballistics_density = autocvar_g_ballistics_density_player;
639 
640  this.deadflag = DEAD_NO;
641 
642  this.angles = spot.angles;
643  this.angles_z = 0; // never spawn tilted even if the spot says to
644  if (IS_BOT_CLIENT(this))
645  {
646  this.v_angle = this.angles;
647  bot_aim_reset(this);
648  }
649  this.fixangle = true; // turn this way immediately
650  this.oldvelocity = this.velocity = '0 0 0';
651  this.avelocity = '0 0 0';
652  this.punchangle = '0 0 0';
653  this.punchvector = '0 0 0';
654 
655  STAT(REVIVE_PROGRESS, this) = 0;
656  this.revival_time = 0;
657 
658  STAT(AIR_FINISHED, this) = 0;
660  this.watertype = CONTENT_EMPTY;
661 
662  entity spawnevent = new_pure(spawnevent);
663  spawnevent.owner = this;
664  Net_LinkEntity(spawnevent, false, 0.5, SpawnEvent_Send);
665 
666  // Cut off any still running player sounds.
667  stopsound(this, CH_PLAYER_SINGLE);
668 
669  this.model = "";
670  FixPlayermodel(this);
671  this.drawonlytoclient = NULL;
672 
673  this.viewloc = NULL;
674 
675  for(int slot = 0; slot < MAX_AXH; ++slot)
676  {
677  entity axh = this.(AuxiliaryXhair[slot]);
678  this.(AuxiliaryXhair[slot]) = NULL;
679 
680  if(axh.owner == this && axh != NULL && !wasfreed(axh))
681  delete(axh);
682  }
683 
684  this.spawnpoint_targ = NULL;
685 
686  UNSET_DUCKED(this);
687  this.view_ofs = STAT(PL_VIEW_OFS, this);
688  setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
689  this.spawnorigin = spot.origin;
690  setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24));
691  // don't reset back to last position, even if new position is stuck in solid
692  this.oldorigin = this.origin;
693  if(this.conveyor)
694  IL_REMOVE(g_conveyed, this);
695  this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
696  if(this.swampslug)
697  IL_REMOVE(g_swamped, this);
698  this.swampslug = NULL;
699  this.swamp_interval = 0;
700  if(this.ladder_entity)
701  IL_REMOVE(g_ladderents, this);
702  this.ladder_entity = NULL;
703  IL_EACH(g_counters, it.realowner == this,
704  {
705  delete(it);
706  });
707  STAT(HUD, this) = HUD_NORMAL;
708 
709  this.event_damage = PlayerDamage;
710  this.event_heal = PlayerHeal;
711 
712  this.draggable = func_null;
713 
714  if(!this.