1 #define HAVOCBOT_ONS_ROLE_NONE 0
2 #define HAVOCBOT_ONS_ROLE_DEFENSE 2
3 #define HAVOCBOT_ONS_ROLE_ASSISTANT 4
4 #define HAVOCBOT_ONS_ROLE_OFFENSE 8
6 .float havocbot_role_flags;
7 .float havocbot_attack_time;
10 .void() havocbot_previous_role;
12 void() havocbot_role_ons_defense;
13 void() havocbot_role_ons_offense;
14 void() havocbot_role_ons_assistant;
16 void(entity bot) havocbot_ons_reset_role;
17 void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
18 void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
23 .float isgenneighbor_blue, iscpneighbor_blue;
24 .float isgenneighbor_red, iscpneighbor_red;
26 void havocbot_role_ons_setrole(entity bot, float role)
28 dprint(strcat(bot.netname," switched to "));
31 case HAVOCBOT_ONS_ROLE_DEFENSE:
33 bot.havocbot_role = havocbot_role_ons_defense;
34 bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
35 bot.havocbot_role_timeout = 0;
37 case HAVOCBOT_ONS_ROLE_ASSISTANT:
39 bot.havocbot_role = havocbot_role_ons_assistant;
40 bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
41 bot.havocbot_role_timeout = 0;
43 case HAVOCBOT_ONS_ROLE_OFFENSE:
45 bot.havocbot_role = havocbot_role_ons_offense;
46 bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
47 bot.havocbot_role_timeout = 0;
53 float havocbot_ons_teamcount(entity bot, float role)
59 if(head.team==self.team)
60 if(head.havocbot_role_flags & role)
66 float havocbot_goalrating_ons_controlpoints_attack(float ratingscale)
68 local entity cp, wp, bestwp;
69 local float radius, found, bestcounter;
71 for (cp = findchain(classname, "onslaught_controlpoint"); cp; cp = cp.chain)
79 if(self.team == COLOR_TEAM1)
81 if( (cp.isgenneighbor_blue || cp.iscpneighbor_blue) && !(cp.isgenneighbor_red || cp.iscpneighbor_red) )
84 else if(self.team == COLOR_TEAM2)
86 if( (cp.isgenneighbor_red || cp.iscpneighbor_red) && !(cp.isgenneighbor_blue || cp.iscpneighbor_blue) )
93 // Rate waypoints near it
96 bestcounter = 99999999999;
97 for(radius=0; radius<1000 && !found; radius+=500)
99 for(wp=findradius(cp.origin,radius); wp; wp=wp.chain)
101 if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
102 if(wp.classname=="waypoint")
103 if(checkpvs(wp.origin,cp))
106 if(wp.cnt<bestcounter)
109 bestcounter = wp.cnt;
117 navigation_routerating(bestwp, ratingscale, 10000);
120 if(checkpvs(self.view_ofs,cp))
121 if(checkpvs(self.view_ofs,bestwp))
122 self.havocbot_attack_time = time + 2;
126 navigation_routerating(cp, ratingscale, 10000);
128 dprint(self.netname, " found an attackable controlpoint at ", vtos(cp.origin) ,"\n");
132 dprint(self.netname, " found a touchable controlpoint at ", vtos(cp.origin) ,"\n");
134 if not(bot_waypoints_for_items)
136 navigation_routerating(cp, ratingscale, 10000);
140 for (wp = findradius(cp.origin,100); wp; wp = wp.chain)
142 if(wp.classname=="waypoint")
144 navigation_routerating(wp, ratingscale, 10000);
148 navigation_routerating(cp, ratingscale, 10000);
154 float havocbot_goalrating_ons_generator_attack(float ratingscale)
156 local entity g, wp, bestwp;
157 local float found, best;
159 for (g = findchain(classname, "onslaught_generator"); g; g = g.chain)
161 if(g.team == self.team || g.isshielded)
164 // Should be attacked
165 // Rate waypoints near it
170 for(wp=findradius(g.origin,350); wp; wp=wp.chain)
172 if(wp.classname=="waypoint")
173 if(checkpvs(wp.origin,g))
186 dprint("waypoints found around generator\n");
187 navigation_routerating(bestwp, ratingscale, 10000);
190 if(checkpvs(self.view_ofs,g))
191 if(checkpvs(self.view_ofs,bestwp))
192 self.havocbot_attack_time = time + 5;
198 dprint("generator found without waypoints around\n");
199 // if there aren't waypoints near the generator go straight to it
200 navigation_routerating(g, ratingscale, 10000);
201 self.havocbot_attack_time = 0;
208 void havocbot_role_ons_offense()
210 if(self.deadflag != DEAD_NO)
212 self.havocbot_attack_time = 0;
213 havocbot_ons_reset_role(self);
217 // Set the role timeout if necessary
218 if (!self.havocbot_role_timeout)
219 self.havocbot_role_timeout = time + 120;
221 if (time > self.havocbot_role_timeout)
223 havocbot_ons_reset_role(self);
227 if(self.havocbot_attack_time>time)
230 if (self.bot_strategytime < time)
232 navigation_goalrating_start();
233 havocbot_goalrating_enemyplayers(20000, self.origin, 650);
235 if(havocbot_goalrating_ons_generator_attack(20000))
236 havocbot_goalrating_items(10000, self.origin, 300);
239 havocbot_goalrating_ons_controlpoints_attack(20000);
240 havocbot_goalrating_items(10000, self.origin, 500);
242 havocbot_goalrating_items(500, self.origin, 10000);
243 navigation_goalrating_end();
245 self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
249 void havocbot_role_ons_assistant()
251 havocbot_ons_reset_role(self);
254 void havocbot_role_ons_defense()
256 havocbot_ons_reset_role(self);
259 void havocbot_ons_reset_role(entity bot)
264 if(self.deadflag != DEAD_NO)
267 // TODO: Defend control points or generator if necessary
269 // if there is only me on the team switch to offense
271 FOR_EACH_PLAYER(head)
272 if(head.team==self.team)
277 havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
281 havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
284 void havocbot_chooserole_ons()
286 havocbot_ons_reset_role(self);