]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/mand1nga/bot-assault'
authormand1nga <mand1nga@xonotic.org>
Wed, 17 Aug 2011 22:37:49 +0000 (19:37 -0300)
committermand1nga <mand1nga@xonotic.org>
Wed, 17 Aug 2011 22:37:49 +0000 (19:37 -0300)
qcsrc/server/assault.qc
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/bot/havocbot/role_assault.qc [new file with mode: 0644]
qcsrc/server/bot/havocbot/roles.qc
qcsrc/server/func_breakable.qc

index 85009dd830967c11f8b9d1a3c08953db803f970d..517da81684928019729e385b6feb244b32963021 100644 (file)
@@ -103,7 +103,7 @@ void assault_objective_decrease_use() {
                                                centerprint(player, s);
                                        }
                                }
-                                       
+
                                oldactivator = activator;
                                activator = oldself;
                                        SUB_UseTargets();
@@ -207,6 +207,7 @@ void spawnfunc_func_assault_destructible() {
                return;
        }
        self.spawnflags = 3;
+       self.classname = "func_assault_destructible";
        if(assault_attacker_team == COLOR_TEAM1) {
                self.team = COLOR_TEAM2;
        } else {
@@ -271,7 +272,7 @@ void assault_roundstart_use() {
        activator = self;
        SUB_UseTargets();
 
-       
+
 #ifdef TTURRETS_ENABLED
        entity ent, oldself;
 
@@ -315,7 +316,7 @@ void spawnfunc_target_assault_roundstart() {
 // reset objectives, toggle spawnpoints, reset triggers, ...
 void vehicles_clearrturn();
 void vehicles_spawn();
-void assault_new_round() 
+void assault_new_round()
 {
     entity oldself;
        //bprint("ASSAULT: new round\n");
@@ -325,9 +326,9 @@ void assault_new_round()
     FOR_EACH_PLAYER(self)
     {
         if(self.vehicle)
-            vehicles_exit(VHEF_RELESE);        
+            vehicles_exit(VHEF_RELESE);
     }
-    
+
     self = findchainflags(vehicle_flags, VHF_ISVEHICLE);
     while(self)
     {
@@ -360,7 +361,7 @@ void assault_new_round()
                                ent.team_saved = COLOR_TEAM1;
                }
        }
-       
+
        // reset the level with a countdown
        cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
        ReadyRestartForce(); // sets game_starttime
index 1d9054952d24bbdde4d63981bc5a86689f3a44f4..79f305a2673af51b9cfe7cfe6326ebe2035d683d 100644 (file)
@@ -4,6 +4,7 @@
 #include "role_keyhunt.qc"
 #include "role_freezetag.qc"
 #include "role_keepaway.qc"
+#include "role_assault.qc"
 #include "roles.qc"
 
 void havocbot_ai()
diff --git a/qcsrc/server/bot/havocbot/role_assault.qc b/qcsrc/server/bot/havocbot/role_assault.qc
new file mode 100644 (file)
index 0000000..5c0be47
--- /dev/null
@@ -0,0 +1,208 @@
+#define HAVOCBOT_AST_ROLE_NONE                 0
+#define HAVOCBOT_AST_ROLE_DEFENSE      2
+#define HAVOCBOT_AST_ROLE_OFFENSE      4
+
+.float havocbot_role_flags;
+.float havocbot_attack_time;
+
+.void() havocbot_role;
+.void() havocbot_previous_role;
+
+void() havocbot_role_ast_defense;
+void() havocbot_role_ast_offense;
+.entity havocbot_ast_target;
+
+void(entity bot) havocbot_ast_reset_role;
+
+void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
+void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
+
+void havocbot_goalrating_ast_targets(float ratingscale)
+{
+       entity ad, best, pl, wp, tod;
+       float radius, found, bestvalue, c;
+       vector p;
+
+       ad = findchain(classname, "func_assault_destructible");
+
+       for (; ad; ad = ad.chain)
+       {
+               if (ad.target == "")
+                       continue;
+
+               if not(ad.bot_attack)
+                       continue;
+
+               found = FALSE;
+               for(tod = world; (tod = find(tod, targetname, ad.target)); )
+               {
+                       if(tod.classname == "target_objective_decrease")
+                       {
+                               if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE)
+                               {
+                               //      dprint(etos(ad),"\n");
+                                       found = TRUE;
+                                       break;
+                               }
+                       }
+               }
+
+               if(!found)
+               {
+               ///     dprint("target not found\n");
+                       continue;
+               }
+               /// dprint("target #", etos(ad), " found\n");
+
+
+               p = 0.5 * (ad.absmin + ad.absmax);
+       //      dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
+       //      te_knightspike(p);
+       //      te_lightning2(world, '0 0 0', p);
+
+               // Find and rate waypoints around it
+               found = FALSE;
+               best = world;
+               bestvalue = 99999999999;
+               for(radius=0; radius<1500 && !found; radius+=500)
+               {
+                       for(wp=findradius(p, radius); wp; wp=wp.chain)
+                       {
+                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
+                               if(wp.classname=="waypoint")
+                               if(checkpvs(wp.origin, ad))
+                               {
+                                       found = TRUE;
+                                       if(wp.cnt<bestvalue)
+                                       {
+                                               best = wp;
+                                               bestvalue = wp.cnt;
+                                       }
+                               }
+                       }
+               }
+
+               if(best)
+               {
+               ///     dprint("waypoints around target were found\n");
+               //      te_lightning2(world, '0 0 0', best.origin);
+               //      te_knightspike(best.origin);
+
+                       navigation_routerating(best, ratingscale, 4000);
+                       best.cnt += 1;
+
+                       self.havocbot_attack_time = 0;
+
+                       if(checkpvs(self.view_ofs,ad))
+                       if(checkpvs(self.view_ofs,best))
+                       {
+                       //      dprint("increasing attack time for this target\n");
+                               self.havocbot_attack_time = time + 2;
+                       }
+               }
+       }
+}
+
+void havocbot_role_ast_offense()
+{
+       if(self.deadflag != DEAD_NO)
+       {
+               self.havocbot_attack_time = 0;
+               havocbot_ast_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_ast_reset_role(self);
+               return;
+       }
+
+       if(self.havocbot_attack_time>time)
+               return;
+
+       if (self.bot_strategytime < time)
+       {
+               navigation_goalrating_start();
+               havocbot_goalrating_enemyplayers(20000, self.origin, 650);
+               havocbot_goalrating_ast_targets(20000);
+               havocbot_goalrating_items(15000, self.origin, 10000);
+               navigation_goalrating_end();
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+       }
+};
+
+void havocbot_role_ast_defense()
+{
+       if(self.deadflag != DEAD_NO)
+       {
+               self.havocbot_attack_time = 0;
+               havocbot_ast_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_ast_reset_role(self);
+               return;
+       }
+
+       if(self.havocbot_attack_time>time)
+               return;
+
+       if (self.bot_strategytime < time)
+       {
+               navigation_goalrating_start();
+               havocbot_goalrating_enemyplayers(20000, self.origin, 3000);
+               havocbot_goalrating_ast_targets(20000);
+               havocbot_goalrating_items(15000, self.origin, 10000);
+               navigation_goalrating_end();
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+       }
+};
+
+void havocbot_role_ast_setrole(entity bot, float role)
+{
+       switch(role)
+       {
+               case HAVOCBOT_AST_ROLE_DEFENSE:
+                       bot.havocbot_role = havocbot_role_ast_defense;
+                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_AST_ROLE_OFFENSE:
+                       bot.havocbot_role = havocbot_role_ast_offense;
+                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+       }
+};
+
+void havocbot_ast_reset_role(entity bot)
+{
+       local entity head;
+       local float c;
+
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if(bot.team==assault_attacker_team)
+               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE);
+       else
+               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE);
+};
+
+void havocbot_chooserole_ast()
+{
+       havocbot_ast_reset_role(self);
+};
index 18699a7bd6f310001cc50e3ac359d250a55f6e5a..4cf685ddb42f970afa43a58c88206333a99fcb76 100644 (file)
@@ -312,6 +312,8 @@ void havocbot_chooserole()
                havocbot_chooserole_ka();
        else if (g_freezetag)
                havocbot_chooserole_ft();
+       else if (g_assault)
+               havocbot_chooserole_ast();
        else // assume anything else is deathmatch
                havocbot_chooserole_dm();
 };
index 1e474c0d641a34764fb55578f77614927f280f33..192e5cd7fb2e69f5b20b5708f4aec9af11224e28 100644 (file)
@@ -114,6 +114,7 @@ void func_breakable_behave_destroyed()
 {
        self.health = self.max_health;
        self.takedamage = DAMAGE_NO;
+       self.bot_attack = FALSE;
        self.event_damage = SUB_Null;
        self.state = 1;
        func_breakable_colormod();
@@ -128,6 +129,7 @@ void func_breakable_behave_restore()
                WaypointSprite_UpdateHealth(self.sprite, self.health);
        }
        self.takedamage = DAMAGE_AIM;
+       self.bot_attack = TRUE;
        self.event_damage = func_breakable_damage;
        self.state = 0;
        self.nextthink = 0; // cancel auto respawn