]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/system/system_damage.qc
Get rid of g_turrets_unit_ewheel_std_target_range_fire, fix g_turrets_targetscan_mind...
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / system / system_damage.qc
1 /*\r
2 * Trow a turret gib\r
3 */\r
4 void turret_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)\r
5 {\r
6     self.velocity += vforce;\r
7 }\r
8 \r
9 void turret_trowgib(\r
10     vector v_from, vector v_to, vector v_colormod,\r
11     string smodel,\r
12     float f_lifetime, float f_fadetime, float b_burn)\r
13 {\r
14     local entity gib;\r
15     local entity burn;\r
16 \r
17     gib = spawn();\r
18 \r
19     gib.classname = "turret_gib";\r
20     setmodel(gib,smodel);\r
21     setorigin(gib,v_from);\r
22     SUB_SetFade(gib,time + f_lifetime,2);\r
23 \r
24     gib.solid              = SOLID_BBOX;\r
25 \r
26     gib.movetype           = MOVETYPE_BOUNCE;\r
27     gib.takedamage         = DAMAGE_YES;\r
28     gib.event_damage       = turret_gib_damage;\r
29     gib.health             = -1;\r
30     gib.effects            = EF_LOWPRECISION;\r
31     gib.flags              = FL_NOTARGET;\r
32     gib.colormod           = v_colormod;\r
33     gib.velocity           = v_to;\r
34 \r
35     if (b_burn)\r
36     {\r
37         burn = spawn();\r
38         burn.effects        = EF_LOWPRECISION;//|EF_FLAME;\r
39         setattachment(burn,gib,"");\r
40         setorigin(burn,(gib.mins + gib.maxs) * 0.5);\r
41         SUB_SetFade(burn,time + (f_lifetime * 0.5) ,2);\r
42     }\r
43 }\r
44 \r
45 void turret_gib_boom()\r
46 {\r
47     entity gib;\r
48     float i;\r
49     string s;\r
50 \r
51     for (i = 1; i < 5; i = i +1)\r
52     {\r
53         gib = spawn();\r
54         gib.classname = "turret_gib";\r
55 \r
56         s = strcat("models/turrets/head-gib",ftos(i));\r
57         s = strcat(s,".md3");\r
58         // bprint("s:",s,"\n");\r
59         setmodel(gib,s);\r
60 \r
61         setorigin(gib,self.origin);\r
62 \r
63         SUB_SetFade(gib,time + 5,2);\r
64 \r
65         gib.solid              = SOLID_BBOX;\r
66 \r
67         gib.movetype           = MOVETYPE_BOUNCE;\r
68         gib.gravity            = 0.5;\r
69         gib.damageforcescale   = 2;\r
70         gib.takedamage         = DAMAGE_YES;\r
71         gib.event_damage       = turret_gib_damage;\r
72         gib.health             = -1;\r
73         gib.effects            = EF_LOWPRECISION;\r
74         gib.flags              = FL_NOTARGET;\r
75         gib.velocity           = self.velocity + (randomvec() * 700);\r
76         gib.avelocity          = randomvec() * 64;\r
77     }\r
78 \r
79     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);\r
80     WriteByte (MSG_BROADCAST, 78);\r
81     WriteCoord (MSG_BROADCAST, self.origin_x);\r
82     WriteCoord (MSG_BROADCAST, self.origin_y);\r
83     WriteCoord (MSG_BROADCAST, self.origin_z);\r
84 \r
85     remove(self);\r
86 }\r
87 \r
88 void turret_trowgib2(\r
89     vector v_from, vector v_to, vector v_colormod,\r
90     entity e_mimic, float boomtime)\r
91 {\r
92     entity gib;\r
93 \r
94     gib = spawn();\r
95 \r
96     gib.classname = "turret_gib";\r
97     setmodel(gib,e_mimic.model);\r
98     setorigin(gib,v_from);\r
99 \r
100     gib.solid              = SOLID_BBOX;\r
101 \r
102     gib.movetype           = MOVETYPE_BOUNCE;\r
103     gib.gravity            = 0.75;\r
104     gib.damageforcescale   = 2;\r
105     gib.takedamage         = DAMAGE_YES;\r
106     gib.event_damage       = turret_gib_damage;\r
107     gib.health             = -1;\r
108     gib.effects            = EF_LOWPRECISION;\r
109     gib.flags              = FL_NOTARGET;\r
110     gib.colormod           = v_colormod;\r
111     gib.velocity           = v_to;\r
112     gib.avelocity          = randomvec() * 32;\r
113     gib.think              = turret_gib_boom;\r
114     gib.nextthink          = boomtime;\r
115     //gib.effects            = EF_FLAME;\r
116 \r
117 \r
118 }\r
119 /*\r
120 * Spawn a boom, trow fake bits arround\r
121 * and hide the real ones.\r
122 */\r
123 void turret_stdproc_die()\r
124 {\r
125     vector org2;\r
126     vector t_dir;\r
127 \r
128     self.deadflag           = DEAD_DEAD;\r
129     self.tur_head.deadflag  = self.deadflag;\r
130 \r
131     sound (self, CHAN_PLAYER, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);\r
132     org2 = self.origin + '0 0 40';\r
133 \r
134 // Explotion grafix\r
135     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);\r
136     WriteByte (MSG_BROADCAST, 78);\r
137     WriteCoord (MSG_BROADCAST, org2_x);\r
138     WriteCoord (MSG_BROADCAST, org2_y);\r
139     WriteCoord (MSG_BROADCAST, org2_z);\r
140 \r
141 // Unsolidify and hide real parts\r
142     self.solid              = SOLID_NOT;\r
143     self.tur_head.solid     = self.solid;\r
144 \r
145     self.alpha             = -1;\r
146     self.tur_head.alpha    = self.alpha;\r
147     self.customizeentityforclient = SUB_False;
148     self.tur_head.customizeentityforclient = SUB_False;
149 \r
150     self.event_damage           = SUB_Null;\r
151     self.tur_head.event_damage  = SUB_Null;\r
152     self.takedamage             = DAMAGE_NO;\r
153     self.tur_head.takedamage    = self.takedamage;\r
154 \r
155     self.effects            = 0;\r
156     self.tur_head.effects   = self.effects;\r
157     self.health             = 0;\r
158 \r
159 // Trow fake parts arround\r
160     // base\r
161     if not(self.damage_flags & TFL_DMG_DEATH_NOGIBS)\r
162     {\r
163         makevectors(self.angles);\r
164         if (random() > 0.5)\r
165         {\r
166             turret_trowgib(self.origin, '0 0 0','1 1 1',"models/turrets/base-gib2.md3",min(self.respawntime,20),1,1);\r
167             t_dir = (v_up * 700) + (randomvec() * 300);\r
168             turret_trowgib(self.origin, t_dir,'1 1 1',"models/turrets/base-gib3.md3",min(self.respawntime,10),1,1);\r
169             t_dir = (v_up * 700) + (randomvec() * 300);\r
170             turret_trowgib(self.origin, t_dir,'1 1 1',"models/turrets/base-gib4.md3",min(self.respawntime,10),1,1);\r
171         }\r
172         else\r
173         {\r
174             turret_trowgib(self.origin, '0 0 0','1 1 1',"models/turrets/base-gib1.md3",min(self.respawntime,20),1,1);\r
175         }\r
176 \r
177         // Blow the top part up into the air\r
178         turret_trowgib2( self.origin + (v_up * 50),\r
179                          v_up * 150 + randomvec() * 50,\r
180                          '0.2 0.2 0.2',\r
181                          self.tur_head,time + 0.5 + (random() * 0.5));\r
182     }\r
183 \r
184 // Go boom\r
185     //RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,DEATH_TURRET,world);\r
186 \r
187     if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)\r
188     {\r
189         if (self.turret_diehook)\r
190             self.turret_diehook();\r
191 \r
192         remove(self.tur_head);\r
193         remove(self);\r
194     }\r
195     else\r
196     {\r
197     // Setup respawn\r
198         self.nextthink      = time + self.respawntime;\r
199         //self.think          = self.turret_spawnfunc;\r
200         self.think          = turret_stdproc_respawn;\r
201         if (self.turret_diehook)\r
202             self.turret_diehook();\r
203     }\r
204 \r
205 }\r
206 \r
207 void turret_stdproc_respawn()\r
208 {\r
209     // Make sure all parts belong to the same team since\r
210     // this function doubles as "teamchange" function.\r
211 \r
212     self.tur_head.team = self.team;\r
213 \r
214     /*\r
215     COLOR_TEAM1       = 4;  // red\r
216     COLOR_TEAM2       = 13; // blue\r
217     COLOR_TEAM3       = 12; // yellow\r
218     COLOR_TEAM4       = 9; // pink\r
219     */\r
220 \r
221         self.colormod = '0 0 0';\r
222 \r
223         switch(self.team)\r
224         {\r
225         case COLOR_TEAM1: // Red\r
226             self.colormod = '1.4 0.8 0.8';\r
227             break;\r
228 \r
229         case COLOR_TEAM2: // Blue\r
230             self.colormod = '0.8 0.8 1.4';\r
231             break;\r
232 \r
233         case COLOR_TEAM3: // Yellow\r
234             self.colormod = '1.4 1.4 0.6';\r
235             break;\r
236 \r
237         case COLOR_TEAM4: // Pink\r
238             self.colormod = '1.4 0.6 1.4';\r
239             break;\r
240         }\r
241 \r
242     self.deadflag           = DEAD_NO;\r
243     self.tur_head.deadflag  = self.deadflag;\r
244     self.effects            = 0;\r
245     self.tur_head.effects   = self.effects;\r
246 \r
247     self.solid              = SOLID_BBOX;\r
248     self.tur_head.solid     = self.solid;\r
249 \r
250     self.alpha = 1;\r
251     self.tur_head.alpha     = self.alpha;
252     self.customizeentityforclient = SUB_True;
253     self.tur_head.customizeentityforclient = SUB_True;
254 \r
255 \r
256     self.takedamage = DAMAGE_AIM;\r
257     self.tur_head.takedamage    = self.takedamage;\r
258 \r
259     self.event_damage           = turret_stdproc_damage;\r
260     self.tur_head.event_damage  = self.event_damage;\r
261 \r
262     self.avelocity              = '0 0 0';\r
263     self.tur_head.avelocity     = self.avelocity;\r
264     self.tur_head.angles        = self.idle_aim;\r
265     self.health                 = self.tur_health;\r
266     self.tur_head.health         = self.tur_health;\r
267 \r
268     self.enemy                  = world;\r
269     self.volly_counter          = self.shot_volly;\r
270     self.ammo                   = self.ammo_max;\r
271 \r
272     self.nextthink  = time + self.ticrate;\r
273     self.think      = turret_think;\r
274 \r
275     if (self.turret_respawnhook)\r
276         self.turret_respawnhook();\r
277 \r
278 }\r
279 \r
280 /*\r
281 * Standard damage proc.\r
282 */\r
283 void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)\r
284 {\r
285     entity baseent;\r
286 \r
287     if (self.owner)\r
288         baseent = self.owner;\r
289     else\r
290         baseent = self;\r
291 \r
292     // Enougth allready!\r
293     if (self.health <= 0)\r
294         return;\r
295 \r
296     // Inactive turrets take no damage. (hm..)\r
297     if not (baseent.tur_active)\r
298         return;\r
299 \r
300     if (teamplay != 0)\r
301     if (self.team == attacker.team)\r
302     {\r
303         // This does not happen anymore. Re-enable if you fix that.\r
304         //if(attacker.flags & FL_CLIENT)\r
305         if(clienttype(attacker) == CLIENTTYPE_REAL)\r
306             sprint(attacker, "\{1}Turret tells you: I'm on your team!\n");\r
307 \r
308         if(cvar("g_friendlyfire"))\r
309             damage = damage * cvar("g_friendlyfire");\r
310         else\r
311             return;\r
312     }\r
313 \r
314     self.health = self.health - damage;\r
315 \r
316     // thorw head slightly off aim when hit?\r
317     if (self.classname == "turret_head")\r
318         if (baseent.damage_flags & TFL_DMG_HEADSHAKE)\r
319         {\r
320             //baseent.tur_aimoff_x += (random() * damage);\r
321             //baseent.tur_aimoff_y += ((random()*0.75) * damage);\r
322             self.angles_x = self.angles_x + (-0.5 + random()) * damage;\r
323             self.angles_y = self.angles_y + (-0.5 + random()) * damage;\r
324         }\r
325 \r
326     if (baseent.turrcaps_flags & TFL_TURRCAPS_MOVE)\r
327         baseent.velocity = baseent.velocity + vforce;\r
328 \r
329     // FIXME: Better damage feedback\r
330     // Start burning when we have 10% or less health left\r
331     //if (self.health < (self.tur_health * 0.1))\r
332     //    self.effects = EF_FLAME;\r
333 \r
334     if (self.health <= 0)\r
335     {\r
336         baseent.event_damage           = SUB_Null;\r
337         baseent.tur_head.event_damage  = SUB_Null;\r
338         baseent.takedamage             = DAMAGE_NO;\r
339         baseent.tur_head.takedamage    = baseent.takedamage;\r
340         baseent.nextthink = time;\r
341         baseent.think = turret_stdproc_die;\r
342     }\r
343 }\r