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.SPELLorSpellArg.SPELL1is specified andSpellArg.EXCLUSIVEisfalse(the default): The spell is cast with the chosen card placed into the spell'sSpellArg.CARDargument. - When
SpellArg.SPELLorSpellArg.SPELL1is specified andSpellArg.EXCLUSIVEistrue: The spell is cast with theCardentity as itstarget. - When
SpellArg.SPELL2is specified: This spell is cast on the cards that were not chosen, using the same rules ofSpellArg.EXCLUSIVEas 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:SpellImplementations ofonCastare 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), interpretSpellArgkeys in thedesc, etc.Observe that subclasses of
Spellmostly just need to implement this function. Also, observe that instances ofSpellare stateless: all the state is provided as arguments to this function.- Specified by:
onCastin classSpell- Parameters:
context- The game contextplayer- The casting playerdesc- The collection ofSpellArgkeys 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:
-