It is currently 25 Apr 2024, 11:31
   
Text Size

Searching for good implementation of "until your next turn"

Moderator: CCGHQ Admins

Searching for good implementation of "until your next turn"

Postby thefiremind » 11 Jul 2013, 12:47

I coded Nivix, Aerie of the Firemind so that "until your next turn" is expressed as "until it is your turn and the turn number is greater than the current one". This is acceptable for Nivix since its owner needs to be in game anyway. But the detain mechanic can't make this assumption, and look at what Gatherer says:
Gatherer wrote:When a player leaves a multiplayer game, any continuous effects with durations that last until that player's next turn or until a specific point in that turn will last until that turn would have begun. They neither expire immediately nor last indefinitely.
So, this is my function that needs to be completed:
Code: Select all
TFM_UntilMyNextTurn = function(currentTurn)
-- to be used in durations that last "until your next turn"
   if currentTurn ~= nil then
      local controller = EffectController()
      if controller ~= nil then
         return controller:MyTurn() and MTG():GetTurnNumber() > currentTurn
      else
         -- WHAT DO I INSERT HERE?
      end
   end
   return true
end
Any ideas?
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby MC Brodie » 11 Jul 2013, 19:07

Could you count upkeeps or end steps instead? Then based on the number of players left in the game you could determine when it was the players turn who left?

I have no idea if this would actually work or how you could change it for something like time warp or eon hub. Can one function tell if another card grants someone an additional turn?

Sorry if this sounds stupid. I don't really have any programming or duels modding background. I just like to follow these threads for some reason...
-----------------------------------------------------------------------
Song of the Day: 46 and 2 (cover)
MC Brodie
 
Posts: 310
Joined: 01 Jun 2013, 00:10
Has thanked: 44 times
Been thanked: 34 times

Re: Searching for good implementation of "until your next tu

Postby thefiremind » 11 Jul 2013, 19:34

I'm not sure if I understood what you mean. About counting the number of players left in the game, this:
Code: Select all
return MTG():GetTurnNumber() >= currentTurn + MTG():GetNumberOfPlayers()
would work if I were able to use the ability only during my turn (I thought about that).
I also thought about saving the next player together with the current turn number, but then in a FFA 4-player game there's the chance that the next player loses together with me... :(
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby MC Brodie » 11 Jul 2013, 20:46

Yea i guess you would need to be able to tell when a player died. What i was thinking was, in a four player match, "until your next turn" is really 4 upkeeps. So you could just keep a turn counter to compare to the number of alive players (i don't know if this method can/will work in 2hg).

its probably more complicated than its worth. I'll post my thoughts on why I'm probably wrong when i get home from work
-----------------------------------------------------------------------
Song of the Day: 46 and 2 (cover)
MC Brodie
 
Posts: 310
Joined: 01 Jun 2013, 00:10
Has thanked: 44 times
Been thanked: 34 times

Re: Searching for good implementation of "until your next tu

Postby thefiremind » 11 Jul 2013, 21:27

MC Brodie wrote:What i was thinking was, in a four player match, "until your next turn" is really 4 upkeeps.
That's what I said earlier: this is true only if I'm starting to count from my turn. Which is true most of the times, but for example if I manage to sneak an Azorius Arrester during another player's turn by giving it flash with something, the detain effect will last for less than 4 turns.
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby MC Brodie » 11 Jul 2013, 21:55

thefiremind wrote:
MC Brodie wrote:What i was thinking was, in a four player match, "until your next turn" is really 4 upkeeps.
That's what I said earlier: this is true only if I'm starting to count from my turn. Which is true most of the times, but for example if I manage to sneak an Azorius Arrester during another player's turn by giving it flash with something, the detain effect will last for less than 4 turns.
Yup that is what I was going to say. I'll just keep my mouth shut and keep to reading threads during my lunchbreak and when I get bored at work. Don't mind me...
-----------------------------------------------------------------------
Song of the Day: 46 and 2 (cover)
MC Brodie
 
Posts: 310
Joined: 01 Jun 2013, 00:10
Has thanked: 44 times
Been thanked: 34 times

Re: Searching for good implementation of "until your next tu

Postby thefiremind » 11 Jul 2013, 22:29

Getting ideas from someone else is always useful even if they are wrong... there's always the chance that I'm not considering an easy solution, and talking about the problem sometimes uncovers new aspects of it. So, thanks for trying, I appreciated it. :)
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby RiiakShiNal » 12 Jul 2013, 01:09

