Category talk

Difference between revisions of "Seek"

From Shadow Era Wiki

m (wording)
(More content)
Line 8: Line 8:
 
| style="vertical-align: top;" |
 
| style="vertical-align: top;" |
 
* CardInfoPanel.cs
 
* CardInfoPanel.cs
 +
* GameModel.cs
 
* KeywordAbilities.cs
 
* KeywordAbilities.cs
 
* SpecificCard.cs
 
* SpecificCard.cs
Line 21: Line 22:
 
|-
 
|-
 
! colspan="2" | Code seek:
 
! colspan="2" | Code seek:
 +
|-
 +
| colspan="2" | Summary of the Seek process:
 +
# `OnUseAbility()`: Handles the activation of the seek ability.
 +
# CanUseAbility(): Checks if the seek ability can be used.
 +
# StartTargetingForSeek(): Initiates the targeting process for the seek.
 +
# GetAbilityTargets(): Retrieves valid targets for the seek.
 +
# DoSeek(): Executes the seek action:
 +
## GameModel.RemoveDeck(ShadowEraCard card): Removes the card from the deck.
 +
## GameModel.ShowCardForPlayer(ShadowEraCard card): Displays the card to the opponent.
 +
## GameModel.AddHand(ShadowEraCard card): Adds the card to the player's hand.
 +
#OnSeek(): May handle additional effects after the card is added to the hand.
 +
# ShuffleOurDeck(): Shuffles the deck after the seek is completed.
 +
|-
 +
| colspan="2"| This code is a collection of all the functions involved in the '''Seek''' mechanic, though it doesn't exist as a single block in any one file.
 
|-
 
|-
 
| colspan="2" |
 
| colspan="2" |
 
<small><syntaxhighlight lang="csharp">
 
<small><syntaxhighlight lang="csharp">
 +
public override void OnUseAbility()
 +
{
 +
    if (!isPartTwo)
 +
    {
 +
        if (!parent.IsDead())
 +
        {
 +
            MoveToCastPosition();
 +
            GameModel.QueuePart2(parent);
 +
            isPartTwo = true;
 +
        }
 +
    }
 +
    else
 +
    {
 +
        isPartTwo = false;
 +
        DoSeek(usedShadowEnergy: true);
 +
    }
 +
}
 +
 +
public override bool CanUseAbility()
 +
{
 +
    if (GameModel.isSimulating)
 +
    {
 +
        return false;
 +
    }
 +
    if (GameModel.DeckCount() == 0)
 +
    {
 +
        return false;
 +
    }
 +
    if (GameModel.HandCount() == GameModel.MaxHandSize())
 +
    {
 +
        return false;
 +
    }
 +
    return true;
 +
}
 +
 
public void StartTargetingForSeek()
 
public void StartTargetingForSeek()
 
{
 
{
Line 47: Line 97:
 
     DeckListDisplay.abilityCard = parent;
 
     DeckListDisplay.abilityCard = parent;
 
     DeckListDisplay.ShowDeck(GameModel.CurSide());
 
     DeckListDisplay.ShowDeck(GameModel.CurSide());
 +
}
 +
 +
public override List<ShadowEraCard> GetAbilityTargets()
 +
{
 +
    List<ShadowEraCard> list = new List<ShadowEraCard>();
 +
    for (int i = 0; i < GameModel.DeckCount(); i++)
 +
    {
 +
        ShadowEraCard deck = GameModel.GetDeck(i);
 +
        if (IsValidAbilityTarget(deck))
 +
        {
 +
            list.Add(deck);
 +
        }
 +
    }
 +
    return list;
 +
}
 +
 +
private static bool IsValidAbilityTarget(ShadowEraCard check)
 +
{
 +
    return check.cardType == CardTypeEnum.Ally && check.cardSubType == CardSubTypeEnum.Aldmor;
 
}
 
}
  
Line 65: Line 134:
 
     ShuffleOurDeck();
 
     ShuffleOurDeck();
 
     targets.Clear();
 
     targets.Clear();
 +
}
 +
 +
public static void RemoveDeck(ShadowEraCard card)
 +
{
 +
    // Code qui gère la suppression d'une carte du deck
 +
}
 +
 +
public static void ShowCardForPlayer(ShadowEraCard card)
 +
{
 +
    if (!isSimulating && Gameplay.Instance != null)
 +
    {
 +
        Gameplay.Instance.UpdateHand(forceUpdate: true);
 +
        Gameplay.Instance.ShowCard(card);
 +
        Gameplay.Instance.BlockInput(2f);
 +
        if (card.gameObject != null)
 +
        {
 +
            CoroutineManager.Start(_ShowCardForPlayer(card));
 +
        }
 +
    }
 +
}
 +
 +
