IdlePixel+ Teams QoL

Various teams quality of life additions, quick deposit/withdraw fight points, better interface when clicking on stored items

目前為 2024-06-21 提交的版本,檢視 最新版本

// ==UserScript==
// @name         IdlePixel+ Teams QoL
// @namespace    com.zlef.idlepixel
// @version      1.1.4
// @description  Various teams quality of life additions, quick deposit/withdraw fight points, better interface when clicking on stored items
// @author       Zlef
// @license      MIT
// @match        *://idle-pixel.com/login/play*
// @grant        none
// @require      https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905
// @require      https://update.greasyfork.org/scripts/484046/1307183/IdlePixel%2B%20Custom%20Handling.js
// ==/UserScript==

(function() {
    'use strict';

    class TeamsQoL extends IdlePixelPlusPlugin {
        constructor() {
            super("teamsqol", {
                about: {
                    name: GM_info.script.name,
                    version: GM_info.script.version,
                    author: GM_info.script.author,
                    description: GM_info.script.description
                },
            });
            this.currentPopup = null;

            this.overlay = document.createElement('div');
            this.overlay.id = 'newCardOverlayTeams';
            this.overlay.style.position = 'fixed';
            this.overlay.style.top = '0';
            this.overlay.style.left = '0';
            this.overlay.style.width = '100%';
            this.overlay.style.height = '100%';
            this.overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
            this.overlay.style.zIndex = '1000';
            this.overlay.style.display = 'flex';
            this.overlay.style.justifyContent = 'center';
            this.overlay.style.alignItems = 'center';
            this.overlay.addEventListener('click', (event) => {
                if (event.target === this.overlay) {
                    this.closePopup();
                }
            });

            window.addEventListener('resize', this.adjustPopupPosition.bind(this));
        }

        onMessageReceived(message) {
            if(message.startsWith("TEAMS_STORAGE_DATA")){
                this.parseStorage(message.split("=")[1])
            }
        }

        parseStorage(storage_string){
            this.team_storage = {}
            const data_array = storage_string.split("~")
            for (let i = 0; i<data_array.length - 1; i+=2) {
                this.team_storage[data_array[i]] = data_array[i+1]
            }
        }

        onLogin() {
            this.teamStorageTopBar();
            this.replaceItemClickModal();
        }

        replaceItemClickModal(){
            const self = this;
            Modals.clicksTeamStorageItem = function(item_var, amount) {
                const player_amount = window[`var_${item_var}`] || 0;
                // New custom modal based on new card interface
                self.newteamsPopup(item_var, amount, player_amount);

            };
        }

        newteamsPopup(item_var, amount, player_amount) {
            const teamsPopupStyles = `
				<style>
					#teamsPopup {
						display: flex;
						flex-direction: column;
						align-items: center;
						width: 100%;
						max-width: 500px;
						margin: 0 auto;
						background-color: #fff;
						border-radius: 8px;
						box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
						padding: 20px;
						box-sizing: border-box;
						position: relative;
					}
					#teamsPopup .teamsPopup-row {
						display: flex;
						width: 100%;
						margin-bottom: 10px;
					}
					#teamsPopup .teamsPopup-col {
						flex: 1;
						box-sizing: border-box;
						padding: 10px;
						display: flex;
						flex-direction: column;
						align-items: center;
					}
					#teamsPopup .teamsPopup-deposit-container,
					#teamsPopup .teamsPopup-withdraw-container {
						display: flex;
						flex-direction: column;
						align-items: center;
					}
					#teamsPopup .teamsPopup-button-container {
						display: flex;
						justify-content: center;
						width: 100%;
					}
					#teamsPopup button {
						padding: 10px 20px;
						cursor: pointer;
						margin-top: 10px;
					}
					#teamsPopup .deposit-button {
						background-color: red;
						color: white;
					}
					#teamsPopup .withdraw-button {
						background-color: green;
						color: white;
					}
					#teamsPopup input {
						margin: 10px 0;
					}
					#teamsPopup .vertical-divider {
						width: 1px;
						background-color: #ccc;
						margin: 0 20px;
					}
					#teamsPopup .close-button {
						position: absolute;
						top: 10px;
						right: 10px;
						background: none;
						border: none;
						font-size: 10x;
						cursor: pointer;
						padding: 5px;
					}
				</style>
			`;

            document.head.insertAdjacentHTML('beforeend', teamsPopupStyles);

            const popupBox = document.createElement('div');
            popupBox.id = 'teamsPopup';

            const titleDiv = document.createElement('div');
            titleDiv.className = "teamsPopup-row";
            popupBox.appendChild(titleDiv);

            const title = document.createElement('h5');
            title.textContent = item_var.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
            title.className = "modal-title";
            title.style.textAlign = 'center';
            titleDiv.appendChild(title);

            const closeButton = document.createElement('button');
            closeButton.textContent = '✖';
            closeButton.className = 'close-button';
            closeButton.type = 'button';
            popupBox.appendChild(closeButton);

            const rowDiv = document.createElement('div');
            rowDiv.className = 'teamsPopup-row';
            popupBox.appendChild(rowDiv);

            const depositColDiv = document.createElement('div');
            depositColDiv.className = 'teamsPopup-col teamsPopup-deposit-container';
            rowDiv.appendChild(depositColDiv);

            const divider = document.createElement('div');
            divider.className = 'vertical-divider';
            rowDiv.appendChild(divider);

            const withdrawColDiv = document.createElement('div');
            withdrawColDiv.className = 'teamsPopup-col teamsPopup-withdraw-container';
            rowDiv.appendChild(withdrawColDiv);

            const depositLabel = document.createElement('label');
            depositLabel.textContent = 'Deposit Amount';
            depositColDiv.appendChild(depositLabel);

            const depositInput = document.createElement('input');
            depositInput.type = 'number';
            depositInput.max = player_amount;
            depositInput.min = 0;
            depositInput.className = 'storage-control';
            depositInput.id = 'depositAmount';
            depositInput.value = player_amount;
            depositColDiv.appendChild(depositInput);

            const depositButton = document.createElement('button');
            depositButton.textContent = 'DEPOSIT';
            depositButton.className = 'btn btn-secondary deposit-button';
            depositColDiv.appendChild(depositButton);

            const withdrawLabel = document.createElement('label');
            withdrawLabel.textContent = 'Withdraw Amount';
            withdrawColDiv.appendChild(withdrawLabel);

            let withdraw_amount = amount;
            if (item_var == "fight_points"){
                const fight_points = window.var_fight_points || 0;
                const max_fight_points = window.var_max_fight_points || 0;
                withdraw_amount = Math.max(0, (max_fight_points - fight_points) - 10);

            }

            const withdrawInput = document.createElement('input');
            withdrawInput.type = 'number';
            withdrawInput.max = amount;
            withdrawInput.min = 0;
            withdrawInput.className = 'storage-control';
            withdrawInput.id = 'withdrawAmount';
            withdrawInput.value = withdraw_amount;
            withdrawColDiv.appendChild(withdrawInput);

            const withdrawButton = document.createElement('button');
            withdrawButton.textContent = 'WITHDRAW';
            withdrawButton.className = 'btn btn-secondary withdraw-button';
            withdrawColDiv.appendChild(withdrawButton);

            const actions = [
                {
                    button: depositButton,
                    handler: () => {
                        // console.log("Pressed deposit button");
                        const store_amount = depositInput.value;
                        websocket.send(`TEAM_STORE_ITEM=${item_var}~${store_amount}`);
                    }
                },
                {
                    button: withdrawButton,
                    handler: () => {
                        // console.log("Pressed withdraw button");
                        let take_amount = withdrawInput.value;
                        websocket.send(`TEAM_TAKE_ITEM=${item_var}~${take_amount}`);
                    }
                },
                {
                    button: closeButton,
                    handler: () => {
                        this.closePopup();
                    },
                    closeOnAction: true
                }
            ];

            this.launchPopup(popupBox, actions);
        }

        launchPopup(popup, actions) {
            if (this.currentPopup) {
                if (this.overlay.contains(this.currentPopup)) {
                    this.overlay.removeChild(this.currentPopup);
                }
                this.currentPopup = null;
            }

            this.currentPopup = popup;

            this.overlay.appendChild(popup);
            document.body.appendChild(this.overlay);

            this.adjustPopupPosition();

            actions.forEach(action => {
                const button = action.button;
                button.addEventListener('click', () => {
                    action.handler();
                    if (action.closeOnAction !== false) {
                        this.closePopup();
                    }
                });
            });
        }

        adjustPopupPosition() {
            if (!this.currentPopup) return;

            const viewportHeight = window.innerHeight;
            const popupHeight = this.currentPopup.offsetHeight;
            const scrollOffset = window.pageYOffset || document.documentElement.scrollTop;
            const topPosition = (viewportHeight - popupHeight) / 2 + scrollOffset;
            this.currentPopup.style.position = 'absolute';
            this.currentPopup.style.top = `${topPosition > 0 ? topPosition : 0}px`;
        }

        closePopup() {
            if (this.currentPopup && this.overlay.contains(this.currentPopup)) {
                this.overlay.removeChild(this.currentPopup);
                this.currentPopup = null;
            }
            if (document.body.contains(this.overlay)) {
                document.body.removeChild(this.overlay);
            }
        }

        teamStorageTopBar(){
            // Get the original container
            const teamTradingBox = document.querySelector('.team-trading-box');

            // Create the new container
            const container = document.createElement('div');
            container.className = 'container';

            const row1 = document.createElement('div');
            row1.className = 'row';
            row1.style.marginBottom = '20px';

            const col1 = document.createElement('div');
            col1.className = 'col';
            col1.style.flex = "0 0 auto"; // Prevents the column from shrinking or growing
            col1.style.width = "auto"; // Adjust the width to match the content
            col1.innerHTML = `
                <div class="font-large" style="color: rgb(175, 131, 14);">Team Storage</div>
                <div><u id="add-item-teams-label" onclick="Modals.clicksAddItemTeamStorage()" class="color-grey hover" style="color: rgb(56, 41, 241);">Add Item</u></div>
            `;

            const col2 = document.createElement('div');
            col2.className = 'col-6';
            col2.style.display = "flex"; // Use flexbox to align items
            col2.style.alignItems = "center"; // Center items vertically
            col2.style.marginLeft = "10px"; // Add a small margin to separate from col1

            // Create buttons using JavaScript
            const arrowSize = 30; // Variable to control the size of the arrows

            const withdrawFPButton = document.createElement("button");
            withdrawFPButton.id = "withdrawFPButton";
            withdrawFPButton.alt = "Withdraw fight points";
            withdrawFPButton.style.border = "none";
            withdrawFPButton.style.background = "none";
            withdrawFPButton.style.cursor = "pointer";
            withdrawFPButton.style.position = "relative";

            const img1 = document.createElement("img");
            img1.src = "https://cdn.idle-pixel.com/images/fight_points.png";
            img1.style.width = "50px";
            img1.style.height = "50px";

            const arrow1 = document.createElement("div");
            arrow1.innerHTML = `
                <svg width="${arrowSize}" height="${arrowSize}" viewBox="0 0 16 16" fill="green" xmlns="http://www.w3.org/2000/svg">
                    <path d="M14.13 9.11h-12l6-7 6 7z"/>
                    <path d="M6.12 8h4v6h-4z" fill="green"/>
                </svg>`;
            arrow1.style.position = "absolute";
            arrow1.style.bottom = "0";
            arrow1.style.right = "0";

            withdrawFPButton.appendChild(img1);
            withdrawFPButton.appendChild(arrow1);

            const despositFPButton = document.createElement("button");
            despositFPButton.id = "despositFPButton";
            despositFPButton.alt = "Deposit fight points";
            despositFPButton.style.border = "none";
            despositFPButton.style.background = "none";
            despositFPButton.style.cursor = "pointer";
            despositFPButton.style.position = "relative";

            const img2 = document.createElement("img");
            img2.src = "https://cdn.idle-pixel.com/images/fight_points.png";
            img2.style.width = "50px";
            img2.style.height = "50px";

            const arrow2 = document.createElement("div");
            arrow2.innerHTML = `
                <svg width="${arrowSize}" height="${arrowSize}" viewBox="0 0 16 16" fill="red" xmlns="http://www.w3.org/2000/svg">
                    <path d="M2.38 7h12l-6 7-6-7z"/>
                    <path d="M10.37 8.11h-4v-6h4z" fill="red"/>
                </svg>`;
            arrow2.style.position = "absolute";
            arrow2.style.bottom = "0";
            arrow2.style.right = "0";

            despositFPButton.appendChild(img2);
            despositFPButton.appendChild(arrow2);

            // Define the click event functions
            withdrawFPButton.addEventListener("click", () => this.withdrawFightPoints());
            despositFPButton.addEventListener("click", () => this.depositFightPoints());

            // Append buttons to the col2
            col2.appendChild(despositFPButton);
            col2.appendChild(withdrawFPButton);


            const col3 = document.createElement('div');
            col3.className = 'col';
            col3.style.width = "200px";
            col3.style.display = "flex";
            col3.style.justifyContent = "flex-end";
            col3.innerHTML = `<input type="text" onkeyup="Modals.searchTeamStorageKeyPress(this)" style="max-width:100%; min-width:20%; max-height:28px;" placeholder="Search Storage">`;

            row1.appendChild(col1);
            row1.appendChild(col2);
            row1.appendChild(col3);

            container.appendChild(row1);

            // Create a new row for team storage content
            const row2 = document.createElement('div');
            row2.className = 'row';

            // Move the original team storage content into the new layout
            const teamStorageBoxContent = document.getElementById('team-storage-box-content');
            if (teamStorageBoxContent) {
                row2.appendChild(teamStorageBoxContent);
            }

            container.appendChild(row2);

            // Replace the original content with the new container
            teamTradingBox.innerHTML = '';
            teamTradingBox.appendChild(container);
        }

        withdrawFightPoints() {
            const fight_points = window.var_fight_points || 0;
            const max_fight_points = window.var_max_fight_points || 0;
            const fight_points_needed = Math.max(0, (max_fight_points - fight_points) - 10);
            if (this.team_storage.fight_points >= fight_points_needed){
                // console.log(`TEAM_TAKE_ITEM=fight_points~${fight_points_needed}`)
                websocket.send(`TEAM_TAKE_ITEM=fight_points~${fight_points_needed}`);
            } else if (this.team_storage.fight_points > 0){
                // console.log(`TEAM_TAKE_ITEM=fight_points~${this.team_storage.fight_points}`)
                websocket.send(`TEAM_TAKE_ITEM=fight_points~${this.team_storage.fight_points}`);
            }
        }

        depositFightPoints() {
            const fight_points = window.var_fight_points || 0;
            websocket.send(`TEAM_STORE_ITEM=fight_points~${fight_points}`);
        }
    }

    const plugin = new TeamsQoL();
    IdlePixelPlus.registerPlugin(plugin);

})();