It is currently 16 Apr 2024, 23:18
   
Text Size

[fixed]Soulflayer doesn't gain all abilities

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

[fixed]Soulflayer doesn't gain all abilities

Postby Aswan jaguar » 16 Sep 2018, 15:59

Describe the Bug:
I used delve with Soulflayer and exiled Spark Trooper but Soulflayer didn't get haste nor lifelink only trample ability.
I looked at the code and if I am not wrong it will not add also deathtouch, hexproof, indestructible and vigilance.
Which card did behave improperly?
Soulflayer

Which update are you using? (date, name)Which type? (duel, gauntlet, sealed deck)
Manalink dev 778ccb5 version - duel

What exactly should be the correct behavior/interaction?
Soulflayer : If a creature card with flying was exiled with Soulflayer's delve ability, Soulflayer has flying. The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, reach, trample, and vigilance.

Are any other cards possibly affected by this bug?
-
Attachments
soulflayer no lifelink, haste.rar
(3.74 KiB) Downloaded 140 times
Last edited by Aswan jaguar on 26 Oct 2023, 08:41, edited 1 time in total.
Reason: fixed
---
Trying to squash some bugs and playtesting.
User avatar
Aswan jaguar
Super Tester Elite
 
Posts: 8078
Joined: 13 May 2010, 12:17
Has thanked: 730 times
Been thanked: 458 times

Re: Soulflayer doesn't gain all abilities

Postby Aswan jaguar » 25 Oct 2023, 14:31

Can we now add special_abilities to Soulflayer? I tried but I always ended up with Soulflayer gaining an extra ability for each other keyword or sp_keyword ability.
---
Trying to squash some bugs and playtesting.
User avatar
Aswan jaguar
Super Tester Elite
 
Posts: 8078
Joined: 13 May 2010, 12:17
Has thanked: 730 times
Been thanked: 458 times

Re: Soulflayer doesn't gain all abilities

Postby drool66 » 25 Oct 2023, 18:01

Yep. One limitation was getting sp_keywords from an iid (we have since overcome this through has_sp_key_by_iid()). The other is carrying them over and storing them on the instance data. cast_spell_with_delve() is called on EVENT_CAST_SPELL, so we have an instance, and we can write the data directly to the instance rather than reading the return value of cast_spell_with_delve(). This is what Murktide Regent does.
The other issue is where to store it. It should properly be stored in instance_info, but we only have one full int (good for the regular keywords) and one int16_t. We can overcome this one of two ways - I would say we should re-enumerate all of SP_KEYWORD_REAL_KEYWORDS to the first 16 bits of sp_keyword_t (there are exactly 16 of them so huzzah). I doubt this would have unintended consequences, and if it does it means there is a problem elsewhere. The other way would be to store the relevant keywords in arbitrary bits of inst_info_t::data2, and then re-interpret them on every EVENT_ABILITIES. eg. store deathtouch at 1<<0 in data2, and then write SP_KEYWORD_DEATHTOUCH (ie. 1<<9) to ext::sp_keywords on EVENT_ABILITIES, store haste as 1<<1, and so on.
User avatar
drool66
Programmer
 
Posts: 1163
Joined: 25 Nov 2010, 22:38
Has thanked: 186 times
Been thanked: 267 times

Re: Soulflayer doesn't gain all abilities

Postby drool66 » 26 Oct 2023, 03:12

