]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/w_electro.qc
handle self/oself CORRECTLY this time
[divverent/nexuiz.git] / data / qcsrc / server / w_electro.qc
1
2 void W_Plasma_Explode (void)
3 {
4         vector org2;
5         org2 = findbetterlocation (self.origin, 8);
6         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
7         WriteByte (MSG_BROADCAST, 79);
8         WriteCoord (MSG_BROADCAST, org2_x);
9         WriteCoord (MSG_BROADCAST, org2_y);
10         WriteCoord (MSG_BROADCAST, org2_z);
11         WriteCoord (MSG_BROADCAST, 0);          // SeienAbunae: groan... Useless clutter
12         WriteCoord (MSG_BROADCAST, 0);
13         WriteCoord (MSG_BROADCAST, 0);
14         WriteByte (MSG_BROADCAST, 155);
15
16         self.event_damage = SUB_Null;
17         if (self.movetype == MOVETYPE_BOUNCE)
18                 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"), IT_ELECTRO);
19         else
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"), IT_ELECTRO);
21         sound (self, CHAN_BODY, "weapons/electro_impact.wav", 1, ATTN_NORM);
22
23         remove (self);
24 }
25
26 void W_Plasma_Explode_Combo (void) {
27         vector org2;
28
29         org2 = findbetterlocation (self.origin, 8);
30         te_spikequad(self.origin);
31
32         sound (self, CHAN_BODY, "weapons/electro_impact_combo.wav", 1, ATTN_NORM);
33
34         self.event_damage = SUB_Null;
35         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"), IT_ELECTRO);
36         te_explosionrgb(org2, '0.5 0.5 1');
37         remove (self);
38 }
39
40 void W_Plasma_Touch (void)
41 {
42         entity o;
43         if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
44         {
45                 sound (self, CHAN_BODY, "misc/null.wav", 1, ATTN_NORM);
46                 remove(self);
47                 return;
48         }
49         if (other.takedamage == DAMAGE_AIM) {
50                 o = self.owner;
51                 W_Plasma_Explode ();
52                 if(other.classname == "player")
53                         if(IsDifferentTeam(o, other))
54                                 if(IsFlying(other))
55                                         announce(o, "announcer/male/electrobitch.ogg");
56         } else {
57                 sound (self, CHAN_IMPACT, "weapons/electro_bounce.wav", 1, ATTN_NORM);
58         }
59 }
60
61 void W_Plasma_TouchExplode (void)
62 {
63         entity o;
64         if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
65         {
66                 sound (self, CHAN_BODY, "misc/null.wav", 1, ATTN_NORM);
67                 remove(self);
68                 return;
69         }
70         o = self.owner;
71         W_Plasma_Explode ();
72         if(other.takedamage == DAMAGE_AIM)
73                 if(other.classname == "player")
74                         if(IsDifferentTeam(o, other))
75                                 if(IsFlying(other))
76                                         announce(o, "announcer/male/electrobitch.ogg");
77 }
78
79 void W_Plasma_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
80 {
81         self.health = self.health - damage;
82         if (self.health <= 0)
83         {
84                 self.takedamage = DAMAGE_NO;
85                 self.nextthink = time;
86                 if (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim")
87                 {
88                         // change owner to whoever caused the combo explosion
89                         self.owner = inflictor.owner;
90                         self.classname = "plasma_chain";
91                         self.think = W_Plasma_Explode_Combo;
92                 }
93                 else
94                         self.think = W_Plasma_Explode;
95         }
96 }
97
98 void() W_Electro_Attack
99 {
100         local entity proj;
101
102         W_SetupShot (self, '11 8 -8', FALSE, 2, "weapons/electro_fire.wav");
103
104         pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg + v_forward * 8, v_forward * 1000, 1);
105
106         proj = spawn ();
107         proj.classname = "plasma_prim";
108         proj.owner = self;
109         proj.bot_dodge = TRUE;
110         proj.bot_dodgerating = cvar("g_balance_electro_primary_damage");
111         proj.think = W_Plasma_Explode;
112         proj.nextthink = time + cvar("g_balance_electro_primary_lifetime");
113         proj.solid = SOLID_BBOX;
114         setorigin(proj, w_shotorg);
115
116         if (cvar("g_use_ammunition"))
117                 self.ammo_cells = self.ammo_cells - cvar("g_balance_electro_primary_ammo");
118         proj.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
119         proj.movetype = MOVETYPE_FLY;
120         proj.velocity = w_shotdir * cvar("g_balance_electro_primary_speed");
121         W_SetupProjectileVelocity(proj);
122         proj.angles = vectoangles(proj.velocity);
123         proj.touch = W_Plasma_TouchExplode;
124         proj.flags = FL_PROJECTILE;
125         setmodel(proj, "models/elaser.mdl"); // precision set above
126         setsize(proj, '0 0 0', '0 0 0');
127
128         // LordHavoc: disabled because no one likes this sound and it sometimes never stops due to packet loss
129         //sound (proj, CHAN_BODY, "weapons/electro_fly.wav", 1, ATTN_NORM);
130 }
131
132 void() W_Electro_Attack2
133 {
134         local entity proj;
135
136         W_SetupShot (self, '8 4.5 -13', FALSE, 2, "weapons/electro_fire2.wav");
137
138         pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg + v_forward * 8, v_forward * 1000, 1);
139
140         proj = spawn ();
141         proj.classname = "plasma";
142         proj.owner = self;
143         proj.think = W_Plasma_Explode;
144         proj.bot_dodge = TRUE;
145         proj.bot_dodgerating = cvar("g_balance_electro_secondary_damage");
146         proj.nextthink = time + cvar("g_balance_electro_secondary_lifetime");
147         proj.solid = SOLID_BBOX;
148         setorigin(proj, w_shotorg);
149
150         if (cvar("g_use_ammunition"))
151                 self.ammo_cells = self.ammo_cells - cvar("g_balance_electro_secondary_ammo");
152         proj.effects = EF_LOWPRECISION;
153         //proj.glow_size = 50;
154         //proj.glow_color = 45;
155         proj.movetype = MOVETYPE_BOUNCE;
156         proj.velocity = (v_forward + randomvec() * cvar("g_balance_electro_secondary_spread")) * cvar("g_balance_electro_secondary_speed") + v_up * cvar("g_balance_electro_secondary_speed_up");
157         W_SetupProjectileVelocity(proj);
158         proj.touch = W_Plasma_Touch;
159         setmodel(proj, "models/ebomb.mdl"); // precision set above
160         setsize(proj, '0 0 -3', '0 0 -3');
161         proj.takedamage = DAMAGE_YES;
162         proj.damageforcescale = 4;
163         proj.health = 5;
164         proj.event_damage = W_Plasma_Damage;
165         proj.flags = FL_PROJECTILE;
166
167         // LordHavoc: disabled because no one likes this sound and it sometimes never stops due to packet loss
168         //sound (proj, CHAN_BODY, "weapons/electro_fly.wav", 1, ATTN_NORM);
169 }
170
171 .float bot_secondary_electromooth;
172 float(float req) w_electro =
173 {
174         if (req == WR_AIM)
175         {
176                 self.button0=FALSE;
177                 self.button3=FALSE;
178                 if(vlen(self.origin-self.enemy.origin) > 1000)
179                         self.bot_secondary_electromooth = 0;
180                 if(self.bot_secondary_electromooth == 0)
181                 {
182                         if(bot_aim(cvar("g_balance_electro_primary_speed"), 0, cvar("g_balance_electro_primary_lifetime"), FALSE))
183                         {
184                                 self.button0 = TRUE;
185                                 if(random() < 0.01) self.bot_secondary_electromooth = 1;
186                         }
187                 }
188                 else
189                 {
190                         if(bot_aim(cvar("g_balance_electro_secondary_speed"), cvar("g_balance_grenadelauncher_secondary_speed_up"), cvar("g_balance_electro_secondary_lifetime"), TRUE))
191                         {
192                                 self.button3 = TRUE;
193                                 if(random() < 0.03) self.bot_secondary_electromooth = 0;
194                         }
195                 }
196         }
197         else if (req == WR_THINK)
198         {
199                 if (self.button0)
200                 if (weapon_prepareattack(0, cvar("g_balance_electro_primary_refire")))
201                 {
202                         W_Electro_Attack();
203                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
204                 }
205                 if (self.button3)
206                 if (weapon_prepareattack(1, cvar("g_balance_electro_secondary_refire")))
207                 {
208                         W_Electro_Attack2();
209                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_secondary_animtime"), w_ready);
210                 }
211         }
212         else if (req == WR_PRECACHE)
213         {
214                 precache_model ("models/ebomb.mdl");
215                 precache_model ("models/elaser.mdl");
216                 precache_model ("models/weapons/g_electro.md3");
217                 precache_model ("models/weapons/v_electro.md3");
218                 precache_model ("models/weapons/w_electro.zym");
219                 precache_sound ("weapons/electro_bounce.wav");
220                 precache_sound ("weapons/electro_fire.wav");
221                 precache_sound ("weapons/electro_fire2.wav");
222                 precache_sound ("weapons/electro_fly.wav");
223                 precache_sound ("weapons/electro_impact.wav");
224                 precache_sound ("weapons/electro_impact_combo.wav");
225         }
226         else if (req == WR_SETUP)
227                 weapon_setup(WEP_ELECTRO, "electro", IT_CELLS);
228         else if (req == WR_CHECKAMMO1)
229                 return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
230         else if (req == WR_CHECKAMMO2)
231                 return self.ammo_cells >= cvar("g_balance_electro_secondary_ammo");
232         else if (req == WR_REGISTER)
233                 weapon_register(WEP_ELECTRO, min(cvar("g_balance_electro_primary_ammo"), cvar("g_balance_electro_secondary_ammo")));
234         return TRUE;
235 };