Class DiscoverSpell
- All Implemented Interfaces:
Serializable
,HasDesc<SpellDesc>
- Direct Known Subclasses:
DiscoverCardSpell
,DiscoverDrawSpell
,DiscoverFilteredCardSpell
,DiscoverRandomCardSpell
,ExoticGoodsSpell
Discover actions prompt the user to select from count=
SpellArg.HOW_MANY
cards, with a default of 3.
If an SpellArg.ATTRIBUTE
is specified, it is added to the cards in the Spellsource.ZonesMessage.Zones.DISCOVER
, and removed
when they leave. This is used with the Attribute.UNCENSORED
attribute to indicate that these cards should be
visible to the opponent.
The cards to prompt the user with are gathered from the SpellArg.CARDS
attribute and the specified CardSource
and CardFilter
in SpellArg.CARD_SOURCE
and SpellArg.CARD_FILTER
. When the number
of cards to discover from is greater than count
, cards are chosen at random from the possible options without
replacement (i.e., duplicates will not appear).
If SpellArg.CARD_FILTER
is specified without a SpellArg.CARD_SOURCE
, it is assumed that the
weighted (i.e., class-specific) catalogue source CatalogueSource
should be used. However, if the
casting player is the HeroClass.ANY
or HeroClass.TEST
class, an UnweightedCatalogueSource
will be used instead.
When SpellArg.CANNOT_RECEIVE_OWNED
is specified, the possible options exclude cards that are already in the
player's Spellsource.ZonesMessage.Zones.HAND
or Spellsource.ZonesMessage.Zones.HERO_POWER
.
Some card sources generate new cards; these card sources implement the HasCardCreationSideEffects
interface.
Other card sources, like DeckSource
, will reference the actual cards in the player's deck. Discovers
always present copies of cards to users, regardless of their origin. To perform the spell on the
actual card, set SpellArg.EXCLUSIVE
to true
. Trying to use an "exclusive" discover on cards
that are always generated will throw an exception.
When the user makes a discover choice, the spell arguments are interpreted to determine what spell is "cast" with the chosen and unchosen cards:
- When
SpellArg.SPELL
orSpellArg.SPELL1
is specified andSpellArg.EXCLUSIVE
isfalse
(the default): The spell is cast with the chosen card placed into the spell'sSpellArg.CARD
argument. - When
SpellArg.SPELL
orSpellArg.SPELL1
is specified andSpellArg.EXCLUSIVE
istrue
: The spell is cast with theCard
entity as itstarget
. - When
SpellArg.SPELL2
is specified: This spell is cast on the cards that were not chosen, using the same rules ofSpellArg.EXCLUSIVE
as above.
If the CardSource
implements the HasWeights
interface, the discover will use the weights for random
selection. Since the CatalogueSource
is the default card source and it supports weighting, a discover spell
with no card source specified will make a weighted selection from collectible cards in this DeckFormat
. The weighting defaults to 4x likelihood for class cards that match the
player's hero class, 1x likelihood for neutral cards, and no likelihood for other class cards.
If there are no choices generated by the card source and filter, or if all the choices are removed due to SpellArg.CANNOT_RECEIVE_OWNED
, the user is not prompted for any choices and no spells are cast.
To discover a minion and put it in the player's hand:
{ "class": "DiscoverSpell", "cardFilter": { "class": "CardFilter", "cardType": "MINION" }, "spell": { "class": "ReceiveCardSpell" } }To discover a random minion from any class without weighting:
{ "class": "DiscoverSpell", "cardFilter": { "class": "CardFilter", "cardType": "MINION" }, "cardSource": { "class": "UnweightedCatalogueSource" }, "spell": { "class": "ReceiveCardSpell" } }To discover a random Totem, including token totems, use an
UncollectibleCatalogueSource
to include tokens in the selection:
{ "class": "DiscoverSpell", "cardFilter": { "class": "CardFilter", "cardType": "MINION", "race": "TOTEM" }, "cardSource": { "class": "UncollectibleCatalogueSource" }, "spell": { "class": "ReceiveCardSpell" } }To choose amongst 3 of a specific list of cards, specify the
SpellArg.CARDS
argument. Only 3 of these 4 cards
will be shown to the user, choosing which 3 randomly but without duplicates.
{ "class": "DiscoverSpell", "cards": [ "minion_bloodfen_raptor", "minion_argent_squire", "minion_snowflipper_penguin", "minion_ironbeak_owl" ], "spell": { "class": "ReceiveCardSpell" } }When
SpellArg.HOW_MANY
is specified and it is greater or equal to the number of SpellArg.CARDS
elements there are, the user will be prompted for a discover choice in the exact order the cards appear:
{ "class": "DiscoverSpell", "spell": { "class": "ReceiveCardSpell" }, "cards": [ "spell_invocation_of_air", "spell_invocation_of_earth", "spell_invocation_of_fire", "spell_invocation_of_water" ], "howMany": 4 }To cast a discovered spell instead of receiving it, change the
SpellArg.SPELL
to a CastCardsSpell
.
When trying to do different effects with the chosen cards, it's important to check if the Spell
supports the
SpellArg.CARD
argument (common ones like CastCardsSpell
, SummonSpell
and ReceiveCardSpell
do:
{ "class": "DiscoverSpell", "spell": { "class": "CastCardsSpell" }, "cards": [ "spell_invocation_of_air", "spell_invocation_of_earth", "spell_invocation_of_fire", "spell_invocation_of_water" ], "howMany": 4 }You can also cast spells on cards that are not chosen. This effect implements the text: "Discover a Fireball and Pyroblast. Draw it. Put the card you did not choose into the opponent's hand."
{ "class": "DiscoverSpell", "spell1": { "class": "ReceiveCardSpell" }, "spell2": { "class": "ReceiveCardSpell" }, "cards": [ "spell_pyroblast", "spell_fireball" ], "howMany": 2 }If you want to discover a copy of a card in the opponent's deck, use a
DeckSource
.
{ "class": "DiscoverSpell", "spell": { "class": "ReceiveCardSpell" }, "cardSource": { "class": "DeckSource", "targetPlayer": "OPPONENT" } }If instead you want to steal a card from the opponent's deck, use a
StealCardSpell
and set SpellArg.EXCLUSIVE
to true
. The SpellArg.EXCLUSIVE
argument will cast StealCardSpell
with
the chosen card's Entity.getId()
as the target
. You must use SpellArg.EXCLUSIVE
whenever you
use spells that only accept target
and not SpellArg.CARD
.
{ "class": "DiscoverSpell", "spell": { "class": "StealCardSpell" }, "cardSource": { "class": "DeckSource", "targetPlayer": "OPPONENT" }, "exclusive": true }Discovering spells from weighted sources like
CatalogueSource
but with different classes is a little tricky.
Currently, only the CardSourceArg.TARGET_PLAYER
argument can
be used to discover against the opponent's class. For example, this spell will discover a rare card in the
opponent's class:
{ "class": "DiscoverSpell", "spell": { "class": "ReceiveCardSpell", "targetPlayer": "SELF" }, "cardFilter": { "class": "AndFilter", "filters": [ { "class": "CardFilter", "heroClass": "OPPONENT" }, { "class": "CardFilter", "rarity": "RARE" } ] }, "cardSource": { "class": "CatalogueSource", "targetPlayer": "OPPONENT" } }
-
Constructor Summary
Constructors -
Method Summary
Methods inherited from class net.demilich.metastone.game.spells.Spell
cast, castForPlayer, checkArguments, getDesc, isNativeStateful, setDesc, toString
-
Constructor Details
-
DiscoverSpell
public DiscoverSpell()
-
-
Method Details
-
create
-
create
-
onCast
protected void onCast(GameContext context, Player player, SpellDesc desc, Entity source, Entity target) Description copied from class:Spell
Implementations ofonCast
are the meat-and-bones of a spell's effects. This should actually call a variety of methods inGameLogic
, generate cards usingSpellUtils.getCards(GameContext, Player, Entity, Entity, SpellDesc)
, interpretSpellArg
keys in thedesc
, etc.Observe that subclasses of
Spell
mostly just need to implement this function. Also, observe that instances ofSpell
are stateless: all the state is provided as arguments to this function.- Specified by:
onCast
in classSpell
- Parameters:
context
- The game contextplayer
- The casting playerdesc
- The collection ofSpellArg
keys and values that are interpreted by the implementation of this function to actually cause effects in a gamesource
- The entity from which this effect is happening (typically a card or a minion if it's a battlecry).target
- The particular target of this invocation of the spell. When a spell hits multiple targets, like an AoE damage effect, this method is called once for each target in the list of targets.- See Also:
-