I just thought of a possibility to code it. The MTG object has a couple of functions that should help here:
  • GetNumberOfStartingPlayers
  • GetNthStartingPlayer

When the effect starts you store your starting player index. At the beginning of each turn you will get the current player's starting player index and compare it to yours. If it equals the effect ends, if not equal then we compare it to the last player's starting player index. If it equals the last player's starting player index then we ignore it (extra turn from Temporal Mastery or another card), otherwise we compare it to a list of starting player indexes of the turns since we started the effect. If it equals one of the stored indexes then we have somehow passed by the player that started the effect (probable that the player died) and the effect should end, otherwise we store the index and allow the effect to continue.

That should do it for most cases, there is one other case I can think of that will require extra work: Skipped Turns. Depending on the rulings for "until your next turn" when you skip a turn either the effect will end when you skip the turn (in which case you don't have to worry about skipped turns) or if the ability should continue past a skipped turn until you actually get a turn (in which case you would need to clear the stored starting player index list when the turn is skipped).

This is currently the best solution I can think of (though is still somewhat complex). As this should allow for correct duration in almost all cases including extra turns, reversed turn order, and the possible special case for skipped turns (unless I forgot something). About the only case I can think of where this would fail is if the turn order reverses in the middle or end of a cycle (with 3 or 4 players, though I don't really think this will be a problem because I don't think we can code Topsy Turvy anyway).

The reason you use the Starting Player Indexes instead of the current player indexes is because in a game with more than two players when one person loses it is possible that the current player indexes will change.
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: Searching for good implementation of "until your next tu

Postby thefiremind » 12 Jul 2013, 11:49

It's hard for me to translate your idea into code... when you have some time, if you can write an example, I'd appreciate it (no need to rush).
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby RiiakShiNal » 12 Jul 2013, 12:41

May take me some time, but sure I'll write up an example.
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: Searching for good implementation of "until your next tu

Postby RiiakShiNal » 13 Jul 2013, 02:19

Sorry, double post, but I figured it would be easier to catch this way since edits don't notify people of the update.

Here is an example of what I tried to explain (semi-tested):
Inaction Injunction | Open
Code: Select all
<?xml version='1.0'?>
<CARD_V2>
   <FILENAME text="RSN_INACTION_INJUNCTION_265376" />
   <CARDNAME text="INACTION_INJUNCTION" />
   <TITLE>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Inaction Injunction]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Injonction d'inaction]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Mandato de inacción]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Untätigkeitsverfügung]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Ingiunzione di Cessata Attività]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[謹慎命令]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[활동 금지령]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Приказ о Бездействии]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Mandado de Inação]]></LOCALISED_TEXT>
   </TITLE>
   <MULTIVERSEID value="265376" />
   <ARTID value="RSN265376" />
   <ARTIST name="Wayne Reynolds" />
   <CASTING_COST cost="{1}{U}" />
   <FLAVOURTEXT>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[“To prevent action is to prevent transgression.”
Azorius Arrester motto]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[« Empêcher l’action, c’est empêcher la transgression. »
—Devise des courtiers d’Azorius]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[“Impedir la acción es impedir la transgresión.”
—Lema de los encarceladores azorios]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[„Handlungen verhindern heißt Übertritte verhindern."
—Motto der Azorius-Eintreiber]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[“Prevenire l’azione è prevenire la trasgressione.”
—Motto della polizia Azorius]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[「行動を防げば罪も防げる。」
――アゾリウスの拘引者のモットー]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[“행동을 막는 것은 범죄를 막는 것이다.”
—아조리우스 체포원의 좌우명]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[«Упредишь действие — предотвратишь преступление».
— девиз Задержателя Азориусов]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[“Prevenir a ação é prevenir a transgressão.”
— Lema dos Encarceiradores Azorius]]></LOCALISED_TEXT>
   </FLAVOURTEXT>
   <TYPE metaname="Sorcery" />
   <EXPANSION value="RTR" />
   <RARITY metaname="C" />
   <SPELL_ABILITY linked_ability_group="1">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Detain target creature an opponent controls. |(Until your next turn, that creature can’t attack or block and its activated abilities can’t be activated.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Détenez une créature ciblée qu’un adversaire contrôle. |(Jusqu’à votre prochain tour, cette créature ne peut ni attaquer ni bloquer et ses capacités activées ne peuvent pas être activées.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Detén la criatura objetivo que controla un oponente. |(Hasta tu próximo turno, esa criatura no puede atacar ni bloquear y sus habilidades activadas no pueden activarse.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Inhaftiere eine Kreatur deiner Wahl, die ein Gegner kontrolliert. |(Bis zu deinem nächsten Zug kann diese Kreatur nicht angreifen oder blocken, und ihre aktivierten Fähigkeiten können nicht aktiviert werden.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Trattieni una creatura bersaglio controllata da un avversario. |(Fino al tuo prossimo turno, quella creatura non può attaccare o bloccare e le sue abilità attivate non possono essere attivate.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[対戦相手1人がコントロールするクリーチャー1体を対象とし、それを留置する。(あなたの次のターンまで、そのクリーチャーでは攻撃もブロックもできず、それの起動型能力は起動できない。)]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[상대가 조종하는 생물 한 개를 목표로 정한다. 그 생물을 억류한다. |(당신의 다음 턴이 될 때까지 그 생물은 공격하거나 방어할 수 없으며, 그 생물의 활성화능력은 활성화될 수 없다.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Задержите целевое существо под контролем оппонента. |(До вашего следующего хода то существо не может атаковать или блокировать, и его активируемые способности не могут быть активированы.)|]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Detenha a criatura alvo que um oponente controla. |(Até seu próximo turno, aquela criatura não pode atacar nem bloquear e as habilidades ativadas dela não podem ser ativadas.)|]]></LOCALISED_TEXT>
      <TARGET tag="CARD_QUERY_CHOOSE_CREATURE_IS_INDESTRUCTIBLE" definition="0" compartment="0" count="1" />
      <TARGET_DEFINITION id="0">
         local oFilter = ClearFilter()
         oFilter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE )
         oFilter:Add( FE_TEAM, OP_NOT, EffectController():GetTeam() )
      </TARGET_DEFINITION>
      <RESOLUTION_TIME_ACTION>
         local oTarget = EffectDC():Get_Targets(0):Get_CardPtr(0)
         if (oTarget ~= nil) then
            -- Figure out the EffectController's starting player index.
            local nControllerStartingIndex = -1
            for i = 0, (MTG():GetNumberOfStartingPlayers() - 1) do
               local oStartingPlayer = MTG():GetNthStartingPlayer( i )
               if (oStartingPlayer == EffectController()) then
                  nControllerStartingIndex = i
                  break
               end
            end

            local oDurationDC = LinkedDC():Make_Chest( 200 )

            -- Store the index in the duration object
            oDurationDC:Int_Set( 1, nControllerStartingIndex )

            -- We also need to set the index of the last player to an invalid index (-1 should work).
            oDurationDC:Int_Set( 2, -1 )

            -- Now set up our delayed trigger.
            local oDelayDC = EffectDC():Make_Chest( 10 )
            oDelayDC:Set_CardPtr( 0, oTarget )
            MTG():CreateDelayedTrigger( 1, oDelayDC )
         end
      </RESOLUTION_TIME_ACTION>
      <CONTINUOUS_ACTION layer="6">
         local oTarget = EffectDC():Get_Targets(0):Get_CardPtr(0)
         if (oTarget ~= nil) then
            local oCharacteristics = oTarget:GetCurrentCharacteristics()
            if (oCharacteristics ~= nil) then
               oCharacteristics:Bool_Set( CHARACTERISTIC_CANT_ATTACK, 1 )
               oCharacteristics:Bool_Set( CHARACTERISTIC_CANT_BLOCK, 1 )
               oCharacteristics:Bool_Set( CHARACTERISTIC_CANT_USE_ACTIVATED_ABILITIES, 1 )
               oCharacteristics:GrantAbility( 2 )
            end
         end
      </CONTINUOUS_ACTION>
      <DURATION>
         -- We need to end when either our target is no longer valid or when we have determined we need
         --  to end the effect because the proper time has come.
         local oTarget = EffectDC():Get_Targets(0):Get_CardPtr(0)
         local oDurationDC = LinkedDC():Get_Chest( 200 )
         return ((oTarget == nil) or (oDurationDC:Int_Get( 0 ) == 1))
      </DURATION>
   </SPELL_ABILITY>
   <TRIGGERED_ABILITY replacement_effect="1" resource_id="1" linked_ability_group="1">
      <TRIGGER value="BEGINNING_OF_PLAYERS_TURN">
         return ((TriggerPlayer() ~= nil) and (TriggerPlayer():MyTurn() ~= 0))
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         local oDurationDC = LinkedDC():Get_Chest( 200 )

         -- First thing we need to do is get the current player's starting player index.
         local nCurrentStartingIndex = -1
         for i = 0, (MTG():GetNumberOfStartingPlayers() - 1) do
            local oStartingPlayer = MTG():GetNthStartingPlayer( i )
            if (oStartingPlayer == TriggerPlayer()) then
               nCurrentStartingIndex = i
               break
            end
         end

         -- Check against the starting index of the original effect controller.
         if (oDurationDC:Int_Get( 1 ) == nCurrentStartingIndex) then
            -- This is the beginning of the next turn so we need to end the effect.
            oDurationDC:Int_Set( 0, 1 )
         else
            -- This is not the beginning of the next turn for the original effect controller.
            -- So, now we need to see if the current player is the same as the last player (extra turns).
            if (oDurationDC:Int_Get( 2 ) ~= nCurrentStartingIndex) then
               -- Record this starting index as the last player so we can compare for
               --  determining if a player took an extra turn.
               oDurationDC:Int_Set( 2, nCurrentStartingIndex )

               -- Nope not the same, so we need to first compare against the indexes of
               --  all the players who have had turns since we started the effect.
               local oPlayerHistory = oDurationDC:Get_Chest( 3 )

               -- If we don't have a chest then we need to create it as we will need it.
               if (oPlayerHistory == nil) then
                  oPlayerHistory = oDurationDC:Make_Chest( 3 )
               end

               -- Look through the history to see if this player has had a non-consecutive turn
               --  since the effect started, if yes then we'll need to end the effect.
               local bFoundInHistory = false
               local nHistoryCount = oPlayerHistory:Int_Get( 0 )
               if (nHistoryCount &gt; 0) then
                  for i = 1, nHistoryCount do
                     if (oPlayerHistory:Int_Get( i ) == nCurrentStartingIndex) then
                        -- This player is starting their second non-consecutive turn
                        --  since the effect started which means the effect should end
                        --  now since the original effect controller is likely no
                        --  longer in the game.
                        oDurationDC:Int_Set( 0, 1 )
                        bFoundInHistory = true
                        break
                     end
                  end
               end

               -- If we did not find the index in the history then we need to add it.
               if (bFoundInHistory ~= true) then
                  oPlayerHistory:Int_Inc( 0 )
                  oPlayerHistory:Int_Set( nHistoryCount + 1, nCurrentStartingIndex )
               end
            end
         end

         -- Apparently LinkedDC() can't be accessed in the CLEANUP tag.
         if (oDurationDC:Int_Get( 0 ) == 1) then
            MTG():RemoveDelayedTrigger( 1 )
         end
      </RESOLUTION_TIME_ACTION>
      <CLEANUP>
         return (EffectDC():Get_CardPtr( 0 ) == nil)
      </CLEANUP>
   </TRIGGERED_ABILITY>
   <STATIC_ABILITY resource_id="2">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Detained.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Detained.]]></LOCALISED_TEXT>
   </STATIC_ABILITY>
   <SPELL_ABILITY>
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Draw a card.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Piochez une carte.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Roba una carta.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Ziehe eine Karte.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Pesca una carta.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[カードを1枚引く。]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[카드 한 장을 뽑는다.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Возьмите карту.]]></LOCALISED_TEXT>
      <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Compre um card.]]></LOCALISED_TEXT>
      <RESOLUTION_TIME_ACTION>
         EffectController():DrawCards(1)
      </RESOLUTION_TIME_ACTION>
   </SPELL_ABILITY>
