Page 1 of 5

[REL] DotP 2014 - Core Fixes Mod v2.01

PostPosted: 18 Jul 2013, 14:55
by RiiakShiNal
This mod contains card fixes for buggy official cards in DotP 2014. This does not fix custom cards, does not include art, decks, or other game changes.

Now contains Chinese Text for all fixed items (thanks to Tigertooth).

List of Fixed Items | Open
Cards:
Text Entries:
  • Tribal Enchantment (thanks to thefiremind)


Requirements:

Additional Information:

Download:

Re: [REL] DotP 2014 - Core Fixes Mod v1.0

PostPosted: 18 Jul 2013, 18:11
by sumomole
Protean Hydra's last ability will make it add counters, even if it had left the battlefield or isn't already on the battlefield.
Original Code | Open
Code: Select all
  <TRIGGERED_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Whenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.]]></LOCALISED_TEXT>
    <TRIGGER value="COUNTERS_CHANGED" simple_qualifier="self">
    if GetAmount() &lt;0 and CounterTypeIndex() == MTG():PlusOnePlusOneCounters() then
       return true
    else
       return false
    end
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    local triggerObject = TriggerObject()
    if triggerObject ~= nil then
       local delayDC = EffectDC():Make_Chest(1)
       delayDC:Set_Int(0, GetAmount() )
       MTG():CreateDelayedTrigger(2, delayDC)
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <TRIGGERED_ABILITY resource_id="2">
    <TRIGGER value="BEGINNING_OF_STEP">
    return MTG():GetStep() == STEP_END_OF_TURN
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    local number = EffectDC():Get_Int(0)*-1
    if EffectSource() ~= nil then
       EffectSource():AddCounters( MTG():PlusOnePlusOneCounters(), number*2 )
    end
    </RESOLUTION_TIME_ACTION>
    <CLEANUP fire_once="1" />
  </TRIGGERED_ABILITY>
Fixed code | Open
Code: Select all
  <TRIGGERED_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Whenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.]]></LOCALISED_TEXT>
    <TRIGGER value="COUNTERS_CHANGED" simple_qualifier="self">
    return GetAmount() &lt;0 and CounterTypeIndex() == MTG():PlusOnePlusOneCounters()
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil then
       local delayDC = EffectDC():Make_Chest(1)
       delayDC:Set_CardPtr(0, TriggerObject())
      for i=1,-GetAmount() do
         MTG():CreateDelayedTrigger(2, delayDC)
      end
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <TRIGGERED_ABILITY resource_id="2">
    <CLEANUP fire_once="1" />
    <TRIGGER value="BEGINNING_OF_STEP">
    return MTG():GetStep() == STEP_END_OF_TURN
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    local creature = EffectDC():Get_CardPtr(0)
    if creature ~= nil then
       creature:AddCounters( MTG():PlusOnePlusOneCounters(), 2 )
    end
    </RESOLUTION_TIME_ACTION>
    <AUTO_SKIP>
    local target = EffectDC():Get_CardPtr(0)
    if target ~= nil then
       return false
    else
       return true
    end
    </AUTO_SKIP>
  </TRIGGERED_ABILITY>

Re: [REL] DotP 2014 - Core Fixes Mod v1.01

PostPosted: 18 Jul 2013, 19:01
by RiiakShiNal

