-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTokenHandler.cs
307 lines (190 loc) · 9.59 KB
/
TokenHandler.cs
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
namespace FightMasters
{
internal abstract class TokenHandler
{
/*This class handles the addition, activation and deactivation of tokens on players*/
//Add tokens
public static List<IToken> AddTokens(Dictionary<string, List<IToken>> tokens, Player player)
{
List<IToken> TokensAdded = new(); //List of tokens actually added to player from the incoming dictionary
foreach (KeyValuePair<string, List<IToken>> TokenElement in tokens)
{
if (player.TokensActive.Count < 4) //A player can only have a max of 4 types of tokens active on them
{
string key = TokenElement.Key;
//A token of a particular type has a limit on how many times it can be applied on to a player
int capacity = 0;
switch (key)
{
case "<B>":
capacity = BurnToken.Capacity; break;
case "<S>":
capacity = ShockToken.Capacity; break;
case "<C>":
capacity = ChillToken.Capacity; break;
case "<P>":
capacity = PoisonToken.Capacity; break;
case "</>":
capacity = DodgeToken.Capacity; break;
case "<+>":
capacity = BlockToken.Capacity; break;
}
if (player.TokensActive.ContainsKey(key))
{
int AmountToAdd = player.TokensActive[key].Count - capacity;
//Difference between {the amount of tokens of that same type already affecting character} and
//{max number of tokens of that type allowed on a character (i.e.capacity)} = amount of tokens
//from the incoming list of tokens that can actually be added to the character
if (AmountToAdd > 0)
{
for (int i = 0; i < AmountToAdd; i++)
{
player.TokensActive[key].Add(TokenElement.Value[i]);
TokensAdded.Add(TokenElement.Value[i]);
}
}
}
else
{
//If player does not already have tokens of a ceratin type active on them, add {key
//, an empty list of ITokens with a capactiy of the max. num of such tokens that
//can be placed on a player + 1} to the player's list of active tokens.
//This is done so that the "grow" method of List is never called, thus preventing
//slowdowns
player.TokensActive.Add(key, new List<IToken>(capacity + 1));
foreach (IToken CurrentToken in TokenElement.Value)
{
//Then add all incoming tokens of the same type to the list
player.TokensActive[key].Add(CurrentToken);
}
TokensAdded.AddRange(TokenElement.Value);
}
}
else { break; } //If the player already has 4 types of tokens on them, do nothing
}
return TokensAdded;
}
public static void ActivateBurnTokens(Player player)
{
//Check for burn tokens
if (player.TokensActive.ContainsKey("<B>"))
{
foreach(BurnToken BToken in player.TokensActive["<B>"].Cast<BurnToken>())
{
//For each burn token, player takes 2 damage. This damage ignores resistances.
player.TakeDamage(BToken.Damage);
}
//Remove all burn tokens by removing the burn key itself
player.TokensActive.Remove("<B>");
}
}
public static void ActivateShockTokens(Player player)
{
//player method is called after a card is played
//Check for shock tokens
if (player.TokensActive.ContainsKey("<S>"))
{
foreach (ShockToken SToken in player.TokensActive["<S>"].Cast<ShockToken>())
{
if (SToken.On)
{
//For each switched on shock token, player loses 20 lightning resistance.
player.Resistances["Lightning"] -= 20;
//Switch off the token after activating it
SToken.On = false;
}
}
}
}
public static void DeactivateShockTokens(Player player)
{
/*Shock token removal is treated differently from other tokens. Only one "off" shock token is removed
every turn from a player.*/
if (player.TokensActive.ContainsKey("<S>"))
{
//LINQ gymnastics
player.TokensActive["<S>"].Remove(player.TokensActive["<S>"]
.OfType<ShockToken>()
.First(SToken => !SToken.On)); //Removing first "off" shock token encountered
//Revert player resistance after token removal
player.Resistances["Lightning"] += 20;
//If there are no more Shock tokens left, remove the Shock key
if (player.TokensActive["<S>"].Count == 0) { player.TokensActive.Remove("<S>"); }
}
}
public static void ActivateChillTokens(Player player)
{
//Check for chill tokens
if (player.TokensActive.ContainsKey("<C>"))
{
for (int i = 0; i < player.TokensActive["<C>"].Count; i++)
{
//For each chill token, player loses 1 stamina.
player.CurrentStamina--;
}
//Removing the chill key to remove all activated chill tokens
player.TokensActive.Remove("<C>");
}
}
public static Damage ActivatePosionTokens(Player player, Damage damage)
{
//Check for poison tokens
if (player.TokensActive.ContainsKey("<P>"))
{
for (int i = 0; i < player.TokensActive["<P>"].Count; i++)
{
//For each poison token, reduce each instance of outgoing damage by 10%
damage.DamageValue -= damage.DamageValue / 10;
//For each poison token, make caster take 1 poison damage; this damage ignores resistances.
//But because this damage is not being resisted at all, the actual type of damage being
//taken is irrelevant, so I've just used the default constructor for damage here.
player.TakeDamage(new Damage());
}
/*Poison tokens are triggered on every instance of damage dealt by a player. Every time they are
triggered, one is removed. player is because a player will generally deal multiple instances of damage
per turn*/
//Remove most recent poison token
player.TokensActive["<P>"].RemoveAt(player.TokensActive["<P>"].Count - 1);
//If there are no more poison tokens, remove the poison key
if (player.TokensActive["<P>"].Count == 0) { player.TokensActive.Remove("<P>"); }
}
return damage;
}
public static bool ActivateDodgeTokens(Player player)
{
//A dodge check happens once per instance of incoming damage and NOT once per token.
if (player.TokensActive.ContainsKey("</>"))
{
//If TokensActive contains a key, that means that the length of the list that is the value of that key
//is > 0. Therefore, the player has a dodge token.
//Check if player dodges incoming damage
if (new Random().Next(0, 2) == 1)
{
player.DodgeCounter += 1;
//Remove most recent dodge token
player.TokensActive["</>"].RemoveAt(player.TokensActive["</>"].Count - 1);
//If no more dodge tokens, remove the key
if (player.TokensActive["</>"].Count == 0) { player.TokensActive.Remove("</>"); }
return true;
}
}
return false;
}
public static (Damage, bool) ActivateBlockTokens(Player player, Damage damage)
{
//If TokensActive contains a key, that means that the length of the list that is the value of that key
//is > 0. Therefore, the player has a Block token.
bool blocked = false;
if (player.TokensActive.ContainsKey("<+>"))
{
damage.DamageValue /= 2;
blocked = true;
//Remove most recent Block token
player.TokensActive["<+>"].RemoveAt(player.TokensActive["<+>"].Count - 1);
//If there are no more Block tokens, remove the Block key
if (player.TokensActive["<+>"].Count == 0) { player.TokensActive.Remove("<+>"); }
}
return (damage, blocked);
}
}
}