It is currently 24 Aug 2019, 13:11
   
Text Size

Functions for "Choose a Creature Type"

Moderators: Xander9009, CCGHQ Admins

Functions for "Choose a Creature Type"

Postby RiiakShiNal » 25 Jul 2012, 02:09

Now updated to work with official Deck Pack 3

I made these functions while working on Patriarch's Bidding for my mod. Those who have downloaded and are using my mod v1.0 already have these functions and should be able to use them without problem. I have posted this here for people who either want to include my functions in their mod (without requiring mine) or for people who want to analyze them without downloading/unpacking my mod. I have also added the permanent text for these functions in an attachment.

Constants:
Code: Select all
-- /////////////////////////////////////////////////////////////////////////////
-- Creature Types
CREATURE_TYPE_GERM = SIZE_OF_TYPE_BAND * CARD_TYPE_CREATURE + 222
CREATURE_TYPE_HIPPOGRIFF = SIZE_OF_TYPE_BAND * CARD_TYPE_CREATURE + 223
CREATURE_TYPE_SIREN = SIZE_OF_TYPE_BAND * CARD_TYPE_CREATURE + 224
CREATURE_TYPE_TOWNSFOLK = SIZE_OF_TYPE_BAND * CARD_TYPE_CREATURE + 225
CREATURE_TYPE_HYENA = SIZE_OF_TYPE_BAND * CARD_TYPE_CREATURE + 226
CREATURE_TYPE_NOGGLE = SIZE_OF_TYPE_BAND * CARD_TYPE_CREATURE + 227

_CREATURE_TYPE_COUNT = 228
_CREATURE_TYPE_FIRST = CREATURE_TYPE_HUMAN
_CREATURE_TYPE_LAST = CREATURE_TYPE_NOGGLE

-- /////////////////////////////////////////////////////////////////////////////
-- Constants for Creature Type Selection
REGISTER_SELECTION_COUNT = 0
REGISTER_SELECTION_BEST_TYPE_INDEX = 1000
REGISTER_SELECTION_WORST_TYPE_INDEX = 1001
REGISTER_SELECTION_SELECTED_INDEX = 1002
REGISTER_SELECTION_SELECTED_TYPE = 1003
REGISTER_SELECTION_FIRST_TIME_INDICATOR = 2000
REGISTER_SELECTION_FORCE_FULL_LIST = 2001
Choosing functions:
Code: Select all
-- /////////////////////////////////////////////////////////////////////////////
-- Asking Player for a Choice //////////////////////////////////////////////////
-- NOTE: This function must be used from within an iterating action block,
--   preferrably as the only major action in that action block.
RSN_ChooseCreatureType = function( oPlayer, oChest )
   local nChoice = Object():GetMultipleChoiceResult()
   local nCurrentType = oChest:Int_Get( REGISTER_SELECTION_SELECTED_TYPE )
   local nMin = _CREATURE_TYPE_FIRST
   local nMax = _CREATURE_TYPE_LAST

   if (oChest:Int_Get( REGISTER_SELECTION_FIRST_TIME_INDICATOR ) == 0) then
      -- We don't check the choice the first time through, but we need to
      --  indicate that we've already gone through the first time for
      --  subsequent iterations.
      oChest:Int_Dec( REGISTER_SELECTION_FIRST_TIME_INDICATOR )
      if (oPlayer:IsAI() ~= 0) then
         -- We don't present the creature type choice to AIs and instead
         --  just have them choose the default.
         return false
      end
   else
      -- Not our first time through so do operations based on choice.
      if (nChoice == 0) then
         -- Go back one type.
         nCurrentType = nCurrentType - 1
         if (nCurrentType < nMin) then
            -- We went below our minimum so wrap around.
            nCurrentType = nMax
         end
      elseif (nChoice == 1) then
         -- Player made their choice so go on to next action.
         return false
      else
         -- Go forward one type.
         nCurrentType = nCurrentType + 1
         if (nCurrentType > nMax) then
            -- We went above our maximum so wrap around.
            nCurrentType = nMin
         end
      end
      -- This makes sure the type persists.
      oChest:Int_Set( REGISTER_SELECTION_SELECTED_TYPE, nCurrentType )
   end

   -- We made it this far which means we need to give the player a choice.
   oPlayer:BeginNewMultipleChoice()
   oPlayer:AddMultipleChoiceAnswer( "CARD_QUERY_OPTION_PREVIOUS" )
   oPlayer:AddMultipleChoiceAnswer( "CARD_QUERY_OPTION_CREATURE_TYPE_"..nCurrentType )
   oPlayer:AddMultipleChoiceAnswer( "CARD_QUERY_OPTION_NEXT" )
   oPlayer:AskMultipleChoiceQuestion( "CARD_QUERY_MC_CREATURE_TYPE" )
   return true
end

