2 .float havocbot_role_timeout;
3 .float bot_strategytime;
6 void(float ratingscale, vector org, float sradius) havocbot_goalrating_items =
10 head = findchainfloat(bot_pickup, TRUE);
13 if (head.solid) // must be possible to pick up (respawning items don't count)
14 if (vlen(head.origin - org) < sradius)
17 //if (!head.bot_pickupevalfunc || head.model == "")
19 // get the value of the item
20 t = head.bot_pickupevalfunc(self, head) * 0.0001;
22 navigation_routerating(head, t * ratingscale);
28 void(float ratingscale, vector org, float sradius) havocbot_goalrating_waypoints =
31 head = findchain(classname, "waypoint");
34 if (vlen(head.origin - org) < sradius && vlen(head.origin - org) > 100)
35 navigation_routerating(head, ratingscale);
40 void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers =
43 local float t, noteam;
44 ratingscale = ratingscale * 1200;
45 noteam = self.team == 0 || teamplay == 0;
46 head = findchain(classname, "player");
50 if (head.team != self.team || noteam)
51 if (vlen(head.origin - org) < sradius)
56 t = t / (head.health + head.armortype * head.armorvalue);
58 navigation_routerating(head, t * ratingscale);
65 void() havocbot_role_ctf_middle;
66 void() havocbot_role_ctf_defense;
67 void() havocbot_role_ctf_offense;
69 void(float ratingscale, vector org, float sradius) havocbot_goalrating_ctf_carrieritems =
73 head = findchainfloat(bot_pickup, TRUE);
76 // look for health and armor only
77 if (head.solid) // must be possible to pick up (respawning items don't count)
78 if (head.health || head.armorvalue)
79 if (vlen(head.origin - org) < sradius)
82 //if (!head.bot_pickupevalfunc || head.model == "")
84 // get the value of the item
85 t = head.bot_pickupevalfunc(self, head) * 0.0001;
87 navigation_routerating(head, t * ratingscale);
93 void(float ratingscale) havocbot_goalrating_ctf_ourflag =
96 if (self.team == 5) // red
97 head = find(world, classname, "item_flag_team1"); // red flag
99 head = find(world, classname, "item_flag_team2"); // blue flag
100 navigation_routerating(head, ratingscale);
103 void(float ratingscale) havocbot_goalrating_ctf_enemyflag =
106 if (self.team == 5) // red
107 head = find(world, classname, "item_flag_team2"); // blue flag
109 head = find(world, classname, "item_flag_team1"); // red flag
110 navigation_routerating(head, ratingscale);
113 void(float ratingscale) havocbot_goalrating_ctf_ourstolenflag =
116 if (self.team == 5) // red
117 head = find(world, classname, "item_flag_team1"); // red flag
119 head = find(world, classname, "item_flag_team2"); // blue flag
120 if (head.cnt != FLAG_BASE)
121 navigation_routerating(head, ratingscale);
124 void(float ratingscale) havocbot_goalrating_ctf_droppedflags =
126 local entity redflag, blueflag;
128 redflag = find(world, classname, "item_flag_team1");
129 blueflag = find(world, classname, "item_flag_team2");
131 if (redflag == world)
132 error("havocbot: item_flag_team1 missing\n");
133 if (blueflag == world)
134 error("havocbot: item_flag_team2 missing\n");
136 if (redflag.cnt != FLAG_BASE) // red flag is carried or out in the field
137 navigation_routerating(redflag, ratingscale);
138 if (blueflag.cnt != FLAG_BASE) // blue flag is carried or out in the field
139 navigation_routerating(blueflag, ratingscale);
142 // CTF: (always teamplay)
144 //role rogue: (is this used?)
145 //pick up items and dropped flags (with big rating boost to dropped flags)
146 void() havocbot_role_ctf_rogue =
148 if (self.bot_strategytime < time)
150 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
151 navigation_goalrating_start();
152 havocbot_goalrating_ctf_droppedflags(5000);
153 //havocbot_goalrating_enemyplayers(3000, self.origin, 3000);
154 havocbot_goalrating_items(10000, self.origin, 10000);
155 navigation_goalrating_end();
160 //pick up armor and health
161 //go to our flag spot
162 void() havocbot_role_ctf_carrier =
164 if (self.flagcarried == world)
166 dprint("changing role to middle\n");
167 self.havocbot_role = havocbot_role_ctf_middle;
168 self.havocbot_role_timeout = 0;
171 if (self.bot_strategytime < time)
173 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
174 navigation_goalrating_start();
175 havocbot_goalrating_ctf_ourflag(5000);
176 havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
177 navigation_goalrating_end();
182 //pick up armor and health
183 //if rockets < 25 || health < 100, change role to middle
184 //if carrying flag, change role to flag carrier
185 //if our flag taken, change role to interceptor
186 //(60-90 second timer) change role to middle
188 void() havocbot_role_ctf_offense =
191 if (self.flagcarried)
193 dprint("changing role to carrier\n");
194 self.havocbot_role = havocbot_role_ctf_carrier;
195 self.havocbot_role_timeout = 0;
200 if (self.team == 5) // red
201 f = find(world, classname, "item_flag_team1");
203 f = find(world, classname, "item_flag_team2");
204 if (f.cnt != FLAG_BASE && canreach(f))
206 dprint("changing role to interceptor\n");
207 self.havocbot_role = havocbot_role_ctf_interceptor;
208 self.havocbot_role_timeout = 0;
212 if (!self.havocbot_role_timeout)
213 self.havocbot_role_timeout = time + random() * 30 + 60;
214 if (self.ammo_rockets < 15 || time > self.havocbot_role_timeout)
216 dprint("changing role to middle\n");
217 self.havocbot_role = havocbot_role_ctf_middle;
218 self.havocbot_role_timeout = 0;
221 if (self.bot_strategytime < time)
223 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
224 navigation_goalrating_start();
225 havocbot_goalrating_ctf_ourstolenflag(5000);
226 havocbot_goalrating_ctf_enemyflag(3000);
227 havocbot_goalrating_items(10000, self.origin, 10000);
228 navigation_goalrating_end();
234 //if carrying flag, change role to flag carrier
235 //if our flag taken, change role to interceptor
236 //if see flag (of either team) follow it (this has many implications)
237 //(10-20 second timer) change role to defense or offense
238 //go to least recently visited area
239 void() havocbot_role_ctf_middle =
241 if (self.flagcarried)
243 dprint("changing role to carrier\n");
244 self.havocbot_role = havocbot_role_ctf_carrier;
245 self.havocbot_role_timeout = 0;
250 if (self.team == 5) // red
251 f = find(world, classname, "item_flag_team1");
253 f = find(world, classname, "item_flag_team2");
254 if (f.cnt != FLAG_BASE && canreach(f))
256 dprint("changing role to interceptor\n");
257 self.havocbot_role = havocbot_role_ctf_interceptor;
258 self.havocbot_role_timeout = 0;
262 if (!self.havocbot_role_timeout)
263 self.havocbot_role_timeout = time + random() * 10 + 10;
264 if (time > self.havocbot_role_timeout)
265 if (self.ammo_rockets >= 25)
269 dprint("changing role to offense\n");
270 self.havocbot_role = havocbot_role_ctf_offense;
274 dprint("changing role to defense\n");
275 self.havocbot_role = havocbot_role_ctf_defense;
277 self.havocbot_role_timeout = 0;
281 if (self.bot_strategytime < time)
283 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
284 navigation_goalrating_start();
285 havocbot_goalrating_ctf_ourstolenflag(5000);
286 havocbot_goalrating_ctf_droppedflags(3000);
287 //havocbot_goalrating_enemyplayers(1000, self.origin, 1000);
288 havocbot_goalrating_items(10000, self.origin, 10000);
289 navigation_goalrating_end();
294 //if rockets < 25 || health < 100, change role to middle
295 //if carrying flag, change role to flag carrier
296 //if our flag taken, change role to interceptor
297 //(30-50 second timer) change role to middle
298 //move to nearest unclaimed defense spot
299 void() havocbot_role_ctf_defense =
302 if (self.flagcarried)
304 dprint("changing role to carrier\n");
305 self.havocbot_role = havocbot_role_ctf_carrier;
306 self.havocbot_role_timeout = 0;
311 if (self.team == 5) // red
312 f = find(world, classname, "item_flag_team1");
314 f = find(world, classname, "item_flag_team2");
315 if (f.cnt != FLAG_BASE && canreach(f))
317 dprint("changing role to interceptor\n");
318 self.havocbot_role = havocbot_role_ctf_interceptor;
319 self.havocbot_role_timeout = 0;
323 if (!self.havocbot_role_timeout)
324 self.havocbot_role_timeout = time + random() * 20 + 30;
325 if (self.ammo_rockets < 15 || time > self.havocbot_role_timeout)
327 dprint("changing role to middle\n");
328 self.havocbot_role = havocbot_role_ctf_middle;
329 self.havocbot_role_timeout = 0;
332 if (self.bot_strategytime < time)
334 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
335 navigation_goalrating_start();
336 havocbot_goalrating_ctf_ourstolenflag(20000);
337 havocbot_goalrating_items(10000, f.origin, 10000);
338 navigation_goalrating_end();
341 // FIXME: place info_ctf_defensepoint entities in CTF maps and use them
342 // change position occasionally
343 if (time > self.bot_strategytime || self.goalentity.classname != "info_ctf_defensepoint")
345 self.bot_strategytime = time + random() * 45 + 15;
346 self.goalentity = world;
347 head = findchain(classname, "info_ctf_defensepoint");
350 if (time > head.count)
352 self.goalentity = head;
357 // if there are no defensepoints defined, switch to middle
358 if (self.goalentity == world)
360 dprint("changing role to middle\n");
361 self.havocbot_role = havocbot_role_ctf_middle;
362 self.havocbot_role_timeout = 0;
366 // keep anyone else from taking this spot
367 if (self.goalentity != world)
368 self.goalentity.count = time + 0.5;
373 // choose a role according to the situation
374 void() havocbot_chooserole_ctf =
377 dprint("choose CTF role...\n");
379 self.havocbot_role = havocbot_role_ctf_rogue;
384 self.havocbot_role = havocbot_role_ctf_offense;
386 self.havocbot_role = havocbot_role_ctf_middle;
388 self.havocbot_role = havocbot_role_ctf_defense;
394 void() havocbot_role_dm =
396 if (self.bot_strategytime < time)
398 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
399 navigation_goalrating_start();
400 havocbot_goalrating_items(10000, self.origin, 10000);
401 havocbot_goalrating_enemyplayers(1, self.origin, 2000);
402 //havocbot_goalrating_waypoints(1, self.origin, 1000);
403 navigation_goalrating_end();
407 void() havocbot_chooserole_dm =
409 self.havocbot_role = havocbot_role_dm;
412 void() havocbot_chooserole =
414 dprint("choose a role...\n");
415 navigation_routetogoal(world);
416 self.bot_strategytime = -1;
418 havocbot_chooserole_ctf();
419 else // assume anything else is deathmatch
420 havocbot_chooserole_dm();