1 #include "clientkill.qh"
3 #include <common/csqcmodel_settings.qh>
4 #include <common/deathtypes/all.qh>
5 #include <common/mapobjects/triggers.qh>
6 #include <common/notifications/all.qh>
7 #include <common/stats.qh>
8 #include <common/stats.qh>
9 #include <common/vehicles/sv_vehicles.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>
18 void ClientKill_Now_TeamChange(entity this)
20 if (this.killindicator_teamchange == -1)
22 TeamBalance_JoinBestTeam(this);
24 else if (this.killindicator_teamchange == -2)
27 Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
28 PutObserverInServer(this, false, true);
32 Player_SetTeamIndexChecked(this, Team_TeamToIndex(
33 this.killindicator_teamchange));
35 this.killindicator_teamchange = 0;
38 void ClientKill_Now(entity this)
42 vehicles_exit(this.vehicle, VHEF_RELEASE);
43 if (!this.killindicator_teamchange)
45 this.vehicle_health = -1;
46 Damage(this, this, this, 1 , DEATH_KILL.m_id, DMG_NOWEP, this.origin, '0 0 0');
50 if (this.killindicator && !wasfreed(this.killindicator))
51 delete(this.killindicator);
53 this.killindicator = NULL;
55 if (this.killindicator_teamchange)
56 ClientKill_Now_TeamChange(this);
58 if (!IS_SPEC(this) && !IS_OBSERVER(this) && MUTATOR_CALLHOOK(ClientKill_Now, this) == false)
60 Damage(this, this, this, 100000, DEATH_KILL.m_id, DMG_NOWEP, this.origin, '0 0 0');
63 // now I am sure the player IS dead
65 void KillIndicator_Think(entity this)
67 if (game_stopped || (this.owner.alpha < 0 && !this.owner.vehicle))
69 this.owner.killindicator = NULL;
76 ClientKill_Now(this.owner);
80 // count == 1 means that it's silent
84 setmodel(this, MDL_NUM(this.cnt));
85 if (IS_REAL_CLIENT(this.owner))
88 Send_Notification(NOTIF_ONE, this.owner, MSG_ANNCE, Announcer_PickNumber(CNT_KILL, this.cnt));
91 this.nextthink = time + 1;
97 .float clientkill_nexttime;
98 void ClientKill_TeamChange(entity this, float targetteam) // 0 = don't change, -1 = auto, -2 = spec
103 float killtime = autocvar_g_balance_kill_delay;
105 if (MUTATOR_CALLHOOK(ClientKill, this, killtime))
107 killtime = M_ARGV(1, float);
109 if(round_handler_IsActive() && !round_handler_IsRoundStarted())
110 killtime = min(killtime, 1);
112 this.killindicator_teamchange = targetteam;
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)
117 ClientKill_Now(this); // allow instant kill in this case
121 if (!this.killindicator)
125 killtime = max(killtime, this.clientkill_nexttime - time);
126 float antispam_delay = autocvar_g_balance_kill_antispam;
127 if(round_handler_IsActive() && !round_handler_IsRoundStarted())
128 antispam_delay = min(antispam_delay, 2);
129 this.clientkill_nexttime = time + killtime + antispam_delay;
132 if (killtime <= 0 || !IS_PLAYER(this) || IS_DEAD(this))
134 ClientKill_Now(this);
138 float starttime = max(time, clientkilltime);
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');
145 setthink(this.killindicator, KillIndicator_Think);
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"));
152 IL_EACH(g_clones, it.enemy == this && !(it.effects & CSQCMODEL_EF_RESPAWNGHOST) && !it.killindicator,
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);
167 if (this.killindicator)
170 if (targetteam == 0) // just die
172 this.killindicator.colormod = '0 0 0';
173 notif = CENTER_TEAMCHANGE_SUICIDE;
175 else if (targetteam == -1) // auto
177 this.killindicator.colormod = '0 1 0';
178 notif = CENTER_TEAMCHANGE_AUTO;
180 else if (targetteam == -2) // spectate
182 this.killindicator.colormod = '0.5 0.5 0.5';
183 notif = CENTER_TEAMCHANGE_SPECTATE;
187 this.killindicator.colormod = Team_ColorRGB(targetteam);
188 notif = APP_TEAM_NUM(targetteam, CENTER_TEAMCHANGE);
190 if (IS_REAL_CLIENT(this) && this.killindicator.cnt > 0)
191 Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, notif, this.killindicator.cnt);
196 void ClientKill_Silent(entity this, float _delay)
198 this.killindicator = new(killindicator);
199 this.killindicator.owner = this;
200 setthink(this.killindicator, KillIndicator_Think);
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
207 // Called when a client types 'kill' in the console
208 void ClientKill(entity this)
210 if (game_stopped || this.player_blocked || STAT(FROZEN, this))
213 ClientKill_TeamChange(this, 0);