From 3c6a488a94328f8050cc01515947f39489d4637b Mon Sep 17 00:00:00 2001 From: Svornost <11434-svornost@users.noreply.gitgud.io> Date: Mon, 20 Jan 2020 01:48:15 -0800 Subject: [PATCH] Begin work on data-driven porn system. saPorn.js now has all the logic to replace saPorn.tw in 1/6 the space and several orders of magnitude faster. Just need to add all the genre data to porn.js, delete saPorn.tw, clean up some other spots (like slaveInteract), and make sure everything works. --- src/endWeek/saPorn.js | 477 +++++++++++++++++++++++++++++++++--------- src/js/porn.js | 36 ++++ 2 files changed, 413 insertions(+), 100 deletions(-) create mode 100644 src/js/porn.js diff --git a/src/endWeek/saPorn.js b/src/endWeek/saPorn.js index 93ab5aa36c5..d988e704800 100644 --- a/src/endWeek/saPorn.js +++ b/src/endWeek/saPorn.js @@ -1,116 +1,393 @@ -/* to later be rolled into saPorn */ +window.saPorn = (function saPorn() { + "use strict"; -/** - * @param {App.Entity.SlaveState} slave - * @returns {object} - */ -window.getHighestPorn = function(slave) { - let max = {value: 0, type: "none"}; + let r; + let he, him, his, hers, himself, girl, loli, He, His; + let decayRate; + let viewership; - if (slave.porn.fame.general > max.value) { - max = {value: slave.porn.fame.general, type: "generic"}; - } - if (slave.porn.fame.fuckdoll > max.value) { - max = {value: slave.porn.fame.fuckdoll, type: "fuckdoll"}; - } - if (slave.porn.fame.rape > max.value) { - max = {value: slave.porn.fame.rape, type: "rape"}; - } - if (slave.porn.fame.preggo > max.value) { - max = {value: slave.porn.fame.preggo, type: "preggo"}; - } - if (slave.porn.fame.BBW > max.value) { - max = {value: slave.porn.fame.BBW, type: "BBW"}; - } - if (slave.porn.fame.gainer > max.value) { - max = {value: slave.porn.fame.gainer, type: "weight gain"}; - } - if (slave.porn.fame.stud > max.value) { - max = {value: slave.porn.fame.stud, type: "big dick"}; - } - if (slave.porn.fame.loli > max.value) { - max = {value: slave.porn.fame.loli, type: "underage"}; - } - if (slave.porn.fame.deepThroat > max.value) { - max = {value: slave.porn.fame.deepThroat, type: "deepthroat"}; - } - if (slave.porn.fame.struggleFuck > max.value) { - max = {value: slave.porn.fame.struggleFuck, type: "unwilling"}; - } - if (slave.porn.fame.painal > max.value) { - max = {value: slave.porn.fame.painal, type: "hardcore anal"}; - } - if (slave.porn.fame.tease > max.value) { - max = {value: slave.porn.fame.tease, type: "softcore"}; - } - if (slave.porn.fame.romantic > max.value) { - max = {value: slave.porn.fame.romantic, type: "romantic"}; - } - if (slave.porn.fame.pervert > max.value) { - max = {value: slave.porn.fame.pervert, type: "really perverted"}; - } - if (slave.porn.fame.caring > max.value) { - max = {value: slave.porn.fame.caring, type: "voyeur"}; - } - if (slave.porn.fame.unflinching > max.value) { - max = {value: slave.porn.fame.unflinching, type: "unspeakable"}; - } - if (slave.porn.fame.sizeQueen > max.value) { - max = {value: slave.porn.fame.sizeQueen, type: "huge insertion"}; - } - if (slave.porn.fame.neglectful > max.value) { - max = {value: slave.porn.fame.neglectful, type: "orgasm denial"}; - } - if (slave.porn.fame.cumAddict > max.value) { - max = {value: slave.porn.fame.cumAddict, type: "cum addiction"}; - } - if (slave.porn.fame.analAddict > max.value) { - max = {value: slave.porn.fame.analAddict, type: "anal addiction"}; - } - if (slave.porn.fame.attentionWhore > max.value) { - max = {value: slave.porn.fame.attentionWhore, type: "exhibition"}; - } - if (slave.porn.fame.breastGrowth > max.value) { - max = {value: slave.porn.fame.breastGrowth, type: "breast expansion"}; - } - if (slave.porn.fame.abusive > max.value) { - max = {value: slave.porn.fame.abusive, type: "abuse"}; - } - if (slave.porn.fame.malicious > max.value) { - max = {value: slave.porn.fame.malicious, type: "sexual torture"}; + return saPorn; + + function saPorn(slave) { + ({ + he, him, his, hers, himself, girl, He, His, loli + } = getPronouns(slave)); + + let oldFame = slave.porn.viewerCount; + + if (V.studio === 1 && slave.porn.feed === 1) { + calcBaseViewership(slave); + + r += `The studio regularly releases clips of ${his} daily affairs. `; + if (V.cheatMode === 1) { + r += `(Decay: ${decayRate} Viewership: ${viewership} Last week's fame: ${oldFame}) `; + } + + prestigeCommentary(slave); + faceCommentary(slave); + hack(); + + genreViews(slave); + updateViewerCount(slave); + if (oldFame > slave.porn.viewerCount) { + r += `Overall, ${his} online fame <span class="red">dropped</span> this week. `; + } else if (oldFame < slave.porn.viewerCount) { + r += `Overall, ${his} online fame <span class="green">rose</span> this week. `; + if (oldFame < 100 && slave.porn.viewerCount >= 100 && V.studioFeed === 1) { + r += `${He} <span class="yellow">has accrued enough views to determine prospective porn genres.</span> `; + } + } else if (slave.porn.viewerCount !== 0) { + r += `Surprisingly, ${his} online fame <span class="yellow">remained consistent</span> this week despite how fickle watchers can be. `; + } else { + r += `${He} went <span class="red">completely overlooked</span> this week and failed to gain any hits at all. `; + } + + if (slave.porn.viewerCount > 0) { + let donations = Math.floor(slave.porn.viewerCount / jsRandom(10, 15 + viewerSoaking)); + if (donations > 0) { + r += `Fans donated a total of <span class="cash inc">${cashFormat(donations)}</span> to ${his} account this week. `; + cashX(donations, "porn", slave); + } + } + if (slave.porn.spending > 0) { + cashX(forceNeg(slave.porn.spending / V.PCSlutContacts), "porn", slave); + } + + prestigeGen(slave); + } else { /* popularity decay from lack of new content */ + if (slave.porn.prestige > 1) { // 500k + decayRate = 5000; + } else if (slave.porn.prestige > 0) { // 10k + decayRate = 500; + } else { + decayRate = 30; + } + + genreDecay(slave); + updateViewerCount(slave); + + prestigeDecay(slave); + } + + return r; } - if (slave.porn.fame.selfHating > max.value) { - max = {value: slave.porn.fame.selfHating, type: "self hating"}; + + function genreDecay(slave) { + for (let genre of App.Porn.getAllGenres()) { + if (slave.porn.fame[genre.fameName] > 0) { + const oldPorn = slave.porn.fame[genre.fameName]; + slave.porn.fame[genre.fameName] = Math.clamp(slave.porn.fame[genre.fameName] - (decayRate * 2), 0, 100000); + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameName]); + } + } } - if (slave.porn.fame.breeder > max.value) { - max = {value: slave.porn.fame.breeder, type: "breeder"}; + + function updateViewerCount(slave) { + slave.porn.viewerCount = Math.trunc(App.Porn.getAllGenres().reduce((acc, cur) => acc + slave.porn.fame[cur.fameVar])); } - if (slave.porn.fame.sub > max.value) { - max = {value: slave.porn.fame.sub, type: "submissive"}; + + function prestigeDecay(slave) { + if (slave.porn.prestige > 0) { + const genre = App.Porn.getGenreByFameName(slave.porn.fameType); + if (slave.porn.fame[genre.fameName] < 40000 && slave.porn.prestige === 2) { + slave.porn.prestige = 1; + slave.porn.prestigeDesc = `$He has a following in slave pornography. ${genre.prestigeDesc1}.`; + r +=`With the lack of any new content, <span class="red">${his} popularity in ${slave.porn.fameType} pornography has dropped considerably,</span> though some viewers still cling to the hope that ${he}'ll come back. `; + } else if (slave.porn.fame[genre.fameName] < 5000) { + slave.porn.prestige = 0; + slave.porn.prestigeDesc = 0; + slave.porn.fameType = "none"; + r += `With no new ${slave.porn.fameType} content coming out, <span class="red">${his} popularity has faded away.</span> `; + } + } } - if (slave.porn.fame.cumSlut > max.value) { - max = {value: slave.porn.fame.cumSlut, type: "cum"}; + + function calcBaseViewership(slave) { + let face; + + if (slave.porn.prestige > 1) { + decayRate = 5000; + if (slave.fuckdoll > 0) { + face = 50; + } else if (slave.collar === "porcelain mask") { + face = 20; + } else { + face = slave.face * 4; + } + viewership = ((500/V.HackingSkillMultiplier)+(slave.porn.spending)+(face)+(slave.prestige*10)-(decayRate)); + } else if (slave.porn.prestige > 0) { + decayRate = 500; + if (slave.fuckdoll > 0) { + face = 20; + } else if (slave.collar === "porcelain mask") { + face = 50; + } else { + face = slave.face * 2; + } + viewership = ((900/V.HackingSkillMultiplier)+(slave.porn.spending/15)+(face)+(slave.prestige*250)-(decayRate)); + } else { + decayRate = 30; + if (slave.fuckdoll > 0) { + face = 0; + } else if (slave.collar === "porcelain mask") { + face = 0; + } else { + face = slave.face / 20; + } + viewership = ((300/V.HackingSkillMultiplier)+(slave.porn.spending > 0 ? 1.01*slave.porn.spending : 200)+(face)+(slave.prestige*20)-(decayRate)); + } + viewership = Math.trunc(viewership); } - if (slave.porn.fame.anal > max.value) { - max = {value: slave.porn.fame.anal, type: "buttslut"}; + + function prestigeCommentary(slave) { + if (slave.porn.prestige > 1) { + r += `${He} is widely regarded in ${slave.porn.fameType} porn, but with so many watchers, turn over is high. `; + } else if (slave.porn.prestige > 0) { + if (slave.porn.fameType === "generic") { + r += `${He} has claimed a niche in slave porn, so there is a constant cycle of new arrivals and bored ex-watchers. `; + } else { + r += `${He} has claimed a niche for ${himself} in ${slave.porn.fameType} porn, so there is a constant cycle of new arrivals and bored ex-watchers. `; + } + } else { + r += `${He} is borderline unknown, so $he tends to hold onto the few watchers ${he} has. `; + } + + if (slave.prestige > 1) { + r += `Interest in porn of ${him} is very high, since ${he}'s already quite prestigious. `; + } else if (slave.prestige > 0) { + r += `Interest in porn of ${him} is high, since ${he}'s already prestigious. `; + } } - if (slave.porn.fame.humiliation > max.value) { - max = {value: slave.porn.fame.humiliation, type: "humiliating"}; + + function faceCommentary(slave) { + if (slave.fuckdoll > 0) { + return; + } else if (slave.collar === "porcelain mask") { + r += `${His} mask adds an air of mystery to $him, `; + if (slave.porn.prestige > 1) { + r += `but people wonder if $he is trying to hide something. `; + } else if (slave.porn.prestige > 0) { + r += `tantalizing viewers with what it hides. `; + } else { + r += `but viewers are more interested in ${his} body. `; + } + } else if (slave.face > 95) { + r += `${His} unbelievably beautiful face seizes the attention of all who see it. `; + } else if (slave.face > 40) { + r += `${His} gorgeous face draws viewers in and keeps them watching. `; + } else if (slave.face > 10) { + r += `${His} pretty face draws viewers in. `; + } else if (slave.face > 0) { + r += `${His} face is attractive, but it attracts few viewers. `; + } else if (slave.face === 0) { + r += `${His} face is completely average and makes no difference to ${his} viewers. `; + } else if (slave.face >= -10) { + r += `${His} face, while attractive, is so average it turns off some viewers. `; + } else if (slave.face >= -40) { + r += `${His} unattractive face causes viewers to move on. `; + } else if (slave.face >= -95) { + r += `${His} ugly face drives viewers off. `; + } else { + r += `${His} face chases off all but the most desperate viewers. `; + } } - if (slave.porn.fame.boobs > max.value) { - max = {value: slave.porn.fame.boobs, type: "breast"}; + + function hack() { + if (V.PC.skill.hacking > 10) { + r += `With your hacking skills, you manage to tweak search algorithms to display ${his} content more often. `; + } else if (V.PC.skill.hacking < 0) { + r += `With your lack of skill with computers you manage to misidentify ${his} content, complicating searches. `; + IncreasePCSkills('hacking', 0.1); + } + IncreasePCSkills('hacking', 0.1); } - if (slave.porn.fame.dom > max.value) { - max = {value: slave.porn.fame.dom, type: "dominant"}; + + function viewershipDelta(newPorn, oldPorn) { + if (newPorn > oldPorn) { + return `Viewership <span class="green">increased</span> this week. `; + } else if (newPorn < oldPorn) { + return `Viewership <span class="red">decreased</span> this week. `; + } else { + return `Viewership <span class="yellow">was stable</span> this week. `; + } } - if (slave.porn.fame.sadist > max.value) { - max = {value: slave.porn.fame.sadist, type: "sadistic"}; + + function cheatDelta(name, oldPorn, newPorn) { + if (V.cheatMode === 1) { + return `(${name}: ${oldPorn} to ${newPorn}). `; + } + return ``; } - if (slave.porn.fame.masochist > max.value) { - max = {value: slave.porn.fame.masochist, type: "masochistic"}; + + function genreViews(slave) { + let viewerSoaking = 1; + let adjustedViewership = viewership; + + /* Paraphilias have the highest take of viewers */ + for (let genre of App.Porn.getGenresByType('paraphilia')) { + const oldPorn = slave.porn.fame[genre.fameVar]; + if (genre.valid(slave)) { + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + adjustedViewership = viewership * 1.5; + } else if (slave.porn.focus !== "none") { + adjustedViewership = viewership * 0.5; + } + slave.porn.fame[genre.fameVar] += adjustedViewership + slave.fetishStrength*2 - ((decayRate/10)*(V.pornStars[genre.fameVar].p1count-1)); + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar], 0, 150000); + viewerSoaking++; + + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + r += `${hitText} `; + r += viewershipDelta(slave.porn.fame[genre.fameVar], oldPorn); + } + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } else if (slave.porn.fame[genre.fameVar] > 0) { + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar] - decayRate*2, 0, 150000); + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } + } + + /* Fetishes */ + for (let genre of App.Porn.getGenresByType('fetish')) { + const oldPorn = slave.porn.fame[genre.fameVar]; + if (genre.valid(slave)) { + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + adjustedViewership = viewership * 2.0; + } else if (slave.porn.focus !== "none") { + adjustedViewership = viewership * 0.5; + } + slave.porn.fame[genre.fameVar] += adjustedViewership/viewerSoaking + slave.fetishStrength - ((decayRate/10)*(V.pornStars[genre.fameVar].p1count-1)); + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar], 0, 150000); + viewerSoaking++; + + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + r += `${hitText} `; + r += viewershipDelta(slave.porn.fame[genre.fameVar], oldPorn); + } + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } else if (slave.porn.fame[genre.fameVar] > 0) { + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar] - decayRate*2, 0, 150000); + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } + } + + /* General */ + for (let genre of App.Porn.getGenresByType('general')) { + const oldPorn = slave.porn.fame[genre.fameVar]; + if (genre.valid(slave)) { + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + adjustedViewership = viewership * 4.0; + } else if (slave.porn.focus !== "none") { + adjustedViewership = viewership * 0.5; + } + slave.porn.fame[genre.fameVar] += adjustedViewership/viewerSoaking - ((decayRate/10)*(V.pornStars[genre.fameVar].p1count-1)); + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar], 0, 150000); + viewerSoaking++; + + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + r += `${hitText} `; + r += viewershipDelta(slave.porn.fame[genre.fameVar], oldPorn); + } + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } else if (slave.porn.fame[genre.fameVar] > 0) { + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar] - decayRate*2, 0, 150000); + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } + } + + /* Quirks are low and unlikely, requiring focus to push into the limelight */ + for (let genre of App.Porn.getGenresByType('quirk')) { + const oldPorn = slave.porn.fame[genre.fameVar]; + if (genre.valid(slave)) { + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + adjustedViewership = viewership * 6.0; + } else if (slave.porn.focus !== "none") { + adjustedViewership = viewership * 0.5; + } + slave.porn.fame[genre.fameVar] += adjustedViewership/viewerSoaking - ((decayRate/10)*(V.pornStars[genre.fameVar].p1count-1)); + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar], 0, 150000); + + if (slave.porn.focus === genre.focusName || slave.porn.fameType === genre.fameName) { + r += `${hitText} `; + r += viewershipDelta(slave.porn.fame[genre.fameVar], oldPorn); + } + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } else if (slave.porn.fame[genre.fameVar] > 0) { + slave.porn.fame[genre.fameVar] = Math.clamp(slave.porn.fame[genre.fameVar] - decayRate*2, 0, 150000); + r += cheatDelta(genre.uiName(), oldPorn, slave.porn.fame[genre.fameVar]); + } + } } - if (slave.porn.fame.pregnancy > max.value) { - max = {value: slave.porn.fame.pregnancy, type: "pregnancy fetish"}; + + function prestigeGen(slave) { + const highestPorn = getHighestPorn(slave); + if (slave.porn.prestige === 0 && slave.porn.viewerCount >= 100000) { + const pornFameGrabBag = App.Porn.getAllGenres().filter((g) => slave.porn.fame[g.fameVar] >= 10000); + if (pornFameGrabBag.length > 0) { + const genre = pornFameGrabBag.pluck(); + slave.porn.fameType = genre.fameName; + slave.porn.prestige = 1; + + r += `<span style="green">${He} has gained a following in ${slave.porn.fameType} pornography!</span> ${genre.prestigeDesc1}, but he isn't famous enough to be called presigious yet. `; + slave.porn.prestigeDesc = `$He has a following in slave pornography. ${genre.prestigeDesc1}.`; + if (genre.type === "fetish" && slave.fetishKnown !== 1) { + slave.fetishKnown = 1; + } + } + } else if (slave.porn.prestige === 1) { + const swapPoint = 1.2; + const genre = App.Porn.getGenreByFameName(slave.porn.fameType); + if (slave.porn.fame[genre.fameVar] >= 50000) { + slave.porn.prestige = 2; + slave.porn.prestigeDesc = `$He is well known from $his career in slave pornography. ${genre.prestigeDesc2}.`; + r += `<span class="green">${He} has gained a hold in ${slave.porn.fameType} pornography!</span> ${genre.prestigeDesc2}, so it is now prestigious to own ${him}. `; + } else if (highestPorn.value >= slave.porn.fame[genre.fameVar] * swapPoint) { + r += `${His} fame in ${slave.porn.fameType} pornography has been overwhelmed by $his surging popularity in other aspects. <span class="yellow">${He} is now better known for ${his} ${highestPorn.type} porn.</span> `; + const newGenre = App.Porn.getGenreByFameName(highestPorn.type); + slave.porn.fameType = newGenre.fameName; + slave.porn.prestigeDesc = `$He has a following in slave pornography. ${newGenre.prestigeDesc1}.`; + if (newGenre.type === "fetish" && slave.fetishKnown !== 1) { + slave.fetishKnown = 1; + } + } else if (slave.porn.fame[genre.fameVar] < 5000) { + slave.porn.prestige = 0; + slave.porn.prestigeDesc = 0; + r += `<span class="red">${His} popularity in ${slave.porn.fameType} pornography has faded.</span> ${He} is once again relatively unknown. `; + slave.porn.fameType = "none"; + } + } else if (slave.porn.prestige === 2) { + const genre = App.Porn.getGenreByFameName(slave.porn.fameType); + if (slave.porn.fame[genre.fameVar] >= 150000 && V.pornStars[genre.fameVar].p3ID === 0) { + slave.porn.prestige = 3; + slave.porn.fame[genre.fameVar] = 250000; + slave.porn.viewerCount = 250000; + V.pornStars[genre.fameVar].p3ID = slave.ID; + slave.porn.prestigeDesc = `$He is world famous for $his career in slave pornography. ${genre.prestigeDesc3}.`; + r += `<span class="green">${He} has become world famous for ${his} career in ${slave.porn.fameType} pornography!</span> ${genre.prestigeDesc3}, so it is now extremely presitigious to own ${him}. `; + V.trinkets.push(`a framed shot from porn starring ${slave.slaveName} ${genre.trinketShotDesc}`); + + r += `Further paid publicity cannot increase ${his} fame, so subsidy of porn featuring ${him} has stopped. `; + slave.porn.spending = 0; + } else if (slave.porn.fame[genre.fameVar] < 40000) { + slave.porn.prestige = 1; + slave.porn.prestigeDesc = `$He has a following in slave pornography. ${genre.prestigeDesc1}.`; + r += `<span class="red">${His} popularity in ${slave.porn.fameType} pornography has dropped considerably,</span> though ${he} still retains a core fanbase. `; + } + } + } +})(); + +/** + * @param {App.Entity.SlaveState} slave + * @returns {object} + */ +window.getHighestPorn = function(slave) { + let max = {value: 0, type: "none"}; + + for (const genre of App.Porn.getAllGenres()) { + if (slave.porn.fame[genre.fameVar] > max.value) { + max = {value: slave.porn.fame[genre.fameVar], type: genre.fameName}; + } } return max; diff --git a/src/js/porn.js b/src/js/porn.js new file mode 100644 index 00000000000..a08723cd1f2 --- /dev/null +++ b/src/js/porn.js @@ -0,0 +1,36 @@ +App.Porn = {}; +App.Porn.Genre = {}; + +App.Porn.Genre.cumAddict = { + fameVar: "cumAddict", + fameName: "cum addiction", + focusName: "cum addict", + hitText: "$His complete obsession with cum makes $him a hit with viewers that enjoy bukkake and cum drinking.", + type: "paraphilia", /* paraphilia, fetish, general, quirk */ + prestigeDesc1: "Thousands have enjoyed watching $him do anything and everything for cum", + prestigeDesc2: "$His many fans relish the sight of $him doing anything for cum", + prestigeDesc3: "Millions are intimately familiar with the sight of $him doing anything for cum", + trinketShotDesc: "showing $him bathing in a tub of cum", + valid: function(slave) { return slave.sexualFlaw === "cum addict"; }, + uiName: function() { return capFirstChar(this.focusName); } + + /* TODO: need pornstarvar too (probably reorg pornstar stuff to $pornStar[fameVar].p2count/p3ID */ + /* TODO: hit up updateSlaveObject with the porn-prestige description reset stuff */ + /* TODO: hit up slaveInteract too */ +}; + +App.Porn.getGenreByFameName = function(fameName) { + return App.Porn.Genre.values().find((g) => g.fameName === fameName); +}; + +App.Porn.getGenreByFocusName = function(focusName) { + return App.Porn.Genre.values().find((g) => g.focusName === focusName); +}; + +App.Porn.getAllGenres = function() { + return App.Porn.Genre.values(); +}; + +App.Porn.getGenresByType = function(type) { + return App.Porn.Genre.values().filter((g) => g.type === type); +}; -- GitLab