|
| 1 | +eventManager.on("GameStart", function battleLogger() { |
| 2 | + const ignoreEvents = Object.keys({ |
| 3 | + getConnectedFirst: '', |
| 4 | + refreshTimer: 'Never need to know about this one', |
| 5 | + getPlayableCards: 'On turn start, selects cards player can play', |
| 6 | + getTurn: 'Turn update', |
| 7 | + getCardDrawed: 'Add card to your hand', |
| 8 | + updateSpell: '', |
| 9 | + updateMonster: 'monster on board updated', |
| 10 | + getFakeDeath: 'Card "died" and respawns 1 second later', |
| 11 | + getMonsterTemp: "You're about to play a monster", |
| 12 | + getSpellTemp: "You're about to play a spell", |
| 13 | + getTempCancel: 'Temp card cancelled', |
| 14 | + getShowMulligan: 'Switching out hands, ignore it', |
| 15 | + getHideMulligan: 'Hide the mulligan, gets called twice', |
| 16 | + getUpdateHand: 'Updates full hand', |
| 17 | + getError: 'Takes you to "home" on errors, can be turned into a toast', |
| 18 | + getGameError: 'Takes you to "play" on game errors, can be turned into a toast', |
| 19 | + }); |
| 20 | + let turn = 0, currentTurn = 0, players = {}, monsters = {}, lastEffect, other = {}, finished = false; |
| 21 | + const yourDust = $('<span>') |
| 22 | + const enemyDust = $('<span>'); |
| 23 | + function addDust(player) { |
| 24 | + const display = player === userId ? yourDust : enemyDust; |
| 25 | + const dust = typeof players[player].dust === 'undefined' ? players[player].dust = 0 : players[player].dust += 1; |
| 26 | + display.html(dust); |
| 27 | + } |
| 28 | + const make = { |
| 29 | + player: function makePlayer(player, title = false) { |
| 30 | + const c = $('<span>'); |
| 31 | + c.append(player.username); |
| 32 | + c.addClass(player.class); |
| 33 | + if (!title) { |
| 34 | + c.css('text-decoration', 'underline'); |
| 35 | + // show lives, show health, show gold, show hand, possibly deck size as well |
| 36 | + const data = `${player.hp} hp, ${player.gold} gold<br />${player.dust} dust`; |
| 37 | + c.hover(hover.show(data, '2px solid white')); |
| 38 | + } |
| 39 | + return c; |
| 40 | + }, |
| 41 | + card: function makeCard(card) { |
| 42 | + const c = $('<span>'); |
| 43 | + c.append(card.name); |
| 44 | + c.css('text-decoration', 'underline'); |
| 45 | + |
| 46 | + let data = `<table class="cardBoard ${card.paralyzed ? 'paralyzed' : ''}">`; |
| 47 | + data += `<tr><td class="cardName resize ${card.classe || card.class}" colspan="3">${card.name}`; |
| 48 | + if (card.shiny) { |
| 49 | + // TODO: rainbow |
| 50 | + } |
| 51 | + // TODO: skins |
| 52 | + data += `</td><td class="cardCost">${card.cost}</td></tr>`; |
| 53 | + data += `<tr><td id="cardImage" colspan="4">`; |
| 54 | + const status = fn.cardStatus(card); |
| 55 | + if (status.length) { |
| 56 | + // add status images |
| 57 | + status.forEach((s, i) => { |
| 58 | + data += `<img class="infoPowers" style="z-index:20;right:${4 + i * 20}px;" src="images/powers/${s}.png"/>`; |
| 59 | + }); |
| 60 | + } |
| 61 | + data += `<img src="images/cards/${card.image}.png"/></td></tr>`; |
| 62 | + data += `<tr><td class="cardDesc" colspan="4">${card.desc || ''}` |
| 63 | + if (card.silence) { |
| 64 | + data += '<img class="silenced" title="Silence" src="images/silence.png">'; |
| 65 | + } |
| 66 | + data += '</td></tr>'; |
| 67 | + if (!card.typeCard) { |
| 68 | + data += `<tr><td id="cardATQ">${card.attack}</td><td id="cardRarity" colspan="2"><img src="images/rarity/${card.rarity}.png" /></td><td id="cardHP" class="${card.hp!==card.maxHp ? "damaged" : ""}">${card.hp}</td></tr>`; |
| 69 | + } else { |
| 70 | + data += `<tr><td id="cardRarity" colspan="4"><img src="images/rarity/${card.rarity}.png" /></td></tr>`; |
| 71 | + } |
| 72 | + data += `</table>`; |
| 73 | + c.hover(hover.show(data)); |
| 74 | + return c; |
| 75 | + }, |
| 76 | + }; |
| 77 | + |
| 78 | + eventManager.on('GameEvent', function logEvent(data) { |
| 79 | + if (finished) { // Sometimes we get events after the battle is over |
| 80 | + fn.debug(`Extra action: ${data.action}`, 'debugging.events.extra'); |
| 81 | + return; |
| 82 | + } |
| 83 | + debug(data.action, 'debugging.events.name'); |
| 84 | + const emitted = eventManager.emit(data.action, data).ran; |
| 85 | + if (!emitted) { |
| 86 | + fn.debug(`Unknown action: ${data.action}`); |
| 87 | + } |
| 88 | + }); |
| 89 | + |
| 90 | + eventManager.on('getAllGameInfos getGameStarted getReconnection', function initBattle(data) { |
| 91 | + debug(data, 'debugging.raw.game'); |
| 92 | + let you, enemy; |
| 93 | + // Battle logging happens after the game runs |
| 94 | + if (this.event === 'getGameStarted') { |
| 95 | + you = { |
| 96 | + id: data.yourId, |
| 97 | + username: data.yourUsername, |
| 98 | + hp: 30, // This is wrong with artifacts? Maybe? |
| 99 | + gold: 2, // This is wrong with artifacts? Maybe? |
| 100 | + }; |
| 101 | + enemy = { |
| 102 | + id: data.enemyId, |
| 103 | + username: data.enemyUsername, |
| 104 | + hp: 30, // This is wrong with artifacts? Maybe? |
| 105 | + gold: 2, // This is wrong with artifacts? Maybe? |
| 106 | + }; |
| 107 | + } else { |
| 108 | + you = JSON.parse(data.you); |
| 109 | + enemy = JSON.parse(data.enemy); |
| 110 | + // Set gold |
| 111 | + const gold = JSON.parse(data.golds); |
| 112 | + you.gold = gold[you.id]; |
| 113 | + enemy.gold = gold[enemy.id]; |
| 114 | + // Set lives |
| 115 | + const lives = JSON.parse(data.lives); |
| 116 | + you.lives = lives[you.id]; |
| 117 | + enemy.lives = lives[enemy.id]; |
| 118 | + // populate monsters |
| 119 | + let count = 0; |
| 120 | + JSON.parse(data.board).forEach(function (card) { |
| 121 | + count += 1; |
| 122 | + if (card === null) return; |
| 123 | + // id, attack, hp, maxHp, originalattack, originalHp, typeCard, name, image, cost, originalCost, rarity, shiny, quantity |
| 124 | + card.desc = getDescription(card); |
| 125 | + card.owner = count <= 4 ? enemy.id : you.id; |
| 126 | + monsters[card.id] = card; |
| 127 | + }); |
| 128 | + } |
| 129 | + you.level = data.yourLevel; |
| 130 | + you.class = data.yourClass; |
| 131 | + you.rank = data.yourRank; |
| 132 | + enemy.level = data.enemyLevel; |
| 133 | + enemy.class = data.enemyClass; |
| 134 | + enemy.rank = data.enemyRank; |
| 135 | + // yourArtifacts, yourAvatar {id, image, name, rarity, ucpCost}, division, oldDivision, profileSkin {id, name, image, ucpCost} |
| 136 | + debug({you, enemy}, 'debugging.game'); |
| 137 | + turn = data.turn || 0; |
| 138 | + players[you.id] = you; |
| 139 | + players[enemy.id] = enemy; |
| 140 | + const dustImg = $('<img style="width: 20px; height: 16px;" title="Number of cards turned to dust." src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAAZElEQVQ4jb2UUQ7AIAhDqfH+V95+NDEdrMSg/UQqr5hoFugZytanWnSwq+4RZIyzDwDW+jnCLBmLSSUhD+KIH8JdsmiwJGQiBVD+KOU7vE9YukMv3vXIMPNjKBLpUd/S38Wr7wVZPk/6kF1cXAAAAABJRU5ErkJggg==">'); |
| 141 | + $('.rightPart').append(dustImg, ' '); |
| 142 | + $(`#user${opponentId} .rightPart`).append(enemyDust, ' '); |
| 143 | + $(`#user${userId} .rightPart`).append(yourDust, ' ', $(`#user${userId} .rightPart > button:last`)); |
| 144 | + addDust(you.id); |
| 145 | + addDust(enemy.id); |
| 146 | + // Test changing ID's at endTurn instead of startTurn |
| 147 | + other[you.id] = enemy.id; |
| 148 | + other[enemy.id] = you.id; |
| 149 | + // Initialize the log |
| 150 | + log.init(); |
| 151 | + $("div#history div.handle").html('').append(`[${data.gameType}] `, make.player(you), ' vs ', make.player(enemy)); |
| 152 | + log.add(`Turn ${turn}`); |
| 153 | + if (data.userTurn) { |
| 154 | + currentTurn = data.userTurn; |
| 155 | + log.add(make.player(players[data.userTurn]), "'s turn"); |
| 156 | + } |
| 157 | + }); |
| 158 | + eventManager.on('getFight getFightPlayer', function fight(data) { |
| 159 | + const target = this.event === 'getFightPlayer' ? make.player(players[data.defendPlayer]) : make.card(monsters[data.defendMonster]); |
| 160 | + log.add(make.card(monsters[data.attackMonster]), ' attacked ', target); |
| 161 | + }); |
| 162 | + eventManager.on('getUpdatePlayerHp', function updateHP(data) { |
| 163 | + debug(data, 'debugging.raw.updateHP'); |
| 164 | + const oHp = players[data.playerId].hp; |
| 165 | + const hp = data.isDamage ? oHp - data.hp : data.hp - oHp; |
| 166 | + players[data.playerId].hp = data.hp; |
| 167 | + if (oHp !== data.hp) { // If the player isn't at 0 hp already |
| 168 | + log.add(make.player(players[data.playerId]), ` ${data.isDamage ? "lost" : "gained"} ${hp} hp`); |
| 169 | + } |
| 170 | + if (data.hp === 0 && players[data.playerId].lives > 1 && !players[data.playerId].hasOwnProperty("lostLife")) { // If they have extra lives, and they didn't lose a life already |
| 171 | + log.add(make.player(players[data.playerId]), ' lost a life'); |
| 172 | + players[data.playerId].lostLife = true; |
| 173 | + } |
| 174 | + }); |
| 175 | + eventManager.on('getDoingEffect', function doEffect(data) { |
| 176 | + debug(data, 'debugging.raw.effect'); |
| 177 | + // affecteds: [ids]; monsters affected |
| 178 | + // playerAffected1: id; player affected |
| 179 | + // playerAffected2: id; player affected |
| 180 | + // TODO: Figure out how to do this better |
| 181 | + if (lastEffect === 'm' + data.monsterId) return; |
| 182 | + lastEffect = 'm' + data.monsterId; |
| 183 | + log.add(make.card(monsters[data.monsterId]), "'s effect activated"); |
| 184 | + }); |
| 185 | + eventManager.on('getArtifactDoingEffect', function doEffect(data) { |
| 186 | + debug(data, 'debugging.raw.effectArtifact'); |
| 187 | + if (lastEffect === 'a' + data.playerId) return; |
| 188 | + lastEffect = 'a' + data.playerId; |
| 189 | + log.add(make.player(players[data.playerId]), "'s artifact activated"); |
| 190 | + }); |
| 191 | + eventManager.on('getSoulDoingEffect', function soulEffect(data) { |
| 192 | + debug(data, 'debugging.raw.effectSoul'); |
| 193 | + if (lastEffect === 's' + data.playerId) return; |
| 194 | + lastEffect = 's' + data.playerId; |
| 195 | + log.add(make.player(players[data.playerId]), "'s soul activated"); |
| 196 | + // affecteds |
| 197 | + // playerAffected1 |
| 198 | + // playerAffected2 |
| 199 | + }); |
| 200 | + eventManager.on('getTurnStart', function turnStart(data) { |
| 201 | + debug(data, 'debugging.raw.turnStart'); |
| 202 | + lastEffect = 0; |
| 203 | + if (data.numTurn !== turn) { |
| 204 | + log.add(`Turn ${data.numTurn}`); |
| 205 | + } |
| 206 | + currentTurn = data.idPlayer; // It would (kindof) help to actually update who's turn it is |
| 207 | + turn = data.numTurn; |
| 208 | + log.add(make.player(players[currentTurn]), "'s turn"); |
| 209 | + }); |
| 210 | + eventManager.on('getTurnEnd', function turnEnd(data) { |
| 211 | + debug(data, 'debugging.raw.turnEnd'); |
| 212 | + // Lets switch the turn NOW, rather than later, the purpose of this is currently unknown... It just sounded like a good idea, also delete the "lostLife" flag... |
| 213 | + if (time <= 0) { |
| 214 | + log.add(make.player(players[currentTurn]), ' timed out'); |
| 215 | + } |
| 216 | + delete players[currentTurn].lostLife; |
| 217 | + currentTurn = other[data.idPlayer]; |
| 218 | + delete players[currentTurn].lostLife; |
| 219 | + lastEffect = 0; |
| 220 | + }); |
| 221 | + eventManager.on('getUpdateBoard', function updateGame(data) { |
| 222 | + debug(data, 'debugging.raw.boardUpdate'); |
| 223 | + const oldMonsters = monsters; |
| 224 | + monsters = {}; |
| 225 | + // TOOD: stuff.... |
| 226 | + let count = 0; |
| 227 | + JSON.parse(data.board).forEach(function (card) { |
| 228 | + count += 1; |
| 229 | + if (card === null) return; |
| 230 | + card.desc = getDescription(card); |
| 231 | + card.owner = count <= 4 ? opponentId : userId; |
| 232 | + monsters[card.id] = card; |
| 233 | + }); |
| 234 | + }); |
| 235 | + eventManager.on('getMonsterDestroyed', function monsterKilled(data) { |
| 236 | + debug(data, 'debugging.raw.kill'); |
| 237 | + // monsterId: # |
| 238 | + log.add(make.card(monsters[data.monsterId]), ' was killed'); |
| 239 | + addDust(monsters[data.monsterId].owner); |
| 240 | + delete monsters[data.monsterId]; |
| 241 | + }); |
| 242 | + eventManager.on('getCardBoard', function playCard(data) { // Adds card to X, Y (0(enemy), 1(you)) |
| 243 | + debug(data, 'debugging.raw.boardAdd'); |
| 244 | + const card = JSON.parse(data.card); |
| 245 | + card.desc = getDescription(card); |
| 246 | + card.owner = data.idPlayer; |
| 247 | + monsters[card.id] = card; |
| 248 | + log.add(make.player(players[data.idPlayer]), ' played ', make.card(card)); |
| 249 | + }); |
| 250 | + eventManager.on('getSpellPlayed', function useSpell(data) { |
| 251 | + debug(data, 'debugging.raw.spell'); |
| 252 | + // immediately calls "getDoingEffect" and "getUpdateBoard" |
| 253 | + const card = JSON.parse(data.card); |
| 254 | + card.desc = getDescription(card); |
| 255 | + monsters[card.id] = card; |
| 256 | + log.add(make.player(players[data.idPlayer]), ' used ', make.card(card)); |
| 257 | + }); |
| 258 | + eventManager.on('getShowCard', function showCard(data) { |
| 259 | + const card = JSON.parse(data.card); |
| 260 | + card.desc = getDescription(card); |
| 261 | + log.add(make.player(players[data.idPlayer]), ' exposed ', make.card(card)); |
| 262 | + }); |
| 263 | + eventManager.on('getCardDestroyedHandFull', function destroyCard(data) { |
| 264 | + debug(data, 'debugging.raw.fullHand'); |
| 265 | + const card = JSON.parse(data.card); |
| 266 | + card.desc = getDescription(card); |
| 267 | + debug(data.card); |
| 268 | + // This event gets called for *all* discards. Have to do smarter logic here (not just currentTurn!) |
| 269 | + log.add(make.player(players[currentTurn]), ' discarded ', make.card(card)); |
| 270 | + }); |
| 271 | + eventManager.on('getPlayersStats', function updatePlayer(data) { // TODO: When does this get called? |
| 272 | + debug(data, 'debugging.raw.stats'); |
| 273 | + let key, temp = JSON.parse(data.handsSize); |
| 274 | + for (key in temp) { |
| 275 | + // TODO: hand size monitoring |
| 276 | + //players[key].hand |
| 277 | + } |
| 278 | + // TODO: deck monitoring (decksSize) |
| 279 | + temp = JSON.parse(data.golds); |
| 280 | + for (key in temp) { |
| 281 | + players[key].gold = temp[key]; |
| 282 | + } |
| 283 | + temp = JSON.parse(data.lives); |
| 284 | + for (key in temp) { |
| 285 | + players[key].lives = temp[key]; |
| 286 | + } |
| 287 | + // data.artifcats |
| 288 | + // data.turn |
| 289 | + }); |
| 290 | + eventManager.on('getVictory getDefeat', function gameEnd(data) { |
| 291 | + debug(data, 'debugging.raw.end'); |
| 292 | + finished = true; |
| 293 | + if (data.disconnected) { |
| 294 | + log.add(make.player(players[opponentId]), " left the game"); |
| 295 | + } |
| 296 | + const you = make.player(players[userId]); |
| 297 | + const enemy = make.player(players[opponentId]); |
| 298 | + if (this.event === 'getDefeat') { |
| 299 | + log.add(enemy, ' beat ', you); |
| 300 | + } else { |
| 301 | + log.add(you, ' beat ', enemy); |
| 302 | + } |
| 303 | + }); |
| 304 | + eventManager.on('getResult', function endSpectating(data) { |
| 305 | + debug(data, 'debugging.raw.end'); |
| 306 | + finished = true; |
| 307 | + if (data.cause === "Surrender") { |
| 308 | + log.add(`${data.looser} surrendered.`); |
| 309 | + } else if (data.cause === "Disconnection") { |
| 310 | + log.add(`${data.looser} disconnected.`); |
| 311 | + } |
| 312 | + if (typeof music !== 'undefined') { |
| 313 | + music.addEventListener('playing', function () { |
| 314 | + if (localStorage.getItem('gameMusicDisabled')) { |
| 315 | + music.pause(); |
| 316 | + } |
| 317 | + }); |
| 318 | + } |
| 319 | + // TODO: colorize |
| 320 | + log.add(`${data.winner} beat ${data.looser}`); |
| 321 | + const toast = { |
| 322 | + title: 'Game Finished', |
| 323 | + text: 'Return Home', |
| 324 | + buttons: { |
| 325 | + className: 'skiptranslate', |
| 326 | + text: '🏠', |
| 327 | + onclick: () => { |
| 328 | + document.location.href = "/"; |
| 329 | + }, |
| 330 | + }, |
| 331 | + }; |
| 332 | + if (!localStorage.getItem('setting.disableResultToast') && fn.toast(toast)) { |
| 333 | + BootstrapDialog.closeAll(); |
| 334 | + } |
| 335 | + }); |
| 336 | + eventManager.on(ignoreEvents.join(' '), function ignore(data) { |
| 337 | + debug(data, 'debugging.raw.ignore'); |
| 338 | + debug(data, `debugging.raw.ignore.${this.event}`); |
| 339 | + }); |
| 340 | + eventManager.on('getTurnEnd', function hideSpells() { |
| 341 | + // Fixes a bug with "mines" and any other potential cards that don't get cleared correctly. |
| 342 | + $('#board .spellPlayed').remove(); |
| 343 | + }) |
| 344 | +}); |
0 commit comments