It is currently 17 Jun 2019, 21:34
   
Text Size

General DotP 2014 Coding Questions

Moderators: Xander9009, CCGHQ Admins

Re: General DotP 2014 Coding Questions

Postby Rockenchick » 30 Oct 2015, 15:07

RiiakShiNal wrote:The problem is on this line:
Code: Select all
EffectSourceLKI():Damage():PreventAll(), TriggerObject():GetPlayer())
The line should be:
Code: Select all
Damage():PreventAll()
  • Damage() is a global function (not part of the card object).
  • Parenthesis are mismatched (extra close at the end of the line).
  • PreventAll() does not take any parameters and you can't separate statements using ",".
  • There is no point in having TriggerObject():GetPlayer() there since we don't need the source's controller for anything.
I'm so grateful, it finally works! :D
I was really relying far too much on code from a card rather than using logic it seems.
Rockenchick
 
Posts: 21
Joined: 16 Oct 2015, 05:05
Has thanked: 4 times
Been thanked: 2 times

Re: General DotP 2014 Coding Questions

Postby Rockenchick » 06 Nov 2015, 02:21

Having issues with getting Brand to work. I tried using ( FE_IS_PERMANENT) and GetOwner (although I have no idea where GetOwner should be placed if it should at all, so I was just guessing). Testing conditions were against a deck that played Act of Treason (really that's all the deck has besides land cards to keep conflicts low) and whenever one of my creatures is stolen for the turn using Brand doesn't do anything.

These are the 2 forms of code I've tried without success:
Code: Select all
<FILTER filter_id="0">
         local filter = ClearFilter()
         filter:Add( FE_IS_PERMANENT, true )
         filter:Add( FE_OWNER, OP_IS, EffectController())
      </FILTER>
      <CONTINUOUS_ACTION layer="2" filter_id="0">
    local card = FilteredCard()
    if card ~= nil then
       card:SetController(EffectController())
                    end
      </CONTINUOUS_ACTION>
Code: Select all
<FILTER filter_id="0">
         local filter = ClearFilter()
         filter:Add( FE_IS_PERMANENT, true )
      </FILTER>
      <CONTINUOUS_ACTION layer="2" filter_id="0">
    local card = FilteredCard()
    if card ~= nil then
       card:GetOwner():SetController(EffectController())
                    end
      </CONTINUOUS_ACTION>
Rockenchick
 
Posts: 21
Joined: 16 Oct 2015, 05:05
Has thanked: 4 times
Been thanked: 2 times

Re: General DotP 2014 Coding Questions

Postby Xander9009 » 06 Nov 2015, 03:33

(This is not the solution, just a note.) In the second attempt, this line is messed up:
Code: Select all
card:GetOwner():SetController(EffectController())
GetOwner returns the owner, a player. So, that line tries to set the owner themselves to be controlled by EffectController(). Essentially, it's doing this:
Code: Select all
Player:SetController(Player)
For that to work, you'd need it to check that the owner is effect controller, and if so, set the controller to effect controller.
Code: Select all
<FILTER filter_id="0">
  local filter = ClearFilter()
  filter:Add(FE_IS_PERMANENT, true)
</FILTER>
<CONTINUOUS_ACTION layer="2" filter_id="0">
  local Card = FilteredCard()
  if Card ~= nil and Card:GetOwner() == EffectController() then
    Card:SetController(EffectController())
  end
</CONTINUOUS_ACTION>
The reason it's not working could be because you don't have a duration. Static abilities can have continuous actions without durations. All other types of abilities MUST have a duration block, even if it's not actually going to do anything because the ability is indefinite. Duration blocks return true when the duration is up and the effect should end. Since you don't want that to ever happen:
Code: Select all
<DURATION>
  return false
</DURATION>
Try that and see if it does anything different.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2880
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 116 times
Been thanked: 435 times

Re: General DotP 2014 Coding Questions

Postby Rockenchick » 06 Nov 2015, 05:17

Xander9009 wrote:The reason it's not working could be because you don't have a duration. Static abilities can have continuous actions without durations. All other types of abilities MUST have a duration block, even if it's not actually going to do anything because the ability is indefinite. Duration blocks return true when the duration is up and the effect should end. Since you don't want that to ever happen:
Code: Select all
<DURATION>
  return false
</DURATION>
Try that and see if it does anything different.
Leaving off a duration was indeed the issue, the first code I presented works fine with that duration added. Thanks for letting me it's needed for most actions.
Rockenchick
 
Posts: 21
Joined: 16 Oct 2015, 05:05
Has thanked: 4 times
Been thanked: 2 times

Re: General DotP 2014 Coding Questions

Postby RiiakShiNal » 06 Nov 2015, 19:28

Or you could have just called SetBaseController() in a RESOLUTION_TIME_ACTION instead of using a CONTINUOUS_ACTION since that would be more accurate (and keep the number of running effects that have to be calculated to a minimum).
Problems with base game cards: DotP 2014 Core Fixes
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
RiiakShiNal
Programmer
 
Posts: 2115
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 468 times

Re: General DotP 2014 Coding Questions

Postby Rockenchick » 09 Nov 2015, 04:25

Having an issue with Lingering Death. I can't seem to find a way for the end step to be recognised as the controller of the creature it's attached to, instead the action is activated on my end step. Looking at the code it says controller, so I take it the enchantment is being seen as being controlled by whomever attached it, even though it's on another players creature, that does make sense, I guess. However, can't find a function to get it to recognise the controller should whomever is the controller of the creature it's attached to.

Code: Select all
<TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller" to_zone="ZONE_ANY" from_zone="ZONE_ANY">
    return MTG():GetStep() == STEP_END_OF_TURN
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
         local parent = EffectSourceLKI():GetParent()
         if parent ~= nil then
            parent:GetPlayer():Sacrifice( parent )
         end
      </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
Rockenchick
 
Posts: 21
Joined: 16 Oct 2015, 05:05
Has thanked: 4 times
Been thanked: 2 times

Re: General DotP 2014 Coding Questions

Postby thefiremind » 09 Nov 2015, 09:46

Rockenchick wrote:However, can't find a function to get it to recognise the controller should whomever is the controller of the creature it's attached to.
Since you are using BEGINNING_OF_PLAYERS_STEP, the player playing the current turn is inside TriggerPlayer, so you just need to check if it's the same as the creature's controller. Incidentally, when you are using simple_qualifier="controller", you are basically using a shortcut for TriggerPlayer() == EffectController().
Code: Select all
    <TRIGGER value="BEGINNING_OF_PLAYERS_STEP">
    if MTG():GetStep() == STEP_END_OF_TURN and
        ((TriggerPlayer() and EffectSource()) and EffectSource():GetParent() ~= nil) then
        return TriggerPlayer() == EffectSource():GetParent():GetController()
    end
    return false
    </TRIGGER>
(The from_zone and to_zone attributes are useless in a trigger that doesn't check for zone changes, I know you can find them on official cards, but they are probably result of careless copy-pasting.)
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 717 times

Re: General DotP 2014 Coding Questions

Postby xanthics » 05 Dec 2015, 10:06

DotP 2014 -- Community WAD

In my journey to make the AI less terrible with dual lands I've been experimenting with having the land type randomized if the controller is AI. However my current implementation proves to be very time consuming(about 2 seconds per dual land). Is there a better way to code this block? Right now its checking, during upkeep -> is controller ai -> if yes choose random.


Code: Select all
   <TRIGGERED_ABILITY linked_ability_group="1">
      <TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller">
         return MTG():GetStep() == STEP_UPKEEP and EffectController():IsAI() == true
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         LinkedDC():Set_Int( 0, MTG():RandomNumberBetween(0, 1) )
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
xanthics
 
Posts: 13
Joined: 26 Jan 2015, 04:57
Has thanked: 2 times
Been thanked: 1 time

Re: General DotP 2014 Coding Questions

Postby Xander9009 » 05 Dec 2015, 18:01

If you add replacement_effect="1" to the triggered_ability tag, it won't get a resolution timer.

Code: Select all
   <TRIGGERED_ABILITY replacement_effect="1" linked_ability_group="1">
      <TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller">
         return MTG():GetStep() == STEP_UPKEEP and EffectController():IsAI() == true
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         LinkedDC():Set_Int( 0, MTG():RandomNumberBetween(0, 1) )
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2880
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 116 times
Been thanked: 435 times

Re: General DotP 2014 Coding Questions

Postby xanthics » 06 Dec 2015, 02:31

That fixed it for me. :) Trying the following out for a few days with a friend to see if it breaks anything.. But has been playing nicely so far.

This is my terrible, thrown together Python3 code for modifying all the multimana cards.

Code: Select all
import os

def main():

    aiMana = '''   <TRIGGERED_ABILITY replacement_effect="1" linked_ability_group="1">
      <TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller">
         return MTG():GetStep() == STEP_UPKEEP and EffectController():IsAI() == true
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         LinkedDC():Set_Int( 0, MTG():RandomNumberBetween(0, {}) )
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
'''

    root = "C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Magic 2014 - Custom\\Modified Gibbed Tools r6_b10 " \
           "Binaries\\DATA_DLC_COMMUNITY_CORE_unpacked\\DATA_DLC_COMMUNITY_CORE\\DATA_ALL_PLATFORMS\\CARDS\\"
    for r, d, f in os.walk(root):
        for i in f:
            with open(root + i, 'r', encoding="utf8") as fi:
                x = fi.read()
                if "\"CARD_QUERY_CHOOSE_COLOUR\"" in x and x.count("</MANA_ABILITY>") > 1:
                    cou = x.count("</MANA_ABILITY>")
                    xx = 0
                    fi.seek(0)
                    fi2 = fi.readlines()
                    for l in fi2:
                        if "MANA_ABILITY resource_id" in l:
                            break
                        xx += 1

                    print(cou, i)
                    with open(root + i, 'w', encoding="utf8") as fo:
                        for l in fi2[:xx]:
                            fo.write(l)
                        fo.write(aiMana.format(cou-1))
                        for l in fi2[xx:]:
                            fo.write(l)


if __name__ == '__main__':
    main()
xanthics
 
Posts: 13
Joined: 26 Jan 2015, 04:57
Has thanked: 2 times
Been thanked: 1 time

Re: General DotP 2014 Coding Questions

Postby Xander9009 » 06 Dec 2015, 03:01

xanthics wrote:That fixed it for me. :) Trying the following out for a few days with a friend to see if it breaks anything.. But has been playing nicely so far.