public static void AddHand(ShadowEraCard card)
 +
{
 +
    // Code qui gère l'ajout d'une carte à la main du joueur
 +
}
 +
 +
public static void OnSeek(ShadowEraCard card)
 +
{
 +
    // Gère les effets ou actions supplémentaires après l'ajout de la carte à la main
 
}
 
}
  
Line 85: Line 183:
 
* Relation to Traps and Why They Are Not Revealed<div style="height: 10px;"></div>
 
* Relation to Traps and Why They Are Not Revealed<div style="height: 10px;"></div>
 
*# The global mechanism for Traps, that they must remain face-down, is integrated into the steps of the '''Seek''' process. This mechanism takes priority over other rules, such as revealing a card that has been '''Seek'''ed.<br />
 
*# The global mechanism for Traps, that they must remain face-down, is integrated into the steps of the '''Seek''' process. This mechanism takes priority over other rules, such as revealing a card that has been '''Seek'''ed.<br />
*# When a Trap is '''Seek'''ed, the face-down rule <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">(PlayFaceDown())</span> inherent to Traps is triggered before any reveal function <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">(RevealCard())</span> can be called. This ensures that the Trap stays hidden, overriding the normal rule that states '''Seek'''ed cards must be revealed.
+
*# When a Trap is '''Seek'''ed, the face-down rule <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">(PlayFaceDown())</span> inherent to Traps is triggered before any reveal function <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">(ShowCardForPlayer())</span> can be called. This ensures that the Trap stays hidden, overriding the normal rule that states '''Seek'''ed cards must be revealed.
*# This behavior highlights how card effects take precedence over standard game rules. The face-down condition bypasses the normal <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">RevealCard()</span> function, ensuring that Traps remain hidden in compliance with their unique mechanics.
+
*# This behavior highlights how card effects take precedence over standard game rules. The face-down condition bypasses the normal <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">ShowCardForPlayer()</span> function, ensuring that Traps remain hidden in compliance with their unique mechanics.
 
*# Therefore, while the '''Seek''' process normally requires cards to be revealed, the Trap mechanic ensures that this reveal is skipped. The handling of Traps shows how <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">AttachCard()</span> triggers card-specific logic (via callbacks) that overrides the default rules, allowing Traps to stay face-down as intended.<div style="height: 20px;"></div>
 
*# Therefore, while the '''Seek''' process normally requires cards to be revealed, the Trap mechanic ensures that this reveal is skipped. The handling of Traps shows how <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">AttachCard()</span> triggers card-specific logic (via callbacks) that overrides the default rules, allowing Traps to stay face-down as intended.<div style="height: 20px;"></div>
 
* Intentional or not?<br />Yes we may say that the behavior of Traps not revealed after '''Seek''' function is intentionally coded by the developers, and here is why:<br />
 
* Intentional or not?<br />Yes we may say that the behavior of Traps not revealed after '''Seek''' function is intentionally coded by the developers, and here is why:<br />
 
*# Traps have specific mechanics that are fundamental to their function: they are played facedown and ''only revealed when triggered''. There is no exception; if a Trap is revealed faceup in the graveyard it is because cards are placed faceup in the graveyard porecess; if a trap is returned to hand, nothing says in the returned to hand process that it should be revealed.
 
*# Traps have specific mechanics that are fundamental to their function: they are played facedown and ''only revealed when triggered''. There is no exception; if a Trap is revealed faceup in the graveyard it is because cards are placed faceup in the graveyard porecess; if a trap is returned to hand, nothing says in the returned to hand process that it should be revealed.
*# The fact that Traps aren’t revealed during a '''Seek''' mechanism follows the logic of the game. The code appears to be structured to ensure this rule is confirmed by preventing the <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">RevealCard()</span> function from being triggered for Traps.
+
*# The fact that Traps aren’t revealed during a '''Seek''' mechanism follows the logic of the game. The code appears to be structured to ensure this rule is confirmed by preventing the <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">ShowCardForPlayer()</span> function from being triggered for Traps.
 
*# Functions like <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">PlayFaceDown()</span> and specific conditions in the code show that the developers have built these special rules for Traps, and they take effect before the standard rules apply.
 
*# Functions like <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">PlayFaceDown()</span> and specific conditions in the code show that the developers have built these special rules for Traps, and they take effect before the standard rules apply.
 
