]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/w_electro.qc
electro: add a cvar to bring back three-shot electro
[divverent/nexuiz.git] / data / qcsrc / server / w_electro.qc
1 .float electro_count;
2
3 void W_Plasma_Explode (void)
4 {
5         if(other.takedamage == DAMAGE_AIM)
6                 if(other.classname == "player")
7                         if(IsDifferentTeam(self.owner, other))
8                                 if(other.deadflag == DEAD_NO)
9                                         if(IsFlying(other))
10                                                 announce(self.owner, "announcer/male/electrobitch.wav");
11
12         self.event_damage = SUB_Null;
13         self.takedamage = DAMAGE_NO;
14         if (self.movetype == MOVETYPE_BOUNCE)
15         {
16                 RadiusDamage (self, self.owner, cvar("g_balance_electro_secondary_damage"), cvar("g_balance_electro_secondary_edgedamage"), cvar("g_balance_electro_secondary_radius"), world, cvar("g_balance_electro_secondary_force"), self.projectiledeathtype, other);
17         }
18         else
19         {
20                 RadiusDamage (self, self.owner, cvar("g_balance_electro_primary_damage"), cvar("g_balance_electro_primary_edgedamage"), cvar("g_balance_electro_primary_radius"), world, cvar("g_balance_electro_primary_force"), self.projectiledeathtype, other);
21         }
22
23         remove (self);
24 }
25
26 void W_Plasma_Explode_Combo (void) {
27         self.event_damage = SUB_Null;
28         RadiusDamage (self, self.owner, cvar("g_balance_electro_combo_damage"), cvar("g_balance_electro_combo_edgedamage"), cvar("g_balance_electro_combo_radius"), world, cvar("g_balance_electro_combo_force"), WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
29         remove (self);
30 }
31
32 void W_Plasma_Touch (void)
33 {
34         PROJECTILE_TOUCH;
35         if (other.takedamage == DAMAGE_AIM) {
36                 W_Plasma_Explode ();
37         } else {
38                 spamsound (self, CHAN_PROJECTILE, "weapons/electro_bounce.wav", VOL_BASE, ATTN_NORM);
39                 self.projectiledeathtype |= HITTYPE_BOUNCE;
40         }
41 }
42
43 void W_Plasma_TouchExplode (void)
44 {
45         PROJECTILE_TOUCH;
46         W_Plasma_Explode ();
47 }
48
49 void W_Plasma_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
50 {
51         if(self.health <= 0)
52                 return;
53         self.health = self.health - damage;
54         if (self.health <= 0)
55         {
56                 self.takedamage = DAMAGE_NO;
57                 self.nextthink = time;
58                 if (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim")
59                 {
60                         // change owner to whoever caused the combo explosion
61                         self.owner = inflictor.owner;
62                         self.classname = "plasma_chain";
63                         self.think = W_Plasma_Explode_Combo;
64                         self.nextthink = time + vlen(self.origin - inflictor.origin) / cvar("g_balance_electro_combo_speed"); // delay combo chains, looks cooler
65                 }
66                 else
67                 {
68                         self.use = W_Plasma_Explode;
69                         self.think = adaptor_think2use;
70                 }
71         }
72 }
73
74 void W_Electro_Attack()
75 {
76         local entity proj;
77
78         W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire.wav", cvar("g_balance_electro_primary_damage"));
79
80         pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
81
82         proj = spawn ();
83         proj.classname = "plasma_prim";
84         proj.owner = self;
85         proj.bot_dodge = TRUE;
86         proj.bot_dodgerating = cvar("g_balance_electro_primary_damage");
87         proj.use = W_Plasma_Explode;
88         proj.think = adaptor_think2use;
89         proj.nextthink = time + cvar("g_balance_electro_primary_lifetime");
90         PROJECTILE_MAKETRIGGER(proj);
91         proj.projectiledeathtype = WEP_ELECTRO;
92         setorigin(proj, w_shotorg);
93
94         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
95                 self.ammo_cells = self.ammo_cells - cvar("g_balance_electro_primary_ammo");
96         proj.movetype = MOVETYPE_FLY;
97         proj.velocity = w_shotdir * cvar("g_balance_electro_primary_speed");
98         W_SetupProjectileVelocity(proj);
99         proj.angles = vectoangles(proj.velocity);
100         proj.touch = W_Plasma_TouchExplode;
101         setsize(proj, '0 0 -3', '0 0 -3');
102         proj.flags = FL_PROJECTILE;
103
104         //sound (proj, CHAN_PAIN, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
105         //sounds bad
106
107         CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
108 }
109
110 void W_Electro_Attack2()
111 {
112         local entity proj;
113
114         W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire2.wav", cvar("g_balance_electro_secondary_damage"));
115         w_shotdir = v_forward; // no TrueAim for grenades please
116
117         pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
118
119         proj = spawn ();
120         proj.classname = "plasma";
121         proj.owner = self;
122         proj.use = W_Plasma_Explode;
123         proj.think = adaptor_think2use;
124         proj.bot_dodge = TRUE;
125         proj.bot_dodgerating = cvar("g_balance_electro_secondary_damage");
126         proj.nextthink = time + cvar("g_balance_electro_secondary_lifetime");
127         PROJECTILE_MAKETRIGGER(proj);
128         proj.projectiledeathtype = WEP_ELECTRO | HITTYPE_SECONDARY;
129         setorigin(proj, w_shotorg);
130
131         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
132                 self.ammo_cells = self.ammo_cells - cvar("g_balance_electro_secondary_ammo");
133         //proj.glow_size = 50;
134         //proj.glow_color = 45;
135         proj.movetype = MOVETYPE_BOUNCE;
136         proj.velocity = (w_shotdir + randomvec() * cvar("g_balance_electro_secondary_spread")) * cvar("g_balance_electro_secondary_speed") + v_up * cvar("g_balance_electro_secondary_speed_up");
137         W_SetupProjectileVelocity(proj);
138         proj.touch = W_Plasma_Touch;
139         setsize(proj, '0 0 -3', '0 0 -3');
140         proj.takedamage = DAMAGE_YES;
141         proj.damageforcescale = cvar("g_balance_electro_secondary_damageforcescale");
142         proj.health = cvar("g_balance_electro_secondary_health");
143         proj.event_damage = W_Plasma_Damage;
144         proj.flags = FL_PROJECTILE;
145
146 #if 0
147         entity p2;
148         p2 = spawn();
149         copyentity(proj, p2);
150         setmodel(p2, "models/ebomb.mdl");
151         setsize(p2, proj.mins, proj.maxs);
152 #endif
153
154         CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO, FALSE); // no culling, it has sound
155 }
156
157 void spawnfunc_weapon_electro (void)
158 {
159         weapon_defaultspawnfunc(WEP_ELECTRO);
160 }
161
162 void w_electro_checkattack()
163 {
164         if(self.electro_count > 1)
165         if(self.BUTTON_ATCK2)
166         if(weapon_prepareattack(1, -1))
167         {
168                 W_Electro_Attack2();
169                 self.electro_count -= 1;
170                 weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_electro_secondary_animtime"), w_electro_checkattack);
171                 return;
172         }
173
174         w_ready();
175 }
176
177 .float bot_secondary_electromooth;
178 float w_electro(float req)
179 {
180         if (req == WR_AIM)
181         {
182                 self.BUTTON_ATCK=FALSE;
183                 self.BUTTON_ATCK2=FALSE;
184                 if(vlen(self.origin-self.enemy.origin) > 1000)
185                         self.bot_secondary_electromooth = 0;
186                 if(self.bot_secondary_electromooth == 0)
187                 {
188                         if(bot_aim(cvar("g_balance_electro_primary_speed"), 0, cvar("g_balance_electro_primary_lifetime"), FALSE))
189                         {
190                                 self.BUTTON_ATCK = TRUE;
191                                 if(random() < 0.01) self.bot_secondary_electromooth = 1;
192                         }
193                 }
194                 else
195                 {
196                         if(bot_aim(cvar("g_balance_electro_secondary_speed"), cvar("g_balance_grenadelauncher_secondary_speed_up"), cvar("g_balance_electro_secondary_lifetime"), TRUE))
197                         {
198                                 self.BUTTON_ATCK2 = TRUE;
199                                 if(random() < 0.03) self.bot_secondary_electromooth = 0;
200                         }
201                 }
202         }
203         else if (req == WR_THINK)
204         {
205                 if (self.BUTTON_ATCK)
206                 if (weapon_prepareattack(0, cvar("g_balance_electro_primary_refire")))
207                 {
208                         W_Electro_Attack();
209                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
210                 }
211                 if (self.BUTTON_ATCK2)
212                 if (weapon_prepareattack(1, cvar("g_balance_electro_secondary_refire")))
213                 {
214                         W_Electro_Attack2();
215                         self.electro_count = cvar("g_balance_electro_secondary_count");
216                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_electro_secondary_animtime"), w_electro_checkattack);
217                 }
218         }
219         else if (req == WR_PRECACHE)
220         {
221                 precache_model ("models/weapons/g_electro.md3");
222                 precache_model ("models/weapons/v_electro.md3");
223                 precache_model ("models/weapons/h_electro.dpm");
224                 precache_sound ("weapons/electro_bounce.wav");
225                 precache_sound ("weapons/electro_fire.wav");
226                 precache_sound ("weapons/electro_fire2.wav");
227                 precache_sound ("weapons/electro_impact.wav");
228                 precache_sound ("weapons/electro_impact_combo.wav");
229         }
230         else if (req == WR_SETUP)
231                 weapon_setup(WEP_ELECTRO);
232         else if (req == WR_CHECKAMMO1)
233                 return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
234         else if (req == WR_CHECKAMMO2)
235                 return self.ammo_cells >= cvar("g_balance_electro_secondary_ammo");
236         else if (req == WR_SUICIDEMESSAGE)
237         {
238                 if(w_deathtype & HITTYPE_SECONDARY)
239                         w_deathtypestring = "could not remember where he put plasma";
240                 else
241                         w_deathtypestring = "played with plasma";
242         }
243         else if (req == WR_KILLMESSAGE)
244         {
245                 if(w_deathtype & HITTYPE_SECONDARY)
246                 {
247                         if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
248                                 w_deathtypestring = "just noticed #'s blue ball";
249                         else // unchecked: BOUNCE
250                                 w_deathtypestring = "got in touch with #'s blue ball";
251                 }
252                 else
253                 {
254                         if(w_deathtype & HITTYPE_BOUNCE) // combo
255                                 w_deathtypestring = "felt the electrifying air of #'s combo";
256                         else if(w_deathtype & HITTYPE_SPLASH)
257                                 w_deathtypestring = "got too close to #'s blue beam";
258                         else
259                                 w_deathtypestring = "was blasted by #'s blue beam";
260                 }
261         }
262         return TRUE;
263 };