</CARD_V2>
Notes:
  • This may or may not work correctly in the Effect Controller skips his/her next turn, I didn't really check the rulings nor did I really want to code up a card for skipping the next turn and do a bunch of tests with it.
  • This uses the trigger BEGINNING_OF_PLAYERS_TURN instead of BEGINNING_OF_TURN because BEGINNING_OF_TURN does not provide a TriggerPlayer() (always nil).
  • The delayed trigger removes itself in the RESOLUTION_TIME_ACTION once the proper time has been met because the LinkedDC() is not available in CLEANUP blocks.
  • I had to use LinkedDC() because the DC that is passed as a parameter to the Delayer Trigger is sent completely by value instead of by reference (meaning any changes to the EffectDC() in the Delayed Trigger did not propagate back to the originating ability).
  • The EffectDC() that is available in CLEANUP blocks in Delayed Triggers is separate from the EffectDC() that is used in the ability itself though it does appear to be a copy of the DC passed into the Delayed Trigger. This means that if you send in a DC with register 0 set to 0 then in the Delayed Trigger RESOLUTION_TIME_ACTION do EffectDC():Int_Set( 0, 1 ) in the CLEANUP block EffectDC():Int_Get( 0 ) will still return 0.
  • I did not do an exhaustive series of tests, but I did do some simple tests in FFA 2-player, 3-player, and 4-player modes. That is why I stated it is semi-tested. I did not do a test in 2-Headed Giant to see what would happen, though I suspect it may fail if the other team takes an extra turn due to probably being triggered twice at the beginning of the combined turn. Though it may be possible to fix it by comparing by checking last team instead of last player.
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: Searching for good implementation of "until your next tu