Edit: Now updated to v1.02 with fixed layers for Drove of Elves, Heedless One, and Krovikan Mist (thanks to thefiremind for pointing them out).

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 22:21
by sumomole
When I tested undying and evolve, I found the official undying code is wrong, it's return creature to the battlefield and put a +1/+1 counter on it, not with a +1/+1 counter on it, so evolve ability won't be triggered.
I'm not sure the fixed code is completely correct, I just tested once, it worked fine and could trigger evolve ability.
Original Undying | Open
Code: Select all
  <TRIGGERED_ABILITY badge="BADGE_UNDYING" active_zone="ZONE_BATTLEFIELD">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Undying]]></LOCALISED_TEXT>
    <TRIGGER value="ZONECHANGE_BEGIN" simple_qualifier="self" to_zone="ZONE_GRAVEYARD" from_zone="ZONE_BATTLEFIELD" />
    <INTERVENING_IF ignore_resolution_check="1">
    if TriggerObject():CountCounters(MTG():PlusOnePlusOneCounters()) == 0 then
       return true
    else
       return false
    end
    </INTERVENING_IF>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil then
       EffectDC():Protect_CardPtr( COMPARTMENT_ID_PARAM_TRIGGER_OBJECT )
       TriggerObject():PutOntoBattlefield( TriggerObject():GetOwner() )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil then
       TriggerObject():AddCounters( MTG():PlusOnePlusOneCounters(), 1)
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
Fixed code? | Open
Code: Select all
  <TRIGGERED_ABILITY badge="BADGE_UNDYING" active_zone="ZONE_BATTLEFIELD">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Undying]]></LOCALISED_TEXT>
    <TRIGGER value="ZONECHANGE_BEGIN" simple_qualifier="self" to_zone="ZONE_GRAVEYARD" from_zone="ZONE_BATTLEFIELD" />
    <INTERVENING_IF ignore_resolution_check="1">
    if TriggerObject():CountCounters(MTG():PlusOnePlusOneCounters()) == 0 then
       return true
    else
       return false
    end
    </INTERVENING_IF>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil and TriggerObject():IsToken() == false then
       local delayDC = EffectDC():Make_Chest(1)
       delayDC:Set_CardPtr(0, TriggerObject())
       delayDC:Protect_CardPtr(0)
       MTG():CreateDelayedTrigger(1, delayDC)
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil then
       TriggerObject():PutOntoBattlefield( TriggerObject():GetOwner() )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    MTG():RemoveDelayedTrigger(1)
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <TRIGGERED_ABILITY resource_id="1" replacement_effect="1">
    <TRIGGER value="ZONECHANGE_TRANSITION" to_zone="ZONE_BATTLEFIELD" from_zone="ZONE_ANY">
    return TriggerObject() == EffectDC():Get_CardPtr(0)
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil then
       TriggerObject():AddCounters( MTG():PlusOnePlusOneCounters(), 1)
    end
    </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
EDIT: Updated to the simplify code.

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 22:29
by thefiremind
Why not putting <CLEANUP fire_once="1" /> into the first delayed trigger instead of cleaning it up with a second delayed trigger?

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 22:40
by sumomole
thefiremind wrote:Why not putting <CLEANUP fire_once="1" /> into the first delayed trigger instead of cleaning it up with a second delayed trigger?
Because Grafdigger's Cage, even if it can't return to the battlefield, delayed trigger won't be remove, the next time some effect put it onto the battlefield, delayed trigger will trigger.

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 22:55
by thefiremind
I suppose Grafdigger's Cage is another one of those cards that would require us to review all the cards we already made in search for incompatibilities... #-o

Since I'm still looking for a way to simplify that code, have you tried to do this?
Code: Select all
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil and TriggerObject():IsToken() == false then
       local delayDC = EffectDC():Make_Chest(1)
       delayDC:Set_CardPtr(0, TriggerObject())
       delayDC:Protect_CardPtr(0)
       MTG():CreateDelayedTrigger(1, delayDC)
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    if TriggerObject() ~= nil then
       TriggerObject():PutOntoBattlefield( TriggerObject():GetOwner() )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    MTG():RemoveDelayedTrigger(1)
    </RESOLUTION_TIME_ACTION>
Theoretically, the card should be already on the battlefield when the third RESOLUTION_TIME_ACTION starts, so this should work without having 2 delayed triggers. But that's just theory, it needs testing. :D

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 23:05
by sumomole
thefiremind wrote:I suppose Grafdigger's Cage is another one of those cards that would require us to review all the cards we already made in search for incompatibilities... #-o
Since I'm still looking for a way to simplify that code, have you tried to do this?Theoretically, the card should be already on the battlefield when the third RESOLUTION_TIME_ACTION starts, so this should work without having 2 delayed triggers. But that's just theory, it needs testing. :D
Yes, I have also thought a delayed trigger ability cancel itself, but now I need to code a Grafdigger's Cage first. :lol:

