It is currently 19 Jul 2025, 21:18
   
Text Size

Community Wad

Moderator: CCGHQ Admins

Re: Community Wad

Postby Xander9009 » 03 Nov 2016, 21:17

By the way, I've got the new lands working such that the only thing that needs changed from one land to the next is the ability's text (which it will already have) and the line RSN_MarkCanProduceMana("{W}{U}") to match its colors. The multiple choice question and other abilities will get their info from that, so nothing else needs changed.

Although, a question for Riiak: I was considering the possibility of granting abilities to a card, and that poses a problem since auto-tap options are available. I was trying to figure out how to make it so other cards (say, Abundant Growth) check if what they're enchanting can produce mana, and simply add to the list if it can (trusting that the land itself will call RSN_ClearCanProduceMana()). However, when I tried leaving the clear function on layer 0 and putting the mark on layer 1 (just having all mana abilities do that should negate the issue, since everything would clear it at about the same time and then add the current ones afterward), the function RSN_GetCanProduceMana() always failed except inside the CA where it was set (which kind of messes up, well, everything). Any thoughts about why that would happen would be appreciated. As it stands, if something grants the ability to produce mana, it'll probably overwrite the land's current mana production abilities.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2905
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 121 times
Been thanked: 445 times

Re: Community Wad

Postby nivmizzet1 » 03 Nov 2016, 22:04

Xander9009 wrote:Regarding the P/T issues, those cards have been like that since they were first coded, and Riiak and I discussed them at some point, and they should work just fine as they are, and should stay that way. I'm not 100% certain why the cards are causing those errors on your end, but they don't on others', and so it's probably an issue with your setup somewhere. I'd suggest temporarily removing everything but the from your game folder and checking if it still happens. If so, get a fresh copy of the deck builder and test with that. (You can just put it into a new folder and run it; no need to overwrite your old installation.) If it still does, then it's the CW's issue and I'll track it down. If it doesn't, then it's either another mod/card/function file you've got or else your deck builder's settings or other files are somehow corrupted (depends on when the troubleshooting above fixed the issue).

If you'd like some assistance, I'm currently on the CW's IRC: https://sites.google.com/site/dotpcommunitywad/irc-chat (which I just discovered can show desktop notifications if you check out the settings.)
I assume you don't mean that Mercy Killing should still have the P/T that it had? I've changed the others back now. As I said, the error log didn't show up again after that one time, without me even changing anything (I think), so I'm not sure why it happened, but it's fine now, and you know what they say -- ignorance is bliss. :mrgreen:
nivmizzet1
 
Posts: 617
Joined: 21 Mar 2013, 10:10
Has thanked: 100 times
Been thanked: 25 times

Re: Community Wad

Postby Xander9009 » 03 Nov 2016, 22:06

nivmizzet1 wrote:
Xander9009 wrote:Regarding the P/T issues, those cards have been like that since they were first coded, and Riiak and I discussed them at some point, and they should work just fine as they are, and should stay that way. I'm not 100% certain why the cards are causing those errors on your end, but they don't on others', and so it's probably an issue with your setup somewhere. I'd suggest temporarily removing everything but the from your game folder and checking if it still happens. If so, get a fresh copy of the deck builder and test with that. (You can just put it into a new folder and run it; no need to overwrite your old installation.) If it still does, then it's the CW's issue and I'll track it down. If it doesn't, then it's either another mod/card/function file you've got or else your deck builder's settings or other files are somehow corrupted (depends on when the troubleshooting above fixed the issue).

If you'd like some assistance, I'm currently on the CW's IRC: https://sites.google.com/site/dotpcommunitywad/irc-chat (which I just discovered can show desktop notifications if you check out the settings.)
I assume you don't mean that Mercy Killing should still have the P/T that it had? I've changed the others back now. As I said, the error log didn't show up again after that one time, without me even changing anything (I think), so I'm not sure why it happened, but it's fine now, and you know what they say -- ignorance is bliss. :mrgreen:
Haha no, Mercy killing definitely shouldn't. The others, yes. I'm glad it didn't happen again. I didn't catch where you said that, sorry. It was likely just a minor bug buried somewhere in the code of either the CW or the deck builder, then. I've encountered it before (which is what prompted my conversation with RiiakShiNal about it), but don't recall coming up with the reason.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2905
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 121 times
Been thanked: 445 times

Re: Community Wad

Postby nivmizzet1 » 03 Nov 2016, 22:48

thefiremind wrote:The second ability makes you draw because you are still creating delayed trigger #1.

The fact that you draw twice could be because you have 2 CLEANUP blocks and the game probably doesn't read both so you get the current delayed trigger plus all the past ones who haven't run at least once. You should keep only 1 CLEANUP with both attributes in it.
Thanks thefiremind, your tip about the trigger helped. It's funny because I initially had MTG():CreateDelayedTrigger(1, nil) for the first ability and MTG():CreateDelayedTrigger(2, nil) for the second ability -- I guessed the number in that function was a reference -- but because I was drawing two cards (at that time I had the card draw ability as the second ability) I thought the number might indicate how many triggers to create. At that stage the counter ability was working fine, until I broke it by changing the second delayed trigger to trigger #1. Then I changed a bunch of other things and forgot how I'd had it.

I've moved this topic to the programming talk section now.


Sorry, now I think I know what you mean by
thefiremind wrote:You should keep only 1 CLEANUP with both attributes in it.
. You're talking about the two cleanup steps for that first ability, aren't you, not the cleanup steps for all abilities.

EDIT: so I combined those cleanups so that <CLEANUP fire_once="1" simple_cleanup="EndOfTurn" />. The cleanups are working well, but it's still drawing two cards. I tried EffectController():DrawCards(0), but that doesn't draw any cards (surprise, surprise!)
nivmizzet1
 
