From d243b1d90680db4945c8da82ba21c872568ca6b5 Mon Sep 17 00:00:00 2001 From: Arkerthan <arkerthan@gmail.com> Date: Tue, 10 Mar 2020 20:47:37 +0100 Subject: [PATCH] add different arc layouts for each location --- src/003-assets/CSS/arcologyBuilding.css | 72 +++++++------ src/004-base/arcologyBuilding.js | 4 +- src/arcologyBuilding/base.js | 138 +++++++++++++++++++----- src/events/intro/initNationalities.tw | 5 + src/events/intro/terrainIntro.tw | 5 + src/init/storyInit.tw | 4 - 6 files changed, 167 insertions(+), 61 deletions(-) diff --git a/src/003-assets/CSS/arcologyBuilding.css b/src/003-assets/CSS/arcologyBuilding.css index 92f86f5c583..a858bf26bb9 100644 --- a/src/003-assets/CSS/arcologyBuilding.css +++ b/src/003-assets/CSS/arcologyBuilding.css @@ -1,24 +1,34 @@ div.building { display: flex; flex-direction: column; - width: 70%; - margin: 0 auto; + width: 100%; +} + +div.building.basement { + box-shadow: 0 -1px 0 #333333; + background-image: repeating-linear-gradient(-45deg, transparent, transparent 20px, #333333 20px, #333333 30px); } div.building div.row { display: flex; flex-direction: row; - width: 100%; - justify-content: center + width: 70%; + margin: 0 auto; + justify-content: center; } -div.building div.cell { - outline: 5px solid; - outline-offset: -8px; - padding: 10px; +div.building div.outerCell { text-align: center; } +div.building div.innerCell { + margin: 3px; + border: 5px solid; + padding: 2px; + /* overwriting with the default background color to hide the basement indicator */ + background-color: #111; +} + /* penthouse formatting */ div.building div.gridWrapper { display: grid; @@ -49,93 +59,93 @@ div.building div.collapsed { /* border color for each cell */ div.building div.row div.apartments { - outline-color: limegreen; + border-color: limegreen; } div.building div.row div.arcade { - outline-color: deeppink; + border-color: deeppink; } div.building div.row div.brothel { - outline-color: violet; + border-color: violet; } div.building div.row div.barracks { - outline-color: olivedrab; + border-color: olivedrab; } div.building div.row div.club { - outline-color: orchid; + border-color: orchid; } div.building div.row div.corporateMarket { - outline-color: purple; + border-color: purple; } div.building div.row div.dairy { - outline-color: white; + border-color: white; } div.building div.row div.denseApartments { - outline-color: seagreen; + border-color: seagreen; } div.building div.row div.empty { - outline-color: lightgray; + border-color: lightgray; } div.building div.row div.farmyard { - outline-color: brown; + border-color: brown; } div.building div.row div.fsShops { - outline-color: mediumpurple; + border-color: mediumpurple; } div.building div.row div.manufacturing { - outline-color: slategray; + border-color: slategray; } div.building div.row div.markets { - outline-color: mediumorchid; + border-color: mediumorchid; } div.building div.row div.nursery { - outline-color: deepskyblue; + border-color: deepskyblue; } div.building div.row div.luxuryApartments { - outline-color: palegreen; + border-color: palegreen; } div.building div.row div.pens { - outline-color: goldenrod; + border-color: goldenrod; } div.building div.row div.penthouse { - outline-color: teal; + border-color: teal; } div.building div.row div.pit { - outline-color: orangered; + border-color: orangered; } div.building div.row div.private { - outline-color: red; + border-color: red; } div.building div.row div.shops { - outline-color: thistle; + border-color: thistle; } div.building div.row div.sweatshops { - outline-color: gray; + border-color: gray; } div.building div.row div.transportHub { - outline-color: magenta; + border-color: magenta; } div.building div.row div.weaponsManufacturing { - outline-color: springgreen; + border-color: springgreen; } diff --git a/src/004-base/arcologyBuilding.js b/src/004-base/arcologyBuilding.js index 19b278a22ed..1bc74651476 100644 --- a/src/004-base/arcologyBuilding.js +++ b/src/004-base/arcologyBuilding.js @@ -87,7 +87,9 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable { const cellClass = eval(`App.Arcology.Cell.${ac}`); if (!(this instanceof cellClass)) { p.append(this._makeUpgrade(`Convert sector to ${cellClass.cellName}.`, () => { - containingBuilding.replaceCell(this, new cellClass(1)); + const newCell = new cellClass(1); + newCell.allowedConversions = this.allowedConversions; + containingBuilding.replaceCell(this, newCell); repX(-5000, "capEx"); }, 50000, "and 5000 reputation as many citizens will lose most of what they own.")); } diff --git a/src/arcologyBuilding/base.js b/src/arcologyBuilding/base.js index 5ff00d496b1..160edfda4be 100644 --- a/src/arcologyBuilding/base.js +++ b/src/arcologyBuilding/base.js @@ -35,22 +35,93 @@ App.Arcology.updateOwnership = function() { }; /** + * @param {string} location * @returns {App.Arcology.Building} */ -App.Arcology.defaultBuilding = function() { +App.Arcology.defaultBuilding = function(location = "default") { const sections = []; sections.push(new App.Arcology.Section("penthouse", [[new App.Arcology.Cell.Penthouse()]])); - sections.push(new App.Arcology.Section("shops", [[new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1)]])); - sections.push(new App.Arcology.Section("apartments", - [ - [new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)], - [new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)], - [new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)], - ] - )); - sections.push(new App.Arcology.Section("markets", [[new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1)]])); - sections.push(new App.Arcology.Section("manufacturing", [[new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1)]])); + sections.push(shops()); + sections.push(apartments()); + sections.push(markets()); + sections.push(manufacturing()); + + + function shops() { + const rows = []; + if (location === "marine") { + rows.push([new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1)]); + } else { + rows.push([new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1)]); + } + return new App.Arcology.Section("shops", rows); + } + + function apartments() { + const rows = []; + if (location === "rural") { + rows.push([new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)]); + rows.push([new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)]); + } else { + if (location === "marine") { + rows.push([new App.Arcology.Cell.Apartment(1, 1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1, 1)]); + } else if (location === "oceanic") { + rows.push([new App.Arcology.Cell.Apartment(1, 1), new App.Arcology.Cell.Apartment(1, 1), new App.Arcology.Cell.Apartment(1, 1), new App.Arcology.Cell.Apartment(1, 1)]); + } else { + rows.push([new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)]); + } + rows.push([new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)]); + + if (location === "urban") { + rows.push([new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Apartment(1, 3)]); + } else { + rows.push([new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Apartment(1)]); + } + } + return new App.Arcology.Section("apartments", rows); + } + + function markets() { + if (location === "ravine") { + return new App.Arcology.Section("ravine-markets", [[new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1)]], true); + } + const rows = []; + if (location === "urban") { + rows.push([convertableCell(new App.Arcology.Cell.Apartment(1, 3), ["Apartment", "Market"]), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), convertableCell(new App.Arcology.Cell.Apartment(1, 3), ["Apartment", "Market"])]); + rows.push([new App.Arcology.Cell.Market(1), convertableCell(new App.Arcology.Cell.Market(1), ["Market", "Manufacturing"]), convertableCell(new App.Arcology.Cell.Market(1), ["Market", "Manufacturing"]), new App.Arcology.Cell.Market(1)]); + } else if (location === "rural") { + rows.push([new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1)]); + } else if (location === "marine") { + rows.push([new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), convertableCell(new App.Arcology.Cell.Manufacturing(1), ["Market", "Manufacturing"]), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1)]); + } else { + rows.push([new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1)]); + } + return new App.Arcology.Section("markets", rows, true); + } + + function manufacturing() { + const rows = []; + if (location === "urban") { + rows.push([new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1)]); + } else if (location === "rural") { + rows.push([new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1)]); + } else if (location === "marine") { + rows.push([convertableCell(new App.Arcology.Cell.Market(1), ["Market", "Manufacturing"]), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), convertableCell(new App.Arcology.Cell.Market(1), ["Market", "Manufacturing"])]); + } else { + rows.push([new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Manufacturing(1)]); + } + return new App.Arcology.Section("manufacturing", rows); + } + + /** + * @param {App.Arcology.Cell.BaseCell} cell + * @param {Array<string>} conversions must include the initial cell + */ + function convertableCell(cell, conversions) { + cell.allowedConversions = conversions; + return cell; + } return new App.Arcology.Building(sections); }; @@ -60,14 +131,15 @@ App.Arcology.defaultBuilding = function() { * * @type {string[]} */ -App.Arcology.sectionOrder = ["penthouse", "spire", "shops", "apartments", "markets", "manufacturing"]; +App.Arcology.sectionOrder = ["penthouse", "spire", "shops", "ravine-markets", "apartments", "markets", "manufacturing"]; App.Arcology.Section = class extends App.Entity.Serializable { /** * @param {string} id unique ID * @param {Array<Array<App.Arcology.Cell.BaseCell>>} rows + * @param {boolean} groundLevel if the section the ground level, all lower layers are automatically in the basement */ - constructor(id, rows) { + constructor(id, rows, groundLevel = false) { super(); /** * @type {string} @@ -77,6 +149,7 @@ App.Arcology.Section = class extends App.Entity.Serializable { * @type {Array<Array<App.Arcology.Cell.BaseCell>>} */ this.rows = rows; + this.groundLevel = groundLevel; } get width() { @@ -105,15 +178,19 @@ App.Arcology.Section = class extends App.Entity.Serializable { * @returns {HTMLDivElement} */ function createCell(cell, rowIndex, cellIndex) { - const div = document.createElement("div"); - div.classList.add("cell"); - div.style.minWidth = `${elementWidth * cell.width}%`; - div.style.maxWidth = `${elementWidth * cell.width}%`; + const outerCell = document.createElement("div"); + outerCell.classList.add("outerCell"); + outerCell.style.minWidth = `${elementWidth * cell.width}%`; + outerCell.style.maxWidth = `${elementWidth * cell.width}%`; - div.classList.add(cell.owner === 1 ? cell.colorClass : "private"); - div.append(cell.cellContent([index, rowIndex, cellIndex])); + const innerCell = document.createElement("div"); + innerCell.classList.add("innerCell"); + innerCell.classList.add(cell.owner === 1 ? cell.colorClass : "private"); + innerCell.append(cell.cellContent([index, rowIndex, cellIndex])); - return div; + outerCell.append(innerCell); + + return outerCell; } /** @@ -209,11 +286,10 @@ App.Arcology.Building = class extends App.Entity.Serializable { } /** - * @returns {HTMLDivElement} + * @returns {DocumentFragment} */ render() { - const div = document.createElement("div"); - div.classList.add("building"); + const fragment = document.createDocumentFragment(); let maxWidth = 0; this.sections.forEach(section => { @@ -221,12 +297,24 @@ App.Arcology.Building = class extends App.Entity.Serializable { }); const elementWidth = 100 / maxWidth; + const upperLevels = document.createElement("div"); + upperLevels.classList.add("building"); + const basement = document.createElement("div"); + basement.classList.add("building", "basement"); + + let wrapper = upperLevels; sortArrayByArray(App.Arcology.sectionOrder, this.sections, "id") .forEach((section, index) => { - div.append(section.render(elementWidth, index)); + wrapper.append(section.render(elementWidth, index)); + if (section.groundLevel) { + // if there are multiple sections that are ground level the first (highest) section wins and all + // others are in the basement. + wrapper = basement; + } }); - return div; + fragment.append(upperLevels, basement); + return fragment; } /** diff --git a/src/events/intro/initNationalities.tw b/src/events/intro/initNationalities.tw index 0de2942a9e3..31bd50290d3 100644 --- a/src/events/intro/initNationalities.tw +++ b/src/events/intro/initNationalities.tw @@ -1,5 +1,10 @@ :: init Nationalities [silently] +<<set $building = App.Arcology.defaultBuilding($terrain)>> +<<set _sellable = $building.findCells(cell => cell.canBeSold())>> +<<set _random12 = jsRandomMany(_sellable, 12)>> +<<run _random12.forEach(cell => {cell.owner = 0})>> + <<if $secExpEnabled > 0>> /* base vars */ <<set $SecExp = SecExpBase()>> diff --git a/src/events/intro/terrainIntro.tw b/src/events/intro/terrainIntro.tw index 95e6a589e84..634c1cdba70 100644 --- a/src/events/intro/terrainIntro.tw +++ b/src/events/intro/terrainIntro.tw @@ -39,26 +39,31 @@ Finally, a few Free Cities have been carved out from old world cities. Urban dec <br> @@.green;High@@ ease of commerce with the old world. <br> @@.green;High@@ access to refugees and other desperate people. <br> @@.red;Low@@ cultural independence. +<br> Unusually compact arcology with few manufacturing sectors. <br>[[Rural|Location Intro][$terrain = "rural"]] <br> @@.yellow;High@@ minimum slave value and initial @@.yellow;bull market@@ for slaves. <br> Moderate ease of commerce with the old world. <br> Moderate access to refugees and other desperate people. <br> Moderate cultural independence. +<br> Widespread arcology with large amount of manufacturing. <br>[[Ravine|Location Intro][$terrain = "ravine"]] <br> @@.yellow;High@@ minimum slave value and initial @@.yellow;bull market@@ for slaves. <br> @@.red;Low@@ ease of commerce with the old world. <br> @@.red;Very low@@ access to refugees and other desperate people. <br> @@.green;High@@ cultural independence. +<br> The arcology is mostly being hidden inside the ravine leads to an unusual layout. <br>[[Marine|Location Intro][$terrain = "marine"]] <br> Moderate minimum slave value and initially balanced market for slaves. <br> Moderate ease of commerce with the old world. <br> @@.red;Low@@ access to refugees and other desperate people. <br> @@.green;High@@ cultural independence. +<br> Large amount of markets and and even an extra shop sector. <br>[[Oceanic|Intro Summary][$terrain = "oceanic"]] <br> @@.yellow;High@@ minimum slave value and initial @@.yellow;bull market@@ for slaves. <br> Moderate ease of commerce with the old world. <br> @@.red;Very low@@ access to refugees and other desperate people. <br> @@.green;Very high@@ cultural independence. +<br> This unique location attracts the wealthy leading to initial luxury apartments. <br> Ensures access to slaves from all over the world and will not associate the arcology with a continent. <<if $showSecExp == 1>> <br>Oceanic arcologies will not be subjects of attacks. diff --git a/src/init/storyInit.tw b/src/init/storyInit.tw index a36abd7abc2..aa41a10086c 100644 --- a/src/init/storyInit.tw +++ b/src/init/storyInit.tw @@ -109,10 +109,6 @@ You should have received a copy of the GNU General Public License along with thi <<run assistant.object()>> <<run repX(1000, "event")>> -<<set $building = App.Arcology.defaultBuilding()>> -<<set _sellable = $building.findCells(cell => cell.canBeSold())>> -<<set _random12 = jsRandomMany(_sellable, 12)>> -<<run _random12.forEach(cell => {cell.owner = 0})>> <<run setup.prostheticIDs.forEach(function(id) { $prosthetics[id] = {amount: 0, research: 0}; })>> -- GitLab