Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Cheat.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Cheat.js (revision 26956) +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Cheat.js (revision 26957) @@ -1,206 +1,204 @@ function Cheat(input) { if (input.player < 0) return; const cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); const playerEnt = cmpPlayerManager.GetPlayerByID(input.player); if (playerEnt == INVALID_ENTITY) return; const cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player); if (!cmpPlayer?.GetCheatsEnabled()) return; const cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); switch(input.action) { case "addresource": if (isNaN(input.parameter)) return; cmpPlayer.AddResource(input.text, input.parameter); return; case "revealmap": Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).SetLosRevealAll(-1, true); return; case "maxpopulation": cmpPlayer.SetPopulationBonuses((cmpPlayerManager.GetMaxWorldPopulation() || cmpPlayer.GetMaxPopulation()) + 500); return; case "changemaxpopulation": { Engine.QueryInterface(SYSTEM_ENTITY, IID_ModifiersManager).AddModifiers("cheat/maxpopulation", { "Player/MaxPopulation": [{ "affects": ["Player"], "add": 500 }], }, playerEnt); return; } case "convertunit": if (isNaN(input.parameter)) return; const playerID = (input.parameter > -1 && QueryPlayerIDInterface(input.parameter) || cmpPlayer).GetPlayerID(); for (const ent of input.selected) Engine.QueryInterface(ent, IID_Ownership)?.SetOwner(playerID); return; case "killunits": for (const ent of input.selected) { const cmpHealth = Engine.QueryInterface(ent, IID_Health); if (cmpHealth) cmpHealth.Kill(); else Engine.DestroyEntity(ent); } return; case "defeatplayer": if (isNaN(input.parameter)) return; QueryPlayerIDInterface(input.parameter)?.SetState("defeated", markForTranslation("%(player)s has been defeated (cheat).") ); return; case "createunits": { if (isNaN(input.player) || isNaN(input.parameter)) return; const cmpTrainer = input.selected.length && Engine.QueryInterface(input.selected[0], IID_Trainer); if (!cmpTrainer) { cmpGuiInterface.PushNotification({ "type": "text", "players": [input.player], "message": markForTranslation("You need to select a building that trains units."), "translateMessage": true }); return; } let owner = input.player; const cmpOwnership = Engine.QueryInterface(input.selected[0], IID_Ownership); if (cmpOwnership) owner = cmpOwnership.GetOwner(); for (let i = 0; i < Math.min(input.parameter, cmpPlayer.GetMaxPopulation() - cmpPlayer.GetPopulationCount()); ++i) { const batch = new cmpTrainer.Item(input.templates[i % input.templates.length], 1, input.selected[0], null); batch.player = owner; batch.Finish(); // ToDo: If not able to spawn, cancel the batch. } return; } case "fastactions": { const cmpModifiersManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ModifiersManager); if (cmpModifiersManager.HasAnyModifier("cheat/fastactions", playerEnt)) cmpModifiersManager.RemoveAllModifiers("cheat/fastactions", playerEnt); else cmpModifiersManager.AddModifiers("cheat/fastactions", { "Cost/BuildTime": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }], "ResourceGatherer/BaseSpeed": [{ "affects": [["Structure"], ["Unit"]], "multiply": 1000 }], "Pack/Time": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }], "Upgrade/Time": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }], "Researcher/TechCostMultiplier/time": [{ "affects": [["Structure"], ["Unit"]], "multiply": 0.01 }] }, playerEnt); return; } case "changephase": { const cmpTechnologyManager = Engine.QueryInterface(playerEnt, IID_TechnologyManager); if (!cmpTechnologyManager) return; // store the phase we want in the next input parameter let parameter; if (!cmpTechnologyManager.IsTechnologyResearched("phase_town")) parameter = "phase_town"; else if (!cmpTechnologyManager.IsTechnologyResearched("phase_city")) parameter = "phase_city"; else return; - if (TechnologyTemplates.Has(parameter + "_" + cmpPlayer.civ)) - parameter += "_" + cmpPlayer.civ; - else - parameter += "_generic"; + const civ = Engine.QueryInterface(playerEnt, IID_Identity).GetCiv(); + parameter += TechnologyTemplates.Has(parameter + "_" + civ) ? "_" + civ : "_generic"; Cheat({ "player": input.player, "action": "researchTechnology", "parameter": parameter, "selected": input.selected }); return; } case "researchTechnology": { if (!input.parameter.length) return; let techname = input.parameter; const cmpTechnologyManager = Engine.QueryInterface(playerEnt, IID_TechnologyManager); if (!cmpTechnologyManager) return; // check, if building is selected if (input.selected[0]) { const cmpResearcher = Engine.QueryInterface(input.selected[0], IID_Researcher); if (cmpResearcher) { // try to spilt the input const tmp = input.parameter.split(/\s+/); const number = +tmp[0]; const pair = tmp.length > 1 && (tmp[1] == "top" || tmp[1] == "bottom") ? tmp[1] : "top"; // use top as default value // check, if valid number was parsed. if (!isNaN(number)) { // get name of tech const techs = cmpResearcher.GetTechnologiesList(); if (number > 0 && number <= techs.length) { const tech = techs[number-1]; if (!tech) return; // get name of tech if (tech.pair) techname = tech[pair]; else techname = tech; } else return; } } } if (TechnologyTemplates.Has(techname)) cmpTechnologyManager.ResearchTechnology(techname); return; } case "metaCheat": for (const resource of Resources.GetCodes()) Cheat({ "player": input.player, "action": "addresource", "text": resource, "parameter": input.parameter }); Cheat({ "player": input.player, "action": "maxpopulation" }); Cheat({ "player": input.player, "action": "changemaxpopulation" }); Cheat({ "player": input.player, "action": "fastactions" }); for (let i = 0; i < 2; ++i) Cheat({ "player": input.player, "action": "changephase", "selected": input.selected }); return; case "playRetro": const play = input.parameter.toLowerCase() != "off"; cmpGuiInterface.PushNotification({ "type": "play-tracks", "tracks": play && input.parameter.split(" "), "lock": play, "players": [input.player] }); return; default: warn("Cheat '" + input.action + "' is not implemented"); return; } } Engine.RegisterGlobal("Cheat", Cheat);