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_enemyplayers =
31 local float t, noteam;
32 ratingscale = ratingscale * 1200;
33 noteam = self.team == 0 || teamplay == 0;
34 head = findchain(classname, "player");
38 if (head.team != self.team || noteam)
39 if (vlen(head.origin - org) < sradius)
44 t = t / (head.health + head.armortype * head.armorvalue);
46 navigation_routerating(head, t * ratingscale);
53 void() havocbot_role_ctf_middle;
54 void() havocbot_role_ctf_defense;
55 void() havocbot_role_ctf_offense;
57 void(float ratingscale, vector org, float sradius) havocbot_goalrating_ctf_carrieritems =
61 head = findchainfloat(bot_pickup, TRUE);
64 // look for health and armor only
65 if (head.solid) // must be possible to pick up (respawning items don't count)
66 if (head.health || head.armorvalue)
67 if (vlen(head.origin - org) < sradius)
70 //if (!head.bot_pickupevalfunc || head.model == "")
72 // get the value of the item
73 t = head.bot_pickupevalfunc(self, head) * 0.0001;
75 navigation_routerating(head, t * ratingscale);
81 void(float ratingscale) havocbot_goalrating_ctf_ourflag =
84 if (self.team == 5) // red
85 head = find(world, classname, "item_flag_team1"); // red flag
87 head = find(world, classname, "item_flag_team2"); // blue flag
88 navigation_routerating(head, ratingscale);
91 void(float ratingscale) havocbot_goalrating_ctf_enemyflag =
94 if (self.team == 5) // red
95 head = find(world, classname, "item_flag_team2"); // blue flag
97 head = find(world, classname, "item_flag_team1"); // red flag
98 navigation_routerating(head, ratingscale);
101 void(float ratingscale) havocbot_goalrating_ctf_ourstolenflag =
104 if (self.team == 5) // red
105 head = find(world, classname, "item_flag_team1"); // red flag
107 head = find(world, classname, "item_flag_team2"); // blue flag
108 if (head.cnt != FLAG_BASE)
109 navigation_routerating(head, ratingscale);
112 void(float ratingscale) havocbot_goalrating_ctf_droppedflags =
114 local entity redflag, blueflag;
116 redflag = find(world, classname, "item_flag_team1");
117 blueflag = find(world, classname, "item_flag_team2");
119 if (redflag == world)
120 error("havocbot: item_flag_team1 missing\n");
121 if (blueflag == world)
122 error("havocbot: item_flag_team2 missing\n");
124 if (redflag.cnt != FLAG_BASE) // red flag is carried or out in the field
125 navigation_routerating(redflag, ratingscale);
126 if (blueflag.cnt != FLAG_BASE) // blue flag is carried or out in the field
127 navigation_routerating(blueflag, ratingscale);
130 // CTF: (always teamplay)
132 //role rogue: (is this used?)
133 //pick up items and dropped flags (with big rating boost to dropped flags)
134 void() havocbot_role_ctf_rogue =
136 if (self.bot_strategytime < time)
138 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
139 navigation_goalrating_start();
140 havocbot_goalrating_ctf_droppedflags(5000);
141 //havocbot_goalrating_enemyplayers(3000, self.origin, 3000);
142 havocbot_goalrating_items(10000, self.origin, 10000);
143 navigation_goalrating_end();
148 //pick up armor and health
149 //go to our flag spot
150 void() havocbot_role_ctf_carrier =
152 if (self.flagcarried == world)
154 dprint("changing role to middle\n");
155 self.havocbot_role = havocbot_role_ctf_middle;
156 self.havocbot_role_timeout = 0;
159 if (self.bot_strategytime < time)
161 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
162 navigation_goalrating_start();
163 havocbot_goalrating_ctf_ourflag(5000);
164 havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
165 navigation_goalrating_end();
170 //pick up armor and health
171 //if rockets < 25 || health < 100, change role to middle
172 //if carrying flag, change role to flag carrier
173 //if our flag taken, change role to interceptor
174 //(60-90 second timer) change role to middle
176 void() havocbot_role_ctf_offense =
179 if (self.flagcarried)
181 dprint("changing role to carrier\n");
182 self.havocbot_role = havocbot_role_ctf_carrier;
183 self.havocbot_role_timeout = 0;
188 if (self.team == 5) // red
189 f = find(world, classname, "item_flag_team1");
191 f = find(world, classname, "item_flag_team2");
192 if (f.cnt != FLAG_BASE && canreach(f))
194 dprint("changing role to interceptor\n");
195 self.havocbot_role = havocbot_role_ctf_interceptor;
196 self.havocbot_role_timeout = 0;
200 if (!self.havocbot_role_timeout)
201 self.havocbot_role_timeout = time + random() * 30 + 60;
202 if (self.ammo_rockets < 15 || time > self.havocbot_role_timeout)
204 dprint("changing role to middle\n");
205 self.havocbot_role = havocbot_role_ctf_middle;
206 self.havocbot_role_timeout = 0;
209 if (self.bot_strategytime < time)
211 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
212 navigation_goalrating_start();
213 havocbot_goalrating_ctf_ourstolenflag(5000);
214 havocbot_goalrating_ctf_enemyflag(3000);
215 havocbot_goalrating_items(10000, self.origin, 10000);
216 navigation_goalrating_end();
222 //if carrying flag, change role to flag carrier
223 //if our flag taken, change role to interceptor
224 //if see flag (of either team) follow it (this has many implications)
225 //(10-20 second timer) change role to defense or offense
226 //go to least recently visited area
227 void() havocbot_role_ctf_middle =
229 if (self.flagcarried)
231 dprint("changing role to carrier\n");
232 self.havocbot_role = havocbot_role_ctf_carrier;
233 self.havocbot_role_timeout = 0;
238 if (self.team == 5) // red
239 f = find(world, classname, "item_flag_team1");
241 f = find(world, classname, "item_flag_team2");
242 if (f.cnt != FLAG_BASE && canreach(f))
244 dprint("changing role to interceptor\n");
245 self.havocbot_role = havocbot_role_ctf_interceptor;
246 self.havocbot_role_timeout = 0;
250 if (!self.havocbot_role_timeout)
251 self.havocbot_role_timeout = time + random() * 10 + 10;
252 if (time > self.havocbot_role_timeout)
253 if (self.ammo_rockets >= 25)
257 dprint("changing role to offense\n");
258 self.havocbot_role = havocbot_role_ctf_offense;
262 dprint("changing role to defense\n");
263 self.havocbot_role = havocbot_role_ctf_defense;
265 self.havocbot_role_timeout = 0;
269 if (self.bot_strategytime < time)
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();
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 =
290 if (self.flagcarried)
292 dprint("changing role to carrier\n");
293 self.havocbot_role = havocbot_role_ctf_carrier;
294 self.havocbot_role_timeout = 0;
299 if (self.team == 5) // red
300 f = find(world, classname, "item_flag_team1");
302 f = find(world, classname, "item_flag_team2");
303 if (f.cnt != FLAG_BASE && canreach(f))
305 dprint("changing role to interceptor\n");
306 self.havocbot_role = havocbot_role_ctf_interceptor;
307 self.havocbot_role_timeout = 0;
311 if (!self.havocbot_role_timeout)
312 self.havocbot_role_timeout = time + random() * 20 + 30;
313 if (self.ammo_rockets < 15 || time > self.havocbot_role_timeout)
315 dprint("changing role to middle\n");
316 self.havocbot_role = havocbot_role_ctf_middle;
317 self.havocbot_role_timeout = 0;
320 if (self.bot_strategytime < time)
322 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
323 navigation_goalrating_start();
324 havocbot_goalrating_ctf_ourstolenflag(20000);
325 havocbot_goalrating_items(10000, f.origin, 10000);
326 navigation_goalrating_end();
329 // FIXME: place info_ctf_defensepoint entities in CTF maps and use them
330 // change position occasionally
331 if (time > self.bot_strategytime || self.goalentity.classname != "info_ctf_defensepoint")
333 self.bot_strategytime = time + random() * 45 + 15;
334 self.goalentity = world;
335 head = findchain(classname, "info_ctf_defensepoint");
338 if (time > head.count)
340 self.goalentity = head;
345 // if there are no defensepoints defined, switch to middle
346 if (self.goalentity == world)
348 dprint("changing role to middle\n");
349 self.havocbot_role = havocbot_role_ctf_middle;
350 self.havocbot_role_timeout = 0;
354 // keep anyone else from taking this spot
355 if (self.goalentity != world)
356 self.goalentity.count = time + 0.5;
361 // choose a role according to the situation
362 void() havocbot_chooserole_ctf =
365 dprint("choose CTF role...\n");
367 self.havocbot_role = havocbot_role_ctf_rogue;
372 self.havocbot_role = havocbot_role_ctf_offense;
374 self.havocbot_role = havocbot_role_ctf_middle;
376 self.havocbot_role = havocbot_role_ctf_defense;
382 void() havocbot_role_dm =
384 if (self.bot_strategytime < time)
386 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
387 navigation_goalrating_start();
388 havocbot_goalrating_items(10000, self.origin, 10000);
389 //havocbot_goalrating_enemyplayers(2000, self.origin, 2000);
390 navigation_goalrating_end();
394 void() havocbot_chooserole_dm =
396 self.havocbot_role = havocbot_role_dm;
399 void() havocbot_chooserole =
401 dprint("choose a role...\n");
402 navigation_routetogoal(world);
403 self.bot_strategytime = -1;
405 havocbot_chooserole_ctf();
406 else // assume anything else is deathmatch
407 havocbot_chooserole_dm();