EDIT: I tested the RemoveDelayedTrigger behind on PutOntoBattlefield really can cancel delay trigger ability, so your simplified code is right. :wink:

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 23:08
by Parabolic
I was playing today without mods, and got this:

[lua] [string "MINDLEECH_MASS_357873_TITLE (RESOLUTION_TIME_ACTION)~0x0000060f"]:2: attempt to index a nil value
This was repeated hundreds of times in the Script_Log, so it wasn't happy about something.

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 23:13
by thefiremind
Parabolic wrote:I was playing today without mods, and got this:

[lua] [string "MINDLEECH_MASS_357873_TITLE (RESOLUTION_TIME_ACTION)~0x0000060f"]:2: attempt to index a nil value
This was repeated hundreds of times in the Script_Log, so it wasn't happy about something.
Yes, I think I understood the problem: if SecondaryPlayer() is nil, the first RESOLUTION_TIME_ACTION doesn't initialize the target chest. The fix is easy:
Code: Select all
local card = EffectDC():Get_Targets(0):Get_CardPtr(0)
in the second RESOLUTION_TIME_ACTION should be changed to
Code: Select all
local card = EffectDC():Get_Targets(0) and EffectDC():Get_Targets(0):Get_CardPtr(0)
(as pcastellazzi taught me. :D)

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 19 Jul 2013, 23:50
by RiiakShiNal
thefiremind wrote:Yes, I think I understood the problem: if SecondaryPlayer() is nil, the first RESOLUTION_TIME_ACTION doesn't initialize the target chest. The fix is easy:
Code: Select all
local card = EffectDC():Get_Targets(0):Get_CardPtr(0)
in the second RESOLUTION_TIME_ACTION should be changed to
Code: Select all
local card = EffectDC():Get_Targets(0) and EffectDC():Get_Targets(0):Get_CardPtr(0)
(as pcastellazzi taught me. :D)
It's probably more along the lines of the SecondaryPlayer had no cards in hand, though the fix is the same.

It's going to take me a little bit of time to get the it updated again because I'm kind of in the middle of something else at the moment. Though I'll get it up relatively soon.

Edit: Updated with some minor changes to the Undying code.

Edit 2: Crap, I just realized that now Undying doesn't work for Mikaeus, the Unhallowed because it is granting the ability to other cards which then don't have the delayed trigger ability. Stand by while I try to figure out a way to make THAT work.

Edit 3: Nothing is coming to me at the moment, so for the time being I have reverted to not include Mikaeus, the Unhallowed until I can come up with a proper fix for him (I'll probably have to do something overly complicated using my fake ObjectDC, though I'm trying to avoid that).

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 20 Jul 2013, 09:30
by thefiremind
RiiakShiNal wrote:Edit 2: Crap, I just realized that now Undying doesn't work for Mikaeus, the Unhallowed because it is granting the ability to other cards which then don't have the delayed trigger ability. Stand by while I try to figure out a way to make THAT work.

Edit 3: Nothing is coming to me at the moment, so for the time being I have reverted to not include Mikaeus, the Unhallowed until I can come up with a proper fix for him (I'll probably have to do something overly complicated using my fake ObjectDC, though I'm trying to avoid that).
I thought about that while I was turning my PC off... :( I'd really like to find some alternative... or we could just leave Mikaeus, the Unhallowed (and the other instant that grants undying until end of turn, can't remember the name) with the old code, and live with the approximation.
I'll definitely keep thinking about a better solution, anyway.

Re: [REL] DotP 2014 - Core Fixes Mod v1.04

PostPosted: 20 Jul 2013, 14:35
by drleg3nd
hey lifelink in sliver deck is bugged it only supposed to revive first creature but it revives any creature that dies

Re: [REL] DotP 2014 - Core Fixes Mod v1.04

PostPosted: 20 Jul 2013, 15:05
by thefiremind
drleg3nd wrote:hey Lifeline in sliver deck is bugged it only supposed to revive first creature but it revives any creature that dies
"Return the first card" means the first creature the ability is talking about, that is the one that died. Wouldn't it be weird to have an artifact that works only once but stays on the battlefield anyway?

