]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_laser.qc
Merge branch 'master' into fruitiex/fruitbalance
[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 (void) // gauntlet
105 {
106         W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", cvar("g_balance_laser_primary_damage"));
107
108         WarpZone_traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * (cvar("g_balance_laser_primary_radius") + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), FALSE, self, ANTILAG_LATENCY(self));
109
110         pointparticles(particleeffectnum("laser_gauntletmuzzleflash"), w_shotorg, w_shotdir * 1000, 1);
111         pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (cvar("g_balance_laser_primary_radius") + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), w_shotdir * 1000, 1);
112         pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (cvar("g_balance_laser_primary_radius") + vlen(eX * self.velocity_x + eY * self.velocity_y)/5) * 0.5, w_shotdir * 1000, 1);
113
114         if (trace_fraction < 1)
115                 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);
116 }
117
118 void spawnfunc_weapon_laser (void)
119 {
120         weapon_defaultspawnfunc(WEP_LASER);
121 }
122
123 float w_laser(float req)
124 {
125         local float r1;
126         local float r2;
127         if (req == WR_AIM)
128         {
129                 if(cvar("g_balance_laser_secondary"))
130                 {
131                         r1 = cvar("g_balance_laser_primary_damage");
132                         r2 = cvar("g_balance_laser_secondary_damage");
133                         if (random() * (r2 + r1) > r1)
134                                 self.BUTTON_ATCK2 = bot_aim(cvar("g_balance_laser_secondary_speed"), 0, cvar("g_balance_laser_secondary_lifetime"), FALSE);
135                         else
136                                 self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
137                 }
138                 else
139                         self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
140         }
141         else if (req == WR_THINK)
142         {
143                 if (self.BUTTON_ATCK)
144                 if (weapon_prepareattack(0, cvar("g_balance_laser_primary_refire")))
145                 {
146                         if(cvar("g_balance_laser_gauntlet"))
147                                 W_Laser_Attack2();
148                         else
149                                 W_Laser_Attack(0);
150                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_laser_primary_animtime"), w_ready);
151                 }
152                 if (self.BUTTON_ATCK2)
153                 {
154                         if(cvar("g_balance_laser_secondary"))
155                         {
156                                 if (weapon_prepareattack(0, cvar("g_balance_laser_secondary_refire")))
157                                 {
158                                         W_Laser_Attack(1);
159                                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_laser_secondary_animtime"), w_ready);
160                                 }
161                         }
162                         else
163                         {
164                                 if(self.switchweapon == WEP_LASER) // don't do this if already switching
165                                         W_SwitchWeapon (self.cnt);
166                         }
167                 }
168         }
169         else if (req == WR_PRECACHE)
170         {
171                 precache_model ("models/weapons/g_laser.md3");
172                 precache_model ("models/weapons/v_laser.md3");
173                 precache_model ("models/weapons/h_laser.iqm");
174                 precache_sound ("weapons/lasergun_fire.wav");
175                 precache_sound ("weapons/gauntlet_fire.wav");
176         }
177         else if (req == WR_SETUP)
178                 weapon_setup(WEP_LASER);
179         else if (req == WR_CHECKAMMO1)
180                 return TRUE;
181         else if (req == WR_CHECKAMMO2)
182                 return TRUE;
183         return TRUE;
184 };
185 #endif
186 #ifdef CSQC
187 float w_laser(float req)
188 {
189         if(req == WR_IMPACTEFFECT)
190         {
191                 vector org2;
192                 org2 = w_org + w_backoff * 6;
193                 pointparticles(particleeffectnum("laser_impact"), org2, w_backoff * 1000, 1);
194                 if(!w_issilent)
195                         sound(self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
196         }
197         else if(req == WR_PRECACHE)
198         {
199                 precache_sound("weapons/laserimpact.wav");
200         }
201         else if (req == WR_SUICIDEMESSAGE)
202                 w_deathtypestring = "lasered themself to hell";
203         else if (req == WR_KILLMESSAGE)
204         {
205                 w_deathtypestring = "was lasered to death by"; // unchecked: SPLASH
206         }
207         return TRUE;
208 }
209 #endif
210 #endif