]> de.git.xonotic.org Git - voretournament/voretournament.git/blobdiff - data/qcsrc/server/bot/havocbot/vore_ai.qc
Team healing AI now working as intended, but not ready yet. Also fix another tiny...
[voretournament/voretournament.git] / data / qcsrc / server / bot / havocbot / vore_ai.qc
index 0e51b841c08da0c7e046aa34803fa70f6754630c..174c428029c7947cb64907608c89f02b93ce2bba 100644 (file)
@@ -1,3 +1,5 @@
+.float status_teamhealing; // 0 = can't team heal, 1 = can team heal, 2 = team healing currently
+
 entity Swallow_distance_check_bot(entity e)
 {
        // check if we can swallow a player instead of firing our weapon
@@ -16,14 +18,60 @@ float Swallow_condition_check_bot(entity prey)
 {
        // checks the necessary conditions for a bot to swallow another player
        if(prey != self && prey.classname == "player" && prey.eater.classname != "player" && prey.deadflag == DEAD_NO && !prey.BUTTON_CHAT) // we can't swallow someone who's already in someone else's stomach
-       if(self.eater.classname != "player" && self.stomach_load < cvar("g_balance_vore_swallow_limit")) // we can't swallow players while inside someone's stomach ourselves
+       if(self.eater.classname != "player" && self.stomach_load < cvar("g_balance_vore_swallow_limit") && self.deadflag == DEAD_NO) // we can't swallow players while inside someone's stomach ourselves
        if not(cvar("g_vore_biggergut") && prey.stomach_load > self.stomach_load)
        if(self.health > cvar("g_balance_vore_kick_damage_max")) // explained below
-       if not(prey.team == self.team && teamplay)
                return TRUE;
        return FALSE;
 }
 
+void Vore_AI_Teamheal(entity prey)
+{
+       // allows bots to take advantage of the teamheal feature in team games, and use this feature to heal damaged team mates
+
+       if not(teamplay)
+               return;
+
+       self.status_teamhealing = 1; // start from the premise we can teamheal until proven otherwise
+       if(self.deadflag != DEAD_NO || self.eater.classname == "player" || self.flagcarried)
+       {
+               self.status_teamhealing = 0;
+               return;
+       }
+
+       // if we are holding a team mate that's been healed to the max, we can release them
+       // also use this check to not go any further if someone from the enemy team is in our stomach
+       entity head;
+       if(self.stomach_load)
+       {
+               FOR_EACH_PLAYER(head)
+               {
+                       if(head.eater.classname == "player")
+                       {
+                               if(head.team == self.team)
+                               {
+                                       self.status_teamhealing = 2;
+                                       if(head.health >= cvar("g_balance_vore_teamheal_stable"))
+                                               self.BUTTON_REGURGITATE = TRUE; // release the team mate
+                               }
+                               else
+                               {
+                                       self.status_teamhealing = 0; // someone from the enemy team is in our belly, which means we can't be teamhealing any more
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       // check if we can heal a damaged team mate we came across, and if so swallow them
+       if(self.status_teamhealing)
+       if(prey.classname == "player" && prey.team == self.team)
+       if not(prey.flagcarried) // don't eat the flag carrier and ruin his job
+       if(Swallow_condition_check_bot(prey))
+       if(prey.health < cvar("g_balance_vore_teamheal_stable"))
+               self.BUTTON_ATCK = TRUE; // swallow
+}
+
 .float swallow_retry, decide_delay1, decide_delay2;
 void Vore_AI()
 {
@@ -56,11 +104,12 @@ void Vore_AI()
        decide_prey = cvar("bot_ai_vore_decide_prey") / (skill * 2 + 1);
        decide_pred = cvar("bot_ai_vore_decide_pred") / (skill * 2 + 1);
 
-       if(Swallow_condition_check_bot(prey))
        if(time > self.swallow_retry)
+       if(Swallow_condition_check_bot(prey))
        {
                // the greater the skill, the higher the chance bots will swallow someone each attempt
                if(skill >= random_try)
+               if not(teamplay && prey.team == self.team)
                {
                        self.BUTTON_ATCK = TRUE; // swallow
                        self.decide_delay1 = time + decide_pred; // time before the bot decides what to do with their prey
@@ -68,6 +117,10 @@ void Vore_AI()
                self.swallow_retry = time + 0.5; // bots retry swallowing every 0.5 seconds, otherwise each frame would be random chance
        }
 
+       Vore_AI_Teamheal(prey);
+       if(self.status_teamhealing > 1) // if we are teamhealing, there's nothing to do from here on
+               return;
+
        // deciding what to do with a victim:
 
        if(self.stomach_load > 0 && time > self.decide_delay1)
@@ -79,12 +132,9 @@ void Vore_AI()
 
                else if(!self.digesting)
                {
-                       // the lower the skill, the more bots will tend to regurgitate you
-                       // the higher the skill, the more they will tend to digest you instead
+                       // the higher the skill, the faster bots will start to digest you
                        if(skill >= random_try)
                                self.BUTTON_DIGEST = TRUE; // digest
-                       else
-                               self.BUTTON_REGURGITATE = TRUE; // regurgitate
 
                        self.decide_delay1 = time + decide_pred; // time before the bot decides what to do with their prey
                }
@@ -94,20 +144,14 @@ void Vore_AI()
 // Prey bot behavior:
 // --------------------------------
 
-       // all we can do in the stomach is either kick and do some damage or trigger the predator's digestion when there's no chance to escape
+       // all we can do in the stomach is kick and do some damage / try to escape
        if(self.eater.classname == "player" && time > self.decide_delay2)
        {
                // the higher the skill, the more the bot will kick in your stomack
                if(skill >= random_try)
-               if(self.team != self.eater.team) // if someone from the same team somehow made it in the belly, don't kick the eater
+               if not(teamplay && prey.team == self.team) // if someone from the same team somehow made it in the belly, don't kick the eater
                        self.BUTTON_ATCK = TRUE; // kick
 
-               // if the bot's health is smaller than this, the bot gives up and triggers your digestion upon them
-               // the higher the skill, the harder the bot will give up
-               else if(self.health < cvar("bot_ai_vore_decide_giveuphealth") / (skill + 1) && !self.eater.digesting)
-               if not(self.eater.digesting) // already happening so don't bother
-                       self.BUTTON_ATCK2 = TRUE; // trigger digestion
-
-       self.decide_delay2 = time + decide_prey; // time before the bot decides what to do with their predator
+               self.decide_delay2 = time + decide_prey; // time before the bot decides what to do with their predator
        }
 }
\ No newline at end of file