This is my terrible, thrown together Python3 code for modifying all the multimana cards.

Code: Select all
import os

def main():

    aiMana = '''   <TRIGGERED_ABILITY replacement_effect="1" linked_ability_group="1">
      <TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller">
         return MTG():GetStep() == STEP_UPKEEP and EffectController():IsAI() == true
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         LinkedDC():Set_Int( 0, MTG():RandomNumberBetween(0, {}) )
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
'''

    root = "C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Magic 2014 - Custom\\Modified Gibbed Tools r6_b10 " \
           "Binaries\\DATA_DLC_COMMUNITY_CORE_unpacked\\DATA_DLC_COMMUNITY_CORE\\DATA_ALL_PLATFORMS\\CARDS\\"
    for r, d, f in os.walk(root):
        for i in f:
            with open(root + i, 'r', encoding="utf8") as fi:
                x = fi.read()
                if "\"CARD_QUERY_CHOOSE_COLOUR\"" in x and x.count("</MANA_ABILITY>") > 1:
                    cou = x.count("</MANA_ABILITY>")
                    xx = 0
                    fi.seek(0)
                    fi2 = fi.readlines()
                    for l in fi2:
                        if "MANA_ABILITY resource_id" in l:
                            break
                        xx += 1

                    print(cou, i)
                    with open(root + i, 'w', encoding="utf8") as fo:
                        for l in fi2[:xx]:
                            fo.write(l)
                        fo.write(aiMana.format(cou-1))
                        for l in fi2[xx:]:
                            fo.write(l)


