Xonotic
clientkill.qc
Go to the documentation of this file.
1 #include "clientkill.qh"
2 
7 #include <common/stats.qh>
8 #include <common/stats.qh>
10 #include <common/weapons/_all.qh>
11 #include <server/client.qh>
12 #include <server/damage.qh>
13 #include <server/mutators/_mod.qh>
14 #include <server/player.qh>
15 #include <server/round_handler.qh>
16 #include <server/teamplay.qh>
17 
19 {
20  if (this.killindicator_teamchange == -1)
21  {
23  }
24  else if (this.killindicator_teamchange == -2)
25  {
26  if (blockSpectators)
27  Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
28  PutObserverInServer(this, false, true);
29  }
30  else
31  {
34  }
35  this.killindicator_teamchange = 0;
36 }
37 
39 {
40  if (this.vehicle)
41  {
42  vehicles_exit(this.vehicle, VHEF_RELEASE);
43  if (!this.killindicator_teamchange)
44  {
45  this.vehicle_health = -1;
46  Damage(this, this, this, 1 , DEATH_KILL.m_id, DMG_NOWEP, this.origin, '0 0 0');
47  }
48  }
49 
50  if (this.killindicator && !wasfreed(this.killindicator))
51  delete(this.killindicator);
52 
53  this.killindicator = NULL;
54 
55  if (this.killindicator_teamchange)
57 
58  if (!IS_SPEC(this) && !IS_OBSERVER(this) && MUTATOR_CALLHOOK(ClientKill_Now, this) == false)
59  {
60  Damage(this, this, this, 100000, DEATH_KILL.m_id, DMG_NOWEP, this.origin, '0 0 0');
61  }
62 
63  // now I am sure the player IS dead
64 }
66 {
67  if (game_stopped || (this.owner.alpha < 0 && !this.owner.vehicle))
68  {
69  this.owner.killindicator = NULL;
70  delete(this);
71  return;
72  }
73 
74  if (this.cnt <= 0)
75  {
76  ClientKill_Now(this.owner);
77  return;
78  }
79 
80  // count == 1 means that it's silent
81  if (this.count != 1)
82  {
83  if (this.cnt <= 10)
84  setmodel(this, MDL_NUM(this.cnt));
85  if (IS_REAL_CLIENT(this.owner))
86  {
87  if (this.cnt <= 10)
88  Send_Notification(NOTIF_ONE, this.owner, MSG_ANNCE, Announcer_PickNumber(CNT_KILL, this.cnt));
89  }
90  }
91  this.nextthink = time + 1;
92  this.cnt -= 1;
93 }
94 
95 .float lip;
98 void ClientKill_TeamChange(entity this, float targetteam) // 0 = don't change, -1 = auto, -2 = spec
99 {
100  if (game_stopped)
101  return;
102 
103  float killtime = autocvar_g_balance_kill_delay;
104 
105  if (MUTATOR_CALLHOOK(ClientKill, this, killtime))
106  return;
107  killtime = M_ARGV(1, float);
108 
110  killtime = min(killtime, 1);
111 
112  this.killindicator_teamchange = targetteam;
113 
114  // this.killindicator.count == 1 means that the kill indicator was spawned by ClientKill_Silent
115  if(killtime <= 0 && this.killindicator && this.killindicator.count == 1)
116  {
117  ClientKill_Now(this); // allow instant kill in this case
118  return;
119  }
120 
121  if (!this.killindicator)
122  {
123  if (!IS_DEAD(this))
124  {
125  killtime = max(killtime, this.clientkill_nexttime - time);
126  float antispam_delay = autocvar_g_balance_kill_antispam;
128  antispam_delay = min(antispam_delay, 2);
129  this.clientkill_nexttime = time + killtime + antispam_delay;
130  }
131 
132  if (killtime <= 0 || !IS_PLAYER(this) || IS_DEAD(this))
133  {
134  ClientKill_Now(this);
135  }
136  else
137  {
138  float starttime = max(time, clientkilltime);
139 
140  this.killindicator = new(killindicator);
141  this.killindicator.owner = this;
142  this.killindicator.scale = 0.5;
143  setattachment(this.killindicator, this, "");
144  setorigin(this.killindicator, '0 0 52');
146  this.killindicator.nextthink = starttime + (this.lip) * 0.05;
147  clientkilltime = max(clientkilltime, this.killindicator.nextthink + 0.05);
148  this.killindicator.cnt = ceil(killtime);
149  this.killindicator.count = bound(0, ceil(killtime), 10);
150  //sprint(this, strcat("^1You'll be dead in ", ftos(this.killindicator.cnt), " seconds\n"));
151 
152  IL_EACH(g_clones, it.enemy == this && !(it.effects & CSQCMODEL_EF_RESPAWNGHOST) && !it.killindicator,
153  {
154  it.killindicator = new(killindicator);
155  it.killindicator.owner = it;
156  it.killindicator.scale = 0.5;
157  setattachment(it.killindicator, it, "");
158  setorigin(it.killindicator, '0 0 52');
159  setthink(it.killindicator, KillIndicator_Think);
160  it.killindicator.nextthink = starttime + (it.lip) * 0.05;
161  //clientkilltime = max(clientkilltime, it.killindicator.nextthink + 0.05);
162  it.killindicator.cnt = ceil(killtime);
163  });
164  this.lip = 0;
165  }
166  }
167  if (this.killindicator)
168  {
169  Notification notif;
170  if (targetteam == 0) // just die
171  {
172  this.killindicator.colormod = '0 0 0';
173  notif = CENTER_TEAMCHANGE_SUICIDE;
174  }
175  else if (targetteam == -1) // auto
176  {
177  this.killindicator.colormod = '0 1 0';
178  notif = CENTER_TEAMCHANGE_AUTO;
179  }
180  else if (targetteam == -2) // spectate
181  {
182  this.killindicator.colormod = '0.5 0.5 0.5';
183  notif = CENTER_TEAMCHANGE_SPECTATE;
184  }
185  else
186  {
187  this.killindicator.colormod = Team_ColorRGB(targetteam);
188  notif = APP_TEAM_NUM(targetteam, CENTER_TEAMCHANGE);
189  }
190  if (IS_REAL_CLIENT(this) && this.killindicator.cnt > 0)
191  Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, notif, this.killindicator.cnt);
192  }
193 
194 }
195 
196 void ClientKill_Silent(entity this, float _delay)
197 {
198  this.killindicator = new(killindicator);
199  this.killindicator.owner = this;
201  this.killindicator.nextthink = time + (this.lip) * 0.05;
202  this.killindicator.cnt = ceil(_delay);
203  this.killindicator.count = 1; // this is used to indicate that it should be silent
204  this.lip = 0;
205 }
206 
207 // Called when a client types 'kill' in the console
208 void ClientKill(entity this)
209 {
210  if (game_stopped || this.player_blocked || STAT(FROZEN, this))
211  return;
212 
213  ClientKill_TeamChange(this, 0);
214 }
#define CSQCMODEL_EF_RESPAWNGHOST
void ClientKill_TeamChange(entity this, float targetteam)
Definition: clientkill.qc:98
#define APP_TEAM_NUM(num, prefix)
Definition: all.qh:85
#define round_handler_IsActive()
#define IL_EACH(this, cond, body)
float blockSpectators
Definition: client.qh:334
vector Team_ColorRGB(int teamid)
Definition: teams.qh:76
void ClientKill(entity this)
Definition: clientkill.qc:208
entity() spawn
#define IS_OBSERVER(v)
Definition: utils.qh:11
int killindicator_teamchange
Definition: clientkill.qh:8
float autocvar_g_balance_kill_delay
Definition: clientkill.qh:3
void ClientKill_Now(entity this)
Definition: clientkill.qc:38
void TeamBalance_JoinBestTeam(entity player)
Assigns the given player to a team that will make the game most balanced.
Definition: teamplay.qc:451
#define round_handler_IsRoundStarted()
void ClientKill_Silent(entity this, float _delay)
Definition: clientkill.qc:196
#define DMG_NOWEP
Definition: damage.qh:126
entity owner
Definition: main.qh:73
void Player_SetTeamIndexChecked(entity player, int team_index)
Sets the team of the player with all sanity checks.
Definition: teamplay.qc:276
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
#define setmodel(this, m)
Definition: model.qh:26
#define IS_SPEC(v)
Definition: utils.qh:10
Model MDL_NUM(int i)
Definition: all.inc:351
float cnt
Definition: powerups.qc:24
IntrusiveList g_clones
Definition: player.qh:44
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 ClientKill_Now_TeamChange(entity this)
Definition: clientkill.qc:18
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition: damage.qc:583
#define M_ARGV(x, type)
Definition: events.qh:17
#define IS_DEAD(s)
Definition: utils.qh:26
float nextthink
Definition: csprogsdefs.qc:121
int Team_TeamToIndex(int team_num)
Converts team value into team index.
Definition: teams.qh:184
entity killindicator
Definition: clientkill.qh:7
float count
Definition: powerups.qc:22
float autocvar_g_maxplayers_spectator_blocktime
Definition: client.qh:44
entity Notification
always last
Definition: all.qh:82
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
bool player_blocked
Definition: client.qh:337
setorigin(ent, v)
#define setthink(e, f)
float clientkilltime
Definition: clientkill.qc:96
void vehicles_exit(entity vehic, bool eject)
Definition: sv_vehicles.qc:788
void KillIndicator_Think(entity this)
Definition: clientkill.qc:65
entity vehicle
Definition: impulse.qc:21
float time
Definition: csprogsdefs.qc:16
float starttime
Definition: strafehud.qc:38
#define IS_PLAYER(v)
Definition: utils.qh:9
float clientkill_nexttime
Definition: clientkill.qc:97
float lip
Definition: clientkill.qc:95
float autocvar_g_balance_kill_antispam
Definition: clientkill.qh:4