#include "bot/api.qh"
#include "cheats.qh"
#include "g_damage.qh"
+#include "handicap.qh"
#include "g_subs.qh"
#include "miscfunctions.qh"
#include "portals.qh"
animdecide_setimplicitstate(this, IS_ONGROUND(this));
}
-void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
{
float take, save;
vector v;
Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, this, attacker);
- // damage resistance (ignore most of the damage from a bullet or similar)
- damage = max(damage - 5, 1);
-
v = healtharmor_applydamage(this.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage);
take = v.x;
save = v.y;
void calculate_player_respawn_time(entity this)
{
- if(g_ca)
+ if(MUTATOR_CALLHOOK(CalculateRespawnTime, this))
return;
float gametype_setting_tmp;
this.respawn_flags = this.respawn_flags | RESPAWN_FORCE;
}
-void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
{
float take, save, dh, da;
vector v;
if(!DEATH_ISSPECIAL(deathtype))
{
- damage *= bound(1.0, CS(this).cvar_cl_handicap, 10.0);
- if(this != attacker && IS_PLAYER(attacker))
- damage /= bound(1.0, CS(attacker).cvar_cl_handicap, 10.0);
+ damage *= Handicap_GetTotalHandicap(this);
+ if (this != attacker && IS_PLAYER(attacker))
+ {
+ damage /= Handicap_GetTotalHandicap(attacker);
+ }
}
if (time < this.spawnshieldtime && autocvar_g_spawnshield_blockdamage < 1)
if (this != attacker) {
float realdmg = damage - excess;
if (IS_PLAYER(attacker)) {
- PlayerScore_Add(attacker, SP_DMG, realdmg);
+ GameRules_scoring_add(attacker, DMG, realdmg);
}
if (IS_PLAYER(this)) {
- PlayerScore_Add(this, SP_DMGTAKEN, realdmg);
+ GameRules_scoring_add(this, DMGTAKEN, realdmg);
}
}
bool valid_damage_for_weaponstats = false;
Weapon awep = WEP_Null;
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
if(vbot || IS_REAL_CLIENT(this))
if(abot || IS_REAL_CLIENT(attacker))
if(this.alivetime)
{
- PS_GR_P_ADDVAL(this, PLAYERSTATS_ALIVETIME, time - this.alivetime);
+ PlayerStats_GameReport_Event_Player(this, PLAYERSTATS_ALIVETIME, time - this.alivetime);
this.alivetime = 0;
}
{
delete(this.killindicator);
this.killindicator = NULL;
- if(CS(this).killindicator_teamchange)
+ if(this.killindicator_teamchange)
defer_ClientKill_Now_TeamChange = true;
if(this.classname == "body")
// print an obituary message
if(this.classname != "body")
- Obituary (attacker, inflictor, this, deathtype);
+ Obituary (attacker, inflictor, this, deathtype, weaponentity);
// increment frag counter for used weapon type
Weapon w = DEATH_WEAPONOF(deathtype);
if(w != WEP_Null && accuracy_isgooddamage(attacker, this))
CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1;
+ this.respawn_time = 0;
MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
damage = M_ARGV(4, float);
excess = max(0, damage - take - save);
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
.entity went = weaponentities[slot];
- if(!this.(weaponentity))
+ if(!this.(went))
continue; // TODO: clones have no weapon, but we don't want to have to check this all the time
- Weapon wep = this.(weaponentity).m_weapon;
+ Weapon wep = this.(went).m_weapon;
wep.wr_playerdeath(wep, this, went);
}
if(this.health >= 1 || !(IS_PLAYER(this) || this.classname == "body"))
return;
+ if (!this.respawn_time) // can be set in the mutator hook PlayerDies
+ calculate_player_respawn_time(this);
+
// when we get here, player actually dies
Unfreeze(this); // remove any icy remains
STAT(MOVEVARS_SPECIALCOMMAND, this) = false; // sweet release
- // when to allow respawn
- calculate_player_respawn_time(this);
-
this.death_time = time;
if (random() < 0.5)
animdecide_setstate(this, this.anim_state | ANIMSTATE_DEAD1, true);
else
animdecide_setstate(this, this.anim_state | ANIMSTATE_DEAD2, true);
- if (this.maxs.z > 5)
- {
- this.maxs_z = 5;
- setsize(this, this.mins, this.maxs);
- }
+
// set damage function to corpse damage
this.event_damage = PlayerCorpseDamage;
// call the corpse damage function just in case it wants to gib
- this.event_damage(this, inflictor, attacker, excess, deathtype, hitloc, force);
+ this.event_damage(this, inflictor, attacker, excess, deathtype, weaponentity, hitloc, force);
// set up to fade out later
SUB_SetFade (this, time + 6 + random (), 1);
if(autocvar_sv_gentle > 0 || autocvar_ekg || this.classname == "body") {
// remove corpse
// clones don't run any animation code any more, so we must gib them when they die :(
- PlayerCorpseDamage(this, inflictor, attacker, autocvar_sv_gibhealth+1.0, deathtype, hitloc, force);
+ this.event_damage(this, inflictor, attacker, autocvar_sv_gibhealth + 1, deathtype, weaponentity, hitloc, force);
}
// reset fields the weapons may use just in case
}
}
-void MoveToTeam(entity client, int team_colour, int type)
+bool MoveToTeam(entity client, int team_colour, int type)
{
int lockteams_backup = lockteams; // backup any team lock
lockteams = 0; // disable locked teams
TeamchangeFrags(client); // move the players frags
- SetPlayerColors(client, team_colour - 1); // set the players colour
- Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player
- lockteams = lockteams_backup; // restore the team lock
- LogTeamchange(client.playerid, client.team, type);
-}
-
-/** print(), but only print if the server is not local */
-void dedicated_print(string input)
-{
- if (server_is_dedicated) print(input);
-}
-
-void PrintToChat(entity player, string text)
-{
- text = strcat("\{1}^7", text, "\n");
- sprint(player, text);
-}
-
-void DebugPrintToChat(entity player, string text)
-{
- if (autocvar_developer)
- {
- PrintToChat(player, text);
- }
-}
-
-void PrintToChatAll(string text)
-{
- text = strcat("\{1}^7", text, "\n");
- bprint(text);
-}
-
-void DebugPrintToChatAll(string text)
-{
- if (autocvar_developer)
- {
- PrintToChatAll(text);
- }
-}
-
-void PrintToChatTeam(int teamnum, string text)
-{
- text = strcat("\{1}^7", text, "\n");
- FOREACH_CLIENT(IS_REAL_CLIENT(it),
- {
- if (it.team == teamnum)
- {
- sprint(it, text);
- }
- });
-}
-
-void DebugPrintToChatTeam(int teamnum, string text)
-{
- if (autocvar_developer)
+ if (!SetPlayerTeamSimple(client, team_colour))
{
- PrintToChatTeam(teamnum, text);
+ return false;
}
+ Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, DMG_NOWEP, client.origin, '0 0 0'); // kill the player
+ lockteams = lockteams_backup; // restore the team lock
+ LogTeamchange(client.playerid, client.team, type);
+ return true;
}
/**
}
if(flood)
- LOG_INFO("NOTE: ", playername(source, true), "^7 is flooding.\n");
+ LOG_INFO("NOTE: ", playername(source, true), "^7 is flooding.");
// build sourcemsgstr by cutting off a prefix and replacing it by the other one
if(privatesay)
if (privatesay && source && !IS_PLAYER(source))
{
if (!game_stopped)
- if ((privatesay && !IS_PLAYER(privatesay)) || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !warmup_stage))
+ if ((privatesay && IS_PLAYER(privatesay)) && ((autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !warmup_stage)))
ret = -1; // just hide the message completely
}