recruit troop rehaul
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name Grepolis Remote Control
|
||||
// @namespace http://tampermonkey.net/
|
||||
// @version 2.0
|
||||
// @version 2.1
|
||||
// @description Polls grepo.haunter-pets.top for remote commands and executes them in-game
|
||||
// @author Dimitrios
|
||||
// @match https://*.grepolis.com/game/*
|
||||
@@ -160,6 +160,49 @@
|
||||
if (r) researches = r.attributes ?? (typeof r === 'object' ? r : {});
|
||||
} catch (e) { log(`[Debug] town.researches() failed: ${e}`); }
|
||||
|
||||
// ---- Unit Data (Costs & Dependencies) -------------------------------
|
||||
let unitDataMap = {};
|
||||
try {
|
||||
const gdUnits = uw.GameData?.units || {};
|
||||
|
||||
for (const u in gdUnits) {
|
||||
if (u === 'militia') continue;
|
||||
|
||||
const reqBuildings = gdUnits[u].building_dependencies || {};
|
||||
const reqResearch = gdUnits[u].research_dependencies || [];
|
||||
|
||||
let missing_deps = {};
|
||||
for (const reqB in reqBuildings) {
|
||||
if ((buildings[reqB] || 0) < reqBuildings[reqB]) {
|
||||
missing_deps[reqB] = { name: reqB, needed_level: reqBuildings[reqB] };
|
||||
}
|
||||
}
|
||||
for (const reqR of reqResearch) {
|
||||
if (!researches[reqR]) {
|
||||
missing_deps[reqR] = { name: reqR, needed_level: 'Έρευνα' };
|
||||
}
|
||||
}
|
||||
|
||||
const cost = gdUnits[u].resources || {};
|
||||
const w = cost.wood || 0;
|
||||
const s = cost.stone || 0;
|
||||
const i = cost.iron || 0;
|
||||
|
||||
let enough = true;
|
||||
if (res.wood < w || res.stone < s || res.iron < i) enough = false;
|
||||
|
||||
unitDataMap[u] = {
|
||||
wood: w,
|
||||
stone: s,
|
||||
iron: i,
|
||||
pop: gdUnits[u].population || 0,
|
||||
build_time: gdUnits[u].build_time || 0,
|
||||
enough_resources: enough,
|
||||
missing_dependencies: missing_deps
|
||||
};
|
||||
}
|
||||
} catch (e) { log(`Failed to gather unit data: ${e}`); }
|
||||
|
||||
// ---- Extra town flags -----------------------------------------------
|
||||
let has_premium = false;
|
||||
let bonuses = {};
|
||||
@@ -184,6 +227,7 @@
|
||||
units: unitsObj,
|
||||
buildingOrder: buildQueue,
|
||||
buildData: buildDataMap,
|
||||
unitData: unitDataMap,
|
||||
researches,
|
||||
has_premium,
|
||||
bonuses,
|
||||
|
||||
@@ -57,6 +57,7 @@ def get_towns():
|
||||
'god': d.get('god', None),
|
||||
'build_queue': d.get('buildingOrder', []),
|
||||
'build_data': d.get('buildData', {}),
|
||||
'unit_data': d.get('unitData', {}),
|
||||
'researches': d.get('researches', {}),
|
||||
'has_premium': d.get('has_premium', False),
|
||||
'bonuses': d.get('bonuses', {}),
|
||||
|
||||
@@ -12,6 +12,7 @@ window.fetchTowns = async function() {
|
||||
if (window.selectedTownId) {
|
||||
window.renderBuildQueuePreview();
|
||||
window.renderBuildingDropdown();
|
||||
window.renderUnitDropdown();
|
||||
window.renderTownDetails();
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -114,10 +115,33 @@ window.sendCommand = async function() {
|
||||
|
||||
payload = { building_id };
|
||||
} else {
|
||||
payload = {
|
||||
unit_id: document.getElementById('unit-select').value,
|
||||
amount: parseInt(document.getElementById('recruit-amount').value) || 1,
|
||||
};
|
||||
const unit_id = document.getElementById('unit-select').value;
|
||||
const amount = parseInt(document.getElementById('recruit-amount').value) || 1;
|
||||
const uData = town.unit_data?.[unit_id];
|
||||
|
||||
// UI Validation logic
|
||||
if (uData) {
|
||||
const missingDeps = uData.missing_dependencies || {};
|
||||
const missingKeys = Object.keys(missingDeps);
|
||||
|
||||
// 1. Popup if dependencies are lacking
|
||||
if (missingKeys.length > 0) {
|
||||
let msg = '⚠ ΑΔΥΝΑΤΗ Η ΕΚΠΑΙΔΕΥΣΗ: Λείπουν προϋποθέσεις!\n\nΑπαιτείται:\n';
|
||||
for (const k of missingKeys) {
|
||||
msg += `- ${missingDeps[k].name || k} (Επίπεδο ${missingDeps[k].needed_level || '1'})\n`;
|
||||
}
|
||||
return alert(msg);
|
||||
}
|
||||
|
||||
// 2. Confirmation if resources are lacking for 1x
|
||||
if (uData.enough_resources === false) {
|
||||
if (!confirm(`❌ Δεν έχετε αρκετούς πόρους για 1x ${unit_id}!\n\nΘέλετε να προστεθεί στην ουρά αναμονής; Το σύστημα θα εκπαιδεύσει τον στρατό μόλις συγκεντρωθούν οι πόροι.`)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload = { unit_id, amount };
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -74,6 +74,68 @@ window.renderBuildingDropdown = function() {
|
||||
}
|
||||
};
|
||||
|
||||
window.renderUnitDropdown = function() {
|
||||
const town = window.getSelectedTown();
|
||||
if (!town) return;
|
||||
const uSelect = document.getElementById('unit-select');
|
||||
const uData = town.unit_data || {};
|
||||
|
||||
const currentVal = uSelect.value;
|
||||
uSelect.innerHTML = '';
|
||||
|
||||
for (const [key, nameGr] of Object.entries(window.UNIT_NAMES_GR)) {
|
||||
if (key === 'militia') continue;
|
||||
|
||||
const data = uData[key];
|
||||
let text = `${nameGr}`;
|
||||
|
||||
if (data) {
|
||||
const w = window.fmt(data.wood || 0);
|
||||
const st = window.fmt(data.stone || 0);
|
||||
const i = window.fmt(data.iron || 0);
|
||||
const pop = data.pop || 0;
|
||||
|
||||
// Unit build_time is usually raw seconds in GameData
|
||||
let t = data.build_time || 0;
|
||||
let tStr = `${t}s`;
|
||||
if (t > 60) {
|
||||
let m = Math.floor(t / 60);
|
||||
let s = t % 60;
|
||||
tStr = `${m}m ${s}s`;
|
||||
}
|
||||
|
||||
const costStr = `Ξ:${w} Π:${st} Α:${i} 🧔:${pop} · ⏱ ${tStr}`;
|
||||
|
||||
const missingKeys = data.missing_dependencies ? Object.keys(data.missing_dependencies) : [];
|
||||
const isLocked = missingKeys.length > 0;
|
||||
|
||||
const option = document.createElement('option');
|
||||
option.value = key;
|
||||
|
||||
if (isLocked) {
|
||||
option.textContent = `${text} — 🔒 Κλειδωμένο`;
|
||||
option.style.color = '#ff4444';
|
||||
} else if (data.enough_resources === false) {
|
||||
option.textContent = `${text} — ❌ ${costStr} (Λείπουν Πόροι 1x)`;
|
||||
option.style.color = '#aa5555';
|
||||
} else {
|
||||
option.textContent = `${text} — ✅ ${costStr}`;
|
||||
}
|
||||
|
||||
uSelect.appendChild(option);
|
||||
} else {
|
||||
const option = document.createElement('option');
|
||||
option.value = key;
|
||||
option.textContent = text;
|
||||
uSelect.appendChild(option);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentVal && Array.from(uSelect.options).some(o => o.value === currentVal)) {
|
||||
uSelect.value = currentVal;
|
||||
}
|
||||
};
|
||||
|
||||
window.renderBuildQueuePreview = function() {
|
||||
const town = window.getSelectedTown();
|
||||
const el = document.getElementById('build-queue-preview');
|
||||
|
||||
@@ -41,6 +41,7 @@ window.selectTown = function(id) {
|
||||
|
||||
window.renderBuildQueuePreview();
|
||||
window.renderBuildingDropdown();
|
||||
window.renderUnitDropdown();
|
||||
window.renderTownDetails();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user