It is currently 14 May 2025, 03:20
   
Text Size

[fixed]Winter Orb - works incorrectly in multiples.

Moderators: BAgate, drool66, Aswan jaguar, gmzombie, stassy, CCGHQ Admins

[fixed]Winter Orb - works incorrectly in multiples.

Postby HarlequinCasts » 23 Sep 2014, 22:53

Describe the Bug:
Multiple Winter Orb s allow for the untapping of multiple lands. Multiple Winter Orb s should be redundant, only 1 land may untap no matter how many orbs.

I assume this card was recently re-coded since it was working previously.

This appears a separate bug from the earlier Winter Orb problem Here

Which card did behave improperly ?
Winter Orb

Which update are you using?(date,name)Which type(Duel,Gauntlet,Sealed Deck)
M15 mini update 2 sept 2014

What exactly should be the correct behavior/interaction ?
1 land untaps no matter how many Winter Orb s are in play.

Are any other cards possibly affected by this bug ?
Attachments
winter orb.zip
(4.64 KiB) Downloaded 199 times
Last edited by Aswan jaguar on 09 Aug 2020, 13:23, edited 3 times in total.
Reason: fixed bug
User avatar
HarlequinCasts
 
Posts: 922
Joined: 07 May 2013, 14:33
Has thanked: 68 times
Been thanked: 30 times

Re: [confirmed]Winter Orb - works incorrectly in multiples.

Postby FastEddie » 09 Aug 2020, 10:55

Again a partial fix that solves the original issue but introduces a new one...

The bug also affects Smoke (tested) and probably Damping Field (not tested). Reason is that untap_only_one_permanent_type is called for every card instance and "doesn't remember" it has been called already.

I patched untap_only_one_permanent_type to store the call in the chosen card and clear those flags during untap_phase. It gets called only once as designed but now two more lands untap and I don't know why... save game used for testing is attached.

unlimited.c
Code: Select all
--- ../github/June2020v3_20200705/cards/unlimited.c   2020-07-06 14:15:07.868862800 +0200
+++ ./cards/unlimited.c   2020-08-09 12:33:10.000000000 +0200
@@ -318,6 +318,19 @@
    if( current_phase == PHASE_UNTAP && event == EVENT_UNTAP && (current_turn == affected_player || affected_player == ANYBODY) &&
       (is_what(player, card, TYPE_EFFECT) || ! is_humiliated(player, card)) )
    {
+      // See whether another card of the same type has been marked for untapping to ensure only one permanent will be untapped
+      int c;
+      card_instance_t *helper;
+      for (c = 0; c < active_cards_count[player]; c++) {
+         if ((helper = in_play(player, c))) {
+            if (cards_data[helper->internal_card_id].type == type) {
+               if ((helper->untap_status & 3) == UNTAP_STATUS_WILL_UNTAP) {
+                  return;
+               }
+            }
+         }
+      }
+
       target_definition_t td;
       default_target_definition(player, card, &td, type);
       td.illegal_type = TYPE_ENCHANTMENT | TARGET_TYPE_PLANESWALKER;
@@ -352,7 +365,9 @@
       }
 
       if( is_what(affected_card_controller, affected_card, type) ){
+         // Lower two bits are deleted by convention, set UNTAP_STATUS_WILL_UNTAP to show this card will untap
          get_card_instance(affected_card_controller, affected_card)->untap_status &= ~3;
+         get_card_instance(affected_card_controller, affected_card)->untap_status |= UNTAP_STATUS_WILL_UNTAP;
       }
    }
engine.c
Code: Select all
--- ../github/June2020v3_20200705/functions/engine.c   2020-07-06 14:15:13.369891600 +0200
+++ ./functions/engine.c   2020-08-09 12:43:05.003557400 +0200
@@ -304,6 +304,17 @@
       else
         dispatch_event_with_attacker_to_one_card(player, c, EVENT_UNTAP_CARD, 1-player, -1);
      }
