]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/weapons/weapon/arc.qc
Merge branch 'drjaska/frozenarcfix' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / weapon / arc.qc
index 2f9b84ed551852c6effa4b17a9b7e5fc0d509fca..c4c396fce597d44f796b826ccfebeb41a95a9307 100644 (file)
@@ -1,8 +1,8 @@
 #include "arc.qh"
 
 #ifdef SVQC
-#include <common/gamemodes/gamemode/onslaught/sv_onslaught.qh>
 #include <common/gamemodes/gamemode/onslaught/sv_generator.qh>
+#include <common/gamemodes/gamemode/onslaught/sv_onslaught.qh>
 
 bool W_Arc_Beam_Send(entity this, entity to, int sf)
 {
@@ -118,19 +118,18 @@ void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float dam
 void W_Arc_Bolt_Touch(entity this, entity toucher)
 {
        PROJECTILE_TOUCH(this, toucher);
-       if(this.cnt > WEP_CVAR(arc, bolt_bounce_count) || !WEP_CVAR(arc, bolt_bounce_count) || toucher.takedamage == DAMAGE_AIM) {
+       if(this.cnt >= WEP_CVAR(arc, bolt_bounce_count) || !WEP_CVAR(arc, bolt_bounce_count) || toucher.takedamage == DAMAGE_AIM) {
                this.use(this, NULL, toucher);
        } else {
-               if(!this.cnt && WEP_CVAR(arc, bolt_bounce_lifetime))
-                       this.nextthink = min(this.nextthink, time + WEP_CVAR(arc, bolt_bounce_lifetime));
                this.cnt++;
                Send_Effect(EFFECT_BALL_SPARKS, this.origin, this.velocity, 1);
                this.angles = vectoangles(this.velocity);
                this.owner = NULL;
-               // initial blast doesn't count as bounce damage!
-               if(WEP_CVAR(arc, bolt_bounce_damage))
-                       RadiusDamage(this, this.realowner, WEP_CVAR(arc, bolt_damage), WEP_CVAR(arc, bolt_edgedamage), WEP_CVAR(arc, bolt_radius), NULL, NULL, WEP_CVAR(arc, bolt_force), this.projectiledeathtype, this.weaponentity_fld, toucher);
                this.projectiledeathtype |= HITTYPE_BOUNCE;
+               if(WEP_CVAR(arc, bolt_bounce_explode))
+                       RadiusDamage(this, this.realowner, WEP_CVAR(arc, bolt_damage), WEP_CVAR(arc, bolt_edgedamage), WEP_CVAR(arc, bolt_radius), NULL, NULL, WEP_CVAR(arc, bolt_force), this.projectiledeathtype, this.weaponentity_fld, toucher);
+               if(this.cnt == 1 && WEP_CVAR(arc, bolt_bounce_lifetime))
+                       this.nextthink = time + WEP_CVAR(arc, bolt_bounce_lifetime);
        }
 }
 
@@ -208,11 +207,16 @@ void W_Arc_Beam_Think(entity this)
 
        Weapon thiswep = WEP_ARC;
 
+       // TODO: use standard weapon use checks here!
        if(
                !IS_PLAYER(own)
                ||
                IS_DEAD(own)
                ||
+                STAT(FROZEN, own)
+                ||
+               game_stopped
+               ||
                !weapon_prepareattack_check(thiswep, own, weaponentity, this.beam_bursting, -1)
                ||
                own.(weaponentity).m_switchweapon != WEP_ARC
@@ -576,9 +580,14 @@ void W_Arc_Attack(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 }
 void Arc_Smoke(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
-       // TODO: spamming this without checking any refires is asking for trouble!
+       // calculate a rough shot origin to show the effect from TODO: move this to the client side!
        makevectors(actor.v_angle);
-       W_SetupShot_Range(actor,weaponentity,false,0,SND_Null,0,0,0,thiswep.m_id); // TODO: probably doesn't need deathtype, since this is just a prefire effect
+       w_shotdir = v_forward;
+       vector md = actor.(weaponentity).movedir;
+       vector vecs = ((md.x > 0) ? md : '0 0 0');
+       vector dv = v_forward * vecs.x + v_right * -vecs.y + v_up * vecs.z;
+       w_shotorg = actor.origin + actor.view_ofs + dv;
+       //W_SetupShot_Range(actor,weaponentity,false,0,SND_Null,0,0,0,thiswep.m_id);
 
        vector smoke_origin = w_shotorg + actor.velocity*frametime;
        if ( actor.arc_overheat > time )
@@ -680,7 +689,7 @@ METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, i
     {
         if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
         {
-               if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
+            if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
             if(!(actor.items & IT_UNLIMITED_AMMO))
             {
                 W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
@@ -931,7 +940,14 @@ void Draw_ArcBeam(entity this)
                // into a weapon system for client code.
 
                // find where we are aiming
-               vector myviewangle = ((autocvar_chase_active) ? warpzone_save_view_angles : view_angles);
+               vector myviewangle = view_angles;
+               if (autocvar_chase_active)
+               {
+                       if (autocvar_cl_lockview)
+                               myviewangle = eX * csqcplayer.v_angle.x + eY * csqcplayer.angles.y;
+                       else
+                               myviewangle = warpzone_save_view_angles;
+               }
                vector forward, right, up;
                MAKE_VECTORS(myviewangle, forward, right, up);
                entity wepent = viewmodels[this.beam_slot];
@@ -1238,7 +1254,7 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew)
                this.move_time = time;
                loopsound(this, CH_SHOTS_SINGLE, SND_ARC_LOOP, VOL_BASE, ATTEN_NORM);
 
-               flash = spawn();
+               flash = new(arc_flash);
                flash.owner = this;
                flash.effects = EF_ADDITIVE | EF_FULLBRIGHT;
                //flash.drawmask = MASK_NORMAL;