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(float ratingscale, vector org, float sradius) havocbot_goalrating_ctf_carrieritems =
57 head = findchainfloat(bot_pickup, TRUE);
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)
66 //if (!head.bot_pickupevalfunc || head.model == "")
68 // get the value of the item
69 t = head.bot_pickupevalfunc(self, head) * 0.0001;
71 havocbot_routerating(head, t * ratingscale);
77 void(float ratingscale) havocbot_goalrating_ctf_ourflag =
80 if (self.team == 5) // red
81 head = find(world, classname, "item_flag_team1"); // red flag
83 head = find(world, classname, "item_flag_team2"); // blue flag
84 havocbot_routerating(head, ratingscale);
87 void(float ratingscale) havocbot_goalrating_ctf_enemyflag =
90 if (self.team == 5) // red
91 head = find(world, classname, "item_flag_team2"); // blue flag
93 head = find(world, classname, "item_flag_team1"); // red flag
94 havocbot_routerating(head, ratingscale);
97 void(float ratingscale) havocbot_goalrating_ctf_ourstolenflag =
100 if (self.team == 5) // red
101 head = find(world, classname, "item_flag_team1"); // red flag
103 head = find(world, classname, "item_flag_team2"); // blue flag
104 if (head.cnt != FLAG_BASE)
105 havocbot_routerating(head, ratingscale);
108 void(float ratingscale) havocbot_goalrating_ctf_droppedflags =
110 local entity redflag, blueflag;
112 redflag = find(world, classname, "item_flag_team1");
113 blueflag = find(world, classname, "item_flag_team2");
115 if (redflag == world)
116 error("havocbot: item_flag_team1 missing\n");
117 if (blueflag == world)
118 error("havocbot: item_flag_team2 missing\n");
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);
126 // CTF: (always teamplay)
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 =
132 if (self.bot_strategytime < time)
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();
144 //pick up armor and health
145 //go to our flag spot
146 void() havocbot_role_ctf_carrier =
148 if (self.flagcarried == world)
150 bprint("changing role to middle\n");
151 self.havocbot_role = havocbot_role_ctf_middle;
152 self.havocbot_role_timeout = 0;
155 if (self.bot_strategytime < time)
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();
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
172 void() havocbot_role_ctf_offense =
175 if (self.flagcarried)
177 bprint("changing role to carrier\n");
178 self.havocbot_role = havocbot_role_ctf_carrier;
179 self.havocbot_role_timeout = 0;
185 if (self.team == 5) // red
186 f = find(world, classname, "item_flag_team1");
188 f = find(world, classname, "item_flag_team2");
189 if (f.cnt != FLAG_BASE && canreach(f))
191 bprint("changing role to interceptor\n");
192 self.havocbot_role = havocbot_role_ctf_interceptor;
193 self.havocbot_role_timeout = 0;
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)
202 bprint("changing role to middle\n");
203 self.havocbot_role = havocbot_role_ctf_middle;
204 self.havocbot_role_timeout = 0;
207 if (self.bot_strategytime < time)
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();
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 =
227 if (self.flagcarried)
229 bprint("changing role to carrier\n");
230 self.havocbot_role = havocbot_role_ctf_carrier;
231 self.havocbot_role_timeout = 0;
237 if (self.team == 5) // red
238 f = find(world, classname, "item_flag_team1");
240 f = find(world, classname, "item_flag_team2");
241 if (f.cnt != FLAG_BASE && canreach(f))
243 bprint("changing role to interceptor\n");
244 self.havocbot_role = havocbot_role_ctf_interceptor;
245 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 (Inventory_Quantity(self, "rockets") >= 25)
257 bprint("changing role to offense\n");
258 self.havocbot_role = havocbot_role_ctf_offense;
262 bprint("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 bprint("changing role to carrier\n");
293 self.havocbot_role = havocbot_role_ctf_carrier;
294 self.havocbot_role_timeout = 0;
300 if (self.team == 5) // red
301 f = find(world, classname, "item_flag_team1");
303 f = find(world, classname, "item_flag_team2");
304 if (f.cnt != FLAG_BASE && canreach(f))
306 bprint("changing role to interceptor\n");
307 self.havocbot_role = havocbot_role_ctf_interceptor;
308 self.havocbot_role_timeout = 0;
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)
317 bprint("changing role to middle\n");
318 self.havocbot_role = havocbot_role_ctf_middle;
319 self.havocbot_role_timeout = 0;
322 if (self.bot_strategytime < time)
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();
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")
336 self.bot_strategytime = time + random() * 45 + 15;
337 self.goalentity = world;
338 head = findchain(classname, "info_ctf_defensepoint");
341 if (time > head.count)
343 self.goalentity = head;
348 // if there are no defensepoints defined, switch to middle
349 if (self.goalentity == world)
351 bprint("changing role to middle\n");
352 self.havocbot_role = havocbot_role_ctf_middle;
353 self.havocbot_role_timeout = 0;
357 // keep anyone else from taking this spot
358 if (self.goalentity != world)
359 self.goalentity.count = time + 0.5;
365 // choose a role according to the situation
366 void() havocbot_chooserole_ctf =
370 self.havocbot_role = havocbot_role_ctf_rogue;
375 self.havocbot_role = havocbot_role_ctf_offense;
377 self.havocbot_role = havocbot_role_ctf_middle;
379 self.havocbot_role = havocbot_role_ctf_defense;
386 void() havocbot_role_dm =
388 if (self.bot_strategytime < time)
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();
398 void() havocbot_chooserole_dm =
400 self.havocbot_role = havocbot_role_dm;
403 void() havocbot_chooserole =
405 navigation_routetogoal(world);
406 self.bot_strategytime = -1;
408 // havocbot_chooserole_ctf();
409 //else // assume anything else is deathmatch
410 havocbot_chooserole_dm();