Here's some code:
future_sight.c::cast_spell_with_delve():
Code: Select all
...
      if( spell_fizzled != 1 ){
         int result = 2;
         int num_spells = 0, num_creatures = 0;
         const int *grave = get_grave(player);
         for(i=0; i<trc; i++){
            if( get_id(player, card) == CARD_ID_SOULFLAYER ){
               int ability_mask = KEYWORD_FIRST_STRIKE | KEYWORD_DOUBLE_STRIKE | KEYWORD_TRAMPLE | KEYWORD_FLYING | KEYWORD_REACH;
               int sp_ability_mask = SP_KEYWORD_DEATHTOUCH | SP_KEYWORD_HASTE | SP_KEYWORD_HEXPROOF | SP_KEYWORD_INDESTRUCTIBLE | SP_KEYWORD_LIFELINK | SP_KEYWORD_VIGILANCE;
               int sp_abilities = has_sp_key_by_iid(grave[targs[i].player, sp_ability_mask);
               int sp_ability_bits = 0;
               if( sp_abilities ){
                  if(sp_abilities & SP_KEYWORD_DEATHTOUCH)
                     sp_ability_bits |= 1<<0;
                  if(sp_abilities & SP_KEYWORD_HASTE)
                     sp_ability_bits |= 1<<1;
                  if(sp_abilities & SP_KEYWORD_HEXPROOF)
                     sp_ability_bits |= 1<<2;
                  if(sp_abilities & SP_KEYWORD_INDESTRUCTIBLE)
                     sp_ability_bits |= 1<<3;
                  if(sp_abilities & SP_KEYWORD_LIFELINK)
                     sp_ability_bits |= 1<<4;
                  if(sp_abilities & SP_KEYWORD_VIGILANCE)
                     sp_ability_bits |= 1<<5;
               }
               set_inst_info(instance, CARD_ID_SOULFLAYER,
                     inst_info(instance, CARD_ID_SOULFLAYER).data | (cards_data[grave[targs[i].player]].static_ability & ability_mask),
                     inst_info(instance, CARD_ID_SOULFLAYER).data2 | sp_ability_bits);
            }
...
fate_reforged.c::card_soulflayer()
Code: Select all
int card_soulflayer(int player, int card, event_t event){
   /*
     Soulflayer |4|B|B
     Creature - Demon
     Delve
     If a creature card with flying was exiled with ~'s delve ability, ~ has flying.
       The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, reach, trample, and vigilance.
     4/4
   */
   delve(player, card, event);

   if( event == EVENT_ABILITIES && affect_me(player, card) && ! is_humiliated(player, card, AL_STATIC) ){
      DECL_INST();
      event_result |= cards_data(inst, CARD_ID_SOULFLAYER).data;
      if( cards_data(inst, CARD_ID_SOULFLAYER).data2 ){
         if(cards_data(inst, CARD_ID_SOULFLAYER).data2 & 1<<0)
            deathtouch(player, card, event);
         if(cards_data(inst, CARD_ID_SOULFLAYER).data2 & 1<<1)
            haste(player, card, event);
         if(cards_data(inst, CARD_ID_SOULFLAYER).data2 & 1<<2)
            hexproof(player, card, event);
         if(cards_data(inst, CARD_ID_SOULFLAYER).data2 & 1<<3)
            indestructible(player, card, event);
         if(cards_data(inst, CARD_ID_SOULFLAYER).data2 & 1<<4)
            lifelink(player, card, event);
         if(cards_data(inst, CARD_ID_SOULFLAYER).data2 & 1<<5)
            vigilance(player, card, event);
      }
   }

   return 0;
}
User avatar
drool66
Programmer
 
Posts: 1163
Joined: 25 Nov 2010, 22:38
Has thanked: 186 times
Been thanked: 267 times

Re: Soulflayer doesn't gain all abilities

Postby Aswan jaguar » 26 Oct 2023, 08:41

Fixed in commit c34ea45, thanks drool66.
---
Trying to squash some bugs and playtesting.
User avatar
Aswan jaguar
Super Tester Elite
 
Posts: 8078
Joined: 13 May 2010, 12:17
Has thanked: 730 times
Been thanked: 458 times


Return to Pending Reports

Who is online

Users browsing this forum: No registered users and 10 guests


Who is online

In total there are 10 users online :: 0 registered, 0 hidden and 10 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 10 guests

Login Form