X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fweapons%2Fweapon%2Farc.qc;h=44fd539bebc5feca780e89e059f5a5f7de1c8461;hb=86ffc5c159e147eed742ec9169c37cbf137df852;hp=5f79c8ccfa58d622c4607dc5129e73783399b103;hpb=bc4be8c518a62d8ae09227114c32a90133d0fde8;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 5f79c8ccf..44fd539be 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -118,20 +118,28 @@ 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); - this.use(this, NULL, toucher); + 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 { + this.cnt++; + Send_Effect(EFFECT_BALL_SPARKS, this.origin, this.velocity, 1); + this.angles = vectoangles(this.velocity); + this.owner = NULL; + 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); + } } -void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity) +void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity, int fire) { - entity missile; - - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(arc, bolt_ammo), weaponentity); - - W_SetupShot(actor, weaponentity, false, 2, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR(arc, bolt_damage), WEP_ARC.m_id | HITTYPE_SECONDARY); + W_SetupShot(actor, weaponentity, false, 2, SND_ELECTRO_FIRE2, CH_WEAPON_A, WEP_CVAR(arc, bolt_damage), thiswep.m_id | HITTYPE_SECONDARY); W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir); - missile = new(missile); + entity missile = new(missile); missile.owner = missile.realowner = actor; missile.bot_dodge = true; IL_PUSH(g_bot_dodge, missile); @@ -145,25 +153,38 @@ void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity) IL_PUSH(g_damagedbycontents, missile); settouch(missile, W_Arc_Bolt_Touch); + missile.cnt = 0; missile.use = W_Arc_Bolt_Explode_use; setthink(missile, adaptor_think2use_hittype_splash); missile.nextthink = time + WEP_CVAR(arc, bolt_lifetime); PROJECTILE_MAKETRIGGER(missile); - missile.projectiledeathtype = WEP_ARC.m_id | HITTYPE_SECONDARY; + missile.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY; missile.weaponentity_fld = weaponentity; setorigin(missile, w_shotorg); setsize(missile, '0 0 0', '0 0 0'); - set_movetype(missile, MOVETYPE_FLY); + set_movetype(missile, MOVETYPE_BOUNCEMISSILE); W_SetupProjVelocity_PRE(missile, arc, bolt_); missile.angles = vectoangles(missile.velocity); missile.flags = FL_PROJECTILE; + IL_PUSH(g_projectiles, missile); missile.missile_flags = MIF_SPLASH; CSQCProjectile(missile, true, PROJECTILE_ARC_BOLT, true); MUTATOR_CALLHOOK(EditProjectile, actor, missile); + + actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1; + if(actor.(weaponentity).misc_bulletcounter == 0) + { + ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(arc, bolt_refire2) * W_WeaponRateFactor(actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), w_ready); + } + else + { + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), W_Arc_Attack_Bolt); + } } void W_Arc_Beam_Think(entity this) @@ -656,10 +677,28 @@ METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, i } else if(fire & 2) { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(arc, bolt_refire))) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) { - W_Arc_Attack_Bolt(thiswep, actor, weaponentity); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), w_ready); + if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity)) + if(!(actor.items & IT_UNLIMITED_AMMO)) + { + W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity); + w_ready(thiswep, actor, weaponentity, fire); + return; + } + float ammo_available = GetResource(actor, thiswep.ammo_type); + // We don't want to shoot 3 rounds if there's 2 left in the mag, so we'll use a fraction. + // Also keep the fraction <= 1 otherwise we'd mag dump in one burst. + float burst_fraction = min(1, ammo_available / WEP_CVAR(arc, bolt_ammo)); + int to_shoot = floor(WEP_CVAR(arc, bolt_count) * burst_fraction); + + // We also don't want to use 3 rounds if there's only 2 left. + int to_use = min(WEP_CVAR(arc, bolt_ammo), ammo_available); + W_DecreaseAmmo(thiswep, actor, to_use, weaponentity); + + // Bursting counts up to 0 from a negative. + actor.(weaponentity).misc_bulletcounter = -to_shoot; + W_Arc_Attack_Bolt(thiswep, actor, weaponentity, fire); } } @@ -761,8 +800,8 @@ METHOD(Arc, wr_impacteffect, void(entity thiswep, entity actor)) { vector org2; org2 = w_org + w_backoff * 6; - pointparticles(EFFECT_ARC_BOLT_EXPLODE, org2, w_backoff * 1000, 1); - if(!w_issilent) { sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } + pointparticles(EFFECT_ELECTRO_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) { sound(actor, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTN_NORM); } } } @@ -931,9 +970,7 @@ void Draw_ArcBeam(entity this) if(!v_shot_idx || this.beam_usevieworigin != 2) { this.beam_shotorigin = wepent.movedir; - origin_offset = - right * -this.beam_shotorigin.y - + up * this.beam_shotorigin.z; + origin_offset = right * -this.beam_shotorigin.y + up * this.beam_shotorigin.z; } else this.beam_shotorigin = '0 0 0';