-- NOTE: This function must be used from within an iterating action block,
--   preferrably as the only major action in that action block.
RSN_ChooseCreatureTypeFromDC = function( oPlayer, oChest )
   local nForceFullList = oChest:Int_Get( REGISTER_SELECTION_FORCE_FULL_LIST )
   if (nForceFullList > 0) then
      return RSN_ChooseCreatureType( oPlayer, oChest )
   else
      local nChoice = Object():GetMultipleChoiceResult()
      local nCurrentIndex = oChest:Int_Get( REGISTER_SELECTION_SELECTED_INDEX )
      local nCurrentType = oChest:Int_Get( nCurrentIndex )
      local nMinIndex = 1
      local nMaxIndex = oChest:Int_Get( REGISTER_SELECTION_COUNT )

      if (oChest:Int_Get( REGISTER_SELECTION_FIRST_TIME_INDICATOR ) == 0) then
         -- We don't check the choice the first time through, but we need to
         --  indicate that we've already gone through the first time for
         --  subsequent iterations.
         oChest:Int_Dec( REGISTER_SELECTION_FIRST_TIME_INDICATOR )
         if (oPlayer:IsAI() ~= 0) then
            -- We don't present the creature type choice to AIs and instead
            --  just have them choose the default.
            return false
         end
         -- Now we add an option allowing them to use choose from full list
         --  instead of just the recommended list.
         local nNewOption = oChest:Int_Get( REGISTER_SELECTION_COUNT ) + 1
         oChest:Int_Set( nNewOption, -1 )
         oChest:Int_Set( REGISTER_SELECTION_COUNT, nNewOption )
      else
         -- Not our first time through so do operations based on choice.
         if (nChoice == 0) then
            -- Go back one index.
            nCurrentIndex = nCurrentIndex - 1
            if (nCurrentIndex < nMinIndex) then
               -- We went below our first index so wrap around.
               nCurrentIndex = nMaxIndex
            end
            nCurrentType = oChest:Int_Get( nCurrentIndex )
         elseif (nChoice == 1) then
            -- Player made their choice so go on to next action.
            if (nCurrentType == -1) then
               -- Player actually asked to choose from Full List.
               --  Reset first time indicator due to list change.
               oChest:Int_Inc( REGISTER_SELECTION_FIRST_TIME_INDICATOR )
               --  Start them off at top of list.
               oChest:Int_Set( REGISTER_SELECTION_SELECTED_TYPE, CREATURE_TYPE_HUMAN )
               --  Flip on Forced Full List.
               oChest:Int_Set( REGISTER_SELECTION_FORCE_FULL_LIST, 1 )
               -- Go ahead and give them a choice this iteration.
               return RSN_ChooseCreatureType( oPlayer, oChest )
            else
               return false
            end
         else
            -- Go forward one index.
            nCurrentIndex = nCurrentIndex + 1
            if (nCurrentIndex > nMaxIndex) then
               -- We went above our maximum index so wrap around.
               nCurrentIndex = nMinIndex
            end
            nCurrentType = oChest:Int_Get( nCurrentIndex )
         end
         -- This makes sure the index persists.
         oChest:Int_Set( REGISTER_SELECTION_SELECTED_INDEX, nCurrentIndex )
      end

      -- We made it this far which means we need to give the player a choice.
      oPlayer:BeginNewMultipleChoice()
      oPlayer:AddMultipleChoiceAnswer( "CARD_QUERY_OPTION_PREVIOUS" )
      oPlayer:AddMultipleChoiceAnswer( "CARD_QUERY_OPTION_CREATURE_TYPE_"..nCurrentType )
      oPlayer:AddMultipleChoiceAnswer( "CARD_QUERY_OPTION_NEXT" )
      oPlayer:AskMultipleChoiceQuestion( "CARD_QUERY_MC_CREATURE_TYPE" )
      return true
   end
end

-- /////////////////////////////////////////////////////////////////////////////
-- Retrieving Choices //////////////////////////////////////////////////////////
RSN_GetChosenCreatureType = function( oChest )
   local nIndex = oChest:Int_Get( REGISTER_SELECTION_SELECTED_INDEX )
   local nType = oChest:Int_Get( nIndex )
   if (nType == -1) then
      nType = oChest:Int_Get( REGISTER_SELECTION_SELECTED_TYPE )
   end
   return nType
