]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Mario/headshots' into 'master'
authorMario <mario.mario@y7mail.com>
Mon, 27 Jul 2020 03:22:55 +0000 (03:22 +0000)
committerMario <mario.mario@y7mail.com>
Mon, 27 Jul 2020 03:22:55 +0000 (03:22 +0000)
Merge branch Mario/headshots (S merge request)

See merge request xonotic/xonotic-data.pk3dir!839

1  2 
qcsrc/server/miscfunctions.qh
qcsrc/server/weapons/tracing.qc

index c61dc1e7167397925c986e13266af9adc5ea5e36,534299f12dedd3cb5ba877ec5d5afe3fbd3e1d6e..1ec27a7818a1cd900aa05f51368968051d358887
@@@ -35,10 -35,16 +35,16 @@@ void soundat(entity e, vector o, float 
  void InitializeEntitiesRun();
  
  void stopsoundto(float _dest, entity e, float chan);
 -void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten);
 +void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten, float _pitch);
  
  void droptofloor(entity this);
  
+ float trace_hits_box_1d(float end, float thmi, float thma);
+ float trace_hits_box(vector start, vector end, vector thmi, vector thma);
+ float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma);
  void attach_sameorigin(entity e, entity to, string tag);
  
  void crosshair_trace(entity pl);
@@@ -82,7 -88,7 +88,7 @@@ void remove_unsafely(entity e)
  
  void SetMovetypeFollow(entity ent, entity e);
  
 -void soundto(float dest, entity e, float chan, string samp, float vol, float atten);
 +void soundto(float dest, entity e, float chan, string samp, float vol, float atten, float _pitch);
  
  void stopsound(entity e, float chan);
  
index 3259523f071474ed95374282594ee255825910d5,9fd07eb2e4920b4e5bd79542b7ebb07bd51ec5fb..ef1b6bd68d81880e15f018ec4217e4f3fe81b7d4
@@@ -211,7 -211,18 +211,18 @@@ void W_SetupProjVelocity_Explicit(entit
  //  Ballistics Tracing
  // ====================
  
- void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
+ bool Headshot(entity targ, entity ent, vector start, vector end)
+ {
+       if(!IS_PLAYER(targ) || IS_DEAD(targ) || STAT(FROZEN, targ) || !targ.takedamage)
+               return false;
+       vector org = targ.origin; // antilag is already taken into consideration //antilag_takebackorigin(targ, CS(targ), time - ANTILAG_LATENCY(ent));
+       vector headmins = org + '0.6 0 0' * targ.mins_x + '0 0.6 0' * targ.mins_y + '0 0 1' * (1.3 * targ.view_ofs_z - 0.3 * targ.maxs_z);
+       vector headmaxs = org + '0.6 0 0' * targ.maxs_x + '0 0.6 0' * targ.maxs_y + '0 0 1' * targ.maxs_z;
+       return trace_hits_box(start, end, headmins, headmaxs);
+ }
+ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, bool headshot_notify, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype)
  {
        vector dir = normalize(end - start);
        vector force = dir * bforce;
        end = end + dir;
  
        float totaldmg = 0;
+       bool headshot = false; // indicates that one of the targets hit was a headshot
  
        // trace multiple times until we hit a wall, each obstacle will be made
        // non-solid so we can hit the next, while doing this we spawn effects and
                if (trace_ent == NULL || trace_fraction == 1)
                        break;
  
+               if(headshot_notify && !headshot && Headshot(trace_ent, this, start, end))
+                       headshot = true;
                // make the entity non-solid so we can hit the next one
                IL_PUSH(g_railgunhit, trace_ent);
                trace_ent.railgunhit = true;
  
                msg_entity = it;
                // we want this to be very loud when close but fall off quickly -> using max base volume and high attenuation
 -              soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASEVOICE, ATTEN_IDLE);
 +              soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASEVOICE, ATTEN_IDLE, 0);
        });
        if(pseudoprojectile)
                delete(pseudoprojectile);
  
        IL_CLEAR(g_railgunhit);
  
+       if(headshot)
+               Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
        // calculate hits and fired shots for hitscan
        if(this.(weaponentity))
                accuracy_add(this, this.(weaponentity).m_weapon, 0, min(bdamage, totaldmg));
@@@ -330,7 -348,7 +348,7 @@@ void fireBullet_trace_callback(vector s
        fireBullet_last_hit = NULL;
  }
  
- void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect, bool do_antilag)
+ void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect, bool do_antilag)
  {
        dir = normalize(dir + randomvec() * spread);
        vector end = start + dir * max_shot_distance;
  
        WarpZone_trace_forent = this;
  
+       bool headshot = false; // indicates that one of the hit targets was a headshot
        for (;;)
        {
                WarpZone_TraceBox_ThroughZone(start, '0 0 0', '0 0 0', end, false, WarpZone_trace_forent, NULL, fireBullet_trace_callback);
                        yoda = 0;
                        MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity));
                        damage = M_ARGV(4, float);
+                       if(headshot_multiplier && Headshot(hit, this, start, end))
+                       {
+                               damage *= headshot_multiplier;
+                               headshot = true;
+                       }
                        bool gooddamage = accuracy_isgooddamage(this, hit);
                        Damage(hit, this, this, damage * damage_fraction, dtype, weaponentity, start, force * dir * damage_fraction);
                        // calculate hits for ballistic weapons
                        Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
        }
  
+       if(headshot)
+               Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
        if(lag)
                antilag_restore_all(this);
  
                this.dphitcontentsmask = oldsolid;
  }
  
- void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect)
+ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float headshot_multiplier, float force, float dtype, entity tracer_effect)
  {
-       fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, force, dtype, tracer_effect, true);
+       fireBullet_antilag(this, weaponentity, start, dir, spread, max_solid_penetration, damage, headshot_multiplier, force, dtype, tracer_effect, true);
  }