if __name__ == '__main__':
    main()
It's a pretty good idea, but it's unnecessary. I already have a tool to add code to all relevant cards. If it works out nicely, I'll see about running it on that ability. My main concern is that there is a better way to do it, it's just more complicated. That is, determine the cards in hand it's possible to cast with the current mana producers, and then set those mana producers to specific colors so as many cards can be cast as possible. I'm not doing anything at the moment, so I'll consider looking into this again. I've gotten a bit more experience since I last attempted it, so it may go more smoothly. For now, though, that's certainly better than dual lands only being usable for one color.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2880
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 116 times
Been thanked: 435 times

Re: General DotP 2014 Coding Questions

Postby xanthics » 08 Dec 2015, 10:30

Using random mana for multi-select sources has been working well. Computer definitely feels a lot more active. Bugs Chrome Mox so that the computer can just use any color, but the computer doesn't use imprint correct anyways(never selects a card to exile on any card with imprint). Probably bugs Coldsteel Heart and similar for the computer, but it always chooses black for those anyways.
xanthics
 
Posts: 13
Joined: 26 Jan 2015, 04:57
Has thanked: 2 times
Been thanked: 1 time

Re: General DotP 2014 Coding Questions

Postby Xander9009 » 29 Apr 2016, 00:58

Quick question, mostly for Riiak. What all is required to add a subtype? Specifically, the new artifact type, Clue? I added this to a lol file:
Code: Select all
ARTIFACT_TYPE_COUNT = 4
ARTIFACT_TYPE_CLUE = 3
Note that CARD_TYPE_ARTIFACT is 0, so the band starts at 0. ARTIFACT_TYPE_FORTIFICATION is 2.