end
Function to find creature types for creatures in a particular zone and put them into a specified data chest:
Code: Select all
-- We will find all creature types that a player has in a particular zone (though it
--  may not work for Changeling, I don't know) and put the creature type of which the
--  player has the most creatures in this zone into int REGISTER_SELECTION_BEST_TYPE.
RSN_FindPlayerCreatureTypesInZone = function( oChest, oPlayer, nZone )
   local nMaxFound = 0
   local nMinFound = 999
   local nBestTypeIndex = -1
   local nWorstTypeIndex = -1
   local nTypesFound = 0
   for i=_CREATURE_TYPE_FIRST,_CREATURE_TYPE_LAST do
      local nCount = RSN_CountPlayerCardsOfTypeAndSubTypeInZone( oPlayer, CARD_TYPE_CREATURE, i, nZone )
      if (nCount > 0) then
         nTypesFound = nTypesFound + 1
         oChest:Int_Set( nTypesFound, i )
         if (nCount > nMaxFound) then
            nMaxFound = nCount
            nBestTypeIndex = nTypesFound
         end
         if (nCount < nMinFound) then
            nMinFound = nCount
            nWorstTypeIndex = nTypesFound
         end
      end
   end
   oChest:Int_Set( REGISTER_SELECTION_COUNT, nTypesFound )
   oChest:Int_Set( REGISTER_SELECTION_BEST_TYPE_INDEX, nBestTypeIndex )
   oChest:Int_Set( REGISTER_SELECTION_WORST_TYPE_INDEX, nWorstTypeIndex )
end

-- We will find all creature types that a player has in multiple zones (though it
--  may not work for Changeling, I don't know) and put the creature type of which the
--  player has the most creatures in this zone into int REGISTER_SELECTION_BEST_TYPE.
RSN_FindPlayerCreatureTypesInZones = function( oChest, oPlayer, ... )
   local nMaxFound = 0
   local nMinFound = 999
   local nBestTypeIndex = -1
   local nWorstTypeIndex = -1
   local nTypesFound = 0
   for i=_CREATURE_TYPE_FIRST,_CREATURE_TYPE_LAST do
      local nCount = 0
      for _, nZone in ipairs(arg) do
         nCount = nCount + RSN_CountPlayerCardsOfTypeAndSubTypeInZone( oPlayer, CARD_TYPE_CREATURE, i, nZone )
      end
      if (nCount > 0) then
         nTypesFound = nTypesFound + 1
         oChest:Int_Set( nTypesFound, i )
         if (nCount > nMaxFound) then
            nMaxFound = nCount
            nBestTypeIndex = nTypesFound
         end
         if (nCount < nMinFound) then
            nMinFound = nCount
            nWorstTypeIndex = nTypesFound
         end
      end
   end
   oChest:Int_Set( REGISTER_SELECTION_COUNT, nTypesFound )
   oChest:Int_Set( REGISTER_SELECTION_BEST_TYPE_INDEX, nBestTypeIndex )
   oChest:Int_Set( REGISTER_SELECTION_WORST_TYPE_INDEX, nWorstTypeIndex )
end
Counting Function:
Code: Select all
RSN_CountPlayerCardsOfTypeAndSubTypeInZone = function( oPlayer, nType, nSubType, nZone )
   local oFilter = Object():GetFilter()
   oFilter:Clear()
   oFilter:SetZone( nZone )
   oFilter:AddCardType( nType )
   oFilter:AddSubType( nSubType )
   oFilter:SetController( oPlayer )
   oFilter:NotTargetted()
   return oFilter:Count()
end
Example Card (Patriarch's Bidding):
Code: Select all
<?xml version='1.0'?>
<CARD_V2>
   <FILENAME text="PATRIARCHS_BIDDING_26747" />
   <CARDNAME text="PATRIARCHS_BIDDING" />
   <TITLE>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Patriarch's Bidding]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Ordre du patriarche]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Órdenes del Patriarca]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Gebot des Patriarchen]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Comando del Patriarca]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Patriarch's Bidding]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Patriarch's Bidding]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Patriarch's Bidding]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Comando do Patriarca]]></LOCALISED_TEXT>
   </TITLE>
   <MULTIVERSEID value="26747" />
   <ARTID value="RSN26747" />
   <ARTIST name="Ben Thompson" />
   <CASTING_COST cost="{3}{B}{B}" />
   <FLAVOURTEXT>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA["Family plots are so convenient."
Cabal Patriarch]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[« Les complots de famille sont si distrayants. »
—Le patriarche de la Coterie]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA["Las parcelas familiares en los cementerios son muy prácticas".
Patriarca de la Cábala]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[„Es ist bequem, wenn alles in der Familie bleibt."
—Patriarch der Kabbalisten]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA["Gli intrighi di famiglia sono davvero utili".
—Patriarca della Cabala]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA["Family plots are so convenient."
Cabal Patriarch]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA["Family plots are so convenient."
Cabal Patriarch]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA["Family plots are so convenient."
Cabal Patriarch]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA["As intrigas familiares são tão convenientes."
— Patriarca da Cabala]]></LOCALISED_TEXT>
   </FLAVOURTEXT>
   <TYPE metaname="Sorcery" />
   <EXPANSION value="ONS" />
   <RARITY metaname="R" />
   <SPELL_ABILITY filter_zone="ZONE_IN_PLAY">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Each player chooses a creature type. Each player returns all creature cards of a type chosen this way from his or her graveyard to play.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Chaque joueur choisit un type de créature. Chaque joueur renvoie en jeu toutes les cartes de créature du type choisi se trouvant dans son cimetière.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Cada jugador elige un tipo de criatura. Cada jugador regresa al juego todas las cartas de criatura del tipo elegido de esta manera de su cementerio.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Jeder Spieler bestimmt einen Kreaturentyp. Jeder Spieler bringt alle Kreaturenkarten, die mindestens einen der so bestimmten Kreaturentypen haben, aus seinem Friedhof ins Spiel zurück.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Ogni giocatore sceglie un tipo di creatura. Ogni giocatore rimette in gioco tutte le carte creatura di un tipo scelto presenti nel proprio cimitero.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Each player chooses a creature type. Each player returns all creature cards of a type chosen this way from his or her graveyard to play.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Each player chooses a creature type. Each player returns all creature cards of a type chosen this way from his or her graveyard to play.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Each player chooses a creature type. Each player returns all creature cards of a type chosen this way from his or her graveyard to play.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Cada jogador escolhe um tipo de criatura. Cada jogador devolve todos os cards de criatura de um dos tipos escolhidos desta maneira de seu cemitério para o jogo.]]></LOCALISED_TEXT>
      <RESOLUTION_TIME_ACTION>
         -- Set things up here.
         for i=0,MTG():GetNumberOfPlayers()-1 do
            local oPlayer = MTG():GetNthPlayer( i )
            EffectDC():Make_Chest( i )
            -- Look-up creature types in player's graveyard.
            RSN_FindPlayerCreatureTypesInZone( EffectDC():Get_Chest( i ), oPlayer, ZONE_GRAVEYARD )
            -- Set the best type as default
            local nBestIndex = EffectDC():Get_Chest( i ):Int_Get( REGISTER_SELECTION_BEST_TYPE_INDEX )
            EffectDC():Get_Chest( i ):Int_Set( REGISTER_SELECTION_SELECTED_INDEX, nBestIndex )
         end
         -- This is so we know where we are at each step.
         EffectDC():Int_Set( 10, -1 )
      </RESOLUTION_TIME_ACTION>
      <!-- Unfortunately, I am unable to have all players choose a type in the same action
         so it must be separated into different play time actions for each player. -->
      <RESOLUTION_TIME_ACTION repeating="1">
         return RSN_ChooseCreatureTypeFromDC( MTG():GetNthPlayer( 0 ), EffectDC():Get_Chest( 0 ) )
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION repeating="1">
         return RSN_ChooseCreatureTypeFromDC( MTG():GetNthPlayer( 1 ), EffectDC():Get_Chest( 1 ) )
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION repeating="1">
         if (MTG():GetNumberOfPlayers() &gt; 2) then
            return RSN_ChooseCreatureTypeFromDC( MTG():GetNthPlayer( 2 ), EffectDC():Get_Chest( 2 ) )
         else
            return false
         end
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION repeating="1">
         if (MTG():GetNumberOfPlayers() &gt; 3) then
            return RSN_ChooseCreatureTypeFromDC( MTG():GetNthPlayer( 3 ), EffectDC():Get_Chest( 3 ) )
         else
            return false
         end
      </RESOLUTION_TIME_ACTION>
      <!-- Now all players have had a chance to choose a creature type so now comes the easy
         part, putting the creatures of the chosen type onto the battlefield. -->
      <RESOLUTION_TIME_ACTION>
         for i=0,MTG():GetNumberOfPlayers()-1 do
            local oPlayer = MTG():GetNthPlayer( i )
            local nChosenType = RSN_GetChosenCreatureType( EffectDC():Get_Chest( i ) )
            local oFilter = Object():GetFilter()

            oFilter:Clear()
            oFilter:SetZone( ZONE_GRAVEYARD )
            oFilter:SetPlayer( oPlayer )
            oFilter:AddCardType( CARD_TYPE_CREATURE )
            oFilter:AddSubType( nChosenType )
            local nCount = oFilter:EvaluateObjects()
            if (nCount &gt; 0) then
               for j=0,nCount-1 do
                  local oCard = oFilter:GetNthEvaluatedObject( j )
                  if (oCard ~= nil) then
                     oCard:PutIntoPlay( oPlayer )
                  end
               end
            end
         end
      </RESOLUTION_TIME_ACTION>
   </SPELL_ABILITY>
