X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fcommon%2Fweapons%2Fw_arc.qc;h=d8faa7be97daead90da13c9ab84dbcd7e23a89c0;hb=459113c6b47ab71204088b818e745879c0e80b25;hp=976b026a102c5fcb326f57f17cd16b23b8f62388;hpb=dccfc3eef40ca210167d43bb30fae6bb116e12f0;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/weapons/w_arc.qc b/qcsrc/common/weapons/w_arc.qc index 976b026a1..d8faa7be9 100644 --- a/qcsrc/common/weapons/w_arc.qc +++ b/qcsrc/common/weapons/w_arc.qc @@ -7,10 +7,10 @@ REGISTER_WEAPON( /* flags */ WEP_FLAG_NORMAL, /* rating */ BOT_PICKUP_RATING_HIGH, /* color */ '1 1 1', -/* modelname */ "hlac", +/* modelname */ "arc", /* simplemdl */ "foobar", /* crosshair */ "gfx/crosshairhlac 0.7", -/* wepimg */ "weaponhlac", +/* wepimg */ "weaponarc", /* refname */ "arc", /* wepname */ _("Arc") ); @@ -42,6 +42,11 @@ REGISTER_WEAPON( w_cvar(id, sn, NONE, burst_damage) \ w_cvar(id, sn, NONE, burst_healing_aps) \ w_cvar(id, sn, NONE, burst_healing_hps) \ + w_cvar(id, sn, NONE, overheat_max)/* maximum heat before jamming */ \ + w_cvar(id, sn, NONE, overheat_min)/* minimum heat to wait for cooldown */ \ + w_cvar(id, sn, NONE, beam_heat) /* heat increase per second (primary) */ \ + w_cvar(id, sn, NONE, burst_heat) /* heat increase per second (secondary) */ \ + w_cvar(id, sn, NONE, cooldown) /* heat decrease per second when resting */ \ w_prop(id, sn, float, switchdelay_raise, switchdelay_raise) \ w_prop(id, sn, float, switchdelay_drop, switchdelay_drop) \ w_prop(id, sn, string, weaponreplace, weaponreplace) \ @@ -50,38 +55,43 @@ REGISTER_WEAPON( w_prop(id, sn, float, weaponthrowable, weaponthrowable) #ifndef MENUQC -#define ARC_MAX_SEGMENTS 20 +const float ARC_MAX_SEGMENTS = 20; vector arc_shotorigin[4]; .vector beam_start; .vector beam_dir; .vector beam_wantdir; -.float beam_type; - -#define ARC_BT_MISS 0 -#define ARC_BT_WALL 1 -#define ARC_BT_HEAL 2 -#define ARC_BT_HIT 3 -#define ARC_BT_BURST_MISS 10 -#define ARC_BT_BURST_WALL 11 -#define ARC_BT_BURST_HEAL 12 -#define ARC_BT_BURST_HIT 13 -#define ARC_BT_BURSTMASK 10 - -#define ARC_SF_SETTINGS 1 -#define ARC_SF_START 2 -#define ARC_SF_WANTDIR 4 -#define ARC_SF_BEAMDIR 8 -#define ARC_SF_BEAMTYPE 16 -#define ARC_SF_LOCALMASK 14 +.int beam_type; + +const int ARC_BT_MISS = 0x00; +const int ARC_BT_WALL = 0x01; +const int ARC_BT_HEAL = 0x02; +const int ARC_BT_HIT = 0x03; +const int ARC_BT_BURST_MISS = 0x10; +const int ARC_BT_BURST_WALL = 0x11; +const int ARC_BT_BURST_HEAL = 0x12; +const int ARC_BT_BURST_HIT = 0x13; +const int ARC_BT_BURSTMASK = 0x10; + +const int ARC_SF_SETTINGS = 1; +const int ARC_SF_START = 2; +const int ARC_SF_WANTDIR = 4; +const int ARC_SF_BEAMDIR = 8; +const int ARC_SF_BEAMTYPE = 16; +const int ARC_SF_LOCALMASK = 14; #endif #ifdef SVQC ARC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP) .entity arc_beam; -.float BUTTON_ATCK_prev; // for better animation control +.float arc_BUTTON_ATCK_prev; // for better animation control .float beam_prev; .float beam_initialized; .float beam_bursting; .float beam_teleporttime; +.float beam_heat; // (beam) amount of heat produced +.float arc_overheat; // (dropped arc/player) time during which it's too hot +.float arc_cooldown; // (dropped arc/player) cooling speed +.float arc_heat_percent; // (player) arc heat in [0,1] (stat) +.float arc_smoke_sound; #endif #ifdef CSQC void Ent_ReadArcBeam(float isnew); @@ -143,28 +153,28 @@ float W_Arc_Beam_Send(entity to, float sf) } if(sf & ARC_SF_START) // starting location { - WriteCoord(MSG_ENTITY, self.beam_start_x); - WriteCoord(MSG_ENTITY, self.beam_start_y); - WriteCoord(MSG_ENTITY, self.beam_start_z); + WriteCoord(MSG_ENTITY, self.beam_start.x); + WriteCoord(MSG_ENTITY, self.beam_start.y); + WriteCoord(MSG_ENTITY, self.beam_start.z); } if(sf & ARC_SF_WANTDIR) // want/aim direction { - WriteCoord(MSG_ENTITY, self.beam_wantdir_x); - WriteCoord(MSG_ENTITY, self.beam_wantdir_y); - WriteCoord(MSG_ENTITY, self.beam_wantdir_z); + WriteCoord(MSG_ENTITY, self.beam_wantdir.x); + WriteCoord(MSG_ENTITY, self.beam_wantdir.y); + WriteCoord(MSG_ENTITY, self.beam_wantdir.z); } if(sf & ARC_SF_BEAMDIR) // beam direction { - WriteCoord(MSG_ENTITY, self.beam_dir_x); - WriteCoord(MSG_ENTITY, self.beam_dir_y); - WriteCoord(MSG_ENTITY, self.beam_dir_z); + WriteCoord(MSG_ENTITY, self.beam_dir.x); + WriteCoord(MSG_ENTITY, self.beam_dir.y); + WriteCoord(MSG_ENTITY, self.beam_dir.z); } if(sf & ARC_SF_BEAMTYPE) // beam type { WriteByte(MSG_ENTITY, self.beam_type); } - return TRUE; + return true; } void Reset_ArcBeam(entity player, vector forward) @@ -176,6 +186,31 @@ void Reset_ArcBeam(entity player, vector forward) player.arc_beam.beam_teleporttime = time; } +float Arc_GetHeat_Percent(entity player) +{ + if ( WEP_CVAR(arc, overheat_max) <= 0 || WEP_CVAR(arc, overheat_max) <= 0 ) + { + player.arc_overheat = 0; + return 0; + } + + if ( player.arc_beam ) + return player.arc_beam.beam_heat/WEP_CVAR(arc, overheat_max); + + if ( player.arc_overheat > time ) + { + return (player.arc_overheat-time) / WEP_CVAR(arc, overheat_max) + * player.arc_cooldown; + } + + return 0; +} +void Arc_Player_SetHeat(entity player) +{ + player.arc_heat_percent = Arc_GetHeat_Percent(player); + //dprint("Heat: ",ftos(player.arc_heat_percent*100),"%\n"); +} + void W_Arc_Beam_Think(void) { if(self != self.owner.arc_beam) @@ -184,16 +219,55 @@ void W_Arc_Beam_Think(void) return; } + + float burst = 0; + if( self.owner.BUTTON_ATCK2 || self.beam_bursting) + { + if(!self.beam_bursting) + self.beam_bursting = true; + burst = ARC_BT_BURSTMASK; + } + if( + !IS_PLAYER(self.owner) + || (self.owner.WEP_AMMO(ARC) <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self.owner.deadflag != DEAD_NO || - (!self.owner.BUTTON_ATCK /* FIXME(Samual): && !self.beam_bursting */) + (!self.owner.BUTTON_ATCK && !burst ) + || + self.owner.frozen || - self.owner.freezetag_frozen + (WEP_CVAR(arc, overheat_max) > 0 && self.beam_heat >= WEP_CVAR(arc, overheat_max)) ) { + if ( WEP_CVAR(arc, cooldown) > 0 ) + { + float cooldown_speed = 0; + if ( self.beam_heat > WEP_CVAR(arc, overheat_min) && WEP_CVAR(arc, cooldown) > 0 ) + { + cooldown_speed = WEP_CVAR(arc, cooldown); + } + else if ( !burst ) + { + cooldown_speed = self.beam_heat / WEP_CVAR(arc, beam_refire); + } + + if ( cooldown_speed ) + { + self.owner.arc_overheat = time + self.beam_heat / cooldown_speed; + self.owner.arc_cooldown = cooldown_speed; + } + + if ( WEP_CVAR(arc, overheat_max) > 0 && self.beam_heat >= WEP_CVAR(arc, overheat_max) ) + { + pointparticles( particleeffectnum("arc_overheat"), + self.beam_start, self.beam_wantdir, 1 ); + sound(self, CH_WEAPON_A, "weapons/arc_stop.wav", VOL_BASE, ATTN_NORM); + } + } + if(self == self.owner.arc_beam) { self.owner.arc_beam = world; } entity oldself = self; self = self.owner; @@ -207,14 +281,6 @@ void W_Arc_Beam_Think(void) return; } - float burst = 0; - if(self.owner.BUTTON_ATCK2 || self.beam_bursting) - { - if(!self.beam_bursting) - self.beam_bursting = TRUE; - burst = ARC_BT_BURSTMASK; - } - // decrease ammo float coefficient = frametime; if(!(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) @@ -231,12 +297,14 @@ void W_Arc_Beam_Think(void) self.owner.WEP_AMMO(ARC) = max(0, self.owner.WEP_AMMO(ARC) - (rootammo * frametime)); } } + float heat_speed = burst ? WEP_CVAR(arc, burst_heat) : WEP_CVAR(arc, beam_heat); + self.beam_heat = min( WEP_CVAR(arc, overheat_max), self.beam_heat + heat_speed*frametime ); makevectors(self.owner.v_angle); W_SetupShot_Range( self.owner, - TRUE, + true, 0, "", 0, @@ -264,7 +332,7 @@ void W_Arc_Beam_Think(void) if(!self.beam_initialized) { self.beam_dir = w_shotdir; - self.beam_initialized = TRUE; + self.beam_initialized = true; } // WEAPONTODO: Detect player velocity so that the beam curves when moving too @@ -273,7 +341,7 @@ void W_Arc_Beam_Think(void) // note that if we do this, it'll always be corrected to a maximum angle by beam_maxangle handling - float segments; + float segments; if(self.beam_dir != w_shotdir) { // calculate how much we're going to move the end of the beam to the want position @@ -322,7 +390,7 @@ void W_Arc_Beam_Think(void) if(WEP_CVAR(arc, beam_degreespersegment)) { segments = bound( - 1, + 1, ( min( angle, @@ -477,7 +545,7 @@ void W_Arc_Beam_Think(void) new_beam_type = ARC_BT_HIT; } - break; + break; } else if(trace_fraction != 1) { @@ -490,7 +558,7 @@ void W_Arc_Beam_Think(void) // te_explosion(trace_endpos); // if we're bursting, use burst visual effects - new_beam_type += burst; + new_beam_type |= burst; // network information: beam type if(new_beam_type != self.beam_type) @@ -505,16 +573,11 @@ void W_Arc_Beam_Think(void) void W_Arc_Beam(float burst) { - // FIXME(Samual): remove this when overheat and burst work. - if (burst) - { - centerprint(self, "^4NOTE:^7 Arc burst (secondary) is not implemented yet."); - } // only play fire sound if 1 sec has passed since player let go the fire button if(time - self.beam_prev > 1) { - sound(self, CH_WEAPON_A, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_WEAPON_A, "weapons/arc_fire.wav", VOL_BASE, ATTN_NORM); } entity beam = self.arc_beam = spawn(); @@ -523,10 +586,10 @@ void W_Arc_Beam(float burst) beam.think = W_Arc_Beam_Think; beam.owner = self; beam.movetype = MOVETYPE_NONE; - beam.bot_dodge = TRUE; + beam.bot_dodge = true; beam.bot_dodgerating = WEP_CVAR(arc, beam_damage); beam.beam_bursting = burst; - Net_LinkEntity(beam, FALSE, 0, W_Arc_Beam_Send); + Net_LinkEntity(beam, false, 0, W_Arc_Beam_Send); entity oldself = self; self = beam; @@ -534,6 +597,42 @@ void W_Arc_Beam(float burst) self = oldself; } +void Arc_Smoke() +{ + makevectors(self.v_angle); + W_SetupShot_Range(self,true,0,"",0,0,0); + + vector smoke_origin = w_shotorg + self.velocity*frametime; + if ( self.arc_overheat > time ) + { + if ( random() < self.arc_heat_percent ) + pointparticles( particleeffectnum("arc_smoke"), smoke_origin, '0 0 0', 1 ); + if ( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) + { + pointparticles( particleeffectnum("arc_overheat_fire"), smoke_origin, w_shotdir, 1 ); + if ( !self.arc_smoke_sound ) + { + self.arc_smoke_sound = 1; + sound(self, CH_SHOTS_SINGLE, "weapons/arc_loop_overheat.wav", VOL_BASE, ATTN_NORM); + } + } + } + else if ( self.arc_beam && WEP_CVAR(arc, overheat_max) > 0 && + self.arc_beam.beam_heat > WEP_CVAR(arc, overheat_min) ) + { + if ( random() < (self.arc_beam.beam_heat-WEP_CVAR(arc, overheat_min)) / + ( WEP_CVAR(arc, overheat_max)-WEP_CVAR(arc, overheat_min) ) ) + pointparticles( particleeffectnum("arc_smoke"), smoke_origin, '0 0 0', 1 ); + } + + if ( self.arc_smoke_sound && ( self.arc_overheat <= time || + !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || self.switchweapon != WEP_ARC ) + { + self.arc_smoke_sound = 0; + sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM); + } +} + float W_Arc(float req) { switch(req) @@ -546,7 +645,7 @@ float W_Arc(float req) WEP_CVAR(arc, beam_botaimspeed), 0, WEP_CVAR(arc, beam_botaimlifetime), - FALSE + false ); } else @@ -555,27 +654,24 @@ float W_Arc(float req) 1000000, 0, 0.001, - FALSE + false ); } - return TRUE; + return true; } case WR_THINK: { - #if 0 - if(self.arc_beam.beam_heat > threshold) - { - stop the beam somehow - play overheat animation - } - #endif + Arc_Player_SetHeat(self); + Arc_Smoke(); - if(self.BUTTON_ATCK || self.BUTTON_ATCK2 /* FIXME(Samual): || self.arc_beam.beam_bursting */) + if ( self.arc_overheat <= time ) + if(self.BUTTON_ATCK || self.BUTTON_ATCK2 || self.arc_beam.beam_bursting ) { - if(self.BUTTON_ATCK_prev) + + if(self.arc_BUTTON_ATCK_prev) { #if 0 - if(self.animstate_startframe == self.anim_shoot_x && self.animstate_numframes == self.anim_shoot_y) + if(self.animstate_startframe == self.anim_shoot.x && self.animstate_numframes == self.anim_shoot.y) weapon_thinkf(WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); else #endif @@ -587,24 +683,25 @@ float W_Arc(float req) if(weapon_prepareattack(!!self.BUTTON_ATCK2, 0)) { W_Arc_Beam(!!self.BUTTON_ATCK2); - - if(!self.BUTTON_ATCK_prev) + + if(!self.arc_BUTTON_ATCK_prev) { weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); - self.BUTTON_ATCK_prev = 1; + self.arc_BUTTON_ATCK_prev = 1; } } } - } - else // todo + + return true; + } + + if(self.arc_BUTTON_ATCK_prev != 0) { - if(self.BUTTON_ATCK_prev != 0) - { - weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); - ATTACK_FINISHED(self) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(); - } - self.BUTTON_ATCK_prev = 0; + sound(self, CH_WEAPON_A, "weapons/arc_stop.wav", VOL_BASE, ATTN_NORM); + weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); + ATTACK_FINISHED(self) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(); } + self.arc_BUTTON_ATCK_prev = 0; #if 0 if(self.BUTTON_ATCK2) @@ -617,23 +714,26 @@ float W_Arc(float req) } #endif - return TRUE; + return true; } case WR_INIT: { precache_model("models/weapons/g_arc.md3"); precache_model("models/weapons/v_arc.md3"); precache_model("models/weapons/h_arc.iqm"); - precache_sound("weapons/lgbeam_fire.wav"); + precache_sound("weapons/arc_fire.wav"); + precache_sound("weapons/arc_loop.wav"); + precache_sound("weapons/arc_stop.wav"); + precache_sound("weapons/arc_loop_overheat.wav"); if(!arc_shotorigin[0]) { - arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), FALSE, FALSE, 1); - arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), FALSE, FALSE, 2); - arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), FALSE, FALSE, 3); - arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), FALSE, FALSE, 4); + arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 1); + arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 2); + arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 3); + arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC), false, false, 4); } - ARC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP) - return TRUE; + ARC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP); + return true; } case WR_CHECKAMMO1: { @@ -641,29 +741,38 @@ float W_Arc(float req) } case WR_CHECKAMMO2: { - return ((!WEP_CVAR(arc, burst_ammo)) || (self.WEP_AMMO(ARC) > 0)); + return WEP_CVAR(arc, overheat_max) > 0 && + ((!WEP_CVAR(arc, burst_ammo)) || (self.WEP_AMMO(ARC) > 0)); } case WR_CONFIG: { - ARC_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS) - return TRUE; + ARC_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS); + return true; } case WR_KILLMESSAGE: { - if(w_deathtype & HITTYPE_SECONDARY) - { - return WEAPON_ELECTRO_MURDER_ORBS; - } - else + return WEAPON_ARC_MURDER; + } + case WR_DROP: + { + weapon_dropevent_item.arc_overheat = self.arc_overheat; + weapon_dropevent_item.arc_cooldown = self.arc_cooldown; + self.arc_overheat = 0; + self.arc_cooldown = 0; + return true; + } + case WR_PICKUP: + { + if ( !client_hasweapon(self, WEP_ARC, false, false) && + weapon_dropevent_item.arc_overheat > time ) { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_ELECTRO_MURDER_COMBO; - else - return WEAPON_ELECTRO_MURDER_BOLT; + self.arc_overheat = weapon_dropevent_item.arc_overheat; + self.arc_cooldown = weapon_dropevent_item.arc_cooldown; } + return true; } } - return FALSE; + return false; } #endif #ifdef CSQC @@ -701,7 +810,7 @@ void Draw_ArcBeam_callback(vector start, vector hit, vector end) // draw primary beam render vector top = hitorigin + (thickdir * thickness); vector bottom = hitorigin - (thickdir * thickness); - + vector last_top = WarpZone_TransformOrigin(WarpZone_trace_transform, Draw_ArcBeam_callback_last_top); vector last_bottom = WarpZone_TransformOrigin(WarpZone_trace_transform, Draw_ArcBeam_callback_last_bottom); @@ -741,7 +850,7 @@ void Draw_ArcBeam_callback(vector start, vector hit, vector end) trailparticles(beam, beam.beam_traileffect, start, hitorigin); } - // set up for the next + // set up for the next Draw_ArcBeam_callback_last_thickness = thickness; Draw_ArcBeam_callback_last_top = WarpZone_UnTransformOrigin(WarpZone_trace_transform, top); Draw_ArcBeam_callback_last_bottom = WarpZone_UnTransformOrigin(WarpZone_trace_transform, bottom); @@ -751,15 +860,19 @@ void Reset_ArcBeam(void) { entity e; for (e = world; (e = findfloat(e, beam_usevieworigin, 1)); ) { - e.beam_initialized = FALSE; + e.beam_initialized = false; } for (e = world; (e = findfloat(e, beam_usevieworigin, 2)); ) { - e.beam_initialized = FALSE; + e.beam_initialized = false; } } void Draw_ArcBeam(void) { + float dt = time - self.move_time; + self.move_time = time; + if(dt <= 0) { return; } + if(!self.beam_usevieworigin) { InterpolateOrigin_Do(); @@ -780,7 +893,7 @@ void Draw_ArcBeam(void) // Currently we have to replicate nearly the same method of figuring // out the shotdir that the server does... Ideally in the future we // should be able to acquire this from a generalized function built - // into a weapon system for client code. + // into a weapon system for client code. // find where we are aiming makevectors(warpzone_save_view_angles); @@ -811,13 +924,13 @@ void Draw_ArcBeam(void) // move shot origin to the actual gun muzzle origin vector origin_offset = - right * -self.beam_shotorigin_y - + up * self.beam_shotorigin_z; + right * -self.beam_shotorigin.y + + up * self.beam_shotorigin.z; start_pos = start_pos + origin_offset; // Move it also forward, but only as far as possible without hitting anything. Don't poke into walls! - traceline(start_pos, start_pos + forward * self.beam_shotorigin_x, MOVE_NORMAL, self); + traceline(start_pos, start_pos + forward * self.beam_shotorigin.x, MOVE_NORMAL, self); start_pos = trace_endpos; // calculate the aim direction now @@ -826,7 +939,7 @@ void Draw_ArcBeam(void) if(!self.beam_initialized) { self.beam_dir = wantdir; - self.beam_initialized = TRUE; + self.beam_initialized = true; } if(self.beam_dir != wantdir) @@ -874,7 +987,7 @@ void Draw_ArcBeam(void) if(self.beam_degreespersegment) { segments = bound( - 1, + 1, ( min( angle, @@ -922,7 +1035,7 @@ void Draw_ArcBeam(void) if(self.beam_degreespersegment) { segments = bound( - 1, + 1, ( min( angle, @@ -998,6 +1111,7 @@ void Draw_ArcBeam(void) // FIXME we really should do this on the server so it actually // matches gameplay. What this client side stuff is doing is no // more than guesswork. + if((trace_ent || trace_fraction < 1) && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)) pointparticles( self.beam_hiteffect, last_origin, @@ -1054,13 +1168,13 @@ void Remove_ArcBeam(void) void Ent_ReadArcBeam(float isnew) { - float sf = ReadByte(); + int sf = ReadByte(); entity flash; if(isnew) { // calculate shot origin offset from gun alignment - float gunalign = autocvar_cl_gunalign; + int gunalign = autocvar_cl_gunalign; if(gunalign != 1 && gunalign != 2 && gunalign != 4) gunalign = 3; // default value --gunalign; @@ -1070,7 +1184,8 @@ void Ent_ReadArcBeam(float isnew) // set other main attributes of the beam self.draw = Draw_ArcBeam; self.entremove = Remove_ArcBeam; - sound(self, CH_SHOTS_SINGLE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTEN_NORM); + self.move_time = time; + loopsound(self, CH_SHOTS_SINGLE, "weapons/arc_loop.wav", VOL_BASE, ATTEN_NORM); flash = spawn(); flash.owner = self; @@ -1161,186 +1276,209 @@ void Ent_ReadArcBeam(float isnew) { case ARC_BT_MISS: { - self.beam_color = '-1 -1 1'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 8; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam"); + self.beam_hiteffect = particleeffectnum("arc_lightning"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; - self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_WALL: // grenadelauncher_muzzleflash healray_muzzleflash { - self.beam_color = '0.5 0.5 1'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 8; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam"); + self.beam_hiteffect = particleeffectnum("arc_lightning"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; // particleeffectnum("grenadelauncher_muzzleflash"); + self.beam_muzzleeffect = -1; // particleeffectnum("grenadelauncher_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_HEAL: { - self.beam_color = '0 1 0'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 8; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("healray_impact"); + self.beam_traileffect = particleeffectnum("arc_beam_heal"); + self.beam_hiteffect = particleeffectnum("arc_beam_healimpact"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_HIT: { - self.beam_color = '1 0 1'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 8; - self.beam_traileffect = particleeffectnum("nex_beam"); - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam"); + self.beam_hiteffect = particleeffectnum("arc_lightning"); self.beam_hitlight[0] = 20; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 0; self.beam_hitlight[3] = 0; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 50; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 0; self.beam_muzzlelight[3] = 0; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_BURST_MISS: { - self.beam_color = '-1 -1 1'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 14; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam"); + self.beam_hiteffect = particleeffectnum("arc_lightning"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_BURST_WALL: { - self.beam_color = '0.5 0.5 1'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 14; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam"); + self.beam_hiteffect = particleeffectnum("arc_lightning"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_BURST_HEAL: { - self.beam_color = '0 1 0'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 14; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam_heal"); + self.beam_hiteffect = particleeffectnum("healray_impact"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } case ARC_BT_BURST_HIT: { - self.beam_color = '1 0 1'; + self.beam_color = '1 1 1'; self.beam_alpha = 0.5; self.beam_thickness = 14; - self.beam_traileffect = FALSE; - self.beam_hiteffect = particleeffectnum("electro_lightning"); + self.beam_traileffect = particleeffectnum("arc_beam"); + self.beam_hiteffect = particleeffectnum("arc_lightning"); self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } @@ -1350,22 +1488,25 @@ void Ent_ReadArcBeam(float isnew) self.beam_color = randomvec(); self.beam_alpha = 1; self.beam_thickness = 8; - self.beam_traileffect = FALSE; - self.beam_hiteffect = FALSE; + self.beam_traileffect = false; + self.beam_hiteffect = false; self.beam_hitlight[0] = 0; self.beam_hitlight[1] = 1; self.beam_hitlight[2] = 1; self.beam_hitlight[3] = 1; - self.beam_muzzleeffect = FALSE; //particleeffectnum("nex_muzzleflash"); + self.beam_muzzleeffect = -1; //particleeffectnum("nex_muzzleflash"); self.beam_muzzlelight[0] = 0; self.beam_muzzlelight[1] = 1; self.beam_muzzlelight[2] = 1; self.beam_muzzlelight[3] = 1; self.beam_image = "particles/lgbeam"; - setmodel(flash, "models/flash.md3"); - flash.alpha = self.beam_alpha; - flash.colormod = self.beam_color; - flash.scale = 0.5; + if(self.beam_muzzleeffect >= 0) + { + setmodel(flash, "models/flash.md3"); + flash.alpha = self.beam_alpha; + flash.colormod = self.beam_color; + flash.scale = 0.5; + } break; } } @@ -1384,20 +1525,20 @@ float W_Arc(float req) case WR_IMPACTEFFECT: { // todo - return TRUE; + return true; } case WR_INIT: { - precache_sound("weapons/lgbeam_fly.wav"); - return TRUE; + precache_sound("weapons/arc_loop.wav"); + return true; } case WR_ZOOMRETICLE: { // no weapon specific image for this weapon - return FALSE; + return false; } } - return FALSE; + return false; } #endif #endif