]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/gamec/havocbot_roles.c
Ignoring team balance settings for campaign mode
[divverent/nexuiz.git] / data / qcsrc / server / gamec / havocbot_roles.c
1
2 //.float havocbot_role_timeout;
3 .float bot_strategytime;
4 .void() havocbot_role;
5
6 void(float ratingscale, vector org, float sradius) havocbot_goalrating_items =
7 {
8         local entity head;
9         local float t;
10         head = findchainfloat(bot_pickup, TRUE);
11         while (head)
12         {
13                 if (head.solid) // must be possible to pick up (respawning items don't count)
14                 if (vlen(head.origin - org) < sradius)
15                 {
16                         // debugging
17                         //if (!head.bot_pickupevalfunc || head.model == "")
18                         //      eprint(head);
19                         // get the value of the item
20                         t = head.bot_pickupevalfunc(self, head) * 0.0001;
21                         if (t > 0)
22                                 navigation_routerating(head, t * ratingscale);
23                 }
24                 head = head.chain;
25         }
26 };
27
28 void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers =
29 {
30         local entity head;
31         local float t, noteam;
32         ratingscale = ratingscale * 1200;
33         noteam = self.team == 0 || teamplay == 0;
34         head = findchain(classname, "player");
35         while (head)
36         {
37                 if (head.health > 0)
38                 if (head.team != self.team || noteam)
39                 if (vlen(head.origin - org) < sradius)
40                 {
41                         t = head.frags + 25;
42                         if (t < 1)
43                                 t = 1;
44                         t = t / (head.health + head.armortype * head.armorvalue);
45                         if (t > 0)
46                                 navigation_routerating(head, t * ratingscale);
47                 }
48                 head = head.chain;
49         }
50 };
51
52 /*
53 void(float ratingscale, vector org, float sradius) havocbot_goalrating_ctf_carrieritems =
54 {
55         local entity head;
56         local float t;
57         head = findchainfloat(bot_pickup, TRUE);
58         while (head)
59         {
60                 // look for health and armor only
61                 if (head.solid) // must be possible to pick up (respawning items don't count)
62                 if (head.bot_pickupevalfunc == item_health_pickupeval || head.bot_pickupevalfunc == item_armor_pickupeval)
63                 if (vlen(head.origin - org) < sradius)
64                 {
65                         // debugging
66                         //if (!head.bot_pickupevalfunc || head.model == "")
67                         //      eprint(head);
68                         // get the value of the item
69                         t = head.bot_pickupevalfunc(self, head) * 0.0001;
70                         if (t > 0)
71                                 havocbot_routerating(head, t * ratingscale);
72                 }
73                 head = head.chain;
74         }
75 };
76
77 void(float ratingscale) havocbot_goalrating_ctf_ourflag =
78 {
79         local entity head;
80         if (self.team == 5) // red
81                 head = find(world, classname, "item_flag_team1"); // red flag
82         else // blue
83                 head = find(world, classname, "item_flag_team2"); // blue flag
84         havocbot_routerating(head, ratingscale);
85 };
86
87 void(float ratingscale) havocbot_goalrating_ctf_enemyflag =
88 {
89         local entity head;
90         if (self.team == 5) // red
91                 head = find(world, classname, "item_flag_team2"); // blue flag
92         else // blue
93                 head = find(world, classname, "item_flag_team1"); // red flag
94         havocbot_routerating(head, ratingscale);
95 };
96
97 void(float ratingscale) havocbot_goalrating_ctf_ourstolenflag =
98 {
99         local entity head;
100         if (self.team == 5) // red
101                 head = find(world, classname, "item_flag_team1"); // red flag
102         else // blue
103                 head = find(world, classname, "item_flag_team2"); // blue flag
104         if (head.cnt != FLAG_BASE)
105                 havocbot_routerating(head, ratingscale);
106 };
107
108 void(float ratingscale) havocbot_goalrating_ctf_droppedflags =
109 {
110         local entity redflag, blueflag;
111
112         redflag = find(world, classname, "item_flag_team1");
113         blueflag = find(world, classname, "item_flag_team2");
114
115         if (redflag == world)
116                 error("havocbot: item_flag_team1 missing\n");
117         if (blueflag == world)
118                 error("havocbot: item_flag_team2 missing\n");
119
120         if (redflag.cnt != FLAG_BASE) // red flag is carried or out in the field
121                 havocbot_routerating(redflag, ratingscale);
122         if (blueflag.cnt != FLAG_BASE) // blue flag is carried or out in the field
123                 havocbot_routerating(blueflag, ratingscale);
124 };
125
126 // CTF: (always teamplay)
127
128 //role rogue: (is this used?)
129 //pick up items and dropped flags (with big rating boost to dropped flags)
130 void() havocbot_role_ctf_rogue =
131 {
132         if (self.bot_strategytime < time)
133         {
134                 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
135                 navigation_goalrating_start();
136                 havocbot_goalrating_ctf_droppedflags(5000);
137                 //havocbot_goalrating_enemyplayers(3000, self.origin, 3000);
138                 havocbot_goalrating_items(10000, self.origin, 10000);
139                 navigation_goalrating_end();
140         }
141 }
142
143 //role flag carrier:
144 //pick up armor and health
145 //go to our flag spot
146 void() havocbot_role_ctf_carrier =
147 {
148         if (self.flagcarried == world)
149         {
150                 bprint("changing role to middle\n");
151                 self.havocbot_role = havocbot_role_ctf_middle;
152                 self.havocbot_role_timeout = 0;
153                 return;
154         }
155         if (self.bot_strategytime < time)
156         {
157                 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
158                 navigation_goalrating_start();
159                 havocbot_goalrating_ctf_ourflag(5000);
160                 havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
161                 navigation_goalrating_end();
162         }
163 };
164
165 //role offense:
166 //pick up armor and health
167 //if rockets < 25 || health < 100, change role to middle
168 //if carrying flag, change role to flag carrier
169 //if our flag taken, change role to interceptor
170 //(60-90 second timer) change role to middle
171 //go to enemy flag
172 void() havocbot_role_ctf_offense =
173 {
174         //local entity f;
175         if (self.flagcarried)
176         {
177                 bprint("changing role to carrier\n");
178                 self.havocbot_role = havocbot_role_ctf_carrier;
179                 self.havocbot_role_timeout = 0;
180                 return;
181         }
182 */
183         /*
184         // check our flag
185         if (self.team == 5) // red
186                 f = find(world, classname, "item_flag_team1");
187         else // blue
188                 f = find(world, classname, "item_flag_team2");
189         if (f.cnt != FLAG_BASE && canreach(f))
190         {
191                 bprint("changing role to interceptor\n");
192                 self.havocbot_role = havocbot_role_ctf_interceptor;
193                 self.havocbot_role_timeout = 0;
194                 return;
195         }
196         */
197 /*
198         if (!self.havocbot_role_timeout)
199                 self.havocbot_role_timeout = time + random() * 30 + 60;
200         if (Inventory_Quantity(self, "rockets") < 15 || time > self.havocbot_role_timeout)
201         {
202                 bprint("changing role to middle\n");
203                 self.havocbot_role = havocbot_role_ctf_middle;
204                 self.havocbot_role_timeout = 0;
205                 return;
206         }
207         if (self.bot_strategytime < time)
208         {
209                 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
210                 navigation_goalrating_start();
211                 havocbot_goalrating_ctf_ourstolenflag(5000);
212                 havocbot_goalrating_ctf_enemyflag(3000);
213                 havocbot_goalrating_items(10000, self.origin, 10000);
214                 navigation_goalrating_end();
215         }
216 };
217
218 //role middle:
219 //pick up items
220 //if carrying flag, change role to flag carrier
221 //if our flag taken, change role to interceptor
222 //if see flag (of either team) follow it (this has many implications)
223 //(10-20 second timer) change role to defense or offense
224 //go to least recently visited area
225 void() havocbot_role_ctf_middle =
226 {
227         if (self.flagcarried)
228         {
229                 bprint("changing role to carrier\n");
230                 self.havocbot_role = havocbot_role_ctf_carrier;
231                 self.havocbot_role_timeout = 0;
232                 return;
233         }
234 */
235         /*
236         // check our flag
237         if (self.team == 5) // red
238                 f = find(world, classname, "item_flag_team1");
239         else // blue
240                 f = find(world, classname, "item_flag_team2");
241         if (f.cnt != FLAG_BASE && canreach(f))
242         {
243                 bprint("changing role to interceptor\n");
244                 self.havocbot_role = havocbot_role_ctf_interceptor;
245                 self.havocbot_role_timeout = 0;
246                 return;
247         }
248         */
249 /*
250         if (!self.havocbot_role_timeout)
251                 self.havocbot_role_timeout = time + random() * 10 + 10;
252         if (time > self.havocbot_role_timeout)
253         if (Inventory_Quantity(self, "rockets") >= 25)
254         {
255                 if (random() < 0.5)
256                 {
257                         bprint("changing role to offense\n");
258                         self.havocbot_role = havocbot_role_ctf_offense;
259                 }
260                 else
261                 {
262                         bprint("changing role to defense\n");
263                         self.havocbot_role = havocbot_role_ctf_defense;
264                 }
265                 self.havocbot_role_timeout = 0;
266                 return;
267         }
268
269         if (self.bot_strategytime < time)
270         {
271                 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
272                 navigation_goalrating_start();
273                 havocbot_goalrating_ctf_ourstolenflag(5000);
274                 havocbot_goalrating_ctf_droppedflags(3000);
275                 //havocbot_goalrating_enemyplayers(1000, self.origin, 1000);
276                 havocbot_goalrating_items(10000, self.origin, 10000);
277                 navigation_goalrating_end();
278         }
279 };
280
281 //role defense:
282 //if rockets < 25 || health < 100, change role to middle
283 //if carrying flag, change role to flag carrier
284 //if our flag taken, change role to interceptor
285 //(30-50 second timer) change role to middle
286 //move to nearest unclaimed defense spot
287 void() havocbot_role_ctf_defense =
288 {
289         local entity f;
290         if (self.flagcarried)
291         {
292                 bprint("changing role to carrier\n");
293                 self.havocbot_role = havocbot_role_ctf_carrier;
294                 self.havocbot_role_timeout = 0;
295                 return;
296         }
297 */
298         /*
299         // check our flag
300         if (self.team == 5) // red
301                 f = find(world, classname, "item_flag_team1");
302         else // blue
303                 f = find(world, classname, "item_flag_team2");
304         if (f.cnt != FLAG_BASE && canreach(f))
305         {
306                 bprint("changing role to interceptor\n");
307                 self.havocbot_role = havocbot_role_ctf_interceptor;
308                 self.havocbot_role_timeout = 0;
309                 return;
310         }
311         */
312 /*
313         if (!self.havocbot_role_timeout)
314                 self.havocbot_role_timeout = time + random() * 20 + 30;
315         if (Inventory_Quantity(self, "rockets") < 15 || time > self.havocbot_role_timeout)
316         {
317                 bprint("changing role to middle\n");
318                 self.havocbot_role = havocbot_role_ctf_middle;
319                 self.havocbot_role_timeout = 0;
320                 return;
321         }
322         if (self.bot_strategytime < time)
323         {
324                 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
325                 navigation_goalrating_start();
326                 havocbot_goalrating_ctf_ourstolenflag(20000);
327                 havocbot_goalrating_items(10000, f.origin, 10000);
328                 navigation_goalrating_end();
329         }
330 */
331         /*
332         // FIXME: place info_ctf_defensepoint entities in CTF maps and use them
333         // change position occasionally
334         if (time > self.bot_strategytime || self.goalentity.classname != "info_ctf_defensepoint")
335         {
336                 self.bot_strategytime = time + random() * 45 + 15;
337                 self.goalentity = world;
338                 head = findchain(classname, "info_ctf_defensepoint");
339                 while (head)
340                 {
341                         if (time > head.count)
342                         {
343                                 self.goalentity = head;
344                                 head.chain = world;
345                         }
346                         head = head.chain;
347                 }
348                 // if there are no defensepoints defined, switch to middle
349                 if (self.goalentity == world)
350                 {
351                         bprint("changing role to middle\n");
352                         self.havocbot_role = havocbot_role_ctf_middle;
353                         self.havocbot_role_timeout = 0;
354                         return;
355                 }
356         }
357         // keep anyone else from taking this spot
358         if (self.goalentity != world)
359                 self.goalentity.count = time + 0.5;
360         */
361 /*
362 };
363
364 // CTF:
365 // choose a role according to the situation
366 void() havocbot_chooserole_ctf =
367 {
368         local float r;
369         if (self.team == 13)
370                 self.havocbot_role = havocbot_role_ctf_rogue;
371         else
372         {
373                 r = random() * 3;
374                 if (r < 0)
375                         self.havocbot_role = havocbot_role_ctf_offense;
376                 else if (r < 1)
377                         self.havocbot_role = havocbot_role_ctf_middle;
378                 else
379                         self.havocbot_role = havocbot_role_ctf_defense;
380         }
381 };
382 */
383
384 //DM:
385 //go to best items
386 void() havocbot_role_dm =
387 {
388         if (self.bot_strategytime < time)
389         {
390                 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
391                 navigation_goalrating_start();
392                 havocbot_goalrating_items(10000, self.origin, 10000);
393                 //havocbot_goalrating_enemyplayers(2000, self.origin, 2000);
394                 navigation_goalrating_end();
395         }
396 };
397
398 void() havocbot_chooserole_dm =
399 {
400         self.havocbot_role = havocbot_role_dm;
401 };
402
403 void() havocbot_chooserole =
404 {
405         navigation_routetogoal(world);
406         self.bot_strategytime = -1;
407         //if (cvar("g_ctf"))
408         //      havocbot_chooserole_ctf();
409         //else // assume anything else is deathmatch
410                 havocbot_chooserole_dm();
411 };
412