// ==UserScript== // @name Grepolis Resources Manager // @version 1.0_ALPHA // @include /http[s]{0,1}://[a-z]{2}[0-9]{1,2}\.grepolis\.com/game*/ // @include https://*.forum.grepolis.com/* // @require http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js // @require https://code.jquery.com/ui/1.12.1/jquery-ui.js // @description A little handy script to help with resource management and more // @author MajorOrbital // @copyright 2020+ // @grant unsafeWindow // @grant GM_addStyle // @namespace https://greasyfork.org/users/451401 // @downloadURL none // ==/UserScript== //The game window, gamedata can be accessed through this constant. const uw = unsafeWindow; //https://imgur.com/a/WmetAfe //#region CSS GM_addStyle(` :root { --main: #ffe2a2 } #GRM_window { background-color: var(--main); display: none; height: 550px; width: 780px; z-index: 1100; position: absolute; top: 100px; left: 30vw; border: 2px black solid } #GRM_toolbar { height: 30px; border-bottom: 2px black solid; } #GRM_toolbar_list { list-style-type: none; margin: 0; padding-top: 3px; padding-left: 1px; overflow: hidden; top: 10px; } #GRM_title { padding-top: 3px; float: left; width: 40%; text-align: left; } #GRM_building { max-width: 360px; position: relative; left: 10px; } #GRM_buildings { margin-left: 5px; } #GRM_troops_container { margin-left: 5px; } #GRM_close { padding-top: 5px; float: left; } #GRM_gods{ height: 100px; width: 100px; position: relative; top: -415px; left: 50px; } .GRM_toolbar_item { height: 25px; float: left; width: 27%; text-align: center; border-left: 1px solid black; border-right: 1px solid black; border-top: 1px solid black; border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; margin: 1px } #GRM_close_img { margin-left: 10px; } #GRM_population_container{ max-width: 120px; position: relative; left: 5px; bottom: 450px; font-weight: bold; } #GRM_pop_icon{ position: relative; top: 2px; left: 5px; } .GRM_building_image { height: 40px; width: 40px; letter-spacing: -1px; margin: 0; display: inline-grid; } .GRM_building_level { position: relative; bottom: -25px; right: -10px; color: white; max-height: 18px; font-weight: bolder; } .GRM_selector { height: 40px; width: 30px; top: 10px; display: inline; position: relative; } .GRM_troop_input { width: 36px; } .GRM_building_input { width: 35px; } input.invalid { border: 2px solid red; background-color: rgba(128, 0, 0, 0.3) } input.valid { border: 2px solid green; background-color: rgba(0, 128, 0, 0.3) } .GRM_troop_container { max-width: 50px; z-index: 5; } .GRM_special_container { width: 168px; height: 42px; border: 1px solid black; overflow: hidden; /* add this to contain floated children */ } .GRM_special_child { width: 40px; height: 40px; float: left; margin-left: 1px; margin-right: 1px; padding-top: 1px; padding-bottom: 1px; } .GRM_label{ max-width: 450px; margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; font-weight: bold; } .GRM_border{ border: #c78e25; border-width: medium; border-style: solid; } `); //#endregion class Utils { static checkMouseClicked(x, y, coords) { return ( coords.x <= x && x <= coords.x + 30 && coords.y <= y && y <= coords.y + 30 ); } static all_gods() { return "https://i.imgur.com/Kvb5gqn.png"; } static artemis() { return "https://i.imgur.com/yNL9x1M.png"; } static hades() { return "https://i.imgur.com/Via8HPf.png"; } static poseidon() { return "https://i.imgur.com/w2LtW83.png"; } static hera() { return "https://i.imgur.com/eNTFFg1.png"; } static athene() { return "https://i.imgur.com/u8SRGdE.png"; } static zeus() { return "https://i.imgur.com/35HpxKg.png"; } static no_god() { return "https://i.imgur.com/dFBR5Jd.png"; } static max_levels = { main: 25, hide: 10, place: 1, lumber: 40, stoner: 40, ironer: 40, market: 30, docks: 30, barracks: 30, wall: 25, storage: 35, farm: 45, academy: 36, temple: 30 }; static farm_pop = [ 14, 38, 69, 105, 145, 189, 237, 288, 342, 399, 458, 520, 584, 651, 720, 790, 863, 938, 1015, 1094, 1174, 1257, 1341, 1426, 1514, 1602, 1693, 1785, 1878, 1973, 2070, 2168, 2267, 2368, 2470, 2573, 2678, 2784, 2891, 3000, 3109, 3220, 3332, 3446, 3560 ]; static main_cost = [ 1, 3, 6, 9, 13, 17, 21, 25, 30, 35, 40, 46, 52, 58, 64, 70, 77, 84, 91, 98, 106, 113, 121, 129, 137 ]; static resources_cost = [ 1, 2.4, 3.9, 5.7, 5.7, 9.4, 11.4, 13.5, 15.6, 17.8, 20, 22.3, 24.7, 27.1, 29.5, 32, 34.5, 37.1, 39.7, 42.3, 45, 47.6, 50.4, 53.1, 55.9, 58.7, 61.5, 64.4, 67.3, 70.2, 73.1, 76.1, 79.1, 82.1, 85.1, 88.2, 91.3, 94.3, 97.5, 100.6 ]; static barracks_cost = [ 1, 2.5, 4.2, 6.1, 8.1, 10.3, 12.5, 14.9, 17.4, 20, 22.6, 25.3, 28.1, 30.9, 33.8, 36.8, 39.8, 42.8, 46, 49.1, 52.3, 55.6, 58.9, 62.3, 65.7, 69.1, 72.6, 76.1, 79.6, 83.2 ]; static harbour_cost = [ 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120 ]; static cave_cost = [3, 4.2, 5.2, 6, 6.7, 7.3, 7.9, 8.5, 9, 9.5]; static academy_cost = [ 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108 ]; static temple_cost = [ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150 ]; static market_cost = [ 2, 4.3, 6.7, 9.2, 11.7, 14.4, 17, 19.7, 22.4, 25.2, 28, 30.8, 33.6, 36.5, 39.3, 42.2, 45.1, 48.1, 51, 54, 56.9, 59.9, 62.9, 66, 69, 72, 75.1, 78.1, 81.2, 84.3 ]; static wall_cost = [ 2, 4.5, 7.2, 10, 12.9, 16, 19.1, 22.3, 25.6, 28.9, 32.3, 35.7, 39.2, 42.7, 46.3, 49.9, 53.5, 57.2, 60.9, 64.6, 68.4, 72.2, 76, 79.8, 83.7 ]; static boar_img = "https://i.imgur.com/1HUB4xG.jpg"; static envoy_img = "https://i.imgur.com/nbXIVhL.png"; static griffin_img = "https://i.imgur.com/G0TYw28.jpg"; static centaur_img = "https://i.imgur.com/Y954Jv4.png"; static pegasus_img = "https://i.imgur.com/qusNCkM.png"; static harpy_img = "https://i.imgur.com/pCxA9u0.png"; static medusas_img = "https://i.imgur.com/3DdtHrv.png"; static cerberus_img = "https://i.imgur.com/BjLWnrL.png"; static eryn_img = "https://i.imgur.com/1FvJy0t.png"; static cyclops_img = "https://i.imgur.com/E8v5wu9.png"; static hydra_img = "https://i.imgur.com/tbc0PK1.png"; static minotaur_img = "https://i.imgur.com/Lw0vKSU.png"; static manticore_img = "https://i.imgur.com/bik0Jzj.png"; static unit_img = "https://i.imgur.com/xLOtNgs.png"; static lightship_img = "https://i.imgur.com/Y5WorTq.png"; static slow_transporter_img = "https://i.imgur.com/43NVBNT.png"; static bireme_img = "https://i.imgur.com/kLQCM99.png"; static catapult_img = "https://i.imgur.com/oFEOsXo.png"; static demolitionship_img = "https://i.imgur.com/JNfJ3h0.png"; static fast_transporter_img = "https://i.imgur.com/WYCQUZo.png"; static trireme_img = "https://i.imgur.com/0YlGkCP.png"; static colo_img = "https://i.imgur.com/e0W5k39.png"; static getMaxLevel(name) { switch (name) { case "main": return max_levels.main; case "hide": return max_levels.hide; case "place": return max_levels.place; case "lumber": return max_levels.lumber; case "stoner": return max_levels.stoner; case "ironer": return max_levels.ironer; case "market": return max_levels.market; case "docks": return max_levels.docks; case "barracks": return max_levels.barracks; case "wall": return max_levels.wall; case "storage": return max_levels.storage; case "farm": return max_levels.farm; case "academy": return max_levels.academy; case "temple": return max_levels.temple; default: return 1; } } static getSpecialBuilding(specialList) { for (let i in specialList) { if (specialList[i][1] === 1) return specialList[i][0]; } return null; } } class View { constructor() {} addMenuItem() { $("#ui_box > div.nui_main_menu > div.middle > div.content > ul").append( `
  • GRM
  • ` ); } initializeWindow() { $("body").append(`

    Enter the amount of troops you want of each type in here.

    The current maximum possible amount of each troop (+ your choices above)

    0000/0000
    `); } fillGRMWindow(town) { $("#GRM_city_name").text(`${town.getName()}`); const buildings = town.getBuildings().getLevels(); $("#GRM_main_level").text(`${buildings.main}`); $("#GRM_hide_level").text(`${buildings.hide}`); $("#GRM_place_level").text(`${buildings.place}`); $("#GRM_lumber_level").text(`${buildings.lumber}`); $("#GRM_stoner_level").text(`${buildings.stoner}`); $("#GRM_ironer_level").text(`${buildings.ironer}`); $("#GRM_market_level").text(`${buildings.market}`); $("#GRM_docks_level").text(`${buildings.docks}`); $("#GRM_barracks_level").text(`${buildings.barracks}`); $("#GRM_wall_level").text(`${buildings.wall}`); $("#GRM_storage_level").text(`${buildings.storage}`); $("#GRM_farm_level").text(`${buildings.farm}`); $("#GRM_academy_level").text(`${buildings.academy}`); $("#GRM_temple_level").text(`${buildings.temple}`); $("#GRM_main_input").val(`${buildings.main}`); $("#GRM_hide_input").val(`${buildings.hide}`); $("#GRM_place_input").val(`${buildings.place}`); $("#GRM_lumber_input").val(`${buildings.lumber}`); $("#GRM_stoner_input").val(`${buildings.stoner}`); $("#GRM_ironer_input").val(`${buildings.ironer}`); $("#GRM_market_input").val(`${buildings.market}`); $("#GRM_docks_input").val(`${buildings.docks}`); $("#GRM_barracks_input").val(`${buildings.barracks}`); $("#GRM_wall_input").val(`${buildings.wall}`); $("#GRM_storage_input").val(`${buildings.storage}`); $("#GRM_farm_input").val(`${buildings.farm}`); $("#GRM_academy_input").val(`${buildings.academy}`); $("#GRM_temple_input").val(`${buildings.temple}`); var json_data = uw.ITowns.getCurrentTown() .getBuildings() .getBuildings(); var specialList = []; var counter = 0; for (var i in json_data) { if (counter !== 14) { counter++; continue; } specialList.push([i, json_data[i]]); } var special_1 = Utils.getSpecialBuilding(specialList.slice(0, 4)); var special_2 = Utils.getSpecialBuilding(specialList.slice(4)); if (special_1 !== null) { $(`#GRM_${special_1}`) .removeClass("GRM_passive") .addClass("GRM_active") .css( "background", `url('https://gpnl.innogamescdn.com/images/game/main/${special_1}.png')` ); } if (special_2 !== null) { $(`#GRM_${special_2}`) .removeClass("GRM_passive") .addClass("GRM_active") .css( "background", `url('https://gpnl.innogamescdn.com/images/game/main/${special_2}.png')` ); } } changeIcon(god, element) { switch (god) { case "artemis": $(element).prop("src", (Presenter.saved = Utils.artemis())); break; case "athene": $(element).prop("src", (Presenter.saved = Utils.athene())); break; case "poseidon": $(element).prop("src", (Presenter.saved = Utils.poseidon())); break; case "hades": $(element).prop("src", (Presenter.saved = Utils.hades())); break; case "zeus": $(element).prop("src", (Presenter.saved = Utils.zeus())); break; case "hera": $(element).prop("src", (Presenter.saved = Utils.hera())); break; default: $(element).prop("src", (Presenter.saved = Utils.no_god())); } } } class Town { constructor(id, name) { this._id = id; this._name = name; this._buildings = { main: 1, hide: 0, place: 1, lumber: 0, stoner: 0, ironer: 0, market: 0, docks: 0, barracks: 0, wall: 0, storage: 0, farm: 1, academy: 0, temple: 0, theater: 0, thermal: 0, library: 0, lighthouse: 0, tower: 0, statue: 0, oracle: 0, trade_office: 0 }; this._population_boost = 0; this._has_plow = false; } getTotalPopulation() { let farm = Utils.farm_pop[this._buildings.farm - 1]; let thermal = this._buildings.thermal === 1; let total = thermal ? farm * 1.1 + this._population_boost : farm + this._population_boost; total = this._has_plow ? total + 200 : total; return total; } getBuildingCost() {} get id() { return this._id; } get buildings() { return this._buildings; } set buildings(b) { this._buildings = b; } get plow() { return this._has_plow; } /** * @param {boolean} bool */ set plow(bool) { this._has_plow = bool; } get populationBoost() { return this._population_boost; } /** * @param {number} boost */ set populationBoost(boost) { this._population_boost = boost; } } class Model { constructor() { this._towns = []; } initTowns() { uw.ITowns.towns_collection.getTowns().forEach(town => { let temp = new Town(town.attributes.id, town.attributes.name); const t = uw.ITowns.getTown(town.id); temp.buildings = t.getBuildings().getBuildings(); temp.plow = t.getResearches().attributes.plow; temp.populationBoost = t.getPopulationExtra(); temp.getTotalPopulation(); temp.getBuildingCost(); this.towns.push(temp); }); console.log(this._towns); } update() { return; } get towns() { return this._towns; } } class Presenter { static saved = null; static artemis = { x: 17, y: 1 }; static athene = { x: 54, y: 1 }; static zeus = { x: 1, y: 26 }; static poseidon = { x: 17, y: 69 }; static hera = { x: 54, y: 69 }; static hades = { x: 69, y: 26 }; constructor(model, view) { this._model = model; this._view = view; } //uw.ITowns.getCurrentTown() addEventHandlers() { var temp = this; $("#GRM_button").on("click", function() { if (temp._model.towns.length === 0) { temp._model.initTowns(); } temp.openWindow(uw.ITowns.getCurrentTown()); }); $("#GRM_window").draggable(); $("#GRM_close_img").on("click", function() { $("#GRM_window").css("display", "none"); }); $(".GRM_input_building").each(function() { $(this).on("input", function() { var input = $(this); var value = input.val(); var attr_name = input.attr("name"); var name = attr_name.substring(0, attr_name.length - 6); var max = Utils.getMaxLevel(name); let int = parseInt(value); if (isNaN(parseInt(int)) || int < 0 || int > max) { input.removeClass("valid").addClass("invalid"); } else { input.removeClass("invalid").addClass("valid"); } this._model.update(); }); }); $(".GRM_special_child").each(function() { $(this).on("click", function() { const el = $(this).first(); const name = el.attr("id").substr(4); const parent = el.parent(); if (el.hasClass("GRM_active")) { el.removeClass("GRM_active").addClass("GRM_passive"); el.css( "background", `url('https://gpnl.innogamescdn.com/images/game/main/${name}_passive.png')` ); } else if (el.hasClass("GRM_passive")) { console.log("clicked a passive"); const active_el = parent.children(".GRM_active").first(); if (active_el.length !== 0) { const active_name = active_el.attr("id").substr(4); active_el.removeClass("GRM_active").addClass("GRM_passive"); active_el.css( "background", `url('https://gpnl.innogamescdn.com/images/game/main/${active_name}_passive.png')` ); } el.removeClass("GRM_passive").addClass("GRM_active"); el.css( "background", `url('https://gpnl.innogamescdn.com/images/game/main/${name}.png')` ); } }); }); $("#GRM_gods") .hover( function() { Presenter.saved = $(this).prop("src"); $(this).prop("src", Utils.all_gods()); }, function() { $(this).prop("src", Presenter.saved); } ) .click(function(e) { var parentOffset = $(this).offset(); var relX = e.pageX - parentOffset.left; var relY = e.pageY - parentOffset.top; if (Utils.checkMouseClicked(relX, relY, Presenter.artemis)) { temp._view.changeIcon("artemis", this); } if (Utils.checkMouseClicked(relX, relY, Presenter.athene)) { temp._view.changeIcon("athene", this); } if (Utils.checkMouseClicked(relX, relY, Presenter.zeus)) { temp._view.changeIcon("zeus", this); } if (Utils.checkMouseClicked(relX, relY, Presenter.hades)) { temp._view.changeIcon("hades", this); } if (Utils.checkMouseClicked(relX, relY, Presenter.poseidon)) { temp._view.changeIcon("poseidon", this); } if (Utils.checkMouseClicked(relX, relY, Presenter.hera)) { temp._view.changeIcon("hera", this); } }); } openWindow(town) { this._view.fillGRMWindow(town); $("#GRM_window").css("display", "block"); } } startup(); function startup() { "use strict"; let view = new View(); let model = new Model(); let presenter = new Presenter(model, view); view.addMenuItem(); view.initializeWindow(); presenter.addEventHandlers(); }