Index: binaries/data/mods/public/gui/session/developer_overlay.js =================================================================== --- binaries/data/mods/public/gui/session/developer_overlay.js +++ binaries/data/mods/public/gui/session/developer_overlay.js @@ -0,0 +1,189 @@ +function DeveloperOverlay() +{ + this.commandHeight = 20; + this.commands = [ + { + "label": translate("Control all units"), + "onPress": checked => Engine.PostNetworkCommand({ + "type": "control-all", + "flag": checked + }), + }, + { + "label": translate("Change perspective"), + "onPress": checked => { + g_DevSettings.changePerspective = checked; + selectViewPlayer(g_ViewedPlayer); + }, + }, + { + "label": translate("Display selection state"), + "onPress": checked => { this.displayState = checked; }, + }, + { + "label": translate("Pathfinder overlay"), + "onPress": checked => Engine.GuiInterfaceCall("SetPathfinderDebugOverlay", checked), + }, + { + "label": translate("Obstruction overlay"), + "onPress": checked => Engine.GuiInterfaceCall("SetObstructionDebugOverlay", checked), + }, + { + "label": translate("Unit motion overlay"), + "onPress": checked => { + g_Selection.SetMotionDebugOverlay(checked); + }, + }, + { + "label": translate("Range overlay"), + "onPress": checked => Engine.GuiInterfaceCall("SetRangeDebugOverlay", checked), + }, + { + "label": translate("Bounding box overlay"), + "onPress": checked => Engine.SetBoundingBoxDebugOverlay(checked), + }, + { + "label": translate("Restrict camera"), + "onPress": checked => Engine.GameView_SetConstrainCameraEnabled(checked), + "checked": () => true, + }, + { + "label": translate("Reveal map"), + "onPress": checked => Engine.PostNetworkCommand({ + "type": "reveal-map", + "enable": checked + }), + "checked": () => Engine.GuiInterfaceCall("IsMapRevealed"), + }, + { + "label": translate("Enable time warp"), + "onPress": checked => { + this.timeWarp = checked; + if (checked) + { + messageBox( + 500, 250, + translate("Note: time warp mode is a developer option, and not intended for use over long periods of time. Using it incorrectly may cause the game to run out of memory or crash."), + translate("Time warp mode") + ); + } + Engine.EnableTimeWarpRecording(checked ? 10 : 0); + }, + }, + { + "label": translate("Promote selected units"), + "onPress": checked => Engine.PostNetworkCommand({ + "type": "promote", + "entities": g_Selection.toList() + }), + }, + { + "label": translate("Hierarchical pathfinder overlay"), + "onPress": checked => Engine.GuiInterfaceCall("SetPathfinderHierDebugOverlay", checked), + }, + ]; + + this.displayState = false; + this.timeWarp = false; +} + +DeveloperOverlay.prototype.init = function() +{ + Engine.GetGUIObjectByName("devCommandsOverlay").onPress = this.toggle; + this.layout(); +} + +DeveloperOverlay.prototype.layout = function() +{ + for (let body of Engine.GetGUIObjectByName("dev_commands").children) + body.hidden = true; + + let overlayHeight = 0; + for (let i = 0; i < g_DeveloperOverlay.commands.length; ++i) + { + let command = g_DeveloperOverlay.commands[i]; + + let body = Engine.GetGUIObjectByName("dev_command[" + i + "]"); + let bodySize = body.size; + bodySize.top = i * this.commandHeight; + bodySize.bottom = bodySize.top + this.commandHeight; + body.size = bodySize; + body.hidden = false; + + let label = Engine.GetGUIObjectByName("dev_command_label[" + i + "]"); + label.caption = command.label; + + let checkbox = Engine.GetGUIObjectByName("dev_command_checkbox[" + i + "]"); + checkbox.checked = command.checked && command.checked(); + checkbox.onPress = function() { + command.onPress(checkbox.checked); + }; + + overlayHeight += this.commandHeight; + } + + let overlay = Engine.GetGUIObjectByName("devCommandsOverlay"); + let overlaySize = overlay.size; + overlaySize.bottom = overlaySize.top + overlayHeight; + overlay.size = overlaySize; +} + +DeveloperOverlay.prototype.toggle = function() +{ + if (!g_GameAttributes.settings.CheatsEnabled && !g_IsReplay) + return; + + let devCommands = Engine.GetGUIObjectByName("devCommandsOverlay"); + devCommands.hidden = !devCommands.hidden; + + let message = devCommands.hidden ? + markForTranslation("The Developer Overlay was closed.") : + markForTranslation("The Developer Overlay was opened."); + + // Only players can send the simulation chat command + if (Engine.GetPlayerID() == -1) + submitChatDirectly(message); + else + Engine.PostNetworkCommand({ + "type": "aichat", + "message": message, + "translateMessage": true, + "translateParameters": [], + "parameters": {} + }); +} + +DeveloperOverlay.prototype.update = function() +{ + let debug = Engine.GetGUIObjectByName("debugEntityState"); + + if (!this.displayState) + { + debug.hidden = true; + return; + } + + debug.hidden = false; + + let conciseSimState = clone(GetSimState()); + conciseSimState.players = "<<>>"; + let text = "simulation: " + uneval(conciseSimState); + + let selection = g_Selection.toList(); + if (selection.length) + { + let entState = GetEntityState(selection[0]); + if (entState) + { + let template = GetTemplateData(entState.template); + text += "\n\nentity: {\n"; + for (let k in entState) + text += " " + k + ":" + uneval(entState[k]) + "\n"; + text += "}\n\ntemplate: " + uneval(template); + } + } + + debug.caption = text.replace(/\[/g, "\\["); +} + +var g_DeveloperOverlay = new DeveloperOverlay(); Index: binaries/data/mods/public/gui/session/developer_overlay.xml =================================================================== --- binaries/data/mods/public/gui/session/developer_overlay.xml +++ binaries/data/mods/public/gui/session/developer_overlay.xml @@ -1,156 +1,20 @@