diff --git a/devTools/javaSanityCheck/ignoredVariables b/devTools/javaSanityCheck/ignoredVariables index b764693d21f995865a6b0d965c2f7941b0f25dc4..834c2f6ed54c2740ff331e051d4a5a32d2756fe1 100644 --- a/devTools/javaSanityCheck/ignoredVariables +++ b/devTools/javaSanityCheck/ignoredVariables @@ -130,8 +130,6 @@ loathes obsession # corporation canFoundCorporation;startingPrice;maintenanceSlaves;room;slaveRevenue;divisionLedger;freeDevelopment;developmentCost;maintenanceCategory;corporate;roll;divisionCategories;divisionCategoriesList;getStored;setStored;endweek;hasDividend;hasPayout;perUnit;acquire -DivSurgeryFounded;DivLegal;DivWhoreDev; -AssetsDev;AssetsDevOld;AssetsSlave;AssetsSlaveOld;Div;DivArcadeFromMarket;DivBreakFromMarket;DivArcadeSlaves;DivBreakSlaves2;DivBreakSlaves;DivBreakToMarket;DivBreakToMenial;DivBreakToSurgery;DivBreakToTrain;DivExtraToArcade;DivDairySlaves;DivDairyFromMarket;DivExtraSlaves;DivExtraToBreak;DivExtraToMarket;Dividend;DivLegalSlaves;DivLegalToMarket;DivLegalToMenial;DivLegalToSurgery;DivLegalToTrain;DivMenialFromMarket;DivMenialSlaves;DivSurgerySlaves2;DivSurgerySlaves;DivSurgeryFromMarket;DivSurgeryToDairy;DivSurgeryToMarket;DivSurgeryToTrain;DivTrainFromMarket;DivTrainSlaves;DivTrainSlaves2;DivTrainToMarket;DivTrainToWhore;DivWhoreFromMarket;DivWhoreSlaves;OpCostOld;OverheadOld;ProfitOld;Rev;RevOld # porn focusedViewershipFactor unfocusedViewershipFactor diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js index dc3df48b781897a8a26127f03c0ac36d999584e6..db845b3033fccf77a7ae46a53c8ec92b5058c49e 100644 --- a/js/003-data/gameVariableData.js +++ b/js/003-data/gameVariableData.js @@ -12,7 +12,7 @@ App.Data.defaultGameStateVariables = { releaseID: 0, // Slaves - slaveIndices: 0, + slaveIndices: [], genePool: [], geneMods: {NCS: 0, rapidCellGrowth: 0}, missingTable: {}, @@ -89,6 +89,7 @@ App.Data.defaultGameStateVariables = { profiler: 0, realRoyalties: 0, retainCareer: 1, + ngpParams: {}, rulesAssistantAuto: 0, rulesAssistantMain: 1, seeAge: 1, diff --git a/js/utils.js b/js/utils.js index 3a3692d0dc26bc03ea93e79d0d649fc83a4a189b..b9e28061be09c68dcd7bb8a688202fc7de17a4f5 100644 --- a/js/utils.js +++ b/js/utils.js @@ -327,8 +327,6 @@ App.Utils.topologicalSort = function(keys, edges) { * Sorts by values accessible by unsorted[key] * Values of the second array must be a subset of sorted * - * O(n + m) - * * @param {Array<any>} sorted * @param {Array<object>} unsorted * @param {string} key diff --git a/src/002-config/Serializable.js b/src/002-config/Serializable.js index 16d26dad17d59de87c5e2f22e17e6724827a5fb3..8bad01a68b2146f4c16853f58da166558a2103cf 100644 --- a/src/002-config/Serializable.js +++ b/src/002-config/Serializable.js @@ -43,7 +43,7 @@ App.Entity.Serializable = class { */ _init(config, clean = false) { if (clean) { - App.Entity.Serializable._cleanupConfigScheme(config); + this.constructor._cleanupConfigScheme(config); } // Clone the given object's own properties into our own properties. diff --git a/src/004-base/arcologyBuilding.js b/src/004-base/arcologyBuilding.js index de02692060f3622221916d4fa2ebe59b3429c8ef..a1f141e179ac2338e8356afa8b4e6ce9e645fc9e 100644 --- a/src/004-base/arcologyBuilding.js +++ b/src/004-base/arcologyBuilding.js @@ -107,12 +107,15 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable { function ownership(cell) { const fragment = document.createDocumentFragment(); const A = V.arcologies[0]; + const allCells = V.building.findCells(cell => !(cell instanceof App.Arcology.Cell.Filler)); + const ownedCells = allCells.filter(cell => cell.owner === 1).length; + const oneCellPercentage = ((1 / allCells.length) * 100).toPrecision(3); const price = 1000 * Math.trunc(A.prosperity * (1 + (A.demandFactor / 100))); if (cell.owner === 1) { - fragment.append(`Selling this sector would relinquish a 4% interest in ${A.name}. Such an interest is worth ${cashFormat(price)}.`); + fragment.append(`Selling this sector would relinquish a ${oneCellPercentage}% interest in ${A.name}. Such an interest is worth ${cashFormat(price)}.`); - if (A.ownership >= 4) { + if (ownedCells > 1) { const span = document.createElement("span"); span.classList.add("clear-formatting"); span.append(App.UI.DOM.passageLink("Sell", "Main", @@ -125,8 +128,9 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable { fragment.append(" ", span); } } else { - fragment.append(`You will have to acquire an additional 4% interest in ${A.name} to take control of this sector. Such an interest is worth ${cashFormat(price)} and will require a transaction cost of ${cashFormat(10000)} to acquire for a total cost of ${cashFormat(price + 10000)}.`); - if (A.ownership + A.minority <= 96) { + fragment.append(`You will have to acquire an additional ${oneCellPercentage}% interest in ${A.name} to take control of this sector. Such an interest is worth ${cashFormat(price)} and will require a transaction cost of ${cashFormat(10000)} to acquire for a total cost of ${cashFormat(price + 10000)}.`); + const availableCells = allCells.length * ((100-A.minority)/100) - ownedCells; + if (availableCells >= 1) { const buySpan = document.createElement("span"); buySpan.classList.add("clear-formatting"); buySpan.append(App.UI.DOM.passageLink("Buy", "Main", diff --git a/src/Mods/SecExp/SecExpBackwardCompatibility.tw b/src/Mods/SecExp/SecExpBackwardCompatibility.tw index c7f0d95dab5f6cc9eff125a5ad8f750c861b67c0..92f7d31b385d4186f0fba6711a369524e3b2e945 100644 --- a/src/Mods/SecExp/SecExpBackwardCompatibility.tw +++ b/src/Mods/SecExp/SecExpBackwardCompatibility.tw @@ -3,7 +3,7 @@ <<set $nextButton = "Continue", $nextLink = "Main", $returnTo = "Main">> /* base stats */ -<<= App.SecExp.Check.general()>> +<<run App.SecExp.Check.general()>> <<if ndef $attackType>> <<set $attackType = "none">> <</if>> diff --git a/src/Mods/SecExp/buildings/weaponsManufacturing.tw b/src/Mods/SecExp/buildings/weaponsManufacturing.tw index efe12683a7e18de5c9694f76ffea2b86e18ffb78..18f85d8d7740e009562d3e650445943a7dfe35b7 100644 --- a/src/Mods/SecExp/buildings/weaponsManufacturing.tw +++ b/src/Mods/SecExp/buildings/weaponsManufacturing.tw @@ -197,10 +197,10 @@ With our current industrial and research capabilities upgrades will be finished <br>Security Drones: <<if $weapLab < 3>> Upgrade the research facility further to unlock more upgrades for the security drones. - <<elseif $completedUpgrades.containsAll(-1, -2, -3)>> + <<elseif $completedUpgrades.includesAll(-1, -2, -3)>> You have fully upgraded the security drones. <</if>> - <<if !$completedUpgrades.containsAll(-1, -2, -3)>> <br> <</if>> + <<if !$completedUpgrades.includesAll(-1, -2, -3)>> <br> <</if>> /* Drones upgrades */ <<if !$completedUpgrades.includes(-1)>> <<link "Develop dynamic battle aware AI">> @@ -240,7 +240,7 @@ With our current industrial and research capabilities upgrades will be finished <</link>> <br>//Will take _time weeks, cost <<print cashFormat(30000)>> and will increase the base hp value of the security drones.// <</if>> - <<if !$completedUpgrades.containsAll(-1, -2, -3)>> <br> <</if>> + <<if !$completedUpgrades.includesAll(-1, -2, -3)>> <br> <</if>> /* human troops upgrades */ <br>Troops: diff --git a/src/Mods/SecExp/seeUnit.tw b/src/Mods/SecExp/seeUnit.tw index e8130c37634b5fe313ac160e264bf7fefa1be652..57ae1e59f1e1e44161ba4b91c41f9d320c94a35c 100644 --- a/src/Mods/SecExp/seeUnit.tw +++ b/src/Mods/SecExp/seeUnit.tw @@ -108,7 +108,7 @@ <br> <<link "Attach commissars to the unit" "seeUnit">> <<set $militiaUnits[$targetIndex].commissars = 1>> - <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Attach a small squad of commissars to the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops) + 1000)>> and will slowly increase the loyalty of the unit.// @@ -116,7 +116,7 @@ <br> <<link "Intensive loyalty training" "seeUnit">> <<set $militiaUnits[$targetIndex].commissars += 1>> - <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Provide special training for the officers and the commissars of the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops) + 1000)>> and will increase the loyalty of the unit faster.// @@ -130,7 +130,7 @@ <br> <<link "Provide enhanced cybernetic enhancements" "seeUnit">> <<set $militiaUnits[$targetIndex].cyber += 1>> - <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 2000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 2000), "securityExpansion")>> <</link>> Will augment all soldiers of the unit with high tech cyber enhancements. <br>//Costs <<print cashFormat(($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops) + 2000)>> and will increase attack, defense and base hp values of the unit.// @@ -142,7 +142,7 @@ <br> <<link "Attach trained medics to the unit" "seeUnit">> <<set $militiaUnits[$targetIndex].medics = 1>> - <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Attach a small squad of trained medics to the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $militiaUnits[$targetIndex].maxTroops) + 1000)>> and will decrease the number of casualties suffered during battle.// @@ -259,7 +259,7 @@ <br> <<link "Attach commissars to the unit" "seeUnit">> <<set $slaveUnits[$targetIndex].commissars = 1>> - <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Attach a small squad of commissars to the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 1000)>> and will slowly increase the loyalty of the unit.// @@ -267,7 +267,7 @@ <br> <<link "Intensive loyalty training" "seeUnit">> <<set $slaveUnits[$targetIndex].commissars += 1>> - <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Provide special training for the officers and the commissars of the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 1000)>> and will increase the loyalty of the unit faster.// @@ -281,7 +281,7 @@ <br> <<link "Provide enhanced cybernetic enhancements" "seeUnit">> <<set $slaveUnits[$targetIndex].cyber += 1>> - <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 2000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 2000), "securityExpansion")>> <</link>> Will augment all soldiers of the unit with high tech cyber enhancements. <br>//Costs <<print cashFormat(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 2000)>> and will increase attack, defense and base hp values of the unit.// @@ -293,7 +293,7 @@ <br> <<link "Attach trained medics to the unit" "seeUnit">> <<set $slaveUnits[$targetIndex].medics = 1>> - <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Attach a small squad of trained medics to the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 1000)>> and will decrease the number of casualties suffered during battle.// @@ -305,7 +305,7 @@ <br> <<link "Attach Special Force advisors" "seeUnit">> <<set $slaveUnits[$targetIndex].SF = 1>> - <<run cashX(forceNeg(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 5000), "specialForces")>> + <<run cashX(forceNeg(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 5000), "securityExpansion")>> <</link>> Attach $SF.Lower advisors to the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $slaveUnits[$targetIndex].maxTroops) + 5000)>> and will slightly increase the base stats of the unit.// @@ -408,7 +408,7 @@ <br> <<link "Attach commissars to the unit" "seeUnit">> <<set $mercUnits[$targetIndex].commissars = 1>> - <<run cashX(forceNeg($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Attach a small squad of commissars to the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops) + 1000)>> and will slowly increase the loyalty of the unit.// @@ -416,7 +416,7 @@ <br> <<link "Intensive loyalty training" "seeUnit">> <<set $mercUnits[$targetIndex].commissars += 1>> - <<run cashX(forceNeg($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops + 1000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops + 1000), "securityExpansion")>> <</link>> Provide special training for the officers and the commissars of the unit. <br>//Costs <<print cashFormat(($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops) + 1000)>> and will increase the loyalty of the unit faster.// @@ -430,7 +430,7 @@ <br> <<link "Provide enhanced cybernetic enhancements" "seeUnit">> <<set $mercUnits[$targetIndex].cyber += 1>> - <<run cashX(forceNeg($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops + 2000), "specialForces")>> + <<run cashX(forceNeg($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops + 2000), "securityExpansion")>> <</link>>Will augment all soldiers of the unit with high tech cyber enhancements. <br>//Costs <<print cashFormat(($equipUpgradeCost * $mercUnits[$targetIndex].maxTroops) + 2000)>> and will increase attack, defense and base hp values of the unit.// <<else>> diff --git a/src/arcologyBuilding/base.js b/src/arcologyBuilding/base.js index b032f52a6ece07f27afc91c76d33ca50527f7f61..40483a5085e033bc25aa34e9a22129eeeb543eed 100644 --- a/src/arcologyBuilding/base.js +++ b/src/arcologyBuilding/base.js @@ -13,9 +13,9 @@ App.Arcology.getCellLink = function(path, message) { * * @param {App.Arcology.Building} building * @param {class} cellClass - * @param {any} cellType - * @param {any} newType - * @param {string} [key] + * @param {*} cellType + * @param {*} newType + * @param {string} [key="type"] */ App.Arcology.cellUpgrade = function(building, cellClass, cellType, newType, key = "type") { building.findCells(cell => cell instanceof cellClass && cell[key] === cellType) @@ -35,7 +35,7 @@ App.Arcology.updateOwnership = function() { }; /** - * @param {string} terrain + * @param {string} [terrain="default"] * @returns {App.Arcology.Building} */ App.Arcology.defaultBuilding = function(terrain = "default") { @@ -58,7 +58,8 @@ 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 + * @param {boolean} [groundLevel=false] if the section the ground level, all lower layers are automatically in the + * basement */ constructor(id, rows, groundLevel = false) { super(); @@ -197,10 +198,20 @@ App.Arcology.Section = class extends App.Entity.Serializable { App.Arcology.Building = class extends App.Entity.Serializable { /** + * @param {string} layout reference to the used layout so we now how to do layout specific actions. (upgrading) * @param {Array<App.Arcology.Section>} sections */ - constructor(sections) { + constructor(layout, sections) { super(); + /** + * @type {string} + */ + this.layout = layout; + /** + * List of all already taken upgrades. + * @type {Array<string>} + */ + this.usedUpgrades = []; /** * @type {Array<App.Arcology.Section>} */ @@ -240,8 +251,8 @@ App.Arcology.Building = class extends App.Entity.Serializable { } /** - * @param {Array<any>} path - * @returns {App.Arcology.Cell.BaseCell} + * @param {Array<*>} path + * @returns {Node} */ renderCell(path) { return this.sections[path[0]].renderCell(path.slice(1), this); @@ -275,7 +286,9 @@ App.Arcology.Building = class extends App.Entity.Serializable { static _cleanupConfigScheme(config) { super._cleanupConfigScheme(config); - // BC code + if (config.layout === undefined) { + config.layout = V.terrain; + } } clone() { diff --git a/src/arcologyBuilding/presets.js b/src/arcologyBuilding/presets.js index 8fc501bc46ef5a12c68b2526a02b6f9e37996378..d48b061d2fcac799248f0b6aef0d838ea6b42736 100644 --- a/src/arcologyBuilding/presets.js +++ b/src/arcologyBuilding/presets.js @@ -22,42 +22,56 @@ App.Arcology.presets = (function() { * @property {boolean} [ground] */ /** - * @typedef {Array<sectionTemplate>} buildingTemplate + * @typedef {Array<sectionTemplate|string>} buildingTemplate first entry is template name */ - /* NOTE: test new templates, broken templates WILL explode */ - /* t is markets, () is possible values for a sector, first is default */ + /* + NOTE: test new templates, broken templates WILL explode + t is markets; () is possible values for a sector, first is default; + [number] is for filler space, must be parsable by Number(), 1 equals the width of a normal cell + */ const templates = { - default: [{id: "penthouse", rows: ["p"]}, + default: ["default", + {id: "penthouse", rows: ["p"]}, {id: "shops", rows: ["sss"]}, {id: "apartments", rows: ["aaaa", "aaaa", "aaaa"]}, {id: "markets", rows: ["ttttt"], ground: true}, {id: "manufacturing", rows: ["mmmmm"]}], - urban: [{id: "penthouse", rows: ["p"]}, + urban: ["urban", + {id: "penthouse", rows: ["p"]}, {id: "shops", rows: ["sss"]}, {id: "apartments", rows: ["aaaa", "aaaa", "dddd"]}, {id: "markets", rows: ["(dt)tt(dt)", "t(tm)(tm)t"], ground: true}, {id: "manufacturing", rows: ["mmmm"]}], - rural: [{id: "penthouse", rows: ["p"]}, + rural: ["rural", + {id: "penthouse", rows: ["p"]}, {id: "shops", rows: ["sss"]}, {id: "apartments", rows: ["aaaaa", "aaaaa"]}, {id: "markets", rows: ["tt(mt)(mt)tt"], ground: true}, {id: "manufacturing", rows: ["mmmmm"]}], - ravine: [{id: "penthouse", rows: ["p"]}, + ravine: ["ravine", + {id: "penthouse", rows: ["p"]}, {id: "shops", rows: ["sss"]}, {id: "ravine-markets", rows: ["ttttt"], ground: true}, {id: "apartments", rows: ["aaaa", "aaaa", "aaaa"]}, {id: "manufacturing", rows: ["mmmmm"]}], - marine: [{id: "penthouse", rows: ["p"]}, + marine: ["marine", + {id: "penthouse", rows: ["p"]}, {id: "shops", rows: ["ssss"]}, {id: "apartments", rows: ["laal", "aaaa", "aaaa"]}, {id: "markets", rows: ["tt(mt)tt"], ground: true}, {id: "manufacturing", rows: ["(tm)mmm(tm)"]}], - oceanic: [{id: "penthouse", rows: ["p"]}, + oceanic: ["oceanic", + {id: "penthouse", rows: ["p"]}, {id: "shops", rows: ["sss"]}, {id: "apartments", rows: ["llll", "aaaa", "aaaa"]}, {id: "markets", rows: ["ttttt"], ground: true}, {id: "manufacturing", rows: ["mmmmm"]}], + dick: ["dick", // yes, this is a giant dick + {id: "penthouse", rows: ["l", "p"]}, + {id: "apartments", rows: ["a", "a", "a", "d[0.75]a[0.75]d", "dd[0.25]s[0.25]dd"]}, + {id: "markets", rows: ["ttsstt"], ground: true}, + {id: "manufacturing", rows: ["tm[0.25]m[0.25]mt", "m[0.75]m[0.75]m"]}], }; /** @@ -66,10 +80,11 @@ App.Arcology.presets = (function() { */ function templateToBuilding(template) { const sections = []; - for (let sectionTemplate of template) { - sections.push(getSection(sectionTemplate)); + const layout = template[0]; + for (let i = 1; i < template.length; i++) { + sections.push(getSection(template[i])); } - return new App.Arcology.Building(sections); + return new App.Arcology.Building(layout, sections); /** * @param {sectionTemplate} section @@ -101,6 +116,14 @@ App.Arcology.presets = (function() { next = iter.next(); } cells.push(cell); + } else if (next.value === "[") { + let number = ""; + next = iter.next(); + while (next.value !== "]") { + number += next.value; + next = iter.next(); + } + cells.push(new App.Arcology.Cell.Filler(Number(number))); } else { cells.push(charToCell(next.value).cell); } @@ -190,29 +213,7 @@ App.Arcology.presets = (function() { apply() {} }, { isAllowed: env => env.established && Math.random() < 0.1, - construct: () => { - // yes, this is a giant dick - const sections = []; - let rows = []; - rows.push([new App.Arcology.Cell.Apartment(1, 1)]); - rows.push([new App.Arcology.Cell.Penthouse()]); - sections.push(new App.Arcology.Section("penthouse", rows)); - rows = []; - rows.push([new App.Arcology.Cell.Apartment(1)]); - rows.push([new App.Arcology.Cell.Apartment(1)]); - rows.push([new App.Arcology.Cell.Apartment(1)]); - rows.push([new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Filler(0.75), new App.Arcology.Cell.Apartment(1), new App.Arcology.Cell.Filler(0.75), new App.Arcology.Cell.Apartment(1, 3)]); - rows.push([new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Filler(0.25), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Filler(0.25), new App.Arcology.Cell.Apartment(1, 3), new App.Arcology.Cell.Apartment(1, 3)]); - sections.push(new App.Arcology.Section("apartments", rows)); - rows = []; - rows.push([new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Shop(1), new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Market(1)]); - sections.push(new App.Arcology.Section("markets", rows, true)); - rows = []; - rows.push([new App.Arcology.Cell.Market(1), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Filler(0.25), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Filler(0.25), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Market(1)]); - rows.push([new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Filler(0.75), new App.Arcology.Cell.Manufacturing(1), new App.Arcology.Cell.Filler(0.75), new App.Arcology.Cell.Manufacturing(1)]); - sections.push(new App.Arcology.Section("manufacturing", rows)); - return new App.Arcology.Building(sections); - }, + construct: () => { return templateToBuilding(templates.dick); }, apply() {} }, ]; @@ -225,3 +226,72 @@ App.Arcology.presets = (function() { App.Arcology.randomPreset = function(environment) { return App.Arcology.presets.filter(p => p.isAllowed(environment)).random(); }; + +/** + * Shows all possible upgrades for a given building. + * @param {App.Arcology.Building} building + * @returns {HTMLElement} + */ +App.Arcology.upgrades = function(building) { + const outerDiv = document.createElement("div"); + + /** + * @typedef upgrade + * @property {string} id used to identify already build upgrades, unique! + * @property {Array<string>} layouts + * @property {Array<string>} exclusive any upgrade is always exclusive to itself. NOTE: keep in mind that + * exclusiveness has to be added to both upgrades! + * @property {string} name as shown to player. + * @property {string} desc Fits in a sentence like this: The next major upgrade needed is "desc" + * @property {number} cost + * @property {function():undefined} apply + */ + // TODO actually add different upgrades, but hey, we have the framework at least. + /** @type {Array<upgrade>} */ + const upgrades = [{ + id: "spire", + layouts: ["default", "urban", "rural", "ravine", "marine", "oceanic"], + exclusive: [], name: "spire", + desc: "the addition of a spire at the top of the arcology to increase the space available for the wealthiest citizens to own whole floors", + cost: 250000, apply: () => { + building.sections.push(new App.Arcology.Section("spire", [ + [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)] + ])); + V.spire = 1; + } + }]; + + let count = 0; + for (let upgrade of upgrades) { + if (upgrade.layouts.includes(building.layout) + && !building.usedUpgrades.includesAny(upgrade.id, ...upgrade.exclusive)) { + const div = document.createElement("div"); + div.classList.add("choices"); + const cost = upgrade.cost * V.upgradeMultiplierArcology; + div.append(`...${upgrade.desc}. `, App.UI.DOM.makeElement("span", `This huge project will cost ${cashFormat(cost)} `, "note"), + App.UI.DOM.passageLink(`Build ${upgrade.name}`, passage(), () => { + if (building.usedUpgrades.length === 0) { + // the first major upgrade gives skill, successive ones not, mainly because there might be a + // different number depending on layout. + V.PC.skill.engineering++; + } + building.usedUpgrades.push(upgrade.id); + upgrade.apply(); + })); + outerDiv.append(div); + count++; + } + } + + if (count === 0) { + return App.UI.DOM.makeElement("span", "The arcology structure is fully upgraded.", "note"); + } else { + if (count === 1) { + outerDiv.prepend("The next major upgrade is..."); + } else { + outerDiv.prepend("Possible major upgrades to the arcology are ..."); + } + return outerDiv; + } +}; diff --git a/src/art/artWidgets.tw b/src/art/artWidgets.tw deleted file mode 100644 index b247e2f8ac5b8068ada94913a7209eb5ffaddae2..0000000000000000000000000000000000000000 --- a/src/art/artWidgets.tw +++ /dev/null @@ -1,6 +0,0 @@ -:: art widgets [nobr widget] - -<<widget "SlaveArtById">> - <<set _s = getSlave($args[0])>> - <<= SlaveArt(_s, $args[1])>> -<</widget>> diff --git a/src/art/vector/Body_Clothing_Control.tw b/src/art/vector/Body_Clothing_Control.tw deleted file mode 100644 index 0ecade1d27598491202ba2574eeee14ef531f83f..0000000000000000000000000000000000000000 --- a/src/art/vector/Body_Clothing_Control.tw +++ /dev/null @@ -1,97 +0,0 @@ -:: Art_Vector_Body_Clothing_Control_ [nobr] - -<<set _eyeBallColor = "#ffffff">> - -<<if hasAnyEyes(_artSlave)>> - <<set _eyeLens = hasLeftEye(_artSlave) ? getLeftEyePupil(_artSlave) : getRightEyePupil(_artSlave)>> - <<if _eyeLens == "demonic">> - <<set _eyeBallColor = hasLeftEye(_artSlave) ? getLeftEyeColor(_artSlave) : getRightEyeColor(_artSlave)>> - <<elseif _eyeLens == "devilish">> - <<set _eyeBallColor = "#000000">> - <</if>> -<</if>> - -<<set _muscles_value = _artSlave.muscles + 101>> -<<set _art_muscle_visibility = 0.910239*Math.log(0.02*_muscles_value) >> - -<<set _showEyes = 1>> -<<set _showLips = 1>> -<<set _showMouth = 1>> -<<set _showPubic = 1>> -<<set _showPussy = (_artSlave.vagina >= 0)>> -<<set _showArmHair = 1>> -<<set _showHair = (_artSlave.hStyle != "shaved")>> -<<set _showBoobs = 1>> -<<set _showNipples = 1>> -<<set _showArmHighlight = 0>> -<<set _showTorsoHighlight = 0>> -<<set _showLegHighlight = 0>> -<<set _showBoobsHighlight = 0>> -<<set _showEyesHighlight = 1>> -<<set _showHeadHighlight = 1>> -<<set _showBellyPiercings = 1>> -<<set _showNipplePiercings = 1>> -<<set _chastityAnal = (_artSlave.chastityAnus == 1)>> - -<<set _chastityVaginal = (_artSlave.chastityVagina == 1)>> - -<<if _artSlave.fuckdoll > 0>> - <<set _showEyes = 0>> - <<set _showPubic = 0>> - <<set _showArmHair = 0>> - <<set _showHair = 0>> - <<set _showArmHighlight = 1>> - <<set _showTorsoHighlight = 1>> - <<set _showBoobsHighlight = 1>> - <<set _showLegHighlight = 1>> - <<set _showHeadHighlight = 1>> -<</if>> - -<<if _artSlave.clothes == "a nice maid outfit">> - <<set _showPubic = 0>> - <<set _showBoobs = 0>> - <<set _showBellyPiercings = 0>> - <<set _showNipplePiercings = 0>> - <<set _showNipples = 0>> -<</if>> - -<<if _artSlave.clothes == "a slutty maid outfit">> - <<set _showBellyPiercings = 0>> -<</if>> - -<<if _artSlave.clothes == "restrictive latex">> - <<set _showEyes = 0>> - <<set _showPubic = 0>> - <<set _showArmHair = 0>> - <<set _showHair = 0>> - <<set _showArmHighlight = 1>> - <<set _showTorsoHighlight = 1>> - <<set _showLegHighlight = 1>> - <<set _showHeadHighlight = 1>> - <<set _showBellyPiercings = 0>> -<</if>> - -<<if _artSlave.clothes == "a latex catsuit">> - <<set _showPubic = 0>> - <<set _showArmHair = 0>> - <<set _showArmHighlight = 1>> - <<set _showTorsoHighlight = 1>> - <<set _showLegHighlight = 1>> - <<set _showBoobsHighlight = 1>> - <<set _showHeadHighlight = 1>> - <<set _showBellyPiercings = 0>> - <<set _showNipplePiercings = 0>> - <<set _chastityAnal = 0>> - <<set _chastityVaginal = 0>> -<</if>> - -<<if $showBodyMods == 0>> - <<set _showNipplePiercings = 0>> -<</if>> - -<<if $seeVectorArtHighlights == 1>> - <<set _showArmHighlight = 0>> - <<set _showTorsoHighlight = 0>> - <<set _showLegHighlight = 0>> - <<set _showBoobsHighlight = 0>> -<</if>> diff --git a/src/data/backwardsCompatibility/BackwardsCompatibility.tw b/src/data/backwardsCompatibility/BackwardsCompatibility.tw index 37b5ad72b811b85e2ef9c0d9390a709f554999b8..b48b6fd48c1980fe89e59b016916596a0395dc93 100644 --- a/src/data/backwardsCompatibility/BackwardsCompatibility.tw +++ b/src/data/backwardsCompatibility/BackwardsCompatibility.tw @@ -1,44 +1,12 @@ :: Backwards Compatibility [nobr] -/* no-usedOnce disabling checking for only used once instances in this file */ <<set $nextButton = "Continue", $nextLink = "Main", $returnTo = "Main">> <<run App.Update.setNonexistantProperties(V, App.Data.defaultGameStateVariables)>> /* resetOnNGPlus contains half of the variables we need, but we use it politely here instead of forcing it so it fills in holes instead of overwriting data */ <<run App.Update.setNonexistantProperties(V, App.Data.resetOnNGPlus)>> - -<div> - <<= App.Update.oldVersions()>> -</div> - -<div> - <<= App.Update.globalVariables()>> -</div> - -<div> - <<= App.Update.slaveVariables()>> -</div> - -<div> - <<= App.Update.slaveRecords()>> -</div> - -<div> - <<= App.Update.RAassistantData()>> -</div> - -/* Sec Exp */ -<div> - <<= App.SecExp.Check.general()>> - <<if $secExpEnabled == 1>> - <br> <<include "SecExpBackwardCompatibility">> - <</if>> -</div> -<div> - <<= App.Update.autoshred()>> -</div> -/* leave this at the bottom of BC */ -<div> - <<= App.Update.cleanUp()>> -</div> +<span id="backwardsCompatibility"></span> +<script> + App.Update.backwardsCompatibility(); +</script> \ No newline at end of file diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js index 606b66073e10036336d7b575014e1ae12bea380d..d899cb28d9035473511c7a2a2580cff2995fdc3e 100644 --- a/src/data/backwardsCompatibility/backwardsCompatibility.js +++ b/src/data/backwardsCompatibility/backwardsCompatibility.js @@ -1,4 +1,4 @@ -App.Update.autoshred = function() { +App.Update.autoshred = function(node) { const set = new Set( Object.getOwnPropertyNames(App.Data.defaultGameStateVariables).concat( Object.getOwnPropertyNames(App.Data.resetOnNGPlus) @@ -21,6 +21,7 @@ App.Update.autoshred = function() { if (extraCount !== 0) { console.log(`and ${extraCount} more`); } + node.append(`Done!`); }; App.Update.setNonexistantProperties = function(obj, props) { @@ -51,8 +52,71 @@ App.Update.setExistantProperties = function(obj, array) { } }; -App.Update.globalVariables = function() { - let r = `Setting missing global variables... `; +App.Update.backwardsCompatibility = function() { + let div; + jQuery('#backwardsCompatibility').empty(); + try { + div = document.createElement('div'); + div.append(`Check for old version... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.oldVersions(div); + + div = document.createElement('div'); + div.append(`Updating gene pool records... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.genePoolRecords(div); + + div = document.createElement('div'); + div.append(`Updating global variables... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.globalVariables(div); + + div = document.createElement('div'); + div.append(`Updating slave variables... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.slaveVariables(div); + + div = document.createElement('div'); + div.append(`Updating slave records... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.slaveRecords(div); + + div = document.createElement('div'); + div.append(`Updating Rule Assistant data... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.RAassistantData(div); + + // Sec Exp + div = document.createElement('div'); + div.append(`Updating Security Expansion... `); + jQuery('#backwardsCompatibility').append(div); + App.SecExp.Check.general(); + if (V.secExpEnabled === 1) { + jQuery(div).wiki(`<<include "SecExpBackwardCompatibility">>`); + } + + div = document.createElement('div'); + div.append(`Checking for old variables... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.autoshred(div); + + // leave this at the bottom of BC + div = document.createElement('div'); + div.append(`Cleaning up... `); + jQuery('#backwardsCompatibility').append(div); + App.Update.cleanUp(div); + } catch (error) { + div = document.createElement('p'); + div.className = "red"; + div.textContent = `Backwards compatibility has failed for your save. Please upload your save to https://gitgud.io/pregmodfan/fc-pregmod/ with notes on what went wrong so that we can fix the backwards compatibility process for everyone. Thank you!`; + jQuery('#backwardsCompatibility').append(div); + State.restore(); + throw (error); // rethrow the exception to Sugarcube so we get a fancy stack trace + } + return; +}; + +App.Update.globalVariables = function(node) { if (Array.isArray(V.nationalities)) { V.nationalities = weightedArray2HashMap(V.nationalities); } @@ -164,6 +228,12 @@ App.Update.globalVariables = function() { V.upgradeMultiplierArcology = upgradeMultiplier('engineering'); V.upgradeMultiplierMedicine = upgradeMultiplier('medicine'); V.upgradeMultiplierTrade = upgradeMultiplier('trading'); + V.AgeEffectOnTrainerPricingPC = 1; + V.AgeEffectOnTrainerEffectivenessPC = 1; + V.AgeTrainingUpperBoundPC = 14; + V.AgeTrainingLowerBoundPC = 12; + V.IsInPrimePC = 3; + V.IsPastPrimePC = 5000; } // Looks at all wombs, including PC. @@ -872,6 +942,12 @@ App.Update.globalVariables = function() { V.building = App.Arcology.defaultBuilding(); } } + if (V.arcologyUpgrade.spire === 1 && !V.building.usedUpgrades.includes("spire")) { + V.building.usedUpgrades.push("spire"); + } + if (!V.building.sections.map(s => s.id).includes("penthouse")) { + V.building.sections.push(new App.Arcology.Section("penthouse", [[new App.Arcology.Cell.Penthouse()]])); + } if (jQuery.isEmptyObject(V.trinkets)) { V.trinkets = []; @@ -1025,9 +1101,10 @@ App.Update.globalVariables = function() { } /* make sure that any new genres get added correctly (and populate V.pornStars for very old games) */ - for (let genre in App.Porn.getAllGenres()) { - if (typeof V.pornStars[genre.fameVar] === "undefined") { - V.pornStars[genre.fameVar] = {p1count: 0, p3ID: 0}; + const pornGenres = App.Porn.getAllGenres(); + for (let genre in pornGenres) { + if (V.pornStars[pornGenres[genre].fameVar] === undefined) { + V.pornStars[pornGenres[genre].fameVar] = {p1count: 0, p3ID: 0}; } } if (V.PCSlutContacts === 0) { @@ -1061,12 +1138,10 @@ App.Update.globalVariables = function() { EconomyDatatypeCleanup(); ArcologyDatatypeCleanup(); - r += ` Done!<br>`; - return r; + node.append(`Done!`); }; -App.Update.slaveVariables = function() { - let r = `Setting missing slave variables... `; +App.Update.slaveVariables = function(node) { /* Adding a new variable? Consider putting it in datatypeCleanupJS.tw instead of here */ for (let bci = 0; bci < V.slaves.length; bci++) { let Slave = V.slaves[bci]; @@ -1080,12 +1155,10 @@ App.Update.slaveVariables = function() { V.slaves[bci] = Slave; } - r += ` Done!<br>`; - return r; + node.append(`Done!`); }; -App.Update.slaveRecords = function() { - let r = `Checking and fixing slave records...`; +App.Update.slaveRecords = function(node) { V.slaves.forEach((slave) => { App.Entity.Utils.SlaveDataSchemeCleanup(slave); SlaveDatatypeCleanup(slave); @@ -1114,21 +1187,25 @@ App.Update.slaveRecords = function() { App.Entity.Utils.SlaveDataSchemeCleanup(V.traitor); SlaveDatatypeCleanup(V.traitor); } - r += ` Done!<br>`; + node.append(`Done!`); if (V.tanks.length > 0) { - r += `Checking and fixing records for incubator tanks... `; + let incubatorDiv = document.createElement("div"); + node.append(incubatorDiv); + incubatorDiv.append(`Checking and fixing records for incubator tanks... `); V.tanks.forEach((slave) => { App.Update.Slave(slave); App.Entity.Utils.SlaveDataSchemeCleanup(slave); SlaveDatatypeCleanup(slave, true); /* pass second argument as true so that slaveAgeDatatypeCleanup is not run */ }); - r += ` Done!<br> `; + incubatorDiv.append(`Done!`); } if (V.cribs.length > 0) { - r += `Checking and fixing records for nursery cribs... `; + let nurseryDiv = document.createElement("div"); + node.append(nurseryDiv); + nurseryDiv.append(`Checking and fixing records for nursery cribs... `); V.cribs.forEach((child) => { if (child.actualAge < 3) { App.Facilities.Nursery.InfantDatatypeCleanup(child); @@ -1138,18 +1215,21 @@ App.Update.slaveRecords = function() { } }); V.cribsIndices = App.Facilities.Nursery.cribsToIndices(); - r += ` Done!<br> `; + if (V.nurseryNannies > 0) { + for (let bci = 0; bci < V.cribs.length; bci++) { + App.Update.Slave(V.cribs[bci]); + // let _nurseryChild = V.cribs[bci]; TODO: on importing this to JS, what is this even supposed to do? + } + } + nurseryDiv.append(`Done!`); } - return r; }; -App.Update.genePoolRecords = function() { - let r = `Updating gene pool records... `; +App.Update.genePoolRecords = function(node) { for (let bci = 0; bci < V.genePool.length; bci++) { + App.Update.Slave(V.genePool[bci], true); let slave = V.genePool[bci]; - App.Update.Slave(slave); - if (V.genePool.map(function(s) { return s.ID; }).count(slave.ID) > 1) { /* first check for duplicate IDs, keep the first entry and delete the others */ for (let bci2 = bci + 1; bci2 < V.genePool.length; bci2++) { @@ -1164,25 +1244,25 @@ App.Update.genePoolRecords = function() { dontDeleteMe = 1; } if (V.traitor !== 0) { - if (isImpregnatedBy(V.traitor, slave) || V.traitor.ID === slave.ID) { + if (isImpregnatedBy(V.traitor, slave, true) || V.traitor.ID === slave.ID) { /* did we impregnate the traitor, or are we the traitor? */ dontDeleteMe = 1; } } if (V.boomerangSlave !== 0) { - if (isImpregnatedBy(V.boomerangSlave, slave) || V.boomerangSlave.ID === slave.ID) { + if (isImpregnatedBy(V.boomerangSlave, slave, true) || V.boomerangSlave.ID === slave.ID) { /* did we impregnate the boomerang, or are we the boomerang? */ dontDeleteMe = 1; } } - if (isImpregnatedBy(V.PC, slave)) { + if (isImpregnatedBy(V.PC, slave, true)) { /* did we impregnate the PC */ dontDeleteMe = 1; } if (dontDeleteMe === 0) { /* avoid going through this loop if possible */ for (let bci2 = 0; bci2 < V.slaves.length; bci2++) { - if (isImpregnatedBy(V.slaves[bci2], slave)) { + if (isImpregnatedBy(V.slaves[bci2], slave, true)) { /* have we impregnated a slave on the slaves array? */ dontDeleteMe = 1; break; @@ -1233,35 +1313,18 @@ App.Update.genePoolRecords = function() { App.Entity.Utils.GenePoolRecordCleanup(slave); V.genePool[bci] = slave; } - if (V.nurseryNannies > 0) { - for (let bci = 0; bci < V.cribs.length; bci++) { - App.Update.Slave(V.cribs[bci]); - // let _nurseryChild = V.cribs[bci]; TODO: on importing this to JS, what is this even supposed to do? - } - } - - V.AgeEffectOnTrainerPricingPC = 1; - V.AgeEffectOnTrainerEffectivenessPC = 1; - V.AgeTrainingUpperBoundPC = 14; - V.AgeTrainingLowerBoundPC = 12; - V.IsInPrimePC = 3; - V.IsPastPrimePC = 5000; - r += ` Done!<br>`; - return r; + node.append(`Done!`); }; -App.Update.RAassistantData = function() { - let r = `Updating Rules Assistant data...`; +App.Update.RAassistantData = function(node) { V.defaultRules = V.defaultRules.map(rule => App.Entity.Utils.RARuleDatatypeCleanup(rule)); - r += ` Done!<br>`; - return r; + node.append(`Done!`); }; -App.Update.oldVersions = function() { +App.Update.oldVersions = function(node) { if (V.releaseID === 1021 || V.releaseID === 1020 || V.releaseID === 1019 || V.releaseID === 2022) { V.releaseID = 1022; } - let r = ""; if (V.releaseID < 1043) { V.defaultRules.forEach((rule) => { if (rule.condition.excludeSpecialSlaves) { @@ -1273,9 +1336,21 @@ App.Update.oldVersions = function() { }); } if (V.releaseID === 1043) { - V.slaves.forEach(s => { s.skill.whoring = s.skill.whore / 2; }); - V.tanks.forEach(s => { s.skill.whoring = s.skill.whore / 2; }); - V.cribs.forEach(s => { s.skill.whoring = s.skill.whore / 2; }); + V.slaves.forEach(s => { + if (s.skill && s.skill.whore) { + s.skill.whoring = s.skill.whore / 2; + } + }); + V.tanks.forEach(s => { + if (s.skill && s.skill.whore) { + s.skill.whoring = s.skill.whore / 2; + } + }); + V.cribs.forEach(s => { + if (s.skill && s.skill.whore) { + s.skill.whoring = s.skill.whore / 2; + } + }); } /* unify cybermod & vanilla */ /* limbs */ @@ -1477,7 +1552,9 @@ App.Update.oldVersions = function() { } } if (V.releaseID < 1057) { - r += `Standardizing player object... `; + let PCdiv = document.createElement("div"); + node.append(PCdiv); + PCdiv.append(`Standardizing player object... `); if (typeof V.PC.actualAge === "undefined") { if (V.PC.age === 1) { V.PC.actualAge = 20; @@ -1911,23 +1988,24 @@ App.Update.oldVersions = function() { V.PC.faceShape = "normal"; } - r += ` Done!`; + PCdiv.append(`Done!`); } - return r; + + node.append(`Done!`); }; -App.Update.cleanUp = function() { +App.Update.cleanUp = function(node) { /* leave this at the bottom of BC */ if (V.releaseID < App.Version.release) { V.releaseID = App.Version.release; } /* reset NaNArray after BC is run */ V.NaNArray = findNaN(); - return; + node.append(`Done!`); }; App.Update.sectorsToBuilding = function() { - V.building = new App.Arcology.Building([]); + V.building = new App.Arcology.Building(V.terrain, []); const B = V.building; const S = V.sectors; @@ -2001,181 +2079,3 @@ App.Update.sectorsToBuilding = function() { return m; } }; - -App.Update.slaveLoopInit = function() { - let SL = V.slaves.length; - for (let i = 0; i < SL; i++) { - if (V.slaves[i].assignment !== "be imported") { - removeNonNGPSlave(V.slaves[i]); - i--, SL--; - } - } - for (let i = 0; i < SL; i++) { - if (V.slaves[i].assignment === "be imported") { - V.slaves[i].ID += NGPOffset; - V.slaves[i].assignment = "rest"; - V.slaves[i].weekAcquired = 0; - V.slaves[i].newGamePlus = 1; - if (V.slaves[i].mother > 0) { - V.slaves[i].mother += NGPOffset; - } else if (V.freshPC === 1 && V.slaves[i].mother === -1) { - V.slaves[i].mother = -NGPOffset; - } else if (V.slaves[i].mother < -1) { - V.slaves[i].mother -= NGPOffset; - } - if (V.slaves[i].father > 0) { - V.slaves[i].father += NGPOffset; - } else if (V.freshPC === 1 && V.slaves[i].father === -1) { - V.slaves[i].father = -NGPOffset; - } else if (V.slaves[i].father < -1) { - V.slaves[i].father -= NGPOffset; - } - V.slaves[i].daughters = 0; - V.slaves[i].sisters = 0; - V.slaves[i].canRecruit = 0; - V.slaves[i].breedingMark = 0; - if (V.arcologies[0].FSRomanRevivalist > 90) { - V.slaves[i].nationality = "Roman Revivalist"; - } else if (V.arcologies[0].FSAztecRevivalist > 90) { - V.slaves[i].nationality = "Aztec Revivalist"; - } else if (V.arcologies[0].FSEgyptianRevivalist > 90) { - V.slaves[i].nationality = "Ancient Egyptian Revivalist"; - } else if (V.arcologies[0].FSEdoRevivalist > 90) { - V.slaves[i].nationality = "Edo Revivalist"; - } else if (V.arcologies[0].FSArabianRevivalist > 90) { - V.slaves[i].nationality = "Arabian Revivalist"; - } else if (V.arcologies[0].FSChineseRevivalist > 90) { - V.slaves[i].nationality = "Ancient Chinese Revivalist"; - } - if (V.slaves[i].relationTarget !== 0) { - V.slaves[i].relationTarget += NGPOffset; - } - if (V.slaves[i].relationshipTarget !== 0) { - V.slaves[i].relationshipTarget += NGPOffset; - } - if (V.slaves[i].cloneID !== 0) { - V.slaves[i].cloneID += NGPOffset; - } - V.slaves[i].rivalry = 0, V.slaves[i].rivalryTarget = 0, V.slaves[i].subTarget = 0; - V.slaves[i].drugs = "no drugs"; - V.slaves[i].porn.spending = 0; - V.slaves[i].rules.living = "spare"; - V.slaves[i].diet = "healthy"; - V.slaves[i].pregControl = "none"; - } - } - V.slaveIndices = slaves2indices(); - for (let k = 0; k < SL; k++) { - for (let i = 0; i < SL; i++) { - if (V.slaves[k].mother === V.slaves[i].ID || V.slaves[k].father === V.slaves[i].ID) { - V.slaves[i].daughters += 1; - } - if (areSisters(V.slaves[k], V.slaves[i]) > 0) { - V.slaves[i].sisters += 1; - } - } - if (V.slaves[k].pregSource > 0) { - V.slaves[k].pregSource += NGPOffset; - let getFather = V.slaveIndices[V.slaves[k].pregSource]; - if (getFather) { - V.slaves[k].pregSource = 0; - } - } - for (let sInit = 0; sInit < V.slaves[k].womb.length; sInit++) { - if (V.slaves[k].womb[sInit].fatherID > 0) { - V.slaves[k].womb[sInit].fatherID += NGPOffset; - } else if (V.freshPC === 1 && V.slaves[k].womb[sInit].fatherID === -1) { - V.slaves[k].womb[sInit].fatherID = -NGPOffset; - } else if (V.slaves[k].womb[sInit].fatherID < -20) { - V.slaves[k].womb[sInit].fatherID -= NGPOffset; - } - if (V.slaves[k].womb[sInit].genetics.father > 0) { - V.slaves[k].womb[sInit].genetics.father += NGPOffset; - } else if (V.freshPC === 1 && V.slaves[k].womb[sInit].genetics.father === -1) { - V.slaves[k].womb[sInit].genetics.father = -NGPOffset; - } else if (V.slaves[k].womb[sInit].genetics.father < -20) { - V.slaves[k].womb[sInit].genetics.father -= NGPOffset; - } - if (V.slaves[k].womb[sInit].genetics.mother > 0) { - V.slaves[k].womb[sInit].genetics.mother += NGPOffset; - } else if (V.freshPC === 1 && V.slaves[k].womb[sInit].genetics.mother === -1) { - V.slaves[k].womb[sInit].genetics.mother = -NGPOffset; - } else if (V.slaves[k].womb[sInit].genetics.mother < -20) { - V.slaves[k].womb[sInit].genetics.mother -= NGPOffset; - } - } - if (V.slaves[k].cloneID !== 0) { - let getClone = V.slaveIndices[V.slaves[k].cloneID]; - if (getClone) { - V.slaves[k].cloneID = 0; - } - } - } - V.genePool = ngUpdateGenePool(V.genePool); - if (typeof V.missingTable === undefined || V.showMissingSlaves === false) { - V.missingTable = {}; - } else { - V.missingTable = ngUpdateMissingTable(V.missingTable); - } - for (let i = 0; i < SL; i++) { - if (V.slaves[i].relation !== 0) { - let seed = 0, rt = V.slaves[i].relationTarget, ID = V.slaves[i].ID; - let j = V.slaveIndices[rt]; - if ((j) && V.slaves[j].relationTarget === ID) { - seed = 1; - } - if (seed === 0) { - V.slaves[i].relation = 0, V.slaves[i].relationTarget = 0; - } - } - if (V.slaves[i].relationship > 0) { - let seed = 0, rt = V.slaves[i].relationshipTarget, ID = V.slaves[i].ID; - let j = V.slaveIndices[rt]; - if ((j) && V.slaves[j].relationshipTarget === ID) { - seed = 1; - } - if (seed === 0) { - V.slaves[i].relationship = 0, V.slaves[i].relationshipTarget = 0; - } - } - } - for (let i = 0; i < SL; i++) { - if (V.familyTesting === 1) { - if (V.slaves[i].canRecruit === 1) { - /* V.recruiters.push(V.slaves[i]);*/ - } - } else { - if (V.slaves[i].relation === 0) { - if (random(1, 100) <= 5) { - V.slaves[i].recruiter = "twin"; - } else if ((V.slaves[i].actualAge > 32) && (random(1, 100) <= 41)) { - V.slaves[i].recruiter = "mother"; - } else if ((V.slaves[i].actualAge < 24) && (random(1, 100) <= 40)) { - V.slaves[i].recruiter = "daughter"; - } else if ((V.slaves[i].actualAge < 43) && (random(1, 100) <= 20)) { - V.slaves[i].recruiter = "older sister"; - } else if ((V.slaves[i].actualAge < 25) && (V.slaves[i].actualAge > 18) && (random(1, 100) <= 20)) { - V.slaves[i].recruiter = "young sister"; - } - } else { - V.slaves[i].recruiter = 0; - } - } - /* closes family mode */ - V.slaves[i].counter.milk = 0; - V.slaves[i].counter.cum = 0; - V.slaves[i].counter.births = 0; - V.slaves[i].counter.mammary = 0; - V.slaves[i].counter.penetrative = 0; - V.slaves[i].counter.oral = 0; - V.slaves[i].counter.anal = 0; - V.slaves[i].counter.vaginal = 0; - V.slaves[i].lifetimeCashExpenses = 0; - V.slaves[i].lifetimeCashIncome = 0; - V.slaves[i].lastWeeksCashIncome = 0; - V.slaves[i].lifetimeRepExpenses = 0; - V.slaves[i].lifetimeRepIncome = 0; - V.slaves[i].lastWeeksRepExpenses = 0; - V.slaves[i].lastWeeksRepIncome = 0; - } -}; diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js index 675c392070cbbf968e37e356df092a5298ba2417..58773c817c636c9d7ee5a3f6d9be3ff2c0f7382a 100644 --- a/src/data/backwardsCompatibility/datatypeCleanup.js +++ b/src/data/backwardsCompatibility/datatypeCleanup.js @@ -581,13 +581,13 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() { slave.pubicHStyle = "neat"; } if (typeof slave.underArmHColor !== "string") { - slave.underArmHColor = "slave.hColor"; + slave.underArmHColor = slave.hColor; } if (typeof slave.underArmHStyle !== "string") { slave.underArmHStyle = "waxed"; } if (typeof slave.eyebrowHColor !== "string") { - slave.eyebrowHColor = "slave.hColor"; + slave.eyebrowHColor = slave.hColor; } if (typeof slave.eyebrowHStyle !== "string") { slave.eyebrowHStyle = "natural"; @@ -1234,13 +1234,13 @@ window.childHairDatatypeCleanup = function childHairDatatypeCleanup(child) { child.pubicHStyle = "neat"; } if (typeof child.underArmHColor !== "string") { - child.underArmHColor = "child.hColor"; + child.underArmHColor = child.hColor; } if (typeof child.underArmHStyle !== "string") { child.underArmHStyle = "waxed"; } if (typeof child.eyebrowHColor !== "string") { - child.eyebrowHColor = "child.hColor"; + child.eyebrowHColor = child.hColor; } if (typeof child.eyebrowHStyle !== "string") { child.eyebrowHStyle = "natural"; diff --git a/src/data/backwardsCompatibility/updateSlaveObject.js b/src/data/backwardsCompatibility/updateSlaveObject.js index 6c98695e4ce036159e9337c18e60012e1ea593e2..d8e22379da71ed8819ab5db01f3b904b71a7216f 100644 --- a/src/data/backwardsCompatibility/updateSlaveObject.js +++ b/src/data/backwardsCompatibility/updateSlaveObject.js @@ -1,8 +1,11 @@ -App.Update.Slave = function(slave) { +App.Update.Slave = function(slave, genepool=false) { slave.geneticQuirks = Object.assign({macromastia: 0, gigantomastia: 0, fertility: 0, hyperFertility: 0, superfetation: 0, gigantism: 0, dwarfism: 0, pFace: 0, uFace: 0, albinism: 0, heterochromia: 0, rearLipedema: 0, wellHung: 0, wGain: 0, wLoss: 0, mGain: 0, mLoss: 0, androgyny: 0, girlsOnly: 0}, slave.geneticQuirks); - - WombInit(slave); + if (genepool) { + slave.womb = []; + } else { + WombInit(slave); + } if (slave.earShape === undefined) { slave.earShape = "normal"; } if (slave.earT === undefined) { slave.earT = "none"; } @@ -63,7 +66,7 @@ App.Update.Slave = function(slave) { } } if (slave.genetics === undefined) { slave.genetics = {}; } - if (slave.geneMods === undefined) { geneMods = {NCS: 0, rapidCellGrowth: 0}; } + if (slave.geneMods === undefined) { slave.geneMods = {NCS: 0, rapidCellGrowth: 0}; } if (slave.inducedNCS !== undefined) { slave.geneMods.NCS = slave.inducedNCS; delete slave.inducedNCS; @@ -213,9 +216,10 @@ App.Update.Slave = function(slave) { } } - if (V.releaseID < 1059) { + if (V.releaseID < 1059 || !(slave.eye)) { slave.eye = new App.Entity.EyeState(); - setGeneticEyeColor(slave, slave.origEye); + const origEye = slave.origEye || "brown"; + setGeneticEyeColor(slave, origEye); if (slave.eyes === -4) { eyeSurgery(slave, "both", "remove"); } else { @@ -229,17 +233,14 @@ App.Update.Slave = function(slave) { } else if (slave.eyes === -1) { eyeSurgery(slave, "both", "blur"); } - setEyeColorFull(slave, slave.eyeColor, slave.pupil, slave.sclerae, "both"); + const eyeColor = slave.pupil || "brown"; + const pupil = slave.pupil || "circular"; + const sclerae = slave.pupil || "white"; + setEyeColorFull(slave, eyeColor, pupil, sclerae, "both"); if (typeof slave.geneticQuirks.heterochromia === "string") { setEyeColor(slave.geneticQuirks.heterochromia, "left"); } } - delete slave.eyes; - delete slave.eyesImplant; - delete slave.eyeColor; - delete slave.origEye; - delete slave.pupil; - delete slave.sclerae; } if (slave.eyes !== undefined) {delete slave.eyes;} @@ -374,6 +375,13 @@ App.Update.Slave = function(slave) { slave.markings = "beauty mark"; } + if (slave.underArmHColor === "slave.hColor") { + slave.underArmHColor === slave.hColor; + } + if (slave.eyebrowHColor === "slave.hColor") { + slave.eyebrowHColor === slave.hColor; + } + if (slave.genes === undefined) { if (slave.ovaries === 1) { slave.genes = "XX"; diff --git a/src/data/newGamePlus.js b/src/data/newGamePlus.js new file mode 100644 index 0000000000000000000000000000000000000000..3301f7de6be125bd34edf7f46a92c576fafc3c9a --- /dev/null +++ b/src/data/newGamePlus.js @@ -0,0 +1,185 @@ +App.Data.NewGamePlus = (function() { + const NGPOffset = 1200000; + + function ngpSlaveID(id, preserveSpecial=false) { + const minID = preserveSpecial ? -20 : -1; + if (id > 0) { + id += NGPOffset; + } else if (V.freshPC === 1 && id === -1) { + id = -NGPOffset; + } else if (id < minID) { + id -= NGPOffset; + } + return id; + } + + function slaveOrZero(id) { + if (id > 0 && !getSlave(id)) { + return 0; + } + return id; + } + + function PCInit() { + if (V.freshPC === 0) { + cashX(V.ngpParams.prosperity, "personalBusiness"); + const oldCash = V.cash; + V.cash = 0; + V.cashLastWeek = 0; + cashX((Math.clamp(1000*Math.trunc(oldCash/100000), 5000, 1000000)), "personalBusiness"); + if (V.retainCareer === 0) { + V.PC.career = "arcology owner"; + V.PC.skill.trading = 100; + V.PC.skill.warfare = 100; + V.PC.skill.hacking = 100; + V.PC.skill.slaving = 100; + V.PC.skill.engineering = 100; + V.PC.skill.medicine = 100; + } + V.PC.mother = ngpSlaveID(V.PC.mother); + V.PC.father = ngpSlaveID(V.PC.father); + V.PC.pregSource = slaveOrZero(ngpSlaveID(V.PC.pregSource, true)); + for (let fetus of V.PC.womb) { + fetus.fatherID = ngpSlaveID(fetus.fatherID, true); + fetus.genetics.father = ngpSlaveID(fetus.genetics.father, true); + fetus.genetics.mother = ngpSlaveID(fetus.genetics.mother, true); + } + } else { + V.PC = basePlayer(); + WombInit(V.PC); + V.cheater = 0; + V.cash = 0; + cashX(10000, "personalBusiness"); + } + } + + function slaveLoopInit() { + const ngUpdateGenePool = function(genePool = []) { + const transferredSlaveIds = (State.variables.slaves || []) + .filter(s => s.ID >= NGPOffset) + .map(s => s.ID - NGPOffset); + return genePool + .filter(s => (transferredSlaveIds.includes(s.ID))) + .map(function(s) { + const result = jQuery.extend(true, {}, s); + result.ID += NGPOffset; + return result; + }); + }; + + const ngUpdateMissingTable = function(missingTable) { + const newTable = {}; + + (State.variables.slaves || []) + .forEach(s => ([s.pregSource + NGPOffset, s.mother + NGPOffset, s.father + NGPOffset] + .filter(i => (i in missingTable)) + .forEach(i => { + newTable[i - NGPOffset] = missingTable[i]; + newTable[i - NGPOffset].ID -= NGPOffset; + }))); + + return newTable; + }; + + V.slaves.deleteWith((s) => s.assignment !== "be imported"); + + for (let slave of V.slaves) { + slave.ID += NGPOffset; + slave.assignment = "rest"; + slave.weekAcquired = 0; + slave.newGamePlus = 1; + slave.mother = ngpSlaveID(slave.mother); + slave.father = ngpSlaveID(slave.father); + slave.canRecruit = 0; + slave.breedingMark = 0; + if (typeof V.ngpParams.nationality === 'string') { + slave.nationality = V.ngpParams.nationality; + } + slave.relationTarget = ngpSlaveID(slave.relationTarget); + slave.relationshipTarget = ngpSlaveID(slave.relationshipTarget); + slave.cloneID = ngpSlaveID(slave.cloneID); + slave.pregSource = ngpSlaveID(slave.pregSource, true); + for (let fetus of slave.womb) { + fetus.fatherID = ngpSlaveID(fetus.fatherID, true); + fetus.genetics.father = ngpSlaveID(fetus.genetics.father, true); + fetus.genetics.mother = ngpSlaveID(fetus.genetics.mother, true); + } + slave.rivalry = 0, slave.rivalryTarget = 0, slave.subTarget = 0; + slave.drugs = "no drugs"; + slave.porn.spending = 0; + slave.rules.living = "spare"; + slave.diet = "healthy"; + slave.pregControl = "none"; + } + V.slaveIndices = slaves2indices(); + for (let slave of V.slaves) { + slave.pregSource = slaveOrZero(slave.pregSource); + slave.cloneID = slaveOrZero(slave.cloneID); + slave.relationshipTarget = slaveOrZero(slave.relationshipTarget); + slave.relationTarget = slaveOrZero(slave.relationTarget); + } + V.genePool = ngUpdateGenePool(V.genePool); + if (typeof V.missingTable === undefined || V.showMissingSlaves === false) { + V.missingTable = {}; + } else { + V.missingTable = ngUpdateMissingTable(V.missingTable); + } + let validRelation = (s) => (s.relationTarget !== 0 && getSlave(s.relationTarget).relationTarget === s.ID); + let validRelationship = (s) => (s.relationshipTarget !== 0 && getSlave(s.relationshipTarget).relationshipTarget === s.ID); + for (let slave of V.slaves) { + if (V.familyTesting === 1) { + if (slave.canRecruit === 1) { + /* V.recruiters.push(slave);*/ + } + } else { + if (slave.relation === 0) { + if (random(1, 100) <= 5) { + slave.recruiter = "twin"; + } else if ((slave.actualAge > 32) && (random(1, 100) <= 41)) { + slave.recruiter = "mother"; + } else if ((slave.actualAge < 24) && (random(1, 100) <= 40)) { + slave.recruiter = "daughter"; + } else if ((slave.actualAge < 43) && (random(1, 100) <= 20)) { + slave.recruiter = "older sister"; + } else if ((slave.actualAge < 25) && (slave.actualAge > 18) && (random(1, 100) <= 20)) { + slave.recruiter = "young sister"; + } + } else { + if (!validRelation(slave)) { + slave.relation = 0; + slave.relationTarget = 0; + } + slave.recruiter = 0; + } + } + if ((slave.relationship < 0 && V.freshPC === 1) || (slave.relationship > 0 && !validRelationship(slave))) { + slave.relationship = 0; + slave.relationshipTarget = 0; + } + slave.counter.milk = 0; + slave.counter.cum = 0; + slave.counter.births = 0; + slave.counter.mammary = 0; + slave.counter.penetrative = 0; + slave.counter.oral = 0; + slave.counter.anal = 0; + slave.counter.vaginal = 0; + slave.lifetimeCashExpenses = 0; + slave.lifetimeCashIncome = 0; + slave.lastWeeksCashIncome = 0; + slave.lifetimeRepExpenses = 0; + slave.lifetimeRepIncome = 0; + slave.lastWeeksRepExpenses = 0; + slave.lastWeeksRepIncome = 0; + } + } + + function doNGPSetup() { + slaveLoopInit(); + PCInit(); + resetFamilyCounters(); + V.ngpParams = {}; + } + + return doNGPSetup; +})(); diff --git a/src/descriptions/arcologyDescription.js b/src/descriptions/arcologyDescription.js index f25075e068ed659282904d9fb6d8abd39322d4a1..e20b22dbe062fe30e789972710d04ab7d7ffe896 100644 --- a/src/descriptions/arcologyDescription.js +++ b/src/descriptions/arcologyDescription.js @@ -196,10 +196,10 @@ App.Desc.playerArcology = function(lastElement) { let buffer = []; buffer.push(`The entryway features the first of ${A.name}'s many banks of public screens.`); if (A.FSSupremacistDecoration >= 40) { - buffer.push(`Some are showing talk shows and documentaries supporting A.FSSupremacistRace supremacy.`); + buffer.push(`Some are showing talk shows and documentaries supporting ${A.FSSupremacistRace} supremacy.`); } if (A.FSSubjugationistDecoration >= 40) { - buffer.push(`Some are showing long pseudoscientific programs explaining A.FSSubjugationistRace degeneracy.`); + buffer.push(`Some are showing long pseudoscientific programs explaining ${A.FSSubjugationistRace} degeneracy.`); } if (A.FSDegradationistDecoration >= 40) { buffer.push(`Some are showing abusive pornography involving slaves being beaten, sodomized, and modified against their will.`); diff --git a/src/events/001-base/baseEvent.js b/src/events/001-base/baseEvent.js index 8fe3d9f7c03eba76c013c2cfee78153af989845f..822c0b1251aee84aa7b1f72d4bed7f802c4caf9c 100644 --- a/src/events/001-base/baseEvent.js +++ b/src/events/001-base/baseEvent.js @@ -56,6 +56,14 @@ App.Events.BaseEvent = class BaseEvent { return JSON.reviveWrapper(`new App.Events.${this.constructor.name}(${JSON.stringify(this.actors)},${JSON.stringify(this.params)})`); } + /** get the event's (human-readable) name. must not include ":". + * default implementation should generally suffice (though we might want to de-camelcase here or something). + * @returns {string} + */ + get eventName() { + return this.constructor.name; + } + /** build the actual list of actors that will be involved in this event. * default implementation should suffice for child classes with a fixed number of actors; may be overridden for events with variable actor count. * @param {App.Entity.SlaveState} firstActor - if non-null, the first actor should be this slave (fail if she is not qualified) diff --git a/src/events/intro/arcologySelection.js b/src/events/intro/arcologySelection.js index ee804bb61e31ba5dfd7e59b20d57b528ccf74eb4..2845f0f8e23a8129b838af342392b2376da1ddb7 100644 --- a/src/events/intro/arcologySelection.js +++ b/src/events/intro/arcologySelection.js @@ -287,7 +287,7 @@ App.Intro.generateEstablishedArcologies = function() { if (V.pedo_mode === 1 || V.minimumSlaveAge < 6) { return setup.ArcologyNamesYouthPreferentialistLow.random(); } else if (V.minimumSlaveAge < 14) { - return either(setup.ArcologyNamesYouthPreferentialist, setup.ArcologyNamesYouthPreferentialistLow).random(); + return setup.ArcologyNamesYouthPreferentialist.concat(setup.ArcologyNamesYouthPreferentialistLow).random(); } else { return setup.ArcologyNamesYouthPreferentialist.random(); } diff --git a/src/events/intro/initNationalities.tw b/src/events/intro/initNationalities.tw index ef78724ae0f087a493d7d801ed54d1d0722228a9..055f786043cdaa94a3a3fd4e2702bf231beaded7 100644 --- a/src/events/intro/initNationalities.tw +++ b/src/events/intro/initNationalities.tw @@ -12,7 +12,7 @@ <<if $secExpEnabled > 0>> /* base vars */ <<set $SecExp = SecExpBase()>> - <<= App.SecExp.Check.general()>> + <<run App.SecExp.Check.general()>> <<set $secExp = SecExpBase()>> <<set $secUpgrades = { nanoCams: 0, diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js index 84ad32ee14c58289a30d74c1a09dadb81befbbfe..dc12e6eac0b207c47102397d98dd05d700ff5a16 100644 --- a/src/events/randomEvent.js +++ b/src/events/randomEvent.js @@ -39,13 +39,13 @@ App.Events.getNonindividualEvents = function() { /** get a stringified list of possible individual events as fake passage names - TODO: kill me */ App.Events.getIndividualEventsPassageList = function(slave) { const events = App.Events.getIndividualEvents(slave); - return events.map(e => `JSRE ${e.constructor.name}:${JSON.stringify(e.toJSON())}`); + return events.map(e => `JSRE ${e.eventName}:${JSON.stringify(e.toJSON())}`); }; /** get a stringified list of possible individual events as fake passage names - TODO: kill me */ App.Events.getNonindividualEventsPassageList = function() { const events = App.Events.getNonindividualEvents(); - return events.map(e => `JSRE ${e.constructor.name}:${JSON.stringify(e.toJSON())}`); + return events.map(e => `JSRE ${e.eventName}:${JSON.stringify(e.toJSON())}`); }; /** execute a fake event passage from the embedded JSON - TODO: kill me */ diff --git a/src/facilities/nursery/nurseryDatatypeCleanup.js b/src/facilities/nursery/nurseryDatatypeCleanup.js index 90f31a73975b4a470702db334fb77092662b1773..9e80c4b3e2c2e5deb6e13a6c2f2c0ec96dcdb3eb 100644 --- a/src/facilities/nursery/nurseryDatatypeCleanup.js +++ b/src/facilities/nursery/nurseryDatatypeCleanup.js @@ -108,13 +108,13 @@ App.Facilities.Nursery.ChildDatatypeCleanup = function(child) { child.pubicHStyle = "neat"; } if (typeof child.underArmHColor !== "string") { - child.underArmHColor = "child.hColor"; + child.underArmHColor = child.hColor; } if (typeof child.underArmHStyle !== "string") { child.underArmHStyle = "waxed"; } if (typeof child.eyebrowHColor !== "string") { - child.eyebrowHColor = "child.hColor"; + child.eyebrowHColor = child.hColor; } if (typeof child.eyebrowHStyle !== "string") { child.eyebrowHStyle = "natural"; @@ -562,7 +562,7 @@ App.Facilities.Nursery.InfantDatatypeCleanup = function(child) { child.pubicHStyle = "neat"; } if (typeof child.eyebrowHColor !== "string") { - child.eyebrowHColor = "child.hColor"; + child.eyebrowHColor = child.hColor; } } diff --git a/src/gui/storyCaption.tw b/src/gui/storyCaption.tw index 1789dc6fdb3bddb9805cd4271774c12c44ae41cd..48970224aa2aaf43cd1db41dc4e673474d8b040d 100644 --- a/src/gui/storyCaption.tw +++ b/src/gui/storyCaption.tw @@ -62,6 +62,9 @@ <<if $ui != "start" && _Pass != "Encyclopedia">> <<if $cheatMode || $debugMode>> <div>_Pass</div> + <<if _Pass == "JS Random Event">> + <div><<= $event.eventName>></div> + <</if>> <</if>> <div> <span id="week">''Week $week''</span> diff --git a/src/init/storyInit.tw b/src/init/storyInit.tw index 48c6b128f139128dc81d142489a8320363870116..cc124ea7944b61eea5f687c630d201eb5737542c 100644 --- a/src/init/storyInit.tw +++ b/src/init/storyInit.tw @@ -20,87 +20,19 @@ You should have received a copy of the GNU General Public License along with thi <<set $ver = App.Version.base, $pmodVer = App.Version.pmod, $releaseID = App.Version.release>> -<<set _NGPOffset = 1200000>> - -<<run App.Update.slaveLoopInit()>> - /* 0 out the record books as we start a new game */ <<run setupLastWeeksCash()>> <<run setupLastWeeksRep()>> <<if $saveImported == 0>> /* new game (not NG+) */ - <<set $PC = basePlayer()>> <<run WombInit($PC)>> <<run cashX(10000, "personalBusiness")>> <<include "Init Rules">> - <<else>> /* imported save (NG+) */ - - <<if $freshPC == 0>> - <<if def $arcologies[0].prosperity>> - <<run cashX((250*$arcologies[0].prosperity*$arcologies[0].ownership), "personalBusiness")>> - <</if>> - <<set _cash = $cash, $cash = 0, $cashLastWeek = 0>> - <<run cashX((Math.clamp(1000*Math.trunc(_cash/100000), 5000, 1000000)), "personalBusiness")>> - <<if $retainCareer == 0>> - <<set $PC.career = "arcology owner", $PC.skill.trading = 100, $PC.skill.warfare = 100, $PC.skill.hacking = 100, $PC.skill.slaving = 100, $PC.skill.engineering = 100, $PC.skill.medicine = 100>> - <</if>> - <<if $PC.mother > 0>> - <<set $PC.mother += _NGPOffset>> - <<elseif $PC.mother < 0>> - <<set $PC.mother -= _NGPOffset>> - <</if>> - <<if $PC.father > 0>> - <<set $PC.father += _NGPOffset>> - <<elseif $PC.father < 0>> - <<set $PC.father -= _NGPOffset>> - <</if>> - <<if $PC.pregSource > 0>> - <<set $PC.pregSource += _NGPOffset>> - <<set _getFather = $slaveIndices[$PC.pregSource]>> - <<if ndef _getFather>> - <<set $PC.pregSource = 0>> - <</if>> - <<for _sInit = 0; _sInit < $PC.womb.length; _sInit++>> - <<if $PC.womb[_sInit].fatherID > 0>> - <<set $PC.womb[_sInit].fatherID += _NGPOffset>> - <</if>> - <</for>> - <</if>> - <<else>> - <<set $PC = basePlayer()>> - <<run WombInit($PC)>> - <<set $cheater = 0>> - <<set $cash = 0>> - <<run cashX(10000, "personalBusiness")>> - <<for _i = 0; _i < _SL; _i++>> - <<if $familyTesting == 1>> - <<if $slaves[_i].mother == -1>> - <<set $slaves[_i].mother = $missingParentID+_NGPOffset>> - <</if>> - <<if $slaves[_i].father == -1>> - <<set $slaves[_i].father = $missingParentID+_NGPOffset>> - <</if>> - <<if $slaves[_i].pregSource == -1>> - <<set $slaves[_i].pregSource = 0>> - <</if>> - <<if $slaves[_i].cloneID == -1>> - <<set $slaves[_i].cloneID = 0>> - <</if>> - <</if>> - <<for _sInit = 0; _sInit < $slaves[_i].womb.length; _sInit++>> - <<if $slaves[_i].womb[_sInit].fatherID == -1>> - <<set $slaves[_i].womb[_sInit].fatherID = 0>> - <</if>> - <</for>> - <</for>> - <</if>> - - /*Undefining corporation variables*/ - <<unset $corp.AssetsDev, $corp.AssetsDevOld, $corp.AssetsSlave, $corp.AssetsSlaveOld, $corp.Cash, $corp.Div, $corp.DivArcadeFromMarket, $corp.DivArcadeSlaves, $corp.DivBreakFromMarket, $corp.DivBreakSlaves, $corp.DivBreakSlaves2, $corp.DivBreakToMarket, $corp.DivBreakToMenial, $corp.DivBreakToSurgery, $corp.DivBreakToTrain, $corp.DivDairyFromMarket, $corp.DivDairySlaves, $corp.DivExtraSlaves, $corp.DivExtraToArcade, $corp.DivExtraToBreak, $corp.DivExtraToMarket, $corp.Dividend, $corp.DivLegalSlaves, $corp.DivLegalToMarket, $corp.DivLegalToMenial, $corp.DivLegalToSurgery, $corp.DivLegalToTrain, $corp.DivMenialFromMarket, $corp.DivMenialSlaves, $corp.DivSurgeryFromMarket, $corp.DivSurgerySlaves, $corp.DivSurgerySlaves2, $corp.DivSurgeryToDairy, $corp.DivSurgeryToMarket, $corp.DivSurgeryToTrain, $corp.DivTrainFromMarket, $corp.DivTrainSlaves, $corp.DivTrainSlaves2, $corp.DivTrainToMarket, $corp.DivTrainToWhore, $corp.DivWhoreFromMarket, $corp.DivWhoreSlaves, $corp.OpCostOld, $corp.OverheadOld, $corp.ProfitOld, $corp.Rev, $corp.RevOld, $corp.SpecAccent, $corp.SpecAge, $corp.SpecNationality, $corp.SpecAmputee, $corp.SpecBalls, $corp.SpecDevotion, $corp.SpecDick, $corp.SpecEducation, $corp.SpecGender, $corp.SpecGenitalia, $corp.SpecHeight, $corp.SpecHormones, $corp.SpecImplants, $corp.SpecInjection, $corp.SpecIntelligence, $corp.SpecMilk, $corp.SpecMuscle, $corp.SpecPussy, $corp.SpecSexEd, $corp.SpecTrust, $corp.SpecVirgin, $corp.SpecWeight, $dividendTimer, $personalShares, $publicShares>> - + <<run App.Data.NewGamePlus()>> <</if>> + /* Porn star counts (prestige 1) and ID's (prestige 3) */ <<set $pornStars = {}>> <<for _genre range App.Porn.getAllGenres()>> diff --git a/src/interaction/slaveInteract.js b/src/interaction/slaveInteract.js index b778f0f66ae52d123d8d56b3952d182c7ce33a89..c35674903bb51c4fd4dc12c2ebdd11648a33af5a 100644 --- a/src/interaction/slaveInteract.js +++ b/src/interaction/slaveInteract.js @@ -1,63 +1,24 @@ /* eslint-disable no-unused-vars */ // TODO: remove after testing App.UI.SlaveInteract.placeInLine = function(slave) { - let slavesInLine = []; - let activeSlaveIndex = V.slaveIndices[slave.ID]; - let SL = V.slaves.length; - - if (assignmentVisible(slave)) { - for (let pil = activeSlaveIndex - 1; pil !== activeSlaveIndex; pil--) { - /* loops backwards through the V.slaves array */ - if (pil < 0) { - pil = SL; - continue; - } - if (assignmentVisible(V.slaves[pil])) { - slavesInLine.push(pil); /* index of the previous slave in line */ - break; - } - } - for (let pil = activeSlaveIndex + 1; pil !== activeSlaveIndex; pil++) { - /* this loops forwards through the V.slaves array */ - if (pil === SL) { - pil = -1; - continue; - } - if (assignmentVisible(V.slaves[pil])) { - slavesInLine.push(pil); /* index of the next slave in line */ - break; - } - } + const useSlave = assignmentVisible(slave) ? ((s) => assignmentVisible(s)) : ((s) => slave.assignment === s.assignment); + const slaveList = V.slaves.filter(useSlave); + SlaveSort.slaves(slaveList); + const curSlaveIndex = slaveList.findIndex((s) => s.ID === slave.ID); + + let nextIndex; + if (curSlaveIndex + 1 > slaveList.length - 1) { + nextIndex = 0; // wrap around to first slave } else { - for (let pil = activeSlaveIndex - 1; pil !== activeSlaveIndex; pil--) { - /* loops backwards through the V.slaves array */ - if (pil < 0) { - pil = SL; - continue; - } - if (V.slaves[pil].assignment === slave.assignment) { - slavesInLine.push(pil); /* index of the previous slave in line */ - break; - } - } - for (let pil = activeSlaveIndex + 1; pil !== activeSlaveIndex; pil++) { - /* this loops forwards through the V.slaves array */ - if (pil === SL) { - pil = -1; - continue; - } - if (V.slaves[pil].assignment === slave.assignment) { - slavesInLine.push(pil); /* index of the next slave in line */ - break; - } - } + nextIndex = curSlaveIndex + 1; } - - if (slavesInLine.length === 0) { - /* if there are no other slaves available, set previous/next slave to self */ - slavesInLine[0] = activeSlaveIndex; - slavesInLine[1] = activeSlaveIndex; + let prevIndex; + if (curSlaveIndex - 1 < 0) { + prevIndex = slaveList.length - 1; // wrap around to last slave + } else { + prevIndex = curSlaveIndex - 1; } - return slavesInLine; + + return [ slaveList[prevIndex].ID, slaveList[nextIndex].ID ]; }; App.UI.SlaveInteract.fucktoyPref = function(slave) { @@ -2367,16 +2328,16 @@ App.UI.SlaveInteract.custom = (function() { kbd.appendChild(filetypeDesc); note.appendChild(kbd); - note.append(`, enter `); + note.append(`, choose `); kbd = document.createElement('kbd'); - kbd.textContent = `headgirl`; + kbd.textContent = `PNG`; note.appendChild(kbd); - note.append(` then choose `); + note.append(` then enter `); kbd = document.createElement('kbd'); - kbd.textContent = `JPG`; + kbd.textContent = `headgirl`; note.appendChild(kbd); note.append(`.`); diff --git a/src/js/assayJS.js b/src/js/assayJS.js index 68a3ec9ed0ccd585dddf27bfd0ceaca48e6f66f4..443245cab40d35fdf0d9db577e6925db32b0b014 100644 --- a/src/js/assayJS.js +++ b/src/js/assayJS.js @@ -1534,7 +1534,17 @@ window.SlaveSort = function() { */ /** @returns {slaveComparator} */ function _comparator() { - return comparators[(V.sortSlavesOrder === "ascending" ? 'A' : 'D') + V.sortSlavesBy]; + return _makeStableComparator(comparators[(V.sortSlavesOrder === "ascending" ? 'A' : 'D') + V.sortSlavesBy]); + } + + /** secondary-sort by ascending ID if the primary comparator would return 0 (equal), so we have a guaranteed stable order regardless of input + * @param {slaveComparator} comparator + * @returns {slaveComparator} + */ + function _makeStableComparator(comparator) { + return function(a, b) { + return comparator(a, b) || comparators.AID(a, b); + }; } }(); diff --git a/src/js/descriptionWidgets.js b/src/js/descriptionWidgets.js index ab97fcf10c600f9e0f3746222fb4d9f435a45d8b..915ba3fc73ff8870016ef5a5ece00627de379e46 100644 --- a/src/js/descriptionWidgets.js +++ b/src/js/descriptionWidgets.js @@ -1,3 +1,65 @@ +/** + * @param {App.Entity.SlaveState} slave + * @returns {string} Slave's nails + */ +App.Desc.nails = function(slave) { + /* eslint-disable no-unused-vars*/ + const {He, His, his} = getPronouns(slave); + if (!hasAnyArms(slave)) { + return `${He} has no hands, and thus, no nails.`; + } else if (slave.nails === 1) { + return `${His} nails are long and elegant.`; + } else if (slave.nails === 2) { + return `${His} nails are color-coordinated with ${his} ${slave.hColor} hair.`; + } else if (slave.nails === 3) { + return `${His} nails are sharp and claw-like.`; + } else if (slave.nails === 4) { + return `${His} nails are bright and glittery.`; + } else if (slave.nails === 5) { + return `${His} nails are long and garish, streetwalker-style.`; + } else if (slave.nails === 6) { + return `${His} nails are vivid and eye-catching.`; + } else if (slave.nails === 7) { + return `${His} nails are vivid, eye-catching and color-coordinated with ${his} ${slave.hColor} hair.`; + } else if (slave.nails === 8) { + return `${His} nails are shiny and metallic.`; + } else if (slave.nails === 9) { + return `${His} nails are shiny, metallic and color-coordinated with ${his} ${slave.hColor} hair.`; + } else { + return `${His} nails are neatly clipped.`; + } +}; + +/** + * @param {App.Entity.SlaveState} slave + * @returns {string} Slave's makeup + */ +App.Desc.makeup = function(slave) { + /* eslint-disable no-unused-vars*/ + const {He, His, his} = getPronouns(slave); + if (slave.makeup === 1) { + return `${He}'s wearing minimal makeup.`; + } else if (slave.makeup === 2) { + return `${He}'s wearing expensive, luxurious makeup.`; + } else if (slave.makeup === 3) { + return `${His} makeup is color-coordinated with ${his} ${slave.hColor} hair.`; + } else if (slave.makeup === 4) { + return `${He}'s wearing stereotypical, garish streetwalker makeup.`; + } else if (slave.makeup === 5) { + return `${He}'s wearing eye-catching neon makeup.`; + } else if (slave.makeup === 6) { + return `${His} neon makeup is color-coordinated with ${his} ${slave.hColor} hair.`; + } else if (slave.makeup === 7) { + return `${He}'s wearing expensive, metallic makeup.`; + } else if (slave.makeup === 8) { + return `${His} metallic makeup is color-coordinated with ${his} ${slave.hColor} hair.`; + } else if (slave.lipsTat === "permanent makeup") { + return `${His} face appears to bear very heavy, slutty makeup, but on closer inspection, the makeup is actually tattooed on.`; + } else { + return `${His} face is makeup-free.`; + } +}; + /** * @param {App.Entity.SlaveState} slave * @returns {string} Slave's eyes diff --git a/src/js/extendedFamilyModeJS.js b/src/js/extendedFamilyModeJS.js index e10f433f13b2e1e2efd383fe75ff328f9483819c..c1d74f93f296a65948fd88d7ada1dfe96665b38c 100644 --- a/src/js/extendedFamilyModeJS.js +++ b/src/js/extendedFamilyModeJS.js @@ -481,3 +481,32 @@ window.relativeTerm = function(slave1, slave2) { return null; }; + +/** completely reset all the family counters in the game state (for both PC and slaves) */ +window.resetFamilyCounters = function() { + for (let slave of V.slaves) { + slave.daughters = 0; + slave.sisters = 0; + } + V.PC.daughters = 0; + V.PC.sisters = 0; + + if (V.familyTesting === 1) { + for (let slave of V.slaves) { + if (slave.mother === -1 || slave.father === -1) { + V.PC.daughters++; + } + if (areSisters(slave, V.PC)) { + V.PC.sisters++; + } + for (let otherSlave of V.slaves) { + if (isParentP(otherSlave, slave)) { + slave.daughters++; + } + if (areSisters(otherSlave, slave)) { + slave.sisters++; + } + } + } + } +}; diff --git a/src/js/generateGenetics.js b/src/js/generateGenetics.js index 07ed18740f38850d2b6789fe376eaeed27089e5b..6cacff3190cdf44704b5c73a1744511ffab55de2 100644 --- a/src/js/generateGenetics.js +++ b/src/js/generateGenetics.js @@ -1389,18 +1389,9 @@ window.generateChild = function(mother, ova, destination) { } child.weekAcquired = V.week; if (child.nationality === "Stateless") { - if (V.arcologies[0].FSRomanRevivalist > 90) { - child.nationality = "Roman Revivalist"; - } else if (V.arcologies[0].FSAztecRevivalist > 90) { - child.nationality = "Aztec Revivalist"; - } else if (V.arcologies[0].FSEgyptianRevivalist > 90) { - child.nationality = "Ancient Egyptian Revivalist"; - } else if (V.arcologies[0].FSEdoRevivalist > 90) { - child.nationality = "Edo Revivalist"; - } else if (V.arcologies[0].FSArabianRevivalist > 90) { - child.nationality = "Arabian Revivalist"; - } else if (V.arcologies[0].FSChineseRevivalist > 90) { - child.nationality = "Ancient Chinese Revivalist"; + const revivalistNationality = getRevivalistNationality(); + if (typeof revivalistNationality === 'string') { + child.nationality = revivalistNationality; } } } else { @@ -1736,18 +1727,9 @@ window.generateChild = function(mother, ova, destination) { child.trust = 0; child.weekAcquired = V.week; if (child.nationality === "Stateless") { - if (V.arcologies[0].FSRomanRevivalist > 90) { - child.nationality = "Roman Revivalist"; - } else if (V.arcologies[0].FSAztecRevivalist > 90) { - child.nationality = "Aztec Revivalist"; - } else if (V.arcologies[0].FSEgyptianRevivalist > 90) { - child.nationality = "Ancient Egyptian Revivalist"; - } else if (V.arcologies[0].FSEdoRevivalist > 90) { - child.nationality = "Edo Revivalist"; - } else if (V.arcologies[0].FSArabianRevivalist > 90) { - child.nationality = "Arabian Revivalist"; - } else if (V.arcologies[0].FSChineseRevivalist > 90) { - child.nationality = "Ancient Chinese Revivalist"; + const revivalistNationality = getRevivalistNationality(); + if (typeof revivalistNationality === 'string') { + child.nationality = revivalistNationality; } } diff --git a/src/js/removeActiveSlave.js b/src/js/removeActiveSlave.js index 1d34fc8386a3e90b0a268d4a4afa3212ee80fa94..82882699038578c6b32da86e938e2283ca12d0c0 100644 --- a/src/js/removeActiveSlave.js +++ b/src/js/removeActiveSlave.js @@ -113,6 +113,9 @@ window.removeActiveSlave = function removeActiveSlave() { slave.origBodyOwnerID = 0; } */ + if (slave.ID === V.activeSlave.subTarget || V.activeSlave.subTarget === slave.ID) { + V.activeSlave.subTarget = 0; slave.subTarget = 0; + } }); /* remove from Pit fighters list, if needed */ @@ -166,7 +169,7 @@ window.removeActiveSlave = function removeActiveSlave() { V.boomerangSlave.father = V.missingParentID; } if (V.boomerangSlave.origBodyOwnerID === AS_ID) { - V.traitor.origBodyOwnerID = 0; + V.boomerangSlave.origBodyOwnerID = 0; } } diff --git a/src/js/storyJS.js b/src/js/storyJS.js index 471646cb25c6ce53de02c0bb2e7e100259e84f0f..b01452d869efb475f502b19e51d32664c43c4e56 100644 --- a/src/js/storyJS.js +++ b/src/js/storyJS.js @@ -367,33 +367,6 @@ window.bodyguardSuccessorEligible = function(slave) { return (slave.devotion > 50 && slave.muscles >= 0 && slave.weight < 100 && slave.boobs < 8000 && slave.butt < 10 && slave.belly < 5000 && slave.balls < 10 && slave.dick < 10 && slave.preg < 20 && slave.fuckdoll === 0 && slave.fetish !== "mindbroken" && canWalk(slave) && canHold(slave) && canSee(slave) && canHear(slave)); }; -window.ngUpdateGenePool = function(genePool = []) { - const transferredSlaveIds = (State.variables.slaves || []) - .filter(s => s.ID >= 1200000) - .map(s => s.ID - 1200000); - return genePool - .filter(s => (transferredSlaveIds.includes(s.ID))) - .map(function(s) { - const result = jQuery.extend(true, {}, s); - result.ID += 1200000; - return result; - }); -}; - -window.ngUpdateMissingTable = function(missingTable) { - const newTable = {}; - - (State.variables.slaves || []) - .forEach(s => ([s.pregSource + 1200000, s.mother + 1200000, s.father + 1200000] - .filter(i => (i in missingTable)) - .forEach(i => { - newTable[i - 1200000] = missingTable[i]; - newTable[i - 1200000].ID -= 1200000; - }))); - - return newTable; -}; - /** * @param {any} obj * @returns {string} @@ -469,10 +442,14 @@ window.overpowerCheck = function(slave, PC) { * @param {App.Entity.SlaveState} slave * @returns {number[]} */ -window.impregnatedBy = function(slave) { +window.impregnatedBy = function(slave, genepool=false) { const IDArray = []; if (!Array.isArray(slave.womb)) { - WombInit(slave); + if (genepool) { + slave.womb = []; + } else { + WombInit(slave); + } } for (let i = 0; i < slave.womb.length; i++) { IDArray.push(slave.womb[i].fatherID); @@ -486,8 +463,8 @@ window.impregnatedBy = function(slave) { * @param {App.Entity.SlaveState} father * @returns {boolean} */ -window.isImpregnatedBy = function(mother, father) { - return impregnatedBy(mother).includes(father.ID); +window.isImpregnatedBy = function(mother, father, genepool=false) { + return impregnatedBy(mother, genepool).includes(father.ID); }; /** diff --git a/src/js/utilsFC.js b/src/js/utilsFC.js index 86717839ff1482f77b213d2dc68e2213b38b8d41..4a4ee7b93826f23ea611964730cdb1be6038e14b 100644 --- a/src/js/utilsFC.js +++ b/src/js/utilsFC.js @@ -2899,3 +2899,20 @@ window.ASDump = function() { } } }; + +window.getRevivalistNationality = function() { + if (V.arcologies[0].FSRomanRevivalist > 90) { + return "Roman Revivalist"; + } else if (V.arcologies[0].FSAztecRevivalist > 90) { + return "Aztec Revivalist"; + } else if (V.arcologies[0].FSEgyptianRevivalist > 90) { + return "Ancient Egyptian Revivalist"; + } else if (V.arcologies[0].FSEdoRevivalist > 90) { + return "Edo Revivalist"; + } else if (V.arcologies[0].FSArabianRevivalist > 90) { + return "Arabian Revivalist"; + } else if (V.arcologies[0].FSChineseRevivalist > 90) { + return "Ancient Chinese Revivalist"; + } + return 0; +}; diff --git a/src/npc/acquisition.tw b/src/npc/acquisition.tw index 963653ab1853507c895cd62c50b8aca540050c7c..3865480798c42877a170a49aac712a26e7023798 100644 --- a/src/npc/acquisition.tw +++ b/src/npc/acquisition.tw @@ -122,10 +122,7 @@ <<set $PC.prostate = 0>> <</if>> <<set $PC.ovaryAge = $PC.physicalAge>> -<<else>> /*testtest*/ - <<set $PC.sisters = 0>> - <<set $PC.daughters = 0>> -<</if>> /*closes ng*/ +<</if>> <<if $familyTesting == 1>> <<set _pcMomFound = 0, _pcDadFound = 0>> <<if def $slaveIndices[$PC.mother]>> @@ -134,14 +131,6 @@ <<if def $slaveIndices[$PC.father]>> <<set _pcDadFound = 1>> <</if>> - <<for _i = 0; _i < $slaves.length; _i++>> - <<if $slaves[_i].mother == $PC.ID || $slaves[_i].father == $PC.ID>> - <<set $PC.daughters += 1>> - <</if>> - <<if areSisters($slaves[_i], $PC) > 0>> - <<set $PC.sisters += 1>> - <</if>> - <</for>> <<if _pcMomFound == 0 && $PC.mother > 0>> <<set _lostMom = $PC.mother>> <<set $PC.mother = $missingParentId>> @@ -205,6 +194,7 @@ <</if>> <<set $targetAge = $minimumSlaveAge>> <<set $targetAgeNursery = $minimumSlaveAge>> +<<run resetFamilyCounters()>> You've done it. <br><br> @@ -850,26 +840,6 @@ The previous owner seems to have left in something of a hurry. <</if>> <</if>> <</for>> -<<if $familyTesting == 1>> - <<set $slaves.forEach(function(s) { s.sisters = 0; s.daughters = 0; })>> - <<set $PC.daughters = 0, $PC.sisters = 0>> - <<for _fp = 0; _fp < $slaves.length; _fp++>> - <<if ($slaves[_fp].mother == -1 || $slaves[_fp].father == -1)>> - <<set $PC.daughters++>> - <</if>> - <<if areSisters($slaves[_fp], $PC) > 0>> - <<set $PC.sisters++>> - <</if>> - <<for _fpt = 0; _fpt < $slaves.length; _fpt++>> - <<if ($slaves[_fpt].mother == $slaves[_fp].ID) || ($slaves[_fpt].father == $slaves[_fp].ID)>> - <<set $slaves[_fp].daughters++>> - <</if>> - <<if areSisters($slaves[_fpt], $slaves[_fp]) > 0>> - <<set $slaves[_fp].sisters++>> - <</if>> - <</for>> - <</for>> -<</if>> <<if _slavesContributing != 0>> <<set $averageTrust = $averageTrust/_slavesContributing>> <<set $averageDevotion = $averageDevotion/_slavesContributing>> diff --git a/src/npc/familyPanic.tw b/src/npc/familyPanic.tw deleted file mode 100644 index b8edb689586d5368549dbe5818b71a0586dd088a..0000000000000000000000000000000000000000 --- a/src/npc/familyPanic.tw +++ /dev/null @@ -1,25 +0,0 @@ -:: family panic [nobr] - -<<set $nextButton = "Back", $nextLink = "Main">> - -<<set $slaves.forEach(function(s) { s.sisters = 0; s.daughters = 0; })>> -<<set $PC.daughters = 0, $PC.sisters = 0>> - -<<for _fp = 0; _fp < $slaves.length; _fp++>> - <<if ($slaves[_fp].mother == -1 || $slaves[_fp].father == -1)>> - <<set $PC.daughters++>> - <</if>> - <<if areSisters($slaves[_fp], $PC) > 0>> - <<set $PC.sisters++>> - <</if>> - <<for _fpt = 0; _fpt < $slaves.length; _fpt++>> - <<if ($slaves[_fpt].mother == $slaves[_fp].ID) || ($slaves[_fpt].father == $slaves[_fp].ID)>> - <<set $slaves[_fp].daughters++>> - <</if>> - <<if areSisters($slaves[_fpt], $slaves[_fp]) > 0>> - <<set $slaves[_fp].sisters++>> - <</if>> - <</for>> -<</for>> - -//Family relations flushed and rebuilt.// diff --git a/src/npc/surgery/surgery.js b/src/npc/surgery/surgery.js index 59689791768fefc004dca2dbdb2c5327070afc23..743dd079b937a84324d59af694832e9696969ac0 100644 --- a/src/npc/surgery/surgery.js +++ b/src/npc/surgery/surgery.js @@ -731,7 +731,7 @@ window.setEyeColor = function setEyeColor(slave, color, side = "both") { * @param {string} sclera * @param {string} side */ -window.setEyeColorFull = function setEyeColorFull(slave, iris, pupil, sclera, side) { +window.setEyeColorFull = function setEyeColorFull(slave, iris = "brown", pupil = "circular", sclera = "white", side) { if (side === "both") { setEyeColorFull(slave, iris, pupil, sclera, "left"); setEyeColorFull(slave, iris, pupil, sclera, "right"); diff --git a/src/personalAssistant/assistantEvents.tw b/src/personalAssistant/assistantEvents.tw index 43a1d38c33f5f29a70b588b5341bedde8510eaa2..9fca4c3f34a582af92a343738b1014320c8f0743 100644 --- a/src/personalAssistant/assistantEvents.tw +++ b/src/personalAssistant/assistantEvents.tw @@ -1306,13 +1306,7 @@ <<case "market assistant">> <<set $assistant.market = {}>> <<run assistant.object()>> - <<set _smartPiercings = 0>> - <<for $i = 0; $i < $slaves.length; $i++>> - <<if ($slaves[$i].clitPiercing == 3)>> - <<set _smartPiercings = 1>> - <<break>> - <</if>> - <</for>> + <<setAssistantPronouns>> Your personal assistant has been adapting to _hisA greatly increased computing power over the course of the week. _HisA avatar has been an even more constant presence than usual, frequently appearing to explain some minor new ability. <<if ($assistant.personality != 0) && ($assistant.appearance != "normal")>> When _heA appears this time, however, _hisA avatar is not alone. _HeA's accompanied by diff --git a/src/pregmod/FCTV/FCTV.js b/src/pregmod/FCTV/FCTV.js index fbe0890115716e4ed4389052b45efae235002d83..3062059acd93ad7647e58f1d4b594fc810ddfc57 100644 --- a/src/pregmod/FCTV/FCTV.js +++ b/src/pregmod/FCTV/FCTV.js @@ -18,8 +18,12 @@ window.FCTV = (function() { return { channels:channels, manage: manage, - showChannel:showChannel, - incrementChannel:incrementChannel, + showChannel: showChannel, + incrementChannel: incrementChannel, + incrementShow: incrementShow, + channelCount: channelCount, + showRange: showRange, + FinalTouches: FinalTouches }; function channels() { @@ -104,6 +108,7 @@ window.FCTV = (function() { if (V.minimumSlaveAge > 13) { x.canSelect = -1; x.text += `<i>Actor not vintage enough, changing program.</i>`; } + break; case 16: if (!V.seeDicks && !V.makeDicks) { x.canSelect = -1; x.text += `<i>Too many hot dogs detected, changing program.</i>`; @@ -111,18 +116,97 @@ window.FCTV = (function() { break; } - if (State.temporary.all) { x.canSelect = 1; } + if (V.all) { x.canSelect = 1; } return x; } function incrementChannel(i = V.FCTV.channel.selected) { V.FCTV.channel.selected = i; V.FCTV.channel[num(i, true)]++; + if (i === 2 && V.FCTV.channel[num(i, true)] >= 12) { + V.FCTV.channel[num(i, true)] = 0; + } if ( - [14, 15].includes(i) && V.FCTV.channel[num(i, true)] == 3 - || [13, 16].includes(i) && V.FCTV.channel[num(i, true)] == 4 - || i === 12 && V.FCTV.channel[num(i, true)] == 9 + [14, 15].includes(i) && V.FCTV.channel[num(i, true)] === 3 + || [13, 16].includes(i) && V.FCTV.channel[num(i, true)] === 4 + || i === 12 && V.FCTV.channel[num(i, true)] === 9 ) { V.FCTV.channel[num(i, true)] = 1; } } + + function incrementShow() { + V.show = V.usedRemote ? V.show + 1 : V.show; + } + + function channelCount(i, operation = 'eq') { + if (operation === 'eq') { + if (V.FCTV.channel[num(V.FCTV.channel.selected, true)] === i) { + return true; + } + } else if (operation === 'gt') { + if (V.FCTV.channel[num(V.FCTV.channel.selected, true)] > i) { + return true; + } + } else if (operation === 'lt') { + if (V.FCTV.channel[num(V.FCTV.channel.selected, true)] < i) { + return true; + } + } + return false; + } + + function showRange(low, max, operation = 'rand') { + if (V.usedRemote) { + V.show = !between(V.show, low, max) ? low : V.show; + } else { + V.show = operation === 'rand' ? jsRandom(low, max) : either(low, max); + } + } + + function FinalTouches(i, channel) { + function applySkill(obj) { + Object.assign(i.skill, obj); + } + if (channel === 14) { + i.behavioralFlaw = "arrogant"; i.markings = "none"; + if (i.weight > 130) { + i.weight -= 100; i.waist = random(-10,50); + } + i.health.condition = random(60,80); + } else if (channel === 4) { + i.pubertyXX = 1; i.career = "a slave"; + i.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel."; + i.health.condition = 75; + if (V.show < 3) { + i.custom.tattoo = "$He has a small stylized 'A' tattooed on the nape of $his neck marking $him as the product of the famous breeding program at Arcturus Arcology."; + applySkill({'vaginal': 0, 'entertainment': jsRandom(50, 80), + 'oral': jsRandom(20, 60), 'anal': 0, + 'whoring': 0}); + } else if (V.show === 3) { + applySkill({'vaginal': jsRandom(50, 80), + 'oral': jsRandom(40, 80), 'anal': jsRandom(20,50), + 'whoring': jsRandom(0, 50)}); + } else if (V.show === 4) { + applySkill({'vaginal': jsRandom(50, 100), + 'oral': jsRandom(20, 50), 'anal': jsRandom(10, 20)}); + i.counter.birthsTotal = jsRandom(2, 3); + } else if (V.show === 5) { + applySkill({'vaginal': jsRandom(50, 100), 'entertainment': jsRandom(20, 80), + 'oral': jsRandom(50, 100), 'anal': jsRandom(20, 80), + 'whoring': jsRandom(20,80)}); + i.counter.birthsTotal = jsRandom(1, 3); + } else if (V.show === 6) { + applySkill({'vaginal': 15, + 'oral': 15, 'anal': 15, + 'whoring': 15}); + } else if (V.show <= 8) { + applySkill({'oral': jsRandom(30, 60), 'anal': jsRandom(20, 50), + 'whoring': jsRandom(0, 25)}); + } else if (V.show === 8) { + applySkill({'oral': jsRandom(40, 80), 'anal': jsRandom(40, 80), + 'whoring': jsRandom(40, 70)}); + } + } + i.health.health = i.health.condition - i.health.shortDamage - i.health.longDamage; + } })(); diff --git a/src/pregmod/FCTV/seFCTVshows.tw b/src/pregmod/FCTV/seFCTVshows.tw index f96ee9054a8efbf2ea670b60ec89bc56d33a23fc..959da8b586f28a12024cc35df709feb13af9c02e 100644 --- a/src/pregmod/FCTV/seFCTVshows.tw +++ b/src/pregmod/FCTV/seFCTVshows.tw @@ -1,7 +1,6 @@ :: SE FCTV Shows [nobr] /* Setup Millie art, since she is on multiple channels */ -<<if $seeImages > 0>> <<set _millie = BaseSlave()>> <<run Object.assign(_millie, { devotion: 100, trust: 100, @@ -11,7 +10,6 @@ hStyle: "luxurious", hColor: "strawberry blonde", clothes: "a leotard" })>> -<</if>> <br> <<if $usedRemote>>You select @@ -23,34 +21,33 @@ <<case -1>> however there is simply nothing on FCTV tonight worth watching. <<case 0>> <<run FCTV.incrementChannel(1)>> - <<if $seeImages > 0>> - <<set _kirk = BaseSlave()>> - <<run Object.assign(_kirk, { - actualAge: 44, devotion: 0, - trust: 0, muscles: 60, - weight: 30, waist: 90, - boobs: 0, shoulders: 3, - butt: 0, hips: -1, - hLength: 10, hColor: "dark brown", - faceShape: "masculine", hStyle: "messy", - eyewear: "glasses", clothes: "conservative clothing", - shoes: "flats" - })>> - <<set _jules = BaseSlave()>> - <<run Object.assign(_jules, { - devotion: 0, trust: 0, - weight: 30, waist: 30, - boobs: 700, butt: 3, - hLength: 50, hStyle: "luxurious", - hColor: "auburn", boobShape: "perky", - clothes: "panties and pasties", collar: "stylish leather" - })>> - <</if>> + <<set _kirk = BaseSlave()>> + <<run Object.assign(_kirk, { + actualAge: 44, devotion: 0, + trust: 0, muscles: 60, + weight: 30, waist: 90, + boobs: 0, shoulders: 3, + butt: 0, hips: -1, + hLength: 10, hColor: "dark brown", + faceShape: "masculine", hStyle: "messy", + eyewear: "glasses", clothes: "conservative clothing", + shoes: "flats" + })>> + + <<set _jules = BaseSlave()>> + <<run Object.assign(_jules, { + devotion: 0, trust: 0, + weight: 30, waist: 30, + boobs: 700, butt: 3, + hLength: 50, hStyle: "luxurious", + hColor: "auburn", boobShape: "perky", + clothes: "panties and pasties", collar: "stylish leather" + })>> officially known as the FCNN stream channel and you've started watching the middle of a news segment. - <<set _show = random(0,2)+1>> - <<if _show == 1 && $FCTV.channel.one > 3 || $FCTV.channel.one == 1>> + <<run FCTV.showRange(1, 3)>> + <<if $show == 1 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(1, 'eq')>> <<if $seeImages > 0>> <div class="imageColumn"> <div class="imageRef medImg"> @@ -65,7 +62,7 @@ <br><br>Jules seems to be quite passionate about the subject, the animated way she talks is causing her sizable tits to bounce all over the place. "It doesn't matter how famous or valuable that slut thinks she is, her behavior was just wrong on SO many levels. It makes all of us good slaves look bad. If you ask me, her master's choice of punishment fits the attention whore perfectly!" <br><br>Kirk's face looks more than a little surprised, but you can't quite tell if it's an act or not. "You won't get any argument from me that she deserves to be punished... but getting chained up with an obedience collar and feeder system in the middle of Times Square, free for public use? A slum like Manhattan, she'll never <<if $seeExtreme == 0>><i>enjoy</i><<else>>survive<</if>> the 10 day sentence!" <br><br>Jules smiles. "That's exactly right Master McMahon, she's going to be <<if $seeExtreme == 0>><i>hugged until she smiles</i><<else>>fucked to death<</if>>. Her precious popularity in the old world will have the locals lined up all the way to New New Jersey waiting for their turn. I'd never question her master's decision, but if it were me, I'd pump her full of curatives and stimulants during the sentence. That way, she doesn't <<if $seeExtreme == 0>><i>smile</i><<else>>die or pass out<</if>> too soon. I think her master is being lenient after the way she badmouthed him in a live broadcast." - <<elseif _show == 2 && $FCTV.channel.one > 3 || $FCTV.channel.one == 2>> + <<elseif $show == 2 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(2, 'eq')>> <<if $seeImages > 0>> <<set _model = BaseSlave()>> <<run Object.assign(_model, { @@ -91,7 +88,7 @@ The segment cuts back to two news anchors, a dark-haired man with a mustache and an aging bottle blonde. <br><br>The bottle blonde speaks to the viewers. "Some of you may recognize the woman in that video as Angry Red, noted femsupremacist and a leading figure in the old world Emancipation Movement. The video you saw was released along with countless other media files and documents from the movement in the EmancipationGate hacktivist attack. This particular video has been confirmed by computer analysis to be behind the scenes footage from the movement's latest documentary about the horrors of slavery." <br><br>The mustached man looks knowingly at the camera. "Anyone remotely familiar with Free City slavery knew the documentary was complete bullshit, but what we didn't know was just how far those radicalists were willing to go to make us all look bad." - <<elseif _show == 3 && $FCTV.channel.one > 3 || $FCTV.channel.one == 3>> + <<elseif $show == 3 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(3, 'eq')>> <<if $seeImages > 0>> <<set _jules.vaginalAccessory = "large dildo">> <div class="imageColumn"> @@ -109,10 +106,16 @@ <br><br>As the AnchorSlave continues to squeeze, one of the researchers answers from off camera. "That's right, it can be rather amazing. To tell you the truth, we didn't believe it at first, but the evidence made it too hard to ignore." Jules starts looking toward the backstage area trying to signal someone as the other researcher continues. "It's also important not to wear a bra unless you're doing high-impact cardio. We've known since the mid 20th century that wearing bras causes sagging; bras devastate the breasts of <<if $seePreg == 0>><i>friendly</i><<else>>postpartum<</if>> women in particular, and promote breast cancer... Despite countless decades-long studies showing us this, the old world insists on forcing women to wear..." <br><br>It seems that Jules finally got the approval she was looking for, because she immediately reached down between her legs, causing the researcher to distractedly forget what he was saying. Apparently the panties she's wearing are of the dildo variety, because when she removes her hand you can see a tell-tale green indicator light glowing on the front of them. A cute rosy flush comes to Jules cheeks before she apologizes and urges the pair of researchers to continue. <</if>> + <<run FCTV.incrementShow()>> + <<case 1>> <<run FCTV.incrementChannel(2)>> - <<set _rerun = random(2,10), _MSL = $MastSiIDs.length>> - which is currently showing <<if $FCTV.channel.two < 12>>the newest episode of a<<else>>a repeat of the<</if>> popular competitive reality show<<if $FCTV.channel.two > 0>>: Next Top Breeder.<<else>> where several female citizens are competing for something.<</if>> The intro sequence shows a succession of beautiful ladies either participating in a mixture of contrived competitions, or talking and going about their lives in a sorority-like setting. The montage is overlaid with a narrator's voice: "12 of Canadia Arcology's most attractive women are all competing for the privilege of having the arcology owner's children. Clint Miles has desirable genes, and these ladies are determined to prove their worth as gestators. And here in Canadia, there are no restrictions on fertility drugs for the winner, so the competition this season is fierce! <<if $FCTV.channel.two < 12>>_rerun<<else>>$FCTV.channel.two<</if>> lad<<if $FCTV.channel.two > 0>>ies have<<else>>y has<</if>> already been sent packing, who will be Canadia's... Next Top Breeder!?" The title finally pops up, redundantly labeling the show as 'Next Top Breeder: Canadia'. + <<set _MSL = $MastSiIDs.length>> + which is currently showing <<if FCTV.channelCount(12, 'lt')>>the newest episode of a<<else>>a repeat of the<</if>> popular competitive reality show<<if FCTV.channelCount(0, 'gt')>>: Next Top Breeder.<<else>> where several female citizens are competing for something.<</if>> + The intro sequence shows a succession of beautiful ladies either participating in a mixture of contrived competitions, or talking and going about their lives in a sorority-like setting. + The montage is overlaid with a narrator's voice: "12 of Canadia Arcology's most attractive women are all competing for the privilege of having the arcology owner's children. + Clint Miles has desirable genes, and these ladies are determined to prove their worth as gestators. + And here in Canadia, there are no restrictions on fertility drugs for the winner, so the competition this season is fierce! $FCTV.channel.two ladies have already been sent packing, who will be Canadia's... Next Top Breeder!?" The title finally pops up, redundantly labeling the show as 'Next Top Breeder: Canadia'. <<if _MSL >= 1>> <br><br>You don't spend very much time actually watching the show; the randy opening, perverted competitions, and constant talk of creampies quickly has <<if _MSL >= 1 && $Concubine != 0>> @@ -125,6 +128,7 @@ the pleasure slaves in your bed eager for some attention from their own arcology owner. You spend the rest of the evening doing something a lot more fun than watching reality TV. <</if>> <</if>> + <<case 2>> <<run FCTV.incrementChannel(3)>> <<if $seeImages > 0>> @@ -146,12 +150,12 @@ </div> </div> <</if>> - <<set _show = random(0,2)+1>> + <<run FCTV.showRange(1, 3)>> which is currently showing the 'Home and Slave' stream channel. The current show features a set of female twins wearing nothing but tool belts. Their assets aren't particularly noteworthy, but they have a great hourglass figure, toned muscles, and gorgeous girl-next-door faces. The girls are hosting a DIY show, and seem to be performing a lot of the work themselves. The occasional bead of sweat makes their smooth tan skin really stand out. It seems like this time they are - <<if _show == 1>> + <<if $show == 1>> working on modifications to an apartment to accommodate enormous anatomy. The pair demonstrate how to tastefully modify a doorway so that giant breasts, <<if $seeDicks == 0>><i>smiles</i><<else>>testicles<</if>>, and <<if $seePreg == 0>><i>hairdos</i><<else>>baby bumps<</if>> can get through easily. Their final results weren't refined enough to use in your own home, but were pretty amazing for the economy-sized apartment they filmed at. <br><br>At the end of the show they test out the new doorways by bringing in a somewhat unusual slave. A naked fu<<if $seeDicks == 0>><i>nny cow</i><<else>>tanari<</if>> wearing only a cowbell collar, she has massive milky tits, gigantic <<if $seeDicks == 0>><i>smile</i><<else>>balls hanging low in her sack<</if>>, and a belly engorged with what was probably a <<if $seePreg == 0>><i>five-course dinner</i><<else>><<if $seeHyperPreg == 0>><i>single baby</i><<else>>dozen babies<</if>><</if>>. The <<if $seeDicks == 0>><i>fun</i><<else>>futa<</if>> cow ambles through the modified door without a problem, resulting in a bouncy victory dance from the naked twins. - <<elseif _show == 2>> + <<elseif $show == 2>> working on setting up a slave nutrition system inside a moderately-sized apartment. They're installing a deluxe system that has integrated nutritional sensing in addition to a food system that supplies the unit's two feeder/med-dispenser combo units. Amazingly, the whole thing fits into the kitchen without a problem, as they located the main system housing in the pantry. When they're finished, you couldn't tell the nutrition system is there, except for the two large dildos that are sticking out of the side of a cabinet. <br><br>After their work is done, you're treated to watching the young twins testing the system out. They each take one feeder and ride it to get a test suppository, before turning around and inhaling the cockfeeders for a small meal. You wonder at their choice for the order of events, sucking the cockfeeder they had just finished ramming up their ass, but they were so enthusiastic about it that you decide they probably liked it that way. <<else>> @@ -159,350 +163,230 @@ <br><br>The room is set up so that slaves sleep in something resembling bunk beds, though there are four beds instead of two. Instead of worrying about the lack of space, the twins use the confined sleeping arrangements as an advantage. A simple neural activity monitor combined with a few sources of stimulation or discomfort serve to condition the slaves while they sleep. The twins helpfully demonstrate for their audience the features of these beds. Part of the stain-proof mattress is covered with flexible strips of metal to conduct electricity for stimulation or pain. Focused speakers play naughty sounds, while a dim display can show a stream of pornography or other material without being bright enough to disturb the slave's sleep. The final addition is a quartet of vibrating dildos that extend from the bunk above to stimulate a slave while they sleep. <br><br>The whole setup seemed impressive, but you aren't really sure how effective it would be... particularly when you compare the likely cost of such a setup to an inexpensive cot on the floor. <</if>> + <<run FCTV.incrementShow()>> <<case 3 4>> <<run FCTV.incrementChannel(4)>> + <<set $oneTimeDisableDisability = 1>> /* NOTE: These slaves are meant to be high quality and expensive, they are the product of the combined slave markets of all the Free Cities. Additionally, they won't follow the player's slave selling policies because they aren't being sold in the PC's arcology. Because they are purchased, it shouldn't be a balance issue or impact the game like a slave gift. */ <<if $seeDicks == 0>> <<if $seePreg == 0>> - <<set _show = random(5,6)>> + <<run FCTV.showRange(5, 6)>> <<else>> - <<set _show = random(0,6)>> + <<run FCTV.showRange(0, 6)>> <</if>> - <<elseif $seeDicks == 100>> + <<elseif $seeDicks == 100>> <<if $seePreg == 0>> - <<set _show = random(7)>> + <<run FCTV.showRange(0, 7)>> <<else>> - <<set _show = random(7,9)>> + <<run FCTV.showRange(7, 9)>> <</if>> <<else>> <<if $seePreg == 0>> - <<set _show = random(5,7)>> + <<run FCTV.showRange(5, 7)>> <<else>> - <<set _show = random(0,9)>> + <<run FCTV.showRange(0, 9)>> <</if>> <</if>> - <<if _show < 3>> /* premium virgin */ - <<set _slaveOneTimeMinAge = ($fertilityAge + 2)>> - <<set _slaveOneTimeMaxAge = 18>> + + <<if $show < 3>> /* premium virgin */ + <<set $slaveOneTimeMinAge = ($fertilityAge + 2)>> + <<set $slaveOneTimeMaxAge = 18>> <<set $one_time_age_overrides_pedo_mode = 1>> - <<set $oneTimeDisableDisability = 1>> + <<set _slave = GenerateNewSlave("XX")>> - <<set _slave.devotion = random(40,60)>> - <<set _slave.weight = random(-10,10)>> - <<set _slave.waist = random(-45,25)>> - <<set _slave.face = random(70,100)>> - <<set _slave.anus = 0>> - <<set _slave.vagina = 0>> - <<set _slave.trueVirgin = 1>> - <<set _slave.boobs = (random(14,26)*50)>> - <<set _slave.boobShape = "perky">> - <<set _slave.hips = 2>> - <<set _slave.butt = random(5,6)>> - <<set _slave.shoulders = -1>> - <<set _slave.preg = 0>> - <<set _slave.ovaries = 1>> - <<set _slave.skill.vaginal = 0>> - <<set _slave.lips = random(20,50)>> - <<set _slave.teeth = "normal">> - <<set _slave.vaginaLube = 2>> - <<set _slave.energy = random(65,95)>> - <<set _slave.attrXY = random(70,100)>> - <<set _slave.attrXX = random(60,90)>> - <<set _slave.attrKnown = 1>> - <<set _slave.fetishKnown = 1>> - <<set _slave.fetish = either("cumslut", "cumslut", "humiliation", "pregnancy", "pregnancy", "pregnancy", "submissive")>> - <<set _slave.fetishStrength = random(70,100)>> - <<set _slave.sexualFlaw = "none">> - <<set _slave.behavioralFlaw = "none">> - <<set _slave.behavioralQuirk = either("advocate", "funny", "insecure", "none", "none")>> - <<set _slave.sexualQuirk = either("caring", "none", "romantic")>> - <<set _slave.skill.entertainment = random(50,80)>> - <<set _slave.skill.oral = random(20,60)>> - <<set _slave.skill.anal = 0>> - <<set _slave.skill.whoring = 0>> - <<set _slave.intelligence = random(51,70)>> - <<set _slave.intelligenceImplant = 30>> - <<set _slave.devotion = random(60,90)>> - <<set _slave.trust = random(50,80)>> - <<set _slave.chem = 0>> - <<set _slave.health.condition = 75>> - <<set _slave.health.health = _slave.health.condition - _slave.health.shortDamage - _slave.health.longDamage>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> - <<set _slave.career = "a slave">> - <<set _slave.custom.tattoo = "$He has a small stylized 'A' tattooed on the nape of $his neck marking $him as the product of the famous breeding program at Arcturus Arcology.">> - <<elseif _show == 3>> /* hyperpregnant */ - <<set _slaveOneTimeMinAge = ($fertilityAge + 3)>> - <<set _slaveOneTimeMaxAge = 20>> + <<run Object.assign(_slave, { + devotion: random(60,90), weight: random(-10,10), + waist: random(-45,25), face: random(70,100), + anus: 0, vagina: 0, + trueVirgin: 1, boobs: random(14,26)*50, + boobShape: "perky", hips: 2, + butt: random(5,6), shoulders: 1, + preg: 0, ovaries: 1, + teeth: "normal", vaginaLube: 2, + energy: random(65,95), attrXY: random(70,100), + attrXX: random(60,90), attrKnown: 1, + fetishKnown: 1, lips: random(20,50), + fetish: either("cumslut", "cumslut", "humiliation", "pregnancy", "pregnancy", "pregnancy", "submissive"), + behavioralQuirk: either("advocate", "funny", "insecure", "none", "none"), + sexualQuirk: either("caring", "none", "romantic"), + fetishStrength: random(70,100), sexualFlaw: "none", + behavioralFlaw: "none", intelligence: random(51,70), + intelligenceImplant: 30, trust: random(50,80), + })>> + <<elseif $show == 3>> /* hyperpregnant */ + <<set $slaveOneTimeMinAge = ($fertilityAge + 3)>> + <<set $slaveOneTimeMaxAge = 20>> <<set $one_time_age_overrides_pedo_mode = 1>> - <<set $oneTimeDisableDisability = 1>> + <<set _slave = GenerateNewSlave("XX")>> - <<set _slave.weight = random(10,20)>> - <<set _slave.waist = random(-25,25)>> - <<set _slave.anus = 1>> - <<set _slave.vagina = 2>> - <<set _slave.preg = random(25,30)>> + <<run Object.assign(_slave, { + weight: random(10,20), waist: random(-25,25), + anus: 1, vagina: 2, + preg: random(25,30), pregKnown: 1, + pregAdaptation: 300, + lips: random(20,50), teeth: "normal", + vaginaLube: 2, boobs: random(10,30)*50, + lactation: 1, lactationDuration: 2, + hips: 3, hipsImplant: 1, + butt: random(7,9), attrKnown: 1, + energy: random(65,100), attrXY: random(40,100), + devotion: random(40,70), trust: random(40,70), + fetish: "pregnancy", fetishKnown: 1, + fetishStrength: 100, sexualFlaw: "breeder", + behavioralFlaw: "none", behavioralQuirk: "none", + sexualQuirk: either("caring", "caring", "romantic"), + intelligence: random(-15,80), intelligenceImplant: 15 + })>> <<if $seeHyperPreg == 0>> <<set _slave.pregType = either(6,7,7,8)>> <<else>> <<set _slave.pregType = random(10,16)>> <</if>> - <<set _slave.pregKnown = 1>> <<set _slave.pregWeek = _slave.preg>> <<run SetBellySize(_slave)>> - <<set _slave.pregAdaptation = 300>> - <<set _slave.ovaries = 1>> - <<set _slave.lips = random(20,50)>> - <<set _slave.teeth = "normal">> - <<set _slave.vaginaLube = 2>> - <<set _slave.boobs = (random(10,30)*50)>> - <<set _slave.lactation = 1>> - <<set _slave.lactationDuration = 2>> - <<set _slave.hips = 3>> - <<set _slave.hipsImplant = 1>> - <<set _slave.butt = random(7,9)>> - <<set _slave.attrKnown = 1>> - <<set _slave.energy = random(65,100)>> - <<set _slave.attrXY = random(70,100)>> - <<set _slave.attrXX = random(40,100)>> - <<set _slave.skill.vaginal = random(50,80)>> - <<set _slave.skill.oral = random(40,80)>> - <<set _slave.skill.anal = random(20,50)>> - <<set _slave.skill.whoring = random(0,50)>> - <<set _slave.devotion = random(40,70)>> - <<set _slave.trust = random(40,70)>> - <<set _slave.fetish = "pregnancy">> - <<set _slave.fetishKnown = 1>> - <<set _slave.fetishStrength = "100">> - <<set _slave.sexualFlaw = "breeder">> - <<set _slave.behavioralFlaw = "none">> - <<set _slave.behavioralQuirk = "none">> - <<set _slave.sexualQuirk = either("caring", "caring", "romantic")>> - <<set _slave.chem = 0>> - <<set _slave.health.condition = 75>> - <<set _slave.health.health = _slave.health.condition - _slave.health.shortDamage - _slave.health.longDamage>> - <<set _slave.intelligence = random(-15,80)>> - <<set _slave.intelligenceImplant = 15>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> - <<set _slave.career = setup.youngCareers.random()>> - <<elseif _show == 4>> /* superfetation */ - <<set _slaveOneTimeMinAge = ($fertilityAge + 4)>> - <<set _slaveOneTimeMaxAge = 24>> + <<elseif $show == 4>> /* superfetation */ + <<set $slaveOneTimeMinAge = ($fertilityAge + 4)>> + <<set $slaveOneTimeMaxAge = 24>> <<set $one_time_age_overrides_pedo_mode = 1>> - <<set $oneTimeDisableDisability = 1>> + <<set _slave = GenerateNewSlave("XX")>> - <<set _slave.weight = random(20,40)>> - <<set _slave.waist = random(-25,25)>> - <<set _slave.boobs = (random(4,6)*100)>> - <<set _slave.butt = random(3,5)>> - <<set _slave.hips = 1>> - <<set _slave.face = random(60,90)>> - <<set _slave.anus = 1>> - <<set _slave.vagina = 3>> - <<set _slave.preg = 0>> - <<set _slave.pregWeek = -2>> - <<set _slave.bellySag = 1>> - <<set _slave.bellySagPreg = 1>> - <<set _slave.geneticQuirks.superfetation = 2>> - <<set _slave.ovaries = 1>> - <<set _slave.teeth = "normal">> - <<set _slave.vaginaLube = 2>> - <<set _slave.energy = random(60,90)>> - <<set _slave.attrXY = random(60,100)>> - <<set _slave.attrXX = random(40,65)>> - <<set _slave.attrKnown = 1>> - <<set _slave.fetishKnown = 1>> - <<set _slave.fetish = either("cumslut", "humiliation", "pregnancy", "pregnancy", "submissive")>> - <<set _slave.fetishStrength = random(70,100)>> - <<set _slave.sexualFlaw = "none">> - <<set _slave.behavioralFlaw = "none">> - <<set _slave.behavioralQuirk = "none">> - <<set _slave.sexualQuirk = "none">> - <<set _slave.skill.oral = random(20,50)>> - <<set _slave.skill.vaginal = random(50,100)>> - <<set _slave.skill.anal = random(10,20)>> - <<set _slave.intelligence = random(-15,80)>> - <<set _slave.intelligenceImplant = 0>> - <<set _slave.devotion = random(60,90)>> - <<set _slave.trust = random(50,80)>> - <<set _slave.chem = 0>> - <<set _slave.health.condition = 75>> - <<set _slave.health.health = _slave.health.condition - _slave.health.shortDamage - _slave.health.longDamage>> - <<set _slave.counter.birthsTotal = random(2,3)>> - <<set _slave.career = setup.youngCareers.random()>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> - <<elseif _show == 5>> /* MILF */ - <<set _slaveOneTimeMinAge = 36>> - <<set _slaveOneTimeMaxAge = 40>> + <<run Object.assign(_slave, { + weight: random(20,40), waist: random(-25,25), + boobs: random(4,6)*100, butt: random(3,5), + hips: 1, face: random(60,90), + anus: 1, vagina: 3, + preg: 0, pregWeek: -2, + bellySag: 1, bellySagPreg: 1, + geneticQuirks: {superfetation: 2}, + teeth: "normal", vaginaLube: 2, + energy: random(60,90), attrXY: random(60,100), + attrXX: random(40,65), attrKnown: 1, + fetishKnown: 1, sexualQuirk: "none", + fetish: either("cumslut", "humiliation", "pregnancy", "pregnancy", "submissive"), + fetishStrength: random(70,100), sexualFlaw: "none", + behavioralFlaw: "none", behavioralQuirk: "none", + intelligence: random(-15,80), intelligenceImplant: 0, + devotion: random(60,90), trust: random(50,80), + })>> + <<elseif $show == 5>> /* MILF */ + <<set $slaveOneTimeMinAge = 36>> + <<set $slaveOneTimeMaxAge = 40>> <<set $one_time_age_overrides_pedo_mode = 1>> - <<set $oneTimeDisableDisability = 1>> + <<set _slave = GenerateNewSlave("XX")>> - <<set _slave.weight = random(20,90)>> - <<set _slave.waist = random(-45,45)>> - <<set _slave.boobs = (random(20,30)*50)>> - <<set _slave.butt = random(5,7)>> - <<set _slave.hips = 2>> - <<set _slave.face = random(60,90)>> - <<set _slave.anus = 1>> - <<set _slave.vagina = 2>> - <<set _slave.preg = 0>> - <<set _slave.ovaries = 1>> - <<set _slave.teeth = "normal">> - <<set _slave.vaginaLube = 2>> - <<set _slave.energy = random(60,90)>> - <<set _slave.attrXY = random(60,100)>> - <<set _slave.attrXX = random(40,85)>> - <<set _slave.attrKnown = 1>> - <<set _slave.fetishKnown = 1>> - <<set _slave.fetish = either("buttslut", "buttslut", "cumslut", "cumslut", "humiliation", "pregnancy", "pregnancy", "submissive")>> - <<set _slave.fetishStrength = random(70,100)>> - <<set _slave.sexualFlaw = "none">> - <<set _slave.behavioralFlaw = "none">> - <<set _slave.behavioralQuirk = "none">> - <<set _slave.sexualQuirk = "none">> - <<set _slave.skill.entertainment = random(20,80)>> - <<set _slave.skill.oral = random(50,100)>> - <<set _slave.skill.vaginal = random(50,100)>> - <<set _slave.skill.anal = random(20,80)>> - <<set _slave.skill.whoring = random(20,80)>> - <<set _slave.intelligence = random(-15,80)>> - <<set _slave.intelligenceImplant = 15>> - <<set _slave.devotion = random(60,90)>> - <<set _slave.trust = random(50,80)>> - <<set _slave.chem = 0>> - <<set _slave.health.condition = 75>> - <<set _slave.health.health = _slave.health.condition - _slave.health.shortDamage - _slave.health.longDamage>> - <<set _slave.counter.birthsTotal = random(1,3)>> - <<set _slave.career = setup.youngCareers.random()>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> - <<elseif _show == 6>> /* discount young hottie */ - <<set _slaveOneTimeMaxAge = 25>> - <<set $oneTimeDisableDisability = 1>> + <<run Object.assign(_slave, { + weight: random(20,90), waist: random(-45,45), + boobs: random(20,30)*50, butt: random(5,7), + hips: 2, face: random(60,90), + anus: 1, vagina: 2, + preg: 0, teeth: "normal", + vaginaLube: 2, energy: random(60,90), + attrXY: random(60,100), attrXX: random(40,85), + attrKnown: 1, fetishKnown: 1, + fetish: either("buttslut", "buttslut", "cumslut", "cumslut", "humiliation", "pregnancy", "pregnancy", "submissive"), + fetishStrength: random(70,100), sexualFlaw: "none", + behavioralFlaw: "none", behavioralQuirk: "none", + sexualQuirk: "none", + intelligence: random(-15,80), intelligenceImplant: 15, + devotion: random(60,90), trust: random(50,80), + })>> + <<elseif $show == 6>> /* discount young hottie */ + <<set $slaveOneTimeMaxAge = 25>> + <<set _slave = GenerateNewSlave("XX")>> - <<set _slave.face = random(70,100)>> - <<set _slave.weight = random(-5,10)>> - <<set _slave.waist = random(-45,25)>> - <<set _slave.anus = 1>> - <<set _slave.vagina = 1>> - <<set _slave.boobs = (random(14,26)*50)>> - <<set _slave.boobShape = "perky">> - <<set _slave.hips = 2>> - <<set _slave.butt = random(5,6)>> - <<set _slave.shoulders = -1>> - <<set _slave.preg = 0>> - <<set _slave.ovaries = 1>> - <<set _slave.lips = random(25,50)>> + <<run Object.assign(_slave, { + face: random(70,100), weight: random(-5,10), + waist: random(-45,25), anus: 1, + vagina: 1, boobs: random(14,26)*50, + boobShape: "perky", hips: 2, + butt: random(5,6), shoulders: -1, + preg: 0, lips: random(25,50), + vaginaLube: 2, + sexualFlaw: either("hates anal", "hates oral", "hates penetration", "idealistic"), + behavioralFlaw: either("arrogant", "bitchy", "hates men"), + energy: 10, fetish: "none", + clit: either(3,3,4,4,5,8,10), + muscles: random(0,25), devotion: random(-25,25), + trust: random(-25,25) + })>> + <<if _slave.physicalAge >= 12>> <<set _slave.teeth = "normal">> <</if>> - <<set _slave.vaginaLube = 2>> - <<set _slave.skill.vaginal = 15>> - <<set _slave.skill.oral = 15>> - <<set _slave.skill.anal = 15>> - <<set _slave.skill.whoring = 15>> - <<set _slave.sexualFlaw = either("hates anal", "hates oral", "hates penetration", "idealistic")>> - <<set _slave.behavioralFlaw = either("arrogant", "bitchy", "hates men")>> - <<set _slave.energy = 10>> - <<set _slave.fetish = "none">> - <<set _slave.clit = either(3,3,4,4,5,8,10)>> - <<set _slave.muscles = random(0,25)>> - <<set _slave.devotion = random(-25,25)>> - <<set _slave.trust = random(-25,25)>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> - <<elseif _show <= 8>> /* huge balls */ - <<set _slaveOneTimeMaxAge = 25>> - <<set $oneTimeDisableDisability = 1>> + <<elseif $show <= 8>> /* huge balls */ + <<set $slaveOneTimeMaxAge = 25>> + <<set _slave = GenerateNewSlave("XY")>> - <<set _slave.anus = 2>> - <<set _slave.balls = random(20,35)>> + <<run Object.assign(_slave, { + anus: 2, balls: random(20,35), + dick: random(3,5), prostate: 2, + devotion: random(50,80), trust: random(50,80) + })>> <<set _slave.scrotum = _slave.balls>> - <<set _slave.dick = random(3,5)>> - <<set _slave.prostate = 2>> - <<set _slave.skill.oral = random(30,60)>> - <<set _slave.skill.anal = random(20,50)>> - <<set _slave.skill.whoring = random(0,25)>> - <<set _slave.devotion = random(50,80)>> - <<set _slave.trust = random(50,80)>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> - <<elseif _show == 9>> /* mpreg dickgirl */ - <<set _slaveOneTimeMaxAge = 22>> - <<set $oneTimeDisableDisability = 1>> + <<elseif $show == 9>> /* mpreg dickgirl */ + <<set $slaveOneTimeMaxAge = 22>> + <<set _slave = GenerateNewSlave("XY")>> - <<set _slave.anus = 2>> - <<set _slave.vagina = -1>> - <<set _slave.ovaries = 0>> - <<set _slave.mpreg = 1>> - <<set _slave.preg = 0>> - <<set _slave.pubertyXX = 1>> - <<set _slave.dick = random(3,5)>> - <<set _slave.balls = random(3,6)>> - <<set _slave.skill.oral = random(40,80)>> - <<set _slave.skill.anal = random(40,80)>> - <<set _slave.skill.whoring = random(40,70)>> - <<set _slave.muscles = either(20, 50)>> - <<set _slave.energy = random(70,100)>> - <<set _slave.attrXY = random(70,100)>> - <<set _slave.attrXX = random(70,100)>> - <<set _slave.attrKnown = 1>> - <<set _slave.fetishKnown = 1>> - <<set _slave.fetish = "pregnancy">> - <<set _slave.fetishStrength = random(80,100)>> - <<set _slave.sexualFlaw = "none">> - <<set _slave.behavioralFlaw = "none">> - <<set _slave.behavioralQuirk = "none">> - <<set _slave.sexualQuirk = "none">> - <<set _slave.intelligence = random(-15,80)>> - <<set _slave.intelligenceImplant = 15>> - <<set _slave.devotion = random(60,90)>> - <<set _slave.trust = random(50,80)>> - <<set _slave.chem = 0>> - <<set _slave.health.condition = 75>> - <<set _slave.health.health = _slave.health.condition - _slave.health.shortDamage - _slave.health.longDamage>> - <<set _slave.career = setup.youngCareers.random()>> - <<set _slave.origin = "You purchased $him from FCTV's Home Slave Shopping stream channel.">> + <<run Object.assign(_slave, { + anus: 2, vagina: 1, + ovaries: 0, mpreg: 1, + preg: 0, dick: random(3,5), + balls: random(3,6), + muscles: either(20, 50), energy: random(70,100), + attrXY: random(70,100), attrXX: random(70,100), + attrKnown: 1, fetishKnown: 1, + fetish: "pregnancy", fetishStrength: random(80,100), + sexualFlaw: "none", behavioralFlaw: "none", + behavioralQuirk: "none", sexualQuirk: "none", + intelligence: random(-15,80), intelligenceImplant: 15, + devotion: random(60,90), trust: random(50,80) + })>> <</if>> + <<run FCTV.FinalTouches(_slave, 4)>> + <<setLocalPronouns _slave>> - which is currently showing the 'Home Slave Shopping' stream channel. It's a bit strange, shopping for slaves without inspecting them in person, but you have to admit it's kind of convenient. Plus, you might find something that'd be difficult to get in your own arcology's markets. You start watching at the end of one slave being displayed; the program goes into a lot of detail that isn't always available from shady salesmen at the market. Two hosts are displaying the merchandise and an older male reads details on each slave from a prompter, while a fit female works the slave for the camera to give viewers a good look at what they might purchase. + which is currently streaming 'Home Slave Shopping'. It's a bit strange, shopping for slaves without inspecting them in person, but you have to admit it's kind of convenient. Plus, you might find something that'd be difficult to get in your own arcology's markets. You start watching at the end of one slave being displayed; the program goes into a lot of detail that isn't always available from shady salesmen at the market. Two hosts are displaying the merchandise and an older male reads details on each slave from a prompter, while a fit female works the slave for the camera to give viewers a good look at what they might purchase. <br><br>"Next up, we have - <<if _show < 3>> /* premium virgin */ + <<if $show < 3>> /* premium virgin */ a premium virgin named _slave.slaveName." A bright pink "VV" symbol flashes on the corner of the screen. "Take a good look, because $he is a product of the famous sex slave breeding program at Arcturus Arcology. Like all the slaves they sell, $he's a premium @@.pink;double virgin.@@ $He has excellent breeding potential, and while $he isn't that skilled yet, $he's got good intelligence and is already well acclimated to the life of a sex slave." - <<elseif _show == 3>> /* hyperpregnant */ + <<elseif $show == 3>> /* hyperpregnant */ <<= addA(_slave.race)>> breeder, young and healthy with an advanced <<if $seeHyperPreg == 0>><i>@@.pink;super pregnancy.@@</i><<else>>@@.pink;hyper pregnancy.@@<</if>> _slave.slaveName is really into making babies, and has even had $his hips surgically widened to help $him carry a large brood. Our tests here at HSS show that $he's pregnant with _slave.pregType babies!" - <<elseif _show == 4>> /* superfetation */ + <<elseif $show == 4>> /* superfetation */ a special slave named _slave.slaveName who has quite the gift, @@.pink;superfetation!@@ $He can become pregnant while pregnant! Isn't that amazing? $He may have a few miles on $him, having just completed a double pregnancy, but with a trait like that, $he's more than worth $his price if you like your <<= $girl>>s to constantly have a bun in the oven." - <<elseif _show == 5>> /* MILF */ + <<elseif $show == 5>> /* MILF */ <<= addA(_slave.race)>> @@.pink;MILF.@@ $He's no longer young, but still quite attractive. $He has been a slave for many years now, and has been trained well. $He also has a good array of skills that you can put to use. $He has huge tits and a huge ass to play with, but $he'd also make good <<if $seePreg == 0>><i>sandwiches</i><<else>>stock for a breeding program<</if>>." - <<elseif _show == 6>> /* discount young hottie */ + <<elseif $show == 6>> /* discount young hottie */ a bargain discount offer on a young _slave.race $girl. Unlike our usual stock $he's something of a @@.red;disobedient@@ slave, but that means savings for you, and all the fun of breaking in a new slave. We have to admit that $his previous owner had a hard time training $him, but I'm sure you can tell that $his body has potential<<if _slave.clit > 4>>, just look at the @@.pink;clit@@ on $him<</if>>!" - <<elseif _show <= 8>> /* huge balls */ + <<elseif $show <= 8>> /* huge balls */ <<= addA(_slave.race)>> cum cow. Just take a look at that pair of @@.pink;massive balls.@@ This slave also has a prostate stimulating hormone implant to ramp up $his cum production even further. $He's a perfect fit for your dairy, or even your own kitchen creamery!" <br><br>The woman helping to display the slaves shows her hand to the camera; it's coated in a sticky layer of precum from handling the cum cow's equipment. - <<elseif _show == 9>> /* mpreg dickgirl */ + <<elseif $show == 9>> /* mpreg dickgirl */ a strong young _slave.race $girl that retains $his cock and balls. _slave.slaveName has something that makes $him special: thanks to medical science $he's got a @@.pink;functional ass womb.@@ That's right folks, this slave is fertile and can get knocked up if you inseminate $his asshole. That's pretty amazing, to be honest, and exceptionally rare. Don't let this opportunity slip by!" <</if>> <<set _slaveCost = slaveCost(_slave)>> - <<if _show < 3 || _show > 6>> + <<if $show < 3 || $show > 6>> <<set _slaveCost *= 1.3>> - <<elseif _show == 4>> + <<elseif $show == 4>> <<set _slaveCost *= 2>> - <<elseif _show == 6>> + <<elseif $show == 6>> <<set _slaveCost *= 0.7>> <</if>> <<set _slaveCost = 500*Math.trunc(_slaveCost/500)>> The offered price is <<print cashFormat(_slaveCost)>>. + <<set $activeSlave = _slave, $saleDescription = 1>> <<if $cash >= _slaveCost>> - <br> <<set $activeSlave = _slave>> - <<link "Buy $his slave contract">> + <<link "Buy this contract.">> <<run cashX(forceNeg(_slaveCost), "slaveTransfer", _slave)>> <<set $nextLink = "Scheduled Event", $returnTo = "Scheduled Event">> <<goto "New Slave Intro">> <</link>> <<else>> - //@@.red;You lack the necessary funds to buy this slave.@@// + //@@.red;You lack the necessary funds.@@// <</if>> - <br><br> - <<set $saleDescription = 1>><<include "Long Slave Description">><<set $saleDescription = 0>> + <br><br> <<include "Long Slave Description">> + <<run FCTV.incrementShow()>> <<case 5>> <<run FCTV.incrementChannel()>> @@ -526,8 +410,8 @@ which is currently showing an episode of the slave-breeding for beginners series: 'Husbandry with Millie'. The show is hosted by the famous and charismatic Millie, a slave breeder from Arcturus who appears to be in her mid thirties. She's wearing something resembling a maternity dress over her large pregnant belly, but the loose fabric doesn't hide her enormous hips and complementary ass. The dress only comes part of the way up her chest, leaving her large milk-engorged breasts exposed as they rest atop the fabric. Millie begins the show the same way as always, by giving her viewers some encouragement. "Anyone can become a breeder, even you! Just be willing to learn, and as I always say..." she pats her full belly meaningfully "be ready to get your hands dirty!" <br><br> - <<set _show = random(2)+1>> - <<if _show == 1 && $FCTV.channel.five > 3 || $FCTV.channel.five == 1>> + <<run FCTV.showRange(1, 3)>> + <<if $show == 1 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(1, 'eq')>> Millie walks away from the classroom-like set, followed by a camera panning along beside her. Her purposeful steps and swinging hips set her breasts jiggling and sending droplets of milk flying from her dark milky nipples. It takes a sadly brief time for her to arrive at her destination, a mostly-white clinical-looking set prepared with several naked — and presumably fertile — slaves. As she comes to a stop in front of the line of slaves, all of the beautiful girls bow their heads and greet her. "<i>Hello Mistress Millie!</i>" <br><br> Millie ignores the naked slaves and turns to the camera. "Today we're going to cover the basics of choosing good breeding sluts, using some of my own stock. Of course, as we covered before, you want to choose breeders that have the traits you're looking for. Intelligence, temperament, bone structure, beauty, or simple cosmetic features like skin and hair color. But that's not all you need to look for!" Millie beckons to one of the slaves in the background, who rushes forward to stand in front of the camera. She points at the girl's flank, and the camera zooms in so that the screen is taken up by the girl's broad hips and moist pussy. "They call them child-bearing hips for a reason!" Millie starts rubbing the girl's hips as she continues. "Wide hips are a solid indicator of a good breeder; they mean a healthier pregnancy and easier — not to mention cheaper — birth. And if you want to increase your production with multiple pregnancies, wide hips are a must!" @@ -535,7 +419,7 @@ The wide hips of the nubile slave girl suddenly walk off camera, and are soon replaced by the hips of another girl that are dramatically smaller. They aren't the hips of a man, but certainly bring to mind the narrow hips of an old-timey fashion model. The girl has a little extra weight, which is more obvious on her narrow frame, but you can tell she is fit with well-developed muscles. Millie starts touching her demonstration model as she points things out. "Sometimes, you're looking for narrow hips. Maybe you want to breed an athlete or pit fighter, or your tastes just run that way for some reason. You don't have to rule out a slut just because she has small hips, but there are some things to look for. First, you want to make sure the bitch is nicely plush, with well-distributed fat. This is important for a healthy pregnancy, but tends to be overlooked in narrow sluts. Also check their core strength. Muscles are even more important for narrow sluts, to help support the uterus and ease childbirth." She traces the shapes of the slave's hips. "They might be small, but make sure they're well formed, you want them to work properly. Finally, check the pubic bone, its joints with the iliac crests, and the fore part of the crests. You want a smooth curve throughout with loose joints that'll open wide n' easy when it's time." <br><br> With a smack on the ass, the bitch trots off camera to be replaced by a girl with her knees bent and feet spaced far apart. When the camera pans down you have a clear view of her sodden slit; the stage lights give the natural lubricant coating her inner thighs a more noticeable sheen. Millie rubs two fingers between the slaves' labia, and withdraws the now-soaked digits for the camera to see. "Remember! A wet cunt is a good cunt!" Without any warm-up, she bunches her fingers and thumbs together and inserts her entire hand into the slave's gaping pussy. "A loose baggy cunt may be no good for fucking, but I guarantee it's perfect for making you new slaves. And it may just help you save money, too. Loose cunts tend to drive down a slut's value, right at the perfect age for turning a slut into a breeding bitch." - <<elseif _show == 2 && $FCTV.channel.five > 3 || $FCTV.channel.five == 2>> + <<elseif $show == 2 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(2, 'eq')>> Millie walks towards the back of the set, returning with her hands behind her back. "This episode, we're going to talk about an important decision any breeder needs to make. Bull" she pulls a large life-like <<if $seeDicks == 0>><i>pop sickle</i><<else>>dildo<</if>> from behind her back, "or no bull?" This time she whips out something resembling a turkey baster. She gives both a hard squeeze, and they both squirt out a jet of <<if $seeDicks == 0>><i>whipped cream.</i><<else>>alabaster fluid.<</if>> She drops both of the spent tools and turns to walk towards her chair, the camera follows to give a good view of hefty ass and swinging hips. <br><br> Sitting down in her comfortable-looking chair, Millie begins her lecture. "So, thanks to the miracles of the modern dairy and industrial <<if $seeDicks == 0>><i>banana</i><<else>>cock<</if>> milkers, a reliable supply of <<if $seeDicks == 0>><i>banana juice</i><<else>>cum<</if>> is available for most citizens. This is definitely the least expensive option for those starting out, and combined with easy access, seems to be a popular choice for new breeders. It's also a common pitfall, so thank goodness you're watching now! Industrial dairies simply aren't focused on reproduction in most arcologies. Owners are focused on production, quantity over quality, and most of the material is used for slave nutrition and industrial purposes. Even if your arcology has a reproduction-focused <<if $seeDicks == 0>><i>banana cream</i><<else>>jizz<</if>> farm, they're usually focused on breeding menials. You still have no way of knowing what you're getting. It makes any attempt at proper husbandry nearly impossible. You don't want to sink all your resources into buying and caring for breeding sluts, only to end up with a litter only fit to be menials!" @@ -554,6 +438,7 @@ <br><br> "You may be thinking: 'as if I could ever afford something like that!'" Millie gives the camera a bright smile. "Don't worry; Mamma Millie's got you covered. It's true that most of you won't be able to afford one of these, not to mention the special electrical hookups and maintenance... but the fact that better models exist means that the older models don't have much use for the types of people that <b>can</b> afford them. That means empty incubators that are just too valuable to simply dispose of, and a chance for you to rent or lease one or two of 'em long enough to get a major jump start on your breeding program. It'll still be expensive, maybe even as much as a high-quality slave ready to be trained. You'll also have to deal with and treat the chemical damage. But when it comes to developing a solid breeding line to produce high quality litters, the time savings can't be beat. Just don't expect the ones fresh out of the incubator to be good for much other that making new slaves!" <</if>> + <<run FCTV.incrementShow()>> <<case 6>> <<run FCTV.incrementChannel()>> @@ -567,20 +452,20 @@ which is currently showing an episode of the 'Modern Dairy' edutainment series, which opens with a montage of milk-related food and cooking shots. After the last of the opening credits disappears, the show sticks to a single shot from the montage, a delicious looking bowl of cereal. The camera zooms out to reveal the show's host wearing her trademark cow print leotard, and getting just a little too much enjoyment out of her cereal. She slowly puts the spoon down while savoring her cereal, reluctantly swallowing and starting the show. "Hi there y'all, welcome to another episode of Modern Dairy!" She gives the camera a wave — setting her gargantuan melons wobbling inside the spandex-like leotard — and the camera fades to black. <br><br> - <<set _show = random(2)+1>> + <<run FCTV.showRange(1, 3)>> <<if $seeExtreme == 0>> <<if $seeDicks == 0>> - <<set _show = 1>> + <<set $show = 1>> <i>CONTENT ADVISOR: Selecting show without too much hugging or hotdogs...</i><br><br> <<else>> - <<set _show = either(1,2)>> + <<run FCTV.showRange(1, 2, 'either')>> <i>CONTENT ADVISOR: Selecting show without too much hugging...</i><br><br> <</if>> <<elseif $seeDicks == 0>> - <<set _show = either(1,3)>> + <<run FCTV.showRange(1, 3, 'either')>> <i>CONTENT ADVISOR: Selecting show without too many hotdogs...</i><br><br> <</if>> - <<if _show == 1>> + <<if $show == 1>> The camera fades in to show an excited Bess standing next to a double door labeled 'Dairy 3'. "I'm here at Arcology G-9 to give you a look at their state-of-the-art milking equipment." Bess gestures to her jiggling bosom. "As you can see, I'm terribly excited! I've heard this dairy's equipment is a pretty radical departure from the standard ones that look like dentist's chairs!" Without further ado, she pushes her way through the swinging doors, and sets off into the dairy. The camera follows, spending as much time focused on her seductively-swinging rear end as it does panning to look around the long room. The first thing you notice is that the lighting is a soft warm glow more at home in a spa than an industrial facility. The room consists of a long hallway, the row of milkers on either side are separated by fabric dividing curtains in earth tone colors, though most of them appear to be open. You didn't notice at first, but it seems like most of the milkers are occupied... the radically different shape tricked your trained eye for a moment. <br><br> Eventually Bess reaches the end of the hallway, and is greeted by a nearly-naked slave with visible muscles that seems to be a milk maid. <i>"Hello there Ma'am, you must be Bess. My name is Anabell, and I'm a milk maid here. Welcome to dairy number three!"</i> @@ -609,39 +494,41 @@ Bess looks a little bit envious of the cow, but gives her approval. "Go ahead; I'll just help myself to some fresh milk while you're busy." She heads toward the dangling udders to retrieve her treat. It only takes Anabell a few shakes <<if $seeDicks == 0>><i>of the massage oil bottle before the cow's ass is glistening, and he gets to work massaging her.</i><<else>>to get her monstrous python of a cock throbbing and ready, and she doesn't waste any time hilting herself in the cow's ready pussy.<</if>> There's a loud muffled moo, and the camera reluctantly moves to get a shot of Bess. <br><br> Bess is on her hands and knees, her mouth full of nipple and milk, messily trying to keep up with the output of the prodigious mammary. She pinches the nipple to stop drinking for a moment so that she can speak to the camera. "Oh my god! This milk is SOOO good!" She sucks the cow's long nipple back into her mouth and resumes her feast. - <<elseif _show == 2>> + <<elseif $show == 2>> Instead of starting a new episode like you were expecting, it starts a teaser trailer for an upcoming episode. It seems to be focused on the semen side of the industrial dairy, and ends with some suggesting shots of Bess drinking "straight from the source." <<else>> Instead of starting a new episode like you were expecting, it starts a teaser trailer for an upcoming episode. It seems to be focused on bulk fluid production and menial bioreactor slaves, something of a departure from earlier episodes showcasing dairies focusing on high-quality product. <</if>> + <<run FCTV.incrementShow()>> <<case 7>> <<run FCTV.incrementChannel()>> which is currently showing an educational program on arcologies titled: "Architecture + Ecology = Arcology". <<if $PC.skill.engineering > 50>>The information is likely to be far too simplistic, considering your knowledge of engineering, but you watch anyway to see how most of your citizens view the massive structures.<<else>>Your practical experience means that this program is unlikely to tell you anything you don't already know, but you watch anyway to see how an average citizen views an arcology.<</if>> A likely-artificial voice of an older man narrates while the program displays video to demonstrate the topic being narrated. The show looks crisp and professional, but you can tell it doesn't have the budget that the more sexually-charged shows do. <br><br> - <<set _show = random(2)+1>> - <<if _show == 1 && $FCTV.channel.seven > 3 || $FCTV.channel.seven == 1>> + <<run FCTV.showRange(1, 3)>> + <<if $show == 1 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(1, 'eq')>> This episode seems to be focusing on some basics in addition to an arcology's Penthouse. <br><br> A standard arcology is so huge that it needs to be divided into levels and sectors to make talking about it easier. Levels are the horizontal rows. An arcology is a very large building, and each Level includes many floors. Sectors are slices of those levels. For example, on Levels with four Sectors, each sector includes a quarter of each floor that's part of that Level. Each Sector is typically occupied by facilities, tenants, or both. Sometimes facilities are owned or leased by tenants! Now when your friend tells you to meet them at "promenade B" or mentions that they live in sector "7C", you'll know how those names came about. <br><br> In most arcologies with a single owner, the uppermost Level is called the Penthouse. It's an entire sector where the owner and slaves under his direct supervision live. With such a large space for a single person or family, there is a great deal of customization possible. Even two arcologies of the same design, built at the same time, are likely to have very different penthouses! It's always worth visiting a penthouse if you get the chance. Not all arcologies are built or owned by a single person, often there is a group or partnership of owners. After all, building a structure as massive as an arcology is an extremely expensive endeavor! In these cases, the term penthouse is typically still used to refer to the top sector, as it is often divided into a number of luxurious penthouse apartments for the owners. - <<elseif _show == 2 && $FCTV.channel.seven > 3 || $FCTV.channel.seven == 2>> + <<elseif $show == 2 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(2, 'eq')>> This episode seems to be focusing on the Promenade and residential areas. <br><br> Below the penthouse — and potentially some residential sectors — is the Promenade, which is a major social area and hosts most of the businesses which cater to the arcology's citizens. Promenade Sectors are occupied by shops, restaurants, and other amusements. A promenade is critical to the success of an arcology; it allows the arcology to function as a self-contained residence, and is important to the economy. Sometimes it's nice to head over to a different arcology in your Free City for some unique cuisine or shopping, but could you imagine having to go through all that trouble any time you wanted to shop or eat out? While the concept of a promenade is almost universal amongst arcologies, the design, layout, and decoration of each tends to be rather unique, making it a fun experience to visit the promenade of arcologies other than your own. <br><br> The next area common to all arcologies are the residential sectors filled with apartments and other living arrangements. While designs and layouts differ — some arcologies have luxury residential areas that resemble an old-fashioned neighborhood complete with artificial sky — the purpose is always to house arcology citizens. Residential areas are critical for an arcology, in order to have a functioning self-contained economy. While all citizens in an arcology are fortunate, some are more fortunate than others. Lower-class citizens commonly live in dense efficiency apartments, while wealthy citizens often live in opulent sectors with large apartments. Without citizens there would be nobody to own or operate the stores, restaurants, and other attractions in the arcology, and there would be nobody to purchase those goods or services either! - <<elseif _show == 3 && $FCTV.channel.seven > 3 || $FCTV.channel.seven == 3>> + <<elseif $show == 3 && FCTV.channelCount(3, 'gt') || FCTV.channelCount(3, 'eq')>> This episode seems to be focusing on the lower levels, the Concourse and Service Level. <br><br> Another common level for an arcology is the Concourse, which is typically located near the bottom of the structure. Like the Promenade, it hosts businesses, but these focus less on the luxury and entertainment needs of citizens than the Promenade. The Concourse typically houses bulk trade, necessary services such as medical clinics, corporate offices, research and development centers, and even education facilities. The best universities in the world are located on the concourse level of an arcology! Of course, the concourse also houses slave markets and slave training facilities. Some arcologies have arenas for sports or other events, while others have venues for sport combat ranging from traditional octagon fighting rings to pits reminiscent of ancient gladiatorial combat. If you're lucky, your arcology may just have a public arcade, where a variety of needs can be met at an affordable price. With research pointing to the benefits of arcades to adolescent development, family-friendly arcologies are quickly adding arcades of their own! <br><br> The lowest and largest level is typically known as the Service level. Its Sectors are occupied by manufacturing and industry, including the production of food resources such as livestock facilities and dairies. Menial slaves are housed in the Service level, and often work there too. The service level also contains much of an arcology's infrastructure, supplying clean water and electricity to the citizens and businesses. Another common sight in the service level is that of a warehouse, which stores the goods and raw materials an arcology needs, and also facilitates trade with other arcologies. Finally, the Service level may contain barracks and training facilities for mercenaries or arcology militia tasked to protect it from the old world. <</if>> + <<run FCTV.incrementShow()>> <<case 8>> - <<set $FCTV.channel.eight++>> + <<run FCTV.incrementChannel()>> <<if $seeImages > 0>> <div class="imageColumn"> <div class="imageRef medImg"> @@ -652,22 +539,21 @@ which is currently showing a preview of the how-to series "Extreme Gestation for Fun and Profit", hosted by Millie. It seems like the show's going to cover topics ranging from hyper-pregnancy to broodmother implants, and even hints and some sort of medical technique to allow anal pregnancy in males. -<<case 9>> /* Hea;th condition of 70 */ +<<case 9>> /* Health condition of 70 */ <<run FCTV.incrementChannel()>> - <<if $seeImages > 0>> - <<set _model = BaseSlave()>> - <<run Object.assign(_model, { - devotion: 0, trust: 0, - hLength: 50, hStyle: "neat - hColor: "brown", boobs: 700, - boobShape: "perky", waist: 180, - butt: 3, hips: 3, - clothes: "conservative clothing", shoes: "flats" - })>> - <</if>> - <<set _show = random(0,3)+1>> - which is currently showing - <<if _show == 1>> + <<run FCTV.showRange(1, 4)>> + <<set _model = BaseSlave()>> + <<run Object.assign(_model, { + devotion: 0, trust: 0, + hLength: 50, hStyle: "neat", + hColor: "brown", boobs: 700, + boobShape: "perky", waist: 180, + butt: 3, hips: 3, + clothes: "conservative clothing", shoes: "flats" + })>> + + which is currently showing a documentary on the + <<if $show == 1>> <<if $seeImages > 0>> <<set _model.belly = 10000>> <<set _model.preg = 35>> @@ -679,15 +565,14 @@ </div> </div> <</if>> - a documentary on the surging Repopulation movement: "Continuing the Dream". After the opening credits, the documentary introduces a young and extremely pregnant woman as the commentator. The program makes an impassioned argument about the need for a new generation of citizens and slaves that were born into the dream of the Free Cities. The woman is wearing semi-conservative business attire, and has on elegant makeup. She looks somewhat plain when compared to the hyper-sexualized style of other FCTV shows, though she does make it plain over the course of the program that she loves sex more than ever. She tends to use herself as an example to show that pregnancy no longer means limitations or sacrifice, instead emphasizing that she's on her fifth pregnancy and would rather be with child than without. + surging Repopulation movement: "Continuing the Dream". After the opening credits, the documentary introduces a young and extremely pregnant woman as the commentator. The program makes an impassioned argument about the need for a new generation of citizens and slaves that were born into the dream of the Free Cities. The woman is wearing semi-conservative business attire, and has on elegant makeup. She looks somewhat plain when compared to the hyper-sexualized style of other FCTV shows, though she does make it plain over the course of the program that she loves sex more than ever. She tends to use herself as an example to show that pregnancy no longer means limitations or sacrifice, instead emphasizing that she's on her fifth pregnancy and would rather be with child than without. <br><br>The woman makes two main points during the course of the documentary. The first is that the combined population of the Free Cities needs to grow explosively for 'Free City Society' to become stable. She points out several economic reasons, including the drive to invest in research and infrastructure. She has interviews with experts explaining the need for independence; that the Free Cities are still dependent on the old world industrially and financially, and that the population must expand dramatically to avoid going down with the metaphorical ship. The more Free Cities there are, the more they become free and independent of the old world. <br><br>The second point concerns the source of the new citizens and slaves that the Free Cities need. Her arguments concerning citizens focus on the unique culture of the Free Cities, and the direction that the future society will take. She points out that immigrants from the old world are rooted in its decaying culture. She asks her viewers how long it took them to adapt to their new lives, and how often they find themselves doubting their new home subconsciously. She admits that even she sometimes finds something wrong or repulsive, until she realizes that it's the ghost of her past life clinging to her. A noted psychologist talks about the strong hold people's earlier lives has on them, and how developing the promise of the Free Cities will need a generation untainted by the old world. The documentary's argument for slaves largely comes down to the fact that second-generation slaves are happier, better adjusted, and simply better slaves. <<if $IntelligenceEugenicsSMR != 0 || $HeightEugenicsSMR != 0 || $FaceEugenicsSMR != 0>> It also points out the practical problems that the mass importation of slaves will cause in the gene pool. <</if>> <br><br>Overall, it's a convincing documentary, if a little too emotional for your tastes. - - <<elseif $arcologies[0].FSGenderFundamentalist == "unset" && _show == 2>> + <<elseif $arcologies[0].FSGenderFundamentalist == "unset" && $show == 2>> <<if $seeImages > 0>> <<set _model.dick = 6>> <<set _model.boobs = 750>> @@ -697,44 +582,42 @@ </div> </div> <</if>> - a documentary on the increasingly-popular Gender Radicalist movement titled: "Power, not Biology". After the opening credits, the documentary introduces an androgynous documentarian in a nicely-cut suit. The finely tailored suit doesn't try to hide the person's breasts, which seem to be a pretty average D-cup. Similarly, another bulge is visible stretching down one of the pants legs. The futanari opens with a pretty simple question: "Am I a man, or am I a woman?" The documentary is focused on answering that question in the context of a modern era where medical science means that genitalia are irrelevant. It argues that a person's body no longer has any relation to their sexuality or ambition, that being free means choosing the body that pleases you most, and that society needs new criteria from which to determine gender. + increasingly-popular Gender Radicalist movement titled: "Power, not Biology". After the opening credits, the documentary introduces an androgynous documentarian in a nicely-cut suit. The finely tailored suit doesn't try to hide the person's breasts, which seem to be a pretty average D-cup. Similarly, another bulge is visible stretching down one of the pants legs. The futanari opens with a pretty simple question: "Am I a man, or am I a woman?" The documentary is focused on answering that question in the context of a modern era where medical science means that genitalia are irrelevant. It argues that a person's body no longer has any relation to their sexuality or ambition, that being free means choosing the body that pleases you most, and that society needs new criteria from which to determine gender. <br><br>The criteria suggested by the documentary is power. The idea is simple; the powerful are male, the weak are female. It argues that the biology and sexual proclivities of a person simply can't represent them any longer. The powerful are often free to choose the body and activities they wish to pursue, while the weak have those decisions made for them. It's a practical argument, and the documentary gives a long list of evidence supporting it, from expert interviews to ancient civilizations that followed a similar idea. The concept is somewhat appealing to you; after all, you wield extraordinary power, and a large part of that power includes altering the bodies of others. Whatever you choose to do, you can't see any reason to let your slaves and citizens criticize you for it. - - <<elseif $arcologies[0].FSGenderRadicalist == "unset" && _show == 2>> + <<elseif $arcologies[0].FSGenderRadicalist == "unset" && $show == 2>> <<if $seeImages > 0>> - <<set _model.faceShape = "masculine">> - <<set _model.waist = 180>> - <<set _model.weight = 180>> - <<set _model.boobs = 0>> - <<set _model.butt = 0>> - <<set _model.hips = -1>> - <<set _model.shoulders = 1>> - <<set _model.dick = 2>> + <<run Object.assign(_model, + { + faceShape: "masculine", waist: 180, + boobs: 0, butt: 0, + hips: -1, shoulders: 1, + dick: 2 + })>> <div class="imageColumn"> <div class="imageRef medImg"> <<= SlaveArt(_model, 2, 0)>> </div> </div> <</if>> - a documentary on conservative Gender Fundamentalism movement titled: "It's Eve, NOT Steve". After the outdated graphics finish displaying the garish opening credits, a portly man in late middle age introduces himself as Reverend Brad, the apparent commentator of the program. You don't pay much attention, but learn that apparently the Futanari Sisters are whore agents of Satan. You also learn that you're apparently destined for hell because of the medical technology in your penthouse that could be used to alter someone's naughty bits. You did get a good laugh when the reverend started yelling that choir boys are boys, and if he wanted a girl he would've found a nun. + conservative Gender Fundamentalism movement titled: "It's Eve, NOT Steve". After the outdated graphics finish displaying the garish opening credits, a portly man in late middle age introduces himself as Reverend Brad, the apparent commentator of the program. You don't pay much attention, but learn that apparently the Futanari Sisters are whore agents of Satan. You also learn that you're apparently destined for hell because of the medical technology in your penthouse that could be used to alter someone's naughty bits. You did get a good laugh when the reverend started yelling that choir boys are boys, and if he wanted a girl he would've found a nun. <br><br>You have to admit that most of the show is complete bullshit, but you can't deny that it's useful for controlling your citizens. As long as they're filling their heads with this bullshit, they won't be getting any dangerous ideas from somewhere else. In a more practical sense, it's a lot easier to manage an arcology and a house full of slaves when you don't have to worry about crazy gender issues or people disliking pregnant slaves. - - <<elseif $arcologies[0].FSSlimnessEnthusiast == "unset" && _show == 3>> + <<elseif $arcologies[0].FSSlimnessEnthusiast == "unset" && $show == 3>> <<if $seeImages > 0>> - <<set _model.dick = 4>> - <<set _model.boobs = 0>> - <<set _model.hLength = 10>> - <<set _model.hColor = "black">> - <<set _model2 = BaseSlave()>> - <<run Object.assign(_model2, { + <<run Object.assign( + _model, { + dick: 4, boobs: 0, + hLength: 10, hColor: "black" + }, + _model2, { devotion: 0, trust: 0, hLength: 50, hStyle: "luxurious", hColor: "blonde", boobs: 700, boobShape: "perky", waist: 180, butt: 3, hips: 3, clothes: "a ball gown", shoes: "heels" - })>> + } + )>> <div class="imageColumn"> <div class="imageRef medImg"> @@ -745,10 +628,9 @@ </div> </div> <</if>> - a documentary on the growing Asset Expansionist movement titled: "More of a Good Thing". After a brief set of opening credits the documentary dives immediately into short clips of numerous interviews with stacked women stating that they love having big tits and a big ass. Eventually, a man and woman are introduced as the hosts of the program. Both are finely dressed in the recent fashions, and despite the subject of the documentary, they don't have humongous assets. The woman does have huge breasts, wide hips, and a large derrière; the man has a noticeable bulge in his pants, but nothing extreme. The hosts explain that seeing Asset Expansionism as a call for ridiculous size is something of a misconception. They emphasize that it's about the freedom to enjoy more of a good thing. + growing Asset Expansionist movement titled: "More of a Good Thing". After a brief set of opening credits the documentary dives immediately into short clips of numerous interviews with stacked women stating that they love having big tits and a big ass. Eventually, a man and woman are introduced as the hosts of the program. Both are finely dressed in the recent fashions, and despite the subject of the documentary, they don't have humongous assets. The woman does have huge breasts, wide hips, and a large derrière; the man has a noticeable bulge in his pants, but nothing extreme. The hosts explain that seeing Asset Expansionism as a call for ridiculous size is something of a misconception. They emphasize that it's about the freedom to enjoy more of a good thing. <br><br>The documentary makes several arguments in favor of the movement, and is clear about explaining the natural biological attraction humans have to large assets. By interviewing stacked members of the movement and psychological experts alike, they try to demonstrate how larger assets lead to happier and more pleasurable lives, both in and out of the bedroom. The documentary neatly tops off its argument by demonstrating how assets have been expanding naturally since the start of the twentieth century, and claiming that it's silly to idolize the way humans looked before modern nutrition and medicine. Western countries in the old world already had average bust sizes of D-cup or larger by the turn of the century, the hosts claim that trying to go back to smaller sizes is synonymous with reducing the prosperity of free citizens. - - <<elseif $arcologies[0].FSAssetExpansionist == "unset" && _show == 3>> + <<elseif $arcologies[0].FSAssetExpansionist == "unset" && $show == 3>> <<if $seeImages > 0>> <<set _model.weight = -30>> <<set _model.butt = 0>> @@ -760,32 +642,26 @@ </div> </div> <</if>> - a documentary on the Slimness Enthusiast counter movement titled: "Slim Is In". Artistic opening credits play across the screen before a slim woman walks up and begins talking to the camera conversationally. She seems to be in her mid to late thirties, and is wearing conservative makeup to accent her natural beauty. Her narrow waist combines with her slim hips and full shoulders to create a balanced but muted hourglass profile. It's a look that was popular for decades on fashion models in the old world, and it improves the attractiveness of her B- or C-cup breasts and taut butt. It's obvious that the woman aspires to be a role model in addition to being the documentary's commentator. + Slimness Enthusiast counter movement titled: "Slim Is In". Artistic opening credits play across the screen before a slim woman walks up and begins talking to the camera conversationally. She seems to be in her mid to late thirties, and is wearing conservative makeup to accent her natural beauty. Her narrow waist combines with her slim hips and full shoulders to create a balanced but muted hourglass profile. It's a look that was popular for decades on fashion models in the old world, and it improves the attractiveness of her B- or C-cup breasts and taut butt. It's obvious that the woman aspires to be a role model in addition to being the documentary's commentator. <br><br>Much of the documentary's arguments center around the concept of fashion and the privileged. They point out how in the past societal changes have altered what people find attractive, giving skin tans as an example. When most worked outside and only the privileged stayed indoors pale skin was considered attractive. When the world changed and most people worked indoors, suddenly the tan skin of those with leisure time to spend outside came into vogue. She argues that modern hormones can easily expand the assets of the masses, but that only the privileged can afford to sculpt themselves into an ideal form like hers. She points out that even though the masses may imitate with surgery, they'll never be able to copy the naturally good bone structure and vibrancy of the well-bred elite. - - <<elseif $arcologies[0].FSTransformationFetishist == "unset" && _show == 4>> + <<elseif $arcologies[0].FSTransformationFetishist == "unset" && $show == 4>> /* Health condition of 70 */ <<if $seeImages > 0>> - <<set _model.devotion = 100>> - <<set _model.trust = 100>> - <<set _model.health.condition = 70>> - <<set _model.health.health = _model.health.condition - _model.health.shortDamage - _model.health.longDamage>> - <<set _model.hLength = 50>> - <<set _model.hStyle = "luxurious">> - <<set _model.hColor = "blonde">> - <<set _model.boobs = 700>> - <<set _model.boobShape = "perky">> - <<set _model.waist = 180>> - <<set _model.butt = 3>> - <<set _model.hips = 3>> - <<set _model.clothes = "a ball gown">> - <<set _model.shoes = "heels">> - <<set _model2 = BaseSlave()>> - <<run Object.assign(_model2, { + <<run Object.assign( + _model, { + devotion: 100, trust: 100, + hLength: 50, hStyle: "luxurious", + hColor: "blonde", boobs: 700, + boobShape: "perky", waist: 100, + butt: 3, hips: 3, + clothes: "a ball gown", shoes: "heels" + }, + _model2, { dick: 4, boobs: 0, hLength: 10, hColor: "grey", clothes: "conservative clothing", shoes: "flats" - })>> + } + )>> <div class="imageColumn"> <div class="imageRef medImg"> @@ -796,10 +672,9 @@ </div> </div> <</if>> - a documentary on the spreading Body Purist movement titled: "Don't Settle for Imitations". The opening credits are displayed over a series of comparison images showing beautiful breasts and asses next to obviously artificial imitations of the same. The screen splits and shows the two hosts in their own environments side by side. One is an extremely attractive doctor, her body is exquisitely curvy underneath her lab coat and her face is an impossible combination of beautiful and cute. The other host is an artist with graying hair; he's working in his studio to create a life-size sculpture of the first host. He starts off the documentary by asking why people are so eager to destroy the natural beauty of the human form. The doctor continues by asking why people are so impatient that they get implants instead of using a superior process of targeted hormonal growth. + spreading Body Purist movement titled: "Don't Settle for Imitations". The opening credits are displayed over a series of comparison images showing beautiful breasts and asses next to obviously artificial imitations of the same. The screen splits and shows the two hosts in their own environments side by side. One is an extremely attractive doctor, her body is exquisitely curvy underneath her lab coat and her face is an impossible combination of beautiful and cute. The other host is an artist with graying hair; he's working in his studio to create a life-size sculpture of the first host. He starts off the documentary by asking why people are so eager to destroy the natural beauty of the human form. The doctor continues by asking why people are so impatient that they get implants instead of using a superior process of targeted hormonal growth. <br><br>The documentary keeps up the two-viewpoint style and approaches the issue from two directions. The first is the stark aesthetic differences between natural and artificial bodies. It demonstrates why implants always fall short of the beauty they seek to imitate, and how those with implants are doomed to a vicious cycle of surgery to try and recapture the beauty they lost in the initial surgery. The other angle, presented by the doctor, is a lot more practical. It points out the numerous shortcomings of implants when compared to natural growth, such as the frequent need for maintenance surgeries, the significant extra health risks, the reduced pleasure and sensitivity felt by implant patients, and the extreme difficulty of a patient to get what they want. Taken together the argument is pretty simple: why get implants when other medical options are cheaper, safer, more effective, healthier, and more attractive? - - <<elseif $arcologies[0].FSBodyPurist == "unset" && _show == 4>> + <<elseif $arcologies[0].FSBodyPurist == "unset" && $show == 4>> <<if $seeImages > 0>> <<set _model2 = BaseSlave()>> <<set _model2.dick = 4>> @@ -812,9 +687,8 @@ </div> </div> <</if>> - a documentary on the rise of the Transformation Fetish titled: "The Mass Insanity of Adding Mass". The opening credits are styled to look like a psychological case study from a mental institution. When the credits finish, the video cuts to a scene of a man sitting behind a desk, the whole shot is high contrast due to the harsh lighting from a lone desk lamp. The middle-aged man screams 'hard-boiled' and looks like he walked straight out of a noir film to host this documentary. His opening monologue makes it pretty clear that this documentary has a lot of parallels with a crime documentary. Worse, is that the evidence and expert witnesses available to the producers were apparently overwhelming, because the program seems rushed trying to fit as much as it can into a narrow time slot. + rise of the Transformation Fetish titled: "The Mass Insanity of Adding Mass". The opening credits are styled to look like a psychological case study from a mental institution. When the credits finish, the video cuts to a scene of a man sitting behind a desk, the whole shot is high contrast due to the harsh lighting from a lone desk lamp. The middle-aged man screams 'hard-boiled' and looks like he walked straight out of a noir film to host this documentary. His opening monologue makes it pretty clear that this documentary has a lot of parallels with a crime documentary. Worse, is that the evidence and expert witnesses available to the producers were apparently overwhelming, because the program seems rushed trying to fit as much as it can into a narrow time slot. <br><br>Evidence and whatever else be damned, this isn't the kind of documentary that should be on the FCTV stream in your arcology. You tell $assistant.name to remind you to send a complaint in the morning. - <<else>> <<if $seeImages > 0>> <<set _model.belly = 10000>> @@ -827,7 +701,7 @@ </div> </div> <</if>> - a documentary on the surging Repopulation movement: "Continuing the Dream". After the opening credits, the documentary introduces a young and extremely pregnant woman as the commentator. The program makes an impassioned argument about the need for a new generation of citizens and slaves that were born into the dream of the Free Cities. The woman is wearing semi-conservative business attire, and has on elegant makeup. She looks somewhat plain when compared to the hyper-sexualized style of other FCTV shows, though she does make it plain over the course of the program that she loves sex more than ever. She tends to use herself as an example to show that pregnancy no longer means limitations or sacrifice, instead emphasizing that she's on her fifth pregnancy and would rather be with child than without. + surging Repopulation movement: "Continuing the Dream". After the opening credits, the documentary introduces a young and extremely pregnant woman as the commentator. The program makes an impassioned argument about the need for a new generation of citizens and slaves that were born into the dream of the Free Cities. The woman is wearing semi-conservative business attire, and has on elegant makeup. She looks somewhat plain when compared to the hyper-sexualized style of other FCTV shows, though she does make it plain over the course of the program that she loves sex more than ever. She tends to use herself as an example to show that pregnancy no longer means limitations or sacrifice, instead emphasizing that she's on her fifth pregnancy and would rather be with child than without. <br><br>The woman makes two main points during the course of the documentary. The first is that the combined population of the Free Cities needs to grow explosively for 'Free City Society' to become stable. She points out several economic reasons, including the drive to invest in research and infrastructure. She has interviews with experts explaining the need for independence; that the Free Cities are still dependent on the old world industrially and financially, and that the population must expand dramatically to avoid going down with the metaphorical ship. The more Free Cities there are, the more they become free and independent of the old world. <br><br>The second point concerns the source of the new citizens and slaves that the Free Cities need. Her arguments concerning citizens focus on the unique culture of the Free Cities, and the direction that the future society will take. She points out that immigrants from the old world are rooted in its decaying culture. She asks her viewers how long it took them to adapt to their new lives, and how often they find themselves doubting their new home subconsciously. She admits that even she sometimes finds something wrong or repulsive, until she realizes that it's the ghost of her past life clinging to her. A noted psychologist talks about the strong hold people's earlier lives has on them, and how developing the promise of the Free Cities will need a generation untainted by the old world. The documentary's argument for slaves largely comes down to the fact that second-generation slaves are happier, better adjusted, and simply better slaves. <<if $IntelligenceEugenicsSMR != 0 || $HeightEugenicsSMR != 0 || $FaceEugenicsSMR != 0>> @@ -835,34 +709,30 @@ <</if>> <br><br>Overall, it's a convincing documentary, if a little too emotional for your tastes. <</if>> + <<run FCTV.incrementShow()>> <<case 10>> <<run FCTV.incrementChannel()>> <<if $seeImages > 0>> - <<set _mindy = BaseSlave()>> - <<set _mindy.devotion = 100>> - <<set _mindy.trust = 100>> - <<set _mindy.health.condition = 70>> - <<set _mindy.health.health = _mindy.health.condition - _mindy.health.shortDamage - _mindy.health.longDamage>> - <<set _mindy.hLength = 50>> - <<set _mindy.hStyle = "luxurious">> - <<set _mindy.hColor = "strawberry blonde">> - <<set _mindy.boobs = 1400>> - <<set _mindy.nipples = "huge">> - <<set _mindy.boobShape = "perky">> - <<set _mindy.areolae = 4>> - <<set _mindy.waist = 180>> - <<set _mindy.butt = 3>> - <<set _mindy.hips = 3>> - <<set _mindy.clothes = "a string bikini">> + <<set _mindy = GenerateNewSlave("XX"), _mike = GenerateNewSlave("XY")>> + + <<run Object.assign( + _mindy, { /* Health condition of 70 */ + devotion: 100, trust: 100, + hLength: 50, hStyle: "luxurious", + hColor: "strawberry blonde", boobs: 1400, + nipples: "huge", boobShape: "perky", + areolae: 4, waist: 180, + butt: 3, hips: 3, + clothes: "a string bikini" + }, + _mike, { + dick: 7, faceShape: "masculine", + boobs: 0, hLength: 10, + hColor: "dark brown", clothes: "sport shorts" + } + )>> - <<set _mike = BaseSlave()>> - <<set _mike.dick = 7>> - <<set _mike.faceShape = "masculine">> - <<set _mike.boobs = 0>> - <<set _mike.hLength = 10>> - <<set _mike.hColor = "dark brown">> - <<set _mike.clothes = "sport shorts">> <div class="imageColumn"> <div class="imageRef medImg"> <<= SlaveArt(_mindy, 2, 0)>> @@ -872,25 +742,25 @@ </div> </div> <</if>> - which is currently showing a competitive game show 'Cum and Cream Challenge' The program has a short opening sequence showing a variety of male and female contestants competing in a variety of lewd and messy body fluid competitions. The program flashes to a title screen where the letters are being spelled out in white fluids: "CUM and CREAM CHALLENGE". The writing is messy enough to <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>>make you wonder<<else>>keep you wondering<</if>> if slaves were actually trained to spell out the text each week, or if it's just some clever camera work. The camera pans up past a large dripping <<if $seeDicks == 0>><i>frankfurter</i><<else>>cock<</if>> and two massive nipples, eventually revealing the two hosts that look to be in their early twenties. <<if $FCTV.channel[num($FCTV.channel.selected, true)] < 2>>A muscular man wearing athletic clothes, and a buxom young woman in a bikini that looks more like a microkini on her large breasts and hips. The pair is helpfully labeled on screen as Mike and Mindy, and as the camera gets closer it reveals that both have rather sizable endowments. Mike's crotch is soaked, and Mindy's bikini top allows small rivulets of milk to stream down from the sodden fabric. <<else>>The fluid enthusiast Mike and Mindy pair are wearing their usual style in new colors, the clothes appearing to be as soddenly wet as any other episode.<</if>> + which is currently showing a competitive game show 'Cum and Cream Challenge' The program has a short opening sequence showing a variety of male and female contestants competing in a variety of lewd and messy body fluid competitions. The program flashes to a title screen where the letters are being spelled out in white fluids: "CUM and CREAM CHALLENGE". The writing is messy enough to <<if FCTV.channelCount(1)>>make you wonder<<else>>keep you wondering<</if>> if slaves were actually trained to spell out the text each week, or if it's just some clever camera work. The camera pans up past a large dripping <<if $seeDicks == 0>><i>frankfurter</i><<else>>cock<</if>> and two massive nipples, eventually revealing the two hosts that look to be in their early twenties. <<if $FCTV.channel[num($FCTV.channel.selected, true)] < 2>>A muscular man wearing athletic clothes, and a buxom young woman in a bikini that looks more like a microkini on her large breasts and hips. The pair is helpfully labeled on screen as Mike and Mindy, and as the camera gets closer it reveals that both have rather sizable endowments. Mike's crotch is soaked, and Mindy's bikini top allows small rivulets of milk to stream down from the sodden fabric. <<else>>The fluid enthusiast Mike and Mindy pair are wearing their usual style in new colors, the clothes appearing to be as soddenly wet as any other episode.<</if>> <br><br> Mindy kicks off the show, speaking to the audience. "Welcome to another episode of Cum and Cream!" <br><br> - <<set _show = random(2)+1>> - <<if (_show == 1 && $FCTV.channel[num(_show, true)] > 3) || $FCTV.channel[num(_show, true)] == 1>> + <<run FCTV.showRange(1, 3)>> + <<if ($show == 1 && FCTV.channelCount(3, 'gt')) || FCTV.channelCount(1, 'eq')>> Mike smoothly continues. "We've got a great show for you tonight! A male-female team challenge!" <br><br>That's right Mike, and this time we've mixed it up! It's a production AND inflation challenge. Just thinking about it has me leaking top and bottom!" <br><br>"You don't have to tell me Mindy, I can see your puddle! In this contest, two teams will compete to produce the largest combined volume of cum and cream. The losing team goes on to a sudden-death inflation contest!" <br><br>Mindy bounces with excitement, sending milk everywhere, and freeing half of one long nipple from her bikini. "All the cum and cream from the previous contest administered anally, first one to tap out goes to the Loser's Pit!" <br><br>You watch with fascination through the contest, hanging on the edge of your seat during the final inflation challenge as the contestants' stomachs bulge further and further. <<if $seeDicks == 0>><i>Everybody smiles and has a good time. The End.</i><<else>>Suddenly, the male's taut stomach shifts and wobbles and he lets out an agonized scream. Medics rush to his side, and it cuts back to the hosts applauding his determination to win.<</if>> - <<elseif (_show == 2 && $FCTV.channel[num(_show, true)] > 3) || $FCTV.channel[num(_show, true)] == 2>> + <<elseif ($show == 2 && FCTV.channelCount(3, 'gt')) || FCTV.channelCount(2, 'eq')>> Mike unexpectedly moves over and starts rubbing Mindy's stomach, the extra attention highlighting how big her stomach is. "Mindy, don't tell me you went and got yourself knocked up... Your belly has gotten downright huge!" <br><br>Mindy laughs and chides Mike. "Oh Mike! You know I'm waiting for the perfect <<if $seeDicks == 0>><i>smile</i><<else>>cock<</if>> before I try out womb inflation!" She uses both hands to grab a handful of each of her large udders. "You know I use my own milk to keep myself pumped up, right? Well these babies have stepped up their production lately, nearly <<if $showInches == 2>>four liters<<else>>a gallon<</if>> a session with my milker. I figure it was my body's way of telling me it's time to step up my inflation game!" <br><br>Mike laughs along with Mindy before reaching over to grab the closest triangle of Mindy's bikini top. Yanking it up off her breast, he gets a firm grip on her nearly <<if $showInches == 2>>4-inch-long<<else>>10-centimeter-long<</if>> milky nipple before bending over and sucking it into his mouth to drink straight from the teat. After a few swallows he straightens up and faces the camera once more. "Wow, delicious as always, Mindy! You should start sending some of that rich cream my way!" <br><br>Mindy didn't look at all bothered by Mike's impromptu snack, and doesn't even attempt to pull her bikini top back into place. "Sure thing Mike, but for now, I'm sure our viewers are dying to know what we've got lined up for the show!" <br><br>Mike nods excitedly. "No new events tonight, but it's still a fan favorite! The Suck n' Gulp Jizz Challenge!" <br><br>"Three hungry ladies, and plenty of <<if $seeDicks == 0>><i>donuts</i><<else>>large studly balls<</if>> ready to feed them... once they've earned it, that is! The scales are ready to measure our contestants before they get started, but first....." - <<elseif (_show == 3 && $FCTV.channel[num(_show, true)] > 3) || $FCTV.channel[num(_show, true)] == 3>> + <<elseif ($show == 3 && FCTV.channelCount(3, 'gt')) || FCTV.channelCount(3, 'eq')>> Both Mike and Mindy are both wearing ecstatic smiles, looking more excited than ever. Mike doesn't try to hide his raging <<if $seeDicks == 0>><i>smile</i><<else>>erection<</if>> as he continues the introduction. "Tonight we have a truly special treat for you, and it's all thanks to Arcology Imperiales!" <br><br>Mindy continues, and makes no attempt to hide the fact that she has one hand stuffed inside her bikini bottom. "Thanks to the wonderful Dr. Picarde, owner of Arcology Imperiales, we have access to three amazing sex slaves for tonight's challenge!" <br><br>Mike nods enthusiastically. "Mindy, tell everyone what makes them so special!" @@ -903,10 +773,11 @@ <br><br>After talking about the surgery, Mindy is openly milking one nipple while her other hand goes wild at her crotch. "Okay Mike, I can't wait anymore, let's start the challenge!" <br><br><br>You watch the challenge, which involves three young contestants with huge <<if $seeDicks == 0>><i>smiles</i><<else>>balls<</if>>, each of them fucking a slave full of cum until one massively swollen stomach finally bursts. <</if>> + <<run FCTV.incrementShow()>> <<case 11>> <<run FCTV.incrementChannel()>> - <<if $usedRemote>>for some foolish reason<</if>><<if $FCTV.channel[num($FCTV.channel.selected, true)] > 1>>, once again,<</if>> + <<if $usedRemote>>for some foolish reason<</if>><<if FCTV.channelCount(1, 'gt')>>, once again,<</if>> which is currently showing an infomercial attempting to sell a product named "sag-B-gone" that claims to be able to prevent breasts from naturally sagging under their own weight. <br><br> <<if $purchasedSagBGone == 1>> @@ -916,7 +787,7 @@ <<setLocalPronouns $Concubine>> "I told you it wouldn't work, <<Master>>. Plu<<s>> you know you can touch the<<s>>e anytime!" $Concubine.slaveName shakes $his chest at you. <</if>> - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] > 1>> + <<elseif FCTV.channelCount(1, 'gt')>> You could always order a crate to play around with. Who knows, maybe it'll actually work?<<if $PC.dick != 0>> At the very least it should make for some decent lubricant for a titfuck.<</if>> <br> <span id="called"> @@ -960,12 +831,12 @@ <<case 12>> <<run FCTV.incrementChannel()>> - <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>> + <<if FCTV.channelCount(1)>> currently airing a drama series about a girl adapting to living in the Free Cities. <<else>> - currently airing another episode of that drama series + currently airing another episode of that drama series. <</if>> - <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>> + <<if FCTV.channelCount(1)>> For a moment you consider changing the channel, but you decide to give it a shot. <br><br>The woman posed in the mirror. She was tall for a woman, fair skinned, and wore a keyhole sweater dress. Her scarlet hair was done in a braid down her back and her plump lips were covered in ruby red lipstick. She was slender, but not intolerably so; at the very least, she filled out her dress enough to avoid being arrested for indecency. All in all, the woman's reflection made for a pleasant picture. The only thing detracting from this scene was her glare. <br><br>"Hey Scott, do you have anything a bit more conservative?" The woman asked. "We've been over this." Scott said. "Not showing off your breasts is seen as very rude here." Scott frowned, "Well, that's not entirely correct, but it is seen as distinctly unfriendly; the only girls who don't show some cleavage are frigid cunts and old-worlders fresh off the boat." @@ -981,7 +852,7 @@ <br><br>Scott called out to Cathy, "Come on out and give us a look!" The door to the bathroom opened and Cathy stepped out, tugging at her skirt. The clothing was a simple blouse and skirt affair with a Holstein pattern. In truth, it didn't look like something that would offend old world sensibilities, except for the fact the skirt was so short that her frilly panties were in plain view. <br><br>"Do you have a skirt that's a little longer?" Cathy said and tugged at her skirt again. "It's supposed to look like that." Scott explained. Cathy looked skeptical. "Really?" she asked. Sarah gave Cathy a look that asked if she really was that stupid. "Why would you wear pretty panties and never show anyone?" She asked rhetorically. Cathy started on a hot retort, but was interrupted by Scott. "We'll stop for now and pick this up later. You can put your new clothes away." Cathy sighed, picked up her clothes, and walked out the door. <br><br>Scott stood up and set his daughter on her feet. She turned her back to her father, bent over slightly, and wiggled her bottom meaningfully. Scott smacked her right butt cheek and said, "Off you go." Sarah didn't move. "Daddy" she said pleadingly and wiggled her bottom again. He smacked her left butt cheek. She giggled happily and jiggled out the door. Scott smiled at his daughter's antics, shook his head, and made his way to his bedroom. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 2>> + <<elseif FCTV.channelCount(2)>> The random function has brought up another episode of that drama series for you. <br><br>On his way to the bedroom he passed through the kitchen and caught sight of June preparing lunch. She was tall for a woman. Her hair was a golden blonde and her figure spoke of her ongoing romance with growth drugs. She wore a black thong and an apron embroidered with the words 'Milk the cook'. Which was rather strange considering she normally wore her 'Rape the cook' apron on Saturdays. But he guessed she was still raw from last night. <br><br>He came up behind her and reached into her apron to give her breasts a squeeze. June made a sound of pleasure in response. "Hello master, are you finished with Cathy for today?" He set his chin on the top of her head. "For the moment. After I've tended to Annie and had lunch, I think I'll take Cathy out for a bit. Maybe take the whole family out for ice cream." @@ -1004,7 +875,7 @@ <br><br>Scott leaned into his wife's breasts to bask in the afterglow. While Annie had coaxed Sarah to turn around, pulled Sarah's cunny to her face and began to slowly eat her daughter out. Sarah just lay bonelessly atop her mother's breasts. <br><br>Scott just enjoyed the sight of mother-daughter bonding for a while before recalling his earlier plans. "I was thinking of taking the family out for ice cream after lunch." Annie made a pleased sound as she continued licking her daughter's cunny, Sarah cheered lazily, Sadie's legs wiggled with what could be called excitement. <br><br>"I was also thinking of taking Cathy with us." Annie stopped sucking on her daughter's clit to frown at him. He made a placating gesture and said, "She won't make a big scene with all of us there and besides you enjoy it when she has a mini freak out." She paused to think for a moment then said, "You have cameras and a drone on her right?" He nodded. "I want copies." She gave him a lusty grin before returning to her meal. He turned Sarah. "I wanna bloom berry sundae with bottom boost sprinkles." He nodded, hooked his head to look behind his wife and said, "How about you Sadie?" The hand that poked out from behind his wife waggled uncertainly, but ultimately became a thumbs up. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 3>> + <<elseif FCTV.channelCount(3)>> <br><br>After a light lunch, the family assembled in the entry hall. Sarah rode in her mother's cleavage, playing with a tablet as they waited on Cathy. When Cathy made her way into the hall Scott frowned at her. "You're not going out dressed like that." Cathy looked down at herself. "What's wrong with this? This shows of my body well enough, right?" <br><br>She wore jeans and a T-shirt made a few sizes too small by her regimen of growth drug. "Why don't you put on that bikini I gave you?" Cathy just furrowed her brow and said nothing. Scott sighed and said, "Just don't wear pants and show some cleavage. For god's sake, people show more skin at funerals than you do." Cathy frowned, but went back to change. When she came back she was wearing the Holstein pattern skirt and blouse he had given her earlier. "You're going to wear that?" he asked. "What's wrong now?" He raised his hands in a placating gesture. "Nothing, nothing. Let's go." <br><br>The family left, made their way to an elevator and rode it down a few floors before exiting. As they turned the corner onto the street, the creamery came into sight. The family continued onward until Sarah spoke up. "Daddy, where's Cathy?" Scott looked back and saw that Cathy had stopped walking a few <<if $showInches == 2>>feet<<else>>meters<</if>> back. She stood staring wide eyed at the creamery. @@ -1018,7 +889,7 @@ <br><br>Cathy looked at the cup in confusion. "Shouldn't we head inside?" Scott just gave her a small smile. "Not just yet." An aura of excitement began to build in the crowd. She noticed that most of the crowd wore very little. Most of the women wore underwear or jewelry and nothing else. Cathy just stared at her cup and then looked up and noticed something she'd missed before. A countdown timer in the corner of the creamery's screen. And it had just hit zero. <br><br>The cowslaves mounted above began to moan and a deluge of milk flowed onto the crowd. The crowd cheered and laughed raising their cups high. Some of the women just basked in the spray, rubbing the milk into their skin. Some of the younger children danced and jumped in the puddles that formed. <br><br>While others were reveling in the downpour, Cathy just stood still, exuding the aura of a wet cat. Scott laughed at Cathy's put out expression and took another swig from his cup. "Now we can go in." - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 4>> + <<elseif FCTV.channelCount(4)>> <br><br>A soft gust of air flowed over the family as they passed through the doors to the creamery. Compared to its outward appearance, the creamery's interior was rather rustic. The warmly colored wood and soft amber lighting gave it a close and homey feel, like walking into an old ranch home at sunset. <br><br>The family passed wooden stalls containing a bevy of cowslaves. Each stall had a plaque with the slave's name on it, milking lines snaked down from the ceiling, and above each stall was a screen displaying the cow's sexual exploits. Some of them were chatting with customers, taking selfies with them and recommending products to try. Others were providing more intimate services to their clientele or simply milked themselves and stared at passersby, their smoldering eyes and flushed faces promising every earthly delight one could imagine. Cathy did her best to ignore the goings on around her and focus her attention forward, but couldn't help herself from taking short peeks from the corner of her eye. <br><br>Eventually, the family came to a stop at a dessert counter. Various cakes, pastries, and other treats tempted customers from behind the glass. Each dessert had stylized pictures of the cows that provided the ingredients. One particularly large cake had a picture of adorably deformed and scantily clad construction crew building the cake in a clumsy, but earnest fashion. Above the counter was a series of chalk boards that listed products on the menu, as well as boasting of the day's specials. On top of the counter was a single silver bell. Annie sidled up to the counter, her breasts pressing into the glass. Her daughter reached over from her perch and rung the bell. They didn't have to wait for long before a voice called out to them. "Oh, master! I didn't know you were coming in today." @@ -1039,7 +910,7 @@ <br><br>Scott pondered her question for a moment, before saying, "Shortly after starting up here, there was a big scandal over slave milk. Apparently, some moron thought adulterating slave milk with actual cow milk was a good idea. As you might guess, it didn't turn out well for him." He took a bite of his ice cream before continuing. "After that, customer trust was at an all-time low. So, I decided to make sure customers could see the whole process right outside the door." He jabbed his cone at her. "That level of transparency made me quite rich and my cows famous. Upstairs, you can buy all sorts of merchandise based on them: clothes, dolls, you name it." He smiled. "There's even a cartoon in the works." Cathy looked at him with a thoughtful expression. "So, that's why?" He gave her a lewd grin. "That, and it's quite sexy. Now, eat your ice cream before it melts." He turned to his wife and daughter. "That goes for you too. Remember, clean your plate, then masturbate." Sarah pulled away from Annie, gobbled down what remained of food, and then pressed her breasts into her mother's face. <br><br>A few minutes later, the family had finished their ice cream and were taking a moment to relax. Sarah rested languidly in her mother's cleavage, basking in the afterglow. Annie shifted uncomfortably. "Feeling pretty sticky. I think mommy is going to go home and take a shower." Scott patted her breast. "Sounds good, I think June and I'll get some shopping done and head back." At the word 'shopping,' Sarah immediately said, "No spinach." Scott looked at his daughter. "Yes spinach. You're not going to grow up to be big and milky like mommy if you don't eat your greens." Sarah pouted and mumbled into her mother's breast, "I want lolimommy cheese curds and a new plushy." Scott ruffled her hair. "We'll see." <br><br>As the family gathered themselves, Cathy held up the remote. "Should we just leave this at the counter?" Annie smiled at her. "Why don't you give her a buzz? I'm sure she'd like it." Cathy gave her a confused frown. Annie sighed and asked, "Kitten, how do you think that gets her attention?" Cathy turned the remote over in her hands. "She would have something that blinked and vibrated when someone used the remote." Annie just looked at her with a serene smile, her eyes twinkling mischievously. With a sudden gasp, Cathy dropped the remote like it had shocked her. A second later, there was a distant squeal and the clatter of a tray hitting the floor. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 5>> + <<elseif FCTV.channelCount(5)>> <br><br>A moment later, a beet red Cathy was stuttering an apology to an even redder Martha. "Don't worry about it, it was just a pleasant surprise." She smiled and pressed her breasts against Cathy's. "Hope to see you 'round soon darlin'." Marth pulled her into a hug and whispered softly into her ear. "I know it's hard to adjust to, but I think you'll do just fine here." She pressed a piece of paper into Cathy's cleavage and sashayed away. <br><br>Cathy fished it out to see it was an email and phone number with a lip print in bright red lipstick. "Oh my," Annie said, her eyes dancing with amusement. "It looks like you've made a friend." She turned to her husband and said, "I think they'd make a cute couple, wouldn't you?" Scott examined Cathy for a second before nodding. "So long as she makes an honest woman out of her, she has my blessing." Cathy just slowly fumed, her face scarlet in embarrassment. A moment passed before Annie couldn't take it anymore and let out loud, breast quaking, laughter. <br><br>Cathy glared at Annie "She was just being friendly." This just sent Annie into another fit of bosom shaking hysterics. Scott attempted to steady his wife. "Cathy, do you remember the remote she gave you?" She nodded warily. "You don't need one of those to call a waitress. The menus have a button that calls the nearest one to the table," he explained. "Remotes like that are typically reserved for VIPs or favored customers." Her brow furrowed. "But you're the owner! Why wouldn't she leave one with you?" He gave her a small grin and said," Indeed I am, but she gave the remote to you, not me." Cathy thought that over for a second before putting her head in her hands and sulked. @@ -1056,7 +927,7 @@ <br><br>Cathy took a tentative bite before popping the rest into her mouth. "It's good." Tabby gave her a sunny smile and said, "Thank you! I worked really hard on them." Scott smiled at her fondly and patted her head, "Yes you did." She preened at his praise and let out a sigh of contentment. <br><br>A moment passed in companionable silence, before Scott noticed that Cathy was starting to get antsy. "Anyway, we're going to get some groceries and head on out." Tabby nodded, but couldn't hide her disappointment. "I'll come by tomorrow to check on you and talk to Gabe." He gave her a squeeze and fondly tousled her hair before heading further into the store, Cathy and June in tow. <br><br>They only made it a few paces before an impish gleam entered Scott's eye. He signaled the rest to wait before heading back to the merchandise tables and returned quickly with a pair of plushies in hand. He handed one to Cathy without breaking stride and continued into the store. Cathy looked at the plushie and saw that it was Martha. She sighed and despite her chagrin, clutched the doll to her chest and followed. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 6>> + <<elseif FCTV.channelCount(6)>> <br><br>By the time Cathy had caught up, June had procured a shopping cart and was making her way to the produce section. A variety of fruits and vegetables tempted passersby, all so enticing that one might think they had been pulled from the canvas of an oil painting. The produce was arranged in finely crafted wooden displays with small chalkboards bearing names and prices written in a tidy hand. Overall, it gave off a rustic charm, like stepping into a small town farmers' market. Detracting from this image somewhat, were a series of screens above the produce. <br><br>The screens displayed what looked like the inside of a greenhouse, although one could be forgiven for not realizing that right away. The LED lamps above gave off an odd magenta light turning the vast swaths of greenery a reddish-black. The odd hue gave the display a rather surreal look. <br><br>While June and Scott were inspecting the produce for freshness, Cathy paused to stare at the screens. "Those are live feeds from the greenhouses," June provided helpfully. Cathy nodded, but continued to stare at the screens, her brow furrowed in confusion. "I got that, but why is it kinda pink?" Scott held an orange to his nose and gave it a quick sniff. "The lights in the greenhouses only produce the wavelengths plants use for photosynthesis. Saves on power, stimulates growth and plant health." He placed the orange in his produce bag. "The carbon dioxide levels are about five times higher than normal in there too." He pressed some produce bags into her hand, "But enough about that, grab some spinach and get a little something for yourself while you're at it." @@ -1071,7 +942,7 @@ <br><br>Eventually, the party made their way to the star of Blue Barn, the dairy aisle. Display coolers lined the aisle, filled to the brim with milk bottles of various shapes and sizes. Each one bore a printed screen containing a recording of the sexual act that had produced the milk. Whoever was in charge of managing the aisle was kind enough to arrange the milk by kink and sexual act. <br><br>Cathy clutched her plushie and looked around the aisle uncertainty. Scott nudged her. "Go grab a bottle of From the Source, it should be in the titfucking section." She clutched the plushie a little harder then walked down the aisle. <br><br>While she was looking for her quarry, something caught her eye. She squinted at a particular bottle for a moment before reaching in to grab it. With a hesitant finger, she pressed the play button on the bottle. As the video played, a look of dawning horror spread across her face. She was so enthralled with the video, she didn't notice Scott walking up to her. "Oh, did you find something you wanted?" She started and spun to face him, brandishing the bottle at him. "YOU MARRIED YOUR SISTER!?" - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 7>> + <<elseif FCTV.channelCount(7)>> <br><br>The offending bottle was of a higher quality than most of its neighbors, offering a gallery of artists' renditions of the cow in addition to the video. The video on the bottle showed Scott fucking Annie from behind, a slightly tinny slap followed by a squeal from the tiny speakers on the bottle. However, this was not the source of Cathy's distress, as surprising as that may be. Rather, it was the words, Top shelf: All in the Family, printed in red lettering across the bottle. <br><br>Scott cocked an eyebrow, utterly unperturbed. "Yes? And?" Cathy sputtered, but quickly regained her momentum. "You don't do that! Why would do that!?" she all but shrieked, her face blotchy. <br><br>"For two reasons," he said, and held up a finger. "One, have you seen her?" A lewd grin spread across his face, "Rawr." Cathy's blush deepened as her outrage engine built up steam. The grin slid off of Scott's face and his voice grew solemn. "Second, parents can't sell their children if they're already married." @@ -1086,7 +957,7 @@ <br><br>Scott walked up behind her and slipped his arms around her to grab her breasts. "Doing some early Christmas shopping?" he asked looking over her shoulder. She leaned into him, "Just looking at the new milker you were going to buy for Sarah." He gave her breasts a squeeze as he read the article over her shoulder. "It's a high end model. I'm a very thoughtful father, aren't I?" he said in faux pompous tone, nodding to himself. A small smile spread across June's face. "Of course you are, master." They enjoyed each other's company for a moment before she spoke in a low tone, "Everything alright?" He teased her nipples and spoke in the same tone, "I think I've made some progress with her." He leaned closer to whisper in her ear, "I told you it was a good idea." <br><br>They separated and returned to the cart. While they were having their little chat, Cathy had decided to brave the contents of the erotica section. The look on her face was difficult to describe, but she was reading the book very intently. Scott caught her eye and said, "you can have it, if you want it..." She snapped the book shut, placed it on the shelf, and tried to look as small as possible. He just shrugged in response and looked through the cart before nodding to himself. "I think we're ready to go. Any objections?" June shook her head, but Cathy looked at the shelf for a long second before shaking her head. <br><br>The three gathered up their purchases and headed to the exit. As they were passing through the checkout, Scott noticed a certain book pass amongst their purchases. He turned to give Cathy a look. She was pointedly not looking in his direction when she snatched up the book and made a beeline for the door. When she stepped outside, she noticed something was off about the building, but she couldn't put her finger on it. Scott and June made their way outside to see her gaze flickering over the building. Scott simply smiled at Cathy. Finally, the penny dropped, Cathy glared at him like she was trying to set him on fire with her mind. The upper level of Blue Barn didn't have cows mounted on the wall. Cackling laughter echoed in the street. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 8>> + <<elseif FCTV.channelCount(8)>> <br><br>Cathy's ire had faded somewhat by the time they made it home. A soft chime rang out as they walked in the door, followed shortly by a faint voice calling out, "Welcome home," from further in the house. The trio put the groceries on the kitchen island and began to put them away. The background murmur of a TV and the faint roar of a hair dryer were coming from the next room. Scott was about to walk into the room, but he paused and looked at the plushie in his hand. He turned and pressed it into June's hands, giving her a meaningful look. She looked at the doll for a moment before returning his look with a smile. Message received. He gave her a quick nod before walking through the door. <br><br>At first glance, the living room didn't look too dissimilar from something of an old-world home decorating magazine. The furniture was well made and comfortable, but was noticeably designed with more robust figures in mind. Books and magazines laid scattered across a number of coffee and end tables. An old copy of <i>Milkers Monthly</i> was opened to a video of a cowslave demonstrating the use of a cleavage vibrator. The shelves on the far wall held a number of statues, their brass figures bearing immobilizing breasts. And on the end was a 1st place ribbon from a school milking competition. <br><br>Annie sat on the couch with a towel around her shoulders, only wearing her exosuit. She relaxed as Sadie went over her vast cleavage with a hair dryer and a towel, letting out noises of contentment as she luxuriated in Sadie's ministrations. Sarah was cuddled up to her mother, her hair still damp from the shower. Scott sat down on the couch and pulled Sarah onto his lap before moving closer to his wife. Sarah just made herself comfortable while Annie leaned over to give him a kiss. "Everything go alright?" He patted his wife's breast reassuringly. "There was a little bump or two, but it went alright. I'll tell you about it later." @@ -1107,13 +978,13 @@ <<case 13>> <<run FCTV.incrementChannel()>> - <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>> + <<if FCTV.channelCount(1)>> <<if $usedRemote>> based off an interesting thumbnail that turns out to be <<else>> - which is + which is currently in <</if>> - currently in the middle of a "real life" documentary. + the middle of a "real life" documentary. <br><br> The mountain roads started getting dangerous when the rains started getting bad. All that water washed away the earth and loosened up rocks that had been there for ages. Rock slides started getting more and more common, so the roads started getting less and less traffic. People with enough money took planes to get across the mountains, and those without money just stayed put. That is until things started getting worse over there. There was an exodus of desperate people leaving some time ago after their government withdrew from the area, and that many vehicles was enough to bring down the rocks and kill hundreds. All that was left back home was those stupid enough to think things would get better, and those smart enough to realize that crossing was death. Now the roads are in pretty bad shape, but occasionally some groups come through. Either stupid or desperate, and either case works for us. <br><br> @@ -1154,11 +1025,11 @@ "Recon, moving out." <br><br> The screen is closed as the pool of heat in the middle slowly cools. The camera and computer are grabbed and the recon team leaves the vantage point. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 2>> + <<elseif FCTV.channelCount(2)>> <<if $usedRemote>> - another interesting thumbail which is currently in + another interesting thumbail which turns out to be in <<else>> - skipping straight to + skipping straight to <</if>> the middle of yet another "real life" documentary. <br><br> @@ -1201,7 +1072,7 @@ "Are you going to go and protect people, Dad?" A pained grimace crosses over his face as he locks eyes with the nurse who has a very similar expression. After a long moment he turns back with the most genuine smile a father can muster and says, "I sure am, kiddo. I sure am," before turning again to leave. "Good luck." - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 3>> + <<elseif FCTV.channelCount(3)>> currently airing a program about the nuances of slave life. <br><br> The screen fades in with a fly-through shot of what is undoubtedly an arcology penthouse littered with slaves accompanied by a somewhat upbeat piano melody. You recognize many of the traditional additions to a penthouse, though there are some stylistic differences. After a short time the show identifies itself as "The Other Hand" before fading out. @@ -1233,7 +1104,7 @@ <<case 14>> <<run FCTV.incrementChannel()>> - <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>> + <<if FCTV.channelCount(1)>> which is currently showing the newest episode of a family-oriented soap opera. The intro shows a beautiful family of three, featuring a husband, wife, and young daughter. When they show the events of the previous episode, it quickly becomes clear that this episode is the finale of the current season of the show. <br> The episode opens with the husband waking up alone in bed and finding a note on his nightstand that his wife had left for him at the end of the previous episode. Through narration in his head, the note is read aloud to the audience. @@ -1351,101 +1222,53 @@ <</if>> <</if>> <<else>> - <<set _slaveOneTimeMinAge = 25>> - <<set _slaveOneTimeMaxAge = 35>> + <<set $slaveOneTimeMinAge = 25>> + <<set $slaveOneTimeMaxAge = 35>> <<set $one_time_age_overrides_pedo_mode = 1>> <<set $oneTimeDisableDisability = 1>> + <<if $arcologies[0].FSSupremacistLawME == 1>> <<set $fixedRace = $arcologies[0].FSSupremacistRace>> <<elseif $arcologies[0].FSSubjugationistLawME == 1>> <<set _races = setup.filterRacesLowercase.filter(race => race !== $arcologies[0].FSSubjugationistRace)>> <<set $fixedRace = _races.random()>> <</if>> + <<if $seeDicks != 100>> - <<set _hostess = GenerateNewSlave("XX")>> + <<set _hostess = GenerateNewSlave("XX"), _nun = GenerateNewSlave("XX")>> <<else>> - <<set _hostess = GenerateNewSlave("XY")>> - <</if>> - <<set _hostess.devotion = 45>> - <<set _hostess.trust = 55>> - <<set _hostess.health.condition = random(60,80)>> - <<set _hostess.health.health = _hostess.health.condition - _hostess.health.shortDamage - _hostess.health.longDamage>> - <<set _hostess.muscles = 60>> - <<if _hostess.weight > 130>> - <<set _hostess.weight -= 100>> - <<set _hostess.waist = random(-10,50)>> - <</if>> - <<set _hostess.behavioralFlaw = "arrogant">> - <<set _hostess.markings = "none">> - <<set _hostess.hLength = 40>> - <<set _hostess.hColor = "brown">> - <<set _hostess.hStyle = "luxurious">> - <<set _hostess.clothes = "a halter top dress">> - <<set _hostess.shoes = "heels">> - - <<set _slaveOneTimeMinAge = 25>> - <<set _slaveOneTimeMaxAge = 35>> - <<set $one_time_age_overrides_pedo_mode = 1>> - <<set $oneTimeDisableDisability = 1>> - <<if $arcologies[0].FSSupremacistLawME == 1>> - <<set $fixedRace = $arcologies[0].FSSupremacistRace>> - <<elseif $arcologies[0].FSSubjugationistLawME == 1>> - <<set _races = setup.filterRacesLowercase.filter(race => race !== $arcologies[0].FSSubjugationistRace)>> - <<set $fixedRace = _races.random()>> + <<set _hostess = GenerateNewSlave("XY"), _nun = GenerateNewSlave("XY")>> <</if>> <<if $seeDicks != 0>> <<set _scientist = GenerateNewSlave("XY")>> <<else>> <<set _scientist = GenerateNewSlave("XX")>> <</if>> - <<set _scientist.devotion = 0>> - <<set _scientist.trust = 0>> - <<set _scientist.health.condition = random(60,80)>> - <<set _scientist.health.health = _scientist.health.condition - _scientist.health.shortDamage - _scientist.health.longDamage>> - <<set _scientist.muscles = 60>> - <<if _scientist.weight > 130>> - <<set _scientist.weight -= 100>> - <<set _scientist.waist = random(-10,50)>> - <</if>> - <<set _scientist.boobs = 0>> - <<set _scientist.butt = 0>> - <<set _scientist.behavioralFlaw = "arrogant">> - <<set _scientist.markings = "none">> - <<set _scientist.hLength = 10>> - <<set _scientist.hStyle = "messy">> - <<set _scientist.eyewear = "glasses">> - <<set _scientist.clothes = "conservative clothing">> - <<set _scientist.shoes = "flats">> - <<set _slaveOneTimeMinAge = 25>> - <<set _slaveOneTimeMaxAge = 35>> - <<set $one_time_age_overrides_pedo_mode = 1>> - <<set $oneTimeDisableDisability = 1>> - <<if $arcologies[0].FSSupremacistLawME == 1>> - <<set $fixedRace = $arcologies[0].FSSupremacistRace>> - <<elseif $arcologies[0].FSSubjugationistLawME == 1>> - <<set _races = setup.filterRacesLowercase.filter(race => race !== $arcologies[0].FSSubjugationistRace)>> - <<set $fixedRace = _races.random()>> - <</if>> - <<if $seeDicks != 100>> - <<set _nun = GenerateNewSlave("XX")>> - <<else>> - <<set _nun = GenerateNewSlave("XY")>> - <</if>> - <<set _nun.devotion = random(45,60)>> - <<set _nun.trust = random(-10)>> - <<set _nun.health.condition = random(60,80)>> - <<set _nun.health.health = _nun.health.condition - _nun.health.shortDamage - _nun.health.longDamage>> - <<set _nun.muscles = 30>> - <<if _nun.weight > 130>> - <<set _nun.weight -= 100>> - <<set _nun.waist = random(-10,50)>> - <</if>> - <<set _nun.behavioralFlaw = "arrogant">> - <<set _nun.markings = "none">> - <<set _nun.hLength = 1>> - <<set _nun.hStyle = "buzzcut">> - <<set _nun.clothes = "a penitent nuns habit">> + <<run Object.assign( + _hostess, { + devotion: 45, trust: 55, + muscles: 60, hLength: 40, + hColor: "brown", hStyle: "luxurious", + clothes: "a halter top dress", shoes: "heels" + }, + _scientist, { + devotion: 0, trust: 0, + muscles: 60, boobs: 0, + butt: 0, hLength: 10, + hStyle: "messy", eyewear: "glasses", + clothes: "conservative clothing", shoes: "flats" + }, + _nun, { + devotion: random(45,60), trust: random(-10), + muscles: 30, hLength: 1, + hStyle: "buzzcut", clothes: "a penitent nuns habit" + } + )>> + + <<run FCTV.FinalTouches(_hostess, 14)>> + <<run FCTV.FinalTouches(_scientist, 14)>> + <<run FCTV.FinalTouches(_nun, 14)>> <<if $seeImages > 0>> <div class="imageColumn"> @@ -1489,11 +1312,7 @@ <<case 15>> <<run FCTV.incrementChannel()>> - <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>> - /* - You awaken one morning, just before the break of dawn, and find yourself unable to go back to sleep. Giving up on the idea of returning to slumber, you idly flip through the channels on your TV, finding mostly static or early morning infomercials, until you finally land on a channel broadcasting so early in the morning. - <br><br> - */ + <<if FCTV.channelCount(1)>> aka the Pirate channel.<br> You're greeted by a man with an eyepatch, a bushy black beard, and a crimson bandanna around his head. He's sitting behind a crude looking bamboo desk. Behind him is the backdrop of a sun rising over the ocean and two slaves in tight revealing sailor outfits swabbing the deck. The whole set looks like some sort of tropical pirate theme and you almost change the channel mistaking the show for a kids show when it catches up to you what the pirate is talking about. <br><br> @@ -1513,7 +1332,7 @@ When the weather finishes, she crosses her arms under her breasts, emphasizing the pair barely restrained by the laces of her blouse and barely slipping free after her energetic report, as credits of strange and funny pirate themed names begin to flash across the bottom of the screen, she happily begins to sign off. "We here at Pieces o' Eight thank ye fer trustin' us with yer global news an' weather, from our crew to yours, have a merry day!" <br><br> You flip off the TV. News from a pirate, how novel. - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 2>> + <<elseif FCTV.channelCount(2)>> the pirate themed channel. Apparently this is a live feed produced by a band of pirates and you tuned in right as they board a small pleasure craft. <br><br> Three armed pirates are swiftly sweeping the boat, gathering the passengers, a man, his wife and his two children, on deck and tying them up. The camera is attached to the pirate captain as he sweeps below deck finding their supplies. @@ -1540,24 +1359,21 @@ <<run FCTV.incrementChannel()>> <<if $seeImages > 0>> <<set _indian = BaseSlave()>> - <<set _indian.devotion = 0>> - <<set _indian.trust = 100>> - <<set _indian.weight = -20>> - <<set _indian.boobs = 300>> - <<set _indian.hips = 0>> - <<set _indian.butt = 1>> - <<set _indian.hLength = 50>> - <<set _indian.skin = "very fair">> - <<set _indian.hStyle = "braided">> - <<set _indian.hColor = "black">> - <<set _indian.clothes = "shibari ropes">> + <<run Object.assign(_indian, { + devotion: 0, trust: 100, + weight: -20, boobs: 300, + hips: 0, butt: 1, + hLength: 50, skin: "very fair", + hStyle: "braided", hColor: "black", + clothes: "shibari ropes" + })>> <</if>> /* All actors are at least 18 */ <p> As you snuggle in for the night<<if $Concubine != 0>> with your concubine<</if>>, you <<if $usedRemote == 1>>tune to<<else>>begin watching<</if>> the <i>Age of Slavery</i> channel. With so many new types of arcologies emerging, it's sometimes difficult to tell if you are watching events unfolding on a set or in a real arcology with a historical society. </p> - <<if $FCTV.channel[num($FCTV.channel.selected, true)] == 1>> + <<if FCTV.channelCount(1)>> "Well, you did well to win the 'cleanest urchin' contest." <br>Currently you seem to be watching a scene from the industrial revolution, in a smoke smudged brick courtyard by a factory. A stout manager, dressed in a black suit, is leading a thin urchin toward a wooden building built out from the main factory. <br>"Thank you, sir," the urchin gulps. "My mother really needs the money. You promised a shilling?" @@ -1590,7 +1406,7 @@ <br>"Then you need some blasted motivation! I'll pack those bearings in myself!" <br>The youth shrieks, and in a panic sprints around the tank. The man follows closely, and then chases him out the door. With no time to grab his clothing, the youth squirts out bearings as he runs, before making the relative safety of the street, still nude. A camera from the street reveals an interesting surprise as the desperation on the fleeing youth's face shifts to consternation. Heads on the street turn, too, as he drops the last bearings and spurts white over coal black skin. There was more than water in the tank: he's dyed now as black as night from head to toe. <br>Pointing and laughing uproariously, the man flips the eighth bearing into the air before pocketing it again and buttoning up his pants. The camera pans out to show the factory's name as "Titan's Textiles." - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 2>> + <<elseif FCTV.channelCount(2)>> <<if $seeImages > 0>> <div class="imageColumn"> <div class="imageRef medImg"> @@ -1612,14 +1428,11 @@ <br><br> "You know what I am thinking, girls," Dakota muses. "I am thinking this might be an honest mistake." The heads of the other two snap around. "Hear me out. I am wondering if she honestly thinks she's not a whore, simply because she doesn't look like one." <br> The others pause for a moment, then start to laugh. "Ahh, I see where this is going. We could teach her. Yes, let's 'help her out'." <br> Kate pulls out a large makeup kit. "Ordered from Sears and Roebuck by my husband, as a 'makeup' present for his dalliances. For all the times I used it I never got his attention. But you know, maybe I just never used <i>enough</i>." - <br> The camera pans away and when it returns, the Indian girls face is positively caked with the most absurdly overdone makeup you have ever seen. It's both hot and hilarious in the same way. + <br> The camera pans away and when it returns, the Indian girl's face is positively caked with the most absurdly overdone makeup you have ever seen. It's both hot and hilarious in the same way. <<if $Concubine.makeup > 0>> You look at your own concubine's face. - <<set _activeSlave = _slave>> - <<set _slave = $Concubine>> - <<makeupDescription>> + <<= App.Desc.makeup($Concubine)>> It's just the way you like it, but it's nowhere near as messy and overdone as the girl in the show. - <<set _slave = _activeSlave>> <</if>> <br> "Mmmm, good but now the rest of her seems a little plain," Annie frowns. "Don't loose girls wear big boots?" <br> "I can help with that," Dakota smiles. @@ -1658,8 +1471,7 @@ <br> "How do you like our hospitality now?" "Think you'll be back soon to tease our husbands?" <br> Little Cloud lets out an enormous wet belch, then two more as she strains her body. <br> "Hahahaha, her breath smells like whiskey and," Annie says as she eyes Kate, "You, to be frank." They both burst out laughing again. - - <<elseif $FCTV.channel[num($FCTV.channel.selected, true)] == 3>> + <<elseif FCTV.channelCount(3)>> <<if $seeImages > 0>> <<set _indian.hStyle = "messy">> <<set _indian.shoeColor = "#c80000">> @@ -1719,7 +1531,4 @@ <</if>> <<default>> It seems there's a technical error preventing you from streaming; you tell $assistant.name to look into it. -<</switch>> - -<<set $FCTV.channel.last = $FCTV.channel.selected>> -<<run delete $FCTV.channel.selected>> <<run delete $usedRemote>> \ No newline at end of file +<</switch>> \ No newline at end of file diff --git a/src/pregmod/FCTV/seFCTVwatch.tw b/src/pregmod/FCTV/seFCTVwatch.tw index 60ac887e83033842b73f649ccabad4f2fe35450b..77933434d2a71ce3d6731bd3ae88b8fdac5b4d54 100644 --- a/src/pregmod/FCTV/seFCTVwatch.tw +++ b/src/pregmod/FCTV/seFCTVwatch.tw @@ -1,9 +1,9 @@ :: SE FCTV Watch [nobr] <<set $nextButton = "Continue", $nextLink = "Scheduled Event", $returnTo = "Scheduled Event", $showEncyclopedia = 1, $encyclopedia = "FCTV">> -<<set $FCTV.pcViewership.count++, _possibleChannels = [0].concat(FCTV.channels()), $usedRemote = $usedRemote || 0>> +<<set $FCTV.pcViewership.count++, _possibleChannels = [0].concat(FCTV.channels())>> -Tired after a long day, you tell <<if $Concubine > 0>>your concubine: @@.pink;$Concubine.slaveName@@<<else>>$assistant.name<</if>> to turn on the TV and +Tired after a long day, you tell <<if $Concubine>>your concubine: @@.pink;$Concubine.slaveName@@<<else>>$assistant.name<</if>> to turn on the TV and <<if !$usedRemote>> set FCTV to find a random show. Your larger-than-life screen flashes on, and is soon playing content from the popular streaming service. <<if $cheatMode > 0 || $debugMode > 0 || $FCTV.remote>> @@ -52,23 +52,23 @@ Tired after a long day, you tell <<if $Concubine > 0>>your concubine: @@.pink;$C <</for>> <br> - <<if $FCTV.channel.selected == $FCTV.channel.last>>You tuned into this channel last week, you may want choose something else.<br> <</if>> - <span id='all'> </span> - <<if $cheatMode > 0 || $debugMode > 0>> <br> - <<link "Toggle inappropriate">> - <<if _all>> - <<set _all = 0>> + <<if $cheatMode > 0 || $debugMode > 0>> + <<link "Toggle inappropriate" "SE FCTV Watch">> + <<if $all>> + <<set $all = 0>> <<else>> - <<set _all = 1>> + <<set $all = 1>> <</if>> - <<replace '#all'>> - <<if _all>> - There is an audible tone from your screen, which then displays a message: <i>Showing all content, for testing purposes.</i> <br> - <</if>> - <</replace>> <</link>> | <</if>> [[Randomise channel selection|SE FCTV Watch][$usedRemote = 0]] + <<if $FCTV.channel.selected == $FCTV.channel.last>> + <br>You tuned into this channel last week, you may want choose something else. + <</if>> + <<if $all>> + <br>There is an audible tone from your screen, which then displays a message: + <i>Showing all content, for testing purposes.</i> + <</if>> </center> <</if>> diff --git a/src/pregmod/widgets/economyWidgets.tw b/src/pregmod/widgets/economyWidgets.tw index e4de275dca65b4af40e90f5bd4362402fbabc19d..8bb509efc59b5d5dab76c8dfccdf8decaf7d6439 100644 --- a/src/pregmod/widgets/economyWidgets.tw +++ b/src/pregmod/widgets/economyWidgets.tw @@ -458,136 +458,3 @@ <</if>> <</if>> <</widget>> - -/* Call with <<CorpDevBuySell "asset" "Numasset">> TODO: replace eval parse with appropriate functions */ -<<widget "CorpDevBuySell">> -<<set _textboxMLArg = '_'+$args[1]>> -| Trade Qty -<<textbox `'_Num' + $args[0]` `eval(parse('_Num' + $args[0]))`>><<script>>setTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>>: -<<link "Buy">> - <<if !Number.isInteger(Number.parseFloat(eval(parse('_Num' + $args[0]))))>> /* Checks if _Numasset is string */ -/* Buy all */ - <<if ["all", "max"].includes(State.temporary[$args[1]].toLowerCase())>> - <<set State.temporary[$args[1]] = Math.floor($corp.Cash/(State.variables[$args[0]+"AssetPrice"] * 500))>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> - Bought <<print num(Math.floor($corp.Cash/(State.variables[$args[0]+"AssetPrice"] * 500)))>> units for <<print cashFormat(Math.floor($corp.Cash/(State.variables[$args[0]+"AssetPrice"] * 500))*500*State.variables[$args[0]+"AssetPrice"])>> - <</replace>> - <<set State.variables[$args[0]+"Assets"] += (eval(parse('_Num' + $args[0]))) * 500>> - <<set $corp.Cash -= (eval(parse('_Num' + $args[0]))) * 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace '#cashOnHand'>> - <<print cashFormat($corp.Cash)>> - <</replace>> - <<replace `'#'+$args[0]+'AssetsDisp'`>> - <<print cashFormat(State.variables[$args[0]+"AssetPrice"] * State.variables[$args[0]+"Assets"])>> (<<print num(Math.floor(State.variables[$args[0]+"Assets"]/500))>> unit<<if State.variables[$args[0]+"Assets"]/500 > 1>>s<</if>>) - <</replace>> - <<replace `'#'+'controls'+$args[0]`>><<CorpDevBuySell $args[0] $args[1]>><</replace>><<script>>setReplaceTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>> - <<else>> -/* Error if decimal or not "all" or "max" string */ - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> Please input a round number. <</replace>> - <</if>> -/* Negative number, try again */ - <<elseif Number.parseFloat(eval(parse('_Num' + $args[0]))) < 0>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>>Please input a positive number.<</replace>> -/* Buy % */ - <<elseif State.temporary[$args[1]].toString().includes("%")>> - <<set _DesPerc = State.temporary[$args[1]]>> - <<set State.temporary[$args[1]] = Math.floor((Math.clamp((Number.parseFloat(State.temporary[$args[1]])/100),0,1)*$corp.Cash)/(State.variables[$args[0]+"AssetPrice"] * 500))>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> - Purchased <<print num(State.temporary[$args[1]])>> units (<<print num((State.temporary[$args[1]]*(State.variables[$args[0]+"AssetPrice"] * 50000)/$corp.Cash).toFixed(2))>>% of cash, desired was _DesPerc) - <</replace>> - <<set State.variables[$args[0]+"Assets"] += (eval(parse('_Num' + $args[0]))) * 500>> - <<set $corp.Cash -= (eval(parse('_Num' + $args[0]))) * 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace '#cashOnHand'>> - <<print cashFormat($corp.Cash)>> - <</replace>> - <<replace `'#'+$args[0]+'AssetsDisp'`>> - <<print cashFormat(State.variables[$args[0]+"AssetPrice"] * State.variables[$args[0]+"Assets"])>> (<<print num(Math.floor(State.variables[$args[0]+"Assets"]/500))>> unit<<if State.variables[$args[0]+"Assets"]/500 > 1>>s<</if>>) - <</replace>> - <<replace `'#'+'controls'+$args[0]`>><<CorpDevBuySell $args[0] $args[1]>><</replace>><<script>>setReplaceTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>> -/* Successful buy */ - <<elseif (eval(parse('_Num' + $args[0]))) * 500 * State.variables[$args[0]+"AssetPrice"] < $corp.Cash>> - <<set State.variables[$args[0]+"Assets"] += (eval(parse('_Num' + $args[0]))) * 500>> - <<set $corp.Cash -= (eval(parse('_Num' + $args[0]))) * 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace '#cashOnHand'>> - <<print cashFormat($corp.Cash)>> - <</replace>> - <<replace `'#'+$args[0]+'AssetsDisp'`>> - <<print cashFormat(State.variables[$args[0]+"AssetPrice"] * State.variables[$args[0]+"Assets"])>> (<<print num(Math.floor(State.variables[$args[0]+"Assets"]/500))>> unit<<if State.variables[$args[0]+"Assets"]/500 > 1>>s<</if>>) - <</replace>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>><</replace>> -/* Unsuccessful buy but have enough cash for more than 1 unit */ - <<elseif $corp.Cash > 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> - The corp can only buy <<print num(Math.floor($corp.Cash/(State.variables[$args[0]+"AssetPrice"] * 500)))>> more unit<<if Math.floor($corp.Cash/(State.variables[$args[0]+"AssetPrice"] * 500)) > 1 >>s<</if>> of $args[0] assets. - <</replace>> - <<set State.temporary[$args[1]] = Math.floor($corp.Cash/(State.variables[$args[0]+"AssetPrice"] * 500))>> - <<replace `'#'+'controls'+$args[0]`>><<CorpDevBuySell $args[0] $args[1]>><</replace>><<script>>setReplaceTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>> -/* Unsuccessful buy */ - <<else>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>>There are insufficient funds for additional purchases.<</replace>> - <</if>> -<</link>> -| <<link "Sell">> - <<if !Number.isInteger(Number.parseFloat(eval(parse('_Num' + $args[0]))))>> -/* Sell all */ - <<if ["all", "max"].includes(State.temporary[$args[1]].toLowerCase())>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> - Sold <<print num(Math.ceil((State.variables[$args[0]+"Assets"]-500)/500))>> units for <<print cashFormat(Math.ceil((State.variables[$args[0]+"Assets"]-500)/500)*500*State.variables[$args[0]+"AssetPrice"])>> - <</replace>> - <<set State.temporary[$args[1]] = Math.ceil((State.variables[$args[0]+"Assets"]-500)/500)>> - <<set State.variables[$args[0]+"Assets"] -= eval(parse('_Num' + $args[0])) * 500>> - <<set $corp.Cash += eval(parse('_Num' + $args[0])) * 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace '#cashOnHand'>> - <<print cashFormat($corp.Cash)>> - <</replace>> - <<replace `'#'+$args[0]+'AssetsDisp'`>> - <<print cashFormat(State.variables[$args[0]+"AssetPrice"] * State.variables[$args[0]+"Assets"])>> (<<if Math.ceil(State.variables[$args[0]+"Assets"]/500) < 1>> < 1 <<else>><<print num(Math.ceil(State.variables[$args[0]+"Assets"]/500))>> <</if>>unit<<if State.variables[$args[0]+"Assets"]/500 > 1>>s<</if>>) - <</replace>> - <<replace `'#'+'controls'+$args[0]`>><<CorpDevBuySell $args[0] $args[1]>><</replace>><<script>>setReplaceTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>> -/* Error if decimal or not "all" or "max" string */ - <<else>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> Please input a round number. <</replace>> - <</if>> -/* Negative number, try again */ - <<elseif Number.parseFloat(eval(parse('_Num' + $args[0]))) < 0>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>>Please input a positive number.<</replace>> -/* Sell % */ - <<elseif State.temporary[$args[1]].toString().includes("%")>> - <<set _DesPerc = State.temporary[$args[1]]>> - <<set State.temporary[$args[1]] = Math.ceil((State.variables[$args[0]+"Assets"]-500)/500*(Math.clamp((Number.parseFloat(State.temporary[$args[1]])/100),0,1)))>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> - Sold <<print num(State.temporary[$args[1]])>> units (<<print num((State.temporary[$args[1]]*100/((State.variables[$args[0]+"Assets"]-500)/500)).toFixed(2))>>% of $args[0] assets, desired was _DesPerc) - <</replace>> - <<set State.variables[$args[0]+"Assets"] -= eval(parse('_Num' + $args[0])) * 500>> - <<set $corp.Cash += eval(parse('_Num' + $args[0])) * 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace '#cashOnHand'>> - <<print cashFormat($corp.Cash)>> - <</replace>> - <<replace `'#'+$args[0]+'AssetsDisp'`>> - <<print cashFormat(State.variables[$args[0]+"AssetPrice"] * State.variables[$args[0]+"Assets"])>> (<<if Math.ceil(State.variables[$args[0]+"Assets"]/500) < 1>> < 1 <<else>><<print num(Math.ceil(State.variables[$args[0]+"Assets"]/500))>> <</if>>unit<<if State.variables[$args[0]+"Assets"]/500 > 1>>s<</if>>) - <</replace>> - <<replace `'#'+'controls'+$args[0]`>><<CorpDevBuySell $args[0] $args[1]>><</replace>><<script>>setReplaceTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>> -/* Successful sell */ - <<elseif State.variables[$args[0]+"Assets"] > 500 && eval(parse('_Num' + $args[0])) * 500 < State.variables[$args[0]+"Assets"]>> - <<set State.variables[$args[0]+"Assets"] -= eval(parse('_Num' + $args[0])) * 500>> - <<set $corp.Cash += eval(parse('_Num' + $args[0])) * 500 * State.variables[$args[0]+"AssetPrice"]>> - <<replace '#cashOnHand'>> - <<print cashFormat($corp.Cash)>> - <</replace>> - <<replace `'#'+$args[0]+'AssetsDisp'`>> - <<print cashFormat(State.variables[$args[0]+"AssetPrice"] * State.variables[$args[0]+"Assets"])>> (<<if (State.variables[$args[0]+"Assets"]/500) < 1>> < 1 <<else>><<print num(Math.ceil(State.variables[$args[0]+"Assets"]/500))>> <</if>>unit<<if State.variables[$args[0]+"Assets"]/500 > 1>>s<</if>>) - <</replace>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>><</replace>> -/* Unsuccessful sell but have enough assets for more than 1 unit */ - <<elseif State.variables[$args[0]+"Assets"] > 500>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>> - The corp can only sell <<print num(Math.ceil((State.variables[$args[0]+"Assets"]-500)/500))>> more unit<<if Math.ceil((State.variables[$args[0]+"Assets"]-500)/500) > 1 >>s<</if>> of $args[0] assets. - <</replace>> - <<set State.temporary[$args[1]] = Math.ceil((State.variables[$args[0]+"Assets"]-500)/500)>> - <<replace `'#'+'controls'+$args[0]`>><<CorpDevBuySell $args[0] $args[1]>><</replace>><<script>>setReplaceTextboxMaxLength(State.temporary["textboxMLArg"], 10);<</script>> -/* Unsuccessful sell */ - <<else>> - <<replace `'#'+$args[0]+'AssetsPurchasing'`>>The corp cannot sell any more $args[0] assets.<</replace>> - <</if>> -<</link>> -<</widget>> diff --git a/src/pregmod/widgets/marketWidgets.tw b/src/pregmod/widgets/marketWidgets.tw deleted file mode 100644 index 517b15aca8f883299eb460568db41c031265cee1..0000000000000000000000000000000000000000 --- a/src/pregmod/widgets/marketWidgets.tw +++ /dev/null @@ -1,38 +0,0 @@ -:: Market Widgets [widget nobr] - -/* -* Look for widgets in passages tagged with "market:marketname" which -* end in "Populate" and calls them all with the second argument -* (an "origins" array) as argument. -* -* Call like <<AddMarketOrigins "marketname" _possibleOrigins>> -*/ - -<<widget "AddMarketOrigins">> -<<if _.isString($args[0]) && _.isArray($args[1])>> - <<set _sanityCheck = '>>', /* to appease sanityCheck */ - _widgets = _(Story.widgets) - .filter(function(wp) { return wp.tags.includes('market:' + $args[0]); }) - .flatMap(function(wp) { - var re = RegExp('<<widget\\s+"([^"]+Populate)"\\s*>>', 'g'); - var match, result = []; - while(match = re.exec(wp.text)) { result.push(match[1]); } - return result; }) - .value()>> - <<silently>><<for _widget range _widgets>> - <<= "<<" + _widget + " $args[1]>>">> - <</for>><</silently>> -<</if>> -<</widget>> - -<<widget "CreateSlaveByOrigin">> -<<silently>> - <<if _.isObject($args[0]) && _.isString($args[0].widget)>> - <<= "<<" + $args[0].widget + " $args[0]>>">> - <<elseif _.isString($args[0])>> - <<= "<<" + $args[0] + " $args[0]>>">> - <<else>> - <<include "Generate Random Slave">> - <</if>> -<</silently>> -<</widget>> diff --git a/src/uncategorized/longSlaveDescription.tw b/src/uncategorized/longSlaveDescription.tw index f638f0b2317976db9a7ef5cb95490cabb8287db2..c70bc545ce3d79ab136a2e9635d54ed1d5285cd6 100644 --- a/src/uncategorized/longSlaveDescription.tw +++ b/src/uncategorized/longSlaveDescription.tw @@ -1937,7 +1937,7 @@ $He is <</if>> <<if $activeSlave.fuckdoll == 0>> - <<nailsDescription>> + <<= App.Desc.nails($activeSlave)>> <</if>> <<= App.Desc.mods($activeSlave, "back")>> <<= App.Desc.mods($activeSlave, "shoulder")>> diff --git a/src/uncategorized/manageArcology.tw b/src/uncategorized/manageArcology.tw index c97c4b352b9dd357e171a2bc95191385a47101af..0728e40674fb62aebf5316f37da4160ae0dfc720 100644 --- a/src/uncategorized/manageArcology.tw +++ b/src/uncategorized/manageArcology.tw @@ -75,15 +75,11 @@ The next major upgrade needed is an improvement of the arcology's electrical transmission lines to make efficient use of the additional power from the solar apron. This upgrade will cost <<print cashFormat(Math.trunc(50000*$upgradeMultiplierArcology))>>. </span> [[Upgrade transmission lines|Manage Arcology][cashX(forceNeg(Math.trunc(50000*$upgradeMultiplierArcology)), "capEx"), $arcologyUpgrade.grid = 1, $PC.skill.engineering += 1]] - <<elseif $arcologyUpgrade.spire != 1>> - <span class="note"> - The next major upgrade needed is the addition of a spire at the top of the arcology to increase the space available for the wealthiest citizens to own whole floors. This huge project will cost <<print cashFormat(Math.trunc(250000*$upgradeMultiplierArcology))>>. - </span> - [[Add spire|Manage Arcology][cashX(forceNeg(Math.trunc(250000*$upgradeMultiplierArcology)), "capEx"), $arcologyUpgrade.spire = 1, $building.sections.push(new App.Arcology.Section("spire", [[new App.Arcology.Cell.Apartment(1, 2), new App.Arcology.Cell.Apartment(1, 2)], [new App.Arcology.Cell.Apartment(1, 2), new App.Arcology.Cell.Apartment(1, 2)]])), $PC.skill.engineering += 1]] <<else>> <span class="note"> The arcology's public areas are fully upgraded. </span> + <<= App.UI.DOM.includeDOM(App.Arcology.upgrades($building))>> <</if>> </div> @@ -99,7 +95,7 @@ <</if>> </span> [[Apply weather cladding|Manage Arcology][cashX(forceNeg(Math.trunc(50000*$upgradeMultiplierArcology)), "capEx"), $weatherCladding = 1, $PC.skill.engineering += 1]] - <<elseif $weatherCladding == 1 && $arcologyUpgrade.spire == 1>> + <<elseif $weatherCladding == 1 && $building.sections.length > 0>> The arcology's exterior is jacketed with unsightly but sturdy weather cladding. Your arcology is so prosperous that remodeling the cladding into something beautiful is within the realm of possibility. This massive project will cost <<print cashFormat(Math.trunc(3500000*$upgradeMultiplierArcology))>> and without a doubt render your arcology one of the wonders of the world. [[Remodel weather cladding|Manage Arcology][cashX(forceNeg(Math.trunc(3500000*$upgradeMultiplierArcology)), "capEx"), $weatherCladding = 2, $PC.skill.engineering += 1]] <<elseif $weatherCladding == 1>> diff --git a/src/uncategorized/newGamePlus.tw b/src/uncategorized/newGamePlus.tw index ccacf4a86b0076f2bdaa8534bd753e40f51f6114..32041f40d4c0c45b5cb08ec8246f9af87585e54a 100644 --- a/src/uncategorized/newGamePlus.tw +++ b/src/uncategorized/newGamePlus.tw @@ -23,6 +23,7 @@ You <<if $cash >= _fee>>have<<else>>lack<</if>> the funds to bring more than $sl <br> +<<set $ngpParams = { nationality: getRevivalistNationality(), prosperity: (250 * $arcologies[0].prosperity * $arcologies[0].ownership) }>> <<if $freshPC == 0>> <<if $retainCareer == 1 && $PC.career != "arcology owner">> <<if $week > 52 || ($PC.skill.slaving >= 100 && $PC.skill.trading >= 100 && $PC.skill.warfare >= 100 && $PC.skill.engineering >= 100 && $PC.skill.medicine >= 100 && $PC.skill.hacking >= 100)>> diff --git a/src/uncategorized/nextWeek.tw b/src/uncategorized/nextWeek.tw index 3f966080aad7b09d95c93eb3a6ea3f230cb92840..0843290b2ec43a7d7a4cd0bdd7249df06bb22cd4 100644 --- a/src/uncategorized/nextWeek.tw +++ b/src/uncategorized/nextWeek.tw @@ -271,11 +271,15 @@ <<set $PC.forcedFertDrugs-->> <</if>> -<<if $FCTV.receiver > 0 && $FCTV.pcViewership.frequency != -1>> - <<set $FCTV.pcViewership.count++>> - <<if $FCTV.pcViewership.count >= $FCTV.pcViewership.frequency>> - <<set $FCTV.pcViewership.count = 0>> +<<if $FCTV.receiver > 0>> + <<if $FCTV.pcViewership.frequency != -1>> + <<set $FCTV.pcViewership.count++>> + <<if $FCTV.pcViewership.count >= $FCTV.pcViewership.frequency>> + <<set $FCTV.pcViewership.count = 0>> + <</if>> <</if>> + <<set $FCTV.channel.last = $FCTV.channel.selected>> + <<run delete $FCTV.channel.selected>> <<run delete $usedRemote>> <<run delete $all>> <<run delete $show>> <</if>> <<set $week++>> diff --git a/src/uncategorized/options.tw b/src/uncategorized/options.tw index 7ed9c60c58abd10b144537254a89f004940c22be..32670ed035e5e20501b921b347375e70f528f14d 100644 --- a/src/uncategorized/options.tw +++ b/src/uncategorized/options.tw @@ -58,7 +58,11 @@ This save was created using FC version $ver build $releaseID. <</link>> <</if>> <<if $familyTesting == 1>> - <br><<link "Reset extended family mode controllers">><<goto "family panic">><</link>> //Clears and rebuilds .sister and .daughter tracking.// + <br><<link "Reset extended family mode controllers">> + <<run resetFamilyCounters()>> + <<replace "#familyHint">>//@@.lightgreen;Done:@@ all family relations flushed and rebuilt.//<</replace>> + <</link>> + <span id="familyHint">//Clears and rebuilds .sister and .daughter tracking.//</span> <</if>> <<if isNaN($rep)>> <br>[[Reset Reputation|Options][$rep = 0]] diff --git a/src/uncategorized/persBusiness.tw b/src/uncategorized/persBusiness.tw index 8f57105528d97458885050785867dd8afe197f97..423c186faa8907e18c08ad497760d0c8586d0b74 100644 --- a/src/uncategorized/persBusiness.tw +++ b/src/uncategorized/persBusiness.tw @@ -784,6 +784,7 @@ <<set _blackMarket = random(7000,8000)>> Your secret service makes use of black markets and illegal streams of goods to make a profit, making you @@.yellowgreen;<<print cashFormat(_blackMarket)>>.@@ This however allows @@.red;crime to flourish@@ in the underbelly of the arcology. <<set $SecExp.core.crimeLow += random(1,3)>> + <<run cashX(_blackMarket, "personalBusiness")>> <</if>> <<if $arcRepairTime > 0>> diff --git a/src/uncategorized/repBudget.tw b/src/uncategorized/repBudget.tw index d8d58f71416037b99d65cb8af0639ccb590c1b46..9e538b4092311fdef9f14dcf00f59cdfe3ccac83 100644 --- a/src/uncategorized/repBudget.tw +++ b/src/uncategorized/repBudget.tw @@ -126,10 +126,10 @@ for (var i = 0; i < State.variables.lastWeeksRepIncome.length; i++){ <h2>Policies</h2> </tr> - <<print budgetLine("policies", "Capital expenses")>> + <<print budgetLine("capEx", "Capital expenses")>> <<print budgetLine("edicts", "<<if $secExpEnabled > 0>>[[Edicts|edicts]]<<else>>Edicts<</if>>")>> - <<print budgetLine("capEx", "[[Policies|Policies][$nextButton = \"Back to Budget\", $nextLink = \"Rep Budget\"]] and [[Edicts|edicts][$nextButton = \"Back to Budget\", $nextLink = \"Rep Budget\"]]")>> + <<print budgetLine("policies", "[[Policies|Policies][$nextButton = \"Back to Budget\", $nextLink = \"Rep Budget\"]]")>> <<print budgetLine("futureSocieties", "[[Society shaping|Future Society][$nextButton = \"Back to Budget\", $nextLink = \"Rep Budget\"]]")>> diff --git a/src/uncategorized/salon.tw b/src/uncategorized/salon.tw index 56997e255032a3350d34f101b606dcc4ecd94a4c..92dcfa97080d1a07eefb0a22fb95447d0f4a9ed2 100644 --- a/src/uncategorized/salon.tw +++ b/src/uncategorized/salon.tw @@ -646,7 +646,7 @@ <h3>Makeup</h3> <div> - <<makeupDescription>> + <<= App.Desc.makeup(getSlave($AS))>> <<if getSlave($AS).makeup > 0>> [[Remove|Salon][getSlave($AS).makeup = 0,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]] <</if>> @@ -671,7 +671,7 @@ /* NAILS */ <div> - <<nailsDescription>> + <<= App.Desc.nails(getSlave($AS))>> <<if hasAnyArms(getSlave($AS))>> <div class="choices"> diff --git a/src/uncategorized/slaveInteract.tw b/src/uncategorized/slaveInteract.tw index 1c6122712fd5c30669f2c741abe18427baff2e7f..ff492afca56eb001cec9f782233f677da74b1239 100644 --- a/src/uncategorized/slaveInteract.tw +++ b/src/uncategorized/slaveInteract.tw @@ -66,7 +66,7 @@ [â†,Q] </span> <span id="prevSlave" style="font-weight:bold"> - <<link "Prev" "Slave Interact">><<set $slaves[_i] = $activeSlave, $activeSlave = $slaves[_slavesInLine[0]]>><</link>> + <<link "Prev" "Slave Interact">><<set $slaves[_i] = $activeSlave, $activeSlave = getSlave(_slavesInLine[0])>><</link>> </span> <span class='slave-name'> @@ -74,7 +74,7 @@ </span> <span id="nextSlave" style="font-weight:bold"> - <<link "Next" "Slave Interact">><<set $slaves[_i] = $activeSlave, $activeSlave = $slaves[_slavesInLine[1]]>><</link>> + <<link "Next" "Slave Interact">><<set $slaves[_i] = $activeSlave, $activeSlave = getSlave(_slavesInLine[1])>><</link>> </span> <span class="cyan"> [E,→] @@ -226,8 +226,6 @@ <div id="Appearance" class="tabcontent"> <div class="content"> <p> - <h3>Appearance</h3> - <span id="clothes"></span> /*<script>App.UI.Wardrobe.clothes(getSlave(V.activeSlave.ID))</script>*/ @@ -283,112 +281,113 @@ <div id="PhysicalRegimen" class="tabcontent"> <div class="content"> - <h3>Physical Regimen</h3> - <span id="drugs"></span> - <script>App.UI.SlaveInteract.drugs(getSlave(V.activeSlave.ID))</script> + <p> + <span id="drugs"></span> + <script>App.UI.SlaveInteract.drugs(getSlave(V.activeSlave.ID))</script> - <span id="curatives"></span> - <script>App.UI.SlaveInteract.curatives(getSlave(V.activeSlave.ID))</script> + <span id="curatives"></span> + <script>App.UI.SlaveInteract.curatives(getSlave(V.activeSlave.ID))</script> - <span id="aphrodisiacs"></span> - <script>App.UI.SlaveInteract.aphrodisiacs(getSlave(V.activeSlave.ID))</script> + <span id="aphrodisiacs"></span> + <script>App.UI.SlaveInteract.aphrodisiacs(getSlave(V.activeSlave.ID))</script> - <span id="fertilityblock"></span> - <script>App.UI.SlaveInteract.fertility(getSlave(V.activeSlave.ID))</script> + <span id="fertilityblock"></span> + <script>App.UI.SlaveInteract.fertility(getSlave(V.activeSlave.ID))</script> - <span id="incubator"></span> - <script>App.UI.SlaveInteract.incubator(getSlave(V.activeSlave.ID))</script> + <span id="incubator"></span> + <script>App.UI.SlaveInteract.incubator(getSlave(V.activeSlave.ID))</script> - <span id="nursery"></span> - <script>App.UI.SlaveInteract.nursery(getSlave(V.activeSlave.ID))</script> + <span id="nursery"></span> + <script>App.UI.SlaveInteract.nursery(getSlave(V.activeSlave.ID))</script> - <<if $propOutcome == 1 && $arcologies[0].FSRestart != "unset">> - <<if $slaves[_i].breedingMark == 0 && $slaves[_i].fuckdoll == 0 && $slaves[_i].eggType == "human" && isFertile($slaves[_i]) && $slaves[_i].preg == 0>> - <br> - [[Breeder Eligibility Exam|BreedingTest]] + <<if $propOutcome == 1 && $arcologies[0].FSRestart != "unset">> + <<if $slaves[_i].breedingMark == 0 && $slaves[_i].fuckdoll == 0 && $slaves[_i].eggType == "human" && isFertile($slaves[_i]) && $slaves[_i].preg == 0>> + <br> + [[Breeder Eligibility Exam|BreedingTest]] + <</if>> <</if>> - <</if>> - <span id="bloating"></span> - <script>App.UI.SlaveInteract.bloating(getSlave(V.activeSlave.ID))</script> + <span id="bloating"></span> + <script>App.UI.SlaveInteract.bloating(getSlave(V.activeSlave.ID))</script> - Hormones: <strong><span id="hormones"> - <<if $slaves[_i].hormones == -2>>intensive male<<elseif $slaves[_i].hormones == -1>>male<<elseif $slaves[_i].hormones == 2>>intensive female<<elseif $slaves[_i].hormones == 1>>female<<else>>none<</if>></span></strong>. - <<if $slaves[_i].indentureRestrictions < 2>> - <<link "Intensive Female">><<set $slaves[_i].hormones = 2>><<replace "#hormones">>intensive female<</replace>><</link>> | - <</if>> - <<link "Female">><<set $slaves[_i].hormones = 1>><<replace "#hormones">>female<</replace>><</link>> | - <<link "None">><<set $slaves[_i].hormones = 0>><<replace "#hormones">>none<</replace>><</link>> | - <<link "Male">><<set $slaves[_i].hormones = -1>><<replace "#hormones">>male<</replace>><</link>> | - <<if $slaves[_i].indentureRestrictions < 2>> - <<link "Intensive Male">><<set $slaves[_i].hormones = -2>><<replace "#hormones">>intensive male<</replace>><</link>> - <</if>> + Hormones: <strong><span id="hormones"> + <<if $slaves[_i].hormones == -2>>intensive male<<elseif $slaves[_i].hormones == -1>>male<<elseif $slaves[_i].hormones == 2>>intensive female<<elseif $slaves[_i].hormones == 1>>female<<else>>none<</if>></span></strong>. + <<if $slaves[_i].indentureRestrictions < 2>> + <<link "Intensive Female">><<set $slaves[_i].hormones = 2>><<replace "#hormones">>intensive female<</replace>><</link>> | + <</if>> + <<link "Female">><<set $slaves[_i].hormones = 1>><<replace "#hormones">>female<</replace>><</link>> | + <<link "None">><<set $slaves[_i].hormones = 0>><<replace "#hormones">>none<</replace>><</link>> | + <<link "Male">><<set $slaves[_i].hormones = -1>><<replace "#hormones">>male<</replace>><</link>> | + <<if $slaves[_i].indentureRestrictions < 2>> + <<link "Intensive Male">><<set $slaves[_i].hormones = -2>><<replace "#hormones">>intensive male<</replace>><</link>> + <</if>> - <br>Diet: <strong><span id="diet">$slaves[_i].diet</span></strong>. - <<link "Healthy">><<set $slaves[_i].diet = "healthy">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<if ($slaves[_i].health.condition < 90 || $slaves[_i].chem >= 10) && ($dietCleanse == 1)>> - | <<link "Cleanse">><<set $slaves[_i].diet = "cleansing">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<elseif ($dietCleanse == 1)>> - | //$He is already healthy// - <</if>> - <<if ($slaves[_i].balls > 0) && ($cumProDiet == 1)>> - | <<link "Cum production">><<set $slaves[_i].diet = "cum production">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <</if>> - <<if isFertile($slaves[_i]) && $slaves[_i].preg == 0 && ($dietFertility == 1)>> - | <<link "Fertility">><<set $slaves[_i].diet = "fertility">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <</if>> - <<if ($slaves[_i].weight >= -95)>> - | <<link "Lose weight">><<set $slaves[_i].diet = "restricted">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<else>> - | //$He is already underweight// - <</if>> - <<if $slaves[_i].weight <= 200>> - | <<link "Fatten">><<set $slaves[_i].diet = "fattening">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<else>> - | //$He is already extremely overweight// - <</if>> - <<if $feeder == 1>> - <<if $slaves[_i].fuckdoll == 0 && $slaves[_i].fetish != "mindbroken">> - <<if ($slaves[_i].weight > 10 || $slaves[_i].weight < -10)>> - | <<link "Correct weight">><<set $slaves[_i].diet = "corrective">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<else>> - //$He is already a healthy weight// + <br>Diet: <strong><span id="diet">$slaves[_i].diet</span></strong>. + <<link "Healthy">><<set $slaves[_i].diet = "healthy">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<if ($slaves[_i].health.condition < 90 || $slaves[_i].chem >= 10) && ($dietCleanse == 1)>> + | <<link "Cleanse">><<set $slaves[_i].diet = "cleansing">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<elseif ($dietCleanse == 1)>> + | //$He is already healthy// + <</if>> + <<if ($slaves[_i].balls > 0) && ($cumProDiet == 1)>> + | <<link "Cum production">><<set $slaves[_i].diet = "cum production">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <</if>> + <<if isFertile($slaves[_i]) && $slaves[_i].preg == 0 && ($dietFertility == 1)>> + | <<link "Fertility">><<set $slaves[_i].diet = "fertility">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <</if>> + <<if ($slaves[_i].weight >= -95)>> + | <<link "Lose weight">><<set $slaves[_i].diet = "restricted">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<else>> + | //$He is already underweight// + <</if>> + <<if $slaves[_i].weight <= 200>> + | <<link "Fatten">><<set $slaves[_i].diet = "fattening">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<else>> + | //$He is already extremely overweight// + <</if>> + <<if $feeder == 1>> + <<if $slaves[_i].fuckdoll == 0 && $slaves[_i].fetish != "mindbroken">> + <<if ($slaves[_i].weight > 10 || $slaves[_i].weight < -10)>> + | <<link "Correct weight">><<set $slaves[_i].diet = "corrective">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<else>> + //$He is already a healthy weight// + <</if>> + <</if>> + | <<link "Estrogen enriched">><<set $slaves[_i].diet = "XX">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + | <<link "Testosterone enriched">><<set $slaves[_i].diet = "XY">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<if $dietXXY == 1 && $slaves[_i].balls > 0 && ($slaves[_i].ovaries == 1 || $slaves[_i].mpreg == 1)>> + | <<link "Herm hormone blend">><<set $slaves[_i].diet = "XXY">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> <</if>> <</if>> - | <<link "Estrogen enriched">><<set $slaves[_i].diet = "XX">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - | <<link "Testosterone enriched">><<set $slaves[_i].diet = "XY">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<if $dietXXY == 1 && $slaves[_i].balls > 0 && ($slaves[_i].ovaries == 1 || $slaves[_i].mpreg == 1)>> - | <<link "Herm hormone blend">><<set $slaves[_i].diet = "XXY">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<if ($slaves[_i].muscles <= 95) && !isAmputee($slaves[_i])>> + | <<link "Build muscle">><<set $slaves[_i].diet = "muscle building">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<elseif !isAmputee($slaves[_i])>> + | //$He is maintaining $his enormous musculature// + <<else>> + | //$He has no limbs and thus can't effectively build muscle// + <</if>> + <<if ($slaves[_i].muscles > 5 || $slaves[_i].fuckdoll == 0) && canWalk($slaves[_i])>> + | <<link "Slim down">><<set $slaves[_i].diet = "slimming">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> + <<elseif !canWalk($slaves[_i])>> + | //$He can't move and thus can't trim down// + <<elseif $slaves[_i].fuckdoll > 0>> + | //$He has no muscles left to lose// <</if>> - <</if>> - <<if ($slaves[_i].muscles <= 95) && !isAmputee($slaves[_i])>> - | <<link "Build muscle">><<set $slaves[_i].diet = "muscle building">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<elseif !isAmputee($slaves[_i])>> - | //$He is maintaining $his enormous musculature// - <<else>> - | //$He has no limbs and thus can't effectively build muscle// - <</if>> - <<if ($slaves[_i].muscles > 5 || $slaves[_i].fuckdoll == 0) && canWalk($slaves[_i])>> - | <<link "Slim down">><<set $slaves[_i].diet = "slimming">><<replace "#diet">>$slaves[_i].diet<</replace>><</link>> - <<elseif !canWalk($slaves[_i])>> - | //$He can't move and thus can't trim down// - <<elseif $slaves[_i].fuckdoll > 0>> - | //$He has no muscles left to lose// - <</if>> - <br>Diet Base: <strong><span id="dietBase"><<if $slaves[_i].dietCum == 2>>cum based<<elseif ($slaves[_i].dietCum == 1) && ($slaves[_i].dietMilk == 0)>>cum added<<elseif ($slaves[_i].dietCum == 1) && ($slaves[_i].dietMilk == 1)>>cum and milk added<<elseif ($slaves[_i].dietMilk == 1) && ($slaves[_i].dietCum == 0)>>milk added<<elseif ($slaves[_i].dietMilk == 2)>>milk based<<elseif ($slaves[_i].dietCum == 0) && ($slaves[_i].dietMilk == 0)>>normal<<else>>THERE HAS BEEN AN ERROR<</if>></span></strong>. - <<link "Normal">><<set $slaves[_i].dietCum = 0>><<set $slaves[_i].dietMilk = 0>><<replace "#dietBase">>normal<</replace>><</link>> | - <<link "Cum added">><<set $slaves[_i].dietCum = 1>><<set $slaves[_i].dietMilk = 0>><<replace "#dietBase">>cum added<</replace>><</link>> | - <<link "Milk added">><<set $slaves[_i].dietCum = 0>><<set $slaves[_i].dietMilk = 1>><<replace "#dietBase">>milk added<</replace>><</link>> | - <<link "Cum & milk added">><<set $slaves[_i].dietCum = 1>><<set $slaves[_i].dietMilk = 1>><<replace "#dietBase">>cum & milk added<</replace>><</link>> | - <<link "Cum based">><<set $slaves[_i].dietCum = 2>><<set $slaves[_i].dietMilk = 0>><<replace "#dietBase">>cum based<</replace>><</link>> | - <<link "Milk based">><<set $slaves[_i].dietCum = 0>><<set $slaves[_i].dietMilk = 2>><<replace "#dietBase">>milk based<</replace>><</link>> - - <<if $arcologies[0].FSHedonisticDecadenceResearch == 1>> - <br>Solid Slave Food Access: <strong><span id="snacks"><<if $slaves[_i].onDiet == 0>>Free to stuff $himself.<<else>>On a strict diet.<</if>></span></strong> - <<link "No access">><<set $slaves[_i].onDiet = 1>><<replace "#snacks">>On a strict diet.<</replace>><</link>> | - <<link "Full access">><<set $slaves[_i].onDiet = 0>><<replace "#snacks">>Free to stuff $himself.<</replace>><</link>> - <</if>> + <br>Diet Base: <strong><span id="dietBase"><<if $slaves[_i].dietCum == 2>>cum based<<elseif ($slaves[_i].dietCum == 1) && ($slaves[_i].dietMilk == 0)>>cum added<<elseif ($slaves[_i].dietCum == 1) && ($slaves[_i].dietMilk == 1)>>cum and milk added<<elseif ($slaves[_i].dietMilk == 1) && ($slaves[_i].dietCum == 0)>>milk added<<elseif ($slaves[_i].dietMilk == 2)>>milk based<<elseif ($slaves[_i].dietCum == 0) && ($slaves[_i].dietMilk == 0)>>normal<<else>>THERE HAS BEEN AN ERROR<</if>></span></strong>. + <<link "Normal">><<set $slaves[_i].dietCum = 0>><<set $slaves[_i].dietMilk = 0>><<replace "#dietBase">>normal<</replace>><</link>> | + <<link "Cum added">><<set $slaves[_i].dietCum = 1>><<set $slaves[_i].dietMilk = 0>><<replace "#dietBase">>cum added<</replace>><</link>> | + <<link "Milk added">><<set $slaves[_i].dietCum = 0>><<set $slaves[_i].dietMilk = 1>><<replace "#dietBase">>milk added<</replace>><</link>> | + <<link "Cum & milk added">><<set $slaves[_i].dietCum = 1>><<set $slaves[_i].dietMilk = 1>><<replace "#dietBase">>cum & milk added<</replace>><</link>> | + <<link "Cum based">><<set $slaves[_i].dietCum = 2>><<set $slaves[_i].dietMilk = 0>><<replace "#dietBase">>cum based<</replace>><</link>> | + <<link "Milk based">><<set $slaves[_i].dietCum = 0>><<set $slaves[_i].dietMilk = 2>><<replace "#dietBase">>milk based<</replace>><</link>> + + <<if $arcologies[0].FSHedonisticDecadenceResearch == 1>> + <br>Solid Slave Food Access: <strong><span id="snacks"><<if $slaves[_i].onDiet == 0>>Free to stuff $himself.<<else>>On a strict diet.<</if>></span></strong> + <<link "No access">><<set $slaves[_i].onDiet = 1>><<replace "#snacks">>On a strict diet.<</replace>><</link>> | + <<link "Full access">><<set $slaves[_i].onDiet = 0>><<replace "#snacks">>Free to stuff $himself.<</replace>><</link>> + <</if>> + </p> </div> </div> diff --git a/src/utility/descriptionWidgetsFlesh.tw b/src/utility/descriptionWidgetsFlesh.tw index 5c3c355a379924d9ebeca5c33ef7168ab3c63959..6ce426619ddb34aa968cc58d2c60b606d212fff8 100644 --- a/src/utility/descriptionWidgetsFlesh.tw +++ b/src/utility/descriptionWidgetsFlesh.tw @@ -4445,7 +4445,7 @@ $His <<if $showBodyMods == 1>> <<if $activeSlave.fuckdoll == 0>> - <<makeupDescription>> + <<= App.Desc.makeup($activeSlave)>> <</if>> <</if>> diff --git a/src/utility/descriptionWidgetsStyle.tw b/src/utility/descriptionWidgetsStyle.tw index a74e002f31814a1aeef86f2e0f94de4aad5ab058..f97c6f8a936603b6ac22e59da80da1f5b9695ec3 100644 --- a/src/utility/descriptionWidgetsStyle.tw +++ b/src/utility/descriptionWidgetsStyle.tw @@ -3585,56 +3585,6 @@ $His <</widget>> -<<widget "nailsDescription">> - <<if !hasAnyArms($activeSlave)>> - $He has no hands, and thus, no nails. - <<elseif $activeSlave.nails == 1>> - $His nails are long and elegant. - <<elseif $activeSlave.nails == 2>> - $His nails are color-coordinated with $his $activeSlave.hColor hair. - <<elseif $activeSlave.nails == 3>> - $His nails are sharp and claw-like. - <<elseif $activeSlave.nails == 4>> - $His nails are bright and glittery. - <<elseif $activeSlave.nails == 5>> - $His nails are long and garish, streetwalker-style. - <<elseif $activeSlave.nails == 6>> - $His nails are vivid and eye-catching. - <<elseif $activeSlave.nails == 7>> - $His nails are vivid, eye-catching and color-coordinated with $his $activeSlave.hColor hair. - <<elseif $activeSlave.nails == 8>> - $His nails are shiny and metallic. - <<elseif $activeSlave.nails == 9>> - $His nails are shiny, metallic and color-coordinated with $his $activeSlave.hColor hair. - <<else>> - $His nails are neatly clipped. - <</if>> -<</widget>> - -<<widget "makeupDescription">> - <<if $activeSlave.makeup == 1>> - $He's wearing minimal makeup. - <<elseif $activeSlave.makeup == 2>> - $He's wearing expensive, luxurious makeup. - <<elseif $activeSlave.makeup == 3>> - $His makeup is color-coordinated with $his $activeSlave.hColor hair. - <<elseif $activeSlave.makeup == 4>> - $He's wearing stereotypical, garish streetwalker makeup. - <<elseif $activeSlave.makeup == 5>> - $He's wearing eye-catching neon makeup. - <<elseif $activeSlave.makeup == 6>> - $His neon makeup is color-coordinated with $his $activeSlave.hColor hair. - <<elseif $activeSlave.makeup == 7>> - $He's wearing expensive, metallic makeup. - <<elseif $activeSlave.makeup == 8>> - $His metallic makeup is color-coordinated with $his $activeSlave.hColor hair. - <<elseif $activeSlave.lipsTat == "permanent makeup">> - $His face appears to bear very heavy, slutty makeup, but on closer inspection, the makeup is actually tattooed on. - <<else>> - $His face is makeup-free. - <</if>> -<</widget>> - <<widget "upperFaceDescription">> <<if $activeSlave.fuckdoll == 0>> <<switch $activeSlave.clothes>>