JavaScript must be enabled to play.
Browser lacks capabilities required to play.
Upgrade or switch to another browser.
Loading…
<<nobr>> /* ── MAILBOX HEADER ── */ <div class="home-header"> <span class="gametitle"><span class="big-letter"> C</span>ritter<span class="big-letter">N</span>est</span> <<set _unreadCount = $mailbox.filter(mail => !mail.read).length>> <<link [img[https://i.imgur.com/kNmJaQS.png][Mailbox]]>><</link>> <<if _unreadCount > 0>> <span class="notification-circle">_unreadCount</span> <</if>> </div> <<if $loginRewards.pendingClaim>> <<run setup.showLoginRewardDialog()>> <</if>> /* ── TUTORIAL PANEL ── */ <<set _allComplete = Object.values($tutorialQuests.quests).every(function(q) { return q.complete; })>> <<if !$tutorialQuests.dismissed && !_allComplete>> <div class="tutorial-panel"> <<if !$tutorialQuests.open>> <div class="tutorial-teaser"> <span>📋 <strong>Getting Started</strong></span> <div class="tutorial-teaser-buttons"> <<link "View Quests">><<set $tutorialQuests.open to true>><<refresh>><</link>> <span class="tutorial-divider">|</span> <<link "Dismiss" "Home">> <<run window.dismissTutorial()>> <<addXP $dismissXP>> <</link>> </div> </div> <<else>> <div class="tutorial-header"> <strong>📋 Getting Started</strong> <div class="tutorial-header-buttons"> <<link "Collapse">><<set $tutorialQuests.open = false>><<refresh>><</link>> <span class="tutorial-divider">|</span> <<link "Dismiss" "Home">> <<run window.dismissTutorial()>> <<addXP $dismissXP>> <</link>> </div> </div> <div class="tutorial-quest-list"> <<set _allAccepted = Object.values($tutorialQuests.quests).every(function(q) { return q.accepted; })>> <<if !_allAccepted>> <div class="accept-button"> <<link "Accept All" "Home">> <<for _questId, _quest range $tutorialQuests.quests>> <<set $tutorialQuests.quests[_questId].accepted = true>> <</for>> <</link>> </div> <</if>> <<for _questId, _quest range $tutorialQuests.quests>> <<capture _questId, _quest>> <div @class="'tutorial-quest' + (_quest.complete ? ' quest-complete' : _quest.accepted ? ' quest-active' : '')"> <div class="quest-title"> <<if _quest.complete>>✅<<elseif _quest.accepted>>🔄<<else>>📌<</if>> <strong><<print _quest.label>></strong> <span class="quest-reward">+<<print _quest.xp>> XP | +$<<print _quest.money>></span> </div> <div class="quest-desc"><<print _quest.desc>></div> <<if _quest.complete>> <div class="quest-claimed">Complete!</div> <<elseif _quest.accepted>> <div class="quest-track-row"> <i>In progress...</i> <<if $tutorialQuests.tracked == _questId>> <<link "📍 Tracking" "Home">><<set $tutorialQuests.tracked = null>><</link>> <<else>> <<link "🎯 Track" "Home">><<set $tutorialQuests.tracked = _questId>><</link>> <</if>> </div> <<else>> <<link "Accept" "Home">><<set $tutorialQuests.quests[_questId].accepted = true>><</link>> <</if>> </div> <</capture>> <</for>> </div> <</if>> </div> <</if>> /* ── FEATURED CRITTER ── */ <<if ndef $featuredCreatureIndex>><<set $featuredCreatureIndex = -1>><</if>> <<set _featuredIndex = -1>> <<if $featuredCreatureIndex >= 0 && $playerCreatures[$featuredCreatureIndex] && $playerCreatures[$featuredCreatureIndex].stage !== "egg">> <<set _featuredIndex = $featuredCreatureIndex>> <<else>> <<for _i = 0; _i < $playerCreatures.length; _i++>> <<if $playerCreatures[_i].stage !== "egg" && _featuredIndex === -1>> <<set _featuredIndex = _i>> <</if>> <</for>> <</if>> <<if _featuredIndex >= 0>> <<set _fc = $playerCreatures[_featuredIndex]>> <<set _fcName = (ndef _fc.petName || _fc.petName === "") ? _fc.name : _fc.petName>> <<set _fcTemplate = setup.creatureTemplates[_fc.species]>> <<set _fcSize = _fc.displayTraits.size>> <<set _fcColor = _fc.displayTraits.color>> <<set _fcPattern = _fc.displayTraits.pattern>> <<set _fcGender = _fc.gender.toLowerCase()>> <<if _fc.stage === "baby">> /* ── baby sprite ── */ <<if _fcTemplate.babySpriteColumns[_fcColor] !== undefined>> <<set _fcCol = _fcTemplate.babySpriteColumns[_fcColor]>> <<else>> <<set _fcCol = _fcTemplate.babySpriteColumns[_fcTemplate.colorDominance[0]]>> <</if>> <<set _fcSpriteSheet = _fcTemplate.avatars[_fcGender].babySpriteSheets[_fcSize]>> <<if _fcSize === "large">> <<set _fcXPos = _fcCol * -180>><<set _fcDim = "180px">> <<elseif _fcSize === "medium">> <<set _fcXPos = _fcCol * -120>><<set _fcDim = "120px">> <<else>> <<set _fcXPos = _fcCol * -60>><<set _fcDim = "60px">> <</if>> <<else>> /* ── adult sprite ── */ <<set _fcColorPattern = setup.getSpriteKey(_fc.name, _fcColor, _fcPattern)>> <<set _fcCol = _fcTemplate.spriteColumns[_fcColorPattern]>> <<if _fcCol === undefined>> <<set _fcCol = _fcTemplate.spriteColumns[_fcTemplate.colorDominance[0] + "_" + _fcTemplate.patternDominance[0]]>> <</if>> <<set _fcSpriteSheet = _fcTemplate.avatars[_fcGender].patternSpriteSheets[_fcSize]>> <<if _fcSize === "large">> <<set _fcXPos = _fcCol * -240>><<set _fcDim = "240px">> <<elseif _fcSize === "medium">> <<set _fcXPos = _fcCol * -160>><<set _fcDim = "160px">> <<else>> <<set _fcXPos = _fcCol * -80>><<set _fcDim = "80px">> <</if>> <</if>> <div class="featured-critter"> <div class="creature-layers" @style="'width:' + _fcDim + ';height:' + _fcDim + ';margin:0 auto;'"> <<if _fc.mimikin !== null>> <<if _fcSize is "small">> <div class="mimikin-small-display">[img[_fc.mimikin.image]]</div> <<elseif _fcSize is "medium">> <div class="mimikin-medium-display">[img[_fc.mimikin.image]]</div> <<else>> <div class="mimikin-large-display">[img[_fc.mimikin.image]]</div> <</if>> <</if>> <div class="creature-sprite-pattern" @style="'background-image:url(' + _fcSpriteSheet + ');background-position:' + _fcXPos + 'px 0px;width:' + _fcDim + ';height:' + _fcDim + ';'"> </div> </div> <div class="featured-critter-name"> <<link _fcName "ViewCreature">> <<set $currentCreature = _featuredIndex>> <</link>> <<if _fc.gender === "Male">>♂️<<else>>♀️<</if>> <<link "✎" "FeaturedCreatureModal">><</link>> </div> </div> <</if>> /* ── QUICK CARE ── */ <div class="home-section" id="quick-care-section"> <p2><strong>Quick Care</strong></p2> <div class="care-container"> /* Feed All */ <<set _eligibleFeed = []>> <<if $playerCreatures && $playerCreatures.length > 0>> <<for _i = 0; _i < $playerCreatures.length; _i++>> <<set _creature = $playerCreatures[_i]>> <<set _hungerPercent = (_creature.hungerCur / _creature.hungerMax) * 100>> <<if _creature.stage !== "egg" && _hungerPercent < 90>> <<set _eligibleFeed.push(_i)>> <</if>> <</for>> <<set _hasEnoughFood = false>> <<if _eligibleFeed.length > 0>> <<for _food range setup.creatureFoods>> <<if $inventory[_food] >= _eligibleFeed.length>> <<set _hasEnoughFood = true>><<break>> <</if>> <</for>> <<if !_hasEnoughFood>> <<for _itemId, _qty range $inventory>> <<if _qty >= _eligibleFeed.length && $mealNames && $mealNames[_itemId]>> <<set _hasEnoughFood = true>><<break>> <</if>> <</for>> <</if>> <</if>> <<if _eligibleFeed.length < 1>> <p class="care-status">All creatures are satisfied ✨</p> <<elseif !_hasEnoughFood>> <p class="care-status">Not enough food for all hungry critters. Visit the Market!</p> <<else>> <<link "🍖 Feed All" "Home">> <<set $eligibleCreaturesToFeed = _eligibleFeed>> <<set $showFoodModal = true>> <<set $feedingAll = true>> <</link>> <</if>> <</if>> /* Care All */ <<set _eligibleCare = []>> <<if $playerCreatures && $playerCreatures.length > 0>> <<for _i = 0; _i < $playerCreatures.length; _i++>> <<set _creature = $playerCreatures[_i]>> <<set _carePercent = (_creature.careCur / _creature.careMax) * 100>> <<if _creature.stage !== "egg" && _carePercent < 100>> <<set _eligibleCare.push(_i)>> <</if>> <</for>> <<if _eligibleCare.length > 0>> <<link "🧼 Care for All" "Home">> <<set $eligibleCreaturesToCare = _eligibleCare>> <<set $showCareConfirm = true>> <</link>> <<else>> <p class="care-status">All creatures cared for ❤️</p> <</if>> <</if>> </div> </div> /* ── HALLWAY LINKS ── */ <div class="home-section"> <p2><strong>Hallway</strong></p2> <div class="hallway-grid"> <a data-passage="Kitchen" class="hallway-card"> <img src="https://i.imgur.com/Tv1IlhR.png" class="hallway-icon"> <span>Kitchen</span> </a> <a data-passage="Inventory" class="hallway-card"> <img src="https://i.imgur.com/ttY1SO0.png" class="hallway-icon"> <span>Inventory</span> </a> <a data-passage="Achievements" class="hallway-card"> <img src="https://i.imgur.com/Zu90o1D.png" class="hallway-icon"> <span>Trophies</span> </a> <<if $freelancingAttempts lt $maxFreelancingAttempts>> <a class="hallway-card" href="javascript:void(0)" onclick="goFreelancing()"> <img src="https://i.imgur.com/c1sxiNm.png" class="hallway-icon"> <span>Freelancing</span> </a> <<else>> <div class="hallway-card hallway-card--disabled"> <img src="https://i.imgur.com/c1sxiNm.png" class="hallway-icon"> <span>Freelancing</span> </div> <</if>> </div> </div> /* ── FEED ALL MODAL ── */ <<if $showFoodModal && $feedingAll && $eligibleCreaturesToFeed>> <div class="modal-overlay" id="modal-overlay"> <div class="modal-content"> <div class="modal-header"> <h3>Select Food for All</h3> <<link "×" "Home">> <<unset $showFoodModal>><<unset $eligibleCreaturesToFeed>><<unset $feedingAll>> <</link>> </div> <p1>Choose food for <<print $eligibleCreaturesToFeed.length>> hungry critter<<if $eligibleCreaturesToFeed.length > 1>>s<</if>>:</p1> <div class="ingredient-list"> <<for _food range setup.creatureFoods>> <<if $inventory[_food] >= $eligibleCreaturesToFeed.length>> <<capture _food>> <div class="ingredient-select-card"> <<link `setup.items[_food].name + " (" + $inventory[_food] + ")"` "Home">> <<for _i range $eligibleCreaturesToFeed>> <<set $playerCreatures[_i].fedCount += 1>> <<set $playerCreatures[_i].hungerCur += 20>> <<set $playerCreatures[_i].hungerCur = Math.min($playerCreatures[_i].hungerCur, $playerCreatures[_i].hungerMax)>> <<run unlockAchievement("firstFeed")>> <<run updateAchievementProgress("feedTenTimes", 1)>> <<run updateAchievementProgress("feedFiftyTimes", 1)>> <<run updateAchievementProgress("feedHundredTimes", 1)>> <<if setup.items[_food].foodBuffs>> <<set _buffs = setup.items[_food].foodBuffs>> <<if _buffs.affection>><<set $playerCreatures[_i].affection = ($playerCreatures[_i].affection || 0) + _buffs.affection>><</if>> <<if _buffs.energy>><<set $playerCreatures[_i].energy = ($playerCreatures[_i].energy || 0) + _buffs.energy>><</if>> <<if _buffs.happiness>><<set $playerCreatures[_i].happiness = ($playerCreatures[_i].happiness || 0) + _buffs.happiness>><</if>> <</if>> <</for>> <<set $inventory[_food] -= $eligibleCreaturesToFeed.length>> <<unset $showFoodModal>><<unset $eligibleCreaturesToFeed>><<unset $feedingAll>> <<if $tutorialQuests.quests.feedCreature.accepted && !$tutorialQuests.quests.feedCreature.complete>> <<set $tutorialQuests.quests.feedCreature.complete = true>><<addXP 20>><<set $money += 50>> <</if>> <</link>> </div> <</capture>> <</if>> <</for>> <<for _mealId, _qty range $inventory>> <<if _qty >= $eligibleCreaturesToFeed.length && $mealNames && $mealNames[_mealId]>> <<capture _mealId>> <div class="ingredient-select-card"> <<link `$mealNames[_mealId] + " (" + $inventory[_mealId] + ")"` "Home">> <<for _i range $eligibleCreaturesToFeed>> <<set $playerCreatures[_i].hungerCur to Math.min($playerCreatures[_i].hungerMax, $playerCreatures[_i].hungerCur += 20)>> <</for>> <<set $inventory[_mealId] -= $eligibleCreaturesToFeed.length>> <<unset $showFoodModal>><<unset $eligibleCreaturesToFeed>><<unset $feedingAll>> <<run updateAchievementProgress("feedTenTimes", 1)>> <<run updateAchievementProgress("feedFiftyTimes", 1)>> <<run updateAchievementProgress("feedHundredTimes", 1)>> <<if $tutorialQuests.quests.feedCreature.accepted && !$tutorialQuests.quests.feedCreature.complete>> <<set $tutorialQuests.quests.feedCreature.complete = true>><<addXP 20>><<set $money += 50>> <</if>> <</link>> </div> <</capture>> <</if>> <</for>> </div> </div> </div> <</if>> /* ── CARE ALL MODAL ── */ <<if $showCareConfirm && $eligibleCreaturesToCare>> <div class="modal-overlay"> <div class="modal-content"> <div class="modal-header"> <h3>Care for All Creatures</h3> <<link "×" "Home">><<unset $showCareConfirm>><<unset $eligibleCreaturesToCare>><</link>> </div> <p1>Care for <<print $eligibleCreaturesToCare.length>> critter<<if $eligibleCreaturesToCare.length > 1>>s<</if>>. Continue?</p1> <div class="creature-action"> <<link "🧼✨ Yes, care for all" "Home">> <<for _i range $eligibleCreaturesToCare>> <<set $playerCreatures[_i].careCur += 30>> <<set $playerCreatures[_i].careCur = Math.min($playerCreatures[_i].careCur, $playerCreatures[_i].careMax)>> <<if $tutorialQuests.quests.careCreature.accepted && !$tutorialQuests.quests.careCreature.complete>> <<set $tutorialQuests.quests.careCreature.complete = true>><<addXP 20>><<set $money += 50>> <</if>> <<run unlockAchievement("firstCare")>> <<run updateAchievementProgress("careTenTimes", 1)>> <<run updateAchievementProgress("careFiftyTimes", 1)>> <<run updateAchievementProgress("careHundredTimes", 1)>> <</for>> <<unset $showCareConfirm>><<unset $eligibleCreaturesToCare>> <</link>> </div> </div> </div> <</if>> <</nobr>>
<<include "InitCreatureSetup">> <<include "InitShopInventory">> <<include "InitTrophyRequest">> <<include "InitFreelanceComp">> <<include "InitFarming">> <<include "InitFishing">> <<include "InitCooking">> <<include "InitRealEstate">> <<include "InitRanks">> <<include "InitLocation">> <<include "InitMimikins">> <<set $gameStarted to true>> <<run setup.startTracking()>>
<<nobr>> <<widget "breedCreatures">> <<set _parent1 to $args[0]>> <<set _parent2 to $args[1]>> /* Check fertility status of both parents */ <<set _parent1Fertile to isCreatureFertile(_parent1)>> <<set _parent2Fertile to isCreatureFertile(_parent2)>> /* Determine breeding success and egg count based on fertility */ <<if _parent1Fertile && _parent2Fertile>> /* Both fertile - best outcome */ <<set _breedingSuccess to true>> <<set _numEggs to random(2, 4)>> <<elseif _parent1Fertile || _parent2Fertile>> /* One fertile - medium outcome */ <<set _breedingSuccess to random(1, 100) <= 25>> <<set _numEggs to _breedingSuccess ? random(1, 3) : 0>> <<else>> /* Neither fertile - worst outcome */ <<set _breedingSuccess to random(1, 100) <= 50>> <<set _numEggs to _breedingSuccess ? random(1, 2) : 0>> <</if>> <<set _currentEggs to setup.countEggs()>> <<set _availableSlots to $maxEggSlots - _currentEggs>> <<set _numEggs to Math.min(_numEggs, _availableSlots)>> <<set $lastBreedingResults to []>> <<set $breedingSuccessful to _breedingSuccess>> <<set $inbreedingPenalty to checkInbreeding(_parent1, _parent2, $playerCreatures) !== null>> <<set $bothParentsFertile to (_parent1Fertile && _parent2Fertile)>> <<set $oneParentFertile to ((_parent1Fertile || _parent2Fertile) && !(_parent1Fertile && _parent2Fertile))>> <<if _breedingSuccess>> <<for _e to 0; _e < _numEggs; _e++>> /* Inherit species alleles from parents */ <<set _template1 to setup.creatureTemplates[_parent1.name]>> <<set _template2 to setup.creatureTemplates[_parent2.name]>> /* Each parent contributes their dominant allele as primary, recessive as secondary */ <<set _parent1DominantSpecies to _parent1.genes.species[0]>> <<set _parent1RecessiveSpecies to _parent1.genes.species[1]>> <<set _parent2DominantSpecies to _parent2.genes.species[0]>> <<set _parent2RecessiveSpecies to _parent2.genes.species[1]>> /* Each parent randomly passes either their dominant or recessive allele */ <<set _inheritedFromParent1 to random(1, 100) <= 50 ? _parent1DominantSpecies : _parent1RecessiveSpecies>> <<set _inheritedFromParent2 to random(1, 100) <= 50 ? _parent2DominantSpecies : _parent2RecessiveSpecies>> /* If both parents passed the same allele, it's homozygous */ <<if _inheritedFromParent1 === _inheritedFromParent2>> <<set _speciesGene1 to _inheritedFromParent1>> <<set _speciesGene2 to _inheritedFromParent1>> <<else>> /* Determine which is dominant based on rarity */ <<set _inheritedWeight1 to setup.rarityWeights[setup.creatureTemplates[_inheritedFromParent1].rarity]>> <<set _inheritedWeight2 to setup.rarityWeights[setup.creatureTemplates[_inheritedFromParent2].rarity]>> <<if _inheritedWeight1 > _inheritedWeight2>> /* Parent1's allele is more common, so it's dominant */ <<set _speciesGene1 to _inheritedFromParent1>> <<set _speciesGene2 to _inheritedFromParent2>> <<elseif _inheritedWeight2 > _inheritedWeight1>> /* Parent2's allele is more common, so it's dominant */ <<set _speciesGene1 to _inheritedFromParent2>> <<set _speciesGene2 to _inheritedFromParent1>> <<else>> /* Same rarity — coin flip for dominant */ <<if random(1, 100) <= 50>> <<set _speciesGene1 to _inheritedFromParent1>> <<set _speciesGene2 to _inheritedFromParent2>> <<else>> <<set _speciesGene1 to _inheritedFromParent2>> <<set _speciesGene2 to _inheritedFromParent1>> <</if>> <</if>> <</if>> /* Expressed species is always slot 0 */ <<set _chosenSpecies to _speciesGene1>> <<set _chosenTemplate to setup.creatureTemplates[_chosenSpecies]>> /* Inherit genes from parents */ <<set _colorGene1 = either(_parent1.genes.color[0], _parent1.genes.color[1])>> <<set _colorGene2 = either(_parent2.genes.color[0], _parent2.genes.color[1])>> <<set _patternGene1 = either(_parent1.genes.pattern[0], _parent1.genes.pattern[1])>> <<set _patternGene2 = either(_parent2.genes.pattern[0], _parent2.genes.pattern[1])>> <<set _sizeGene1 = either(_parent1.genes.size[0], _parent1.genes.size[1])>> <<set _sizeGene2 = either(_parent2.genes.size[0], _parent2.genes.size[1])>> /* Sanitize color alleles for the chosen species */ <<set _template1 to setup.creatureTemplates[_parent1.name]>> <<set _template2 to setup.creatureTemplates[_parent2.name]>> <<set _sanitized1 to sanitizeColorAllele(_colorGene1, _chosenTemplate, _parent1.species === _chosenSpecies ? null : _template1)>> <<set _sanitized2 to sanitizeColorAllele(_colorGene2, _chosenTemplate, _parent2.species === _chosenSpecies ? null : _template2)>> <<set _colorGene1 to _sanitized1.allele>> <<set _colorGene2 to _sanitized2.allele>> /* Store original genes for mutation tracking */ <<set _origColor1 = _colorGene1>> <<set _origColor2 = _colorGene2>> /* Apply mutations — skip if allele is already exotic from inheritance */ <<if !_sanitized1.wasExotic && !_sanitized2.wasExotic>> <<set _colorResult = applyMutation(_colorGene1, _colorGene2, _chosenTemplate, "color", $playerRank)>> <<set _colorGene1 = _colorResult[0]>> <<set _colorGene2 = _colorResult[1]>> <<elseif _sanitized1.wasExotic && _sanitized2.wasExotic>> /* Both exotic from inheritance — keep both, no mutation roll */ <<elseif _sanitized1.wasExotic>> <<set _colorResult = applyMutation(_colorGene1, _colorGene2, _chosenTemplate, "color", $playerRank)>> <<set _colorGene1 = _colorResult[0]>> <<set _colorGene2 = _colorResult[1]>> <<else>> <<set _colorResult = applyMutation(_colorGene1, _colorGene2, _chosenTemplate, "color", $playerRank)>> <<set _colorGene1 = _colorResult[0]>> <<set _colorGene2 = _colorResult[1]>> <</if>> <<set _patternResult = applyMutation(_patternGene1, _patternGene2, _chosenTemplate, "pattern")>> <<set _patternGene1 = _patternResult[0]>> <<set _patternGene2 = _patternResult[1]>> <<set _sizeResult = applyMutation(_sizeGene1, _sizeGene2, _chosenTemplate, "size")>> <<set _sizeGene1 = _sizeResult[0]>> <<set _sizeGene2 = _sizeResult[1]>> /* Track which traits mutated */ <<set _mutated = []>> <<if _colorGene1 !== _origColor1 || _colorGene2 !== _origColor2>> <<run _mutated.push("color")>> <</if>> /* Calculate displayed traits */ <<set _displayColor to getDisplayedTrait(_colorGene1, _colorGene2, _chosenTemplate.colorDominance, _mutated.includes("color"))>> <<set _displayPattern to getDisplayedTrait(_patternGene1, _patternGene2, _chosenTemplate.patternDominance)>> <<set _displaySize to getBlendedSize(_sizeGene1, _sizeGene2, _chosenTemplate.possibleSizes)>> <<set _mother to _parent1.gender === "Female" ? _parent1 : _parent2>> <<set _father to _parent1.gender === "Male" ? _parent1 : _parent2>> /* Create egg */ <<set _newEgg to { species: _chosenSpecies, name: _chosenSpecies, id: random(100000, 999999), gender: either("Male", "Female"), age: 0, stage: "egg", hatchSteps: $steps + setup.HATCH_STEPS[_chosenTemplate.rarity] || 500, generation: Math.max(_parent1.generation, _parent2.generation) + 1, parents: { motherId: _mother.id, fatherId: _father.id, motherName: _mother.petName || _mother.species, fatherName: _father.petName || _father.species, motherSpecies: _mother.species, fatherSpecies: _father.species }, grandparents: { maternalGrandmotherId: _mother.parents ? _mother.parents.motherId : null, maternalGrandfatherId: _mother.parents ? _mother.parents.fatherId : null, paternalGrandmotherId: _father.parents ? _father.parents.motherId : null, paternalGrandfatherId: _father.parents ? _father.parents.fatherId : null, maternalGrandmotherName: _mother.parents ? _mother.parents.motherName : null, maternalGrandfatherName: _mother.parents ? _mother.parents.fatherName : null, paternalGrandmotherName: _father.parents ? _father.parents.motherName : null, paternalGrandfatherName: _father.parents ? _father.parents.fatherName : null, maternalGrandmotherSpecies: (_mother.parents && _mother.parents.motherSpecies) ? _mother.parents.motherSpecies : null, maternalGrandfatherSpecies: (_mother.parents && _mother.parents.fatherSpecies) ? _mother.parents.fatherSpecies : null, paternalGrandmotherSpecies: (_father.parents && _father.parents.motherSpecies) ? _father.parents.motherSpecies : null, paternalGrandfatherSpecies: (_father.parents && _father.parents.fatherSpecies) ? _father.parents.fatherSpecies : null }, genes: { color: [_colorGene1, _colorGene2], pattern: [_patternGene1, _patternGene2], size: [_sizeGene1, _sizeGene2], species: [_speciesGene1, _speciesGene2] }, displayTraits: { color: _displayColor, pattern: _displayPattern, size: _displaySize }, careCur: 50, careMax: 100, affectionCur: 70, affectionMax: 100, staminaCur: 3, staminaMax: $inbreedingPenalty ? 2 : 3, type: _chosenTemplate.type, rarity: _chosenTemplate.rarity, }>> <<if _newEgg.displayTraits.size === "large">> <<set _newEgg.hungerCur to 60>> <<set _newEgg.hungerMax to 120>> <<elseif _newEgg.displayTraits.size === "medium">> <<set _newEgg.hungerCur to 50>> <<set _newEgg.hungerMax to 100>> <<else>> <<set _newEgg.hungerCur to 40>> <<set _newEgg.hungerMax to 80>> <</if>> <<if $playerXP gte 500>> <<set _newEgg.geneticTestingDone = true>> <<else>> <<set _newEgg.geneticTestingDone to false>> <</if>> <<set _newEgg.flavorText to _chosenTemplate.flavorText>> <<set _newEgg.mutations to _mutated>> <<set _newEgg.mimikin to null>> <<run _newEgg.fertilityOffset = Date.now()>> <<run _newEgg.lastAgeDay = Date.now()>> <<run _newEgg.lastHungerDrain = Date.now()>> <<run _newEgg.lastCareDrain = Date.now()>> <<run _newEgg.lastStaminaRegen = Date.now()>> <<run _newEgg.wasHappy = false>> <<set _newEgg.immortal = false>> <<run finalizeDisplayTraits(_newEgg)>> <<run $playerCreatures.push(_newEgg)>> <<run $lastBreedingResults.push(_newEgg)>> /* Achievement triggers - per egg */ <<run window.updateAchievementProgress("tenEggs", 1)>> <<run window.updateAchievementProgress("fiftyEggs", 1)>> <<run window.updateAchievementProgress("hundredEggs", 1)>> <<if $playerCreatures.length >= 5>><<run window.unlockAchievement("fiveCreatures")>><</if>> <<if $playerCreatures.length >= 10>><<run window.unlockAchievement("tenCreatures")>><</if>> <<if $playerCreatures.length >= 20>><<run window.unlockAchievement("twentyCreatures")>><</if>> <<if _newEgg.generation >= 3>><<run window.unlockAchievement("thirdGeneration")>><</if>> <<if _newEgg.generation >= 5>><<run window.unlockAchievement("fifthGeneration")>><</if>> <<if _newEgg.generation >= 10>><<run window.unlockAchievement("tenthGeneration")>><</if>> <</for>> <</if>> <<if _breedingSuccess>> <<run window.unlockAchievement("firstBreeding")>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<set _creature = $playerCreatures[$currentCreature]>> <div class="passage-container"> /* ── NAME + RENAME ── */ <div class="profile-name-row"> <h4 style="margin:0;"> <<if _creature.stage === "baby">>🍼 <<elseif _creature.stage === "egg">>🥚 <</if>><<creatureName _creature>> </h4> <<button "✏️">> <<set _newName = prompt("Enter a new name for your critter:", _creature.petName)>> <<if _newName and _newName.trim() !== "">> <<set _creature.petName = _newName.trim()>> <<goto `passage()`>> <<run unlockAchievement("firstRename")>> <</if>> <</button>> </div> /* ── SPRITE + FLAVOR TEXT ── */ <div class="profile-hero"> <div class="mimikin-button"> <<link "𐔌՞. .՞𐦯 mimikins" "MimikinModal">> <</link>> </div> <div class="creature-profile-container" @style="'background-image: url(' + setup.typeBackgrounds[_creature.type] + ');'"> <<if _creature.mimikin !== null>> <div class="mimikin-display"> [img[_creature.mimikin.image]] </div> <<else>> <</if>> <div class="creature-display"> <<set _template to setup.creatureTemplates[_creature.name]>> <<set _size to _creature.displayTraits.size>> <<set _gender to _creature.gender.toLowerCase()>> <<if _creature.stage === "egg">> <div class="egg-placeholder" @style="'font-size: ' + (_size === 'large' ? '120px' : _size === 'medium' ? '80px' : '60px')">🥚</div> <<elseif _creature.stage === "baby">> <<set _template to setup.creatureTemplates[_creature.species]>> <<set _color to _creature.displayTraits.color>> <<if _template.babySpriteColumns[_color] !== undefined>> <<set _col to _template.babySpriteColumns[_color]>> <<else>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<set _babySpriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<if _size === "large">> <<set _xPos to _col * -180>><<set _dimensions to "180px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>><<set _dimensions to "120px">> <<else>> <<set _xPos to _col * -60>><<set _dimensions to "60px">> <</if>> <div class="creature-layers" @style="'width:' + _dimensions + ';height:' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _babySpriteSheet + ');background-position:' + _xPos + 'px 0px;width:' + _dimensions + ';height:' + _dimensions + ';'"> </div> </div> <<else>> <<set _pattern to _creature.displayTraits.pattern>> <<set _color to _creature.displayTraits.color>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to _color + "_" + _pattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _size === "large">> <<set _xPos to _col * -240>><<set _dimensions to "240px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>><<set _dimensions to "160px">> <<else>> <<set _xPos to _col * -80>><<set _dimensions to "80px">> <</if>> <div class="creature-layers" @style="'width:' + _dimensions + ';height:' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _spriteSheet + ');background-position:' + _xPos + 'px 0px;width:' + _dimensions + ';height:' + _dimensions + ';'"> </div> </div> <</if>> </div> </div> <div class="profile-flavor"> <<print _creature.flavorText>> </div> </div> /* ── TYPE + GENDER + FEED ROW ── */ <div class="profile-badge-row"> <div class="profile-badge profile-badge--type"> <<print setup.typeEmojis[_creature.type]>> _creature.type </div> <<if _creature.gender === "Male">> <div class="profile-badge profile-badge--male">♂ Male</div> <<else>> <div class="profile-badge profile-badge--female">♀ Female</div> <</if>> <div class="profile-badge profile-badge--age"> <<= setup.getAgeDisplay(_creature)>> <<if _creature.immortal>>IMMORTAL<</if>> </div> </div> <div class="profile-badge-row"> /* Feed button */ <<set _hungerPercent = (_creature.hungerCur / _creature.hungerMax) * 100>> <<set _hasAnyFood = false>> <<if _creature.stage !== "egg" && _hungerPercent < 100>> <<for _food range setup.creatureFoods>> <<if $inventory[_food] > 0>><<set _hasAnyFood = true>><<break>><</if>> <</for>> <<if !_hasAnyFood>> <<for _itemId, _qty range $inventory>> <<if _qty > 0 && $mealNames && $mealNames[_itemId]>> <<set _hasAnyFood = true>><<break>> <</if>> <</for>> <</if>> <</if>> <<if _creature.stage === "egg">> <div class="profile-badge profile-badge--disabled">No feeding</div> <<elseif _hungerPercent >= 100>> <div class="profile-badge profile-badge--full">Full ✨</div> <<elseif !_hasAnyFood>> <div class="profile-badge profile-badge--disabled">No food</div> <<else>> <<link "🍖 Feed" "ViewCreature">> <<set $selectedCreatureToFeed = $currentCreature>> <<set $showFoodModal = true>> <<set $feedingAll = false>> <</link>> <</if>> </div> /* ── STATS / GENETICS TABS ── */ <<set $profileTab = $profileTab || "stats">> <div class="profile-tabs"> <span class="profile-tab <<if $profileTab === 'stats'>>profile-tab--active<</if>>" onclick="void(0)"> <<link "📊 Stats">> <<set $profileTab = "stats">> <<goto `passage()`>> <</link>> </span> <span class="profile-tab <<if $profileTab === 'genetics'>>profile-tab--active<</if>>" onclick="void(0)"> <<link "🧬 Genetics">> <<set $profileTab = "genetics">> <<refresh>> <</link>> </span> </div> <<if $profileTab === "stats">> <div class="column"> <div class="stat-text"> Hunger <div class="stat-bar-container"> <img src="https://i.imgur.com/JOGyfUZ.png" class="stat-hunger"> <div id="hzhungerbarbkg" class="hzbarbkg"><div id="hzhungerbar" class="hzbar"></div></div> </div> <<script>>$(document).one(':passageend', function (ev) { var creature = State.temporary.creature; StatBar(creature.hungerCur, creature.hungerMax, "hzhungerbar", true, ev.content, {h: 39, s: 100, l: 31}, {h: 180, s: 100, l: 37}); });<</script>> Care <div class="stat-bar-container"> <img src="https://i.imgur.com/MAI8DYv.png" class="stat-icon"> <div id="hzcarebarbkg" class="hzbarbkg"><div id="hzcarebar" class="hzbar"></div></div> </div> <<script>>$(document).one(':passageend', function (ev) { var creature = State.temporary.creature; StatBar(creature.careCur, creature.careMax, "hzcarebar", true, ev.content, {h: 10, s: 80, l: 60}, {h: 55, s: 90, l: 85}); });<</script>> Affection <div class="stat-bar-container"> <img src="https://i.imgur.com/Ncydkz3.png" class="stat-heart"> <div id="hzaffectionbarbkg" class="hzbarbkg"><div id="hzaffectionbar" class="hzbar"></div></div> </div> <<script>>$(document).one(':passageend', function (ev) { var creature = State.temporary.creature; StatBar(creature.affectionCur, creature.affectionMax, "hzaffectionbar", true, ev.content, {h: 340, s: 20, l: 40}, {h: 340, s: 80, l: 85}); });<</script>> <div class="stamina-display"> Stamina <div class="stamina-stars"> <<for _i = 0; _i < _creature.staminaMax; _i++>> <<if _i < _creature.staminaCur>> <div class="star star-filled"></div> <<else>> <div class="star star-empty"></div> <</if>> <</for>> </div> </div> </div> </div> <<else>> <div class="column"> <div class="trait-display"> <<link "View Family Tree">> <<set $lineageCreatureId to _creature.id>> <<goto "CreatureLineage">> <</link>> <div class="trait-row"> <span class="trait-label">Color:</span> <div class="gene-pair"> <<set _colorGene1 = _creature.genes.color[0]>> <<set _colorGene2 = _creature.genes.color[1]>> <<set _template to setup.creatureTemplates[_creature.name]>> <<set _color1Dominant = _template.colorDominance.indexOf(_colorGene1) < _template.colorDominance.indexOf(_colorGene2)>> <<if _creature.geneticTestingDone>> <span class="gene-box" @data-dominant="_color1Dominant">_colorGene1</span> <span class="gene-box" @data-dominant="!_color1Dominant">_colorGene2</span> <<else>> <span class="gene-box" data-dominant="true">_creature.displayTraits.color</span> <span class="gene-box-hidden">?</span> <</if>> </div> </div> <div class="trait-row"> <span class="trait-label">Pattern:</span> <div class="gene-pair"> <<set _patternGene1 = _creature.genes.pattern[0]>> <<set _patternGene2 = _creature.genes.pattern[1]>> <<set _pattern1Dominant = _template.patternDominance.indexOf(_patternGene1) < _template.patternDominance.indexOf(_patternGene2)>> <<if _creature.geneticTestingDone>> <span class="gene-box" @data-dominant="_pattern1Dominant">_patternGene1</span> <span class="gene-box" @data-dominant="!_pattern1Dominant">_patternGene2</span> <<else>> <span class="gene-box" data-dominant="true">_creature.displayTraits.pattern</span> <span class="gene-box-hidden">?</span> <</if>> </div> </div> <div class="trait-row"> <span class="trait-label">Size:</span> <div class="gene-pair"> <<if _creature.geneticTestingDone>> <span class="gene-box size-gene">_creature.genes.size[0]</span> <span class="gene-box size-gene">_creature.genes.size[1]</span> <span class="size-result">→ _creature.displayTraits.size</span> <<else>> <span class="gene-box size-gene">_creature.displayTraits.size</span> <</if>> </div> </div> <div class="trait-row"> <span class="trait-label">Species:</span> <div class="gene-pair"> <<if _creature.geneticTestingDone>> <<set _speciesGene1 to _creature.genes.species[0]>> <<set _speciesGene2 to _creature.genes.species[1]>> <span class="gene-box" data-dominant="true">_speciesGene1</span> <span class="gene-box" data-dominant="false">_speciesGene2</span> <<else>> <span class="gene-box size-gene">_creature.species</span> <span class="gene-box-hidden">?</span> <</if>> </div> </div> <<if !_creature.geneticTestingDone>> <div class="genetic-testing">Unlock full genetics at vet</div> <</if>> <<if _creature.mutations && _creature.mutations.length > 0>> <div class="trait-row mutation-row"> <span class="trait-label">Mutations:</span> <div class="mutation-badges"> <<for _i to 0; _i < _creature.mutations.length; _i++>> <span class="mutation-badge">✨ <<print _creature.mutations[_i]>></span> <</for>> </div> </div> <</if>> </div> </div> <</if>> /* ── THEME SELECTOR ── */ <<set _currentTheme = $playerCreatures[$currentCreature].profileTheme || "default">> <div class="theme-selector"> <div class="theme-selector-title">🎨 Theme</div> <div class="theme-chip-row" id="theme-buttons"> <<for _themeKey, _themeData range setup.creatureThemes>> <<capture _themeKey>> <<set _isActive = _currentTheme === _themeKey>> <span @class="'theme-chip' + (_isActive ? ' theme-chip--active' : '')" @data-theme="_themeKey" onclick="applyCreatureTheme(this.dataset.theme); $('.theme-chip').removeClass('theme-chip--active'); $(this).addClass('theme-chip--active'); window.unlockAchievement('firstCustomize')"> </span> <</capture>> <</for>> </div> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> </div> /* ── FOOD MODAL ── */ <<if $showFoodModal && $selectedCreatureToFeed !== undefined && !$feedingAll>> <<set _creatureToFeed = $playerCreatures[$selectedCreatureToFeed]>> <div class="cart-modal" style="display:flex;"> <div class="cart-modal-content"> <div class="cart-modal-header"> <h3>Select Food</h3> <<link "✕" "ViewCreature">> <<unset $showFoodModal>> <<unset $selectedCreatureToFeed>> <</link>> </div> <p1>Choose food for <<creatureName _creatureToFeed>>:</p1> <div class="cart-items"> <<for _food range setup.creatureFoods>> <<if $inventory[_food] > 0>> <<capture _food>> <div class="ingredient-select-card"> <<link `setup.items[_food].name + " (" + $inventory[_food] + ")"` "ViewCreature">> <<set $playerCreatures[$selectedCreatureToFeed].hungerCur to Math.min($playerCreatures[$selectedCreatureToFeed].hungerMax, $playerCreatures[$selectedCreatureToFeed].hungerCur + 20)>> <<set $inventory[_food] -= 1>> <<if $firstFeeding is false>><<set $firstFeeding to true>><<addXP 20>><</if>> <<if setup.items[_food].foodBuffs>> <<set _buffs = setup.items[_food].foodBuffs>> <<if _buffs.affection>><<set $playerCreatures[$selectedCreatureToFeed].affectionCur = ($playerCreatures[$selectedCreatureToFeed].affectionCur || 0) + _buffs.affection>><</if>> <<if _buffs.energy>><<set $playerCreatures[$selectedCreatureToFeed].energy = ($playerCreatures[$selectedCreatureToFeed].energy || 0) + _buffs.energy>><</if>> <<if _buffs.happiness>><<set $playerCreatures[$selectedCreatureToFeed].happiness = ($playerCreatures[$selectedCreatureToFeed].happiness || 0) + _buffs.happiness>><</if>> <</if>> <<unset $showFoodModal>><<unset $selectedCreatureToFeed>> <<if $tutorialQuests.quests.feedCreature.accepted && !$tutorialQuests.quests.feedCreature.complete>> <<set $tutorialQuests.quests.feedCreature.complete = true>><<addXP 20>><<set $money += 50>> <</if>> <</link>> </div> <</capture>> <</if>> <</for>> <<for _mealId, _qty range $inventory>> <<if _qty > 0 && $mealNames && $mealNames[_mealId]>> <<capture _mealId>> <div class="ingredient-select-card"> <<link `$mealNames[_mealId] + " (" + $inventory[_mealId] + ")"` "ViewCreature">> <<set $playerCreatures[$selectedCreatureToFeed].hungerCur to Math.min($playerCreatures[$selectedCreatureToFeed].hungerMax, $playerCreatures[$selectedCreatureToFeed].hungerCur += 20)>> <<set $inventory[_mealId] -= 1>> <<if $firstFeeding is false>><<set $firstFeeding to true>><<addXP 20>><</if>> <<unset $showFoodModal>><<unset $selectedCreatureToFeed>> <<run unlockAchievement("firstFeed")>> <<run updateAchievementProgress("feedTenTimes", 1)>> <<run updateAchievementProgress("feedFiftyTimes", 1)>> <<run updateAchievementProgress("feedHundredTimes", 1)>> <<if $tutorialQuests.quests.feedCreature.accepted && !$tutorialQuests.quests.feedCreature.complete>> <<set $tutorialQuests.quests.feedCreature.complete = true>><<addXP 20>><<set $money += 50>> <</if>> <</link>> </div> <</capture>> <</if>> <</for>> </div> </div> </div> <</if>> <</nobr>>
<<nobr>> <<run $playerCreatures.forEach(function(c) { ensureSpeciesGene(c); })>> <<set _availableEggSlots to $maxEggSlots - setup.countEggs()>> <<if _availableEggSlots <= 0>> <h2>Creature Breeding</h2> <div class="warning"> <p>You have no available egg slots! ( <<= setup.countEggs()>> / $maxEggSlots )</p> <p>Hatch some eggs or purchase more egg slots before breeding.</p> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> <div class="forth-button"> <<link "Purchase Egg Slots" "RealEstate">> <</link>> </div></div> <<else>> <<set _maleCreatures to $playerCreatures.filter(function(c) { return c.gender === "Male" && c.stage === "adult" && c.staminaCur >= 1; })>> <<set _femaleCreatures to $playerCreatures.filter(function(c) { return c.gender === "Female" && c.stage === "adult" && c.staminaCur >= 1; })>> <h2>Creature Breeding</h2> <div class="info-box"> <strong>Egg Slots:</strong> <<= setup.countEggs()>>/$maxEggSlots <br> <strong>Breeding:</strong> Select two adult creatures of opposite genders </div> <<if $selectedMaleId === undefined>> <!-- STEP 1: Select Male Creature --> <h3>Select Male Creature</h3> <div class="creature-selection"> <<if _maleCreatures.length === 0>> <p class="warning">No adult male creatures available for breeding.</p> <<else>> <<for _i to 0; _i < _maleCreatures.length; _i++>> <<set _c to _maleCreatures[_i]>> <<capture _i, _c>> <<set _template to setup.creatureTemplates[_c.name]>> <<set _gender to _c.gender.toLowerCase()>> <div class="creature-card"> <div class="creature-display"> <<set _size to _c.displayTraits.size>> <<set _pattern to _c.displayTraits.pattern>> <<set _color to _c.displayTraits.color>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to _color + "_" + _pattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _size === "large">> <<set _xPos to _col * -240>> <<set _dimensions to "240px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>> <<set _dimensions to "160px">> <<else>> <<set _xPos to _col * -80>> <<set _dimensions to "80px">> <</if>> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> <div class="creature-info"> <strong>_c.name</strong> (♂) <<if isCreatureFertile(_c)>> <br> <span style="color: var(--coral); font-size: 1.2em;">✨Fertile✨</span> <</if>><br> Type: _c.type<br> Gen: _c.generation<br> Color: _c.displayTraits.color<br> Pattern: _c.displayTraits.pattern<br> Size: _c.displayTraits.size </div> <<link "Select">> <<set $selectedMaleId to _c.id>> <<goto "Breeding">> <</link>> </div> <</capture>> <</for>> <</if>> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <<elseif $selectedFemaleId === undefined>> <!-- STEP 2: Select Female Creature --> <<set _selectedMale to $playerCreatures.find(function(c) { return c.id === $selectedMaleId; })>> <<set _maleTemplate to setup.creatureTemplates[_selectedMale.name]>> <div class="selected-parent"> <strong>Selected Male:</strong> _selectedMale.name (♂)<br> Traits: _selectedMale.displayTraits.color _selectedMale.displayTraits.pattern _selectedMale.displayTraits.size <<link "Change">> <<unset $selectedMaleId>> <<goto "Breeding">> <</link>> </div> <h3>Select Female Creature</h3> <div class="creature-selection"> <<if _femaleCreatures.length === 0>> <p class="warning">No adult female creatures available for breeding.</p> <<else>> <<for _j to 0; _j < _femaleCreatures.length; _j++>> <<set _c to _femaleCreatures[_j]>> <<capture _j, _c>> <<set _template to setup.creatureTemplates[_c.name]>> <<set _gender to _c.gender.toLowerCase()>> <div class="creature-card"> <div class="creature-display"> <<set _size to _c.displayTraits.size>> <<set _pattern to _c.displayTraits.pattern>> <<set _color to _c.displayTraits.color>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to _color + "_" + _pattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _size === "large">> <<set _xPos to _col * -240>> <<set _dimensions to "240px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>> <<set _dimensions to "160px">> <<else>> <<set _xPos to _col * -80>> <<set _dimensions to "80px">> <</if>> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> <div class="creature-info"> <strong>_c.name</strong> (♀) <<if isCreatureFertile(_c)>> <br> <span style="color: var(--coral); font-size: 1.2em;">✨Fertile✨</span> <</if>><br> Type: _c.type<br> Gen: _c.generation<br> Color: _c.displayTraits.color<br> Pattern: _c.displayTraits.pattern<br> Size: _c.displayTraits.size </div> <<link "Select">> <<set $selectedFemaleId to _c.id>> <<goto "Breeding">> <</link>> </div> <</capture>> <</for>> <</if>> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <<else>> <!-- STEP 3: Confirm and Breed --> <<set _selectedMale to null>> <<for _i to 0; _i < $playerCreatures.length; _i++>> <<if $playerCreatures[_i].id === $selectedMaleId>> <<set _selectedMale to $playerCreatures[_i]>> <</if>> <</for>> <<set _selectedFemale to null>> <<for _i to 0; _i < $playerCreatures.length; _i++>> <<if $playerCreatures[_i].id === $selectedFemaleId>> <<set _selectedFemale to $playerCreatures[_i]>> <</if>> <</for>> <div class="selected-parent"> <strong>Selected Male:</strong> _selectedMale.name (♂)<br> Traits: _selectedMale.displayTraits.color _selectedMale.displayTraits.pattern _selectedMale.displayTraits.size <<link "Change">> <<unset $selectedMaleId>> <<unset $selectedFemaleId>> <<goto "Breeding">> <</link>> </div> <div class="selected-parent"> <strong>Selected Female:</strong> _selectedFemale.name (♀)<br> Traits: _selectedFemale.displayTraits.color _selectedFemale.displayTraits.pattern _selectedFemale.displayTraits.size <<link "Change">> <<unset $selectedFemaleId>> <<goto "Breeding">> <</link>> </div> <<set _inbreedingRelationship to checkInbreeding(_selectedMale, _selectedFemale, $playerCreatures)>> <div class="breeding-confirm <<if _inbreedingRelationship>>breeding-warning<</if>>"> <<if _inbreedingRelationship>> <h3>⚠️ Warning! ⚠️</h3> <p class="warning"><<= getInbreedingMessage(_inbreedingRelationship) >> Offspring will have a reduced stamina max of 2.</p> <<else>> <h3>Ready to Breed!</h3> <</if>> <p><strong>Parents:</strong> _selectedMale.species (♂) + _selectedFemale.species (♀)</p> <p><strong>Possible Species:</strong> _selectedMale.name (_selectedMale.rarity) or _selectedFemale.name (_selectedFemale.rarity)</p> <p class="info">More common species have higher chance of being selected. Will produce 1-4 eggs.</p> <<link "Breed Creatures">> <<set _selectedMale.staminaCur -= 1>> <<set _selectedFemale.staminaCur -= 1>> <<breedCreatures _selectedMale _selectedFemale>> <<unset $selectedMaleId>> <<unset $selectedFemaleId>> <<goto "BreedingResult">> <</link>> <<link "Cancel">> <<unset $selectedMaleId>> <<unset $selectedFemaleId>> <<goto "Breeding">> <</link>> </div> <</if>> <</if>> <</nobr>>
<<nobr>> <h2>Breeding Results</h2> <<if $tutorialQuests.quests.breeding.accepted && !$tutorialQuests.quests.breeding.complete>> <<set $tutorialQuests.quests.breeding.complete = true>> <<addXP 60>> <<set $money += 150>> <</if>> <<if $breedingSuccessful>> <<if $bothParentsFertile>> <p class="success">Perfect timing! Both parents were in their fertile window.</p> <<elseif $oneParentFertile>> <p class="partial-success">Good timing! One parent was in their fertile window.</p> <<else>> <p class="low-success">You got lucky! Neither parent was in their fertile window, but breeding succeeded anyway.</p> <</if>> <p>Your creatures have produced <<print $lastBreedingResults.length>> egg<<if $lastBreedingResults.length > 1>>s<</if>>!</p> <<for _i to 0; _i < $lastBreedingResults.length; _i++>> <<set _egg to $lastBreedingResults[_i]>> <div class="egg-result"> <strong>Egg #<<print _i + 1>></strong><br> Species: _egg.species (_egg.rarity)<br> Gender: _egg.gender<br> Generation: _egg.generation<br> Will hatch in: <<print Math.max(0, _egg.hatchSteps - $steps)>> steps<br> <<if _egg.mutations && _egg.mutations.length > 0>> <span class="mutation">✨ Mutation!</span> <</if>> </div> <</for>> <<if $lastBreedingResults.some(egg => egg.mutations && egg.mutations.length > 0)>> <p class="info">Mutations introduce new genetic variation from the species' trait pool. Rarer species have higher mutation rates.</p> <</if>> <<elseif $oneParentFertile && !$breedingSuccessful>> <p class="breeding-failure">Breeding was unsuccessful. A parent was in a fertile window, but luck wasn't on your side this time. Try again?</p> <<else>> <p class="breeding-failure">Breeding was unsuccessful. Neither parent was in their fertile window, and luck wasn't on your side this time. Try again when they're more fertile!</p> <</if>> <p style="text-align: center; font-family:'Quicksand', sans-serif; font-size:16px; font-weight:bold; color:var(--mid-text);">Egg Slots: <<= setup.countEggs()>> / $maxEggSlots </p> <div class="back-forth-buttons"> <div class="back-button"> <<link "Breed Again" "Breeding">> <</link>> </div><div class="forth-button"> <<link "View Eggs" "ViewEggs">> <</link>> </div> </div> <</nobr>>
<<nobr>> <<set _eggs to $playerCreatures.filter(function(c) { return c.stage === "egg"; })>> <div class="view-grid-panel"> <h2>Eggs <<= setup.countEggs()>> / $maxEggSlots</h2> <div class="view-grid"> <<if _eggs.length === 0>> <div class="view-grid-empty">No eggs yet!</div> <<else>> <<for _i = 0; _i < _eggs.length; _i++>> <<capture _i>> <<set _egg = _eggs[_i]>> <div class="view-grid-card"> <<capture _egg>> <<link [[ViewCreature]]>> <<set $currentCreature = $playerCreatures.indexOf(_egg)>> <</link>> <</capture>> <div style="font-size: 3em; line-height: 1;">🥚</div> <div class="card-label"><<= _egg.species>> Egg</div> <div class="card-sublabel"><<= Math.max(0, _egg.hatchSteps - $steps)>> steps left</div> </div> <<capture _egg>> <<button "🐣 Hatch">> <<set _egg.hatchSteps = 0>> <<run setup.checkStepEvents()>> <<goto "ViewEggs">> <</button>> <</capture>> <</capture>> <</for>> <</if>> </div> </div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> <div class="forth-button"> <<link "Buy Slots" "RealEstate">><</link>> </div> </div> <</nobr>>
<<nobr>> <<if !$shopCart>><<set $shopCart = []>><</if>> /* ── BANNER ── */ <div class="shop-banner"> <h5 style="margin: 0 0 6px 0;">🏪 Critter Center</h5> <p style="margin: 0; opacity: 0.9;">Your Money: <strong>💰 $money g</strong></p> <<run setup.checkDailyFeatured()>> <<set _featured = setup.items[$featuredItemId]>> <div class="shop-featured"> ✨ <strong>Daily Featured:</strong> _featured.name — <span style="text-decoration: line-through;">_featured.basePrice g</span> <strong><<= Math.floor(_featured.basePrice * 0.8)>> g</strong> (20% OFF!) </div> <div class="shop-list-add">Tap image to add to cart</div> </div> <div class="gogogacha-links"><<link "✨Check out the gacha machines✨" "GachaMachines">><</link>></div> /* ── CATEGORY PILLS ── */ <div class="shop-categories-scroll"> <<link "All">><<set $shopCategory = "All">><<refresh>><</link>> <<link "Creatures">><<set $shopCategory = "Creatures">><<refresh>><</link>> <span id="shop-tab-consumables"><<link "Consumables">><<set $shopCategory = "Consumables">><<refresh>><</link>></span> <<link "Ingredients">><<set $shopCategory = "Ingredients">><<refresh>><</link>> <<link "Seeds">><<set $shopCategory = "Seeds">><<refresh>><</link>> <<link "Items">><<set $shopCategory = "Items">><<refresh>><</link>> <<link "Fishing">><<set $shopCategory = "Fishing">><<refresh>><</link>> </div> /* ── ITEM LIST ── */ <div class="shop-item-list"> <<for _key, _item range setup.items>> <<capture _item>> <<set _shouldDisplay = false>> <<if _item.category != "Fish" && _item.category != "Meals">> <<set _shouldDisplay = true>> <</if>> <<set _isLocked = false>> <<if _item.id == "FishingRod" && !$fishingrodUnlocked>> <<set _isLocked = true>> <<elseif _item.id == "Lantern" && !$lanternUnlocked>> <<set _isLocked = true>> <<elseif _item.id == "WormBait" && !$wormbaitUnlocked>> <<set _isLocked = true>> <</if>> <<if _shouldDisplay && ($shopCategory == "All" || _item.category == $shopCategory)>> <<if _item.id == $featuredItemId>> <<set _actualPrice = Math.floor(_item.basePrice * 0.8)>> <<else>> <<set _actualPrice = _item.basePrice>> <</if>> <div class="shop-list-card"> <div class="shop-list-img-wrap"> <<if _isLocked>> [img[_item.image]] <div class="lock-overlay">🔒</div> <<elseif _item.category == "Creatures">> <<link [img[_item.image]]>> <<set $selectedItem = _item>> <<goto "ItemDetail">> <</link>> <<else>> <<set _isUnique = (_item.id == "FishingRod" || _item.id == "Lantern")>> <<if _item.id == $featuredItemId>> <<set _cartPrice = Math.floor(_item.basePrice * 0.8)>> <<else>> <<set _cartPrice = _item.basePrice>> <</if>> <<capture _isUnique, _cartPrice>> <<link [img[_item.image]]>> <<set _existingIndex = -1>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<if $shopCart[_ci].id == _item.id>> <<set _existingIndex = _ci>> <</if>> <</for>> <<if _existingIndex == -1>> <<run $shopCart.push({ id: _item.id, name: _item.name, image: _item.image, price: _cartPrice, quantity: 1, isUnique: _isUnique })>> <</if>> <<refresh>> <</link>> <</capture>> <</if>> </div> <div class="shop-list-body"> <div class="shop-list-name">_item.name</div> <div class="shop-list-price">💰 _actualPrice g</div> <div class="shop-list-rarity"> <<if _item.rarity == "Common">><span style="color:#95a5a6;">Common</span> <<elseif _item.rarity == "Uncommon">><span style="color:#1bd602;">Uncommon</span> <<elseif _item.rarity == "Rare">><span style="color:#0070dd;">Rare</span> <<elseif _item.rarity == "Epic">><span style="color:#a335ee;">Epic</span> <<elseif _item.rarity == "Legendary">><span style="color:#ff8000;">Legendary</span> <</if>> </div> <div class="shop-list-desc">_item.description</div> <<if _isLocked>> <span class="shop-list-locked">🔒 Locked</span> <</if>> </div> </div> <</if>> <</capture>> <</for>> </div> /* ── FLOATING CART BUTTON ── */ <<set _cartCount = 0>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _cartCount += $shopCart[_ci].quantity>> <</for>> <button class="cart-fab" onclick="document.getElementById('cart-modal').style.display='flex'"> 🛒 Cart <<if _cartCount > 0>><span class="cart-fab-badge">_cartCount</span><</if>> </button> /* ── CART MODAL ── */ <div class="cart-modal" id="cart-modal" style="display:none;"> <div class="cart-modal-content"> <div class="cart-modal-header"> <h3>🛒 Your Cart</h3> <button class="cart-modal-close" onclick="document.getElementById('cart-modal').style.display='none'">✕</button> </div> <<if $shopCart.length == 0>> <p style="color:var(--mid-text); font-style:italic; text-align:center;">Your cart is empty!</p> <<else>> <<set _cartTotal = 0>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _cartTotal += $shopCart[_ci].price * $shopCart[_ci].quantity>> <</for>> <div class="cart-items"> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<capture _ci>> <<set _entry = $shopCart[_ci]>> <<set _lineTotal = _entry.price * _entry.quantity>> <div class="cart-line"> <div class="cart-line-info"> <<= '<img src="' + _entry.image + '" style="width:36px;height:36px;object-fit:contain;margin-right:8px;vertical-align:middle;">'>> <span>_entry.name</span> </div> <div class="cart-line-controls"> <<if _entry.isUnique>> <span class="cart-qty">1</span> <<else>> <<link "−">> <<if $shopCart[_ci].quantity > 1>> <<set $shopCart[_ci].quantity -= 1>> <<else>> <<run $shopCart.splice(_ci, 1)>> <</if>> <<refresh>> <</link>> <<= '<input type="number" class="macro-numberbox" value="' + _entry.quantity + '" min="1" onchange="var idx=' + _ci + ';var val=parseInt(this.value,10);if(!val||val<1){SugarCube.State.variables.shopCart.splice(idx,1);}else{SugarCube.State.variables.shopCart[idx].quantity=val;}SugarCube.Engine.play(\'Shop\');">'>> <<link "+">> <<set $shopCart[_ci].quantity += 1>> <<refresh>> <</link>> <</if>> <span class="cart-line-price">💰 _lineTotal g</span> <<link "✕">> <<run $shopCart.splice(_ci, 1)>> <<refresh>> <</link>> </div> </div> <</capture>> <</for>> </div> <div class="cart-total">Total: 💰 _cartTotal g</div> <<if $money >= _cartTotal>> <<link "✅ Checkout">> <<set $money -= _cartTotal>> <<set $purchaseSummary = []>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _entry = $shopCart[_ci]>> <<set $inventory[_entry.id] += _entry.quantity>> <<run $purchaseSummary.push(_entry.quantity + "x " + _entry.name)>> <<if _entry.id == "CreatureChow">> <<if $tutorialQuests.quests.buyFood.accepted && !$tutorialQuests.quests.buyFood.complete>> <<set $tutorialQuests.quests.buyFood.complete = true>> <<addXP 30>> <<set $money += 75>> <</if>> <</if>> <</for>> <<set $shopCart = []>> <<goto "CartCheckoutComplete">> <</link>> <<else>> <div class="button-disabled">Not enough money!</div> <</if>> <</if>> </div> </div> <button class="scroll-top-btn" onclick="window.scrollTo({top: 0, behavior: 'smooth'})">↑ Back to Top</button> <</nobr>>
<<nobr>> <<if !$selectedGender>><<set $selectedGender = "Female">><</if>> <div class="modal-overlay"> <div class="detail-card1"> <div class="modal-header-buy"> <<link "❌Close" "Shop">> <<set $selectedGender = null>> <</link>> </div> <div class="detail-header1"> $selectedItem.name </div> <div class="item-image1"> <div class="image-box1"> [img[$selectedItem.image]] </div> </div> <div class="rarity-badge1"> <<if $selectedItem.rarity == "Common">> <span class="rarity-common1">Common</span> <<elseif $selectedItem.rarity == "Uncommon">> <span class="rarity-uncommon1">Uncommon</span> <<elseif $selectedItem.rarity == "Rare">> <span class="rarity-rare1">Rare</span> <</if>> </div> <<set _itemPrice = $selectedItem.basePrice>> <div class="price-display1"> $ _itemPrice </div> <div class="gender-toggle"> <<if $selectedGender == "Female">> <span class="active-cat-pill">♀ Female</span> <<link "♂ Male">> <<set $selectedGender = "Male">> <<refresh>> <</link>> <<else>> <<link "♀ Female">> <<set $selectedGender = "Female">> <<refresh>> <</link>> <span class="active-cat-pill">♂ Male</span> <</if>> </div> <div class="description-box1"> <p>$selectedItem.description</p> </div> <<if $selectedItem.category == "Creatures">> <<if $money >= _itemPrice>> <div class="purchase-buttons1"> <<link "Buy Creature">> <<set $money -= _itemPrice>> <<set _purchasedCreature = clone(setup.creatureTemplates[$selectedItem.id])>> <<set _purchasedCreature.id to random(100000, 999999)>> <<set _purchasedCreature.gender to $selectedGender>> <<set _possibleColors = setup.getCreaturePossibleColors(_purchasedCreature.name)>> <<set _purchasedCreature.genes = { color: [_possibleColors.random(), _possibleColors.random()], pattern: [_purchasedCreature.possiblePatterns.random(), _purchasedCreature.possiblePatterns.random()], size: [_purchasedCreature.possibleSizes.random(), _purchasedCreature.possibleSizes.random()] }>> <<set _purchasedCreature.displayTraits = { color: getDisplayedTrait(_purchasedCreature.genes.color[0], _purchasedCreature.genes.color[1], _purchasedCreature.colorDominance), pattern: getDisplayedTrait(_purchasedCreature.genes.pattern[0], _purchasedCreature.genes.pattern[1], _purchasedCreature.patternDominance), size: getBlendedSize(_purchasedCreature.genes.size[0], _purchasedCreature.genes.size[1], _purchasedCreature.possibleSizes), species: [_purchasedCreature.species, _purchasedCreature.species] }>> <<run finalizeDisplayTraits(_purchasedCreature)>> <<if _purchasedCreature.displayTraits.size === "large">> <<set _purchasedCreature.hungerCur = 100>> <<set _purchasedCreature.hungerMax = 120>> <<elseif _purchasedCreature.displayTraits.size === "medium">> <<set _purchasedCreature.hungerCur = 80>> <<set _purchasedCreature.hungerMax = 100>> <<else>> <<set _purchasedCreature.hungerCur = 60>> <<set _purchasedCreature.hungerMax = 80>> <</if>> <<set _purchasedCreature.geneticTestingDone to false>> <<set _purchasedCreature.stage to "adult">> <<run _purchasedCreature.bornAt = Date.now() - (random(1, 3) * 24 * 60 * 60 * 1000)>> <<set _purchasedCreature.elderAt to null>> <<set _purchasedCreature.hadSurgery to false>> <<set _purchasedCreature.generation to 1>> <<set _purchasedCreature.fedCount to 0>> <<set _purchasedCreature.caredCount to 0>> <<set _purchasedCreature.mimikin to null>> <<run _purchasedCreature.fertilityOffset = Date.now() - Math.floor(Math.random() * getFertilityCycleLength(_purchasedCreature.rarity))>> <<run _purchasedCreature.lastAffectionBonus = Date.now()>> <<run _purchasedCreature.lastHungerDrain = Date.now()>> <<run _purchasedCreature.lastCareDrain = Date.now()>> <<run _purchasedCreature.lastStaminaRegen = Date.now()>> <<run _purchasedCreature.wasHappy = false>> <<run _purchasedCreature.immortal = false>> <<run $playerCreatures.push(_purchasedCreature)>> <<run setup.recordCombo(_purchasedCreature)>> <<set $purchaseSuccess = $selectedItem.name + " has joined your corral!">> <<if $playerCreatures.length >= 5>><<run unlockAchievement("fiveCreatures")>><</if>> <<if $playerCreatures.length >= 10>><<run unlockAchievement("tenCreatures")>><</if>> <<if $playerCreatures.length >= 20>><<run unlockAchievement("twentyCreatures")>><</if>> <<goto "PurchaseComplete">> <</link>> </div> <<else>> <div class="button-disabled1"> Not enough money! </div> <</if>> <</if>> </div> </div> <</nobr>>
<<nobr>> <div style="text-align: center; padding: 50px;"> <h1 style="color: green;">✅ Purchase Complete!</h1> <p style="font-size: 1.3em; margin: 30px 0;">$purchaseSuccess</p> <p>Money remaining: <strong>💰 $money</strong></p> <div style="margin-top: 40px;"> <div class="back-forth-buttons"> <div class="back-button"> <<link "To Shop" "Shop">> <</link>> </div><div class="forth-button"> <<link "Go Home" "Home">> <</link>> </div> </div> </div> <</nobr>>
<<nobr>> <<set $selectedCategory = $selectedCategory || "Consumables">> <<set _categories = ["Consumables", "Meals", "Fish", "Ingredients", "Seeds", "Items", "Fishing"]>> /* ── HEADER ── */ <div class="vet-banner"> <h5>🎒 Inventory</h5> </div> /* ── CATEGORY PILLS ── */ <div class="shop-categories-scroll"> <<for _cat range _categories>> <<capture _cat>> <<if _cat === $selectedCategory>> <span class="active-cat-pill">_cat</span> <<else>> <<link _cat>> <<set $selectedCategory = _cat>> <<refresh>> <</link>> <</if>> <</capture>> <</for>> </div> /* ── RESULT MESSAGE ── */ <div id="result-message"></div> /* ── ITEMS ── */ <div class="inv-item-list" id="inventory-items"> <<include "InventoryItemDisplay">> </div> /* ── MODALS ── */ <div id="creature-select-modal"></div> <div id="ability-select-modal"></div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" "Home">><</link>> </div> </div> <</nobr>>
<<nobr>> <<set _itemsInCategory = []>> <<for _itemId, _item range setup.items>> <<if _item.category === $selectedCategory && $inventory[_item.id] > 0>> <<set _itemsInCategory.push(_item)>> <</if>> <</for>> <<if $selectedCategory === "Meals">> <<set _hasMeals = false>> <<for _mealId, _qty range $inventory>> <<if _qty > 0 && $mealNames && $mealNames[_mealId]>> <<set _hasMeals = true>> <div class="inv-item-card"> <div class="inv-item-body"> <div class="inv-item-name"><<print $mealNames[_mealId]>></div> <div class="inv-item-qty">Owned: <strong><<print _qty>></strong></div> <span class="inv-item-note">Ready to eat</span> </div> </div> <</if>> <</for>> <<if !_hasMeals>> <div class="vet-no-creatures">No meals in your inventory yet.</div> <</if>> <<else>> <<if _itemsInCategory.length === 0 && _item.category !== "Meals">> <div class="vet-no-creatures">No items in this category yet.</div> <<else>> <<for _item range _itemsInCategory>> <<capture _item>> <<set _quantity = $inventory[_item.id]>> <div class="inv-item-card"> /* Image */ <div class="inv-item-img-wrap"> <img @src="_item.image" @alt="_item.name"> </div> /* Body */ <div class="inv-item-body"> <div class="inv-item-name">_item.name</div> <div class="inv-item-qty">Owned: <strong>_quantity</strong></div> <div class="inv-item-desc">_item.description</div> /* Action */ <<if _quantity > 0>> <<if _item.id === "CreatureChow" && _item.category !== "Meals">> <span class="inv-item-note">Background item</span> <<elseif _item.requiresMonster>> <<capture _item>> <<link "Use →">> <<set _currentItem = _item>> <<replace "#creature-select-modal">><<include "CreatureSelectModal">><</replace>> <</link>> <</capture>> <<else>> <span class="inv-item-note">Ready to use</span> <</if>> <<else>> <span class="inv-item-disabled">None owned</span> <</if>> </div> </div> <</capture>> <</for>> <</if>> <</if>> <</nobr>>
<<nobr>> <<set _itemToUse = _currentItem>> <div class="cart-modal" id="creature-modal-overlay" style="display:flex;"> <div class="modal-bg-snapshot" id="modal-bg"></div> <div class="cart-modal-content"> /* ── HEADER ── */ <div class="cart-modal-header"> <h3>Select a Creature</h3> <button class="cart-modal-close" onclick="document.getElementById('creature-modal-overlay').style.display='none'">✕</button> </div> <div class="inv-modal-subtitle">Using: <strong>_itemToUse.name</strong></div> /* ── CREATURE LIST ── */ <<if !$playerCreatures || $playerCreatures.length === 0>> <div class="vet-no-creatures">You don't have any creatures available!</div> <<else>> <div class="vet-creature-list"> <<for _i = 0; _i < $playerCreatures.length; _i++>> <<set _creature = $playerCreatures[_i]>> <<set _canUse = true>> <<set _disabledReason = "">> <<if _itemToUse.id === "CarePotion">> <<if _creature.care >= 100>> <<set _canUse to false>> <<set _disabledReason to "Already at full care">> <</if>> <</if>> <<if _itemToUse.id === "ScrollFertility">> <<if isCreatureFertile(_creature)>> <<set _canUse to false>> <<set _disabledReason to "Already fertile">> <</if>> <</if>> <<if _itemToUse.id === "ScrollFertility">> <<if _creature.stage === "baby" || _creature.stage === "egg">> <<set _canUse to false>> <<set _disabledReason to "Too young">> <</if>> <</if>> <<capture _i, _creature>> /* ── SPRITE SETUP ── */ <<if _creature.stage === "baby">> <<set _baby = _creature>> <<set _template to setup.creatureTemplates[_baby.species]>> <<set _gender to _baby.gender.toLowerCase()>> <<set _size to _baby.displayTraits.size>> <<set _color to _baby.displayTraits.color>> <<if _template.babySpriteColumns[_color] !== undefined>> <<set _col to _template.babySpriteColumns[_color]>> <<else>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<set _babySpriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<if _size === "large">> <<set _xPos to _col * -180>> <<set _dimensions to "180px">> <<set _scale = "scale(0.4)">> <<set _scaledDimensions = "90px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>> <<set _dimensions to "120px">> <<set _scale = "scale(0.5)">> <<set _scaledDimensions = "60px">> <<else>> <<set _xPos to _col * -60>> <<set _dimensions to "60px">> <<set _scale = "scale(0.9)">> <<set _scaledDimensions = "30px">> <</if>> <<elseif _creature.stage === "adult">> <<set _template = setup.creatureTemplates[_creature.species]>> <<set _size = _creature.displayTraits.size>> <<set _pattern = _creature.displayTraits.pattern>> <<set _color = _creature.displayTraits.color>> <<set _gender = _creature.gender.toLowerCase()>> <<set _colorPattern = setup.getSpriteKey(_creature.name, _color, _pattern)>> <<set _col = _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _col = _template.spriteColumns[_template.colorDominance[0] + "_" + _template.patternDominance[0]]>> <</if>> <<if _size === "large">> <<set _xPos = _col * -240>><<set _dim = "240px">><<set _scale = "scale(0.4)">> <<elseif _size === "medium">> <<set _xPos = _col * -160>><<set _dim = "160px">><<set _scale = "scale(0.5)">> <<else>> <<set _xPos = _col * -80>><<set _dim = "80px">><<set _scale = "scale(0.9)">> <</if>> <</if>> /* ── CARD ── */ <div class="vet-creature-card <<if !_canUse>>vet-creature-card--disabled<</if>>"> /* Sprite */ <div class="vet-sprite-wrap"> <<if _creature.stage === "egg">> <span style="font-size:2em;">🥚</span> <<elseif _creature.stage === "baby">> <div @style="'width:' + _scaledDimensions + ';height:' + _scaledDimensions + ';overflow:hidden;flex-shrink:0;'"> <div style="transform:scale(0.5);transform-origin:top left;"> <div class="creature-layers" @style="'width:' + _dimensions + ';height:' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _babySpriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> <<else>> <<if _size === "large">> <<set _xPos = _col * -240>> <<set _dimensions = "240px">> <<set _scaledDimensions = "120px">> <<elseif _size === "medium">> <<set _xPos = _col * -160>> <<set _dimensions = "160px">> <<set _scaledDimensions = "80px">> <<else>> <<set _xPos = _col * -80>> <<set _dimensions = "80px">> <<set _scaledDimensions = "40px">> <</if>> <div @style="'width:' + _scaledDimensions + ';height:' + _scaledDimensions + ';overflow:hidden;flex-shrink:0;'"> <div style="transform:scale(0.5);transform-origin:top left;"> <div class="creature-layers" @style="'width:' + _dimensions + ';height:' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _template.avatars[_gender].patternSpriteSheets[_size] + ');background-position:' + _xPos + 'px 0px;width:' + _dimensions + ';height:' + _dimensions + ';'"> </div> </div> </div> </div> <</if>> </div> /* Info */ <div class="vet-creature-body"> <div class="vet-creature-name"> <<creatureName _creature>> <<if _creature.gender === "Male">>♂️<<else>>♀️<</if>> </div> <<if !_canUse>> <div class="vet-action-disabled">_disabledReason</div> <</if>> <<if _itemToUse.isAccessory && _alreadyEquipped>> <div class="inv-equipped-badge">✓ Equipped</div> <</if>> /* Action */ <div class="creature-action"> <<if _canUse>> <<if _itemToUse.id === "CarePotion">> <<capture _i, _itemToUse>> <<link "Use">> <<set _careAmount = Math.min(30, 100 - _creature.careCur)>> <<set _creature.careCur += _careAmount>> <<set $inventory[_itemToUse.id] -= 1>> <<set _resultMessage = `Used ${_itemToUse.name} on ${_creature.name}! Restored ${_careAmount} Care Points.`>> <<replace "#creature-select-modal">><</replace>> <<replace "#inventory-items">><<include "InventoryItemDisplay">><</replace>> <<replace "#result-message">><div class="result-message success">_resultMessage</div><</replace>> <</link>> <</capture>> <<elseif _itemToUse.id === "ScrollFertility">> <<capture _i, _itemToUse>> <<link "Use">> <<run $playerCreatures[_i].fertilityOffset = Date.now()>> <<set $inventory.ScrollFertility -= 1>> <<set _resultMessage = `Used Scroll of Fertility on ${_creature.name}! They are now fertile for the next day.`>> <<replace "#creature-select-modal">><</replace>> <<replace "#inventory-items">><<include "InventoryItemDisplay">><</replace>> <<replace "#result-message">><div class="result-message success">_resultMessage</div><</replace>> <</link>> <</capture>> <<elseif _itemToUse.id === "ScrollImmortality">> <<capture _i, _itemToUse>> <<link "Use">> <<set _creature.immortal = true>> <<set $inventory.ScrollImmortality -= 1>> <<set _resultMessage = `Used Scroll of Immortality on ${_creature.name}! They will now live forever.`>> <<replace "#creature-select-modal">><</replace>> <<replace "#inventory-items">><<include "InventoryItemDisplay">><</replace>> <<replace "#result-message">><div class="result-message success">_resultMessage</div><</replace>> <</link>> <</capture>> <</if>> <<else>> <span class="inv-item-disabled">Cannot Use</span> <</if>> </div> </div> </div> <</capture>> <</for>> </div> <</if>> </div> </div> <<run $(document).one(':passageend', function() { $('#modal-bg').html(State.variables.modalBg); })>> <</nobr>>
<<nobr>> <<set $selectedBait = null>> <<if !$weatherChecked>> <<run setup.fetchWeather()>> <</if>> <<set _isDay = setup.isDay()>> <<if !$weatherChecked>> /* Still loading weather */ <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <div class="weather-msg">Checking the weather...</div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Refresh">><<refresh>><</link>> </div> <div class="forth-button"> <<link "Go back" `previous()`>><</link>> </div> </div> <<elseif $isBadWeather>> /* Bad weather — no fishing */ <img src="https://i.imgur.com/L0B1rWw.png" class="lake-image"> <div class="weather-msg"><<print setup.getWeatherMessage($weatherCode)>></div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" "Home">><</link>> </div> </div> <<elseif !_isDay && $inventory.Lantern === 0>> /* Night, no lantern */ <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <div class="weather-msg">It's too dark to fish without a lantern.</div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <<elseif $inventory.FishingRod === 0>> /* No fishing rod */ <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <div class="weather-msg">The weather is perfect for fishing, but you don't have a fishing rod!</div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <<elseif !_isDay>> /* NIGHT FISHING */ <<if !$currentEnvironmentalCue || $lastCueWasDay>> <<set $currentEnvironmentalCue = either(setup.nightEnvironmentalCues)>> <<set $lastCueWasDay = false>> <</if>> <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <div class="weather-msg">//The lantern's glow casts a cool light over the dock.//</div> <div class="environmental-cue">$currentEnvironmentalCue.text</div> <<if $inventory.WormBait gt 0>> <div class="bait-selection"> <label><input type="checkbox" id="use-worm-bait"> Use Worm Bait (×$inventory.WormBait)</label> </div> <</if>> <div class="fishing-styles"> <div class="style-button"> <<button "Gentle Cast">> <<set $chosenCastStyle = "gentle">><<set $chosenCastIsNight = true>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">A soft, careful cast. Better for timid fish.</div> </div> <div class="style-button"> <<button "Aggressive Cast">> <<set $chosenCastStyle = "aggressive">><<set $chosenCastIsNight = true>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">A bold, powerful cast. Attracts big fish.</div> </div> <div class="style-button"> <<button "Deep Cast">> <<set $chosenCastStyle = "deep">><<set $chosenCastIsNight = true>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">Cast far and let it sink. Targets deep-water species.</div> </div> <div class="style-button"> <<button "Shallow Cast">> <<set $chosenCastStyle = "shallow">><<set $chosenCastIsNight = true>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">Stay near the surface. Good for common fish and finds.</div> </div> </div> <div class="back-forth-buttons"> <div class="back-button"><<link "Go Back" `previous()`>><</link>></div> </div> <<else>> /* DAY FISHING */ <<if !$currentEnvironmentalCue || !$lastCueWasDay>> <<set $currentEnvironmentalCue = either(setup.environmentalCues)>> <<set $lastCueWasDay = true>> <</if>> <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <div class="weather-msg">The weather is perfect for fishing.</div> <div class="environmental-cue">$currentEnvironmentalCue.text</div> <<if $inventory.WormBait gt 0>> <div class="bait-selection"> <label><input type="checkbox" id="use-worm-bait"> Use Worm Bait (×$inventory.WormBait)</label> </div> <</if>> <div class="fishing-styles"> <div class="style-button"> <<button "Gentle Cast">> <<set $chosenCastStyle = "gentle">><<set $chosenCastIsNight = false>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">A soft, careful cast. Better for timid fish.</div> </div> <div class="style-button"> <<button "Bold Cast">> <<set $chosenCastStyle = "aggressive">><<set $chosenCastIsNight = false>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">An aggressive, powerful cast. Attracts big fish.</div> </div> <div class="style-button"> <<button "Deep Cast">> <<set $chosenCastStyle = "deep">><<set $chosenCastIsNight = false>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">Cast far and let it sink. Targets deep-water species.</div> </div> <div class="style-button"> <<button "Shallow Cast">> <<set $chosenCastStyle = "shallow">><<set $chosenCastIsNight = false>> <<if $inventory.WormBait gt 0 && document.getElementById("use-worm-bait").checked>><<set $selectedBait = "WormBait">><</if>> <<goto "ProcessCast">> <</button>> <div class="style-description">Stay near the surface. Good for common fish and finds.</div> </div> </div> <div class="back-forth-buttons"> <div class="back-button"><<link "Go Back" `previous()`>><</link>></div> </div> <</if>> <</nobr>>
<<nobr>> <<set _babies to $playerCreatures.filter(function(c) { return c.stage === "baby"; })>> <div class="view-grid-panel"> <h2>Babies</h2> <div class="view-grid"> <<if _babies.length === 0>> <div class="view-grid-empty">No babies yet!</div> <<else>> <<for _i = 0; _i < _babies.length; _i++>> <<capture _i>> <<set _baby = _babies[_i]>> <<set _template to setup.creatureTemplates[_baby.species]>> <<set _gender to _baby.gender.toLowerCase()>> <<set _size to _baby.displayTraits.size>> <<set _color to _baby.displayTraits.color>> <<if _template.babySpriteColumns[_color] !== undefined>> <<set _col to _template.babySpriteColumns[_color]>> <<else>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<set _babySpriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<if _size === "large">> <<set _xPos to _col * -180>> <<set _dimensions to "180px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>> <<set _dimensions to "120px">> <<else>> <<set _xPos to _col * -60>> <<set _dimensions to "60px">> <</if>> <div class="view-grid-card"> <<capture _baby>> <<link [[ViewCreature]]>> <<set $currentCreature = $playerCreatures.indexOf(_baby)>> <</link>> <</capture>> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _babySpriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> <div class="card-label"><<= _baby.species>><<if _baby.gender === "Male">> ♂<<else>> ♀<</if>></div> <div class="card-sublabel"><<= _baby.displayTraits.color>> · <<= _baby.displayTraits.size>></div> </div> <<capture _baby>> <<button "🌟 Grow Up">> <<run _baby.bornAt = Date.now() - setup.BABY_DURATION>> <<goto "ViewBabies">> <</button>> <</capture>> <</capture>> <</for>> <</if>> </div> </div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <</nobr>>
<<nobr>> <<if not $filter>> <<set $filter to { open: false, search: "", species: [], gender: [], size: [], color: [], pattern: [] }>> <</if>> <<set _adults to $playerCreatures.filter(function(c) { return c.stage === "adult"; })>> <<set _optSpecies to []>> <<set _optGender to []>> <<set _optSize to []>> <<set _optColor to []>> <<set _optPattern to []>> <<for _i = 0; _i < _adults.length; _i++>> <<set _a to _adults[_i]>> <<set _tmpl to setup.creatureTemplates[_a.name]>> <<set _sp to (_tmpl.species ? _tmpl.species : _a.species)>> <<if not _optSpecies.includes(_sp)>> <<run _optSpecies.push(_sp)>> <</if>> <<if not _optGender.includes(_a.gender)>> <<run _optGender.push(_a.gender)>> <</if>> <<if not _optSize.includes(_a.displayTraits.size)>> <<run _optSize.push(_a.displayTraits.size)>> <</if>> <<if not _optColor.includes(_a.displayTraits.color)>> <<run _optColor.push(_a.displayTraits.color)>> <</if>> <<if not _optPattern.includes(_a.displayTraits.pattern)>> <<run _optPattern.push(_a.displayTraits.pattern)>> <</if>> <</for>> <<set _searchLower to $filter.search.toLowerCase().trim()>> <<set _filtered to _adults.filter(function(a) { var tmpl = setup.creatureTemplates[a.name]; var rawName = (a.petName ? a.petName : a.name).toLowerCase(); var sp = (tmpl.species ? tmpl.species : a.species).toLowerCase(); if (_searchLower !== "" && rawName.indexOf(_searchLower) === -1 && sp.indexOf(_searchLower) === -1) return false; if ($filter.species.length > 0 && !$filter.species.includes(sp)) return false; if ($filter.gender.length > 0 && !$filter.gender.includes(a.gender)) return false; if ($filter.size.length > 0 && !$filter.size.includes(a.displayTraits.size)) return false; if ($filter.color.length > 0 && !$filter.color.includes(a.displayTraits.color)) return false; if ($filter.pattern.length > 0 && !$filter.pattern.includes(a.displayTraits.pattern)) return false; return true; })>> <<set _activeCount to ($filter.search.trim() !== "" ? 1 : 0) + $filter.species.length + $filter.gender.length + $filter.size.length + $filter.color.length + $filter.pattern.length >> <div class="view-grid-panel"> <h2>Adults</h2> <div class="filter-toggle-row"> <<if $filter.open>> <<link "☰ Filter">><<set $filter.open = false>><<refresh>><</link>> <<else>> <<if _activeCount > 0>> <<link `"☰ Filter (" + _activeCount + ")"`>><<set $filter.open = true>><<refresh>><</link>> <<else>> <<link "☰ Filter">><<set $filter.open = true>><<refresh>><</link>> <</if>> <</if>> <<if _activeCount > 0>> <<link "Clear">> <<set $filter.search = "">> <<set $filter.species = []>> <<set $filter.gender = []>> <<set $filter.size = []>> <<set $filter.color = []>> <<set $filter.pattern = []>> <<refresh>> <</link>> <</if>> </div> <<if $filter.open>> <div class="filter-panel"> <div class="filter-search-row"> <<textbox "$filter.search" $filter.search autofocus>> <<link "🔎">><<refresh>><</link>> </div> <<if _optSpecies.length > 1>> <div class="filter-pill-row"> <span class="filter-pill-label">Species</span> <div class="filter-pills"> <<for _pi = 0; _pi < _optSpecies.length; _pi++>> <<capture _pi>> <<set _val to _optSpecies[_pi]>> <<capture _val>> <<if $filter.species.includes(_val)>> <span class="filter-pills-active"><<link `_val`>><<run $filter.species.splice($filter.species.indexOf(_val), 1)>><<refresh>><</link>></span> <<else>> <<link `_val`>><<run $filter.species.push(_val)>><<refresh>><</link>> <</if>> <</capture>> <</capture>> <</for>> </div> </div> <</if>> <div class="filter-pill-row"> <span class="filter-pill-label">Gender</span> <div class="filter-pills"> <<for _pi = 0; _pi < _optGender.length; _pi++>> <<capture _pi>> <<set _val to _optGender[_pi]>> <<capture _val>> <<if $filter.gender.includes(_val)>> <span class="filter-pills-active"><<link `_val`>><<run $filter.gender.splice($filter.gender.indexOf(_val), 1)>><<refresh>><</link>></span> <<else>> <<link `_val`>><<run $filter.gender.push(_val)>><<refresh>><</link>> <</if>> <</capture>> <</capture>> <</for>> </div> </div> <div class="filter-pill-row"> <span class="filter-pill-label">Size</span> <div class="filter-pills"> <<for _pi = 0; _pi < _optSize.length; _pi++>> <<capture _pi>> <<set _val to _optSize[_pi]>> <<capture _val>> <<if $filter.size.includes(_val)>> <span class="filter-pills-active"><<link `_val`>><<run $filter.size.splice($filter.size.indexOf(_val), 1)>><<refresh>><</link>></span> <<else>> <<link `_val`>><<run $filter.size.push(_val)>><<refresh>><</link>> <</if>> <</capture>> <</capture>> <</for>> </div> </div> <div class="filter-pill-row"> <span class="filter-pill-label">Color</span> <div class="filter-pills"> <<for _pi = 0; _pi < _optColor.length; _pi++>> <<capture _pi>> <<set _val to _optColor[_pi]>> <<capture _val>> <<if $filter.color.includes(_val)>> <span class="filter-pills-active"><<link `_val`>><<run $filter.color.splice($filter.color.indexOf(_val), 1)>><<refresh>><</link>></span> <<else>> <<link `_val`>><<run $filter.color.push(_val)>><<refresh>><</link>> <</if>> <</capture>> <</capture>> <</for>> </div> </div> <div class="filter-pill-row"> <span class="filter-pill-label">Pattern</span> <div class="filter-pills"> <<for _pi = 0; _pi < _optPattern.length; _pi++>> <<capture _pi>> <<set _val to _optPattern[_pi]>> <<capture _val>> <<if $filter.pattern.includes(_val)>> <span class="filter-pills-active"><<link `_val`>><<run $filter.pattern.splice($filter.pattern.indexOf(_val), 1)>><<refresh>><</link>></span> <<else>> <<link `_val`>><<run $filter.pattern.push(_val)>><<refresh>><</link>> <</if>> <</capture>> <</capture>> <</for>> </div> </div> </div> <</if>> <<if _activeCount > 0>> <div class="filter-result-count">Showing <<= _filtered.length>> of <<= _adults.length>></div> <</if>> <div class="view-grid"> <<if _filtered.length === 0>> <div class="view-grid-empty"> <<if _adults.length === 0>>No adults yet! <<else>>No adults match those filters. <</if>> </div> <<else>> <<for _i = 0; _i < _filtered.length; _i++>> <<capture _i>> <<set _adult to _filtered[_i]>> <<set _template to setup.creatureTemplates[_adult.name]>> <<set _gender to _adult.gender.toLowerCase()>> <<set _size to _adult.displayTraits.size>> <<set _color to _adult.displayTraits.color>> <<set _pattern to _adult.displayTraits.pattern>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to _color + "_" + _pattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _size === "large">> <<set _xPos to _col * -240>> <<set _dimensions to "240px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>> <<set _dimensions to "160px">> <<else>> <<set _xPos to _col * -80>> <<set _dimensions to "80px">> <</if>> <div class="view-grid-card"> <<capture _adult>> <<link [[ViewCreature]]>> <<set $currentCreature = $playerCreatures.indexOf(_adult)>> <</link>> <</capture>> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> <div class="card-label"><<creatureName _adult>><<if _adult.gender === "Male">> ♂<<else>> ♀<</if>></div> <div class="card-sublabel"><<= _adult.displayTraits.color>> · <<= _adult.displayTraits.size>></div> </div> <</capture>> <</for>> <</if>> </div> </div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <</nobr>>
<<nobr>> <h2>Sell Creatures</h2> <div class="info-box"> <strong>Your Money:</strong> $money dollars<br> </div> <h3>Select Creature to Sell</h3> <<set _sellableCreatures to $playerCreatures.filter(function(c) { return c.careCur > 0 || c.affectionCur > 0; })>> <<if _sellableCreatures.length === 0>> <p class="warning">You have no creatures available to sell. Creatures with 0 care and 0 affection can't be sold.</p> <<else>> <div class="creature-selection"> <<for _i to 0; _i < _sellableCreatures.length; _i++>> <<capture _i, _c, _sellPrice>> <<set _c to _sellableCreatures[_i]>> <<set _template to setup.creatureTemplates[_c.name]>> <<set _sellPrice to calculateSellPrice(_c)>> <div class="creature-card"> <div class="creature-display"> <<if _c.stage === "egg">> <p style="font-size: 3em;">🥚</p> <<elseif _c.stage === "baby">> <<set _size to _c.displayTraits.size>> <<set _color to _c.displayTraits.color>> <<set _gender to _c.gender.toLowerCase()>> <<if _template.avatars && _template.avatars[_gender] && _template.avatars[_gender].babySpriteSheets>> <<set _babySpriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<set _col to _template.babySpriteColumns[_color]>> <<if _col === undefined>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<if _size === "large">> <<set _xPos to _col * -180>> <<set _dimensions to "180px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>> <<set _dimensions to "120px">> <<else>> <<set _xPos to _col * -60>> <<set _dimensions to "60px">> <</if>> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _babySpriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> <<else>> <p style="font-size: 2em;">👶</p> <</if>> <<else>> <!-- Adult/Elder --> <<set _size to _c.displayTraits.size>> <<set _color to _c.displayTraits.color>> <<set _pattern to _c.displayTraits.pattern>> <<set _gender to _c.gender.toLowerCase()>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to setup.getSpriteKey(_c.name, _color, _pattern)>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _fallbackColor to _template.colorDominance[0]>> <<set _fallbackPattern to _template.patternDominance[0]>> <<set _colorPattern to _fallbackColor + "_" + _fallbackPattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <</if>> <<if _size === "large">> <<set _xPos to _col * -240>> <<set _dimensions to "240px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>> <<set _dimensions to "160px">> <<else>> <<set _xPos to _col * -80>> <<set _dimensions to "80px">> <</if>> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> <</if>> </div> <div class="creature-info"> <strong>_c.name</strong> <<if _c.gender === "Male">>♂<<else>>♀<</if>><br> Stage: _c.stage<br> Gen: _c.generation<br> <<if isCreatureFertile(_c, $currentDay)>> <span style="color: var(--teal);">✨ Fertile</span><br> <</if>> <strong style="color: var(--coral);">Sell Price: _sellPrice coins</strong> </div> <<link "Sell This Creature">> <<set $confirmSellCreature to _c>> <<set $confirmSellPrice to _sellPrice>> <<goto "ConfirmSell">> <</link>> </div> <</capture>> <</for>> </div> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <</nobr>>
<<nobr>> <h2>Confirm Sale</h2> <<set _template to setup.creatureTemplates[$confirmSellCreature.name]>> <div class="breeding-confirm"> <h3>Are you sure you want to sell this creature?</h3> <div class="creature-info" style="text-align: center; margin: 1em 0;"> <strong>$confirmSellCreature.name</strong><br> <<if $confirmSellCreature.gender === "Male">>♂<<else>>♀<</if>> | Stage: $confirmSellCreature.stage | Gen: $confirmSellCreature.generation<br> Rarity: _template.rarity </div> <p style="font-size: 1.3em; color: var(--teal);"><strong>Sale Price: $confirmSellPrice coins</strong></p> <p style="font-style: italic;">The creature will be sent to market and sold. You'll receive payment immediately.</p> <<link "Confirm Sale">> <<set _creatureIndex to $playerCreatures.findIndex(function(c) { return c.id === $confirmSellCreature.id; })>> <<run $departedCreatures.push({ id: $confirmSellCreature.id, name: $confirmSellCreature.petName || $confirmSellCreature.species, species: $confirmSellCreature.species, gender: $confirmSellCreature.gender, parents: $confirmSellCreature.parents, reason: "sold" })>> <<run $playerCreatures.splice(_creatureIndex, 1)>> <<set $money += $confirmSellPrice>> /* Check for first sell achievement */ <<if !$achievements.firstSell.unlocked>> <<run unlockAchievement("firstSell")>> <</if>> <<unset $confirmSellCreature>> <<unset $confirmSellPrice>> <<goto "SaleConfirmed">> <</link>> <<link "Cancel">> <<unset $confirmSellCreature>> <<unset $confirmSellPrice>> <<goto "SellCreatures">> <</link>> </div> <</nobr>>
<<nobr>> <h2>Creature Sent to Market</h2> <div class="success"> <p>Your creature has been sent to market!</p> </div> <<if $firstSell is false>> <<set $firstSell to true>> <<addXP 35>> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Sell Another" "SellCreatures">> <</link>> </div> <div class="forth-button"> <<link "Return Home" "Home">> <</link>> </div> </div> <</nobr>>
<<nobr>> <<if $photosCompleted gte 5>> <p><strong>Photography Session Complete!</strong></p> <p>You've finished photographing 5 products today.</p> <p><strong>Total earned:</strong> $<<print $photosMoney>></p> <p>Time to clean up and return to other responsibilities.</p> <p><<link "Wrap Up" "Home">> <<set $activeGig to "">> <<set $money += $photosMoney>> <<set $freelancingAttempts += 1>> <<set $photosCompleted to 0>> <<set $photosMoney to 0>> <<if $firstFreelance is false>> <<set $firstFreelance to true>> <<addXP 30>> <</if>> <</link>></p> <<else>> <<set $currentProduct to $products.random()>> <p style="display: block; text-align: center; font-size: 20px;"><strong>Product Photography Gig</strong> - Shot <<print $photosCompleted + 1>>/5</p> <p style="display: block; text-align: center; font-family: 'Quicksand', serif; font-size: 16px; color: var(--mid-text); font-weight: bold; margin: 10px;">Please match each product to its corresponding composition style. If you select the incorrect style, be sure to read the client feedback for hints!</p> <div class="product-box"> <p style="text-align: center; font-size: 20px;"><strong>Current Product:</strong> <<print $currentProduct.name>><<print $currentProduct.emoji>></p> <p style="margin-left: 10px;"><em>Choose your composition approach:</em></p> <p style="margin-left: 10px; font-weight: bold; line-height: 2.5em;">📷 <<link "Close-up detail shot" "DetailShot">><</link>> <br> 📷 <<link "Full product with context" "ContextShot">><</link>> <br> 📷 <<link "Lifestyle/in-use shot" "LifestyleShot">><</link>> <br> 📷 <<link "Overhead flat lay" "FlatLay">><</link>></p> </div> <p><em>Money earned so far: $<<print $photosMoney>></em></p> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Quit" "Home">><</link>> </div> </div> <</if>> <</nobr>>
<<nobr>> <<set $selectedShot to "detail">> <<set $photosCompleted += 1>> <p><strong><div style="text-align:center">You focus tight on the <<print $currentProduct.name>>, capturing intricate details and textures.</div></strong></p> <br> <<if $currentProduct.correct is "detail">> <b>Excellent choice! ⭐⭐⭐</b><br> <br> <<print $currentProduct.reason>>. Your detailed shot perfectly showcases what makes this product special.<br> <br> <b>Client feedback:</b> "Perfect! This is exactly what we needed for our premium product listing."<br> <br> <<set $photosMoney += 20>> <b>+$20 earned!</b><br> <<else>> <b>Not quite right... ⭐</b><br> <br> While technically competent, this wasn't the ideal approach for this product. <<print $currentProduct.reason>>.<br> <br> <b>Client feedback:</b> "It's okay, but not quite what we were looking for."<br> <br> <<set $photosMoney += 5>> <b>+$5 earned</b><br> <</if>> [[OK|Composition]] <</nobr>>
<<nobr>> <<set $selectedShot to "context">> <<set $photosCompleted += 1>> <p><strong><div style="text-align:center">You photograph the full <<print $currentProduct.name>> with clean background and proper context.</div></strong></p> <br> <<if $currentProduct.correct is "context">> <b>Excellent choice! ⭐⭐⭐</b><br> <br> <<print $currentProduct.reason>>. Your full product shot gives customers exactly what they need to see.<br> <br> <b>Client feedback:</b> "Perfect! Customers will know exactly what they're buying."<br> <br> <<set $photosMoney += 20>> <b>+$20 earned!</b><br> <<else>> <b>Not quite right... ⭐</b><br> <br> The shot is technically sound, but this product needed a different approach. <<print $currentProduct.reason>>.<br> <br> <b>Client feedback:</b> "It's usable, but not our preferred style for this item."<br> <br> <<set $photosMoney += 5>> <b>+$5 earned</b><br> <</if>> [[OK|Composition]] <</nobr>>
<<nobr>> <<set $selectedShot to "lifestyle">> <<set $photosCompleted += 1>> <p><strong><div style="text-align:center">You create an appealing lifestyle shot showing the <<print $currentProduct.name>> in use or natural context.</div></strong></p> <br> <<if $currentProduct.correct is "lifestyle">> <b>Excellent choice! ⭐⭐⭐</b><br> <br> <<print $currentProduct.reason>>. Your lifestyle approach makes the product irresistible to potential buyers.<br> <br> <b>Client feedback:</b> "Amazing! This makes people want to buy it immediately."<br> <br> <<set $photosMoney += 20>> <b>+$20 earned!</b><br> <<else>> <b>Not quite right... ⭐</b><br> <br> Creative approach, but not ideal for this product type. <<print $currentProduct.reason>>.<br> <br> <b>Client feedback:</b> "Nice creativity, but we need something more straightforward."<br> <br> <<set $photosMoney += 5>> <b>+$5 earned</b><br> <</if>> [[OK|Composition]] <</nobr>>
<<nobr>> <<set $selectedShot to "flatlay">> <<set $photosCompleted += 1>> <p><strong><div style="text-align:center">You arrange the <<print $currentProduct.name>> in a beautiful overhead flat lay composition with complementary props.</div></strong></p> <br> <<if $currentProduct.correct is "flatlay">> <b>Excellent choice! ⭐⭐⭐</b><br> <br> <<print $currentProduct.reason>>. Your styled flat lay creates an Instagram-worthy shot that will drive engagement.<br> <br> <b>Client feedback:</b> "Gorgeous! This will look amazing on our social media."<br> <br> <<set $photosMoney += 20>> <b>+$10 earned!</b><br> <<else>> <b>Not quite right... ⭐</b><br> <br> Beautiful styling, but this product needed a different treatment. <<print $currentProduct.reason>>.<br> <br> <b>Client feedback:</b> "Lovely composition, but not quite right for this product."<br> <br> <<set $photosMoney += 5>> <b>+$5 earned</b><br> <</if>> [[OK|Composition]] <</nobr>>
<<nobr>> <<for _ach, _achData range $achievements>> <<if _achData.goal !== undefined && !_achData.unlocked && _ach.startsWith("first") && _ach.endsWith("Steps")>> <<set $achievements[_ach].progress = Math.min($steps, _achData.goal)>> <</if>> <</for>> /* ── TRAINER CARD ── */ <div class="trainer-card"> <div class="trainer-card-holo"></div> <div class="trainer-card-inner"> <div class="trainer-card-left"> <div class="trainer-stamp"> <div class="trainer-stamp-inner"> <div class="trainer-stamp-logo">🐾</div> <div class="trainer-stamp-text">DCHW</div> </div> </div> </div> <div class="trainer-card-right"> <div class="trainer-card-title">Creature Breeder License</div> <div class="trainer-card-name">$playerName</div> <div class="trainer-card-sub">$playerPronouns</div> <div class="trainer-card-divider"></div> <div class="trainer-card-stats"> <div class="trainer-stat"> <span class="trainer-stat-label">Birthday</span> <span class="trainer-stat-value">$playerBirthday</span> </div> <div class="trainer-stat"> <span class="trainer-stat-label">Rank</span> <span class="trainer-stat-value">$playerRank.name</span> </div> <div class="trainer-stat"> <span class="trainer-stat-label">XP</span> <span class="trainer-stat-value">$playerXP</span> </div> </div> <div class="trainer-card-footer">DEPT. OF CREATURE HEALTH & WELFARE</div> </div> </div> </div> /* ── ACHIEVEMENT COUNT ── */ <div class="ach-count-bar"> 🏆 <strong>$totalAchievementsUnlocked</strong> / <<print getTotalAchievements()>> Achievements Unlocked </div> /* ── TABS ── */ <<set $achTab = $achTab || "unlocked">> <div class="profile-tabs"> <span class="profile-tab <<if $achTab === 'unlocked'>>profile-tab--active<</if>>"> <<link "🏆 Unlocked">> <<set $achTab = "unlocked">> <<goto `passage()`>> <</link>> </span> <span class="profile-tab <<if $achTab === 'locked'>>profile-tab--active<</if>>"> <<link "🔒 Locked">> <<set $achTab = "locked">> <<goto `passage()`>> <</link>> </span> </div> /* ── UNLOCKED ── */ <<if $achTab === "unlocked">> <div class="ach-list"> <<set _unlockedAchievements to getUnlockedAchievements()>> <<if _unlockedAchievements.length === 0>> <div class="vet-no-creatures">No achievements unlocked yet. Keep playing!</div> <<else>> <<for _i to 0; _i < _unlockedAchievements.length; _i++>> <<set _achievement to _unlockedAchievements[_i]>> <div class="ach-card ach-card--unlocked"> <div class="ach-icon">🏆</div> <div class="ach-body"> <div class="ach-name">_achievement.name</div> <div class="ach-desc">_achievement.description</div> <<if _achievement.rewards>> <div class="ach-reward"> <<if _achievement.rewards.money>> 💰 +_achievement.rewards.money g <</if>> <<if _achievement.rewards.items>> <<for _itemId, _qty range _achievement.rewards.items>> · +_qty <<print setup.items[_itemId].name>> <</for>> <</if>> </div> <</if>> </div> </div> <</for>> <</if>> </div> /* ── LOCKED ── */ <<else>> <div class="ach-list"> <<set _lockedAchievements to getLockedAchievements()>> <<if _lockedAchievements.length === 0>> <div class="vet-no-creatures">All achievements unlocked! Congratulations! 🎉</div> <<else>> <<for _i to 0; _i < _lockedAchievements.length; _i++>> <<set _achievement to _lockedAchievements[_i]>> <div class="ach-card ach-card--locked"> <div class="ach-icon">🔒</div> <div class="ach-body"> <div class="ach-name">???</div> <div class="ach-desc ach-hint">_achievement.hint</div> <<if _achievement.progress !== undefined && _achievement.goal !== undefined>> <div class="ach-progress-label">_achievement.progress / _achievement.goal</div> <div class="progress-bar"> <<set _progressPercent to Math.min(100, (_achievement.progress / _achievement.goal) * 100)>> <div class="progress-fill" @style="'width:' + _progressPercent + '%;'"></div> </div> <</if>> </div> </div> <</for>> <</if>> </div> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Home" "Home">><</link>> </div> </div> <</nobr>>
<<nobr>> <p6>Memorial</p6> <<if $deadCreatures === undefined || $deadCreatures.length === 0>> <p class="info">No creatures have passed away yet.</p> <<else>> <p>In loving memory of the creatures who have passed...</p> <div class="creature-selection"> <<for _i to 0; _i < $deadCreatures.length; _i++>> <<set _dead to $deadCreatures[_i]>> <div class="creature-card" style="opacity: 0.7;"> <div class="creature-info"> <strong>_dead.name</strong> <<if _dead.gender === "Male">>♂<<else>>♀<</if>><br> Generation: _dead.generation<br> Lived: _dead.age days<br> Died: Day _dead.deathDay </div> </div> <</for>> </div> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <</nobr>>
<<nobr>> <<if !$kitchenRenovated>> <div class="re-banner" style="text-align:center;"> <div style="font-size:2em;">🍳</div> <h2 class="re-banner-title">Kitchen</h2> <p>The kitchen is in poor condition. It requires an experienced enough breeder technician to renovate at Real Estate (Rank 3).</p> </div> <div class="back-forth-buttons"> <div class="back-button"><<link "Go Back" `previous()`>><</link>></div> </div> <<else>> <div class="kitchen-banner"> <img src="https://i.imgur.com/ZY99Plb.png" class="kitchen-banner-img" alt="Kitchen"> <div class="kitchen-banner-text"> <h2 class="re-banner-title" style="margin:0;">🍳 Kitchen</h2> <p style="margin:0.3em 0 0 0; font-family:'Georgia',serif; font-size:0.9em;">Combine 3 ingredients to cook a dish.</p> </div> </div> /* ── SELECTED INGREDIENTS TRAY ── */ <div class="kitchen-tray"> <div class="kitchen-tray-header"> <span>🥘 Selected (<strong><<print $cookingSelection.length>>/3</strong>)</span> <<if $cookingSelection.length > 0>> <<link "Clear">><<set $cookingSelection = []>><<goto "Kitchen">><</link>> <</if>> </div> <div class="kitchen-tray-slots"> <<for _i = 0; _i < 3; _i++>> <<if _i < $cookingSelection.length>> <<set _selId = $cookingSelection[_i]>> <<set _selItem = setup.items[_selId]>> <div class="kitchen-tray-slot filled"> <<if _selItem.image>><img @src="_selItem.image" alt="_selItem.name"><</if>> <span class="kitchen-tray-name"><<print _selItem.name>></span> <<capture _i>> <span class="kitchen-tray-remove"> <<link "✕">> <<set $cookingSelection.splice(_i, 1)>> <<refresh>> <</link>> </span> <</capture>> </div> <<else>> <div class="kitchen-tray-slot empty"> <span class="kitchen-tray-empty-label">Empty</span> </div> <</if>> <</for>> </div> <<if $cookingSelection.length === 3>> <div style="text-align:center; margin-top:0.8em;"> <<link "🔥 Cook!" "CookingResult">><</link>> </div> <</if>> </div> /* ── INGREDIENT TABS ── */ <<set _availableIngredients = []>> <<for _itemId, _quantity range $inventory>> <<if _quantity > 0 && setup.ingredientProperties[_itemId]>> <<run _availableIngredients.push(_itemId)>> <</if>> <</for>> <<set _byCategory = { "Protein": [], "Vegetable": [], "Base": [], "Flavor": [] }>> <<for _ingId range _availableIngredients>> <<run _byCategory[setup.ingredientProperties[_ingId].category].push(_ingId)>> <</for>> <<if !$kitchenTab>><<set $kitchenTab = "Protein">><</if>> <div class="kitchen-tabs-wrap"> <div class="shop-categories-scroll"> <<for _cat range ["Protein", "Vegetable", "Base", "Flavor"]>> <<capture _cat>> <<link _cat>><<set $kitchenTab = _cat>><<refresh>><</link>> <</capture>> <</for>> </div> </div> <div class="kitchen-ingredient-panel"> <<if _byCategory[$kitchenTab].length === 0>> <div class="re-empty"> <p>No <<print $kitchenTab.toLowerCase()>> ingredients in your inventory.</p> </div> <<else>> <<for _ingId range _byCategory[$kitchenTab]>> <<capture _ingId>> <<set _item = setup.items[_ingId]>> <<set _prop = setup.ingredientProperties[_ingId]>> <<set _isSelected = $cookingSelection.includes(_ingId)>> <<set _isFull = $cookingSelection.length >= 3>> <div @class="'kitchen-ing-card' + (_isSelected ? ' ing-selected' : '')"> <<if _item.image>> <img @src="_item.image" class="kitchen-ing-img" @alt="_item.name"> <</if>> <div class="kitchen-ing-info"> <div class="kitchen-ing-name"><<print _item.name>> <span class="kitchen-ing-qty">(<<print $inventory[_ingId]>>)</span></div> <div class="kitchen-ing-tags"><<print _prop.flavorTags.join(", ")>></div> <div class="kitchen-ing-hint"><i><<print _prop.hint>></i></div> <<if _isSelected>> <span class="kitchen-ing-status selected">✓ Selected</span> <<elseif _isFull>> <span class="kitchen-ing-status full">Tray full</span> <<else>> <<link "+ Add">> <<run $cookingSelection.push(_ingId)>> <<refresh>> <</link>> <</if>> </div> </div> <</capture>> <</for>> <</if>> </div> /* ── COOKING QUEUE ── */ <div class="kitchen-queue"> <div class="kitchen-queue-header">🍳 Currently Cooking (<strong><<print $cookingQueue.length>>/3</strong>)</div> <<for _qi = 0; _qi < $cookingQueue.length; _qi++>> <<set _qm = $cookingQueue[_qi]>> <div class="kitchen-queue-item"> <span class="kitchen-queue-name">🍲 <<print _qm.recipeName>></span> <<if _qm.done>> <<capture _qi>> <<link "✅ Collect">> <<set _collected = $cookingQueue[_qi]>> <<if !$inventory[_collected.mealId]>><<set $inventory[_collected.mealId] = 0>><</if>> <<set $inventory[_collected.mealId] += 1>> <<run $cookingQueue.splice(_qi, 1)>> <<refresh>> <</link>> <</capture>> <<else>> <<set _msLeft = Math.max(0, _qm.finishTime - Date.now())>> <<set _minsLeft = Math.ceil(_msLeft / 60000)>> <span class="kitchen-queue-time">⏳ <<print _minsLeft>> min left</span> <</if>> </div> <</for>> </div> /* ── COOKBOOK LINK ── */ <div class="cookbook-section" style="margin-top:1em;"> <h3 style="margin:0 0 0.3em 0;">📖 Your Cookbook</h3> <p style="margin:0 0 0.6em 0; font-size:0.9em;"><<print $cookbook.length>> <<if $cookbook.length === 1>>recipe<<else>>recipes<</if>> discovered</p> <<link "View Cookbook" "Cookbook">><</link>> </div> <div class="back-forth-buttons" style="margin-top:1em;"> <div class="back-button"><<link "Go Home" "Home">><</link>></div> </div> <</if>> <</nobr>>
<<nobr>> <<checkExpiredRequests>> <h style="display: block; font-family: 'Fontdiner Swanky', serif; color: var(--coral); text-align: center; font-size: 2.5em; margin-bottom: 0.5em;">📋 Request Board</h> <div style="background-color: var(--tangerine); padding: 1.5em; border-radius: 10px; margin-bottom: 1.5em; border: 3px solid var(--coral);"> <p style="margin: 0; font-family: 'Georgia', serif; font-size: 1.1em;">Local breeders and collectors are looking for specific creatures! Complete requests to earn rewards and unlock more challenging opportunities.</p> </div> <div style="background-color: rgba(255, 227, 187, 0.5); padding: 1em; border-radius: 8px; margin-bottom: 1.5em;"> <strong>Progress:</strong><br> Simple Requests Completed: $completedRequests.simple / 5 <<if $requestsUnlocked.medium>><span style="color: var(--teal);">✓ Medium Unlocked!</span><</if>><br> <<if $requestsUnlocked.medium>>Medium Requests Completed: $completedRequests.medium / 5 <<if $requestsUnlocked.complex>><span style="color: var(--teal);">✓ Complex Unlocked!</span><</if>><</if>> </div> /* Next request timer */ <<set _msUntilNext = Math.max(0, $nextRequestTime - Date.now())>> <<set _hoursUntilNext = Math.floor(_msUntilNext / 3600000)>> <<set _minutesUntilNext = Math.floor((_msUntilNext % 3600000) / 60000)>> <div style="background-color: rgba(3, 168, 161, 0.2); padding: 0.75em 1em; border-radius: 8px; margin-bottom: 1.5em; border: 2px solid var(--teal);"> <<if $requests.length >= 3>> 📋 Request board is full. Complete a request to make room! <<elseif _msUntilNext === 0>> ⏳ A new request will arrive soon! <<else>> ⏳ Next request in: _hoursUntilNext h _minutesUntilNext m <</if>> </div> <<if $requests.length === 0>> <div style="background-color: var(--lightyellow); padding: 2em; border-radius: 10px; border: 2px dashed var(--coral); text-align: center;"> <p style="font-style: italic; color: var(--dark-text);">No requests available right now. Check back later!</p> </div> <<else>> <<for _i, _request range $requests>> <<set _hoursLeft = Math.max(0, Math.floor((_request.expiresTime - Date.now()) / 3600000))>> <<set _minutesLeft = Math.max(0, Math.floor(((_request.expiresTime - Date.now()) % 3600000) / 60000))>> <div style="background-color: var(--lightyellow); padding: 1.5em; border-radius: 10px; margin-bottom: 1.5em; border: 3px solid var(--coral); box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1em;"> <h3 style="font-family: 'Chewy', cursive; color: var(--coral); margin: 0;">Request #<<print _request.id>></h3> <<set _diff = _request.difficulty.toLowerCase().trim()>> <<= '<span class="difficulty-badge difficulty-' + _diff + '">' + _request.difficulty.toUpperCase() + '</span>'>> </div> <div style="margin-bottom: 1em;"> <strong>Wanted:</strong> <<print _request.species>> (<<print _request.rarity>>)<br> <strong>Requirements:</strong> <ul style="margin: 0.5em 0; padding-left: 2em;"> <li>Stage: Adult</li> <<if _request.requiredTraits.color>><li>Color: <<print _request.requiredTraits.color>></li><</if>> <<if _request.requiredTraits.size>><li>Size: <<print _request.requiredTraits.size>></li><</if>> <<if _request.requiredTraits.pattern>><li>Pattern: <<print _request.requiredTraits.pattern>></li><</if>> </ul> <strong>Reward:</strong> $<<print _request.reward>><br> <strong>Expires in:</strong> _hoursLeft h _minutesLeft m </div> <<capture _i, _request>> <div style="display: flex; gap: 0.5em; flex-wrap: wrap;"> <<link "View My Creatures">> <<set $viewingRequest = _request>> <<set $viewingRequestIndex = _i>> <<goto "FulfillRequest">> <</link>> /* Refresh: allowed once per 24 real hours */ <<set _canRefresh = (!$lastRequestRefreshTime || (Date.now() - $lastRequestRefreshTime) >= 86400000)>> <<if _canRefresh>> | <<link "🔄 Refresh This Request">> <<set _refreshDifficulty = _request.difficulty>> <<run $requests.deleteAt(_i)>> <<set $lastRequestRefreshTime = Date.now()>> <<generateRequest _refreshDifficulty>> <<goto "RequestBoard">> <</link>> <</if>> </div> <</capture>> </div> <</for>> <</if>> /* Refresh availability notice */ <<set _canRefresh = (!$lastRequestRefreshTime || (Date.now() - $lastRequestRefreshTime) >= 86400000)>> <<if _canRefresh>> <div style="margin-top: 1.5em; padding: 1em; background-color: rgba(3, 168, 161, 0.2); border-radius: 8px; border: 2px solid var(--teal);"> <p style="margin: 0;">💡 You can refresh ONE request every 24 hours by clicking the 🔄 button next to any request above!</p> </div> <<else>> <<set _msUntilRefresh = Math.max(0, 86400000 - (Date.now() - $lastRequestRefreshTime))>> <<set _refreshHours = Math.floor(_msUntilRefresh / 3600000)>> <<set _refreshMinutes = Math.floor((_msUntilRefresh % 3600000) / 60000)>> <div style="margin-top: 1.5em; padding: 1em; background-color: rgba(150, 150, 150, 0.2); border-radius: 8px; border: 2px solid #999;"> <p style="margin: 0; color: #666;">Daily refresh already used. Available again in _refreshHours h _refreshMinutes m.</p> </div> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <</nobr>>
<<nobr>> <h style="font-family: 'Chewy', cursive; color: var(--coral); text-align: center; font-size: 2.5em; margin-bottom: 0.5em;">Select a Creature</h> <div style="background-color: var(--tangerine); padding: 1.5em; border-radius: 10px; margin-bottom: 1.5em; border: 3px solid var(--coral);"> <strong>Request #<<print $viewingRequest.id>></strong><br> Looking for: <<print $viewingRequest.species>> (<<print $viewingRequest.rarity>>)<br> Requirements: <ul style="margin: 0.5em 0; padding-left: 2em;"> <li>Stage: Adult</li> <<if $viewingRequest.requiredTraits.color>><li>Color: <<print $viewingRequest.requiredTraits.color>></li><</if>> <<if $viewingRequest.requiredTraits.size>><li>Size: <<print $viewingRequest.requiredTraits.size>></li><</if>> <<if $viewingRequest.requiredTraits.pattern>><li>Pattern: <<print $viewingRequest.requiredTraits.pattern>></li><</if>> </ul> Reward: $<<print $viewingRequest.reward>> <<print $viewingRequest.xp>> XP </div> <<set _matchingCreatures = []>> <<set _nonMatchingCreatures = []>> <<for _i, _creature range $playerCreatures>> <<checkCreatureMatch _creature $viewingRequest>> <<if _matchResult>> <<run _matchingCreatures.push({creature: _creature, index: _i})>> <<else>> <<run _nonMatchingCreatures.push({creature: _creature, index: _i})>> <</if>> <</for>> <<if _matchingCreatures.length > 0>> <h2 style="font-family: 'Chewy', cursive; color: var(--teal);">✓ Matching Creatures</h2> <<for _i, _match range _matchingCreatures>> <<capture _i>> <<set _creature = _match.creature>> <<set _creatureIndex = _match.index>> <<set _template to setup.creatureTemplates[_creature.name]>> <div style="background-color: rgba(3, 168, 161, 0.2); padding: 1em; border-radius: 10px; margin-bottom: 1em; border: 3px solid var(--teal); display: flex; align-items: center; justify-content: space-between;"> <div> <strong><<print _creature.name>> #<<print _creature.id>></strong> (<<print _creature.gender>>)<br> Stage: <<print _creature.stage>> | Age: <<= setup.getAgeDisplay(_creature)>><br> Color: <<print _creature.displayTraits.color>> | Size: <<print _creature.displayTraits.size>> | Pattern: <<print _creature.displayTraits.pattern>><br> <<link "Fulfill Request with This Creature">> <<run $departedCreatures.push({ id: _creature.id, name: _creature.petName || _creature.species, species: _creature.species, gender: _creature.gender, parents: _creature.parents, reason: "fulfilled request" })>> <<addXP $viewingRequest.xp>> <<set $money += $viewingRequest.reward>> <<set $completedRequests[$viewingRequest.difficulty] += 1>> <<run unlockAchievement("firstRequest")>> <<run updateAchievementProgress("tenRequests", 1)>> <<if !$requestsUnlocked.medium && $completedRequests.simple >= 5>> <<set $requestsUnlocked.medium = true>> <<set $unlockedMedium = true>> <</if>> <<if !$requestsUnlocked.complex && $completedRequests.medium >= 5>> <<set $requestsUnlocked.complex = true>> <<set $unlockedComplex = true>> <</if>> <<run $playerCreatures.deleteAt(_creatureIndex)>> <<run $requests.deleteAt($viewingRequestIndex)>> <<goto "RequestComplete">> <</link>> </div> <!-- Scaled sprite display --> <<if _creature.stage === "egg">> <div style="width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;"> <p style="font-size: 2em; margin: 0;">🥚</p> </div> <<elseif _creature.stage === "baby">> <<set _size to _creature.displayTraits.size>> <<set _color to _creature.displayTraits.color>> <<set _gender to _creature.gender.toLowerCase()>> <<if _template.avatars && _template.avatars[_gender] && _template.avatars[_gender].babySpriteSheets>> <<set _babySpriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<set _col to _template.babySpriteColumns[_color]>> <<if _col === undefined>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<if _size === "large">> <<set _xPos to _col * -180>> <<set _dimensions to "180px">> <<set _scaledDimensions to "90px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>> <<set _dimensions to "120px">> <<set _scaledDimensions to "60px">> <<else>> <<set _xPos to _col * -60>> <<set _dimensions to "60px">> <<set _scaledDimensions to "30px">> <</if>> <div @style="'width: ' + _scaledDimensions + '; height: ' + _scaledDimensions + '; overflow: hidden; flex-shrink: 0;'"> <div style="transform: scale(0.5); transform-origin: top left;"> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _babySpriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> </div> <<else>> <p style="font-size: 1.5em; margin: 0;">👶</p> <</if>> <<else>> <!-- Adult/Elder --> <<set _size to _creature.displayTraits.size>> <<set _color to _creature.displayTraits.color>> <<set _pattern to _creature.displayTraits.pattern>> <<set _gender to _creature.gender.toLowerCase()>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to setup.getSpriteKey(_creature.name, _color, _pattern)>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _fallbackColor to _template.colorDominance[0]>> <<set _fallbackPattern to _template.patternDominance[0]>> <<set _colorPattern to _fallbackColor + "_" + _fallbackPattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <</if>> <<if _size === "large">> <<set _xPos to _col * -240>> <<set _dimensions to "240px">> <<set _scaledDimensions to "120px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>> <<set _dimensions to "160px">> <<set _scaledDimensions to "80px">> <<else>> <<set _xPos to _col * -80>> <<set _dimensions to "80px">> <<set _scaledDimensions to "40px">> <</if>> <div @style="'width: ' + _scaledDimensions + '; height: ' + _scaledDimensions + '; overflow: hidden; flex-shrink: 0;'"> <div style="transform: scale(0.5); transform-origin: top left;"> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> </div> <</if>> </div> <</capture>> <</for>> <<else>> <div style="background-color: rgba(234, 91, 111, 0.2); padding: 1.5em; border-radius: 10px; margin-bottom: 1.5em; border: 2px solid var(--coral);"> <p style="margin: 0; font-weight: bold; color: var(--darkcoral);">❌ You don't have any creatures that match this request.</p> </div> <</if>> <<if _nonMatchingCreatures.length > 0>> <h style="font-family: 'Chewy', cursive; color: var(--dark-text);">Your Other Creatures</h> <div class="request-box"> <<for _i, _match range _nonMatchingCreatures>> <<capture _i>> <<set _creature = _match.creature>> <<set _template to setup.creatureTemplates[_creature.name]>> <div style="background-color: rgba(90, 62, 43, 0.1); padding: 1em; border-radius: 10px; margin-bottom: 1em; border: 2px solid #ccc; display: flex; align-items: center; justify-content: space-between;"> <div> <strong><<print _creature.name>> #<<print _creature.id>></strong> (<<print _creature.gender>>)<br> Stage: <<print _creature.stage>> | Age: <<= setup.getAgeDisplay(_creature)>><br> <<if _creature.stage === "adult">> Color: <<print _creature.displayTraits.color>> | Size: <<print _creature.displayTraits.size>> | Pattern: <<print _creature.displayTraits.pattern>> <<else>> <em>Must be adult to fulfill requests</em> <</if>> </div> <!-- Scaled sprite display --> <<if _creature.stage === "egg">> <div style="width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;"> <p style="font-size: 2em; margin: 0;">🥚</p> </div> <<elseif _creature.stage === "baby">> <<set _size to _creature.displayTraits.size>> <<set _color to _creature.displayTraits.color>> <<set _gender to _creature.gender.toLowerCase()>> <<if _template.avatars && _template.avatars[_gender] && _template.avatars[_gender].babySpriteSheets>> <<set _babySpriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<set _col to _template.babySpriteColumns[_color]>> <<if _col === undefined>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<if _size === "large">> <<set _xPos to _col * -180>> <<set _dimensions to "180px">> <<set _scaledDimensions to "90px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>> <<set _dimensions to "120px">> <<set _scaledDimensions to "60px">> <<else>> <<set _xPos to _col * -60>> <<set _dimensions to "60px">> <<set _scaledDimensions to "30px">> <</if>> <div @style="'width: ' + _scaledDimensions + '; height: ' + _scaledDimensions + '; overflow: hidden; flex-shrink: 0;'"> <div style="transform: scale(0.5); transform-origin: top left;"> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _babySpriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> </div> <<else>> <p style="font-size: 1.5em; margin: 0;">👶</p> <</if>> <<else>> <!-- Adult/Elder --> <<set _size to _creature.displayTraits.size>> <<set _color to _creature.displayTraits.color>> <<set _pattern to _creature.displayTraits.pattern>> <<set _gender to _creature.gender.toLowerCase()>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<set _colorPattern to setup.getSpriteKey(_creature.name, _color, _pattern)>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _fallbackColor to _template.colorDominance[0]>> <<set _fallbackPattern to _template.patternDominance[0]>> <<set _colorPattern to _fallbackColor + "_" + _fallbackPattern>> <<set _col to _template.spriteColumns[_colorPattern]>> <</if>> <<if _size === "large">> <<set _xPos to _col * -240>> <<set _dimensions to "240px">> <<set _scaledDimensions to "120px">> <<elseif _size === "medium">> <<set _xPos to _col * -160>> <<set _dimensions to "160px">> <<set _scaledDimensions to "80px">> <<else>> <<set _xPos to _col * -80>> <<set _dimensions to "80px">> <<set _scaledDimensions to "40px">> <</if>> <div @style="'width: ' + _scaledDimensions + '; height: ' + _scaledDimensions + '; overflow: hidden; flex-shrink: 0;'"> <div style="transform: scale(0.5); transform-origin: top left;"> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> </div> <</if>> </div> <</capture>> <</for>> </div> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Back to Board" "RequestBoard">> <</link>> </div> </div> <</nobr>>
<<nobr>> <h style="font-family: 'Chewy', cursive; color: var(--teal); text-align: center; font-size: 2.5em; margin-bottom: 0.5em;">✓ Request Complete!</h> <<if $tutorialQuests.quests.fulfillRequest.accepted && !$tutorialQuests.quests.fulfillRequest.complete>> <<set $tutorialQuests.quests.fulfillRequest.complete = true>> <<addXP 60>> <<set $money += 150>> <</if>> <div style="background-color: rgba(3, 168, 161, 0.3); padding: 2em; border-radius: 10px; margin-bottom: 1.5em; border: 3px solid var(--teal); text-align: center;"> <p style="font-size: 1.3em; margin: 0;">You've successfully fulfilled the request!</p> <p style="font-size: 1.5em; font-weight: bold; color: var(--teal); margin: 0.5em 0;">+$<<print $viewingRequest.reward>></p> <!-- NOTE: Display special reward items here when you implement them --> </div> <<if $unlockedMedium>> <div style="background-color: rgba(255, 138, 79, 0.3); padding: 1.5em; border-radius: 10px; margin-bottom: 1.5em; border: 3px solid var(--coralorange); text-align: center;"> <p style="font-size: 1.4em; font-weight: bold; color: var(--coralorange); margin: 0;">🎉 MEDIUM DIFFICULTY UNLOCKED! 🎉</p> <p style="margin: 0.5em 0;">You can now access more challenging requests with better rewards!</p> </div> <<set $unlockedMedium = false>> <</if>> <<if $unlockedComplex>> <div style="background-color: rgba(234, 91, 111, 0.3); padding: 1.5em; border-radius: 10px; margin-bottom: 1.5em; border: 3px solid var(--coral); text-align: center;"> <p style="font-size: 1.4em; font-weight: bold; color: var(--coral); margin: 0;">🏆 COMPLEX DIFFICULTY UNLOCKED! 🏆</p> <p style="margin: 0.5em 0;">You've proven yourself as a master breeder! The most challenging requests are now available!</p> </div> <<set $unlockedComplex = false>> <</if>> <<if $firstRequest is false>> <<set $firstRequest to true>> <<addXP 50>> <</if>> <div class="back-forth-buttons"> <div class="back-button"> <<link "Fulfill Another" "RequestBoard">> <</link>> </div> <div class="forth-button"> <<link "Go Home" "Home">> <</link>> </div> </div> <</nobr>>
<<nobr>> /* ── HEADER ── */ <div class="vet-banner"> <h5>🌺 Critter Clinic</h5> <p class="tagline">Care for all creatures small or tall!</p> </div> /* ── SERVICES ── */ <div class="vet-services"> <p2><strong>Our Services</strong></p2> <div class="vet-service-card"> <div class="vet-service-icon">❤️</div> <div class="vet-service-body"> <div class="vet-service-title">Emergency Care</div> <div class="vet-service-desc">Immediate triage and stabilization for urgent, all-species emergencies.</div> <div class="vet-service-footer"> <span class="vet-service-price">From $175</span> <<link "Select Creature">> <<set $vetService = "emergency">> <<goto "VetSelectCreature">> <</link>> </div> </div> </div> <div class="vet-service-card"> <div class="vet-service-icon">⚕️</div> <div class="vet-service-body"> <div class="vet-service-title">Surgery</div> <div class="vet-service-desc">Sex reassignment procedures with species-tailored anesthesia and care.</div> <div class="vet-service-footer"> <span class="vet-service-price">From $250</span> <<link "Select Creature">> <<set $vetService = "surgery">> <<goto "VetSelectCreature">> <</link>> </div> </div> </div> <div class="vet-service-card"> <div class="vet-service-icon">💊</div> <div class="vet-service-body"> <div class="vet-service-title">Medicine & Wellness</div> <div class="vet-service-desc">Checkups, vaccines, diagnostics, and long-term health plans for every critter.</div> <div class="vet-service-footer"> <span class="vet-service-price">Browse Items</span> <<link "View Supplies">> <<goto "VetShop">> <</link>> </div> </div> </div> <div class="vet-service-card"> <div class="vet-service-icon">🧬</div> <div class="vet-service-body"> <div class="vet-service-title">Genetic Testing</div> <div class="vet-service-desc">Unlock your creature's complete genetic profile, revealing hidden recessive traits.</div> <div class="vet-service-footer"> <span class="vet-service-price">$25</span> <<link "Select Creature">> <<set $vetService = "geneticTesting">> <<goto "VetSelectCreature">> <</link>> </div> </div> </div> <div class="vet-service-card"> <div class="vet-service-icon">✨</div> <div class="vet-service-body"> <div class="vet-service-title">Grooming & Comfort</div> <div class="vet-service-desc">Gentle baths, trims, and spa-style visits designed for low-stress comfort.</div> <div class="vet-service-footer"> <span class="vet-service-price">From $50</span> <<link "Select Creature">> <<set $vetService = "grooming">> <<goto "VetSelectCreature">> <</link>> </div> </div> </div> </div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <</nobr>>
<<nobr>> /* ── SERVICE BANNER ── */ <div class="vet-select-banner"> <<if $vetService === "emergency">> <div class="vet-select-title">❤️ Emergency Care</div> <div class="vet-select-subtitle">Restores hunger and care to 100% — $175</div> <<elseif $vetService === "surgery">> <div class="vet-select-title">⚕️ Sex Reassignment Surgery</div> <div class="vet-select-subtitle">Changes creature's sex (one-time only) — $250</div> <<elseif $vetService === "grooming">> <div class="vet-select-title">✨ Grooming & Comfort</div> <div class="vet-select-subtitle">Restores care to 100% — $50</div> <<elseif $vetService === "geneticTesting">> <div class="vet-select-title">🧬 Genetic Testing</div> <div class="vet-select-subtitle">Reveals complete genetic profile including hidden traits — $25</div> <</if>> <div class="vet-select-money">💰 $money g</div> </div> /* ── CREATURE LIST ── */ <<set _eligibleCreatures = $playerCreatures.filter(function(c) { return c.stage === "adult"; })>> <<if _eligibleCreatures.length === 0>> <div class="vet-no-creatures"> <p>You don't have any adult creatures available for vet services.</p> <p><em>Only adult creatures can receive veterinary care.</em></p> </div> <<else>> <div class="vet-creature-list"> <<for _i = 0; _i < $playerCreatures.length; _i++>> <<set _creature = $playerCreatures[_i]>> <<if _creature.stage === "adult">> <<capture _i, _creature>> <<if !_creature.isBaby>> <<set _template = setup.creatureTemplates[_creature.name]>> <<set _size = _creature.displayTraits.size>> <<set _pattern = _creature.displayTraits.pattern>> <<set _color = _creature.displayTraits.color>> <<set _gender = _creature.gender.toLowerCase()>> <<set _colorPattern = setup.getSpriteKey(_creature.name, _color, _pattern)>> <<set _col = _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _col = _template.spriteColumns[_template.colorDominance[0] + "_" + _template.patternDominance[0]]>> <</if>> <<if _size === "large">> <<set _xPos = _col * -240>><<set _dim = "240px">><<set _scale = "scale(0.4)">> <<elseif _size === "medium">> <<set _xPos = _col * -160>><<set _dim = "160px">><<set _scale = "scale(0.5)">> <<else>> <<set _xPos = _col * -80>><<set _dim = "80px">><<set _scale = "scale(0.9)">> <</if>> <</if>> /* ── CARD ── */ <div class="vet-creature-card <<if !_canUse>>vet-creature-card--disabled<</if>>"> /* Sprite */ <div class="vet-sprite-wrap"> <<if _creature.isBaby>> <span style="font-size:2em;">🥚</span> <<else>> <<if _size === "large">> <<set _xPos = _col * -240>> <<set _dimensions = "240px">> <<set _scaledDimensions = "120px">> <<elseif _size === "medium">> <<set _xPos = _col * -160>> <<set _dimensions = "160px">> <<set _scaledDimensions = "80px">> <<else>> <<set _xPos = _col * -80>> <<set _dimensions = "80px">> <<set _scaledDimensions = "40px">> <</if>> <div @style="'width:' + _scaledDimensions + ';height:' + _scaledDimensions + ';overflow:hidden;flex-shrink:0;'"> <div style="transform:scale(0.5);transform-origin:top left;"> <div class="creature-layers" @style="'width:' + _dimensions + ';height:' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _template.avatars[_gender].patternSpriteSheets[_size] + ');background-position:' + _xPos + 'px 0px;width:' + _dimensions + ';height:' + _dimensions + ';'"> </div> </div> </div> </div> <</if>> </div> /* Info */ <div class="vet-creature-body"> <div class="vet-creature-name"> <<if ndef _creature.petName || _creature.petName === "">> _creature.name <<else>> _creature.petName <</if>> <<if _creature.gender === "Male">>♂️<<else>>♀️<</if>> </div> <div class="vet-creature-age">Age: <<= setup.getAgeDisplay(_creature)>></div> /* Action button */ <<if $vetService === "surgery">> <<if _creature.hadSurgery>> <div class="vet-action-disabled">Already had surgery</div> <<elseif $money >= 250>> <<link "Surgery ($250)">> <<set $money -= 250>> <<set $playerCreatures[_i].gender = (_creature.gender === "Male" ? "Female" : "Male")>> <<set $playerCreatures[_i].hadSurgery = true>> <<set $vetServiceComplete = _creature.name + "'s gender has been changed to " + $playerCreatures[_i].gender + "!">> <<goto "VetServiceComplete">> <</link>> <<else>> <div class="vet-action-disabled">Not enough money</div> <</if>> <<elseif $vetService === "emergency">> <<if $money >= 175>> <<link "Emergency Care ($175)">> <<set $money -= 175>> <<set $playerCreatures[_i].hungerCur = $playerCreatures[_i].hungerMax>> <<set $playerCreatures[_i].careCur = $playerCreatures[_i].careMax>> <<set $vetServiceComplete = _creature.name + " has been fully restored!">> <<goto "VetServiceComplete">> <</link>> <<else>> <div class="vet-action-disabled">Not enough money</div> <</if>> <<elseif $vetService === "grooming">> <<if $money >= 50>> <<link "Groom ($50)">> <<set $money -= 50>> <<set $playerCreatures[_i].careCur = $playerCreatures[_i].careMax>> <<set $vetServiceComplete = _creature.name + " is feeling pampered and refreshed!">> <<goto "VetServiceComplete">> <</link>> <<else>> <div class="vet-action-disabled">Not enough money</div> <</if>> <<elseif $vetService === "geneticTesting">> <<if _creature.geneticTestingDone>> <div class="vet-action-disabled">Testing already done</div> <<elseif $money >= 25>> <<link "Genetic Testing ($25)">> <<set $money -= 25>> <<set $playerCreatures[_i].geneticTestingDone = true>> <<set $vetServiceComplete = _creature.name + "'s genetic profile has been unlocked!">> <<goto "VetServiceComplete">> <</link>> <<else>> <div class="vet-action-disabled">Not enough money</div> <</if>> <</if>> </div> </div> <</capture>> <</if>> <</for>> </div> <</if>> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <</nobr>>
<<nobr>> <div class="vet-complete-wrap"> <div class="vet-complete-icon">✓</div> <div class="vet-complete-title">Service Complete!</div> <div class="vet-complete-message">$vetServiceComplete</div> <div class="vet-complete-money"> 💰 Remaining: <strong>$money g</strong> </div> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Back to Clinic" "VetClinic">><</link>> </div> <div class="forth-button"> <<link "Go Home" "Home">><</link>> </div> </div> <</nobr>>
<<nobr>> /* ── HEADER ── */ <div class="vet-banner"> <h5>💊 Medicine & Wellness</h5> <p class="tagline">Your Money: <strong>💰 $money g</strong></p> </div> /* ── ITEM LIST ── */ <div class="vet-shop-list"> <<for _key, _item range setup.items>> <<if _item.category === "Consumables">> <<capture _item>> <div class="vet-shop-card"> <div class="vet-shop-img-wrap"> [img[_item.image]] </div> <div class="vet-shop-body"> <div class="vet-shop-name">_item.name</div> <div class="vet-shop-price">💰 _item.basePrice g</div> <div class="vet-shop-rarity"> <<if _item.rarity === "Common">><span style="color:#95a5a6;">Common</span> <<elseif _item.rarity === "Uncommon">><span style="color:#1bd602;">Uncommon</span> <<elseif _item.rarity === "Rare">><span style="color:#0070dd;">Rare</span> <</if>> </div> <<link "View & Buy →" "VetItemDetail">> <<set $selectedVetItem = _item>> <<set $vetPurchaseQuantity = 1>> <</link>> </div> </div> <</capture>> <</if>> <</for>> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <</nobr>>
<<nobr>> <div class="modal-bg-snapshot" id="modal-bg"></div> <div class="vet-item-overlay"> <div class="vet-item-sheet"> /* ── HEADER ── */ <div class="vet-item-header"> <div class="vet-item-header-title">$selectedVetItem.name</div> <<link "✕" "VetShop">><</link>> </div> /* ── IMAGE ── */ <div class="vet-item-img-wrap"> [img[$selectedVetItem.image]] </div> /* ── RARITY ── */ <div class="vet-item-rarity"> <<if $selectedVetItem.rarity === "Common">> <span class="rarity-badge rarity-common">Common</span> <<elseif $selectedVetItem.rarity === "Uncommon">> <span class="rarity-badge rarity-uncommon">Uncommon</span> <<elseif $selectedVetItem.rarity === "Rare">> <span class="rarity-badge rarity-rare">Rare</span> <</if>> </div> /* ── PRICE ── */ <div class="vet-item-price">💰 $selectedVetItem.basePrice g</div> /* ── DESCRIPTION ── */ <div class="vet-item-desc">$selectedVetItem.description</div> /* ── QUANTITY ── */ <div class="vet-item-qty-row"> <<link "−" "VetItemDetail">> <<if !$vetPurchaseQuantity>><<set $vetPurchaseQuantity = 1>><</if>> <<if $vetPurchaseQuantity > 1>><<set $vetPurchaseQuantity -= 1>><</if>> <</link>> <span class="vet-item-qty"> <<if !$vetPurchaseQuantity>><<set $vetPurchaseQuantity = 1>><</if>> $vetPurchaseQuantity </span> <<link "+" "VetItemDetail">> <<if !$vetPurchaseQuantity>><<set $vetPurchaseQuantity = 1>><</if>> <<set $vetPurchaseQuantity += 1>> <</link>> </div> /* ── PURCHASE ── */ <<set _totalCost = $selectedVetItem.basePrice * $vetPurchaseQuantity>> <div class="vet-item-total">Total: 💰 _totalCost g</div> <<if $money >= _totalCost>> <<link "✅ Buy Now" "VetServiceComplete">> <<set $money -= _totalCost>> <<set $inventory[$selectedVetItem.id] += $vetPurchaseQuantity>> <<set $vetServiceComplete = "Purchased " + $vetPurchaseQuantity + "x " + $selectedVetItem.name + "!">> <<set $vetPurchaseQuantity = 1>> <</link>> <<else>> <div class="vet-action-disabled">Not enough money!</div> <</if>> </div> </div> <<run $(document).one(':passageend', function() { $('#modal-bg').html(State.variables.modalBg); })>> <</nobr>>
<<nobr>> <<widget "creatureName">> <<set _creature to $args[0]>> <<if _creature.petName>> <<print _creature.petName>> <<else>> <<print _creature.name>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "showAchievements">> <span id="achievement-wrapper"> <<if $achievementQueue.length > 0>> <<set _achievement to $achievementQueue[0]>> <div class="achievement-modal"> <div class="achievement-content"> <h2>🏆 Achievement Unlocked!</h2> <<addXP 10>> <h3>_achievement.name</h3> <p>_achievement.description</p> <<if _achievement.rewards>> <div class="achievement-rewards"> <strong>Rewards:</strong><br> <<if _achievement.rewards.money>> +_achievement.rewards.money coins<br> <</if>> <<if _achievement.rewards.eggSlots>> +_achievement.rewards.eggSlots egg slots<br> <</if>> <<if _achievement.rewards.items>> <<for _itemId, _qty range _achievement.rewards.items>> +_qty <<print setup.items[_itemId].name>><br> <</for>> <</if>> </div> <</if>> <<link "Claim">> /* Grant money */ <<if _achievement.rewards && _achievement.rewards.money>> <<set $money += _achievement.rewards.money>> <</if>> /* Grant egg slots */ <<if _achievement.rewards && _achievement.rewards.eggSlots>> <<set $eggSlots += _achievement.rewards.eggSlots>> <</if>> /* Grant items */ <<if _achievement.rewards && _achievement.rewards.items>> <<for _itemId, _qty range _achievement.rewards.items>> <<if !$inventory[_itemId]>> <<set $inventory[_itemId] = 0>> <</if>> <<set $inventory[_itemId] += _qty>> <</for>> <</if>> /*base XP given per achievement*/ <<run $achievementQueue.shift()>> <<replace "#achievement-wrapper">><<showAchievements>><</replace>> <</link>> </div> </div> <</if>> </span> <</widget>> <<widget "generateRequest">> <<set _difficulty = _args[0]>> <<set _now = Date.now()>> <<set _MS = setup.MS_PER_DAY>> <<set _newRequest = { id: random(100000, 999999), difficulty: _difficulty, createdTime: _now }>> /* Expiration in ms */ <<if _difficulty === "simple">> <<set _newRequest.expiresTime = _now + (_MS * 32 / 24)>> <<elseif _difficulty === "medium">> <<set _newRequest.expiresTime = _now + (_MS * 64 / 24)>> <<else>> <<set _newRequest.expiresTime = _now + (_MS * 80 / 24)>> <</if>> /* Get available species not already in active requests */ <<set _usedSpecies = $requests.map(function(r) { return r.species; })>> <<set _availableSpecies = Object.keys(setup.creatureTemplates).filter(function(s) { return !_usedSpecies.includes(s); })>> <<if _availableSpecies.length === 0>> <<set _availableSpecies = Object.keys(setup.creatureTemplates)>> <</if>> <<set _species = _availableSpecies.random()>> <<set _template = setup.creatureTemplates[_species]>> <<set _newRequest.species = _species>> <<set _newRequest.rarity = _template.rarity>> <<set _possibleColors = setup.getCreaturePossibleColors(_species)>> <<if _difficulty === "simple">> <<set _newRequest.rarity = "Common">> <<set _commonSpecies = _availableSpecies.filter(function(s) { return setup.creatureTemplates[s].rarity === "Common"; })>> <<if _commonSpecies.length > 0>> <<set _species = _commonSpecies.random()>> <<set _template = setup.creatureTemplates[_species]>> <<set _newRequest.species = _species>> <<set _possibleColors = setup.getCreaturePossibleColors(_species)>> <</if>> <<set _newRequest.requiredTraits = { color: _possibleColors.random() }>> <<set _newRequest.reward = random(300, 400)>> <<set _newRequest.xp to 10>> <<elseif _difficulty === "medium">> <<set _allowedRarities = ["Common", "Uncommon"]>> <<set _mediumSpecies = _availableSpecies.filter(function(s) { return _allowedRarities.includes(setup.creatureTemplates[s].rarity); })>> <<if _mediumSpecies.length > 0>> <<set _species = _mediumSpecies.random()>> <<set _template = setup.creatureTemplates[_species]>> <<set _newRequest.species = _species>> <<set _newRequest.rarity = _template.rarity>> <<set _possibleColors = setup.getCreaturePossibleColors(_species)>> <</if>> <<set _traitCount = either(1, 2)>> <<set _possibleTraits = ["color", "size", "pattern"]>> <<set _selectedTraits = []>> <<for _i = 0; _i < _traitCount; _i++>> <<set _available = _possibleTraits.filter(function(t) { return !_selectedTraits.includes(t); })>> <<run _selectedTraits.push(_available.random())>> <</for>> <<set _newRequest.requiredTraits = {}>> <<for _i, _trait range _selectedTraits>> <<if _trait === "color">><<set _newRequest.requiredTraits.color = _possibleColors.random()>> <<elseif _trait === "size">><<set _newRequest.requiredTraits.size = _template.possibleSizes.random()>> <<elseif _trait === "pattern">><<set _newRequest.requiredTraits.pattern = _template.possiblePatterns.random()>> <</if>> <</for>> <<set _newRequest.reward = random(500, 800)>> <<set _newRequest.xp to 25>> <<else>> <<set _newRequest.requiredTraits = { color: _possibleColors.random(), size: _template.possibleSizes.random(), pattern: _template.possiblePatterns.random() }>> <<set _newRequest.reward = random(900, 1200)>> <<set _newRequest.xp to 50>> <</if>> <<run $requests.push(_newRequest)>> <</widget>> <<widget "checkExpiredRequests">> <<set _now = Date.now()>> <<set _expiredIndexes = []>> <<for _i = 0; _i < $requests.length; _i++>> <<if $requests[_i].expiresTime <= _now>> <<run _expiredIndexes.push(_i)>> <</if>> <</for>> <<for _i = _expiredIndexes.length - 1; _i >= 0; _i-->> <<run $requests.deleteAt(_expiredIndexes[_i])>> <</for>> <</widget>> <<widget "tickRequests">> <<checkExpiredRequests>> <<set _now = Date.now()>> /* First-time initialization: give one request immediately */ <<if !$requestsInitialized>> <<set $requestsInitialized = true>> <<generateRequest "simple">> <<set $nextRequestTime = _now + 21600000>>/* 6 hours in ms */ <<elseif _now >= $nextRequestTime && $requests.length < 3>> <<if $requestsUnlocked.complex && either(true, false)>> <<generateRequest "complex">> <<elseif $requestsUnlocked.medium && either(true, false, false)>> <<generateRequest "medium">> <<else>> <<generateRequest "simple">> <</if>> <<set $nextRequestTime = _now + 21600000>> <</if>> <</widget>> /* checkCreatureMatch is unchanged */ <<widget "checkCreatureMatch">> <<set _creature = _args[0]>> <<set _request = _args[1]>> <<set _matches = true>> <<if _creature.name !== _request.species>><<set _matches = false>><</if>> <<if _creature.stage !== "adult">><<set _matches = false>><</if>> <<if _matches && _request.requiredTraits.color>> <<if _creature.displayTraits.color !== _request.requiredTraits.color>><<set _matches = false>><</if>> <</if>> <<if _matches && _request.requiredTraits.size>> <<if _creature.displayTraits.size !== _request.requiredTraits.size>><<set _matches = false>><</if>> <</if>> <<if _matches && _request.requiredTraits.pattern>> <<if _creature.displayTraits.pattern !== _request.requiredTraits.pattern>><<set _matches = false>><</if>> <</if>> <<set _matchResult = _matches>> <</widget>> <<widget "addXP">> <<if $playerXP gte 2050>> <<else>> <<set $playerXP += _args[0]>> <<run setup.checkRankUp()>> <</if>> <</widget>> <<widget "refresh">> <<silently>> <<replace ".passage">> <<include `passage()`>> <</replace>> <</silently>> <</widget>> <<widget "smBuildSession">> <<set _pool to $smQuestionPool.filter(function(q) { return !$smLastSession.includes(q.id); })>> <<if _pool.length lt 5>> <<set _pool to $smQuestionPool>> <</if>> <<set _shuffled to _pool.shuffle()>> <<set $smSessionQuestions to _shuffled.slice(0, 5)>> <<set $smCurrentQ to 0>> <<set $gigScore to 0>> <<set $gigLastResult to "">> <</widget>> <</nobr>>
<<nobr>> /* ── Constants ── */ <<set setup.MS_PER_DAY = 86400000>> /* ── updateSeason ── */ <<widget "updateSeason">> <<set _month = new Date().getMonth()>> <<if _month >= 2 && _month <= 4>> <<set $currentSeason = "Spring">> <<elseif _month >= 5 && _month <= 7>> <<set $currentSeason = "Summer">> <<elseif _month >= 8 && _month <= 10>> <<set $currentSeason = "Fall">> <<else>> <<set $currentSeason = "Winter">> <</if>> <</widget>> /* ── updateFarm ── called on load and whenever you need to sync state ── */ <<widget "updateFarm">> <<set _now = Date.now()>> <<set _MS = setup.MS_PER_DAY>> <<set _droughtLimit = ($currentSeason === "Summer") ? _MS : (_MS * 2)>> <<for _i = 0; _i < $farmPlots.length; _i++>> <<set _plot = $farmPlots[_i]>> <<if _plot.crop !== null>> <<set _cropData = setup.crops[_plot.crop]>> <<set _msSinceWatered = _now - _plot.lastWatered>> <<if _msSinceWatered >= _droughtLimit>> <<set _plot.crop = null>> <<set _plot.plantedDay = 0>> <<set _plot.lastWatered = 0>> <<set _plot.growthStage = 0>> <<set _plot._dyingNotified = false>> <<set _plot._harvestNotified = false>> <<else>> <<set _winterMod = ($currentSeason === "Winter") ? 1.5 : 1>> <<set _growthDurationMs = Math.ceil(_cropData.growthDays * _winterMod * _MS)>> <<set _plot.growthStage = Math.min(100, Math.floor(((_now - _plot.plantedDay) / _growthDurationMs) * 100))>> <</if>> <<if $isBadWeather>> <<set _plot.lastWatered = _now>> <</if>> <</if>> <</for>> <</widget>> /* ── plantCrop _plotId _cropType ── */ <<widget "plantCrop">> <<set _plotId = _args[0]>> <<set _cropType = _args[1]>> <<set _seedId = _cropType + "Seeds">> <<if $inventory[_seedId] > 0>> <<set _now = Date.now()>> <<set $farmPlots[_plotId].crop = _cropType>> <<set $farmPlots[_plotId].plantedDay = _now>> <<set $farmPlots[_plotId].lastWatered = _now>> <<set $farmPlots[_plotId].growthStage = 0>> <<set $farmPlots[_plotId].justPlanted = true>> <<set $farmPlots[_plotId]._dyingNotified = false>> <<set $farmPlots[_plotId]._harvestNotified = false>> <<set $inventory[_seedId] -= 1>> <</if>> <</widget>> /* ── waterCrop _plotId ── */ <<widget "waterCrop">> <<set _plotId = _args[0]>> <<if $farmPlots[_plotId].crop !== null>> <<set $farmPlots[_plotId].lastWatered = Date.now()>> <<set $farmPlots[_plotId].justPlanted = false>> <<set $farmPlots[_plotId]._dyingNotified = false>> <</if>> <</widget>> /* ── waterAllCrops ── */ <<widget "waterAllCrops">> <<set _now = Date.now()>> <<set _wateredCount = 0>> <<for _i = 0; _i < $farmPlots.length; _i++>> <<if $farmPlots[_i].crop !== null>> <<set $farmPlots[_i].lastWatered = _now>> <<set $farmPlots[_i].justPlanted = false>> <<set $farmPlots[_i]._dyingNotified = false>> <<set _wateredCount += 1>> <</if>> <</for>> <<if _wateredCount > 0>> <<set $farmMessage = "Watered " + _wateredCount + " crop(s)!">> <<else>> <<set $farmMessage = "All crops are already watered!">> <</if>> <</widget>> /* ── harvestCrop _plotId ── */ <<widget "harvestCrop">> <<set _plotId = _args[0]>> <<set _plot = $farmPlots[_plotId]>> <<if _plot.crop !== null && _plot.growthStage >= 100>> <<set _cropData = setup.crops[_plot.crop]>> <<set _seasonKey = $currentSeason.toLowerCase()>> <<set _harvestAmount = _cropData.harvestAmount[_seasonKey]>> <<if $inventory[_plot.crop] !== undefined>> <<set $inventory[_plot.crop] += _harvestAmount>> <<else>> <<set $inventory[_plot.crop] = _harvestAmount>> <</if>> <<set _harvestedCrop = _cropData.name>> <<set _harvestedAmount = _harvestAmount>> <<set _plot.crop = null>> <<set _plot.plantedDay = 0>> <<set _plot.lastWatered = 0>> <<set _plot.growthStage = 0>> <<set _plot._dyingNotified = false>> <<set _plot._harvestNotified = false>> <</if>> <</widget>> <</nobr>>
<<set setup.creatureTemplates = { "Caervira": { name: "Caervira", species: "Caervira", type: "Forest", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/yXpe86N.png", medium: "https://i.imgur.com/FucIucz.png", large: "https://i.imgur.com/idrBn5N.png" }, babySpriteSheets: { small: "https://i.imgur.com/pydO04l.png", medium: "https://i.imgur.com/4UqukjT.png", large: "https://i.imgur.com/5uYBnT2.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/MplrXpf.png", medium: "https://i.imgur.com/DCzjsyX.png", large: "https://i.imgur.com/nhlXUEV.png" }, babySpriteSheets: { small: "https://i.imgur.com/QfcTgsT.png", medium: "https://i.imgur.com/HW3YS0k.png", large: "https://i.imgur.com/DQIc15J.png" } } }, spriteColumns: { brown_solid: 0, brown_stripes: 1, brown_spots: 2, beige_solid: 3, beige_stripes: 4, beige_spots: 5, tan_solid: 6, tan_stripes: 7, tan_spots: 8, black_solid: 9, black_stripes: 10, black_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, red_solid: 15, red_stripes: 16, red_spots: 17, pink_solid: 18, blue_solid: 19 }, babySpriteColumns: { brown: 0, beige: 1, tan: 2, black: 3, white: 4, red: 5, pink: 6, blue: 7 }, silhouettes: { male: { small: "https://i.imgur.com/t1cAS7i.png", medium: "https://i.imgur.com/6DSx0ry.png", large: "https://i.imgur.com/Ty82fML.png" }, female: { small: "https://i.imgur.com/fjc46km.png", medium: "https://i.imgur.com/IafnMvC.png", large: "https://i.imgur.com/gAIuPFE.png" } }, rarity: "Common", flavorText: "Gentle and curious, Caevira wander forest trails collecting small treasures. They’re friendly companions who bond quickly with patient breeders.", careCur: 80, careMax: 100, affectionCur: 30, affectionMax: 100, fertility: 50, speciesColors: ["tan", "red"], exoticColors: ["pink", "blue"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["brown", "red", "tan", "beige", "white", "black"], patternDominance: ["solid", "stripes", "spots"] }, "Noctulo": { name: "Noctulo", species: "Noctulo", type: "Forest", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/8OvuQMh.png", medium: "https://i.imgur.com/dZVVa0L.png", large: "https://i.imgur.com/pT9Uj61.png", }, babySpriteSheets: { small: "https://i.imgur.com/P7fDV7A.png", medium: "https://i.imgur.com/CLqbqVh.png", large: "https://i.imgur.com/0ofXVjE.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/ImfBWXf.png", medium: "https://i.imgur.com/u9OggXA.png", large: "https://i.imgur.com/hUSXvUt.png", }, babySpriteSheets: { small: "https://i.imgur.com/m65Qwr4.png", medium: "https://i.imgur.com/7xit7pB.png", large: "https://i.imgur.com/xF4hpk3.png" } } }, spriteColumns: { tan_solid: 0, tan_stripes: 1, tan_spots: 2, beige_solid: 3, beige_stripes: 4, beige_spots: 5, brown_solid: 6, brown_stripes: 7, brown_spots: 8, white_solid: 9, white_stripes: 10, white_spots: 11, black_solid: 12, black_stripes: 13, black_spots: 14, gray_solid: 15, gray_stripes: 16, gray_spots: 17, forest_solid: 18, spring_solid: 19 }, babySpriteColumns: { tan: 0, beige: 1, brown: 2, white: 3, black: 4, gray: 5, forest: 6, spring: 7 }, silhouettes: { male: { small: "https://i.imgur.com/0S78F1Y.png", medium: "https://i.imgur.com/0S78F1Y.png", large: "https://i.imgur.com/0S78F1Y.png" }, female: { small: "https://i.imgur.com/IPuRhBk.png", medium: "https://i.imgur.com/IPuRhBk.png", large: "https://i.imgur.com/IPuRhBk.png" } }, rarity: "Common", flavorText: "Noctulo are lively dusk-dwellers who enjoy fluttering between treetops. They’re playful companions that brighten any woodland outing.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["tan", "gray"], exoticColors: ["forest", "spring"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["tan", "beige", "brown", "white", "gray", "black"], patternDominance: ["stripes", "solid", "spots"] }, "Urcanis": { name: "Urcanis", species: "Urcanis", type: "Mountain", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/apl3QRM.png", medium: "https://i.imgur.com/Hhi5YDw.png", large: "https://i.imgur.com/6r9ABY5.png" }, babySpriteSheets: { small: "https://i.imgur.com/amNHIes.png", medium: "https://i.imgur.com/d7Rqecc.png", large: "https://i.imgur.com/35hTs0U.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/q4BeqIK.png", medium: "https://i.imgur.com/aSCKiJn.png", large: "https://i.imgur.com/V0BOXFl.png" }, babySpriteSheets: { small: "https://i.imgur.com/oeH3QnI.png", medium: "https://i.imgur.com/a2gHwDu.png", large: "https://i.imgur.com/VcTx6cL.png" } } }, spriteColumns: { brown_solid: 0, brown_stripes: 1, brown_spots: 2, orange_solid: 3, orange_stripes: 4, orange_spots: 5, beige_solid: 6, beige_stripes: 7, beige_spots: 8, black_solid: 9, black_stripes: 10, black_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, gray_solid: 15, gray_stripes: 16, gray_spots: 17, candy_solid: 18, molten_solid: 19 }, babySpriteColumns: { brown: 0, orange: 1, beige: 2, black: 3, white: 4, gray: 5, candy: 6, molten: 7 }, silhouettes: { male: { small: "https://i.imgur.com/EZBxgeS.png", medium: "https://i.imgur.com/EZBxgeS.png", large: "https://i.imgur.com/EZBxgeS.png" }, female: { small: "https://i.imgur.com/1MLYzzC.png", medium: "https://i.imgur.com/1MLYzzC.png", large: "https://i.imgur.com/1MLYzzC.png" } }, rarity: "Common", flavorText: "A sturdy critter with a mellow spirit, Urcanis enjoy lounging on warm rocks. They’re dependable helpers who adapt easily to any home.", careCur: 80, careMax: 100, affectionMax: 100, affectionCur: 30, fertility: 50, speciesColors: ["orange", "gray"], exoticColors: ["candy", "molten"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["brown", "black", "beige", "gray", "orange", "white"], patternDominance: ["solid", "spots", "stripes"] }, "Capranis": { name: "Capranis", species: "Capranis", type: "Mountain", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/J26VLMF.png", medium: "https://i.imgur.com/0ZGN13I.png", large: "https://i.imgur.com/BcfeuRA.png" }, babySpriteSheets: { small: "https://i.imgur.com/P0TA2uD.png", medium: "https://i.imgur.com/YB4KPT1.png", large: "https://i.imgur.com/nPykLUf.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/Ljy9Q4i.png", medium: "https://i.imgur.com/hMamBbg.png", large: "https://i.imgur.com/0O0G2Qt.png", }, babySpriteSheets: { small: "https://i.imgur.com/UJ4GCzX.png", medium: "https://i.imgur.com/CKanp7o.png", large: "https://i.imgur.com/lx4gjX6.png" } } }, spriteColumns: { red_solid: 0, red_stripes: 1, red_spots: 2, orange_solid: 3, orange_stripes: 4, orange_spots: 5, brown_solid: 6, brown_stripes: 7, brown_spots: 8, beige_solid: 9, beige_stripes: 10, beige_spots: 11, black_solid: 12, black_stripes: 13, black_spots: 14, white_solid: 15, white_stripes: 16, white_spots: 17, retro_solid: 18, beach_solid: 19 }, babySpriteColumns: { red: 0, orange: 1, brown: 2, beige: 3, black: 4, white: 5, retro: 6, beach: 7 }, silhouettes: { male: { small: "https://i.imgur.com/FTHrZuo.png", medium: "https://i.imgur.com/FTHrZuo.png", large: "https://i.imgur.com/FTHrZuo.png" }, female: { small: "https://i.imgur.com/uMhgOh5.png", medium: "https://i.imgur.com/uMhgOh5.png", large: "https://i.imgur.com/uMhgOh5.png" } }, rarity: "Uncommon", flavorText: "Playful and sure-footed, Capranis love bounding across rugged terrain. Their upbeat nature makes them a favorite among new collectors.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["red", "orange"], exoticColors: ["retro", "beach"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["red", "orange", "brown", "beige", "black", "white"], patternDominance: ["stripes", "spots", "solid"] }, "Chiroden": { name: "Chiroden", species: "Chiroden", type: "Mountain", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/FK1q2Qj.png", medium: "https://i.imgur.com/uxClqZD.png", large: "https://i.imgur.com/jv8Ioxo.png" }, babySpriteSheets: { small: "https://i.imgur.com/oI7StKK.png", medium: "https://i.imgur.com/SOd25an.png", large: "https://i.imgur.com/Y3hpgsf.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/ZxDqgHp.png", medium: "https://i.imgur.com/aT2EMn0.png", large: "https://i.imgur.com/Qc1z53m.png" }, babySpriteSheets: { small: "https://i.imgur.com/Bv2Hehb.png", medium: "https://i.imgur.com/66Jstyo.png", large: "https://i.imgur.com/dXlu6NI.png" } } }, spriteColumns: { purple_solid: 0, purple_stripes: 1, purple_spots: 2, blue_solid: 3, blue_stripes: 4, blue_spots: 5, black_solid: 6, black_stripes: 7, black_spots: 8, brown_solid: 9, brown_stripes: 10, brown_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, beige_solid: 15, beige_stripes: 16, beige_spots: 17, red_solid: 18, neon_solid: 19 }, babySpriteColumns: { purple: 0, blue: 1, black: 2, brown: 3, white: 4, beige: 5, red: 6, neon: 7 }, silhouettes: { male: { small: "https://i.imgur.com/8hSvsi2.png", medium: "https://i.imgur.com/8hSvsi2.png", large: "https://i.imgur.com/8hSvsi2.png" }, female: { small: "https://i.imgur.com/83gZ8ug.png", medium: "https://i.imgur.com/83gZ8ug.png", large: "https://i.imgur.com/83gZ8ug.png" } }, rarity: "Common", flavorText: "Quiet and clever, Chiroden prefer cozy caves and twilight skies. Despite their shyness, they form strong connections with kind caretakers.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["purple", "blue"], exoticColors: ["red", "neon"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["purple", "blue", "black", "brown", "beige", "white"], patternDominance: ["solid", "spots", "stripes"] }, "Cetium": { name: "Cetium", species: "Cetium", type: "Aether", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/tTdTWij.png", medium: "https://i.imgur.com/3qd4Ryf.png", large: "https://i.imgur.com/ZLLoDyz.png" }, babySpriteSheets: { small: "https://i.imgur.com/oa2dKac.png", medium: "https://i.imgur.com/8byD2yR.png", large: "https://i.imgur.com/LYTYp35.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/o0cpko8.png", medium: "https://i.imgur.com/DnNrVCi.png", large: "https://i.imgur.com/n0q0U64.png" }, babySpriteSheets: { small: "https://i.imgur.com/oa2dKac.png", medium: "https://i.imgur.com/8byD2yR.png", large: "https://i.imgur.com/LYTYp35.png" } } }, spriteColumns: { purple_solid: 0, purple_stripes: 1, purple_spots: 2, blue_solid: 3, blue_stripes: 4, blue_spots: 5, black_solid: 6, black_stripes: 7, black_spots: 8, brown_solid: 9, brown_stripes: 10, brown_spots: 11, beige_solid: 12, beige_stripes: 13, beige_spots: 14, white_solid: 15, white_stripes: 16, white_spots: 17, y2k_solid: 18, mystical_solid: 19 }, babySpriteColumns: { purple: 0, blue: 1, black: 2, brown: 3, white: 4, y2k: 6, mystical: 7, }, silhouettes: { male: { small: "", medium: "", large: "" }, female: { small: "", medium: "", large: "" } }, rarity: "Rare", flavorText: "Mysterious and serene, Cetium drift gracefully through open spaces as if guided by unseen winds. They’re said to bring clarity and calm to any nest.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["purple", "blue"], exoticColors: ["y2k", "mystical"], possiblePatterns: ["solid", "stripes", "spots"], possibleSizes: ["small", "medium", "large"], colorDominance: ["purple", "blue", "black", "brown", "beige", "white"], patternDominance: ["solid", "stripes", "spots"] }, "Zerdasus": { name: "Zerdasus", species: "Zerdasus", type: "Desert", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/hxXJXFo.png", medium: "https://i.imgur.com/0kk3Xfn.png", large: "https://i.imgur.com/cjY8JdJ.png" }, babySpriteSheets: { small: "https://i.imgur.com/4Ofupg7.png", medium: "https://i.imgur.com/nj8kM5p.png", large: "https://i.imgur.com/cOkloBM.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/rBViGiI.png", medium: "https://i.imgur.com/uYB19Im.png", large: "https://i.imgur.com/EQ8m0dd.png" }, babySpriteSheets: { small: "https://i.imgur.com/4Ofupg7.png", medium: "https://i.imgur.com/nj8kM5p.png", large: "https://i.imgur.com/cOkloBM.png" } } }, spriteColumns: { orange_solid: 0, orange_stripes: 1, orange_spots: 2, beige_solid: 3, beige_stripes: 4, beige_spots: 5, black_solid: 6, black_stripes: 7, black_spots: 8, brown_solid: 9, brown_stripes: 10, brown_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, yellow_solid: 15, yellow_stripes: 16, yellow_spots: 17, rose_solid: 18, retro_solid: 19 }, babySpriteColumns: { orange: 0, beige: 1, black: 2, brown: 3, white: 4, yellow: 5, rose: 6, retro: 7 }, silhouettes: { male: { small: "https://i.imgur.com/dZmR2fm.png", medium: "https://i.imgur.com/dZmR2fm.png", large: "https://i.imgur.com/dZmR2fm.png" }, female: { small: "https://i.imgur.com/dZmR2fm.png", medium: "https://i.imgur.com/dZmR2fm.png", large: "https://i.imgur.com/dZmR2fm.png" } }, rarity: "Uncommon", flavorText: "Energetic and alert, Zerdasus thrive under the hot sun and enjoy exploring hidden dunes. They learn tricks quickly and love showing off.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["orange", "yellow"], exoticColors: ["rose", "retro"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["orange", "yellow", "beige", "brown", "black", "white"], patternDominance: ["stripes", "spots", "solid"] }, "Dipothio": { name: "Dipothio", species: "Dipothio", type: "Desert", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/cWVb31C.png", medium: "https://i.imgur.com/QBFtEbY.png", large: "https://i.imgur.com/rZrTHcM.png" }, babySpriteSheets: { small: "https://i.imgur.com/ccx5aGX.png", medium: "https://i.imgur.com/iebpKkm.png", large: "https://i.imgur.com/GEP2tFG.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/cWVb31C.png", medium: "https://i.imgur.com/QBFtEbY.png", large: "https://i.imgur.com/rZrTHcM.png" }, babySpriteSheets: { small: "https://i.imgur.com/ccx5aGX.png", medium: "https://i.imgur.com/iebpKkm.png", large: "https://i.imgur.com/GEP2tFG.png" } } }, spriteColumns: { brown_solid: 0, brown_stripes: 1, brown_spots: 2, beige_solid: 3, beige_stripes: 4, beige_spots: 5, tan_solid: 6, tan_stripes: 7, tan_spots: 8, orange_solid: 9, orange_stripes: 10, orange_spots: 11, black_solid: 12, black_stripes: 13, black_spots: 14, white_solid: 15, white_stripes: 16, white_spots: 17, pink_solid: 18, blue_solid: 19 }, babySpriteColumns: { brown: 0, beige: 1, tan: 2, orange: 3, black: 4, white: 5, pink: 6, blue: 7 }, silhouettes: { male: { small: "", medium: "", large: "" }, female: { small: "", medium: "", large: "" } }, rarity: "Uncommon", flavorText: "A patient burrow-dweller, Dipothio spends much of its time resting in cool sands. Once befriended, it becomes a loyal and steady partner.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["tan", "orange"], exoticColors: ["pink", "blue"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["brown", "tan", "beige", "black", "white"], patternDominance: ["solid", "spots", "stripes"] }, "Amphorea": { name: "Amphorea", species: "Amphorea", type: "River", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/uObhmQc.png", medium: "https://i.imgur.com/koJmfO0.png", large: "https://i.imgur.com/ms8HVQO.png" }, babySpriteSheets: { small: "https://i.imgur.com/8nY07ko.png", medium: "https://i.imgur.com/uYNOhzC.png", large: "https://i.imgur.com/355AMLq.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/d78zjoD.png", medium: "https://i.imgur.com/TQHC7CE.png", large: "https://i.imgur.com/AO6dVOL.png" }, babySpriteSheets: { small: "https://i.imgur.com/8nY07ko.png", medium: "https://i.imgur.com/uYNOhzC.png", large: "https://i.imgur.com/355AMLq.png" } } }, spriteColumns: { purple_solid: 0, purple_stripes: 1, purple_spots: 2, blue_solid: 3, blue_stripes: 4, blue_spots: 5, brown_solid: 6, brown_stripes: 7, brown_spots: 8, black_solid: 9, black_stripes: 10, black_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, beige_solid: 15, beige_stripes: 16, beige_spots: 17, seafoam_solid: 18, sunset_solid: 19 }, babySpriteColumns: { purple: 0, blue: 1, brown: 2, black: 3, white: 4, beige: 5, seafoam: 6, sunset: 7 }, silhouettes: { male: { small: "https://i.imgur.com/7sv1qod.png", medium: "https://i.imgur.com/7sv1qod.png", large: "https://i.imgur.com/7sv1qod.png" }, female: { small: "", medium: "", large: "" } }, rarity: "Uncommon", flavorText: "Amphorea adore splashing through streams and collecting smooth stones. They’re gentle souls who get along with almost every other critter.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["purple", "blue"], exoticColors: ["seafoam", "sunset"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["purple", "blue", "white", "beige", "brown", "black"], patternDominance: ["spots", "solid", "stripes"] }, "Tiadylus": { name: "Tiadylus", species: "Tiadylus", type: "Jungle", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/hNrdaE8.png", medium: "https://i.imgur.com/E1JffAw.png", large: "https://i.imgur.com/2cmKbfZ.png" }, babySpriteSheets: { small: "https://i.imgur.com/RzJ0X3N.png", medium: "https://i.imgur.com/TYQ9ZGQ.png", large: "https://i.imgur.com/91SSYc5.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/hNrdaE8.png", medium: "https://i.imgur.com/E1JffAw.png", large: "https://i.imgur.com/2cmKbfZ.png" }, babySpriteSheets: { small: "https://i.imgur.com/RzJ0X3N.png", medium: "https://i.imgur.com/TYQ9ZGQ.png", large: "https://i.imgur.com/91SSYc5.png" } } }, spriteColumns: { orange_solid: 0, orange_stripes: 1, orange_spots: 2, brown_solid: 3, brown_stripes: 4, brown_spots: 5, tan_solid: 6, tan_stripes: 7, tan_spots: 8, black_solid: 9, black_stripes: 10, black_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, beige_solid: 15, beige_stripes: 16, beige_spots: 17, blue_solid: 18, pink_solid: 19 }, babySpriteColumns: { orange: 0, brown: 1, tan: 2, black: 3, white: 4, beige: 5, blue: 6, pink: 7 }, silhouettes: { male: { small: "", medium: "", large: "" }, female: { small: "", medium: "", large: "" } }, rarity: "Uncommon", flavorText: "Stealthy and observant, Tiadylus move silently through dense foliage. They appreciate calm environments and reward attentive keepers with deep trust.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["tan", "orange"], exoticColors: ["blue", "pink"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["orange", "brown", "tan", "beige", "black", "white"], patternDominance: ["stripes", "spots", "solid"] }, "Falciphus": { name: "Falciphus", species: "Falciphus", type: "Volcano", staminaCur: 3, staminaMax: 3, avatars: { male: { patternSpriteSheets: { small: "https://i.imgur.com/rwppa8a.png", medium: "https://i.imgur.com/dRz3hys.png", large: "https://i.imgur.com/lfaNQXE.png" }, babySpriteSheets: { small: "https://i.imgur.com/IZBEduB.png", medium: "https://i.imgur.com/AcOjhr9.png", large: "https://i.imgur.com/IMCI9Pz.png" } }, female: { patternSpriteSheets: { small: "https://i.imgur.com/iVOP93S.png", medium: "https://i.imgur.com/qVOZc57.png", large: "https://i.imgur.com/lABZTmn.png" }, babySpriteSheets: { small: "https://i.imgur.com/IZBEduB.png", medium: "https://i.imgur.com/AcOjhr9.png", large: "https://i.imgur.com/IMCI9Pz.png" } } }, spriteColumns: { gray_solid: 0, gray_stripes: 1, gray_spots: 2, blue_solid: 3, blue_stripes: 4, blue_spots: 5, brown_solid: 6, brown_stripes: 7, brown_spots: 8, black_solid: 9, black_stripes: 10, black_spots: 11, white_solid: 12, white_stripes: 13, white_spots: 14, beige_solid: 15, beige_stripes: 16, beige_spots: 17, pine_solid: 18, lavender_solid: 19 }, babySpriteColumns: { gray: 0, blue: 1, brown: 2, black: 3, white: 4, beige: 5, pine: 6, lavender: 7 }, silhouettes: { male: { small: "https://i.imgur.com/0jF9R9c.png", medium: "https://i.imgur.com/0jF9R9c.png", large: "https://i.imgur.com/0jF9R9c.png" }, female: { small: "https://i.imgur.com/JE8qGgU.png", medium: "https://i.imgur.com/JE8qGgU.png", large: "https://i.imgur.com/JE8qGgU.png" } }, rarity: "Rare", flavorText: "Bold and spirited, Falciphus thrive near heat and challenge. Their fierce determination makes them exceptional partners for experienced breeders.", careMax: 100, affectionMax: 100, careCur: 80, affectionCur: 30, fertility: 50, speciesColors: ["gray", "blue"], exoticColors: ["pine", "lavender"], possiblePatterns: ["solid", "spots", "stripes"], possibleSizes: ["small", "medium", "large"], colorDominance: ["gray", "blue", "brown", "black", "white", "beige"], patternDominance: ["solid", "spots", "stripes"] } }>> <<set $playerCreatures to []>> <<set $deadCreatures to []>> <<set $discoveredCombos to []>> <<set $featuredCreatureIndex to -1>> <<set $vetServiceComplete = "">> <<set $money = 3000>> <<set $maxEggSlots to 6>> <<set $eggSlotUpgradeCost to 200>> <<set $creaturesForSale to []>> <<set $pendingSales to []>> <<set $departedCreatures to []>> <<set $escapedCreatures to []>> <<set $lastEscapeCheckDate to "">> <<set $playerName to "">> <<set $playerPronouns to "">> <<set $breedingLicense to false>> <<set $playerBirthday to "">> <<set $currentCreature to []>> <<set $activeSpecies to "">> <<set $lineageTab to "ancestors">> <<set _randomCreature1 to Object.values(setup.creatureTemplates).filter(function(c) { return c.rarity === "Common"; }).random()>> <<set $creature1 to clone(_randomCreature1)>> <<set $creature1.id to random(100000, 999999)>> <<set $creature1.gender to "Male">> <<set _possibleColors to setup.getCreaturePossibleColors(_randomCreature1.name)>> <<set $creature1.genes = { color: [_possibleColors.random(), _possibleColors.random()], pattern: [_randomCreature1.possiblePatterns.random(), _randomCreature1.possiblePatterns.random()], size: [_randomCreature1.possibleSizes.random(), _randomCreature1.possibleSizes.random()], species: [_randomCreature1.species, _randomCreature1.species] }>> <<set $creature1.displayTraits to { color: getDisplayedTrait($creature1.genes.color[0], $creature1.genes.color[1], _randomCreature1.colorDominance), pattern: getDisplayedTrait($creature1.genes.pattern[0], $creature1.genes.pattern[1], _randomCreature1.patternDominance), size: getBlendedSize($creature1.genes.size[0], $creature1.genes.size[1], _randomCreature1.possibleSizes) }>> <<run finalizeDisplayTraits($creature1)>> <<if $creature1.displayTraits.size === "large">> <<set $creature1.hungerCur to 100>> <<set $creature1.hungerMax to 120>> <<elseif $creature1.displayTraits.size === "medium">> <<set $creature1.hungerCur to 80>> <<set $creature1.hungerMax to 100>> <<else>> <<set $creature1.hungerCur to 60>> <<set $creature1.hungerMax to 80>> <</if>> <<set $creature1.stage to "adult">> <<run $creature1.bornAt = Date.now() - (random(1, 3) * 24 * 60 * 60 * 1000)>> <<set $creature1.elderAt to []>> <<set $creature1.hadSurgery = false>> <<set $creature1.geneticTestingDone = false>> <<set $creature1.generation to 1>> <<set $creature1.fedCount to 0>> <<set $creature1.caredCount to 0>> <<set $creature1.mimikin to null>> <<run $creature1.fertilityOffset = Date.now() - Math.floor(Math.random() * getFertilityCycleLength(_randomCreature1.rarity))>> <<run $creature1.lastAffectionBonus = Date.now()>> <<run $creature1.lastHungerDrain = Date.now()>> <<run $creature1.lastCareDrain = Date.now()>> <<run $creature1.lastStaminaRegen = Date.now()>> <<run $creature1.wasHappy = false>> <<run $creature1.immortal = false>> <<run $playerCreatures.push($creature1)>> <<run setup.recordCombo($creature1)>> <<set _randomCreature2 to Object.values(setup.creatureTemplates).filter(function(c) { return c.rarity === "Common" && c.name !== _randomCreature1.name; }).random()>> <<set $creature2 to clone(_randomCreature2)>> <<set $creature2.id to random(100000, 999999)>> <<set $creature2.gender to "Female">> <<set _possibleColors to setup.getCreaturePossibleColors(_randomCreature2.name)>> <<set $creature2.genes to { color: [_possibleColors.random(), _possibleColors.random()], pattern: [_randomCreature2.possiblePatterns.random(), _randomCreature2.possiblePatterns.random()], size: [_randomCreature2.possibleSizes.random(), _randomCreature2.possibleSizes.random()], species: [_randomCreature2.species, _randomCreature2.species] }>> <<set $creature2.displayTraits to { color: getDisplayedTrait($creature2.genes.color[0], $creature2.genes.color[1], _randomCreature2.colorDominance), pattern: getDisplayedTrait($creature2.genes.pattern[0], $creature2.genes.pattern[1], _randomCreature2.patternDominance), size: getBlendedSize($creature2.genes.size[0], $creature2.genes.size[1], _randomCreature2.possibleSizes) }>> <<run finalizeDisplayTraits($creature2)>> <<if $creature2.displayTraits.size === "large">> <<set $creature2.hungerCur to 100>> <<set $creature2.hungerMax to 120>> <<elseif $creature2.displayTraits.size === "medium">> <<set $creature2.hungerCur to 80>> <<set $creature2.hungerMax to 100>> <<else>> <<set $creature2.hungerCur to 60>> <<set $creature2.hungerMax to 80>> <</if>> <<set $creature2.stage to "adult">> <<run $creature2.bornAt = Date.now() - (random(1, 3) * 24 * 60 * 60 * 1000)>> <<set $creature2.elderAt to null>> <<set $creature2.hadSurgery to false>> <<set $creature2.geneticTestingDone to false>> <<set $creature2.generation to 1>> <<set $creature2.fedCount to 0>> <<set $creature2.caredCount to 0>> <<set $creature2.mimikin to null>> <<run $creature2.fertilityOffset = Date.now() - Math.floor(Math.random() * getFertilityCycleLength(_randomCreature2.rarity))>> <<run $creature2.lastAffectionBonus = Date.now()>> <<run $creature2.lastHungerDrain = Date.now()>> <<run $creature2.lastCareDrain = Date.now()>> <<run $creature2.lastStaminaRegen = Date.now()>> <<run $creature2.wasHappy = false>> <<run $creature2.immortal = false>> <<run $playerCreatures.push($creature2)>> <<run setup.recordCombo($creature2)>> <<set setup.typeBackgrounds = { "Forest": "https://i.imgur.com/l71nP47.png", "Mountain": "https://i.imgur.com/IVG7p2r.png", "Aether": "https://i.imgur.com/CwL6Z10.png", "Desert": "https://i.imgur.com/t4RBZ12.png", "River": "https://i.imgur.com/py0HA0y.png", "Jungle": "https://i.imgur.com/eZ4BKzj.png", "Volcano": "https://i.imgur.com/32mLz2B.jpeg" }>> <<set setup.typeEmojis = { "Forest": "🌲", "Mountain": "🏔️", "Desert": "🏜️", "River": "💧", "Jungle": "🌴", "Volcano": "🌋", "Aether": "✨" }>> <<set $lastTickTime to Date.now()>>
<<set $shopCategory = "Creatures">> <<set $shopCart = []>> <<set $purchaseSummary = []>> <<set setup.items = { /* CREATURES */ "Caervira": { id: "Caervira", name: "Caervira", category: "Creatures", basePrice: 300, monsterType: "Forest", image: "https://i.imgur.com/hGZvv72.png", description: "A Forest-type creature.", rarity: "Common", isConsumable: false, requiresMonster: false }, "Noctulo": { id: "Noctulo", name: "Noctulo", category: "Creatures", basePrice: 400, monsterType: "Forest", image: "https://i.imgur.com/xdzXb9E.png", description: "A Forest-type creature.", rarity: "Common", isConsumable: false, requiresMonster: false }, "Urcanis": { id: "Urcanis", name: "Urcanis", category: "Creatures", basePrice: 300, monsterType: "Mountain", image: "https://i.imgur.com/BGOQ8yG.png", description: "A Mountain-type creature.", rarity: "Common", isConsumable: false, requiresMonster: false }, "Capranis": { id: "Capranis", name: "Capranis", category: "Creatures", basePrice: 400, monsterType: "Mountain", image: "https://i.imgur.com/ikHKmrY.png", description: "A Mountain-type monster.", rarity: "Uncommon", isConsumable: false, requiresMonster: false }, "Chiroden": { id: "Chiroden", name: "Chiroden", category: "Creatures", basePrice: 400, monsterType: "Mountain", image: "https://i.imgur.com/ajbba7R.png", description: "A Mountain-type creature.", rarity: "Common", isConsumable: false, requiresMonster: false }, "Amphorea": { id: "Amphorea", name: "Amphorea", category: "Creatures", basePrice: 500, monsterType: "River", image: "https://i.imgur.com/GJ2zDiQ.png", description: "A flowing River-type creature.", rarity: "Uncommon", isConsumable: false, requiresMonster: false }, "Dipothio": { id: "Dipothio", name: "Dipothio", category: "Creatures", basePrice: 600, monsterType: "Desert", image: "https://i.imgur.com/s4KCFbw.png", description: "A jumpy Desert-type creature.", rarity: "Uncommon", isConsumable: false, requiresMonster: false }, "Zerdasus": { id: "Zerdasus", name: "Zerdasus", category: "Creatures", basePrice: 700, monsterType: "Desert", image: "https://i.imgur.com/8nAxAdp.png", description: "A fierce Desert-type creature.", rarity: "Uncommon", isConsumable: false, requiresMonster: false }, "Tiadylus": { id: "Tiadylus", name: "Tiadylus", category: "Creatures", basePrice: 800, monsterType: "Jungle", image: "https://i.imgur.com/SLJvRY0.png", description: "A wild Jungle-type creature.", rarity: "Uncommon", isConsumable: false, requiresMonster: false }, "Falciphus": { id: "Falciphus", name: "Falciphus", category: "Creatures", basePrice: 900, monsterType: "Volcano", image: "https://i.imgur.com/HTWg2ff.png", description: "A wild creature from the Volcanic regions.", rarity: "Rare", isConsumable: false, requiresMonster: false }, "Cetium": { id: "Cetium", name: "Cetium", category: "Creatures", basePrice: 1000, monsterType: "Aether", image: "https://i.imgur.com/9R1wmwh.png", description: "A mystical Aether-type creature.", rarity: "Rare", isConsumable: false, requiresMonster: false }, /* MEDICINE */ "CarePotion": { id: "CarePotion", name: "Care Potion", category: "Consumables", basePrice: 40, baseSell: 20, image: "https://i.imgur.com/Danc2bM.png", description: "A beverage-type medicine for restoring 20 care points.", rarity: "Common", isConsumable: true, requiresMonster: true }, "EnergyDrink": { id: "EnergyDrink", name: "Energy Drink", category: "Consumables", basePrice: 60, baseSell: 30, image: "https://i.imgur.com/hUsByXM.png", description: "A beverage for raising energy levels. Restores 30 Physical Energy Points to a creature.", rarity: "Common", isConsumable: true, requiresMonster: true }, /* FOOD */ "CreatureChow": { id: "CreatureChow", name: "Creature Chow", category: "Consumables", basePrice: 20, baseSell: 10, image: "https://i.imgur.com/vbQR804.png", description: "Basic nutritious food for creatures.", rarity: "Common", isConsumable: false, requiresMonster: false }, /* ITEMS */ "ScrollFertility": { id: "ScrollFertility", name: "Scroll of Fertility", category: "Items", basePrice: 100, baseSell: 50, image: "https://i.imgur.com/mWbF7UO.png", description: "An ancient scroll that grants fertility to a creature for one day.", rarity: "Common", isConsumable: true, requiresMonster: true }, "ScrollImmortality": { id: "ScrollImmortality", name: "Scroll of Immortality", category: "Items", rarity: "Legendary", basePrice: 9999, baseSell: 5000, image: "", description: "When used on a creature, they will no longer age.", isConsumable: true, requiresMonster: true }, "WheatSeeds": { id: "WheatSeeds", name: "Wheat Seeds", category: "Seeds", basePrice: 20, baseSell: 10, description: "Plant these to grow wheat. Takes 7 days to mature.", rarity: "Common", isConsumable: true }, "CornSeeds": { id: "CornSeeds", name: "Corn Seeds", category: "Seeds", basePrice: 25, baseSell: 12, description: "Plant these to grow corn. Takes 9 days to mature.", rarity: "Common", isConsumable: true }, "PotatoSeeds": { id: "PotatoSeeds", name: "Potato Seeds", category: "Seeds", basePrice: 15, baseSell: 7, description: "Plant these to grow potatoes. Takes 6 days to mature.", rarity: "Common", isConsumable: true }, "CarrotSeeds": { id: "CarrotSeeds", name: "Carrot Seeds", category: "Seeds", basePrice: 15, baseSell: 7, description: "Plant these to grow carrots. Takes 5 days to mature.", rarity: "Common", isConsumable: true }, "TomatoSeeds": { id: "TomatoSeeds", name: "Tomato Seeds", category: "Seeds", basePrice: 30, baseSell: 15, description: "Plant these to grow tomatoes. Takes 8 days to mature.", rarity: "Common", isConsumable: true }, "OnionSeeds": { id: "OnionSeeds", name: "Onion Seeds", category: "Seeds", basePrice: 20, baseSell: 10, description: "Plant these to grow onions. Takes 6 days to mature.", rarity: "Common", isConsumable: true }, "LettuceSeeds": { id: "LettuceSeeds", name: "Lettuce Seeds", category: "Seeds", basePrice: 10, baseSell: 5, description: "Plant these to grow lettuce. Takes 4 days to mature.", rarity: "Common", isConsumable: true }, "RiceSeeds": { id: "RiceSeeds", name: "Rice Seeds", category: "Seeds", basePrice: 35, baseSell: 16, description: "Plant these to grow rice. Takes 10 days to mature.", rarity: "Common", isConsumable: true }, "GarlicSeeds": { id: "GarlicSeeds", name: "Garlic Cloves", category: "Seeds", basePrice: 25, baseSell: 12, description: "Plant these to grow garlic. Takes 7 days to mature.", rarity: "Common", isConsumable: true }, "BasilSeeds": { id: "BasilSeeds", name: "Basil Seeds", category: "Seeds", basePrice: 20, baseSell: 10, description: "Plant these to grow basil. Takes 5 days to mature.", rarity: "Common", isConsumable: true }, "ParsleySeeds": { id: "ParsleySeeds", name: "Parsley Seeds", category: "Seeds", basePrice: 20, baseSell: 10, description: "Plant these to grow parsley. Takes 5 days to mature.", rarity: "Common", isConsumable: true }, "CilantroSeeds": { id: "CilantroSeeds", name: "Cilantro Seeds", category: "Seeds", basePrice: 18, baseSell: 9, description: "Plant these to grow cilantro. Takes 4 days to mature.", rarity: "Common", isConsumable: true }, /* Also add these crop items to inventory initialization */ "Wheat": { id: "Wheat", name: "Wheat", category: "Ingredients", basePrice: 15, baseSell: 7, description: "Freshly harvested wheat.", rarity: "Common", isConsumable: false }, "Corn": { id: "Corn", name: "Corn", category: "Ingredients", basePrice: 20, baseSell: 10, description: "Fresh corn on the cob.", rarity: "Common", isConsumable: false }, "Potato": { id: "Potato", name: "Potato", category: "Ingredients", basePrice: 12, baseSell: 6, description: "Hearty potatoes.", rarity: "Common", isConsumable: false }, "Carrot": { id: "Carrot", name: "Carrot", category: "Ingredients", basePrice: 12, baseSell: 6, description: "Crunchy orange carrots.", rarity: "Common", isConsumable: false }, "Lettuce": { id: "Lettuce", name: "Lettuce", category: "Ingredients", basePrice: 8, baseSell: 4, description: "Crisp green lettuce.", rarity: "Common", isConsumable: false }, "Garlic": { id: "Garlic", name: "Garlic", category: "Ingredients", basePrice: 18, baseSell: 9, description: "Aromatic garlic bulbs.", rarity: "Common", isConsumable: false }, "Basil": { id: "Basil", name: "Basil", category: "Ingredients", basePrice: 15, baseSell: 7, description: "Fresh basil leaves.", rarity: "Common", isConsumable: false }, "Parsley": { id: "Parsley", name: "Parsley", category: "Ingredients", basePrice: 15, baseSell: 7, description: "Fresh parsley sprigs.", rarity: "Common", isConsumable: false }, "Cilantro": { id: "Cilantro", name: "Cilantro", category: "Ingredients", basePrice: 14, baseSell: 7, description: "Fresh cilantro leaves.", rarity: "Common", isConsumable: false }, /* INGREDIENTS */ "CookingOil": { id: "CookingOil", name: "Cooking Oil", category: "Ingredients", basePrice: 10, baseSell: 5, image: "https://i.imgur.com/O6GHV5T.png", description: "", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Herbs": { id: "Herbs", name: "Herbs", category: "Ingredients", basePrice: 10, baseSell: 5, image: "https://i.imgur.com/QEiQ9VM.png", description: "", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Berries": { id: "Berries", name: "Berries", category: "Ingredients", basePrice: 10, baseSell: 5, image: "https://i.imgur.com/QRTqK6k.png", description: "", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Flour": { id: "Flour", name: "Flour", category: "Ingredients", basePrice: 10, baseSell: 5, image: "https://i.imgur.com/8NRXksc.png", description: "", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Sugar": { id: "Sugar", name: "Sugar", category: "Ingredients", basePrice: 10, baseSell: 5, image: "https://i.imgur.com/RcfFLB3.png", description: "", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Tomato": { id: "Tomato", name: "Tomato", category: "Ingredients", basePrice: 15, baseSell: 7, image: "https://i.imgur.com/GVaobZY.png", description: "", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Onion": { id: "Onion", name: "Onion", category: "Ingredients", basePrice: 15, baseSell: 7, image: "https://i.imgur.com/OzoqVn5.png", description: "", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Rice": { id: "Rice", name: "Rice", category: "Ingredients", basePrice: 15, baseSell: 7, image: "https://i.imgur.com/JgQxOBk.png", description: "", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Pasta": { id: "Pasta", name: "Pasta", category: "Ingredients", basePrice: 15, baseSell: 7, image: "https://i.imgur.com/AxyU3FN.png", description: "", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Coconut": { id: "Coconut", name: "Coconut", category: "Ingredients", basePrice: 25, baseSell: 12, image: "https://i.imgur.com/4edSX7o.png", description: "", rarity: "Rare", isConsumable: false, requiresMonster: false, isAccessory: false, }, "PickledVeggies": { id: "PickledVeggies", name: "Pickled Vegetables", category: "Ingredients", basePrice: 25, baseSell: 12, image: "https://i.imgur.com/Iq2obyU.png", description: "", rarity: "Rare", isConsumable: false, requiresMonster: false, isAccessory: false, }, "Saffron": { id: "Saffron", name: "Saffron", category: "Ingredients", basePrice: 25, baseSell: 12, image: "https://i.imgur.com/qgXonoi.png", description: "", rarity: "Rare", isConsumable: false, requiresMonster: false, isAccessory: false, }, /* FISH (no shop purchase) */ "YellowPerch": { id: "YellowPerch", name: "Yellow Perch", baseSell: 10, image: "https://i.imgur.com/L0Ja1ae.png", description: "A small schooling fish prized for its sweet, delicate flavor.", rarity: "Common", category: "Fish", isConsumable: false, requiresMonster: false, isAccessory: false }, "LargemouthBass": { id: "LargemouthBass", name: "Largemouth Bass", baseSell: 12, image: "https://i.imgur.com/PzZxJ5x.png", description: "An aggressive predator that ambushes prey from cover.", category: "Fish", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false }, "Pike": { id: "Pike", name: "Pike", baseSell: 14, image: "https://i.imgur.com/ptsd4Y8.png", description: "A fierce ambush hunter known for explosive strikes.", category: "Fish", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "RainbowTrout": { id: "RainbowTrout", name: "Rainbow Trout", baseSell: 16, image: "https://i.imgur.com/4XIjQhb.png", description: "A colorful, acrobatic fish that puts up a spirited fight.", category: "Fish", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, }, "LakeTrout": { id: "LakeTrout", name: "Lake Trout", baseSell: 18, image: "https://i.imgur.com/yH4mZBf.png", description: "A deep-dwelling coldwater predator that grows to impressive sizes.", category: "Fish", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false }, "BullTrout": { id: "BullTrout", name: "Bull Trout", baseSell: 20, image: "https://i.imgur.com/SzKhYRn.png", description: "An uncommon char species that inhabits pristine, icy waters.", category: "Fish", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false }, "Muskellunge": { id: "Muskellunge", name: "Muskellunge", baseSell: 24, image: "https://i.imgur.com/LV8qXaR.png", description: "The apex predator known as the \"fish of 10,000 casts.\"", category: "Fish", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false }, "Sturgeon": { id: "Sturgeon", name: "Sturgeon", baseSell: 40, image: "https://i.imgur.com/uWP3Zpp.png", description: "An ancient bottom-feeder that can live for decades and reach massive sizes.", category: "Fish", rarity: "Rare", isConsumable: false, requiresMonster: false, isAccessory: false }, "Sheefish": { id: "Sheefish", name: "Sheefish", baseSell: 50, image: "https://i.imgur.com/ma31AO2.png", description: "A powerful fighter prized for its strength and excellent flavor.", category: "Fish", rarity: "Rare", isConsumable: false, requiresMonster: false, isAccessory: false }, "MoonglowPerch": { id: "MoonglowPerch", name: "Moonglow Perch", baseSell: 30, image: "https://i.imgur.com/L0Ja1ae.png", description: "A small perch that glimmers with an ethereal silver light under moonbeams.", rarity: "Common", category: "Fish", isConsumable: false, requiresMonster: false, isAccessory: false, nightVariant: true }, "TwilightBass": { id: "TwilightBass", name: "Twilight Bass", baseSell: 32, image: "https://i.imgur.com/PzZxJ5x.png", description: "An aggressive hunter that emerges from the depths when darkness falls.", category: "Fish", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, nightVariant: true }, "ShadowPike": { id: "ShadowPike", name: "Shadow Pike", baseSell: 35, image: "https://i.imgur.com/ptsd4Y8.png", description: "A dark predator that blends seamlessly with the night waters.", category: "Fish", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, nightVariant: true }, "StardustTrout": { id: "StardustTrout", name: "Stardust Trout", baseSell: 38, image: "https://i.imgur.com/4XIjQhb.png", description: "A magical trout whose scales sparkle like stars reflected on water.", category: "Fish", rarity: "Common", isConsumable: false, requiresMonster: false, isAccessory: false, nightVariant: true }, "AbyssalTrout": { id: "AbyssalTrout", baseSell: 40, name: "Abyssal Trout", image: "https://i.imgur.com/yH4mZBf.png", description: "A deep-dwelling trout that only rises to feed under cover of darkness.", category: "Fish", rarity: "Uncommon", isConsumable: false, requiresMonster: false, isAccessory: false, nightVariant: true }, "FishingRod": { id: "FishingRod", name: "Basic Fishing Rod", category: "Fishing", basePrice: 300, image: "https://i.imgur.com/Nz0angj.png", description: "A basic fishing rod. Unlocks fishing at the lake.", rarity: "Common", isConsumable: false, isAccessory: false }, "Lantern": { id: "Lantern", name: "Lantern", category: "Fishing", basePrice: 250, image: "https://i.imgur.com/wZ33WBh.png", description: "A lantern for lighting the dark. Unlocks fishing at night.", rarity: "Common", isConsumable: false, isAccessory: false }, "WormBait": { id: "WormBait", name: "Worm Bait", category: "Fishing", basePrice: 25, baseSell: 12, image: "https://i.imgur.com/Z7iQbYS.png", description: "Earth worms used as bait for fishing.", rarity: "Common", isConsumable: false, isAccessory: false } }>> /* Player inventory */ <<if !$inventory>> <<set $inventory = { CarePotion: 0, EnergyDrink: 0, CreatureChow: 0, ScrollFertility: 0, ScrollImmortality: 0, WheatSeeds: 0, CornSeeds: 0, PotatoSeeds: 0, CarrotSeeds: 0, TomatoSeeds: 0, OnionSeeds: 0, LettuceSeeds: 0, RiceSeeds: 0, GarlicSeeds: 0, BasilSeeds: 0, ParsleySeeds: 0, CilantroSeeds: 0, Wheat: 0, Corn: 0, Potato: 0, Carrot: 0, Lettuce: 0, Garlic: 0, Basil: 0, Parsley: 0, Cilantro: 0, CookingOil: 0, Herbs: 0, Berries: 0, Flour: 0, Sugar: 0, Tomato: 0, Onion: 0, Rice: 0, Pasta: 0, Coconut: 0, PickledVeggies: 0, Saffron: 0, FishingRod: 0, WormBait: 0, Lantern: 0, YellowPerch: 0, LargemouthBass: 0, Pike: 0, RainbowTrout: 0, LakeTrout: 0, BullTrout: 0, Muskellunge: 0, Sturgeon: 0, Sheefish: 0, MoonglowPerch: 0, TwilightBass: 0, ShadowPike: 0, StardustTrout: 0, AbyssalTrout: 0 }>> <</if>> <<set setup.creatureFoods = ["CreatureChow"]>> <<set $featuredItemId = "">> <<set $featuredDayKey = "">>
<<set $maxFreelancingAttempts to 2>> <<set $freelancingAttempts to 0>> <<set $activeGig to "">> <<set $photosCompleted to 0>> <<set $photosMoney to 0>> <<set $products to [ { name: "Artisan Coffee Mug", correct: "detail", reason: "Handcrafted items need close-ups to show texture and craftsmanship", emoji: "☕" }, { name: "Luxury Perfume Bottle", correct: "detail", reason: "High-end fragrance bottles require detail shots to showcase premium materials", emoji: "🧴" }, { name: "Vintage Leather Jacket", correct: "context", reason: "Clothing needs full product shots to show fit and style", emoji: "🧥" }, { name: "Gourmet Pizza", correct: "lifestyle", reason: "Food looks most appealing in lifestyle shots showing it ready to eat", emoji: "🍕" }, { name: "Yoga Mat", correct: "context", reason: "Exercise equipment needs full shots to show size and proportions", emoji: "🧘♀️" }, { name: "Wedding Ring Set", correct: "detail", reason: "Jewelry requires macro detail shots to show sparkle and craftsmanship", emoji: "💍" }, { name: "Smartphone Case", correct: "context", reason: "Phone accessories need full context to show how they fit the device", emoji: "📱" }, { name: "Artisan Soap Bar", correct: "flatlay", reason: "Bath products work well in styled flat lay compositions", emoji: "🧼" }, { name: "Fresh Salad Bowl", correct: "lifestyle", reason: "Fresh food looks best in natural eating contexts", emoji: "🥗" }, { name: "Designer Sunglasses", correct: "detail", reason: "Luxury accessories need detail shots to highlight premium features", emoji: "🕶️" }, { name: "Hiking Boots", correct: "context", reason: "Footwear needs full product shots to show design and build quality", emoji: "🥾" }, { name: "Scented Candle", correct: "flatlay", reason: "Home decor items work beautifully in styled flat lay arrangements", emoji: "🕯️" }, { name: "Craft Beer Bottle", correct: "context", reason: "Beverages need full shots to show label design and bottle shape", emoji: "🍺" }, { name: "Handmade Necklace", correct: "detail", reason: "Handcrafted jewelry requires close-ups to show intricate details", emoji: "📿" }, { name: "Gourmet Burger", correct: "lifestyle", reason: "Food photography works best showing the item ready to be enjoyed", emoji: "🍔" } ]>> <<set $gigScore to 0>> <<set $gigLastResult to "">> <<set $smCurrentQ to -1>> <<set $smSessionQuestions to []>> <<set $smLastSession to []>> <<set $smQuestionPool to [ { id: "b1", type: "brand", prompt: "Someone handed you this post without a label. Which brand does it belong to?", post: "Rise and shine! ☀️ Our lavender honey scones are fresh out of the oven. Stop by before they're gone — we bake in small batches for a reason. 🍯🌿", options: [ "🐾 Critter Crunch Co. — bold snacks for adventurous eaters", "🌸 The Mossy Kettle — a cozy cottage bakery & tea room", "⚡ Zap & Go — an energy drink startup for gamers" ], correct: 1, win: "That warm, artisan tone is pure Mossy Kettle.", lose: "That cozy, handmade voice belongs to The Mossy Kettle." }, { id: "b2", type: "brand", prompt: "This post came in unlabelled. Which client wrote it?", post: "New flavor. No warning. Just vibes. ⚡🍓 Strawberry Static is here and it HITS. Grab yours before it's gone. #ZapAndGo", options: [ "🌸 The Mossy Kettle — a cozy cottage bakery & tea room", "🌿 Fernwood Apothecary — a calm, botanical wellness brand", "⚡ Zap & Go — an energy drink startup for gamers" ], correct: 2, win: "High energy, punchy, and hype-forward — that's Zap & Go through and through.", lose: "That bold, fast-paced voice belongs to Zap & Go." }, { id: "b3", type: "brand", prompt: "Which brand does this post belong to?", post: "A little lavender. A little rest. 🌿 Our new Sleep Well tincture is here — crafted slowly, with intention. Your evenings deserve this.", options: [ "⚡ Zap & Go — an energy drink startup for gamers", "🌿 Fernwood Apothecary — a calm, botanical wellness brand", "🐾 Critter Crunch Co. — bold snacks for adventurous eaters" ], correct: 1, win: "Gentle, intentional, and grounded — that's Fernwood Apothecary's voice exactly.", lose: "That calm, botanical tone belongs to Fernwood Apothecary." }, { id: "s1", type: "schedule", prompt: "Zap & Go wants to post this. When do you schedule it?", post: "Your 3PM slump just met its match. ⚡ New Citrus Storm flavor — crack one open and get back in the game. #ZapAndGo #GameFuel", options: [ "7:00 AM", "2:45 PM", "11:00 PM" ], correct: 1, win: "Post it right before the slump and the timing writes itself.", lose: "The post references the 3PM slump — 2:45 PM is the sweet spot." }, { id: "s2", type: "schedule", prompt: "Critter Crunch Co. is running a weekend flash sale. When do you post the announcement?", post: "🚨 FLASH SALE — this weekend only! 40% off ALL crunch packs. Stock up before your faves sell out. 🐾🔥", options: [ "Thursday evening", "Saturday afternoon", "Monday morning" ], correct: 0, win: "Thursday evening builds anticipation and gives followers the whole weekend to act.", lose: "Saturday afternoon is too late to build buzz. Thursday evening is the move." }, { id: "s3", type: "schedule", prompt: "The Mossy Kettle wants to promote their Sunday brunch menu. When's the best time to post?", post: "Sunday mornings were made for this. 🥐☕ Our brunch menu is back — soft eggs, fresh pastries, and a seat by the window waiting for you.", options: [ "Friday evening", "Sunday noon", "Monday morning" ], correct: 0, win: "Friday evening catches people right as they're deciding how to spend their weekend.", lose: "Friday evening is the sweet spot — people are actively making weekend plans then." }, { id: "c1", type: "caption", prompt: "The Mossy Kettle is posting a photo of their new mushroom & brie toastie. Which caption fits their brand best?", post: null, options: [ `"MUSHROOM BRIE TOASTIE IS HERE. EAT IT."`, `"Rainy day? We've got you. 🍄🧀 Warm, melty, and made for slow mornings. Come find your corner. ☕"`, `"New toastie available now. Check our bio for hours."` ], correct: 1, win: "Cozy, warm, and inviting — that's the Mossy Kettle down to a crumb.", lose: "Option A is too aggressive and C is too flat. The Mossy Kettle speaks in warmth — that's Option B." }, { id: "c2", type: "caption", prompt: "Critter Crunch Co. is posting a photo of their new limited-edition Scorched Pepper pack. Which caption fits?", post: null, options: [ `"Introducing our new Scorched Pepper flavor. Available in stores now."`, `"Some like it hot. 🌶️🔥 Scorched Pepper is here and it does not apologize. Grab a bag if you dare. #CritterCrunch"`, `"A new flavor has arrived! We hope you enjoy it. 🐾"` ], correct: 1, win: "Bold, daring, and a little bit of a challenge — that's pure Critter Crunch Co. energy.", lose: "Critter Crunch Co. is loud and proud. Option B matches that energy — A and C are both too flat." }, { id: "c3", type: "caption", prompt: "Fernwood Apothecary is posting about a restock of their best-selling rose facial mist. Which caption fits their brand?", post: null, options: [ `"ROSE MIST IS BACK. GET IT NOW BEFORE IT SELLS OUT AGAIN 🌹🌹🌹"`, `"She's back. 🌹 Our rose facial mist has been restocked — a gentle reset for your skin and your day. Take your time with it."`, `"Rose mist restocked. Limited quantities. Link in bio."` ], correct: 1, win: "Soft, unhurried, and intentional — Fernwood Apothecary never rushes, and neither does that caption.", lose: "Fernwood Apothecary's voice is calm and considered. Option B is the only one that fits." }, { id: "o1", type: "offbrand", prompt: "Your intern queued up three posts for Zap & Go. One of them is completely off-brand. Which one doesn't belong?", post: null, options: [ `"Monday got you? We got you. ⚡ Crack a Zap & Go and make it count. #FuelUp"`, `"Nothing beats a quiet evening with chamomile tea and a good book. 🌙🍵 #SlowLiving"`, `"New flavor dropped and it SLAPS. 🍋⚡ Citrus Storm is here. Grab yours. #ZapAndGo"` ], correct: 1, win: "Slow living and chamomile tea have no business in Zap & Go's feed. Good catch.", lose: "Option B — quiet evenings and chamomile tea — is completely off-brand for an energy drink." }, { id: "o2", type: "offbrand", prompt: "Three posts were drafted for The Mossy Kettle's queue. One doesn't fit their brand at all. Which one is it?", post: null, options: [ `"New week, new pastries. 🥐 Come in and see what's fresh — we'd love to have you."`, `"NO DAYS OFF. GRIND HARDER. SLEEP WHEN YOU'RE DEAD. ☕💀 #MondayMotivation"`, `"Quiet afternoon light, a warm cup, and nowhere to be. 🌿 This is what we made this place for."` ], correct: 1, win: "Hustle culture and The Mossy Kettle are not a match. Their whole brand is rest, not grind.", lose: "Option B — hustle culture slogans — is wildly off-brand for a cozy tea room." }, { id: "o3", type: "offbrand", prompt: "Someone queued three posts for Fernwood Apothecary. One of them doesn't belong. Which is it?", post: null, options: [ `"Breathe in. Breathe out. 🌿 Our new eucalyptus balm is here — slow down and let it work."`, `"CRUNCH TIME. 💥 Our new formula hits HARD and FAST. No more waiting around. #GetResults"`, `"A small ritual for a calmer evening. 🕯️ Light a candle, pour a bath, add a few drops of our lavender oil."` ], correct: 1, win: "Fast, aggressive, and results-obsessed — that's the opposite of Fernwood Apothecary's voice.", lose: "Option B — pushy, aggressive, and rushed — has no place in Fernwood Apothecary's calm, intentional feed." } ]>> <<set $logoScore to 0>> <<set $logosMoney to 0>> <<set $logosCompleted to 0>> <<set $clients to [ { id: 0, name: "The Mossy Kettle", type: "café", vibe: "cozy and quaint", hint: "The Mossy Kettle is all about comfort and coziness in a sophisticated style.", shape: ["round", "organic", "cloud"], colorPalette: ["sage green, beige, warm brown", "green, dark brown, gold"], fontStyle: ["script", "handwriting", "calligraphy"], incorrectShape: "The Mossy Kettle prefers natural shapes with no sharp edges.", correctShape: "This perfectly captures the Mossy Kettle's soft vibes.", incorrectColorPalette: "A color palette inspired by the Mossy Kettle should be natural and inviting.", correctColorPalette: "These colors really encapsulate the Mossy Kettle's organic and warm tones.", incorrectFontStyle: "Some fonts are too playful or energetic for the Mossy Kettle's refined style.", correctFontStyle: "This style says the Mossy Kettle without being too bold or brash." }, { id: 1, name: "Fernwood Apothecary", type: "self-care", vibe: "calm and mindful", hint: "Fernwood Apothecary is looking for a logo that matches their regal serenity.", shape: ["ornate", "flowing", "spirals"], colorPalette: ["plum, silver, white"], fontStyle: ["script", "calligraphy", "formal"], incorrectShape: "When thinking of a shape for Fernwood Apothecary, think elegance and intricacy.", correctShape: "A perfect shape design for Fernwood Apothecary's luxurious ambiance.", incorrectColorPalette: "Fernwood Apothecary's color palette should be subtle and stylish.", correctColorPalette: "This is an excellent choice for Fernwood Apothecary. Each color is understated yet distinguished togther.", incorrectFontStyle: "The font style of Fernwood Apothecary should flow and give the viewer a sense of tranquility.", correctFontStyle: "This is the correct font style to envoke peace and mindfulness." }, { id: 2, name: "Zap and Go", type: "energy drinks", vibe: "amped and friendly", hint: "A logo for Zap and Go should match its raring to go energy.", shape: ["zigzag", "triangle", "dynamic"], colorPalette: ["lime green, bright blue, yellow"], fontStyle: ["futuristic", "bold"], incorrectShape: "Some shapes are too soft or round to convey Zap and Go's energetic nature.", correctShape: "The bold edges of this shape makes it an exceptional choice.", incorrectColorPalette: "Color palettes that are sophisticated or warm are not what Zap and Go is looking for.", correctColorPalette: "These colors pop and attract the viewer's eye, which is perfect for Zap and Go.", incorrectFontStyle: "Zap and Go's font style should be clear and draw attention. Avoid intricate or light font styles.", correctFontStyle: "Legible and striking. Just what Zap and Go is looking for." }, { id: 3, name: "Critter Crunch Co.", type: "pet food", vibe: "bold and adventurous", hint: "A logo for Critter Crunch Co. should match its modern-edge and daring vibe.", shape: ["geometric", "abstract", "minimalist"], colorPalette: ["navy blue, teal, orange"], fontStyle: ["sans-serif", "modern"], incorrectShape: "Think of shapes that emphasize simplicity, or feature contemporary elements that alter real world visuals.", correctShape: "Simple, clean, or conceptual shapes are a must for Critter Crunch Co.'s logo's foundation.", incorrectColorPalette: "Avoid palettes that are too mellow or high contrast.", correctColorPalette: "A palette that is stylish and eye-catching is the right balance for Critter Crunch Co.", incorrectFontStyle: "A font style for Critter Crunch Co. should be understated and clearly legible.", correctFontStyle: "A subtle choice, but effective and easy to read. Perfect for Critter Crunch Co.'s modern and avant-garde approach." }, { id: 4, name: "Moonroot Nursery", type: "plant shop", vibe: "delicate and whimsical", hint: "Moonroot Nursery is looking for a logo that matches its soft and dreamy aura.", shape: ["stars", "organic", "cloud"], colorPalette: ["purple, green, golden yellow", "orange, periwinkle, teal"], fontStyle: ["handwriting", "bubble", "brush"], incorrectShape: "Be wary of intricate designs or shapes with sharp edges.", correctShape: "This is exactly what Moonroot Nursery is looking for to capture its soft playfulness.", incorrectColorPalette: "Avoid palettes that are too earthy or bold.", correctColorPalette: "A perfect quirky combo for a plant shop like Moonroot Nursery.", incorrectFontStyle: "Formal or striking font styles distract from the intended vibe. Try something softer or rounded.", correctFontStyle: "A playful choice that's not too bold or distracting, just what Moonroot Nursery is looking for." }, { id: 5, name: "Patchwork Systems", type: "tech repair", vibe: "playful and inventive", hint: "Patchwork Systems requires a logo that showcases their passion to have fun with their work.", shape: ["geometric", "polygons", "trapezoids"], colorPalette: ["slate gray, peacock blue, red orange", "white, sky blue, indigo"], fontStyle: ["monospaced", "retro", "bold"], incorrectShape: "Avoid organic, flowing shapes. Instead, aim for something with edges.", correctShape: "This type of shape is perfect for Patchwork Systems and their playful edge.", incorrectColorPalette: "Think of complementary colors that might go on a quilt. Avoid palettes that may be better suited for another company.", correctColorPalette: "A great choice for Patchwork Systems' handmade, inventive vibe.", incorrectFontStyle: "Nothing too formal or simple; Patchwork Systems wants loud and clear.", correctFontStyle: "This is a great font style for grabbing attention while maintaining the company's vibe." }, ]>> <<set $allShapes to ["round", "organic", "cloud", "ornate", "flowing", "spirals", "zigzag", "triangle", "dynamic", "geometric", "abstract", "minimalist", "stars", "polygons", "trapezoids"]>> <<set $allColorPalettes to ["sage green, beige, warm brown", "green, dark brown, gold", "plum, silver, white", "lime green, bright blue, yellow", "navy blue, teal, orange", "purple, green, golden yellow", "orange, periwinkle, teal", "slate gray, peacock blue, red orange", "white, sky blue, indigo"]>> <<set $allFontStyles to ["script", "handwriting", "calligraphy", "futuristic", "bold", "sans-serif", "modern", "formal", "bubble", "brush", "retro", "monospaced"]>>
/* Request Stuff */ <<set $requests = []>> <<set $completedRequests = { simple: 0, medium: 0, complex: 0 }>> <<set $requestsUnlocked = { simple: true, medium: false, complex: false }>> <<set $nextRequestTime = Date.now()>> <<set $requestsInitialized = false>> <<set $lastRequestRefreshTime = 0>> <<set $achievements to { /* Feeding chain */ firstFeed: { id: "firstFeed", name: "Bon Appétit", description: "Feed a creature for the first time", hint: "Your creatures need food to stay healthy", unlocked: false, rewards: { money: 50, items: { CreatureChow: 3 } } }, feedTenTimes: { id: "feedTenTimes", name: "Dedicated Feeder", description: "Feed your creatures 10 times total", hint: "Keep those critters fed!", unlocked: false, progress: 0, goal: 10, rewards: { money: 100, items: { CreatureChow: 5 } } }, feedFiftyTimes: { id: "feedFiftyTimes", name: "Full Bellies", description: "Feed your creatures 50 times total", hint: "A well-fed critter is a happy critter", unlocked: false, progress: 0, goal: 50, rewards: { money: 250, items: { CreatureChow: 10 } } }, feedHundredTimes: { id: "feedHundredTimes", name: "Master Feeder", description: "Feed your creatures 100 times total", hint: "Your creatures never go hungry", unlocked: false, progress: 0, goal: 100, rewards: { money: 500, items: { CreatureChow: 20 } } }, /* Care chain */ firstCare: { id: "firstCare", name: "Tender Loving Care", description: "Care for a creature for the first time", hint: "Creatures need regular grooming and attention", unlocked: false, rewards: { money: 50, items: { CarePotion: 1 } } }, careTenTimes: { id: "careTenTimes", name: "Attentive Keeper", description: "Care for your creatures 10 times total", hint: "Keep those critters happy!", unlocked: false, progress: 0, goal: 10, rewards: { money: 100, items: { CarePotion: 2 } } }, careFiftyTimes: { id: "careFiftyTimes", name: "Devoted Keeper", description: "Care for your creatures 50 times total", hint: "Your dedication shows", unlocked: false, progress: 0, goal: 50, rewards: { money: 250, items: { CarePotion: 3 } } }, careHundredTimes: { id: "careHundredTimes", name: "Master Keeper", description: "Care for your creatures 100 times total", hint: "Your creatures are always pristine", unlocked: false, progress: 0, goal: 100, rewards: { money: 500, items: { CarePotion: 5 } } }, /* Max stats */ maxAffection: { id: "maxAffection", name: "Best Friends", description: "Max out a creature's affection", hint: "Keep feeding and caring for your creatures", unlocked: false, rewards: { money: 300, items: { CarePotion: 3 } } }, maxAllStats: { id: "maxAllStats", name: "Perfect Bond", description: "Max out all stats on a single creature", hint: "Hunger, care, and affection all at maximum", unlocked: false, rewards: { money: 500, items: { CarePotion: 5, CreatureChow: 5 } } }, firstMeal: { id: "firstMeal", name: "Home Cook", description: "Cook your first meal", hint: "Head to the Kitchen and combine some ingredients", unlocked: false, rewards: { money: 100, items: { Flour: 3 } } }, firstSlop: { id: "firstSlop", name: "Yikes...", description: "Create your first batch of inedible slop", hint: "Not every combination works out", unlocked: false, rewards: { money: 50 } }, /* Recipe discovery chain */ tenRecipes: { id: "tenRecipes", name: "Budding Chef", description: "Discover 10 unique recipes", hint: "Keep experimenting in the kitchen", unlocked: false, progress: 0, goal: 10, rewards: { money: 200, items: { CookingOil: 3, Herbs: 3 } } }, twentyFiveRecipes: { id: "twentyFiveRecipes", name: "Seasoned Cook", description: "Discover 25 unique recipes", hint: "Your cookbook is filling up nicely", unlocked: false, progress: 0, goal: 25, rewards: { money: 400, items: { Saffron: 2, CookingOil: 5 } } }, fiftyRecipes: { id: "fiftyRecipes", name: "Master Chef", description: "Discover 50 unique recipes", hint: "Half the cookbook filled!", unlocked: false, progress: 0, goal: 50, rewards: { money: 800, items: { Saffron: 5, CookingOil: 10 } } }, /* Fish cooking chain */ firstFishMeal: { id: "firstFishMeal", name: "From Lake to Table", description: "Cook a meal using a fish you caught", hint: "Combine a fish with other ingredients in the kitchen", unlocked: false, rewards: { money: 200, items: { CookingOil: 3 } } }, tenFishMeals: { id: "tenFishMeals", name: "Fisherman's Feast", description: "Cook 10 meals using fish", hint: "Put your catches to good use", unlocked: false, progress: 0, goal: 10, rewards: { money: 400, items: { CookingOil: 5, Herbs: 5 } } }, /* Variety cooking */ cookAllCategories: { id: "cookAllCategories", name: "Well Rounded", description: "Cook a meal using ingredients from every category", hint: "Protein, vegetable, base, and flavor — use them all", unlocked: false, rewards: { money: 300, items: { Saffron: 2 } } }, feedFishMeal: { id: "feedFishMeal", name: "Gourmet Critter", description: "Feed a creature a home-cooked fish meal", hint: "Your critters appreciate fine dining too", unlocked: false, rewards: { money: 250, items: { CreatureChow: 5 } } }, /* Slop and experimentation */ fiveSlopMeals: { id: "fiveSlopMeals", name: "Mad Scientist", description: "Create slop 5 times", hint: "Failure is just research", unlocked: false, progress: 0, goal: 5, rewards: { money: 100 } }, cookWithSaffron: { id: "cookWithSaffron", name: "Golden Touch", description: "Cook a meal using Saffron", hint: "The most luxurious of ingredients", unlocked: false, rewards: { money: 200, items: { Saffron: 1 } } }, cookAllFish: { id: "cookAllFish", name: "Full Catch", description: "Cook a meal with every fish species at least once", hint: "Every fish deserves a chance in the kitchen", unlocked: false, progress: 0, goal: 14, rewards: { money: 1000, items: { Saffron: 5, CookingOil: 10, Herbs: 10 } } }, firstCatch: { id: "firstCatch", name: "Gone Fishin'", description: "Catch your first fish", hint: "Head to a fishing spot and cast your line", unlocked: false, rewards: { money: 100, items: { WormBait: 3 } } }, /* Fish count chain */ tenFish: { id: "tenFish", name: "Fishy Business", description: "Catch 10 fish total", hint: "Keep fishing!", unlocked: false, progress: 0, goal: 10, rewards: { money: 200, items: { WormBait: 5 } } }, fiftyFish: { id: "fiftyFish", name: "Reel Deal", description: "Catch 50 fish total", hint: "A dedicated angler", unlocked: false, progress: 0, goal: 50, rewards: { money: 400, items: { WormBait: 10 } } }, hundredFish: { id: "hundredFish", name: "Master Angler", description: "Catch 100 fish total", hint: "The fish fear your name", unlocked: false, progress: 0, goal: 100, rewards: { money: 800, items: { WormBait: 20, Lantern: 1 } } }, /* Rare fish chain */ firstMagicalFish: { id: "firstMagicalFish", name: "Something Shimmers", description: "Catch your first magical fish", hint: "Some fishing spots hold more than ordinary catches...", unlocked: false, rewards: { money: 300, items: { WormBait: 5 } } }, allMagicalFish: { id: "allMagicalFish", name: "Collector of Wonders", description: "Catch all four magical fish species at least once", hint: "Seek out every magical fishing spot", unlocked: false, progress: 0, goal: 4, rewards: { money: 1000, items: { WormBait: 20, Lantern: 1 } } }, /* Location chain */ firstNewLocation: { id: "firstNewLocation", name: "Wanderer", description: "Fish at a new location for the first time", hint: "Explore beyond your starting fishing spot", unlocked: false, rewards: { money: 150, items: { WormBait: 3 } } }, allLocations: { id: "allLocations", name: "World Fisher", description: "Fish at every available location", hint: "There's always another spot to explore", unlocked: false, progress: 0, goal: 4, rewards: { money: 500, items: { WormBait: 10, Lantern: 1 } } }, /* Misc fishing */ earlyBird: { id: "earlyBird", name: "Early Bird", description: "Use all 3 daytime fishing attempts in a single day", hint: "Make the most of the daylight hours", unlocked: false, rewards: { money: 200, items: { WormBait: 5 } } }, bigCatch: { id: "bigCatch", name: "The Big One", description: "Catch a Sturgeon or Muskellunge", hint: "These rare catches require patience and luck", unlocked: false, rewards: { money: 400, items: { WormBait: 10 } } }, nightCatcher: { id: "nightCatcher", name: "Creature of the Night", description: "Catch 10 fish at night", hint: "The lantern reveals what daylight hides", unlocked: false, progress: 0, goal: 10, rewards: { money: 300, items: { WormBait: 10, Lantern: 1 } } }, nightFisher: { id: "nightFisher", name: "Night Owl", description: "Catch a fish after unlocking the Lantern", hint: "The Lantern opens up new possibilities at night", unlocked: false, rewards: { money: 250, items: { WormBait: 5 } } }, firstRename: { id: "firstRename", name: "Pet Names", description: "From Fluffy to Sir Reginald the III, make your critter feel loved with a special nickname", hint: "Try using the pencil icon in your creature's profile", unlocked: false, rewards: { money: 100 } }, firstCustomize: { id: "firstCustomize", name: "That Looks Fabulous, Darling", description: "Customize a creature's profile theme", hint: "Explore and interact with a creature's profile page", unlocked: false, rewards: { money: 100 } }, firstBreeding: { id: "firstBreeding", name: "First Steps", description: "Successfully breed your first pair of creatures", hint: "Try breeding two adult creatures together", unlocked: false, rewards: { money: 100, items: { CreatureChow: 3 } } }, tenEggs: { id: "tenEggs", name: "Egg Collector", description: "Produce 10 eggs total", hint: "Keep breeding creatures", unlocked: false, progress: 0, goal: 10, rewards: { money: 250, items: { CreatureChow: 5 } } }, fiftyEggs: { id: "fiftyEggs", name: "Egg Hoarder", description: "Produce 50 eggs total", hint: "Keep breeding creatures", unlocked: false, progress: 0, goal: 50, rewards: { money: 500, items: { CreatureChow: 10, CarePotion: 2 } } }, hundredEggs: { id: "hundredEggs", name: "The Egg Whisperer", description: "Produce 100 eggs total", hint: "A truly dedicated breeder", unlocked: false, progress: 0, goal: 100, rewards: { money: 1000, items: { CreatureChow: 20, CarePotion: 5 } } }, thirdGeneration: { id: "thirdGeneration", name: "New Generations", description: "Hatch a third generation creature", hint: "Breed creatures for lineage", unlocked: false, rewards: { money: 150, items: { CreatureChow: 3 } } }, fifthGeneration: { id: "fifthGeneration", name: "Dynasty Begins", description: "Hatch a fifth generation creature", hint: "Keep breeding across generations", unlocked: false, rewards: { money: 400, items: { CarePotion: 3 } } }, tenthGeneration: { id: "tenthGeneration", name: "Living Legacy", description: "Hatch a tenth generation creature", hint: "A true lineage of critters", unlocked: false, rewards: { money: 800, items: { CarePotion: 5, CreatureChow: 10 } } }, fiveCreatures: { id: "fiveCreatures", name: "Growing Family", description: "Have 5 creatures in your corral at once", hint: "Keep breeding and buying creatures", unlocked: false, rewards: { money: 200, items: { CreatureChow: 5 } } }, tenCreatures: { id: "tenCreatures", name: "Full House", description: "Have 10 creatures in your corral at once", hint: "That's a lot of critters!", unlocked: false, rewards: { money: 400, items: { CreatureChow: 10, CarePotion: 2 } } }, twentyCreatures: { id: "twentyCreatures", name: "Corral Chaos", description: "Have 20 creatures in your corral at once", hint: "How do you keep track of them all?", unlocked: false, rewards: { money: 750, items: { CreatureChow: 20, CarePotion: 5 } } }, /* Misc breeding */ firstSell: { id: "firstSell", name: "Nothing Gold Can Stay", description: "Sell your first creature", hint: "Too many creatures, not enough money?", unlocked: false, rewards: { money: 150 } }, firstOldDeath: { id: "firstOldDeath", name: "All critters go to heaven", description: "Have a creature die from old age", hint: "It's a waiting game", unlocked: false, rewards: { money: 200 } }, firstRequest: { id: "firstRequest", name: "Budding Breeder", description: "Fulfill your first request", hint: "Find the Request Board and complete one", unlocked: false, rewards: { money: 200 } }, tenRequests: { id: "tenRequests", name: "Amateur Breeder", description: "Fulfill ten requests", hint: "Keep fulfilling requests", unlocked: false, progress: 0, goal: 10, rewards: { money: 300 } }, firstRare: { id: "firstRare", name: "Rare Find", description: "Hatch a Rare creature", hint: "Rare creatures are harder to breed...", unlocked: false, rewards: { money: 500 } }, /* steps */ first100Steps: { id: "first100Steps", name: "100 Steps", description: "Step 100 Times", hint: "Step to it!", unlocked: false, progress: 0, goal: 100, rewards: { xp: 20 } }, first500Steps: { id: "first500Steps", name: "500 Steps", description: "Step 500 Times", hint: "Getting warmed up!", unlocked: false, progress: 0, goal: 500, rewards: { xp: 30 } }, first1000Steps: { id: "first1000Steps", name: "1,000 Steps", description: "Step 1,000 Times", hint: "On a roll!", unlocked: false, progress: 0, goal: 1000, rewards: { xp: 50 } }, first5000Steps: { id: "first5000Steps", name: "5,000 Steps", description: "Step 5,000 Times", hint: "Seasoned walker.", unlocked: false, progress: 0, goal: 5000, rewards: { xp: 75 } }, first10000Steps:{ id: "first10000Steps",name: "10,000 Steps",description: "Step 10,000 Times",hint: "Marathon legs.", unlocked: false, progress: 0, goal: 10000, rewards: { xp: 100 } }, }>> <<set $stepMilestones = {}>> <<set $totalAchievementsUnlocked to 0>> <<set $achievementQueue to []>> /* For displaying achievement notifications */
/* Farm Stuff */ <<run setup.startFarmPoller()>> <<set $farmPlots = [ {id: 0, crop: null, plantedDay: 0, lastWatered: 0, growthStage: 0, justPlanted: false}, {id: 1, crop: null, plantedDay: 0, lastWatered: 0, growthStage: 0, justPlanted: false}, {id: 2, crop: null, plantedDay: 0, lastWatered: 0, growthStage: 0, justPlanted: false} ]>> <<set $maxPlots = 3>> <<set $lastPlotPurchaseDay = 0>> <<set $justPlanted to false>> <<set setup.crops = { "Wheat": { id: "Wheat", name: "Wheat", growthDays: 7, harvestAmount: {spring: 3, summer: 3, fall: 2, winter: 1}, seedCost: 20, images: { stage0: "https://i.imgur.com/JD5qVV8.png", // 0-24% stage1: "https://i.imgur.com/LvbDuDQ.png", // 25-49% growth stage2: "https://i.imgur.com/OdOa3Ve.png", // 50-74% growth stage3: "https://i.imgur.com/GSHVhhY.png", // 75-99% growth stage4: "https://i.imgur.com/LVPhx4Y.png" // 100% growth (mature) } }, "Corn": { id: "Corn", name: "Corn", growthDays: 9, harvestAmount: {spring: 2, summer: 3, fall: 2, winter: 1}, seedCost: 25, images: { stage0: "https://i.imgur.com/wEavyYE.png", stage1: "https://i.imgur.com/z9fCbC3.png", stage2: "https://i.imgur.com/GUcc66J.png", stage3: "https://i.imgur.com/ACDIoVZ.png", stage4: "https://i.imgur.com/TZ75m2j.png" } }, "Potato": { id: "Potato", name: "Potato", growthDays: 6, harvestAmount: {spring: 4, summer: 4, fall: 3, winter: 2}, seedCost: 15, images: { stage0: "https://i.imgur.com/7bSvPuh.png", stage1: "https://i.imgur.com/NANRK90.png", stage2: "https://i.imgur.com/gYEf3fM.png", stage3: "https://i.imgur.com/Yoamgz5.png", stage4: "https://i.imgur.com/VaXayIA.png" } }, "Carrot": { id: "Carrot", name: "Carrot", growthDays: 5, harvestAmount: {spring: 3, summer: 3, fall: 3, winter: 2}, seedCost: 15, images: { stage0: "https://i.imgur.com/XsCZTwq.png", stage1: "https://i.imgur.com/qcWV7zF.png", stage2: "https://i.imgur.com/XyHJyAn.png", stage3: "https://i.imgur.com/scAJ6Yd.png", stage4: "https://i.imgur.com/s6DdBeA.png" } }, "Tomato": { id: "Tomato", name: "Tomato", growthDays: 8, harvestAmount: {spring: 3, summer: 4, fall: 2, winter: 1}, seedCost: 30, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Onion": { id: "Onion", name: "Onion", growthDays: 6, harvestAmount: {spring: 3, summer: 3, fall: 3, winter: 2}, seedCost: 20, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Lettuce": { id: "Lettuce", name: "Lettuce", growthDays: 4, harvestAmount: {spring: 2, summer: 2, fall: 2, winter: 1}, seedCost: 10, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Rice": { id: "Rice", name: "Rice", growthDays: 10, harvestAmount: {spring: 4, summer: 5, fall: 3, winter: 2}, seedCost: 35, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Garlic": { id: "Garlic", name: "Garlic", growthDays: 7, harvestAmount: {spring: 3, summer: 3, fall: 2, winter: 1}, seedCost: 25, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Basil": { id: "Basil", name: "Basil", growthDays: 5, harvestAmount: {spring: 2, summer: 3, fall: 2, winter: 1}, seedCost: 20, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Parsley": { id: "Parsley", name: "Parsley", growthDays: 5, harvestAmount: {spring: 2, summer: 3, fall: 2, winter: 1}, seedCost: 20, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } }, "Cilantro": { id: "Cilantro", name: "Cilantro", growthDays: 4, harvestAmount: {spring: 2, summer: 2, fall: 2, winter: 1}, seedCost: 18, images: { stage0: "https://i.imgur.com/PLACEHOLDER0.png", stage1: "https://i.imgur.com/PLACEHOLDER1.png", stage2: "https://i.imgur.com/PLACEHOLDER2.png", stage3: "https://i.imgur.com/PLACEHOLDER3.png", stage4: "https://i.imgur.com/PLACEHOLDER4.png" } } }>>
<<nobr>> <<updateSeason>> <div class="farm-title">🌾 Your Farm</div> <div class="farm-message"> <div style="background-color: #f0f8f0; padding: 10px; border-radius: 5px; margin-bottom: 15px;"> <strong>Day:</strong> <<= new Date().toLocaleDateString("en-US", { month: "long", day: "numeric" })>> | <strong>Season:</strong> $currentSeason | <strong>Weather:</strong> <<if $isBadWeather>>🌧️ Wet<<else>>☀️ Clear<</if>> </div> </div> <div class="farm-header">Farm Plots ($maxPlots / 12)</div> <<if $isbadWeather>> <div style="background-color: #d1ecf1; color: #0c5460; padding: 10px; border-radius: 5px; margin-bottom: 15px;"> 🌧️ <em>The rain is watering all your crops today!</em> </div> <</if>> <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin: 15px 0;"> <<for _i = 0; _i < $farmPlots.length; _i++>> <<set _plot = $farmPlots[_i]>> <<capture _i, _plot>> <div style="border: 2px solid #8b4513; padding: 10px; background-color: #faf8f3; border-radius: 5px; min-height: 260px; box-sizing: border-box;"> <div style="font-weight: bold; margin-bottom: 8px; text-align: center; border-bottom: 1px solid #8b4513; padding-bottom: 5px;"> Plot <<= _i + 1>> </div> <<if _plot.crop === null>> <div style="text-align: center; margin: 10px auto;"> <img src="https://i.imgur.com/qtYB5PE.png" class="farm-plot" alt="Empty Plot" style="width: 100%; max-width: 110px; height: auto; display: block; margin: 0 auto; image-rendering: crisp-edges; image-rendering: pixelated;"> </div> <div style="margin-top: 10px; font-size: 0.9em;"> <strong>Plant:</strong><br> <<if $inventory.WheatSeeds > 0>><<link "Wheat" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Wheat">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.CornSeeds > 0>><<link "Corn" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Corn">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.PotatoSeeds > 0>><<link "Potatoes" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Potato">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.CarrotSeeds > 0>><<link "Carrots" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Carrot">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.TomatoSeeds > 0>><<link "Tomatoes" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Tomato">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.OnionSeeds > 0>><<link "Onions" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Onion">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.LettuceSeeds > 0>><<link "Lettuce" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Lettuce">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.RiceSeeds > 0>><<link "Rice" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Rice">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.GarlicSeeds > 0>><<link "Garlic" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Garlic">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.BasilSeeds > 0>><<link "Basil" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Basil">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.ParsleySeeds > 0>><<link "Parsley" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Parsley">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.CilantroSeeds > 0>><<link "Cilantro" "Farm">><<set $tempPlot = _i>><<set $tempCrop = "Cilantro">><<plantCrop $tempPlot $tempCrop>><</link>><br><</if>> <<if $inventory.WheatSeeds === 0 && $inventory.CornSeeds === 0 && $inventory.PotatoSeeds === 0 && $inventory.CarrotSeeds === 0 && $inventory.TomatoSeeds === 0 && $inventory.OnionSeeds === 0 && $inventory.LettuceSeeds === 0 && $inventory.RiceSeeds === 0 && $inventory.GarlicSeeds === 0 && $inventory.BasilSeeds === 0 && $inventory.ParsleySeeds === 0 && $inventory.CilantroSeeds === 0>> <span style="color: #888; font-size: 0.85em;">No seeds</span> <</if>> </div> <<else>> <<set _cropData = setup.crops[_plot.crop]>> <div style="color: #2d5016; font-weight: bold; text-align: center; margin-bottom: 8px;"> _cropData.name </div> <div style="position: relative; width: 100%; max-width: 110px; height: 110px; margin: 8px auto;"> <img src="https://i.imgur.com/qtYB5PE.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 8px; border: 2px solid var(--mid-text); image-rendering: crisp-edges; image-rendering: pixelated;" alt="Plot"> <<if _plot.growthStage < 20>> <img @src="_cropData.images.stage0" style="position: absolute; top: 2px; left: 0; width: 100%; height: 100%; image-rendering: crisp-edges; image-rendering: pixelated;" alt="_cropData.name Seedling"> <<elseif _plot.growthStage < 50>> <img @src="_cropData.images.stage1" style="position: absolute; top: 3px; left: 0; width: 100%; height: 100%; image-rendering: crisp-edges; image-rendering: pixelated;" alt="_cropData.name Sprout"> <<elseif _plot.growthStage < 75>> <img @src="_cropData.images.stage2" style="position: absolute; top: 2px; left: 0; width: 100%; height: 100%; image-rendering: crisp-edges; image-rendering: pixelated;" alt="_cropData.name Young"> <<elseif _plot.growthStage < 100>> <img @src="_cropData.images.stage3" style="position: absolute; top: 2px; left: 0; width: 100%; height: 100%; image-rendering: crisp-edges; image-rendering: pixelated;" alt="_cropData.name Growing"> <<else>> <img @src="_cropData.images.stage4" style="position: absolute; top: 2px; left: 0; width: 100%; height: 100%; image-rendering: crisp-edges; image-rendering: pixelated;" alt="_cropData.name Mature"> <</if>> </div> <div style="font-size: 0.85em; margin-bottom: 5px;"> <strong>Growth:</strong> <<= _plot.growthStage>>% </div> <<set _now = Date.now()>> <<set _MS = setup.MS_PER_DAY>> <<set _msSinceWatered = _now - _plot.lastWatered>> <<set _droughtLimit = ($currentSeason === "Summer") ? _MS : (_MS * 2)>> <div style="font-size: 0.85em; margin-bottom: 8px;"> <strong>Water:</strong><br> <<if $isRainy>> <span style="color: #1e90ff;">💧 Watered (raining)</span> <<elseif _plot.justPlanted>> <span style="color: #ffa500;">⚠️ Needs water</span> <<elseif _msSinceWatered < (_droughtLimit * 0.5)>> <span style="color: #1e90ff;">💧 Watered</span> <<elseif _msSinceWatered < (_droughtLimit * 0.75)>> <span style="color: #ffa500;">⚠️ Needs water</span> <<elseif _msSinceWatered < _droughtLimit>> <span style="color: #d90000;">⚠️ Dying! Water immediately!</span> <<else>> <span style="color: #7d0101;">💀 Dead</span> <</if>> </div> <div style="text-align: center; margin-top: 8px;"> <<if _plot.crop !== null && _plot.growthStage < 100 && !$isRainy>> <<link "💧 Water" "Farm">><<waterCrop _i>><</link>> <</if>> <<if _plot.growthStage >= 100>> <<if _plot.crop !== null && _plot.growthStage < 100 && !$isRainy>><br><</if>> <<link "🌾 Harvest" "Farm">> <<harvestCrop _i>> <<set $farmMessage = "Harvested " + _harvestedAmount + "x " + _harvestedCrop + "!">> <</link>> <</if>> </div> <</if>> </div> <</capture>> <</for>> </div> <<if $farmMessage>> <div style="background-color: #d4edda; color: #155724; padding: 10px; border-radius: 5px; margin: 15px 0;"> $farmMessage </div> <<unset $farmMessage>> <</if>> <<if $maxPlots >= 12>> <em>Your farm is at maximum capacity (12 plots).</em> <</if>> --- <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <</nobr>>
<<nobr>> /* Fish behavior definitions */ <<set setup.fishBehaviors = { YellowPerch: { temperament: "timid", preferredDepth: "shallow", activity: "day", baseWeight: 25 }, LargemouthBass: { temperament: "aggressive", preferredDepth: "shallow", activity: "day", baseWeight: 20 }, Pike: { temperament: "aggressive", preferredDepth: "mid", activity: "day", baseWeight: 18 }, RainbowTrout: { temperament: "skittish", preferredDepth: "mid", activity: "day", baseWeight: 22 }, LakeTrout: { temperament: "steady", preferredDepth: "deep", activity: "day", baseWeight: 15 }, BullTrout: { temperament: "strong", preferredDepth: "deep", activity: "day", baseWeight: 12 }, Muskellunge: { temperament: "aggressive", preferredDepth: "mid", activity: "day", baseWeight: 10 }, Sturgeon: { temperament: "ancient", preferredDepth: "deep", activity: "day", baseWeight: 5 }, Sheefish: { temperament: "powerful", preferredDepth: "deep", activity: "day", baseWeight: 3 }, MoonglowPerch: { temperament: "timid", preferredDepth: "shallow", activity: "night", baseWeight: 20, dayVariant: "YellowPerch" }, ShadowPike: { temperament: "aggressive", preferredDepth: "mid", activity: "night", baseWeight: 15, dayVariant: "Pike" }, StardustTrout: { temperament: "skittish", preferredDepth: "mid", activity: "night", baseWeight: 18, dayVariant: "RainbowTrout" }, TwilightBass: { temperament: "aggressive", preferredDepth: "shallow", activity: "night", baseWeight: 16, dayVariant: "LargemouthBass" }, AbyssalTrout: { temperament: "steady", preferredDepth: "deep", activity: "night", baseWeight: 10, dayVariant: "LakeTrout" } }>> /* Environmental cues */ <<set setup.environmentalCues = [ { id: "calm_deep", text: "The lake looks unusually calm today. A few slow shadows drift deeper down.", boosts: { deep: 15 }, penalties: { shallow: -10 } }, { id: "ripples", text: "Fast ripples dart near the surface, breaking the water's stillness.", boosts: { shallow: 15, skittish: 10 }, penalties: { deep: -10, timid: -5 } }, { id: "still_water", text: "The water goes eerily still... not even a breeze disturbs it.", boosts: { timid: 20, steady: 10 }, penalties: { aggressive: -15 } }, { id: "shadow_passes", text: "A large shadow passes beneath the waterline, slow and deliberate.", boosts: { deep: 20, ancient: 25, powerful: 20 }, penalties: { shallow: -15 } }, { id: "cloudy_water", text: "The water looks murky today—visibility is low.", boosts: { aggressive: 10 }, penalties: { skittish: -15, timid: -10 } }, { id: "clear_bright", text: "The sun breaks through the clouds, illuminating the clear water.", boosts: { shallow: 10, skittish: 5 }, penalties: { deep: -5 } }, { id: "neutral", text: "The lake is peaceful. Small waves lap gently at the dock.", boosts: {}, penalties: {} } ], /* Night-specific environmental cues */ setup.nightEnvironmentalCues = [ { id: "moonlight", text: "Moonlight dances across the dark water, revealing silver flashes below.", boosts: { shallow: 15, skittish: 10 }, penalties: { deep: -10 } }, { id: "deep_night", text: "The depths are pitch black. Only your lantern's glow pierces the darkness.", boosts: { deep: 20, ancient: 15 }, penalties: { shallow: -15 } }, { id: "still_night", text: "The night is utterly silent. Even the water seems to hold its breath.", boosts: { timid: 25, steady: 15 }, penalties: { aggressive: -10 } }, { id: "active_night", text: "Splashes echo across the dark lake—something's hunting tonight.", boosts: { aggressive: 20, powerful: 15 }, penalties: { timid: -20 } } ]>> /* Fishing style modifiers */ <<set setup.fishingStyles = { gentle: { name: "Gentle Cast", description: "A soft, careful cast. Better for timid fish.", modifiers: { timid: 25, skittish: 15, common: 20 }, penalties: { aggressive: -15, powerful: -20, rare: -10 }, trashChance: -15 }, aggressive: { name: "Aggressive Cast", description: "A bold, powerful cast. Attracts big fish.", modifiers: { aggressive: 25, powerful: 20, rare: 15 }, penalties: { timid: -25, skittish: -20, common: -5 }, trashChance: 5 }, deep: { name: "Deep Cast", description: "Cast far and let it sink. Targets deep-water species.", modifiers: { deep: 30, ancient: 25, steady: 15, rare: 10 }, penalties: { shallow: -30, common: -15 }, trashChance: 10, baseCatchChance: -20 }, shallow: { name: "Shallow Cast", description: "Stay near the surface. Good for common fish and finds.", modifiers: { shallow: 25, common: 20 }, penalties: { deep: -25, rare: -15 }, trashChance: 25, baseCatchChance: 10 } }>> <<set $caughtMagicalFish = []>> <<set setup.baitModifiers = { WormBait: { biteChance: 10, trashChance: -8 } }>> <<set $isBadWeather to false>> <<set $weatherChecked to false>> <<set $weatherCode to 0>> <</nobr>>
<<nobr>> <<set $fishingAttempts += 1>> <!-- Determine what was caught --> <<set $catchResult = setup.determineCatch($chosenCastStyle, $currentEnvironmentalCue, $chosenCastIsNight, $selectedBait)>> <<if $selectedBait and $inventory[$selectedBait] gt 0>> <<set $inventory[$selectedBait] -= 1>> <</if>> <<if $catchResult.type === "nothing">> <!-- Nothing bites --> <<if $chosenCastIsNight>> <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <<else>> <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <</if>> <div class="catch-result"> <h3>Nothing Bites...</h3> <p>Your line sits still in the water. Not even a nibble.</p> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Keep Fishing" "TheLake">><</link>></div> <div class="forth-button"> <<link "Go Home" "Home">><</link>></div> </div> <<elseif $catchResult.type === "trash">> <!-- Caught trash - for now just show this, we'll add specific trash items next --> <<if $chosenCastIsNight>> <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <<else>> <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <</if>> <div class="catch-result"> <h3>Something Tugs...</h3> <p>You reel in... old trash. Maybe next time.</p> <p><em>(Trash items coming soon!)</em></p> </div> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Keep Fishing" "TheLake">><</link>></div> <div class="forth-button"> <<link "Go Home" "Home">><</link>></div> </div> <<else>> <<set $caughtFishId = $catchResult.id>> <<set $caughtFishBehavior = setup.fishBehaviors[$caughtFishId]>> <<if $chosenCastIsNight>> <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <<else>> <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <</if>> <div class="catch-result"> <h3>Something Bites!</h3> <!-- Fish-specific narrative based on temperament --> <<switch $caughtFishBehavior.temperament>> <<case "timid">> <p>A gentle, hesitant tug—barely there. Whatever this is, it's careful.</p> <<case "skittish">> <p>A quick, darting pull! The line zips left, then right—this one's nervous.</p> <<case "aggressive">> <p>A sudden, violent strike! Your rod bends hard—something powerful just hit.</p> <<case "steady">> <p>A slow, heavy pull drags the line downward—this one has weight to it.</p> <<case "strong">> <p>The line goes taut with a forceful jerk. Whatever's down there isn't giving up easily.</p> <<case "ancient">> <p>A deep, ponderous pull... something massive and old moves beneath the surface.</p> <<case "powerful">> <p>Your line snaps tight as something enormously strong takes off with your bait!</p> <<default>> <p>The line pulls tight—you've hooked something!</p> <</switch>> </div> <div style="text-align: center; margin-top: 30px;"> <<button "Start Reeling!" "TensionGame">> <</button>> </div> <</if>> <</nobr>>
<<nobr>> <!-- Initialize tension game on first visit --> <<if !$tensionGame>> <<set $tensionGame = setup.initTensionGame($caughtFishId)>> <</if>> <<if $chosenCastIsNight>> <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <<else>> <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <</if>> <div class="tension-game-container"> <h2>Catch the Fish!</h2> <!-- Tension Bar --> <div class="tension-bar-container"> <div class="tension-label">Line Tension</div> <div class="hzbarbkg" id="tensionbarbkg"> <div class="hzbar" id="tensionbar"></div> </div> <div class="tension-value"><<print Math.round($tensionGame.currentTension)>>/100</div> </div> <!-- Turns Remaining --> <div class="turns-remaining"> Turns Remaining: <span class="turn-count">$tensionGame.turnsRemaining</span> </div> <!-- Action feedback (only shown after first action) --> <<if $tensionGame.lastAction>> <div class="action-feedback"> <div class="fish-action">$tensionActionResult.fishText <<if $tensionActionResult.fishChange > 0>> <span class="tension-up">+$tensionActionResult.fishChange tension</span> <<elseif $tensionActionResult.fishChange < 0>> <span class="tension-down">$tensionActionResult.fishChange tension</span> <<else>> <span class="tension-neutral">No change</span> <</if>> </div> <div class="player-action">$tensionActionResult.actionText <<if $tensionActionResult.playerChange > 0>> <span class="tension-up">+$tensionActionResult.playerChange tension</span> <<elseif $tensionActionResult.playerChange < 0>> <span class="tension-down">$tensionActionResult.playerChange tension</span> <<else>> <span class="tension-neutral">No change</span> <</if>> </div> <div class="outcome-feedback">$tensionActionResult.outcomeText</div> </div> <</if>> <!-- Action Buttons --> <div class="tension-actions"> <div class="tension-button-row"> <div class="tension-button-container"> <<button "Reel Fast">> <<set $tensionActionResult = setup.processTensionAction("reel_fast", $tensionGame, setup.fishBehaviors[$caughtFishId])>> <<if $tensionActionResult.outcome === "continue">> <<goto "TensionGame">> <<else>> <<goto "TensionResult">> <</if>> <</button>> <div class="action-hint">+6 to +15 tension</div> </div> <div class="tension-button-container"> <<button "Reel Slow">> <<set $tensionActionResult = setup.processTensionAction("reel_slow", $tensionGame, setup.fishBehaviors[$caughtFishId])>> <<if $tensionActionResult.outcome === "continue">> <<goto "TensionGame">> <<else>> <<goto "TensionResult">> <</if>> <</button>> <div class="action-hint">+1 to +8 tension</div> </div> </div> <div class="tension-button-row"> <div class="tension-button-container"> <<button "Hold Line">> <<set $tensionActionResult = setup.processTensionAction("hold_line", $tensionGame, setup.fishBehaviors[$caughtFishId])>> <<if $tensionActionResult.outcome === "continue">> <<goto "TensionGame">> <<else>> <<goto "TensionResult">> <</if>> <</button>> <div class="action-hint">-3 to +3 tension</div> </div> <div class="tension-button-container"> <<button "Give Slack">> <<set $tensionActionResult = setup.processTensionAction("give_slack", $tensionGame, setup.fishBehaviors[$caughtFishId])>> <<if $tensionActionResult.outcome === "continue">> <<goto "TensionGame">> <<else>> <<goto "TensionResult">> <</if>> <</button>> <div class="action-hint">-18 to -5 tension</div> </div> </div> </div> </div> <<script>> $(document).one(':passageend', function (ev) { var tensionGame = State.variables.tensionGame; StatBar(tensionGame.currentTension, 100, "tensionbar", true, ev.content, {h: 120, s: 70, l: 50}, /* Green */ {h: 0, s: 70, l: 50} /* Red */ ); }); <</script>> <</nobr>>
<<nobr>> <<if $chosenCastIsNight>> <img src="https://i.imgur.com/MH9qcEf.png" class="lake-image"> <<else>> <img src="https://i.imgur.com/zkmGWEa.png" class="lake-image"> <</if>> <div class="tension-result-container"> <<if $tensionActionResult.outcome === "caught">> <!-- SUCCESS! --> <div class="result-success"> <h2>🎣 Success!</h2> <img @src="setup.items[$caughtFishId].image" class="fish-image"> <h3>You caught a <<print setup.items[$caughtFishId].name>>!</h3> <p class="fish-description"><<print setup.items[$caughtFishId].description>></p> <p class="rarity-badge rarity-<<print setup.items[$caughtFishId].rarity.toLowerCase()>>"> <<print setup.items[$caughtFishId].rarity>> </p> <<set $inventory[$caughtFishId] += 1>> /* Fishing achievement triggers */ <<run unlockAchievement("firstCatch")>> <<run updateAchievementProgress("tenFish", 1)>> <<run updateAchievementProgress("fiftyFish", 1)>> <<run updateAchievementProgress("hundredFish", 1)>> <<if $fishingAttempts >= 3 && !$chosenCastIsNight>> <<run unlockAchievement("earlyBird")>> <</if>> /* Big catch */ <<if $caughtFishId === "Sturgeon" || $caughtFishId === "Muskellunge">> <<run unlockAchievement("bigCatch")>> <</if>> /* Magical fish */ <<set _magicalFish = ["MoonglowPerch", "TwilightBass", "ShadowPike", "StardustTrout", "AbyssalTrout"]>> <<if _magicalFish.includes($caughtFishId)>> <<run unlockAchievement("firstMagicalFish")>> /* Track unique magical fish caught */ <<if !$caughtMagicalFish>><<set $caughtMagicalFish = []>><</if>> <<if !$caughtMagicalFish.includes($caughtFishId)>> <<run $caughtMagicalFish.push($caughtFishId)>> <<run updateAchievementProgress("allMagicalFish", 1)>> <</if>> <</if>> /* Night fishing */ <<if $chosenCastIsNight>> <<run unlockAchievement("nightFisher")>> <</if>> /* Night fishing count */ <<if $chosenCastIsNight>> <<run updateAchievementProgress("nightCatcher", 1)>> <</if>> </div> <<elseif $tensionActionResult.outcome === "escaped">> <!-- Fish escaped - too much slack --> <div class="result-failure"> <h2>The Fish Escaped...</h2> <p>The line went completely slack. The fish swam away into the depths.</p> <p class="failure-reason">The tension dropped to zero—you gave it too much slack!</p> </div> <<elseif $tensionActionResult.outcome === "broke">> <!-- Line broke - too much tension --> <div class="result-failure"> <h2>The Line Broke!</h2> <p>The fishing line couldn't take the strain and snapped clean through.</p> <p class="failure-reason">The tension exceeded 100—you pulled too hard!</p> </div> <<elseif $tensionActionResult.outcome === "timeout">> <!-- Ran out of turns --> <div class="result-failure"> <h2>Out of Time...</h2> <p>The fish fought long enough to tire you out. It wriggled free and escaped.</p> <p class="failure-reason">You ran out of turns—the fish was too strong!</p> </div> <</if>> <div class="battle-summary"> <h4>Fishing Summary</h4> <p>Turns Used: <<print 12 - $tensionGame.turnsRemaining>>/12</p> <p>Final Tension: <<print Math.round($tensionGame.currentTension)>>/100</p> <<if $tensionActionResult.outcome === "caught">> <p class="summary-success">Perfect stabilization achieved!</p> <</if>> </div> </div> <div class="back-forth-buttons"> <div class="back-button"> <<link "Keep Fishing" "TheLake">> <<unset $tensionGame>> <<unset $tensionActionResult>> <<unset $caughtFishId>> <</link>> </div> <div class="forth-button"> <<link "Go Home" "Home">> <<unset $tensionGame>> <<unset $tensionActionResult>> <<unset $caughtFishId>> <</link>> </div> </div> <</nobr>>
<<set setup.ingredientProperties = { /* PROTEINS */ "YellowPerch": { category: "Protein", flavorTags: ["Savory", "Mild"], hint: "A delicate fish that pairs well with light seasonings." }, "LargemouthBass": { category: "Protein", flavorTags: ["Savory", "Rich"], hint: "A hearty fish perfect for robust dishes." }, "Pike": { category: "Protein", flavorTags: ["Savory", "Bold"], hint: "A strong-flavored fish that stands up to bold spices." }, "RainbowTrout": { category: "Protein", flavorTags: ["Savory", "Fresh"], hint: "A versatile fish with a clean, fresh taste." }, "LakeTrout": { category: "Protein", flavorTags: ["Savory", "Rich"], hint: "A fatty, flavorful fish ideal for smoking or baking." }, "BullTrout": { category: "Protein", flavorTags: ["Savory", "Delicate"], hint: "A tender fish that melts in your mouth." }, "Muskellunge": { category: "Protein", flavorTags: ["Savory", "Bold"], hint: "A powerful fish with intense flavor." }, "Sturgeon": { category: "Protein", flavorTags: ["Savory", "Luxurious"], hint: "A prized fish with a buttery texture." }, "Sheefish": { category: "Protein", flavorTags: ["Savory", "Sweet"], hint: "A subtly sweet fish perfect for any preparation." }, "MoonglowPerch": { category: "Protein", flavorTags: ["Savory", "Ethereal"], hint: "A mystical fish that shimmers with magical flavor." }, "TwilightBass": { category: "Protein", flavorTags: ["Savory", "Mysterious"], hint: "A dark fish with deep, complex flavors." }, "ShadowPike": { category: "Protein", flavorTags: ["Savory", "Intense"], hint: "A shadowy fish with bold, unforgettable taste." }, "StardustTrout": { category: "Protein", flavorTags: ["Savory", "Magical"], hint: "A sparkling fish that adds wonder to any dish." }, "AbyssalTrout": { category: "Protein", flavorTags: ["Savory", "Deep"], hint: "A mysterious fish from the depths, rich and complex." }, /* VEGETABLES */ "Wheat": { category: "Vegetable", flavorTags: ["Earthy", "Nutty"], hint: "Wholesome grain that adds body to dishes." }, "Corn": { category: "Vegetable", flavorTags: ["Sweet", "Fresh"], hint: "Sweet kernels that brighten any meal." }, "Potato": { category: "Vegetable", flavorTags: ["Earthy", "Hearty"], hint: "A filling staple that absorbs flavors well." }, "Carrot": { category: "Vegetable", flavorTags: ["Sweet", "Earthy"], hint: "Naturally sweet root that adds color and nutrition." }, "Lettuce": { category: "Vegetable", flavorTags: ["Fresh", "Crisp"], hint: "Crisp greens perfect for fresh dishes." }, "Tomato": { category: "Vegetable", flavorTags: ["Tangy", "Juicy"], hint: "Juicy and acidic, the foundation of many sauces." }, "Onion": { category: "Vegetable", flavorTags: ["Pungent", "Sweet"], hint: "A pungent bulb that becomes sweet when cooked." }, "Coconut": { category: "Vegetable", flavorTags: ["Sweet", "Tropical"], hint: "Exotic sweetness that transports you elsewhere." }, "PickledVeggies": { category: "Vegetable", flavorTags: ["Tangy", "Sour"], hint: "Preserved vegetables with sharp, zesty flavor." }, /* BASES */ "CookingOil": { category: "Base", flavorTags: ["Neutral", "Essential"], hint: "The foundation of most cooking methods." }, "Flour": { category: "Base", flavorTags: ["Neutral", "Binding"], hint: "Binds ingredients together and adds substance." }, "Sugar": { category: "Base", flavorTags: ["Sweet", "Balancing"], hint: "Sweetness that balances savory flavors." }, "Rice": { category: "Base", flavorTags: ["Neutral", "Filling"], hint: "A versatile grain that complements everything." }, "Pasta": { category: "Base", flavorTags: ["Neutral", "Comforting"], hint: "Comforting noodles that carry sauces beautifully." }, "Berries": { category: "Base", flavorTags: ["Sweet", "Tart"], hint: "Bright, fruity flavor for sweet or savory dishes." }, /* FLAVOR ENHANCERS */ "Herbs": { category: "Flavor", flavorTags: ["Aromatic", "Fresh"], hint: "Fragrant greens that elevate any dish." }, "Garlic": { category: "Flavor", flavorTags: ["Pungent", "Bold"], hint: "Powerful aroma that adds depth and warmth." }, "Basil": { category: "Flavor", flavorTags: ["Aromatic", "Sweet"], hint: "Sweet herb that brings Italian flair." }, "Parsley": { category: "Flavor", flavorTags: ["Fresh", "Bright"], hint: "Bright herb that adds a fresh finish." }, "Cilantro": { category: "Flavor", flavorTags: ["Fresh", "Citrusy"], hint: "Citrusy herb perfect for bold dishes." }, "Saffron": { category: "Flavor", flavorTags: ["Aromatic", "Luxurious"], hint: "Precious threads that add golden elegance." } }>> <<set setup.cookingRecipes = { /* Format: "Ingredient1|Ingredient2|Ingredient3": "MealName" */ /* REMEMBER: Keys must be sorted alphabetically */ /* Vegetarian dishes (initial dishes to be organized) */ "CookingOil|Herbs|Potato": "Herbed Roasted Potatoes", "Corn|Flour|Sugar": "Sweet Corn Fritters", "Basil|Pasta|Tomato": "Classic Tomato Basil Pasta", "Coconut|Rice|Sugar": "Sweet Coconut Rice", "Carrot|Herbs|Onion": "Garden Vegetable Medley", "CookingOil|Lettuce|Tomato": "Fresh Garden Salad", "Flour|Sugar|Wheat": "Wheat Bread", "CookingOil|Garlic|Potato": "Crispy Garlic Potatoes", "Garlic|Onion|Tomato": "Roasted Tomato Onion Blend", "Berries|Rice|Sugar": "Berry Rice Pudding", "Corn|Herbs|Potato": "Corn and Potato Hash", "Cilantro|PickledVeggies|Rice": "Tangy Pickled Rice Bowl", /* Vegetarian - Pasta dishes */ "Garlic|Herbs|Pasta": "Garlic Herb Pasta", "Basil|Garlic|Pasta": "Pesto-Style Pasta", "Onion|Pasta|Tomato": "Rustic Tomato Onion Pasta", "Carrot|Parsley|Pasta": "Carrot and Parsley Noodles", "Pasta|Saffron|Tomato": "Golden Saffron Pasta", "Cilantro|Corn|Pasta": "Zesty Corn Noodles", /* Vegetarian - Rice dishes */ "Carrot|Onion|Rice": "Carrot and Onion Pilaf", "Garlic|Rice|Tomato": "Spanish-Style Tomato Rice", "Herbs|Lettuce|Rice": "Fresh Herb Rice Bowl", "Onion|Parsley|Rice": "Herbed Onion Rice", "Onion|Rice|Saffron": "Saffron Onion Rice", "Cilantro|Garlic|Rice": "Cilantro Garlic Rice", /* Vegetarian - Bread and Flour dishes */ "Basil|Flour|Tomato": "Tomato Flatbread", "Flour|Garlic|Herbs": "Rustic Herb Bread", "Carrot|Flour|Sugar": "Carrot Cake Loaf", "Flour|Onion|Parsley": "Onion and Herb Rolls", "Coconut|Flour|Sugar": "Coconut Sweet Bread", "Corn|Flour|Parsley": "Herbed Corn Flatbread", /* Vegetarian - Soups and stews */ "Carrot|Onion|Tomato": "Homestyle Vegetable Soup", "Garlic|Lettuce|Onion": "Wilted Green Soup", "Basil|Carrot|Tomato": "Basil Tomato Bisque", "Garlic|Parsley|Potato": "Creamy Parsley Potato Soup", "Corn|Onion|Parsley": "Corn Chowder", "Garlic|Tomato|Wheat": "Rustic Wheat Tomato Stew", "Carrot|Garlic|Wheat": "Hearty Wheat and Carrot Stew", "Onion|Potato|Wheat": "Farmhouse Potato Soup", /* Vegetarian - Salads and fresh dishes */ "Basil|Onion|Tomato": "Caprese-Style Salad", "Carrot|Lettuce|Parsley": "Garden Fresh Salad", "Cilantro|Corn|Tomato": "Summer Corn Salsa", "Lettuce|Onion|Parsley": "Simple Green Salad", "Basil|Lettuce|Tomato": "Garden Herb Salad", "Cilantro|Lettuce|Tomato": "Zesty Taco Salad", "Carrot|Cilantro|Lettuce": "Crunchy Cilantro Slaw", "Corn|Lettuce|Tomato": "Harvest Salad", /* Vegetarian - Sides and misc */ "Garlic|Onion|Wheat": "Savory Wheat Pilaf", "Basil|Garlic|Tomato": "Roasted Garlic Tomato Sauce", "Coconut|Corn|Sugar": "Sweet Coconut Corn", "Berries|Flour|Sugar": "Simple Berry Tart", "Berries|Coconut|Sugar": "Tropical Berry Dessert", "Onion|PickledVeggies|Wheat": "Pickled Wheat Grain Bowl", "Carrot|PickledVeggies|Rice": "Pickled Carrot Rice Bowl", "Herbs|Potato|Saffron": "Saffron Roasted Potatoes", "Basil|Coconut|Rice": "Coconut Basil Rice", "Cilantro|Onion|Potato": "Cilantro Smashed Potatoes", /* Fried dishes - CookingOil + Flour + Vegetable */ "CookingOil|Corn|Flour": "Crispy Fried Corn Cakes", "Carrot|CookingOil|Flour": "Fried Carrot Fritters", "CookingOil|Flour|Tomato": "Fried Green Tomatoes", "CookingOil|Flour|Onion": "Crispy Onion Rings", "CookingOil|Flour|Wheat": "Golden Wheat Fritters", /* Sauteed dishes - CookingOil + Vegetable + Seasoning */ "Carrot|CookingOil|Garlic": "Garlic Sauteed Carrots", "Basil|CookingOil|Tomato": "Sauteed Tomato and Basil", "CookingOil|Corn|Herbs": "Buttery Herb Corn", "CookingOil|Herbs|Onion": "Caramelized Herb Onions", "Carrot|CookingOil|Parsley": "Glazed Parsley Carrots", "CookingOil|Garlic|Lettuce": "Wilted Garlic Greens", "Cilantro|CookingOil|Tomato": "Sauteed Cilantro Tomatoes", /* Three vegetable combos */ "Carrot|Onion|Potato": "Rustic Root Vegetable Roast", "Corn|Onion|Tomato": "Summer Vegetable Medley", "Carrot|Corn|Onion": "Farmhouse Vegetable Blend", "Garlic|Onion|Potato": "Golden Roasted Vegetables", "Basil|Carrot|Onion": "Herbed Carrot and Onion Bake", "Carrot|Lettuce|Tomato": "Classic Garden Toss", "Carrot|Corn|Potato": "Harvest Root Medley" }>> /* Initialize cookbook if it doesn't exist */ <<if !$cookbook>> <<set $cookbook = []>> <</if>> /* Initialize cooking selection if it doesn't exist */ <<if !$cookingSelection>> <<set $cookingSelection = []>> <</if>> <<set $cookedFishSpecies = []>> <<set $kitchenTab = "Protein">> <<set $cookingQueue = []>> <<run setup.startCookingPoller()>>
<<nobr>> <<set _ing1 = $cookingSelection[0]>> <<set _ing2 = $cookingSelection[1]>> <<set _ing3 = $cookingSelection[2]>> <<set _recipeKey = [_ing1, _ing2, _ing3].sort().join("|")>> <<set _recipeName = setup.cookingRecipes[_recipeKey]>> /* Pattern matching — unchanged from your original */ <<if !_recipeName>> <<set _ingredients = [_ing1, _ing2, _ing3]>> <<set _fishIngredient = null>> <<set _otherIngredients = []>> <<for _ing range _ingredients>> <<if setup.ingredientProperties[_ing] && setup.ingredientProperties[_ing].category === "Protein">> <<set _fishIngredient = _ing>> <<else>> <<run _otherIngredients.push(_ing)>> <</if>> <</for>> <<if _fishIngredient && _otherIngredients.length === 2>> <<set _patternKey = _otherIngredients.sort().join("|")>> <<set _ing1 = _otherIngredients[0]>> <<set _ing2 = _otherIngredients[1]>> <<set _fishName = setup.items[_fishIngredient].name>> <<set _recipePatterns = { "CookingOil|Herbs": "Herbed Pan-Fried", "Garlic|Rice": "Garlic Rice Bowl with", "Onion|Potato": "Hearty Stew with", "Basil|Pasta": "Basil Pasta with", "CookingOil|Saffron": "Saffron-Crusted", "Flour|Herbs": "Herb-Dusted", "Garlic|Tomato": "Tomato Garlic", "Rice|Saffron": "Luxurious Risotto with", "CookingOil|Parsley": "Pan-Seared", "Basil|Rice": "Herbed Rice Bowl with", "Garlic|Pasta": "Garlic Pasta with", "Herbs|Potato": "Herb-Roasted with", "Cilantro|Tomato": "Spicy Tomato Stew with", "CookingOil|Flour": "Crispy Battered", "Garlic|Onion": "Garlic and Onion Roasted", "Garlic|Herbs": "Garlic Herb Pan-Fried", "Onion|Tomato": "Tomato and Onion Braised", "Pasta|Tomato": "Tomato Pasta with", "Carrot|Onion": "Rustic Vegetable Stew with", "CookingOil|Garlic": "Garlic Pan-Seared", "Herbs|Onion": "Herb and Onion Roasted", "Cilantro|Rice": "Cilantro Rice Bowl with", "Parsley|Potato": "Parsley Potato Bake with", "Onion|Rice": "Onion Rice Bowl with", "Corn|CookingOil": "Grilled Corn and", "Pasta|Parsley": "Parsley Pasta with", "Saffron|Tomato": "Saffron Tomato Braise with" }>> <<if _recipePatterns[_patternKey]>> <<set _pattern = _recipePatterns[_patternKey]>> <<set _recipeName = _pattern + " " + _fishName>> <<set _recipeKey = [_fishIngredient, _otherIngredients[0], _otherIngredients[1]].sort().join("|")>> <<elseif _ing1 === "CookingOil" || _ing2 === "CookingOil">> <<set _otherIng = (_ing1 === "CookingOil") ? setup.items[_ing2].name : setup.items[_ing1].name>> <<set _recipeName = "Pan-Seared " + _fishName + " with " + _otherIng>> <<set _recipeKey = "PATTERN:CookingOil|*">> <<elseif _ing1 === "Flour" || _ing2 === "Flour">> <<set _otherIng = (_ing1 === "Flour") ? setup.items[_ing2].name : setup.items[_ing1].name>> <<set _recipeName = _otherIng + "-Crusted " + _fishName>> <<set _recipeKey = "PATTERN:Flour|*">> <<elseif _ing1 === "Rice" || _ing2 === "Rice">> <<set _otherIng = (_ing1 === "Rice") ? setup.items[_ing2].name : setup.items[_ing1].name>> <<set _recipeName = _otherIng + " Rice Bowl with " + _fishName>> <<set _recipeKey = "PATTERN:Rice|*">> <<elseif _ing1 === "Pasta" || _ing2 === "Pasta">> <<set _otherIng = (_ing1 === "Pasta") ? setup.items[_ing2].name : setup.items[_ing1].name>> <<set _recipeName = _otherIng + " Pasta with " + _fishName>> <<set _recipeKey = "PATTERN:Pasta|*">> <<elseif _ing1 === "Garlic" || _ing2 === "Garlic">> <<set _otherIng = (_ing1 === "Garlic") ? setup.items[_ing2].name : setup.items[_ing1].name>> <<set _recipeName = "Garlic " + _otherIng + " " + _fishName>> <<set _recipeKey = "PATTERN:Garlic|*">> <<elseif ["Herbs","Basil","Parsley","Cilantro"].includes(_ing1) || ["Herbs","Basil","Parsley","Cilantro"].includes(_ing2)>> <<set _herbIng = (["Herbs","Basil","Parsley","Cilantro"].includes(_ing1)) ? setup.items[_ing1].name : setup.items[_ing2].name>> <<set _otherIng = (["Herbs","Basil","Parsley","Cilantro"].includes(_ing1)) ? setup.items[_ing2].name : setup.items[_ing1].name>> <<set _recipeName = _herbIng + "-Seasoned " + _fishName + " with " + _otherIng>> <<set _recipeKey = "PATTERN:Herb|*">> <<else>> <<set _vegIngredients = ["Wheat","Corn","Potato","Carrot","Lettuce","Tomato","Onion","PickledVeggies"]>> <<if _vegIngredients.includes(_ing1) && _vegIngredients.includes(_ing2)>> <<set _recipeName = "Roasted " + _fishName + " with Vegetables">> <<set _recipeKey = "PATTERN:Veg|Veg">> <</if>> <</if>> <</if>> <</if>> <<if _recipeName>> /* ── Check queue limit ── */ <<if $cookingQueue.length >= 3>> <div class="cooking-failure" style="text-align:center;"> <p><strong>🍳 Kitchen is full!</strong></p> <p>You already have 3 meals cooking. Wait for one to finish before starting another.</p> </div> <<else>> /* ── Valid recipe — start cooking ── */ <<set _tier = setup.getCookingTier(_recipeKey)>> <<set _duration = setup.getCookingDuration(_tier)>> <<set _now = Date.now()>> <<set _mealId = [$cookingSelection[0], $cookingSelection[1], $cookingSelection[2]].sort().join("_")>> /* Consume ingredients immediately */ <<set $inventory[_ing1] -= 1>> <<set $inventory[_ing2] -= 1>> <<set $inventory[_ing3] -= 1>> <<if !$mealNames>><<set $mealNames = {}>><</if>> <<set $mealNames[_mealId] = _recipeName>> /* Add to cooking queue */ <<run $cookingQueue.push({ mealId: _mealId, recipeName: _recipeName, recipeKey: _recipeKey, tier: _tier, startTime: _now, finishTime: _now + _duration, done: false })>> /* Add to cookbook if new */ <<if !$cookbook.includes(_recipeKey)>> <<run updateAchievementProgress("tenRecipes", 1)>> <<run updateAchievementProgress("twentyFiveRecipes", 1)>> <<run updateAchievementProgress("fiftyRecipes", 1)>> <<run $cookbook.push(_recipeKey)>> <<if !$cookbookNames>><<set $cookbookNames = {}>><</if>> <<set $cookbookNames[_recipeKey] = _recipeName>> <</if>> /* Achievement triggers */ <<run unlockAchievement("firstMeal")>> <<if _fishIngredient>> <<run unlockAchievement("firstFishMeal")>> <<run updateAchievementProgress("tenFishMeals", 1)>> <<if !$cookedFishSpecies>><<set $cookedFishSpecies = []>><</if>> <<if !$cookedFishSpecies.includes(_fishIngredient)>> <<run $cookedFishSpecies.push(_fishIngredient)>> <<run updateAchievementProgress("cookAllFish", 1)>> <</if>> <</if>> <<if _ing1 === "Saffron" || _ing2 === "Saffron" || _ing3 === "Saffron">> <<run unlockAchievement("cookWithSaffron")>> <</if>> <<if $firstCook is false>> <<set $firstCook = true>> <<addXP 35>> <</if>> /* Work out display time */ <<if _tier === "exact">><<set _timeDisplay = "15 minutes">> <<elseif _tier === "tier1">><<set _timeDisplay = "30 minutes">> <<else>><<set _timeDisplay = "1 hour">><</if>> <div class="cooking-success" style="text-align:center;"> <p style="font-size:1.3em;">🍳</p> <p><strong><<print _recipeName>></strong> is now cooking!</p> <p style="font-size:0.9em; opacity:0.8;">Ready in <strong>_timeDisplay</strong>. You'll get a notification when it's done.</p> <<if $cookingQueue.length >= 3>> <p style="font-size:0.85em; color:var(--coral);">⚠️ Kitchen is now full — wait for a meal to finish before cooking again.</p> <</if>> </div> <</if>> <<else>> /* ── Slop — instant as before ── */ <div class="cooking-failure" style="text-align:center;"> <p style="font-size:1.3em;">😰</p> <p>You combined <<print setup.items[$cookingSelection[0]].name>>, <<print setup.items[$cookingSelection[1]].name>>, and <<print setup.items[$cookingSelection[2]].name>>...</p> <p>The result is <strong>inedible slop</strong>. 🤢</p> <p><i>These ingredients don't work well together. Try a different combination!</i></p> </div> <<run unlockAchievement("firstSlop")>> <<run updateAchievementProgress("fiveSlopMeals", 1)>> <<if $firstSlop is false>> <<set $firstSlop = true>> <<addXP 20>> <</if>> <</if>> <<set $cookingSelection = []>> <br> <div class="back-forth-buttons"> <div class="back-button"><<link "Keep Cooking" "Kitchen">><</link>></div> <div class="forth-button"><<link "Go Home" "Home">><</link>></div> </div> <</nobr>>
<<nobr>> <div class="re-banner" style="text-align:center;"> <div style="font-size:2em;">📖</div> <h2 class="re-banner-title">Your Cookbook</h2> <p style="margin:0; font-family:'Georgia',serif; font-size:0.9em;"><<print $cookbook.length>> <<if $cookbook.length === 1>>recipe<<else>>recipes<</if>> discovered</p> </div> <<if $cookbook.length === 0>> <div class="re-empty"> <p>Your cookbook is empty.</p> <p style="font-size:0.85em; opacity:0.7;">Experiment in the kitchen to discover new recipes!</p> </div> <<else>> <div class="cookbook-list"> <<for _recipeKey range $cookbook>> <<capture _recipeKey>> <<if _recipeKey.startsWith("PATTERN:")>> <<set _recipeName = $cookbookNames[_recipeKey]>> <div class="cookbook-card"> <div class="cookbook-card-header"> <span class="cookbook-card-name"><<print _recipeName>></span> <span class="cookbook-card-tag">Flexible</span> </div> <p class="cookbook-card-note"><i>Works with any fish!</i></p> </div> <<else>> <<set _recipeName = setup.cookingRecipes[_recipeKey] || $cookbookNames[_recipeKey]>> <<set _ingredients = _recipeKey.split("|")>> <<set _canCook = true>> <<for _ingId range _ingredients>> <<if !$inventory[_ingId] || $inventory[_ingId] < 1>> <<set _canCook = false>> <</if>> <</for>> <div @class="'cookbook-card' + (_canCook ? '' : ' cookbook-card-missing')"> <div class="cookbook-card-header"> <span class="cookbook-card-name"><<print _recipeName>></span> <<if _canCook>> <span class="cookbook-card-tag cookable">Ready</span> <<else>> <span class="cookbook-card-tag missing">Missing</span> <</if>> </div> <div class="cookbook-card-ingredients"> <<for _ingId range _ingredients>> <<set _has = $inventory[_ingId] && $inventory[_ingId] >= 1>> <span @class="'cookbook-ing-chip' + (_has ? '' : ' chip-missing')"> <<print setup.items[_ingId].name>> </span> <</for>> </div> <<if _canCook>> <<capture _recipeKey, _ingredients>> <div style="margin-top:0.6em;"> <<link "🔥 Cook this" "CookingResult">> <<set $cookingSelection = _ingredients.slice()>> <</link>> </div> <</capture>> <</if>> </div> <</if>> <</capture>> <</for>> </div> <</if>> <div class="back-forth-buttons" style="margin-top:1em;"> <div class="back-button"><<link "Back to Kitchen" "Kitchen">><</link>></div> <div class="forth-button"><<link "Go Home" "Home">><</link>></div> </div> <</nobr>>
<<set $buildCategory to "All">> <<set $hasFarm to false>> <<set $kitchenRenovated to false>> <<set $fishingUnlocked to false>> <<set $kitchenUnlocked to false>> <<set $farmUnlocked to false>> <<set setup.realEstate = { "Kitchen": { id: "Kitchen", name: "Kitchen Renovation", category: "Home", price: 700, image: "", requiredRank: "rankThree", requiredRankName: "Rank 3", description: "Renovate your kitchen to cook meals for your critters." }, "FarmPurchase": { id: "FarmPurchase", name: "Farm Purchase", category: "Farm", price: 1000, image: "", requiredRank: "rankFour", requiredRankName: "Rank 4", description: "Buy a farm to plant seeds and grow tasty crops. Comes with three plots and the ability to purchase more." }, "FarmPlots": { id: "FarmPlots", name: "Farm Plot Upgrade", category: "Farm", price: 350, image: "", requiredRank: "rankFour", requiredRankName: "Rank 4", description: "Buy an additional plot for your farm. Can hold one type of seed at a time." }, "EggSlots": { id: "EggSlots", name: "Hatchery Expansion", category: "Hatchery", price: 0, image: "", requiredRank: "rankOne", requiredRankName: "Rank 1", description: "Purchase additional egg slots for your hatchery. +6 slots per upgrade." } }>>
<<nobr>> /* ── BANNER ── */ <div class="re-banner"> <div class="re-banner-icon">🏡</div> <h2 class="re-banner-title">Real Estate</h2> <p class="re-banner-money">💰 <strong>$money g</strong></p> <p class="re-banner-tagline">Upgrade your home and land as you grow your rank.</p> </div> /* ── CATEGORY PILLS ── */ <div class="shop-categories-scroll"> <<link "All">><<set $buildCategory = "All">><<goto "RealEstate">><</link>> <<link "Home">><<set $buildCategory = "Home">><<goto "RealEstate">><</link>> <<link "Farm">><<set $buildCategory = "Farm">><<goto "RealEstate">><</link>> <<link "Hatchery">><<set $buildCategory = "Hatchery">><<goto "RealEstate">><</link>> </div> /* ── PROPERTY LIST ── */ <div class="re-list"> <<set _anyDisplayed = false>> <<for _key, _build range setup.realEstate>> <<capture _build>> /* Determine locked/hidden/owned state */ <<set _isOwned = false>> <<set _isLocked = false>> <<set _isHidden = false>> <<if _build.id === "Kitchen">> <<if $kitchenRenovated>><<set _isOwned = true>> <<elseif !$kitchenUnlocked>><<set _isLocked = true>> <</if>> <<elseif _build.id === "FarmPurchase">> <<if $hasFarm>><<set _isOwned = true>> <<elseif !$farmUnlocked>><<set _isLocked = true>> <</if>> <<elseif _build.id === "FarmPlots">> <<if !$hasFarm>><<set _isHidden = true>> <<elseif $maxPlots >= 12>><<set _isOwned = true>> <</if>> <<elseif _build.id === "EggSlots">> /* EggSlots are never owned since they can always be upgraded */ /* No lock condition — rankOne is starting rank */ <</if>> /* Set dynamic price for EggSlots before rendering */ <<if _build.id === "EggSlots">> <<set _build.price = $eggSlotUpgradeCost>> <</if>> <<if !_isHidden && ($buildCategory === "All" || _build.category === $buildCategory)>> <<set _anyDisplayed = true>> <<set _canAfford = $money >= _build.price>> <div @class="'re-card' + (_isLocked ? ' re-card-locked' : _isOwned ? ' re-card-owned' : '')"> /* Image */ <div class="re-card-img-wrap"> <<if _build.image>> [img[_build.image]] <<else>> <span class="re-card-img-placeholder">🏠</span> <</if>> <<if _isLocked>> <div class="re-card-lock-overlay">🔒</div> <<elseif _isOwned>> <div class="re-card-lock-overlay">✅</div> <</if>> </div> /* Info */ <div class="re-card-body"> <div class="re-card-name">_build.name</div> <div class="re-card-category">_build.category</div> <div class="re-card-desc">_build.description</div> <<if _isOwned>> <div class="re-card-owned-label">Already purchased</div> <<elseif _isLocked>> <div class="re-card-locked-label">🔒 Requires _build.requiredRankName</div> <<else>> <div class="re-card-price">💰 _build.price g</div> <<if _canAfford>> <<capture _build>> <<link "🏡 Purchase" "RealEstate">> <<if _build.id === "Kitchen">> <<set $money -= _build.price>> <<set $kitchenRenovated = true>> <<set $farmMessage = "Kitchen renovated! You can now cook meals.">> <<elseif _build.id === "FarmPurchase">> <<set $money -= _build.price>> <<set $hasFarm = true>> <<set $maxPlots = 3>> <<set $farmMessage = "Farm purchased! Head to your Farm to get started.">> <<elseif _build.id === "FarmPlots">> <<set $money -= _build.price>> <<set $maxPlots += 1>> <<set _newPlot = { crop: null, plantedDay: 0, lastWatered: 0, growthStage: 0, justPlanted: false }>> <<run $farmPlots.push(_newPlot)>> <<set $farmMessage = "New plot added! You now have " + $maxPlots + " plots.">> <<elseif _build.id === "EggSlots">> <<set $money -= $eggSlotUpgradeCost>> <<set $maxEggSlots += 6>> <<set $eggSlotUpgradeCost = Math.round($eggSlotUpgradeCost * 1.5)>> <<set $farmMessage = "Hatchery expanded! You now have " + $maxEggSlots + " egg slots.">> <</if>> <</link>> <</capture>> <<else>> <div class="re-card-cantafford">Not enough money</div> <</if>> <</if>> </div> </div> <</if>> <</capture>> <</for>> <<if !_anyDisplayed>> <div class="re-empty"> <p>No upgrades available in this category yet.</p> <p style="font-size:0.85em; opacity:0.7;">Rank up to unlock more!</p> </div> <</if>> </div> <<if $farmMessage>> <div class="re-purchase-confirm">$farmMessage</div> <<unset $farmMessage>> <</if>> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>> <</link>> </div> </div> <</nobr>>
<<nobr>> <div class="modal-overlay"> <div class="detail-card1"> <<link "← Back" "RealEstate">><</link>> <div class="detail-header1"> <h2>$selectedBuild.name</h2> </div> <div class="item-image1"> <div class="image-box1"> [img[$selectedBuild.image]] </div> </div> <<set _buildPrice = $selectedBuild.price>> <div class="price-display1"> $ _buildPrice </div> <div class="description-box1"> <p>$selectedBuild.description</p> </div> <div class="purchase-buttons1"> <<if $maxPlots == 12>> <div class="button-disabled"> Max plots owned! </div> <<else>> <<if $money >= _buildPrice>> <<link "Buy Now">> <<set $money -= _buildPrice>> <<if $selectedUnlock == "Kitchen">> <<set $kitchenRenovated to true>> <<elseif $selectedUnlock == "FarmPurchase">> <<set $hasFarm to true>> <<elseif $selectedUnlock == "FarmPlots">> <<set $maxPlots += 1>> <<set $lastPlotPurchaseDay = $currentDay>> <<set $farmPlots.push({id: $farmPlots.length, crop: null, plantedDay: 0, lastWatered: 0, growthStage: 0})>> <</if>> <<goto "BuildComplete">> <</link>> <<else>> <div class="button-disabled"> Not enough money! </div> <</if>> <</if>> </div> </div> </div> <</nobr>>
<<nobr>> <div style="text-align: center; padding: 50px;"> <h1 style="color: green;">✅ Purchase Complete!</h1> <p style="font-size: 1.3em; margin: 30px 0;">Your new building or renovation is waiting for you.</p> <p>Money remaining: <strong>💰 $money</strong></p> <div class="back-forth-buttons"> <div class="back-button"> <<link "Back to Office" "RealEstate">> <</link>> </div><div class="forth-button"> <<link "Go Home" "Home">> <</link>> </div> </div> </div> <</nobr>>
<<nobr>> <<if Save.browser.auto.has(0)>> <button id="btn-continue">Resume</button> <</if>> <div class="interface-container"> <div class="interface-header"> <center>DCHW</center> </div> <div class="interface-body"> <center> <span class="interface-details"> Department of Creature Health and Welfare </span> </center> <center> <strong> <p4>Welcome. Thank you for using our quick and secure online portal — because ethical breeding should be simple, safe, and supported.</p4> </strong> </center> <div class="interface-links"> <div class="interface-columns"> <div class="interface-left"> <<if $playerName is "">> ▶ <<link "Enter Name">> <<replace "#name-input">> <<textbox "$playerName" "">> <<button "Submit Name">> <<goto `passage()`>> <</button>> <</replace>> <</link>> <span id="name-input"></span> <<else>> $playerName <</if>> <br> <<if $playerPronouns is "">> ▶ <<link "Enter Pronouns">> <<replace "#pronouns-input">> <br> <<listbox "$playerPronouns">> <<option "He/Him">> <<option "They/Them">> <<option "She/Her">> <</listbox>> <br> <<button "Submit Pronouns">> <<goto `passage()`>> <</button>> <</replace>> <</link>> <span id="pronouns-input"></span> <<else>> $playerPronouns <</if>> <br> <<if $playerBirthday is "">> ▶ <<link "Enter Birthday">> <<replace "#birthday-input">> <br> Please select your birth season: <br> <<listbox "$playerBirthSeason">> <<option "Spring">> <<option "Summer">> <<option "Fall">> <<option "Winter">> <</listbox>> <br> Please enter your birth date (1-31): <<textbox "$playerBirthDay" "1">> <<if $playerBirthDay >=1 and $playerBirthday <= 31>> <br> <<button "Submit Birthday">> <<set $playerBirthday = $playerBirthSeason + " " + $playerBirthDay>> <<goto `passage()`>> <</button>> <<else>> Please enter a date between 1 and 31. <</if>> <</replace>> <</link>> <span id="birthday-input"></span> <<else>> $playerBirthday <</if>> <br> </div> <div class="interface-right"> <<if $playerPronouns is "" || $playerName is "" || $playerBirthday is "">> <div class="error-link"> ERROR: Please finish filling out your personal info before continuing. </div> <<else>> <p4>Click to continue.</p4> ▶ <<link "Receive License" "LoadingLicense">> <</link>> <</if>> </div> </div> </div> </div> <</nobr>>
<<nobr>> <span class="printLicense"> <center> <div class="trainer-card"> <div class="trainer-card-holo"></div> <div class="trainer-card-inner"> <div class="trainer-card-left"> <div class="trainer-stamp"> <div class="trainer-stamp-inner"> <div class="trainer-stamp-logo">🐾</div> <div class="trainer-stamp-text">DCHW</div> </div> </div> </div> <div class="trainer-card-right"> <div class="trainer-card-title">Creature Breeder License</div> <div class="trainer-card-name">$playerName</div> <div class="trainer-card-sub">$playerPronouns</div> <div class="trainer-card-divider"></div> <div class="trainer-card-stats"> <div class="trainer-stat"> <span class="trainer-stat-label">Birthday</span> <span class="trainer-stat-value">$playerBirthday</span> </div> <div class="trainer-stat"> <span class="trainer-stat-label">Rank</span> <span class="trainer-stat-value">$playerRank.name</span> </div> <div class="trainer-stat"> <span class="trainer-stat-label">XP</span> <span class="trainer-stat-value">$playerXP</span> </div> </div> <div class="trainer-card-footer">DEPT. OF CREATURE HEALTH & WELFARE</div> </div> </div> </div> </center> <div class="back-forth-buttons"> <div class="forth-button"> <<link "Continue" "Home">> <</link>> </div> </div> </span> <</nobr>>
<<set $loginRewards = { currentDay: 0, lastClaimTime: 0, completed: false, pendingClaim: false }>> <<set $mailbox = []>> <<set $fishingrodUnlocked to false>> <<set $wormbaitUnlocked to false>> <<set $lanternUnlocked to false>> <<set $firstSell to false>> <<set $firstRequest to false>> <<set $firstCook to false>> <<set $firstSlop to false>> <<set $firstFreelance to false>> <<set setup.playerRanks = { "rankOne": { id: "rankOne", name: "Novice Nester", xp: 0, xpRequired: 200, description: "Congratulations on receiving your breeding license! Explore and complete activities to rank up.", next: "rankTwo", unlocks: function() { }, unlocksText: "" }, "rankTwo": { id: "rankTwo", name: "Up-and-Coming Apprentice", xp: 200, xpRequired: 500, description: "Welcome to Rank Two.", next: "rankThree", unlocks: function() { var v = State.variables; v.maxFreelancingAttempts++; v.fishingrodUnlocked = true; v.wormbaitUnlocked = true; }, unlocksText: "//Buy Fishing Rod and Worm Bait, +1 Freelancing Attempt a day//" }, "rankThree": { id: "rankThree", name: "Certified Caretaker", xp: 500, xpRequired: 900, description: "Welcome to Rank Three.", next: "rankFour", unlocks: function() { var v = State.variables; v.maxFreelancingAttempts++; }, unlocksText: "//Auto Genetic Testing for Eggs, +1 Freelancing Attempt a day//" }, "rankFour": { id: "rankFour", name: "Tactful Technician", xp: 900, xpRequired: 1450, description: "Welcome to Rank Four.", next: "rankFive", unlocks: function() { var v = State.variables; v.maxFreelancingAttempts++; v.kitchenUnlocked = true; v.lanternUnlocked = true; }, unlocksText: "//Purchase the Kitchen renovation from Real Estate, Buy the Lantern, +1 Freelancing Attempt a day//" }, "rankFive": { id: "rankFive", name: "Bountiful Breeder", xp: 1450, xpRequired: 2050, description: "Welcome to Rank Five.", next: "rankSix", unlocks: function() { var v = State.variables; v.maxFreelancingAttempts++; }, unlocksText: "//+1 Freelancing Attempt a day//" }, "rankSix": { id: "rankSix", name: "Trained Expert", xp: 2050, xpRequired: 2050, description: "Welcome to Rank Six.", next: null, unlocks: function() { var v = State.variables; v.farmUnlocked = true; v.maxFreelancingAttempts++; }, unlocksText: "//Purchase Farmlands from Real Estate, +1 Freelancing Attempt a day//" } }>> <<set $breedingLicense to true>> <<set $playerRank to setup.playerRanks.rankOne>> <<set $playerXP to 0>> <<set $tutorialQuests = { dismissed: false, open: false, tracked: null, startTime: Date.now(), quests: { feedCreature: { label: "Feed a Creature", desc: "Your critters need food to avoid starvation and neglect, which can lead to running away. Feed all creatures in Home or feed one in its Profile.", accepted: false, complete: false, xp: 20, money: 50 }, careCreature: { label: "Care for a Creature", desc: "Creatures need regular grooming and attention to avoid neglect. Care for all of your critters in Home.", accepted: false, complete: false, xp: 20, money: 50 }, buyFood: { label: "Buy Food", desc: "Visit the markets from the map in the bottom toolbar and go to the Critter Center. Purchase Creature Chow for your creatures to eat.", accepted: false, complete: false, xp: 30, money: 75 }, endDay: { label: "End Your First Day", desc: "Time moves in real-time. Check in after a day!", accepted: true, complete: false, xp: 30, money: 75 }, breeding: { label: "Breed Your Creatures", desc: "Tap the map on the bottom toolbar and visit the Breeding Barn. Breed a male and female creature.", accepted: false, complete: false, xp: 40, money: 100 }, fulfillRequest: { label: "Fulfill a Request", desc: "Head to the map in the bottom toolbar and check out the Request Board. Fulfill a request.", accepted: false, complete: false, xp: 60, money: 150 } } }>>
<<nobr>> <<if $mailbox.length > 0>> <<for _i = 0; _i < $mailbox.length; _i++>> <<capture _i>> <<set $mailbox[_i].read = true>> <div class="letter-container"> <div class="letter-box"> <div class="letter-heading"> $mailbox[_i].title </div> <div class="letter-message"> $mailbox[_i].message </div> </div> </div> <div style="margin-top: 40px;"> <div class="back-forth-buttons"> <div class="forth-button"> <<link "Delete">> <<run $mailbox.deleteAt(_i)>> <<goto "Mailbox">> <</link>> </div> </div> </div> <hr> <</capture>> <</for>> <<else>> <div class="empty-message">Your mailbox is empty.</div> <</if>> <div style="margin-top: 40px;"> <div class="back-forth-buttons"> <div class="back-button"> <<link "← Back" "Home">> <</link>> </div> </div> </div> <</nobr>>
<center><div class="story-icon"><img src="https://i.imgur.com/30UEn7N.png"></div></center>
<<nobr>> <<if ndef $locationsTab>><<set $locationsTab to "plaza">><</if>> <div class="locations-tabs"> <<if $locationsTab is "plaza">> <span class="active-tab">Plaza</span> <<else>> <<link "Plaza">> <<set $locationsTab to "plaza">> <<refresh>> <</link>> <</if>> <<if $locationsTab is "nature">> <span class="active-tab">Nature</span> <<else>> <<link "Nature">> <<set $locationsTab to "nature">> <<refresh>> <</link>> <</if>> <<if $locationsTab is "critterzone">> <span class="active-tab">Critters</span> <<else>> <<link "Critters">> <<set $locationsTab to "critterzone">> <<refresh>> <</link>> <</if>> </div> <<if $locationsTab is "plaza">> /* ── THE PLAZA ── */ <div class="locations-grid"> <div class="loc-card" id="loc-critter-center"> <img src="https://i.imgur.com/rJwhAt0.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Critter Center</div> <div class="loc-desc">Buy critters and shop all necessary goods for a breeding technician.</div> <<link "Shop →" "Shop">><</link>> </div> </div> <div class="loc-card"> <img src="https://i.imgur.com/koNW8yx.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Sell Critters</div> <div class="loc-desc">Sell your creatures for a profit. Different factors influence each creature's value.</div> <<link "Sell →" "SellCreatures">><</link>> </div> </div> <div class="loc-card" id="loc-request-board"> <img src="https://i.imgur.com/rqvSHBV.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Request Board</div> <div class="loc-desc">Fulfill unique requests for gold, experience, or special gifts.</div> <<link "Requests →" "RequestBoard">><</link>> </div> </div> <div class="loc-card"> <img src="" class="loc-img loc-img--placeholder"> <div class="loc-body"> <div class="loc-title">Pawn Shop</div> <div class="loc-desc">Sell your excess goods and items here.</div> <<link "Pawn Shop →" "PawnShop">><</link>> </div> </div> <div class="loc-card"> <img src="https://i.imgur.com/vWOcl39.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Real Estate</div> <div class="loc-desc">Purchase land and upgrades to unlock new features and progress gameplay.</div> <<link "Browse →" "RealEstate">><</link>> </div> </div> <div class="loc-card"> <img src="https://i.imgur.com/meix5Fv.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Vet Clinic</div> <div class="loc-desc">Care for all critters, including emergency services.</div> <<link "Visit →" "VetClinic">><</link>> </div> </div> </div> <<elseif $locationsTab is "nature">> /* ── EXPLORE NATURE ── */ <div class="locations-grid"> <<if $hasFarm>> <div class="loc-card"> <img src="https://i.imgur.com/bkYTBN7.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Farmlands</div> <div class="loc-desc">An excellent source of produce for cooking once renovated.</div> <<link "Farm →" "Farm">><</link>> </div> </div> <<else>> <div class="loc-card loc-card--disabled"> <img src="https://i.imgur.com/bkYTBN7.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Farmlands</div> <div class="loc-desc">Unlock via Real Estate to grow produce for cooking.</div> <span class="loc-wip">🔒 Locked</span> </div> </div> <</if>> <div class="loc-card"> <img src="https://i.imgur.com/pbCD0ND.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">The Lake</div> <div class="loc-desc">Buy a fishing rod to unlock fishing at the docks.</div> <<link "Docks →" "TheLake">><</link>> </div> </div> <div class="loc-card"> <img src="https://i.imgur.com/jHlCFmZ.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Cemetery</div> <div class="loc-desc">View creatures who have passed on.</div> <<link "Visit →" "Memorial">><</link>> </div> </div> </div> <<elseif $locationsTab is "critterzone">> /* ── CRITTER ZONE ── */ <div class="locations-grid"> <div class="loc-card"> <img src="https://i.imgur.com/ehdX3Yl.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Hatchery</div> <div class="loc-desc">Eggs don't need feeding or care until hatched.</div> <<link "Eggs →" "ViewEggs">><</link>> </div> </div> <div class="loc-card"> <img src="https://i.imgur.com/fpJrvdm.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Nursery</div> <div class="loc-desc">Babies require much more attention than an egg!</div> <<link "Babies →" "ViewBabies">><</link>> </div> </div> <div class="loc-card"> <img src="https://i.imgur.com/yTPO88Y.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">The Corral</div> <div class="loc-desc">Customize your critters' names via their profile link.</div> <<link "Adults →" "ViewAdults">><</link>> </div> </div> <div class="loc-card" id="loc-breeding-barn"> <img src="https://i.imgur.com/eijnFKw.png" class="loc-img"> <div class="loc-body"> <div class="loc-title">Breeding Barn</div> <div class="loc-desc">Critters have a higher chance of more offspring when fertile.</div> <<link "Breed →" "Breeding">><</link>> </div> </div> <div class="loc-card"> <img src="" class="loc-img loc-img--placeholder"> <div class="loc-body"> <div class="loc-title">Collection</div> <div class="loc-desc">View your collection here.</div> <<link "Collection →" "CollectionMenu">><</link>> </div> </div> </div> <</if>> <</nobr>>
<<nobr>> <div style="text-align: center; padding: 50px;"> <h1 style="color: green;">✅ Purchase Complete!</h1> <p style="font-size: 1.1em; margin: 20px 0; color: var(--dark-text);">You bought:</p> <ul style="list-style: none; padding: 0; margin: 0 0 20px 0;"> <<for _si = 0; _si < $purchaseSummary.length; _si++>> <li style="font-size: 1.1em; margin: 6px 0;">✔ $purchaseSummary[_si]</li> <</for>> </ul> <p>Money remaining: <strong>💰 $money</strong></p> <div style="margin-top: 40px;"> <div class="back-forth-buttons"> <div class="back-button"> <<link "To Shop" "Shop">><</link>> </div> <div class="forth-button"> <<link "Go Home" "Home">> <</link>> </div> </div> </div> </div> <</nobr>>
<<nobr>> <<if $pawnCategory == undefined>><<set $pawnCategory = "All">><</if>> <<if !$shopCart>><<set $shopCart = []>><</if>> /* ── BANNER ── */ <div class="shop-banner"> <h5 style="margin: 0 0 6px 0;">🏪 Pawn Shop</h5> <p style="margin: 0; opacity: 0.9;">Your Money: <strong>💰 $money g</strong></p> </div> /* ── CATEGORY PILLS ── */ <div class="shop-categories-scroll"> <<link "All">><<set $pawnCategory = "All">><<goto "PawnShop">><</link>> <<link "Consumables">><<set $pawnCategory = "Consumables">><<goto "PawnShop">><</link>> <<link "Ingredients">><<set $pawnCategory = "Ingredients">><<goto "PawnShop">><</link>> <<link "Fish">><<set $pawnCategory = "Fish">><<goto "PawnShop">><</link>> <<link "Seeds">><<set $pawnCategory = "Seeds">><<goto "PawnShop">><</link>> <<link "Items">><<set $pawnCategory = "Items">><<goto "PawnShop">><</link>> <<link "Fishing">><<set $pawnCategory = "Fishing">><<goto "PawnShop">><</link>> <<link "Accessories">><<set $pawnCategory = "Accessories">><<goto "PawnShop">><</link>> </div> /* ── ITEM LIST ── */ <div class="shop-item-list"> <<for _key, _item range setup.items>> <<capture _item>> <<if _item.category !== "Creatures" && _item.id !== "FishingRod" && _item.id !== "Lantern">> <<set _ownedQty = $inventory[_item.id] ?? 0>> <<if _ownedQty > 0 && ($pawnCategory === "All" || _item.category === $pawnCategory)>> <<set _cartProfit = _item.baseSell>> <<capture _cartProfit>> <div class="shop-list-card"> <div class="shop-list-img-wrap"> <<link [img[_item.image]]>> <<set _existingIndex = -1>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<if $shopCart[_ci].id == _item.id>> <<set _existingIndex = _ci>> <</if>> <</for>> <<if _existingIndex == -1>> <<run $shopCart.push({ id: _item.id, name: _item.name, image: _item.image, price: _cartProfit, quantity: 1 })>> <</if>> <<goto "PawnShop">> <</link>> </div> <div class="shop-list-body"> <div class="shop-list-name">_item.name</div> <div class="shop-list-price">💰 _cartProfit g each</div> <div class="shop-list-rarity"> <<if _item.rarity === "Common">><span style="color:#95a5a6;">Common</span> <<elseif _item.rarity === "Uncommon">><span style="color:#1bd602;">Uncommon</span> <<elseif _item.rarity === "Rare">><span style="color:#0070dd;">Rare</span> <<elseif _item.rarity === "Epic">><span style="color:#a335ee;">Epic</span> <<elseif _item.rarity === "Legendary">><span style="color:#ff8000;">Legendary</span> <</if>> </div> <div class="shop-list-add">Owned: <strong>_ownedQty</strong> · Tap image to add</div> </div> </div> <</capture>> <</if>> <</if>> <</capture>> <</for>> </div> /* ── FLOATING SELL BUTTON ── */ <<set _cartCount = 0>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _cartCount += $shopCart[_ci].quantity>> <</for>> <button class="cart-fab pawn-fab" onclick="document.getElementById('pawn-modal').style.display='flex'"> 🛒 To Sell <<if _cartCount > 0>><span class="cart-fab-badge">_cartCount</span><</if>> </button> /* ── SELL MODAL ── */ <div class="cart-modal" id="pawn-modal" style="display:none;"> <div class="cart-modal-content"> <div class="cart-modal-header"> <h3>🛒 To Sell</h3> <button class="cart-modal-close" onclick="document.getElementById('pawn-modal').style.display='none'">✕</button> </div> <<if $shopCart.length == 0>> <p style="color:var(--mid-text); font-style:italic; text-align:center;">Nothing queued to sell yet!</p> <<else>> <<set _cartTotal = 0>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _cartTotal += $shopCart[_ci].price * $shopCart[_ci].quantity>> <</for>> /* Validate quantities */ <<set _canSell = true>> <<set _overLimitName = "">> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _cartEntry = $shopCart[_ci]>> <<set _foundOwned = $inventory[_cartEntry.id] ?? 0>> <<if _cartEntry.quantity > _foundOwned>> <<set _canSell = false>> <<set _overLimitName = _cartEntry.name>> <</if>> <</for>> <div class="cart-items"> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<capture _ci>> <<set _entry = $shopCart[_ci]>> <<set _lineTotal = _entry.price * _entry.quantity>> <div class="cart-line"> <div class="cart-line-info"> <<= '<img src="' + _entry.image + '" style="width:36px;height:36px;object-fit:contain;margin-right:8px;vertical-align:middle;">'>> <span>_entry.name</span> </div> <div class="cart-line-controls"> <<link "−">> <<if $shopCart[_ci].quantity > 1>> <<set $shopCart[_ci].quantity -= 1>> <<else>> <<run $shopCart.splice(_ci, 1)>> <</if>> <<goto "PawnShop">> <</link>> <<= '<input type="number" class="macro-numberbox" value="' + _entry.quantity + '" min="1" onchange="var idx=' + _ci + ';var val=parseInt(this.value,10);if(!val||val<1){SugarCube.State.variables.shopCart.splice(idx,1);}else{SugarCube.State.variables.shopCart[idx].quantity=val;}SugarCube.Engine.play(\'PawnShop\');">'>> <<link "+">> <<set $shopCart[_ci].quantity += 1>> <<goto "PawnShop">> <</link>> <span class="cart-line-price">💰 _lineTotal g</span> <<link "✕">> <<run $shopCart.splice(_ci, 1)>> <<goto "PawnShop">> <</link>> </div> </div> <</capture>> <</for>> </div> <div class="cart-total">You'll receive: 💰 _cartTotal g</div> <<if !_canSell>> <div class="button-disabled">Not enough _overLimitName to sell!</div> <<else>> <<link "✅ Sell All">> <<set $money += _cartTotal>> <<set $sellSummary = []>> <<for _ci = 0; _ci < $shopCart.length; _ci++>> <<set _entry = $shopCart[_ci]>> <<set $inventory[_entry.id] -= _entry.quantity>> <<run $sellSummary.push(_entry.quantity + "x " + _entry.name)>> <</for>> <<for _key, _val range $inventory>> <<if _val <= 0>><<run delete $inventory[_key]>><</if>> <</for>> <<set $shopCart = []>> <<goto "SellCheckoutComplete">> <</link>> <</if>> <</if>> </div> </div> /* ── BACK BUTTON ── */ <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back" `previous()`>><</link>> </div> </div> <</nobr>>
<<nobr>> <<widget "comboKey">> <<set _key = _args[0] + "_" + _args[1]>> <</widget>> <<widget "hasCombo">> <<set _key = _args[0] + "_" + _args[1] + "_" + _args[2] + "_" + _args[3] + "_" + _args[4]>> <<set _owned = $discoveredCombos.includes(_key)>> <</widget>> <<widget "recordCombo">> <<run setup.recordCombo(_args[0])>> <</widget>> <</nobr>>
<<nobr>> <<if $activeSpecies is "">> <<for _species, _data range setup.creatureTemplates>> <<if $activeSpecies is "">> <<set $activeSpecies to _species>> <</if>> <</for>> <</if>> <<set _data = setup.creatureTemplates[$activeSpecies]>> <<set _sheet = _data.avatars>> <div id="collection-menu"> <h5 style="font-size: 30px; font-family: 'Fontdiner Swanky', serif;">Your Collection🃏</h5> <div class="tab-container"> <div class="tab-bar"> <<for _tabSpecies, _tabData range setup.creatureTemplates>> <<capture _tabSpecies>> <<link _tabSpecies>> <<set $activeSpecies = _tabSpecies>> <<replace "#collection-menu">><<include "CollectionMenu">><</replace>> <</link>> <</capture>> <</for>> </div> </div> <p3 style="display: block; text-align: center; font-size: 24px; border-bottom: none; font-weight: bold; font-family: 'Chewy', system-ui; margin-bottom: -20px;">$activeSpecies</p3> <<for _gender range ["Male", "Female"]>> <<capture _gender, _data, _sheet>> <<set _genderLower = _gender.toLowerCase()>> <h3 style= "margin-left: 10px;"><<= _gender>><<if _gender is "Male">> ♂<<else>> ♀<</if>></h3> <div class="combo-grid"> <<for _size range _data.possibleSizes>> <<capture _size, _data, _sheet, _gender, _genderLower>> <<if _size === "large">> <<set _dimensions = "240px">> <<set _scale = "0.333">> <<elseif _size === "medium">> <<set _dimensions = "160px">> <<set _scale = "0.5">> <<else>> <<set _dimensions = "80px">> <<set _scale = "1">> <</if>> <<for _comboKey, _colIndex range _data.spriteColumns>> <<capture _comboKey, _colIndex, _data, _sheet, _gender, _genderLower, _size, _dimensions, _scale>> <<set _parts = _comboKey.split("_")>> <<set _color = _parts[0]>> <<set _pattern = _parts[1]>> <<hasCombo $activeSpecies _color _pattern _size _gender>> <div class="combo-card"> <<if _owned>> <<set _spriteSheet = _sheet[_genderLower].patternSpriteSheets[_size]>> <<set _colorPattern = setup.getSpriteKey($activeSpecies, _color, _pattern)>> <<set _col = _data.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _col = _data.spriteColumns[_data.colorDominance[0] + "_" + _data.patternDominance[0]]>> <</if>> <<if _size === "large">> <<set _xPos = _col * -240>> <<elseif _size === "medium">> <<set _xPos = _col * -160>> <<else>> <<set _xPos = _col * -80>> <</if>> <div style="width: 80px; height: 80px; overflow: hidden; flex-shrink: 0;"> <div @style="'transform: scale(' + _scale + '); transform-origin: top left;'"> <div class="creature-layers" @style="'width: ' + _dimensions + '; height: ' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _spriteSheet + '); background-position: ' + _xPos + 'px 0px; width: ' + _dimensions + '; height: ' + _dimensions + ';'"> </div> </div> </div> </div> <<else>> <<set _silhouette = _data.silhouettes[_genderLower][_size]>> <img class="silhouette" @src="_silhouette" alt="Locked" style="width: 80px; height: 80px;"> <</if>> <<if _owned>> <p><<= _color>> / <<= _pattern>> / <<= _size>></p> <<else>> <p>???</p> <</if>> </div> <</capture>> <</for>> <</capture>> <</for>> </div> <</capture>> <</for>> </div> <</nobr>>
<<nobr>> <div class="gig-wrap"> <div class="sm-tutorial-box"> <p style="display: block; text-align: center; font-size: 20px; font-family: 'Fontdiner Swanky, cursive; color: var(--teal); font-size: 24px;"><strong>📱 Social Media Manager</strong></p> <p>You've taken on a social media management gig for a small roster of local brands. Your job is to keep their online presence consistent, on-schedule, and true to their voice.</p> <p>Here's what you'll be handling:</p> <ul> <li><strong>Brand matching</strong> — identify which post belongs to which client.</li> <li><strong>Scheduling</strong> — choose the best time to publish a post for maximum reach.</li> <li><strong>Captions</strong> — select the copy that best fits a brand's tone.</li> <li><strong>Content review</strong> — catch anything that doesn't belong in a brand's feed.</li> </ul> <p>There are <strong>5 tasks</strong> per session. Each correct answer earns <strong>$20</strong>, and you'll always receive at least <strong>$5</strong> per task. Good luck!</p> </div> <<if $smCurrentQ is -1>> <<smBuildSession>> <<link "Begin gig" "SMGig">><</link>> <<else>> <<set _q to $smSessionQuestions[$smCurrentQ]>> <<if $gigLastResult is "correct">> <div class="gig-result"> <p class="result-correct">✅ <strong>+$20!</strong> <<= _q.win>></p> </div> <<elseif $gigLastResult is "wrong">> <div class="gig-result"> <p class="result-wrong">❌ <strong>+$5.</strong> <<= _q.lose>></p> </div> <</if>> <<if $smCurrentQ lt 5>> <<set _q to $smSessionQuestions[$smCurrentQ]>> <div class="gig-question"> <p class="gig-progress">Task <<= $smCurrentQ + 1>> of 5</p> <<if _q.type is "brand">> <h3>🏷️ Brand Match</h3> <<elseif _q.type is "schedule">> <h3>🕐 Scheduling</h3> <<elseif _q.type is "caption">> <h3>✍️ Best Caption</h3> <<else>> <h3>🚩 Spot the Problem</h3> <</if>> <p><<= _q.prompt>></p> <<if _q.post isnot null>> <div class="post-preview"><<= _q.post>></div> <</if>> <<set _correct to _q.correct>> <<set _qid to _q.id>> <<set _win to _q.win>> <<set _lose to _q.lose>> <<link _q.options[0]>> <<if 0 is _correct>> <<set $gigLastResult to "correct">> <<set $gigScore += 20>> <<else>> <<set $gigLastResult to "wrong">> <<set $gigScore += 5>> <</if>> <<set $smCurrentQ += 1>> <<goto "SMGig">> <</link>> <br><br> <<link _q.options[1]>> <<if 1 is _correct>> <<set $gigLastResult to "correct">> <<set $gigScore += 20>> <<else>> <<set $gigLastResult to "wrong">> <<set $gigScore += 5>> <</if>> <<set $smCurrentQ += 1>> <<goto "SMGig">> <</link>> <br><br> <<link _q.options[2]>> <<if 2 is _correct>> <<set $gigLastResult to "correct">> <<set $gigScore += 20>> <<else>> <<set $gigLastResult to "wrong">> <<set $gigScore += 5>> <</if>> <<set $smCurrentQ += 1>> <<goto "SMGig">> <</link>> </div> <<else>> <<set $smLastSession to $smSessionQuestions.map(function(q) { return q.id; })>> <<set $smCurrentQ to -1>> <<set $activeGig to "">> <<set $freelancingAttempts += 1>> <<set $money += $gigScore>> <<goto "SMResults">> <</if>> <</if>> </div> <</nobr>>
<<nobr>> <div class="gig-wrap"> <div class="gig-results-box"> <h2 class="gig-title">📊 Gig Complete!</h2> <<if $gigScore gte 80>> <p>🌟 Outstanding work! You nailed this gig.</p> <<elseif $gigScore gte 60>> <p>👍 Pretty solid! A few slip-ups but your clients are happy enough.</p> <<elseif $gigScore gte 40>> <p>😬 Rough around the edges. The brands noticed, but they're keeping you on.</p> <<else>> <p>💀 Yikes. Next time, maybe read the brief first.</p> <</if>> <p class="gig-score-display">You earned: <strong>$<<= $gigScore>></strong> out of $100</p> <p>Your balance: <strong>$<<= $money>></strong></p> <hr> <p class="result-breakdown"><strong>Score breakdown:</strong><br> ✅ Correct answers (+$20 each)<br> ❌ Wrong answers (+$5 each)</p> <<link "Go Home" "Home">> <</link>> </div> </div> <</nobr>>
<<nobr>> <div class="gig-wrap"> <div class="sm-tutorial-box"> <h2 class="gig-title">⏸️ Gig In Progress</h2> <p>You have an unfinished gig. Would you like to pick up where you left off, or start over with a new one?</p> <p><em>Note: restarting will forfeit any earnings from your current session.</em></p> <<link "Resume my gig">> <<goto $activeGig>> <</link>> <br><br> <<link "Start a new gig">> <<set $smCurrentQ to -1>> <<set $gigScore to 0>> <<set $gigLastResult to "">> <<set $photosCompleted to 0>> <<set $photosMoney to 0>> <<set $activeGig to "">> <<set _gigPool to ["SMGig", "Composition"]>> <<set $activeGig to _gigPool.random()>> <<goto $activeGig>> <</link>> </div> </div> <</nobr>>
<<nobr>> <div style="text-align: center; padding: 50px;"> <h1 style="color: green;">✅ Sale Complete!</h1> <p style="font-size: 1.1em; margin: 20px 0; color: var(--dark-text);">You sold:</p> <ul style="list-style: none; padding: 0; margin: 0 0 20px 0;"> <<for _si = 0; _si < $sellSummary.length; _si++>> <li style="font-size: 1.1em; margin: 6px 0;">✔ $sellSummary[_si]</li> <</for>> </ul> <p>Current Funds: <strong>💰 $money</strong></p> <div style="margin-top: 40px;"> <div class="back-forth-buttons"> <div class="back-button"> <<link "Sell More" "PawnShop">><</link>> </div> <div class="forth-button"> <<link "Go Home" "Home">><</link>> </div> </div> </div> </div> <</nobr>>
<<nobr>> <<if $logosCompleted gte 3>> <p><strong>Logo Design Session Complete!</strong></p> <p>You've finished designing 3 logos today.</p> <p><strong>Total earned:</strong> $<<print $logosMoney>></p> <p>Time to clean up and return to other responsibilities.</p> <p><<link "Wrap Up" "Home">> <<set $activeGig to "">> <<set $money += $logosMoney>> <<set $freelancingAttempts += 1>> <<set $logosCompleted to 0>> <<set $logosMoney to 0>> <<if $firstFreelance is false>> <<set $firstFreelance to true>> <<addXP 30>> <</if>> <</link>></p> <<else>> <<set $currentClient to $clients.random()>> <p style="display: block; text-align: center; font-size: 20px;"><strong>Logo Design Gig</strong> - Logo <<print $logosCompleted + 1>>/3</p> <p style="display: block; text-align: center; font-family: 'Quicksand', serif; font-size: 16px; color: var(--mid-text); font-weight: bold; margin: 10px;">Please review each client brief carefully and select each matching design element to create the client's perfect logo!</p> <br> <div class="back-forth-buttons"> <div class="back-button"> <<link "Quit" "Home">><</link>> </div> <div class="forth-button"> <<link "Continue" "LogoShape">><</link>> </div> </div> <</if>> <</nobr>>
<<nobr>> <<set $correctShape to $currentClient.shape.random()>> <<set $tempShapes to clone($allShapes)>> <<for _shape range $currentClient.shape>> <<run $tempShapes.delete(_shape)>> <</for>> <<set _shapeOne to $tempShapes.pluck()>> <<set _shapeTwo to $tempShapes.pluck()>> <<set _shapeThree to $tempShapes.pluck()>> <<set $shapeOptions to [_shapeOne, _shapeTwo, _shapeThree, $correctShape]>> <<run $shapeOptions.shuffle()>> <center><strong><p style="font-size: 24px; font-family: 'Lilita One', serif; color: var(--mid-text); margin-bottom: 0;">Client Briefing</p></strong></center> <div class="product-box"> <p style="text-align: left; font-size: 18px; line-height: 1.5em; font-family: 'Quicksand', serif; color: var(--mid-text);"><strong>Current Client:</strong> <<print $currentClient.name>> <br> <strong>Product Type:</strong> <<print $currentClient.type>> <br> <strong>Desired Vibe:</strong> <<print $currentClient.vibe>> <br> <strong>Prompt:</strong> <<print $currentClient.hint>> </p> </div> <center><strong><p style="font-size: 24px; font-family: 'Lilita One', serif; color: var(--mid-text); margin-bottom: 0;">Logo Shape</p></strong></center> <p style="margin-left: 10px; font-size: 16px; color: var(--mid-text);"><em>Choose the logo's <strong>shape</strong>:</em></p> <p style="margin-left: 10px; font-weight: bold; line-height: 2.5em;"> <<for _shapeOption range $shapeOptions>> <<capture _shapeOption>> ▶ <<link _shapeOption>> <<if _shapeOption is $correctShape>> <<set $logoScore += 1>> <<set $logosMoney += 10>> <<else>> <<set $logosMoney += 2>> <</if>> <<set $playerShape to _shapeOption>> <<goto "LogoColorPalette">> <</link>> <</capture>> <br> <</for>> </p> <</nobr>>
<<nobr>> <<set $correctColorPalette to $currentClient.colorPalette.random()>> <<set $tempColorPalettes to clone($allColorPalettes)>> <<for _colorPalette range $currentClient.colorPalette>> <<run $tempColorPalettes.delete(_colorPalette)>> <</for>> <<set _colorPaletteOne to $tempColorPalettes.pluck()>> <<set _colorPaletteTwo to $tempColorPalettes.pluck()>> <<set _colorPaletteThree to $tempColorPalettes.pluck()>> <<set $colorPaletteOptions to [_colorPaletteOne, _colorPaletteTwo, _colorPaletteThree, $correctColorPalette]>> <<run $colorPaletteOptions.shuffle()>> <center><strong><p style="font-size: 24px; font-family: 'Lilita One', serif; color: var(--mid-text); margin-bottom: 0;">Client Briefing</p></strong></center> <div class="product-box"> <p style="text-align: left; font-size: 18px; line-height: 1.5em; font-family: 'Quicksand', serif; color: var(--mid-text);"><strong>Current Client:</strong> <<print $currentClient.name>> <br> <strong>Desired Vibe:</strong> <<print $currentClient.vibe>> <br> <strong>Prompt:</strong> <<print $currentClient.hint>> </p> </div> <center><strong><p style="font-size: 24px; font-family: 'Lilita One', serif; color: var(--mid-text); margin-bottom: 0;">Logo Color Palette</p></strong></center> <p style="margin-left: 10px; font-size: 16px; color: var(--mid-text);"><em>Choose the logo's <strong>color palette</strong>:</em></p> <p style="margin-left: 10px; font-weight: bold; line-height: 2.5em;"> <<for _colorPaletteOption range $colorPaletteOptions>> <<capture _colorPaletteOption>> ▶ <<link _colorPaletteOption>> <<if _colorPaletteOption is $correctColorPalette>> <<set $logoScore += 1>> <<set $logosMoney += 10>> <<else>> <<set $logosMoney += 2>> <</if>> <<set $playerColorPalette to _colorPaletteOption>> <<goto "LogoFontStyle">> <</link>> <</capture>> <br> <</for>> </p> <</nobr>>
<<nobr>> <<set $correctFontStyle to $currentClient.fontStyle.random()>> <<set $tempFontStyles to clone($allFontStyles)>> <<for _fontStyle range $currentClient.fontStyle>> <<run $tempFontStyles.delete(_fontStyle)>> <</for>> <<set _fontStyleOne to $tempFontStyles.pluck()>> <<set _fontStyleTwo to $tempFontStyles.pluck()>> <<set _fontStyleThree to $tempFontStyles.pluck()>> <<set $fontStyleOptions to [_fontStyleOne, _fontStyleTwo, _fontStyleThree, $correctFontStyle]>> <<run $fontStyleOptions.shuffle()>> <center><strong><p style="font-size: 24px; font-family: 'Lilita One', serif; color: var(--mid-text); margin-bottom: 0;">Client Briefing</p></strong></center> <div class="product-box"> <p style="text-align: left; font-size: 18px; line-height: 1.5em; font-family: 'Quicksand', serif; color: var(--mid-text);"><strong>Current Client:</strong> <<print $currentClient.name>> <br> <strong>Desired Vibe:</strong> <<print $currentClient.vibe>> <br> <strong>Prompt:</strong> <<print $currentClient.hint>> </p> </div> <center><strong><p style="font-size: 24px; font-family: 'Lilita One', serif; color: var(--mid-text); margin-bottom: 0;">Logo Font Style</p></strong></center> <p style="margin-left: 10px; font-size: 16px; color: var(--mid-text);"><em>Choose the logo's <strong>font style</strong>:</em></p> <p style="margin-left: 10px; font-weight: bold; line-height: 2.5em;"> <<for _fontStyleOption range $fontStyleOptions>> <<capture _fontStyleOption>> ▶ <<link _fontStyleOption>> <<if _fontStyleOption is $correctFontStyle>> <<set $logoScore += 1>> <<set $logosMoney += 10>> <<else>> <<set $logosMoney += 2>> <</if>> <<set $playerFontStyle to _fontStyleOption>> <<goto "LogoComplete">> <</link>> <</capture>> <br> <</for>> </p> <</nobr>>
<<nobr>> <p style="display: block; text-align: center; font-size: 20px;"><strong>Logo Design Complete</strong> </p> <div class="product-box"> <p style="text-align: left; font-size: 18px; line-height: 1.5em; font-family: 'Quicksand', serif; color: var(--mid-text);"> <strong>Selected Shape:</strong> <<print $playerShape>> <<if $playerShape is $correctShape>>✅ <br><em><<print $currentClient.correctShape>></em><<else>>🚫 <br><em><<print $currentClient.incorrectShape>></em><</if>> <br> <strong>Selected Color Palette:</strong> <<print $playerColorPalette>> <<if $playerColorPalette is $correctColorPalette>>✅ <br><em><<print $currentClient.correctColorPalette>></em><<else>>🚫 <br><em><<print $currentClient.incorrectColorPalette>></em><</if>> <br> <strong>Selected Font Style:</strong> <<print $playerFontStyle>> <<if $playerFontStyle is $correctFontStyle>>✅ <br><em><<print $currentClient.correctFontStyle>></em><<else>>🚫 <br><em><<print $currentClient.incorrectFontStyle>></em><</if>> </p> </div> <p style="margin-left: 10px; font-size: 16px; color: var(--mid-text);"> <strong>Score:</strong> $logoScore / 3 <br> <strong>Money Earned So Far:</strong> $logosMoney</p> <div class="back-forth-buttons"> <div class="center-button"> <<link "Continue" "LogoDesign">> <<set $logosCompleted += 1>> <<set $logoScore to 0>> <</link>> </div> </div> <</nobr>>
<<set $latitude to 0>> <<set $longitude to 0>> <<set $steps to 0>> <<set $eggPending to false>> <<set $eggHatchAt to 0>> <<set $critterReady to false>> <<set $hatchQueue to []>> <<set $notificationQueue to []>>
<<nobr>> <<widget "showHatchedEggs">> <span id="hatch-wrapper"> <<if $hatchQueue.length > 0>> <<set _critter to $hatchQueue[0]>> <div class="achievement-modal"> <div class="achievement-content"> <h2>🥚 Egg Hatched!</h2> <h3>_critter.name</h3> <p>A new baby _critter.displayTraits.color _critter.displayTraits.size critter is waiting for you!</p> <<link "Meet them!">> <<run $hatchQueue.shift()>> <<replace "#hatch-wrapper">><<showHatchedEggs>><</replace>> <</link>> </div> </div> <</if>> </span> <</widget>> <<widget "showNotifications">> <span id="notification-wrapper"> <<if $notificationQueue.length > 0>> <<set _notif to $notificationQueue[0]>> <div class="achievement-modal"> <div class="achievement-content"> <h2>_notif.icon _notif.title</h2> <p>_notif.message</p> <<link "Okay">> <<run $notificationQueue.shift()>> <<replace "#notification-wrapper">><<showNotifications>><</replace>> <</link>> </div> </div> <</if>> </span> <</widget>> <</nobr>>
<<nobr>> <<run setup.applyRealTimeTick()>> <<showHatchedEggs>> <<showNotifications>> <<showAchievements>> <<updateFarm>> <<tickRequests>> <<run setup.checkLoginReward()>> <<if passage() !== "Fishing">> <<set $weatherRendered to false>> <</if>> <<run setup.checkDailyEscape()>> <</nobr>>
<div id="ui-wrapper"> <div id="passage-container"> <div id="passages"> <div data-passage></div> </div> </div> <nav id="toolbar"> <button id="btn-back">↩</button> <button id="btn-save">💾</button> <button id="btn-home">🏠</button> <button id="btn-locations">🗺️</button> <button id="btn-devtools">🛠️</button> </nav> </div>
<<nobr>> <div class="modal-bg-snapshot" id="modal-bg"></div> <div class="cart-modal" id="featured-modal-overlay" style="display:flex;"> <div class="cart-modal-content"> <div class="cart-modal-header"> <h3>Choose Featured Critter</h3> <button class="cart-modal-close" id="btn-devtools-close">✕</button> </div> <div class="inv-modal-subtitle">Select which critter appears on your home screen.</div> <<set _nonEggs = []>> <<for _i = 0; _i < $playerCreatures.length; _i++>> <<if $playerCreatures[_i].stage !== "egg">> <<run _nonEggs.push(_i)>> <</if>> <</for>> <<if _nonEggs.length === 0>> <div class="vet-no-creatures">You don't have any hatched creatures yet!</div> <<else>> <div class="vet-creature-list"> <<for _j = 0; _j < _nonEggs.length; _j++>> <<set _idx = _nonEggs[_j]>> <<set _creature = $playerCreatures[_idx]>> <<set _template = setup.creatureTemplates[_creature.species]>> <<set _size = _creature.displayTraits.size>> <<set _color = _creature.displayTraits.color>> <<set _pattern = _creature.displayTraits.pattern>> <<set _gender = _creature.gender.toLowerCase()>> <<set _isSelected = ($featuredCreatureIndex === _idx)>> <<capture _idx, _creature>> <div class="vet-creature-card <<if _isSelected>>vet-creature-card--selected<</if>>"> <div class="vet-sprite-wrap"> <<if _creature.stage === "baby">> <<if _template.babySpriteColumns[_color] !== undefined>> <<set _col = _template.babySpriteColumns[_color]>> <<else>> <<set _col = _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<set _spriteSheet = _template.avatars[_gender].babySpriteSheets[_size]>> <<if _size === "large">> <<set _xPos = _col * -180>><<set _dimensions = "180px">><<set _scaledDimensions = "90px">> <<elseif _size === "medium">> <<set _xPos = _col * -120>><<set _dimensions = "120px">><<set _scaledDimensions = "60px">> <<else>> <<set _xPos = _col * -60>><<set _dimensions = "60px">><<set _scaledDimensions = "30px">> <</if>> <<else>> <<set _colorPattern = setup.getSpriteKey(_creature.name, _color, _pattern)>> <<set _col = _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _col = _template.spriteColumns[_template.colorDominance[0] + "_" + _template.patternDominance[0]]>> <</if>> <<set _spriteSheet = _template.avatars[_gender].patternSpriteSheets[_size]>> <<if _size === "large">> <<set _xPos = _col * -240>><<set _dimensions = "240px">><<set _scaledDimensions = "120px">> <<elseif _size === "medium">> <<set _xPos = _col * -160>><<set _dimensions = "160px">><<set _scaledDimensions = "80px">> <<else>> <<set _xPos = _col * -80>><<set _dimensions = "80px">><<set _scaledDimensions = "40px">> <</if>> <</if>> <div @style="'width:' + _scaledDimensions + ';height:' + _scaledDimensions + ';overflow:hidden;flex-shrink:0;'"> <div style="transform:scale(0.5);transform-origin:top left;"> <div class="creature-layers" @style="'width:' + _dimensions + ';height:' + _dimensions + ';'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _spriteSheet + ');background-position:' + _xPos + 'px 0px;width:' + _dimensions + ';height:' + _dimensions + ';'"> </div> </div> </div> </div> </div> <div class="vet-creature-body"> <div class="vet-creature-name"> <<if ndef _creature.petName || _creature.petName === "">> _creature.name <<else>> _creature.petName <</if>> <<if _creature.gender === "Male">>♂️<<else>>♀️<</if>> </div> <<if _isSelected>> <div class="inv-equipped-badge">✓ Featured</div> <</if>> <div class="creature-action"> <<if _isSelected>> <<link "Unfeature">> <<set $featuredCreatureIndex = -1>> <<goto "Home">> <</link>> <<else>> <<capture _idx>> <<link "Feature">> <<set $featuredCreatureIndex = _idx>> <<goto "Home">> <</link>> <</capture>> <</if>> </div> </div> </div> <</capture>> <</for>> </div> <</if>> </div> </div> <<run $(document).one(':passageend', function() { $('#modal-bg').html(State.variables.modalBg); })>> <</nobr>>
<<nobr>> <div class="devtools-modal" id="creature-modal-overlay" style="display:flex;"> <div class="devtools-bg-snapshot" id="devtools-bg"></div> <div class="devtools-modal-content"> <div class="cart-modal-header"> <h3>Developer Tools</h3> <button class="cart-modal-close" id="btn-devtools-close">✕</button> </div> <div class="devtools"> <button id="btn-undo">↶</button> <button id="btn-xp">✨</button> <button id="btn-money">💰</button> <button id="btn-restart">↻</button> </div> <p style="font-size: 14px; font-family: 'Quicksand', sans-serif; color: var(--mid-text); text-align: center;">//Alpha Version 0.6.21.26//</p> </div> </div> <<run $(document).one(':passageend', function() { $('#devtools-bg').html(State.variables.devtoolsBg); })>> <</nobr>>
<<set setup.slotSymbols to [ { emoji: "🌸", rarity: "Common", weight: 65, consolation: 10 }, { emoji: "⭐", rarity: "Common", weight: 65, consolation: 10 }, { emoji: "🐾", rarity: "Uncommon", weight: 35, consolation: 25 }, { emoji: "💎", rarity: "Uncommon", weight: 35, consolation: 25 }, { emoji: "🍄", rarity: "Rare", weight: 30, consolation: 60 }, { emoji: "💨", rarity: null, weight: 20, consolation: 0 } ]>> <<set $playerMimikins to []>> <<set setup.mimikins = { /* MIMIKINS */ "Borb": { id: "Borb", name: "Borb", mimikinsType: "Forest", image: "https://i.imgur.com/IKgtJdF.png", description: "A Forest-type mimikin.", rarity: "Common", gachaWeight: 60 }, "Muumu": { id: "Muumu", name: "Muumu", mimikinsType: "Mountain", image: "https://i.imgur.com/tm1IN2R.png", description: "A Mountain-type mimikin.", rarity: "Common", gachaWeight: 60 }, "Spipup": { id: "Spipup", name: "Spipup", mimikinsType: "Desert", image: "https://i.imgur.com/yad86HC.png", description: "A Desert-type mimikin.", rarity: "Uncommon", gachaWeight: 45 }, "Arobus": { id: "Arobus", name: "Arobus", mimikinsType: "Aether", image: "https://i.imgur.com/7dZjw4D.png", description: "An Aether-type mimikin.", rarity: "Rare", gachaWeight: 30 }, "Blepin": { id: "Blepin", name: "Blepin", mimikinsType: "Volcano", image: "https://i.imgur.com/UWs1PHb.png", description: "An Volcano-type mimikin.", rarity: "Rare", gachaWeight: 30 } }>>
<<nobr>> <div class="steady-machine"> <div class="steady-machine-title">✦ MimiMax ✦</div> <div class="capsule-chute"> <div class="capsule" id="capsule">🫧</div> </div> <div class="crank-wrapper"> <span class="crank-handle" id="crank-handle">🍀</span> </div> <div id="steady-result"></div> <div id="steady-final"></div> </div> <<if $money < 150>> <p style="text-align:center; font-family:'Quicksand',sans-serif;"> You need 150 coins to play! </p> <<link "Back" "GachaMachines">><</link>> <<else>> <div style="text-align:center;"> <button class="crank-btn" id="crank-btn">150 🪙</button> </div> <</if>> <</nobr>>
<<nobr>> <div class="slot-machine"> <div class="slot-machine-title">✦ Luckykin ✦</div> <div class="slot-reels"> <div class="slot-reel spinning" id="reel-1">〜</div> <div class="slot-reel spinning" id="reel-2">〜</div> <div class="slot-reel spinning" id="reel-3">〜</div> </div> <div id="slot-result"></div> <div id="slot-final"></div> </div> <<if $money < 50>> <p style="text-align:center; font-family:'Quicksand',sans-serif;"> You need 50 coins to play! </p> <<link "Back" "GachaMachines">><</link>> <<else>> <div style="text-align:center;"> <button class="slot-lever-btn" id="lever-btn">Pull! (50 🪙)</button> </div> <</if>> <div class="paytable"> <p>✦ Paytable ✦</p> <<for _sym range setup.slotSymbols>> <<if _sym.rarity !== null>> <div class="paytable-row"> <span><<= _sym.emoji >> <<= _sym.emoji >> <<= _sym.emoji >></span> <span><<= _sym.rarity >> Mimikin</span> </div> <div class="paytable-row"> <span><<= _sym.emoji >> <<= _sym.emoji >> ✦</span> <span>+<<= _sym.consolation >> 🪙</span> </div> <</if>> <</for>> <div class="paytable-row"> <span>No match</span> <span>No prize</span> </div> </div> <</nobr>>
<<nobr>> <div style="text-align:center; font-family:'Chewy', cursive; color:#f4d35e; font-size:1.1em; margin-bottom:12px;"> 🪙 <<= $money>> coins </div> <div class="gacha-machines-grid"> <div class="gacha-machine-card steady-card"> <div class="gacha-machine-card-title">✦ MimiMax ✦</div> <div class="gacha-machine-card-cost">150 🪙</div> <<link "Crank!" "GachaSteady">><</link>> </div> <div class="gacha-machine-card lucky-card"> <div class="gacha-machine-card-title">✦ Luckykin ✦</div> <div class="gacha-machine-card-cost">50 🪙</div> <<link "Pull!" "GachaLucky">><</link>> </div> </div> <div class="back-forth-buttons"> <<link "Back" "Shop">><</link>> </div> <</nobr>>
<<nobr>> <div class="modal-bg-snapshot" id="modal-bg"></div> <div class="cart-modal" id="creature-modal-overlay" style="display:flex;"> <div class="cart-modal-content"> <div class="cart-modal-header"> <h3>Select a Mimikin</h3> <<link "✕" "ViewCreature">><</link>> </div> <<if $playerCreatures[$currentCreature].mimikin !== null>> <div class="vet-creature-list"> <div class="vet-creature-card"> <div class="vet-sprite-wrap"> [img[$playerCreatures[$currentCreature].mimikin.image]] </div> <div class="vet-creature-body"> <div class="vet-creature-name"> <<= $playerCreatures[$currentCreature].mimikin.name>> </div> </div> <div class="creature-action"> <<link "Remove">> <<set $playerCreatures[$currentCreature].mimikin to null>> <<goto "ViewCreature">> <</link>> </div> </div> </div> <<else>> <<set _availableMimikins to $playerMimikins.filter(function(m) { return !$playerCreatures.some(function(c) { return c.mimikin && c.mimikin.instanceId === m.instanceId; }); })>> <<if !$playerMimikins || _availableMimikins.length === 0>> <div class="vet-no-creatures">You don't have any mimikins!</div> <<else>> <div class="vet-creature-list"> <<for _mimi range $playerMimikins>> <<set _inUse to $playerCreatures.some(function(c) { return c.mimikin && c.mimikin.instanceId === _mimi.instanceId; })>> <<if !_inUse>> <<capture _mimi>> <<set _totalOwned to $playerMimikins.filter(function(m) { return m.id === _mimi.id; }).length>> <<set _totalInUse to $playerCreatures.filter(function(c) { return c.mimikin && c.mimikin.id === _mimi.id; }).length>> <<set _totalAvailable to _totalOwned - _totalInUse>> <div class="vet-creature-card"> <div class="vet-sprite-wrap"> [img[_mimi.image]] </div> <div class="vet-creature-body"> <div class="vet-creature-name"> <<= _mimi.name>> </div> <div class="mimikin-rarity"> <<if _mimi.rarity === "Common">> <span class="mimikin-rarity-badge rarity-common1">Common</span> <<elseif _mimi.rarity === "Uncommon">> <span class="mimikin-rarity-badge rarity-uncommon1">Uncommon</span> <<elseif _mimi.rarity === "Rare">> <span class="mimikin-rarity-badge rarity-rare1">Rare</span> <</if>> </div> <div class="vet-creature-desc"> <<= _totalAvailable>> / <<= _totalOwned>> available </div> </div> <div class="creature-action"> <<link "Give">> <<set $playerCreatures[$currentCreature].mimikin to clone(_mimi)>> <<goto "ViewCreature">> <</link>> </div> </div> <</capture>> <</if>> <</for>> </div> <</if>> <</if>> </div> </div> <<run $(document).one(':passageend', function() { $('#modal-bg').html(State.variables.modalBg); })>> <</nobr>>
<<nobr>> <<widget "lineageNode">> <<set _nodeCreature to $args[0]>> <<set _nodeRole to $args[1]>> <<if _nodeCreature !== null>> <<set _nodeTemplate to setup.creatureTemplates[_nodeCreature.species]>> <<set _nodeLiveIndex to findCreatureIndexInPlayerCreatures(_nodeCreature.id)>> <<set _nodeIsLive to _nodeLiveIndex >= 0>> <<set _nodeIsDead to false>> <<for _di to 0; _di < $deadCreatures.length; _di++>> <<if $deadCreatures[_di].id === _nodeCreature.id>> <<set _nodeIsDead to true>> <</if>> <</for>> <div class="lineage-node <<if _nodeIsLive>>lineage-node--live<<elseif _nodeIsDead>>lineage-node--dead<<else>>lineage-node--gone<</if>>"> <<if _nodeIsLive || _nodeIsDead>> /* Show actual sprite */ <<if _nodeCreature.stage === "egg">> <span style="font-size:2em;">🥚</span> <<elseif _nodeCreature.stage === "baby">> <<set _nodeSize to _nodeCreature.displayTraits.size>> <<set _nodeColor to _nodeCreature.displayTraits.color>> <<set _nodeGender to _nodeCreature.gender.toLowerCase()>> <<set _nodeCol to _nodeTemplate.babySpriteColumns[_nodeColor]>> <<if _nodeCol === undefined>> <<set _nodeCol to _nodeTemplate.babySpriteColumns[_nodeTemplate.colorDominance[0]]>> <</if>> <<set _nodeSpriteSheet to _nodeTemplate.avatars[_nodeGender].babySpriteSheets[_nodeSize]>> <<if _nodeSize === "large">> <<set _nodeXPos to _nodeCol * -180>><<set _nodeDim to "180px">><<set _scale = "scale(0.4)">> <<set _scaledDimensions = "90px">> <<elseif _nodeSize === "medium">> <<set _nodeXPos to _nodeCol * -120>><<set _nodeDim to "120px">><<set _scale = "scale(0.5)">> <<set _scaledDimensions = "60px">> <<else>> <<set _nodeXPos to _nodeCol * -60>><<set _nodeDim to "60px">><<set _scale = "scale(0.9)">> <<set _scaledDimensions = "30px">> <</if>> <div @style="'width:' + _scaledDimensions + ';height:' + _scaledDimensions + ';overflow:hidden;flex-shrink:0;'"> <div style="transform:scale(0.5);transform-origin:top left;"> <div class="creature-layers" @style="'width:' + _nodeDim + ';height:' + _nodeDim + ';'"> <div class="creature-sprite-pattern" @style="'background-image: url(' + _nodeSpriteSheet + '); background-position: ' + _nodeXPos + 'px 0px; width: ' + _nodeDim + '; height: ' + _nodeDim + ';'"> </div> </div> </div> </div> <<else>> /* Adult sprite — existing code continues here unchanged */ <<set _nodeSize to _nodeCreature.displayTraits.size>> <<set _nodeColor to _nodeCreature.displayTraits.color>> <<set _nodePattern to _nodeCreature.displayTraits.pattern>> <<set _nodeGender to _nodeCreature.gender.toLowerCase()>> <<set _nodeColorPattern to setup.getSpriteKey(_nodeCreature.species, _nodeColor, _nodePattern)>> <<set _nodeCol to _nodeTemplate.spriteColumns[_nodeColorPattern]>> <<if _nodeCol === undefined>> <<set _nodeCol to _nodeTemplate.spriteColumns[_nodeTemplate.colorDominance[0] + "_" + _nodeTemplate.patternDominance[0]]>> <</if>> <<set _nodeSpriteSheet to _nodeTemplate.avatars[_nodeGender].patternSpriteSheets[_nodeSize]>> <<if _nodeSize === "large">> <<set _nodeXPos to _nodeCol * -240>><<set _nodeDim to "240px">> <<set _scaledDimensions to "120px">> <<elseif _nodeSize === "medium">> <<set _nodeXPos to _nodeCol * -160>><<set _nodeDim to "160px">> <<set _scaledDimensions to "80px">> <<else>> <<set _nodeXPos to _nodeCol * -80>><<set _nodeDim to "80px">> <<set _scaledDimensions to "40px">> <</if>> <div @style="'width:' + _scaledDimensions + ';height:' + _scaledDimensions + ';overflow:hidden;flex-shrink:0;'"> <div style="transform:scale(0.5);transform-origin:top left;"> <div class="creature-layers" @style="'width:' + _nodeDim + ';height:' + _nodeDim + ';'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _nodeTemplate.avatars[_gender].patternSpriteSheets[_nodeSize] + ');background-position:' + _nodeXPos + 'px 0px;width:' + _nodeDim + ';height:' + _nodeDim + ';'"> </div> </div> </div> </div> <</if>> <<else>> /* Show silhouette for sold/lost */ <<set _nodeGender to _nodeRole === "mother" ? "female" : "male">> <<set _nodeSilhouette to _nodeTemplate.silhouettes[_nodeGender].small>> <div class="lineage-silhouette"> <img @src="_nodeSilhouette" style="width:80px;height:80px;opacity:0.6;"> </div> <</if>> <div class="lineage-node-name"> <<if _nodeIsLive>> <<set _nodeName to _nodeCreature.petName || _nodeCreature.species>> <<set _nodeId to _nodeCreature.id>> <<capture _nodeId, _nodeName>> <<link _nodeName>> <<set $lineageCreatureId to _nodeId>> <<set $lineageTab to "ancestors">> <<goto "CreatureLineage">> <</link>> <</capture>> <<else>> <<set _nodeName to _nodeCreature.petName || _nodeCreature.species>> <<= _nodeName>> <<if _nodeIsDead>> <span class="lineage-status">🕯️</span> <<else>> <span class="lineage-status">🚫</span> <</if>> <</if>> </div> <div class="lineage-node-species">_nodeCreature.species</div> </div> <<else>> <div class="lineage-node lineage-node--unknown"> <div class="lineage-silhouette"> <img src="_nodeTemplate.silhouettes.female.small" style="width:80px;height:80px;opacity:0.2;"> </div> <div class="lineage-node-name">Unknown</div> </div> <</if>> <</widget>> <</nobr>>
<<nobr>> <<set _creature to findCreatureAnywhere($lineageCreatureId)>> <<run console.log("Lineage creature ID:", $lineageCreatureId, "Found:", _creature ? _creature.species : "null", "Gender:", _creature ? _creature.gender : "null")>> <<set _template to setup.creatureTemplates[_creature.species]>> <<set _creatureName to (_creature.petName && _creature.petName !== "") ? _creature.petName : _creature.species>> /* ── HEADER: Viewed Creature ── */ <h2>_creatureName's Lineage</h2> /* Sprite */ <<set _size to _creature.displayTraits.size>> <<set _color to _creature.displayTraits.color>> <<set _pattern to _creature.displayTraits.pattern>> <<set _gender to _creature.gender.toLowerCase()>> <<if _creature.stage === "egg">> <<set _spriteSheet to null>> <<set _dim to "80px">> <<set _xPos to 0>> <<elseif _creature.stage === "baby">> <<set _col to _template.babySpriteColumns[_color]>> <<if _col === undefined>> <<set _col to _template.babySpriteColumns[_template.colorDominance[0]]>> <</if>> <<set _spriteSheet to _template.avatars[_gender].babySpriteSheets[_size]>> <<if _size === "large">> <<set _xPos to _col * -180>><<set _dim to "180px">> <<elseif _size === "medium">> <<set _xPos to _col * -120>><<set _dim to "120px">> <<else>> <<set _xPos to _col * -60>><<set _dim to "60px">> <</if>> <<else>> <<set _colorPattern to setup.getSpriteKey(_creature.species, _color, _pattern)>> <<set _col to _template.spriteColumns[_colorPattern]>> <<if _col === undefined>> <<set _col to _template.spriteColumns[_template.colorDominance[0] + "_" + _template.patternDominance[0]]>> <</if>> <<set _spriteSheet to _template.avatars[_gender].patternSpriteSheets[_size]>> <<if _size === "large">> <<set _xPos = _col * -240>><<set _dim = "240px">> <<elseif _size === "medium">> <<set _xPos = _col * -160>><<set _dim = "160px">> <<else>> <<set _xPos = _col * -80>><<set _dim = "80px">> <</if>> <</if>> <div class="lineage-subject"> <<if _creature.stage === "egg">> <span style="font-size:4em;">🥚</span> <<else>> <div class="creature-layers" @style="'width:' + _dim + ';height:' + _dim + ';margin:0 auto;'"> <div class="creature-sprite-pattern" @style="'background-image:url(' + _spriteSheet + ');background-position:' + _xPos + 'px 0px;width:' + _dim + ';height:' + _dim + ';'"> </div> </div> <</if>> <div class="lineage-subject-name">_creatureName <<if _creature.gender === "Male">>♂️<<else>>♀️<</if>></div> <div class="lineage-subject-species">_creature.species • Gen _creature.generation</div> </div> /* ── TABS ── */ <<if ndef $lineageTab>><<set $lineageTab to "ancestors">><</if>> <div class="lineage-tabs"> <<link "Ancestors">> <<set $lineageTab to "ancestors">> <<refresh>> <</link>> <<link "Descendants">> <<set $lineageTab to "descendants">> <<refresh>> <</link>> </div> /* ── ANCESTORS TAB ── */ <<if $lineageTab === "ancestors">> <<if !_creature.parents>> <div class="lineage-empty">No ancestry data available.</div> <<else>> /* Parents */ <<set _mother to findCreatureAnywhere(_creature.parents.motherId)>> <<set _father to findCreatureAnywhere(_creature.parents.fatherId)>> /* If not found anywhere, build a stub from stored data */ <<if _mother === null && _creature.parents.motherName>> <<set _mother to { id: _creature.parents.motherId, species: _creature.parents.motherSpecies, petName: _creature.parents.motherName, gender: "Female", parents: null, displayTraits: null }>> <</if>> <<if _father === null && _creature.parents.fatherName>> <<set _father to { id: _creature.parents.fatherId, species: _creature.parents.fatherSpecies, petName: _creature.parents.fatherName, gender: "Male", parents: null, displayTraits: null }>> <</if>> <div class="lineage-tree"> /* Generation label */ <div class="lineage-gen-label">Parents</div> <div class="lineage-row"> <<lineageNode _mother "mother">> <<lineageNode _father "father">> </div> /* Grandparents */ <<if (_mother && _mother.parents) || (_father && _father.parents)>> <div class="lineage-gen-label">Maternal Grandparents</div> <div class="lineage-row"> <<if _mother && _mother.parents>> <<set _maternalGrandmother to findCreatureAnywhere(_mother.parents.motherId)>> <<set _maternalGrandfather to findCreatureAnywhere(_mother.parents.fatherId)>> <<if _maternalGrandmother === null && _mother.parents.motherName>> <<set _maternalGrandmother to { id: _mother.parents.motherId, species: _mother.parents.motherSpecies, petName: _mother.parents.motherName, gender: "Female", parents: null, displayTraits: null }>> <</if>> <<if _maternalGrandfather === null && _mother.parents.fatherName>> <<set _maternalGrandfather to { id: _mother.parents.fatherId, species: _mother.parents.fatherSpecies, petName: _mother.parents.fatherName, gender: "Male", parents: null, displayTraits: null }>> <</if>> <<lineageNode _maternalGrandmother "mother">> <<lineageNode _maternalGrandfather "father">> <<else>> <div class="lineage-node lineage-node--unknown"><div class="lineage-node-name">No Data</div></div> <div class="lineage-node lineage-node--unknown"><div class="lineage-node-name">No Data</div></div> <</if>> </div> <div class="lineage-gen-label">Paternal Grandparents</div> <div class="lineage-row"> <<if _father && _father.parents>> <<set _paternalGrandmother to findCreatureAnywhere(_father.parents.motherId)>> <<set _paternalGrandfather to findCreatureAnywhere(_father.parents.fatherId)>> <<if _paternalGrandmother === null && _father.parents.motherName>> <<set _paternalGrandmother to { id: _father.parents.motherId, species: _father.parents.motherSpecies, petName: _father.parents.motherName, gender: "Female", parents: null, displayTraits: null }>> <</if>> <<if _paternalGrandfather === null && _father.parents.fatherName>> <<set _paternalGrandfather to { id: _father.parents.fatherId, species: _father.parents.fatherSpecies, petName: _father.parents.fatherName, gender: "Male", parents: null, displayTraits: null }>> <</if>> <<lineageNode _paternalGrandmother "mother">> <<lineageNode _paternalGrandfather "father">> <<else>> <div class="lineage-node lineage-node--unknown"><div class="lineage-node-name">No Data</div></div> <div class="lineage-node lineage-node--unknown"><div class="lineage-node-name">No Data</div></div> <</if>> </div> /* Great-grandparents */ <<set _ggpSources to [_maternalGrandmother, _maternalGrandfather, _paternalGrandmother, _paternalGrandfather]>> <<set _ggpLabels to ["Maternal Grandmother's Parents", "Maternal Grandfather's Parents", "Paternal Grandmother's Parents", "Paternal Grandfather's Parents"]>> <<set _hasGGP to false>> <<for _gi to 0; _gi < _ggpSources.length; _gi++>> <<if _ggpSources[_gi] && _ggpSources[_gi].parents>><<set _hasGGP to true>><</if>> <</for>> <<if _hasGGP>> <<for _gi to 0; _gi < _ggpSources.length; _gi++>> <<capture _gi>> <div class="lineage-gen-label"><<= _ggpLabels[_gi]>></div> <div class="lineage-row"> <<set _ggpSource to _ggpSources[_gi]>> <<if _ggpSource && _ggpSource.parents>> <<set _ggpMother to findCreatureAnywhere(_ggpSource.parents.motherId)>> <<set _ggpFather to findCreatureAnywhere(_ggpSource.parents.fatherId)>> <<if _ggpMother === null && _ggpSource.parents.motherName>> <<set _ggpMother to { id: _ggpSource.parents.motherId, species: _ggpSource.parents.motherSpecies, petName: _ggpSource.parents.motherName, gender: "Female", parents: null, displayTraits: null }>> <</if>> <<if _ggpFather === null && _ggpSource.parents.fatherName>> <<set _ggpFather to { id: _ggpSource.parents.fatherId, species: _ggpSource.parents.fatherSpecies, petName: _ggpSource.parents.fatherName, gender: "Male", parents: null, displayTraits: null }>> <</if>> <<lineageNode _ggpMother "mother">> <<lineageNode _ggpFather "father">> <<else>> <div class="lineage-node lineage-node--unknown"><div class="lineage-node-name">No Data</div></div> <div class="lineage-node lineage-node--unknown"><div class="lineage-node-name">No Data</div></div> <</if>> </div> <</capture>> <</for>> <</if>> <</if>> </div> <</if>> /* ── DESCENDANTS TAB ── */ <<elseif $lineageTab === "descendants">> <<set _allCreatures to [].concat( $playerCreatures, $deadCreatures, $escapedCreatures, $departedCreatures )>> <<set _directOffspring to _allCreatures.filter(function(c) { return c.parents && (c.parents.motherId === _creature.id || c.parents.fatherId === _creature.id); })>> <<if _directOffspring.length === 0>> <div class="lineage-empty">No descendants found.</div> <<else>> <div class="lineage-tree"> <div class="lineage-gen-label">Offspring</div> <div class="lineage-row"> <<for _oi to 0; _oi < _directOffspring.length; _oi++>> <<capture _oi>> <<set _offspring to _directOffspring[_oi]>> <<set _offspringRole to _offspring.gender === "Female" ? "mother" : "father">> <<lineageNode _offspring _offspringRole>> <</capture>> <</for>> </div> /* Grandchildren */ <<set _grandchildren to _allCreatures.filter(function(c) { return c.parents && _directOffspring.some(function(o) { return c.parents.motherId === o.id || c.parents.fatherId === o.id; }); })>> <<if _grandchildren.length > 0>> <div class="lineage-gen-label">Grandchildren</div> <div class="lineage-row"> <<for _gci to 0; _gci < _grandchildren.length; _gci++>> <<capture _gci>> <<set _grandchild to _grandchildren[_gci]>> <<set _grandchildRole to _grandchild.gender === "Female" ? "mother" : "father">> <<lineageNode _grandchild _grandchildRole>> <</capture>> <</for>> </div> /* Great-grandchildren */ <<set _greatGrandchildren to _allCreatures.filter(function(c) { return c.parents && _grandchildren.some(function(gc) { return c.parents.motherId === gc.id || c.parents.fatherId === gc.id; }); })>> <<if _greatGrandchildren.length > 0>> <div class="lineage-gen-label">Great-Grandchildren</div> <div class="lineage-row"> <<for _ggci to 0; _ggci < _greatGrandchildren.length; _ggci++>> <<capture _ggci>> <<set _greatGrandchild to _greatGrandchildren[_ggci]>> <<set _greatGrandchildRole to _greatGrandchild.gender === "Female" ? "mother" : "father">> <<lineageNode _greatGrandchild _greatGrandchildRole>> <</capture>> <</for>> </div> <</if>> <</if>> </div> <</if>> <</if>> /* ── BACK BUTTON ── */ <div class="back-forth-buttons"> <div class="back-button"> <<link "Go Back">> <<unset $lineageCreatureId>> <<goto "ViewCreature">> <</link>> </div> </div> <</nobr>>