]> icculus.org git repositories - divverent/nexuiz.git/blob - attic/TeamNexuiz/game/gamec/ctf.c
moved navnodeedit & TeamNexuiz to attic
[divverent/nexuiz.git] / attic / TeamNexuiz / game / gamec / ctf.c
1 \r
2 .entity flagcarried;\r
3 \r
4 float FLAGSCORE_PICKUP        =  1;\r
5 float FLAGSCORE_RETURN        =  5; // returned by owner team\r
6 float FLAGSCORE_RETURNROGUE   = 10; // returned by rogue team\r
7 float FLAGSCORE_CAPTURE       =  5;\r
8 float FLAGSCORE_CAPTURE_TEAM  = 20;\r
9 \r
10 float FLAG_BASE = 1;\r
11 float FLAG_CARRY = 2;\r
12 float FLAG_DROPPED = 3;\r
13 \r
14 void() FlagThink;\r
15 void() FlagTouch;\r
16 \r
17 void() place_flag =\r
18 {\r
19         self.mdl = self.model;\r
20         self.flags = FL_ITEM;\r
21         self.solid = SOLID_TRIGGER;\r
22         self.movetype = MOVETYPE_TOSS;\r
23         self.velocity = '0 0 0';\r
24         self.origin_z = self.origin_z + 6;\r
25         self.think = FlagThink;\r
26         self.touch = FlagTouch;\r
27         self.nextthink = time + 0.1;\r
28         self.cnt = FLAG_BASE;\r
29         self.mangle = self.angles;\r
30         self.effects = self.effects | EF_DIMLIGHT;\r
31         if (!droptofloor(0, 0))\r
32         {\r
33                 dprint("Flag fell out of level at ", vtos(self.origin), "\n");\r
34                 remove(self);\r
35                 return;\r
36         }\r
37         self.oldorigin = self.origin;\r
38 };\r
39 \r
40 void(entity e) RegenFlag =\r
41 {\r
42         e.movetype = MOVETYPE_TOSS;\r
43         e.solid = SOLID_TRIGGER;\r
44         // TODO: play a sound here\r
45         sound (e, CHAN_AUTO, self.noise3, 1, ATTN_NONE);\r
46         setorigin(e, e.oldorigin);\r
47         e.angles = e.mangle;\r
48         e.cnt = FLAG_BASE;\r
49         e.owner = world;\r
50         e.flags = FL_ITEM; // clear FL_ONGROUND and any other junk\r
51 };\r
52 \r
53 void(entity e) ReturnFlag =\r
54 {\r
55         if (e.owner)\r
56         if (e.owner.flagcarried == e)\r
57                 e.owner.flagcarried = world;\r
58         e.owner = world;\r
59         RegenFlag(e);\r
60 };\r
61 \r
62 /*void(entity e) DropFlag =                     // Gold - using TF function for this one :x\r
63 {\r
64         local entity p;\r
65 \r
66         if (!e.owner)\r
67         {\r
68                 dprint("FLAG: drop - no owner?!?!\n");\r
69                 return;\r
70         }\r
71         p = e.owner;\r
72         if (p.flagcarried != e)\r
73         {\r
74                 dprint("FLAG: drop - owner is not carrying this flag??\n");\r
75                 return;\r
76         }\r
77         bprint(p.netname);\r
78         if (e.team == 5)\r
79                 bprint(" lost the RED flag\n");\r
80         else\r
81                 bprint(" lost the BLUE flag\n");\r
82         if (p.flagcarried == e)\r
83                 p.flagcarried = world;\r
84         e.owner = world;\r
85 \r
86         e.flags = FL_ITEM; // clear FL_ONGROUND and any other junk\r
87         e.solid = SOLID_TRIGGER;\r
88         e.movetype = MOVETYPE_TOSS;\r
89         // setsize(e, '-16 -16 0', '16 16 74');\r
90         setorigin(e, p.origin - '0 0 24');\r
91         e.cnt = FLAG_DROPPED;\r
92         e.velocity = '0 0 300';\r
93         e.pain_finished = time + 30;\r
94 };*/\r
95 \r
96 void() FlagThink =\r
97 {\r
98         local entity e;\r
99         local vector v;\r
100         local float f;\r
101 \r
102         self.nextthink = time + 0.1;\r
103 \r
104         if (self.cnt == FLAG_BASE)\r
105                 return;\r
106 \r
107         if (self.cnt == FLAG_DROPPED)\r
108         {\r
109                 if (time > self.pain_finished)\r
110                 {\r
111                         if (self.team == 5)\r
112                                 bprint("The RED flag has returned to base\n");\r
113                         else\r
114                                 bprint("The BLUE flag has returned to base\n");\r
115                         ReturnFlag(self);\r
116                 }\r
117                 return;\r
118         }\r
119 \r
120         e = self.owner;\r
121         if (e.classname != "player" || (e.deadflag) || (e.flagcarried != self))\r
122         {\r
123                 DropFlag(self);\r
124                 return;\r
125         }\r
126 \r
127         // borrowed from threewave CTF, because it would be way too much work\r
128 \r
129         makevectors (e.angles);\r
130         v = v_forward;\r
131         v_z = 0 - v_z; // reverse z\r
132 \r
133         f = 14;\r
134         /*\r
135         if (e.frame >= 29 && e.frame <= 40)\r
136         {\r
137                 if (e.frame >= 29 && e.frame <= 34)\r
138                 {\r
139                         //axpain\r
140                         if      (e.frame == 29) f = f + 2;\r
141                         else if (e.frame == 30) f = f + 8;\r
142                         else if (e.frame == 31) f = f + 12;\r
143                         else if (e.frame == 32) f = f + 11;\r
144                         else if (e.frame == 33) f = f + 10;\r
145                         else if (e.frame == 34) f = f + 4;\r
146                 }\r
147                 else if (e.frame >= 35 && e.frame <= 40)\r
148                 {\r
149                         // pain\r
150                         if      (e.frame == 35) f = f + 2;\r
151                         else if (e.frame == 36) f = f + 10;\r
152                         else if (e.frame == 37) f = f + 10;\r
153                         else if (e.frame == 38) f = f + 8;\r
154                         else if (e.frame == 39) f = f + 4;\r
155                         else if (e.frame == 40) f = f + 2;\r
156                 }\r
157         }\r
158         else if (e.frame >= 103 && e.frame <= 118)\r
159         {\r
160                 if      (e.frame >= 103 && e.frame <= 104) f = f + 6;  //nailattack\r
161                 else if (e.frame >= 105 && e.frame <= 106) f = f + 6;  //light\r
162                 else if (e.frame >= 107 && e.frame <= 112) f = f + 7;  //rocketattack\r
163                 else if (e.frame >= 112 && e.frame <= 118) f = f + 7;  //shotattack\r
164         }\r
165         */\r
166         self.angles = e.angles + '0 0 -45';\r
167         setorigin (self, e.origin + '0 0 -16' - f*v + v_right * 22);\r
168         self.nextthink = time + 0.01;\r
169 };\r
170 \r
171 float   flagcaptimerecord;\r
172 .float  flagpickuptime;\r
173 \r
174 void() FlagTouch =\r
175 {\r
176         local float t;\r
177         local entity head;\r
178         if (other.classname != "player")\r
179                 return;\r
180         if (other.health < 1) // ignore dead players\r
181                 return;\r
182 \r
183         if (self.cnt == FLAG_CARRY)\r
184                 return;\r
185 \r
186         if (self.cnt == FLAG_BASE)\r
187         if (other.team == self.team)\r
188         if (other.flagcarried) // he's got a flag\r
189         if (other.flagcarried.team != self.team) // capture\r
190         {\r
191                 t = time - other.flagpickuptime;\r
192                 if (flagcaptimerecord == 0)\r
193                 {\r
194                         if (other.flagcarried.team == 5)\r
195                                 bprint(other.netname, " captured the RED flag in ", ftos(t), " seconds\n");\r
196                         else\r
197                                 bprint(other.netname, " captured the BLUE flag in ", ftos(t), " seconds\n");\r
198                         flagcaptimerecord = t;\r
199                 }\r
200                 else if (t < flagcaptimerecord)\r
201                 {\r
202                         if (other.flagcarried.team == 5)\r
203                                 bprint(other.netname, " captured the RED flag in ", ftos(t), ", breaking the previous record of", ftos(flagcaptimerecord), " seconds\n");\r
204                         else\r
205                                 bprint(other.netname, " captured the BLUE flag in ", ftos(t), ", breaking the previous record of", ftos(flagcaptimerecord), " seconds\n");\r
206                         flagcaptimerecord = t;\r
207                 }\r
208                 else\r
209                 {\r
210                         if (other.flagcarried.team == 5)\r
211                                 bprint(other.netname, " captured the RED flag in ", ftos(t), ", failing to break the previous record of", ftos(flagcaptimerecord), " seconds\n");\r
212                         else\r
213                                 bprint(other.netname, " captured the BLUE flag in ", ftos(t), ", failing to break the previous record of", ftos(flagcaptimerecord), " seconds\n");\r
214                 }\r
215                 other.frags = other.frags + FLAGSCORE_CAPTURE;\r
216                 head = find(head, classname, "player");\r
217                 while (head)\r
218                 {\r
219                         if (head.team == self.goalentity.team)\r
220                                 head.frags = head.frags + FLAGSCORE_CAPTURE_TEAM;\r
221                         head = find(head, classname, "player");\r
222                 }\r
223                 sound (self, CHAN_AUTO, self.noise2, 1, ATTN_NONE);\r
224                 ReturnFlag(other.flagcarried);\r
225         }\r
226         if (self.cnt == FLAG_BASE)\r
227         if (other.team == 5 || other.team == 14) // only red and blue team can steal flags\r
228         if (other.team != self.team)\r
229         if (!other.flagcarried)\r
230         {\r
231                 // pick up\r
232                 other.flagpickuptime = time; // used for timing runs\r
233                 self.solid = SOLID_NOT;\r
234                 setorigin(self, self.origin); // relink\r
235                 self.owner = other;\r
236                 other.flagcarried = self;\r
237                 self.cnt = FLAG_CARRY;\r
238                 if (other.flagcarried.team == 5)\r
239                         bprint(other.netname, " got the RED flag\n");\r
240                 else\r
241                         bprint(other.netname, " got the BLUE flag\n");\r
242                 other.frags = other.frags + FLAGSCORE_PICKUP;\r
243                 sound (self, CHAN_AUTO, self.noise, 1, ATTN_NONE);\r
244                 return;\r
245         }\r
246 \r
247         if (self.cnt == FLAG_DROPPED)\r
248         {\r
249                 self.flags = FL_ITEM; // clear FL_ONGROUND and any other junk\r
250                 if (other.team == self.team || (other.team != 5 && other.team != 14))\r
251                 {\r
252                         // return flag\r
253                         if (self.team == 5)\r
254                                 bprint(other.netname, " returned the RED flag\n");\r
255                         else\r
256                                 bprint(other.netname, " returned the BLUE flag\n");\r
257                         if (other.team == 5 || other.team == 14)\r
258                                 other.frags = other.frags + FLAGSCORE_RETURN;\r
259                         else\r
260                                 other.frags = other.frags + FLAGSCORE_RETURNROGUE;\r
261                         sound (self, CHAN_AUTO, self.noise1, 1, ATTN_NONE);\r
262                         ReturnFlag(self);\r
263                 }\r
264                 else if (!other.flagcarried)\r
265                 {\r
266                         // pick up\r
267                         other.flagpickuptime = time; // used for timing runs\r
268                         self.solid = SOLID_NOT;\r
269                         setorigin(self, self.origin); // relink\r
270                         self.owner = other;\r
271                         other.flagcarried = self;\r
272                         self.cnt = FLAG_CARRY;\r
273                         if (self.team == 5)\r
274                                 bprint(other.netname, " picked up the RED flag\n");\r
275                         else\r
276                                 bprint(other.netname, " picked up the BLUE flag\n");\r
277                         other.frags = other.frags + FLAGSCORE_PICKUP;\r
278                         sound (self, CHAN_AUTO, self.noise, 1, ATTN_NONE);\r
279                 }\r
280         }\r
281 };\r
282 \r
283 /*QUAKED info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24)\r
284 CTF Starting point for a player\r
285 in team one (Red).\r
286 \r
287 Keys:\r
288 "angle"\r
289  viewing angle when spawning\r
290 */\r
291 //void() info_player_team1 = {};//self.team = 4;self.classname = "info_player_start";info_player_start();};\r
292 \r
293 /*QUAKED info_player_team2 (1 0 0) (-16 -16 -24) (16 16 24)\r
294 CTF Starting point for a player in\r
295 team two (Blue).\r
296 \r
297 Keys:\r
298 "angle"\r
299  viewing angle when spawning\r
300 */\r
301 //void() info_player_team2 = {};//self.team = 13;self.classname = "info_player_start";info_player_start();};\r
302 \r
303 /*QUAKED item_flag_team1 (0 0.5 0.8) (-48 -48 -24) (48 48 64)\r
304 CTF flag for team one (Red).\r
305 Multiple are allowed.\r
306 \r
307 Keys:\r
308 "angle"\r
309  Angle the flag will point\r
310 (minus 90 degrees)\r
311 "model"\r
312  model to use, note this needs red and blue as skins 0 and 1\r
313  (default models/ctf/flag.md3)\r
314 "noise"\r
315  sound played when flag is picked up\r
316  (default ctf/take.wav)\r
317 "noise1"\r
318  sound played when flag is returned by a teammate\r
319  (default ctf/return.wav)\r
320 "noise2"\r
321  sound played when flag is captured\r
322  (default ctf/capture.wav)\r
323 "noise3"\r
324  sound played when flag is lost in the field and respawns itself\r
325  (default ctf/respawn.wav)\r
326 */\r
327 \r
328 /*void() item_flag_team1 =\r
329 {\r
330         if (!cvar("g_ctf"))\r
331                 return;\r
332         self.team = 5; // color 4 team (red)\r
333         self.items = IT_KEY2; // gold key (redish enough)\r
334         self.skin = 0;\r
335         if (!self.model)\r
336                 self.model = "models/ctf/flag.md3";\r
337         if (!self.noise)\r
338                 self.noise = "ctf/take.wav";\r
339         if (!self.noise1)\r
340                 self.noise1 = "ctf/return.wav";\r
341         if (!self.noise2)\r
342                 self.noise2 = "ctf/capture.wav";\r
343         if (!self.noise3)\r
344                 self.noise3 = "ctf/respawn.wav";\r
345         precache_model (self.model);\r
346         setmodel (self, self.model);\r
347         precache_sound (self.noise);\r
348         precache_sound (self.noise1);\r
349         precache_sound (self.noise2);\r
350         precache_sound (self.noise3);\r
351         setsize(self, '-16 -16 0', '16 16 74');\r
352         self.nextthink = time + 0.2; // start after doors etc\r
353         self.think = place_flag;\r
354 };\r
355 */\r
356 \r
357 /*QUAKED item_flag_team2 (0 0.5 0.8) (-48 -48 -24) (48 48 64)\r
358 CTF flag for team two (Blue).\r
359 Multiple are allowed.\r
360 \r
361 Keys:\r
362 "angle"\r
363  Angle the flag will point\r
364 (minus 90 degrees)\r
365 \r
366 */\r
367 \r
368 /*\r
369 void() item_flag_team2 =\r
370 {\r
371         if (!cvar("g_ctf"))\r
372                 return;\r
373         self.team = 14; // color 13 team (blue)\r
374         self.items = IT_KEY1; // silver key (bluish enough)\r
375         self.skin = 1;\r
376         if (!self.model)\r
377                 self.model = "models/ctf/flag.md3";\r
378         if (!self.noise)\r
379                 self.noise = "ctf/take.wav";\r
380         if (!self.noise1)\r
381                 self.noise1 = "ctf/return.wav";\r
382         if (!self.noise2)\r
383                 self.noise2 = "ctf/capture.wav";\r
384         if (!self.noise3)\r
385                 self.noise3 = "ctf/respawn.wav";\r
386         precache_model (self.model);\r
387         setmodel (self, self.model);\r
388         precache_sound (self.noise);\r
389         precache_sound (self.noise1);\r
390         precache_sound (self.noise2);\r
391         precache_sound (self.noise3);\r
392         setsize(self, '-16 -16 0', '16 16 74');\r
393         self.nextthink = time + 0.2; // start after doors etc\r
394         self.think = place_flag;\r
395 };\r
396 */\r