]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/player.qc
Merge branch 'master' into terencehill/accuracy_shotgun
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / player.qc
index 827c86ae47ccda1a6c8acfae6e8809ee75f57728..9d9281c0e9eb079298e25f4e08010298a9599aa8 100644 (file)
@@ -4,6 +4,7 @@
 #include "bot/api.qh"
 #include "cheats.qh"
 #include "g_damage.qh"
+#include "handicap.qh"
 #include "g_subs.qh"
 #include "miscfunctions.qh"
 #include "portals.qh"
@@ -22,7 +23,7 @@
 #include "../common/minigames/sv_minigames.qh"
 
 #include "../common/physics/player.qh"
-#include "../common/effects/qc/all.qh"
+#include "../common/effects/qc/_mod.qh"
 #include "../common/mutators/mutator/waypoints/waypointsprites.qh"
 #include "../common/triggers/include.qh"
 #include "../common/wepent.qh"
@@ -172,9 +173,6 @@ void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float da
        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;
@@ -317,9 +315,11 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
 
        if(!DEATH_ISSPECIAL(deathtype))
        {
-               damage *= bound(1.0, this.cvar_cl_handicap, 10.0);
-               if(this != attacker)
-                       damage /= bound(1.0, 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)
@@ -472,10 +472,10 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
        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);
                }
        }
 
@@ -514,7 +514,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
 
                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;
                }
 
@@ -535,7 +535,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                {
                        delete(this.killindicator);
                        this.killindicator = NULL;
-                       if(CS(this).killindicator_teamchange)
+                       if(this.killindicator_teamchange)
                                defer_ClientKill_Now_TeamChange = true;
 
                        if(this.classname == "body")
@@ -555,6 +555,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                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);
@@ -583,6 +584,9 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                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
@@ -618,19 +622,21 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
 
                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);
+
+               /* // postpone resize until frame end so that dead player can still
+               // properly get hit by all the projectiles fired in this frame (shotgun)
                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
@@ -649,7 +655,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                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, hitloc, force);
                }
 
                // reset fields the weapons may use just in case
@@ -668,15 +674,19 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
        }
 }
 
-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
+       if (!SetPlayerTeamSimple(client, team_colour))
+       {
+               return false;
+       }
        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);
+       return true;
 }
 
 /** print(), but only print if the server is not local */
@@ -939,7 +949,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
        }
 
        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)