I also added "CARD_SUBTYPE_CLUE" to a text permanent file. But that's how creature types were done. I wouldn't expect it would be different for artifacts, but I don't know. It's also how planeswalkers were done, as far as I know. I checked that ARTIFACT_TYPE_CLUE is 3 like it should be, but "Clue" doesn't appear on the tokens. I checked that they have
Code: Select all
<TYPE metaname="Artifact" />
<SUB_TYPE metaname="Clue" />
I'm not sure what else to do. Any thoughts?
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2880
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 116 times
Been thanked: 435 times

Re: General DotP 2014 Coding Questions

Postby RiiakShiNal » 29 Apr 2016, 10:38

You have probably forgotten to add the subtype to the appropriate SPEC file, this is what allows cards to actually use a subtype (tells the engine about the subtype). The TEXT_PERMANENT allows for the subtype to display correctly, and the LOL entries allow for Lua code to reference the number by a friendly name.
Problems with base game cards: DotP 2014 Core Fixes
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
RiiakShiNal
Programmer
 
Posts: 2115
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 468 times

Re: General DotP 2014 Coding Questions

Postby Xander9009 » 29 Apr 2016, 13:49

RiiakShiNal wrote:You have probably forgotten to add the subtype to the appropriate SPEC file, this is what allows cards to actually use a subtype (tells the engine about the subtype). The TEXT_PERMANENT allows for the subtype to display correctly, and the LOL entries allow for Lua code to reference the number by a friendly name.
Thank you. I knew what the TEXT_PERMANENT file did, but I thought the LOL entry was enough for both LUA and usage on cards. It's now fixed, with the Clue subtype both appearing and filtering properly.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2880
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 116 times
Been thanked: 435 times

PreviousNext

Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 2 guests


Who is online

In total there are 2 users online :: 0 registered, 0 hidden and 2 guests (based on users active over the past 10 minutes)
Most users ever online was 287 on 31 Mar 2019, 04:11

Users browsing this forum: No registered users and 2 guests

Login Form