experimental gauntlet, use it in nexrun, do a small lg tweak for the nexrun balance
[divverent/nexuiz.git] / data / qcsrc / server / w_laser.qc
1 void(float imp) W_SwitchWeapon;
2
3 void W_Laser_Touch (void)
4 {
5         PROJECTILE_TOUCH;
6
7         self.event_damage = SUB_Null;
8         if (self.dmg)
9                 RadiusDamage (self, self.owner, cvar("g_balance_laser_secondary_damage"), cvar("g_balance_laser_secondary_edgedamage"), cvar("g_balance_laser_secondary_radius"), world, cvar("g_balance_laser_secondary_force"), self.projectiledeathtype, other);
10         else
11                 RadiusDamage (self, self.owner, cvar("g_balance_laser_primary_damage"), cvar("g_balance_laser_primary_edgedamage"), cvar("g_balance_laser_primary_radius"), world, cvar("g_balance_laser_primary_force"), self.projectiledeathtype, other);
12
13         remove (self);
14 }
15
16 void W_Laser_Think()
17 {
18         self.movetype = MOVETYPE_FLY;
19         self.think = SUB_Remove;
20         if (self.dmg)
21                 self.nextthink = time + cvar("g_balance_laser_secondary_lifetime");
22         else
23                 self.nextthink = time + cvar("g_balance_laser_primary_lifetime");
24         CSQCProjectile(self, TRUE, PROJECTILE_LASER, TRUE);
25 }
26
27 void W_Laser_Attack (float issecondary)
28 {
29         local entity missile;
30         vector s_forward;
31         float a;
32         float nodamage;
33
34         if(issecondary == 2) // minstanex shot
35                 nodamage = g_minstagib;
36         else
37                 nodamage = FALSE;
38
39         if (issecondary == 1)
40                 a = cvar("g_balance_laser_secondary_shotangle");
41         else
42                 a = cvar("g_balance_laser_primary_shotangle");
43         s_forward = v_forward * cos(a * DEG2RAD) + v_up * sin(a * DEG2RAD);
44
45         if(nodamage)
46                 W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", 0);
47         else if(issecondary == 1)
48                 W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", cvar("g_balance_laser_secondary_damage"));
49         else
50                 W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", cvar("g_balance_laser_primary_damage"));
51         pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
52
53         missile = spawn ();
54         missile.owner = self;
55         missile.classname = "laserbolt";
56         missile.dmg = (issecondary == 1);
57         if(!nodamage)
58         {
59                 missile.bot_dodge = TRUE;
60                 if (issecondary == 1)
61                         missile.bot_dodgerating = cvar("g_balance_laser_secondary_damage");
62                 else
63                         missile.bot_dodgerating = cvar("g_balance_laser_primary_damage");
64         }
65
66         PROJECTILE_MAKETRIGGER(missile);
67         missile.projectiledeathtype = WEP_LASER;
68         if(issecondary == 1)
69                 missile.projectiledeathtype |= HITTYPE_SECONDARY;
70
71         setorigin (missile, w_shotorg);
72         setsize(missile, '0 0 0', '0 0 0');
73
74         if (issecondary == 1)
75                 W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_secondary);
76         else
77                 W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_primary);
78         missile.angles = vectoangles (missile.velocity);
79         //missile.glow_color = 250; // 244, 250
80         //missile.glow_size = 120;
81         missile.touch = W_Laser_Touch;
82
83         missile.flags = FL_PROJECTILE;
84
85         missile.think = W_Laser_Think;
86         if (issecondary == 1)
87                 missile.nextthink = time + cvar("g_balance_laser_secondary_delay");
88         else
89                 missile.nextthink = time + cvar("g_balance_laser_primary_delay");
90         if(time >= missile.nextthink)
91         {
92                 entity oldself;
93                 oldself = self;
94                 self = missile;
95                 self.think();
96                 self = oldself;
97         }
98 }
99
100 void W_Laser_Attack2 (void) // gauntlet
101 {
102         W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", cvar("g_balance_laser_primary_damage"));
103
104         traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * cvar("g_balance_laser_primary_radius"), FALSE, self, self.ping * 0.001);
105
106         pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * cvar("g_balance_laser_primary_radius"), '0 0 0', 1);
107
108         if (trace_fraction < 1)
109                 Damage(trace_ent, self, self, cvar("g_balance_laser_primary_damage"), WEP_LASER | HITTYPE_SECONDARY, trace_endpos, cvar("g_balance_laser_primary_force") * w_shotdir);
110 }
111
112 void spawnfunc_weapon_laser (void)
113 {
114         weapon_defaultspawnfunc(WEP_LASER);
115 }
116
117 float w_laser(float req)
118 {
119         local float r1;
120         local float r2;
121         if (req == WR_AIM)
122         {
123                 if(cvar("g_balance_laser_secondary"))
124                 {
125                         r1 = cvar("g_balance_laser_primary_damage");
126                         r2 = cvar("g_balance_laser_secondary_damage");
127                         if (random() * (r2 + r1) > r1)
128                                 self.BUTTON_ATCK2 = bot_aim(cvar("g_balance_laser_secondary_speed"), 0, cvar("g_balance_laser_secondary_lifetime"), FALSE);
129                         else
130                                 self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
131                 }
132                 else
133                         self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
134         }
135         else if (req == WR_THINK)
136         {
137                 if (self.BUTTON_ATCK)
138                 if (weapon_prepareattack(0, cvar("g_balance_laser_primary_refire")))
139                 {
140                         if(cvar("g_balance_laser_gauntlet"))
141                                 W_Laser_Attack2();
142                         else
143                                 W_Laser_Attack(0);
144                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_laser_primary_animtime"), w_ready);
145                 }
146                 if (self.BUTTON_ATCK2)
147                 {
148                         if(cvar("g_balance_laser_secondary"))
149                         {
150                                 if (weapon_prepareattack(0, cvar("g_balance_laser_secondary_refire")))
151                                 {
152                                         W_Laser_Attack(1);
153                                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_laser_secondary_animtime"), w_ready);
154                                 }
155                         }
156                         else
157                         {
158                                 if(self.switchweapon == WEP_LASER) // don't do this if already switching
159                                         W_SwitchWeapon (self.cnt);
160                         }
161                 }
162         }
163         else if (req == WR_PRECACHE)
164         {
165                 precache_model ("models/weapons/g_laser.md3");
166                 precache_model ("models/weapons/v_laser.md3");
167                 precache_model ("models/weapons/h_laser.dpm");
168                 precache_sound ("weapons/lasergun_fire.wav");
169         }
170         else if (req == WR_SETUP)
171                 weapon_setup(WEP_LASER);
172         else if (req == WR_CHECKAMMO1)
173                 return TRUE;
174         else if (req == WR_CHECKAMMO2)
175                 return TRUE;
176         else if (req == WR_SUICIDEMESSAGE)
177                 w_deathtypestring = "lasered themself to hell";
178         else if (req == WR_KILLMESSAGE)
179         {
180                 w_deathtypestring = "was lasered to death by"; // unchecked: SPLASH
181         }
182         return TRUE;
183 };