diff --git a/src/js/assayJS.js b/src/js/assayJS.js deleted file mode 100644 index 0d8e416e5db1124c9301a7c85c7c8188d24f3f31..0000000000000000000000000000000000000000 --- a/src/js/assayJS.js +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @param {App.Entity.SlaveState[]} [slaves] - * @returns {Object.<number, number>} - */ -globalThis.slaves2indices = function(slaves = V.slaves) { - return slaves.reduce((acc, slave, i) => { acc[slave.ID] = i; return acc; }, {}); -}; - -/** - * @param {number} ID - * @returns {App.Entity.SlaveState} - */ -globalThis.getSlave = function(ID) { - const index = V.slaveIndices[ID]; - return index === undefined ? undefined : V.slaves[index]; -}; - -/** - * @param {number} ID - * @returns {App.Entity.SlaveState} - */ -globalThis.slaveStateById = function(ID) { - const index = V.slaveIndices[ID]; - return index === undefined ? null : V.slaves[index]; -}; - -globalThis.getChild = function(ID) { - return V.cribs.find(s => s.ID === ID); -}; - -globalThis.SlaveSort = function() { - const effectivePreg = (slave) => { - // slave.preg is only *mostly* usable for sorting - if (slave.preg > 0 && !slave.pregKnown) { - // don't reveal unknown pregnancies - return 0; - } - if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - // not ovulating yet - sort between barren slaves and slaves on contraceptives - return -1.2; - } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { - // menopausal - sort between barren slaves and slaves on contraceptives - return -1.1; - } else if (slave.pregWeek < 0) { - // postpartum - sort between slaves on contraceptives and fertile slaves - return -0.1; - } - return slave.preg; - }; - - const effectiveEnergy = (slave) => { - return slave.attrKnown === 1 ? slave.energy : -101; - }; - - const comparators = { - Aassignment: (a, b) => a.assignment < b.assignment ? -1 : 1, - Dassignment: (a, b) => a.assignment > b.assignment ? -1 : 1, - Aname: (a, b) => a.slaveName < b.slaveName ? -1 : 1, - Dname: (a, b) => a.slaveName > b.slaveName ? -1 : 1, - Aseniority: (a, b) => b.weekAcquired - a.weekAcquired, - Dseniority: (a, b) => a.weekAcquired - b.weekAcquired, - AactualAge: (a, b) => a.actualAge - b.actualAge, - DactualAge: (a, b) => b.actualAge - a.actualAge, - AvisualAge: (a, b) => a.visualAge - b.visualAge, - DvisualAge: (a, b) => b.visualAge - a.visualAge, - AphysicalAge: (a, b) => a.physicalAge - b.physicalAge, - DphysicalAge: (a, b) => b.physicalAge - a.physicalAge, - Adevotion: (a, b) => a.devotion - b.devotion, - Ddevotion: (a, b) => b.devotion - a.devotion, - AID: (a, b) => a.ID - b.ID, - DID: (a, b) => b.ID - a.ID, - AweeklyIncome: (a, b) => a.lastWeeksCashIncome - b.lastWeeksCashIncome, - DweeklyIncome: (a, b) => b.lastWeeksCashIncome - a.lastWeeksCashIncome, - Ahealth: (a, b) => a.health.health - b.health.health, - Dhealth: (a, b) => b.health.health - a.health.health, - Aweight: (a, b) => a.weight - b.weight, - Dweight: (a, b) => b.weight - a.weight, - Amuscles: (a, b) => a.muscles - b.muscles, - Dmuscles: (a, b) => b.muscles - a.muscles, - AsexDrive: (a, b) => effectiveEnergy(a) - effectiveEnergy(b), - DsexDrive: (a, b) => effectiveEnergy(b) - effectiveEnergy(a), - Apregnancy: (a, b) => effectivePreg(a) - effectivePreg(b), - Dpregnancy: (a, b) => effectivePreg(b) - effectivePreg(a), - }; - - return { - slaves: sortSlaves, - IDs: sortIDs, - indices: sortIndices - }; - - /** @param {App.Entity.SlaveState[]} [slaves] */ - function sortSlaves(slaves) { - slaves = slaves || V.slaves; - slaves.sort(_comparator()); - if (slaves === V.slaves) { - V.slaveIndices = slaves2indices(); - } - } - - /** @param {number[]} [slaveIDs] */ - function sortIDs(slaveIDs) { - const slaves = V.slaves; - const slaveIndices = V.slaveIndices; - const cmp = _comparator(); - slaveIDs = slaveIDs || slaves.map(s => s.ID); - slaveIDs.sort((IDa, IDb) => cmp(slaves[slaveIndices[IDa]], slaves[slaveIndices[IDb]])); - } - - /** @param {number[]} [slaveIdxs] */ - function sortIndices(slaveIdxs) { - const slaves = V.slaves; - const cmp = _comparator(); - slaveIdxs = slaveIdxs || [...slaves.keys()]; - slaveIdxs.sort((ia, ib) => cmp(slaves[ia], slaves[ib])); - } - - /** - * @callback slaveComparator - * @param {App.Entity.SlaveState} a - * @param {App.Entity.SlaveState} b - * @returns {number} - */ - /** @returns {slaveComparator} */ - function _comparator() { - 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); - }; - } -}(); - -/** - * @param {App.Entity.SlaveState[]} slaves - */ -globalThis.slaveSortMinor = function(slaves) { - slaves.sort((a, b) => a.slaveName < b.slaveName ? -1 : 1); -}; - -globalThis.menialPopCap = function() { - let r = ""; - - let popCap = 500 * (1 + V.building.findCells(cell => cell instanceof App.Arcology.Cell.Manufacturing && cell.type === "Pens").length); - - let overMenialCap = V.menials + V.fuckdolls + V.menialBioreactors - popCap; - if (overMenialCap > 0) { - const price = menialSlaveCost(-overMenialCap); - if (V.menials > 0) { - if (V.menials > overMenialCap) { - cashX((overMenialCap * price), "menialTrades"); - V.menialDemandFactor -= overMenialCap; - V.menials -= overMenialCap; - overMenialCap = 0; - r += "You don't have enough room for all your menials and are obliged to sell some."; - } else { - cashX((V.menials * price), "menialTrades"); - V.menialDemandFactor -= V.menials; - overMenialCap -= V.menials; - V.menials = 0; - r += "You don't have enough room for your menials and are obliged to sell them."; - } - } - if (overMenialCap > 0 && V.fuckdolls > 0) { - if (V.fuckdolls > overMenialCap) { - cashX(overMenialCap * (price * 2), "menialTrades"); - V.menialDemandFactor -= overMenialCap; - V.fuckdolls -= overMenialCap; - overMenialCap = 0; - r += "You don't have enough room for all your Fuckdolls and are obliged to sell some."; - } else { - cashX(V.fuckdolls * (price * 2), "menialTrades"); - V.menialDemandFactor -= V.fuckdolls; - overMenialCap -= V.fuckdolls; - V.fuckdolls = 0; - r += "You don't have enough room for your Fuckdolls and are obliged to sell them."; - } - } - if (overMenialCap > 0 && V.menialBioreactors > 0) { - cashX(overMenialCap * (price - 100), "menialTrades"); - V.menialDemandFactor -= overMenialCap; - V.menialBioreactors -= overMenialCap; - r += "You don't have enough room for all your menial bioreactors and are obliged to sell some."; - } - } - return {text: r, value: popCap}; -}; - -globalThis.initRules = function() { - const rule = emptyDefaultRule(); - rule.name = "Obedient Slaves"; - rule.condition.function = "between"; - rule.condition.data.attribute = "devotion"; - rule.condition.data.value = [20, null]; - rule.set.removalAssignment = "rest"; - - V.defaultRules = [rule]; - V.rulesToApplyOnce = {}; -}; diff --git a/src/js/utilsFC.js b/src/js/utilsFC.js index a0e1a9eccc68e9fd125bed479dda7aa44c8856c3..59ed3ac912bb4d544253d6a78bf53cbed248abdb 100644 --- a/src/js/utilsFC.js +++ b/src/js/utilsFC.js @@ -306,3 +306,209 @@ App.Utils.alphabetizeIterable = function(iterable) { const clonedArray = (Array.from(iterable)); return clonedArray.sort(compare); }; + +/** + * @param {App.Entity.SlaveState[]} [slaves] + * @returns {Object.<number, number>} + */ +globalThis.slaves2indices = function(slaves = V.slaves) { + return slaves.reduce((acc, slave, i) => { acc[slave.ID] = i; return acc; }, {}); +}; + +/** + * @param {number} ID + * @returns {App.Entity.SlaveState} + */ +globalThis.getSlave = function(ID) { + const index = V.slaveIndices[ID]; + return index === undefined ? undefined : V.slaves[index]; +}; + +/** + * @param {number} ID + * @returns {App.Entity.SlaveState} + */ +globalThis.slaveStateById = function(ID) { + const index = V.slaveIndices[ID]; + return index === undefined ? null : V.slaves[index]; +}; + +globalThis.getChild = function(ID) { + return V.cribs.find(s => s.ID === ID); +}; + +globalThis.SlaveSort = function() { + const effectivePreg = (slave) => { + // slave.preg is only *mostly* usable for sorting + if (slave.preg > 0 && !slave.pregKnown) { + // don't reveal unknown pregnancies + return 0; + } + if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { + // not ovulating yet - sort between barren slaves and slaves on contraceptives + return -1.2; + } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { + // menopausal - sort between barren slaves and slaves on contraceptives + return -1.1; + } else if (slave.pregWeek < 0) { + // postpartum - sort between slaves on contraceptives and fertile slaves + return -0.1; + } + return slave.preg; + }; + + const effectiveEnergy = (slave) => { + return slave.attrKnown === 1 ? slave.energy : -101; + }; + + const comparators = { + Aassignment: (a, b) => a.assignment < b.assignment ? -1 : 1, + Dassignment: (a, b) => a.assignment > b.assignment ? -1 : 1, + Aname: (a, b) => a.slaveName < b.slaveName ? -1 : 1, + Dname: (a, b) => a.slaveName > b.slaveName ? -1 : 1, + Aseniority: (a, b) => b.weekAcquired - a.weekAcquired, + Dseniority: (a, b) => a.weekAcquired - b.weekAcquired, + AactualAge: (a, b) => a.actualAge - b.actualAge, + DactualAge: (a, b) => b.actualAge - a.actualAge, + AvisualAge: (a, b) => a.visualAge - b.visualAge, + DvisualAge: (a, b) => b.visualAge - a.visualAge, + AphysicalAge: (a, b) => a.physicalAge - b.physicalAge, + DphysicalAge: (a, b) => b.physicalAge - a.physicalAge, + Adevotion: (a, b) => a.devotion - b.devotion, + Ddevotion: (a, b) => b.devotion - a.devotion, + AID: (a, b) => a.ID - b.ID, + DID: (a, b) => b.ID - a.ID, + AweeklyIncome: (a, b) => a.lastWeeksCashIncome - b.lastWeeksCashIncome, + DweeklyIncome: (a, b) => b.lastWeeksCashIncome - a.lastWeeksCashIncome, + Ahealth: (a, b) => a.health.health - b.health.health, + Dhealth: (a, b) => b.health.health - a.health.health, + Aweight: (a, b) => a.weight - b.weight, + Dweight: (a, b) => b.weight - a.weight, + Amuscles: (a, b) => a.muscles - b.muscles, + Dmuscles: (a, b) => b.muscles - a.muscles, + AsexDrive: (a, b) => effectiveEnergy(a) - effectiveEnergy(b), + DsexDrive: (a, b) => effectiveEnergy(b) - effectiveEnergy(a), + Apregnancy: (a, b) => effectivePreg(a) - effectivePreg(b), + Dpregnancy: (a, b) => effectivePreg(b) - effectivePreg(a), + }; + + return { + slaves: sortSlaves, + IDs: sortIDs, + indices: sortIndices + }; + + /** @param {App.Entity.SlaveState[]} [slaves] */ + function sortSlaves(slaves) { + slaves = slaves || V.slaves; + slaves.sort(_comparator()); + if (slaves === V.slaves) { + V.slaveIndices = slaves2indices(); + } + } + + /** @param {number[]} [slaveIDs] */ + function sortIDs(slaveIDs) { + const slaves = V.slaves; + const slaveIndices = V.slaveIndices; + const cmp = _comparator(); + slaveIDs = slaveIDs || slaves.map(s => s.ID); + slaveIDs.sort((IDa, IDb) => cmp(slaves[slaveIndices[IDa]], slaves[slaveIndices[IDb]])); + } + + /** @param {number[]} [slaveIdxs] */ + function sortIndices(slaveIdxs) { + const slaves = V.slaves; + const cmp = _comparator(); + slaveIdxs = slaveIdxs || [...slaves.keys()]; + slaveIdxs.sort((ia, ib) => cmp(slaves[ia], slaves[ib])); + } + + /** + * @callback slaveComparator + * @param {App.Entity.SlaveState} a + * @param {App.Entity.SlaveState} b + * @returns {number} + */ + /** @returns {slaveComparator} */ + function _comparator() { + 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); + }; + } +}(); + +/** + * @param {App.Entity.SlaveState[]} slaves + */ +globalThis.slaveSortMinor = function(slaves) { + slaves.sort((a, b) => a.slaveName < b.slaveName ? -1 : 1); +}; + +globalThis.menialPopCap = function() { + let r = ""; + + let popCap = 500 * (1 + V.building.findCells(cell => cell instanceof App.Arcology.Cell.Manufacturing && cell.type === "Pens").length); + + let overMenialCap = V.menials + V.fuckdolls + V.menialBioreactors - popCap; + if (overMenialCap > 0) { + const price = menialSlaveCost(-overMenialCap); + if (V.menials > 0) { + if (V.menials > overMenialCap) { + cashX((overMenialCap * price), "menialTrades"); + V.menialDemandFactor -= overMenialCap; + V.menials -= overMenialCap; + overMenialCap = 0; + r += "You don't have enough room for all your menials and are obliged to sell some."; + } else { + cashX((V.menials * price), "menialTrades"); + V.menialDemandFactor -= V.menials; + overMenialCap -= V.menials; + V.menials = 0; + r += "You don't have enough room for your menials and are obliged to sell them."; + } + } + if (overMenialCap > 0 && V.fuckdolls > 0) { + if (V.fuckdolls > overMenialCap) { + cashX(overMenialCap * (price * 2), "menialTrades"); + V.menialDemandFactor -= overMenialCap; + V.fuckdolls -= overMenialCap; + overMenialCap = 0; + r += "You don't have enough room for all your Fuckdolls and are obliged to sell some."; + } else { + cashX(V.fuckdolls * (price * 2), "menialTrades"); + V.menialDemandFactor -= V.fuckdolls; + overMenialCap -= V.fuckdolls; + V.fuckdolls = 0; + r += "You don't have enough room for your Fuckdolls and are obliged to sell them."; + } + } + if (overMenialCap > 0 && V.menialBioreactors > 0) { + cashX(overMenialCap * (price - 100), "menialTrades"); + V.menialDemandFactor -= overMenialCap; + V.menialBioreactors -= overMenialCap; + r += "You don't have enough room for all your menial bioreactors and are obliged to sell some."; + } + } + return {text: r, value: popCap}; +}; + +globalThis.initRules = function() { + const rule = emptyDefaultRule(); + rule.name = "Obedient Slaves"; + rule.condition.function = "between"; + rule.condition.data.attribute = "devotion"; + rule.condition.data.value = [20, null]; + rule.set.removalAssignment = "rest"; + + V.defaultRules = [rule]; + V.rulesToApplyOnce = {}; +};