-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathCardCostModifierSpell.java
More file actions
119 lines (109 loc) · 5.58 KB
/
CardCostModifierSpell.java
File metadata and controls
119 lines (109 loc) · 5.58 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
110
111
112
113
114
115
116
117
118
119
package net.demilich.metastone.game.spells;
import net.demilich.metastone.game.GameContext;
import net.demilich.metastone.game.Player;
import net.demilich.metastone.game.cards.costmodifier.CardCostModifier;
import net.demilich.metastone.game.entities.Entity;
import net.demilich.metastone.game.spells.desc.SpellArg;
import net.demilich.metastone.game.spells.desc.SpellDesc;
import net.demilich.metastone.game.spells.desc.manamodifier.CardCostModifierArg;
import net.demilich.metastone.game.spells.desc.manamodifier.CardCostModifierDesc;
import net.demilich.metastone.game.spells.desc.valueprovider.AlgebraicOperation;
import net.demilich.metastone.game.targeting.EntityReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* Creates a {@link CardCostModifier} specified by {@link SpellArg#CARD_COST_MODIFIER} that is hosted by the specified
* {@link SpellArg#TARGET}.
* <p>
* The following <b>example</b> makes the cards in the player's hand cost zero for the rest of the game. When the player
* draws new cards, those cards still cost zero. The "rest of the game" part is enforced by the {@link SpellArg#TARGET}
* of {@link EntityReference#FRIENDLY_PLAYER}, the entity that hosts rest of the game triggers and effects like card
* cost modification.
* <pre>
* {
* "class": "CardCostModifierSpell",
* "target": "FRIENDLY_PLAYER",
* "cardCostModifier": {
* "class": "CardCostModifier",
* "target": "FRIENDLY_HAND",
* "operation": "SET",
* "value": 0
* }
* }
* </pre>
* However, this <b>example</b> sets the cost of all cards <b>currently</b> in the player's hand to zero. Later cards
* that are drawn do not get their cost reduced.
* <pre>
* {
* "class": "CardCostModifierSpell",
* "target": "FRIENDLY_HAND",
* "cardCostModifier": {
* "class": "CardCostModifier",
* "target": "SELF",
* "operation": "SET",
* "value": 0
* }
* }
* </pre>
* Notice that the target of the {@link CardCostModifierSpell} is the entity that hosts the effect, while the {@link
* SpellArg#CARD_COST_MODIFIER} is the actual modifier that should go into play. By using {@link
* CardCostModifierArg#TARGET} of {@link EntityReference#SELF}, the hosting entity modifies itself.
*
* @see CardCostModifier for a description of the format for a card cost modifier.
*/
public class CardCostModifierSpell extends Spell {
private static Logger LOGGER = LoggerFactory.getLogger(CardCostModifierSpell.class);
/**
* Creates this spell.
*
* @param cardCostModifierDesc A configuration for the {@link CardCostModifier}. The {@link
* CardCostModifierDesc#create()} method is used to actually create the {@link
* CardCostModifier} instance.
* @param host The {@link Entity} that should host the modifier. This should resolve to a single
* target.
* @return The spell.
*/
public static SpellDesc create(CardCostModifierDesc cardCostModifierDesc, EntityReference host) {
Map<SpellArg, Object> arguments = new SpellDesc(CardCostModifierSpell.class);
arguments.put(SpellArg.CARD_COST_MODIFIER, cardCostModifierDesc);
arguments.put(SpellArg.TARGET, host);
return new SpellDesc(arguments);
}
/**
* Creates this spell to modify the cost of the target with the given operation and value. The target is also the
* host, so the {@link CardCostModifierArg#TARGET} is set to {@link EntityReference#SELF}.
*
* @param target The {@link EntityReference} whose cost should be modified.
* @param operation The way the {@code value} should be interpreted. To increase the cost, use a positive {@code
* value} and the {@link AlgebraicOperation#ADD}; to set the value, use {@link
* AlgebraicOperation#SET}.
* @param value The value that should be used for modifying the cost.
* @return The spell.
*/
public static SpellDesc create(EntityReference target, AlgebraicOperation operation, int value) {
CardCostModifierDesc manaModifierDesc = new CardCostModifierDesc(CardCostModifier.class);
manaModifierDesc = manaModifierDesc.addArg(CardCostModifierArg.OPERATION, operation);
manaModifierDesc = manaModifierDesc.addArg(CardCostModifierArg.TARGET, EntityReference.SELF);
manaModifierDesc = manaModifierDesc.addArg(CardCostModifierArg.VALUE, value);
return create(manaModifierDesc, target);
}
@Override
protected void onCast(GameContext context, Player player, SpellDesc desc, Entity source, Entity target) {
checkArguments(LOGGER, context, source, desc, SpellArg.CARD_COST_MODIFIER);
CardCostModifierDesc manaModifierDesc = (CardCostModifierDesc) desc.get(SpellArg.CARD_COST_MODIFIER);
if (manaModifierDesc.containsKey(CardCostModifierArg.TARGET)
&& target != null
&& !target.getReference().equals(manaModifierDesc.get(CardCostModifierArg.TARGET))
&& !manaModifierDesc.get(CardCostModifierArg.TARGET).equals(EntityReference.SELF)) {
LOGGER.debug("onCast {} {}: The target of this spell, {}, and the mana cost modifier's target, {}, do not match.",
context.getGameId(), source, target, manaModifierDesc.get(CardCostModifierArg.TARGET));
}
// The target is the host of the mana cost modifier.
CardCostModifier cardCostModifier = manaModifierDesc.create();
if (source != null && source.getSourceCard() != null) {
cardCostModifier.setSourceCard(source.getSourceCard());
}
context.getLogic().addEnchantment(player, cardCostModifier, source, target == null ? player : target);
}
}