Page 1 of 1

[confirmed]Experimental Frenzy loops for AI

PostPosted: 02 Oct 2021, 16:50
by Aswan jaguar
Describe the Bug:
Experimental Frenzy if played by AI in AI's next turn AI will loop trying to play a land, works for human.
For now cards we have like this either loop for AI or AI ignores them and plays
lands as normal, Aggressive Mining is the case for latter and works only for human.
Which update are you using? (date, name)Which type? (duel, gauntlet, sealed deck)
dev c4e7027

What exactly should be the correct behavior/interaction?
No loop, it prevents AI from playing a land.

Are any other cards possibly affected by this bug?
-
Aggressive Mining different bugs here:
viewtopic.php?f=86&t=15288&p=243659#p243659

Re: Experimental Frenzy loops for AI

PostPosted: 23 Oct 2021, 18:18
by Aswan jaguar
I guess by mistake this was updated with test code with the work for auras and now not even human can cast cards or play lands from the top of his library.

Re: Experimental Frenzy loops for AI

PostPosted: 23 Oct 2021, 21:06
by drool66
Ugh, I'm seeing a few things I was working on made it through :/

Re: Experimental Frenzy loops for AI

PostPosted: 25 Oct 2021, 03:46
by drool66
I've worked on this for two days and I haven't gotten much of anywhere. Experimental Frenzy now only loops at the beginning of AI's next main phase 1, which makes me think it has something to do with TENTATIVE_LCBP_DURING_EITHER_MAIN_PHASE or TENTATIVE_LCBP_DURING_SECOND_MAIN_PHASE. Here's where I am at the moment:
Code: Select all
int card_experimental_frenzy(int player, int card, event_t event){
   /*
   CARD_ID_EXPERIMENTAL_FRENZY   19357
   Experimental Frenzy   |3|R
   Enchantment
   You may look at the top card of your library any time.
   You may play the top card of your library.
   You can't play cards from your hand.
   |3|R: Destroy ~.
   */
   if( event == EVENT_MODIFY_COST_GLOBAL )
      if( affected_card_controller == player && in_hand(affected_card_controller, affected_card) && !check_state(affected_card_controller, affected_card, STATE_INVISIBLE) )
         infinite_casting_cost();

   if( event == EVENT_STATIC_EFFECTS && current_turn == player ){
      if( !is_humiliated(player, card, AL_STATIC) ){
         player_bits[player] |= PB_COUNT_TOTAL_PLAYABLE_LANDS;
         land_can_be_played |= LCBP_LAND_HAS_BEEN_PLAYED;
         lands_played |= 0x100;  //the idea is that anything that plays lands from somewhere other than hand would lood for this
      }
      else{
         lands_played &= ~0x100;
         if( lands_played < total_playable_lands(player) ){
            land_can_be_played &= ~LCBP_LAND_HAS_BEEN_PLAYED;
         }
      }
   }

   leaves_play(player, card, event, 0, 0);
   if( event == EVENT_LEAVES_PLAY_ABILITY ){
      lands_played &= ~0x100;
      if( lands_played < total_playable_lands(player) )
         land_can_be_played &= ~LCBP_LAND_HAS_BEEN_PLAYED;
   }

   if(!IS_GAA_EVENT(event))
      return global_enchantment(player, card, event);

   if( event == EVENT_CAN_ACTIVATE ){
      if( get_card_instance(player, card)->targets[9].card == 66 )
         return 0;
      int rv = 0, iid = deck_ptr[player][0];
      if( iid != -1 && is_what(-1, iid, TYPE_LAND) && !(is_humiliated(player, card, AL_STATIC)) ){
         if( (lands_played & ~0x100) < total_playable_lands(player) && can_sorcery_be_played(player, event) && current_turn == player)
            return 1;
      }
      else if( iid != -1 && has_mana_to_cast_iid(player, event, iid) && (rv = can_legally_play_iid_now(player, iid, event)) && !(is_humiliated(player, card, AL_STATIC)) ){
         return rv;
      }
      return( (iid != -1 && player != AI && !(is_humiliated(player, card, AL_STATIC))) || generic_activated_ability(player, card, event, 0, MANACOST_XR(3, 1), 0, NULL, NULL) );
   }

   enum{
      CHOICE_REVEAL = 1,
      CHOICE_PLAY,
      CHOICE_DESTROY,
   };

   if( event == EVENT_ACTIVATE ){
      card_instance_t* inst = get_card_instance(player, card);
      inst->targets[9].card = 66;
      int iid = deck_ptr[player][0];
      int ab1 = !IS_AI(player) && iid != -1;
      int ab2 = 0;
      if( iid != -1 && is_what(-1, iid, TYPE_LAND) ){

         if( IS_AI(player) ){
            if( (lands_played & ~0x100) < total_playable_lands(player) && can_sorcery_be_played(player, event) && current_turn == player){
               play_card_in_deck_for_free(player, player, 0);
               inst->targets[9].card = 0;
               return 0;
            }
         }
         else if( (lands_played & ~0x100) < total_playable_lands(player) && can_sorcery_be_played(player, event) && current_turn == player)
            ab2 = 1;
      }
      else if( iid != -1 && has_mana_to_cast_iid(player, event, iid) && can_legally_play_iid_now(player, iid, event) ){
         ab2 = 1;
      }
      int ab3 = generic_activated_ability(player, card, EVENT_CAN_ACTIVATE, 0, MANACOST_XR(3,1), 0, NULL, NULL);

      int choice = DIALOG(player, card, event, DLG_RANDOM, DLG_AUTOCHOOSE_IF_1, DLG_NO_STORAGE,
                     "Check top card of deck", ab1, 0,
                     "Play top card", ab2, 10,
                     "Destroy Experimental Frenzy", ab3, ab2 ? -10 : 5);
      if( ! choice ){
         inst->targets[9].card = 0;
         spell_fizzled = 1;
         return 0;
      }
      if( choice == CHOICE_REVEAL ){
         show_deck( player, deck_ptr[player], 1, "Here's the top card of your deck", 0, 0x7375B0 );
         inst->targets[9].card = 0;
         spell_fizzled = 1;
      }
      if( choice == CHOICE_PLAY ){
         if( is_what(-1, deck_ptr[player][0], TYPE_LAND) ){
            int old_lcbp = land_can_be_played;
            land_can_be_played &= ~(LCBP_LAND_HAS_BEEN_PLAYED | LCBP_SPELL_BEING_PLAYED);
            lands_played &= ~0x100;
            play_card_in_deck_for_free(player, player, 0);
            land_can_be_played = old_lcbp;
            lands_played |= 0x100;
            cant_be_responded_to = 1;
         }
         else if( charge_mana_from_id(player, -1, event, cards_data[deck_ptr[player][0]].id) ){
            play_card_in_deck_for_free(player, player, 0);
            cant_be_responded_to = 1;
         }
         inst->targets[9].card = 0;
      }
      if( choice == CHOICE_DESTROY ){
         inst->targets[9].card = 0;
         inst->info_slot = choice;
         return generic_activated_ability(player, card, event, 0, MANACOST_XR(3,1), 0, NULL, NULL);
      }
   }

   if( event == EVENT_RESOLVE_ACTIVATION )
      if( get_card_instance(player, card)->info_slot == CHOICE_DESTROY )
         kill_card(get_card_instance(player, card)->parent_controller, get_card_instance(player, card)->parent_card, KILL_DESTROY);

   return 0;
}