Flight Rising Baldwin

Automatically transmutes items from your list.

目前为 2023-06-29 提交的版本。查看 最新版本

// ==UserScript==
// @name         Flight Rising Baldwin
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Automatically transmutes items from your list.
// @author       Triggernometry
// @match        https://www1.flightrising.com/trading/baldwin/transmute*
// @grant        none
// @license      GNU GPLv3
// ==/UserScript==

(function() {
    'use strict';
    getState();
})();

// Categories are food, mats, app, fam, other

let transmuteItems = {
    "food"      : [],
    "mats"      : ["Smooth Pebbles", "Bone Fragments", "Sparrow Skull", "Crumbling Leather", "Birch Logs", "Fir Logs", "Shattered Ceramic Shard", "Perfect Skipping Stone", "Skipping Stone"],
    "app"       : ["Dented Iron Belt", "Iron Steampunk Wing Armor", "Simple Copper Wing Bangles", "Windwalker's Arctic Gloves", "Bloody Neck Bandage", "Bronze Steampunk Tail Bauble", "Cloudgazer's Arctic Bags", "Cloudgazer's Arctic Tail Cozy", "Dusk Rogue Tail Binding", "Gold Aviator Satchel", "Golden Birdskull Headdress", "Nomad's Sandwastes Turban", "Pretty Buttercup Leg Bow", "Shadowscale Shoulder Guards", "Studious Healer's Slippers", "Teardrop Pastel Spinel Ring", "Celadon Tail Bangle", "Dusky Peacekeeping Vest", "Nightglider's Arctic Coat", "Porcelain Steampunk Scarf", "Pretty Periwinkle Leg Bow", "Teardrop Pearl Tail Ring", "Teardrop Ruby Anklet", "White Birdskull Necklace", "Burnished Gold Belt", "Contrast Rogue Cape", "Contrast Rogue Vest", "Gentle Healer's Trail", "Preserving Tail Segments", "Psion Mitts", "Brave Bonecarver's Cage", "Brave Bonecarver's Claws", "Brave Bonecarver's Jar", "Brave Bonecarver's Mask", "Brave Bonecarver's Scythe", "Brave Bonecarver's Spine", "Dark Dinosaur Arm Guards", "Dark Dinosaur Helmet", "Dark Dinosaur Leg Guards", "Dark Dinosaur Shoulder Guard", "Dark Dinosaur Tail Guard", "Dark Dinosaur Wing Guard", "Dusty Dinosaur Breastplate", "Dusty Dinosaur Leg Guards", "Dusty Dinosaur Shoulder Guard", "Dusty Dinosaur Wing Guard", "Gold Dinosaur Arm Guards", "Gold Dinosaur Breastplate", "Gold Dinosaur Helmet", "Gold Dinosaur Shoulder Guard", "Gold Dinosaur Tail Guard", "Gold Dinosaur Wing Guard", "Jade Dinosaur Arm Guards", "Jade Dinosaur Helmet", "Jade Dinosaur Shoulder Guard", "Jade Dinosaur Tail Guard", "Jade Dinosaur Wing Guard", "Skilled Bonecarver's Cage", "Skilled Bonecarver's Claws", "Skilled Bonecarver's Jar", "Skilled Bonecarver's Mask", "Skilled Bonecarver's Scythe", "Skilled Bonecarver's Spine", "Supportive Bonecarver's Cage", "Supportive Bonecarver's Mask", "Supportive Bonecarver's Wings", "Wise Bonecarver's Cage", "Wise Bonecarver's Claws", "Wise Bonecarver's Jar", "Wise Bonecarver's Mask", "Wise Bonecarver's Scythe", "Wise Bonecarver's Spine", "Wise Bonecarver's Wings"],
    "fam"       : ["Carmine Serthis", "Golden Porpoise", "Cloud Chaser", "Blue Dragon Reef Snail", "Longneck Mender", "Maned Rasa", "Elk", "Psywurm", "Greatshell", "Bucktooth Digger", "Mammertee", "Relic Eel", "Maren Warrior", "Nephrite Chameleon", "Corundum Chameleon", "Swift Lumen", "Ectoplasmime", "Manticore Screamer", "Barkback Boar", "Wetland Unicorn", "Corrosive Depin", "Animated Statue", "Rainbow Sprite", "Longneck Skirmisher", "Serthis Alchemist", "Deadly Reflection", "Living Sculpture", "Opposing Forces", "Spellbound Tome", "Unlikely Alliance", "Unlikely Alliance", "Monkey Wrench", "Maren Shark Hunter", "Maren Defender", "Mirage Puffer", "Axe Mimic", "Crooked Hatchet", "Ball-Jointed Bogsneak", "Enchanted Armaments", "Glowing Globe", "Masked Phantom", "Masked Phantom", "Masked Phantom", "Ashscale Ophiotaurus", "Silky Webwing", "Bluelight Chipskink", "Barkskin Watcher", "Flora Cerdae", "Ashmane Chimera", "Ashmane Chimera", "Longneck Scrapper", "Colubrid Column", "Serthis Support", "Transmuted Treasure", "Transmuted Treasure", "Antique Chair", "Spidered Seat", "Spidered Seat", "Time Devourer", "Plantation Pincher", "Plantation Pincher", "Flesh Forager", "Plainstrider Bard", "Raptorik Wanderer", "Rabid Grinfin", "Grassland Skira", "Fenfisher Flattail", "Fenfisher Flattail", "Mischievous Magnifier", "Blooming Hedgehide", "Blooming Hedgehide", "Four-Eyed Phylactery", "Four-Eyed Phylactery", "Four-Eyed Phylactery", "Four-Eyed Phylactery", "Kyorinrin", "Kyorinrin", "Chocolate Noggle", "Strawberry Noggle", "Mossy Beetleboar", "Mossy Beetleboar", "Wolpertinger", "Redfin Wavespinner", "Banshee Brooch", "Banshee Brooch", "Pitfall Fixture", "Spritely Portrait", "Battered Vase", "Glazed Sentry", "Workshop Monitor", "Gearspring Pocketmouse", "Wind-Up Pocketmouse", "Green-Breasted Sawbeak", "Green-Breasted Sawbeak", "Polarized Bell Goat", "Polarized Bell Goat", "Manticore's Might", "Catty Cannon", "Wicker Dragon", "Silverstring Harp", "Poltergeist Piano", "Buff Dunerunner", "Brave Sphinx", "Petalprayer Mantis", "Swamp Wolf", "Decision Maker", "Decision Maker", "Leisure Loaf", "Leisure Loaf", "Brass Knocker", "Guest Greeter", "Splendiferous Sunshade", "Ruche Slug", "Maren Seahunter", "Abyss Wanderer", "Abyss Wanderer", "Fossil Hunter", "Fossil Hunter", "Walking Fish", "Walking Fish", "Eel of the Depths", "Eel of the Depths", "Seaweed Nautilus", "Seaweed Nautilus", "Deepglow Nautilus", "Carcass Cleaner", "Carcass Cleaner", "Filter Fiend", "Filter Fiend", "Trench Siren", "Trench Siren", "Abyssal Bard", "Abyssal Bard", "Salt and Pepper", "Sugar and Spice", "Book Swarm", "Book Hoard", "Undertide Fidget Toy", "Articulated Fidget Toy", "Articulated Fidget Toy", "Articulated Fidget Toy", "Nutcracker", "Nutcracker", "Formal Tea Set", "Crumbling Relief"],
    "other"     : ["Broken Clay Pot", "Stone Arrowhead"]
};

