diff --git a/GrepolisRemoteControl.user.js b/GrepolisRemoteControl.user.js index e1da60a..eb5876c 100644 --- a/GrepolisRemoteControl.user.js +++ b/GrepolisRemoteControl.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Grepolis Remote Control // @namespace http://tampermonkey.net/ -// @version 3.5.5 +// @version 3.5.6 // @description Polls grepo.haunter-pets.top for remote commands and executes them in-game (Multi-Player) // @author Dimitrios // @match https://*.grepolis.com/game/* @@ -529,31 +529,71 @@ return { ok: false, msg: 'Farm collections not loaded yet — open island view first' }; } - // Build polis list: one town per island, using MM (all towns, not just visible) - const islandsSeen = new Set(); - const polisList = []; + // Build island groups using MM (all towns, not just visible) + const islandTownsMap = {}; // island_id -> [town_id1, town_id2] try { const allTowns = uw.MM.getCollections().Town[0].models; for (const town of allTowns) { const { on_small_island, island_id, id } = town.attributes; if (on_small_island) continue; - if (!islandsSeen.has(island_id)) { - islandsSeen.add(island_id); - polisList.push(id); - } + if (!islandTownsMap[island_id]) islandTownsMap[island_id] = []; + islandTownsMap[island_id].push(id); } } catch (e) { return { ok: false, msg: `Cannot build town list: ${e.message}` }; } + const islandList = Object.keys(islandTownsMap); - log(`Farm: processing ${polisList.length} islands with option=${option}`); + log(`Farm: processing ${islandList.length} islands with option=${option}`); let claimed = 0; let skipped = 0; let errors = 0; - for (let i = 0; i < polisList.length; i++) { - const town_id = polisList[i]; + for (let i = 0; i < islandList.length; i++) { + const island_id = islandList[i]; + const townIds = islandTownsMap[island_id]; + + let selected_town_id = null; + let lowest_total_res = Infinity; + + for (const t_id of townIds) { + const t = uw.ITowns?.towns?.[t_id]; + if (!t) continue; + + let storageCapacity = t.getStorageCapacity?.() || 0; + if (!storageCapacity) { + const buildings = t.buildings?.()?.attributes || {}; + const storageLevel = buildings.storage ?? 0; + const gd = uw.GameData?.buildingData?.storage; + storageCapacity = gd?.max_storage?.[storageLevel] || gd?.storage?.[storageLevel] || 0; + } + + const res = t.resources?.() || {}; + const w = res.wood || 0; + const s = res.stone || 0; + const ir = res.iron || 0; + + // If completely full (all 3 resources >= max storage), skip this town + if (storageCapacity > 0 && w >= storageCapacity && s >= storageCapacity && ir >= storageCapacity) { + continue; + } + + // Pick town with most space (lowest total resources) + const total_res = w + s + ir; + if (total_res < lowest_total_res) { + lowest_total_res = total_res; + selected_town_id = t_id; + } + } + + if (!selected_town_id) { + log(`Farm: Skipping island ${island_id} (All towns are 100% full)`); + skipped++; + continue; + } + + const town_id = selected_town_id; const town = uw.ITowns?.towns?.[town_id]; if (!town) { skipped++; continue; } @@ -604,7 +644,7 @@ try { uw.WMap.removeFarmTownLootCooldownIconAndRefreshLootTimers(); } catch (e) { } // Random between-island delay: 30s – 90s (only if more islands remain) - if (i < polisList.length - 1) { + if (i < islandList.length - 1) { const gap = randInt(30000, 90000); log(`Farm: island done. Waiting ${(gap / 1000).toFixed(0)}s before next island...`); await sleep(gap);