</CARD_V2>
It should be noted that the AI will only be able to make partial use of cards coded with these functions. The AI probably can't handle the use of iterating multiple choice questions correctly so I have chosen to make the AI use whatever default is set based on the coding of the card (pick best/worst creature type based on how many of each type there are).

Edit: Since I have now added creature types for 4 more partially implemented creature types (Hippogriff, Siren, Surrakar, Townsfolk) I have included the new spec (adds types to game so they can be used with filters) and text files (required for my above code to show proper text) for this all to work.

The new types were added after the other partially implemented type of Germ (which was added after Werewolf) so these should not conflict with any existing mod that I am aware of.

Edit 2: Added RSN_FindPlayerCreatureTypesInZones() to make getting creature types from multiple zones for a player easier.

Edit 3: Added ChooseCreatureTypeFiles.zip to the post which contains all of the above code (except the example card Patriarch's Bidding) into a single downloadable package to getting all of this somewhat easier than copying and pasting it all one block at a time.

Edit 4: Added two more missing types (These were completely missing from the game): Hyena, Noggle

I updated the code somewhat to make adding new types take less time (though hopefully we won't need to add any more) by adding _CREATURE_TYPE_FIRST, _CREATURE_TYPE_LAST, and _CREATURE_TYPE_COUNT constants and updating the code to use them where appropriate. I've also updated both the attachments so there should be no old code here.

Edit 5: The official game was updated to support the Surrakar type for a card in Deck Pack 3, this meant that Germ and those I had above Surrakar had to be shifted down 1. The only changes here are in the Constants and string table.
Attachments
ChooseCreatureTypeFilesUpdatedForDeckPack3.zip
Contains all the above code, spec, and text files (except for example card).
(18.02 KiB) Downloaded 147 times
Last edited by RiiakShiNal on 27 May 2013, 15:59, edited 6 times in total.
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Re: Functions for "Choose a Creature Type"

Postby MisterBenn » 08 Aug 2012, 21:02

This looks amazing thank you. Have you defined the Germ creature type as a constant somewhere? My installation has Werewolf as the final creature type constant defined and it prevents that find creature type loop from working...
MisterBenn
 
Posts: 97
Joined: 19 Mar 2011, 16:19
Has thanked: 24 times
Been thanked: 11 times

Re: Functions for "Choose a Creature Type"

Postby thefiremind » 08 Aug 2012, 21:06

The Germ type is defined in my core-fixing WAD and in RiiakShiNal's mod. Just have one of them installed and it should work.

EDIT: Corrected myself... I didn't include it in my mod because I assumed that everyone who uses my mod also uses my core-fixing WAD (I hope it's true :D).
Last edited by thefiremind on 08 Aug 2012, 23:17, edited 1 time in total.
< 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: Functions for "Choose a Creature Type"

Postby RiiakShiNal » 08 Aug 2012, 21:12

I'm probably going to have to go back and define some more creature types though as there are several which are only partially defined.
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Re: Functions for "Choose a Creature Type"

Postby thefiremind » 08 Aug 2012, 21:23

RiiakShiNal wrote:I'm probably going to have to go back and define some more creature types though as there are several which are only partially defined.
What do you mean? What creature types are missing?
< 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: Functions for "Choose a Creature Type"

Postby RiiakShiNal » 08 Aug 2012, 21:50

Well, for starters:
  • Alligator
  • Colossus
  • General
  • Hippogriff
  • Newt
  • Noble
  • Ranger
  • Siren
  • Surrakar
  • Townsfolk

There may be others, but I have to verify they are actually creature types first.
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Re: Functions for "Choose a Creature Type"

Postby thefiremind » 08 Aug 2012, 23:00

Many old cards received an errata that converted their creature types (often very close to the card name because types didn't matter) to actual ones, so always check the most recent Oracle text. Another example is the suppression of the Lord type.
< 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: Functions for "Choose a Creature Type"

Postby RiiakShiNal » 08 Aug 2012, 23:11

thefiremind wrote:Many old cards received an errata that converted their creature types (often very close to the card name because types didn't matter) to actual ones, so always check the most recent Oracle text. Another example is the suppression of the Lord type.
That may be true for Alligator, Colossus, General, Newt, Noble, and Ranger, but the oracle text does use the types Hippogriff (1-card), Siren (1-Card), Surrakar (several cards), and Townsfolk (2-Cards) a simple type search on gatherer will reveal that.

I got these types by looking at the listed sub types in the SYSTEM_TEXT0000.XML file in the base game.

And for the Surrakar type, I've already had to use it in creating Surrakar Spellblade in my mod (it was present in DotP 2010).
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Re: Functions for "Choose a Creature Type"

Postby thefiremind » 08 Aug 2012, 23:19

Surrakar is a quite recent creature type, it's strange that they stopped including it. Anyway, if you come up with your CREATURE_TYPES.TXT with all the missing types, post it here so I can adopt the same order and our mods will keep being compatible.
< 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: Functions for "Choose a Creature Type"

Postby RiiakShiNal » 08 Aug 2012, 23:50

Once, I make sure to look up all the types (still in use) and add them properly I will post both the CREATURE_TYPES.TXT and the constants for them here as well as updating the first post to include the new types.

Edit: After checking all types in SYSTEM_TEXT0000.XML that did not have creature type constants the only ones that are currently valid that were not fully implemented were:
  • Hippogriff
  • Siren
  • Surrakar
  • Townsfolk

All the other types referred to other card types or are not currently used.

First post has been updated with new code to support these types (constants, minor changes to code for the new ending point, etc...).
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Re: Functions for "Choose a Creature Type"

Postby MisterBenn » 09 Aug 2012, 22:03

I made Adaptive Automaton, Door of Destinies and Luminescent Rain based upon your ideas here, RiiakShiNal - thanks a lot. Currently I autodetect the best types to set without quizzing the player as that always produces the best result in my deck, and I have the code within the card to work with the creature types I currently have as constants... when and if the deck is good enough to be in the community DLC I will revisit it to use the shared constants and functions.

I was thinking about an improvement to my Adaptive Automaton, currently I just detect the best creature type found in the player's library, but perhaps I should also check the best creature type on the battlefield and give the user an either/or choice if the two best creature types are different. That would give a good option if someone played something like a Hunted Phantasm and you suddenly found yourself with a host of goblins out of nowhere.
MisterBenn
 
Posts: 97
Joined: 19 Mar 2011, 16:19
Has thanked: 24 times
Been thanked: 11 times

Re: Functions for "Choose a Creature Type"

Postby thefiremind » 09 Aug 2012, 22:39

I included the new creature types list in my core-fixing WAD, hoping that it will become the default for modders, so that we can preserve the compatibility between mods (at least for creature types).
< 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: Functions for "Choose a Creature Type"

Postby RiiakShiNal » 09 Aug 2012, 23:44

MisterBenn wrote:I made Adaptive Automaton, Door of Destinies and Luminescent Rain based upon your ideas here, RiiakShiNal - thanks a lot. Currently I autodetect the best types to set without quizzing the player as that always produces the best result in my deck, and I have the code within the card to work with the creature types I currently have as constants... when and if the deck is good enough to be in the community DLC I will revisit it to use the shared constants and functions.
I'm glad you found a good use for this work, though you may still want to ask the player which creature type they want to choose because the card could be put into other decks which may have more than one good type to use, using my functions though you still can set the best type to default (like I do with Patriarch's Bidding, my example card). That way the player still has the choice, but the auto-detected choice is still given as the default choice.
MisterBenn wrote:I was thinking about an improvement to my Adaptive Automaton, currently I just detect the best creature type found in the player's library, but perhaps I should also check the best creature type on the battlefield and give the user an either/or choice if the two best creature types are different. That would give a good option if someone played something like a Hunted Phantasm and you suddenly found yourself with a host of goblins out of nowhere.
I still think giving the player a chance to choose any type they want can be better (though obviously still automatically putting the best detected choice as the default) that way if the player knows both their deck and/or their opponent's deck they may come up with a strategy that requires them to pick a type other than the detected best type(s). Such as they have out several of one creature type as well as a smaller number of another creature type along with one or more Followed Footsteps or other such way of copying/duplicating creatures. In that case an auto-detected best may not actually be the best choice.

Checking multiple zones can indeed be a good move though you may want to create a new function to detect from multiple zones so you can properly detect what could be the actual detected best choice. It is also actually possible to have no creature types detected in a zone (for example if detecting from library after Selective Memory is used). So only using the best detected type can cause problems in certain situations.
thefiremind wrote:I included the new creature types list in my core-fixing WAD, hoping that it will become the default for modders, so that we can preserve the compatibility between mods (at least for creature types).
Cool, hopefully we can keep game changing things like that compatible across all mods. Also hopefully we won't have to change too much else.
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Re: Functions for "Choose a Creature Type"

Postby alexandreonly » 11 Aug 2012, 23:26

How do i apply this in my Door of Destinies?
Code: Select all
<?xml version='1.0'?>
<CARD_V2>
  <FILENAME text="DOOR_OF_DESTINIES_152526" />
  <CARDNAME text="DOOR_OF_DESTINIES" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="152526" />
  <ARTID value="152526" />
  <ARTIST name="Larry MacDougall" />
  <CASTING_COST cost="{4}" />
  <TYPE metaname="Artifact" />
  <EXPANSION value="DPG" />
  <RARITY metaname="R" />
  <STATIC_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[As Door of Destinies enters the battlefield, choose a creature type.]]></LOCALISED_TEXT>
  </STATIC_ABILITY>
  <TRIGGERED_ABILITY filter_zone="ZONE_IN_PLAY">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <TRIGGER value="SPELL_PLAYED">
         return (TriggerObject():GetSubType():Test( CREATURE_TYPE_RAT ) ~= 0) and TriggerObject():GetPlayer() == EffectController()
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
      EffectSource():AddCounters( MTG():ChargeCounters(), 1 )
   </RESOLUTION_TIME_ACTION>
  </TRIGGERED_ABILITY>
  <STATIC_ABILITY filter_zone="ZONE_IN_PLAY">
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
    <FILTER>
    return (FilteredCard() ~= nil and
    FilteredCard():GetCardType():Test( CARD_TYPE_CREATURE ) ~= 0 and
   FilteredCard():GetSubType():Test( CREATURE_TYPE_RAT ) ~= 0 and
    FilteredCard():GetZone() == ZONE_IN_PLAY and 
    FilteredCard():GetPlayer() == Object():GetPlayer())
    </FILTER>
   <CONTINUOUS_ACTION layer="7C">
    if FilteredCard() ~= nil then
       local total = Object():CountCounters(MTG():ChargeCounters())
       local characteristics = FilteredCard():GetCurrentCharacteristics()
       if characteristics ~= nil then
          characteristics:Power_Add( total )
          characteristics:Toughness_Add( total )
       end
    end
    </CONTINUOUS_ACTION>   
  </STATIC_ABILITY>
</CARD_V2>
My version is using rats by default.
alexandreonly
 
Posts: 145
Joined: 04 Jul 2011, 17:27
Has thanked: 0 time
Been thanked: 8 times

Re: Functions for "Choose a Creature Type"

Postby RiiakShiNal » 12 Aug 2012, 01:10

For the most part it is simply implementing a comes into play trigger with a little code calling my functions, saving the chosen type to the ObjectDC() and getting it later. I've given you the full card code below (localized and with a simplified filter for the last ability).
Code: Select all
<?xml version='1.0'?>
<CARD_V2>
   <FILENAME text="DOOR_OF_DESTINIES_152526" />
   <CARDNAME text="DOOR_OF_DESTINIES" />
   <TITLE>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Porte des Destinées]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Puerta de los destinos]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Tür der Schicksale]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Porta dei Destini]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[運命の扉]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Door of Destinies]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Дверь Судеб]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Porta dos Destinos]]></LOCALISED_TEXT>
   </TITLE>
   <MULTIVERSEID value="152526" />
   <ARTID value="152526" />
   <ARTIST name="Larry MacDougall" />
   <CASTING_COST cost="{4}" />
   <TYPE metaname="Artifact" />
   <EXPANSION value="DPG" />
   <RARITY metaname="R" />
   <TRIGGERED_ABILITY auto_skip="1">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[As Door of Destinies comes into play, choose a creature type.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Au moment où la Porte des Destinées arrive en jeu, choisissez un type de créature.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[En cuanto la Puerta de los destinos entre en juego, elige un tipo de criatura.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Sowie die Tür der Schicksale ins Spiel kommt, bestimme einen Kreaturentyp.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Mentre la Porta dei Destini entra in gioco, scegli un tipo di creatura.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[運命の扉が場に出るに際し、クリーチャー・タイプを1つ選ぶ。]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[As Door of Destinies comes into play, choose a creature type.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[При входе Двери Судеб в игру выберите тип существа.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Conforme Porta dos Destinos entra em jogo, escolha um tipo de criatura.]]></LOCALISED_TEXT>
      <TRIGGER value="ZONECHANGE_END" simple_qualifier="self" to_zone="ZONE_IN_PLAY" />
      <RESOLUTION_TIME_ACTION>
         -- Set things up here.
         EffectDC():Make_Chest( 0 )
         -- Look-up creature types in player's library and in play.
         RSN_FindPlayerCreatureTypesInZones( EffectDC():Get_Chest( 0 ), EffectController(), ZONE_IN_PLAY, ZONE_LIBRARY )
         -- Set the best type as default
         local nBestIndex = EffectDC():Get_Chest( 0 ):Int_Get( REGISTER_SELECTION_BEST_TYPE_INDEX )
         EffectDC():Get_Chest( 0 ):Int_Set( REGISTER_SELECTION_SELECTED_INDEX, nBestIndex )
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION repeating="1">
         return RSN_ChooseCreatureTypeFromDC( EffectController(), EffectDC():Get_Chest( 0 ) )
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
         local nChosenType = RSN_GetChosenCreatureType( EffectDC():Get_Chest( 0 ) )
         ObjectDC():Int_Set( 0, nChosenType )
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY filter_zone="ZONE_IN_PLAY">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Whenever you play a spell of that type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[À chaque fois  que vous jouez un sort de ce type, mettez un marqueur « charge » sur la Porte des Destinées.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Siempre que juegues un hechizo de ese tipo, pon un contador de carga sobre la Puerta de los destinos.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Immer wenn du einen Zauberspruch dieses Typs spielst, lege eine Ladungsmarke auf die Tür der Schicksale.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Ogniqualvolta giochi una magia del tipo scelto, metti un segnalino carica sulla Porta dei Destini.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[あなたがそのタイプの呪文をプレイするたび、運命の扉の上に蓄積カウンターを1個置く。]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Whenever you play a spell of that type, put a charge counter on Door of Destinies.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Каждый раз, когда вы разыгрываете заклинание того типа, положите жетон заряда на Дверь Судеб.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Toda vez que você jogar uma mágica daquele tipo, coloque um marcador de carga sobre Porta dos Destinos.]]></LOCALISED_TEXT>
      <TRIGGER value="SPELL_PLAYED">
         local nChosenType = ObjectDC():Int_Get( 0 )
         return (TriggerObject():GetSubType():Test( nChosenType ) ~= 0) and TriggerObject():GetPlayer() == EffectController()
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         EffectSource():AddCounters( MTG():ChargeCounters(), 1 )
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
   <STATIC_ABILITY filter_zone="ZONE_IN_PLAY">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Creatures you control of that type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Les créatures de ce type que vous contrôlez gagnent +1/+1 pour chaque marqueur « charge » sur la Porte des Destinées.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Las criaturas de ese tipo que controlas obtienen +1/+1 por cada contador de carga sobre la Puerta de los destinos.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Kreaturen dieses Typs, die du kontrollierst, erhalten +1/+1 für jede Ladungsmarke auf der Tür der Schicksale.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Le creature che controlli del tipo scelto prendono +1/+1 per ogni segnalino carica sulla Porta dei Destini.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[あなたがコントロールするそのタイプのクリーチャーは、運命の扉の上の蓄積カウンター1個につき+1/+1の修整を受ける。]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Creatures you control of that type get +1/+1 for each charge counter on Door of Destinies.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Находящиеся под вашим контролем существа того типа получают +1/+1 за каждый жетон заряда на Двери Судеб.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[As criaturas daquele tipo que você controla recebem +1/+1 para cada marcador de carga sobre Porta dos Destinos.]]></LOCALISED_TEXT>
      <FILTER>
         local nChosenType = ObjectDC():Int_Get( 0 )
         return CreaturesYouControlOfType( nChosenType )
      </FILTER>
      <CONTINUOUS_ACTION layer="7C">
         if FilteredCard() ~= nil then
            local total = Object():CountCounters(MTG():ChargeCounters())
            local characteristics = FilteredCard():GetCurrentCharacteristics()
            if characteristics ~= nil then
               characteristics:Power_Add( total )
               characteristics:Toughness_Add( total )
            end
         end
      </CONTINUOUS_ACTION>
   </STATIC_ABILITY>