async function getFood(maxPoints) {
    // page thru item tabs (will hit food first, and fail for all others as they don't have food points)
    for (const key of Object.keys(transmuteItems)) {
        let valueList = transmuteItems[key];
        console.log("key:", key);
        // switch to category tab
        let chooseCategory = document.querySelector('#swaptabs > a[data-tab-id="food"]').click();
        await sleep(2000);

        // get all items in category
        let itemList = document.querySelectorAll('#itempage > span > a');

        // compare to own list of allowed items
        for (const node of itemList) {
            // get tooltip name
            var tooltipID = node.getAttribute('rel');
            // get first matching tooltip. this might fail if similar tooltips exist, like #17 and #177? need to test
            var tooltip = document.querySelectorAll(`${tooltipID} .foodval > strong`)[0];
            var foodPoints = Number(tooltip.firstChild.data);

            if(foodPoints <= maxPoints ) {
                // if allowed item found, set and break loop
                return node;
            }
        }
    }

    //if reached end of loop without returning, no valid food found
    return null;
}

async function getMatchingTransmutable() {
    for (const key of Object.keys(transmuteItems)) {
        let valueList = transmuteItems[key];
        console.log("key:", key);
        // switch to category tab
        let chooseCategory = document.querySelector(`#swaptabs > a[data-tab-id="${key}"]`).click();
        await sleep(2000);

        // get all items in category
        let itemList = document.querySelectorAll('#itempage > span > a');

        // compare to own list of allowed items
        for (const node of itemList) {
            if(valueList.includes(node.getAttribute('data-name'))) {
                // if allowed item found, return and break loops
                return node;
            }
        }
    }

    //if reached end of loop without returning, no item found
    return null;
}

function getState(){

    let idle = document.querySelector('#plus-button-container');
    let brewing = document.querySelector('.baldwin-cauldron-brewing');
    let done = document.querySelector('.baldwin-cauldron-done');

    if(done){
        collectItem();
    } else if (brewing){
        brewingWait();
    } else if(idle){
        transmute();
    }
}

async function collectItem(){
    let collectDoneItem = document.querySelector('input[value="Collect!"]').click();
    // wait for page to load after click
    // await collectDoneItem.DOMContentLoaded();
    await sleep(2000);
    location.reload();
}

async function brewingWait(){
    let brewingTime = document.querySelector('#baldwin-timer-value').getAttribute('data-seconds-left');
    brewingTime = parseInt(brewingTime) + 3;
    console.log(`Now waiting for ${brewingTime} seconds. Please Stand by.`)
    await sleep(brewingTime * 1000);
    location.reload();
}

async function transmute(){
    let clickTransmuteButton = document.querySelector('#plus-button').click();
    console.log(`Click return object: ${clickTransmuteButton}`)
    // wait for item load
    // await clickTransmuteButton.DOMContentLoaded();
    await sleep(2000);
    //console.log(`${transmuteItem[0]} : ${transmuteItem[1]}`)
    let transmuteSelection;

    transmuteSelection = await getFood(2);

    console.log(transmuteSelection);

    if (!transmuteSelection) {
        transmuteSelection = await getMatchingTransmutable();
    }

    // if not null, item found
    if(transmuteSelection) {
        console.log(transmuteSelection);
        transmuteSelection.click();
        await sleep(1000);
        let transmuteStart = document.querySelector('#attch').click();
        await sleep(2000);
        let transmuteConfirm = document.querySelector('#transmute-confirm-ok').click();
    }
    // otherwise, reached end of items without findin a match. Exit.
    else {
        console.log("Reached end without finding a match. Nothing to brew.");
        return 0;
    }
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}