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