*# Now, the following example code would essentially stop <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">PlayFaceDown()</span> from bypassing the reveal process for '''Seek'''ed cards.
 
*# Now, the following example code would essentially stop <span style="font-family: monospace; background-color: #f8f9fa; padding: 0.2em 0.4em; border: 1px solid #d1d5da; border-radius: 3px;">PlayFaceDown()</span> from bypassing the reveal process for '''Seek'''ed cards.
Line 100: Line 198:
 
     if (isSeeked)
 
     if (isSeeked)
 
     {
 
     {
         // Allow RevealCard() to be invoked for Seeked cards
+
         // Allow ShowCardForPlayer() to be invoked for Seeked cards
         RevealCard(card);
+
         ShowCardForPlayer(card);
 
     }
 
     }
 
     else
 
     else

Revision as of 20:21, 6 September 2024

Explanation of why Krugal Trapper (ll073)'s ability does not reveal the trap card
… still in v4.981

File References in the Game Terms to Locate Seek Reference
  • CardInfoPanel.cs
  • GameModel.cs
  • KeywordAbilities.cs
  • SpecificCard.cs
  • ll001.cs
  • ll006.cs
  • ll040.cs
  • ll154.cs
  • There are more files that refers to cards number, but it was not needed
  • OnSeek
  • DoSeek
  • Seek
Code seek:
Summary of the Seek process:
  1. `OnUseAbility()`: Handles the activation of the seek ability.
  2. CanUseAbility(): Checks if the seek ability can be used.
  3. StartTargetingForSeek(): Initiates the targeting process for the seek.
  4. GetAbilityTargets(): Retrieves valid targets for the seek.
  5. DoSeek(): Executes the seek action:
    1. GameModel.RemoveDeck(ShadowEraCard card): Removes the card from the deck.
    2. GameModel.ShowCardForPlayer(ShadowEraCard card): Displays the card to the opponent.
    3. GameModel.AddHand(ShadowEraCard card): Adds the card to the player's hand.
  6. OnSeek(): May handle additional effects after the card is added to the hand.
  7. ShuffleOurDeck(): Shuffles the deck after the seek is completed.
This code is a collection of all the functions involved in the Seek mechanic, though it doesn't exist as a single block in any one file.
public override void OnUseAbility()
{
    if (!isPartTwo)
    {
        if (!parent.IsDead())
        {
            MoveToCastPosition();
            GameModel.QueuePart2(parent);
            isPartTwo = true;
        }
    }
    else
    {
        isPartTwo = false;
        DoSeek(usedShadowEnergy: true);
    }
}
 
public override bool CanUseAbility()
{
    if (GameModel.isSimulating)
    {
        return false;
    }
    if (GameModel.DeckCount() == 0)
    {
        return false;
    }
    if (GameModel.HandCount() == GameModel.MaxHandSize())
    {
        return false;
    }
    return true;
}
 
public void StartTargetingForSeek()
{
    ClearTargets();
    MoveToCastPosition();
    GameModel.UnhighlightCards();
    GameModel.SetGameState(GameState.GameStateType.target);
    List<ShadowEraCard> abilityTargets = GetAbilityTargets();
    for (int i = 0; i < GameModel.DeckCount(); i++)
    {
        ShadowEraCard deck = GameModel.GetDeck(i);
        if (abilityTargets.Contains(deck))
        {
            GameModel.RemoveDeck(deck);
            i--;
        }
    }
    for (int j = 0; j < abilityTargets.Count; j++)
    {
        GameModel.AddDeck(abilityTargets[j]);
    }
    GameModel.HighlightCards(GetAbilityTargets());
    DeckListDisplay.abilityCard = parent;
    DeckListDisplay.ShowDeck(GameModel.CurSide());
}
 
public override List<ShadowEraCard> GetAbilityTargets()
{
    List<ShadowEraCard> list = new List<ShadowEraCard>();
    for (int i = 0; i < GameModel.DeckCount(); i++)
    {
        ShadowEraCard deck = GameModel.GetDeck(i);
        if (IsValidAbilityTarget(deck))
        {
            list.Add(deck);
        }
    }
    return list;
}
 
private static bool IsValidAbilityTarget(ShadowEraCard check)
{
    return check.cardType == CardTypeEnum.Ally && check.cardSubType == CardSubTypeEnum.Aldmor;
}
 
