]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_hagar.qc
First part of a more common weapon reload code. Implemented for the hagar currently...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_hagar.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(HAGAR, w_hagar, IT_ROCKETS, 8, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hagar", "hagar", _("Hagar"))
3 #else
4 #ifdef SVQC
5 // NO bounce protection, as bounces are limited!
6
7 // weapon load persistence, for weapons that support reloading
8 .float hagar_load;
9
10 void W_Hagar_SetAmmoCounter()
11 {
12         // set clip_load to the weapon we have switched to, if the gun uses reloading
13         if(!autocvar_g_balance_hagar_reload_ammo)
14                 self.clip_load = 0; // also keeps crosshair ammo from displaying
15         else
16         {
17                 self.clip_load = self.hagar_load;
18                 self.clip_size = autocvar_g_balance_hagar_reload_ammo; // for the crosshair ammo display
19         }
20 }
21
22 void W_Hagar_Reload()
23 {
24         self.reload_ammo_player = ammo_rockets;
25         self.reload_ammo_min = min(autocvar_g_balance_hagar_primary_ammo, autocvar_g_balance_hagar_secondary_ammo);
26         self.reload_ammo_amount = autocvar_g_balance_hagar_reload_ammo;
27         self.reload_time = autocvar_g_balance_hagar_reload_time;
28         self.reload_sound = "weapons/reload.wav";
29
30         W_Reload();
31 }
32
33 void W_Hagar_Explode (void)
34 {
35         self.event_damage = SUB_Null;
36         RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_primary_damage, autocvar_g_balance_hagar_primary_edgedamage, autocvar_g_balance_hagar_primary_radius, world, autocvar_g_balance_hagar_primary_force, self.projectiledeathtype, other);
37
38         remove (self);
39 }
40
41 void W_Hagar_Explode2 (void)
42 {
43         self.event_damage = SUB_Null;
44         RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_secondary_damage, autocvar_g_balance_hagar_secondary_edgedamage, autocvar_g_balance_hagar_secondary_radius, world, autocvar_g_balance_hagar_secondary_force, self.projectiledeathtype, other);
45
46         remove (self);
47 }
48
49 void W_Hagar_Touch (void)
50 {
51         PROJECTILE_TOUCH;
52         self.use ();
53 }
54
55 void W_Hagar_Touch2 (void)
56 {
57         PROJECTILE_TOUCH;
58
59         if(self.cnt > 0 || other.takedamage == DAMAGE_AIM) {
60                 self.use();
61         } else {
62                 self.cnt++;
63                 pointparticles(particleeffectnum("hagar_bounce"), self.origin, self.velocity, 1);
64                 self.angles = vectoangles (self.velocity);
65                 self.owner = world;
66                 self.projectiledeathtype |= HITTYPE_BOUNCE;
67         }
68 }
69
70 void W_Hagar_Attack (void)
71 {
72         local entity missile;
73
74         // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
75         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
76         {
77                 if(autocvar_g_balance_hagar_reload_ammo)
78                 {
79                         self.clip_load -= autocvar_g_balance_hagar_primary_ammo;
80                         self.hagar_load = self.clip_load;
81                 }
82                 else
83                         self.ammo_rockets -= autocvar_g_balance_hagar_primary_ammo;
84         }
85
86         W_SetupShot (self, FALSE, 2, "weapons/hagar_fire.wav", CHAN_WEAPON, autocvar_g_balance_hagar_primary_damage);
87
88         pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
89
90         missile = spawn ();
91         missile.owner = missile.realowner = self;
92         missile.classname = "missile";
93         missile.bot_dodge = TRUE;
94         missile.bot_dodgerating = autocvar_g_balance_hagar_primary_damage;
95         missile.touch = W_Hagar_Touch;
96         missile.use = W_Hagar_Explode;
97         missile.think = adaptor_think2use_hittype_splash;
98         missile.nextthink = time + autocvar_g_balance_hagar_primary_lifetime;
99         PROJECTILE_MAKETRIGGER(missile);
100         missile.projectiledeathtype = WEP_HAGAR;
101         setorigin (missile, w_shotorg);
102         setsize(missile, '0 0 0', '0 0 0');
103
104         missile.movetype = MOVETYPE_FLY;
105         W_SETUPPROJECTILEVELOCITY(missile, g_balance_hagar_primary);
106
107         missile.angles = vectoangles (missile.velocity);
108         missile.flags = FL_PROJECTILE;
109
110         CSQCProjectile(missile, TRUE, PROJECTILE_HAGAR, TRUE);
111
112         other = missile; MUTATOR_CALLHOOK(EditProjectile);
113 }
114
115 void W_Hagar_Attack2 (void)
116 {
117         local entity missile;
118
119         // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
120         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
121         {
122                 if(autocvar_g_balance_hagar_reload_ammo)
123                 {
124                         self.clip_load -= autocvar_g_balance_hagar_secondary_ammo;
125                         self.hagar_load = self.clip_load;
126                 }
127                 else
128                         self.ammo_rockets -= autocvar_g_balance_hagar_secondary_ammo;
129         }
130
131         W_SetupShot (self, FALSE, 2, "weapons/hagar_fire.wav", CHAN_WEAPON, autocvar_g_balance_hagar_secondary_damage);
132
133         pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
134
135         missile = spawn ();
136         missile.owner = missile.realowner = self;
137         missile.classname = "missile";
138         missile.bot_dodge = TRUE;
139         missile.bot_dodgerating = autocvar_g_balance_hagar_secondary_damage;
140         missile.touch = W_Hagar_Touch2;
141         missile.cnt = 0;
142         missile.use = W_Hagar_Explode2;
143         missile.think = adaptor_think2use_hittype_splash;
144         missile.nextthink = time + autocvar_g_balance_hagar_secondary_lifetime_min + random() * autocvar_g_balance_hagar_secondary_lifetime_rand;
145         PROJECTILE_MAKETRIGGER(missile);
146         missile.projectiledeathtype = WEP_HAGAR | HITTYPE_SECONDARY;
147         setorigin (missile, w_shotorg);
148         setsize(missile, '0 0 0', '0 0 0');
149
150         missile.movetype = MOVETYPE_BOUNCEMISSILE;
151         W_SETUPPROJECTILEVELOCITY(missile, g_balance_hagar_secondary);
152
153         missile.angles = vectoangles (missile.velocity);
154         missile.flags = FL_PROJECTILE;
155
156         CSQCProjectile(missile, TRUE, PROJECTILE_HAGAR_BOUNCING, TRUE);
157
158         other = missile; MUTATOR_CALLHOOK(EditProjectile);
159 }
160
161 void spawnfunc_weapon_hagar (void)
162 {
163         weapon_defaultspawnfunc(WEP_HAGAR);
164 }
165
166 float w_hagar(float req)
167 {
168         float ammo_amount;
169         if (req == WR_AIM)
170                 if (random()>0.15)
171                         self.BUTTON_ATCK = bot_aim(autocvar_g_balance_hagar_primary_speed, 0, autocvar_g_balance_hagar_primary_lifetime, FALSE);
172                 else
173                 {
174                         // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming
175                         self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_hagar_primary_speed, 0, autocvar_g_balance_hagar_primary_lifetime, FALSE);
176                 }
177         else if (req == WR_THINK)
178         {
179                 if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(autocvar_g_balance_hagar_primary_ammo, autocvar_g_balance_hagar_secondary_ammo)) // forced reload
180                         W_Hagar_Reload();
181                 else if (self.BUTTON_ATCK)
182                 {
183                         if (weapon_prepareattack(0, autocvar_g_balance_hagar_primary_refire))
184                         {
185                                 W_Hagar_Attack();
186                                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hagar_primary_refire, w_ready);
187                         }
188                 }
189                 else if (self.BUTTON_ATCK2 && autocvar_g_balance_hagar_secondary)
190                 {
191                         if (weapon_prepareattack(1, autocvar_g_balance_hagar_secondary_refire))
192                         {
193                                 W_Hagar_Attack2();
194                                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hagar_secondary_refire, w_ready);
195                         }
196                 }
197         }
198         else if (req == WR_PRECACHE)
199         {
200                 precache_model ("models/weapons/g_hagar.md3");
201                 precache_model ("models/weapons/v_hagar.md3");
202                 precache_model ("models/weapons/h_hagar.iqm");
203                 precache_sound ("weapons/hagar_fire.wav");
204                 precache_sound ("weapons/reload.wav");
205         }
206         else if (req == WR_SETUP)
207         {
208                 weapon_setup(WEP_HAGAR);
209                 W_Hagar_SetAmmoCounter();
210         }
211         else if (req == WR_CHECKAMMO1)
212         {
213                 ammo_amount = self.ammo_rockets >= autocvar_g_balance_hagar_primary_ammo;
214                 ammo_amount += self.hagar_load >= autocvar_g_balance_hagar_primary_ammo;
215                 return ammo_amount;
216         }
217         else if (req == WR_CHECKAMMO2)
218         {
219                 ammo_amount = self.ammo_rockets >= autocvar_g_balance_hagar_secondary_ammo;
220                 ammo_amount += self.hagar_load >= autocvar_g_balance_hagar_secondary_ammo;
221                 return ammo_amount;
222         }
223         else if (req == WR_RESETPLAYER)
224         {
225                 // all weapons must be fully loaded when we spawn
226                 self.hagar_load = autocvar_g_balance_hagar_reload_ammo;
227         }
228         else if (req == WR_RELOAD)
229         {
230                 W_Hagar_Reload();
231         }
232         return TRUE;
233 };
234 #endif
235 #ifdef CSQC
236 float w_hagar(float req)
237 {
238         if(req == WR_IMPACTEFFECT)
239         {
240                 vector org2;
241                 org2 = w_org + w_backoff * 6;
242                 pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
243                 if(!w_issilent)
244                 {
245                         if (w_random<0.15)
246                                 sound(self, CHAN_PROJECTILE, "weapons/hagexp1.wav", VOL_BASE, ATTN_NORM);
247                         else if (w_random<0.7)
248                                 sound(self, CHAN_PROJECTILE, "weapons/hagexp2.wav", VOL_BASE, ATTN_NORM);
249                         else
250                                 sound(self, CHAN_PROJECTILE, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
251                 }
252         }
253         else if(req == WR_PRECACHE)
254         {
255                 precache_sound("weapons/hagexp1.wav");
256                 precache_sound("weapons/hagexp2.wav");
257                 precache_sound("weapons/hagexp3.wav");
258         }
259         else if (req == WR_SUICIDEMESSAGE)
260                 w_deathtypestring = _("%s played with tiny rockets");
261         else if (req == WR_KILLMESSAGE)
262         {
263                 if(w_deathtype & HITTYPE_BOUNCE) // must be secondary; unchecked: SPLASH
264                         w_deathtypestring = _("%s hoped %s's missiles wouldn't bounce");
265                 else // unchecked: SPLASH, SECONDARY
266                         w_deathtypestring = _("%s was pummeled by %s");
267         }
268         return TRUE;
269 }
270 #endif
271 #endif