diff --git a/src/005-passages/managePassages.js b/src/005-passages/managePassages.js index b1d1e2f7731581e4b97d0ca64133c3d2704a5af6..e05ee918eb52a2180ce1368dbad4626d38f79458 100644 --- a/src/005-passages/managePassages.js +++ b/src/005-passages/managePassages.js @@ -1 +1,11 @@ +new App.DomPassage("Main", + () => { + V.nextButton = "END WEEK"; + V.nextLink = "End Week"; + V.encyclopedia = "How to Play"; + + return App.MainView.full(); + }, ["jump-to-safe", "jump-from-safe"] +); + new App.DomPassage("Future Society", () => { return App.UI.fsPassage(); }, ["jump-to-safe", "jump-from-safe"]); diff --git a/src/js/main.js b/src/js/main.js index c5c79eaa41ef4ae343827bab732036b628f9773b..750d32686277c38d6865c7cac47a8c4311cb13cf 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,97 +1,3 @@ -/** - * @returns {DocumentFragment} - */ -App.MainView.errors = function() { - const fragment = document.createDocumentFragment(); - - /** - * @returns {HTMLParagraphElement} - */ - function newError() { - const error = document.createElement("p"); - fragment.append(error); - return error; - } - - // check for correct version - if (V.releaseID >= 1000 || ["0.9", "0.8", "0.7", "0.6"].includes(V.ver)) { - if (V.releaseID < App.Version.release) { - newError().append(App.UI.DOM.makeElement("span", "INCOMPATIBILITY WARNING:", "major-warning"), - ` Your saved game was created using version: ${V.ver}, build: ${V.releaseID}. You must run `, - App.UI.DOM.passageLink("Backwards Compatibility", "Backwards Compatibility")); - } - } else { - newError().append(App.UI.DOM.makeElement("span", "INCOMPATIBLE SAVE WARNING:", "major-warning"), - ` Your saved game was created using version: ${V.ver}, and you are using a later version which New Game Plus cannot reconcile. Please start a new game.`); - } - - // check for correct rules - if (V.defaultRules.length > 0 && (V.defaultRules[0].condition === undefined || V.defaultRules[0].set === undefined)) { - const error = newError(); - error.append(App.UI.DOM.makeElement("span", "INCOMPATIBILITY WARNING:", "major-warning"), - " The rules assistant format has changed. In the Options Menu, please "); - const ra = document.createElement("strong"); - ra.append("Reset RA Rules"); - error.append(ra); - } - - // check for NaN - if (V.NaNArray.length > 0) { - const error = newError(); - error.id = "NaNArray"; - error.append(App.UI.DOM.makeElement("span", "ERROR: The following variables are NaN! Please report this.", "error")); - V.NaNArray.forEach(e => { - const div = document.createElement("div"); - div.append(e); - error.append(div); - }); - error.append(App.UI.DOM.link("Hide NaN variables until next week", - () => { - error.outerHTML = ""; - V.NaNArray = []; - }) - ); - } - - // check custom slaves - if (App.Utils.IsCustomSlaveMutated(V.customSlave)) { - newError().append(App.UI.DOM.makeElement("span", "ERROR: Your custom slave order has taken on a mutated life of its own and has been summarily shot. Refile your custom slave order, if necessary, and notify the appropriate authorities if you see this message again.", "error")); - V.customSlave = new App.Entity.CustomSlaveOrder(); - } - if (App.Utils.IsCustomSlaveMutated(V.huskSlave)) { - newError().append(App.UI.DOM.makeElement("span", "ERROR: Your husk slave order has taken on a mutated life of its own and has been summarily shot. Refile your husk slave order, if necessary, and notify the appropriate authorities if you see this message again.", "error")); - V.huskSlave = new App.Entity.CustomSlaveOrder(); - } - - return fragment; -}; - -/** - * @returns {Text} - */ -App.MainView.fcnn = function() { - let text; - - if (V.FCNNstation !== 1 && V.week >= 90) { - text = "FCNN: FCNN service has been temporarily suspended. Please stand by."; - } else { - text = V.fcnn.random(); - } - - return document.createTextNode(`${text} `); -}; - -App.MainView.useFucktoys = function() { - const fragment = document.createDocumentFragment(); - for (const slave of V.slaves) { - if (slave.assignment !== Job.FUCKTOY) { - continue; - } - fragment.append(App.MainView.useFucktoy(slave)); - } - return fragment; -}; - /** * @param {App.Entity.SlaveState} slave * @returns {HTMLDivElement} @@ -210,18 +116,109 @@ App.MainView.useGuard = function() { return outerDiv; }; -App.MainView.walkPast = function() { - const outerDiv = document.createElement("div"); +App.MainView.full = function() { + /** + * @returns {DocumentFragment} + */ + function errors() { + const fragment = document.createDocumentFragment(); + + /** + * @returns {HTMLParagraphElement} + */ + function newError() { + const error = document.createElement("p"); + fragment.append(error); + return error; + } + + // check for correct version + if (V.releaseID >= 1000 || ["0.9", "0.8", "0.7", "0.6"].includes(V.ver)) { + if (V.releaseID < App.Version.release) { + newError().append(App.UI.DOM.makeElement("span", "INCOMPATIBILITY WARNING:", "major-warning"), + ` Your saved game was created using version: ${V.ver}, build: ${V.releaseID}. You must run `, + App.UI.DOM.passageLink("Backwards Compatibility", "Backwards Compatibility")); + } + } else { + newError().append(App.UI.DOM.makeElement("span", "INCOMPATIBLE SAVE WARNING:", "major-warning"), + ` Your saved game was created using version: ${V.ver}, and you are using a later version which New Game Plus cannot reconcile. Please start a new game.`); + } + + // check for correct rules + if (V.defaultRules.length > 0 && (V.defaultRules[0].condition === undefined || V.defaultRules[0].set === undefined)) { + const error = newError(); + error.append(App.UI.DOM.makeElement("span", "INCOMPATIBILITY WARNING:", "major-warning"), + " The rules assistant format has changed. In the Options Menu, please "); + const ra = document.createElement("strong"); + ra.append("Reset RA Rules"); + error.append(ra); + } - const slave = V.slaves.filter(s => ![Job.BODYGUARD, Job.FUCKTOY].includes(s.assignment)).random(); - if (slave) { - App.UI.DOM.appendNewElement("span", outerDiv, walkPast(slave), "scene-intro"); + // check for NaN + if (V.NaNArray.length > 0) { + const error = newError(); + error.id = "NaNArray"; + error.append(App.UI.DOM.makeElement("span", "ERROR: The following variables are NaN! Please report this.", "error")); + V.NaNArray.forEach(e => { + const div = document.createElement("div"); + div.append(e); + error.append(div); + }); + error.append(App.UI.DOM.link("Hide NaN variables until next week", + () => { + error.outerHTML = ""; + V.NaNArray = []; + }) + ); + } + + // check custom slaves + if (App.Utils.IsCustomSlaveMutated(V.customSlave)) { + newError().append(App.UI.DOM.makeElement("span", "ERROR: Your custom slave order has taken on a mutated life of its own and has been summarily shot. Refile your custom slave order, if necessary, and notify the appropriate authorities if you see this message again.", "error")); + V.customSlave = new App.Entity.CustomSlaveOrder(); + } + if (App.Utils.IsCustomSlaveMutated(V.huskSlave)) { + newError().append(App.UI.DOM.makeElement("span", "ERROR: Your husk slave order has taken on a mutated life of its own and has been summarily shot. Refile your husk slave order, if necessary, and notify the appropriate authorities if you see this message again.", "error")); + V.huskSlave = new App.Entity.CustomSlaveOrder(); + } + + return fragment; } - return outerDiv; -}; + /** + * All main passage logic that should be performed at the beginning ogf the passage but generate no visual output. + */ + function cleanup() { + if (V.tabChoice.SlaveInteract !== "Description") { + V.tabChoice.SlaveInteract = "Description"; + } -App.MainView.full = function() { + penthouseCensus(); + V.costs = Math.trunc(calculateCosts.predict()); + V.currentRule = V.defaultRules[0]; + SlaveSort.slaves(V.slaves); + + App.UI.SlaveList.ScrollPosition.restore(); + } + + /** + * @returns {Text} + */ + function fcnn() { + let text; + + if (V.FCNNstation !== 1 && V.week >= 90) { + text = "FCNN: FCNN service has been temporarily suspended. Please stand by."; + } else { + text = V.fcnn.random(); + } + + return document.createTextNode(`${text} `); + } + + /** + * @returns {HTMLDivElement} + */ function mainMenu() { const div = document.createElement("div"); @@ -269,30 +266,101 @@ App.MainView.full = function() { return div; } - const fragment = document.createDocumentFragment(); + /** + * @returns {DocumentFragment} + */ + function useFucktoys() { + const fragment = document.createDocumentFragment(); + for (const slave of V.slaves) { + if (slave.assignment !== Job.FUCKTOY) { + continue; + } + fragment.append(App.MainView.useFucktoy(slave)); + } + return fragment; + } - fragment.append(App.Reminders.list({maxFuture: 5, link: true})); + /** + * @returns {HTMLDivElement} + */ + function walkPast() { + const outerDiv = document.createElement("div"); - if (V.seeFCNN === 1) { - const div = document.createElement("div"); - div.classList.add("main-fcnn"); - div.append(App.MainView.fcnn(), - App.UI.DOM.passageLink("Hide", passage(), () => { V.seeFCNN = 0; }) - ); - fragment.append(div); + const slave = V.slaves.filter(s => ![Job.BODYGUARD, Job.FUCKTOY].includes(s.assignment)).random(); + if (slave) { + App.UI.DOM.appendNewElement("span", outerDiv, globalThis.walkPast(slave), "scene-intro"); + } + + return outerDiv; } - fragment.append(mainMenu()); + /** + * @returns {DocumentFragment} + */ + function assemble() { + const fragment = document.createDocumentFragment(); + if (V.newModelUI === 1) { + fragment.append(V.building.render()); + } + + if (V.seeArcology === 1) { + fragment.append(App.Desc.playerArcology( + App.UI.DOM.passageLink("Hide", "Main", () => {V.seeArcology = 0;}))); + } + + if (V.seeDesk === 1) { + fragment.append(App.Desc.officeDescription( + App.UI.DOM.passageLink("Hide", "Main", () => {V.seeDesk = 0;}))); + } + + fragment.append(App.Reminders.list({maxFuture: 5, link: true})); + + if (V.seeFCNN === 1) { + const div = document.createElement("div"); + div.classList.add("main-fcnn"); + div.append(fcnn(), App.UI.DOM.passageLink("Hide", passage(), () => { V.seeFCNN = 0; }) + ); + fragment.append(div); + } + + fragment.append(mainMenu()); - fragment.append(App.UI.SlaveList.penthousePage()); + fragment.append(App.UI.SlaveList.penthousePage()); - if (V.fucktoyInteractionsPosition === 0) { - fragment.append(App.MainView.useFucktoys()); + if (V.fucktoyInteractionsPosition === 0) { + fragment.append(useFucktoys()); + } + if (V.useSlaveSummaryOverviewTab === 0) { + fragment.append(App.MainView.useGuard()); + } + fragment.append(walkPast()); + + return fragment; } - if (V.useSlaveSummaryOverviewTab === 0) { - fragment.append(App.MainView.useGuard()); + + const fragment = document.createDocumentFragment(); + + fragment.append(errors()); + + // wrap everything in a try/catch statement, so App.MainView.errors() always gets shown. At the end print error out + // as well. + try { + cleanup(); + + fragment.append(assemble()); + } catch (ex) { + App.UI.DOM.appendNewElement("p", fragment, `${ex.name}: ${ex.message}`, ["bold", "error"]); + + const p = document.createElement("p"); + const lines = ex.stack.split("\n"); + for (const ll of lines) { + const div = document.createElement("div"); + // remove file path from error message + div.append(ll.replace(/file:.*\//, "<path>/")); + p.append(div); + } + fragment.append(p); } - fragment.append(App.MainView.walkPast()); return fragment; }; diff --git a/src/uncategorized/main.tw b/src/uncategorized/main.tw deleted file mode 100644 index cd73e8b5f033317e518a90f032a661b8e827dcad..0000000000000000000000000000000000000000 --- a/src/uncategorized/main.tw +++ /dev/null @@ -1,33 +0,0 @@ -:: Main [nobr jump-to-safe jump-from-safe] - -<<includeDOM App.MainView.errors()>> - -<<set $nextButton = "END WEEK", $nextLink = "End Week", $encyclopedia = "How to Play">> - -<<if $tabChoice.SlaveInteract != 'Description'>> - <<set $tabChoice.SlaveInteract = 'Description'>> -<</if>> - -<<run penthouseCensus()>> - -<<set $costs = Math.trunc(calculateCosts.predict())>> - -<<set $currentRule = $defaultRules[0]>> - -<<run SlaveSort.slaves($slaves)>> - -<<if $newModelUI == 1>> - <<includeDOM V.building.render()>> -<</if>> - -<<if $seeArcology == 1>> - <<includeDOM App.Desc.playerArcology(App.UI.DOM.passageLink("Hide", "Main", () => {V.seeArcology = 0}))>> -<</if>> - -<<if $seeDesk == 1>> - <<includeDOM App.Desc.officeDescription(App.UI.DOM.passageLink("Hide", "Main", () => {V.seeDesk = 0}))>> -<</if>> - -<<includeDOM App.MainView.full()>> - -<<run App.UI.SlaveList.ScrollPosition.restore()>>