This repository has been archived on 2023-01-26. You can view files and clone it, but cannot push or open issues or pull requests.
scripts-old/src/mapCoordsPicker.js

285 lines
7.8 KiB
JavaScript

import getTranslations from './i18n/mapCoordsPicker';
import { getItem, setItem } from './utils/localStorage';
// ==UserScript==
// @name Map coords picker
// @namespace https://github.com/tribalwarshelp/scripts
// @updateURL https://raw.githubusercontent.com/tribalwarshelp/scripts/master/dist/mapCoordsPicker.js
// @downloadURL https://raw.githubusercontent.com/tribalwarshelp/scripts/master/dist/mapCoordsPicker.js
// @version 0.7.4
// @description Map coords picker
// @author Kichiyaki https://dwysokinski.me/
// @match *://*/game.php*screen=map*
// @grant none
// ==/UserScript==
const LOCAL_STORAGE_KEY = 'kichiyaki_map_coords_picker';
const container = document.querySelector('#content_value > h2');
let button;
let formsContainer;
let actionsContainer;
let config = getItem(LOCAL_STORAGE_KEY, {
started: false,
groups: {
All: {
villages: [],
color: '#ffffff',
},
},
selectedGroup: 'All',
});
let intervalID;
const translations = getTranslations();
const saveConfig = () => {
setItem(LOCAL_STORAGE_KEY, config);
};
const villageIDByCoords = (x, y) => {
const xy = parseInt(`${x}${y}`, 10);
const village = TWMap.villages[xy];
if (village) {
return TWMap.villages[xy].id;
}
return NaN;
};
const setVillageBorder = (x, y, color = 'transparent') => {
const id = villageIDByCoords(x, y);
if (isNaN(id)) return;
const village = document.querySelector('#map_village_' + id);
if (village) {
village.style.boxSizing = 'border-box';
village.style.border =
color !== 'transparent' ? `5px solid ${color}` : 'none';
}
};
const deleteVillageFromOtherGroups = key => {
for (let name in config.groups) {
if (name === config.selectedGroup) return;
config.groups[name].villages = config.groups[name].villages.filter(
village => village.key !== key
);
}
};
const handleMapClick = (x, y, e) => {
e.preventDefault();
const key = `${x}|${y}`;
const selected = config.groups[config.selectedGroup].villages.some(
village => village.key === key
);
if (selected) {
config.groups[config.selectedGroup].villages = config.groups[
config.selectedGroup
].villages.filter(village => village.key !== key);
setVillageBorder(x, y, 'transparent');
} else {
config.groups[config.selectedGroup].villages = [
...config.groups[config.selectedGroup].villages,
{
x,
y,
key,
},
];
setVillageBorder(x, y, config.groups[config.selectedGroup].color);
deleteVillageFromOtherGroups(key);
}
};
const renderForm = (container, group) => {
const selected = group && group.name !== config.selectedGroup;
const html = `
<input type="color" value="${group ? group.color : ''}" required />
<input type="text" required placeholder="${
translations.groupName
}" value="${group ? group.name : ''}" />
<button type="submit">${
group ? translations.save : translations.add
}</button>
${
group
? `<button type="button">${translations.delete}</button>`
: ''
}
${
selected
? `<button class="selectButton" type="button">${translations.select}</button>`
: ''
}
`;
const form = document.createElement('form');
form.innerHTML = html;
form.addEventListener('submit', e => {
e.preventDefault();
if (group) {
if (group.name === config.selectedGroup)
config.selectedGroup = e.target[1].value;
colorizeGroupVillages(group.name, e.target[0].value);
config.groups[e.target[1].value] = {
...config.groups[group.name],
color: e.target[0].value,
};
if (group.name !== e.target[1].value) delete config.groups[group.name];
} else {
config.groups[e.target[1].value] = {
color: e.target[0].value,
villages: [],
};
}
renderGroups();
});
if (group) {
form
.querySelector('button[type="button"]')
.addEventListener('click', () => {
if (config.selectedGroup === group.name) {
return UI.ErrorMessage(translations.cannotDeleteSelectedGroup);
}
colorizeGroupVillages(group.name, 'transparent');
delete config.groups[group.name];
form.remove();
});
const selectButton = form.querySelector('.selectButton');
if (selectButton) {
selectButton.addEventListener('click', e => {
config.selectedGroup = group.name;
renderGroups();
});
}
}
container.appendChild(form);
};
const renderGroups = () => {
formsContainer.innerHTML = '';
for (let name in config.groups) {
renderForm(formsContainer, { ...config.groups[name], name });
}
renderForm(formsContainer);
};
const handleExportVillages = () => {
const groups = [];
for (let name in config.groups) {
groups.push(`<div style="margin-bottom: 30px;">
<h3>${name}</h3>
<textarea cols=30 rows=8 readonly>${config.groups[name].villages
.map(village => village.key)
.join(' ')
.trim()}</textarea>
</div>`);
}
const html = `
${groups.join('')}
`;
Dialog.show(translations.exportedVillages, html);
};
const renderActions = () => {
const exportVillages = document.createElement('button');
exportVillages.innerHTML = translations.export;
exportVillages.addEventListener('click', handleExportVillages);
actionsContainer.appendChild(exportVillages);
};
const handleSpawnSector = (data, sector) => {
TWMap.mapHandler.__spawnSector(data, sector);
colorizeVillages();
};
const handleStart = () => {
TWMap.map.handler.__onClick = TWMap.map.handler.onClick;
TWMap.map.handler.onClick = handleMapClick;
TWMap.mapHandler.__spawnSector = TWMap.map.handler.spawnSector;
TWMap.mapHandler.spawnSector = handleSpawnSector;
button.innerHTML = translations.stopCoordsPicker;
renderActions();
colorizeVillages();
renderGroups();
intervalID = setInterval(saveConfig, 500);
};
const handleStop = () => {
if (typeof TWMap.map.handler.__onClick === 'function') {
TWMap.map.handler.onClick = TWMap.map.handler.__onClick;
}
if (typeof TWMap.map.handler.__spawnSector === 'function') {
TWMap.mapHandler.spawnSector = TWMap.map.handler.__spawnSector;
}
button.innerHTML = translations.startCoordsPicker;
formsContainer.innerHTML = '';
actionsContainer.innerHTML = '';
colorizeVillages('transparent');
if (intervalID) {
clearInterval(intervalID);
}
for (let name in config.groups) {
config.groups[name].villages = [];
}
};
const handleButtonClick = () => {
if (config.started) {
handleStop();
} else {
handleStart();
}
config.started = !config.started;
saveConfig();
};
const colorizeGroupVillages = (name, bgColor = '') => {
config.groups[name].villages.forEach(village => {
setVillageBorder(
village.x,
village.y,
bgColor ? bgColor : config.groups[name].color
);
});
};
const colorizeVillages = (bgColor = '') => {
for (let name in config.groups) {
colorizeGroupVillages(name, bgColor);
}
};
const renderUI = () => {
button = document.createElement('button');
button.style.marginLeft = '5px';
button.innerHTML = config.started
? translations.stopCoordsPicker
: translations.startCoordsPicker;
button.addEventListener('click', handleButtonClick);
container.appendChild(button);
formsContainer = document.createElement('div');
container.parentElement.insertBefore(formsContainer, container.nextSibling);
actionsContainer = document.createElement('div');
container.parentElement.insertBefore(actionsContainer, container.nextSibling);
if (config.started) {
handleStart();
}
};
(function () {
try {
renderUI();
} catch (error) {
console.log('Map Coords Picker', error);
}
})();