diff --git a/src/Mods/SecExp/js/buildingsJS.js b/src/Mods/SecExp/js/buildingsJS.js index 505208bf5a8933d1ba861c1935e1adf1da0cdd7a..0b6650b04f058adb136337d1e9d8847fcdd34d67 100644 --- a/src/Mods/SecExp/js/buildingsJS.js +++ b/src/Mods/SecExp/js/buildingsJS.js @@ -294,7 +294,7 @@ App.SecExp.weapManu = (function() { Init:Init, BC:BC }; - + function Init() { V.SecExp.buildings.weapManu = { menials: 0, @@ -353,7 +353,7 @@ App.SecExp.weapManu = (function() { V.SecExp.buildings.weapManu.upgrades.human.morale = V.SecExp.buildings.weapManu.upgrades.human.morale || 0; V.SecExp.buildings.weapManu.upgrades.current = V.SecExp.buildings.weapManu.upgrades.current || {time: 0}; - if (V.currentUpgrade) { + if (jsDef(V.currentUpgrade)) { V.SecExp.buildings.weapManu.upgrades.current = {ID: V.currentUpgrade.ID, time: V.currentUpgrade.time}; } } diff --git a/src/Mods/SecExp/js/secExp.js b/src/Mods/SecExp/js/secExp.js index c035d0501039da78b0c417c3182c138018118cde..25a3d310cd57f339adbe56e2a192712163f74031 100644 --- a/src/Mods/SecExp/js/secExp.js +++ b/src/Mods/SecExp/js/secExp.js @@ -56,9 +56,9 @@ App.SecExp.generalInit = function(){ allowSlavePrestige: 1, force: 0, showStats: 0, + frequency: 1, major: { enabled: 0, - frequency: 1, gameOver: 1, mult: 1, force: 0 @@ -91,6 +91,7 @@ App.SecExp.generalInit = function(){ waterway: 0 }, units: { + bots: {}, slaves: { created: 0, casualties: 0, @@ -150,9 +151,7 @@ App.SecExp.generalInit = function(){ pharaonTradition: 0, } }, - smilingMan: { - progress : 0, - } + smilingMan: { progress : 0 } }); App.SecExp.initTrade(); diff --git a/src/Mods/SecExp/js/secExpBC.js b/src/Mods/SecExp/js/secExpBC.js index d6dddc8d68c99d196618ddfd52c5aea33ee7a161..8884e43a3ef66354761d58724b8b9c021c3ff30d 100644 --- a/src/Mods/SecExp/js/secExpBC.js +++ b/src/Mods/SecExp/js/secExpBC.js @@ -80,8 +80,8 @@ App.SecExp.generalBC = function() { active: V.secBots.active || V.arcologyUpgrade.drones > 0 ? 1 : 0, ID: -1, isDeployed: V.secBots.isDeployed || 0, - troops: Math.max(V.secBots.troops, V.arcologyUpgrade.drones > 0 ? 30 : 0), - maxTroops: Math.max(V.secBots.maxTroops, V.arcologyUpgrade.drones > 0 ? 30 : 0) + troops: Math.max(V.secBots.troops || 0, V.arcologyUpgrade.drones > 0 ? 30 : 0), + maxTroops: Math.max(V.secBots.maxTroops || 0, V.arcologyUpgrade.drones > 0 ? 30 : 0) }); /* if (V.secBots) { V.SecExp.units.bots = V.secBots; @@ -161,7 +161,7 @@ App.SecExp.generalBC = function() { V.SecExp.core.security = V.SecExp.security.cap; delete V.SecExp.security; } - V.SecExp.core.totalKills = V.SecExp.core.totalKills || V.totalKills || 0; + V.SecExp.core.totalKills = +V.SecExp.core.totalKills || V.totalKills || 0; if (V.week === 1 || !jsDef(V.SecExp.core.crimeLow)) { V.SecExp.core.crimeLow = 30; @@ -306,37 +306,25 @@ App.SecExp.generalBC = function() { /* V.SecExp.rebellions.repairTime = V.SecExp.rebellions.repairTime || {}; V.SecExp.rebellions.repairTime.waterway = V.SecExp.rebellions.repairTime.waterway || 0; - if (V.garrison && V.garrison.waterwayTime) { - V.SecExp.rebellions.repairTime.waterway = V.garrison.waterwayTime; - } V.SecExp.rebellions.repairTime.assistant = V.SecExp.rebellions.repairTime.assistant || 0; - if (V.garrison && V.garrison.assistantTime) { - V.SecExp.rebellions.repairTime.assistant = V.garrison.assistantTime; - } V.SecExp.rebellions.repairTime.reactor = V.SecExp.rebellions.repairTime.reactor || 0; - if (V.garrison && V.garrison.reactorTime) { - V.SecExp.rebellions.repairTime.reactor = V.garrison.reactorTime; - } V.SecExp.rebellions.repairTime.arc = V.SecExp.rebellions.repairTime.arc || 0; - if (V.arcRepairTime) { + if (jsDef(V.garrison)) { + V.SecExp.rebellions.repairTime.waterway = V.garrison.waterwayTime; + V.SecExp.rebellions.repairTime.assistant = V.garrison.assistantTime; + V.SecExp.rebellions.repairTime.reactor = V.garrison.reactorTime; V.SecExp.rebellions.repairTime.arc = V.arcRepairTime; } V.SecExp.rebellions.garrison = V.SecExp.rebellions.garrison || {}; V.SecExp.rebellions.garrison.penthouse = V.SecExp.rebellions.garrison.penthouse || 0; - if (V.garrison && V.garrison.penthouse) { - V.SecExp.rebellions.garrison.penthouse = V.garrison.penthouse; - } V.SecExp.rebellions.garrison.reactor = V.SecExp.rebellions.garrison.reactor || 0; - if (V.garrison && V.garrison.reactor) { - V.SecExp.rebellions.garrison.reactor = V.garrison.reactor; - } V.SecExp.rebellions.garrison.assistant = V.SecExp.rebellions.garrison.assistant || 0; - if (V.garrison && V.garrison.assistant) { - V.SecExp.rebellions.garrison.assistant = V.garrison.assistant; - } V.SecExp.rebellions.garrison.waterway = V.SecExp.rebellions.garrison.waterway || 0; - if (V.garrison && V.garrison.waterway) { + if (jsDef(V.garrison)) { + V.SecExp.rebellions.garrison.penthouse = V.garrison.penthouse; + V.SecExp.rebellions.garrison.reactor = V.garrison.reactor; + V.SecExp.rebellions.garrison.assistant = V.garrison.assistant; V.SecExp.rebellions.garrison.waterway = V.garrison.waterway; } */ diff --git a/src/Mods/SecExp/widgets/miscSecExpWidgets.tw b/src/Mods/SecExp/widgets/miscSecExpWidgets.tw index 23f8b40b0e77037329060c751cf29dd2282e3aad..f2e993457f03834f477748497bd40754410bd13d 100644 --- a/src/Mods/SecExp/widgets/miscSecExpWidgets.tw +++ b/src/Mods/SecExp/widgets/miscSecExpWidgets.tw @@ -1,9 +1,6 @@ :: miscSecExpWidgets [widget nobr] <<widget "fixBrokenStats">> - <<if !Number.isInteger($SecExp.core.totalKills)>> - <<set $SecExp.core.totalKills = 0>> - <</if>> <<if !Number.isInteger($mercTotalCasualties)>> <<set $mercTotalCasualties = 0>> <</if>> diff --git a/src/events/scheduled/murderAttempt.js b/src/events/scheduled/murderAttempt.js index c5bd773daedd5c0bb286e9879c90e91a33799b3d..83612903fe120416693f6673c4ee58fda807d95a 100644 --- a/src/events/scheduled/murderAttempt.js +++ b/src/events/scheduled/murderAttempt.js @@ -365,7 +365,7 @@ App.Events.murderAttempt = function() { function gameOver(fragment) { App.Events.addParagraph(fragment, ["<span class='bold'>GAME OVER</span>"]); V.ui = "start"; - UIBar.update(); + App.Utils.scheduleSidebarRefresh(); } function endEvent() { @@ -377,7 +377,7 @@ App.Events.murderAttempt = function() { fragment.append(App.UI.DOM.passageLink("Continue", nextPassage)); V.nextButton = "Continue"; V.nextLink = nextPassage; - UIBar.update(); + App.Utils.scheduleSidebarRefresh(); } }; diff --git a/src/gui/theming.js b/src/gui/theming.js index 903f0ea5fe7279c9bb21f6bf59b9c30561993427..bd49204cca988acc9a6c4613f8e5111696e18ea9 100644 --- a/src/gui/theming.js +++ b/src/gui/theming.js @@ -2,12 +2,12 @@ App.UI.Theme = (function() { // NOTE: Due to browser limitations it is not possible to retrieve the path of selected files, only the filename. // We therefore expect all files to be located in the same directory as the HTML file. Selected files from somewhere // else will simply not be loaded or if a file in the correct place has the same name, it will be loaded instead. + /** @type {HTMLLinkElement} */ let currentThemeElement = null; - let devTheme = null; return { selector: selector, - devTheme: reloadDevTheme, + loadTheme: loadTheme, init: loadFromStorage, }; @@ -22,26 +22,37 @@ App.UI.Theme = (function() { selector.accept = ".css"; div.append(selector); - div.append(" ", App.UI.DOM.link("Apply", () => { - unset(); + div.append(" ", App.UI.DOM.link("Load", () => { if (selector.files.length > 0) { const themeFile = selector.files[0]; - set(themeFile.name); + loadTheme(themeFile.name); } - }), " ", App.UI.DOM.link("Unload", unset)); + }), " ", App.UI.DOM.link("Unload", unloadTheme)); return div; } /** - * @param {string} filename or filepath relative to the HTML file. + * @param {string} [filename] or filepath relative to the HTML file. */ - function set(filename) { - SugarCube.storage.set("theme", filename); - currentThemeElement = newTheme(filename); + function loadTheme(filename) { + unloadTheme(); + if (filename) { + SugarCube.storage.set("theme", filename); + currentThemeElement = document.createElement("link"); + currentThemeElement.setAttribute("rel", "stylesheet"); + currentThemeElement.setAttribute("type", "text/css"); + currentThemeElement.setAttribute("href", `./${filename}`); + // make it unique to force reloading instead of using the cached version + currentThemeElement.href += `?id=${Date.now()}`; + document.head.appendChild(currentThemeElement); + } } - function unset() { + /** + * Unloads the current theme + */ + function unloadTheme() { if (currentThemeElement !== null) { document.head.removeChild(currentThemeElement); currentThemeElement = null; @@ -49,41 +60,13 @@ App.UI.Theme = (function() { } } + /** + * Loads a saved theme from browser storage + */ function loadFromStorage() { const file = SugarCube.storage.get("theme"); if (file !== null) { - set(file); - } - } - - /** - * Unloads current dev theme and loads new theme if specified. - * @param {string} [filename] - */ - function reloadDevTheme(filename) { - if (devTheme !== null) { - document.head.removeChild(devTheme); - devTheme = null; - } - - if (filename !== undefined) { - devTheme = newTheme(filename); + loadTheme(file); } } - - /** - * Creates an new theme and adds it to the head element - * @param {string} filename - * @returns {HTMLLinkElement} - */ - function newTheme(filename) { - const theme = document.createElement("link"); - theme.setAttribute("rel", "stylesheet"); - theme.setAttribute("type", "text/css"); - theme.setAttribute("href", `./${filename}`); - // make it unique to force reloading instead of using the cached version - theme.href += `?id=${Date.now()}`; - document.head.appendChild(theme); - return theme; - } })(); diff --git a/src/gui/tooltips.js b/src/gui/tooltips.js index b3856abfd80ece48bb3af64d7d3712209eda1203..86079833941412672219a2054ce4afbd31db509c 100644 --- a/src/gui/tooltips.js +++ b/src/gui/tooltips.js @@ -1,4 +1,4 @@ -(function() { +App.UI.updateSidebarTooltips = (function() { // The performance impact is around O(tooltips * nodes), with large passages (main, slave assignment report) adding // tooltips could potentially take a significant amount of time when there are many potential tooltips. const tooltips = { @@ -46,10 +46,16 @@ } } + function updateSidebar() { + addTooltips(document.getElementById("story-caption")); + } + // passage - $(document).on(':passagerender', e => addTooltips(e.content)); + $(document).on(":passagerender", e => addTooltips(e.content)); // story caption - $(document).on(':passageend', () => addTooltips(document.getElementById("story-caption"))); + $(document).on(":passageend", updateSidebar); // dialog - $(document).on(':dialogopening', e => addTooltips(e.target)); + $(document).on(":dialogopening", e => addTooltips(e.target)); + + return updateSidebar; })(); diff --git a/src/js/utilsFC.js b/src/js/utilsFC.js index ef28e4bdb902fcda9ff44cec070361bf4f9ee8b6..e33d9c8e2e7e349085711420d007cbd300c8869e 100644 --- a/src/js/utilsFC.js +++ b/src/js/utilsFC.js @@ -2237,7 +2237,7 @@ globalThis.slaveSkillIncrease = function(targetSkill, slave, skillIncrease = 1) if (isleadershipRole()) { skillDec = `${capFirstChar(targetSkill)} skills.`; } - + if (slave.skill[targetSkill] + skillIncrease > 10) { r = `<span class="green">${He} now has basic ${skillDec}</span>`; switch(targetSkill) { @@ -2267,7 +2267,7 @@ globalThis.slaveSkillIncrease = function(targetSkill, slave, skillIncrease = 1) if (isleadershipRole()) { skillDec = `skill as a ${capFirstChar(targetSkill)}.`; } - + if (slave.skill.oral + skillIncrease > 30) { r = `<span class="green">${He} now has some ${skillDec}</span>`; switch(targetSkill) { @@ -2297,7 +2297,7 @@ globalThis.slaveSkillIncrease = function(targetSkill, slave, skillIncrease = 1) if (isleadershipRole()) { skillDec = `expert ${capFirstChar(targetSkill)}.`; } - + if (slave.skill[targetSkill] + skillIncrease > 60) { r = `<span class="green">${He} is now an ${skillDec}</span>`; switch(targetSkill) { @@ -2327,7 +2327,7 @@ globalThis.slaveSkillIncrease = function(targetSkill, slave, skillIncrease = 1) if (isleadershipRole()) { skillDec = `is now a masterful ${capFirstChar(targetSkill)}.`; } - + if (slave.skill[targetSkill] + skillIncrease >= 100) { r = `<span class="green">${He} ${skillDec}</span>`; switch(targetSkill) { @@ -2976,9 +2976,9 @@ globalThis.deflate = function(slave) { SetBellySize(slave); }; -/** Notify the game that the sidbar needs to be refreshed as soon as possible, but do not do it immediately. - * This allows us to call this function repeatedly without impacting performance (for example, from repX() and cashX()). - * The game will redraw the sidebar exactly once, as soon as all the scripts have finished executing. +/** Notify the game that the sidebar needs to be refreshed as soon as possible, but do not do it immediately. + * This allows us to call this function repeatedly without impacting performance (for example, from repX() and cashX()). + * The game will redraw the sidebar exactly once, as soon as all the scripts have finished executing. */ App.Utils.scheduleSidebarRefresh = (function() { let refresh = false; @@ -2986,6 +2986,7 @@ App.Utils.scheduleSidebarRefresh = (function() { function updateSidebar() { refresh = false; UIBar.update(); + App.UI.updateSidebarTooltips(); } function schedule() { diff --git a/themes/themes.md b/themes/themes.md index 92cb3198767a3d60fd7f0c20955d8ed1b2ef82b7..24c3350e20d61a89bf45cea34237abb4aa8a4d15 100644 --- a/themes/themes.md +++ b/themes/themes.md @@ -6,4 +6,8 @@ page. ## Creating new themes Files inside these directories are combined into one CSS file based on -alphabetical ordering. The light theme is recommended as a base for creating new themes. +alphabetical ordering. The light theme is recommended as a base for creating new themes. + +For quick testing run `App.UI.Theme.loadTheme("yourTheme.css")` in the browser console. This will unload the current +theme and load the new theme. If you modify the same file it is effectively reloading. Supplying no argument (eg. +`App.UI.Theme.loadTheme()`) will unload any theme.