diff --git a/abilities.js b/abilities.js index fd3592b..1e2258b 100644 --- a/abilities.js +++ b/abilities.js @@ -1198,19 +1198,86 @@ var ability_dict = { }, lady_wood_brewess: { description: "Each time when your faction ability triggers, draw two cards instead of one. Play one of them, another one shuffle back into your deck.", - placed: card => card.holder.velenCardDraw = 2 + placed: card => { + card.holder.disableLeader(); + game.gameStart.push(async () => { + card.holder.velenCardDraw = 2; + }); + } }, lady_wood_weavess: { description: "Draw a Curse card from your deck and play it immediatly.", - gameStart: () => game.spyPowerMult = 1 + activated: async card => { + let cards = card.holder.deck.cards.filter(c => c.key == "spe_curse"); + if (cards.length == 0) + return false; + let targetCard = cards[0]; + if (card.holder.controller instanceof ControllerAI) { + targetCard.autoplay(card.holder.deck); + } else { + // let player select where to play the card + card.holder.selectCardDestination(targetCard, card.holder.deck); + } + }, + weight: card => { + if (card.holder.opponent().passed) + return 0; + return 8; + } }, lady_wood_whispess: { description: "Take from your discard pile in your hand 3 or less unit cards, that died in the current round.", - gameStart: () => game.spyPowerMult = 1 + activated: async card => { + let units = card.holder.grave.cards.filter(c => c.isUnit() && c.destructionRound == game.roundCount); + if (units.length == 0) + return false; + let cardsCount = Math.min(3, units.length); + let targetCards = []; + if (card.holder.controller instanceof ControllerAI) { + targetCards = card.holder.controller.getWeights(units).sort((a, b) => (b.weight - a.weight)).slice(0, cardsCount); + } else { + await ui.queueCarousel({ cards: units }, cardsCount, (c, i) => targetCards.push(c.cards[i]), c => true, true, true, "Choose up to " + String(cardsCount)+" to bring back to your hand."); + } + targetCards.forEach(async card => { + await board.toHand(card, card.holder.grave); + }); + } }, ghost_tree: { description: "Destroy the weakest unit card on the battlefield (any player). If there are several, choose one.", - gameStart: () => game.spyPowerMult = 1 + activated: async card => { + let rows = board.row.filter(row => !row.isShielded()); + let units = rows.reduce((a, r) => a.concat(r.minUnits()), []) + .reduce((a, c) => (!a.length || a[0].power > c.power) ? [c] : a[0].power === c.power ? a.concat([c]) : a, []); + let targetCard = null; + if (units.length > 0) { + if (card.holder.controller instanceof ControllerAI) { + targetCard = units.filter(c => c.holder !== card.holder)[0]; + } else { + if (units.length == 1) { + targetCard = units[0]; + } else { + await ui.queueCarousel({ cards: units }, 1, (c, i) => targetCard = c.cards[i], () => true, true, false, "Choose which enemy card to destroy"); + } + } + } else { + return false; + } + if (targetCard) { + await targetCard.animate("scorch", true, false); + await board.toGrave(targetCard, targetCard.currentLocation); + } + }, + weight: card => { + let rows = board.row.filter(row => !row.isShielded()); + let units = rows.reduce((a, r) => a.concat(r.minUnits()), []) + .reduce((a, c) => (!a.length || a[0].power > c.power) ? [c] : a[0].power === c.power ? a.concat([c]) : a, []) + .filter(c => c.holder !== card.holder); + if (units.length == 0) + return 0; + return 5 + units[0].power; + + } }, queen_calanthe: { description: "Play a unit then draw a card from you deck.", diff --git a/decks.js b/decks.js index e326a7f..c7b45c7 100644 --- a/decks.js +++ b/decks.js @@ -258,7 +258,7 @@ let default_decks = [{ { "title": "Velen Deck 1 - Cursed Land", "description": "Deck relying mostly on bond, scorch and drawing cards", - "leader": "ve_lady_wood_weavess", + "leader": "ve_ghost_tree", "faction": "velen", "cards": [ ["spe_horn", 1], diff --git a/factions.js b/factions.js index 96cb018..9904b8a 100644 --- a/factions.js +++ b/factions.js @@ -272,16 +272,13 @@ var factions = { name: "Velen", factionAbilityAction: async player => { await ui.notification("velen", 1000); - let cardsToDraw = player.velenCardDraw + player.getAllRowCards().filter(c => c.abilities.includes("soothsayer")).length; + let cardsToDraw = Math.min(player.velenCardDraw + player.getAllRowCards().filter(c => c.abilities.includes("soothsayer")).length, player.deck.cards.length); let cards = { cards: player.deck.cards.slice(0, cardsToDraw) }; let targetCard = null; ui.helper.showMessage(String(player.destroyedCards)+" card(s) were destroyed last round.",3); if (player.controller instanceof ControllerAI) { targetCard = player.controller.getHighestWeightCard(cards.cards); } else { - try { - Carousel.curr.cancel(); - } catch (err) { } await ui.queueCarousel(cards, 1, (c, i) => targetCard = c.cards[i], c => true, true, true, "Choose up to one card to draw and play immediatly"); } if (player.destroyedCards > 1) { diff --git a/gwent.js b/gwent.js index 9059348..cb73e7f 100644 --- a/gwent.js +++ b/gwent.js @@ -3388,11 +3388,11 @@ class UI { return; ui.ytActive = true; ui.youtube.playVideo(); - let timer = setInterval(() => { + let initbtntimer = setInterval(() => { if (ui.youtube.getPlayerState() !== YT.PlayerState.PLAYING) ui.youtube.playVideo(); else { - clearInterval(timer); + clearInterval(initbtntimer); ui.toggleMusic_elem.classList.remove("fade"); } }, 500); @@ -3711,13 +3711,13 @@ class UI { // Displays a Carousel menu of filtered container items that match the predicate. // Suspends gameplay until the Carousel is closed. Automatically picks random card if activated for AI player async queueCarousel(container, count, action, predicate, bSort, bQuit, title) { - if (game.currPlayer && game.currPlayer.controller instanceof ControllerAI) { + /*if (game.currPlayer && game.currPlayer.controller instanceof ControllerAI) { for (let i = 0; i < count; ++i) { let cards = container.cards.reduce((a, c, i) => !predicate || predicate(c) ? a.concat([i]) : a, []); await action(container, cards[randomInt(cards.length)]); } return; - } + }*/ let carousel = new Carousel(container, count, action, predicate, bSort, bQuit, title); if (Carousel.curr === undefined || Carousel.curr === null) { carousel.start(); @@ -4423,12 +4423,12 @@ class HelperBox { var h = this; setTimeout(function () { // Fading out - 1s - var interval = setInterval(function () { + var helperBoxInterval = setInterval(function () { if (opacity > 0) { opacity -= 0.1; h.elem.style.opacity = opacity; } else { - clearInterval(interval); // Stop the interval when opacity reaches 0 + clearInterval(helperBoxInterval); // Stop the interval when opacity reaches 0 h.hide(); // Hide the element h.elem.style.opacity = 1; } @@ -5374,16 +5374,16 @@ async function fade(fadeIn, elem, dur, delay) { elem.style.filter = "alpha(opacity=" + (op * 100) + ")"; if (fadeIn) elem.classList.remove("hide"); - let timer = setInterval(async function () { + let fadetimer = setInterval(async function () { op += (fadeIn ? 0.1 : -0.1); if (op >= 1) { - clearInterval(timer); + clearInterval(fadetimer); return; } else if (op <= 0.1) { elem.classList.add("hide"); elem.style.opacity = ""; elem.style.filter = ""; - clearInterval(timer); + clearInterval(fadetimer); return; } elem.style.opacity = op; @@ -5578,9 +5578,9 @@ function sleep(ms) { // Suspends execution until the predicate condition is met, checking every ms milliseconds function sleepUntil(predicate, ms) { return new Promise(resolve => { - let timer = setInterval(function () { + let sutimer = setInterval(function () { if (predicate()) { - clearInterval(timer); + clearInterval(sutimer); resolve(); } }, ms)