// ==UserScript== // @author Audrey // @description Helper script for Fallenlondon // @downloadURL https://forge.chapril.org/audrey/fallen_london_scripts/raw/branch/master/FL_enhancer.user.js // @grant none // @icon https://images.fallenlondon.com/favicons/favicon.ico // @match https://www.fallenlondon.com/* // @name FallenLondon Enhancer // @namespace https://forge.chapril.org/audrey/ // @require https://forge.chapril.org/audrey/fallen_london_scripts/raw/branch/master/jquery/jquery-3.6.0.min.js // @version 0.1-rc3 // ==/UserScript== "use strict"; $(document).ready(fl_enhancer); //////////// // BAZAAR // //////////// let items_total_value_displayed = false; function display_items_total_value() { // If anyone spams the "bazaar" link if (items_total_value_displayed) { return; } // Only computing the sum if all items are displayed let shop = document.getElementsByClassName('menu-item--active'); if ( shop.length && shop[0].textContent != "Sell my things") { return; } let total_price = 0; for (let item of window.document.getElementsByClassName('shop__item')) { let num_object = item.getElementsByClassName('js-item-value'); let price_object = item.getElementsByClassName('item__price'); if (price_object.length && num_object.length) { let num = num_object[0].textContent; let price = price_object[0].textContent; total_price += ( num * price); } } $('.input--item-search').after('
  • Total value:
    ' + total_price + '
  • '); items_total_value_displayed = true; } function update_third_tier_counts() { const t3_qualities = { '0' : { id: '525', src: '//images.fallenlondon.com/icons/bookpurplesmall.png' }, // Journal of Infamy '1' : { id: '932', src: '//images.fallenlondon.com/icons/scrawl1small.png' }, // Correspondence Plaque '2' : { id: '827', src: '//images.fallenlondon.com/icons/sunsetsmall.png' }, // Vision of the Surface '3' : { id: '587', src: '//images.fallenlondon.com/icons/mountainglowsmall.png' }, // Mystery of the Elder Continent '4' : { id: '659', src: '//images.fallenlondon.com/icons/conversationsmall.png' }, // Scrap of Incendiary Gossip '5' : { id: '825', src: '//images.fallenlondon.com/icons/wakesmall.png' }, // Memory of Distant Shores '6' : { id: '668', src: '//images.fallenlondon.com/icons/bottledsoulbluesmall.png' }, // Brilliant Soul '7' : { id: '828', src: '//images.fallenlondon.com/icons/scaryeyesmall.png' }, // A Tale of Terror!! '8' : { id: '830', src: '//images.fallenlondon.com/icons/papers3small.png' }, // Compromising Document '9' : { id: '589', src: '//images.fallenlondon.com/icons/mirrorsmall.png' }, // Memory of Light 'A' : { id: '831', src: '//images.fallenlondon.com/icons/waves3small.png' }, // Zee-Ztory 'B' : { id: '822', src: '//images.fallenlondon.com/icons/bottlewillowsmall.png' }, // Bottle of Stranngling Willow Absinthe 'C' : { id: '915', src: '//images.fallenlondon.com/icons/scrap2small.png' }, // Whisper-Satin Scrap }; $('div#FLE-ccc').remove(); let html = '
    '; $.each(t3_qualities, function(order, quality) { let quality_id = quality.id; let image_src = quality.src; let elem = $('div [data-quality-id="' + quality_id + '"]'); let quantity = elem.length == 1 ? elem.find('.js-item-value').html() : 0; html += '
    ' + quantity + '
    '; }); $(html + '
    ').insertAfter('div#FLE-quirks'); } //////////// // MYSELF // //////////// function update_quirks_bar() { if (!localStorage.FLE_quirks) { return; } let quirks = JSON.parse(localStorage.FLE_quirks); let html = '
    '; $.each(quirks, function( key, value ) { html += '
    ' + value.num + '
    '; }); $('div#FLE-quirks').remove(); $(html + '
    ').insertAfter('button.travel-button--infobar'); } function update_contacts_bar() { if (!localStorage.FLE_contacts) { return; } let icon_value_color = { '0': '', '1': '', '2': '', '3': '', '4': '', '5': 'background-color: rgb(180, 140, 0);', '6': 'background-color: rgb(190, 110, 23);', '7': 'background-color: rgb(183, 70, 5);', }; let contacts = JSON.parse(localStorage.FLE_contacts); let html = '
    '; let z_index = 0; $.each(contacts, function( key, value ) { html += '
    ' + value.Renown + '+' + value.Favours + '
    '; }); $('div#FLE-contacts').remove(); $(html + '
    ').insertAfter('button.travel-button--infobar'); } function get_quirks() { let quirks = {} $("[data-group-name=Quirks] li.quality-item").each( function( index, element ){ let found = $( this ).find('span').prop('textContent').match(/(\w+)\s+(\d+)/); if (found){ let [_, quirk, num] = found; quirks[quirk] = {'num': num, img: $( this).find('img').prop('src')}; } }); localStorage.setItem('FLE_quirks', JSON.stringify(quirks)); update_quirks_bar(); } function get_contacts() { let contacts = {} $("[data-group-name=Contacts] li.quality-item").each( function( index, element ){ let found = $( this ).find('span').prop('textContent').match(/(:?Favours|Renown): (.*) (\d+)\/\d+/); if (found) { let [_, type, faction, num] = found; if (!contacts[faction]) { contacts[faction] = {'Renown': 0, 'Favours': 0, img: $( this).find('img').prop('src')}; } contacts[faction][type] = num; } }); localStorage.setItem('FLE_contacts', JSON.stringify(contacts)); } function myself() { get_quirks(); update_quirks_bar(); get_contacts(); update_contacts_bar(); } ///////////////// // POSSESSIONS // ///////////////// function update_advantage_bar() { if (!localStorage.FLE_advantage) { return; } let advantage = JSON.parse(localStorage.FLE_advantage); let html = '
    '; $.each(advantage, function( key, value ) { html += '
    ' + value + '
    '; }); $('div#FLE-advantage').remove(); $(html + '
    ').insertAfter('button.travel-button--infobar'); } function get_advantage() { let advantage = {}; $("[data-group-name=Advantage] li.item img").each( function( index, element ){ let found = $( this ).prop('alt').match(/× (\d+);/); if (found) { advantage[$( this ).prop('src')] = found[1]; } }); localStorage.setItem('FLE_advantage', JSON.stringify(advantage)); } function possessions() { get_advantage(); update_advantage_bar(); update_quirks_bar(); update_contacts_bar(); update_third_tier_counts(); } function monitor_url_change() { // https://dirask.com/posts/JavaScript-on-location-changed-event-on-url-changed-event-DKeyZj // If the url is updated ... ;(function() { let pushState = history.pushState; let replaceState = history.replaceState; history.pushState = function() { pushState.apply(history, arguments); window.dispatchEvent(new Event('pushstate')); window.dispatchEvent(new Event('locationchange')); }; history.replaceState = function() { replaceState.apply(history, arguments); window.dispatchEvent(new Event('replacestate')); window.dispatchEvent(new Event('locationchange')); }; window.addEventListener('popstate', function() { window.dispatchEvent(new Event('locationchange')); }); })(); } //////////// // GLOBAL // //////////// function cleanup() { // Remove the banner $('div.banner').remove(); // Remove the candles $('div.candle-container').remove(); } function display_stats_progress() { const capped_qualities = ["Dangerous", "Persuasive", "Shadowy", "Watchful"]; $('ul.items--list li.sidebar-quality').each( function( index, element ){ bar = $( this ).find('div.progress-bar'); percent = bar.find('span').prop('style').width.slice(0, -1); lvl = Number($( this ).find('span.item__value').text()); quality = $( this ).find('span.item__name').text(); target = lvl + 1; lvl_pts = Math.round(lvl * target / 2); if (capped_qualities.includes(quality) && target > 70) { target = 70; lvl_pts = 2485 + (lvl-70) * 70; } CP = Math.round(target * percent / 100); points = Math.round(lvl_pts + CP); bar.html( bar.html() + '' + points + ' (' + lvl_pts + '+' + CP + '/' + target + ')' ); }); } function common() { // Remove the FL banner to avoid useless scrolling cleanup(); // Display CP and number of points required for the next level near the progress bar display_stats_progress(); // Display contacts & quirks in the sidebar update_advantage_bar(); update_quirks_bar(); update_contacts_bar(); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function go() { // Always done regardless of the location common(); // Actions specific to some locations url = window.location.toString(); if (url != 'https://www.fallenlondon.com/bazaar') { items_total_value_displayed = false; } switch (url) { case 'https://www.fallenlondon.com/bazaar': display_items_total_value(); break; case 'https://www.fallenlondon.com/possessions': possessions(); break; case 'https://www.fallenlondon.com/myself': myself(); break; default: console.log(''); } } async function fl_enhancer() { // On page load (by the browser) await sleep(3600); go(); // When the url is updated by js monitor_url_change(); window.addEventListener('locationchange', async function(){ await sleep(2); go(); }); }