public void DoSeek(bool usedShadowEnergy)
{
    DeckListDisplay.CloseDeck();
    if (targets.Count > 0 && GameModel.HandCount() < GameModel.MaxHandSize())
    {
        GameModel.RemoveDeck(targets[0]);
        GameModel.ShowCardForPlayer(targets[0]);
        GameModel.AddHand(targets[0]);
        GameModel.OnSeek(targets[0]);
    }
    else
    {
        GameModel.OnSeek(null);
    }
    ShuffleOurDeck();
    targets.Clear();
}
 
public static void RemoveDeck(ShadowEraCard card)
{
    // Code qui gère la suppression d'une carte du deck
}
 
public static void ShowCardForPlayer(ShadowEraCard card)
{
    if (!isSimulating && Gameplay.Instance != null)
    {
        Gameplay.Instance.UpdateHand(forceUpdate: true);
        Gameplay.Instance.ShowCard(card);
        Gameplay.Instance.BlockInput(2f);
        if (card.gameObject != null)
        {
            CoroutineManager.Start(_ShowCardForPlayer(card));
        }
    }
}
 
public static void AddHand(ShadowEraCard card)
{
    // Code qui gère l'ajout d'une carte à la main du joueur
}
 
public static void OnSeek(ShadowEraCard card)
{
    // Gère les effets ou actions supplémentaires après l'ajout de la carte à la main
}
 
public void ShuffleOurDeck()
{
    GameModel.ShuffleDeck();
}


Alan said: "Card effects take precedence over the game rules."

  • This concept Alan said in english is the C# function AttachCard(ShadowEraCard card, bool doCallbacks = true):
    1. AttachCard(): When a card is played or attached, the game makes it "linked" to a player, hero, or ally.
    2. During this pocress, if doCallbacks = true, additional logic, such as the card’s effects, is executed.
    3. Callbacks = Card effects: The callbacks trigger specific card effects, such as Rapid Fire allowing a hero to attack twice, or Net Trap disabling an enemy ally for several turns. These effects override general game rules.
    4. Effects > General rules: Once the callbacks are executed, the card effects modify or bypass the standard game rules. For example, the rule "one attack per turn" can be changed by the effect of Rapid Fire.
    5. Thus, AttachCard() and its callbacks manage these exceptions to the game’s general rules, allowing card-specific effects to take precedence when triggered.
  • Relation to Traps and Why They Are Not Revealed
    1. The global mechanism for Traps, that they must remain face-down, is integrated into the steps of the Seek process. This mechanism takes priority over other rules, such as revealing a card that has been Seeked.
    2. When a Trap is Seeked, the face-down rule (PlayFaceDown()) inherent to Traps is triggered before any reveal function (ShowCardForPlayer()) can be called. This ensures that the Trap stays hidden, overriding the normal rule that states Seeked cards must be revealed.
    3. This behavior highlights how card effects take precedence over standard game rules. The face-down condition bypasses the normal ShowCardForPlayer() function, ensuring that Traps remain hidden in compliance with their unique mechanics.
    4. Therefore, while the Seek process normally requires cards to be revealed, the Trap mechanic ensures that this reveal is skipped. The handling of Traps shows how AttachCard() triggers card-specific logic (via callbacks) that overrides the default rules, allowing Traps to stay face-down as intended.
  • Intentional or not?
    Yes we may say that the behavior of Traps not revealed after Seek function is intentionally coded by the developers, and here is why:
    1. Traps have specific mechanics that are fundamental to their function: they are played facedown and only revealed when triggered. There is no exception; if a Trap is revealed faceup in the graveyard it is because cards are placed faceup in the graveyard porecess; if a trap is returned to hand, nothing says in the returned to hand process that it should be revealed.
    2. The fact that Traps aren’t revealed during a Seek mechanism follows the logic of the game. The code appears to be structured to ensure this rule is confirmed by preventing the ShowCardForPlayer() function from being triggered for Traps.
    3. Functions like PlayFaceDown() and specific conditions in the code show that the developers have built these special rules for Traps, and they take effect before the standard rules apply.
    4. Now, the following example code would essentially stop PlayFaceDown() from bypassing the reveal process for Seeked cards.
    5. So, if the deloppers of the game wanted to modify the PlayFaceDown() behavior as explicitly stated in the rulebook, they would likely handle the situation easily. It would only require a global phase test.
void PlayFaceDown(ShadowEraCard card, bool isSeeked)

{

   if (isSeeked)
   {
       // Allow ShowCardForPlayer() to be invoked for Seeked cards
       ShowCardForPlayer(card);
   }
   else
   {
       // Keep the card face-down as usual (normal Trap behavior)
       KeepCardFaceDown(card);
   }

}