Posts: 617
Joined: 21 Mar 2013, 10:10
Has thanked: 100 times
Been thanked: 25 times

Re: Community Wad

Postby RiiakShiNal » 04 Nov 2016, 11:10

Xander9009 wrote:By the way, I've got the new lands working such that the only thing that needs changed from one land to the next is the ability's text (which it will already have) and the line RSN_MarkCanProduceMana("{W}{U}") to match its colors. The multiple choice question and other abilities will get their info from that, so nothing else needs changed.

Although, a question for Riiak: I was considering the possibility of granting abilities to a card, and that poses a problem since auto-tap options are available. I was trying to figure out how to make it so other cards (say, Abundant Growth) check if what they're enchanting can produce mana, and simply add to the list if it can (trusting that the land itself will call RSN_ClearCanProduceMana()). However, when I tried leaving the clear function on layer 0 and putting the mark on layer 1 (just having all mana abilities do that should negate the issue, since everything would clear it at about the same time and then add the current ones afterward), the function RSN_GetCanProduceMana() always failed except inside the CA where it was set (which kind of messes up, well, everything). Any thoughts about why that would happen would be appreciated. As it stands, if something grants the ability to produce mana, it'll probably overwrite the land's current mana production abilities.
Well, you have a few problems. Granting of abilities is supposed to happen on Layer 6 and any ability granted that tries to do things with chests and such on a lower layer typically doesn't work (there are some minor exceptions which I don't remember off hand). If you grant on a lower layer then abilities that modify chests and such start working on a layer at or above the granted layer, but then if the card loses abilities from LoseAllAbilities() the chests will be incorrectly marked because they were set at lower levels. Generally this isn't a problem when dealing with manual mana abilities since without the activated ability being available what's in the chests doesn't matter. When you check for something that has been put in a chest at a particular layer you need to check it at a higher layer otherwise the ability may not have run yet to put the value into the chest (I do fallback checks on the last layer possible, 8, to try and make sure everything that can do modifications has had a chance to run). If you grant on a higher layer than 6 then the granted abilities will remain even when the card loses abilities. So cards that have to grant complex abilities that require multiple layers become quite difficult to manage and code properly. I had similar issues with custom characteristics and found I had to manage them very carefully.

To do any more debugging I would need to see the code.
RiiakShiNal
Programmer
 
Posts: 2188
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: Community Wad

Postby Xander9009 » 04 Nov 2016, 12:00

RiiakShiNal wrote:Well, you have a few problems. Granting of abilities is supposed to happen on Layer 6 and any ability granted that tries to do things with chests and such on a lower layer typically doesn't work (there are some minor exceptions which I don't remember off hand). If you grant on a lower layer then abilities that modify chests and such start working on a layer at or above the granted layer, but then if the card loses abilities from LoseAllAbilities() the chests will be incorrectly marked because they were set at lower levels. Generally this isn't a problem when dealing with manual mana abilities since without the activated ability being available what's in the chests doesn't matter. When you check for something that has been put in a chest at a particular layer you need to check it at a higher layer otherwise the ability may not have run yet to put the value into the chest (I do fallback checks on the last layer possible, 8, to try and make sure everything that can do modifications has had a chance to run). If you grant on a higher layer than 6 then the granted abilities will remain even when the card loses abilities. So cards that have to grant complex abilities that require multiple layers become quite difficult to manage and code properly. I had similar issues with custom characteristics and found I had to manage them very carefully.

To do any more debugging I would need to see the code.
My confusion was regarding the fact that it's checking the mana marked as producible in an RTA, not a CA. That RTA is itself inside a COST block. I tried an RTA and a PTA, both inside and outside a COST block for testing, and all failed if the RSN_ClearCanProduceMana() and RSN_MarkCanProduceMana("{W}{B}") were on different layers. Here's Scrubland and the function file.

The granting of abilities is actually done on layer 8 just like you had the fallback abilities, because it was the same code. I just changed the conditions to be a LinkedDC check, so the player can manually choose to have an auto-tap ability active.

If you can think of another way to get abilities granted by other cards and abilities inherent on the cards to work together, then I'm open to suggestions. It just seemed to me that putting them on different layers so everything clears on layer 0 and is set by any abilities, whether granted or inherent, on layer 1 would allow them to mesh well.