Postby thefiremind » 13 Jul 2013, 09:46

Thanks for the example, anyway that's a lot of code... I think I'll follow the
Code: Select all
return MTG():GetTurnNumber() >= currentTurn + MTG():GetNumberOfPlayers()
for now, since the detain mechanic is always on creatures, sorceries, or triggers at the beginning of my upkeep with Martial Law. I won't include cards that give flash to something that doesn't have it. :lol: Maybe I'll enhance it with your idea in the future.
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby RiiakShiNal » 13 Jul 2013, 11:49

I never said it was going to be easy or that it could be done with very little code. It's just the only method I can come up with that is as correct as possible and even then I thought of another way it could be screwed up:
  • Player 0 cast Inaction Injunction during your turn (player 0) on a creature belonging to player 2.
  • Player 1 then skips their turn due to some effect.
  • Player 2 goes (creature still detained) and kills Player 0.
  • Player 0 should have a turn here except he died (No BEGINNING_OF_PLAYERS_TURN trigger).
  • Player 1 goes (since this is the first time Player 1 has had a turn since the effect started it thinks the creature should still be detained even though it shouldn't).
  • Player 2 starts his turn and the creature is finally no longer detained (1 turn longer than it should have been).
I think this can be fixed (though fixing this problem would probably remove compatibility with reversed turn order, which probably won't matter because of other issues with trying to code Topsy Turvy), but it will mean more checks and more code which I'm not even going to think about at the moment (maybe in a week or two).

Your current method with GetTurnNumber and GetNumberOfPlayers also doesn't take into account extra turns from say a Temporal Mastery or Emrakul, the Aeons Torn. So even if you don't include cards that can give flash or pseudo flash, other players (even the AI) can still screw up your counting.

Oh and I did try to make my code fairly reusable so that most if not all could be picked up and dropped into another card with little to no changes.
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: Searching for good implementation of "until your next tu

Postby thefiremind » 13 Jul 2013, 12:06

RiiakShiNal wrote:Your current method with GetTurnNumber and GetNumberOfPlayers also doesn't take into account extra turns from say a Temporal Mastery or Emrakul, the Aeons Torn. So even if you don't include cards that can give flash or pseudo flash, other players (even the AI) can still screw up your counting.
I didn't think about that, but I still think that the solution is too complicated to be worth using it. Most people only play 1v1 after all. :wink:

I'm sorry for having asked an example and then not using it, but I really didn't imagine it would have needed so much code.
< 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: 721 times

Re: Searching for good implementation of "until your next tu

Postby RiiakShiNal » 13 Jul 2013, 12:25

thefiremind wrote:I didn't think about that, but I still think that the solution is too complicated to be worth using it. Most people only play 1v1 after all. :wink:
Maybe, but it's not the only complicated piece of code that has had to be written (look at my ObjectDC and Manual Mana functions they have quite a bit of complicated code) nor will it likely be the last (the Transform functions have yet to be recoded for 2014). When I look at it again I'll probably wind up moving large chunks of it into a function file for reuse (which will make the code on the card much smaller).

thefiremind wrote:I'm sorry for having asked an example and then not using it, but I really didn't imagine it would have needed so much code.
No apologies necessary, though I'm not going to look at this code again for at least a week or two because I'm currently sick of it (mainly due to all the limitations I encountered when coding it). I had wanted to avoid using the LinkedDC, but the DC passed to the Delayed Trigger is done completely by value instead of by reference which is a pain.
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 17 guests


Who is online

In total there are 17 users online :: 0 registered, 0 hidden and 17 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 17 guests

Login Form