Page 1 of 1

AI check all possible attackers together then dismiss?

PostPosted: 06 Jan 2023, 09:51
by Aswan jaguar
Is it possible to force AI in EVENT_CHECK_ABILITIES or AI assign attackers maybe (though it needs a lot more testing then) when checking which creatures to assign as attackers to also check them all for attacking together and not only one by one and only then dismiss the ones that are not beneficial to attack with especially when AI could make the attack for the win. I am trying to make AI get how cards like Cavalry Pegasus work. The problem is that when AI checks Cavalry Pegasus as a potential attacker and sees that it will die in combat from human defender then it will not attack with it making his other creatures gain flying and go for the win (when human can't block so many fliers).

Re: AI check all possible attackers together then dismiss?

PostPosted: 07 Jan 2023, 00:34
by drool66
I think the closest we can get using existing architecture is:
if( event == EVENT_CHECK_ABILITIES && affected_card_controller == player && current_turn == player )
check_abilities_keywords |= KEYWORD_FLYING;

The ai already checks attackers in groups, but it doesn't check abilities for the whole group like you're saying. Look at engine.c::ai_declare_attackers() for where int combo is declared. The following loop is where each combo is checked.
Just to spitball an idea - you could possibly dispatch another EVENT_CHECK_ABILITIES there, but only read and augment abilities, since power and toughness were already added in setup_ai_combat_data(). You would have to cache and restore the abilities after each loop so they didn't carry over.
So ai_declare_attackers would add after what is currently line 3423, just before the first inner loop is closed:
Code: Select all
      int old_check_abilities_keywords = check_abilities_keywords;
       check_abilities_keywords = KEYWORD_0;

       {
         int old_activating_player = activating_player;
         activating_player = player;
         dispatch_event(player, attack_indices[i], EVENT_CHECK_ABILITIES);
         activating_player = old_activating_player;
       }

      ai_combat_attack_abils[num_attackers] |= check_abilities_keywords;
       check_abilities_keywords = old_check_abilities_keywords;
and Cavalry Pegasus would instead add:
Code: Select all
   if( event == EVENT_CHECK_ABILITIES && affected_card_controller == player && (get_card_instance(player, card)->state & STATE_ATTACKING) ){
      int i;
      for(i=0; i<num_attackers; i++){
         if( ai_combat_attack_card[i] == card ){
            check_abilities_keywords |= KEYWORD_FLYING;
            break;
         }
      }
   }
No idea if this would work or if it's a good idea, you'll have to check yourself. Luckily you're a great tester :D Also not sure if the loop in Cavalry Pegasus is necessary since STATE_ATTACKING is already checked.

Re: AI check all possible attackers together then dismiss?

PostPosted: 09 Jan 2023, 08:51
by Aswan jaguar
drool66 wrote:No idea if this would work or if it's a good idea, you'll have to check yourself.
I tested this and some variations of this but with no luck.