[nexuiz-commits] r6896 - trunk/data/qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sat Jun 6 17:03:19 EDT 2009
Author: mand1nga
Date: 2009-06-06 17:03:19 -0400 (Sat, 06 Jun 2009)
New Revision: 6896
Added:
trunk/data/qcsrc/server/havocbot_ons.qc
Modified:
trunk/data/qcsrc/server/havocbot_roles.qc
trunk/data/qcsrc/server/progs.src
Log:
ONS ai. Currently only one role (offense) is supported. Please test.
Added: trunk/data/qcsrc/server/havocbot_ons.qc
===================================================================
--- trunk/data/qcsrc/server/havocbot_ons.qc (rev 0)
+++ trunk/data/qcsrc/server/havocbot_ons.qc 2009-06-06 21:03:19 UTC (rev 6896)
@@ -0,0 +1,262 @@
+#define HAVOCBOT_ONS_ROLE_NONE 0
+#define HAVOCBOT_ONS_ROLE_DEFENSE 2
+#define HAVOCBOT_ONS_ROLE_ASSISTANT 4
+#define HAVOCBOT_ONS_ROLE_OFFENSE 8
+
+.float havocbot_role_flags;
+
+.void() havocbot_role;
+.void() havocbot_previous_role;
+
+void() havocbot_role_ons_defense;
+void() havocbot_role_ons_offense;
+void() havocbot_role_ons_assistant;
+
+void(entity bot) havocbot_ons_reset_role;
+void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
+void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
+
+.float isshielded;
+.float iscaptured;
+.float islinked;
+float (entity controlpoint, float team) onslaught_controlpoint_can_be_linked;
+float (entity controlpoint, float team) onslaught_controlpoint_attackable;
+
+void havocbot_role_ons_setrole(entity bot, float role)
+{
+ dprint(strcat(bot.netname," switched to "));
+ switch(role)
+ {
+ case HAVOCBOT_ONS_ROLE_DEFENSE:
+ dprint("defense");
+ bot.havocbot_role = havocbot_role_ons_defense;
+ bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
+ bot.havocbot_role_timeout = 0;
+ break;
+ case HAVOCBOT_ONS_ROLE_ASSISTANT:
+ dprint("assistant");
+ bot.havocbot_role = havocbot_role_ons_assistant;
+ bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
+ bot.havocbot_role_timeout = 0;
+ break;
+ case HAVOCBOT_ONS_ROLE_OFFENSE:
+ dprint("offense");
+ bot.havocbot_role = havocbot_role_ons_offense;
+ bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
+ bot.havocbot_role_timeout = 0;
+ break;
+ }
+ dprint("\n");
+};
+
+float havocbot_ons_teamcount(entity bot, float role)
+{
+ local float c;
+ local entity head;
+
+ FOR_EACH_PLAYER(head)
+ if(head.team==self.team)
+ if(head.havocbot_role_flags & role)
+ ++c;
+
+ return c;
+};
+
+void havocbot_goalrating_ons_controlpoints_attack(float ratingscale)
+{
+ local entity cps, cp, wp, bestwp;
+ local float radius, found, bestcounter, status;
+
+ for (cps = findchain(classname, "onslaught_controlpoint_shield"); cps; cps = cps.chain)
+ {
+ // Found its corresponding onslaught_controlpoint entity (...)
+ for (cp = findradius(cps.origin, 100); cp; cp = cp.chain)
+ {
+ if(cp.classname=="onslaught_controlpoint")
+ break;
+ }
+
+ if(cp==world)
+ continue;
+
+ status = onslaught_controlpoint_attackable(cp, self.team);
+
+ dprint(self.classname," found a controlpoint with status ",ftos(status),"\n");
+
+ if(status==1 || status == 3)
+ {
+ // Should be attacked
+ // Rate waypoints near it
+ found = FALSE;
+ bestwp = world;
+ bestcounter = 99999999999;
+ for(radius=0; radius<1000 && !found; radius+=500)
+ {
+ for(wp=findradius(cp.origin,radius); wp; wp=wp.chain)
+ {
+ if(wp.classname=="waypoint")
+ if(checkpvs(wp.origin,cp))
+ {
+ found = TRUE;
+ if(wp.cnt<bestcounter)
+ {
+ bestwp = wp;
+ bestcounter = wp.cnt;
+ }
+ }
+ }
+
+ if(found)
+ break;
+ }
+
+ if(bestwp)
+ {
+ navigation_routerating(bestwp, ratingscale, 10000);
+ bestwp.cnt += 1;
+ }
+ dprint("attackable controlpoint found at ", vtos(cp.origin) ,"\n");
+ }
+ else if(status==2 || status==4)
+ {
+ // Should be touched
+ if not(bot_waypoints_for_items)
+ {
+ navigation_routerating(cp, ratingscale, 10000);
+ return;
+ }
+
+ for (wp = findradius(cp.origin,100); wp; wp = wp.chain)
+ {
+ if(wp.classname=="waypoint")
+ {
+ navigation_routerating(wp, ratingscale, 10000);
+ return;
+ }
+ }
+ dprint("touchable controlpoint found at ", vtos(cp.origin) ,"\n");
+ }
+ }
+};
+
+void havocbot_goalrating_ons_generator_attack(float ratingscale)
+{
+ local entity g, wp, bestwp;
+ local float radius, found, bestcounter;
+
+ for (g = findchain(classname, "onslaught_generator"); g; g = g.chain)
+ {
+ if(g.team == self.team || g.isshielded)
+ continue;
+
+ // Should be attacked
+ // Rate waypoints near it
+ found = FALSE;
+ bestwp = world;
+ bestcounter = 99999999999;
+ for(radius=0; radius<1500 && !found; radius+=500)
+ {
+ for(wp=findradius(g.origin,radius); wp; wp=wp.chain)
+ {
+ if(wp.classname=="waypoint")
+ if(checkpvs(wp.origin,g))
+ {
+ found = TRUE;
+ if(wp.cnt<bestcounter)
+ {
+ bestwp = wp;
+ bestcounter = wp.cnt;
+ }
+ }
+ }
+
+ if(found)
+ break;
+ }
+
+ if(bestwp)
+ {
+ dprint("waypoints found around generator\n");
+ navigation_routerating(bestwp, ratingscale, 10000);
+ bestwp.cnt += 1;
+ }
+ else
+ {
+ dprint("generator found without waypoints around\n");
+ // if there aren't waypoints near the generator go straight to it
+ navigation_routerating(g, ratingscale, 10000);
+ }
+ }
+};
+
+void havocbot_role_ons_offense()
+{
+ if(self.deadflag != DEAD_NO)
+ {
+ havocbot_ons_reset_role(self);
+ return;
+ }
+
+ // Set the role timeout if necessary
+ if (!self.havocbot_role_timeout)
+ self.havocbot_role_timeout = time + 120;
+
+ if (time > self.havocbot_role_timeout)
+ {
+ havocbot_ons_reset_role(self);
+ return;
+ }
+
+ if (self.bot_strategytime < time)
+ {
+ navigation_goalrating_start();
+ havocbot_goalrating_enemyplayers(20000, self.origin, 500);
+ havocbot_goalrating_ons_generator_attack(20000);
+ havocbot_goalrating_ons_controlpoints_attack(20000);
+ havocbot_goalrating_items(15000, self.origin, 1000);
+ havocbot_goalrating_items(2500, self.origin, 10000);
+ navigation_goalrating_end();
+
+ self.bot_strategytime = time + cvar("bot_ai_strategyinterval");
+ }
+};
+
+void havocbot_role_ons_assistant()
+{
+ havocbot_ons_reset_role(self);
+};
+
+void havocbot_role_ons_defense()
+{
+ havocbot_ons_reset_role(self);
+};
+
+void havocbot_ons_reset_role(entity bot)
+{
+ local entity head;
+ local float c;
+
+ if(self.deadflag != DEAD_NO)
+ return;
+
+ // TODO: Defend control points or generator if necessary
+
+ // if there is only me on the team switch to offense
+ c = 0;
+ FOR_EACH_PLAYER(head)
+ if(head.team==self.team)
+ ++c;
+
+ if(c==1)
+ {
+ havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
+ return;
+ }
+
+ havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
+};
+
+void havocbot_chooserole_ons()
+{
+ havocbot_ons_reset_role(self);
+};
Modified: trunk/data/qcsrc/server/havocbot_roles.qc
===================================================================
--- trunk/data/qcsrc/server/havocbot_roles.qc 2009-06-06 21:01:11 UTC (rev 6895)
+++ trunk/data/qcsrc/server/havocbot_roles.qc 2009-06-06 21:03:19 UTC (rev 6896)
@@ -639,6 +639,8 @@
havocbot_chooserole_kh();
else if (g_race)
havocbot_chooserole_race();
+ else if (g_onslaught)
+ havocbot_chooserole_ons();
else // assume anything else is deathmatch
havocbot_chooserole_dm();
};
Modified: trunk/data/qcsrc/server/progs.src
===================================================================
--- trunk/data/qcsrc/server/progs.src 2009-06-06 21:01:11 UTC (rev 6895)
+++ trunk/data/qcsrc/server/progs.src 2009-06-06 21:03:19 UTC (rev 6896)
@@ -54,6 +54,7 @@
// LordHavoc's bots
havocbot.qc
havocbot_ctf.qc
+havocbot_ons.qc
havocbot_roles.qc
g_subs.qc
More information about the nexuiz-commits
mailing list