Added Wild Hunt faction
Added full new Wild Hunt faction with its very specific abilities
247
abilities.js
@ -27,6 +27,25 @@ var ability_dict = {
|
||||
}
|
||||
}
|
||||
},
|
||||
white_frost: {
|
||||
name: "White Frost",
|
||||
description: "Sets the strength of all cards on the 2 corresponding rows to 1 for both players.",
|
||||
placed: async (card, row) => {
|
||||
if(card.targetRows === "agile_cr")
|
||||
card.abilities = ["frost", "fog"];
|
||||
else if (card.targetRows === "agile_cs")
|
||||
card.abilities = ["frost", "rain"];
|
||||
else if (card.targetRows === "agile_rs")
|
||||
card.abilities = ["fog", "rain"];
|
||||
// If ability carried by a unit/hero card, draw the weather card from the deck
|
||||
if (card.isUnit() || card.hero) {
|
||||
let wCard = card.holder.deck.findCard(c => c.row === "weather" && c.abilities.includes("white_frost"));
|
||||
if (wCard) {
|
||||
await wCard.autoplay(card.holder.deck);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
fog: {
|
||||
name: "Impenetrable Fog",
|
||||
description: "Sets the strength of all Ranged Combat cards to 1 for both players. ",
|
||||
@ -214,7 +233,7 @@ var ability_dict = {
|
||||
try {
|
||||
Carousel.curr.cancel();
|
||||
} catch (err) { }
|
||||
await ui.queueCarousel(cards, 1, (c, i) => targetCard = c.cards[i], c => true, true, false, "Choose the card to draw and play keep");
|
||||
await ui.queueCarousel(cards, 1, (c, i) => targetCard = c.cards[i], c => true, true, false, "Choose the card to draw and keep");
|
||||
}
|
||||
cards.cards.forEach(c => {
|
||||
if (c === targetCard) {
|
||||
@ -643,11 +662,6 @@ var ability_dict = {
|
||||
|
||||
}
|
||||
},
|
||||
eredin_commander: {
|
||||
description: "Double the strength of all your Close Combat units (unless a Commander's horn is also present on that row).",
|
||||
activated: async card => await board.getRow(card, "close", card.holder).leaderHorn(card),
|
||||
weight: (card, ai) => ai.weightHornRow(card, board.getRow(card, "close", card.holder))
|
||||
},
|
||||
eredin_bringer_of_death: {
|
||||
name: "Eredin : Bringer of Death",
|
||||
description: "Restore a unit card from your discard pile to your hand.",
|
||||
@ -1234,13 +1248,17 @@ var ability_dict = {
|
||||
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);
|
||||
targetCards = card.holder.controller.getWeights(units).sort((a, b) => (b.weight - a.weight)).slice(0, cardsCount).map(c => c.card);
|
||||
} 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);
|
||||
});
|
||||
},
|
||||
weight: card => {
|
||||
let units = card.holder.grave.cards.filter(c => c.isUnit() && c.destructionRound == game.roundCount);
|
||||
return Math.min(15, units.length * 5);
|
||||
}
|
||||
},
|
||||
ghost_tree: {
|
||||
@ -1279,6 +1297,114 @@ var ability_dict = {
|
||||
|
||||
}
|
||||
},
|
||||
eredin_commander: {
|
||||
description: "Choose on your battlefield two or less unit and/or hero cards and take them into your hand.",
|
||||
activated: async card => {
|
||||
let cards = card.holder.getAllRowCards().filter(c => c.hero || c.isUnit());
|
||||
if (cards.length == 0)
|
||||
return false;
|
||||
let targetCards = [];
|
||||
let cardsCount = Math.min(2, cards.length);
|
||||
if (card.holder.controller instanceof ControllerAI) {
|
||||
targetCards = card.holder.controller.selectBestCards(cards, cardsCount, { "spy": 10, "zirael": 10, "medic": 8, "sage": 4, "scorch_c": 4, "scorch_r": 4 }).map(c => c.card);
|
||||
} else {
|
||||
await ui.queueCarousel({ cards: cards }, cardsCount, (c, i) => targetCards.push(c.cards[i]), c => true, true, true, "Choose up to " + String(cardsCount)+" cards to take back into your hand.");
|
||||
}
|
||||
if (targetCards.length > 0) {
|
||||
targetCards.forEach(async c => {
|
||||
await board.moveTo(c, card.holder.hand, c.currentLocation);
|
||||
});
|
||||
}
|
||||
},
|
||||
weight: card => {
|
||||
let cards = card.holder.getAllRowCards().filter(c => c.hero || c.isUnit());
|
||||
if (cards.length == 0)
|
||||
return card.holder.controller.selectBestCards(cards, Math.min(2, cards.length), { "spy": 10, "medic": 8, "sage": 4, "scorch_c": 4 }).reduce((a,c) => a + c.weight,0);
|
||||
return 5;
|
||||
|
||||
}
|
||||
},
|
||||
auberon_king: {
|
||||
description: "Draw from your deck or graveyard any number of Navigator cards. Then choose in your hand the same number of cards and put them back in any place of the deck.",
|
||||
activated: async card => {
|
||||
let navigators = card.holder.deck.cards.filter(c => c.abilities.includes("door_o"))
|
||||
.concat(card.holder.grave.cards.filter(c => c.abilities.includes("door_o")))
|
||||
.sort((a, b) => b.basePower - a.basePower);
|
||||
if (navigators.length < 1)
|
||||
return false;
|
||||
if (card.holder.controller instanceof ControllerAI) {
|
||||
// AI draws only one, the strongest
|
||||
await board.toHand(navigators[0], card.currentLocation);
|
||||
let targetCard = card.holder.controller.getLowestWeightCard(card.holder.hand.cards);
|
||||
if (targetCard)
|
||||
await board.toDeck(targetCard, card.holder.hand);
|
||||
} else {
|
||||
let targetCards = [];
|
||||
await ui.queueCarousel({ cards: navigators }, navigators.length, (c, i) => targetCards.push(c.cards[i]), c => true, true, true, "Choose any number of cards to draw, but you'll have to put back into the deck an equal amount.");
|
||||
await targetCards.forEach(async c => board.toHand(c, card.currentLocation));
|
||||
await ui.queueCarousel(card.holder.hand, targetCards.length, async (c, i) => await board.toDeck(c.cards[i], card.holder.hand), c => true, true, false, "Choose " + String(targetCards.length) +" cards to put back into your deck.");
|
||||
}
|
||||
},
|
||||
weight: card => {
|
||||
let navigators = card.holder.deck.cards.filter(c => c.abilities.includes("door_o")).concat(card.holder.grave.cards.filter(c => c.abilities.includes("door_o")));
|
||||
if (navigators.length < 1 || card.holder.deck.cards.length < 4)
|
||||
return 0;
|
||||
if (card.holder.hand.cards.filter(c => c.abilities.includes("door_o")).length > 0)
|
||||
return 0;
|
||||
if (game.roundCount < 3)
|
||||
return 15;
|
||||
if (game.roundCount > 2) {
|
||||
navigators = card.holder.getAllRowCards().filter(c => c.abilities.includes("door_o"));
|
||||
if (navigators.length == 0 || (navigators.length == 1 && card.holder.leader.key == "wh_caranthir_navigator"))
|
||||
return 15;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
winter_queen: {
|
||||
description: "Draw any special card from your deck and play it immediatly.",
|
||||
activated: async card => {
|
||||
let specials = card.holder.deck.cards.filter(c => !(c.hero || c.isUnit()));
|
||||
if (specials.length < 1)
|
||||
return false;
|
||||
let targetCard = null;
|
||||
if (card.holder.controller instanceof ControllerAI) {
|
||||
targetCard = card.holder.controller.getHighestWeightCard(specials)[0];
|
||||
if (targetCard)
|
||||
card.holder.getAIController().playCardDefault(targetCard, card.holder.deck);
|
||||
} else {
|
||||
await ui.queueCarousel({ cards: specials }, 1, (c, i) => targetCard = c.cards[i], c => true, true, false, "Choose a special card to play immediatly.");
|
||||
if (targetCard) {
|
||||
// let player select where to play the card
|
||||
let choiceDone = false;
|
||||
card.holder.selectCardDestination(targetCard, card.holder.deck, async () => {
|
||||
choiceDone = true;
|
||||
ui.enablePlayer(true);
|
||||
});
|
||||
// We sleep until the choice is made, otherwise the turn continues as normal
|
||||
await sleepUntil(() => choiceDone, 100);
|
||||
}
|
||||
}
|
||||
},
|
||||
weight: card => {
|
||||
let specials = card.holder.deck.cards.filter(c => !(c.hero || c.isUnit()));
|
||||
if (specials.length < 1)
|
||||
return 0;
|
||||
return card.holder.controller.getWeights(specials).sort((a, b) => b.weight - a.weight)[0].weight;
|
||||
}
|
||||
},
|
||||
caranthir_navigator: {
|
||||
description: "You can open two Dimensional Doors at the same time (but only if there is at least one navigator in each of these 2 rows).",
|
||||
placed: card => {
|
||||
card.holder.disableLeader();
|
||||
}
|
||||
},
|
||||
imlerith_general: {
|
||||
description: "Passive: Imlerith will shield Navigators from destruction.",
|
||||
placed: card => {
|
||||
card.holder.disableLeader();
|
||||
}
|
||||
},
|
||||
queen_calanthe: {
|
||||
description: "Play a unit then draw a card from you deck.",
|
||||
activated: async card => {
|
||||
@ -2138,4 +2264,111 @@ var ability_dict = {
|
||||
description: "Place on your or opponent's battlefield on any row. Next unit card (not hero) that will be placed on this row will be destroyed and it's abilities will not work",
|
||||
weight: (card) => 20
|
||||
},
|
||||
door: {
|
||||
name: "Dimensional Door",
|
||||
description: "While the door is active, at the end of each of your turns you should draw one card from your deck. If the row of the card matches the row of the door, play it immediatly, otherwise put it back into the deck. If it does not have a row, you can play it or put it back into the deck.",
|
||||
weight: (card) => 0
|
||||
},
|
||||
door_o: {
|
||||
name: "Dimensional Door Opening",
|
||||
description: "Opens the dimensional door of the row it is in, if none other is opened",
|
||||
weight: (card) => 0,
|
||||
placed: async card => {
|
||||
if (card.isLocked())
|
||||
return;
|
||||
let openedDoors = card.holder.getAllRows().map(r => r.special).reduce((a, c) => a.concat(c.cards.filter(c => c.key === "spe_dimensional_door" && c.faceUp)), []);
|
||||
if (openedDoors.length == 0 || (card.holder.leader.key === "wh_caranthir_navigator" && openedDoors.length < 2)) {
|
||||
let door = card.currentLocation.special.findCard(c => c.key === "spe_dimensional_door");
|
||||
if (door && !door.faceUp)
|
||||
door.flip();
|
||||
}
|
||||
},
|
||||
removed: async (card) => {
|
||||
// If last navigator in row, close the door
|
||||
let navigators = card.currentLocation.cards.filter(c => c.abilities.includes("door_o"));
|
||||
if (navigators.length == 0) {
|
||||
let door = card.currentLocation.special.findCard(c => c.key === "spe_dimensional_door");
|
||||
if (door && door.faceUp)
|
||||
door.flip();
|
||||
}
|
||||
}
|
||||
},
|
||||
sage: {
|
||||
name: "Sage",
|
||||
description: "Place on your battlefield and draw 4 cards from your deck. Look at them and put them back at the top or bottom of the deck in the order of your choice.",
|
||||
weight: (card) => 20,
|
||||
placed: async card => {
|
||||
if (card.isLocked())
|
||||
return;
|
||||
if (card.holder.controller instanceof ControllerAI)
|
||||
return; // Meh, too tricky to implement for the AI, just skip
|
||||
if (card.holder.deck.cards.length > 0) {
|
||||
await ui.startDeckSorter(card.holder.deck.cards.slice(0, Math.min(4, card.holder.deck.cards.length)), card.holder, null, "Re-order the cards back into the deck", true);
|
||||
}
|
||||
}
|
||||
},
|
||||
zirael: {
|
||||
name: "Zirael",
|
||||
description: "Place on your battlefield and draw 2 cards from your deck. Play them immediatly or put them back at the top or bottom of the deck in the order of your choice.",
|
||||
weight: (card) => 20,
|
||||
placed: async card => {
|
||||
if (card.isLocked())
|
||||
return;
|
||||
let cards = card.holder.deck.cards.slice(0, Math.min(2, card.holder.deck.cards.length));
|
||||
if (cards.length == 0)
|
||||
return;
|
||||
let targetCards = [];
|
||||
if (card.holder.controller instanceof ControllerAI) {
|
||||
targetCards = card.holder.controller.getWeights(cards).filter(c => c.weight > 0).map(c => c.card);
|
||||
} else {
|
||||
await ui.queueCarousel({ cards: cards }, Math.min(2, card.holder.deck.cards.length), (c, i) => targetCards.push(c.cards[i]), c => true, true, true, "Choose up to 2 cards to play right away.");
|
||||
}
|
||||
// Discarding cards left aside
|
||||
cards.forEach(c => {
|
||||
if (!targetCards.includes(c)) {
|
||||
card.holder.deck.removeCard(c);
|
||||
card.holder.deck.addCard(c);
|
||||
}
|
||||
});
|
||||
for (var i = 0; i < targetCards.length; i++) {
|
||||
let c = targetCards[i];
|
||||
if (card.holder.controller instanceof ControllerAI) {
|
||||
await card.holder.getAIController().playCardDefault(c, card.holder.deck);
|
||||
} else {
|
||||
// let player select where to play the card
|
||||
let choiceDone = false;
|
||||
card.holder.selectCardDestination(c, card.holder.deck, async () => {
|
||||
choiceDone = true;
|
||||
ui.enablePlayer(true);
|
||||
});
|
||||
// We sleep until the choice is made, otherwise the turn continues as normal
|
||||
await sleepUntil(() => choiceDone, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
naglfar: {
|
||||
name: "Naglfar",
|
||||
description: "Place on your battlefield and draw 2 cards or less from your deck with the word 'Naglfar' in their name and play them immediatly.",
|
||||
weight: (card) => 20,
|
||||
placed: async card => {
|
||||
if (card.isLocked())
|
||||
return;
|
||||
// Find available Naglfar cards in the deck
|
||||
let cards = card.holder.deck.cards.filter(c => c.name.toLowerCase().includes("naglfar"));
|
||||
if (cards.length == 0)
|
||||
return;
|
||||
let targetCards = [];
|
||||
// Select up to 2, AI takes highest weights
|
||||
if (card.holder.controller instanceof ControllerAI) {
|
||||
targetCards = card.holder.controller.getWeights(cards).sort((a, b) => b.weight - a.weight).slice(0, Math.min(2, cards.length)).map(c => c.card);
|
||||
} else {
|
||||
await ui.queueCarousel({ cards: cards }, Math.min(2, card.holder.deck.cards.length), (c, i) => targetCards.push(c.cards[i]), c => true, true, true, "Choose up to 2 cards to play right away.");
|
||||
}
|
||||
for (var i = 0; i < targetCards.length; i++) {
|
||||
let c = targetCards[i];
|
||||
await card.holder.getAIController().playCardDefault(c, card.holder.deck); // Should be enought, all these cards play on a single row
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
341
cards.js
@ -3357,6 +3357,346 @@ var ext_ve_cards = {
|
||||
},
|
||||
};
|
||||
|
||||
var ext_wh_cards = {
|
||||
"spe_dimensional_door": {
|
||||
"name": "Dimensional Door",
|
||||
"deck": "special wild_hunt",
|
||||
"row": "",
|
||||
"strength": "",
|
||||
"ability": "door",
|
||||
"filename": "dimensional_door",
|
||||
"count": "0",
|
||||
"quote": "Very useful for travels to other dimensions and bringing apocalypse upon the world."
|
||||
},
|
||||
"spe_white_frost_1": {
|
||||
"name": "White Frost",
|
||||
"deck": "weather wild_hunt",
|
||||
"row": "agile_cr",
|
||||
"strength": "",
|
||||
"ability": "white_frost",
|
||||
"filename": "white_frost",
|
||||
"count": "1",
|
||||
"quote": "It is the beginning of the end!"
|
||||
},
|
||||
"spe_white_frost_2": {
|
||||
"name": "White Frost",
|
||||
"deck": "weather wild_hunt",
|
||||
"row": "agile_cs",
|
||||
"strength": "",
|
||||
"ability": "white_frost",
|
||||
"filename": "white_frost",
|
||||
"count": "1",
|
||||
"quote": "It is the beginning of the end!"
|
||||
},
|
||||
"spe_white_frost_3": {
|
||||
"name": "White Frost",
|
||||
"deck": "weather wild_hunt",
|
||||
"row": "agile_rs",
|
||||
"strength": "",
|
||||
"ability": "white_frost",
|
||||
"filename": "white_frost",
|
||||
"count": "1",
|
||||
"quote": "It is the beginning of the end!"
|
||||
},
|
||||
"wh_eredin_commander": {
|
||||
"name": "Eredin Bréacc Glas: Commander of Dearg Ruadhri",
|
||||
"deck": "wild_hunt",
|
||||
"row": "leader",
|
||||
"strength": "",
|
||||
"ability": "eredin_commander",
|
||||
"filename": "eredin_commander",
|
||||
"count": "1",
|
||||
"quote": "Any last words?"
|
||||
},
|
||||
"wh_auberon_king": {
|
||||
"name": "Auberon Muirketah: King of Aen Elle",
|
||||
"deck": "wild_hunt",
|
||||
"row": "leader",
|
||||
"strength": "",
|
||||
"ability": "auberon_king",
|
||||
"filename": "auberon_king",
|
||||
"count": "1",
|
||||
"quote": "After having lived over six hundred and fifty years, little remains to excite."
|
||||
},
|
||||
"wh_winter_queen": {
|
||||
"name": "Winter Queen: Destroyer of the Worlds",
|
||||
"deck": "wild_hunt",
|
||||
"row": "leader",
|
||||
"strength": "",
|
||||
"ability": "winter_queen",
|
||||
"filename": "winter_queen",
|
||||
"count": "1",
|
||||
"quote": "Truth is but a shard of ice."
|
||||
},
|
||||
"wh_caranthir_navigator": {
|
||||
"name": "Caranthir Ar-Feiniel: Sorcerer-Navigator",
|
||||
"deck": "wild_hunt",
|
||||
"row": "leader",
|
||||
"strength": "",
|
||||
"ability": "caranthir_navigator",
|
||||
"filename": "caranthir_navigator",
|
||||
"count": "1",
|
||||
"quote": "A favorite son who chose a life of villainy."
|
||||
},
|
||||
"wh_imlerith_general": {
|
||||
"name": "Imlerith: General of the Wild Hunt",
|
||||
"deck": "wild_hunt",
|
||||
"row": "leader",
|
||||
"strength": "",
|
||||
"ability": "imlerith_general",
|
||||
"filename": "imlerith_general",
|
||||
"count": "1",
|
||||
"quote": "The sisters said you would come. They saw you arrive in the water's surface."
|
||||
},
|
||||
"wh_wild_hunt_warrior_1": {
|
||||
"name": "Wild Hunt Warrior",
|
||||
"id": 2,
|
||||
"deck": "wild_hunt",
|
||||
"row": "close",
|
||||
"strength": "3",
|
||||
"ability": "bond",
|
||||
"filename": "wild_hunt_warrior_1",
|
||||
"count": "3",
|
||||
"target": "wh_wild_hunt_warrior",
|
||||
"quote": "The White Frost is coming."
|
||||
},
|
||||
"wh_wild_hunt_warrior_2": {
|
||||
"name": "Wild Hunt Warrior",
|
||||
"id": 2,
|
||||
"deck": "wild_hunt",
|
||||
"row": "close",
|
||||
"strength": "4",
|
||||
"ability": "bond",
|
||||
"filename": "wild_hunt_warrior_2",
|
||||
"count": "1",
|
||||
"target": "wh_wild_hunt_warrior",
|
||||
"quote": "THe considers it an excellent joke - to split the skulls of the living with the skulls of the dead. "
|
||||
},
|
||||
"wh_imlerith": {
|
||||
"name": "Imlerith",
|
||||
"deck": "wild_hunt",
|
||||
"row": "close",
|
||||
"strength": "7",
|
||||
"ability": "scorch_c",
|
||||
"filename": "imlerith",
|
||||
"count": "1",
|
||||
"quote": "He boasted that no weapon would ever pierce his armor. And he was right — even in death."
|
||||
},
|
||||
"wh_geralt": {
|
||||
"name": "Geralt of Rivia",
|
||||
"deck": "wild_hunt",
|
||||
"row": "close",
|
||||
"strength": "8",
|
||||
"ability": "hero",
|
||||
"filename": "geralt",
|
||||
"count": "1",
|
||||
"quote": "I'm only here for Yen."
|
||||
},
|
||||
"wh_cirilla": {
|
||||
"name": "Cirilla",
|
||||
"deck": "wild_hunt",
|
||||
"row": "close",
|
||||
"strength": "0",
|
||||
"ability": "hero zirael",
|
||||
"filename": "cirilla",
|
||||
"count": "1",
|
||||
"quote": "Zireael possesses a great power she cannot control."
|
||||
},
|
||||
"wh_avallach": {
|
||||
"name": "Avallac'h",
|
||||
"deck": "wild_hunt",
|
||||
"row": "close",
|
||||
"strength": "6",
|
||||
"ability": "hero sage",
|
||||
"filename": "avallach",
|
||||
"count": "1",
|
||||
"quote": "You humans have… unusual tastes."
|
||||
},
|
||||
"wh_wild_hunt_rider_1": {
|
||||
"name": "Wild Hunt Rider",
|
||||
"deck": "wild_hunt",
|
||||
"row": "agile_cr",
|
||||
"strength": "5",
|
||||
"ability": "",
|
||||
"filename": "wild_hunt_rider_1",
|
||||
"count": "2",
|
||||
"quote": "First the buffalo horns atop their helms penetrate one's view, then the crest betwixt them."
|
||||
},
|
||||
"wh_wild_hunt_rider_2": {
|
||||
"name": "Wild Hunt Rider",
|
||||
"deck": "wild_hunt",
|
||||
"row": "agile_rs",
|
||||
"strength": "5",
|
||||
"ability": "",
|
||||
"filename": "wild_hunt_rider_2",
|
||||
"count": "2",
|
||||
"quote": "The cavalcade of wraiths on undead horses galloping accross the sky."
|
||||
},
|
||||
"wh_wild_hunt_rider_3": {
|
||||
"name": "Wild Hunt Rider",
|
||||
"deck": "wild_hunt",
|
||||
"row": "agile_cs",
|
||||
"strength": "5",
|
||||
"ability": "",
|
||||
"filename": "wild_hunt_rider_3",
|
||||
"count": "2",
|
||||
"quote": "They paint the sky with snow and the earth with fire."
|
||||
},
|
||||
"wh_aen_elle_conqueror_1": {
|
||||
"name": "Aen Elle Conqueror",
|
||||
"id": 1,
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "4",
|
||||
"ability": "bond",
|
||||
"filename": "aen_elle_conqueror_1",
|
||||
"count": "1",
|
||||
"quote": "The end of one world can be the beginning of another."
|
||||
},
|
||||
"wh_aen_elle_conqueror_2": {
|
||||
"name": "Aen Elle Conqueror",
|
||||
"id": 2,
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "4",
|
||||
"ability": "bond",
|
||||
"filename": "aen_elle_conqueror_2",
|
||||
"count": "1",
|
||||
"quote": "If they will not submit, they shall be driven out!"
|
||||
},
|
||||
"wh_aen_elle_conqueror_3": {
|
||||
"name": "Aen Elle Conqueror",
|
||||
"id": 3,
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "4",
|
||||
"ability": "bond",
|
||||
"filename": "aen_elle_conqueror_3",
|
||||
"count": "1",
|
||||
"quote": "For his noble kind morality is but a whim enjoyed by others. More specifically, those who lose."
|
||||
},
|
||||
"wh_wild_hunt_hound_1": {
|
||||
"name": "Wild Hunt Hound",
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "7",
|
||||
"ability": "",
|
||||
"filename": "wild_hunt_hound_1",
|
||||
"count": "1",
|
||||
"quote": "Cry 'Havoc!', and let slip the dogs of war."
|
||||
},
|
||||
"wh_wild_hunt_hound_2": {
|
||||
"name": "Wild Hunt Hound",
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "7",
|
||||
"ability": "",
|
||||
"filename": "wild_hunt_hound_2",
|
||||
"count": "1",
|
||||
"quote": "Who's a good boy? Well, surely not him."
|
||||
},
|
||||
"wh_yennefer_captive": {
|
||||
"name": "Yennefer: Eredin's Captive",
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "5",
|
||||
"ability": "hero medic",
|
||||
"filename": "yennefer_captive",
|
||||
"count": "1",
|
||||
"quote": "I'll exchange her for your sould, witcher!"
|
||||
},
|
||||
"wh_nithral": {
|
||||
"name": "Nithral",
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "7",
|
||||
"ability": "hero morale",
|
||||
"filename": "nithral",
|
||||
"count": "1",
|
||||
"quote": "Eredin's personal cavalcade includes only the most brutal and most ferocious of the Aen Elle."
|
||||
},
|
||||
"wh_geels": {
|
||||
"name": "Ge'els",
|
||||
"deck": "wild_hunt",
|
||||
"row": "ranged",
|
||||
"strength": "6",
|
||||
"ability": "hero sage",
|
||||
"filename": "geels",
|
||||
"count": "1",
|
||||
"quote": "Paintings should convey emotion, not words."
|
||||
},
|
||||
"wh_naglfar_taskmaster": {
|
||||
"name": "Naglfar's Taskmaster",
|
||||
"deck": "wild_hunt",
|
||||
"row": "siege",
|
||||
"strength": "4",
|
||||
"ability": "medic",
|
||||
"filename": "naglfar_taskmaster",
|
||||
"count": "1",
|
||||
"quote": "She ensures the ship is sustained by squeezing the life essence from those insignificant human vermin."
|
||||
},
|
||||
"wh_naglfar_crew": {
|
||||
"name": "Naglfar's Crew",
|
||||
"deck": "wild_hunt",
|
||||
"row": "siege",
|
||||
"strength": "3",
|
||||
"ability": "bond",
|
||||
"filename": "naglfar_crew",
|
||||
"count": "4",
|
||||
"quote": "Humans don’t know what powers the Naglfar. For those that discover the truth... Well, it’s already too late for them."
|
||||
},
|
||||
"wh_naglfar_cartographer": {
|
||||
"name": "Naglfar's Cartographer",
|
||||
"deck": "wild_hunt",
|
||||
"row": "siege",
|
||||
"strength": "4",
|
||||
"ability": "sage",
|
||||
"filename": "naglfar_cartographer",
|
||||
"count": "1",
|
||||
"quote": "We're almost there, my lord!"
|
||||
},
|
||||
"wh_naglfar": {
|
||||
"name": "Naglfar",
|
||||
"deck": "wild_hunt",
|
||||
"row": "siege",
|
||||
"strength": "0",
|
||||
"ability": "hero naglfar",
|
||||
"filename": "naglfar",
|
||||
"count": "1",
|
||||
"quote": "Naglfar will wage the final battle of good and evil known as Ragh nar Roog."
|
||||
},
|
||||
"wh_navigator_1": {
|
||||
"name": "Navigator",
|
||||
"deck": "wild_hunt",
|
||||
"row": "agile_crs",
|
||||
"strength": "3",
|
||||
"ability": "door_o",
|
||||
"filename": "navigator_1",
|
||||
"count": "1",
|
||||
"quote": "They are powerful mages who had the ability to manipulate space and to open portals between different worlds."
|
||||
},
|
||||
"wh_navigator_2": {
|
||||
"name": "Navigator",
|
||||
"deck": "wild_hunt",
|
||||
"row": "agile_crs",
|
||||
"strength": "4",
|
||||
"ability": "door_o",
|
||||
"filename": "navigator_2",
|
||||
"count": "1",
|
||||
"quote": "They would guide the Riders of the Hunt along mystic pathways through time and space in order to reach other worlds."
|
||||
},
|
||||
"wh_navigator_3": {
|
||||
"name": "Navigator",
|
||||
"deck": "wild_hunt",
|
||||
"row": "agile_crs",
|
||||
"strength": "5",
|
||||
"ability": "door_o",
|
||||
"filename": "navigator_3",
|
||||
"count": "1",
|
||||
"quote": "All of them are apprentices of Avallac'h"
|
||||
},
|
||||
};
|
||||
|
||||
var ext_wu_cards = {
|
||||
"wu_vilgefortz_magician_kovir": {
|
||||
"name": "Vilgefortz: Magician of Kovir",
|
||||
@ -6789,6 +7129,7 @@ card_dict = Object.assign({}, card_dict, ext_sk_cards);
|
||||
card_dict = Object.assign({}, card_dict, ext_re_cards);
|
||||
card_dict = Object.assign({}, card_dict, ext_to_cards);
|
||||
card_dict = Object.assign({}, card_dict, ext_ve_cards);
|
||||
card_dict = Object.assign({}, card_dict, ext_wh_cards);
|
||||
|
||||
card_dict = Object.assign({}, card_dict, ext_wu_cards);
|
||||
card_dict = Object.assign({}, card_dict, ext_lr_cards);
|
||||
|
||||
29
decks.js
@ -290,6 +290,35 @@ let default_decks = [{
|
||||
["ve_hungry_wolves_3", 1],
|
||||
["ve_abandoned_girl", 1]
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Wild Hunt Deck 1 - Worlds Conquest",
|
||||
"description": "Deck relying mostly on bond door mechanic",
|
||||
"leader": "wh_winter_queen",
|
||||
"faction": "wild_hunt",
|
||||
"cards": [
|
||||
["spe_decoy", 2],
|
||||
["spe_scorch", 1],
|
||||
["spe_clear", 1],
|
||||
["spe_white_frost_1", 1],
|
||||
["wh_geralt", 1],
|
||||
["wh_imlerith", 1],
|
||||
["wh_nithral", 1],
|
||||
["wh_avallach", 1],
|
||||
["wh_geels", 1],
|
||||
["wh_navigator_3", 1],
|
||||
["wh_wild_hunt_rider_1", 2],
|
||||
["wh_wild_hunt_rider_2", 2],
|
||||
["wh_wild_hunt_rider_3", 2],
|
||||
["wh_yennefer_captive", 1],
|
||||
["wh_naglfar_cartographer", 1],
|
||||
["wh_naglfar_taskmaster", 1],
|
||||
["wh_navigator_2", 1],
|
||||
["wh_naglfar_crew", 4],
|
||||
["wh_navigator_1", 1],
|
||||
["wh_cirilla", 1],
|
||||
["wh_naglfar", 1]
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
106
factions.js
@ -303,7 +303,7 @@ var factions = {
|
||||
}
|
||||
if (player.controller instanceof ControllerAI) {
|
||||
if(targetCard)
|
||||
targetCard.autoplay(player.deck);
|
||||
player.controller.playCardDefault(targetCard, player.deck);
|
||||
// If more than 1 card was destroyed, we trigger the faction ability once more
|
||||
if (player.destroyedCards > 0) {
|
||||
await factions["velen"].factionAbilityAction(player);
|
||||
@ -349,4 +349,108 @@ var factions = {
|
||||
},
|
||||
unavailableSpecials: []
|
||||
},
|
||||
wild_hunt: {
|
||||
name: "Wild Hunt",
|
||||
factionAbilityAction: async player => {
|
||||
if (player.deck.cards.length == 0)
|
||||
return;
|
||||
let openedDoors = player.getAllRows().map(r => r.special).reduce((a, c) => a.concat(c.cards.filter(c => c.key === "spe_dimensional_door" && c.faceUp)), []);
|
||||
if (openedDoors.length > 0) {
|
||||
for (var i = 0; i < openedDoors.length; i++) {
|
||||
if (player.deck.cards.length > 0) {
|
||||
let door = openedDoors[i];
|
||||
let card = player.deck.cards.slice(0, 1)[0];
|
||||
ui.showPreviewVisuals(card);
|
||||
await sleep(2000);
|
||||
let play = false;
|
||||
if (card.hero || card.isUnit()) {
|
||||
if (card.getPlayableRows().filter(r => r === door.currentLocation.row).length > 0) {
|
||||
play = true;
|
||||
} else {
|
||||
ui.helper.showMessage("Card drawn cannot be played on a row with an opened door.", 2);
|
||||
}
|
||||
} else {
|
||||
if (!(player.controller instanceof ControllerAI)) {
|
||||
play = await ui.popup("Play [E]", (p) => p.choice = true, "Discard [Q]", (p) => p.choice = false, "Play the card?", "Do you want to play this special card or put it back in the deck?");
|
||||
} else {
|
||||
if (player.controller.getWeights([card])[0].weight > 0)
|
||||
play = true;
|
||||
}
|
||||
}
|
||||
ui.preview.classList.add("hide");
|
||||
ui.previewCard = null;
|
||||
if (play) {
|
||||
if (!(player.controller instanceof ControllerAI)) {
|
||||
// let player select where to play the card
|
||||
let choiceDone = false;
|
||||
player.selectCardDestination(card, player.deck, async () => {
|
||||
choiceDone = true;
|
||||
ui.enablePlayer(true);
|
||||
});
|
||||
// We sleep until the choice is made, otherwise the turn continues as normal
|
||||
await sleepUntil(() => choiceDone, 100);
|
||||
} else {
|
||||
player.getAIController().playCardDefault(card, player.deck);
|
||||
}
|
||||
} else {
|
||||
player.deck.removeCard(card);
|
||||
player.deck.addCard(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
factionAbility: player => {
|
||||
game.gameStart.push(async () => {
|
||||
player.getAllRows().forEach(r => {
|
||||
let c = new Card("spe_dimensional_door", card_dict["spe_dimensional_door"], player);
|
||||
c.flip(); // Starts the game face down
|
||||
c.noRemove = true; // Stays on the board until the end
|
||||
r.special.addCard(c);
|
||||
});
|
||||
// Draws an additional card
|
||||
player.deck.draw(player.hand);
|
||||
player.playedLeaders = [player.leader.key];
|
||||
return false;
|
||||
});
|
||||
game.roundStart.push(async () => {
|
||||
// We put all Dimensional Doors face down again
|
||||
player.getAllRows().forEach(r => {
|
||||
let door = r.special.findCard(c => c.abilities.includes("door"));
|
||||
if (door && door.faceUp)
|
||||
door.flip();
|
||||
});
|
||||
// Select a different leader starting from round 2
|
||||
if (game.roundCount > 1) {
|
||||
let availableLeaders = Object.keys(card_dict).filter(cid => card_dict[cid].deck === "wild_hunt" && card_dict[cid].row === "leader" && !player.playedLeaders.includes(cid))
|
||||
.map(cid => new Card(cid, card_dict[cid], player));
|
||||
let targetCard = null;
|
||||
if (player.controller instanceof ControllerAI) {
|
||||
let rand = randomInt(availableLeaders.length);
|
||||
targetCard = availableLeaders[rand];
|
||||
} else {
|
||||
await ui.queueCarousel({ cards: availableLeaders }, 1, (c, i) => targetCard = c.cards[i], c => true, true, false, "Select the next leader to start the round with");
|
||||
}
|
||||
if (targetCard) {
|
||||
player.playedLeaders.push(targetCard.key);
|
||||
player.replaceLeader(targetCard);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
// On player's turn end, try to run the faction ability
|
||||
game.turnEnd.push(async () => {
|
||||
if(game.currPlayer === player)
|
||||
await factions["wild_hunt"].factionAbilityAction(player);
|
||||
});
|
||||
},
|
||||
description: "At the beginning of each round select a different Leader card. You will be able to use its ability in upcoming round before chosing another. Start the game with 11 cards instead of 10",
|
||||
activeAbility: false,
|
||||
abilityUses: 0,
|
||||
weight: (player) => {
|
||||
return 0;
|
||||
},
|
||||
unavailableSpecials: ["spe_horn","spe_fog","spe_rain","spe_frost"]
|
||||
},
|
||||
}
|
||||
109
gwent.js
@ -239,6 +239,23 @@ class ControllerAI {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Analyses the list of cards provided and computes their total weight based on the mapping provided (dict: ability=>weight)
|
||||
// Return best X cards found with a weight higher than 0
|
||||
selectBestCards(cards, count, weights, keepZeros=false) {
|
||||
let wCards = [];
|
||||
cards.forEach(c => {
|
||||
let w = 0;
|
||||
c.abilities.forEach(ab => {
|
||||
if (ab in weights)
|
||||
w += weights[ab];
|
||||
});
|
||||
wCards.push({ card: c, weight: w });
|
||||
});
|
||||
if (keepZeros)
|
||||
return wCards.sort((a, b) => b.weight - a.weight).slice(0, Math.min(wCards.length, count));
|
||||
return wCards.filter(c => c.weight > 0).sort((a, b) => b.weight - a.weight).slice(0, Math.min(wCards.length, count));
|
||||
}
|
||||
|
||||
// Swaps a card from the hand with the deck if beneficial
|
||||
redraw() {
|
||||
let card = this.discardOrder({
|
||||
@ -350,6 +367,15 @@ class ControllerAI {
|
||||
await this.player.playCard(c);
|
||||
}
|
||||
|
||||
// Plays any card with a default behaviour
|
||||
async playCardDefault(card,src=null) {
|
||||
let data_max = this.getMaximums();
|
||||
let data_board = this.getBoardData();
|
||||
if (src && src !== card.holder.hand)
|
||||
board.moveTo(card, card.holder.hand, src);
|
||||
await this.playCard(card, data_max, data_board)
|
||||
}
|
||||
|
||||
// Plays a Commander's Horn to the most beneficial row. Assumes at least one viable row.
|
||||
async horn(card) {
|
||||
let rows = this.player.getAllRows().filter(r => !r.special.containsCardByKey("spe_horn"));
|
||||
@ -1221,7 +1247,7 @@ class Player {
|
||||
await this.playCardAction(card, async () => await board.moveTo(card, row, this.hand), endTurn);
|
||||
}
|
||||
|
||||
// Plays a card to the board
|
||||
// Plays a card to the board from hand
|
||||
async playCard(card) {
|
||||
await this.playCardAction(card, async () => await card.autoplay(this.hand));
|
||||
}
|
||||
@ -1394,6 +1420,15 @@ class Player {
|
||||
await ui.viewCard(player_me.leader, async () => await player_me.activateLeader());
|
||||
}
|
||||
|
||||
replaceLeader(newLeader) {
|
||||
this.leader = newLeader;
|
||||
this.elem_leader.children[0].children[0].replaceWith(this.leader.elem);
|
||||
this.enableLeader();
|
||||
let ab = this.leader.abilities[0];
|
||||
if (ability_dict[ab].placed)
|
||||
ability_dict[ab].placed(this.leader);
|
||||
}
|
||||
|
||||
async activateFactionAbility() {
|
||||
let factionData = factions[this.deck.faction];
|
||||
if (factionData.activeAbility && this.factionAbilityUses > 0) {
|
||||
@ -2007,7 +2042,8 @@ class Row extends CardContainer {
|
||||
}
|
||||
this.updateState(card, false);
|
||||
if (runEffect) {
|
||||
if (!card.decoyTarget) {
|
||||
// Decoy targets do no trigger the removed effect, exept for cards holding a door opened, door closes when they leave the row
|
||||
if (!card.decoyTarget || card.abilities.includes("door_o")) {
|
||||
for (let x of card.removed)
|
||||
x(card);
|
||||
} else {
|
||||
@ -2407,6 +2443,10 @@ class Board {
|
||||
}
|
||||
}
|
||||
}
|
||||
// For Wild Hunt faction: Imlerith protects navigators
|
||||
if (card.abilities.includes("door_o") && card.holder.leader.key === "wh_imlerith_general") {
|
||||
destroy = false;
|
||||
}
|
||||
}
|
||||
if (destroy) {
|
||||
await this.moveTo(card, "grave", source);
|
||||
@ -2419,7 +2459,8 @@ class Board {
|
||||
}
|
||||
} else {
|
||||
card.animate("comrade");
|
||||
await protectors[0].animate("comrade");
|
||||
if (protectors.length > 0)
|
||||
await protectors[0].animate("comrade");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2921,7 +2962,9 @@ class Card {
|
||||
}
|
||||
this.abilities = (card_data.ability === "") ? [] : card_data.ability.split(" ");
|
||||
this.row = (this.faction === "weather") ? this.faction : card_data.row;
|
||||
this.targetRows = (this.faction === "weather") ? card_data.row : "";
|
||||
this.filename = card_data.filename;
|
||||
this.faceUp = true;
|
||||
this.placed = [];
|
||||
this.removed = [];
|
||||
this.activated = [];
|
||||
@ -3031,6 +3074,8 @@ class Card {
|
||||
this.desc += "<p><b>Hero:</b> " + ability_dict["hero"].description + "</p>";
|
||||
|
||||
this.elem = this.createCardElem(this);
|
||||
this.faceUpElem = this.elem;
|
||||
this.faceDownElem = null;
|
||||
}
|
||||
|
||||
// Returns the identifier for this type of card
|
||||
@ -3194,6 +3239,9 @@ class Card {
|
||||
num.classList.add("center");
|
||||
power.appendChild(num);
|
||||
row.style.backgroundImage = iconURL("card_row_" + card.row);
|
||||
} else if (card.faction === "weather" && card.targetRows.length > 0) {
|
||||
// Some weather cards can target different rows for a same weather type (such as White Frost)
|
||||
row.style.backgroundImage = iconURL("card_row_" + card.targetRows);
|
||||
}
|
||||
|
||||
let abi = document.createElement("div");
|
||||
@ -3233,6 +3281,36 @@ class Card {
|
||||
return elem;
|
||||
}
|
||||
|
||||
createCardBackElem() {
|
||||
let elem = document.createElement("div");
|
||||
elem.classList.add("card");
|
||||
let f = this.faction;
|
||||
if (f == "special") {
|
||||
f = this.holder.leader.faction;
|
||||
elem.classList.add("special");
|
||||
}
|
||||
elem.style.backgroundImage = iconURL("deck_back_" + f, "jpg");
|
||||
return elem;
|
||||
}
|
||||
|
||||
flip() {
|
||||
if (this.faceUp) {
|
||||
if (!this.faceDownElem) {
|
||||
this.faceDownElem = this.createCardBackElem();
|
||||
if (this.faceUpElem.style.left)
|
||||
this.faceDownElem.style.left = this.faceUpElem.style.left;
|
||||
}
|
||||
this.elem.replaceWith(this.faceDownElem);
|
||||
this.elem = this.faceDownElem;
|
||||
} else {
|
||||
this.elem.replaceWith(this.faceUpElem);
|
||||
this.elem = this.faceUpElem;
|
||||
if (this.faceDownElem.style.left)
|
||||
this.faceUpElem.style.left = this.faceDownElem.style.left;
|
||||
}
|
||||
this.faceUp = !this.faceUp;
|
||||
}
|
||||
|
||||
// Indicates whether or not the abilities of this card are locked
|
||||
isLocked() {
|
||||
return this.locked;
|
||||
@ -4124,6 +4202,7 @@ class Carousel {
|
||||
|
||||
if (!Carousel.elem) {
|
||||
Carousel.elem = document.getElementById("carousel");
|
||||
Carousel.submitBtn = document.getElementById("carousel_submit");
|
||||
Carousel.elem.children[0].addEventListener("click", () => Carousel.curr.cancel(), false);
|
||||
window.addEventListener("keydown", function (e) {
|
||||
if (e.keyCode == 81) {
|
||||
@ -4133,6 +4212,11 @@ class Carousel {
|
||||
} catch (err) { }
|
||||
}
|
||||
});
|
||||
Carousel.submitBtn.addEventListener("click", function (e) {
|
||||
Carousel.curr.selection.map(async s => await Carousel.curr.action(Carousel.curr.container, s));
|
||||
Carousel.curr.selection = [];
|
||||
Carousel.curr.exit();
|
||||
});
|
||||
}
|
||||
this.elem = Carousel.elem;
|
||||
document.getElementsByTagName("main")[0].classList.remove("noclick");
|
||||
@ -4140,7 +4224,9 @@ class Carousel {
|
||||
this.elem.children[0].classList.remove("noclick");
|
||||
this.previews = this.elem.getElementsByClassName("card-lg");
|
||||
this.desc = this.elem.getElementsByClassName("card-description")[0];
|
||||
this.title_elem = this.elem.children[2];
|
||||
this.title_elem = document.getElementById("carousel_label");
|
||||
this.submitBtn = Carousel.submitBtn;
|
||||
|
||||
}
|
||||
|
||||
// Initializes the current Carousel
|
||||
@ -4164,6 +4250,12 @@ class Carousel {
|
||||
this.title_elem.classList.add("hide");
|
||||
}
|
||||
|
||||
if (this.bExit) {
|
||||
this.submitBtn.classList.remove("hide");
|
||||
} else {
|
||||
this.submitBtn.classList.add("hide");
|
||||
}
|
||||
|
||||
this.elem.classList.remove("hide");
|
||||
ui.enablePlayer(true);
|
||||
tocar("explaining", false);
|
||||
@ -5511,6 +5603,9 @@ function getPreviewElem(elem, card, nb = 0) {
|
||||
num.classList.add("card-large-power-strength");
|
||||
power.appendChild(num);
|
||||
row.style.backgroundImage = iconURL("card_row_" + card.row);
|
||||
} else if (card.row === "weather" && card.targetRows.length > 0) {
|
||||
// For rare weather cards which can target different rows for a same wheather type (such as White Frost)
|
||||
row.style.backgroundImage = iconURL("card_row_" + card.targetRows);
|
||||
}
|
||||
|
||||
if (c_abilities.length > 0) {
|
||||
@ -5529,7 +5624,7 @@ function getPreviewElem(elem, card, nb = 0) {
|
||||
if (str === "shield_c" || str == "shield_r" || str === "shield_s")
|
||||
str = "shield";
|
||||
abi.style.backgroundImage = iconURL("card_ability_" + str);
|
||||
} else if (card.row.includes("agile")) {
|
||||
} else if (card.row.includes("agile") && !faction.startsWith("weather")) {
|
||||
abi.style.backgroundImage = iconURL("card_ability_" + "agile");
|
||||
}
|
||||
|
||||
@ -5634,12 +5729,12 @@ document.onkeydown = function (e) {
|
||||
|
||||
var elem_principal = document.documentElement;
|
||||
|
||||
function openFullscreen() {
|
||||
async function openFullscreen() {
|
||||
try {
|
||||
if (elem_principal.requestFullscreen) elem_principal.requestFullscreen();
|
||||
else if (elem_principal.webkitRequestFullscreen) elem_principal.webkitRequestFullscreen();
|
||||
else if (elem_principal.msRequestFullscreen) elem_principal.msRequestFullscreen();
|
||||
window.screen.orientation.lock("landscape");
|
||||
await window.screen.orientation.lock("landscape");
|
||||
} catch (err) { }
|
||||
}
|
||||
|
||||
|
||||
BIN
img/icons/card_ability_door.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
img/icons/card_ability_door_o.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
img/icons/card_ability_naglfar.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
img/icons/card_ability_sage.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
img/icons/card_ability_zirael.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
img/icons/card_special_door.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
img/icons/card_special_naglfar.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
img/icons/card_special_sage.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
img/icons/card_special_zirael.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
img/icons/deck_back_wild_hunt.jpg
Normal file
|
After Width: | Height: | Size: 490 KiB |
BIN
img/icons/deck_shield_wild_hunt.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
img/icons/faction-band-wild_hunt.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
img/icons/notif_wild_hunt.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
img/icons/power_door.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
img/icons/power_white_frost.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
img/sm/faction_wild_hunt.jpg
Normal file
|
After Width: | Height: | Size: 490 KiB |
BIN
img/sm/special_dimensional_door.jpg
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
img/sm/weather_white_frost.jpg
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
img/sm/wild_hunt_aen_elle_conqueror_1.jpg
Normal file
|
After Width: | Height: | Size: 275 KiB |
BIN
img/sm/wild_hunt_aen_elle_conqueror_2.jpg
Normal file
|
After Width: | Height: | Size: 321 KiB |
BIN
img/sm/wild_hunt_aen_elle_conqueror_3.jpg
Normal file
|
After Width: | Height: | Size: 318 KiB |
BIN
img/sm/wild_hunt_auberon_king.jpg
Normal file
|
After Width: | Height: | Size: 268 KiB |
BIN
img/sm/wild_hunt_avallach.jpg
Normal file
|
After Width: | Height: | Size: 254 KiB |
BIN
img/sm/wild_hunt_caranthir_navigator.jpg
Normal file
|
After Width: | Height: | Size: 270 KiB |
BIN
img/sm/wild_hunt_cirilla.jpg
Normal file
|
After Width: | Height: | Size: 292 KiB |
BIN
img/sm/wild_hunt_eredin_commander.jpg
Normal file
|
After Width: | Height: | Size: 337 KiB |
BIN
img/sm/wild_hunt_geels.jpg
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
img/sm/wild_hunt_geralt.jpg
Normal file
|
After Width: | Height: | Size: 387 KiB |
BIN
img/sm/wild_hunt_imlerith.jpg
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
img/sm/wild_hunt_imlerith_general.jpg
Normal file
|
After Width: | Height: | Size: 366 KiB |
BIN
img/sm/wild_hunt_naglfar.jpg
Normal file
|
After Width: | Height: | Size: 280 KiB |
BIN
img/sm/wild_hunt_naglfar_cartographer.jpg
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
img/sm/wild_hunt_naglfar_crew.jpg
Normal file
|
After Width: | Height: | Size: 290 KiB |
BIN
img/sm/wild_hunt_naglfar_taskmaster.jpg
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
img/sm/wild_hunt_navigator_1.jpg
Normal file
|
After Width: | Height: | Size: 291 KiB |
BIN
img/sm/wild_hunt_navigator_2.jpg
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
img/sm/wild_hunt_navigator_3.jpg
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
img/sm/wild_hunt_nithral.jpg
Normal file
|
After Width: | Height: | Size: 479 KiB |
BIN
img/sm/wild_hunt_wild_hunt_hound_1.jpg
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
img/sm/wild_hunt_wild_hunt_hound_2.jpg
Normal file
|
After Width: | Height: | Size: 350 KiB |
BIN
img/sm/wild_hunt_wild_hunt_rider_1.jpg
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
img/sm/wild_hunt_wild_hunt_rider_2.jpg
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
img/sm/wild_hunt_wild_hunt_rider_3.jpg
Normal file
|
After Width: | Height: | Size: 309 KiB |
BIN
img/sm/wild_hunt_wild_hunt_warrior_1.jpg
Normal file
|
After Width: | Height: | Size: 320 KiB |
BIN
img/sm/wild_hunt_wild_hunt_warrior_2.jpg
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
img/sm/wild_hunt_winter_queen.jpg
Normal file
|
After Width: | Height: | Size: 351 KiB |
BIN
img/sm/wild_hunt_yennefer_captive.jpg
Normal file
|
After Width: | Height: | Size: 158 KiB |
@ -164,6 +164,7 @@
|
||||
<p></p>
|
||||
</div>
|
||||
<div id = "carousel_label"></div>
|
||||
<div id = "carousel_submit">✓</div>
|
||||
</section>
|
||||
<section id="deck-sorter" class="hide">
|
||||
<div class="drop-container">
|
||||
|
||||
41
style.css
@ -547,6 +547,7 @@ html {
|
||||
top: 77%;
|
||||
}
|
||||
|
||||
/* Carousel Title */
|
||||
#carousel>:nth-child(3) {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
@ -559,9 +560,45 @@ html {
|
||||
box-shadow: 0 0 1vw #ffffff54;
|
||||
}
|
||||
|
||||
/* Modal helpers */
|
||||
/* Carousel Submit Button */
|
||||
#carousel > #carousel_submit {
|
||||
position: absolute;
|
||||
top: 13.5%;
|
||||
right: 5%;
|
||||
width: 5%;
|
||||
height: 5%;
|
||||
text-align: center;
|
||||
color: tan;
|
||||
font-weight: bold;
|
||||
font-size: 1.6vw;
|
||||
}
|
||||
|
||||
#helper-box {
|
||||
#carousel > #carousel_submit:hover {
|
||||
color: green;
|
||||
border: 1px green solid;
|
||||
border-radius: 5px;
|
||||
background-color: #86d986;
|
||||
}
|
||||
/*
|
||||
|
||||
#arrangementWindow-button {
|
||||
bottom: 35%;
|
||||
right: -88%;
|
||||
width: 5%;
|
||||
height: 5%;
|
||||
text-align: center;
|
||||
color: tan;
|
||||
font-weight: bold;
|
||||
font-size: 1.6vw;
|
||||
}
|
||||
|
||||
#arrangementWindow-button:hover {
|
||||
color: green;
|
||||
}
|
||||
*/
|
||||
/* Modal helpers */
|
||||
|
||||
#helper-box {
|
||||
position: absolute;
|
||||
top: 1vw;
|
||||
width: 100%;
|
||||
|
||||