Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- javascript: (function() {
- /*
- * Duelyst data export bookmarklet.
- *
- * Licenced under the wtfpl licence version 2.
- * http://www.wtfpl.net/txt/copying/
- *
- * This bookmarklet, when executed, opens a new page in your browser and
- * displays information regarding your duelyst account. This version displays:
- * - All squads you built (including a duelystdb link).
- * - An overview of the number of craftable cards in the game.
- * - An overview of of the number of craftable cards in your collection.
- * - A detailed overview of your collection of craftable cards.
- *
- * Planned features for to be added:
- * - Improve the card collection summary.
- *
- * The bookmarklet needs to be executed when logged in on your duelyst account.
- * First you need to install the bookmarklet [1], then you also need to allow
- * popus from the beta.duelyst.com domain [2].
- *
- * The bookmarklet has been tested with Duelyst 0.63.2.
- *
- *
- * [1]
- * https://crossbrowsertesting.com/faq/how-do-i-install-bookmarklet-google-chrome-mac-os
- * [2] https://support.google.com/chrome/answer/95472
- */
- /*
- * Contains the main code of the bookmarklet.
- */
- /*
- * Contains the global resources of the code.
- */
- /**
- * The number of factions (including neutral) in the game.
- *
- * There are also hidden factions, like the tutorial teachers. They are not
- * counted.
- */
- const faction_count = 7;
- /** The names of the factions in the game. */
- const faction_names = [
- "Lyonar",
- "Songhai",
- "Vetruvian",
- "Abyssian",
- "Magmar",
- "Vanar",
- "Neutral"
- ];
- /** The number of card rarities in the game. */
- const rarity_count = 4;
- /** The names of the card rarities. */
- const rarity_names = [ "Common", "Rare", "Epic", "Legendary" ];
- /** The cost to craft a card based on its rarity. */
- const spirit_craft_cost = [ 40, 100, 350, 900 ];
- /** The value of disenchanting a card based on its rarity. */
- const spirit_disenchant_value = [ 10, 20, 100, 350 ];
- /**
- * The maximum copies of a card in a deck.
- *
- * This value is not based on the rarity of the card.
- */
- const maximum_copies_per_deck = 3;
- /*
- * Contains the basic library functions.
- */
- /**
- * Returns the attributes object of a faction.
- *
- * @param id The ID of the faction.
- */
- var get_faction = function(id) {
- return GameDataManager.instance.factionsCollection._byId[id].attributes;
- };
- /**
- * Returns the attributes object of a card.
- *
- * @param id The ID of the card.
- */
- var get_card = function(id) {
- return GameDataManager.instance.cardsCollection._byId[id].attributes;
- };
- /**
- * `Sorts' a set of cards.
- *
- * This function creates an array with the sorted order of cards.
- * It expects a map with:
- * - Key The type does not matter.
- * - Value A card record containing at least:
- * * name The name of the card.
- * * mana The amount of mana the card costs.
- *
- * @param cards The set of cards to sort.
- *
- * @returns An sorted array with the keys of cards.
- */
- var sort_cards = function(cards) {
- var result = Object.keys(cards);
- result.sort(function(rhs, lhs) {
- var compare = cards[rhs].mana < cards[lhs].mana ||
- (cards[rhs].mana == cards[lhs].mana &&
- cards[rhs].name < cards[lhs].name);
- return compare ? -1 : 1;
- });
- return result;
- };
- /**
- * Escapes HTML special characters in a string.
- *
- * @param html The string to escape.
- *
- * @returns The escaped string.
- */
- var escape_html = function(html) {
- var replacement_table = {
- "&" : "&",
- "<" : "<",
- ">" : ">",
- '"' : '"',
- "'" : '''
- };
- return html.replace(/[&<>"']/g, function(c) {
- return replacement_table[c];
- });
- };
- /**
- * `Shows a set' of cards.
- *
- * The function creates HTML table for a set of cards.
- * It expects a map with:
- * - Key The type does not matter.
- * - Value A card record containing at least:
- * * name The name of the card.
- * * is_general Is the card the general?
- * * mana The amount of mana the card costs.
- * * count The number of copies of the card.
- *
- * @returns The HTML output.
- */
- var show_cards = function(cards, title) {
- var keys = sort_cards(cards);
- var result = title;
- result += "<table>";
- keys.forEach(function(i) {
- if (!cards[i].is_general) {
- result += "<tr><td>" + cards[i].mana + "</td><td>" +
- escape_html(cards[i].name) + "</td><td>" + cards[i].count +
- "</td></tr>";
- }
- });
- result += "<table>";
- return result;
- };
- /**
- * `Shows' a card matrix.
- *
- * The function creates a HTML table for a matrix of cards. The matrix will be
- * displayed in a table. The function adds the titles for the matrix.
- *
- * @param matrix The matrix to show. The matrix must be
- * compatible with the one created by
- * create_matrix.
- */
- var show_matrix = function(matrix) {
- var result = "<table>";
- result += "<tr><td></td>";
- for (var i = 0; i < rarity_count; ++i) {
- result += "<td>" + rarity_names[i] + "</td>";
- }
- result += "</tr>";
- for (var f = 0; f < faction_count; ++f) {
- result += "<tr>";
- result += "<td>" + faction_names[f] + "</td>";
- for (var r = 0; r < rarity_count; ++r) {
- result += "<td>" + matrix[f][r] + "</td>";
- }
- result += "</tr>";
- }
- result += "</table>";
- return result;
- };
- /**
- * Returns the number of usable copies of a card.
- *
- * @param count The number of copies of a card.
- *
- * @returns The usable number of copies of the card.
- */
- var get_usable_count = function(count) {
- return Math.min(count, 3);
- };
- /**
- * Returns the number of disenchantable copies of a card.
- *
- * @param count The number of copies of a card.
- *
- * @returns The disenchanteble number of copies of the
- * card.
- */
- var get_disenchant_count = function(count) {
- return Math.max(count - 3, 0);
- };
- /**
- * Returns the number of copies of the card the user misses.
- *
- * @param count The number of copies of a card.
- *
- * @returns The missing number of copies of the card.
- */
- function get_missing_count(count) {
- return Math.max(maximum_copies_per_deck - count, 0);
- }
- /*
- * Contains the basic card class.
- */
- /**
- * Contains the definition of a card.
- *
- * The class has the following member variables:
- * * id The ID of the card as used by Duelyst.
- * * name The in-game name of the card.
- * * mana The amount of mana the card costs.
- * * count The number of copies of the card. The meaning
- * of count depends on the context where the
- * card is used.
- * * is_general Is the card the general?
- * * faction_index The index of the faction as returned by
- * @ref get_card_faction_index
- * * rarity_index The index of the rarity as returned by
- * @ref get_card_rarity_index.
- */
- class tcard {
- /**
- * Constructor.
- *
- * @param card A Duelyst card record as returned by
- * @ref get_card.
- * @param count he number of copies of the card.
- */
- constructor(card, count) {
- this.id = card.id;
- this.name = card.name;
- this.mana = card.manaCost;
- this.count = count;
- this.is_general = card.isGeneral;
- this.faction_index = get_card_faction_index(card);
- this.rarity_index = get_card_rarity_index(card);
- }
- /** Returns a HTML table row for a deck list. */
- get deck_list_html() {
- return `<tr><td>${this.mana}</td>` + `<td>${escape_html(this.name)}</td>` +
- `<td>${this.count}</td></tr>`;
- }
- /** Returns a CSV table row for a deck list.*/
- get deck_list_csv() {
- return `${this.mana}\t${this.name}\t${this.count}\n`
- }
- /** Returns a Duelystdb card record for a deck list. */
- get deck_list_duelystdb() {
- return `${this.count}:${this.id}`
- }
- /** Returns the field names for a collection list. */
- static get_collection_list_field_names() {
- return [ "Mana", "Name", "Rarity", "Count" ];
- }
- /** Returns a HTML table row for a collection list. */
- get collection_list_html() {
- return `<tr><td>${this.mana}</td>` + `<td>${escape_html(this.name)}</td>` +
- `<td>${rarity_names[this.rarity_index]}</td>` +
- `<td>${this.count}</td></tr>`;
- }
- /** Returns the field names for a detailed collection list. */
- static get_collection_detailed_list_field_names() {
- return [ "ID", "Name", "Mana", "Rarity", "Faction", "Count" ];
- }
- /** Returns a CSV table row for a detailed collection list.*/
- get collection_detailed_list_csv() {
- return `${this.id}\t` + `${this.name}\t` + `${this.mana}\t` +
- `${rarity_names[this.rarity_index]}\t` +
- `${faction_names[this.faction_index]}\t` + `${this.count}\n`;
- }
- }
- /*
- * Contains the deck export code.
- */
- /**
- * Contains the definition of a deck.
- *
- * The class has the following member variables:
- * * id The ID of the deck as used by Duelyst.
- * * name The in-game name of the deck.
- * * faction The in-game name of the faction.
- * * title The title of the deck.
- * * cards A map with cards in the deck
- * - Key The ID of the card.
- * - Value A @ref tcard object.
- */
- class tdeck {
- /**
- * Constructor
- *
- * @param deck A Duelyst deck record.
- */
- constructor(deck) {
- this.id = deck.id;
- this.name = deck.name;
- this.faction = get_faction(deck.faction_id).name;
- this.title = `${this.name} (${this.faction})`;
- this.cards = this.load_cards_(deck);
- }
- /** Returns the TOC section of the deck. */
- get toc() {
- const link = `<a href="#deck_${this.id}">${escape_html(this.title)}</a>`;
- const result = `<li>${link} [${this.download_}] [${this.duelystdb_}]</li>`;
- return result;
- }
- /** Returns the body section of the deck. */
- get body() {
- let result = `<h2 id="deck_${this.id}">${escape_html(this.title)}</h2>`;
- result += html_;
- return result;
- }
- /**
- * Loads the cards in the deck.
- *
- * @param deck A Duelyst deck record.
- *
- * @returns The loaded cards.
- */
- load_cards_(deck) {
- let cards = {};
- deck.cards.forEach(function(card) {
- if (!cards[card.id]) {
- cards[card.id] = 1;
- } else {
- ++cards[card.id];
- }
- });
- let result = {};
- for (let i in cards) {
- result[i] = new tcard(get_card(i), cards[i]);
- };
- return result;
- }
- /**
- * Creates a download link for the deck.
- *
- * The download link contains a link to a CSV file. The file is stored in the
- * HTML link. This makes it easy to download a deck.
- */
- get download_() {
- const filename = `${this.name}.csv`;
- let data = `${this.title}\n`;
- sort_cards(this.cards).forEach(function(i) {
- if (!this.cards[i].is_general) {
- data += this.cards[i].deck_list_csv;
- }
- }, this);
- const result = `<a download="${filename}" ` +
- `href="data:application/octet-stream;base64,${btoa(data)}"` +
- `>download</a>`;
- return result;
- }
- /**
- * Creates a link for the squad on the duelystdb site.
- *
- * The link contains a path and a parameter string. Some testing revealed the
- * following properties of the string:
- * - The parameter string is encoded as Base64 string.
- * - The string contains a list of card pairs separated by a comma.
- * - Every pair has two field separated by a colon:
- * - The number of copies of the card.
- * - The ID of the card as used in the game.
- * - The list of pairs must be sorted by the card ID.
- *
- * @param cards A map of cards containg at least:
- * - Key The ID of the card.
- * - Value The card record containing:
- * * count The number of copies in the
- * deck.
- */
- get duelystdb_() {
- let data = "";
- Object.keys(this.cards).sort().forEach(function(i) {
- if (data != "") {
- data += ",";
- }
- data += this.cards[i].deck_list_duelystdb;
- }, this);
- const result = `<a href="http://duelystdb.com/squad/build#${btoa(data)}"` +
- ` target="_blank">duelystdb</a>`;
- return result;
- }
- /** Creates the HTML table for the deck. */
- get html_() {
- let result = "<table>";
- sort_cards(this.cards).forEach(function(i) {
- if (!this.cards[i].is_general) {
- result += this.cards[i].deck_list_html;
- }
- }, this);
- result += "<table>";
- return result;
- }
- }
- /**
- * Contains the collection of all user created decks.
- *
- * The class has the following member variables:
- * * decks An array with @ref tdeck objects.
- */
- class tdeck_collection {
- /** Constructor. */
- constructor() {
- this.decks = this.load_decks_();
- }
- /** Returns the TOC section of the deck collection. */
- get toc() {
- let result = `<li><a href="#decks">Squads</a></li><ul>`;
- this.decks.forEach(function(deck) {
- result += deck.toc;
- });
- result += "</ul>";
- return result;
- }
- /** Returns the body section of the deck collection. */
- get body() {
- let result = `<h1 id="decks">Squads</h1>`;
- this.decks.forEach(function(deck) {
- result += `<h2 id="deck_${deck.id}">${escape_html(deck.title)}</h2>`;
- result += deck.html_;
- });
- return result;
- }
- /** Returns the decks created by the user. */
- load_decks_() {
- let result = [];
- InventoryManager.instance.decksCollection.models.forEach(function(model) {
- result.push(new tdeck(model.attributes));
- });
- return result;
- }
- }
- /*
- * Contains the CSV specific functions.
- */
- /*
- * Contains the code to create a duelystdb link.
- */
- /*
- * Contains the functions regarding the user's card collection and the cards
- * available in the game.
- */
- /**
- * Is the card available for crafting?
- *
- * The function's implementation has been determined experimentally:
- * - rarityIsCraftable Only seems to list cards which can be crafted.
- * - factionId Determines the faction
- * * IDs [1, 6] are the in game factions.
- * * ID 100 are the neutrals.
- * * ID 200 are the tutorial teachers.
- * - isAvailable Determines whether the card is available for usage. For
- * example the monthly rewards are in the card database
- * before they can be used, when the new month starts this
- * flag is updated.
- *
- * @param card A card as returned by get_card.
- *
- * @returns True of craftable, false otherwise.
- */
- var is_card_craftable = function(card) {
- return card.rarityIsCraftable && card.factionId != 200 && card.isAvailable;
- };
- /**
- * Returns the faction index of a card.
- *
- * The returned index can be used as index in an array.
- *
- * The game's faction index is explained in is_card_craftable.
- *
- * @pre The faction is collectable, so one of the in
- * game factions or a neutral card.
- *
- * @param card A card as returned by get_card.
- *
- * @returns A zero-based index.
- */
- var get_card_faction_index = function(card) {
- /*
- * The min function is used to map neutrals after the normal factions.
- */
- return Math.min(card.factionId, faction_count) - 1;
- };
- /**
- * Returns the rarity index of a card.
- *
- * The returned index can be used as index in an array.
- *
- * @param card A card as returned by get_card.
- *
- * @returns A zero-based index.
- */
- var get_card_rarity_index = function(card) {
- return card.rarityId - 1
- };
- /**
- * Loads all craftable cards in the game.
- *
- * @returns An array with card record. The array is not
- * sorted. The record has the following fields:
- * - id The ID of the card as used
- * by Duelyst.
- * - count The number of copies of the
- * card. In order to be
- * compatible with other card
- * records a count is required.
- * The number is always 1.
- * - name The game of the card.
- * - mana The amount of mana the card
- * costs.
- * - faction_index The index of the faction as
- * returned by
- * get_card_faction_index
- * - rarity_index The index of the rarity as
- * returned by
- * get_card_rarity_index
- */
- var load_card_database = function() {
- var result = [];
- GameDataManager.instance.cardsCollection.models.forEach(function(model) {
- var card = model.attributes;
- if (!is_card_craftable(card)) {
- return;
- }
- var record = {};
- record.id = card.id;
- record.count = 1;
- record.name = card.name;
- record.mana = card.manaCost;
- record.faction_index = get_card_faction_index(card);
- record.rarity_index = get_card_rarity_index(card);
- result.push(record);
- });
- return result;
- };
- /**
- * Loads all cards collected by the player.
- *
- * @returns An array with card record. The array is not
- * sorted. The record is the same as returned by
- * load_card_database, except for the count
- * field. The count field contains the number of
- * copies the player owns. (The number of items
- * in this array is less than or equal to the
- * number of items in the array returned by
- * load_card_database.)
- */
- var load_collection = function() {
- var result = [];
- InventoryManager.instance.cardsCollection.models.forEach(function(model) {
- var card = get_card(model.id);
- if (!card.rarityIsCraftable) {
- return;
- }
- var record = {};
- record.id = model.id;
- record.count = model.attributes.count;
- record.name = card.name;
- record.mana = card.manaCost;
- record.faction_index = get_card_faction_index(card);
- record.rarity_index = get_card_rarity_index(card);
- result.push(record);
- });
- return result;
- };
- /**
- * Create an empty matrix.
- *
- * It creates a 2-dimensional matrix faction_count x rarity_count initialised
- * with 0.
- */
- var create_matrix = function() {
- var result = new Array(7);
- for (var i = 0; i < 7; ++i) {
- result[i] = new Array(4);
- for (var j = 0; j < 4; ++j) {
- result[i][j] = 0;
- }
- }
- return result;
- };
- /**
- * Validates whether a faction and rarity index are valid.
- *
- * @param faction_index The faction index to validate.
- * @param rarity_index The rarity index to validate.
- *
- * @returns Whether the indices are valid.
- */
- var validate_index = function(faction_index, rarity_index) {
- if (faction_index < 0) {
- console.error("Faction index »" + faction_index + "« underflow.");
- return false;
- }
- if (faction_index >= faction_count) {
- console.error("Faction index »" + faction_index + "« overflow.");
- return false;
- }
- if (rarity_index < 0) {
- console.error("Rarity index »" + rarity_index + "« underflow.");
- return false;
- }
- if (rarity_index >= rarity_count) {
- console.error("Rarity index »" + rarity_index + "« overflow.");
- return false;
- }
- return true;
- };
- /**
- * Builds a matrix with the number of collected usable cards.
- *
- * @param collection A card collection as generated by
- * load_collection.
- *
- * @returns A matrix as generated by create_matrix, but
- * filled with the proper values.
- */
- var build_collected_matrix = function(collection) {
- var result = create_matrix();
- collection.forEach(function(card) {
- if (!validate_index(card.faction_index, card.rarity_index)) {
- return;
- }
- result[card.faction_index][card.rarity_index] +=
- get_usable_count(card.count);
- });
- return result;
- };
- /**
- * Builds a matrix with the number of collected unusable cards.
- *
- * @param collection A card collection as generated by
- * load_collection.
- *
- * @returns A matrix as generated by create_matrix, but
- * filled with the proper values.
- */
- var build_disenchant_matrix = function(collection) {
- var result = create_matrix();
- collection.forEach(function(card) {
- if (!validate_index(card.faction_index, card.rarity_index)) {
- return;
- }
- result[card.faction_index][card.rarity_index] +=
- get_disenchant_count(card.count);
- });
- return result;
- };
- /**
- * `Shows' the body section for the game's card database.
- *
- * @returns The string containing the body section.
- */
- var show_card_database = function() {
- var result = "<h2 id=\"cp_database\">Card database</h2>";
- result +=
- "<p>The table below shows the number of craftable cards in the game. " +
- "In order to determine the number of cards required for a full " +
- " collection these numbers need to be multiplied by the maximum " +
- "number of copies in a squad (" + maximum_copies_per_deck + ").</p>";
- result += show_matrix(build_collected_matrix(load_card_database()));
- return result;
- };
- /**
- * `Shows' the body section for the user's useful card collection.
- *
- * @returns The string containing the body section.
- */
- var show_collected_database = function(collection) {
- var result = "<h2 id=\"cp_collected\">Card collection</h2>";
- result += "<p>The table below shows the number of usable cards collected. " +
- " The definition of usable here is : "A maximum of " +
- maximum_copies_per_deck +
- " copies of a card". Whether the card is playable is " +
- "in the eye of the beholder.</p>";
- result += show_matrix(build_collected_matrix(collection));
- result +=
- "<p>In order to determine the spirit value of your collection, the " +
- "number of cards need to be multiplied by their crafting cost as " +
- "shown in the table below.</p>";
- result += "<table>";
- result += "<tr><td>Rarity</td><td>Craft cost</td></tr>";
- for (var i = 0; i < rarity_count; ++i) {
- result += "<tr>";
- result += "<td>" + rarity_names[i] + "</td>";
- result += "<td>" + spirit_craft_cost[i] + "</td>";
- result += "</tr>";
- }
- result += "</table>";
- return result;
- };
- /**
- * `Shows' the body section for the user's useless card collection.
- *
- * @returns The string containing the body section.
- */
- var show_disenchantable_database = function(collection) {
- var result = "<h2 id=\"cp_disenchantable\">Disenchant collection</h2>";
- result +=
- "<p>The table below shows the number of useless cards collected. " +
- "The definition of useless here is: "Every card you have more " +
- "than " + maximum_copies_per_deck + " copies of".</p>";
- result += show_matrix(build_disenchant_matrix(collection));
- result +=
- "<p>In order to determine the amount of spirit that can be gained by " +
- "disenchanting, the number of cards need to be multiplied by their " +
- "disenchant value as shown in the table below.</p>";
- result += "<table>";
- result += "<tr><td>Rarity</td><td>Disenchant value</td></tr>";
- for (var i = 0; i < rarity_count; ++i) {
- result += "<tr>";
- result += "<td>" + rarity_names[i] + "</td>";
- result += "<td>" + spirit_disenchant_value[i] + "</td>";
- result += "</tr>";
- }
- result += "</table>";
- return result;
- };
- /**
- * `Shows' the card collection progress.
- *
- * It creates the header and body sections for the following data sets:
- * - The game's card database.
- * - The user's useful card collection.
- * - The user's useless card collection.
- *
- * @returns A tuple containing:
- * # The TOC part of the data.
- * # The body part of the data.
- */
- var show_collection_progress = function() {
- var header = "<li><a href=\"#cp\">Collection progress</a></li><ul>";
- header += "<li><a href=\"#cp_database\">Card database</a></li>";
- header += "<li><a href=\"#cp_collected\">Card collection</a></li>";
- header += "<li><a href=\"#cp_disenchantable\">Disenchant collection</a></li>";
- header += "</ul>";
- var body = "<h1 id=\"cp\">Collection progress</h1>";
- body += "This sections show the progress of your collection, the number " +
- "of cards collected and the number that can savely be disenchanted.";
- body += show_card_database();
- var collection = load_collection();
- body += show_collected_database(collection);
- body += show_disenchantable_database(collection);
- var result = [ header, body ];
- return result;
- };
- /**
- * Create an empty card list.
- *
- * @returns A card list. This is a matrix of @ref
- * faction_count elements, initialised with
- * empty arrays.
- */
- function create_card_list() {
- let result = [];
- for (let i = 0; i < faction_count; ++i) {
- result.push([]);
- }
- return result;
- }
- /**
- * Helper class to generate output for collection views.
- *
- * @note initially had helper functions but they had issues with calling the
- * static @ref tcard member @ref get_collection_list_field_names. Also a helper
- * class with static member functions didn't work. So now have a circular
- * class, where the view holds the output generator and the output generator
- * holds the collection view. (Not really happy with the design, but it works.)
- *
- * The class holds the following member variables:
- * * collection The collection view we generate the output
- * for.
- *
- */
- class tcollection_output_generator {
- /**
- * Constructor
- *
- * @param collection The collection view we generate the output
- * for. It requires the object to have the
- * following members:
- * * anchor A HTML anchor name for the
- * section. For the faction based
- * anchors it uses this as a
- * basename.
- * * title The title of the collection view.
- * * filename The filename of the CSV files.
- * * cards The cards in the view.
- */
- constructor(collection) {
- this.collection = collection;
- }
- /** Returns the TOC section for the collection detail section. */
- get details_toc() {
- let result = `<li><a href="#${this.collection.anchor}">` +
- `${this.collection.title}</a> ` +
- `[${this.details_download_}]</li><ul>`;
- for (let i = 0; i < faction_count; ++i) {
- result += `<li><a href="#${this.collection.anchor}_${i}">` +
- `${faction_names[i]}</a></li>`;
- }
- result += "</ul>";
- return result;
- }
- /** Returns the body section for the collection detail section. */
- get details_body() {
- let result =
- `<h2 id="${this.collection.anchor}">${this.collection.title}</h2>`;
- for (let f = 0; f < faction_count; ++f) {
- result +=
- `<h3 id="${this.collection.anchor}_${f}">${faction_names[f]}</h3>`;
- if (this.collection.cards[f].length == 0) {
- result += "There are no cards available in this section.";
- continue;
- }
- result += "<table><tr>";
- tcard.get_collection_list_field_names().forEach(function(name) {
- result += `<td>${name}</td>`;
- });
- result += "</tr>";
- sort_cards(this.collection.cards[f]).forEach(function(c) {
- result += `\n${this.collection.cards[f][c].collection_list_html}`;
- }, this);
- result += "</table>";
- }
- return result;
- }
- /** Returns the download links for the collection detail section. */
- get details_download_() {
- let data = "";
- tcard.get_collection_detailed_list_field_names().forEach(function(name) {
- if (data != "") {
- data += "\t";
- }
- data += name;
- });
- data += "\n";
- for (let f = 0; f < faction_count; ++f) {
- this.collection.cards[f].forEach(function(card) {
- data += card.collection_detailed_list_csv;
- });
- }
- const result = `<a download="${this.collection.filename}" ` +
- `href="data:application/octet-stream;base64,${btoa(data)}"` +
- `>download</a>`;
- return result;
- }
- }
- /**
- * Class containing a list with all cards available in the game.
- *
- * The class is a data collector for a @ref tcollection_output_generator. It
- * has all member required for this class and an additional member, the output
- * generator object.
- */
- class tcards_available {
- constructor() {
- this.anchor = "cd_available";
- this.title = "Available";
- this.filename = "cards_available.csv";
- this.cards = this.load_cards_();
- this.output_generator = new tcollection_output_generator(this);
- }
- /** Forwarded to @ref tcollection_output_generator.details_toc. */
- get details_toc() {
- return this.output_generator.details_toc;
- }
- /** Forwarded to @ref tcollection_output_generator.details_body. */
- get details_body() {
- return this.output_generator.details_body;
- }
- /** Loads the cards. */
- load_cards_() {
- let result = create_card_list();
- GameDataManager.instance.cardsCollection.models.forEach(function(model) {
- let card = model.attributes;
- if (!is_card_craftable(card)) {
- return;
- }
- card = new tcard(card, 1);
- result[card.faction_index].push(card);
- });
- return result;
- }
- }
- /**
- * Class containing a list with all cards collected by the user.
- *
- * The class is a data collector for a @ref tcollection_output_generator. It
- * has all member required for this class and an additional member, the output
- * generator object.
- */
- class tcards_collected {
- constructor() {
- this.anchor = "cd_collected";
- this.title = "Collected";
- this.filename = "cards_collected.csv";
- this.cards = this.load_cards_();
- this.output_generator = new tcollection_output_generator(this);
- }
- /** Forwarded to @ref tcollection_output_generator.details_toc. */
- get details_toc() {
- return this.output_generator.details_toc;
- }
- /** Forwarded to @ref tcollection_output_generator.details_body. */
- get details_body() {
- return this.output_generator.details_body;
- }
- /** Loads the cards. */
- load_cards_() {
- let result = create_card_list();
- InventoryManager.instance.cardsCollection.models.forEach(function(model) {
- let card = get_card(model.id);
- if (!card.rarityIsCraftable) {
- return;
- }
- card = new tcard(card, model.attributes.count);
- result[card.faction_index].push(card);
- });
- return result;
- }
- }
- /**
- * Class containing a list with all useful cards collected by the user.
- *
- * This class is a view of the collected cards by the user.
- *
- * The class is a data collector for a @ref tcollection_output_generator. It
- * has all member required for this class and an additional member, the output
- * generator object.
- */
- class tcards_useful {
- /**
- * Constructor
- *
- * @param cards The cards member of a @ref tcards_collected
- * object containing all cards collected by the
- * user.
- */
- constructor(cards) {
- this.anchor = "cd_useful";
- this.title = "Useful";
- this.filename = "cards_useful.csv";
- this.cards = this.load_cards_(cards);
- this.output_generator = new tcollection_output_generator(this);
- }
- /** Forwarded to @ref tcollection_output_generator.details_toc. */
- get details_toc() {
- return this.output_generator.details_toc;
- }
- /** Forwarded to @ref tcollection_output_generator.details_body. */
- get details_body() {
- return this.output_generator.details_body;
- }
- /**
- * Creates a view of the collected cards.
- *
- * @param cards The cards member of a @ref tcards_collected
- * object containing all cards collected by the
- * user.
- */
- load_cards_(cards) {
- let result = create_card_list();
- for (let f = 0; f < faction_count; ++f) {
- for (let c in cards[f]) {
- let card = Object.create(cards[f][c]);
- card.count = get_usable_count(card.count);
- result[f].push(card);
- }
- }
- return result;
- }
- }
- /**
- * Class containing a list with all useless cards collected by the user.
- *
- * This class is a view of the collected cards by the user.
- *
- * The class is a data collector for a @ref tcollection_output_generator. It
- * has all member required for this class and an additional member, the output
- * generator object.
- */
- class tcards_useless {
- /**
- * Constructor
- *
- * @param cards The cards member of a @ref tcards_collected
- * object containing all cards collected by the
- * user.
- */
- constructor(cards) {
- this.anchor = "cd_useless";
- this.title = "Useless";
- this.filename = "cards_useless.csv";
- this.cards = this.load_cards_(cards);
- this.output_generator = new tcollection_output_generator(this);
- }
- /** Forwarded to @ref tcollection_output_generator.details_toc. */
- get details_toc() {
- return this.output_generator.details_toc;
- }
- /** Forwarded to @ref tcollection_output_generator.details_body. */
- get details_body() {
- return this.output_generator.details_body;
- }
- /**
- * Creates a view of the collected cards.
- *
- * @param cards The cards member of a @ref tcards_collected
- * object containing all cards collected by the
- * user.
- */
- load_cards_(cards) {
- let result = create_card_list();
- for (let f = 0; f < faction_count; ++f) {
- for (let c in cards[f]) {
- const count = get_disenchant_count(cards[f][c].count);
- if (count > 0) {
- let card = Object.create(cards[f][c]);
- card.count = count;
- result[f].push(card);
- }
- }
- }
- return result;
- }
- }
- /**
- * Class containing a list with all cards the user misses for a full collection.
- *
- * This class is a view of the collected cards by the user.
- *
- * The class is a data collector for a @ref tcollection_output_generator. It
- * has all member required for this class and an additional member, the output
- * generator object.
- */
- class tcards_missing {
- /**
- * Constructor
- *
- * @param available A cards member of a @ref tcards_available
- * object containing all cards available in the
- * game.
- * @param collected The cards member of a @ref tcards_collected
- * object containing all cards collected by the
- * user.
- */
- constructor(available, collected) {
- this.anchor = "cd_missing";
- this.title = "Missing";
- this.filename = "cards_missing.csv";
- this.cards = this.load_cards_(available, collected);
- this.output_generator = new tcollection_output_generator(this);
- }
- /** Forwarded to @ref tcollection_output_generator.details_toc. */
- get details_toc() {
- return this.output_generator.details_toc;
- }
- /** Forwarded to @ref tcollection_output_generator.details_body. */
- get details_body() {
- return this.output_generator.details_body;
- }
- /**
- * Creates a view of the collected cards.
- *
- * @param available A cards member of a @ref tcards_available
- * object containing all cards available in the
- * game.
- * @param collected The cards member of a @ref tcards_collected
- * object containing all cards collected by the
- * user.
- */
- load_cards_(available, collected) {
- let result = create_card_list();
- for (let f = 0; f < faction_count; ++f) {
- for (let c in available[f]) {
- /*
- * Find the card in our collection, so we can determine how many copies
- * we are missing. (It is possible we have 0 copies of the card and
- * will not be found in our collection.)
- */
- const index = collected[f]
- .map(function(card) {
- return card.id;
- })
- .indexOf(available[f][c].id);
- const count = index == -1
- ? maximum_copies_per_deck
- : get_missing_count(collected[f][index].count);
- if (count != 0) {
- let card = Object.create(available[f][c]);
- card.count = count;
- result[f].push(card);
- }
- }
- }
- return result;
- }
- }
- /**
- * Contains the collection of in-game and user owned cards.
- *
- * The class holds two main variables containing the set of in-game craftable
- * cards and the set of cards owned by the user. Next to these variables it
- * contains views of the collection: the useful and useless cards. The
- * usefulness is determined whether a card can be put in a deck, not whether
- * it
- * is a good idea to include a card in your deck.
- *
- * @note The class is still work-in-progress and future versions of the class
- * will hold and generate more information.
- *
- * The class has the following member variables:
- * * available A @ref tcards_available object with the cards
- * available in the game. The count of the cards
- * is always 1.
- * * collected A @ref tcards_collected object with all cards
- * collected by the user. The count of the cards
- * is the number in the user's collection.
- * * useful A @ref tcards_useful object with all useful
- * cards collected by the user. The count of the
- * cards <= 3.
- * * useless A @ref tcards_useless object with all useless
- * cards collected by the user. The count of
- * cards > 0. If the user had collected less
- * than 4 copies of a card it is not in this
- * object.
- */
- class tcard_collection {
- constructor() {
- this.available = new tcards_available();
- this.collected = new tcards_collected();
- this.useful = new tcards_useful(this.collected.cards);
- this.useless = new tcards_useless(this.collected.cards);
- this.missing =
- new tcards_missing(this.available.cards, this.collected.cards);
- }
- get toc() {
- let result = "";
- result += `<li><a href="#cd">Collection details</a></li><ul>`;
- result += this.available.details_toc;
- result += this.collected.details_toc;
- result += this.useful.details_toc;
- result += this.useless.details_toc;
- result += this.missing.details_toc;
- result += "</ul>";
- return result;
- }
- get body() {
- let result = "";
- result += `<h1 id="cd">Collection details</h1>`;
- result += this.available.details_body;
- result += this.collected.details_body;
- result += this.useful.details_body;
- result += this.useless.details_body;
- result += this.missing.details_body;
- return result;
- }
- }
- var main = function() {
- var collection_progress = show_collection_progress();
- const deck_collection = new tdeck_collection();
- const card_collection = new tcard_collection();
- var page = "data:text/html;charset=utf-8,<html>";
- page += "<head><title>Duelyst export</title></head><body>";
- /*** TOC ***/
- page += "<h1>Table of contents</h1><ul>";
- page += deck_collection.toc;
- page += collection_progress[0];
- page += card_collection.toc;
- /*** Data ***/
- page += "<h1 id=\"decks\">Squads</h1><ul>";
- page += "</ul>";
- page += deck_collection.body;
- page += collection_progress[1];
- page += card_collection.body;
- page += "</body></html>";
- window.open(page);
- };
- main();
- })();
- /*
- * Changelog:
- * 0.4.0
- * - Fixed a bug in the crafting cost table.
- * - Added a CSV file download link for decks.
- * - Changed refactored code.
- * - Added details of your card collection and available cards.
- *
- * 2016.03.09 0.3.0
- * - Added experimental support for duelystdb links.
- *
- * 2016.03.09 0.2.0
- * - Added the collection progress part.
- *
- * 2016.03.05 0.1.0 - Initial release.
- */
Add Comment
Please, Sign In to add comment