| Open
Scrubland
Code: Select all
<?xml version="1.0"?>
<CARD_V2 ExportVersion="4">
   <FILENAME text="SCRUBLAND_CW_580" />
   <CARDNAME text="SCRUBLAND" />
   <TITLE>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Scrubland]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="zh-CN"><![CDATA[灌木丛林地]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="zh-HK"><![CDATA[灌木叢林地]]></LOCALISED_TEXT>
   </TITLE>
   <MULTIVERSEID value="580" />
   <ARTID value="SCRUBLAND" />
   <ARTIST name="Cliff Childs" />
   <CASTING_COST cost="" />
   <TYPE metaname="Land" />
   <SUB_TYPE metaname="Plains" />
   <SUB_TYPE metaname="Swamp" />
   <EXPANSION value="DPI" />
   <RARITY metaname="R" />
   <STATIC_ABILITY active_zone="ZONE_ANY">
      <CONTINUOUS_ACTION layer="0">
         RSN_ClearCanProduceMana()
         RSN_MarkCanProduceMana("{W}{B}")
      </CONTINUOUS_ACTION>
   </STATIC_ABILITY>
   <ACTIVATED_ABILITY forced_skip="1" linked_ability_group="1">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[{T}: Add {W} or {B} to your mana pool.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[{T} : Ajoutez {W} ou {B} à votre réserve.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[{T}: Agrega {W} o {B} a tu reserva de maná.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[{T}: Erhöhe deinen Manavorrat um {W} oder {B}.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[{T}: Aggiungi {W} o {B} alla tua riserva di mana.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[{T}:あなたのマナ・プールに{W}か{B}を加える。]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[{T}: {W} 또는 {B}를 당신의 마나풀에 담는다.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[{T}: добавьте {W} или {B} в ваше хранилище маны.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[{T}: Adicione {W} ou {B} à sua reserva de mana.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="zh-CN"><![CDATA[{T}:加{W}或{B}到你的法术力池中。]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="zh-HK"><![CDATA[{T}:加{W}或{B}到你的魔法力池中。]]></LOCALISED_TEXT>
      <COST type="Generic">
         <PREREQUISITE>
            return EffectController() ~= nil and EffectController():IsAI() == false and EffectSource() ~= nil and EffectSource():IsTapped() == false
         </PREREQUISITE>
         <PLAY_TIME_ACTION>
            RSN_MarkManaAbilityStart()
         </PLAY_TIME_ACTION>
         <RESOLUTION_TIME_ACTION repeating="1">
            return CW_Mana_ChooseManaOption()
         </RESOLUTION_TIME_ACTION>
         <RESOLUTION_TIME_ACTION>
            RSN_MarkManaAbilityEnd()
         </RESOLUTION_TIME_ACTION>
      </COST>
      <PLAY_TIME_ACTION>
         RSN_MarkManaAbilityStart()
      </PLAY_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
         local oSource = EffectSource()
         local oController = EffectController()
         if oSource ~= nil and oController ~= nil then
            CW_Mana_Produce(EffectDC():Get_Int(0))
         end
      </RESOLUTION_TIME_ACTION>
      <RESOLUTION_TIME_ACTION>
         RSN_EliminateExtraManaTokens()
         S_DisplayManaPool(EffectController())
         RSN_MarkManaAbilityEnd()
      </RESOLUTION_TIME_ACTION>
   </ACTIVATED_ABILITY>
   <TRIGGERED_ABILITY replacement_effect="1" linked_ability_group="1" active_zone="ZONE_TRANSITION">
      <TRIGGER value="ZONECHANGE_TRANSITION" simple_qualifier="self" to_zone="ZONE_BATTLEFIELD" from_zone="ZONE_ANY" pre_trigger="1" />
      <RESOLUTION_TIME_ACTION>
         LinkedDC():Set_Int(0, CW_Mana_GetRandomProducibleColor())
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY replacement_effect="1" linked_ability_group="1">
      <TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller">
         return MTG():GetStep() == STEP_MAIN_1 or MTG():GetStep() == STEP_MAIN_2
      </TRIGGER>
      <TRIGGER value="SPELL_RESOLVED" />
      <TRIGGER value="ABILITY_RESOLVED" />
      <INTERVENING_IF ignore_resolution_check="1">
         return EffectSource() ~= nil and EffectController() ~= nil and EffectSource():IsTapped() == false and EffectController():IsAI()
      </INTERVENING_IF>
      <RESOLUTION_TIME_ACTION>
         LinkedDC():Set_Int(0, CW_Mana_GetRandomProducibleColor())
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
   <STATIC_ABILITY linked_ability_group="1">
      <CONTINUOUS_ACTION layer="8">
         local nDefaultColour = CW_Mana_GetNthProducibleColor()
         local oCard = EffectSource()
         local nColour = LinkedDC():Get_Int(0)
         if nColour ~= -1 then
            local oCharacteristics = oCard:GetCurrentCharacteristics()
            oCharacteristics:GrantAbility( nColour )
            if oCard:GetCardType():Test(CARD_TYPE_CREATURE) == false then
               oCharacteristics:GrantAbility(nColour+10)
            end
         end
      </CONTINUOUS_ACTION>
   </STATIC_ABILITY>
   <TRIGGERED_ABILITY forced_skip="1" replacement_effect="1">
      <TRIGGER value="BEGINNING_OF_STEP" pre_trigger="1" />
      <RESOLUTION_TIME_ACTION>
         RSN_ClearProducedMana()
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
   <MANA_ABILITY resource_id="0">
      <COST type="TapSelf" />
      <PRODUCES amount="{1}" />
   </MANA_ABILITY>
   <MANA_ABILITY resource_id="1">
      <COST type="TapSelf" />
      <PRODUCES amount="{W}" />
   </MANA_ABILITY>
   <MANA_ABILITY resource_id="2">
      <COST type="TapSelf" />
      <PRODUCES amount="{U}" />
   </MANA_ABILITY>
   <MANA_ABILITY resource_id="3">
      <COST type="TapSelf" />
      <PRODUCES amount="{B}" />
   </MANA_ABILITY>
   <MANA_ABILITY resource_id="4">
      <COST type="TapSelf" />
      <PRODUCES amount="{R}" />
   </MANA_ABILITY>
   <MANA_ABILITY resource_id="5">
      <COST type="TapSelf" />
      <PRODUCES amount="{G}" />
   </MANA_ABILITY>
   <TRIGGERED_ABILITY resource_id="10" badge="BADGE_ANNIHILATOR">
      <TRIGGER value="ATTACKING" simple_qualifier="self" />
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY resource_id="11" badge="BADGE_PLAINS_WALK">
      <TRIGGER value="ATTACKING" simple_qualifier="self" />
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY resource_id="12" badge="BADGE_ISLAND_WALK">
      <TRIGGER value="ATTACKING" simple_qualifier="self" />
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY resource_id="13" badge="BADGE_SWAMP_WALK">
      <TRIGGER value="ATTACKING" simple_qualifier="self" />
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY resource_id="14" badge="BADGE_MOUNTAIN_WALK">
      <TRIGGER value="ATTACKING" simple_qualifier="self" />
   </TRIGGERED_ABILITY>
   <TRIGGERED_ABILITY resource_id="15" badge="BADGE_FOREST_WALK">
      <TRIGGER value="ATTACKING" simple_qualifier="self" />
   </TRIGGERED_ABILITY>
   <TOKEN_REGISTRATION reservation="1" type="RSN_TOKEN_MANA_C" />
   <TOKEN_REGISTRATION reservation="1" type="RSN_TOKEN_MANA_W" />
   <TOKEN_REGISTRATION reservation="1" type="RSN_TOKEN_MANA_U" />
   <TOKEN_REGISTRATION reservation="1" type="RSN_TOKEN_MANA_B" />
   <TOKEN_REGISTRATION reservation="1" type="RSN_TOKEN_MANA_R" />
   <TOKEN_REGISTRATION reservation="1" type="RSN_TOKEN_MANA_G" />
   <AI_BASE_SCORE score="150" zone="ZONE_BATTLEFIELD" />
   <AUTHOR><![CDATA[Xander9009]]></AUTHOR>
   <EDITORS><![CDATA[Xander9009]]></EDITORS>
   <DATE><![CDATA[02-11-16]]></DATE>
</CARD_V2>
CW_MANA.LOL
Code: Select all
-------------------------
--File Info--------------
-------------------------
--Author: Xander9009
--Created: 28-05-15
--Updated: 02-11-16

--A set of functions for the automated choosing of mana color production among multiple sources.

-------------------------
--Chest Registers--------
-------------------------

CW_MANA_CHEST = 90090004 -- The RSN_ObjectDC constant on the Mana Manager.


-----------------------------
--Duel Data Chest Registers--
-----------------------------

CW_MANA_COLORLAND = {}
CW_MANA_COLORLAND[COLOUR_COLOURLESS] = "WASTE"
CW_MANA_COLORLAND[COLOUR_WHITE] = "PLAINS"
CW_MANA_COLORLAND[COLOUR_BLUE] = "ISLAND"
CW_MANA_COLORLAND[COLOUR_BLACK] = "SWAMP"
CW_MANA_COLORLAND[COLOUR_RED] = "MOUNTAIN"
CW_MANA_COLORLAND[COLOUR_GREEN] = "FOREST"

CW_MANA_COLORABBREVIATION = {}
CW_MANA_COLORABBREVIATION[COLOUR_COLOURLESS] = "C"
CW_MANA_COLORABBREVIATION[COLOUR_WHITE] = "W"
CW_MANA_COLORABBREVIATION[COLOUR_BLUE] = "U"
CW_MANA_COLORABBREVIATION[COLOUR_BLACK] = "B"
CW_MANA_COLORABBREVIATION[COLOUR_RED] = "R"
CW_MANA_COLORABBREVIATION[COLOUR_GREEN] = "G"


-------------------------
--Function List----------
-------------------------

--CW_Mana_GetRandomProducibleColor({oCard = EffectSource(), bIncludeColorless = false})
--    Returns a random color {oCard} can produce, optionally including colorless mana.
--    Input: {Card}
--    Output: Int

--CW_Mana_GetNthProducibleColor({iIndex = 1, oCard = EffectSource(), bIncludeColorless = true})
--    Returns then {iIndex}th color {oCard} can produce, optionally including colorless mana.
--    Input: {Int, Card, Bool}
--    Output: Int

--CW_Mana_ChooseManaOption({oCard = EffectSource()})
--    USE INSIDE REPEATING ACTION - RETURN FUNCTION RESULT
--    Asks player to choose a mana option. The options are dynamically built from {oCard}'s producible colors.
--    Options are available for both Auto-Mana and Manual-Mana.
--    Stores color chosen in either LinkedDC():Get_Int(0) or EffectDC():Get_Int(0), based on whether an Auto-Mana or a Manual-Mana option is chosen.
--    Input: {Card}
--    Output: Bool

--CW_Mana_Produce(nMana, nAmount, bDoNotMark)
--    Shorthand for CW_IMM_Produce() while ignoring -1.
--    Input: Int/String, {Int, Bool}
--    Output: None

-------------------------
--Functions Definitions--
-------------------------

--Returns a random color {oCard} can produce, optionally including colorless mana.
--Input: {Card, Bool}
--Output: Int
CW_Mana_GetRandomProducibleColor = function(oCard, bIncludeColorless)
   if oCard == nil then
      oCard = EffectSource()
   end
   if oCard ~= nil then
      local aiProducibleColors = {}
      local iNumProducibleColors = 0
      local iStartColor = COLOUR_WHITE
      if bIncludeColorless == true and bIncludeColorless ~= 0 then
         iStartColor = COLOUR_COLOURLESS
      end
      for i=iStartColor,COLOUR_GREEN do
         if RSN_GetCanProduceMana(oCard, i) then
            iNumProducibleColors = iNumProducibleColors + 1
            aiProducibleColors[iNumProducibleColors] = i
         end
      end
      if iNumProducibleColors == 0 and RSN_GetCanProduceMana(oCard, COLOUR_COLOURLESS) then
         return 0
      elseif iNumProducibleColors == 1 then
         return aiProducibleColors[math.random(1, 1)]
      else
         return aiProducibleColors[math.random(1, iNumProducibleColors)]
      end
   end
   return -1
end

--Returns then {iIndex}th color {oCard} can produce, optionally including colorless mana.
--Input: {Int, Card, Bool}
--Output: Int
CW_Mana_GetNthProducibleColor = function(iIndex, oCard, bIncludeColorless)
   if oCard == nil then
      oCard = EffectSource()
   end
   if iIndex == nil or iIndex < 1 then
      iIndex = 1
   end
   if oCard ~= nil then
      local iStartColor = COLOUR_WHITE
      if bIncludeColorless == nil or (bIncludeColorless == true and bIncludeColorless ~= 0) then
         iStartColor = COLOUR_COLOURLESS
      end
      for i=iStartColor,COLOUR_GREEN do
         if RSN_GetCanProduceMana(oCard, i) then
            iIndex = iIndex - 1
            if iIndex == 0 then
               return i
            end
         end
      end
   end
   return -1
end

--USE INSIDE REPEATING ACTION - RETURN FUNCTION RESULT
--Asks player to choose a mana option. The options are dynamically built from {oCard}'s producible colors.
--Options are available for both Auto-Mana and Manual-Mana.
--Stores color chosen in either LinkedDC():Get_Int(0) or EffectDC():Get_Int(0), based on whether an Auto-Mana or a Manual-Mana option is chosen.
--Input: {Card}
--Output: Bool
CW_Mana_ChooseManaOption = function(oCard)
   if oCard == nil then
      oCard = EffectSource()
   end
   local oController = EffectController()
   if oCard ~= nil and oController ~= nil then
      local iParity = MTG():GetActionRepCount() % 2
      local aiProducibleColors = {}
      local iNumProducibleColors = 0
      for i=COLOUR_COLOURLESS,COLOUR_GREEN do
         if RSN_GetCanProduceMana(oCard, i) then
            iNumProducibleColors = iNumProducibleColors + 1
            aiProducibleColors[iNumProducibleColors] = i
         end
      end
      if iNumProducibleColors >= 1 and iNumProducibleColors <= 3 then
         if iParity == 0 then
            oController:BeginNewMultipleChoice()
            for i=1,iNumProducibleColors do
               oController:AddMultipleChoiceAnswer("CARD_QUERY_AM_MANUAL_"..CW_MANA_COLORABBREVIATION[aiProducibleColors[i]])
            end
            for i=1,iNumProducibleColors do
               oController:AddMultipleChoiceAnswer("CARD_QUERY_AM_AUTO_"..CW_MANA_COLORABBREVIATION[aiProducibleColors[i]])
            end
            oController:AddMultipleChoiceAnswer("CARD_QUERY_AM_AUTO_OFF")
            oController:AskMultipleChoiceQuestion("CARD_QUERY_AM_CHOOSE_MANA_OPTION", oCard)
            return true
         else
            local oController = EffectController()
            local iResult = oController:GetMultipleChoiceResult()
            EffectDC():Set_Int(0, -1)
            if iResult < iNumProducibleColors then
               EffectDC():Set_Int(0, CW_Mana_GetNthProducibleColor(iResult+1))
               oCard:Tap()
            elseif iResult < iNumProducibleColors * 2 then
               LinkedDC():Set_Int(0, CW_Mana_GetNthProducibleColor(iResult-iNumProducibleColors+1))
            else
               LinkedDC():Set_Int(0, -1)
            end
            return false
         end
      else
         CW_General_Error("CW_Mana_ChooseManaOption: More than three colors not implemented.")
      end
   end
   return false
end

--Shorthand for CW_IMM_Produce() while ignoring -1.
--Input: Int/String, {Int, Bool}
--Output: None
CW_Mana_Produce = function(nMana, nAmount, bDoNotMark)
   if type(nMana) == "number" and nMana >= 0 or type(nMana) == "string" then
      CW_IMM_Produce(nMana, nAmount, bDoNotMark)
   end
end
Note that CW_IMM_Produce() just calls RSN_Produce(), except it first replaces nMana with a string if it's a number. So, 'COLOUR_WHITE' or '1' becomes '"{W}"' for the RSN_Produce call. A bit of unnecessary nesting, but I made the IMM functions quite awhile back, and I didn't want to deal with them now. I just remember they worked well. It's shouldn't be relevant to this anyway.

In the card's first static ability, if you split the function calls up into two CAs, layer 0 for the clearing and layer 1 for the marking, then the checks inside the function CW_Mana_ChooseManaOption() fail despite being in an RTA, not a CA.
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2905
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 121 times
Been thanked: 445 times

Re: Community Wad

Postby Splinterverse » 04 Nov 2016, 22:10

Finished coding for today; all cards referenced are from the missing cards list.

Coded, tested, and uploaded:
Brooding Saurian -- updated to ensure even auras are impacted by its effect
Charging Rhino
Desertion
Double Negative
Goblin Bangchuckers
Golgothian Sylex
Hunter's Insight
Library of Lat-Nam
Liquid Fire
Limited Resources
Loafing Giant
Lodestone Bauble
Lost Order of Jarkeld
Loxodon Peacekeeper
Lumengrid Drake
Malignant Growth
Mangara's Blessing
Metamorphose
Musician
Swift Spinner

Bugs fixed:
Ancestral Knowledge -- cumulative upkeep colorless loop correction; not tested
Freyalise's Radiance -- cumulative upkeep colorless loop correction; not tested
Fyndhorn Pollen -- cumulative upkeep colorless loop correction; not tested
Garza's Assassin -- was not paying Recover cost because <COST type="Life" amount="GetLifeTotal()/2" /> is not a valid method of paying life; tested
Juju Bubble -- cumulative upkeep colorless loop correction; not tested
Survivor of the Unseen -- cumulative upkeep colorless loop correction; not tested

HQ art uploaded (all were missing):
Double Negative
Goblin Bangchuckers
Hunter's Insight
Library of Lat-Nam
Swift Spinner

Open Items:

-- CW_CARD_QUERY_SPLINTERVERSE has been updated and uploaded.

-- Please rest assured that if I put a card up here for advice, that I have literally banged my head against the wall for hours on it before bothering to post it. :)

-- Omen Machine and Maralen of the Mornsong are coded and their abilities work, with one exception. I can't seem to find a way to prevent drawing the card that is drawn during the draw step. I have tried the following with/without pre_trigger="1":
Code: Select all
<TRIGGER value="DREW_CARD" pre_trigger="1">
         MTG():OverrideEvent()
         return true
      </TRIGGER>
-- Fatal Lore http://pastebin.com/ZPeie9Ef This one is odd. I am playing against the AI and when the AI is asked to make a multiple choice, the answer returned is 2, which is not one of the options.

-- Lurking Evil http://pastebin.com/TK2cwMtp Will not turn into a creature no matter what I do. I've tried it without the cost. I've looked at similar cards such as Veiled Crocodile and Daxos's Torment. Don't know what i'm doing wrong here.

-- Magebane Armor http://pastebin.com/txigdn71 Can't seem to prevent the noncombat damage. I've tried variations (as shown in the comment in the code).

-- Meandering Towershell http://pastebin.com/x4V3GKXx This guy attacks, goes into exile, and returns tapped and "appearing" to attack the other player. But, all it really does is put the light beam on the other player and remain there until end of combat on the --subsequent-- turn (lasts through my combat and into the next turn's). I've tried messing with the pre_trigger. I thought maybe it had to do with it's attacking trigger firing again upon its return, so I tried a linkdc check, but that didn't work. Really not sure what to do.

Next:

Back tomorrow to code more missing cards and implement any suggestions on the above.
---------------------------------------------
The DOTP2014 CW is updated nightly between 11 PM and 12 AM EST.
Known Issues/Bugs |
Impossible Cards List | Update Your Land Pools
Splinterverse
 
Posts: 918
Joined: 04 Sep 2016, 13:32
Has thanked: 150 times
Been thanked: 76 times

Re: Community Wad

Postby fallenangle » 05 Nov 2016, 01:55

For the card drawing problem, you can use an interrogation query to check if the number of cards drawn during the draw step is zero. If it is, you can override the event. Like this:

Code: Select all
<TRIGGERED_ABILITY replacement_effect="1">
<TRIGGER value="DREW_CARD" simple_qualifier="objectyoucontrol"  pre_trigger="1">
local interrogation = MTG():ClearInterrogationQuery()
         interrogation:SetPlayer( EffectController() )
         local num_drawn_this_step = interrogation:Count( INTERROGATE_CARDS_DRAWN, INTERROGATE_THIS_STEP, 2 )
         if EffectController():MyTurn() and num_drawn_this_step == 0 and MTG():GetStep() == STEP_DRAW then
            MTG():OverrideEvent()
end
</TRIGGER>
</TRIGGERED_ABILITY>
This should be a separate triggered ability, as it will only override the first card normally drawn during the draw step.

For the Towershell, one of the things I see is that you exile the card before setting and protecting the pointer to it. Your trigger will return nil values if it fires, since the card you mean to call becomes nil before it can become part of the delay DC.

Magebane Armor should use a pre-trigger so that it prevents the damage before it is dealt rather than as it is dealt.

I'm betting that Lurking Evil won't turn into a creature because your current code does not give it power or toughness values.
fallenangle
 
Posts: 319
Joined: 20 Jul 2013, 02:31
Has thanked: 73 times
Been thanked: 41 times

Re: Community Wad

Postby migookman » 05 Nov 2016, 11:25

Cards coded:
Vesuvan Doppleganger
Varchild's War-riders
Vanishing
Valor Made Real
Ursine Fylgia
Volrath's Shapeshifter
User avatar
migookman
 
Posts: 135
Joined: 05 Aug 2014, 06:37
Has thanked: 22 times
Been thanked: 28 times

Re: Community Wad

Postby thefiremind » 05 Nov 2016, 13:06

Splinterverse wrote:-- Omen Machine and Maralen of the Mornsong
May I see the full code for one of these, too? It seems strange to me that it prevents all the draws except the one in the draw step. Are there cards with dredge in the CW? If there are, they should be perfect examples of how to do it.

I can't see anything wrong: it's a mystery to me as well. But aside from that, I want to be sure you know that this would be an approximated card: it should be treated as a modal spell, but we have no way to make another player choose the mode.
EDIT: I just had an idea for a better approximation. Mind you: I don't know if it works, it will still be an approximation, and it will be a bit convoluted (that is, not very comfortable for a human player and maybe incomprehensible for the AI). I'll write some code later.

fallenangle's comment seems to be the only possible explanation. I would have expected the card to be put into the graveyard, though, if P/T isn't specified, since it should be 0/0 by default.
Are the examples you followed working? In Magic Duels we have to use layers 4A and 4B for changing types and sub-types, can't remember if it was like that in DotP2014 already.

You need pre_trigger="1", but you also need the TRIGGERED_ABILITY to be replacement_effect="1".

fallenangle is right, you have to set the card pointer in the delayDC and protect it before exiling the source. But you should also use that pointer inside the delayed trigger instead of using EffectSource(), otherwise what have you set it for? :wink:
You can safely remove pre_trigger="1" from the delayed trigger, I think it doesn't even get considered without replacement_effect/replacement_query (and even if it does, it's useless here).
< 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: Community Wad

Postby Splinterverse » 05 Nov 2016, 13:38

thefiremind wrote:
Splinterverse wrote:-- Omen Machine and Maralen of the Mornsong
May I see the full code for one of these, too? It seems strange to me that it prevents all the draws except the one in the draw step. Are there cards with dredge in the CW? If there are, they should be perfect examples of how to do it.
I think I've got them working and it appears to have been a minor typo elsewhere. Let me get back to you later today on these when I've finished testing to be sure.

thefiremind wrote:
I can't see anything wrong: it's a mystery to me as well. But aside from that, I want to be sure you know that this would be an approximated card: it should be treated as a modal spell, but we have no way to make another player choose the mode.
EDIT: I just had an idea for a better approximation. Mind you: I don't know if it works, it will still be an approximation, and it will be a bit convoluted (that is, not very comfortable for a human player and maybe incomprehensible for the AI). I'll write some code later.
Since "mode" isn't really something that happens in paper Magic, how is using a multiple choice an approximation? I understand that under the hood, it functions differently, but doesn't it offer the same result?

thefiremind wrote:
fallenangle's comment seems to be the only possible explanation. I would have expected the card to be put into the graveyard, though, if P/T isn't specified, since it should be 0/0 by default.
Are the examples you followed working? In Magic Duels we have to use layers 4A and 4B for changing types and sub-types, can't remember if it was like that in DotP2014 already.
The examples are working and I think fallenangle is correct. I overlooked the P/T piece. Will know more when I've finished my testing.

thefiremind wrote:
fallenangle is right, you have to set the card pointer in the delayDC and protect it before exiling the source. But you should also use that pointer inside the delayed trigger instead of using EffectSource(), otherwise what have you set it for? :wink:
You can safely remove pre_trigger="1" from the delayed trigger, I think it doesn't even get considered without replacement_effect/replacement_query (and even if it does, it's useless here).
This is new information me. So you have to have both pre_trigger and replacement_effect/query in place for pre_trigger to work? Glad to learn this. This might be the issue in some of the cards I have shelved.

Thank you for the help thefiremind and falleangle. I couldn't do this stuff without the support of this community. Many thanks!
---------------------------------------------
The DOTP2014 CW is updated nightly between 11 PM and 12 AM EST.
Known Issues/Bugs |
Impossible Cards List | Update Your Land Pools
Splinterverse
 
Posts: 918
Joined: 04 Sep 2016, 13:32
Has thanked: 150 times
Been thanked: 76 times

Re: Community Wad

Postby Splinterverse » 05 Nov 2016, 13:39

Oh, thefiremind, another question for you. With regard to the "Name a card" functions you wrote, can I keep adding items to S_FillAlphabeticChest? In other words, can I filter one zone and add to the chest and then filter another zone and add that to the existing chest?
---------------------------------------------
The DOTP2014 CW is updated nightly between 11 PM and 12 AM EST.
Known Issues/Bugs |
Impossible Cards List | Update Your Land Pools
Splinterverse
 
Posts: 918
Joined: 04 Sep 2016, 13:32
Has thanked: 150 times
Been thanked: 76 times

Re: Community Wad

Postby thefiremind » 05 Nov 2016, 13:50

Splinterverse wrote:Since "mode" isn't really something that happens in paper Magic, how is using a multiple choice an approximation? I understand that under the hood, it functions differently, but doesn't it offer the same result?
Your code doesn't target the creatures, so you could potentially destroy creatures with shroud, hexproof or protection from black. Also, the opponent wouldn't be able to know which creatures you chose in order to be able to answer properly (by sacrificing them, bouncing them or whatever), and that would be unfair.
However, just putting a TARGET block for the 2 creatures would be wrong: the modal choice should happen before choosing targets. In fact, if your opponent chooses the first mode, you shouldn't target any creature. This is relevant in case of Phantasmal Bear and similar cards.

My idea involves using 2 TARGET blocks with not_targeted="1": one to choose the opponent, and one to make the opponent choose the mode. And here's where it gets a bit weird: the opponent would choose you for mode 1 (you draw 3 cards) or themselves for mode 2 (you destroy the creatures and they draw 3 cards). Here's the code I wrote, totally untested:
An untested Fatal Lore idea | Open
Code: Select all
    <TARGET tag="CARD_QUERY_CHOOSE_OPPONENT" definition="0" compartment="0" count="1" not_targeted="1" />
    <TARGET_DEFINITION id="0">
    -- This will be the opponent who makes the choice.
    local filter = ClearFilter()
    filter:SetFilterType(FILTER_TYPE_PLAYERS)
    filter:Add( FE_TEAM, OP_NOT, EffectController():GetTeam() )
    </TARGET_DEFINITION>
    <TARGET tag="CARD_QUERY_CHOOSE_CONTROLLER_OR_YOURSELF" definition="1" compartment="1" count="1" not_targeted="1">
    MTG():SetTargetAnswerer( EffectDC():Get_Targets(0):Get_PlayerPtr(0) )
    </TARGET>
    <TARGET_DEFINITION id="1">
    -- This will be how the opponent chooses the mode:
    -- If they choose the spell's controller, then it means mode 1 ("You draw three cards").
    -- If they choose themselves, then it means mode 2 ("You destroy up to...").
    -- The text for the tag "CARD_QUERY_CHOOSE_CONTROLLER_OR_YOURSELF" will need to explain this clearly.
    local filter = ClearFilter()
    filter:SetFilterType(FILTER_TYPE_PLAYERS)
    local subFilter = filter:AddSubFilter_Or()
       subFilter:Add( FE_PLAYER_INSTANCE, OP_IS, EffectController() )
       subFilter:Add( FE_PLAYER_INSTANCE, OP_IS, EffectDC():Get_Targets(0):Get_PlayerPtr(0) )
    </TARGET_DEFINITION>
    <TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_DESTROY" definition="2" compartment="2" up_to="1">
    local count = 0
    if EffectDC():Get_Targets(0):Get_PlayerPtr(0) == EffectDC():Get_Targets(1):Get_PlayerPtr(0) then
       count = 2 -- If the opponent chose themselves, we can destroy up to 2 creatures
    end
    MTG():SetTargetCount(count)
    </TARGET>
    <TARGET_DEFINITION id="2">
    local filter = ClearFilter()
    filter:Add(FE_TYPE, OP_IS, CARD_TYPE_CREATURE)
    filter:Add( FE_CONTROLLER, OP_IS, EffectDC():Get_Targets(0):Get_PlayerPtr(0) )
    </TARGET_DEFINITION>
    <RESOLUTION_TIME_ACTION>
    local opponent = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
    if opponent == EffectDC():Get_Targets(1):Get_PlayerPtr(0) then
       -- Mode 2: Destroy the creatures and let the opponent draw 3 cards
       local targetDC = EffectDC():Get_Targets(2)
       for i=0,1 do
          local creature = targetDC:Get_CardPtr(i)
          if creature ~= nil then
             creature:DestroyWithoutRegenerate()
          end
       end
       opponent:DrawCards(3) -- Actually, you should ask the opponent how many cards they want to draw, but I'd leave it simple as a first test phase
    else
       -- Mode 1: Draw 3 cards
       EffectController():DrawCards(3)
    end
    </RESOLUTION_TIME_ACTION>
Splinterverse wrote:With regard to the "Name a card" functions you wrote, can I keep adding items to S_FillAlphabeticChest? In other words, can I filter one zone and add to the chest and then filter another zone and add that to the existing chest?
I can't remember how I wrote those functions, too much time has passed. But wasn't I already including all the cards existing in the current match?
< 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: Community Wad

Postby Splinterverse » 05 Nov 2016, 14:04

thefiremind wrote:My idea involves using 2 TARGET blocks with not_targeted="1": one to choose the opponent, and one to make the opponent choose the mode. And here's where it gets a bit weird: the opponent would choose you for mode 1 (you draw 3 cards) or themselves for mode 2 (you destroy the creatures and they draw 3 cards).
Ok. I see what you are saying. I like your idea and will test it. Not that it would help in this scenario, but it would be cool if there was a targeted="1" option available to us outside of target blocks.

thefiremind wrote:
Splinterverse wrote:With regard to the "Name a card" functions you wrote, can I keep adding items to S_FillAlphabeticChest? In other words, can I filter one zone and add to the chest and then filter another zone and add that to the existing chest?
I can't remember how I wrote those functions, too much time has passed. But wasn't I already including all the cards existing in the current match?
I haven't checked in game, but code-wise, it looks like it's building the DC based on the filter. The reason I ask is because I want to create a DC with cards from an opponent, but I don't think it's fair to include everything in that opponent's library (it would be akin to searching his/her library). I want to include only cards in the battlefield, graveyard, and exile. I know this wouldn't account for cards that had previously been put back in the library or revealed from the hand, but I'd rather have the list be smaller than give the player an unfair advantage of knowing every card inside the opponent's library.

Here's the code from the LOL file:
Code: Select all
-- The original author: thefiremind
-- October 19, 2013 Updated

S_NameChest = {}

S_SaveName = function(card)
   S_NameChest[Object()] = card:GetCardName()
end

S_LoadName = function()
   return S_NameChest[Object()]
end

S_FillAlphabeticChest = function(chest, filter)
   if chest == nil or filter == nil then
      return
   end
   local cards = {}
   local card_index = 0
   local filter_count = filter:EvaluateObjects()
   for i=0,filter_count-1 do
      local current_card = filter:GetNthEvaluatedObject(i)
      local duplicate = false
      if card_index > 0 then
         for j=0,card_index-1 do
            duplicate = duplicate or ( cards[j]:GetCardName() == current_card:GetCardName() )
         end
      end
      if duplicate == false then
         cards[card_index] = current_card
         card_index = card_index + 1
      end
   end
   for i=card_index-1,1,-1 do
      for j=0,i-1 do
         if cards[j]:GetCardName() > cards[j+1]:GetCardName() then
            local temp = cards[j]
            cards[j] = cards[j+1]
            cards[j+1] = temp
         end
      end
   end
   for i=0,card_index-1 do
      chest:Set_CardPtr(i, cards[i])
   end
end

S_DeclareCardName = function(card, controller)
   local doesnt_need_message = EffectController()
   if controller ~= nil then
      doesnt_need_message = controller
   end
   for i=0,MTG():GetNumberOfPlayers()-1 do
     local player = MTG():GetNthPlayer(i)
      if player ~= nil and player:IsAI() == false and player ~= doesnt_need_message then
      player:SetCustomQueryInstructionCardPtr(card)
       player:BeginNewMultipleChoice()
       player:AddMultipleChoiceAnswer("CONTROL_MB_CONFIRM")
       player:AskMultipleChoiceQuestion("CARD_QUERY_OPTION_CHOSEN_NAME")
      end
   end
end
My current code (untested) has two calls to the same DC created for the first call to S_FillAlphabeticChest(). The reason I am doing it that way is I can't do a subfilter for zones (or at least it hasn't worked in other cards for me; maybe I was doing it wrong?).
---------------------------------------------
The DOTP2014 CW is updated nightly between 11 PM and 12 AM EST.
Known Issues/Bugs |
Impossible Cards List | Update Your Land Pools
Splinterverse
 
Posts: 918
Joined: 04 Sep 2016, 13:32
Has thanked: 150 times
Been thanked: 76 times

Re: Community Wad

Postby thefiremind » 05 Nov 2016, 14:15

Splinterverse wrote:The reason I ask is because I want to create a DC with cards from an opponent, but I don't think it's fair to include everything in that opponent's library (it would be akin to searching his/her library). I want to include only cards in the battlefield, graveyard, and exile.
OK, now I understood. You can't use SetZone in a subfilter, but you can use FE_ZONE, like this:
Code: Select all
filter:Add(FE_ZONE, OP_NOT, ZONE_LIBRARY)
Of course this code would exclude your own library as well.

While I was looking for my functions in the Programming Talk section, I found a topic about Meandering Towershell:
viewtopic.php?f=63&t=15629
The problem described here is that if you put Meandering Towershell onto the battlefield attacking during the declare attackers step, it will fire the ATTACKING trigger, while it shouldn't.
< 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

PreviousNext

Return to 2014

Who is online

Users browsing this forum: No registered users and 5 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form