</CARD_V2>
It makes use of a new function I added so that it can look in multiple zones (I used ZONE_IN_PLAY and ZONE_LIBRARY in the card, but you could also add ZONE_HAND if you wanted) for the actual detected best creature type (I will add the new function to the first post as well).
Code: Select all
-- We will find all creature types that a player has in multiple zones (though it
--  may not work for Changeling, I don't know) and put the creature type of which the
--  player has the most creatures in this zone into int REGISTER_SELECTION_BEST_TYPE.
RSN_FindPlayerCreatureTypesInZones = function( oChest, oPlayer, ... )
   local nMaxFound = 0
   local nMinFound = 999
   local nBestTypeIndex = -1
   local nWorstTypeIndex = -1
   local nTypesFound = 0
   for i=CREATURE_TYPE_HUMAN,CREATURE_TYPE_TOWNSFOLK do
      local nCount = 0
      for _, nZone in ipairs(arg) do
         nCount = nCount + RSN_CountPlayerCardsOfTypeAndSubTypeInZone( oPlayer, CARD_TYPE_CREATURE, i, nZone )
      end
      if (nCount > 0) then
         nTypesFound = nTypesFound + 1
         oChest:Int_Set( nTypesFound, i )
         if (nCount > nMaxFound) then
            nMaxFound = nCount
            nBestTypeIndex = nTypesFound
         end
         if (nCount < nMinFound) then
            nMinFound = nCount
            nWorstTypeIndex = nTypesFound
         end
      end
   end
   oChest:Int_Set( REGISTER_SELECTION_COUNT, nTypesFound )
   oChest:Int_Set( REGISTER_SELECTION_BEST_TYPE_INDEX, nBestTypeIndex )
   oChest:Int_Set( REGISTER_SELECTION_WORST_TYPE_INDEX, nWorstTypeIndex )
end
If you just want to see the really important added lines then look at the code box below:
Code: Select all
   <!-- Choosing Type Code -->
      <RESOLUTION_TIME_ACTION>
         -- Create a chest to store found types along with best/worst and default.
         EffectDC():Make_Chest( 0 )
         -- Look-up creature types in player's library and in play.
         RSN_FindPlayerCreatureTypesInZones( EffectDC():Get_Chest( 0 ), EffectController(), ZONE_IN_PLAY, ZONE_LIBRARY )
         -- Set the best type as default
         local nBestIndex = EffectDC():Get_Chest( 0 ):Int_Get( REGISTER_SELECTION_BEST_TYPE_INDEX )
         EffectDC():Get_Chest( 0 ):Int_Set( REGISTER_SELECTION_SELECTED_INDEX, nBestIndex )
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION repeating="1">
         -- This is the "Choose Creature Type" that the user sees (it's a single simple line for card coders)
         return RSN_ChooseCreatureTypeFromDC( EffectController(), EffectDC():Get_Chest( 0 ) )
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
         -- Retrieve the chosen type
         local nChosenType = RSN_GetChosenCreatureType( EffectDC():Get_Chest( 0 ) )
         -- Save it to the ObjectDC() so we can use it later.
         ObjectDC():Int_Set( 0, nChosenType )
      </RESOLUTION_TIME_ACTION>


   <!-- Retrieving type for use in other abilities. -->
      local nChosenType = ObjectDC():Int_Get( 0 )
P.S. I did test this to make sure it works. Also in many respects this card is actually easier to code than Patriarch's Bidding was because the only player who has to choose a creature type is the one with who puts the artifact into play (other players don't get to choose a type with Door of Destinies).
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: 2126
Joined: 16 May 2011, 21:37
Has thanked: 73 times
Been thanked: 472 times

Next

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