-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheffect.js
369 lines (341 loc) · 16.5 KB
/
effect.js
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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
class Effect {
constructor(type, intensity, affection, trigger) {
this.type = type; //The type of effect. List shown at the bottom of this code.
this.intensity = intensity; //The magnitude of the effect. ONE attack vs THREE attack vs NEGATIVE ONE attack (heals instead).
this.affection = affection; //Affection modifier. Determines if it can affect this player, the next player, all players, etc. List is shown at the bottom of this code.
this.trigger = trigger; //Determines what requirements are necessary for the effect to happen. List shown at the bottom of this code.
}
/*get type() { return this.type; }
get intensity() { return this.intensity; }
get affection() { return this.affection; }
get trigger() { return this.trigger; }*/
//Function returning an array of players to affect
whoToAffect(numPlayers, currentPlayer) {
let players = [];
if(this.affection > -11 && this.affection < 11) {
players[0] = (this.affection + currentPlayer ) % numPlayers;
}
else if(this.affection == 20) {
for(let i=0; i<numPlayers; i++) {
players[i] = i;
}
}
else if(this.affection > 10 && this.affection < 20) {
//Code that lets the user select players goes here
}
return players;
}
apply(trig = 0, villainPos = 0) {
let effectString = "";
let KOstring = "";
if(this.trigger == trig) {
// First, round non-integer intensity values
let intensity = Math.trunc(this.intensity); // Rounds towards zero
let intensityDecimal = Math.abs(this.intensity - intensity);
if(this.intensity >= 0 && intensityDecimal != 0) {
let rand = Math.random();
if(rand < intensityDecimal)
intensity++;
}
else // Intensity is a negative value
if(Math.random() < intensityDecimal)
intensity--;
// Adds a +/- prefix to the effect string
if(this.intensity >= 0) {
effectString += "+";
}
else if(this.intensity < 0 && this.type == 6) {
// Checks to see if you are discarding cards instead of drawing cards.
intensity *= -1;
this.type = 60;
}
effectString += intensity;
switch(this.type) {
case 1: //elixir
p1._elixir += intensity;
p1._totalElixir += intensity;
p1._score += 10*intensity;
document.getElementById("p1score").innerHTML = p1._score;
document.getElementById("p1elixir").innerHTML = p1._elixir;
effectString += " elixir!";
changeShopCardColors();
break;
case 2: //money
p1._money += intensity;
p1._totalMoney += intensity;
p1._score += 10*intensity;
document.getElementById("p1score").innerHTML = p1._score;
document.getElementById("p1money").innerHTML = p1._money;
effectString += " money!";
changeShopCardColors();
break;
case 3: //attack
p1._attack += intensity;
p1._totalAttack += intensity;
p1._score += 10*intensity;
document.getElementById("p1score").innerHTML = p1._score;
document.getElementById("p1attack").innerHTML = p1._attack;
effectString += " attack!";
break;
case 4: //health
p1._health += intensity;
effectString += " health!";
if(p1._health > p1._maxHealth) {
p1._score += 20*(p1._health - p1._maxHealth);
document.getElementById("p1score").innerHTML = p1._score;
p1._health = p1._maxHealth;
}
else if(p1._health <= 0) {
p1._health = 0;
if(!p1._KOed)
KOstring = p1.stun();
}
else if(p1._KOed)
p1._health = 0;
setPlayerHealthLevel(p1._health, p1._maxHealth);
break;
case 6: //cards
// Add nerf to too many cards drawn to prevent infinite turns
p1._unnerfedCardsToDraw += intensity;
let cardsThisTurn = p1._cardsDrawnThisTurn + p1._unnerfedCardsToDraw;
let a = (0.5+0.5*(1-Math.pow(0.95,pr.csx))); // Softcap power
let b = 10 + pr.csr; // Softcap threshold
let c = 0.2*pr.csa; // Softcap abruptness
let d = Math.pow((cardsThisTurn - c*b*(1-Math.pow(a, 1/(1-a)))), a) * Math.pow(b, 1-a) - c*b*(Math.pow(a, 1/(1-a))-1);
let softcapCTT = d - (Math.pow((b - c*b*(1-Math.pow(a, 1/(1-a)))), a) * Math.pow(b, 1-a) - c*b*(Math.pow(a, 1/(1-a))-1) - Math.pow(b,a)*Math.pow(b, 1-a));
let nerfedCTT = cardsThisTurn > b ? softcapCTT : cardsThisTurn;
console.log("Original effect: " + intensity + ", Cards drawn this turn: " + p1._cardsDrawnThisTurn + ", Unnerfed CTD: " + p1._unnerfedCardsToDraw + ", Total cards this turn: " + cardsThisTurn + ", Nerfed CTD: " + nerfedCTT);
console.log("x-value: " + cardsThisTurn + ", Purple curve: " + d + ", Black curve: " + softcapCTT);
if(nerfedCTT == cardsThisTurn)
document.getElementById("cardSoftcap").innerHTML = "";
else
document.getElementById("cardSoftcap").innerHTML = "(softcapped)";
p1._cardsToDraw = (nerfedCTT - p1._cardsDrawnThisTurn);
document.getElementById("playerAvailableCards").innerHTML = Math.floor(p1._cardsToDraw);
// Fix the bug where getting this effect at the end of turn nullifies the effect
if(Math.floor(p1._cardsToDraw) > 0 && p1._turnState == 0) {
p1._turnState = 1;
}
effectString += " cards!";
break;
case 11: // +/- player defense stage
p1._defenseStage += intensity;
effectString += " stages to your defense!";
break;
case 13: // +/- player attack stage
p1._attackStage += intensity;
effectString += " stages to your attack!";
break;
case 14: // heal this villain
effectString += " health to the " + villainList[villainPos].title + "!";
p1.attackVillain(villainPos, -1*intensity, 1);
break;
case 15: // heal all villains
effectString += " health to all villains!";
for(let i=1; i<villainList.length; i++) {
p1.attackVillain(i, -1*intensity, 1);
}
break;
case 16: // +1 attack priority to the villain
villainList[villainPos].attackPriority += intensity;
effectString += " attack priority to the " + villainList[villainPos].title + "!";
break;
case 18: // health per hitpoint of villain
let numHits = villainList[villainPos].currentHealth;
effectString = effectString.substring(0, effectString.length - String(intensity).length);
effectString += ((this.intensity).toFixed(2) + "x" + Math.sqrt(numHits).toFixed(2) + " health!");
p1._health += stochasticRound(this.intensity * Math.sqrt(numHits));
if(p1._health > p1._maxHealth) {
p1._score += 20*(p1._health - p1._maxHealth);
document.getElementById("p1score").innerHTML = p1._score;
p1._health = p1._maxHealth;
}
else if(p1._health <= 0) {
p1._health = 0;
if(!p1._KOed)
KOstring = p1.stun();
}
else if(p1._KOed)
p1._health = 0;
setPlayerHealthLevel(p1._health, p1._maxHealth);
break;
case 60: //random discarding of a card
effectString += " random cards are discarded from your hand...";
p1._effectiveCardsDrawnThisTurn -= intensity;
for(let i=0; i<intensity; i++) {
// Checks for an empty hand first
if(isArrayNull(p1._deck.hand)) break;
// Get all cards in the hand
const handHTML = document.getElementById("mainCardHand");
const cardsHTML = handHTML.getElementsByClassName("card");
// Get a random card
const cardToBeDiscarded = cardsHTML[Math.floor(Math.random()*cardsHTML.length)];
// Apply discarded and forcibly discarded effects.
p1.applyEffects(cardToBeDiscarded.getAttribute("cid"), [1,11]);
// Discard that card
p1._deck.discardCard(Number(cardToBeDiscarded.id.substring(4)));
}
// Checks to see if the player has no cards in hand to start a new turn
if(p1._cardsToDraw < 1 && isArrayNull(p1._deck.hand)) {
p1.endTurn();
}
break;
}
effectString += " " + KOstring + " ";
}
return effectString;
}
}
// Merely scouts an effect option to return a string
function scoutEffects(FX, triggers) {
let str = "";
for(let i=0; i<FX.length; i++) {
for(let j=0; j<triggers.length; j++) {
if(FX[i].trigger == triggers[j]) {
if(str.length > 0) {
str += ", ";
}
if(FX[i].intensity >= 0) {
str += "+";
}
str += FX[i].intensity;
str += " ";
switch(FX[i].type) {
case 1:
str += "elixir";
break;
case 2:
str += "money";
break;
case 3:
str += "attack";
break;
case 4:
str += "health";
break;
case 6:
str += "cards";
break;
case 60:
str += "randomly discarded cards";
break;
}
}
}
}
return str;
}
/*
Types:
1: Elixir
2: Money
3: Attack
4: Health
5: Location
6: Cards to draw
11: +/- player defense stage
12: +/- player special defense stage
13: +/- player attack stage
14: Heal this villain
15: Heal all villains
16: Forces all attack on this villain
17: Negates all attack on this villain (can still attack other villains)
18: Health per sqrt(hitpoint) of villain
60: Randomly discarded cards from hand
61: Cards discarded by your choice
Positive values are discarded randomly, negative values are discarded with your choice
62: Highest value cards discarded from hand
63: Lowest value cards discarded from hand
64: Card with a value of 0 discarded from hand
65: Card with a value of 1-5 discarded from hand
69: This card discarded
71-79: Same as 61-69 except with banish instead of discard
OLD:
62: Highest rank cards randomly discarded from hand
63: Lowest rank cards randomly discarded from hand
64: Highest value cards randomly discarded from hand
65: Lowest value cards randomly discarded from hand
66: Highest rank cards discarded from hand (your choice)
67: Lowest rank cards discarded from hand (your choice)
68: Highest value cards discarded from hand (your choice)
69: Lowest value cards discarded from hand (your choice)
70: Banish a random card from hand
71-79: Same as 61-69 except with banish instead of discard
80-89: Same as 70-79 except it's banished from discard pile
90-99: Same as 70-79 except it's banished from whole deck
Affection modifiers:
0: This player.
(-10, 10): The player x after this player.
(11, 19): Any (x-10) players.
20: All players.
21: This player and their neighbors.
-101: Player with lowest health
101: Player with highest health
NaN: Effect doesn't apply to a player (i.e. location effects)
Triggers:
Negative numbers will allow no stacking. [Stacking is when an Effect happens twice when KO'ing two villians, for example.] Positive numbers allow stacking.
0: Always happens
1: When discarding this card
2: When discarding any card
3: When KO'ing a villian this turn
4: When you are KO'd
5: When any player is KO'd
6: When buying a card with elixir
7: When buying a card with money
8: When buying any card
9: When something is added to the location
10: When something is removed from the location
11: When forcibly discarding this card (closes the "discard loophole")
12: When forcibly discaring any card
13: When using this card to KO a villain
14: Innate - Happens before villains attack.
21: When card of normal type is played
*/
/* POSSIBLY DEPRECATED
toString(numPlayers) {
var s = "";
//Trigger stuff
switch (this.trigger) {
case 1:
s += "If discarded, ";
break;
case -2:
s += "If any card is discarded, ";
break;
case 2:
s += "When discarding any card, ";
break;
case -3:
s += "If a villian is KO'd, ";
break;
case 3:
s += "When any villian is KO'd, ";
break;
case -4:
s += "If you are KO'd, "
}
//Affection stuff
if(this.affection == 0) s += "This player ";
else if(this.affection > -11 && this.affection < 0) s += "The player " + this.affection * -1 + "before this player ";
else if(this.affection > 0 && this.affection < 11) s += "The player " + this.affection + "after this player ";
else if(this.affection == 11 && numPlayers > 1) s += "Any one player ";
else if(this.affection > 10 && this.affection < 20 && this.affection - 10 < numPlayers) s += "Any " + (this.affection-10) + " players ";
else if(affection == NaN)
//Gains/Loses
if(this.type < 5) {
if(this.intensity < 0) s += "loses ";
else s += "gains ";
//Goes by type
if(this.type == 1) s += "elixir.";
if(this.type == 2) s += "money.";
if(this.type == 3) s += "attack.";
if(this.type == 4) s += "health.";
}
if(this.type == 5) {
if(this.intensity < 0) s += this.intensity * -1 + "points are removed from the location.";
else s += this.intensity + "points are added to the location.";
}
if(this.type == 6) s += "draws " + this.intensity + " cards.";
if(this.type == 60) s += "must discard " + this.intensity + " random cards.";
if(this.type == 61) s += "must discard " + this.intensity + " cards of their choice.";
}*/