+
+  // Clear cards that have been marked as "untap only once" in untap_only_one_permanent_type
+  for (c = 0; c < active_cards_count[player]; ++c) {
+   if (untapped[c]) {
+      instance = in_play(player, c);
+      if ((instance->untap_status & 3) == UNTAP_STATUS_WILL_UNTAP) {
+         instance->untap_status &= ~3;
+      }
+   }
+  }
+
   // End additions
 
   recalculate_all_cards_in_play();
@@ -1590,7 +1601,6 @@
   // End additions
 
   int tapping_for_mana = (cards_data[iid].extra_ability & EA_MANA_SOURCE) && tapped_for_mana_color != -1;
-
   if (!tapping_for_mana && !cant_be_responded_to)
    allow_response_to_activation(player, card);
Attachments
WinterOrb.zip
(3.23 KiB) Downloaded 151 times
WinterOrbPatch.zip
(1.51 KiB) Downloaded 178 times
---
Argivian Archaeologist in the Library of Leng studying the Spells of the Ancients
User avatar
FastEddie
 
Posts: 246
Joined: 24 Dec 2019, 10:59
Has thanked: 15 times
Been thanked: 19 times

Re: [confirmed]Winter Orb - works incorrectly in multiples.

Postby Aswan jaguar » 09 Aug 2020, 13:22

Fixed in commit d2bd20, no pushed yet. Gargaroz had already fixed that for Static Orb and I applied the fix here and it works.
Code: Select all
void untap_only_one_permanent_type(int player, int card, event_t event, int affected_player, int type){

   card_instance_t *instance = get_card_instance(player, card);

   if( current_phase == PHASE_UNTAP && event == EVENT_UNTAP && (current_turn == affected_player || affected_player == ANYBODY) &&
      (is_what(player, card, TYPE_EFFECT) || ! is_humiliated(player, card)) )
   {

      int i;
      for(i=0; i<2; i++){
         int count = active_cards_count[i]-1;
         while( count > -1 ){
               if( in_play(i, count) && get_id(i, count) == get_id(player, card) && !(i == player && count == card) ){
                  get_card_instance(i, count)->info_slot = 2;
               }
               count--;
         }
      }

      target_definition_t td;
      default_target_definition(player, card, &td, type);
      td.illegal_type = TYPE_ENCHANTMENT | TARGET_TYPE_PLANESWALKER;
      td.allowed_controller = current_turn;
      td.preferred_controller = current_turn;
      td.who_chooses = current_turn;
      td.required_state = TARGET_STATE_TAPPED;
      td.illegal_abilities = 0;
      td.allow_cancel = 0;
      td.extra = (int32_t)can_be_untapped;
      td.special = TARGET_SPECIAL_EXTRA_FUNCTION;

      char buffer[100];
      int pos = scnprintf(buffer, 100, "Select a");
      if( type == TYPE_LAND ){
         pos+=scnprintf(buffer+pos, 100-pos, " land");
      }
      if( type == TYPE_CREATURE ){
         pos+=scnprintf(buffer+pos, 100-pos, " creature");
      }
      if( type == TYPE_ARTIFACT ){
         pos+=scnprintf(buffer+pos, 100-pos, "n artifact");
      }
      pos+=scnprintf(buffer+pos, 100-pos, " to untap.");

      while( instance->info_slot < 1 && can_target(&td) ){
            if( select_target(player, card, &td, buffer, &(instance->targets[0])) ){
               instance->number_of_targets = 1;
               untap_card(instance->targets[0].player, instance->targets[0].card);
               instance->info_slot++;
            }
      }

      if( is_what(affected_card_controller, affected_card, type) ){
         get_card_instance(affected_card_controller, affected_card)->untap_status &= ~3;
      }
   }

   if( event == EVENT_CLEANUP ){
      instance->info_slot = 0;
   }
}
---
Trying to squash some bugs and playtesting.
User avatar
Aswan jaguar
Super Tester Elite
 
Posts: 8129
Joined: 13 May 2010, 12:17
Has thanked: 748 times
Been thanked: 477 times


Return to Archived Reports

Who is online

Users browsing this forum: No registered users and 43 guests


Who is online

In total there are 43 users online :: 0 registered, 0 hidden and 43 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 43 guests

Login Form