]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_laser.qc
laser secondary = gauntlet, better effects coming soon
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_laser.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(LASER, w_laser, 0, 1, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, 0, "laser", "laser", "Laser");
3 #else
4 #ifdef SVQC
5 void(float imp) W_SwitchWeapon;
6
7 void W_Laser_Touch (void)
8 {
9         PROJECTILE_TOUCH;
10
11         self.event_damage = SUB_Null;
12         if (self.dmg)
13                 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);
14         else
15                 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);
16
17         remove (self);
18 }
19
20 void W_Laser_Think()
21 {
22         self.movetype = MOVETYPE_FLY;
23         self.think = SUB_Remove;
24         if (self.dmg)
25                 self.nextthink = time + cvar("g_balance_laser_secondary_lifetime");
26         else
27                 self.nextthink = time + cvar("g_balance_laser_primary_lifetime");
28         CSQCProjectile(self, TRUE, PROJECTILE_LASER, TRUE);
29 }
30
31 void W_Laser_Attack (float issecondary)
32 {
33         local entity missile;
34         vector s_forward;
35         float a;
36         float nodamage;
37
38         if(issecondary == 2) // minstanex shot
39                 nodamage = g_minstagib;
40         else
41                 nodamage = FALSE;
42
43         if (issecondary == 1)
44                 a = cvar("g_balance_laser_secondary_shotangle");
45         else
46                 a = cvar("g_balance_laser_primary_shotangle");
47         s_forward = v_forward * cos(a * DEG2RAD) + v_up * sin(a * DEG2RAD);
48
49         if(nodamage)
50                 W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", 0);
51         else if(issecondary == 1)
52                 W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", cvar("g_balance_laser_secondary_damage"));
53         else
54                 W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", cvar("g_balance_laser_primary_damage"));
55         pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
56
57         missile = spawn ();
58         missile.owner = self;
59         missile.classname = "laserbolt";
60         missile.dmg = (issecondary == 1);
61         if(!nodamage)
62         {
63                 missile.bot_dodge = TRUE;
64                 if (issecondary == 1)
65                         missile.bot_dodgerating = cvar("g_balance_laser_secondary_damage");
66                 else
67                         missile.bot_dodgerating = cvar("g_balance_laser_primary_damage");
68         }
69
70         PROJECTILE_MAKETRIGGER(missile);
71         missile.projectiledeathtype = WEP_LASER;
72         if(issecondary == 1)
73                 missile.projectiledeathtype |= HITTYPE_SECONDARY;
74
75         setorigin (missile, w_shotorg);
76         setsize(missile, '0 0 0', '0 0 0');
77
78         if (issecondary == 1)
79                 W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_secondary);
80         else
81                 W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_primary);
82         missile.angles = vectoangles (missile.velocity);
83         //missile.glow_color = 250; // 244, 250
84         //missile.glow_size = 120;
85         missile.touch = W_Laser_Touch;
86
87         missile.flags = FL_PROJECTILE;
88
89         missile.think = W_Laser_Think;
90         if (issecondary == 1)
91                 missile.nextthink = time + cvar("g_balance_laser_secondary_delay");
92         else
93                 missile.nextthink = time + cvar("g_balance_laser_primary_delay");
94         if(time >= missile.nextthink)
95         {
96                 entity oldself;
97                 oldself = self;
98                 self = missile;
99                 self.think();
100                 self = oldself;
101         }
102 }
103
104 void W_Laser_Attack2 (float issecondary) // gauntlet
105 {
106         float damage, force, myradius;
107         if(issecondary)
108         {
109                 damage = cvar("g_balance_laser_secondary_damage");
110                 force = cvar("g_balance_laser_secondary_force");
111                 myradius = cvar("g_balance_laser_secondary_radius");
112         }
113         else
114         {
115                 damage = cvar("g_balance_laser_primary_damage");
116                 force = cvar("g_balance_laser_primary_force");
117                 myradius = cvar("g_balance_laser_primary_radius");
118         }
119
120         W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", damage);
121
122         WarpZone_traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * (myradius + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), FALSE, self, ANTILAG_LATENCY(self));
123
124         pointparticles(particleeffectnum("laser_gauntletmuzzleflash"), w_shotorg, w_shotdir * 1000, 1);
125         pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (myradius + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), w_shotdir * 1000, 1);
126         pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (myradius + vlen(eX * self.velocity_x + eY * self.velocity_y)/5) * 0.5, w_shotdir * 1000, 1);
127
128         if (trace_fraction < 1)
129                 Damage(trace_ent, self, self, damage, WEP_LASER | HITTYPE_SECONDARY, trace_endpos, cvar("g_balance_laser_primary_force") * w_shotdir);
130 }
131
132 void spawnfunc_weapon_laser (void)
133 {
134         weapon_defaultspawnfunc(WEP_LASER);
135 }
136
137 float w_laser(float req)
138 {
139         local float r1;
140         local float r2;
141         if (req == WR_AIM)
142         {
143                 if(cvar("g_balance_laser_secondary"))
144                 {
145                         r1 = cvar("g_balance_laser_primary_damage");
146                         r2 = cvar("g_balance_laser_secondary_damage");
147                         if (random() * (r2 + r1) > r1)
148                                 self.BUTTON_ATCK2 = bot_aim(cvar("g_balance_laser_secondary_speed"), 0, cvar("g_balance_laser_secondary_lifetime"), FALSE);
149                         else
150                                 self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
151                 }
152                 else
153                         self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
154         }
155         else if (req == WR_THINK)
156         {
157                 if (self.BUTTON_ATCK)
158                 if (weapon_prepareattack(0, cvar("g_balance_laser_primary_refire")))
159                 {
160                         if(cvar("g_balance_laser_primary_gauntlet"))
161                                 W_Laser_Attack2(0);
162                         else
163                                 W_Laser_Attack(0);
164                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_laser_primary_animtime"), w_ready);
165                 }
166                 if (self.BUTTON_ATCK2)
167                 {
168                         if(cvar("g_balance_laser_secondary"))
169                         {
170                                 if (weapon_prepareattack(0, cvar("g_balance_laser_secondary_refire")))
171                                 {
172                                         if(cvar("g_balance_laser_secondary_gauntlet"))
173                                                 W_Laser_Attack2(1);
174                                         else
175                                                 W_Laser_Attack(1);
176                                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_laser_secondary_animtime"), w_ready);
177                                 }
178                         }
179                         else
180                         {
181                                 if(self.switchweapon == WEP_LASER) // don't do this if already switching
182                                         W_SwitchWeapon (self.cnt);
183                         }
184                 }
185         }
186         else if (req == WR_PRECACHE)
187         {
188                 precache_model ("models/weapons/g_laser.md3");
189                 precache_model ("models/weapons/v_laser.md3");
190                 precache_model ("models/weapons/h_laser.iqm");
191                 precache_sound ("weapons/lasergun_fire.wav");
192                 precache_sound ("weapons/gauntlet_fire.wav");
193         }
194         else if (req == WR_SETUP)
195                 weapon_setup(WEP_LASER);
196         else if (req == WR_CHECKAMMO1)
197                 return TRUE;
198         else if (req == WR_CHECKAMMO2)
199                 return TRUE;
200         return TRUE;
201 };
202 #endif
203 #ifdef CSQC
204 float w_laser(float req)
205 {
206         if(req == WR_IMPACTEFFECT)
207         {
208                 vector org2;
209                 org2 = w_org + w_backoff * 6;
210                 pointparticles(particleeffectnum("laser_impact"), org2, w_backoff * 1000, 1);
211                 if(!w_issilent)
212                         sound(self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
213         }
214         else if(req == WR_PRECACHE)
215         {
216                 precache_sound("weapons/laserimpact.wav");
217         }
218         else if (req == WR_SUICIDEMESSAGE)
219                 w_deathtypestring = "lasered themself to hell";
220         else if (req == WR_KILLMESSAGE)
221         {
222                 w_deathtypestring = "was lasered to death by"; // unchecked: SPLASH
223         }
224         return TRUE;
225 }
226 #endif
227 #endif