4 /* function */ W_Laser,
7 /* flags */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
10 /* netname */ "laser",
11 /* fullname */ _("Blaster")
15 void spawnfunc_weapon_laser() { weapon_defaultspawnfunc(WEP_LASER); }
16 void(float imp) W_SwitchWeapon;
19 void SendCSQCShockwaveParticle(vector endpos)
21 //endpos = WarpZone_UnTransformOrigin(transform, endpos);
23 WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
24 WriteByte(MSG_BROADCAST, TE_CSQC_SHOCKWAVEPARTICLE);
25 WriteCoord(MSG_BROADCAST, w_shotorg_x);
26 WriteCoord(MSG_BROADCAST, w_shotorg_y);
27 WriteCoord(MSG_BROADCAST, w_shotorg_z);
28 WriteCoord(MSG_BROADCAST, endpos_x);
29 WriteCoord(MSG_BROADCAST, endpos_y);
30 WriteCoord(MSG_BROADCAST, endpos_z);
31 WriteByte(MSG_BROADCAST, bound(0, autocvar_g_balance_laser_shockwave_spread_max, 255));
32 WriteByte(MSG_BROADCAST, bound(0, autocvar_g_balance_laser_shockwave_spread_min, 255));
33 WriteByte(MSG_BROADCAST, num_for_edict(self));
40 self.event_damage = func_null;
43 RadiusDamage(self, self.realowner, autocvar_g_balance_laser_secondary_damage, autocvar_g_balance_laser_secondary_edgedamage, autocvar_g_balance_laser_secondary_radius, world, world, autocvar_g_balance_laser_secondary_force, self.projectiledeathtype, other);
45 RadiusDamage(self, self.realowner, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_radius, world, world, autocvar_g_balance_laser_primary_force, self.projectiledeathtype, other);
52 self.movetype = MOVETYPE_FLY;
53 self.think = SUB_Remove;
56 self.nextthink = time + autocvar_g_balance_laser_secondary_lifetime;
58 self.nextthink = time + autocvar_g_balance_laser_primary_lifetime;
60 CSQCProjectile(self, TRUE, PROJECTILE_LASER, TRUE);
63 void W_Laser_Attack(float issecondary)
69 a = autocvar_g_balance_laser_primary_shotangle;
70 s_forward = v_forward * cos(a * DEG2RAD) + v_up * sin(a * DEG2RAD);
73 // W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, 0);
74 /*else*/if(issecondary == 1)
75 W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_secondary_damage);
77 W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_primary_damage);
78 pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
81 missile.owner = missile.realowner = self;
82 missile.classname = "laserbolt";
84 missile.bot_dodge = TRUE;
85 missile.bot_dodgerating = autocvar_g_balance_laser_primary_damage;
87 PROJECTILE_MAKETRIGGER(missile);
88 missile.projectiledeathtype = WEP_LASER;
90 setorigin(missile, w_shotorg);
91 setsize(missile, '0 0 0', '0 0 0');
93 W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_primary);
94 missile.angles = vectoangles(missile.velocity);
95 //missile.glow_color = 250; // 244, 250
96 //missile.glow_size = 120;
97 missile.touch = W_Laser_Touch;
99 missile.flags = FL_PROJECTILE;
100 missile.missile_flags = MIF_SPLASH;
102 missile.think = W_Laser_Think;
103 missile.nextthink = time + autocvar_g_balance_laser_primary_delay;
105 other = missile; MUTATOR_CALLHOOK(EditProjectile);
107 if(time >= missile.nextthink)
117 float W_Laser(float request)
123 if((autocvar_g_balance_laser_secondary == 2) && (vlen(self.origin-self.enemy.origin) <= autocvar_g_balance_laser_melee_range))
124 self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
126 self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
132 if(autocvar_g_balance_laser_reload_ammo && self.clip_load < 1) // forced reload
133 WEP_ACTION(self.weapon, WR_RELOAD);
134 else if(self.BUTTON_ATCK)
136 if(weapon_prepareattack(0, autocvar_g_balance_laser_primary_refire))
138 W_DecreaseAmmo(ammo_none, 1, TRUE);
140 if not(autocvar_g_balance_laser_primary)
143 W_Laser_Attack(FALSE);
145 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_primary_animtime, w_ready);
148 else if(self.BUTTON_ATCK2)
150 switch(autocvar_g_balance_laser_secondary)
152 case 0: // switch to last used weapon
154 if(self.switchweapon == WEP_LASER) // don't do this if already switching
160 case 1: // normal projectile secondary
162 if(weapon_prepareattack(1, autocvar_g_balance_laser_secondary_refire))
164 W_DecreaseAmmo(ammo_none, 1, TRUE);
165 W_Laser_Attack(TRUE);
166 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_laser_secondary_animtime, w_ready);
172 case 2: // melee attack secondary
174 if(!self.crouch) // we are not currently crouching; this fixes an exploit where your melee anim is not visible, and besides wouldn't make much sense
175 if(weapon_prepareattack(1, autocvar_g_balance_laser_melee_refire))
177 // attempt forcing playback of the anim by switching to another anim (that we never play) here...
179 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_melee_animtime, w_ready);
189 precache_model("models/weapons/g_laser.md3");
190 precache_model("models/weapons/v_laser.md3");
191 precache_model("models/weapons/h_laser.iqm");
192 precache_sound("weapons/lasergun_fire.wav");
198 self.current_ammo = ammo_none;
205 return TRUE; // laser has infinite ammo
210 W_Reload(0, "weapons/reload.wav");
214 case WR_SUICIDEMESSAGE:
216 return WEAPON_LASER_SUICIDE;
221 return WEAPON_LASER_MURDER;
229 float W_Laser(float request)
233 case WR_IMPACTEFFECT:
236 org2 = w_org + w_backoff * 6;
237 pointparticles(particleeffectnum("new_laser_impact"), org2, w_backoff * 1000, 1);
238 if(!w_issilent) { sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM); }
244 precache_sound("weapons/laserimpact.wav");