DayZ Map Improvement

6/11/2024, 1:26:23 AM

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name        DayZ Map Improvement
// @namespace   https://azzurite.tv
// @match       https://dayz.xam.nu/*
// @run-at      document-start
// @grant       none
// @version     1.4.0
// @author      Azzurite
// @license     GPLv3
// @description 6/11/2024, 1:26:23 AM
// ==/UserScript==

(() => {
    const highlighters = {};

    function makeHuntingMoreVisible() {
        if (this.options.iconUrl === `https://dayz.xam.nu/js/../images/b8fe30b7.webp`) {
            this.options.iconUrl = `https://images.azzurite.tv/uploads/original/d3/0f/6a50614db7df56f32d5aa2840268.webp`;
        } else if (this.options?.iconUrl === `https://dayz.xam.nu/js/../images/a92e2f53.webp`) {
            this.options.iconUrl = `https://images.azzurite.tv/uploads/original/92/8b/e706a502ab0931c2338883333633.webp`;
        }
    }

    Object.defineProperty(window, `L`, {
        set(obj) {
            this.storedL = obj;
            obj.Map.addInitHook(function() { // addInitHook binds `this`
                window.map = this;
            });
            obj.Icon.addInitHook(makeHuntingMoreVisible);
        },
        get() {
            return this.storedL;
        }
    })

    function getMarkers() {
        return window.map.modules.filters.markers;
    }

    function getFilters() {
        return window.map.modules.filters.filters;
    }

    function setFilters(filters) {
        window.map.modules.filters.filters = filters;
    }

    function filtersContain(filters, key, subKey) {
        return filters[key] === true || filters[key]?.includes(subKey);
    }

    function areExactlyTheseFiltersActive(filters) {
        return Object.entries(getFilters()).every(([filterKey, filterValue]) => {
            return Object.keys(filterValue).every(subFilterKey => {
                if (filterKey === `tier`) return true;
                if (filtersContain(filters, filterKey, subFilterKey)) {
                    return filterValue[subFilterKey] === 1;
                } else {
                    return filterValue[subFilterKey] === 0;
                }
            });
        });
    }

    function updateButtonsState() {
        document.querySelector(`.azzu-all > button`).dataset.active = anyMarkerActive() ? 1 : 0;
        for (let highlighter of Object.values(highlighters)) {
            if (highlighter.isActive) {
                highlighter.button.dataset.active = highlighter.isActive() ? 1 : 0;
            }
        }
    }

    function updateDisplay() {
        window.map.modules.filters._check();
        map.modules.filters._updateStorage();
        updateButtonsState();
    }

    function anyMarkerActive() {
        return Object.entries(getFilters()).some(([subFilterKey, subFilterValue]) => {
            if (subFilterKey === `tier`) return false;
            return Object.values(subFilterValue).some(state => state === 1)
        });
    }

    function forAllFiltersExceptTiers(callback) {
        Object.entries(getFilters()).forEach(([subFilterKey, subFilterValue]) => {
            if (subFilterKey !== `tier`) {
                callback(subFilterKey, subFilterValue);
            }
        })
    }

    function getButtonList() {
        return document.querySelector(`.filters`).parentNode;
    }

    function setAllFiltersTo(state) {
        forAllFiltersExceptTiers((_, val) => {
            for (let key of Object.keys(val)) {
                val[key] = state;
            }
        });
    }

    function setFiltersTo(filters, state) {
        forAllFiltersExceptTiers((key, val) => {
            if (Object.keys(filters).includes(key)) {
                const toChange = filters[key] === true ? Object.keys(getFilters()[key]) : filters[key];
                for (let toDisable of toChange) {
                    val[toDisable] = state;
                }
            }
        });
    }

    function setMarkersTo(filterFn, value) {
        for (let e of getMarkers()) {
            if (filterFn(e)) {
                e.options.visible = value;
                e.options.interactive = value;
            }
        }
        map.modules.filters.layer._redraw()
    }

    function nicerToggleAll() {
        if (anyMarkerActive()) {
            setAllFiltersTo(0);
            updateDisplay();
        } else {
            const unwanted = {
                food: [`pear`, `apple`, `plum`],
                animal: true,
                area: [`dynamiccontamination`],
                misc: [`infected`, `playerspawnhop`, `playerspawnsafe`, `playerspawntravel`],
                vehicle: [`playerspawnhop`, `playerspawnsafe`, `playerspawntravel`]
            }
            setAllFiltersTo(1);
            setFiltersTo(unwanted, 0);

            updateDisplay();

            setMarkersTo((marker) => marker.data.m[0] === `land_mil_tower_small`, 0);
            setMarkersTo((marker) => marker.data.t.includes(`no loot`), 0);
        }
    }

    function replaceFilterAllButton() {
        const li = document.createElement(`li`);
        li.classList.add(`azzu-all`);
        const btn = document.querySelector(`[data-type="all"][data-weight="all"]`).cloneNode(true);
        li.append(btn);
        btn.addEventListener(`click`, () => {
            stopHighlighters();
            nicerToggleAll();
        });
        getButtonList().prepend(li);
        document.querySelector(`.filters`).style.display = `none`;
    }

    function createTextButton(text) {
        const li = document.createElement(`li`);
        li.classList.add(`azzu-highlight`);
        const btn = document.createElement(`button`);
        btn.style.padding = `0 10px`;
        btn.style.width = `inherit`;
        btn.innerHTML = text;
        li.append(btn);
        getButtonList().prepend(li);
        return btn;
    }

    function stopHighlighters() {
        for (const [key, {timeout}] of Object.entries(highlighters)) {
            if (timeout) {
                clearTimeout(timeout);
                highlighters[key].timeout = false;
            }
        }
    }

    function isHighlighterRunning(id) {
        return !!highlighters[id]?.timeout;
    }

    function addBlinkingBehavior(btn, id, highlight, isEnabled = () => btn.dataset.active == `1`) {
        highlighters[id] = { button: btn, timeout: false, };

        btn.addEventListener(`contextmenu`, (ev) => {
            ev.preventDefault();

            doBlinkingBehavior(id, highlight, isEnabled);
        });
        btn.addEventListener(`click`, (ev) => {
            if (!ev.isTrusted) {
                return;
            }
            const running = isHighlighterRunning(id);
            stopHighlighters();
        })
    }

    function doBlinkingBehavior(id, highlight, isEnabled) {
        if (!highlighters[id]) highlighters[id] = { timeout: false };

        const running = isHighlighterRunning(id);
        stopHighlighters();
        if (running) {
            if (!isEnabled()) highlight();
            return;
        }

        const doHighlight = () => {
            if (isEnabled()) {
                highlight();
                highlighters[id].timeout = setTimeout(doHighlight, 100);
            } else {
                highlight();
                highlighters[id].timeout = setTimeout(doHighlight, 600);
            }
        }
        highlighters[id].timeout = setTimeout(doHighlight, 0);
    }

    function areTheseFiltersActive(filters) {
        return Object.entries(getFilters()).every(([filterKey, filterValue]) => {
            return Object.keys(filterValue).every(subFilterKey => {
                if (filterKey === `tier`) return true;
                if (filtersContain(filters, filterKey, subFilterKey)) {
                    return filterValue[subFilterKey] === 1;
                } else {
                    return true;
                }
            });
        });
    }

    function createHighlightButton(text, toHighlight, isActive = () => areTheseFiltersActive(toHighlight)) {
        const btn = createTextButton(text);
        btn.classList.add(`highlighter`);
        btn.classList.add(text);

        const toggle = (newState) => {
            if (typeof toHighlight === `function`) {
                toHighlight(btn, newState);
            } else {
                setFiltersTo(toHighlight, newState);
                updateDisplay();
            }
        };

        btn.addEventListener(`click`, (ev) => {
            if (btn.dataset.active === `1`) {
                toggle(0);
            } else {
                toggle(1);
            }
        });

        addBlinkingBehavior(btn, text,
                            () => {
                                toggle(isActive() ? 0 : 1);
                            },
                            isActive
        );
        highlighters[text].isActive = isActive;
        updateDisplay();

        return btn;
    }

    function addWeaponAmmoHighlight() {
        createCustomHighlightButton(`HighValue`, (marker) => {
            const subType = marker.data.w;
            const lootTypes = marker.data.t;
            return ((lootTypes.includes(`military`) && subType !== `helicrash`) ||
                lootTypes.includes(`police`) ||
                lootTypes.includes(`medic`)  ||
                (lootTypes.includes(`hunting`) && subType !== `deerstand` && subType !== `feedshack`));
        });
    }

    function addShowCarSpawns() {
        createHighlightButton(`Vehicles`, {vehicle: [`vehicleoffroadhatchback`, `vehiclehatchback02`, `vehicleoffroad02`, `vehicletruck01`, `vehicleciviliansedan`, `vehiclesedan02`]});
    }

    function addBlinkingToAllButtons() {
        for (const btn of [...document.querySelectorAll(`[data-weight][data-type]:not([data-type="all"])`)]) {
            const {type, weight} = btn.dataset;
            const id = `${type}-${weight}`;
            btn.classList.add(`highlighter`);
            btn.classList.add(id);
            addBlinkingBehavior(btn, id, () => btn.click());
        }
    }


    function createCustomHighlightButton(text, filterFn) {
        createHighlightButton(text, (btn, newState) => {
            setMarkersTo(filterFn, newState);
            updateButtonsState();
        }, () => getMarkers().some(marker => filterFn(marker) && marker.options.visible === 1));

    }

    function addCoastal() {
        createCustomHighlightButton(`Coastal`, (marker) => marker.data.t.includes(`coast`))
    }

    function addModelBlinkingButton() {
        setInterval(() => {
            const panel = document.querySelector(`#economy`);
            if (!panel) return;

            const buttonClassName = `azzu-blink-button`;
            if (panel.querySelector(`.${buttonClassName}`)) return;

            const button = document.createElement(`button`);
            button.classList.add(buttonClassName);
            button.dataset.tooltip = `Blink`;
            button.dataset.tooltippos = `left`;
            button.innerHTML = `<?xml version="1.0" encoding="iso-8859-1"?><svg height="800px" width="800px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve"><g><g><path d="M250.826,386.309c-9.235,0-16.722,7.487-16.722,16.722v91.874c0,9.235,7.487,16.722,16.722,16.722 c9.235,0,16.722-7.487,16.722-16.722v-91.874C267.547,393.796,260.061,386.309,250.826,386.309z"/></g></g><g><g><path d="M250.826,9.975c-9.235,0-16.722,7.487-16.722,16.722v66.887c0,9.235,7.487,16.722,16.722,16.722 c9.235,0,16.722-7.487,16.722-16.722V26.697C267.547,17.462,260.061,9.975,250.826,9.975z"/></g></g><g><g><path d="M60.721,131.736l-35.023-20.221c-7.999-4.62-18.226-1.877-22.842,6.12c-4.619,7.999-1.878,18.226,6.12,22.842 l35.023,20.221c7.997,4.619,18.223,1.878,22.842-6.12C71.46,146.579,68.72,136.352,60.721,131.736z"/></g></g><g><g><path d="M503.636,387.452l-70.673-40.803c-7.999-4.621-18.226-1.877-22.842,6.12c-4.619,7.999-1.878,18.226,6.12,22.842 l70.673,40.803c7.997,4.619,18.223,1.878,22.842-6.12C514.375,402.297,511.634,392.07,503.636,387.452z"/></g></g><g><g><path d="M165.794,408.082c-8-4.62-18.224-1.88-22.842,6.12l-23.659,40.977c-4.619,7.997-1.878,18.224,6.12,22.842 c7.997,4.619,18.224,1.878,22.842-6.12l23.659-40.977C176.531,422.928,173.791,412.701,165.794,408.082z"/></g></g><g><g><path d="M391.587,16.998c-7.999-4.62-18.226-1.88-22.842,6.12l-32.07,55.545c-4.619,7.997-1.878,18.224,6.12,22.842 c7.997,4.619,18.224,1.878,22.842-6.12l32.07-55.545C402.326,31.842,399.586,21.615,391.587,16.998z"/></g></g><g><g><path d="M484.93,244.079h-66.887c-9.235,0-16.722,7.487-16.722,16.722c0,9.235,7.487,16.722,16.722,16.722h66.887 c9.235,0,16.722-7.487,16.722-16.722C501.651,251.566,494.165,244.079,484.93,244.079z"/></g></g><g><g><path d="M83.609,244.079H16.722C7.487,244.079,0,251.566,0,260.801c0,9.235,7.487,16.722,16.722,16.722h66.887 c9.235,0,16.722-7.487,16.722-16.722C100.33,251.566,92.843,244.079,83.609,244.079z"/></g></g><g><g><path d="M400.589,486.644l-41.403-71.628c-4.622-7.995-14.847-10.73-22.845-6.108c-7.995,4.622-10.731,14.849-6.108,22.845 l41.403,71.628c4.62,7.993,14.843,10.732,22.845,6.108C402.476,504.868,405.212,494.641,400.589,486.644z"/></g></g><g><g><path d="M198.415,136.552L148.25,49.765c-4.622-7.995-14.851-10.731-22.845-6.108c-7.995,4.622-10.731,14.849-6.108,22.845 l50.165,86.787c4.621,7.995,14.848,10.732,22.845,6.108C200.303,154.775,203.038,144.548,198.415,136.552z"/></g></g><g><g><path d="M494.351,120.132c-4.621-7.995-14.85-10.73-22.845-6.108l-88.868,51.368c-7.995,4.622-10.731,14.849-6.108,22.845 c4.621,7.995,14.848,10.732,22.845,6.108l88.868-51.368C496.238,138.355,498.974,128.128,494.351,120.132z"/></g></g><g><g><path d="M140.221,324.638c-4.622-7.997-14.85-10.729-22.845-6.108L39.79,363.376c-7.995,4.622-10.731,14.849-6.108,22.845 c4.619,7.99,14.841,10.734,22.845,6.108l77.585-44.847C142.108,342.861,144.844,332.634,140.221,324.638z"/></g></g><g><g><path d="M494.643,40.631l11.824-11.824c6.53-6.529,6.53-17.117,0-23.648c-6.529-6.529-17.117-6.529-23.648,0l-11.824,11.826 L459.172,5.16c-6.529-6.529-17.117-6.529-23.648,0c-6.53,6.529-6.53,17.117,0,23.648l11.824,11.824l-11.824,11.825 c-6.531,6.529-6.531,17.117,0,23.647c6.53,6.53,17.117,6.53,23.648,0l11.823-11.824l11.824,11.824c6.53,6.53,17.117,6.53,23.648,0 c6.53-6.529,6.53-17.117,0-23.648L494.643,40.631z"/></g></g><g><g><path d="M65.452,469.822l11.824-11.824c6.531-6.529,6.531-17.117,0-23.647c-6.529-6.529-17.117-6.529-23.648,0l-11.824,11.824 L29.98,434.351c-6.529-6.529-17.117-6.529-23.648,0c-6.53,6.529-6.53,17.117,0,23.648l11.824,11.825L6.333,481.647 c-6.53,6.529-6.53,17.117,0,23.648s17.117,6.53,23.648,0l11.823-11.824l11.824,11.824c6.53,6.53,17.117,6.53,23.648,0 c6.53-6.529,6.53-17.117,0-23.648L65.452,469.822z"/></g></g><g><g><circle cx="72.461" cy="82.436" r="16.722"/></g></g><g><g><circle cx="27.87" cy="37.844" r="16.722"/></g></g><g><g><circle cx="473.782" cy="483.759" r="16.722"/></g></g><g><g><circle cx="429.191" cy="439.168" r="16.722"/></g></g><g><g><path d="M359.955,221.513l-65.045-9.452l-29.09-58.942c-6.124-12.405-23.865-12.407-29.99,0l-29.089,58.942l-65.046,9.452 c-13.686,1.987-19.178,18.862-9.267,28.522l47.067,45.88l-11.111,64.782c-2.337,13.628,12.007,24.066,24.263,17.628l58.179-30.589 l58.178,30.587c12.244,6.435,26.602-3.984,24.263-17.628l-11.112-64.782l47.067-45.879 C379.128,240.379,373.648,223.5,359.955,221.513z M292.515,278.101c-3.941,3.842-5.739,9.376-4.808,14.801l6.87,40.052 c-39.141-20.578-38.257-20.832-43.752-20.832c-5.506,0-4.791,0.348-43.751,20.832l6.869-40.053 c0.931-5.423-0.867-10.958-4.808-14.8l-29.1-28.366l40.216-5.844c5.447-0.792,10.155-4.212,12.59-9.147l17.984-36.442 l17.986,36.441c2.437,4.935,7.143,8.355,12.59,9.147l40.215,5.844L292.515,278.101z"/></g></g><g><g><circle cx="108.691" cy="182.211" r="16.722"/></g></g><g><g><circle cx="317.713" cy="143.751" r="16.722"/></g></g><g><g><circle cx="376.239" cy="327.69" r="16.722"/></g></g></svg>`;
            panel.querySelector(`.controls`).append(button);
            button.addEventListener(`click`, () => {
                const modelName = panel.querySelector(`h2`).textContent;
                const filter = (marker) => marker.data.m[0] === modelName;
                const running = isHighlighterRunning(modelName);
                if (!running) {
                    doBlinkingBehavior(
                        modelName,
                        () => {
                            const setTo = button.dataset.active === `1` ? 0 : 1;
                            setMarkersTo(filter, setTo);
                            button.dataset.active = setTo;
                        },
                        () => button.dataset.active === `1`
                    );
                } else {
                    if (button.dataset.active === `0`) {
                        setMarkersTo(filter, 1);
                    }
                    stopHighlighters();
                }

            });
        }, 420);
    }

    function init() {
        if (!document.querySelector(`.filters`)) {
            setTimeout(init, 100);
            return;
        }

        replaceFilterAllButton();
        addBlinkingToAllButtons();
        addModelBlinkingButton();
        addWeaponAmmoHighlight();
        addShowCarSpawns();
        addCoastal();
    }

    setTimeout(init, 100);
})();