JavaScript must be enabled to play.
Browser lacks capabilities required to play.
Upgrade or switch to another browser.
Loading…
<<set $player = { name: "Alex", money: 15000, reputation: 1, day: 1 }>> <<set $archetype = "">> <<set $charismaticSatBonus = 0>> <<set $studioName = "Thunder Agency">> <<set $shootingPlayedToday = false>> <<set $allPositions = [ { name: "BJ", price: 0, repMin: 0, unlocked: true, level: 1, minSat: 0 }, { name: "Missionary", price: 500, repMin: 10, unlocked: false, level: 2, minSat: 10 }, { name: "Doggy", price: 800, repMin: 20, unlocked: false, level: 3, minSat: 20 }, { name: "Cowgirl", price: 1200, repMin: 30, unlocked: false, level: 4, minSat: 30 }, { name: "Reverse Cowgirl",price: 1500, repMin: 40, unlocked: false, level: 5, minSat: 40 }, { name: "Spooning", price: 2000, repMin: 50, unlocked: false, level: 6, minSat: 50, comingSoon: true }, { name: "69", price: 2500, repMin: 60, unlocked: false, level: 7, minSat: 60, comingSoon: true }, { name: "Standing Up", price: 3000, repMin: 70, unlocked: false, level: 8, minSat: 70, comingSoon: true }, { name: "DP", price: 4000, repMin: 80, unlocked: false, level: 9, minSat: 80, comingSoon: true } ]>> <<set $playerPositions = ["BJ"]>> <<set $adItem = { name: "AD", price: 3000, repMin: 0, bought: false, repBonus: 7, buyCount: 0 }>> <<set $doublePositionItem = { name: "Double Feature", price: 5000, repMin: 50, bought: false }>> <<set $marketStudyItem = { name: "Market Study", price: 4000, repMin: 25, bought: false }>> <<set $pool1UpgradeItem = { name: "Established Dip", price: 2500, repMin: 5, bought: false }>> <<set $pool1Upgrade2A = { name: "Established Surge", price: 5000, repMin: 0, bought: false }>> <<set $pool1Upgrade2B = { name: "Double Scouting", price: 5000, repMin: 10, bought: false }>> <<set $pool1Upgrade2C = { name: "Triple Scouting", price: 5000, repMin: 0, bought: false }>> <<set $pool1Upgrade2D = { name: "Quadruple Scouting", price: 5000, repMin: 0, bought: false }>> <<set $targetedScoutItem = { name: "Targeted Scout", price: 500, bought: false }>> <<set $targetedScoutStar = "">> <<set $pool2UpgradeItem = { name: "Elite Dip", price: 6000, repMin: 20, bought: false }>> <<set $pool1IntelItem = { name: "Pool 1 Intel", price: 500, bought: false }>> <<set $pool2IntelItem = { name: "Pool 2 Intel", price: 500, bought: false }>> <<set $pool3IntelItem = { name: "Pool 3 Intel", price: 500, bought: false }>> <<set $pool2Upgrade2 = { name: "Elite Surge", price: 10000, repMin: 30, bought: false }>> <<set $satisfactionDelayItem = { name: "Patience Training", price: 3500, repMin: 50, bought: false }>> <<set $poolBeginner = []>> <<set $poolConfirmed = []>> <<set $poolElite = []>> <<set $poolSpecial = null>> <<set $bonusEventStar = "">> <<set $rivalStartStar = "">> <<set $bnoEventDone = false>> <<set $day18EventDone = false>> <<set $day30EventDone = false>> <<set $rivalVideoPrefix = "">> <<set $rivalOriginalName = "">> <<set $pool2Stolen = false>> <<set $drawResult = []>> <<set $drawLuckyNames = []>> <<set $drawEliteNames = []>> <<set $drawPool = "">> <<set $drawSignName = "">> <<set $drawCount = 1>> <<set $drawCost = 200>> /* popularity = initial stat, grows with productions weekly upkeep = popularity * 70 $ repMin scales with popularity */ <<set $recruitPool = [ { name: "Octavia", favPosition: "Spooning", bonusPosition1: "Doggy", bonusPosition2: "BJ", bonusChosen: false, contractCost: 3000, popularity: 5, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Blonde", height: "Medium", ageNum: 28, ageCat: "Neutral",breast: "Large", breastType: "Real", ethnicity: "Caucasian" }, { name: "Summers", favPosition: "Cowgirl", bonusPosition1: "Missionary", bonusPosition2: "Spooning", bonusChosen: false, contractCost: 2500, popularity: 4, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Black", height: "Medium", ageNum: 42, ageCat: "Veteran",breast: "Small", breastType: "Real", ethnicity: "Caucasian" }, { name: "Kira", favPosition: "69", bonusPosition1: "Doggy", bonusPosition2: "Missionary", bonusChosen: false, contractCost: 2000, popularity: 3, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Brown", height: "Short", ageNum: 25, ageCat: "Neutral",breast: "Medium", breastType: "Real", ethnicity: "Latina" }, { name: "Ava", favPosition: "69", bonusPosition1: "Standing Up", bonusPosition2: "Reverse Cowgirl",bonusChosen: false, contractCost: 4000, popularity: 8, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 10, hair: "Brown", height: "Medium", ageNum: 40, ageCat: "Veteran",breast: "Huge", breastType: "Fake", ethnicity: "Caucasian" }, { name: "Brittney", favPosition: "Doggy", bonusPosition1: "Standing Up", bonusPosition2: "BJ", bonusChosen: false, contractCost: 3500, popularity: 6, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 10, hair: "Black", height: "Short", ageNum: 20, ageCat: "Young", breast: "Huge", breastType: "Real", ethnicity: "Black" }, { name: "Jada", favPosition: "Doggy", bonusPosition1: "Reverse Cowgirl", bonusPosition2: "69", bonusChosen: false, contractCost: 30000, popularity: 30, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Black", height: "Medium", ageNum: 28, ageCat: "Neutral", breast: "Large", breastType: "Fake", ethnicity: "Black" }, { name: "Gabbie", favPosition: "Standing Up", bonusPosition1: "Missionary", bonusPosition2: "Cowgirl", bonusChosen: false, contractCost: 3500, popularity: 9, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: false, repMin: 999, hair: "Blonde", height: "Medium", ageNum: 20, ageCat: "Young", breast: "Large", breastType: "Real", ethnicity: "Caucasian" }, { name: "Sharon", favPosition: "Spooning", bonusPosition1: "Cowgirl", bonusPosition2: "69", bonusChosen: false, contractCost: 6000, popularity: 12, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 12, hair: "Brown", height: "Medium", ageNum: 29, ageCat: "Neutral",breast: "Large", breastType: "Real", ethnicity: "Asian" }, { name: "Sirena", favPosition: "DP", bonusPosition1: "Reverse Cowgirl",bonusPosition2: "Spooning", bonusChosen: false, contractCost: 7000, popularity: 15, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 15, hair: "Brown", height: "Short", ageNum: 30, ageCat: "Neutral",breast: "Medium", breastType: "Fake", ethnicity: "Latina" }, { name: "Lena", favPosition: "Spooning", bonusPosition1: "Cowgirl", bonusPosition2: "Standing Up", bonusChosen: false, contractCost: 9000, popularity: 20, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 20, hair: "Blonde", height: "Medium", ageNum: 26, ageCat: "Neutral",breast: "Huge", breastType: "Real", ethnicity: "Caucasian" }, { name: "Eliza", favPosition: "Reverse Cowgirl", bonusPosition1: "69", bonusPosition2: "DP", bonusChosen: false, contractCost: 8000, popularity: 18, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 18, hair: "Black", height: "Tall", ageNum: 28, ageCat: "Neutral",breast: "Medium", breastType: "Real", ethnicity: "Latina" }, { name: "Angela", favPosition: "DP", bonusPosition1: "69", bonusPosition2: "Doggy", bonusChosen: false, contractCost: 15000, popularity: 30, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 30, hair: "Brown", height: "Medium", ageNum: 36, ageCat: "Veteran",breast: "Huge", breastType: "Real", ethnicity: "Caucasian" }, { name: "Skylar", favPosition: "DP", bonusPosition1: "Spooning", bonusPosition2: "Reverse Cowgirl",bonusChosen: false, contractCost: 20000, popularity: 40, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 40, hair: "Blonde", height: "Medium", ageNum: 27, ageCat: "Neutral",breast: "Huge", breastType: "Real", ethnicity: "Caucasian" }, { name: "Lulu", favPosition: "DP", bonusPosition1: "Reverse Cowgirl", bonusPosition2: "Spooning", bonusChosen: false, contractCost: 25000, popularity: 25, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Black", height: "Short", ageNum: 22, ageCat: "Young", breast: "Small", breastType: "Real", ethnicity: "Asian" }, { name: "Alina", favPosition: "69", bonusPosition1: "DP",bonusPosition2: "Doggy", bonusChosen: false, contractCost: 28000, popularity: 27, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Black", height: "Medium", ageNum: 29, ageCat: "Neutral", breast: "Small", breastType: "Real", ethnicity: "Latina" }, { name: "Caprice", favPosition: "Reverse Cowgirl", bonusPosition1: "Cowgirl", bonusPosition2: "69", bonusChosen: false, contractCost: 22000, popularity: 26, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Brown", height: "Short", ageNum: 21, ageCat: "Young", breast: "Small", breastType: "Real", ethnicity: "Caucasian" }, { name: "Valentina", favPosition: "BJ", bonusPosition1: "Missionary", bonusPosition2: "Standing Up", bonusChosen: false, contractCost: 30000, popularity: 30, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Brown", height: "Medium", ageNum: 29, ageCat: "Neutral", breast: "Medium", breastType: "Real", ethnicity: "Caucasian" }, { name: "Kimmy", favPosition: "Spooning", bonusPosition1: "69", bonusPosition2: "Standing Up", bonusChosen: false, contractCost: 24000, popularity: 25, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Black", height: "Short", ageNum: 29, ageCat: "Neutral", breast: "Small", breastType: "Real", ethnicity: "Asian" }, { name: "Vicky", favPosition: "Standing Up", bonusPosition1: "DP",bonusPosition2: "BJ", bonusChosen: false, contractCost: 32000, popularity: 28, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Blonde", height: "Medium", ageNum: 35, ageCat: "Veteran", breast: "Huge", breastType: "Fake", ethnicity: "Caucasian" }, { name: "Blake", favPosition: "BJ", bonusPosition1: "Cowgirl", bonusPosition2: "Missionary", bonusChosen: false, contractCost: 5000, popularity: 10, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Blonde", height: "Tall", ageNum: 27, ageCat: "Neutral", breast: "Large", breastType: "Real", ethnicity: "Caucasian" }, { name: "Angie", favPosition: "Missionary", bonusPosition1: "BJ", bonusPosition2: "Cowgirl", bonusChosen: false, contractCost: 4500, popularity: 8, satisfaction: 12, weekShootings: 0, lastShootingDay: 0, consecutiveDays: 0, restDay: false, lowSatAlerted: false, available: true, repMin: 0, hair: "Brown", height: "Medium", ageNum: 24, ageCat: "Neutral", breast: "Medium", breastType: "Real", ethnicity: "Caucasian" } ]>> <<set $roster = []>> <<set $rival = { name: "Iron Studio", money: 60000, reputation: 8, roster: [] }>> <<set $trends = { position: "", carType: "", carValue: "", carType2: "", carValue2: "", bonusRep: 0 }>> <<set $shootingC1 = -1>> <<set $shootingC2 = -1>> <<set $advancedFormat = false>> <<set $selectedPositions = []>> <<set $positionToAdd = "">> <<set $shootingLastPosition = "">> <<set $shootingW1File = "">> <<set $shootingW2File = "">> <<set $positionIndex = 0>> <<set $recruitIndex = 0>> <<set $poachMessage = "">> <<set $poachVideoStar = "">> <<set $rosterMessage = "">> <<set $zeroSatStar = "">> <<set $rivalFirstPick = "">> <<set $rivalLastShooting = null>> <<set $popularityAlert = "">> <<set $lastPopGain = []>> <<set $bonusChoiceStar = "">> <<set $roxyEventTriggered = false>> <<set $roxyTriggerStar = "">> <<set $contract1 = { active: false, accepted: false, criteria: "", criteriaType: "", options: [], shootingsDone: 0, startDay: -1, failed: false }>> <<set $contractShopAvailable = false>> <<set $trophies = { fullHouse: false, empire: false, dealMaker: false, harderDeal: false, asianDuoComplete: false, fallenAngelsComplete: false, firstMillion: false, brokeBurBack: false, firstPoach: false, poachMaster: false }>> <<set $totalContractsCompleted = 0>> <<set $totalEarnings = 0>> <<set $newTrophy = "">> <<set $poachingInvestments = {}>> <<set $poachAttempts = {}>> <<set $totalPoachingSteps = 0>> <<set $lastPoachStepDay = -1>> <<set $lastPoachDay = -1>> <<set $totalPoachesSucceeded = 0>> <<set $rivalAggression = 0>> <<set $rivalSabotageStar = "">> <<set $poachingUnlocked = false>> <<set $contractShopPrice = 200>> <<set $contractShopAvailableDay = -1>> <<set $contract3rdOptionItem = { name: "3rd Option", price: 500, bought: false }>> <<set $contractHarderItem = { name: "Harder Contract", price: 1500, bought: false }>> <<set $contractIsHarder = false>> <<set $contract1.criteria2 = "">> <<set $contract1.criteriaType2 = "">> <<set $contract3 = { active: false, accepted: false, shootingsDone: 0, startDay: -1, failed: false, starName: "" }>> <<set $contract3Success = false>> <<set $contract4 = { active: false, accepted: false, star1: "", star2: "", shootingsDone: 0, failed: false }>> <<set $contract4Success = false>> <<set $asianDuoLastShootingDay = -1>> <<set $asianDuoShoot1Day = -1>> <<set $asianDuoShoot2Unlocked = false>> <<set $fallenAngelsShoot1Day = -1>> <<set $fallenAngelsShoot2Day = -1>> <<set $fallenAngelsShoot2Unlocked = false>> <<set $fallenAngelsShoot3Unlocked = false>> <<set $asianDuoAbsentDay = -1>> <<set $asianDuoAbsentNotified = false>> <<set $asianDuoGoneDay = -1>> <<set $asianDuoGoneNotified = false>> <<set $asianDuoWebm2Day = -1>> <<set $asianDuoWebm3Day = -1>> <<set $fallenAngelsLastShootingDay = -1>> <<set $fallenAngelsAbsentDay = -1>> <<set $fallenAngelsAbsentNotified = false>> <<set $fallenAngelsGoneDay = -1>> <<set $fallenAngelsGoneNotified = false>> <<set $fallenAngelsWebm2Day = -1>> <<set $fallenAngelsWebm3Day = -1>> <<set $questlines = { asianDuo: { id: "asianDuo", name: "Asian Duo", active: false, step: 0, star1: "", star2: "", specialAvailable: false, shooting1Done: false, shooting2Done: false }, fallenAngels: { id: "fallenAngels", name: "Two Fallen Angels", active: false, step: 0, star1: "", star2: "", specialAvailable: false, shooting1Done: false, shooting2Done: false, shooting3Done: false } }>> <<set $contract1Success = false>> <<set $rivalOfferStar = "">> <<set $rivalOfferShootingsLeft = 0>> <<set $rivalOfferDeadlineDay = -1>> <<set $thirdRecruitDay = -1>> <<set $rivalPoachEvent = false>> <<set $rivalOfferStar = "">> <<set $rivalOfferIdx = -1>> <<set $rivalOfferChallenge = false>> <<set $rivalOfferShootingsDone = 0>> <<set $rivalOfferChallengeWon = false>> <<set $rep15EventDone = false>> <<set $rep15EventPending = false>> <<set $day22EventDone = false>> <<set $day25EventDone = false>> <<set $day22Idx = -1>> <<set $day22Pop = 0>> <<set $day22Price = 0>> <<set $objective1Done = false>> <<set $objective1Notified = false>> <<set $gameOver = false>> <<set $skillfulChallengeActive = false>> <<set $skillfulChallengeEndDay = -1>> <<set $skillfulChallengeWon = false>> <<set $vacationStar = "">> <<set $vacationEndDay = -1>> <<set $lastGain = 0>> <<set $lastRepBonus = 0>> <<set $lastMulti = 1.0>> <<set $lastPositionBonus = false>> <<set $lastCarBonus = "">> <<set $lastCarBonus2 = "">> <<set $allowedPositions = 1>> <<set $weeklyPaid = 0>> <<set $shopSortCol = "name">> <<set $recruitSortCol = "name">> <<set $rosterSortCol = "name">> <<set $profileIndex = 0>> <<set $advancedThreshold = 25>> /* ════════════════════════════════════════════ WIDGET : calcAllowedPositions ════════════════════════════════════════════ */ <<widget "calcAllowedPositions">> <<if $doublePositionItem.bought>> <<set $allowedPositions = 2>> <<else>> <<set $allowedPositions = 1>> <</if>> <</widget>> /* ════════════════════════════════════════════ WIDGET : genTrends ════════════════════════════════════════════ */ <<widget "genTrends">> <<set _weightedPositions = []>> <<for _pi = 0; _pi < $allPositions.length; _pi++>> <<set _pm = $allPositions[_pi]>> <<set _weight = Math.max(1, 6 - _pm.level)>> <<for _pw = 0; _pw < _weight; _pw++>> <<set _weightedPositions.push(_pm.name)>> <</for>> <</for>> <<set $trends.position = _weightedPositions[random(0, _weightedPositions.length - 1)]>> <<set _tPool = [ "hair:Brown","hair:Brown","hair:Blonde","hair:Blonde","hair:Black","hair:Black", "height:Short","height:Short","height:Tall","height:Tall", "ageCat:Young","ageCat:Young","ageCat:Veteran","ageCat:Veteran", "breast:Small","breast:Small","breast:Large","breast:Large","breast:Huge","breast:Huge", "breastType:Fake","breastType:Fake","breastType:Fake","breastType:Real", "ethnicity:Latina","ethnicity:Latina","ethnicity:Asian","ethnicity:Asian","ethnicity:Black","ethnicity:Caucasian" ]>> <<set _tPick = _tPool[random(0, _tPool.length - 1)]>> <<set $trends.carType = _tPick.split(":")[0]>> <<set $trends.carValue = _tPick.split(":")[1]>> <<set $trends.bonusRep = 1>> <<if $marketStudyItem.bought>> <<set _tPool2 = [ "hair:Brown","hair:Brown","hair:Blonde","hair:Blonde","hair:Black","hair:Black", "height:Short","height:Short","height:Tall","height:Tall", "ageCat:Young","ageCat:Young","ageCat:Veteran","ageCat:Veteran", "breast:Small","breast:Small","breast:Large","breast:Large","breast:Huge","breast:Huge", "breastType:Fake","breastType:Fake","breastType:Fake","breastType:Real", "ethnicity:Latina","ethnicity:Latina","ethnicity:Asian","ethnicity:Asian","ethnicity:Black","ethnicity:Caucasian" ]>> <<set _tPick2 = _tPool2[random(0, _tPool2.length - 1)]>> <<set $trends.carType2 = _tPick2.split(":")[0]>> <<set $trends.carValue2 = _tPick2.split(":")[1]>> <<else>> <<set $trends.carType2 = "">> <<set $trends.carValue2 = "">> <</if>> <</widget>> /* ════════════════════════════════════════════ WIDGET : checkRival ════════════════════════════════════════════ */ <<widget "checkRival">> <<set _sabotageChance = 10 + ($rivalAggression || 0)>> <<set $rivalSabotageStar = "">> <<set $rivalSabotageStolen = false>> <<if $poachingUnlocked && $roster.length > 0 && (random(1,100) <= _sabotageChance)>> <<set _weights = []>> <<for _wi = 0; _wi < $roster.length; _wi++>> <<set _w = Math.max(1, 110 - $roster[_wi].satisfaction)>> <<for _wj = 0; _wj < _w; _wj++>> <<set _weights.push(_wi)>> <</for>> <</for>> <<set _si = _weights[random(0, _weights.length - 1)]>> <<set $roster[_si].satisfaction = Math.max(0, $roster[_si].satisfaction - 10)>> <<set $rivalSabotageStar = $roster[_si].name>> <<if $roster[_si].satisfaction <= 5>> <<set $rival.roster.push(clone($roster[_si]))>> <<set $roster.deleteAt(_si)>> <<set $player.reputation = Math.max(0, $player.reputation - 2)>> <<set $rivalAggression = Math.max(0, ($rivalAggression || 0) - 4)>> <<set $rivalSabotageStolen = true>> <<if $player.day >= 30>> <<set $poachVideoStar = $rivalSabotageStar>> <</if>> <</if>> <</if>> <<for _i = $roster.length - 1; _i >= 0; _i-->> <<set _w = $roster[_i]>> <<if _w.satisfaction <= 0>> <<if true>> <<set $rival.roster.push(clone(_w))>> <<set $roster.deleteAt(_i)>> <<set $player.reputation = Math.max(0, $player.reputation - 2)>> <<if $player.day >= 30>> <<set $poachMessage = _w.name + " left your roster for " + $rival.name + " — went to find out if the grass is bigger on the other side. She already shot her first BJ scene with them.">> <<set $poachVideoStar = _w.name>> <<else>> <<set $poachMessage = _w.name + " left your roster for " + $rival.name + " — went to find out if the grass is bigger on the other side.">> <<set $poachVideoStar = "">> <</if>> <</if>> <</if>> <</for>> <</widget>> /* ════════════════════════════════════════════ WIDGET : resolveShooting _w1 _w2 _positions _adv Earnings = player rep × talent popularity × multiplier Multiplier: 1.0 base, +0.3 if trending position used, +0.3 if trending profile matches Two Shootings in a Day: average popularity of both talents ════════════════════════════════════════════ */ <<widget "resolveShooting" "_w1" "_w2" "_adv">> <<set $lastPositionBonus = false>> <<set $lastCarBonus = "">> <<set $lastCarBonus2 = "">> <<set $lastPopGain = []>> /* ── Genre trend → rep bonus ── */ <<if $selectedPositions.includes($trends.position)>> <<set $lastPositionBonus = true>> <</if>> /* ── Physical trend 1 → earnings multiplier ── */ <<set _ct = $trends.carType>> <<set _cv = $trends.carValue>> <<set _carShooting = false>> <<if _w1 && _w1[_ct] is _cv>> <<set _carShooting = true>> <<set $lastCarBonus = _w1.name>> <</if>> <<if _w2 && _w2[_ct] is _cv>> <<set _carShooting = true>> <<if $lastCarBonus>><<set $lastCarBonus += " & " + _w2.name>><<else>><<set $lastCarBonus = _w2.name>><</if>> <</if>> /* ── Physical trend 2 → earnings multiplier ── */ <<set _carShooting2 = false>> <<if $trends.carType2>> <<set _ct2 = $trends.carType2>> <<set _cv2 = $trends.carValue2>> <<if _w1 && _w1[_ct2] is _cv2>> <<set _carShooting2 = true>> <<set $lastCarBonus2 = _w1.name>> <</if>> <<if _w2 && _w2[_ct2] is _cv2>> <<set _carShooting2 = true>> <<if $lastCarBonus2>><<set $lastCarBonus2 += " & " + _w2.name>><<else>><<set $lastCarBonus2 = _w2.name>><</if>> <</if>> <</if>> /* ── Earnings multiplier: physical trends only ── */ <<set _physicalMatches = (_carShooting ? 1 : 0) + (_carShooting2 ? 1 : 0)>> <<if _physicalMatches is 2>> <<set _multi = 1.6>> <<elseif _physicalMatches is 1>> <<set _multi = 1.3>> <<else>> <<set _multi = 1.0>> <</if>> <<set $lastMulti = _multi>> <<if _adv && _w2>> <<set _avgPop = (_w1.popularity + _w2.popularity) / 2>> <<elseif _w1>> <<set _avgPop = _w1.popularity>> <<else>> <<set _avgPop = 1>> <</if>> <<set $lastGain = Math.round(($player.reputation * 5 + _avgPop * 50) * _multi)>> <<if $skillfulChallengeActive && $lastPositionBonus && $player.day <= $skillfulChallengeEndDay>> <<set $skillfulChallengeActive = false>> <<set $skillfulChallengeWon = true>> <</if>> /* Rival offer challenge tracking */ <<if $rivalOfferChallenge && $rivalOfferIdx >= 0>> <<if _w1 && _w1.name is $rivalOfferStar || (_w2 && _w2.name is $rivalOfferStar)>> <<set $rivalOfferShootingsDone += 1>> <<if $rivalOfferShootingsDone >= 3>> <<set $rivalOfferChallenge = false>> <<set $rivalOfferChallengeWon = true>> <<set $roster[$rivalOfferIdx].popularity += 1>> <<set $roster[$rivalOfferIdx].satisfaction = Math.min(100, $roster[$rivalOfferIdx].satisfaction + 10)>> <<set $rivalOfferIdx = -1>> <<set $rivalOfferStar = "">> <</if>> <</if>> <</if>> /* Rival offer challenge tracking */ <<if $rivalOfferShootingsLeft > 0>> <<set _os = _w1 && _w1.name is $rivalOfferStar ? _w1 : (_w2 && _w2.name is $rivalOfferStar ? _w2 : null)>> <<if _os>> <<set _os.consecutiveDays = 0>> <<set _os.restDay = false>> <</if>> <</if>> /* Contract 1 tracking — 2 shootings with matching stat within 3 days */ <<if $contract1.accepted && !$contract1.failed>> <<set _ct = $contract1.criteriaType>> <<set _cv = $contract1.criteria>> <<set _validStar = (_w1 && _w1[_ct] is _cv) || (_w2 && _w2[_ct] is _cv)>> <<if $contractIsHarder>><<set _ct2h = $contract1.criteriaType2>><<set _cv2h = $contract1.criteria2>><<set _validStar2h = (_w1 && _w1[_ct2h] is _cv2h) || (_w2 && _w2[_ct2h] is _cv2h)>><<set _validStar = _validStar && _validStar2h>><</if>> <<if _validStar>> <<set $contract1.shootingsDone += 1>> <<if $contract1.shootingsDone >= 2>> <<set $contract1.accepted = false>> <<set $contract1.active = false>> <<set $contract1Success = true>> <<set $totalContractsCompleted += 1>> <<if $contractIsHarder>> <<set $player.reputation += 5>> <<set $player.money += 1500>> <<if !$trophies.harderDeal>><<set $trophies.harderDeal = true>><<set $newTrophy = "🏆 Harder Deal — first harder contract completed!">><</if>> <<else>> <<set $player.reputation += 3>> <<set $player.money += 500>> <</if>> <<if !$trophies.dealMaker && $totalContractsCompleted >= 5>><<set $trophies.dealMaker = true>><<set $newTrophy = "🏆 Deal Maker — 5 contracts completed!">><</if>> <<set $contractShopAvailableDay = $player.day + 3>> <</if>> <</if>> <</if>> /* Contract 4 tracking — specific confirmed stars */ <<if $contract4.accepted && !$contract4.failed>> <<set _c4match = false>> <<set _c4star = null>> <<if _w1 && (_w1.name is $contract4.star1 || _w1.name is $contract4.star2)>><<set _c4match = true>><<set _c4star = _w1>><</if>> <<if !_c4match && _w2 && (_w2.name is $contract4.star1 || _w2.name is $contract4.star2)>><<set _c4match = true>><<set _c4star = _w2>><</if>> <<if _c4match>> <<set $contract4.shootingsDone += 1>> <<set $contract4.accepted = false>> <<set $contract4.active = false>> <<set $contract4Success = true>> <<set $player.money += 1000>> <</if>> <</if>> /* Contract 3 tracking — any Established (pool 2) star counts */ <<if $contract3.accepted && !$contract3.failed>> <<set _c3star = null>> <<if _w1 && $poolConfirmed.indexOf(_w1.name) >= 0>><<set _c3star = _w1>><</if>> <<if !_c3star && _w2 && $poolConfirmed.indexOf(_w2.name) >= 0>><<set _c3star = _w2>><</if>> <<if _c3star>> <<set $contract3.shootingsDone += 1>> <<set $contract3.accepted = false>> <<set $contract3.active = false>> <<set $contract3Success = true>> <<set _c3star.popularity += 2>> <<set $player.money += 500>> <<set $player.reputation += 1>> <<set $contract3.starName = _c3star.name>> <</if>> <</if>> /* ── Rep: +1 base, +2 extra if genre trending (total +3) ── */ <<set $lastRepBonus = 1>> <<if $lastPositionBonus>><<set $lastRepBonus = 3>><</if>> <<set $player.money += $lastGain>> <<set $player.reputation += $lastRepBonus>> <<for _m = 0; _m < $selectedPositions.length; _m++>> <<set _mn = $selectedPositions[_m]>> <<set _mvObj = $allPositions.find(function(m){ return m.name is _mn; })>> <<set _mvLevel = _mvObj ? _mvObj.level : 1>> <<if _w1>> <<if _mn is _w1.favPosition || (_w1.favPosition2 && _mn is _w1.favPosition2)>> <<set _w1.satisfaction = Math.min(100, _w1.satisfaction + Math.ceil(_mvLevel * 1.5))>> <<else>> <<set _w1.satisfaction = Math.min(100, _w1.satisfaction + _mvLevel)>> <</if>> <</if>> <<if _w2>> <<if _mn is _w2.favPosition || (_w2.favPosition2 && _mn is _w2.favPosition2)>> <<set _w2.satisfaction = Math.min(100, _w2.satisfaction + Math.ceil(_mvLevel * 1.5))>> <<else>> <<set _w2.satisfaction = Math.min(100, _w2.satisfaction + _mvLevel)>> <</if>> <</if>> <</for>> <<if _w1>> <<set _w1.weekShootings += 1>> <<set _w1.totalShootings = (_w1.totalShootings || 0) + ($lastPositionBonus ? 2 : 1)>> <<set _w1popBefore = _w1.popularity>> <<set _w1.popularity = _w1.popularity + ((_w1.totalShootings % 3 is 0) ? 1 : 0)>> <<if _w1.popularity > _w1popBefore>><<set $lastPopGain.push({ name: _w1.name, pop: _w1.popularity })>><</if>> <<if _w1.lastShootingDay is $player.day - 1>> <<set _w1.consecutiveDays += 1>> <<else>> <<set _w1.consecutiveDays = 1>> <</if>> <<set _w1.lastShootingDay = $player.day>> <<if _w1.consecutiveDays >= 2>><<set _w1.restDay = true>><<set _w1.restUntilDay = $player.day + 1>><</if>> <<if _w1.popularity is 50>><<set $popularityAlert = _w1.name>><</if>> <<if _w1.satisfaction >= 30 && !_w1.bonusChosen>><<set $bonusChoiceStar = _w1.name>><</if>> <<if _w1.satisfaction >= 25 && !$roxyEventTriggered>><<set $roxyEventTriggered = true>><<set $roxyTriggerStar = _w1.name>><</if>> <</if>> <<if _w2>> <<set _w2.weekShootings += 1>> <<set _w2.totalShootings = (_w2.totalShootings || 0) + ($lastPositionBonus ? 2 : 1)>> <<set _w2popBefore = _w2.popularity>> <<set _w2.popularity = _w2.popularity + ((_w2.totalShootings % 3 is 0) ? 1 : 0)>> <<if _w2.popularity > _w2popBefore>><<set $lastPopGain.push({ name: _w2.name, pop: _w2.popularity })>><</if>> <<if _w2.lastShootingDay is $player.day - 1>> <<set _w2.consecutiveDays += 1>> <<else>> <<set _w2.consecutiveDays = 1>> <</if>> <<set _w2.lastShootingDay = $player.day>> <<if _w2.consecutiveDays >= 2>><<set _w2.restDay = true>><<set _w2.restUntilDay = $player.day + 1>><</if>> <<if _w2.popularity is 50>><<set $popularityAlert = _w2.name>><</if>> <<if _w2.satisfaction >= 30 && !_w2.bonusChosen>><<set $bonusChoiceStar = _w2.name>><</if>> <<if _w2.satisfaction >= 25 && !$roxyEventTriggered>><<set $roxyEventTriggered = true>><<set $roxyTriggerStar = _w2.name>><</if>> <</if>> <</widget>> /* ════════════════════════════════════════════ PASSAGE : StoryStylesheet ════════════════════════════════════════════ */
<div id="sidebar-content" style="font-size:0.85em;line-height:1.4;"> <hr style="border-color:#333;margin:4px 0;"> <div style="text-align:center;font-size:2em;"><a href="https://patreon.com/hubbgames?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink" target="_blank">Patreon</a></div> <strong>📅 Day <<= $player.day>></strong> | 💰 💲<<= $player.money.toLocaleString()>> | 🌟 <<= $player.reputation>><br> 🎭 <<= $archetype ? $archetype.charAt(0).toUpperCase() + $archetype.slice(1) : "">> | 🎬 <<if $shootingPlayedToday>>@@color:red;Produced@@<<else>>@@color:green;Not produced@@<</if>><br> <<if $roster.length > 0>><<set _nextPayDay = 7 - ($player.day % 7)>><<set _upkeepTotal = 0>><<for _si = 0; _si < $roster.length; _si++>><<set _upkeepTotal += $roster[_si].popularity * 70>><</for>><<if _nextPayDay <= 3 && $player.money < _upkeepTotal>>@@color:red;⚠️ Upkeep: $<<= _upkeepTotal.toLocaleString()>> in <<= _nextPayDay>>d — LOW FUNDS!@@<<else>>💸 Upkeep: $<<= _upkeepTotal.toLocaleString()>> in <<= _nextPayDay>>d<</if>><br><</if>> <<if $skillfulChallengeActive>>@@color:gold;⚡ Trending position before day <<= $skillfulChallengeEndDay>>@@<br><</if>> <<if $rivalOfferShootingsLeft > 0>>@@color:orange;💬 <<= $rivalOfferStar>>: <<= $rivalOfferShootingsLeft>> shoots left, <<= Math.max(0, $rivalOfferDeadlineDay - $player.day)>>d remaining@@<br><</if>> <<if $contract1.accepted>>@@color:cyan;📋 <<= $contract1.criteria>> <<= $contract1.criteriaType>> (<<= $contract1.shootingsDone>>/2) — <<= Math.max(0, $contract1.startDay + 3 - $player.day)>>d left@@<br><</if>> <<if $contract3.accepted>>@@color:gold;📋 Established contract: shoot before day 40@@<br><</if>> <<if $contract4.accepted>>@@color:gold;📋 Investors: <<= $contract4.star1>><<if $contract4.star2>> or <<= $contract4.star2>><</if>> before day 50@@<br><</if>><<if $questlines.asianDuo.active>><<set _qlA = $questlines.asianDuo>><<if _qlA.step is 1>>@@color:cyan;🎌 Asian Duo: <<= _qlA.star1>> → 25 satis (<<= $roster.find(function(w){ return w.name is _qlA.star1; }) ? $roster.find(function(w){ return w.name is _qlA.star1; }).satisfaction : 0>>/25)@@<br><<elseif _qlA.step is 2>>@@color:cyan;🎌 Asian Duo: recruit <<= (_qlA.star1 is "Kimmy") ? "Lulu" : "Kimmy">>@@<br><<elseif _qlA.step is 3>>@@color:cyan;🎌 Asian Duo: <<= _qlA.star2>> → 25 satis (<<= $roster.find(function(w){ return w.name is _qlA.star2; }) ? $roster.find(function(w){ return w.name is _qlA.star2; }).satisfaction : 0>>/25)@@<br><</if>><<elseif $questlines.asianDuo.shooting2Done>><<if $asianDuoGoneDay > 0>>@@color:gold;🎌 Asian Duo: ✅@@<br><<else>>@@color:cyan;🎌 Asian Duo: story unfolding...@@<br><</if>><<elseif $questlines.asianDuo.shooting1Done>>@@color:cyan;🎌 Asian Duo: 2nd special available!@@<br><<elseif $questlines.asianDuo.specialAvailable>>@@color:gold;🎌 Asian Duo: 🌟 1st special available!@@<br><</if>><<if $questlines && $questlines.fallenAngels>><<if $questlines.fallenAngels.shooting3Done>><<if $fallenAngelsGoneDay > 0>>@@color:gold;👼 Angels: ✅@@<br><<else>>@@color:cyan;👼 Angels: unfolding...@@<br><</if>><<elseif $questlines.fallenAngels.shooting2Done>>@@color:cyan;👼 Angels: 3rd!@@<br><<elseif $questlines.fallenAngels.shooting1Done>>@@color:cyan;👼 Angels: 2nd!@@<br><<elseif $questlines.fallenAngels.specialAvailable>>@@color:gold;👼 Angels: 🌟@@<br><<elseif $questlines.fallenAngels.active>>@@color:cyan;👼 Angels: Step <<= $questlines.fallenAngels.step>>/6@@<br><</if>><</if>><<if !$objective1Done && $player.day >= 10>>@@color:orange;🎯 <<= $roster.length>>/3 talents before day 15@@<br><</if>> <details style="margin:4px 0;"> <summary style="cursor:pointer;font-weight:bold;list-style:none;display:flex;justify-content:center;gap:8px;text-align:center;">📈 Trends <span style="color:#555;font-size:0.85em;">▾</span></summary> <div style="margin-top:4px;"> <<if $trends.position>>🎭 <<= $trends.position>> | ✨ <<= $trends.carType>>: <<= $trends.carValue>><<if $trends.carType2>> | ✨ <<= $trends.carType2>>: <<= $trends.carValue2>><</if>><<else>><em>Not revealed yet</em><</if>> </div> </details> <details style="margin:4px 0;" open> <summary style="cursor:pointer;font-weight:bold;list-style:none;display:flex;justify-content:center;gap:8px;text-align:center;">📋 Roster (<<= $roster.length>>) <span style="color:#555;font-size:0.85em;">▾</span></summary> <div style="margin-top:1px;"> <<if $roster.length is 0>><em>Empty</em><<else>><<for _si = 0; _si < $roster.length; _si++>><<set _sw = $roster[_si]>><<= _sw.name>> 🌟<<= _sw.popularity>><<if _sw.restDay>> 😴<</if>> <<if _sw.satisfaction >= 100>>@@color:darkgreen;💕<<= _sw.satisfaction>>@@<<elseif _sw.satisfaction >= 65>>@@color:darkgreen;💗<<= _sw.satisfaction>>@@<<elseif _sw.satisfaction >= 40>>@@color:red;❤️<<= _sw.satisfaction>>@@<<elseif _sw.satisfaction >= 12>>@@color:orange;🧡<<= _sw.satisfaction>>@@<<elseif _sw.satisfaction >= 6>>@@color:#555;🖤<<= _sw.satisfaction>>@@<<else>>@@color:red;⚠️<<= _sw.satisfaction>>@@<</if>><br><</for>><</if>> </div> </details> <hr style="border-color:#333;margin:4px 0;"> <strong>🏆</strong> <<= $studioName>> 🌟<<= $player.reputation>> | <<= $rival.name>> 🌟<<= $rival.reputation>> <<if $poachingUnlocked>><br>😈 <<= $rival.name>> agressivity: <<= ($rivalAggression || 0).toFixed(2)>><</if>> </div> <<script>> jQuery(document).on(':passageinit', function(){ var states = {}; document.querySelectorAll('#ui-bar details').forEach(function(d, i){ states[i] = d.open; }); window._detailsState = states; }); jQuery(document).on(':passageend', function(){ var states = window._detailsState || {}; document.querySelectorAll('#ui-bar details').forEach(function(d, i){ if(states[i] !== undefined) d.open = states[i]; }); }); <</script>> /* ════════════════════════════════════════════ PASSAGE : StoryMenu ════════════════════════════════════════════ */
[[📊 Dashboard|Dashboard]] [[🛒 Shop|Shop]] [[👤 Recruit|Recruitment]] [[📜 Questlines|QuestlinesMenu]] [[🏆 Trophies|TrophiesMenu]] <<if $targetedScoutItem && $targetedScoutItem.bought>>[[🎯 Scout Target<<if $targetedScoutStar>>: <<= $targetedScoutStar>><</if>>|TargetedScoutMenu]]<</if>> <<script>> window.resolvePortraits = function(){ document.querySelectorAll('img[data-portrait-var]').forEach(function(img){ var varName = img.getAttribute('data-portrait-var'); // Remove leading underscore for SugarCube temporary variable lookup var key = varName.replace(/^_/, ''); try { var val = SugarCube.State.temporary[key] || ''; if(val) img.src = 'img/portraits/' + val + '.jpg'; } catch(e) {} }); }; window.zoomPortrait = function(src){ var ov = document.getElementById('portrait-overlay'); if(!ov){ ov = document.createElement('div'); ov.id = 'portrait-overlay'; ov.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.85);display:flex;align-items:center;justify-content:center;z-index:9999;cursor:zoom-out;'; ov.onclick = function(){ ov.remove(); }; document.body.appendChild(ov); } ov.innerHTML = '<img src="'+src+'" style="max-width:90vw;max-height:90vh;border-radius:12px;box-shadow:0 0 40px rgba(0,0,0,0.8);">'; }; jQuery(document).on(':passageend', function(){ if(window.resolvePortraits) window.resolvePortraits(); }); window.buildStarTable = function(roster, trends, excludeIdx, wrapperId, onSelect, emptyMsg, hideDecay){ var heightOrder = {Short:1,Medium:2,Tall:3}; var breastOrder = {Small:1,Medium:2,Large:3,Huge:4}; var currentSort = 'satisfaction'; var currentDay = SugarCube.State.variables.player ? SugarCube.State.variables.player.day : 0; function isTrendStat(w, key){ return (trends && trends.carType && key === trends.carType && w[key] === trends.carValue) || (trends && trends.carType2 && key === trends.carType2 && w[key] === trends.carValue2); } function isContractStat(w, key){ var sv2 = SugarCube.State.variables; var c1 = sv2.contract1; return c1 && c1.accepted && !c1.failed && key === c1.criteriaType && w[key] === c1.criteria; } function tdStat(w, key){ var val = w[key] || '—'; var style = ''; if(isTrendStat(w, key)) style = 'background:#3a3a00;color:gold;font-weight:bold;'; else if(isContractStat(w, key)) style = 'background:#002244;color:#4af;font-weight:bold;outline:1px solid #4af;'; var badge = isContractStat(w, key) ? ' 📋' : ''; return '<td style="'+style+'">'+val+badge+'</td>'; } var currentDay = SugarCube.State.variables.player ? SugarCube.State.variables.player.day : 0; function isTrendStat(w, statKey){ return (trends && trends.carType && statKey === trends.carType && w[statKey] === trends.carValue) || (trends && trends.carType2 && statKey === trends.carType2 && w[statKey] === trends.carValue2); } function isContractStat(w, statKey){ var sv2 = SugarCube.State.variables; var c1 = sv2.contract1; var c2 = sv2.contract2; var match1 = c1 && c1.accepted && !c1.failed && statKey === c1.criteriaType && w[statKey] === c1.criteria; var match2 = c2 && c2.accepted && !c2.failed && statKey === c2.criteriaType && w[statKey] === c2.criteria; return match1 || match2; } function tdStat(w, statKey){ var val = w[statKey] || '—'; var style = ''; if(isTrendStat(w, statKey)) style = 'background:#3a3a00;color:gold;font-weight:bold;'; else if(isContractStat(w, statKey)) style = 'background:#002244;color:#4af;font-weight:bold;outline:1px solid #4af;'; var badge = isContractStat(w, statKey) ? ' 📋' : ''; return '<td style="'+style+'">'+val+badge+'</td>'; } function buildTable(sortCol){ currentSort = sortCol; var rs = roster.slice(); rs.sort(function(a,b){ if(sortCol==='name') return a.name<b.name?-1:1; if(sortCol==='ageNum') return a.ageNum-b.ageNum; if(sortCol==='hair') return a.hair<b.hair?-1:1; if(sortCol==='height') return (heightOrder[a.height]||0)-(heightOrder[b.height]||0); if(sortCol==='breast') return (breastOrder[a.breast]||0)-(breastOrder[b.breast]||0); if(sortCol==='breastType') return a.breastType<b.breastType?-1:1; if(sortCol==='ethnicity') return (a.ethnicity||'').localeCompare(b.ethnicity||''); if(sortCol==='popularity') return b.popularity-a.popularity; if(sortCol==='satisfaction') return b.satisfaction-a.satisfaction; if(sortCol==='decay') return (a.lastShootingDay||0)-(b.lastShootingDay||0); return 0; }); var html = '<table class="recruit-table"><tr>'; html += '<th></th>'; var cols = hideDecay ? ['name','ageNum','hair','height','breast','breastType','ethnicity','popularity','satisfaction'] : ['name','ageNum','hair','height','breast','breastType','ethnicity','popularity','satisfaction','decay']; var labels = hideDecay ? ['Name ↕','Age ↕','Hair ↕','Height ↕','Tits ↕','Type ↕','Origin ↕','🌟 ↕','❤️ ↕'] : ['Name ↕','Age ↕','Hair ↕','Height ↕','Tits ↕','Type ↕','Origin ↕','🌟 ↕','❤️ ↕','⏳ ↕']; var showTier = !hideDecay; for(var c=0;c<cols.length;c++){ html += '<th data-col="'+cols[c]+'">'+labels[c]+'</th>'; } html += '</tr>'; var found = false; rs.forEach(function(w){ var origIdx = roster.indexOf(w); if(origIdx === excludeIdx) return; var file = w.name.toLowerCase().replace(/ /g,'_'); /* Absent questline stars */ var sv3 = SugarCube.State.variables; var absentStars = []; if(sv3.asianDuoAbsentDay > 0 && sv3.asianDuoGoneDay < 0){ absentStars.push('Kimmy'); absentStars.push('Lulu'); } if(sv3.fallenAngelsAbsentDay > 0 && sv3.fallenAngelsGoneDay < 0){ absentStars.push('Angie'); absentStars.push('Angela'); } var isAbsent = absentStars.indexOf(w.name) >= 0; var isResting = w.restDay || isAbsent; /* Contract match check */ var sv = SugarCube.State.variables; var matchesContract = false; if(sv.contract1 && sv.contract1.accepted && !sv.contract1.failed){ matchesContract = matchesContract || w[sv.contract1.criteriaType] === sv.contract1.criteria; } var nameExtra = isAbsent ? ' 🙅' : (isResting ? ' 😴' : ''); if(matchesContract) nameExtra += ' 📋'; var sat = w.satisfaction; var satColor = sat>=100?'darkgreen':sat>=65?'darkgreen':sat>=40?'red':sat>=12?'orange':sat>=6?'#555':'#222'; var satIcon = sat>=100?'💕':sat>=65?'💗':sat>=40?'❤️':sat>=12?'🧡':sat>=6?'🖤':'⚠️'; var daysSince = currentDay - (w.lastShootingDay || 0); var decayThreshold = SugarCube.State.variables.satisfactionDelayItem && SugarCube.State.variables.satisfactionDelayItem.bought ? 5 : 4; if(w.satisfaction > 40) decayThreshold += 1; var dbd = decayThreshold - daysSince; var dbdStr = isResting ? '😴' : (dbd <= 0 ? '🔴 now' : (dbd === 1 ? '⚠️ 1d' : dbd+'d')); var dbdStyle = dbd <= 0 ? 'color:red;font-weight:bold;' : (dbd === 1 ? 'color:orange;' : ''); var sv4 = SugarCube.State.variables; /* inPlayerRoster/inRivalRoster only relevant when viewing recruit pools (hideDecay=true) */ var inPlayerRoster = hideDecay && sv4.roster && sv4.roster.find(function(r){ return r.name === w.name; }); var inRivalRoster = hideDecay && sv4.rival && sv4.rival.roster && sv4.rival.roster.find(function(r){ return r.name === w.name; }); if(isResting || inPlayerRoster || inRivalRoster){ html += '<tr style="opacity:0.35;">'; if(inPlayerRoster) nameExtra += ' ✅'; else if(inRivalRoster) nameExtra += ' ❌'; } else { found = true; html += '<tr class="data-row" data-orig-idx="'+origIdx+'" style="cursor:pointer;">'; } html += '<td><img style="width:72px;height:72px;object-fit:cover;border-radius:6px;display:block;" src="img/portraits/'+file+'.jpg" alt="'+w.name+'"></td>'; /* Absent questline stars */ var sv3 = SugarCube.State.variables; var absentStars = []; if(sv3.asianDuoAbsentDay > 0 && sv3.asianDuoGoneDay < 0){ absentStars.push('Kimmy'); absentStars.push('Lulu'); } if(sv3.fallenAngelsAbsentDay > 0 && sv3.fallenAngelsGoneDay < 0){ absentStars.push('Angie'); absentStars.push('Angela'); } var isAbsent = absentStars.indexOf(w.name) >= 0; /* Pool tier */ var tierLabel = '⭐'; var sv2 = SugarCube.State.variables; if(sv2.poolElite && sv2.poolElite.indexOf(w.name) >= 0) tierLabel = '⭐⭐⭐'; else if(sv2.poolConfirmed && sv2.poolConfirmed.indexOf(w.name) >= 0) tierLabel = '⭐⭐'; html += '<td>'+w.name+nameExtra+' <span style="font-size:0.8em;opacity:0.7;">'+tierLabel+'</span></td>'; html += '<td>'+w.ageNum+'</td>'; html += tdStat(w,'hair'); html += tdStat(w,'height'); html += tdStat(w,'breast'); html += tdStat(w,'breastType'); html += tdStat(w,'ethnicity'); html += '<td>'+w.popularity+'</td>'; html += '<td><span style="color:'+satColor+'">'+satIcon+' '+sat+'</span></td>'; if(!hideDecay) html += '<td style="'+dbdStyle+'">'+dbdStr+'</td>'; html += '</tr>'; }); html += '</table>'; if(!found) html += '<p>'+emptyMsg+'</p>'; var wrap = document.getElementById(wrapperId); if(wrap){ wrap.innerHTML = html; wrap.querySelectorAll('th[data-col]').forEach(function(th){ th.style.cursor = 'pointer'; th.addEventListener('click', function(){ buildTable(this.getAttribute('data-col')); }); }); wrap.querySelectorAll('tr.data-row').forEach(function(row){ row.addEventListener('click', function(){ onSelect(parseInt(this.getAttribute('data-orig-idx'))); }); }); } } buildTable(currentSort); }; window.buildStarCards = function(stars, trends, containerId, onClick, luckyNames, showTrending){ if(!stars || stars.length === 0){ var el = document.getElementById(containerId); if(el) el.innerHTML = '<em>No talents to display.</em>'; return; } luckyNames = luckyNames || []; var eliteNames = (SugarCube.State.variables.drawEliteNames) || []; showTrending = showTrending !== false; var trendType = trends ? trends.carType : ''; var trendVal = trends ? trends.carValue : ''; var trendType2 = trends ? trends.carType2 : ''; var trendVal2 = trends ? trends.carValue2 : ''; var html = '\x3cdiv style="text-align:center;">'; stars.forEach(function(w, idx){ var file = w.name.toLowerCase().replace(/ /g,'_'); var isTrending = showTrending && ((trendType && w[trendType] === trendVal) || (trendType2 && w[trendType2] === trendVal2)); var isResting = w.restDay; var isElite = eliteNames.indexOf(w.name) >= 0; var isLucky = luckyNames.indexOf(w.name) >= 0; var sat = w.satisfaction; var satColor = sat>=100?'#4caf50':sat>=65?'#4caf50':sat>=40?'#e53935':sat>=12?'#ff9800':sat>=6?'#555':'#c62828'; var satIcon = sat>=100?'💕':sat>=65?'💗':sat>=40?'❤️':sat>=12?'🧡':sat>=6?'🖤':'⚠️'; var satPct = Math.min(100, sat) + '%'; var classes = 'star-card'; if(isElite) classes += ' lucky-gold'; else if(isLucky) classes += ' lucky-silver'; else if(isTrending) classes += ' trending'; if(isResting) classes += ' resting'; var clickAttr = onClick ? ' data-idx="'+idx+'" style="cursor:pointer;"' : ''; html += '<div class="'+classes+'"'+clickAttr+'>'; if(isResting) html += '<div class="badge">😴</div>'; if(isTrending && !isResting) html += '<div class="badge" style="background:rgba(255,215,0,0.85);color:#000;">🌟 Trending</div>'; html += '<img src="img/portraits/'+file+'.jpg" alt="'+w.name+'" style="cursor:zoom-in;" onclick="zoomPortrait(this.src)">'; html += '<div class="star-name">'+w.name+'</div>'; html += '\x3cdiv class="star-stats">'; html += w.ageNum+' y.o. | '+w.hair+' | '+w.height+'<br>'; html += w.breast+' ('+w.breastType+') | '+(w.ethnicity||'—')+'<br>'; html += '🌟 Pop: <b>'+w.popularity+'</b>'; if(w.favPosition) html += '<br>💖 Pos: '+w.favPosition + (w.favPosition2 ? ' & '+w.favPosition2 : ''); if(w.contractCost !== undefined) html += '<br>💳 $'+((SugarCube.State.variables.archetype==='charismatic')?Math.ceil(w.contractCost*0.9):w.contractCost).toLocaleString()+(SugarCube.State.variables.archetype==='charismatic'?' (-10%)':''); html += '\x3c/div>'; html += '<div style="margin-top:8px;color:'+satColor+';font-weight:bold;">'+satIcon+' '+sat+'</div>'; html += '<div class="sat-bar"><div class="sat-bar-fill" style="width:'+satPct+';background:'+satColor+';"></div></div>'; html += '\x3c/div>'; }); html += '\x3c/div>'; var wrap = document.getElementById(containerId); if(wrap){ wrap.innerHTML = html; if(onClick){ wrap.querySelectorAll('.star-card').forEach(function(card){ card.addEventListener('click', function(){ onClick(parseInt(this.getAttribute('data-idx'))); }); }); } } }; <</script>> /* ════════════════════════════════════════════ PASSAGE : Competition ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">🏴 <<= $rival.name>><<if $rivalVideoPrefix && $rivalOriginalName>> @@color:#888;<small>(formerly <<= $rivalOriginalName>>)</small>@@<</if>></h1> 🌟 Reputation: <<= $rival.reputation>> <b>Their roster:</b> <div id="rival-roster"></div> <div id="poach-buttons" style="margin-top:8px;"></div> <b>Their last production:</b> <div id="rival-last-shooting"></div> [[⬅️ Dashboard|Dashboard]] <<script>> jQuery(document).one(':passageend', function(){ var rival = SugarCube.State.variables.rival; var rivalLastShooting = SugarCube.State.variables.rivalLastShooting; var rosterEl = document.getElementById('rival-roster'); if(rosterEl){ if(rival.roster.length === 0){ rosterEl.innerHTML = '<em>'+rival.name+' has no talents yet.</em>'; } else { var html = '<div style="display:flex;flex-wrap:wrap;gap:12px;margin:10px 0;">'; rival.roster.forEach(function(w){ var file = w.name.toLowerCase().replace(/ /g,'_'); html += '<div style="text-align:center;">'; html += '<img src="img/portraits/'+file+'.jpg" style="width:80px;height:80px;object-fit:cover;border-radius:8px;display:block;">'; html += '<small>'+w.name+'</small></div>'; }); html += '\x3c/div>'; rosterEl.innerHTML = html; } } /* ── Poach buttons ── */ var poachWrap = document.getElementById('poach-buttons'); if(poachWrap){ if(!SugarCube.State.variables.poachingUnlocked){ poachWrap.innerHTML = '<em style="color:#555;font-size:0.85em;">Poaching will become available after a special event.</em>'; } else { var agg = SugarCube.State.variables.rivalAggression || 0; var aggColor = agg >= 5 ? '#ff7a7a' : (agg >= 2 ? '#ffcc44' : '#888'); var html = '<div style="font-size:0.8em;color:'+aggColor+';margin-bottom:6px;">😈 '+rival.name+' agressivity: '+agg.toFixed(2)+' <span style="color:#555;">(+'+(10+agg).toFixed(2)+'% daily sabotage chance)</span></div>'; var investments = SugarCube.State.variables.poachingInvestments || {}; rival.roster.forEach(function(w){ var steps = investments[w.name] || 0; var stepCosts = [500, 1000, 1500]; var attempts = (SugarCube.State.variables.poachAttempts || {})[w.name] || 0; var successPct = Math.round(((attempts + 1) / 4) * 100); html += '<div style="display:flex;align-items:center;gap:8px;margin:4px 0;padding:6px 10px;background:#0a0a1a;border-radius:6px;">'; html += '<b style="flex:1;font-size:0.9em;">'+w.name+'</b>'; if(steps < 3){ html += '<span style="font-size:0.78em;color:#888;">Approach: '+steps+'/3</span>'; } else { html += '<span style="font-size:0.78em;color:#888;">'+successPct+'% chance</span>'; } if(steps < 3){ var cost = stepCosts[steps]; var usedToday = (SugarCube.State.variables.lastPoachStepDay >= SugarCube.State.variables.player.day); if(usedToday){ html += '<span style="font-size:0.78em;color:#555;opacity:0.5;">Approach tomorrow</span>'; } else if(SugarCube.State.variables.player.money >= cost){ html += '<button class="poach-step-btn" data-name="'+w.name+'" data-cost="'+cost+'" data-step="'+steps+'" style="padding:3px 10px;background:#1a1a2e;border:1px solid #4a9eff;color:#4a9eff;border-radius:4px;cursor:pointer;font-size:0.8em;">Approach $'+cost.toLocaleString()+'</button>'; } else { html += '<span style="font-size:0.78em;color:#555;">$'+cost.toLocaleString()+' needed</span>'; } } if(steps === 3){ var poachUsedToday = (SugarCube.State.variables.lastPoachDay >= SugarCube.State.variables.player.day); if(poachUsedToday){ html += '<span style="font-size:0.78em;color:#555;opacity:0.5;">Poach tomorrow</span>'; } else if(SugarCube.State.variables.player.money >= 1500){ html += '<button class="poach-btn" data-name="'+w.name+'" data-steps="'+steps+'" style="padding:3px 10px;background:#1a1a2e;border:1px solid #cc4444;color:#cc4444;border-radius:4px;cursor:pointer;font-size:0.8em;">Poach $1,500</button>'; } else { html += '<span style="font-size:0.78em;color:#555;opacity:0.5;">Poach $1,500 — no funds</span>'; } } html += '</div>'; }); poachWrap.innerHTML = html; poachWrap.querySelectorAll('.poach-step-btn').forEach(function(btn){ btn.addEventListener('click', function(){ var name = this.getAttribute('data-name'); var cost = parseInt(this.getAttribute('data-cost')); var sv = SugarCube.State.variables; if(sv.player.money < cost) return; if(sv.lastPoachStepDay >= sv.player.day){ alert('You already invested in a poaching step today. Come back tomorrow.'); return; } sv.player.money -= cost; if(!sv.poachingInvestments) sv.poachingInvestments = {}; sv.poachingInvestments[name] = (sv.poachingInvestments[name] || 0) + 1; sv.totalPoachingSteps = (sv.totalPoachingSteps || 0) + 1; sv.lastPoachStepDay = sv.player.day; sv.rivalAggression = (sv.rivalAggression || 0) + 0.25; SugarCube.Engine.play('Competition'); }); }); poachWrap.querySelectorAll('.poach-btn').forEach(function(btn){ btn.addEventListener('click', function(){ var name = this.getAttribute('data-name'); var steps = parseInt(this.getAttribute('data-steps')); var sv = SugarCube.State.variables; if(steps < 3){ alert('You need to complete all 3 approach steps before poaching.'); return; } if(sv.player.money < 1500) return; if(sv.lastPoachDay >= sv.player.day){ alert('You already attempted a poach today. Come back tomorrow.'); return; } sv.player.money -= 1500; sv.lastPoachDay = sv.player.day; sv.totalPoachingSteps = (sv.totalPoachingSteps || 0) + 1; sv.rivalAggression = (sv.rivalAggression || 0) + 0.5; if(!sv.poachAttempts) sv.poachAttempts = {}; var attempts = sv.poachAttempts[name] || 0; var roll = Math.random(); var threshold = (attempts + 1) / 4; if(roll < threshold){ /* Success — move star to player roster */ var starIdx = sv.rival.roster.findIndex(function(w){ return w.name === name; }); if(starIdx >= 0){ var star = sv.rival.roster.splice(starIdx, 1)[0]; star.available = true; /* Force SugarCube array reactivity by reassigning */ var newRoster = sv.roster.slice(); newRoster.push(star); sv.roster = newRoster; var newRivalRoster = sv.rival.roster.slice(); sv.rival.roster = newRivalRoster; /* Reset investment */ if(sv.poachingInvestments) delete sv.poachingInvestments[name]; if(sv.poachAttempts) delete sv.poachAttempts[name]; sv.totalPoachesSucceeded = (sv.totalPoachesSucceeded || 0) + 1; sv.rivalAggression = (sv.rivalAggression || 0) + 2; /* Trophy checks */ if(!sv.trophies.firstPoach){ sv.trophies.firstPoach = true; sv.newTrophy = '🏆 Poacher — first rival star successfully poached!'; } if(!sv.trophies.poachMaster && sv.totalPoachesSucceeded >= 5){ sv.trophies.poachMaster = true; sv.newTrophy = '🏆 Poach Master — 5 rival stars poached!'; } alert('✅ ' + name + ' has joined your agency!'); } } else { sv.poachAttempts[name] = Math.min((sv.poachAttempts[name] || 0) + 1, 3); alert('❌ Poaching failed. ' + name + ' stayed with ' + sv.rival.name + '. ($1,500 lost)'); } SugarCube.Engine.play('Competition'); }); }); } /* end poachingUnlocked */ } var shootingEl = document.getElementById('rival-last-shooting'); if(shootingEl){ if(rivalLastShooting){ var starFile = rivalLastShooting.star.toLowerCase().replace(/ /g,'_'); var posFile = rivalLastShooting.position.toLowerCase().replace(/ /g,'_').replace(/-/g,'_'); var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var videoSrc = 'videos/' + prefix + starFile + '_' + posFile + '.webm'; console.log('[Competition] video path:', videoSrc); shootingEl.innerHTML = '<em>'+rivalLastShooting.star+' — <strong>'+rivalLastShooting.position+'</strong></em><br>' + '<video src="'+videoSrc+'" autoplay loop muted playsinline ' + 'style="width:100%;max-width:480px;border-radius:8px;margin-top:8px;" ' + 'onerror="this.nextElementSibling.style.display=\'block\';this.style.display=\'none\'"></video>' + '<em style="display:none;color:#888;">⚠️ Video not found: '+videoSrc+'</em>'; } else { shootingEl.innerHTML = '<em>'+rival.name+' hasn\'t produced anything yet.</em>'; } } }); <</script>> /* ════════════════════════════════════════════ PASSAGE : StarProfile ════════════════════════════════════════════ */
<<set _w = $roster[$profileIndex]>> <h1 style="margin:0 0 0.4em 0;">👤 <<= _w.name>></h1> <<= _w.ageNum>> y.o. (<<= _w.ageCat>>) 💇 Hair: <<= _w.hair>> | 📏 Height: <<= _w.height>> 🎭 Tits: <<= _w.breast>> (<<= _w.breastType>>) 🌟 Popularity: <<= _w.popularity>> | 🔄 Upkeep: $<<= (_w.popularity * 70).toLocaleString()>>/week 💖 Fav Position: <<= _w.favPosition>> | 🔓 Bonus (sat. 30+): <<= _w.bonusPosition>> Productions this week: <<= _w.weekShootings>> Satisfaction: <<if _w.satisfaction >= 70>> @@color:green;<<= _w.satisfaction>>% 😊@@ <<elseif _w.satisfaction >= 40>> @@color:orange;<<= _w.satisfaction>>% 😐@@ <<else>> @@color:red;<<= _w.satisfaction>>% 😠 (at risk of leaving!)@@ <</if>> [[⬅️ Back|Roster]] /* ════════════════════════════════════════════ PASSAGE : INTRO ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">🎬 Casting Couch Manager V.2</h1> <img src="img/banner.jpg" style="width:100%;max-height:300px;object-fit:cover;border-radius:8px;margin-bottom:12px;"> <em>Los Angeles. 2 AM.</em> 2 AM. The city doesn't sleep and neither do you. Your agency is worth nothing yet — but you've got hunger, instinct, and a roster of women who know exactly what they're doing on camera. The audience is out there, credit card in hand. They want faces, bodies, chemistry — and someone bold enough to put it all on screen without blinking. Your rival is already signing contracts. They're not waiting. Neither are you. <em>Sign your talents. Direct their scenes. Make them stars — and make the audience beg for more.</em> <div style="padding:10px;background:#111;border-radius:6px;font-size:0.88em;line-height:1.6;"> 🌟 <b>Reputation</b> grows with every production. It unlocks new positions, new talents, and new opportunities.<br> 💰 <b>Money</b> comes from your productions — the more popular your talents and the higher your reputation, the bigger the earnings. But talents cost money to keep: you pay weekly upkeep based on their popularity.<br> ❤️ <b>Satisfaction</b> is everything. A happy performer gives their best and unlocks new positions. Neglect them and they'll look for work elsewhere — your rival will be happy to oblige.<br> 📈 <b>Daily trends</b> shift every day. Matching the trending position or talent profile gives you a multiplier bonus on earnings and extra reputation.<br> ⏳ <b>Rest days</b> are mandatory. After two consecutive productions, a talent needs a day off. Plan ahead.<br> 🎯 <b>Your first goal:</b> sign at least 3 talents before Day 15 — or it's game over. </div> <b>Your name:</b> <<textbox "$player.name" "Alex">> <b>Your agency name:</b> <<textbox "$studioName" "Thunder Agency">> <b>Your rival's name:</b> <<textbox "$rival.name" "Iron Studio">> [[▶️ Choose your archetype|ChooseArchetype]] /* ════════════════════════════════════════════ PASSAGE : ChooseArchetype ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">🎭 Choose Your Archetype</h1> <div style="display:flex;flex-wrap:wrap;justify-content:center;gap:12px;align-items:flex-start;"> <div class="archetype-card"> <h3>💰 Rich</h3> <em style="font-size:0.85em;color:#aaa;">You come from money. Less hustle, more capital.</em> <div style="font-size:0.85em;margin:8px 0;text-align:left;"><div style="padding:2px 0;">• Start with <b>$6,000</b></div> <div style="padding:2px 0;">• No special bonuses</div></div> [[▶️ Play|ApplyArchetype][$archetype = "rich"]] </div> <div class="archetype-card"> <h3>🥋 Skillful</h3> <em style="font-size:0.85em;color:#aaa;">You've trained hard and know your positions.</em> <div style="font-size:0.85em;margin:8px 0;text-align:left;"><div style="padding:2px 0;">• Start with <b>$4,750</b></div> <div style="padding:2px 0;">• Start with <b>reputation 4</b></div> <div style="padding:2px 0;">• <b>BJ & Missionary</b> unlocked</div> <div style="padding:2px 0;">• <b>−10%</b> on positions</div></div> [[▶️ Play|ApplyArchetype][$archetype = "skillful"]] </div> <div class="archetype-card"> <h3>✨ Charismatic</h3> <em style="font-size:0.85em;color:#aaa;">Everyone loves you. Talents want to work with you.</em> <div style="font-size:0.85em;margin:8px 0;text-align:left;"><div style="padding:2px 0;">• Start with <b>$4,500</b></div> <div style="padding:2px 0;">• <b>−10%</b> on contracts</div> <div style="padding:2px 0;">• Talents start at <b>15 satisfaction</b></div></div> [[▶️ Play|ApplyArchetype][$archetype = "charismatic"]] </div> <div class="archetype-card"> <h3>🎲 Gambler</h3> <em style="font-size:0.85em;color:#aaa;">You live for the thrill. Every draw is a bet.</em> <div style="font-size:0.85em;margin:8px 0;text-align:left;"><div style="padding:2px 0;">• Start with <b>$5,000</b></div> <div style="padding:2px 0;">• Draw costs <b>cut in half</b></div> <div style="padding:2px 0;">• Quantity over certainty</div></div> [[▶️ Play|ApplyArchetype][$archetype = "gambler"]] </div> </div> /* ════════════════════════════════════════════ PASSAGE : ApplyArchetype ════════════════════════════════════════════ */
<<if $archetype is "rich">> <<set $player.money = 6000>> <<elseif $archetype is "skillful">> <<set $player.money = 4750>> <<set $player.reputation = 4>> <<set $allPositions[1].unlocked = true>> <<set $playerPositions.push("Missionary")>> <<elseif $archetype is "charismatic">> <<set $player.money = 4500>> <<set $charismaticSatBonus = 5>> <<elseif $archetype is "gambler">> <<set $player.money = 5000>> <</if>> [[🏠 Start|Dashboard]] <<script>> /* All 18 stars — neutral shuffle, pools assigned at runtime */ (function(){ var pool = SugarCube.State.variables.recruitPool.slice(); /* Extract questline stars before shuffle to guarantee their pool placement */ var questlineNames = ['Kimmy', 'Lulu', 'Angie', 'Angela']; var questlineStars = {}; questlineNames.forEach(function(name){ var idx = pool.findIndex(function(w){ return w.name === name; }); if(idx >= 0){ questlineStars[name] = pool.splice(idx, 1)[0]; } }); /* Shuffle the remaining pool */ for(var i = pool.length-1; i>0; i--){ var j = Math.floor(Math.random()*(i+1)); var tmp = pool[i]; pool[i]=pool[j]; pool[j]=tmp; } /* Assign pools from shuffled non-questline stars */ /* After extracting 4 questline stars, 17 remain. Pool layout: 7 pool1 + 4 pool2 + 4 elite + 1 rival + 1 bonus = 17 */ var beginner = pool.slice(0,7); var confirmed = pool.slice(7,11); var elite = pool.slice(11,15); var rivalStar = pool[15]; var bonusStar = pool[16]; /* Force questline stars into their fixed pools */ /* Asian Duo: Kimmy → pool1, Lulu → pool2 */ if(questlineStars['Kimmy']) beginner.push(questlineStars['Kimmy']); if(questlineStars['Lulu']) confirmed.push(questlineStars['Lulu']); /* Two Fallen Angels: Angie → pool1, Angela → pool2 */ if(questlineStars['Angie']) beginner.push(questlineStars['Angie']); if(questlineStars['Angela']) confirmed.push(questlineStars['Angela']); beginner.forEach(function(w){ if(w && w.popularity !== undefined){ w.popularity = Math.floor(Math.random()*4)+3; w.contractCost = Math.floor(Math.random()*3)*250+2000; }}); confirmed.forEach(function(w){ if(w && w.popularity !== undefined){ w.popularity = Math.floor(Math.random()*4)+10; w.contractCost = (Math.floor(Math.random()*3)+10)*500; }}); elite.forEach(function(w){ if(w && w.popularity !== undefined){ w.popularity = Math.floor(Math.random()*6)+25; w.contractCost = (Math.floor(Math.random()*5)+20)*1000; }}); if(rivalStar){ rivalStar.popularity = Math.floor(Math.random()*4)+5; rivalStar.contractCost = 3000; rivalStar.available = false; } if(bonusStar){ bonusStar.popularity = Math.floor(Math.random()*4)+6; bonusStar.contractCost = Math.floor(Math.random()*(4250-3000+1))+3000; bonusStar.available = false; } /* ── Randomize favorite/bonus positions, weighted by star tier ── Beginner (1★): biased toward low-level positions Confirmed (2★): uniform across all positions Elite (3★): biased toward high-level positions */ var allPos = SugarCube.State.variables.allPositions; function weightFor(tier, level){ if(tier === 'beginner') return Math.max(1, 11 - level); if(tier === 'elite') return level; return 1; /* confirmed */ } function weightedPick(tier, exclude){ var bag = []; allPos.forEach(function(p){ if(exclude && exclude.indexOf(p.name) >= 0) return; var w = weightFor(tier, p.level); for(var i=0; i<w; i++) bag.push(p.name); }); return bag[Math.floor(Math.random()*bag.length)]; } function assignFavPositions(arr, tier){ arr.forEach(function(w){ if(!w) return; var fav = weightedPick(tier); var b1 = weightedPick(tier, [fav]); var b2 = weightedPick(tier, [fav, b1]); w.favPosition = fav; w.bonusPosition1 = b1; w.bonusPosition2 = b2; }); } assignFavPositions(beginner, 'beginner'); assignFavPositions(confirmed, 'confirmed'); assignFavPositions(elite, 'elite'); if(rivalStar) assignFavPositions([rivalStar], 'confirmed'); if(bonusStar) assignFavPositions([bonusStar], 'confirmed'); SugarCube.State.variables.poolBeginner = beginner.filter(function(w){ return w && w.name; }).map(function(w){ return w.name; }); SugarCube.State.variables.poolConfirmed = confirmed.filter(function(w){ return w && w.name; }).map(function(w){ return w.name; }); SugarCube.State.variables.poolElite = elite.filter(function(w){ return w && w.name; }).map(function(w){ return w.name; }); SugarCube.State.variables.poolSpecial = null; SugarCube.State.variables.bonusEventStar = bonusStar.name; SugarCube.State.variables.rivalStartStar = rivalStar.name; SugarCube.State.variables.rivalOriginalName = SugarCube.State.variables.rival.name; rivalStar.available = false; SugarCube.State.variables.rival.roster.push(JSON.parse(JSON.stringify(rivalStar))); })(); <</script>> /* ════════════════════════════════════════════ PASSAGE : DASHBOARD ════════════════════════════════════════════ */
<<if $rivalSabotageStar>> <<if $rivalSabotageStolen>> @@color:red;😈 <b><<= $rival.name>></b> got to <b><<= $rivalSabotageStar>></b> — satisfaction crashed and she walked. <<= $rival.name>> picked her up immediately.@@<<if $player.day >= 30>><div id="poach-video-wrap"></div><<script>>jQuery(document).one(':passageend',function(){var s=SugarCube.State.variables.poachVideoStar;if(!s)return;var f=s.toLowerCase().replace(/ /g,'_');var src='videos/b_'+f+'_bj.webm';var el=document.getElementById('poach-video-wrap');if(el){var v=document.createElement('video');v.src=src;v.autoplay=true;v.loop=true;v.muted=true;v.playsInline=true;v.style.width='100%';v.style.maxWidth='480px';v.style.borderRadius='8px';v.style.marginTop='8px';v.onerror=function(){this.style.display='none';};el.innerHTML='';el.appendChild(v);}SugarCube.State.variables.poachVideoStar='';});<</script>><</if>> <<else>> @@color:orange;😈 <b><<= $rival.name>></b> got to <b><<= $rivalSabotageStar>></b> — satisfaction dropped by 10.@@ <</if>> <<set $rivalSabotageStar = "">> <<set $rivalSabotageStolen = false>> <</if>> <<if $poachMessage>> @@color:red;⚠️ <<= $poachMessage>>@@ <<set $poachMessage = "">> <<if $poachVideoStar>><div id="poach-video-wrap"></div><<script>>jQuery(document).one(':passageend',function(){var s=SugarCube.State.variables.poachVideoStar;if(!s)return;var f=s.toLowerCase().replace(/ /g,'_');var src='videos/b_'+f+'_bj.webm';var el=document.getElementById('poach-video-wrap');if(el){var v=document.createElement('video');v.src=src;v.autoplay=true;v.loop=true;v.muted=true;v.playsInline=true;v.style.width='100%';v.style.maxWidth='480px';v.style.borderRadius='8px';v.style.marginTop='8px';v.onerror=function(){this.style.display='none';};el.innerHTML='';el.appendChild(v);}SugarCube.State.variables.poachVideoStar='';});<</script>><</if>> <</if>> <<if $newTrophy>>@@color:gold;<<= $newTrophy>>@@ <<set $newTrophy = "">> <</if>> <h1 style="margin:0 0 0.4em 0;">📊 Dashboard — Day <<= $player.day>></h1> <<if $shootingPlayedToday>> @@color:orange;✋ You already produced today. Move to the next day to continue.@@ <</if>> <style> .db-btn { display:inline-block; width:190px; padding:14px 10px; margin:5px; text-align:center; border-radius:10px; border:1px solid; text-decoration:none; font-size:1.05em; font-weight:600; cursor:pointer; transition:transform 0.15s, filter 0.15s; } .db-btn:hover { transform:translateY(-2px); filter:brightness(1.25); } .db-btn-green { background:#0d2b1a; border-color:#2a7a3a; color:#5fcf7a; } .db-btn-blue { background:#0d1f3a; border-color:#2a4a9e; color:#6a9eff; } .db-btn-purple { background:#1e0d3a; border-color:#6a2a9e; color:#c07aff; } .db-btn-amber { background:#2b1d00; border-color:#9e6a00; color:#ffcc44; } .db-btn-teal { background:#001f2b; border-color:#007a7a; color:#44dfdf; } .db-btn-red { background:#2b0d0d; border-color:#9e2a2a; color:#ff7a7a; } .db-btn-gray { background:#1a1a1a; border-color:#444; color:#aaa; opacity:0.5; cursor:not-allowed; } .db-btn-next { background:#1a1200; border-color:#9e8000; color:#ffd700; width:240px; font-size:1.15em; padding:16px 10px; } .db-btn-next:hover { transform:translateY(-2px); filter:brightness(1.2); } </style> <div id="dash-buttons" style="display:flex;flex-wrap:wrap;gap:4px;margin:10px 0;max-width:540px;"> [[🎬 Run a production|OrgShooting]] [[🌟 Special Shooting|SpecialShootingMenu]] [[📋 Roster|Roster]] [[🛒 Shop|Shop]] [[👤 Recruit|Recruitment]] <<if $rival.roster.length > 0>>[[🏴 Competition|Competition]]<</if>> <<if $contractShopAvailable && !$contract1.active && !$contract1.accepted>>[[📋 Contract Shop|ContractShop]]<<elseif $contract1.active || $contract1.accepted>><span class="db-btn db-btn-gray">📋 Contract Shop</span><<elseif $contractShopAvailableDay > 0>><span class="db-btn db-btn-gray">📋 Contract — <<= $contractShopAvailableDay - $player.day>>d</span><<else>><span class="db-btn db-btn-gray">📋 Contract Shop</span><</if>> </div> <div style="margin:10px 0;"> [[📅 Next day|NextDay]] </div> <<script>> jQuery(document).one(':passageend', function(){ var colorMap = [ ['Run a production', 'db-btn-green'], ['Special Shooting', 'db-btn-purple'], ['Roster', 'db-btn-teal'], ['Shop', 'db-btn-blue'], ['Recruit', 'db-btn-amber'], ['Competition', 'db-btn-red'], ['Contract Shop', 'db-btn-blue'], ['Contract —', 'db-btn-blue'], ['Next day', 'db-btn-next'], ]; var wrap = document.getElementById('dash-buttons'); if(wrap){ wrap.querySelectorAll('a').forEach(function(a){ var txt = a.textContent.trim(); for(var i=0;i<colorMap.length;i++){ if(txt.indexOf(colorMap[i][0]) >= 0){ a.classList.add('db-btn', colorMap[i][1]); break; } } }); } var nextBtn = document.querySelector('#passages a[href*="NextDay"]'); if(nextBtn) nextBtn.classList.add('db-btn', 'db-btn-next'); }); <</script>> /* ════════════════════════════════════════════ PASSAGE : SHOP ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">🛒 Skill Tree</h1> <div id="skill-tree-wrap"></div> [[⬅️ Dashboard|Dashboard]] <<script>> jQuery(document).one(':passageend', function(){ var sv = SugarCube.State.variables; var p = sv.player; var arch = sv.archetype; /* ── helpers ── */ function price(base){ return (arch === 'skillful' && base > 0) ? Math.ceil(base * 0.9) : base; } function fmt(n){ return '$' + n.toLocaleString(); } /* state helpers */ function posObj(name){ return sv.allPositions.find(function(m){ return m.name === name; }); } function posUnlocked(name){ return sv.playerPositions.includes(name); } /* ── node status ── */ function status(id){ switch(id){ /* GENRES */ case 'BJ': return { ok: posUnlocked('BJ'), lock: false, reason: '' }; case 'Missionary': return chk('Missionary', posUnlocked('BJ'), 'BJ required'); case 'Doggy': return chk('Doggy', posUnlocked('Missionary'), 'Missionary required'); case 'Cowgirl': return chk('Cowgirl', posUnlocked('Doggy'), 'Doggy required'); case 'Reverse Cowgirl': return chk('Reverse Cowgirl',posUnlocked('Cowgirl'),'Cowgirl required'); case 'DoubleFeature': return chkItem(sv.doublePositionItem, posUnlocked('Reverse Cowgirl') && p.reputation >= 50, 'Reverse Cowgirl + rep 50'); case 'SciFi': return chk('Spooning', sv.doublePositionItem.bought && posUnlocked('Spooning'), 'Double Feature required'); case '69': return chk('69', posUnlocked('Spooning'), 'Spooning required'); case 'Standing Up': return chk('Standing Up', posUnlocked('69'), '69 required'); case 'DP': return chk('DP', posUnlocked('69'), '69 required'); /* INTEL */ case 'P1Intel': return chkItem(sv.pool1IntelItem, true, ''); case 'P2Intel': return chkItem(sv.pool2IntelItem, sv.pool1IntelItem && sv.pool1IntelItem.bought, 'Pool 1 Intel required'); case 'P3Intel': return chkItem(sv.pool3IntelItem, sv.pool2IntelItem && sv.pool2IntelItem.bought, 'Pool 2 Intel required'); /* UPGRADES */ case 'EstDip': return chkItem(sv.pool1UpgradeItem, sv.player.day >= 30, 'Available from day 30'); case 'EstSurge': return chkItem(sv.pool1Upgrade2A, sv.pool1UpgradeItem.bought && sv.roster.filter(function(w){ return sv.poolConfirmed.indexOf(w.name) >= 0; }).length > 0, 'Est. Dip + 1 Established star'); case 'DblScouting': return chkItem(sv.pool1Upgrade2B, sv.pool1UpgradeItem.bought && p.reputation >= 10, 'Est. Dip + rep 10'); case 'TplScouting': return chkItem(sv.pool1Upgrade2C, sv.pool1Upgrade2B && sv.pool1Upgrade2B.bought, 'Double Scout required'); case 'QadScouting': return chkItem(sv.pool1Upgrade2D, sv.pool1Upgrade2C && sv.pool1Upgrade2C.bought, 'Triple Scout required'); case 'TargetedScout': return chkItem(sv.targetedScoutItem, false, 'Future version'); case 'EliteDip': return chkItem(sv.pool2UpgradeItem, sv.pool1Upgrade2B.bought && sv.doublePositionItem.bought && p.reputation >= 20, 'Dbl Scout + Double Feature + rep 20'); case 'EliteSurge': return chkItem(sv.pool2Upgrade2, sv.pool2UpgradeItem.bought && p.reputation >= 30, 'Elite Dip + rep 30'); /* AGENCE */ case 'AD': { var adOk = sv.adItem.buyCount >= 3; return { ok: adOk, lock: false, canBuy: !adOk && sv.player.money >= sv.adItem.price, reason: '', count: sv.adItem.buyCount }; } case 'MarketStudy': return chkItem(sv.marketStudyItem, sv.adItem.buyCount >= 1 && p.reputation >= 25, 'AD Campaign + rep 25'); case 'Patience': return chkItem(sv.satisfactionDelayItem, sv.roster.length >= 5 && sv.adItem.buyCount >= 2 && p.reputation >= 50, '5 stars + 2 AD + rep 50'); /* CONTRACTS */ case 'ThirdOption': return chkItem(sv.contract3rdOptionItem, sv.contractShopAvailable || sv.contractShopAvailableDay > 0 || (sv.contract3rdOptionItem && sv.contract3rdOptionItem.bought), 'Complete Contract 1 first'); case 'HarderContract': return chkItem(sv.contractHarderItem, sv.contract3rdOptionItem && sv.contract3rdOptionItem.bought, '3rd Option required'); default: return { ok: false, lock: true, reason: 'Unknown' }; } } function chk(posName, cond, reason){ var obj = sv.allPositions.find(function(m){ return m.name === posName; }); var unlocked = obj && obj.unlocked; if(unlocked) return { ok: true, lock: false, reason: '' }; if(!cond) return { ok: false, lock: true, reason: reason }; var p2 = price(obj ? obj.price : 0); if(p2 > 0 && sv.player.money < p2) return { ok: false, lock: false, reason: 'No funds' }; return { ok: false, lock: false, reason: '', canBuy: true, buyId: posName }; } function chkItem(item, cond, reason){ if(!item) return { ok: false, lock: true, reason: reason || 'Not available' }; if(item.bought) return { ok: true, lock: false, reason: '' }; if(!cond) return { ok: false, lock: true, reason: reason }; if(sv.player.money < item.price) return { ok: false, lock: false, reason: 'No funds' }; return { ok: false, lock: false, reason: '', canBuy: true }; } /* ── node definitions ── */ var genres = [ { id:'BJ', label:'BJ', sub:'Gratuit', pass:null }, { id:'Missionary', label:'Missionary', sub:fmt(price(500))+' · rep10', pass:'BuyPosition', pidx:1 }, { id:'Doggy', label:'Doggy', sub:fmt(price(800))+' · rep20', pass:'BuyPosition', pidx:2 }, { id:'Cowgirl', label:'Cowgirl', sub:fmt(price(1200))+' · rep30', pass:'BuyPosition', pidx:3 }, { id:'Reverse Cowgirl', label:'Reverse Cowgirl',sub:fmt(price(1500))+' · rep40', pass:'BuyPosition', pidx:4 }, { id:'DoubleFeature',label:'Double Feature', sub:fmt(5000)+' · rep50', pass:'BuyDoubleFeature' }, { id:'SciFi', label:'Spooning', sub:fmt(price(2000))+' · rep50', pass:'BuyPosition', pidx:6 }, { id:'69', label:'69', sub:fmt(price(2500))+' · rep60', pass:'BuyPosition', pidx:7 }, ]; var genresBottom = [ { id:'Standing Up', label:'Standing Up', sub:fmt(price(3000)), pass:'BuyPosition', pidx:8 }, { id:'DP', label:'DP', sub:fmt(price(4000)), pass:'BuyPosition', pidx:9 }, ]; var intel = [ { id:'P1Intel', label:'Pool 1 Intel', sub:fmt(500)+' · free', pass:'BuyPool1Intel' }, { id:'P2Intel', label:'Pool 2 Intel', sub:fmt(500)+' · P1 Intel', pass:'BuyPool2Intel' }, { id:'P3Intel', label:'Pool 3 Intel', sub:fmt(500)+' · Elite Dip', pass:'BuyPool3Intel' }, { id:'TargetedScout', label:'Targeted Scout', sub:fmt(500)+' · P3 Intel', pass:'BuyTargetedScout' }, ]; var upgradesChance = [ { id:'EstDip', label:'Est. Dip', sub:fmt(2500)+' · j30', pass:'BuyPool1Upgrade' }, { id:'EstSurge', label:'Est. Surge', sub:fmt(5000)+' · 1★ Est.', pass:'BuyPool1Upgrade2A' }, { id:'EliteDip', label:'Elite Dip', sub:fmt(6000)+' · rep20', pass:'BuyPool2Upgrade' }, { id:'EliteSurge', label:'Elite Surge', sub:fmt(10000)+' · rep30', pass:'BuyPool2Upgrade2' }, ]; var upgradesMulti = [ { id:'DblScouting', label:'Double Scout', sub:fmt(5000)+' · rep10', pass:'BuyPool1Upgrade2B' }, { id:'TplScouting', label:'Triple Scout', sub:fmt(5000)+' · Dbl', pass:'BuyTripleScouting' }, { id:'QadScouting', label:'Quad Scout', sub:fmt(5000)+' · Tpl', pass:'BuyQuadScouting' }, ]; var agence = [ { id:'AD', label:'AD Campaign ×3', sub:fmt(3000)+' / achat', pass:'BuyAD' }, { id:'MarketStudy', label:'Market Study', sub:fmt(4000)+' · rep25', pass:'BuyMarketStudy' }, { id:'Patience', label:'Patience Train.', sub:fmt(3500)+' · rep50', pass:'BuySatisfactionDelay' }, ]; /* ── render node ── */ function renderNode(item, extraClass){ var s = status(item.id); var cls = 'sk-node'; var icon = ''; var buyBtn = ''; if(s.ok){ cls += ' sk-done'; icon = '✅'; } else if(s.lock){ cls += ' sk-lock'; icon = '🔒'; } else if(s.canBuy){ cls += ' sk-buy'; var passTarget = item.pass; var extra = ''; if(item.pidx !== undefined) extra = ' data-pidx="'+item.pidx+'"'; buyBtn = '<button class="sk-btn" data-pass="'+passTarget+'"'+extra+'>Buy</button>'; } else { cls += ' sk-no'; icon = '💸'; } if(extraClass) cls += ' ' + extraClass; var countBadge = (item.id === 'AD' && !s.ok) ? ' <small>('+sv.adItem.buyCount+'/3)</small>' : ''; var tip = ({ 'BJ':'Unlock BJ productions — free','Missionary':'Unlock Missionary productions', 'Doggy':'Unlock Doggy productions','Cowgirl':'Unlock Cowgirl productions', 'Reverse Cowgirl':'Unlock Reverse Cowgirl productions','DoubleFeature':'Two Shootings in a Day — film 2 stars at once', 'SciFi':'Unlock Spooning productions','69':'Unlock 69 productions', 'Standing Up':'Unlock Standing Up productions','DP':'Unlock DP productions', 'P1Intel':'Reveal Pool 1 star count & contract range', 'P2Intel':'Reveal Pool 2 star count & contract range', 'P3Intel':'Reveal Pool 3 star count & contract range', 'TargetedScout':'Target a star — she appears twice in draws (+20% chance)', 'EstDip':'15% chance to draw a Pool 2 star from Pool 1 scout', 'EstSurge':'Increase Est. Dip chance to 50%', 'EliteDip':'15% chance to draw a Pool 3 Elite star', 'EliteSurge':'Increase Elite Dip chance to 40%', 'DblScouting':'Draw 2 stars at once when scouting', 'TplScouting':'Draw 3 stars at once when scouting', 'QadScouting':'Draw 4 stars at once when scouting', 'AD':'Gain reputation instantly — up to ×3', 'MarketStudy':'Reveal a 2nd physical trend each day', 'Patience':'Stars tolerate 1 extra day without shooting before losing satisfaction', 'ThirdOption':'Contracts show 3 options instead of 2', 'HarderContract':'Unlock Harder Contracts — 2 stats to match, higher reward & penalty', })[item.id] || ''; var tipHtml = tip ? '<div class="sk-tooltip">'+tip+'</div>' : ''; return '<div class="'+cls+'" data-id="'+item.id+'">'+tipHtml+ '<div class="sk-label">'+item.label+icon+countBadge+'</div>'+ '<div class="sk-sub">'+item.sub+'</div>'+ (s.reason && !s.ok && !s.canBuy ? '<div class="sk-reason">'+s.reason+'</div>' : '')+ buyBtn+ '</div>'; } /* ── build HTML ── */ var html = '<style>'+ '#skill-tree-wrap{font-size:0.82em;}'+ '.sk-cols{display:flex;gap:14px;align-items:flex-start;}'+ '.sk-col{flex:1;min-width:0;}'+ '.sk-col.sk-col-scouting{flex:2.4;}'+ '.sk-col.sk-col-agence{flex:0.9;}'+ '.sk-col-head{text-align:center;font-weight:500;font-size:0.9em;padding:4px 0;border-bottom:1px solid #333;margin-bottom:6px;}'+ '.sk-subcols{display:flex;gap:6px;}'+ '.sk-subcol{flex:1;min-width:0;}'+ '.sk-subcol-head{text-align:center;font-size:0.78em;color:#888;padding:2px 0;border-bottom:1px solid #222;margin-bottom:4px;}'+ '.sk-node{border:1px solid #333;border-radius:6px;padding:5px 7px;margin-bottom:5px;background:#111;transition:border-color 0.2s;position:relative;}'+ '.sk-node .sk-tooltip{display:none;position:absolute;left:105%;top:0;z-index:99;background:#222;border:1px solid #555;border-radius:6px;padding:6px 10px;font-size:0.8em;color:#ccc;width:180px;white-space:normal;pointer-events:none;}'+ '.sk-node:hover .sk-tooltip{display:block;}'+ '.sk-done{border-color:#2a5;background:#0a1a0a;}'+ '.sk-lock{opacity:0.5;}'+ '.sk-buy{border-color:#4a9eff;cursor:pointer;}'+ '.sk-buy:hover{background:#0a1a2e;}'+ '.sk-no{border-color:#555;}'+ '.sk-label{font-weight:500;margin-bottom:1px;}'+ '.sk-sub{font-size:0.85em;color:#888;}'+ '.sk-reason{font-size:0.78em;color:#cc6644;margin-top:2px;}'+ '.sk-btn{margin-top:4px;padding:2px 10px;background:#1a1a2e;border:1px solid #4a9eff;color:#4a9eff;border-radius:4px;cursor:pointer;font-size:0.85em;}'+ '.sk-btn:hover{background:#4a9eff;color:#000;}'+ '.sk-arrow{text-align:center;color:#444;font-size:0.85em;margin:1px 0;}'+ '.sk-fork{display:flex;gap:4px;}'+ '.sk-fork > .sk-node{flex:1;}'+ '</style>'; html += '<div class="sk-cols">'; /* ── GENRES col ── */ html += '<div class="sk-col"><div class="sk-col-head">🎬 Genres</div>'; genres.forEach(function(g){ html += renderNode(g); html += '<div class="sk-arrow">↓</div>'; }); html += '<div class="sk-fork">'+renderNode(genresBottom[0])+renderNode(genresBottom[1])+'</div>'; html += '\x3c/div>'; /* ── SCOUTING col ── */ html += '<div class="sk-col sk-col-scouting"><div class="sk-col-head">🔍 Scouting</div><div class="sk-subcols">'; html += '<div class="sk-subcol"><div class="sk-subcol-head">Intel</div>'; intel.forEach(function(n){ html += renderNode(n); html += '<div class="sk-arrow">↓</div>'; }); html += '\x3c/div>'; html += '<div class="sk-subcol"><div class="sk-subcol-head">Chance</div>'; upgradesChance.forEach(function(n){ html += renderNode(n); html += '<div class="sk-arrow">↓</div>'; }); html += '\x3c/div>'; html += '<div class="sk-subcol"><div class="sk-subcol-head">Multi</div>'; upgradesMulti.forEach(function(n){ html += renderNode(n); html += '<div class="sk-arrow">↓</div>'; }); html += '\x3c/div>'; html += '\x3c/div>\x3c/div>'; /* ── AGENCE col ── */ html += '<div class="sk-col sk-col-agence"><div class="sk-col-head">📣 Agence</div>'; agence.forEach(function(n, i){ html += renderNode(n); if(i < agence.length - 1) html += '<div class="sk-arrow">↓</div>'; }); html += '\x3c/div>'; /* ── CONTRACT col ── */ html += '<div class="sk-col"><div class="sk-col-head">📋 Contracts</div>'; var contracts = [ { id:'ThirdOption', label:'3rd Option', sub:fmt(500)+' · after C1', pass:'Buy3rdOption' }, { id:'HarderContract', label:'Harder Contract', sub:fmt(1500)+' · 3rd Opt.', pass:'BuyHarderContract2' }, ]; contracts.forEach(function(n){ html += renderNode(n); html += '<div class="sk-arrow">↓</div>'; }); html += '\x3c/div>'; html += '\x3c/div>'; var wrap = document.getElementById('skill-tree-wrap'); if(wrap){ wrap.innerHTML = html; /* buy buttons */ wrap.querySelectorAll('.sk-btn').forEach(function(btn){ btn.addEventListener('click', function(){ var pass = this.getAttribute('data-pass'); var pidx = this.getAttribute('data-pidx'); if(pidx !== null){ SugarCube.State.variables.positionIndex = parseInt(pidx); } SugarCube.Engine.play(pass); }); }); } }); <</script>> /* ════════════════════════════════════════════ PASSAGE : ListShop ════════════════════════════════════════════ */
<<set _sm = $allPositions.slice().sort(function(a,b){ return a.price - b.price; })>> <<for _i = 0; _i < _sm.length; _i++>><<set _m = _sm[_i]>><<set _p = ($archetype is "skillful" && _m.price > 0) ? Math.ceil(_m.price * 0.9) : _m.price>> — <<if _m.price is 0>><b><<= _m.name>></b> ✅<<elseif _m.comingSoon>><b><<= _m.name>></b> — 🔜 <em>Coming in a future update</em><<else>><b><<= _m.name>></b> $<<= _p.toLocaleString()>> | Rep.<<= _m.repMin>> | Lvl<<= _m.level>> — <<if _m.unlocked>>✅<<elseif _m.repMin > $player.reputation>>🔒 <em>(rep <<= _m.repMin>>)</em><<elseif $player.money < _p>>@@color:red;No funds@@<<else>><<set _idx = $allPositions.indexOf(_m)>><<capture _idx>>[[🛒|BuyPosition][$positionIndex = _idx]]<</capture>><</if>><</if>> <</for>> — <b>AD Campaign</b> $<<= $adItem.price.toLocaleString()>> <em>(+<<= $adItem.repBonus>> rep)</em> — <<if $adItem.buyCount >= 3>>✅ ×3 (max)<br><<elseif $player.money < $adItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyAD]] <em>(<<= $adItem.buyCount>>/3)</em><</if>> — <b>Patience Training</b> $<<= $satisfactionDelayItem.price.toLocaleString()>> <em>(talents stay happy 4 days instead of 3)</em> — <<if $satisfactionDelayItem.bought>>✅<<elseif $roster.length < 5>>🔒 <em>(need 5 stars in roster — <<= $roster.length>>/5)</em><<elseif $adItem.buyCount < 2>>🔒 <em>(need 2 AD Campaigns — <<= $adItem.buyCount>>/2)</em><<elseif $player.reputation < $satisfactionDelayItem.repMin>>🔒 <em>(rep <<= $satisfactionDelayItem.repMin>>)</em><<elseif $player.money < $satisfactionDelayItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuySatisfactionDelay]]<</if>> — <b>Established Dip</b> $<<= $pool1UpgradeItem.price.toLocaleString()>> <em>(20% chance to draw from Pool 2)</em> — <<if $pool1UpgradeItem.bought>>✅<<elseif $player.day < 30>>🔒 <em>(available from day 30)</em><<elseif $player.money < $pool1UpgradeItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool1Upgrade]]<</if>> — <b>Established Surge</b> $<<= $pool1Upgrade2A.price.toLocaleString()>> <em>(50% chance to draw from Pool 2)</em> — <<if !$pool1UpgradeItem.bought>>🔒 <em>(requires Established Dip)</em><<elseif $pool1Upgrade2A.bought>>✅<<elseif $roster.filter(function(w){ return $poolConfirmed.indexOf(w.name) >= 0; }).length is 0>>🔒 <em>(need 1 Established star in roster)</em><<elseif $player.money < $pool1Upgrade2A.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool1Upgrade2A]]<</if>> — <b>Double Scouting</b> $<<= $pool1Upgrade2B.price.toLocaleString()>> <em>(draw 2 talents at once)</em> — <<if !$pool1UpgradeItem.bought>>🔒 <em>(requires Established Dip)</em><<elseif $pool1Upgrade2B.bought>>✅<<elseif $player.reputation < $pool1Upgrade2B.repMin>>🔒 <em>(rep <<= $pool1Upgrade2B.repMin>>)</em><<elseif $player.money < $pool1Upgrade2B.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool1Upgrade2B]]<</if>> — <b>Double Feature</b> $<<= $doublePositionItem.price.toLocaleString()>> <em>(2 positions | rep<<= $doublePositionItem.repMin>>)</em> — <<if $doublePositionItem.bought>>✅<<elseif $player.reputation < $doublePositionItem.repMin>>🔒 <em>(rep <<= $doublePositionItem.repMin>>)</em><<elseif $player.money < $doublePositionItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyDoubleFeature]]<</if>> — <b>Pool 1 Intel</b> $<<= $pool1IntelItem.price.toLocaleString()>> <em>(view Pool 1 content)</em> — <<if $pool1IntelItem.bought>>✅<<elseif $player.money < $pool1IntelItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool1Intel]]<</if>> — <b>Pool 2 Intel</b> $<<= $pool2IntelItem.price.toLocaleString()>> <em>(view Pool 2 content)</em> — <<if !$pool1IntelItem.bought>>🔒 <em>(requires Pool 1 Intel)</em><<elseif $pool2IntelItem.bought>>✅<<elseif $player.money < $pool2IntelItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool2Intel]]<</if>> — <b>Pool 3 Intel</b> $<<= $pool3IntelItem.price.toLocaleString()>> <em>(view Pool 3 content)</em> — <<if !$pool2IntelItem.bought>>🔒 <em>(requires Pool 2 Intel)</em><<elseif $pool3IntelItem.bought>>✅<<elseif $player.money < $pool3IntelItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool3Intel]]<</if>> — <b>Elite Dip</b> $<<= $pool2UpgradeItem.price.toLocaleString()>> <em>(15% chance Elite | rep<<= $pool2UpgradeItem.repMin>>)</em> — <<if $pool2UpgradeItem.bought>>✅<<elseif $player.reputation < $pool2UpgradeItem.repMin>>🔒 <em>(rep <<= $pool2UpgradeItem.repMin>>)</em><<elseif $player.money < $pool2UpgradeItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool2Upgrade]]<</if>> — <b>Elite Surge</b> $<<= $pool2Upgrade2.price.toLocaleString()>> <em>(40% chance Elite | rep<<= $pool2Upgrade2.repMin>>)</em> — <<if !$pool2UpgradeItem.bought>>🔒 <em>(requires Elite Dip)</em><<elseif $pool2Upgrade2.bought>>✅<<elseif $player.reputation < $pool2Upgrade2.repMin>>🔒 <em>(rep <<= $pool2Upgrade2.repMin>>)</em><<elseif $player.money < $pool2Upgrade2.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyPool2Upgrade2]]<</if>> — <b>Market Study</b> $<<= $marketStudyItem.price.toLocaleString()>> <em>(2nd daily trend | rep<<= $marketStudyItem.repMin>>)</em> — <<if $marketStudyItem.bought>>✅<<elseif $player.reputation < $marketStudyItem.repMin>>🔒 <em>(rep <<= $marketStudyItem.repMin>>)</em><<elseif $player.money < $marketStudyItem.price>>@@color:red;No funds@@<<else>>[[🛒 Buy|BuyMarketStudy]]<</if>>
<<set $player.money -= $doublePositionItem.price>> <<set $doublePositionItem.bought = true>> ✅ <b>Double Feature</b> purchased! You can now use 2 positions per production. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $satisfactionDelayItem.price>> <<set $satisfactionDelayItem.bought = true>> ✅ <b>Patience Training</b> purchased! Your talents now stay satisfied for <b>4 days</b> instead of 3 before satisfaction starts decaying. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool1UpgradeItem.price>> <<set $pool1UpgradeItem.bought = true>> ✅ <b>Established Dip</b> purchased! Drawing from Pool 1 now has a <b>20% chance</b> to give you a Pool 2 talent instead. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool1Upgrade2A.price>> <<set $pool1Upgrade2A.bought = true>> ✅ <b>Established Surge</b> purchased! Drawing from Pool 1 now has a <b>50% chance</b> to give you a Pool 2 talent. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool1Upgrade2B.price>> <<set $pool1Upgrade2B.bought = true>> ✅ <b>Double Scouting</b> purchased! You can now draw 2 talents at once from Pool 1. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool1IntelItem.price>> <<set $pool1IntelItem.bought = true>> ✅ <b>Pool 1 Intel</b> purchased! You can now view Pool 1 content in recruitment. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool2IntelItem.price>> <<set $pool2IntelItem.bought = true>> ✅ <b>Pool 2 Intel</b> purchased! You can now view Pool 2 content in recruitment. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool3IntelItem.price>> <<set $pool3IntelItem.bought = true>> ✅ <b>Pool 3 Intel</b> purchased! You can now view Pool 3 content in recruitment. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<if $targetedScoutItem.bought>> Already purchased. [[⬅️ Shop|Shop]] <<elseif !$pool3IntelItem.bought>> @@color:red;Pool 3 Intel required.@@ [[⬅️ Shop|Shop]] <<elseif $player.money < $targetedScoutItem.price>> @@color:red;Not enough funds ($<<= $targetedScoutItem.price>> required).@@ [[⬅️ Shop|Shop]] <<else>> <<set $player.money -= $targetedScoutItem.price>> <<set $targetedScoutItem.bought = true>> ✅ <b>Targeted Scout</b> purchased! You can now target a specific star to increase their draw chance. [[🎯 Set Target|TargetedScoutMenu]] | [[🛒 Shop|Shop]] <</if>>
<<if $pool1Upgrade2C.bought>>Already purchased. [[⬅️ Shop|Shop]] <<elseif !$pool1Upgrade2B.bought>>@@color:red;Double Scouting required.@@ [[⬅️ Shop|Shop]] <<elseif $player.money < $pool1Upgrade2C.price>>@@color:red;Not enough funds.@@ [[⬅️ Shop|Shop]] <<else>> <<set $player.money -= $pool1Upgrade2C.price>> <<set $pool1Upgrade2C.bought = true>> ✅ <b>Triple Scouting</b> purchased! You can now draw 3 stars at once. [[🛒 Shop|Shop]] | [[📊 Dashboard|Dashboard]] <</if>>
<<if $pool1Upgrade2D.bought>>Already purchased. [[⬅️ Shop|Shop]] <<elseif !$pool1Upgrade2C.bought>>@@color:red;Triple Scouting required.@@ [[⬅️ Shop|Shop]] <<elseif $player.money < $pool1Upgrade2D.price>>@@color:red;Not enough funds.@@ [[⬅️ Shop|Shop]] <<else>> <<set $player.money -= $pool1Upgrade2D.price>> <<set $pool1Upgrade2D.bought = true>> ✅ <b>Quadruple Scouting</b> purchased! You can now draw 4 stars at once. [[🛒 Shop|Shop]] | [[📊 Dashboard|Dashboard]] <</if>>
<h1 style="margin:0 0 0.3em 0;">🎯 Targeted Scout</h1> <<if !$targetedScoutItem || !$targetedScoutItem.bought>> @@color:red;Targeted Scout not purchased yet.@@ [[⬅️ Shop|Shop]] <<else>> <<if $targetedScoutStar>> Currently targeting: <b><<= $targetedScoutStar>></b> <em style="color:#888;">(+20% draw chance)</em><br> [[❌ Clear target|TargetedScoutClear]] <<else>> <em style="color:#888;">Select a star to target — she will appear twice in your draws.</em> <</if>> <b>Available stars:</b> <<set _tsPool = $recruitPool.filter(function(w){ return w.available && !$roster.find(function(r){ return r.name is w.name; }); })>> <div id="ts-star-list"></div> <<script>> jQuery(document).one(':passageend', function(){ var sv = SugarCube.State.variables; var allPools = (sv.poolBeginner || []).concat(sv.poolConfirmed || []).concat(sv.poolElite || []); var pool = sv.recruitPool.filter(function(w){ return allPools.indexOf(w.name) >= 0 && w.available && !sv.roster.find(function(r){ return r.name === w.name; }) && !(sv.rival && sv.rival.roster && sv.rival.roster.find(function(r){ return r.name === w.name; })); }); var html = ''; pool.forEach(function(w){ html += '<div style="margin:4px 0;padding:5px 8px;background:#111;border-radius:5px;display:flex;align-items:center;gap:8px;">'; html += '<button class="ts-pick-btn" data-name="'+w.name+'" style="padding:3px 10px;background:#1a1a2e;border:1px solid #4a9eff;color:#4a9eff;border-radius:4px;cursor:pointer;font-size:0.85em;">🎯 '+w.name+'</button>'; html += '<em style="font-size:0.82em;color:#666;">'+w.hair+' | '+w.height+' | '+w.breast+'</em>'; html += '</div>'; }); var wrap = document.getElementById('ts-star-list'); if(wrap){ wrap.innerHTML = html; wrap.querySelectorAll('.ts-pick-btn').forEach(function(btn){ btn.addEventListener('click', function(){ sv.targetedScoutStar = this.getAttribute('data-name'); SugarCube.Engine.play('TargetedScoutMenu'); }); }); } }); <</script>> [[⬅️ Dashboard|Dashboard]] <</if>>
[[⬅️ Back|TargetedScoutMenu]]
<<set $targetedScoutStar = "">> [[⬅️ Back|TargetedScoutMenu]]
<<set $player.money -= $pool2UpgradeItem.price>> <<set $pool2UpgradeItem.bought = true>> ✅ <b>Elite Dip</b> purchased! 15% chance to draw an Elite star. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $pool2Upgrade2.price>> <<set $pool2Upgrade2.bought = true>> ✅ <b>Elite Surge</b> purchased! 40% chance to draw an Elite star. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]]
<<set $player.money -= $marketStudyItem.price>> <<set $marketStudyItem.bought = true>> ✅ <b>Market Study</b> purchased! You now get <b>2 daily trends</b>. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : BuyAD ════════════════════════════════════════════ */
<<set $player.money -= $adItem.price>> <<set $player.reputation += $adItem.repBonus>> <<set $adItem.buyCount += 1>> <<set $adItem.bought = true>> ✅ 'AD Campaign' launched! You gained '+<<= $adItem.repBonus>> reputation'. Your reputation is now <<= $player.reputation>>. [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : BuyPosition ════════════════════════════════════════════ */
<<set _m = $allPositions[$positionIndex]>> <<set _price = _m.price>> <<if $archetype is "skillful">><<set _price = Math.ceil(_price * 0.9)>><</if>> <<set _m.unlocked = true>> <<set $player.money -= _price>> <<set $playerPositions.push(_m.name)>> ✅ You've unlocked <b><<= _m.name>></b> style!<<if $archetype is "skillful">> <em>(−10% Skillful discount applied)</em><</if>> [[🛒 Keep shopping|Shop]] | [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : RECRUITMENT ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.2em 0;">👤 Talent Scouting</h1> <<if $drawResult.length > 0>> <div style="padding:8px;background:#111;border-radius:6px;margin-bottom:8px;"> <b>🎲 Scout result:</b><br> <div id="draw-cards-container"></div> <<script>> jQuery(document).one(':passageend', function(){ var btn = document.getElementById('new-scout-btn'); if(!btn) return; btn.addEventListener('click', function(){ var sv = SugarCube.State.variables; var cost = sv.bDrawCost || (sv.archetype === 'gambler' ? 100 : 200); if(sv.player.money < cost){ alert('Not enough funds to scout.'); return; } sv.player.money -= cost; sv.drawPool = 'beginner'; sv.drawLuckyNames = []; sv.drawEliteNames = []; var chance = 0; if(sv.pool1Upgrade2A && sv.pool1Upgrade2A.bought) chance = 50; else if(sv.pool1UpgradeItem && sv.pool1UpgradeItem.bought) chance = 20; var eliteChance = 0; if(sv.pool2Upgrade2 && sv.pool2Upgrade2.bought) eliteChance = 40; else if(sv.pool2UpgradeItem && sv.pool2UpgradeItem.bought) eliteChance = 15; var recruitPool = sv.recruitPool; var cAvail = sv.poolConfirmed.filter(function(n){ var w = recruitPool.find(function(r){ return r.name===n; }); return w && w.available; }); var eAvail = sv.poolElite.filter(function(n){ var w = recruitPool.find(function(r){ return r.name===n; }); return w && w.available; }); var bAvail = sv.poolBeginner.filter(function(n){ var w = recruitPool.find(function(r){ return r.name===n; }); return w && w.available; }); if(sv.targetedScoutItem && sv.targetedScoutItem.bought && sv.targetedScoutStar){ var ts = sv.targetedScoutStar; if(bAvail.indexOf(ts)>=0) bAvail = bAvail.concat([ts]); else if(cAvail.indexOf(ts)>=0) cAvail = cAvail.concat([ts]); else if(eAvail.indexOf(ts)>=0) eAvail = eAvail.concat([ts]); } var multiDraw = 1; if(sv.pool1Upgrade2D && sv.pool1Upgrade2D.bought) multiDraw = 4; else if(sv.pool1Upgrade2C && sv.pool1Upgrade2C.bought) multiDraw = 3; else if(sv.pool1Upgrade2B && sv.pool1Upgrade2B.bought) multiDraw = 2; if(multiDraw >= 2 && (bAvail.length + cAvail.length) >= 2){ sv.drawResult = []; for(var di=0; di<multiDraw; di++){ var useElite2 = eliteChance>0 && Math.random()*100<eliteChance && eAvail.length>0; var useUpgrade2 = chance > 0 && Math.random()*100 < chance && cAvail.length > 0; var bEmpty = bAvail.length === 0 && cAvail.length > 0; if(useElite2){ var ri=Math.floor(Math.random()*eAvail.length); sv.drawPool='elite'; sv.drawResult.push(eAvail[ri]); sv.drawEliteNames.push(eAvail[ri]); eAvail.splice(ri,1); } else if(useUpgrade2 || bEmpty){ var ri=Math.floor(Math.random()*cAvail.length); sv.drawPool='confirmed'; sv.drawResult.push(cAvail[ri]); if(useUpgrade2) sv.drawLuckyNames.push(cAvail[ri]); cAvail.splice(ri,1); } else if(bAvail.length>0){ var ri=Math.floor(Math.random()*bAvail.length); sv.drawResult.push(bAvail[ri]); bAvail.splice(ri,1); } } if(sv.drawResult.length===0){ alert('No talents available to scout.'); return; } } else { var useElite = eliteChance>0 && Math.random()*100<eliteChance && eAvail.length>0; var useUpgrade = chance > 0 && Math.random()*100 < chance; if(useElite){ sv.drawPool='elite'; var ri=Math.floor(Math.random()*eAvail.length); sv.drawResult=[eAvail[ri]]; sv.drawEliteNames.push(eAvail[ri]); } else if((useUpgrade || bAvail.length===0) && cAvail.length>0){ sv.drawPool='confirmed'; var ri=Math.floor(Math.random()*cAvail.length); sv.drawResult=[cAvail[ri]]; if(useUpgrade) sv.drawLuckyNames.push(cAvail[ri]); } else if(bAvail.length>0){ var ri=Math.floor(Math.random()*bAvail.length); sv.drawResult=[bAvail[ri]]; } else { alert('No talents available to scout.'); return; } } SugarCube.Engine.play('Recruitment'); }); }); <</script>> <button id="new-scout-btn" style="padding:6px 16px;background:#1a1a2e;border:1px solid #4a9eff;color:#4a9eff;border-radius:6px;cursor:pointer;font-size:0.9em;margin:4px 0;">🎲 Scout again ($<<= $bDrawCost>>)</button> </div> <<script>> jQuery(document).one(':passageend', function(){ var drawResult = SugarCube.State.variables.drawResult; var recruitPool = SugarCube.State.variables.recruitPool; var trends = SugarCube.State.variables.trends; var luckyNames = SugarCube.State.variables.drawLuckyNames || []; var eliteNames = SugarCube.State.variables.drawEliteNames || []; var playerMoney = SugarCube.State.variables.player.money; var stars = drawResult.map(function(name){ return recruitPool.find(function(r){ return r.name === name; }); }).filter(function(w){ return !!w; }); /* Build cards with sign buttons underneath each card */ if(!stars || stars.length === 0){ var el = document.getElementById('draw-cards-container'); if(el) el.innerHTML = '<em>No talents to display.</em>'; return; } var trendType = trends ? trends.carType : ''; var trendVal = trends ? trends.carValue : ''; var trendType2 = trends ? trends.carType2 : ''; var trendVal2 = trends ? trends.carValue2 : ''; var html = '\x3cdiv style="text-align:center;">'; stars.forEach(function(w){ var file = w.name.toLowerCase().replace(/ /g,'_'); var isElite = eliteNames.indexOf(w.name) >= 0; var isLucky = luckyNames.indexOf(w.name) >= 0; var sat = w.satisfaction; var satColor = sat>=65?'#4caf50':sat>=40?'#e53935':sat>=12?'#ff9800':'#c62828'; var satIcon = sat>=65?'💗':sat>=40?'❤️':sat>=12?'🧡':'⚠️'; var satPct = Math.min(100,sat)+'%'; var canAfford = playerMoney >= ((SugarCube.State.variables.archetype === 'charismatic') ? Math.ceil(w.contractCost * 0.9) : w.contractCost); var classes = 'star-card' + (isElite ? ' lucky-gold' : isLucky ? ' lucky-silver' : ''); html += '\x3cdiv style="display:inline-block;vertical-align:top;margin:8px;">'; html += '\x3cdiv class="'+classes+'">'; if(isLucky) html += ''; html += '<img src="img/portraits/'+file+'.jpg" alt="'+w.name+'" style="cursor:zoom-in;" onclick="zoomPortrait(this.src)">'; html += '<div class="star-name">'+w.name+'</div>'; /* Check contract4 investor pick */ var sv5 = SugarCube.State.variables; var c4 = sv5.contract4; var isC4Star = c4 && c4.accepted && !c4.failed && (w.name === c4.star1 || w.name === c4.star2); html += '\x3cdiv class="star-stats">'; html += w.ageNum+' y.o. | '+w.hair+' | '+w.height+'<br>'; html += w.breast+' ('+w.breastType+') | '+(w.ethnicity||'—')+'<br>'; html += '🌟 Pop: <b>'+w.popularity+'</b>'; if(w.favPosition) html += '<br>💖 Pos: '+w.favPosition+(w.favPosition2?' & '+w.favPosition2:''); html += '<br>💳 $'+w.contractCost.toLocaleString(); html += '\x3c/div>'; html += '<div style="margin-top:8px;color:'+satColor+';font-weight:bold;">'+satIcon+' '+sat+'</div>'; html += '<div class="sat-bar"><div class="sat-bar-fill" style="width:'+satPct+';background:'+satColor+';"></div></div>'; if(isC4Star) html += '<div style="margin-top:6px;padding:3px 8px;background:#1a1000;border:1px solid #9e6a00;border-radius:5px;font-size:0.78em;color:#ffcc44;text-align:center;">📋 💼 Investor pick</div>'; html += '\x3c/div>'; /* Sign button directly under the card */ if(canAfford){ html += '\x3cdiv style="margin-top:6px;text-align:center;">'; html += '<button class="sign-btn link-internal" data-name="'+w.name+'" style="border-color:#4a9eff;color:#4a9eff;padding:5px 14px;border-radius:6px;background:#1a1a2e;border:1px solid #4a9eff;cursor:pointer;font-size:0.85em;transition:all 0.2s;">✅ Sign ($'+((SugarCube.State.variables.archetype==='charismatic')?Math.ceil(w.contractCost*0.9):w.contractCost).toLocaleString()+')</button>'; html += '\x3c/div>'; } else { html += '<div style="margin-top:6px;text-align:center;color:#cc4444;font-size:0.8em;">❌ Not enough funds</div>'; } html += '\x3c/div>'; }); html += '\x3c/div>'; var wrap = document.getElementById('draw-cards-container'); if(wrap){ wrap.innerHTML = html; wrap.querySelectorAll('.sign-btn').forEach(function(btn){ btn.addEventListener('mouseenter', function(){ this.style.background='#4a9eff'; this.style.color='#000'; }); btn.addEventListener('mouseleave', function(){ this.style.background='#1a1a2e'; this.style.color='#4a9eff'; }); btn.addEventListener('click', function(){ var name = this.getAttribute('data-name'); SugarCube.State.variables.drawSignName = name; SugarCube.State.variables.drawPool = SugarCube.State.variables.drawPool || 'beginner'; SugarCube.Engine.play('SignDrawStar'); }); }); } }); <</script>> <</if>> <<set $bDrawCost = $archetype is "gambler" ? 100 : 200>> <<set $cDrawCost = $archetype is "gambler" ? 250 : 500>> <<if $drawResult.length is 0>> <table style="width:100%;border-collapse:separate;border-spacing:6px;margin-bottom:8px;"> <tr> <td style="vertical-align:top;background:#111;border-radius:6px;padding:6px;width:33%;"> <b>🌟 Emerging Pool</b><br> <em style="font-size:0.85em;color:#888;">Scout: $<<= $bDrawCost>></em><br> <<set _bAvail = $poolBeginner.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<set _bMinCost = 9999>><<set _bMaxCost = 0>><<for _bi = 0; _bi < $poolBeginner.length; _bi++>><<set _bw = $recruitPool.find(function(w){ return w.name is $poolBeginner[_bi]; })>><<if _bw>><<if _bw.contractCost < _bMinCost>><<set _bMinCost = _bw.contractCost>><</if>><<if _bw.contractCost > _bMaxCost>><<set _bMaxCost = _bw.contractCost>><</if>><</if>><</for>> <em style="font-size:0.78em;color:#555;">💳 $<<= _bMinCost.toLocaleString()>>–$<<= _bMaxCost.toLocaleString()>></em><br> <em style="font-size:0.8em;color:#666;"><<= _bAvail.length>> available</em><br><<if !$pool1IntelItem.bought>><em style="font-size:0.78em;color:#555;">🔒 Pool 1 Intel for details</em><</if>><br> <<set _hasUpgrade = $pool1UpgradeItem.bought || $pool1Upgrade2A.bought>> <<set _cAvailForFallback = $poolConfirmed.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; }).length>> <<set _canDraw = (_bAvail.length > 0 || (_hasUpgrade && _cAvailForFallback > 0)) && $player.money >= $bDrawCost>> <<if _canDraw>> <<set _multiDraw = ($pool1Upgrade2D && $pool1Upgrade2D.bought) ? 4 : (($pool1Upgrade2C && $pool1Upgrade2C.bought) ? 3 : ($pool1Upgrade2B.bought ? 2 : 1))>> <<if _multiDraw >= 2 && (_bAvail.length + _cAvailForFallback >= 2)>> <<link `"🎲×" + _multiDraw + " Scout ($" + $bDrawCost + ")"`>> <<set $player.money -= $bDrawCost>><<set $drawPool = "beginner">><<set $drawResult = []>><<set $drawLuckyNames = []>><<set $drawEliteNames = []>> <<set _chance = 0>><<if $pool1Upgrade2A.bought>><<set _chance = 50>><<elseif $pool1UpgradeItem.bought>><<set _chance = 20>><</if>> <<set _eliteChance = 0>><<if $pool2Upgrade2.bought>><<set _eliteChance = 40>><<elseif $pool2UpgradeItem.bought>><<set _eliteChance = 15>><</if>> <<set _cAvail2 = $poolConfirmed.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<set _eAvail2 = $poolElite.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<set _bAvailNow = $poolBeginner.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<for _di = 0; _di < _multiDraw; _di++>> <<set _useElite = _eliteChance > 0 && random(1, 100) <= _eliteChance && _eAvail2.length > 0>> <<set _useUpgrade = _chance > 0 && random(1, 100) <= _chance && _cAvail2.length > 0>> <<set _b1Empty = _bAvailNow.length is 0 && _cAvail2.length > 0>> <<if _useElite>><<set $drawPool = "elite">><<set _ri = random(0, _eAvail2.length-1)>><<set $drawResult.push(_eAvail2[_ri])>><<set $drawEliteNames.push(_eAvail2[_ri])>><<set _eAvail2.splice(_ri, 1)>> <<elseif _useUpgrade || _b1Empty>><<set $drawPool = "confirmed">><<set _ri = random(0, _cAvail2.length-1)>><<set $drawResult.push(_cAvail2[_ri])>><<if _useUpgrade>><<set $drawLuckyNames.push(_cAvail2[_ri])>><</if>><<set _cAvail2.splice(_ri, 1)>> <<elseif _bAvailNow.length > 0>><<set _ri = random(0, _bAvailNow.length-1)>><<set $drawResult.push(_bAvailNow[_ri])>><<set _bAvailNow.splice(_ri, 1)>><</if>> <</for>> <<goto "Recruitment">> <</link>> <<else>> <<link `"🎲 Scout ($" + $bDrawCost + ")"`>> <<set $player.money -= $bDrawCost>><<set $drawPool = "beginner">><<set $drawLuckyNames = []>><<set $drawEliteNames = []>> <<set _chance = 0>><<if $pool1Upgrade2A.bought>><<set _chance = 50>><<elseif $pool1UpgradeItem.bought>><<set _chance = 20>><</if>> <<set _eliteChance = 0>><<if $pool2Upgrade2.bought>><<set _eliteChance = 40>><<elseif $pool2UpgradeItem.bought>><<set _eliteChance = 15>><</if>> <<set _useUpgrade = _chance > 0 && random(1, 100) <= _chance>> <<set _cAvail2 = $poolConfirmed.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<set _eAvail2 = $poolElite.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<set _bAvailNow = $poolBeginner.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<if $targetedScoutItem && $targetedScoutItem.bought && $targetedScoutStar>> <<if _bAvailNow.indexOf($targetedScoutStar) >= 0>><<set _bAvailNow = _bAvailNow.concat([$targetedScoutStar])>> <<elseif _cAvail2.indexOf($targetedScoutStar) >= 0>><<set _cAvail2 = _cAvail2.concat([$targetedScoutStar])>> <<elseif _eAvail2.indexOf($targetedScoutStar) >= 0>><<set _eAvail2 = _eAvail2.concat([$targetedScoutStar])>><</if>> <</if>> <<set _useElite = _eliteChance > 0 && random(1, 100) <= _eliteChance && _eAvail2.length > 0>> <<if _useElite>><<set $drawPool = "elite">><<set _ri = random(0, _eAvail2.length-1)>><<set $drawResult = [_eAvail2[_ri]]>><<set $drawEliteNames.push(_eAvail2[_ri])>> <<elseif (_useUpgrade || _bAvailNow.length is 0) && _cAvail2.length > 0>><<set $drawPool = "confirmed">><<set _ri = random(0, _cAvail2.length-1)>><<set $drawResult = [_cAvail2[_ri]]>><<if _useUpgrade>><<set $drawLuckyNames.push(_cAvail2[_ri])>><</if>> <<else>><<set _ri = random(0, _bAvailNow.length-1)>><<set $drawResult = [_bAvailNow[_ri]]>><</if>> <<goto "Recruitment">> <</link>> <</if>> <<elseif _bAvail.length is 0>><em style="color:#666;">Pool empty</em> <<else>>@@color:red;No funds@@ <</if>> </td> <td style="vertical-align:top;background:#111;border-radius:6px;padding:6px;width:33%;"> <b>🌟🌟 Established</b><br> <<set _cAvail = $poolConfirmed.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<set _cMinCost = 9999>><<set _cMaxCost = 0>><<for _ci = 0; _ci < $poolConfirmed.length; _ci++>><<set _cw = $recruitPool.find(function(w){ return w.name is $poolConfirmed[_ci]; })>><<if _cw>><<if _cw.contractCost < _cMinCost>><<set _cMinCost = _cw.contractCost>><</if>><<if _cw.contractCost > _cMaxCost>><<set _cMaxCost = _cw.contractCost>><</if>><</if>><</for>> <em style="font-size:0.78em;color:#555;">💳 $<<= _cMinCost.toLocaleString()>>–$<<= _cMaxCost.toLocaleString()>></em><br> <em style="font-size:0.8em;color:#666;"><<= _cAvail.length>> available</em><br><<if !$pool2IntelItem.bought>><em style="font-size:0.78em;color:#555;">🔒 Pool 2 Intel for details</em><</if>> <<if $pool2UpgradeItem.bought>><em style="font-size:0.75em;color:gold;"><<= $pool2Upgrade2.bought ? "40%" : "15%">> Elite chance</em><br><</if>> <em style="font-size:0.8em;color:#666;">Via Est. Dip upgrade</em> </td> <td style="vertical-align:top;background:#111;border-radius:6px;padding:6px;width:33%;"> <b>🌟🌟🌟 Elite</b><br> <<set _eAvail = $poolElite.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>> <<if $pool2UpgradeItem.bought>> <<set _eMinCost = 9999>><<set _eMaxCost = 0>><<for _ei = 0; _ei < $poolElite.length; _ei++>><<set _ew = $recruitPool.find(function(w){ return w.name is $poolElite[_ei]; })>><<if _ew>><<if _ew.contractCost < _eMinCost>><<set _eMinCost = _ew.contractCost>><</if>><<if _ew.contractCost > _eMaxCost>><<set _eMaxCost = _ew.contractCost>><</if>><</if>><</for>> <em style="font-size:0.78em;color:#555;">💳 $<<= _eMinCost.toLocaleString()>>–$<<= _eMaxCost.toLocaleString()>></em><br> <em style="font-size:0.8em;color:#666;"><<= _eAvail.length>> available</em><br><<if !$pool3IntelItem.bought>><em style="font-size:0.78em;color:#555;">🔒 Pool 3 Intel for details</em><</if>> <em style="font-size:0.8em;color:#666;">Via Elite Dip upgrade</em> <<else>> <em style="font-size:0.8em;color:#555;">Unlock via Elite Dip</em> <</if>> </td> </tr> </table> <</if>> <<if $pool1IntelItem.bought>><details><summary style="cursor:pointer;padding:6px 10px;background:#1a1a2e;border:1px solid #444;border-radius:6px;font-size:0.9em;color:#e0e0e0;list-style:none;">👁️ View Pool 1 — Emerging Talents</summary><div id="pool1-table" style="margin-top:8px;"></div></details><</if>> <<if $pool2IntelItem.bought>><details><summary style="cursor:pointer;padding:6px 10px;background:#1a1a2e;border:1px solid #444;border-radius:6px;font-size:0.9em;color:#e0e0e0;list-style:none;margin-top:6px;">👁️ View Pool 2 — Established Talents</summary><div id="pool2-table" style="margin-top:8px;"></div></details><</if>> <<if $pool3IntelItem.bought>><details><summary style="cursor:pointer;padding:6px 10px;background:#1a1a2e;border:1px solid #444;border-radius:6px;font-size:0.9em;color:#e0e0e0;list-style:none;margin-top:6px;">👁️ View Pool 3 — Elite Talents</summary><div id="pool3-table" style="margin-top:8px;"></div></details><</if>> <<script>> jQuery(document).one(':passageend', function(){ var sv = SugarCube.State.variables; var recruitPool = sv.recruitPool; var trends = sv.trends; function getStars(names){ return (names||[]).map(function(n){ return recruitPool.find(function(r){ return r.name===n; }); }).filter(Boolean); } var pools = [ { id: 'pool1-table', names: sv.poolBeginner, loaded: false }, { id: 'pool2-table', names: sv.poolConfirmed, loaded: false }, { id: 'pool3-table', names: sv.poolElite, loaded: false } ]; document.querySelectorAll('details').forEach(function(det){ var poolId = det.querySelector('div[id]') ? det.querySelector('div[id]').id : null; if(!poolId) return; var pool = pools.find(function(p){ return p.id === poolId; }); if(!pool) return; det.addEventListener('toggle', function(){ if(det.open && !pool.loaded){ pool.loaded = true; buildStarTable(getStars(pool.names), trends, -1, pool.id, function(){}, '<em>Pool empty.</em>', true); } }); }); }); <</script>> <<= ''>> [[⬅️ Dashboard|Dashboard]]
<<silently>> <<set _dw = $recruitPool.find(function(w){ return w.name is $drawSignName; })>> <<set _contractPrice = _dw.contractCost>> <<if $archetype is "charismatic">><<set _contractPrice = Math.ceil(_contractPrice * 0.9)>><</if>> <<set _dw.available = false>> <<set _dw.weekShootings = 0>> <<set _dw.lastShootingDay = $player.day>> <<set $drawResult = []>> <</silently>> <<if ($drawPool is "confirmed" || $poolConfirmed.indexOf(_dw.name) >= 0) && !$pool2Stolen>> <<silently>><<set $pool2Stolen = true>><<set $rival.roster.push(clone(_dw))>><</silently>> @@color:red;⚠️ <b>Outbid!</b> <<= $rival.name>> swooped in and offered <<= _dw.name>> a better deal at the last second.@@ <em>"Sorry... they made me an offer I couldn't refuse."</em> 💳 Contract cost refunded: <b>$<<= _contractPrice.toLocaleString()>></b> <<silently>><<set $poachingUnlocked = true>><</silently>> @@color:cyan;💡 <b>Poaching unlocked!</b> You can now invest in poaching rival stars from the Competition page.@@ [[👤 Keep scouting|Recruitment]] | [[📊 Dashboard|Dashboard]] <<else>> <<set $player.money -= _contractPrice>> <<silently>><<set $roster.push(clone(_dw))>> <<if $archetype is "charismatic">><<set $roster[$roster.length - 1].satisfaction = 15>><</if>> <<if $targetedScoutStar is _dw.name>><<set $targetedScoutStar = "">><</if>> <<if $roster.length is 3 && $thirdRecruitDay < 0>><<set $thirdRecruitDay = $player.day>><</if>><</silently>> ✅ <b><<= _dw.name>></b> signs with your agency! 💳 <b>$<<= _contractPrice.toLocaleString()>></b> paid | 🔄 <b>$<<= (_dw.popularity * 70).toLocaleString()>>/week</b> upkeep <<if $roster.length is 1 && $rivalStartStar>>@@color:red;⚠️ <b><<= $rival.name>> recruited <<= $rivalStartStar>>.</b>@@ <div id="rival-recruit-portrait-1" style="text-align:center;margin:6px 0;"></div> <<script>>jQuery(document).one(':passageend',function(){var n=SugarCube.State.variables.rivalStartStar;var el=document.getElementById('rival-recruit-portrait-1');if(el&&n){var f=n.toLowerCase().replace(/ /g,'_');el.innerHTML='<img style="width:100px;height:100px;object-fit:cover;border-radius:10px;box-shadow:0 4px 12px rgba(0,0,0,0.5);" src="img/portraits/'+f+'.jpg">';}SugarCube.State.variables.rivalStartStar='';});<</script>><</if>> <<if $roster.length is 2>><<silently>><<set _p1Avail = $poolBeginner.filter(function(n){ var w = $recruitPool.find(function(r){ return r.name is n; }); return w && w.available; })>><<if _p1Avail.length > 0>><<set _ri2 = random(0, _p1Avail.length - 1)>><<set _rs2name = _p1Avail[_ri2]>><<set _rs2 = $recruitPool.find(function(w){ return w.name is _rs2name; })>><<set _rs2.available = false>><<set $rival.roster.push(clone(_rs2))>><</if>><</silently>><<if _p1Avail.length > 0>><<silently>><<set $rivalRecruitName = _rs2name>><</silently>>@@color:red;⚠️ <b><<= $rival.name>> recruited <<= _rs2name>>.</b>@@ <div id="rival-recruit-portrait-2" style="text-align:center;margin:6px 0;"></div> <<script>>jQuery(document).one(':passageend',function(){var n=SugarCube.State.variables.rivalRecruitName;var el=document.getElementById('rival-recruit-portrait-2');if(el&&n){var f=n.toLowerCase().replace(/ /g,'_');el.innerHTML='<img style="width:100px;height:100px;object-fit:cover;border-radius:10px;box-shadow:0 4px 12px rgba(0,0,0,0.5);" src="img/portraits/'+f+'.jpg">';}});<</script>><</if>><</if>> [[👤 Keep scouting|Recruitment]] | [[📋 Roster|Roster]] <</if>> /* ════════════════════════════════════════════ PASSAGE : ROSTER ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">🏆 Trophies</h1> <div style="display:grid;gap:8px;margin:12px 0;"> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.fullHouse>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.fullHouse>>🏆<<else>>🔒<</if>> <b>Full House</b> — Sign 10 stars </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.empire>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.empire>>🏆<<else>>🔒<</if>> <b>Empire</b> — Sign 20 stars </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.dealMaker>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.dealMaker>>🏆<<else>>🔒<</if>> <b>Deal Maker</b> — Complete 5 contracts (<<= $totalContractsCompleted>>/5) </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.harderDeal>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.harderDeal>>🏆<<else>>🔒<</if>> <b>Harder Deal</b> — Complete a Harder Contract </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.asianDuoComplete>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.asianDuoComplete>>🏆<<else>>🔒<</if>> <b>Asian Duo</b> — Complete the Asian Duo questline </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.fallenAngelsComplete>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.fallenAngelsComplete>>🏆<<else>>🔒<</if>> <b>Fallen Angels</b> — Complete the Two Fallen Angels questline </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.firstMillion>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.firstMillion>>🏆<<else>>🔒<</if>> <b>First Million</b> — Earn $1,000,000 total (<<if $totalEarnings >= 1000000>>✅<<else>>$<<= $totalEarnings.toLocaleString()>><</if>>) </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.brokeBurBack>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.brokeBurBack>>🏆<<else>>🔒<</if>> <b>Broke But Back</b> — Survive a negative upkeep </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.firstPoach>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.firstPoach>>🏆<<else>>🔒<</if>> <b>Poacher</b> — Successfully poach a rival star </div> <div style="padding:8px 12px;background:#111;border-radius:6px;border:1px solid <<if $trophies.poachMaster>>#ffd700<<else>>#333<</if>>;"> <<if $trophies.poachMaster>>🏆<<else>>🔒<</if>> <b>Poach Master</b> — Poach 5 rival stars (<<= $totalPoachesSucceeded>>/5) </div> </div> [[⬅️ Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">📜 Questlines</h1> <<if $questlines.asianDuo.specialAvailable>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><<if $questlines.asianDuo.shooting2Done>><<if $asianDuoGoneDay > 0>><b>🎌 Asian Duo</b> @@color:gold;✅ Complete!@@<<else>><b>🎌 Asian Duo</b> @@color:cyan;Shootings done — story unfolding...@@<</if>><<elseif $questlines.asianDuo.shooting1Done>><b>🎌 Asian Duo</b> @@color:cyan;Step 5/6 — Second special available!@@<<elseif $questlines.asianDuo.specialAvailable>><b>🎌 Asian Duo</b> @@color:gold;Step 4/6 — Special shooting unlocked!@@<br><em style="font-size:0.85em;color:#888;">Kimmy & Lulu — first special available!</em><</if>></div> <<elseif $questlines.asianDuo.active>><<set _qlA = $questlines.asianDuo>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><b>🎌 Asian Duo</b> @@color:cyan;In progress — Step <<= _qlA.step>>/4@@<br><<if _qlA.step is 1>><em style="font-size:0.85em;color:#888;">Get <<= _qlA.star1>> to 25 satisfaction (<<= $roster.find(function(w){ return w.name is _qlA.star1; }) ? $roster.find(function(w){ return w.name is _qlA.star1; }).satisfaction : 0>>/25)</em><<elseif _qlA.step is 2>><em style="font-size:0.85em;color:#888;">Recruit <<= (_qlA.star1 is "Kimmy") ? "Lulu" : "Kimmy">></em><<elseif _qlA.step is 3>><em style="font-size:0.85em;color:#888;">Get <<= _qlA.star2>> to 25 satisfaction (<<= $roster.find(function(w){ return w.name is _qlA.star2; }) ? $roster.find(function(w){ return w.name is _qlA.star2; }).satisfaction : 0>>/25)</em><</if>></div> <<else>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;opacity:0.5;"><b>🎌 Asian Duo</b> 🔒 <em style="font-size:0.85em;color:#888;">Recruit Kimmy or Lulu to unlock</em></div> <</if>> <<if $questlines.fallenAngels.shooting3Done>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><<if $fallenAngelsGoneDay > 0>><b>👼 Two Fallen Angels</b> @@color:gold;✅ Complete!@@<<else>><b>👼 Two Fallen Angels</b> @@color:cyan;Shootings done — story unfolding...@@<</if>></div> <<elseif $questlines.fallenAngels.shooting2Done>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><b>👼 Two Fallen Angels</b> @@color:cyan;Step 6/6 — 3rd special!@@</div> <<elseif $questlines.fallenAngels.shooting1Done>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><b>👼 Two Fallen Angels</b> @@color:cyan;Step 5/6 — 2nd special!@@</div> <<elseif $questlines.fallenAngels.specialAvailable>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><b>👼 Two Fallen Angels</b> @@color:gold;Step 4/6 — Specials unlocked!@@</div> <<elseif $questlines.fallenAngels.active>><<set _qlF2 = $questlines.fallenAngels>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;"><b>👼 Two Fallen Angels</b> @@color:cyan;In progress — Step <<= _qlF2.step>>/6@@<br><<if _qlF2.step is 1>><em style="font-size:0.85em;color:#888;">Get <<= _qlF2.star1>> to 25 satis</em><<elseif _qlF2.step is 2>><em style="font-size:0.85em;color:#888;">Recruit <<= (_qlF2.star1 is "Angie") ? "Angela" : "Angie">></em><<elseif _qlF2.step is 3>><em style="font-size:0.85em;color:#888;">Get <<= _qlF2.star2>> to 25 satis</em><</if>></div> <<else>><div style="padding:10px;background:#111;border-radius:6px;margin:6px 0;opacity:0.5;"><b>👼 Two Fallen Angels</b> 🔒 <em style="font-size:0.85em;color:#888;">Recruit Angie or Angela to unlock</em></div> <</if>> [[⬅️ Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">🌟 Special Shootings</h1> <<if $questlines.asianDuo.specialAvailable && !$questlines.asianDuo.shooting1Done>> [[🎬 Kimmy & Lulu — First Special|AsianDuoShooting1]] <em style="font-size:0.85em;color:#888;">Their first collaboration together</em> <<elseif $questlines.asianDuo.shooting1Done && !$questlines.asianDuo.shooting2Done>> <<if $asianDuoShoot2Unlocked>>[[🎬 Kimmy & Lulu — Second Special|AsianDuoShooting2]]<<else>><em style="color:#888;">Second special available in <<= Math.max(0, ($asianDuoShoot1Day + 3) - $player.day)>> day(s)...</em><</if>> <em style="font-size:0.85em;color:#888;">The finale — their signature</em> <<elseif $questlines.asianDuo.shooting2Done>> <<if $asianDuoGoneDay > 0>><em style="color:#888;">✅ Asian Duo — complete</em><<else>><em style="color:#888;">🎌 Asian Duo — awaiting outcome...</em><</if>> <</if>> <<if $questlines.fallenAngels.specialAvailable && !$questlines.fallenAngels.shooting1Done>> [[👼 Angie & Angela — First Special|FallenAngelsShoot1]] <em style="font-size:0.85em;color:#888;">Two Fallen Angels — first scene together</em> <<elseif $questlines.fallenAngels.shooting1Done && !$questlines.fallenAngels.shooting2Done>> <<if $fallenAngelsShoot2Unlocked>>[[👼 Angie & Angela — Second Special|FallenAngelsShoot2]]<<else>><em style="color:#888;">Second special available in <<= Math.max(0, ($fallenAngelsShoot1Day + 3) - $player.day)>> day(s)...</em><</if>> <em style="font-size:0.85em;color:#888;">Two Fallen Angels — rising together</em> <<elseif $questlines.fallenAngels.shooting2Done && !$questlines.fallenAngels.shooting3Done>> <<if $fallenAngelsShoot3Unlocked>>[[👼 Angie & Angela — Third Special|FallenAngelsShoot3]]<<else>><em style="color:#888;">Third special available in <<= Math.max(0, ($fallenAngelsShoot2Day + 3) - $player.day)>> day(s)...</em><</if>> <em style="font-size:0.85em;color:#888;">Two Fallen Angels — the final act</em> <<elseif $questlines.fallenAngels.shooting3Done>> <<if $fallenAngelsGoneDay > 0>><em style="color:#888;">✅ Two Fallen Angels — complete</em><<else>><em style="color:#888;">👼 Two Fallen Angels — awaiting outcome...</em><</if>> <</if>> <<if !$questlines.asianDuo.specialAvailable && !$questlines.asianDuo.shooting1Done && !$questlines.fallenAngels.specialAvailable && !$questlines.fallenAngels.shooting1Done>> <em>No special shooting available yet. They are unlockable through questlines and events.</em> <</if>> [[⬅️ Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">📋 My Roster</h1> <<if $rosterMessage>>@@color:orange;⚠️ <<= $rosterMessage>>@@ <<set $rosterMessage = "">> <</if>> <<if $roster.length is 0>> <em>Your roster is empty.</em> <<else>> <div id="roster-controls" style="margin-bottom:12px;padding:10px;background:#111;border-radius:6px;"> <div style="margin-bottom:8px;"> <b style="font-size:0.9em;">Sort:</b> <span class="sort-btn" data-sort="name">Name</span> <span class="sort-btn" data-sort="satisfaction">❤️ Satisfaction</span> <span class="sort-btn" data-sort="popularity">🌟 Popularity</span> <span class="sort-btn" data-sort="ageNum">Age</span> </div> <div> <b style="font-size:0.9em;">Filter:</b> <span id="filter-list"></span> <span class="filter-clear" style="display:none;">✖ Clear</span> </div> </div> <div id="roster-cards"></div> <style> .sort-btn, .filter-btn, .filter-clear { display: inline-block; margin: 2px 4px; padding: 3px 10px; background: #1a1a2e; border: 1px solid #444; border-radius: 12px; cursor: pointer; font-size: 0.8em; transition: all 0.15s; } .sort-btn:hover, .filter-btn:hover, .filter-clear:hover { background: #2a2a4e; border-color: #888; } .sort-btn.active, .filter-btn.active { background: #4a9eff; color: #000; border-color: #4a9eff; } </style> <<script>> jQuery(document).one(':passageend', function(){ var roster = SugarCube.State.variables.roster; var trends = SugarCube.State.variables.trends; var sortKey = 'name'; var activeFilters = {}; var filterTypes = ['hair','height','breast','breastType','ethnicity']; var filterValues = {}; filterTypes.forEach(function(k){ filterValues[k] = []; }); roster.forEach(function(w){ filterTypes.forEach(function(k){ var v = w[k]; if(v && filterValues[k].indexOf(v) < 0) filterValues[k].push(v); }); }); var filterHtml = ''; filterTypes.forEach(function(k){ filterValues[k].sort().forEach(function(v){ filterHtml += '<span class="filter-btn" data-key="'+k+'" data-val="'+v+'">'+v+'</span>'; }); }); document.getElementById('filter-list').innerHTML = filterHtml; function applyView(){ var filtered = roster.filter(function(w){ for(var k in activeFilters){ if(activeFilters[k] && w[k] !== activeFilters[k]) return false; } return true; }); filtered.sort(function(a,b){ if(sortKey === 'name') return a.name < b.name ? -1 : 1; if(sortKey === 'satisfaction') return b.satisfaction - a.satisfaction; if(sortKey === 'popularity') return b.popularity - a.popularity; if(sortKey === 'ageNum') return a.ageNum - b.ageNum; return 0; }); buildStarCards(filtered, trends, 'roster-cards', null, [], false); /* Add Let Go buttons */ var cards = document.querySelectorAll('#roster-cards .star-card'); cards.forEach(function(card, i){ var star = filtered[i]; if(!star) return; var payout = Math.round(star.contractCost * 0.25); var btn = document.createElement('button'); btn.textContent = '\u{1F6AA} Let Go (+$'+payout.toLocaleString()+')'; btn.style.cssText = 'display:block;width:90%;margin:6px auto 2px;padding:5px 8px;background:#2b0d0d;border:1px solid #cc4444;color:#ff7a7a;border-radius:6px;cursor:pointer;font-size:0.78em;transition:all 0.2s;'; btn.addEventListener('mouseenter', function(){ this.style.background='#cc4444'; this.style.color='#fff'; }); btn.addEventListener('mouseleave', function(){ this.style.background='#2b0d0d'; this.style.color='#ff7a7a'; }); btn.addEventListener('click', function(e){ e.stopPropagation(); var sv = SugarCube.State.variables; var sat = star.satisfaction; var rivalChance; if(sat <= 10) rivalChance = 1.0; else if(sat >= 30) rivalChance = 0.10; else rivalChance = 1.0 - (sat - 10) * (0.90 / 20); var rivalPct = Math.round(rivalChance * 100); if(!confirm('Let go of '+star.name+'? You receive $'+payout.toLocaleString()+' (25% of contract). '+rivalPct+'% chance she joins '+sv.rival.name+'.')) return; sv.player.money += payout; var realIdx = sv.roster.findIndex(function(w){ return w.name === star.name; }); if(realIdx >= 0) sv.roster.splice(realIdx, 1); if(Math.random() < rivalChance){ sv.rival.roster.push(star); sv.rosterMessage = star.name+' was let go — and walked straight to '+sv.rival.name+'. She went to find out how massive they are.'; } else { /* Return star to recruit pool */ star.available = true; star.satisfaction = 10; star.weekShootings = 0; star.restDay = false; if(!sv.recruitPool) sv.recruitPool = []; sv.recruitPool.push(star); sv.rosterMessage = star.name+' has left the agency. You received $'+payout.toLocaleString()+'. She\'s back on the market.'; } SugarCube.Engine.play('Roster'); }); card.appendChild(btn); }); } document.querySelectorAll('.sort-btn').forEach(function(btn){ btn.addEventListener('click', function(){ document.querySelectorAll('.sort-btn').forEach(function(b){ b.classList.remove('active'); }); this.classList.add('active'); sortKey = this.getAttribute('data-sort'); applyView(); }); }); document.querySelectorAll('.filter-btn').forEach(function(btn){ btn.addEventListener('click', function(){ var key = this.getAttribute('data-key'); var val = this.getAttribute('data-val'); if(activeFilters[key] === val){ delete activeFilters[key]; this.classList.remove('active'); } else { document.querySelectorAll('.filter-btn[data-key="'+key+'"]').forEach(function(b){ b.classList.remove('active'); }); activeFilters[key] = val; this.classList.add('active'); } var hasFilters = Object.keys(activeFilters).length > 0; document.querySelector('.filter-clear').style.display = hasFilters ? 'inline-block' : 'none'; applyView(); }); }); document.querySelector('.filter-clear').addEventListener('click', function(){ activeFilters = {}; document.querySelectorAll('.filter-btn').forEach(function(b){ b.classList.remove('active'); }); this.style.display = 'none'; applyView(); }); document.querySelector('.sort-btn[data-sort="name"]').classList.add('active'); applyView(); }); <</script>> <</if>> [[⬅️ Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : OrgShooting — Choose format ════════════════════════════════════════════ */
<<silently>><<calcAllowedPositions>><</silently>> <h1 style="margin:0 0 0.4em 0;">🎬 Today's Production</h1> <<if $shootingPlayedToday>> @@color:orange;✋ Production already done today. Come back tomorrow!@@ [[📅 Next day|NextDay]] | [[⬅️ Dashboard|Dashboard]] <<elseif $roster.length < 1>> ⚠️ You need at least <b>1 talent</b> in your roster. [[👤 Recruit|Recruitment]] | [[⬅️ Dashboard|Dashboard]] <<else>> You can use <b><<= $allowedPositions>> position(s)</b> today <em>(rep: <<= $player.reputation>>)</em>. <b>Choose a format:</b> [[📽️ Solo production|OrgShootingClassic][$advancedFormat = false, $selectedPositions = []]] <<if $player.reputation >= $advancedThreshold>> [[🌟 Two Shootings in a Day|OrgShootingAdvanced][$advancedFormat = true, $selectedPositions = []]] <<else>> 🔒 <b>Two Shootings in a Day</b> <em>(Reputation <<= $advancedThreshold>> required — you have <<= $player.reputation>>)</em> <</if>> [[⬅️ Dashboard|Dashboard]] <</if>> /* ════════════════════════════════════════════ PASSAGE : Classic format — Pick talent ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">📽️ Solo production — Pick your talent</h1> <div id="star-select-table"></div> <<script>> jQuery(document).one(':passageend', function(){ buildStarTable( SugarCube.State.variables.roster, SugarCube.State.variables.trends, -1, 'star-select-table', function(idx){ SugarCube.State.variables.shootingC1 = idx; SugarCube.State.variables.shootingC2 = -1; SugarCube.Engine.play('PickPositions'); }, '⚠️ No talents available — all are resting today!' ); }); <</script>> [[⬅️ Cancel|OrgShooting]]
<h1 style="margin:0 0 0.4em 0;">🌟 Two Shootings in a Day — Pick first talent</h1> <div id="star-select-table"></div> <<script>> jQuery(document).one(':passageend', function(){ buildStarTable( SugarCube.State.variables.roster, SugarCube.State.variables.trends, -1, 'star-select-table', function(idx){ SugarCube.State.variables.shootingC1 = idx; SugarCube.Engine.play('OrgShootingAdvanced2'); }, '⚠️ You need at least <b>2 talents</b> available for this format.' ); }); <</script>> [[⬅️ Cancel|OrgShooting]]
<h1 style="margin:0 0 0.4em 0;">🌟 First talent: <<= $roster[$shootingC1].name>></h1> <div id="star-select-table"></div> <<script>> jQuery(document).one(':passageend', function(){ buildStarTable( SugarCube.State.variables.roster, SugarCube.State.variables.trends, SugarCube.State.variables.shootingC1, 'star-select-table', function(idx){ SugarCube.State.variables.shootingC2 = idx; SugarCube.Engine.play('PickPositions'); }, '⚠️ You need at least <b>2 available talents</b> for this format.' ); }); <</script>> [[⬅️ Cancel|OrgShooting]] /* ════════════════════════════════════════════ PASSAGE : Pick styles for the production ════════════════════════════════════════════ */
<<calcAllowedPositions>><<set _w1 = $roster[$shootingC1]>><<if $shootingC2 >= 0>><<set _w2 = $roster[$shootingC2]>><<else>><<set _w2 = null>><</if>><strong>🎭 Pick Your Positions</strong> <<if $advancedFormat>><b><<= $player.name>> & <<= _w1.name>></b> and <b><<= $player.name>> & <<= _w2.name>></b><<else>><b><<= $player.name>></b> with <b><<= _w1.name>></b><</if>> | <b>Slots:</b> <<= $selectedPositions.length>>/<<= $allowedPositions>> | 🎬 Trending: @@color:gold;<b><<= $trends.position || "?">></b>@@ (+rep) <div style="padding:6px 10px;background:#111;border-radius:6px;font-size:0.85em;margin:4px 0;">💖 <<= _w1.name>>: <b><<= _w1.favPosition>><<if _w1.favPosition2>> & <<= _w1.favPosition2>><</if>></b><<if !_w1.bonusChosen>> <em style="color:#666">| 🔓 sat.30: <<= _w1.bonusPosition1>> / <<= _w1.bonusPosition2>></em><</if>><<if $advancedFormat && _w2>><br>💖 <<= _w2.name>>: <b><<= _w2.favPosition>><<if _w2.favPosition2>> & <<= _w2.favPosition2>><</if>></b><<if !_w2.bonusChosen>> <em style="color:#666">| 🔓 sat.30: <<= _w2.bonusPosition1>> / <<= _w2.bonusPosition2>></em><</if>><</if>></div> <div style="margin:4px 0;"><<for _i = 0; _i < $playerPositions.length; _i++>><<set _mn = $playerPositions[_i]>><<set _isTrend = (_mn is $trends.position)>><<set _posObj = $allPositions.find(function(p){ return p.name is _mn; })>><<set _minSat = _posObj ? (_posObj.minSat || 0) : 0>><<set _sat1 = _w1 ? _w1.satisfaction : 100>><<set _sat2 = _w2 ? _w2.satisfaction : 100>><<set _minRosterSat = $advancedFormat ? Math.min(_sat1, _sat2) : _sat1>><<set _satLocked = _minRosterSat < _minSat>><<if $selectedPositions.includes(_mn)>><span style="display:inline-block;margin:2px;padding:3px 8px;background:#1a3a1a;border:1px solid #4a4;border-radius:4px;">✅ <<if _isTrend>>@@color:gold;<b><<= _mn>></b>@@<<else>><b><<= _mn>></b><</if>></span><<elseif _satLocked>><span style="display:inline-block;margin:2px;padding:3px 8px;background:#1a1a1a;border:1px solid #444;border-radius:4px;opacity:0.5;" title="Requires <<= _minSat>> satisfaction">🔒 <<= _mn>> <em style="font-size:0.8em">(sat.<<= _minSat>>)</em></span><<elseif $selectedPositions.length < $allowedPositions>><<if _isTrend>><<capture _mn>>@@color:gold;<span style="display:inline-block;margin:2px;"><<print "[[🌟 " + _mn + "|AddPosition][$positionToAdd = \"" + _mn + "\"]]">></span>@@<</capture>><<else>><<capture _mn>><span style="display:inline-block;margin:2px;"><<print "[[" + _mn + "|AddPosition][$positionToAdd = \"" + _mn + "\"]]">></span><</capture>><</if>><<else>><span style="display:inline-block;margin:2px;padding:3px 8px;background:#1a1a1a;border:1px solid #333;border-radius:4px;opacity:0.4;"><<= _mn>></span><</if>><</for>></div> <<if $selectedPositions.length > 0>><div style="padding:4px 10px;background:#111;border-radius:4px;font-size:0.85em;margin:4px 0;"><b>Selected:</b> <<= $selectedPositions.join(", ")>></div><</if>> <<if $selectedPositions.length >= 1>>[[🎬 Run the production!|RunShooting]]<</if>> [[⬅️ Cancel|OrgShooting]] /* ════════════════════════════════════════════ PASSAGE : AddPosition ════════════════════════════════════════════ */
<<set $selectedPositions.push($positionToAdd)>><<goto "PickPositions">> /* ════════════════════════════════════════════ PASSAGE : RunShooting ════════════════════════════════════════════ */
<<silently>><<set _w1 = $roster[$shootingC1]>><<if $shootingC2 >= 0>><<set _w2 = $roster[$shootingC2]>><<else>><<set _w2 = null>><</if>><<set $shootingLastPosition = $selectedPositions[$selectedPositions.length - 1].toLowerCase().replace(/ /g, "_")>><<set $shootingW1File = _w1.name.toLowerCase().replace(/ /g, "_")>><<if _w2>><<set $shootingW2File = _w2.name.toLowerCase().replace(/ /g, "_")>><<else>><<set $shootingW2File = "">><</if>><<resolveShooting _w1 _w2 $advancedFormat>><<set $shootingPlayedToday = true>><</silently>><h1 style="margin:0 0 0.3em 0;">🎬 Production Result!</h1> <<if $advancedFormat>><b><<= $player.name>> & <<= _w1.name>></b> and <b><<= $player.name>> & <<= _w2.name>></b><<else>><b><<= $player.name>></b> with <b><<= _w1.name>></b><</if>> Cut! <<if $advancedFormat>>Both talents gave everything — raw, unfiltered, completely uninhibited. The crew is speechless.<<else>><<= _w1.name>> delivered exactly what the audience wanted — raw, unfiltered, and completely uninhibited.<</if>> <b>Positions used:</b> <<= $selectedPositions.join(", ")>> <div id="shooting-videos"></div> <<script>> jQuery(document).one(':passageend', function(){ var sv = SugarCube.State.variables; var w1 = sv.shootingW1File; var w2 = sv.shootingW2File; var pos = sv.shootingLastPosition; var wrap = document.getElementById('shooting-videos'); if(!wrap) return; var html = ''; if(w1 && pos){ html += '<video src="videos/'+w1+'_'+pos+'.webm" autoplay loop muted playsinline style="width:100%;max-width:560px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; } if(w2 && pos){ html += '<video src="videos/'+w2+'_'+pos+'.webm" autoplay loop muted playsinline style="width:100%;max-width:560px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; } wrap.innerHTML = html; }); <</script>> <<if $lastCarBonus || $lastCarBonus2>>💰 <b class="gain-reveal glow-gold">Earnings: $<<= $lastGain.toLocaleString()>></b> <em>(×<<= $lastMulti>> physical trend bonus)</em><<else>>💰 <b>Earnings: $<<= $lastGain.toLocaleString()>></b><</if>> <<if $lastPositionBonus>>🌟 <b class="gain-reveal glow-gold">Reputation: +<<= $lastRepBonus>></b> <em>(✅ Trending genre «<<= $trends.position>>»: +2 bonus)</em><<else>>🌟 <b>Reputation: +<<= $lastRepBonus>></b><</if>> <<if $lastCarBonus>> <em>💥 <<if $trends.carType is "breast">>The crowd went feral the second <<= $lastCarBonus>> got on screen — those <<= $trends.carValue>> tits had them stroking their screens<<elseif $trends.carType is "breastType">>><<= $lastCarBonus>>'s <<= $trends.carValue>> tits broke the internet tonight — fans know what they want and they got it<<elseif $trends.carType is "hair">>Every fantasy about <<= $trends.carValue>> hair came true the moment <<= $lastCarBonus>> let it loose on those sheets<<elseif $trends.carType is "height">>That <<= $trends.carValue>> body on <<= $lastCarBonus>> wrapped around the camera like a dream — the comments section is on fire<<elseif $trends.carType is "ageCat" && $trends.carValue is "Young">>Barely legal and completely uninhibited — <<= $lastCarBonus>> left the audience begging for a second take<<elseif $trends.carType is "ageCat" && $trends.carValue is "Veteran">>><<= $lastCarBonus>> fucked like she had something to prove — and a decade of experience to back it up<<elseif $trends.carType is "ageCat">>><<= $lastCarBonus>> knew exactly what buttons to push — old enough to own it, young enough to go all night<<elseif $trends.carType is "ethnicity">>The audience had one type on their mind tonight — <<= $trends.carValue>> — and <<= $lastCarBonus>> delivered every single fantasy<<else>>✅ <<= $trends.carType>>: <<= $trends.carValue>> — <<= $lastCarBonus>><</if>></em> <</if>> <<if $lastCarBonus2>> <em>💥 <<if $trends.carType2 is "breast">>The crowd went feral the second <<= $lastCarBonus2>> got on screen — those <<= $trends.carValue2>> tits had them stroking their screens<<elseif $trends.carType2 is "breastType">>><<= $lastCarBonus2>>'s <<= $trends.carValue2>> tits broke the internet tonight — fans know what they want and they got it<<elseif $trends.carType2 is "hair">>Every fantasy about <<= $trends.carValue2>> hair came true the moment <<= $lastCarBonus2>> let it loose on those sheets<<elseif $trends.carType2 is "height">>That <<= $trends.carValue2>> body on <<= $lastCarBonus2>> wrapped around the camera like a dream — the comments section is on fire<<elseif $trends.carType2 is "ageCat" && $trends.carValue2 is "Young">>Barely legal and completely uninhibited — <<= $lastCarBonus2>> left the audience begging for a second take<<elseif $trends.carType2 is "ageCat" && $trends.carValue2 is "Veteran">>><<= $lastCarBonus2>> fucked like she had something to prove — and a decade of experience to back it up<<elseif $trends.carType2 is "ageCat">>><<= $lastCarBonus2>> knew exactly what buttons to push — old enough to own it, young enough to go all night<<elseif $trends.carType2 is "ethnicity">>The audience had one type on their mind tonight — <<= $trends.carValue2>> — and <<= $lastCarBonus2>> delivered every single fantasy<<else>>✅ <<= $trends.carType2>>: <<= $trends.carValue2>> — <<= $lastCarBonus2>><</if>></em> <</if>> <<if $contract3Success>>@@color:gold;📋 <b>Established Contract complete!</b> <<= $contract3.starName>> +2 pop, +$500, +1 rep@@<<set $contract3Success = false>><<silently>> <<set $contract4 = { active: false, accepted: false, star1: "", star2: "", shootingsDone: 0, failed: false }>> <<set $contract4Success = false>> <<set $asianDuoLastShootingDay = -1>> <<set $asianDuoShoot1Day = -1>> <<set $asianDuoShoot2Unlocked = false>> <<set $fallenAngelsShoot1Day = -1>> <<set $fallenAngelsShoot2Day = -1>> <<set $fallenAngelsShoot2Unlocked = false>> <<set $fallenAngelsShoot3Unlocked = false>> <<set $asianDuoAbsentDay = -1>> <<set $asianDuoAbsentNotified = false>> <<set $asianDuoGoneDay = -1>> <<set $asianDuoGoneNotified = false>> <<set $asianDuoWebm2Day = -1>> <<set $asianDuoWebm3Day = -1>> <<set $fallenAngelsLastShootingDay = -1>> <<set $fallenAngelsAbsentDay = -1>> <<set $fallenAngelsAbsentNotified = false>> <<set $fallenAngelsGoneDay = -1>> <<set $fallenAngelsGoneNotified = false>> <<set $fallenAngelsWebm2Day = -1>> <<set $fallenAngelsWebm3Day = -1>> <<set $questlines = { asianDuo: { id: "asianDuo", name: "Asian Duo", active: false, step: 0, star1: "", star2: "", specialAvailable: false, shooting1Done: false, shooting2Done: false }, fallenAngels: { id: "fallenAngels", name: "Two Fallen Angels", active: false, step: 0, star1: "", star2: "", specialAvailable: false, shooting1Done: false, shooting2Done: false, shooting3Done: false } }>> <</silently>><</if>> <<if $rivalOfferChallengeWon>>@@color:gold;🌟 <b><<= $rivalOfferStar>> chose to stay!</b> +1 popularity, +10 satisfaction@@<<set $rivalOfferChallengeWon = false>><</if>><<if $contract1Success>><<if $contractIsHarder>>@@color:gold;📋 <b>Harder Contract completed!</b> +$1,500, +5 rep@@<<else>>@@color:gold;📋 <b>Contract completed!</b> +3 rep, +$500@@<</if>><<set $contract1Success = false>><<set $contractIsHarder = false>><</if>><<if $skillfulChallengeWon>>@@color:gold;⚡ Challenge completed! +5 reputation!@@<<set $player.reputation += 5>><<set $skillfulChallengeWon = false>><</if>><<if $popularityAlert>>@@color:gold;🌟 <b><<= $popularityAlert>></b> hit popularity 50 — they're a superstar!@@<<set $popularityAlert = "">><</if>><<if $bonusChoiceStar>>@@color:cyan;💖 <b><<= $bonusChoiceStar>></b> reached 30 satisfaction! She's learning to love a new position.@@<</if>> <<if $lastPopGain.length > 0>><<for _pgi = 0; _pgi < $lastPopGain.length; _pgi++>>🌟 <b class="gain-reveal glow-gold"><<= $lastPopGain[_pgi].name>> gained popularity! Now 🌟<<= $lastPopGain[_pgi].pop>></b><br><</for>><</if>> <b>Satisfaction after production:</b> <<= _w1.name>>: ❤️ <<= _w1.satisfaction>><<if _w1.restDay>> 😴<</if>><<if $advancedFormat && _w2>> | <<= _w2.name>>: ❤️ <<= _w2.satisfaction>><<if _w2.restDay>> 😴<</if>><</if>> <<set $selectedPositions = []>> <<if $roxyEventTriggered && $roxyTriggerStar>>[[🌟 Special Event!|RoxyEvent]]<<elseif $bonusChoiceStar>>[[💖 Choose their bonus position|BonusPositionChoice]]<<else>>[[📊 Dashboard|Dashboard]] | [[📅 Next day|NextDay]]<</if>>
<h1 style="margin:0 0 0.4em 0;">🎯 New Objective!</h1> Your phone buzzes. An industry contact sends you a message: <em>"The market is watching. If you can't field a proper roster by Day 15, you'll be laughed out of the business. You need at least <b>3 talents</b> signed by then."</em> @@color:cyan;Progress: <<= $roster.length>>/3 talents signed@@ <<if $roster.length >= 3>> @@color:green;✅ You're already there — well done!@@ <<else>> @@color:orange;⚠️ You have until Day 15. Don't waste time.@@ <</if>> [[📊 Dashboard|Dashboard]] | [[👤 Recruit|Recruitment]]
<h1 style="margin:0 0 0.4em 0;">💀 Game Over</h1> You didn't manage to sign <b>3 talents</b> before <b>Day 15</b>. Without enough talent, your agency collapses. <<= $rival.name>> takes over the market. <em>"Should've moved faster."</em>
<<set $rep15EventPending = false>> <h1 style="margin:0 0 0.4em 0;">🌟 Reputation Milestone!</h1> You've reached reputation 15! Your agency is making waves. <<if $archetype is "rich">> Your accountant calls, sounding almost aroused by the numbers. <em>"The portfolio is performing beautifully. Just like your roster. Your returns just came in."</em> [[💰 Take $2,000|Rep15Rich1]] <<elseif $archetype is "skillful">> A trade daynalist reaches out. <em>"I've been watching your productions. If you can pull off a trending position in the next 3 days, I'll run a feature on your agency. That kind of exposure is worth a lot."</em> <b>Challenge:</b> use a trending position in a production within 3 days. [[✅ Accept the challenge|Rep15Skillful]] <<elseif $archetype is "charismatic">> Your talents gather before the shoot, half-dressed and glowing. <em>"You make us want to give everything. Every. Single. Time."</em> One of them steps closer. The room gets warm. <b>All your talents gain +5 satisfaction!</b> [[💖 Accept their gratitude|Rep15Charismatic]] <<elseif $archetype is "gambler">> A stranger leans against the wall outside, watching you with a smirk. <em>"You've got that look. Like you know how to play rough and win. Heads or tails — $3,000 says I win."</em> She flips a coin in the air and catches it. [[🪙 Heads|Rep15GamblerFlip][$gamblerChoice = "heads"]] [[🪙 Tails|Rep15GamblerFlip][$gamblerChoice = "tails"]] <</if>> /* ════════════════════════════════════════════ PASSAGE : Rep15GamblerFlip ════════════════════════════════════════════ */
<<set _flip = either("heads", "tails")>> <<if $gamblerChoice is _flip>> <h1 style="margin:0 0 0.4em 0;">🪙 You win!</h1> The coin lands your way. The stranger laughs and hands over the cash. <em>"Not bad. You've got luck on your side."</em> 💰 <b>+$3,000</b> added to your account! <<set $player.money += 3000>> <<else>> <h1 style="margin:0 0 0.4em 0;">🪙 You lose.</h1> The coin doesn't land your way. You shrug it off — that's the game. <em>"Better luck next time, friend."</em> <em>You walk away empty-handed.</em> <</if>> [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : Rep15Rich1 ════════════════════════════════════════════ */
<<set $player.money += 2000>> 💰 <b>+$2,000</b> added to your account! [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : Rep15Rich2 ════════════════════════════════════════════ */
<<set _stella = $recruitPool.find(function(w){ return w.name is "Eliza"; })>> <<if _stella>><<set _stella.repMin = 0>><</if>> 🌟 <b>Eliza</b> is now available in recruitment! <em>"I heard you've been doing great things. Let's talk."</em> [[👤 Go to Recruitment|Recruitment]] | [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : Rep15Skillful ════════════════════════════════════════════ */
<<set $skillfulChallengeActive = true>> <<set $skillfulChallengeEndDay = $player.day + 3>> ⚡ Challenge active! Use a 'trending position' in a production before day <<= $skillfulChallengeEndDay>>. [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : Rep15Charismatic ════════════════════════════════════════════ */
<<for _i = 0; _i < $roster.length; _i++>> <<set $roster[_i].satisfaction = Math.min(100, $roster[_i].satisfaction + 5)>> <</for>> <b>💖 All talents gain +5 satisfaction!</b> [[📊 Dashboard|Dashboard]]
<<set _os = $roster.find(function(w){ return w.name is $rivalOfferStar; })>> <h1 style="margin:0 0 0.4em 0;">💬 <<= $rivalOfferStar>> Has Something to Say</h1> <<set _roeFile = $rivalOfferStar.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img data-portrait-var="_roeFile" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <em>"Hey... I need to talk to you. <<= $rival.name>> reached out to me. They made me an offer."</em> <em>"They called me. Offered more shoots, better positions, more money. I turned them down... but I'd be lying if I said I wasn't tempted. I need to know you still want me — on set and off it."</em> <<if _os>> <b><<= _os.name>></b> — 🌟 Pop: <<= _os.popularity>> <em style="color:#888">(lowest in your roster)</em> | ❤️ Sat: <<= _os.satisfaction>> <b>Contract cost:</b> $<<= _os.contractCost.toLocaleString()>> | Severance if they leave: <b>$<<= Math.ceil(_os.contractCost * 0.5).toLocaleString()>></b> <</if>> [[🎬 Keep them — 3 productions in 4 days|RivalOfferKeep]] [[👋 Let them go|RivalOfferLeave]]
<<set $rivalOfferShootingsLeft = 3>> <<set $rivalOfferDeadlineDay = $player.day + 4>> <<set $rivalOfferEvent = false>> <<set _os = $roster.find(function(w){ return w.name is $rivalOfferStar; })>> <<if _os>><<set _os.consecutiveDays = 0>><<set _os.restDay = false>><</if>> <em>"Fine. But I want to feel wanted — on set and in front of that camera. Put me to work. Show me you still know what to do with me."</em> <b><<= $rivalOfferStar>></b> stays — you must feature them in <b>3 productions within 4 days</b>. If you do, they gain +1 popularity and +10 satisfaction. If you fail, they leave with no severance. [[📊 Dashboard|Dashboard]]
<<set _os = $roster.find(function(w){ return w.name is $rivalOfferStar; })>> <<if _os>> <<set $rival.roster.push(clone(_os))>> <<set $roster.delete(_os)>> <</if>> <<set $rivalOfferEvent = false>> <em>"I understand. Thanks for the opportunity."</em> @@color:red;<b><<= $rivalOfferStar>></b> has joined <<= $rival.name>>. Heard she couldn't stop smiling after her first day there.@@ [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">📰 A New Player on the Market</h1> An industry insider sends you an encrypted message. <em>"Heads up. There's a new studio that just incorporated — well-funded, aggressive, and they're already making calls. Word is they're going after the same talent pool as you and <<= $rival.name>>."</em> <em>"They don't have a name yet. But they will soon. And when they do, the market won't be the same."</em> This concerns both you and <<= $rival.name>>. The landscape is about to get more crowded. @@color:orange;⚠️ A third competitor is rising. Keep an eye on the market.@@ [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">📰 Industry News</h1> A contact in the industry sends you a message. <em>"Heard through the grapevine that <<= $rival.name>> is having serious cash flow problems. Word is they might be forced to let some of their talents go soon — maybe as early as day 30. Could be an opportunity for you..."</em> <<if $rival.roster.length > 0>> Their current roster has <b><<= $rival.roster.length>> talent(s)</b>. Keep an eye on the situation. <<else>> <em>Looks like they don't have anyone right now anyway.</em> <</if>> [[📊 Dashboard|Dashboard]]
<<set _maxPop = 0>> <<for _i = 0; _i < $roster.length; _i++>> <<if $roster[_i].popularity > _maxPop>><<set _maxPop = $roster[_i].popularity>><</if>> <</for>> <<set _ri = random(0, $rival.roster.length - 1)>> <<set _rivalStar = $rival.roster[_ri]>> <h1 style="margin:0 0 0.4em 0;">💸 <<= $rival.name>> in Trouble!</h1> Rumours spread through the industry — <<= $rival.name>> has taken a massive financial hit. <em>"We're restructuring. Some contracts need to go."</em> <<set _rivalFile = _rivalStar.name.toLowerCase().replace(/ /g, "_")>> <div style="display:flex;align-items:flex-start;gap:16px;margin:12px 0;padding:12px;background:#111;border-radius:8px;"> <img data-portrait-var="_rivalFile" style="width:120px;height:120px;object-fit:cover;border-radius:10px;flex-shrink:0;" src=""> <div> <b style="font-size:1.05em;"><<= _rivalStar.name>></b><br> <em style="color:#888;"><<= _rivalStar.ageNum>> y.o. | <<= _rivalStar.hair>> | <<= _rivalStar.height>></em><br> <em style="color:#888;"><<= _rivalStar.breast>> (<<= _rivalStar.breastType>>) | <<= _rivalStar.ethnicity>></em><br> 💖 <<= _rivalStar.favPosition>><br> 🌟 Pop: <b><<= _maxPop>></b> <em style="color:#666;">(matched to your best)</em> </div> </div> <<set _discountPrice = Math.ceil(_rivalStar.contractCost * 0.5)>> 💳 Contract: <b>$<<= _discountPrice.toLocaleString()>></b> <em style="color:#888;">(50% off — rival's loss, your gain!)</em> <<capture _ri _rivalStar _maxPop _discountPrice>> <<if $player.money >= _discountPrice>> [[✅ Sign them|Day22Sign][$day22Idx = _ri, $day22Pop = _maxPop, $day22Price = _discountPrice]] [[❌ Pass|Dashboard]] <<else>> @@color:red;Not enough funds ($<<= _discountPrice.toLocaleString()>> required)@@ [[❌ Pass|Dashboard]] <</if>> <</capture>> /* ════════════════════════════════════════════ PASSAGE : Day22Sign ════════════════════════════════════════════ */
<<set _w = $rival.roster[$day22Idx]>> <<set _w.popularity = $day22Pop>> <<set _w.satisfaction = 10>> <<set _w.lastShootingDay = $player.day>> <<set _w.weekShootings = 0>> <<set _w.totalShootings = 0>> <<set _w.consecutiveDays = 0>> <<set _w.restDay = false>> <<set $player.money -= $day22Price>> <<set $roster.push(clone(_w))>> <<set $rival.roster.deleteAt($day22Idx)>> ✅ <b><<= _w.name>></b> joins your roster with popularity <b><<= $day22Pop>></b>! <em>"Glad to be somewhere stable for once."</em> [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">📋 New Contract!</h1> <em>"We need 2 consecutive productions featuring a specific type of talent. Pick a brief that works for you."</em> <<if $contractIsHarder>><b>Reward:</b> +$1,500, +5 rep | <b>Fail:</b> −5 rep<<else>><b>Reward:</b> +3 rep, +$500 | <b>Fail:</b> −2 rep<</if>> <b>Your roster:</b> <div id="contract-roster-table"></div> <b>Choose a brief:</b> <<for _oi = 0; _oi < $contract1.options.length; _oi++>><<set _opt = $contract1.options[_oi]>><<set _hasEligible = false>><<for _ri = 0; _ri < $roster.length; _ri++>><<if $roster[_ri][_opt.type] is _opt.value>><<set _hasEligible = true>><</if>><</for>><<capture _oi _opt _hasEligible>><div style="margin:3px 0;padding:5px 10px;background:#111;border-radius:4px;"><<if $contractIsHarder && _opt.type2>><b><<= _opt.value>></b> <em style="color:#888">(<<= _opt.type>>)</em> + <b><<= _opt.value2>></b> <em style="color:#888">(<<= _opt.type2>>)</em><<else>><b><<= _opt.value>></b> <em style="color:#888">(<<= _opt.type>>)</em><</if>> <<if _hasEligible>>@@color:green;✅ you have one@@<<else>>@@color:red;⚠️ none@@<</if>> <<if $contractIsHarder && _opt.type2>>[[✅ Accept|Contract1Accept][$contract1.criteriaType = _opt.type, $contract1.criteria = _opt.value, $contract1.criteriaType2 = _opt.type2, $contract1.criteria2 = _opt.value2]]<<else>>[[✅ Accept|Contract1Accept][$contract1.criteriaType = _opt.type, $contract1.criteria = _opt.value]]<</if>></div><</capture>><</for>> [[❌ Refuse all|Contract1Refuse]] <<script>> jQuery(document).one(':passageend', function(){ buildStarTable(SugarCube.State.variables.roster, SugarCube.State.variables.trends, -1, 'contract-roster-table', function(){}, '<em>Roster empty.</em>'); }); <</script>>
<<set $contract1.accepted = true>><<set $contract1.startDay = $player.day>><<set $contract1.shootingsDone = 0>><<set $contract1.active = false>> <b>Contract accepted!</b> You have <b>3 days</b> to complete 2 productions featuring <<if $contractIsHarder>>a <b><<= $contract1.criteria>></b> <<= $contract1.criteriaType>> AND <b><<= $contract1.criteria2>></b> <<= $contract1.criteriaType2>> talent.<<else>>a <b><<= $contract1.criteria>></b> <<= $contract1.criteriaType>> talent.<</if>> [[📊 Dashboard|Dashboard]]
<<set $contract1.active = false>> <<set $contractShopAvailableDay = $player.day + 1>> <em>"Understood. Maybe next time."</em> [[📊 Dashboard|Dashboard]]
<<set $contract1.failed = false>> <h1 style="margin:0 0 0.4em 0;">❌ Contract Failed</h1> @@color:red;You failed to complete the contract in time.@@ <<if $contractIsHarder>>The client is furious. <b>−5 reputation.</b><<else>>The client is disappointed. <b>−2 reputation.</b><</if>> [[📊 Dashboard|Dashboard]]
<<set $contract3.active = false>> <h1 style="margin:0 0 0.4em 0;">📋 Established Contract (⭐⭐)</h1> An independent producer reaches out. <em>"I've heard about your agency. I need a confirmed star for an urgent shoot — you have until day 40. If you accept, I'll advance you $1,000 now."</em> <em>"Any star from your Established pool (⭐⭐) will do."</em> <div style="padding:8px 12px;background:#111;border-radius:6px;font-size:0.85em;"> ⏳ Deadline: before <b>day 40</b> (<<= 40 - $player.day>> day(s) remaining)<br> ✅ Accepted: <b>+$1,000</b> advance<br> 🏆 Success: <b>+2 pop</b> on the star, <b>+$500</b>, <b>+1 rep</b><br> ❌ Fail: <b>−$2,000</b> </div> [[✅ Accept|Contract3Accept]] [[❌ Refuse|Contract3Refuse]]
<<set $contract3.accepted = true>> <<set $contract3.startDay = $player.day>> <<set $contract3.shootingsDone = 0>> <<set $contract3.failed = false>> <<set $contract3.active = false>> <<set $player.money += 1000>> ✅ Contract accepted! Advance of <b>+$1,000</b> received. Produce with a star from the <b>Established pool (⭐⭐)</b> before day 40. <em>If you fail, you will lose <b>$2,000</b>.</em> [[📊 Dashboard|Dashboard]]
<<set $contract3.active = false>> <em>"Too bad. I'll find someone else."</em> [[📊 Dashboard|Dashboard]]
<<set $contract4.active = false>> <<set $contract4.accepted = true>> <<set $contract4.shootingsDone = 0>> <<set $contract4.failed = false>> <h1 style="margin:0 0 0.4em 0;">💼 Investor Demand</h1> Your phone rings. It's your main investor — their tone is firm. <em>"We've been watching your agency closely. We need to see a production featuring one of our preferred talents before day 50. This isn't a request."</em> They name two stars: <div style="padding:10px;background:#111;border-radius:6px;margin:12px 0;"> ⭐⭐ <b><<= $contract4.star1>></b><<if $contract4.star2>> or ⭐⭐ <b><<= $contract4.star2>></b><</if>> </div> Shoot with one of them before <b>day 50</b> or face a <b>$2,000 penalty</b>. [[📊 Dashboard|Dashboard]] | [[👤 Recruit|Recruitment]]
<<set $contract4.failed = false>> <h1 style="margin:0 0 0.4em 0;">❌ Investor Demand Failed</h1> @@color:red;You failed to produce with the requested star before day 50.@@ The investors are furious. <b>−$2,000</b> [[📊 Dashboard|Dashboard]]
<<set $contract3.failed = false>> <h1 style="margin:0 0 0.4em 0;">❌ Established Contract Failed</h1> @@color:red;You didn't produce with <<= $contract3.starName>> before day 40.@@ The producer claims damages. <b>−$2,000</b> [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">🌟 A Visitor Arrives</h1> A few days after <b><<= $roxyTriggerStar>></b>'s breakthrough performance, your phone rings. <em>"Hey... is this <<= $player.name>>? Yeah, I've been watching your productions. Your talents look like they're actually having fun out there. That's... rare."</em> <em>"I'm <<= $bonusEventStar>>. I've done some work here and there — private shoots mostly. I know how to perform, and I know how to make people watch. I just need the right director."</em> <em>"Give me a chance. I'll make it worth your while."</em> <<set _roxy = $recruitPool.find(function(w){ return w.name is $bonusEventStar; })>> <<set _roxyFile = $bonusEventStar.toLowerCase().replace(/ /g, "_")>> <<if _roxy>> <div style="display:flex;align-items:flex-start;gap:16px;margin:12px 0;padding:12px;background:#111;border-radius:8px;"> <img data-portrait-var="_roxyFile" style="width:130px;height:130px;object-fit:cover;border-radius:10px;flex-shrink:0;" src=""> <div> <b style="font-size:1.05em;"><<= $bonusEventStar>></b><br> <em style="color:#888;"><<= _roxy.hair>> | <<= _roxy.height>> | <<= _roxy.ageCat>> (<<= _roxy.ageNum>>)</em><br> 🎭 Tits: <<= _roxy.breast>> (<<= _roxy.breastType>>) | 🌟 Popularity: <<= _roxy.popularity>> 💖 Favorite position: <<= _roxy.favPosition>><br> 💳 Contract: <b>$<<= _roxy.contractCost.toLocaleString()>></b><br> 🔄 Upkeep: <b>$<<= (_roxy.popularity * 70).toLocaleString()>>/week</b> </div> </div> <<if $player.money >= _roxy.contractCost>> [[✅ Sign them|SignRoxy]] [[❌ Pass|RoxyDecline]] <<else>> @@color:red;Not enough funds ($<<= _roxy.contractCost.toLocaleString()>> required)@@ <em>"Guess you can't afford me right now..."</em> [[⬅️ She walks away|RoxyDecline]] <</if>> <</if>> /* ════════════════════════════════════════════ PASSAGE : SignRoxy ════════════════════════════════════════════ */
<<set _roxy = $recruitPool.find(function(w){ return w.name is $bonusEventStar; })>> <<if _roxy>> <<set _roxy.available = false>> <<set _roxy.lastShootingDay = $player.day>> <<set $player.money -= _roxy.contractCost>> <<set $roster.push(clone(_roxy))>> <</if>> <<set $roxyTriggerStar = "">> ✅ <b><<= $bonusEventStar>></b> joins your roster! <em>She leans in close enough that you catch her perfume. "I've been watching your work. I know exactly what you want from me." A slow smile. "I won't let you down."</em> [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : RoxyDecline ════════════════════════════════════════════ */
<<set _roxy = $recruitPool.find(function(w){ return w.name is $bonusEventStar; })>> <<if _roxy>> <<set _roxy.available = false>> <<set $rival.roster.push(clone(_roxy))>> <</if>> <<set $roxyTriggerStar = "">> <em>She gives you one last look — up and down, slow. "Their loss is someone else's gain." She picks up her bag, hips swaying on the way out. "<<= $rival.name>> already called. Twice."</em> @@color:red;⚠️ <<= $bonusEventStar>> has joined <<= $rival.name>>!@@ [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : BonusPositionChoice ════════════════════════════════════════════ */
<<set _bw = $roster.find(function(w){ return w.name is $bonusChoiceStar; })>> <h1 style="margin:0 0 0.4em 0;">💖 A New Favorite!</h1> <b><<= $bonusChoiceStar>></b> pulls you aside after the shoot, cheeks flushed. <em>"I didn't expect to enjoy that so much... I think I've found something new I really love."</em> She's discovered a second favorite position. What does she want to try? <<if _bw>> <<capture _bw>> <<link `_bw.bonusPosition1`>><<set $bonusPositionChosen = _bw.bonusPosition1>><<goto "ApplyBonusPosition">><</link>> | <<link `_bw.bonusPosition2`>><<set $bonusPositionChosen = _bw.bonusPosition2>><<goto "ApplyBonusPosition">><</link>> <</capture>> <</if>>
<<set _bw = $roster.find(function(w){ return w.name is $bonusChoiceStar; })>> <<if _bw>> <<set _bw.favPosition2 = $bonusPositionChosen>> <<set _bw.bonusChosen = true>> <</if>> ✅ <b><<= $bonusChoiceStar>></b> now also loves <b><<= $bonusPositionChosen>></b>! <<set $bonusChoiceStar = "">> [[📊 Dashboard|Dashboard]] | [[📅 Next day|NextDay]] /* ════════════════════════════════════════════ PASSAGE : Day30Event ════════════════════════════════════════════ */
<<set _minSat = 9999>><<set _minIdx = -1>><<for _i = 0; _i < $roster.length; _i++>><<if $roster[_i].satisfaction < _minSat>><<set _minSat = $roster[_i].satisfaction>><<set _minIdx = _i>><</if>><</for>><<if _minIdx >= 0>><<set $roster[_minIdx].satisfaction = Math.max(0, $roster[_minIdx].satisfaction - 5)>><<set _contactedStar = $roster[_minIdx].name>><<set _portraitFile = $roster[_minIdx].name.toLowerCase().replace(/ /g, "_")>><<else>><<set _contactedStar = "one of your talents">><</if>><h1 style="margin:0 0 0.2em 0;">📞 <<= $rival.name>> Makes a Move</h1> <<if _minIdx >= 0>><div style="text-align:center;margin:6px 0;"><img data-portrait-var="_portraitFile" style="width:140px;height:140px;object-fit:cover;border-radius:10px;box-shadow:0 4px 12px rgba(0,0,0,0.5);" src=""></div><</if>> Your phone rings — unknown number. You pick up. <em>"Hello. I'm reaching out on behalf of <<= $rival.name>>. We've been watching your agency and... well, we think some of your talent deserves better opportunities."</em> The call ends before you can respond. <<= _contactedStar>> looks distracted at the next shoot. Something's on their mind. When you ask, they're honest. <em>"They called me. Said they'd let me do things you never put me in. Rougher. Longer. No limits. I said no... but my body wasn't so sure."</em> @@color:red;⚠️ <b><<= _contactedStar>></b> was contacted by <<= $rival.name>> and hesitated. <b>−5 satisfaction.</b>@@ [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : BNOEvent ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">🏢 A New Player Enters the Market</h1> Your phone blows up with notifications: <em>"Breaking: A major investment group has acquired <<= $rival.name>> and all its assets. The studio will be rebranded immediately under new management."</em> <em>"Their talent roster has been absorbed and put straight to work. Word is the first shoots under the new banner were intense — the kind that trend for weeks. Well-funded, aggressive, and hungry."</em> @@color:red;⚠️ All talents with satisfaction below 40 lose <b>5 satisfaction</b> immediately.@@ <<silently>><<for _i = 0; _i < $roster.length; _i++>><<if $roster[_i].satisfaction < 40>><<set $roster[_i].satisfaction = Math.max(0, $roster[_i].satisfaction - 5)>><</if>><</for>><<set $rivalOriginalName = $rival.name>><</silently>> <b>What is the new studio called?</b> <<textbox "$rival.name" "BNO">> <br> [[✅ Confirm|BNOConfirm]]
<<set $rivalVideoPrefix = "b_">> <h1 style="margin:0 0 0.4em 0;">🏢 <<= $rival.name>> — The New Rival</h1> The takeover is official. <<= $rival.name>> inherits the full roster and reputation of the old studio. Roster: <b><<= $rival.roster.length>> star(s)</b> | Reputation: <b>🌟 <<= $rival.reputation>></b> <em>"This city just got a lot more competitive."</em> [[📊 Dashboard|Dashboard]]
<<set $questlines.asianDuo.step2Notified = true>> <h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — Step 2</h1> <<set _as2File = $questlines.asianDuo.star1.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img data-portrait-var="_as2File" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <b><<= $questlines.asianDuo.star1>></b> knocks on your office door. <em>"There's someone you should meet... we worked together before. I think she'd fit right in here."</em> She puts a name on your desk. You know what you have to do. @@color:cyan;➡️ Recruit <<= ($questlines.asianDuo.star1 is "Kimmy") ? "Lulu" : "Kimmy">> to continue the questline.@@ [[📊 Dashboard|Dashboard]] | [[👤 Recruitment|Recruitment]]
<<set $questlines.asianDuo.step3Notified = true>> <h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — Step 3</h1> <<set _as3File = $questlines.asianDuo.star2.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img data-portrait-var="_as3File" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <b><<= $questlines.asianDuo.star2>></b> arrives at the agency. The two recognize each other immediately. <em>"We meet again."</em> A smile, a knowing look. They clearly have history. @@color:cyan;➡️ Get <<= $questlines.asianDuo.star2>> to 25 satisfaction.@@ [[📊 Dashboard|Dashboard]]
<<set $questlines.asianDuo.step4Notified = true>> <h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — Special Shooting Unlocked!</h1> <<set _as4aFile = $questlines.asianDuo.star1.toLowerCase().replace(/ /g, "_")>><<set _as4bFile = $questlines.asianDuo.star2.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;display:flex;justify-content:center;gap:12px;"><img data-portrait-var="_as4aFile" style="width:140px;height:140px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""><img data-portrait-var="_as4bFile" style="width:140px;height:140px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <b><<= $questlines.asianDuo.star2>></b> comes to see you, <b><<= $questlines.asianDuo.star1>></b> right behind her. <em>Lulu slides in behind Kimmy, lips at her ear. "We've been talking... about what we want to do together. On camera." Kimmy bites her lip. "All of it." They both look at you. "We're ready."</em> The air in the room shifts. Whatever happens next, the camera is going to love it. @@color:gold;🌟 Asian Duo Special Shooting now available in the menu!@@ [[📊 Dashboard|Dashboard]]
<<set _kimmy = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _kimmy>><<set _kimmy.popularity += 2>><<set _kimmy.lastShootingDay = $player.day>><</if>> <<if _lulu>><<set _lulu.popularity += 2>><<set _lulu.lastShootingDay = $player.day>><</if>> <<set $player.money += 1500>> <<set $player.reputation += 2>> <<set $questlines.asianDuo.shooting1Done = true>> <<set $shootingPlayedToday = true>> <<set $asianDuoShoot1Day = $player.day>> <h1 style="margin:0 0 0.4em 0;">🎬 Asian Duo — First Special</h1> <div style="text-align:center;margin:12px 0;display:flex;justify-content:center;gap:12px;"> <<set _kFile = "kimmy">><<set _lFile = "lulu">> <img data-portrait-var="_kFile" style="width:140px;height:140px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""> <img data-portrait-var="_lFile" style="width:140px;height:140px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""> </div> <em>They barely need direction. Kimmy's hands find Lulu instinctively — lips, hips, every movement synchronized. The camera can barely keep up. This is what the audience has been waiting for.</em> @@color:gold;🌟 Kimmy & Lulu: +2 popularity each@@ @@color:gold;💰 +$1,500 earnings@@ @@color:gold;🌟 +2 reputation@@ <em>A second special shooting is now available!</em> [[📊 Dashboard|Dashboard]] | [[🌟 Special Shootings|SpecialShootingMenu]]
<<set _kimmy = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _kimmy>><<set _kimmy.popularity += 3>><<set _kimmy.lastShootingDay = $player.day>><</if>> <<if _lulu>><<set _lulu.popularity += 3>><<set _lulu.lastShootingDay = $player.day>><</if>> <<set $player.money += 3000>> <<set $player.reputation += 3>> <<set $questlines.asianDuo.shooting2Done = true>> <<set $shootingPlayedToday = true>> <<set $asianDuoLastShootingDay = $player.day>> <h1 style="margin:0 0 0.4em 0;">🎬 Asian Duo — Second Special</h1> <div style="text-align:center;margin:12px 0;display:flex;justify-content:center;gap:12px;"> <<set _kFile = "kimmy">><<set _lFile = "lulu">> <img data-portrait-var="_kFile" style="width:140px;height:140px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""> <img data-portrait-var="_lFile" style="width:140px;height:140px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""> </div> <em>No script needed. Lulu pins Kimmy against the sheets and takes control — slow at first, then relentless. Their chemistry has cured into something primal. The final scene runs 40 minutes and nobody calls cut.</em> @@color:gold;🌟 Kimmy & Lulu: +3 popularity each@@ @@color:gold;💰 +$3,000 earnings@@ @@color:gold;🌟 +3 reputation@@ @@color:gold;🎌 Asian Duo questline complete!@@ [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.3em 0;">🎌 Asian Duo — Good News</h1> <div style="display:flex;justify-content:center;gap:12px;margin:10px 0;"> <img src="img/portraits/kimmy.jpg" style="width:100px;height:100px;object-fit:cover;border-radius:10px;"> <img src="img/portraits/lulu.jpg" style="width:100px;height:100px;object-fit:cover;border-radius:10px;"> </div> Kimmy and Lulu stop by your office, both smiling. <em>"We loved the first one. We'd like to do another."</em> @@color:gold;🎌 Second special shooting now available!@@ [[⭐ Special Shootings|SpecialShootingMenu]] | [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.3em 0;">👼 Two Fallen Angels — Good News</h1> <div style="display:flex;justify-content:center;gap:12px;margin:10px 0;"> <img src="img/portraits/angie.jpg" style="width:100px;height:100px;object-fit:cover;border-radius:10px;"> <img src="img/portraits/angela.jpg" style="width:100px;height:100px;object-fit:cover;border-radius:10px;"> </div> Angie and Angela reach out together. <em>"That was something special. We want to do it again."</em> @@color:gold;👼 Second special shooting now available!@@ [[⭐ Special Shootings|SpecialShootingMenu]] | [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.3em 0;">👼 Two Fallen Angels — One More</h1> <div style="display:flex;justify-content:center;gap:12px;margin:10px 0;"> <img src="img/portraits/angie.jpg" style="width:100px;height:100px;object-fit:cover;border-radius:10px;"> <img src="img/portraits/angela.jpg" style="width:100px;height:100px;object-fit:cover;border-radius:10px;"> </div> <em>"We're not done yet. One more — the real finale."</em> @@color:gold;👼 Third special shooting now available!@@ [[⭐ Special Shootings|SpecialShootingMenu]] | [[📊 Dashboard|Dashboard]]
<<set $questlines.fallenAngels.step2Notified = true>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Step 2</h1> <<set _fa2pFile = $questlines.fallenAngels.star1.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img data-portrait-var="_fa2pFile" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <b><<= $questlines.fallenAngels.star1>></b> stops you in the hallway. <em>"There's someone I used to work with. We had something special on set. I think you should meet her."</em> @@color:cyan;➡️ Recruit <<= ($questlines.fallenAngels.star1 is "Angie") ? "Angela" : "Angie">> to continue.@@ [[📊 Dashboard|Dashboard]] | [[👤 Recruitment|Recruitment]]
<<set $questlines.fallenAngels.step3Notified = true>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Step 3</h1> <<set _fa3pFile = $questlines.fallenAngels.star2.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img data-portrait-var="_fa3pFile" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <b><<= $questlines.fallenAngels.star2>></b> walks in. The two look at each other — something unspoken passes between them. <em>"I didn't think I'd see you again."</em> <em>"Neither did I."</em> @@color:cyan;➡️ Get <<= $questlines.fallenAngels.star2>> to 25 satisfaction.@@ [[📊 Dashboard|Dashboard]]
<<set $questlines.fallenAngels.step4Notified = true>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Special Shootings Unlocked!</h1> <<set _fa4aF = $questlines.fallenAngels.star1.toLowerCase().replace(/ /g, "_")>> <<set _fa4bF = $questlines.fallenAngels.star2.toLowerCase().replace(/ /g, "_")>> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img data-portrait-var="_fa4aF" style="width:140px;height:140px;object-fit:cover;border-radius:12px;" src=""> <img data-portrait-var="_fa4bF" style="width:140px;height:140px;object-fit:cover;border-radius:12px;" src=""> </div> <em>Angie grabs Angela's hand and pulls her forward. "We didn't sleep last night. Too busy remembering." Angela's cheeks are flushed. "We know exactly what we want to shoot. And we want you to watch."</em> @@color:gold;👼 Three special shootings now available!@@ [[📊 Dashboard|Dashboard]]
<<set _fa1a = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _fa1b = $roster.find(function(w){ return w.name is "Angela"; })>> <<if _fa1a>><<set _fa1a.popularity += 2>><<set _fa1a.lastShootingDay = $player.day>><</if>> <<if _fa1b>><<set _fa1b.popularity += 2>><<set _fa1b.lastShootingDay = $player.day>><</if>> <<set $player.money += 1500>><<set $player.reputation += 2>> <<set $questlines.fallenAngels.shooting1Done = true>><<set $shootingPlayedToday = true>> <<set $fallenAngelsShoot1Day = $player.day>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — First Special</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/angie.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> <img src="img/portraits/angela.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> </div> <em>Ten years apart and their bodies remember everything. Angie traces every curve like she never left. Angela gasps — and for the first time in years, it's not performance. It's real.</em> @@color:gold;🌟 Angie & Angela: +2 pop each | 💰 +$1,500 | 🌟 +2 rep@@ [[📊 Dashboard|Dashboard]] | [[🌟 Special Shootings|SpecialShootingMenu]]
<<set _fa2a = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _fa2b = $roster.find(function(w){ return w.name is "Angela"; })>> <<if _fa2a>><<set _fa2a.popularity += 3>><<set _fa2a.lastShootingDay = $player.day>><</if>> <<if _fa2b>><<set _fa2b.popularity += 3>><<set _fa2b.lastShootingDay = $player.day>><</if>> <<set $player.money += 3000>><<set $player.reputation += 3>> <<set $questlines.fallenAngels.shooting2Done = true>><<set $shootingPlayedToday = true>> <<set $fallenAngelsShoot2Day = $player.day>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Second Special</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/angie.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> <img src="img/portraits/angela.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> </div> <em>They've found their rhythm again. Angela on top, Angie pulling her down — sweat, urgency, zero hesitation. The director doesn't say a word. There's nothing to direct.</em> @@color:gold;🌟 Angie & Angela: +3 pop each | 💰 +$3,000 | 🌟 +3 rep@@ [[📊 Dashboard|Dashboard]] | [[🌟 Special Shootings|SpecialShootingMenu]]
<<set _fa3a = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _fa3b = $roster.find(function(w){ return w.name is "Angela"; })>> <<if _fa3a>><<set _fa3a.popularity += 3>><<set _fa3a.lastShootingDay = $player.day>><</if>> <<if _fa3b>><<set _fa3b.popularity += 3>><<set _fa3b.lastShootingDay = $player.day>><</if>> <<set $player.money += 3000>><<set $player.reputation += 3>> <<set $questlines.fallenAngels.shooting3Done = true>><<set $shootingPlayedToday = true>> <<set $fallenAngelsLastShootingDay = $player.day>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Final Act</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/angie.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> <img src="img/portraits/angela.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> </div> <em>The finale. Both of them completely unguarded — no performance, no filters. Angela buries her face in Angie's neck and whispers something the mic barely catches. The crew watches in silence. Nobody moves when it's over.</em> @@color:gold;🌟 Angie & Angela: +3 pop each | 💰 +$3,000 | 🌟 +3 rep@@ @@color:gold;👼 Two Fallen Angels questline complete!@@ [[📊 Dashboard|Dashboard]]
<<if $contract3rdOptionItem.bought>> Already purchased. [[⬅️ Dashboard|Dashboard]] <<elseif $player.money < $contract3rdOptionItem.price>> @@color:red;Not enough funds ($<<= $contract3rdOptionItem.price>> required).@@ [[⬅️ Shop|Shop]] <<else>> <<set $player.money -= $contract3rdOptionItem.price>> <<set $contract3rdOptionItem.bought = true>> ✅ <b>3rd Option</b> purchased! Contracts now offer 3 choices instead of 2. [[🛒 Shop|Shop]] | [[📊 Dashboard|Dashboard]] <</if>>
<<if $contractHarderItem.bought>> Already purchased. [[⬅️ Dashboard|Dashboard]] <<elseif !$contract3rdOptionItem.bought>> @@color:red;Requires 3rd Option first.@@ [[⬅️ Shop|Shop]] <<elseif $player.money < $contractHarderItem.price>> @@color:red;Not enough funds ($<<= $contractHarderItem.price>> required).@@ [[⬅️ Shop|Shop]] <<else>> <<set $player.money -= $contractHarderItem.price>> <<set $contractHarderItem.bought = true>> ✅ <b>Harder Contract</b> purchased! You can now buy harder contracts for $500 with double stat criteria — higher reward, higher risk. [[🛒 Shop|Shop]] | [[📊 Dashboard|Dashboard]] <</if>>
<<if !$contractHarderItem.bought>> @@color:red;Harder Contract upgrade not purchased yet.@@ [[⬅️ Dashboard|Dashboard]] <<elseif $player.money < 500>> @@color:red;Not enough funds ($500 required).@@ [[⬅️ Dashboard|Dashboard]] <<else>> <<set $player.money -= 500>> <<set _pool = ["hair:Brown","hair:Brown","hair:Blonde","hair:Blonde","hair:Black","hair:Black", "height:Short","height:Tall","height:Medium", "ageCat:Young","ageCat:Veteran","ageCat:Neutral", "breast:Small","breast:Small","breast:Large","breast:Large","breast:Huge","breast:Huge","breast:Medium", "breastType:Fake","breastType:Fake","breastType:Fake","breastType:Real", "ethnicity:Latina","ethnicity:Latina","ethnicity:Asian","ethnicity:Asian","ethnicity:Black","ethnicity:Caucasian"]>> <<set _options = []>> <<set _numOptions = $contract3rdOptionItem.bought ? 3 : 2>> <<set $contractIsHarder = true>> <<for _oi = 0; _oi < _numOptions; _oi++>> <<set _pick = _pool[random(0, _pool.length - 1)]>> <<set _ct = _pick.split(":")[0]>> <<set _cv = _pick.split(":")[1]>> <<set _pick2 = _pool[random(0, _pool.length - 1)]>> <<set _ct2 = _pick2.split(":")[0]>> <<set _cv2 = _pick2.split(":")[1]>> <<set _options.push({ type: _ct, value: _cv, type2: _ct2, value2: _cv2 })>> <</for>> <<set $contract1.active = true>> <<set $contract1.options = _options>> <<set $contract1.failed = false>> <<set $contract1.accepted = false>> <<set $contract1.shootingsDone = 0>> <<set $contractShopAvailable = false>> <<set $trophies = { fullHouse: false, empire: false, dealMaker: false, harderDeal: false, asianDuoComplete: false, fallenAngelsComplete: false, firstMillion: false, brokeBurBack: false, firstPoach: false, poachMaster: false }>> <<set $totalContractsCompleted = 0>> <<set $totalEarnings = 0>> <<set $newTrophy = "">> <<set $contractShopAvailableDay = -1>> <<goto "Contract1Event">> <</if>>
<h1 style="margin:0 0 0.4em 0;">📋 Contract Shop</h1> <div style="display:flex;gap:12px;flex-wrap:wrap;margin:12px 0;"> <div style="flex:1;min-width:180px;padding:12px;background:#111;border-radius:8px;border:1px solid #333;"> <b>📋 Standard Contract</b><br> <em style="font-size:0.85em;color:#888;">2 productions with 1 matching stat in 3 days</em><br><br> <em style="font-size:0.82em;color:#666;">Cost: <b>$200</b></em><br> <em style="font-size:0.82em;color:green;">Reward: +$500, +3 rep</em><br> <em style="font-size:0.82em;color:red;">Fail: −2 rep</em><br><br> <<if $player.money >= 200>> [[✅ Buy Standard|BuyContract]] <<else>> <span style="opacity:0.5;font-size:0.85em;">❌ Not enough funds</span> <</if>> </div> <div id="harder-contract-card" style="flex:1;min-width:180px;padding:12px;background:#111;border-radius:8px;border:1px solid #333;"> <b>💀 Harder Contract</b><br> <em style="font-size:0.85em;color:#888;">2 productions with 2 matching stats in 3 days</em><br><br> <em style="font-size:0.82em;color:#666;">Cost: <b>$500</b></em><br> <em style="font-size:0.82em;color:green;">Reward: +$1,500, +5 rep</em><br> <em style="font-size:0.82em;color:red;">Fail: −5 rep</em><br><br> <<if !$contractHarderItem.bought>> <span style="opacity:0.5;font-size:0.85em;">🔒 Requires <b>Harder Contract</b> upgrade</span> <<elseif $player.money >= 500>> [[💀 Buy Harder|BuyHarderContract]] <<else>> <span style="opacity:0.5;font-size:0.85em;">❌ Not enough funds</span> <</if>> </div> </div> [[⬅️ Dashboard|Dashboard]] <<script>> jQuery(document).one(':passageend', function(){ var card = document.getElementById('harder-contract-card'); if(card && SugarCube.State.variables.contractHarderItem.bought){ card.style.borderColor = '#553300'; } }); <</script>>
<<if $player.money < $contractShopPrice>> @@color:red;Not enough funds ($<<= $contractShopPrice>> required).@@ [[⬅️ Dashboard|Dashboard]] <<else>> <<set $player.money -= $contractShopPrice>> <<set _pool = ["hair:Brown","hair:Brown","hair:Blonde","hair:Blonde","hair:Black","hair:Black","height:Short","height:Short","height:Tall","height:Tall","ageCat:Young","ageCat:Young","ageCat:Veteran","ageCat:Veteran","breast:Small","breast:Small","breast:Large","breast:Large","breast:Huge","breast:Huge","breastType:Fake","breastType:Fake","breastType:Fake","breastType:Real","ethnicity:Latina","ethnicity:Latina","ethnicity:Asian","ethnicity:Asian","ethnicity:Black","ethnicity:Caucasian"]>> <<set _options = []>> <<set _numOptions = $contract3rdOptionItem.bought ? 3 : 2>> <<set $contractIsHarder = false>> <<for _oi = 0; _oi < _numOptions; _oi++>> <<set _pick = _pool[random(0, _pool.length - 1)]>> <<set _ct = _pick.split(":")[0]>> <<set _cv = _pick.split(":")[1]>> <<set _options.push({ type: _ct, value: _cv })>> <</for>> <<set $contract1.active = true>> <<set $contract1.options = _options>> <<set $contract1.failed = false>> <<set $contract1.accepted = false>> <<set $contract1.shootingsDone = 0>> <<set $contractShopAvailable = false>> <<set $trophies = { fullHouse: false, empire: false, dealMaker: false, harderDeal: false, asianDuoComplete: false, fallenAngelsComplete: false, firstMillion: false, brokeBurBack: false, firstPoach: false, poachMaster: false }>> <<set $totalContractsCompleted = 0>> <<set $totalEarnings = 0>> <<set $newTrophy = "">> <<set $contractShopAvailableDay = -1>> <<goto "Contract1Event">> <</if>>
<<set $asianDuoAbsentNotified = true>> <h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — Silence</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/kimmy.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;opacity:0.6;"> <img src="img/portraits/lulu.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;opacity:0.6;"> </div> Kimmy and Lulu didn't show up to the studio today. No message, no call. <em>Their chairs are empty. The set feels different without them.</em> @@color:orange;⚠️ Kimmy & Lulu are absent. Both lose 10 satisfaction. They cannot be scheduled until further notice.@@ [[📊 Dashboard|Dashboard]]
<<set $asianDuoGoneNotified = true>> <<set _kimmy = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu = $roster.find(function(w){ return w.name is "Lulu"; })>> <<set _payment = 0>> <<if _kimmy>> <<set _payment += _kimmy.contractCost + (100 * _kimmy.popularity) + (10 * _kimmy.satisfaction)>> <<set $rival.roster.push(clone(_kimmy))>> <<set $roster.delete(_kimmy)>> <</if>> <<if _lulu>> <<set _payment += _lulu.contractCost + (100 * _lulu.popularity) + (10 * _lulu.satisfaction)>> <<set $rival.roster.push(clone(_lulu))>> <<set $roster.delete(_lulu)>> <</if>> <<set $player.money += _payment>> <<set $asianDuoLastShootingDay = -1>> <<set $asianDuoShoot1Day = -1>> <<set $asianDuoShoot2Unlocked = false>> <<set $fallenAngelsShoot1Day = -1>> <<set $fallenAngelsShoot2Day = -1>> <<set $fallenAngelsShoot2Unlocked = false>> <<set $fallenAngelsShoot3Unlocked = false>> <<set $asianDuoAbsentDay = -1>> <<set $asianDuoAbsentNotified = false>> <<set $asianDuoGoneDay = -1>> <<set $asianDuoGoneNotified = false>> <<set $asianDuoWebm2Day = -1>> <<set $asianDuoWebm3Day = -1>> <h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — Signed Away</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/kimmy.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> <img src="img/portraits/lulu.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> </div> An envelope arrives. Inside — a contract signed by both Kimmy and Lulu. Underneath, a printed still from a shoot. <em>"We found something we couldn't say no to. Thank you for everything."</em> <<= $rival.name>> has signed them both. Word is their new director pushes them harder than you ever did — and they love it. Went to BNO, learnt how massive their new co-stars are — and they're not complaining. A video of their first joint shoot under the new banner is already making the rounds. <div id="asian-duo-gone-video"></div> <<script>> jQuery(document).one(':passageend', function(){ var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var wrap = document.getElementById('asian-duo-gone-video'); if(wrap){ wrap.innerHTML = '<video src="videos/'+prefix+'kimmy_lulu_collab.webm" autoplay loop muted playsinline style="width:100%;max-width:480px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; } }); <</script>> @@color:gold;💰 Contract buyout received: <b>$<<= _payment.toLocaleString()>></b>@@ [[📊 Dashboard|Dashboard]]
<<set $fallenAngelsAbsentNotified = true>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Silence</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/angie.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;opacity:0.6;"> <img src="img/portraits/angela.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;opacity:0.6;"> </div> Angie and Angela didn't show up. No message, no call. <em>The set is quiet. Something feels off.</em> @@color:orange;⚠️ Angie & Angela are absent. Both lose 10 satisfaction. They cannot be scheduled until further notice.@@ [[📊 Dashboard|Dashboard]]
<<set $fallenAngelsGoneNotified = true>> <<set _angie = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _angela = $roster.find(function(w){ return w.name is "Angela"; })>> <<set _payment2 = 0>> <<if _angie>> <<set _payment2 += _angie.contractCost + (100 * _angie.popularity) + (10 * _angie.satisfaction)>> <<set $rival.roster.push(clone(_angie))>> <<set $roster.delete(_angie)>> <</if>> <<if _angela>> <<set _payment2 += _angela.contractCost + (100 * _angela.popularity) + (10 * _angela.satisfaction)>> <<set $rival.roster.push(clone(_angela))>> <<set $roster.delete(_angela)>> <</if>> <<set $player.money += _payment2>> <<set $fallenAngelsLastShootingDay = -1>> <<set $fallenAngelsAbsentDay = -1>> <<set $fallenAngelsAbsentNotified = false>> <<set $fallenAngelsGoneDay = -1>> <<set $fallenAngelsGoneNotified = false>> <<set $fallenAngelsWebm2Day = -1>> <<set $fallenAngelsWebm3Day = -1>> <h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — Gone</h1> <div style="display:flex;justify-content:center;gap:12px;margin:12px 0;"> <img src="img/portraits/angie.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> <img src="img/portraits/angela.jpg" style="width:140px;height:140px;object-fit:cover;border-radius:12px;"> </div> A message arrives from <<= $rival.name>>. Attached — a clip from a shoot with both Angie and Angela. <em>"They came to us. We made them an offer they deserved — and a director who knows how to bring out their full potential. Stronger. Harder. Better."</em> <em>Went to BNO. Both of them. Rumour has it their first shoot left them walking differently.</em> <div id="fallen-angels-gone-video"></div> <<script>> jQuery(document).one(':passageend', function(){ var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var wrap = document.getElementById('fallen-angels-gone-video'); if(wrap){ wrap.innerHTML = '<video src="videos/'+prefix+'angie_angela_collab.webm" autoplay loop muted playsinline style="width:100%;max-width:480px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; } }); <</script>> @@color:gold;💰 Contract buyout received: <b>$<<= _payment2.toLocaleString()>></b>@@ [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — <<= $rival.name>> Update</h1> A clip surfaces online. Kimmy and Lulu, under <<= $rival.name>>'s banner. <em>"They look... happy."</em> <div id="asian-webm2"></div> <<script>> jQuery(document).one(':passageend', function(){ var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var wrap = document.getElementById('asian-webm2'); if(wrap) wrap.innerHTML = '<video src="videos/'+prefix+'kimmy_lulu_special2.webm" autoplay loop muted playsinline style="width:100%;max-width:480px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; }); <</script>> [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">🎌 Asian Duo — <<= $rival.name>> Update</h1> Another clip. They're fully settled in now. <div id="asian-webm3"></div> <<script>> jQuery(document).one(':passageend', function(){ var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var wrap = document.getElementById('asian-webm3'); if(wrap) wrap.innerHTML = '<video src="videos/'+prefix+'kimmy_lulu_special3.webm" autoplay loop muted playsinline style="width:100%;max-width:480px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; }); <</script>> [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — <<= $rival.name>> Update</h1> A clip of Angie and Angela surfaces. They're working again — together. <div id="fa-webm2"></div> <<script>> jQuery(document).one(':passageend', function(){ var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var wrap = document.getElementById('fa-webm2'); if(wrap) wrap.innerHTML = '<video src="videos/'+prefix+'angie_angela_special2.webm" autoplay loop muted playsinline style="width:100%;max-width:480px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; }); <</script>> [[📊 Dashboard|Dashboard]]
<h1 style="margin:0 0 0.4em 0;">👼 Two Fallen Angels — <<= $rival.name>> Update</h1> The final clip. Angie and Angela at their best — under someone else's name. <div id="fa-webm3"></div> <<script>> jQuery(document).one(':passageend', function(){ var prefix = SugarCube.State.variables.rivalVideoPrefix || ''; var wrap = document.getElementById('fa-webm3'); if(wrap) wrap.innerHTML = '<video src="videos/'+prefix+'angie_angela_special3.webm" autoplay loop muted playsinline style="width:100%;max-width:480px;display:block;margin:12px auto;border-radius:10px;" onerror="this.style.display=\'none\'"></video>'; }); <</script>> [[📊 Dashboard|Dashboard]]
<<silently>><<set $player.day += 1>><<set $shootingPlayedToday = false>><<set $weeklyPaid = 0>><<if $player.day % 7 is 0>><<for _i = 0; _i < $roster.length; _i++>><<set _upkeep = $roster[_i].popularity * 70>><<set $weeklyPaid += _upkeep>><<set $player.money -= _upkeep>><</for>><<for _i = 0; _i < $roster.length; _i++>><<set $roster[_i].weekShootings = 0>><</for>><</if>><<for _i = 0; _i < $roster.length; _i++>><<set _daysSince = $player.day - $roster[_i].lastShootingDay>><<set _decayThreshold = $satisfactionDelayItem.bought ? 5 : 4>><<if $roster[_i].satisfaction > 40>><<set _decayThreshold += 1>><</if>><<if _daysSince >= _decayThreshold>><<if $roster[_i].name isnot $vacationStar>><<set $roster[_i].satisfaction = Math.max(0, $roster[_i].satisfaction - 5)>><</if>><</if>><<if $roster[_i].name is $vacationStar>><<set $roster[_i].lastShootingDay = $player.day>><</if>><<if $roster[_i].restDay && $roster[_i].name isnot $vacationStar && $player.day > $roster[_i].restUntilDay>><<set $roster[_i].restDay = false>><<set $roster[_i].consecutiveDays = 0>><</if>><</for>><<set $zeroSatStar = "">> /* ── Rival offer deadline check ── */ <<if $rivalOfferShootingsLeft > 0 && $rivalOfferDeadlineDay > 0 && $player.day >= $rivalOfferDeadlineDay>> <<set _failStar = $roster.find(function(w){ return w.name is $rivalOfferStar; })>> <<if _failStar>> <<set $rival.roster.push(clone(_failStar))>> <<set $roster.delete(_failStar)>> <</if>> <<set $rivalOfferShootingsLeft = 0>> <<set $rivalOfferDeadlineDay = -1>> <<set $poachMessage = $rivalOfferStar + " left for " + $rival.name + " — you didn't feature them enough.">> <</if>> /* ── Questline post-completion tracking ── */ /* Asian Duo */ <<if $asianDuoLastShootingDay > 0 && $asianDuoAbsentDay < 0 && $player.day >= $asianDuoLastShootingDay + 7>> <<set $asianDuoAbsentDay = $player.day>> <<set _kimmyAsian = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _luluAsian = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _kimmyAsian>><<set _kimmyAsian.satisfaction = Math.max(0, _kimmyAsian.satisfaction - 10)>><</if>> <<if _luluAsian>> <<set _luluAsian.satisfaction = Math.max(0, _luluAsian.satisfaction - 10)>><</if>> <</if>> <<if $asianDuoAbsentDay > 0 && $asianDuoGoneDay < 0 && $player.day >= $asianDuoAbsentDay + 7>> <<set $asianDuoGoneDay = $player.day>> <<set $asianDuoWebm2Day = $asianDuoLastShootingDay + 17>> <<set $asianDuoWebm3Day = $asianDuoLastShootingDay + 20>> <</if>> /* Fallen Angels */ <<if $fallenAngelsLastShootingDay > 0 && $fallenAngelsAbsentDay < 0 && $player.day >= $fallenAngelsLastShootingDay + 7>> <<set $fallenAngelsAbsentDay = $player.day>> <<set _angieFA = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _angelaFA = $roster.find(function(w){ return w.name is "Angela"; })>> <<if _angieFA>> <<set _angieFA.satisfaction = Math.max(0, _angieFA.satisfaction - 10)>><</if>> <<if _angelaFA>><<set _angelaFA.satisfaction = Math.max(0, _angelaFA.satisfaction - 10)>><</if>> <</if>> <<if $fallenAngelsAbsentDay > 0 && $fallenAngelsGoneDay < 0 && $player.day >= $fallenAngelsAbsentDay + 7>> <<set $fallenAngelsGoneDay = $player.day>> <<set $fallenAngelsWebm2Day = $fallenAngelsLastShootingDay + 17>> <<set $fallenAngelsWebm3Day = $fallenAngelsLastShootingDay + 20>> <</if>> /* ── Special shooting unlock checks ── */ <<if $asianDuoShoot1Day > 0 && !$asianDuoShoot2Unlocked && $player.day >= $asianDuoShoot1Day + 3>> <<set $asianDuoShoot2Unlocked = true>> <</if>> <<if $fallenAngelsShoot1Day > 0 && !$fallenAngelsShoot2Unlocked && $player.day >= $fallenAngelsShoot1Day + 3>> <<set $fallenAngelsShoot2Unlocked = true>> <</if>> <<if $fallenAngelsShoot2Day > 0 && !$fallenAngelsShoot3Unlocked && $player.day >= $fallenAngelsShoot2Day + 3>> <<set $fallenAngelsShoot3Unlocked = true>> <</if>> /* ── Trophy checks ── */ <<if !$trophies.fullHouse && $roster.length >= 10>> <<set $trophies.fullHouse = true>><<set $newTrophy = "🏆 Full House — 10 stars signed!">> <</if>> <<if !$trophies.empire && $roster.length >= 20>> <<set $trophies.empire = true>><<set $newTrophy = "🏆 Empire — 20 stars signed!">> <</if>> <<if !$trophies.asianDuoComplete && $asianDuoGoneDay > 0>> <<set $trophies.asianDuoComplete = true>><<set $newTrophy = "🏆 Asian Duo — questline complete!">> <</if>> <<if !$trophies.fallenAngelsComplete && $fallenAngelsGoneDay > 0>> <<set $trophies.fallenAngelsComplete = true>><<set $newTrophy = "🏆 Fallen Angels — questline complete!">> <</if>> <<if !$trophies.firstMillion && $totalEarnings >= 1000000>> <<set $trophies.firstMillion = true>><<set $newTrophy = "🏆 First Million — $1,000,000 earned!">> <</if>> /* ── Contract shop day check ── */ <<if $contractShopAvailableDay > 0 && $player.day >= $contractShopAvailableDay>> <<set $contractShopAvailable = true>> <<set $contractShopAvailableDay = -1>> <</if>> /* ── Questline: Asian Duo trigger ── */ <<if !$questlines.asianDuo.active && !$questlines.asianDuo.specialAvailable>> <<set _kimmy = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _kimmy || _lulu>> <<set $questlines.asianDuo.active = true>> <<set $questlines.asianDuo.star1 = _kimmy ? "Kimmy" : "Lulu">> <<set $questlines.asianDuo.step = Math.max($questlines.asianDuo.step, 1)>> <</if>> <</if>> /* ── Asian Duo step progression ── */ <<if $questlines.asianDuo.active>> <<set _ql = $questlines.asianDuo>> <<set _s1 = $roster.find(function(w){ return w.name is _ql.star1; })>> <<set _kimmy2 = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu2 = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _ql.step is 1 && _s1 && _s1.satisfaction >= 25>> <<set _ql.step = 2>> <</if>> <<if _ql.step >= 2>> <<if _kimmy2 && _lulu2>> <<if !_ql.star2>> <<set _ql.star2 = (_ql.star1 is "Kimmy") ? "Lulu" : "Kimmy">> <<set _ql.step = 3>> <</if>> <</if>> <</if>> <<set _s2 = _ql.star2 ? $roster.find(function(w){ return w.name is _ql.star2; }) : null>> <<if _ql.step is 3 && _s2 && _s2.satisfaction >= 25>> <<set _ql.step = 4>> <<set _ql.specialAvailable = true>> <<set _ql.active = false>> <</if>> <</if>> /* ── Two Fallen Angels trigger ── */ <<if !$questlines.fallenAngels.active && !$questlines.fallenAngels.specialAvailable && !$questlines.fallenAngels.shooting3Done>> <<set _angie = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _angela = $roster.find(function(w){ return w.name is "Angela"; })>> <<if _angie || _angela>> <<set $questlines.fallenAngels.active = true>> <<set $questlines.fallenAngels.star1 = _angie ? "Angie" : "Angela">> <<set $questlines.fallenAngels.step = Math.max($questlines.fallenAngels.step, 1)>> <</if>> <</if>> /* ── Two Fallen Angels step progression ── */ <<if $questlines.fallenAngels.active>> <<set _qlF = $questlines.fallenAngels>> <<set _fa1 = $roster.find(function(w){ return w.name is _qlF.star1; })>> <<set _angie2 = $roster.find(function(w){ return w.name is "Angie"; })>> <<set _angela2 = $roster.find(function(w){ return w.name is "Angela"; })>> <<if _qlF.step is 1 && _fa1 && _fa1.satisfaction >= 25>><<set _qlF.step = 2>><</if>> <<if _qlF.step >= 2 && _angie2 && _angela2 && !_qlF.star2>> <<set _qlF.star2 = (_qlF.star1 is "Angie") ? "Angela" : "Angie">> <<set _qlF.step = 3>> <</if>> <<set _fa2 = _qlF.star2 ? $roster.find(function(w){ return w.name is _qlF.star2; }) : null>> <<if _qlF.step is 3 && _fa2 && _fa2.satisfaction >= 25>> <<set _qlF.step = 4>> <<set _qlF.specialAvailable = true>> <<set _qlF.active = false>> <</if>> <</if>><<for _i = 0; _i < $roster.length; _i++>><<if $roster[_i].satisfaction <= 5 && !$roster[_i].lowSatAlerted>><<set $roster[_i].lowSatAlerted = true>><<set $zeroSatStar = $roster[_i].name>><</if>><</for>><<if $rival.roster.length > 0 && $allPositions.length > 0>><<set _ri = random(0, $rival.roster.length - 1)>> <<if $bnoEventDone>> <<set _bnoPositions = ["BJ", "Missionary"]>> <<set _bnoPos = _bnoPositions[random(0, _bnoPositions.length - 1)]>> <<if $rival.roster[_ri]>><<set $rivalLastShooting = { star: $rival.roster[_ri].name, position: _bnoPos }>><</if>> <<else>> <<set _rivalPositions = ["BJ", "Missionary", "Doggy", "Cowgirl", "Reverse Cowgirl"]>> <<set _rm = _rivalPositions[random(0, _rivalPositions.length - 1)]>> <<if $rival.roster[_ri]>><<set $rivalLastShooting = { star: $rival.roster[_ri].name, position: _rm }>><</if>> <</if>><</if>><<genTrends>><<checkRival>><<if $thirdRecruitDay > 0 && $player.day is $thirdRecruitDay + 7 && $roster.length > 0 && !$rivalOfferEvent>> <<set _lowestPop = 9999>><<set _lowestIdx = -1>> <<for _i = 0; _i < $roster.length; _i++>> <<if $roster[_i].popularity < _lowestPop>><<set _lowestPop = $roster[_i].popularity>><<set _lowestIdx = _i>><</if>> <</for>> <<if _lowestIdx >= 0 && $roster[_lowestIdx]>> <<set $rivalOfferEvent = true>> <<set $rivalOfferStar = $roster[_lowestIdx].name>> <</if>> <</if>><<if $player.day is 12 && !$contract1.active && !$contract1.accepted>> <<set _pool12 = ["hair:Brown","hair:Brown","hair:Blonde","hair:Blonde","hair:Black","hair:Black","height:Short","height:Short","height:Tall","height:Tall","ageCat:Young","ageCat:Young","ageCat:Veteran","ageCat:Veteran","breast:Small","breast:Small","breast:Large","breast:Large","breast:Huge","breast:Huge","breastType:Fake","breastType:Fake","breastType:Fake","breastType:Real","ethnicity:Latina","ethnicity:Latina","ethnicity:Asian","ethnicity:Asian","ethnicity:Black","ethnicity:Caucasian"]>> <<set _options = []>> <<set _numOptions12 = $contract3rdOptionItem.bought ? 3 : 2>> <<set $contractIsHarder = false>> <<for _oi = 0; _oi < _numOptions12; _oi++>> <<set _pick = _pool12[random(0, _pool12.length - 1)]>> <<set _ct = _pick.split(":")[0]>> <<set _cv = _pick.split(":")[1]>> <<set _options.push({ type: _ct, value: _cv })>> <</for>> <<set $contract1.active = true>> <<set $contract1.options = _options>> <</if>> <<if $contract1.accepted && !$contract1.failed>> <<if $player.day > $contract1.startDay + 3 && $contract1.shootingsDone < 2>> <<set $contract1.failed = true>> <<set $contract1.accepted = false>> <<if $contractIsHarder>><<set $player.reputation = Math.max(0, $player.reputation - 5)>><<else>><<set $player.reputation = Math.max(0, $player.reputation - 2)>><</if>> <<set $contractShopAvailableDay = $player.day + 3>> <</if>> <</if>> <<if $player.day is 35 && !$contract3.active && !$contract3.accepted && !$contract3.failed>> <<set $contract3.active = true>> <</if>> <<if $player.day is 45 && !$contract4.active && !$contract4.accepted && !$contract4.failed>> <<set _c4pool = $poolConfirmed.slice()>> <<if _c4pool.length >= 2>> <<set _c4i1 = random(0, _c4pool.length - 1)>> <<set $contract4.star1 = _c4pool[_c4i1]>> <<set _c4pool.splice(_c4i1, 1)>> <<set $contract4.star2 = _c4pool[random(0, _c4pool.length - 1)]>> <<elseif _c4pool.length is 1>> <<set $contract4.star1 = _c4pool[0]>> <<set $contract4.star2 = "">> <</if>> <<set $contract4.active = true>> <</if>> <<if $contract3.accepted && !$contract3.failed>> <<if $player.day >= 40 && $contract3.shootingsDone < 1>> <<set $contract3.failed = true>> <<set $contract3.accepted = false>> <<set $player.money -= 2000>> <</if>> <</if>> <<if $contract4.accepted && !$contract4.failed>> <<if $player.day >= 50 && $contract4.shootingsDone < 1>> <<set $contract4.failed = true>> <<set $contract4.accepted = false>> <<set $player.money -= 2000>> <</if>> <</if>> <<if $player.day is 8 && !$day5EventDone && $roster.length > 0>><<set $day5EventDone = true>><</if>><<if $player.day is 10 && !$objective1Notified>><<set $objective1Notified = true>><</if>><<if $player.reputation >= 15 && !$rep15EventDone>><<set $rep15EventDone = true>><<set $rep15EventPending = true>><</if>><<if $player.day is 25 && !$day22EventDone && $rival.roster.length > 0>><<set $day22EventDone = true>><</if>><<if $player.day is 18 && !$day18EventDone>><<set $day18EventDone = true>><</if>><<if $player.day is 22 && !$day25EventDone>><<set $day25EventDone = true>><</if>><<if $player.day is 29 && !$bnoEventDone>><<set $bnoEventDone = true>><</if>><<if $player.day is 30 && !$day30EventDone>><<set $day30EventDone = true>><</if>><<if $player.day is 15 && !$objective1Done>><<set $objective1Done = true>><<if $roster.length < 3>><<set $gameOver = true>><</if>><</if>><<if $skillfulChallengeActive && $player.day > $skillfulChallengeEndDay>><<set $skillfulChallengeActive = false>><</if>><<if $vacationEndDay > 0 && $player.day >= $vacationEndDay>><<for _i = 0; _i < $roster.length; _i++>><<if $roster[_i].name is $vacationStar>><<set $roster[_i].restDay = false>><<set $roster[_i].consecutiveDays = 0>><</if>><</for>><<set $vacationEndDay = -1>><<set $vacationStar = "">><</if>><</silently>><strong>📅 Day <<= $player.day>></strong> A new day begins! <<if $rivalSabotageStar>><<if $rivalSabotageStolen>>@@color:red;😈 <b><<= $rival.name>></b> got to <b><<= $rivalSabotageStar>></b> — satisfaction crashed and she walked. <<= $rival.name>> picked her up immediately.@@<<else>>@@color:orange;😈 <b><<= $rival.name>></b> got to <b><<= $rivalSabotageStar>></b> — satisfaction dropped by 10.@@<</if>> <<set $rivalSabotageStar = "">> <<set $rivalSabotageStolen = false>> <</if>> <<if $poachMessage>>@@color:red;⚠️ <<= $poachMessage>>@@ <<set $poachMessage = "">> <<if $poachVideoStar>><div id="poach-video-wrap"></div><<script>>jQuery(document).one(':passageend',function(){var s=SugarCube.State.variables.poachVideoStar;if(!s)return;var f=s.toLowerCase().replace(/ /g,'_');var src='videos/b_'+f+'_bj.webm';var el=document.getElementById('poach-video-wrap');if(el){var v=document.createElement('video');v.src=src;v.autoplay=true;v.loop=true;v.muted=true;v.playsInline=true;v.style.width='100%';v.style.maxWidth='480px';v.style.borderRadius='8px';v.style.marginTop='8px';v.onerror=function(){this.style.display='none';};el.innerHTML='';el.appendChild(v);}SugarCube.State.variables.poachVideoStar='';});<</script>><</if>> <</if>> <<if $rivalOfferShootingsLeft > 0>> <<set $rivalOfferShootingsLeft -= 1>> <<if $rivalOfferShootingsLeft is 0>> <<set _os = $roster.find(function(w){ return w.name is $rivalOfferStar; })>> <<if _os>> <<set _os.popularity += 1>> <<set _os.satisfaction = Math.min(100, _os.satisfaction + 10)>> <<set $rivalOfferEvent = false>> <</if>> <</if>> <</if>> <<if $gameOver>>[[💀 Game Over|GameOver]]<<elseif $player.day is 29 && $bnoEventDone>>[[🏢 New Rival!|BNOEvent]]<<elseif $weeklyPaid > 0>>[[💸 Weekly Upkeep|WeeklyUpkeep]]<<elseif $rivalPoachEvent>>[[⚠️ Rival Alert|RivalPoachEvent]]<<elseif $rivalOfferEvent>>[[🌟 Special Event|RivalOfferEvent]]<<elseif $rep15EventPending>>[[🌟 Special Event|Rep15Event]]<<elseif $player.day is 25 && $day22EventDone && $rival.roster.length > 0>>[[🌟 Special Event|Day22Event]]<<elseif $player.day is 18 && $day18EventDone>>[[📰 New Studio Alert|Day18Event]]<<elseif $player.day is 22 && $day25EventDone>>[[📰 Industry News|Day25Event]]<<elseif $player.day is 30 && $day30EventDone && $roster.length > 0>><<link `"📞 " + $rival.name + " Contact"`>><<goto "Day30Event">><</link>><<elseif $contract1.active && !$contract1.accepted && !$contract1.failed>>[[📋 New Contract!|Contract1Event]]<<elseif $contract1.failed>>[[❌ Contract Failed|Contract1Failed]]<<elseif $contract3.active && !$contract3.accepted && !$contract3.failed>>[[📋 Established Contract!|Contract3Event]]<<elseif $contract3.failed>>[[❌ Established Contract Failed|Contract3Failed]]<<elseif $contract4.active && !$contract4.accepted && !$contract4.failed>>[[📋 Investor Demand!|Contract4Event]]<<elseif $contract4.failed>>[[❌ Investor Contract Failed|Contract4Failed]]<<elseif $player.day is 10 && $objective1Notified>>[[🎯 Objective!|Objective1Event]]<<elseif $player.day is 8 && $day5EventDone && $roster.length > 0>>[[🌟 Special Event|Day5Event]]<<elseif $zeroSatStar>>[[⚠️ Critical Alert!|ZeroSatisfaction]]<<elseif $questlines.asianDuo.step is 2 && !$questlines.asianDuo.step2Notified>>[[🎌 Questline|AsianDuoStep2]]<<elseif $questlines.asianDuo.step is 3 && !$questlines.asianDuo.step3Notified>>[[🎌 Questline|AsianDuoStep3]]<<elseif $questlines.asianDuo.step is 4 && !$questlines.asianDuo.step4Notified>>[[🎌 Questline|AsianDuoStep4]]<<elseif $questlines.fallenAngels.step is 2 && !$questlines.fallenAngels.step2Notified>>[[👼 Questline|FallenAngelsStep2]]<<elseif $questlines.fallenAngels.step is 3 && !$questlines.fallenAngels.step3Notified>>[[👼 Questline|FallenAngelsStep3]]<<elseif $questlines.fallenAngels.step is 4 && !$questlines.fallenAngels.step4Notified>>[[👼 Questline|FallenAngelsStep4]]<<elseif $asianDuoShoot2Unlocked && $asianDuoShoot1Day > 0 && $player.day is $asianDuoShoot1Day + 3 && !$questlines.asianDuo.shooting2Done>>[[🎌 Asian Duo|AsianDuoShootUnlock2]]<<elseif $fallenAngelsShoot2Unlocked && $fallenAngelsShoot1Day > 0 && $player.day is $fallenAngelsShoot1Day + 3 && !$questlines.fallenAngels.shooting2Done>>[[👼 Fallen Angels|FAShootUnlock2]]<<elseif $fallenAngelsShoot3Unlocked && $fallenAngelsShoot2Day > 0 && $player.day is $fallenAngelsShoot2Day + 3 && !$questlines.fallenAngels.shooting3Done>>[[👼 Fallen Angels|FAShootUnlock3]]<<elseif $asianDuoAbsentDay > 0 && $player.day >= $asianDuoAbsentDay && !$asianDuoAbsentNotified>>[[🎌 Asian Duo|AsianDuoAbsent]]<<elseif $asianDuoGoneDay > 0 && $player.day >= $asianDuoGoneDay && !$asianDuoGoneNotified>>[[🎌 Asian Duo|AsianDuoGone]]<<elseif $asianDuoWebm2Day > 0 && $player.day is $asianDuoWebm2Day>>[[🎌 Asian Duo|AsianDuoWebm2]]<<elseif $asianDuoWebm3Day > 0 && $player.day is $asianDuoWebm3Day>>[[🎌 Asian Duo|AsianDuoWebm3]]<<elseif $fallenAngelsAbsentDay > 0 && $player.day >= $fallenAngelsAbsentDay && !$fallenAngelsAbsentNotified>>[[👼 Fallen Angels|FallenAngelsAbsent]]<<elseif $fallenAngelsGoneDay > 0 && $player.day >= $fallenAngelsGoneDay && !$fallenAngelsGoneNotified>>[[👼 Fallen Angels|FallenAngelsGone]]<<elseif $fallenAngelsWebm2Day > 0 && $player.day is $fallenAngelsWebm2Day>>[[👼 Fallen Angels|FallenAngelsWebm2]]<<elseif $fallenAngelsWebm3Day > 0 && $player.day is $fallenAngelsWebm3Day>>[[👼 Fallen Angels|FallenAngelsWebm3]]<<else>>[[📊 Dashboard|Dashboard]]<</if>>
<<set _highSat = -1>><<set _highIdx = -1>><<for _i = 0; _i < $roster.length; _i++>><<if $roster[_i].satisfaction > _highSat && !$roster[_i].restDay>><<set _highSat = $roster[_i].satisfaction>><<set _highIdx = _i>><</if>><</for>><<set _diva = $roster[_highIdx]>> <h1 style="margin:0 0 0.4em 0;">🌟 A Request</h1> <<set _portraitFile = _diva.name.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img id="day5-portrait" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> <<script>> jQuery(document).one(':passageend', function(){ var f = SugarCube.State.temporary.portraitFile || ''; var img = document.getElementById('day5-portrait'); if(img && f) img.src = 'img/portraits/' + f + '.jpg'; }); <</script>> <<= _diva.name>> leans against your office doorframe, wrapped in a robe. <em>"I've given you everything this week. My body needs a break — or I won't be able to give you what you actually want on camera."</em> <em>"Three days. I'll come back and make it worth the wait, I promise."</em> Their satisfaction: ❤️ <<= _diva.satisfaction>> <<capture _highIdx>> [[✅ Grant 3 days off|VacationAccept][$vacationIdx = _highIdx, $vacationDays = 3]] [[🤝 Offer 1 day off|VacationAccept][$vacationIdx = _highIdx, $vacationDays = 1]] [[❌ Refuse|VacationRefuse][$vacationIdx = _highIdx]] <</capture>>
<<set _diva = $roster[$vacationIdx]>><<set $vacationStar = _diva.name>><<set $vacationEndDay = $player.day + $vacationDays>><<set _diva.restDay = true>> <<if $vacationDays is 3>> <<set _diva.satisfaction = Math.min(100, _diva.satisfaction + 5)>> ✅ <em>She throws her arms around you. "Three days... I'll spend every minute thinking about what I'm going to do to that camera when I'm back. Don't miss me too much."</em> <b><<= _diva.name>></b> will be back on day <<= $vacationEndDay>>. <em>(+5 satisfaction)</em> <<else>> 🤝 <em>She sighs, runs a hand slowly down her side. "One day. Fine. I'll make it count — rest up, touch myself, come back ready to put on a show."</em> <b><<= _diva.name>></b> takes a day off. <</if>> [[📊 Dashboard|Dashboard]]
<<set _diva = $roster[$vacationIdx]>><<set _diva.satisfaction = Math.max(0, _diva.satisfaction - 10)>> ❌ <em>Her jaw tightens. "Fine. But you're going to feel this on camera — and not in a good way." She turns and walks out without looking back.</em> <b><<= _diva.name>></b>'s satisfaction: ❤️ <<= _diva.satisfaction>> <em>(−10)</em> [[📊 Dashboard|Dashboard]]
<<set $rivalPoachEvent = false>> <<set _lowestPop = 9999>><<set _lowestIdx = -1>> <<for _i = 0; _i < $roster.length; _i++>> <<if $roster[_i].popularity < _lowestPop>> <<set _lowestPop = $roster[_i].popularity>> <<set _lowestIdx = _i>> <</if>> <</for>> <<set $rivalOfferIdx = _lowestIdx>> <<set $rivalOfferStar = $roster[_lowestIdx].name>> <<set $roster[_lowestIdx].restDay = false>> <<set $roster[_lowestIdx].consecutiveDays = 0>> <h1 style="margin:0 0 0.4em 0;">📞 An Unexpected Visit</h1> <b><<= $rivalOfferStar>></b> stops by, looking uneasy. <em>"Hey... I got a call from <<= $rival.name>> today. They made me an offer. I wanted to tell you first before making any decision."</em> <em>"I like it here, but... I need to feel valued, you know?"</em> Their popularity: 🌟 <<= $roster[$rivalOfferIdx].popularity>> | Satisfaction: <<if $roster[$rivalOfferIdx].satisfaction >= 65>>💗<<elseif $roster[$rivalOfferIdx].satisfaction >= 40>>❤️<<elseif $roster[$rivalOfferIdx].satisfaction >= 12>>🧡<<else>>🖤<</if>> <<= $roster[$rivalOfferIdx].satisfaction>> [[🎬 Give them 3 productions|RivalOfferChallenge]] <em>(they stay, fatigue resets — complete 3 productions to earn their loyalty)</em> [[👋 Let them go|RivalOfferLeave]] <em>(they join <<= $rival.name>>, you receive $<<= Math.ceil($roster[$rivalOfferIdx].contractCost * 0.5).toLocaleString()>>)</em>
<<set $rivalOfferChallenge = true>> <<set $rivalOfferShootingsDone = 0>> <<set $roster[$rivalOfferIdx].restDay = false>> <<set $roster[$rivalOfferIdx].consecutiveDays = 0>> <<set $roster[$rivalOfferIdx].lastShootingDay = $player.day>> <em>She presses a hand against your chest. "Three shoots. I want to feel it every single time." Her eyes don't leave yours. "Don't disappoint me."</em> <b><<= $rivalOfferStar>></b> stays! Complete <b>3 productions</b> featuring them to prove their value. The sidebar will track your progress. [[📊 Dashboard|Dashboard]] /* ════════════════════════════════════════════ PASSAGE : WeeklyUpkeep ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">💸 Weekly Upkeep</h1> It's payday! The following amounts have been deducted from your account: <<for _i = 0; _i < $roster.length; _i++>> <<set _w = $roster[_i]>> - <b><<= _w.name>></b> — $<<= (_w.popularity * 70).toLocaleString()>> <</for>> Total paid: <b>$<<= $weeklyPaid.toLocaleString()>></b> Remaining balance: <b>@@color:<<= $player.money < 0 ? "red" : "white">>;$<<= $player.money.toLocaleString()>>@@</b> <<if $player.money < 0>> @@color:red;⚠️ <b>Your agency is in the red!</b> All talents lose <b>5 satisfaction</b>.@@ <<for _i = 0; _i < $roster.length; _i++>> <<set $roster[_i].satisfaction = Math.max(0, $roster[_i].satisfaction - 5)>> <</for>> <em>You must sell contracts to get back above $0 before continuing.</em> [[💸 Sell Contracts|SellContracts]] <<elseif $zeroSatStar>> [[⚠️ Critical Alert!|ZeroSatisfaction]] <<else>> [[📊 Dashboard|Dashboard]] <</if>> /* ════════════════════════════════════════════ PASSAGE : SellContracts ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">💸 Sell Contracts</h1> @@color:red;Balance: <b>$<<= $player.money.toLocaleString()>></b>@@ — You must reach $0 to continue. Sell a talent's contract at <b>50% of their contract cost</b>. They have a <b>25% chance</b> of being picked up by <<= $rival.name>>. <div id="sell-roster-container"></div> <<if $player.money >= 0>> @@color:green;✅ You're back above $0!@@ <<if !$trophies.brokeBurBack>><<set $trophies.brokeBurBack = true>><<set $newTrophy = "🏆 Broke But Back — survived a negative upkeep!">><</if>> [[▶️ Continue|Dashboard]] <</if>> <<script>> jQuery(document).one(':passageend', function(){ function renderSell(){ var roster = SugarCube.State.variables.roster; var rival = SugarCube.State.variables.rival; var player = SugarCube.State.variables.player; var wrap = document.getElementById('sell-roster-container'); if(!wrap) return; if(roster.length === 0){ wrap.innerHTML = '<em>No talents left to sell.</em>'; return; } var html = '<div style="display:flex;flex-wrap:wrap;gap:10px;margin:10px 0;">'; roster.forEach(function(w, idx){ var sellPrice = Math.ceil(w.contractCost * 0.5); var file = w.name.toLowerCase().replace(/ /g,'_'); html += '<div style="background:#111;border:1px solid #333;border-radius:8px;padding:10px;text-align:center;width:140px;">'; html += '<img src="img/portraits/'+file+'.jpg" style="width:80px;height:80px;object-fit:cover;border-radius:6px;display:block;margin:0 auto 6px;">'; html += '<b style="font-size:0.9em;">'+w.name+'</b><br>'; html += '<small style="color:#888;">🌟 '+w.popularity+' | ❤️ '+w.satisfaction+'</small><br>'; html += '<small style="color:#4a9eff;">+$'+sellPrice.toLocaleString()+'</small><br>'; html += '<button data-idx="'+idx+'" data-price="'+sellPrice+'" style="margin-top:6px;padding:4px 10px;background:#1a1a2e;border:1px solid #cc4444;color:#cc4444;border-radius:4px;cursor:pointer;font-size:0.8em;">💸 Sell</button>'; html += '\x3c/div>'; }); html += '\x3c/div>'; wrap.innerHTML = html; wrap.querySelectorAll('button[data-idx]').forEach(function(btn){ btn.addEventListener('click', function(){ var idx = parseInt(this.getAttribute('data-idx')); var price = parseInt(this.getAttribute('data-price')); var w = SugarCube.State.variables.roster[idx]; if(!w) return; /* Remove from roster */ SugarCube.State.variables.roster.splice(idx, 1); SugarCube.State.variables.player.money += price; /* 25% chance rival picks them up */ if(Math.random() < 0.25){ SugarCube.State.variables.poachMessage = (SugarCube.State.variables.poachMessage || '') + ' ' + w.name + ' was picked up by ' + SugarCube.State.variables.rival.name + ' — went to find out how massive they are.'; w.available = false; SugarCube.State.variables.rival.roster.push(w); } else { /* Return to recruit pool as available */ var pool = SugarCube.State.variables.recruitPool; var existing = pool.find(function(r){ return r.name === w.name; }); if(existing) existing.available = true; } /* Re-render */ SugarCube.Engine.play('SellContracts'); }); }); } renderSell(); }); <</script>> /* ════════════════════════════════════════════ PASSAGE : ZeroSatisfaction ════════════════════════════════════════════ */
<h1 style="margin:0 0 0.4em 0;">⚠️ Warning!</h1> <<set _zsFile = $zeroSatStar.toLowerCase().replace(/ /g, "_")>> <div style="text-align:center;margin:10px 0;"><img data-portrait-var="_zsFile" style="width:160px;height:160px;object-fit:cover;border-radius:12px;box-shadow:0 4px 16px rgba(0,0,0,0.5);" src=""></div> @@color:red;<<= $zeroSatStar>>'s satisfaction has dropped to critical levels!@@ She's not performing anymore — she's enduring it. The spark is gone. Keep this up and she'll walk straight into <<= $rival.name>>'s arms — and their bed. <em>Get her back on set fast — and give her what she actually enjoys.</em> <<set $zeroSatStar = "">> /* ── Questline: Asian Duo trigger ── */ <<if !$questlines.asianDuo.active && !$questlines.asianDuo.specialAvailable>> <<set _kimmy = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _kimmy || _lulu>> <<set $questlines.asianDuo.active = true>> <<set $questlines.asianDuo.star1 = _kimmy ? "Kimmy" : "Lulu">> <<set $questlines.asianDuo.step = Math.max($questlines.asianDuo.step, 1)>> <</if>> <</if>> /* ── Asian Duo step progression ── */ <<if $questlines.asianDuo.active>> <<set _ql = $questlines.asianDuo>> <<set _s1 = $roster.find(function(w){ return w.name is _ql.star1; })>> <<set _kimmy2 = $roster.find(function(w){ return w.name is "Kimmy"; })>> <<set _lulu2 = $roster.find(function(w){ return w.name is "Lulu"; })>> <<if _ql.step is 1 && _s1 && _s1.satisfaction >= 25>> <<set _ql.step = 2>> <</if>> <<if _ql.step >= 2>> <<if _kimmy2 && _lulu2>> <<if !_ql.star2>> <<set _ql.star2 = (_ql.star1 is "Kimmy") ? "Lulu" : "Kimmy">> <<set _ql.step = 3>> <</if>> <</if>> <</if>> <<set _s2 = _ql.star2 ? $roster.find(function(w){ return w.name is _ql.star2; }) : null>> <<if _ql.step is 3 && _s2 && _s2.satisfaction >= 25>> <<set _ql.step = 4>> <<set _ql.specialAvailable = true>> <<set _ql.active = false>> <</if>> <</if>> [[⚠️ Understood — Go to Dashboard|Dashboard]]