-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathDiscardSpell.java
More file actions
110 lines (100 loc) · 4.07 KB
/
DiscardSpell.java
File metadata and controls
110 lines (100 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package net.demilich.metastone.game.spells;
import net.demilich.metastone.game.GameContext;
import net.demilich.metastone.game.Player;
import net.demilich.metastone.game.cards.Attribute;
import net.demilich.metastone.game.cards.Card;
import net.demilich.metastone.game.cards.CardList;
import net.demilich.metastone.game.entities.Entity;
import net.demilich.metastone.game.events.DiscardEvent;
import net.demilich.metastone.game.events.RoastEvent;
import net.demilich.metastone.game.spells.desc.SpellArg;
import net.demilich.metastone.game.spells.desc.SpellDesc;
import net.demilich.metastone.game.spells.desc.filter.AndFilter;
import net.demilich.metastone.game.spells.desc.filter.EntityFilter;
import net.demilich.metastone.game.spells.desc.source.CardSource;
import net.demilich.metastone.game.spells.desc.source.DeckSource;
import net.demilich.metastone.game.spells.desc.source.HandSource;
import net.demilich.metastone.game.targeting.EntityReference;
import java.util.Map;
/**
* Discards cards from the {@link com.hiddenswitch.spellsource.rpc.Spellsource.ZonesMessage.Zones#HAND} or from a {@link CardSource} like
* {@link DeckSource} which does not generate new cards (does not implement {@link
* net.demilich.metastone.game.spells.desc.source.HasCardCreationSideEffects}), like {@link DeckSource}.
* <p>
* Discarding from the hand generates a {@link DiscardEvent}, while discarding from the deck generates a {@link
* RoastEvent}. Use {@link RoastSpell} to remove cards from the deck when using the <b>Roast</b> keyword.
* <p>
* To discard all cards, use a {@link SpellArg#VALUE} of {@code -1}.
* <p>
* Cards to discard are always chosen at random.
* <p>
* {@link SpellArg#CARD_FILTER} can be specified to filter which cards should be discarded.
* <p>
* For example, to implement "Battlecry: Discard a Banana to deal 3 damage to an enemy minion:"
* <pre>
* "battlecry": {
* "condition": {
* "class": "HoldsCardCondition",
* "cardFilter": {
* "class": "SpecificCardFilter",
* "card": "spell_bananas"
* }
* },
* "targetSelection": "ENEMY_MINIONS",
* "spell": {
* "class": "MetaSpell",
* "spells": [
* {
* "class": "DiscardSpell",
* "cardFilter": {
* "class": "SpecificCardFilter",
* "card": "spell_bananas"
* }
* },
* {
* "class": "DamageSpell",
* "value": 3
* }
* ]
* }
* }
* </pre>
*/
public class DiscardSpell extends AbstractRemoveCardSpell {
public static final int ALL_CARDS = -1;
public static SpellDesc create() {
return create(1);
}
public static SpellDesc create(int numberOfCards) {
Map<SpellArg, Object> arguments = new SpellDesc(DiscardSpell.class);
arguments.put(SpellArg.VALUE, numberOfCards);
arguments.put(SpellArg.TARGET, EntityReference.NONE);
return new SpellDesc(arguments);
}
@Override
protected void onCast(GameContext context, Player player, SpellDesc desc, Entity source, Entity target) {
CardSource cardSource = (CardSource) desc.getOrDefault(SpellArg.CARD_SOURCE, HandSource.create());
EntityFilter cardFilter = desc.getCardFilter();
if (cardFilter == null) {
cardFilter = AndFilter.create();
}
int numberOfCards = desc.getValue(SpellArg.VALUE, context, player, target, source, 1);
if (target instanceof Card && player.getHand().contains(target)) {
context.getLogic().discardCard(player, (Card) target);
} else {
CardList discardableCards = cardSource.getCards(context, source, player).filtered(cardFilter.matcher(context, player, source));
int cardCount = numberOfCards == ALL_CARDS ? discardableCards.getCount() : numberOfCards;
for (int i = 0; i < cardCount; i++) {
Card randomCard = context.getLogic().getRandom(discardableCards);
if (randomCard == null) {
return;
}
context.getLogic().discardCard(player, randomCard);
if (randomCard.hasAttribute(Attribute.DISCARDED)) {
SpellUtils.castChildSpell(context, player, desc.getSpell(), source, target, randomCard);
}
discardableCards.remove(randomCard);
}
}
}
}