--------------------------------------------

EDIT: I found a TEXT_PERMANENT error: the localised strings for Tribal Enchantment have the 2 types inverted, even in English (who wrote them? :lol:). I found the same strings in another XML file, this time in the correct order, so if you want to start a TEXT_PERMANENT folder in the core fixes, here's the first entry to add:
Code: Select all
   <Row>
    <Cell><Data ss:Type="String">COMPOUND_TYPE_ENCHANTMENT_TRIBAL</Data></Cell>
    <Cell ss:Index="3"><Data ss:Type="String">Tribal Enchantment</Data></Cell>
    <Cell><Data ss:Type="String">Enchantement tribal</Data></Cell>
    <Cell><Data ss:Type="String">Encantamiento tribal</Data></Cell>
    <Cell><Data ss:Type="String">Stammesverzauberung</Data></Cell>
    <Cell><Data ss:Type="String">Incantesimo Tribale</Data></Cell>
    <Cell ss:Index="9"><Data ss:Type="String">部族エンチャント</Data></Cell>
    <Cell><Data ss:Type="String">트라이벌 부여마법</Data></Cell>
    <Cell><Data ss:Type="String">Племенные Чары</Data></Cell>
    <Cell><Data ss:Type="String">Encantamento Tribal</Data></Cell>
   </Row>

Re: [REL] DotP 2014 - Core Fixes Mod v1.02

PostPosted: 20 Jul 2013, 22:05
by RiiakShiNal
thefiremind wrote:I thought about that while I was turning my PC off... :( I'd really like to find some alternative... or we could just leave Mikaeus, the Unhallowed (and the other instant that grants undying until end of turn, can't remember the name) with the old code, and live with the approximation.
I'll definitely keep thinking about a better solution, anyway.
Well, I think I found a solution. It's hideously complex and there is still a couple of minor things (like getting the Undying badge to show up properly) I'm trying to work out, but here is the gist of it. I created a fake characteristic system that is built using and on top of my ObjectDC functions (I didn't really want to have to use them, but I couldn't find any other way). Cards that use the fake characteristic system will need to create a characteristic manager token when the game starts (to make sure it is always in effect and no token doubling/modifications are yet in play, at most we want one per player in case a player dies and all their cards/permanents/tokens get removed). The characteristic manager's main function is to clear the fake characteristics from all cards (in any and all zones) at the lowest continuous action layer (layer 0, this allows the characteristics to be easily and reliably removed if the card changes zones, controllers, ceases to be meet the conditions for the ability, etc...) at higher levels (I recommend adding the ability at layer 5 then in that ability use layer 6 to set the characteristic) the fake characteristics can then be added by the cards/abilities that need to add them (I have some functions to make all this easy). So for our example with Mikaeus, the Unhallowed we have him assign a simple ability to the cards he affects which simply adds the fake characteristic to the card and has some text so we know it has been added (this allows the system to work with cards like Ovinize and Turn to Frog which uses LoseAllAbilities()). Now we have a token in play that acts as that ability's manager (I'm building Undying and Persist directly into the characteristics manager to keep the tokens to a minimum) which actually has the real abilities for the characteristic and will call them on the other card's behalf if and only if the other card currently has the characteristic (it won't have the characteristic if it lost all abilities because the granted ability that would bestow the characteristic has been turned off). This allows the abilities to correctly trigger if and only if the card should really get them.

While this is quite complex it should work under all conditions (as the token has shroud and other abilities to make sure it can't lose all it's abilities). The system should also be fairly flexible so that other people can add their own ability managers (for abilities like unearth) then piggy-back the creation onto the creation of the characteristics manager. If I have missed something conceptually then please tell me so I can try to address that before I release this system and the updated core fixes to include Mikaeus, the Unhallowed.

thefiremind wrote:EDIT: I found a TEXT_PERMANENT error: the localised strings for Tribal Enchantment have the 2 types inverted, even in English (who wrote them? :lol:). I found the same strings in another XML file, this time in the correct order, so if you want to start a TEXT_PERMANENT folder in the core fixes, here's the first entry to add:
I'll add one in the next update.