It is currently 07 Sep 2025, 21:22
   
Text Size

Functions for mana cost retrieval

Moderator: CCGHQ Admins

Functions for mana cost retrieval

Postby thefiremind » 18 Jul 2012, 19:27

I just inserted the following functions in my GENERAL_FUNCTIONS.LOL file:
Code: Select all
ManaCost = function(object, colour)
-- returns the amount of mana of the selected colour in object's cost
   local filter = Object():GetFilter()
   filter:Clear()
   filter:NotTargetted()
   filter:SetCardInstance(object)
   return filter:ChromaCount(colour)
end

ManaCostString = function(object, colour)
-- same as ManaCost, but it generates a string (useful for TapLand, CanAfford, etc.)
   local amount = ManaCost(object, colour)
   if amount > 0 then
      local colour_table = {"{W}", "{U}", "{B}", "{R}", "{G}"}
      local string = ""
      for i=1,amount do
         string = string..colour_table[colour]
      end
      return string
   else
      return "{0}"
   end
end

FullManaCostString = function(object)
-- returns the full mana cost string (I think it won't work properly with hybrid or phyrexian mana, for obvious reasons)
   local cmc = object:GetConvertedManaCost()
   if cmc > 0 then
      local string = ""
      local coloured_mana = 0
      for i=1,5 do
         local amount = ManaCost(object, i)
         coloured_mana = coloured_mana + amount
         if amount > 0 then
            string = string..ManaCostString(object, i)
         end
      end
      if cmc > coloured_mana then
         string = "{"..(cmc-coloured_mana).."}"..string
      end
      return string
   else
      return "{0}"
   end
end
Maybe someone already thought about using ChromaCount like this... it's a simple idea but it could be helpful for trying to code Convoke or other similar mechanics.

As I wrote in the file, I think they could generate wrong results with hybrid or phyrexian mana. You must also be careful not to use those functions while you are setting another filter, otherwise you would clear it and screw what you are doing (same as CountCardsInHand and similar).
< 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: 722 times

Re: Functions for mana cost retrieval

Postby sadlyblue » 19 Jul 2012, 22:16

I'm thinking it could be useful for Snapcaster Mage, also.
sadlyblue
 
Posts: 175
Joined: 06 Feb 2012, 13:18
Has thanked: 18 times
Been thanked: 16 times

Re: Functions for mana cost retrieval

Postby thefiremind » 31 Jul 2012, 21:03

I expanded my collection of functions related to mana costs, edited some function names so that they are more coherent, and moved the functions to a separate MANA_FUNCTIONS.LOL file. This is the result:
Code: Select all
ColourToString = function(colour)
-- converts colour constants (i.e. COLOUR_RED) to mana strings (i.e. "{R}")
   local mana_table = {"{W}", "{U}", "{B}", "{R}", "{G}"}
   return mana_table[colour]
end

ManaString = function(colour, amount)
-- generates a mana string of the selected colour and amount
   local string = ""
   if amount == 0 then
      return "{0}"
   end
   for i=1,amount do
      string = string..ColourToString(colour)
   end
   return string
end

GetCostOfColour = function(object, colour)
-- returns the amount of mana of the selected colour in object's cost
   local filter = Object():GetFilter()
   filter:Clear()
   filter:NotTargetted()
   filter:SetCardInstance(object)
   return filter:ChromaCount(colour)
end

GetCostStringOfColour = function(object, colour)
-- same as GetCostOfColour, but it generates a string (useful for TapLand, CanAfford, etc.)
   local amount = GetCostOfColour(object, colour)
   return ManaString(colour, amount)
end

GetCostString = function(object)
-- returns the full mana cost string but it doesn't work with hybrid or phyrexian mana, for obvious reasons
   local cmc = object:GetConvertedManaCost()
   if cmc > 0 then
      local string = ""
      local coloured_mana = 0
      for i=1,5 do
         local amount = GetCostOfColour(object, i)
         coloured_mana = coloured_mana + amount
         if amount > 0 then
            string = string..GetCostStringOfColour(object, i)
         end
      end
      if cmc > coloured_mana then
         string = "{"..(cmc-coloured_mana).."}"..string
      end
      return string
   else
      return "{0}"
   end
end

GetTotalManaOfColour = function(player, colour)
-- returns the maximum amount of mana of the selected colour that player can afford
   local total = player:GetTotalMana()
   local string = ""
   for i=0,total do
      string = string..ColourToString(colour)
      if player:CanAfford(string) == 0 then
         return i
      end
   end
   return 0
end
Now I can easily code abilities that ask to "spend only <color> mana this way" (without using the DotP2012 trick, that consisted in including the card in a mono-colored deck :lol:).
Example: the good old Crimson Hellkite:
Code: Select all
  <ACTIVATED_ABILITY filter_zone="ZONE_IN_PLAY">
    <COST type="TapSelf" />
    <TARGET_DEFINITION id="0">
    local filter = Object():GetFilter()
    filter:Clear()
    filter:AddCardType( CARD_TYPE_CREATURE )
    filter:SetZone( ZONE_IN_PLAY )
    filter:SetHint( HINT_ENEMY_ONLY, EffectController() )
    </TARGET_DEFINITION>
    <TARGET_DETERMINATION>
    return AtLeastOneTargetFromDefinition(0)
    </TARGET_DETERMINATION>
    <PLAY_TIME_ACTION>
    local player = EffectController()
    local max_mana = GetTotalManaOfColour(player, COLOUR_RED)       
    player:BeginNewNumericalChoice()
    player:AddNumericalChoiceAnswer(max_mana)
    player:AskNumericalChoiceQuestion("NUM_LANDS")
    </PLAY_TIME_ACTION>
    <PLAY_TIME_ACTION>
    EffectDC():Set_Int( 1, Object():GetNumericalChoiceResult() )
    </PLAY_TIME_ACTION>
    <PLAY_TIME_ACTION target_choosing="1">
    local damage = EffectDC():Get_Int(1)
    EffectController():SetCustomQueryInstructionValue(damage)
    EffectController():ChooseTarget( 0, "CARD_QUERY_CHOOSE_DEAL_DAMAGE_AMOUNT", EffectDC():Make_Targets(0) )
    </PLAY_TIME_ACTION>
    <PLAY_TIME_ACTION>
    local damage = EffectDC():Get_Int(1)
    local mana_string = ManaString(COLOUR_RED, damage)
    local player = EffectController()
    if player:CanAfford(mana_string) then
       player:TapLand(mana_string)
    end
    </PLAY_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local damage = EffectDC():Get_Int(1)
    local target_creature = EffectDC():Get_Targets(0):Get_CardPtr(0)
    local source = EffectSource()
    if source == nil then
       source = Object()
    end
    if target_creature ~= nil then
       target_creature:DealDamage(damage, source)
    end
    </RESOLUTION_TIME_ACTION>
    <SFX text="TARGET_FIREBALL_PLAY" />
    <AI_AVAILABILITY type="in_response" />
    <AI_AVAILABILITY step="begin_combat" turn="their_turn" />
    <AI_AVAILABILITY step="main_1" turn="my_turn" />
    <AI_AVAILABILITY step="declare_attackers" turn="their_turn" />
    <AI_AVAILABILITY step="declare_blockers" />
    <AI_AVAILABILITY step="end_of_turn" turn="their_turn" />
  </ACTIVATED_ABILITY>
The code works, there's just a visual bug: while you choose the value for X, the game will automatically highlight a mana combination and will allow you to change it with CTRL (even if it includes non-red mana). After the choices are made, only red mana will be tapped anyway.
< 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: 722 times

Re: Functions for mana cost retrieval

Postby nabeshin » 13 Aug 2012, 18:19

violation of the game rules
User avatar
nabeshin
 
Posts: 207
Joined: 27 Jun 2011, 20:07
Has thanked: 5 times
Been thanked: 31 times

Re: Functions for mana cost retrieval

Postby thefiremind » 13 Aug 2012, 18:29

nabeshin wrote:violation of the game rules
Why do you always make riddles? You should use a sphinx as avatar... :lol:
Which rules are you talking about?
< 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: 722 times

Re: Functions for mana cost retrieval

Postby nabeshin » 13 Aug 2012, 18:35

I didn't see {X} in your code ( excuse me, I not riddler, just mood bad )
User avatar
nabeshin
 
Posts: 207
Joined: 27 Jun 2011, 20:07
Has thanked: 5 times
Been thanked: 31 times

Re: Functions for mana cost retrieval

Postby thefiremind » 13 Aug 2012, 18:43

nabeshin wrote:I didn't see {X} in your code
If I need to select only one type of mana I can't use {X}. Instead of that, I use a numerical choice that lets me select a number between 0 and the maximum amount of mana of that type that I can pay. When I have selected how much I want to pay, I tap that mana with TapLand. I don't see any problem with the rules by doing that.

EDIT: I think I finally solved the riddle... ehm... understood what you mean. :lol: My code wouldn't work in case something decreases the cost of abilities, because it should lower the amount needed to reach a certain {X} as well. So, my code shouldn't be used when {X} is in the spell cost, for example in Drain Life... but DotP2013 doesn't implement decreasing ability costs, so Crimson Hellkite is still correct. :D
< 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: 722 times


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 11 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 11 users online :: 0 registered, 0 hidden and 11 guests (based on users active over the past 10 minutes)
Most users ever online was 7303 on 15 Jul 2025, 20:46

Users browsing this forum: No registered users and 11 guests

Login Form