brother-torn / Halloween Chainer

// ==UserScript==
// @name         Halloween Chainer
// @version      1.4
// @namespace    http://tampermonkey.net/
// @description  Adds a Chain button and a minimizable UI for weapon and outcome selection.
// @author       Omanpx [1906686] & Brother [2590792]
// @match        https://www.torn.com/*
// @grant        none
// @license      AGPL-3.0-only
// @updateURL    https://openuserjs.org/meta/brother-torn/Halloween_Chainer.meta.js
// ==/UserScript==

(function() {
    'use strict';

    // --- CONFIGURATION ---
    const minID = 3500000;
    const maxID = 3900000;
    // --- END CONFIGURATION ---

    function createUI() {
        const controlContainer = document.createElement('div');
        controlContainer.style.position = 'fixed';
        controlContainer.style.top = '20%';
        controlContainer.style.left = '10px';
        controlContainer.style.zIndex = '9998';
        controlContainer.style.backgroundColor = 'rgba(10, 10, 10, 0.8)';
        controlContainer.style.padding = '10px';
        controlContainer.style.borderRadius = '8px';
        controlContainer.style.display = 'flex';
        controlContainer.style.flexDirection = 'column';
        controlContainer.style.gap = '10px';
        controlContainer.style.border = '1px solid #444';

        const uiHeader = document.createElement('div');
        uiHeader.style.display = 'flex';
        uiHeader.style.justifyContent = 'space-between';
        uiHeader.style.alignItems = 'center';

        const title = document.createElement('span');
        title.textContent = 'Controls';
        title.style.color = 'white';
        title.style.fontWeight = 'bold';
        title.style.userSelect = 'none';

        const toggleButton = document.createElement('button');
        toggleButton.style.backgroundColor = '#555';
        toggleButton.style.color = 'white';
        toggleButton.style.border = '1px solid #777';
        toggleButton.style.borderRadius = '4px';
        toggleButton.style.padding = '2px 4px';
        toggleButton.style.cursor = 'pointer';
        toggleButton.style.fontWeight = 'bold';

        uiHeader.appendChild(title);
        uiHeader.appendChild(toggleButton);

        const dropdownWrapper = document.createElement('div');
        dropdownWrapper.style.display = 'flex';
        dropdownWrapper.style.flexDirection = 'column';
        dropdownWrapper.style.gap = '5px';

        const createDropdown = (id, labelText, options) => {
            const wrapper = document.createElement('div');
            const label = document.createElement('label');
            label.setAttribute('for', id);
            label.textContent = labelText;
            label.style.color = 'white';
            label.style.fontWeight = 'bold';
            label.style.display = 'block';
            label.style.marginBottom = '4px';

            const select = document.createElement('select');
            select.id = id;
            select.style.width = '120px';
            select.style.padding = '4px';
            select.style.borderRadius = '4px';
            select.style.border = '1px solid #555';
            select.style.backgroundColor = '#333';
            select.style.color = 'white';

            for (const [text, value] of Object.entries(options)) {
                const option = document.createElement('option');
                option.value = value;
                option.textContent = text;
                select.appendChild(option);
            }

            wrapper.appendChild(label);
            wrapper.appendChild(select);
            return { wrapper, select };
        };

        const weaponOptions = { 'Secondary': 'secondary', 'Primary': 'primary', 'Melee': 'melee' };
        const outcomeOptions = { 'Leave': 'leave', 'Mug': 'mug', 'Hospitalize': 'hospitalize' };

        const { wrapper: weaponWrapper, select: weaponSelect } = createDropdown('chainHelperWeapon', 'Weapon:', weaponOptions);
        const { wrapper: outcomeWrapper, select: outcomeSelect } = createDropdown('chainHelperOutcome', 'Outcome:', outcomeOptions);

        dropdownWrapper.appendChild(weaponWrapper);
        dropdownWrapper.appendChild(outcomeWrapper);
        controlContainer.appendChild(uiHeader);
        controlContainer.appendChild(dropdownWrapper);
        document.body.appendChild(controlContainer);

        const savedWeapon = localStorage.getItem('chainHelperWeapon');
        const savedOutcome = localStorage.getItem('chainHelperOutcome');
        if (savedWeapon) weaponSelect.value = savedWeapon;
        if (savedOutcome) outcomeSelect.value = savedOutcome;

        weaponSelect.addEventListener('change', () => localStorage.setItem('chainHelperWeapon', weaponSelect.value));
        outcomeSelect.addEventListener('change', () => localStorage.setItem('chainHelperOutcome', outcomeSelect.value));

        const setMinimizedState = (isMinimized) => {
            dropdownWrapper.style.display = isMinimized ? 'none' : 'flex';
            toggleButton.textContent = isMinimized ? '[+]' : '[-]';
            localStorage.setItem('chainHelperUIMinimized', isMinimized);
        };

        toggleButton.addEventListener('click', () => {
            const isCurrentlyMinimized = dropdownWrapper.style.display === 'none';
            setMinimizedState(!isCurrentlyMinimized);
        });

        const isInitiallyMinimized = localStorage.getItem('chainHelperUIMinimized') === 'true';
        setMinimizedState(isInitiallyMinimized);
    }

    function getRandomNumber(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function findNewTarget() {
        let randID = getRandomNumber(minID, maxID);
        let attackLink = `https://www.torn.com/loader.php?sid=attack&user2ID=${randID}`;
        window.location.href = attackLink;
    }

    const chainButton = document.createElement('button');
    chainButton.innerHTML = 'Chain';
    chainButton.style.position = 'fixed';
    chainButton.style.top = '27%';
    chainButton.style.right = '0%';
    chainButton.style.zIndex = '9999';
    chainButton.style.backgroundColor = '#4CAF50';
    chainButton.style.color = 'white';
    chainButton.style.border = 'none';
    chainButton.style.padding = '8px 12px';
    chainButton.style.borderRadius = '6px';
    chainButton.style.cursor = 'pointer';
    chainButton.style.fontSize = '14px';
    chainButton.style.fontWeight = 'bold';

    chainButton.addEventListener('click', function() {
        const startFightButton = document.querySelector('.defender___niX1M .dialogButtons___nX4Bz button');
        if (startFightButton && startFightButton.innerText.toLowerCase().includes('start fight')) {
            startFightButton.click();
            return;
        }

        const postFightContainer = document.querySelector('.defender___niX1M .dialogButtons___nX4Bz');
        if (postFightContainer) {
            const outcomeButtons = Array.from(postFightContainer.querySelectorAll('button'));
            const isPostFight = outcomeButtons.some(btn => btn.innerText.toLowerCase() === 'mug');

            if (isPostFight) {
                const desiredOutcome = document.getElementById('chainHelperOutcome').value;
                const targetButton = outcomeButtons.find(btn => btn.innerText.toLowerCase() === desiredOutcome);
                if (targetButton) {
                    targetButton.click();
                } else {
                    outcomeButtons.find(btn => btn.innerText.toLowerCase() === 'leave')?.click();
                }
                return;
            }
        }

        const preferredWeapon = document.getElementById('chainHelperWeapon').value;
        const weaponSelectorMap = {
            'primary': '#weapon_main',
            'secondary': '#weapon_second',
            'melee': '#weapon_melee'
        };
        const weaponSelector = weaponSelectorMap[preferredWeapon] || '#weapon_second';
        const chosenWeapon = document.querySelector(weaponSelector);
        const fightStarted = document.querySelector(`${weaponSelector}.attackStarted___iMM2u`);

        if (chosenWeapon && fightStarted) {
            chosenWeapon.click();
            return;
        }

        findNewTarget();
    });

    document.body.appendChild(chainButton);
    createUI();
})();