JavaScript must be enabled to play.
Browser lacks capabilities required to play.
Upgrade or switch to another browser.
Loading…
你坐在潜艇的驾驶舱里,面前是黄铜的操作台。 [[起身去走廊|走廊]]
架子上罗列着所有库存。 <<nobr>> <<set _s_store = State.variables.store>> <<set _s_items = State.variables.items>> <<set _s_cats = Object.keys(_s_store)>> <<for _ci = 0; _ci < _s_cats.length; _ci++>> <<set _cat = _s_cats[_ci]>> <<set _val = _s_store[_cat]>> <<if Array.isArray(_val)>> <<set _filled = _val.filter(x => x.quantity > 0)>> <<if _filled.length > 0>> <div class="inv-category"><<print _cat>></div> <div class="inv-grid"> <<for _ii = 0; _ii < _filled.length; _ii++>> <<set _entry = _filled[_ii]>> <<capture _entry>> <<set _def = _s_items[_entry.id]>> <<set _rarity = _def.rarity === "稀有" ? " rare" : (_def.rarity === "传说" ? " legendary" : "")>> <span class="inv-item<<print _rarity>>"><<link _def.name>><<set $selectitem = _entry.id>><<goto "仓库物品页面">><</link>><span class="item-qty">×<<print _entry.quantity>><<freshnessTag _entry>></span></span> <</capture>> <</for>> </div> <</if>> <</if>> <</for>> <</nobr>> [[炼金室]]
<<nobr>> <div id="sc-status"> <<include "侧边栏状态">> </div> <<cpNotifyDisplay>> <</nobr>>
/* ═══════════════════════════════════════════════════════════ StoryInit — SugarCube 标准启动 passage 只做三件事:1.调用VarIndex 2.加载数据Defs 3.初始化系统 ═══════════════════════════════════════════════════════════ */ /* === 1. 变量声明(全部在 VarIndex 中集中管理) === */ <<include "VarIndex">> /* === 2. 数据定义加载 === */ /* --- 纯数据 passage(用 <<include>> 执行) --- */ <<include "ViewDefs">> <<include "StoreDefs">> <<include "ItemDefs">> <<include "FishingDefs">> <<include "RecipeDefs">> <<include "CookTemplates">> <<include "CookFragments">> <<include "DisassemblyDefs">> <<include "DisassemblyFlavors">> <<include "DecayDefs">> <<include "AlchemyItemDefs">> <<include "AlchemyDefs">> /* --- widget 数据定义 passage(用宏调用同时注册并执行) --- */ <<fuelDefs>> <<upgradeDefs>> <<exploreDefs>> <<microEventTable>> <<smallEventTable>> <<worldSceneDefs>> <<largeSceneDefs>> <<diveSceneDefs>> <<diveInteractDefs>> <<temporalEventDefs>> <<combatEnemyDefs>> <<cpDefs>> <<cpProactiveDefs>> <<questDefs>> <<npcDefs>> <<locationDefs>> /* === 3. 系统初始化完成 === */
<<link "背包">> <<navigate "go" "backpack">> <</link>> <<link "载具">> <<navigate "go" "ship">> <</link>> <<link "备忘录">> <<navigate "go" "note">> <</link>>
/* ═══════════════════════════════════════════════════════════ VarIndex — 所有 Story Variable 集中声明 tag: startup 其他 passage 一律只引用、不重复声明 ═══════════════════════════════════════════════════════════ */ /* ═══════════════════════════════════════════════════ 玩家状态 */ <<set $life = 100>> /* 生命值 */ <<set $lifeMax = 100>> /* 生命上限 */ <<set $hunger = 100>> /* 饱食度(100=饱, 0=饿死) */ <<set $water = 100>> /* 水分 */ <<set $san = 100>> /* 精神值 */ <<set $tre = 0>> /* ??? */ <<set $magic = 100>> /* 魔力/能量 */ <<set $power = 100>> /* 体力 */ <<set $weaponMult = 1>> /* 武器伤害倍率(战斗用,默认1) */ /* 环境状态 */ <<set $tem = 20>> /* 体温(℃) */ <<set $wet = 0>> /* 湿度 */ <<set $worldtem = 20>> /* 世界温度 */ <<set $outdoor = 0>> /* 是否在户外 */ <<set $inwater = 0>> /* 是否在水中 */ <<set $fire = 0>> /* 附近有火 */ <<set $bath = 0>> /* 在浴缸 */ <<set $cloth = 0>> /* 穿衣状态 */ /* 六维运算 */ <<set $hungerlim = -4320>> /* 饥饿阈值 */ <<set $waterlim = -1440>> /* 缺水阈值 */ <<set $hungerpass = 0>> /* 饥饿累计 */ <<set $waterpass = 0>> /* 缺水累计 */ <<set $lifepass = 0>> /* 生命累计 */ <<set $sanpass = 0>> /* 精神累计 */ <<set $powerpass = 0>> /* 体力累计 */ <<set $tempass = 0>> /* 温度累计 */ <<set $wetpass = 0>> /* 湿度累计 */ <<set $heatpass = -120>> /* 热量累计 */ <<set $addtem = 0>> /* 附加温度 */ <<set $coldpass = 0>> /* 寒冷累计 */ <<set $seasontem = 20>> /* 季节温度 */ <<set $wavetem = 0>> /* 温度波动 */ /* ═══════════════════════════════════════════════════ 世界时间 */ <<set $minute = 0>> /* 分钟 */ <<set $hour = 7>> /* 小时 */ <<set $day = 1>> /* 天数 */ <<set $season = 1>> /* 季节 */ <<set $showhour = 7>> /* 显示用小时 */ <<set $showday = 1>> /* 显示用天数 */ <<set $showminute = 0>> /* 显示用分钟 */ <<set $showseason = 1>> /* 显示用季节 */ <<set $timepass = 0>> /* 时间累计 */ <<set $hourpass = 0>> /* 小时累计 */ /* 天气 */ <<set $weather = 3>> /* 当前天气索引 */ <<set $showweather = ['冰封','风雪','炎热','雾气','晴朗','阴云','小雨','大雨','大风','暴风雨']>> <<set $viewweather = ['frozen','snow','hot','fog','clear','cloudy','lightrain','heavyrain','windy','storm']>> <<set $weatem = [-15,-10,5,-2,0,-2,-4,-5,-4,-6]>> /* 天气温度修正 */ /* ═══════════════════════════════════════════════════ 潜艇状态 */ <<set $shell = 100>> /* 外壳耐久 */ <<set $shellMax = 100>> /* 外壳上限 */ <<set $fuel = 300>> /* 燃料(初始满油箱)【修复:原为40000】 */ <<set $fuelMax = 300>> /* 燃料上限 */ <<set $sys = 100>> /* 系统完整度 */ <<set $shipOxygen = 100>> /* 潜艇氧气 */ /* 船只子系统(运行状态) */ <<set $shipSystems = { propulsion:true, fishing:true, oxygen:true, heating:true, storage:true }>> /* 船只升级(统一用 $upgrades,删除旧 $shipUpgrades) */ <<set $upgrades = { hull: 0, /* 隔热层:减少深度燃料系数 [0.3, 0.6, 1.0] */ pressure: 0, /* 加压舱:安全深度 [300, 600, 1500, 5000] */ thruster: 0, /* 推进器:航速 */ arm: 0, /* 机械臂:探索能力 */ oxygen_sys: 0, /* 供氧系统 */ fuel_tank: 0, /* 燃料箱:燃料上限 */ kitchen: 0, /* 厨房 */ alchemy: 0 /* 炼金室 */ }>> /* ═══════════════════════════════════════════════════ 航行/地图 */ <<set $map = 10>> /* 当前在区域内的位置(前进距离) */ <<set $maplim = 100>> /* 当前区域总长度 */ <<set $mapspan = 0>> /* 跨度显示值 */ <<set $maplimspan = 0>> /* 区域跨度显示值 */ <<set $maptype = "sand">> /* 当前地形类型 */ <<set $spdmax = 1000>> /* 最大航速 */ <<set $sailspd = 0>> /* 当前航行速度 */ <<set $sailtime = 0>> /* 航行计划时间 */ <<set $sailpass = 0>> /* 已航行计数 */ <<set $sailMode = "travel">> /* "travel"=航行中 / "explore"=锚定探索 */ <<set $fishing = 0>> /* 捕鱼状态 */ /* 地形定义 */ <<set $mapinfo = { sand: { type: "/*::GEN::UI::terrain_sand:: */沙海床/*::END:: */", depthmin: 20, depthmax: 10000, spanmin: 30000, spanmax: 200000, weight: 40, spdmax: 2, spdmin: -2 }, flat: { type: "/*::GEN::UI::terrain_flat:: */岩海床/*::END:: */", depthmin: 200, depthmax: 500, spanmin: 20000, spanmax: 70000, weight: 30, spdmax: 3, spdmin: -3 }, cliff: { type: "/*::GEN::UI::terrain_cliff:: */峭壁/*::END:: */", depthmin: 200, depthmax: 10000, spanmin: 20000, spanmax: 60000, weight: 10, spdmax: 5, spdmin: -5 }, grass: { type: "/*::GEN::UI::terrain_grass:: */海草床/*::END:: */", depthmin: 20, depthmax: 200, spanmin: 20000, spanmax: 80000, weight: 10, spdmax: 2, spdmin: -2 }, reef: { type: "/*::GEN::UI::terrain_reef:: */珊瑚礁/*::END:: */", depthmin: 20, depthmax: 200, spanmin: 20000, spanmax: 60000, weight: 5, spdmax: 3, spdmin: -3 }, forest: { type: "/*::GEN::UI::terrain_forest:: */海藻森林/*::END:: */", depthmin: 200, depthmax: 600, spanmin: 30000, spanmax: 80000, weight: 5, spdmax: 3, spdmin: -3 }, vent: { type: "/*::GEN::UI::terrain_vent:: */热液裂谷/*::END:: */", depthmin: 500, depthmax: 10000, spanmin: 10000, spanmax: 40000, weight: 3, spdmax: 4, spdmin: -4 }, abyss: { type: "/*::GEN::UI::terrain_abyss:: */深渊/*::END:: */", depthmin: 2000, depthmax: 10000, spanmin: 15000, spanmax: 50000, weight: 2, spdmax: 2, spdmin: -2 } }>> /* ═══════════════════════════════════════════════════ 深度系统 */ /* 三层深度: $depthdeep = 海底深度(海面到海底的距离) $depth = 潜艇当前深度(0=水面) $depthnoc = 深度波动中间值(随机变化,floor后赋给depthdeep) */ <<set $depth = 200>> /* 潜艇当前深度 */ <<set $depthdeep = 300>> /* 海底深度 */ <<set $depthnoc = 100>> /* 深度波动值 */ <<set $depthspd = 0>> /* 深度变化速度(正=变深, 负=变浅) */ <<set $depthwave = 0>> /* 深度方向持续距离 */ <<set $depthpass = 0>> /* 深度方向已持续距离 */ /* 导航控制(新增) */ <<set $nav = { slopeDir: "natural" /* 转向倾向: natural | downhill | uphill */ }>> /* ═══════════════════════════════════════════════════ 区域转换 */ <<set $prevArea = null>> /* 上一区域 {type, depth, maplim} */ <<set $nextAreas = []>> /* 预生成的下一区域选项 */ <<set $nextAreasReady = 0>> /* 是否已预生成 */ <<set $selectedNextArea = 0>> /* 玩家选择的方向索引 */ /* ═══════════════════════════════════════════════════ 世界场景 */ <<set $worldScene = null>> /* 当前世界场景 */ <<set $wsChild = null>> /* 场景子事件 */ <<set $wsLastActionText = "">> /* 最后动作文本 */ <<set $wsLastActionLoot = "">> /* 最后掉落 */ <<set $largeScene = 0>> /* 大型场景 */ <<set $worldSceneQueue = []>> /* 场景队列 */ <<set $worldSceneQueueIdx = 0>> /* 队列索引 */ <<set $mapReservations = []>> /* 当前地形的地图区间预留 [{start,end,kind,id}] */ <<set $regionRichness = 60>> /* 区域丰富度(0-100) */ <<set $devEventPoolOverview = null>> /* DEV 当前事件池快照 */ <<set $devRegionId = "">> /* DEV 当前区域解析结果 */ /* 临时事件 */ <<set $temporalEvent = 0>> /* 临时事件 */ <<set $temporalLog = "">> /* 临时事件日志 */ /* 漂流状态 */ <<set $driftMode = false>> /* 燃料耗尽漂流 */ /* ═══════════════════════════════════════════════════ 背包/库存 */ <<set $inv = {}>> /* 物品持有 {itemId: count} */ <<set $storageCapacity = 100>> /* 背包容量 */ <<set $specialPassages = ["backpack", "背包物品页面", "ship"]>> /* 烹饪状态(玩家自己的,CP用独立变量) */ <<set $cookMethod = "">> <<set $cookIngredients = []>> <<set $cookTimer = 0>> <<set $cookFinalTime = 0>> <<set $cookDuration = 20>> <<set $cookSuccessMin = 5>> <<set $cookSuccessMax = 18>> <<set $cookPerfectMin = 8>> <<set $cookPerfectMax = 15>> <<set $cookResultId = "">> <<set $fridge = [null,null,null,null,null,null,null,null]>> <<set $assembleResult = "">> <<set $assembleSlot = 0>> <<set $selectFridgeSlot = 0>> <<set $cookRecipeName = "">> <<set $cookQuality = "">> /* CP 烹饪状态(独立于玩家变量)【修复:原侵入 $cookMethod/$cookIngredients】 */ <<set $cpCookMethod = "">> <<set $cpCookIngredients = []>> /* ═══════════════════════════════════════════════════ 炼金 */ <<set $alchemyInstrument = "">> /* 当前仪器 */ <<set $alchemyMaterials = []>> /* 当前材料 */ <<set $alchemyTimer = 0>> /* 炼金计时 */ /* 精炼状态 */ <<set $refineState = null>> /* 酊剂制作状态(4步连续,不可中断) */ <<set $tinctureState = null>> /* 制作状态 */ <<set $tinctureCurrent = null>> /* 当前配方id */ <<set $tinctureStep = 0>> /* 当前步骤(1-4) */ /* 仪器升级等级(5种仪器,0-3) */ <<set $instrumentLevels = { refiner: 0, /* 黑化炉: 0=粗制 1=标准 2=精制 3=完美 */ dissolver: 0, /* 溶解皿: 0=石皿 1=骨皿 2=水晶皿 */ distiller: 0, /* 蒸馏器 */ condenser: 0, /* 冷凝器 */ reddener: 0 /* 赤化炉 */ }>> /* ═══════════════════════════════════════════════════ 事件系统 */ <<set $activeEvent = 0>> /* 当前激活事件 */ <<set $eventLog = []>> /* 事件日志 */ <<set $eventPass = 0>> /* 旧事件计数(兼容保留) */ <<set $eventTimer = 0>> /* 事件计时器 */ <<set $eventDistance = 0>> /* 正常航行累计实际地图距离 */ <<set $eventDistanceMin = 2000>> /* 随机遭遇门槛下限:40 单位 */ <<set $eventDistanceMax = 8000>> /* 随机遭遇门槛上限:160 单位 */ <<set $eventDistanceThreshold = $eventDistanceMin + Math.floor(Math.random() * ($eventDistanceMax - $eventDistanceMin + 1))>> <<set $eventDistanceCooldown = 0>> /* 遭遇后的剩余距离冷却 */ <<set $eventCooldownDistance = 0>> /* 门槛本身已覆盖节奏,不额外叠加距离冷却 */ <<set $currentContext = "sailing">> /* 当前上下文 */ <<set $pendingEvent = null>> /* 待处理事件 */ <<set $envEffects = []>> /* 持久环境影响 */ <<set $ecoBonds = {}>> /* 生态驻留好感 */ <<set $lastMicroText = "">> <<set $lastSmallEventText = "">> <<set $activeHuntItems = []>> /* 内联微型事件ID列表 */ <<set $smallExplorePointDefs = {}>> /* 从微型事件原池派生的探索点池 */ <<set $lastHuntText = "">> <<set $lastEnvText = "">> <<set $lastExploreText = "">> <<set $exploreLog = []>> <<set $exploreSearchCost = { min: 3, max: 7 }>> <<set $activeMicroEvent = null>> <<set $activeSmallEvent = null>> /* ═══════════════════════════════════════════════════ 战斗 */ <<set $combatState = null>> /* 战斗状态 */ <<set $activeCombat = null>> /* 进行中战斗 */ <<set $combatEnemyTable = null>> /* 敌人定义表 */ <<set $combatLog = "">> /* 战斗日志 */ <<set $combatReturn = null>> /* 战斗返回passage */ /* ═══════════════════════════════════════════════════ NPC/CP */ <<set $npcState = null>> /* 当前NPC交互状态 */ <<set $activeNpc = null>> /* 当前NPC */ <<set $metNpcs = {}>> /* 已遇NPC {npcId: {firstDay, meetCount}} */ <<set $npcSpawnCooldown = 0>> /* NPC出现冷却 */ <<set $npcReturn = null>> /* NPC交互返回passage */ <<set $bondLevel = {}>> /* 好感度 {cpId: 0-100} */ <<set $cpUnlocked = {}>> /* CP解锁 {cpId: true} */ <<set $cpState = {}>> /* CP状态 */ <<set $cpActionResult = null>> /* CP交互结果 */ /* ═══════════════════════════════════════════════════ CP 升级新增全局 */ <<set $playerRecent = { caught:"", fought:"", lastAction:"", lastHarvest:"" }>> /* 玩家近期行为(陪伴类点评用) */ <<set $cpBondSettleDay = 1>> /* 上次 bond 结算所在天数(每日结算用) */ /* ═══════════════════════════════════════════════════ 任务 */ <<set $questFlags = {}>> /* 旗标 */ <<set $questProgress = 0>> /* 主线节点索引 */ <<set $questLog = []>> /* 日记条目 */ <<set $sideQuestProgress = {}>> /* 支线进度 */ <<set $sideQuestLog = {}>> /* 支线日记 */ <<set $questNotify = "">> /* 任务提示 */ /* ═══════════════════════════════════════════════════ 书签/地点 */ <<set $bookmarks = []>> /* 书签列表 */ <<set $activeLocations = []>> /* 当前区域挂载的固定地点 */ <<set $showBookmarks = false>> /* 是否显示书签 */ /* ═══════════════════════════════════════════════════ 仓外探索 */ <<set $divingMode = false>> /* 是否在仓外 */ <<set $diveOxygen = 100>> /* 当前氧气 */ <<set $diveOxygenMax = 100>> /* 氧气上限 */ <<set $diveCold = 0>> /* 冷压积累 */ <<set $diveStepsOut = 0>> /* 深入步数 */ <<set $diveStepCostO2 = 4>> /* 每步氧气消耗 */ <<set $diveStepTime = 3>> /* 每步时间消耗 */ <<set $diveChain = []>> /* 探索路线 */ <<set $diveChainSub = []>> /* 分叉路线 */ <<set $diveChainTerrain = "">> /* 路线地形 */ <<set $diveIdx = 0>> /* 位置指针 */ <<set $diveLog = "">> <<set $diveInteractResult = "">> <<set $diveO2Dead = false>> /* 氧气耗尽 */ <<set $diveArmBlocked = {}>> /* 被阻塞的元素 */ <<set $diveArmCleared = {}>> /* 已清除的障碍 */ <<set $diveShowIntro = false>> /* 显示简介 */ <<set $diveIntro = "">> /* ═══════════════════════════════════════════════════ 功能解锁 */ <<set $unlock = { sailing: true, /* 航行 */ fishing: false, /* 钓鱼 */ alchemy: false, /* 炼金 */ refine: false, /* 精炼 */ tincture: false, /* 酊剂 */ potion: false, /* 药剂 */ combat: true, /* 战斗 */ cook: false, /* 烹饪 */ settlement: false, /* 聚落 */ bookmarks: false, /* 书签 */ cp: false, /* CP系统 */ upgrade: false /* 升级 */ }>> /* ═══════════════════════════════════════════════════ 主线进度 */ <<set $storyPhase = 0>> /* 主线阶段(0=初始) */ <<set $storyFlags = {}>> /* 主线标志位 */ /* ═══════════════════════════════════════════════════ 聚落 */ <<set $settlementLevel = 0>> /* 繁荣度 */ <<set $settlementDonations = {}>> /* 捐赠记录 */ <<set $settlementResidents = []>> /* 居民列表 */ <<set $settlementReturnGifts = []>> /* 回礼记录 */ /* ═══════════════════════════════════════════════════ 系统 */ <<set $devMode = false>> /* 开发模式(发布前关闭) */ <<set $devCpId = "viona">> /* CP DEV 当前调试角色 */ <<set $devMsg = "">> /* DEV 调试台操作回执 */ <<set $autoBrake = false>> /* 自动刹车:进入地点接近范围时自动减速 */ <<set $lastUpgradeText = "">>
/* 精炼规则:原始材料 → 炼金材料 element: 水/火/土/风 form: 固/液/气/离子 ether: 以太析出概率 (0-1) etherType: "blessed"/"corrupt" */ <<set $refineRules = { fish_bone: { element:"水", form:"固", ether:0 }, fish_blood: { element:"水", form:"液", ether:0.2, etherType:"blessed" }, fish_scale: { element:"水", form:"固", ether:0 }, fish_roe: { element:"水", form:"液", ether:0.1, etherType:"blessed" }, fish_liver: { element:"水", form:"液", ether:0 }, gill_membrane: { element:"风", form:"固", ether:0 }, fin_membrane: { element:"风", form:"固", ether:0 }, air_sac: { element:"风", form:"固", ether:0 }, swim_bladder: { element:"风", form:"固", ether:0 }, jellyfluid: { element:"水", form:"液", ether:0 }, jellyfilm: { element:"水", form:"固", ether:0 }, jellyfish: { element:"水", form:"液", ether:0 }, kelp_fiber: { element:"土", form:"固", ether:0 }, seagrass_str: { element:"土", form:"固", ether:0 }, coral_frag: { element:"土", form:"固", ether:0.1, etherType:"blessed" }, shell_frag: { element:"土", form:"固", ether:0 }, shell_powder: { element:"土", form:"固", ether:0 }, crab_shell: { element:"土", form:"固", ether:0 }, urchin_spine_core:{ element:"土", form:"固", ether:0.3, etherType:"blessed" }, pearl_dust: { element:"土", form:"固", ether:0 }, pearl: { element:"土", form:"固", ether:0.15, etherType:"blessed" }, blackpearl: { element:"风", form:"固", ether:0.3, etherType:"corrupt" }, bone_ash: { element:"土", form:"固", ether:0 }, sand_extract: { element:"土", form:"液", ether:0 }, seawater_ext: { element:"水", form:"液", ether:0 }, seajelly: { element:"水", form:"液", ether:0 }, ember_crystal: { element:"火", form:"固", ether:0.8, etherType:"blessed" }, char_scale: { element:"火", form:"固", ether:0 }, coal: { element:"火", form:"固", ether:0 }, bile: { element:"火", form:"液", ether:0 }, current_stone: { element:"风", form:"固", ether:0.6, etherType:"blessed" }, god_ember: { element:"火", form:"液", ether:1.0, etherType:"blessed" }, deep_eye: { element:"水", form:"固", ether:0.4, etherType:"blessed" }, glass: { element:"土", form:"固", ether:0 }, wood: { element:"土", form:"固", ether:0 }, rope: { element:"土", form:"固", ether:0 }, metal: { element:"土", form:"固", ether:0 }, iron: { element:"土", form:"固", ether:0 }, rubber_seal: { element:"土", form:"固", ether:0 }, /* ══ 特殊粗制材料精炼规则 ══ */ jellyfish_tissue: { element:"火", form:"固", ether:0.15, etherType:"blessed" }, candle_jelly_core: { element:"风", form:"固", ether:0.2, etherType:"blessed" }, whale_relic_bone: { element:"水", form:"固", ether:0.1, etherType:"blessed" }, parasite: { element:"土", form:"固", ether:0.1, etherType:"corrupt" }, mermaid_bone: { element:"风", form:"固", ether:0.2, etherType:"blessed" }, mermaid_blood: { element:"风", form:"液", ether:0.3, etherType:"blessed" }, vitality: { element:"水", form:"离子", ether:0.4, etherType:"blessed" }, phosphor_flame: { element:"风", form:"离子", ether:0.3, etherType:"blessed" }, ambergris: { element:"土", form:"固", ether:0.2, etherType:"blessed" }, storm_flesh: { element:"火", form:"固", ether:0.15, etherType:"corrupt" }, glow_moss_juice: { element:"水", form:"液", ether:0.1, etherType:"blessed" }, salt_lake_crystal: { element:"土", form:"离子", ether:0.2, etherType:"blessed" }, soul_sea_slime: { element:"水", form:"离子", ether:0.3, etherType:"corrupt" }, soul_sea_bone: { element:"土", form:"固", ether:0.2, etherType:"corrupt" }, thaumas_blood: { element:"土", form:"液", ether:0.6, etherType:"corrupt" }, vent_glow_fluid: { element:"火", form:"液", ether:0.25, etherType:"blessed" }, tubeworm_fluid: { element:"火", form:"液", ether:0.1, etherType:"blessed" }, glow_coral: { element:"水", form:"固", ether:0.15, etherType:"blessed" }, giant_ray_sac: { element:"风", form:"气", ether:0.2, etherType:"blessed" }, inscription_frag: { element:"水", form:"气", ether:0.3, etherType:"blessed" }, surface_light: { element:"风", form:"气", ether:0.35, etherType:"blessed" }, god_bone_raw: { element:"火", form:"气", ether:0.8, etherType:"corrupt" }, ceto_breath: { element:"土", form:"气", ether:0.7, etherType:"corrupt" }, jade_feather: { element:"火", form:"离子", ether:0.4, etherType:"blessed" } }>> /* 仪器定义 instrument → { stage, single:{input,output}, tincture:{pair,result}, desc[], dur } */ <<set $alchemyInstrumentDefs = { "精炼台": { stage: "精炼", single: null, tincture: null, dur: 8, desc: [ { ratio:0, text:/*::GEN::炼金描述:: */"将原始材料放入精炼台,开始提取其中的元素精质。"/*::END:: */ }, { ratio:0.3, text:/*::GEN::炼金描述:: */"台面微微震动,材料的杂质开始向外析出。"/*::END:: */ }, { ratio:0.6, text:/*::GEN::炼金描述:: */"元素精质逐渐从混合物中分离,散发出淡淡的光晕。"/*::END:: */ }, { ratio:0.85, text:/*::GEN::炼金描述:: */"提炼接近完成,纯净的精质即将析出。"/*::END:: */ }, { ratio:1.0, text:"精炼完成。" } ] }, "溶解皿": { stage: "黑化", single: { input:"固", output:"液" }, tincture: { pair:["水","风"], result:"tincture_love" }, dur: 12, desc: [ { ratio:0, text:/*::GEN::炼金描述:: */"将材料投入溶解皿,溶剂开始缓慢渗透固体的结构。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::炼金描述:: */"固体外层开始软化,微小的气泡从底部涌起。"/*::END:: */ }, { ratio:0.5, text:/*::GEN::炼金描述:: */"溶解加速,材料的形态正在发生根本性的变化。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::炼金描述:: */"固体结构基本瓦解,液态精质在皿中汇聚。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::炼金描述:: */"黑化完成,固态已转化为液态。"/*::END:: */ } ] }, "蒸馏器": { stage: "白化", single: { input:"液", output:"气" }, tincture: { pair:["火","土"], result:"tincture_beacon" }, dur: 15, desc: [ { ratio:0, text:/*::GEN::炼金描述:: */"蒸馏器开始加热,液态材料在底部缓缓升温。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::炼金描述:: */"第一缕蒸汽升起,杂质开始在冷凝管壁上沉积。"/*::END:: */ }, { ratio:0.5, text:/*::GEN::炼金描述:: */"蒸馏稳定,纯净的气态精质向上汇聚,以太成分在此阶段分离。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::炼金描述:: */"大部分液体已转化,气态收集室中充满了精纯的蒸汽。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::炼金描述:: */"白化完成,液态已蒸馏为气态。"/*::END:: */ } ] }, "凝结炉": { stage: "黄化", single: { input:"气", output:"固" }, tincture: { pair:["水","土"], result:"tincture_silence" }, dur: 18, desc: [ { ratio:0, text:/*::GEN::炼金描述:: */"凝结炉降温启动,气态材料在低温环境中开始失去活性。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::炼金描述:: */"气体边缘出现细小的凝结点,逐渐向中心蔓延。"/*::END:: */ }, { ratio:0.5, text:/*::GEN::炼金描述:: */"相变正在发生,气态结构在压力与低温下开始固化。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::炼金描述:: */"固化接近完成,新形成的固态精质在炉底慢慢成形。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::炼金描述:: */"黄化完成,气态已凝结为固态。"/*::END:: */ } ] }, "赤化炉": { stage: "赤化", single: { input:null, output:"离子" }, tincture: { pair:["风","火"], result:"tincture_change" }, dur: 20, desc: [ { ratio:0, text:/*::GEN::炼金描述:: */"赤化炉内的共鸣核心开始激活,炉腔温度急速上升。"/*::END:: */ }, { ratio:0.2, text:/*::GEN::炼金描述:: */"材料的分子结构在极端条件下开始解离,散发出刺眼的光。"/*::END:: */ }, { ratio:0.5, text:/*::GEN::炼金描述:: */"离子化反应剧烈进行,物质以前所未有的状态存在着。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::炼金描述:: */"反应接近顶峰,高度不稳定的离子态精质在磁场约束下汇聚。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::炼金描述:: */"赤化完成,材料已跃迁为离子态。"/*::END:: */ } ] } }>> /* 形态→仪器名对应(用于提示玩家) */ <<set $formToInstrument = { "固":"溶解皿", "液":"蒸馏器", "气":"凝结炉" }>> /* 元素对→酊剂对应 */ <<set $tincturePairs = { "水_风": "tincture_love", "风_水": "tincture_love", "火_土": "tincture_beacon", "土_火": "tincture_beacon", "水_土": "tincture_silence","土_水": "tincture_silence", "风_火": "tincture_change", "火_风": "tincture_change" }>> /* 酊剂需要在哪个仪器里制备 */ <<set $tincturePairInstrument = { "水_风": "溶解皿", "风_水": "溶解皿", "火_土": "蒸馏器", "土_火": "蒸馏器", "水_土": "凝结炉", "土_水": "凝结炉", "风_火": "赤化炉", "火_风": "赤化炉" }>>
<<set $items = $items || {}>> <<set $items.alch_water_s = { size:1, name:/*::GEN::物品名::alch_water_s:: */"水·固精质"/*::END:: */, type:"炼金材料", element:"水", form:"固态", desc:/*::GEN::物品描述::alch_water_s:: */"具有流动性和渗透力,在分解与凝结反应中表现活跃。固态,结构稳定,适合作为仓储材料或黑化反应的输入端。"/*::END:: */ }>> <<set $items.alch_water_l = { size:1, name:/*::GEN::物品名::alch_water_l:: */"水·液精质"/*::END:: */, type:"炼金材料", element:"水", form:"液态", desc:/*::GEN::物品描述::alch_water_l:: */"具有流动性和渗透力,在分解与凝结反应中表现活跃。液态,流动活跃,适合作为黑化产物或白化反应的输入端。"/*::END:: */ }>> <<set $items.alch_water_g = { size:1, name:/*::GEN::物品名::alch_water_g:: */"水·气精质"/*::END:: */, type:"炼金材料", element:"水", form:"气态", desc:/*::GEN::物品描述::alch_water_g:: */"具有流动性和渗透力,在分解与凝结反应中表现活跃。气态,挥发性强,难以储存但反应迅速,适合白化产物或黄化输入。"/*::END:: */ }>> <<set $items.alch_water_i = { size:1, name:/*::GEN::物品名::alch_water_i:: */"水·离精质"/*::END:: */, type:"炼金材料", element:"水", form:"离子态", desc:/*::GEN::物品描述::alch_water_i:: */"具有流动性和渗透力,在分解与凝结反应中表现活跃。离子态,高度不稳定,蕴含大量能量,是赤化炉的专属产物与输入。"/*::END:: */ }>> <<set $items.alch_fire_s = { size:1, name:/*::GEN::物品名::alch_fire_s:: */"火·固精质"/*::END:: */, type:"炼金材料", element:"火", form:"固态", desc:/*::GEN::物品描述::alch_fire_s:: */"携带高温能量,易于触发蒸馏与升华反应。固态,结构稳定,适合作为仓储材料或黑化反应的输入端。"/*::END:: */ }>> <<set $items.alch_fire_l = { size:1, name:/*::GEN::物品名::alch_fire_l:: */"火·液精质"/*::END:: */, type:"炼金材料", element:"火", form:"液态", desc:/*::GEN::物品描述::alch_fire_l:: */"携带高温能量,易于触发蒸馏与升华反应。液态,流动活跃,适合作为黑化产物或白化反应的输入端。"/*::END:: */ }>> <<set $items.alch_fire_g = { size:1, name:/*::GEN::物品名::alch_fire_g:: */"火·气精质"/*::END:: */, type:"炼金材料", element:"火", form:"气态", desc:/*::GEN::物品描述::alch_fire_g:: */"携带高温能量,易于触发蒸馏与升华反应。气态,挥发性强,难以储存但反应迅速,适合白化产物或黄化输入。"/*::END:: */ }>> <<set $items.alch_fire_i = { size:1, name:/*::GEN::物品名::alch_fire_i:: */"火·离精质"/*::END:: */, type:"炼金材料", element:"火", form:"离子态", desc:/*::GEN::物品描述::alch_fire_i:: */"携带高温能量,易于触发蒸馏与升华反应。离子态,高度不稳定,蕴含大量能量,是赤化炉的专属产物与输入。"/*::END:: */ }>> <<set $items.alch_earth_s = { size:1, name:/*::GEN::物品名::alch_earth_s:: */"土·固精质"/*::END:: */, type:"炼金材料", element:"土", form:"固态", desc:/*::GEN::物品描述::alch_earth_s:: */"性质稳定厚重,是固化与形态锚定的理想材料。固态,结构稳定,适合作为仓储材料或黑化反应的输入端。"/*::END:: */ }>> <<set $items.alch_earth_l = { size:1, name:/*::GEN::物品名::alch_earth_l:: */"土·液精质"/*::END:: */, type:"炼金材料", element:"土", form:"液态", desc:/*::GEN::物品描述::alch_earth_l:: */"性质稳定厚重,是固化与形态锚定的理想材料。液态,流动活跃,适合作为黑化产物或白化反应的输入端。"/*::END:: */ }>> <<set $items.alch_earth_g = { size:1, name:/*::GEN::物品名::alch_earth_g:: */"土·气精质"/*::END:: */, type:"炼金材料", element:"土", form:"气态", desc:/*::GEN::物品描述::alch_earth_g:: */"性质稳定厚重,是固化与形态锚定的理想材料。气态,挥发性强,难以储存但反应迅速,适合白化产物或黄化输入。"/*::END:: */ }>> <<set $items.alch_earth_i = { size:1, name:/*::GEN::物品名::alch_earth_i:: */"土·离精质"/*::END:: */, type:"炼金材料", element:"土", form:"离子态", desc:/*::GEN::物品描述::alch_earth_i:: */"性质稳定厚重,是固化与形态锚定的理想材料。离子态,高度不稳定,蕴含大量能量,是赤化炉的专属产物与输入。"/*::END:: */ }>> <<set $items.alch_wind_s = { size:1, name:/*::GEN::物品名::alch_wind_s:: */"风·固精质"/*::END:: */, type:"炼金材料", element:"风", form:"固态", desc:/*::GEN::物品描述::alch_wind_s:: */"轻盈而具有扩散性,在气态反应与元素共鸣中表现突出。固态,结构稳定,适合作为仓储材料或黑化反应的输入端。"/*::END:: */ }>> <<set $items.alch_wind_l = { size:1, name:/*::GEN::物品名::alch_wind_l:: */"风·液精质"/*::END:: */, type:"炼金材料", element:"风", form:"液态", desc:/*::GEN::物品描述::alch_wind_l:: */"轻盈而具有扩散性,在气态反应与元素共鸣中表现突出。液态,流动活跃,适合作为黑化产物或白化反应的输入端。"/*::END:: */ }>> <<set $items.alch_wind_g = { size:1, name:/*::GEN::物品名::alch_wind_g:: */"风·气精质"/*::END:: */, type:"炼金材料", element:"风", form:"气态", desc:/*::GEN::物品描述::alch_wind_g:: */"轻盈而具有扩散性,在气态反应与元素共鸣中表现突出。气态,挥发性强,难以储存但反应迅速,适合白化产物或黄化输入。"/*::END:: */ }>> <<set $items.alch_wind_i = { size:1, name:/*::GEN::物品名::alch_wind_i:: */"风·离精质"/*::END:: */, type:"炼金材料", element:"风", form:"离子态", desc:/*::GEN::物品描述::alch_wind_i:: */"轻盈而具有扩散性,在气态反应与元素共鸣中表现突出。离子态,高度不稳定,蕴含大量能量,是赤化炉的专属产物与输入。"/*::END:: */ }>> <<set $items.ether_blessed = { size:1, name:/*::GEN::物品名::ether_blessed:: */"祝福以太碎片"/*::END:: */, type:"以太副产物", desc:/*::GEN::物品描述::ether_blessed:: */"白化分离时析出的洁净以太,带着隐约的温暖光晕,是稀有的炼金附产物。"/*::END:: */ }>> <<set $items.ether_corrupt = { size:1, name:/*::GEN::物品名::ether_corrupt:: */"污染以太碎片"/*::END:: */, type:"以太副产物", desc:/*::GEN::物品描述::ether_corrupt:: */"白化分离时析出的浑浊以太,散发着不安定的气息,用途特殊但需谨慎处理。"/*::END:: */ }>> <<set $items.alch_residue = { size:1, name:/*::GEN::物品名::alch_residue:: */"炼金杂质"/*::END:: */, type:"炼金材料", desc:/*::GEN::物品描述::alch_residue:: */"精炼或四化过程中分离出的杂质,成分复杂,可重新投入精炼台二次处理。"/*::END:: */ }>> <<set $items.alch_mixed = { size:1, name:/*::GEN::物品名::alch_mixed:: */"混杂精质"/*::END:: */, type:"炼金材料", desc:/*::GEN::物品描述::alch_mixed:: */"两种不相容元素在错误条件下反应的产物,需重新精炼才能分离出有效成分。"/*::END:: */ }>> <<set $items.tincture_love = { size:1, name:/*::GEN::物品名::tincture_love:: */"慈爱纯粹酊剂"/*::END:: */, type:"纯粹酊剂", form:"液态", desc:/*::GEN::物品描述::tincture_love:: */"水与风的共鸣产物,呈半透明的流动液体,渗透力极强,是慈爱理型力量的凝聚。"/*::END:: */ }>> <<set $items.tincture_beacon = { size:1, name:/*::GEN::物品名::tincture_beacon:: */"信标纯粹酊剂"/*::END:: */, type:"纯粹酊剂", form:"气态", desc:/*::GEN::物品描述::tincture_beacon:: */"火与土的共鸣产物,以薄雾形态封存于特制容器,是信标理型力量的凝聚。"/*::END:: */ }>> <<set $items.tincture_silence = { size:1, name:/*::GEN::物品名::tincture_silence:: */"死寂纯粹酊剂"/*::END:: */, type:"纯粹酊剂", form:"固态", desc:/*::GEN::物品描述::tincture_silence:: */"水与土的共鸣产物,沉重的深色固体,边界分明、永恒静止,是死寂理型力量的凝聚。"/*::END:: */ }>> <<set $items.tincture_change = { size:1, name:/*::GEN::物品名::tincture_change:: */"变革纯粹酊剂"/*::END:: */, type:"纯粹酊剂", form:"离子态", desc:/*::GEN::物品描述::tincture_change:: */"风与火的共鸣产物,以不稳定的离子态存在,蕴含剧烈的变革力量,极难储存。"/*::END:: */ }>> <<set $items.philosophers_stone = { size:1, name:/*::GEN::物品名::philosophers_stone:: */"贤者之石"/*::END:: */, type:"纯粹酊剂", desc:/*::GEN::物品描述::philosophers_stone:: */"四种纯粹酊剂融合的终极产物,外观如黑红相间的石块,内部流动着看不见的光。传说中可以改变一切物质的本质。"/*::END:: */ }>>
<<nobr>> <<widget "combatEnemyDefs">> <<set $combatEnemyTable = {}>> <<set $combatEnemyTable["jellyfish_swarm"] = { name:/*::GEN::敌人名:: */"水母群"/*::END:: */, alertness:30, morale:[40,60], hp:40, injuryMax:50, loot:[{id:"jellyfish",qty:[1,2]}], stateDesc:{ high_high:/*::GEN::状态描述:: */"水母群密密麻麻地环绕着你,触手微微颤动"/*::END:: */, high_low: /*::GEN::状态描述:: */"水母群开始向外扩散,似乎在寻找退路"/*::END:: */, low_high: /*::GEN::状态描述:: */"水母群毫无章法地涌来,刺针乱舞"/*::END:: */, low_low: /*::GEN::状态描述:: */"水母群已经溃散,漫无目的地漂流"/*::END:: */ }, hpDesc:{ 50:/*::GEN::状态描述:: */"水母群数量明显减少"/*::END:: */, 25:/*::GEN::状态描述:: */"残余的水母萎靡漂散"/*::END:: */ }, injuryDesc:{ 40:/*::GEN::状态描述:: */"部分水母已经破碎"/*::END:: */, 70:/*::GEN::状态描述:: */"水母群几近瓦解"/*::END:: */ } }>> <<set $combatEnemyTable["armored_crab"] = { name:/*::GEN::敌人名:: */"岩甲蟹"/*::END:: */, alertness:55, morale:[60,80], hp:60, injuryMax:70, loot:[{id:"kingcrab",qty:[1,1]},{id:"fish_bone",qty:[0,1]}], stateDesc:{ high_high:/*::GEN::状态描述:: */"岩甲蟹横举双钳,步步为营地逼近"/*::END:: */, high_low: /*::GEN::状态描述:: */"岩甲蟹缩入壳中,双眼警惕地盯着你"/*::END:: */, low_high: /*::GEN::状态描述:: */"岩甲蟹横冲直撞,钳子横扫而来"/*::END:: */, low_low: /*::GEN::状态描述:: */"岩甲蟹踉踉跄跄,夹钳无力地垂着"/*::END:: */ }, hpDesc:{ 50:/*::GEN::状态描述:: */"它的动作开始迟缓"/*::END:: */, 25:/*::GEN::状态描述:: */"它气喘吁吁,步伐沉重"/*::END:: */ }, injuryDesc:{ 40:/*::GEN::状态描述:: */"它的外壳出现了裂缝"/*::END:: */, 70:/*::GEN::状态描述:: */"血从甲缝中渗出"/*::END:: */ } }>> <<set $combatEnemyTable["patrol_shark"] = { name:/*::GEN::敌人名:: */"巡游鲨"/*::END:: */, alertness:65, morale:[65,85], hp:100, injuryMax:80, loot:[{id:"fish_scale",qty:[1,2]},{id:"fish_meat",qty:[1,3]}], stateDesc:{ high_high:/*::GEN::状态描述:: */"它警惕地环绕你游动,伺机而动"/*::END:: */, high_low: /*::GEN::状态描述:: */"它保持距离,似乎在犹豫是否撤退"/*::END:: */, low_high: /*::GEN::状态描述:: */"它毫无顾忌地直扑过来"/*::END:: */, low_low: /*::GEN::状态描述:: */"它慌乱地冲撞,动作越来越混乱"/*::END:: */ }, hpDesc:{ 50:/*::GEN::状态描述:: */"它的动作开始迟缓"/*::END:: */, 25:/*::GEN::状态描述:: */"它气喘吁吁,游动愈发沉重"/*::END:: */ }, injuryDesc:{ 40:/*::GEN::状态描述:: */"它身上渗出淡淡的血色"/*::END:: */, 70:/*::GEN::状态描述:: */"血流不止,伤口在水中晕开大片红雾"/*::END:: */ } }>> <<set $combatEnemyTable["deep_eel"] = { name:"狼鳗", alertness:70, morale:[50,70], hp:50, injuryMax:60, loot:[{id:"eel",qty:[1,2]}], stateDesc:{ high_high:/*::GEN::状态描述:: */"狼鳗缠绕成螺旋,在暗处窥视你的破绽"/*::END:: */, high_low: /*::GEN::状态描述:: */"它收缩身体,慢慢向后退去"/*::END:: */, low_high: /*::GEN::状态描述:: */"狼鳗猛地弹射而来,獠牙大张"/*::END:: */, low_low: /*::GEN::状态描述:: */"它扭动着受伤的身躯,本能地乱咬"/*::END:: */ }, hpDesc:{ 50:/*::GEN::状态描述:: */"它的扭动变得迟钝"/*::END:: */, 25:/*::GEN::状态描述:: */"它颤抖着,几乎无法保持姿态"/*::END:: */ }, injuryDesc:{ 40:/*::GEN::状态描述:: */"它皮肤上出现了撕裂伤"/*::END:: */, 70:/*::GEN::状态描述:: */"它血迹斑斑,奄奄一息"/*::END:: */ } }>> <<set $combatEnemyTable["angler_lurker"] = { name:/*::GEN::敌人名:: */"深渊灯笼鱼"/*::END:: */, alertness:75, morale:[55,75], hp:80, injuryMax:85, loot:[{id:"anglerfish",qty:[1,1]},{id:"fish_meat",qty:[1,2]}], stateDesc:{ high_high:/*::GEN::状态描述:: */"它的诱饵灯摇曳着,耐心等待你靠近"/*::END:: */, high_low: /*::GEN::状态描述:: */"诱饵灯光芒黯淡,它缓缓向深处沉去"/*::END:: */, low_high: /*::GEN::状态描述:: */"它张开血盆大口直扑而来,诱饵乱晃"/*::END:: */, low_low: /*::GEN::状态描述:: */"它慌乱地闪烁着微弱的光,四处乱窜"/*::END:: */ }, hpDesc:{ 50:/*::GEN::状态描述:: */"它的发光器官开始闪烁不稳"/*::END:: */, 25:/*::GEN::状态描述:: */"它几乎无法维持平衡"/*::END:: */ }, injuryDesc:{ 40:/*::GEN::状态描述:: */"它的鳞片破碎脱落"/*::END:: */, 70:/*::GEN::状态描述:: */"它的伤口在黑暗中发着惨淡的光"/*::END:: */ } }>> <</widget>> <</nobr>>
/* 每种食材在不同烹饪方式下的感官描述碎片(1-2句) 降级规则:fragments[id][method] → fragments[id]["_"] → fragments["_tag_"][method] → "" key "_tag_" 为分类兜底 */ <<set $cookFragments = { /* ─── 鱼肉 ─── */ "salmon_meat": { "明火烤": /*::GEN::烹饪碎片:: */"鲑鱼肉在炭火上油脂渗出,粉红色的肌肉转变为金黄,边缘微微焦脆。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"鲑鱼肉在蒸汽中轻柔展开,橙粉色的纹理清晰可见,脂肪的清香随热气散开。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"鲑鱼肉融入汤底,脂肪乳化,汤色呈现乳白,带来醇厚的回甘。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"鲑鱼肉入锅后嗤嗤作响,外层迅速锁住汁水,焦香的表皮包裹着嫩滑的鱼肉。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"鲑鱼肉在热油中翻滚,金黄酥脆,切开后橙色的内里冒着热气。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"鲑鱼肉切成薄片,粉红色的纹理如同绸缎,入口即化,带着淡淡的海水甘甜。"/*::END:: */ }, "cod_meat": { "明火烤": /*::GEN::烹饪碎片:: */"鳕鱼肉在炭火上层层剥落,雪白的鱼肉沿纹理分离,带着淡淡的焦香。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"鳕鱼肉的层状纹理在蒸汽中清晰展现,用筷子轻轻一拨就成片,汁水清甜。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"鳕鱼肉在汤底慢慢软化,释放出清淡的鲜味,汤色维持透明。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"鳕鱼肉入热锅,表面迅速变白定型,外脆内嫩,口感清淡而鲜美。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"鳕鱼肉片在热油中膨胀酥化,外层金黄,内里依然洁白软嫩。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"鳕鱼肉洁白如雪,切成薄片后几乎透明,鲜味清淡纯粹。"/*::END:: */ }, "tuna_meat": { "明火烤": /*::GEN::烹饪碎片:: */"金枪鱼肉在炭火上迅速变色,深红转为棕色,油脂在表面渗出带着焦香。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"金枪鱼肉在蒸汽中保持着厚实的质地,深色的肌肉透出血铁质特有的浓郁鲜味。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"金枪鱼肉入汤,将汤底染上淡淡的红色,释放出浓厚的海鲜鲜味。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"金枪鱼肉入锅,表面迅速上色,内里保持粉红,大火快炒保留了汁水。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"金枪鱼肉裹粉入油,外层酥脆,内里仍带着特有的铁腥鲜味。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"金枪鱼肉呈深红色,油脂丰富,切成厚片后在舌尖缓缓化开,是最适合生食的鱼肉之一。"/*::END:: */ }, "eel_meat": { "明火烤": /*::GEN::烹饪碎片:: */"鳗鱼肉在炭火上油脂大量渗出,滴落在炭上腾起白烟,香气极其浓郁。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"鳗鱼肉在蒸汽中软化,脂肪均匀渗透肌肉,口感绵密而香腴。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"鳗鱼肉在汤底慢慢熬煮,大量脂肪融入汤中,汤底变得异常浓郁丰腴。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"鳗鱼肉入热锅,油脂迅速渗出自行润锅,焦香与脂香同时散发。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"鳗鱼肉的高油脂在炸制时产生独特的香气,外层酥脆而内里极为软嫩。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"鳗鱼特有的脂香在烹饪过程中持续散发,是少数越简单处理越出彩的食材。"/*::END:: */ }, "flounder_meat": { "清蒸": /*::GEN::烹饪碎片:: */"比目鱼肉的两片薄肉在蒸汽中微微卷起,洁白如雪,鲜甜几乎不需要任何调味。"/*::END:: */, "明火烤": /*::GEN::烹饪碎片:: */"比目鱼薄肉在炭火上迅速熟透,边缘焦脆,中心依然嫩滑。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"比目鱼肉在汤底几乎化开,留下清甜的鲜味而不见形状。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"比目鱼肉切成透明薄片,晶莹剔透,入口的清甜令人难忘。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"比目鱼肉质极嫩,任何烹饪方式都需要控制时间,稍过就会失去独特的细腻。"/*::END:: */ }, "sardine_meat": { "明火烤": /*::GEN::烹饪碎片:: */"沙丁鱼肉在炭火上脂肪渗出,腥气在高温中转化为浓郁的焦香。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"沙丁鱼肉在汤底快速散开,将丰富的脂肪释放进汤中,味道厚重而直接。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"沙丁鱼肉细碎而脂肪丰富,加热后腥气转化为独特的浓郁鲜味。"/*::END:: */ }, /* ─── 贝肉 ─── */ "scallop_meat": { "明火烤": /*::GEN::烹饪碎片:: */"扇贝肉在炭火边缘慢慢受热,圆润的闭壳肌微微焦化,边缘泛出金黄色。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"扇贝肉在蒸汽中保持着丰腴的形态,表面微微收紧,汁水锁在内里。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"扇贝肉在汤底慢慢舒展,释放出浓郁的贝汁,汤底因此带上乳白色的甜鲜。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"扇贝肉入热锅,两面各煎出金黄的焦壳,内里保持嫩滑,鲜甜迸发。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"扇贝肉洁白圆润,生食时鲜甜几乎不需要任何佐料,是最直接的海洋馈赠。"/*::END:: */ }, "oyster_meat": { "明火烤": /*::GEN::烹饪碎片:: */"牡蛎在炭火上慢慢加热,壳边汁水沸腾,带着海水咸鲜的蒸汽腾起。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"牡蛎在蒸汽中保持了饱满的形态,汁水充盈在壳内,矿物鲜味极为浓郁。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"牡蛎入汤后软化,将浓烈的矿物鲜味全部释放,汤底因此格外深沉。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"牡蛎的软体光滑饱满,生食时带着海水的冷冽与矿物的复杂,入口即化。"/*::END:: */ }, "clam_meat": { "铜锅炖": /*::GEN::烹饪碎片:: */"蛤蜊肉在汤底中释放出浓郁的贝汁,将清澈的汤底迅速染上深沉的鲜味。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"蛤蜊肉在蒸汽中收紧,壳内积聚的原汁是汤汁中最鲜甜的部分。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"蛤蜊肉入热锅,贝汁迅速蒸发浓缩,鲜味在瞬间变得极为集中。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"蛤蜊的咸鲜味道极为浓郁,少量入菜便能提升整道料理的层次。"/*::END:: */ }, /* ─── 虾肉 ─── */ "prawn_meat": { "明火烤": /*::GEN::烹饪碎片:: */"对虾在炭火上迅速变红,壳与肉之间的汁水被封存,外层微微焦脆。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"对虾在蒸汽中保持着弯曲的形态,弹牙的肉质在蒸汽中达到最佳口感。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"对虾入汤后橙红色的虾壳将甜鲜释放进汤底,虾肉保持弹牙。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"对虾入热锅,壳迅速锁住内部的汁水,大火翻炒出弹牙的口感。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"整只对虾裹粉入油,外壳酥脆,一口咬下汁水迸发。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"对虾肉半透明,处理好后带着清甜的鲜味,是生食中口感最佳的虾类。"/*::END:: */ }, "lobster_meat": { "明火烤": /*::GEN::烹饪碎片:: */"龙虾肉在炭火上受热,厚实的肌肉纤维分离,表面微焦而内里极为鲜嫩。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"龙虾在蒸汽中慢慢熟透,厚实的肌肉在蒸汽中保持了丰润的汁水。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"龙虾肉入汤,将浓郁的甜鲜释放进汤底,是所有海鲜中汤底最浓郁的之一。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"龙虾肉厚实而鲜甜,是虾类中品质最高的食材,任何烹饪方式都难以糟蹋它。"/*::END:: */ }, /* ─── 蟹肉 ─── */ "kingcrab_meat": { "明火烤": /*::GEN::烹饪碎片:: */"帝王蟹肉纤维分明,在炭火上慢慢受热,蟹黄的香气随油脂渗出。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"帝王蟹肉在蒸汽中保持了厚实的质地,洁白的肌肉纤维呈现美丽的条纹。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"帝王蟹腿肉入汤,将浓厚的甜鲜析入汤底,是最奢华的汤底来源。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"帝王蟹肉是蟹类中最为丰厚的食材,纤维质感和甜鲜味道在海鲜中无与伦比。"/*::END:: */ }, "crab_meat": { "清蒸": /*::GEN::烹饪碎片:: */"蟹肉在蒸汽中慢慢熟透,蟹黄凝固成金色,拆开后鲜甜浓郁。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"蟹肉与蟹黄在汤底中慢慢融合,将橙黄色的浓郁鲜味渗入汤底。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"蟹肉细腻鲜甜,蟹黄的浓香是整道料理的灵魂。"/*::END:: */ }, /* ─── 腕足 ─── */ "squid_meat": { "明火烤": /*::GEN::烹饪碎片:: */"鱿鱼筒在炭火上迅速卷曲,表面焦化,吸盘弹开,散发出特有的海鲜焦香。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"鱿鱼肉在蒸汽中保持着筒状,微微收紧,口感介于嫩滑与Q弹之间。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"鱿鱼肉入锅,墨汁轻微渗出,为汤底添加了一层深沉的海洋气息。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"鱿鱼圈入热锅,大火快炒,吸盘在锅气中膨胀,外缘微焦,口感爽脆。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"鱿鱼圈裹粉入油,外层酥脆金黄,内里依然Q弹,是最受欢迎的炸海鲜形态。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"鱿鱼肉切成薄片,晶莹如玉,Q弹的口感与淡淡的海水甜味令人印象深刻。"/*::END:: */ }, "octopus_meat": { "铜锅炖": /*::GEN::烹饪碎片:: */"章鱼肉入锅,墨囊破裂,漆黑的墨汁将汤底染成深邃的黑色,带着复杂的海洋鲜味。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"章鱼腕足入热锅,吸盘在高温下焦脆,大火快炒出弹牙的口感与焦香。"/*::END:: */, "明火烤": /*::GEN::烹饪碎片:: */"章鱼肉在炭火上受热卷曲,吸盘变脆,表面焦化,散发浓郁的烟熏海鲜香气。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"章鱼肉含有大量墨汁,烹饪时往往为料理增添深色与独特的矿物气息。"/*::END:: */ }, "cuttlefish_meat": { "铜锅炖": /*::GEN::烹饪碎片:: */"墨鱼肉入汤,厚实的外套膜慢慢软化,特有的墨囊香气弥漫在汤底之中。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"墨鱼肉入热锅,厚实的肉质在大火中保持形状,口感比鱿鱼更为厚重扎实。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"墨鱼肉厚实肥腴,口感介于鱿鱼与章鱼之间,墨囊香气是其独特之处。"/*::END:: */ }, /* ─── 海草 ─── */ "dried_kelp": { "铜锅炖": /*::GEN::烹饪碎片:: */"干海带泡发后入锅,在热汤中慢慢舒展,释放出深海的矿物鲜味与淡淡的碘香。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"泡发的海带切段入热锅,翻炒中水分蒸发,口感从柔韧变为微脆。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"干海带泡发后体积大幅增加,带着浓缩的矿物鲜味,是汤底的极佳提鲜材料。"/*::END:: */ }, "dried_nori": { "铜锅炖": /*::GEN::烹饪碎片:: */"干紫菜遇水迅速软化舒展,将深绿色与浓郁的海洋鲜味释放进汤底。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"干紫菜可以直接入口,薄脆的质感在口中化开,带着淡淡的盐味与海洋清香。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"干紫菜处理简单,鲜味浓缩,少量入菜便能大幅提升整体风味。"/*::END:: */ }, "seajelly": { "生食": /*::GEN::烹饪碎片:: */"水母冻处理干净后呈现半透明的凝冻状,口感极为滑嫩,几乎无味,需要配合其他食材。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"水母冻在蒸汽中进一步凝固,口感从滑嫩转为略带弹性,保留了独特的质地。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"水母冻几乎无味,其价值在于独特的滑嫩口感,以及作为其他食材风味的衬托。"/*::END:: */ }, /* ─── 块茎蔬菜 ─── */ "potato_tuber": { "明火烤": /*::GEN::烹饪碎片:: */"海薯在炭火边缘慢慢受热,外皮焦化,内里的淀粉糊化为绵软的质地。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"海薯切块入锅,淀粉慢慢析出,汤底因此变得浓稠丰满。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"海薯切片入热油,表面迅速焦化,内里绵软,咸香的口感令人满足。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"海薯淀粉含量高,任何烹饪方式都能带来饱腹感与绵密的质地。"/*::END:: */ }, "kelp_tuber": { "铜锅炖": /*::GEN::烹饪碎片:: */"海带茎切段入汤,在沸腾中软化,释放出淡淡的矿物鲜味,口感保持脆爽。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"海带茎大火快炒,保留了脆爽的口感,表面微微焦化带来咸香。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"海带茎比海带叶更为厚实,口感脆爽,矿物质含量丰富。"/*::END:: */ }, "sealeaf": { "煎炒": /*::GEN::烹饪碎片:: */"海叶菜入热锅,大火翻炒,水分迅速蒸发,叶片边缘微微焦脆。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"海叶菜质地脆嫩,生食时带着淡淡的咸味与清新的植物气息。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"海叶菜入汤后迅速软化,将淡绿色与清新的植物鲜味释放进汤底。"/*::END:: */ }, "sprout": { "煎炒": /*::GEN::烹饪碎片:: */"芽苗入热锅,脆嫩的茎叶在大火中迅速软化,保留了鲜亮的绿色。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"芽苗清脆多汁,生食时鲜嫩清甜,带着植物特有的清香。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"芽苗生长迅速,质地脆嫩,无论何种烹饪方式都能带来清新的口感。"/*::END:: */ }, /* ─── 谷物 ─── */ "wheat_grain": { "铜锅炖": /*::GEN::烹饪碎片:: */"小麦粒在大量水中慢慢熬煮,淀粉充分糊化,粥底变得绵密醇厚。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"熟制的小麦粒入热锅,在锅气中迅速分离,外层微脆,香气浓郁。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"小麦的淀粉质地在烹饪中提供扎实的饱腹感,是耐饿的基础食材。"/*::END:: */ }, "seaweed_grain": { "铜锅炖": /*::GEN::烹饪碎片:: */"海草籽在水中慢慢膨胀糊化,粥底带着淡淡的海洋清香,质地比普通粥更为细腻。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"海草籽营养密度高,在熬煮中散发出淡淡的海洋气息,是特殊的谷物选择。"/*::END:: */ }, /* ─── 分类兜底 ─── */ "_鱼_": { "明火烤": /*::GEN::烹饪碎片:: */"鱼肉在炭火上油脂渗出,表面逐渐焦化,鲜味被封存在内里。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"鱼肉在蒸汽中慢慢熟透,保留了鲜嫩的质地与天然的鲜甜。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"鱼肉在汤底中释放出清甜的鲜味,汤色随脂肪含量变得乳白或清澈。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"鱼肉入热锅,外层迅速定型,大火保住了内里的汁水与鲜嫩。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"鱼肉在热油中酥化,外脆内嫩,鱼的鲜味被完好地封存其中。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"鱼肉新鲜处理,原始的海洋鲜甜不加掩饰地呈现。"/*::END:: */ }, "_虾_": { "明火烤": /*::GEN::烹饪碎片:: */"虾在高温下迅速变红,壳肉之间的汁水被封存,弹牙鲜甜。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"虾在蒸汽中弯曲定型,肉质Q弹,鲜甜充盈。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"虾入汤后橙红色的壳将甜鲜渗入汤底,肉质保持弹牙。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"虾入热锅,壳锁汁水,大火翻炒出弹牙的口感。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"虾在热油中酥化,外壳脆响,咬下去汁水迸发。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"新鲜的虾肉半透明,处理好后鲜甜清爽。"/*::END:: */ }, "_蟹_": { "明火烤": /*::GEN::烹饪碎片:: */"蟹肉在炭火边慢慢受热,蟹黄的香气随油脂渗出。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"蟹在蒸汽中慢慢熟透,蟹黄凝固为金色,鲜甜达到顶点。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"蟹肉入汤,蟹黄溶入汤底,汤色变得橙黄浓郁。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"蟹肉在大火中迅速上色,蟹黄的浓香弥漫开来。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"蟹的鲜甜在高温中完全释放,蟹黄是整道料理的灵魂所在。"/*::END:: */ }, "_贝_": { "明火烤": /*::GEN::烹饪碎片:: */"贝类在高温下慢慢开口,汁水蒸发浓缩,鲜甜与焦香交融。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"贝类在蒸汽中张开,原汁积聚在壳内,是纯粹的海洋鲜甜。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"贝类入汤,壳在沸腾中开口,将浓郁的贝汁全部释放。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"贝肉入热锅,鲜甜被迅速封存,口感爽脆。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"贝肉裹粉入油,外层酥脆,内里依然鲜嫩多汁。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"贝肉带着天然的海水咸鲜,生食是最诚实的呈现方式。"/*::END:: */ }, "_腕足_": { "明火烤": /*::GEN::烹饪碎片:: */"腕足在炭火上卷曲,吸盘变脆,表面焦化,散发独特的烟熏海鲜香气。"/*::END:: */, "清蒸": /*::GEN::烹饪碎片:: */"腕足在蒸汽中保持形态,Q弹的肌肉在蒸汽中缓缓达到最佳状态。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"腕足入汤,墨汁若隐若现,汤底带上了深沉的海洋气息。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"腕足在热锅中卷曲,吸盘焦脆,大火快炒出弹牙的口感。"/*::END:: */, "油炸": /*::GEN::烹饪碎片:: */"腕足裹粉入油,外层酥脆,内里Q弹,是炸海鲜中口感最丰富的之一。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"腕足薄切后晶莹剔透,Q弹的口感在生食中格外突出。"/*::END:: */ }, "_海草_": { "铜锅炖": /*::GEN::烹饪碎片:: */"海草在热汤中舒展,释放出矿物鲜味与淡淡的碘香。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"海草入热锅,水分蒸发,口感从柔韧变为微脆。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"海草漂洗后保留了海洋的原始清新,是最低调的生食食材。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"海草带着来自深海的矿物气息,是料理中独特的点缀与提鲜材料。"/*::END:: */ }, "_蔬菜_": { "铜锅炖": /*::GEN::烹饪碎片:: */"蔬菜在热汤中慢慢软化,为汤底带来植物的清甜与绿意。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"蔬菜在大火中迅速熟化,保留脆爽的口感与鲜亮的色泽。"/*::END:: */, "生食": /*::GEN::烹饪碎片:: */"蔬菜清洗后保留了脆嫩的质地与天然的清甜。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"蔬菜为料理增添清新的色彩与植物的天然甘甜。"/*::END:: */ }, "_块茎_": { "明火烤": /*::GEN::烹饪碎片:: */"块茎在炭火中缓缓熟透,外皮焦化,内里绵软香甜。"/*::END:: */, "铜锅炖": /*::GEN::烹饪碎片:: */"块茎的淀粉在炖煮中析出,让汤底变得浓稠而有饱腹感。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"块茎切片入热油,表面焦化,内里绵软,满足而朴素。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"块茎富含淀粉,任何烹饪方式都能带来扎实的饱腹感。"/*::END:: */ }, "_谷物_": { "铜锅炖": /*::GEN::烹饪碎片:: */"谷物在大量水中慢慢膨胀糊化,淀粉充分释放,粥底醇厚绵密。"/*::END:: */, "煎炒": /*::GEN::烹饪碎片:: */"熟谷物在锅气中分离翻炒,每一粒都饱含香气。"/*::END:: */, "_": /*::GEN::烹饪碎片:: */"谷物是最耐饿的食材,提供了稳定而持久的热量。"/*::END:: */ } }>>
/* ── 单类模板:1种食材,单一分类标签 ── key = "分类标签_烹饪方式" 当选择1种食材时命中对应 key 查询 */ <<set $cookSingleTemplates = { /* ─── 鱼 ─── */ "鱼_明火烤": { name:/*::GEN::菜品模板名:: */"烤鱼"/*::END:: */, hunger:18, water:0, life:4, power:2, san:3, magic:0, dur:25, sMin:6, sMax:22, pMin:10, pMax:18, open:/*::GEN::烹饪开场白:: */"鱼肉架在炭火上,油脂渗出,滋滋作响。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"表皮焦香而内里鲜嫩,是最朴素也最直接的美味。"/*::END:: */ }, "鱼_清蒸": { name:/*::GEN::菜品模板名:: */"清蒸鱼"/*::END:: */, hunger:16, water:3, life:6, power:1, san:4, magic:0, dur:28, sMin:7, sMax:25, pMin:12, pMax:21, open:/*::GEN::烹饪开场白:: */"鱼肉摆入蒸格,蒸汽轻柔地将热量渗入肌理。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"肉质细嫩,鲜味完整地保存在每一片纤维里。"/*::END:: */ }, "鱼_铜锅炖": { name:/*::GEN::菜品模板名:: */"鱼汤"/*::END:: */, hunger:15, water:12, life:5, power:1, san:3, magic:0, dur:30, sMin:8, sMax:27, pMin:14, pMax:22, open:/*::GEN::烹饪开场白:: */"鱼肉入锅,汤底逐渐泛起奶白色的乳化脂肪。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底鲜甜,喝下去从胃里暖到指尖。"/*::END:: */ }, "鱼_煎炒": { name:/*::GEN::菜品模板名:: */"煎鱼"/*::END:: */, hunger:17, water:0, life:3, power:3, san:2, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:/*::GEN::烹饪开场白:: */"热锅冷油,鱼肉下锅的瞬间嗤嗤作响。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"两面金黄,外脆里嫩,锅气赋予了鱼肉额外的香气。"/*::END:: */ }, "鱼_油炸": { name:/*::GEN::菜品模板名:: */"炸鱼"/*::END:: */, hunger:20, water:-2, life:2, power:3, san:2, magic:0, dur:22, sMin:5, sMax:19, pMin:9, pMax:16, open:/*::GEN::烹饪开场白:: */"鱼肉裹上薄薄的粉衣,在滚热的油中翻滚。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"捞出后金黄酥脆,每一口都是热油的满足感。"/*::END:: */ }, "鱼_生食": { name:/*::GEN::菜品模板名:: */"鱼刺身"/*::END:: */, hunger:12, water:2, life:3, power:0, san:5, magic:1, dur:15, sMin:4, sMax:13, pMin:6, pMax:11, open:/*::GEN::烹饪开场白:: */"将最新鲜的鱼肉切成薄片,刀工决定一切。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"入口即化,是对食材原味最诚实的呈现。"/*::END:: */ }, /* ─── 虾 ─── */ "虾_明火烤": { name:/*::GEN::菜品模板名:: */"烤虾"/*::END:: */, hunger:16, water:0, life:3, power:2, san:3, magic:0, dur:18, sMin:5, sMax:16, pMin:8, pMax:14, open:/*::GEN::烹饪开场白:: */"虾放上烤架,外壳在高温中迅速变红。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"弹牙的虾肉带着炭火的焦香,壳与肉之间汁水充盈。"/*::END:: */ }, "虾_清蒸": { name:/*::GEN::菜品模板名:: */"清蒸虾"/*::END:: */, hunger:14, water:3, life:4, power:1, san:3, magic:0, dur:20, sMin:5, sMax:18, pMin:9, pMax:15, open:/*::GEN::烹饪开场白:: */"虾整齐排入蒸格,蒸汽升腾。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"虾肉Q弹鲜甜,原味丝毫未失。"/*::END:: */ }, "虾_铜锅炖": { name:/*::GEN::菜品模板名:: */"虾汤"/*::END:: */, hunger:13, water:10, life:4, power:1, san:2, magic:0, dur:25, sMin:6, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"虾入锅,橙红色的虾壳将颜色渗入汤底。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底带着淡淡的甜鲜,是简单而令人满足的一碗。"/*::END:: */ }, "虾_煎炒": { name:/*::GEN::菜品模板名:: */"炒虾"/*::END:: */, hunger:15, water:0, life:2, power:3, san:2, magic:0, dur:18, sMin:4, sMax:16, pMin:7, pMax:14, open:/*::GEN::烹饪开场白:: */"虾入热锅,壳在高温下迅速锁住内部的汁水。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"爆炒出锅,脆嫩鲜香,火候是关键。"/*::END:: */ }, "虾_油炸": { name:/*::GEN::菜品模板名:: */"炸虾"/*::END:: */, hunger:18, water:-1, life:2, power:2, san:3, magic:0, dur:18, sMin:4, sMax:16, pMin:8, pMax:13, open:/*::GEN::烹饪开场白:: */"整只虾裹粉入油,在金黄的油浪中翻腾。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"酥脆的外壳包裹着弹牙的虾肉,是让人忍不住多吃的口感。"/*::END:: */ }, /* ─── 蟹 ─── */ "蟹_明火烤": { name:/*::GEN::菜品模板名:: */"烤蟹"/*::END:: */, hunger:17, water:0, life:3, power:2, san:3, magic:0, dur:25, sMin:7, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"蟹肉在炭火边缘慢慢受热,蟹黄逐渐凝固成金色。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"焦香的外壳锁住了蟹肉的鲜甜,需要耐心拆开才能取食。"/*::END:: */ }, "蟹_清蒸": { name:/*::GEN::菜品模板名:: */"清蒸蟹"/*::END:: */, hunger:15, water:2, life:5, power:1, san:5, magic:0, dur:25, sMin:6, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"整只蟹摆入蒸格,蟹壳在蒸汽中逐渐由青灰转为鲜艳的橙红。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"掀开蟹盖,金黄的蟹黄凝固如玉,是一年中最奢侈的时刻。"/*::END:: */ }, "蟹_铜锅炖": { name:/*::GEN::菜品模板名:: */"蟹汤"/*::END:: */, hunger:14, water:11, life:4, power:1, san:3, magic:0, dur:28, sMin:7, sMax:25, pMin:12, pMax:20, open:/*::GEN::烹饪开场白:: */"蟹肉入锅,蟹黄溶入汤底,汤色渐渐变得橙黄浓郁。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底香浓,带着蟹特有的甘甜与微腥,喝完意犹未尽。"/*::END:: */ }, "蟹_煎炒": { name:/*::GEN::菜品模板名:: */"炒蟹"/*::END:: */, hunger:16, water:0, life:2, power:3, san:2, magic:0, dur:20, sMin:5, sMax:18, pMin:9, pMax:15, open:/*::GEN::烹饪开场白:: */"蟹肉下锅,蟹黄在高温中散开,香气扑鼻。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"大火快炒,蟹肉鲜嫩不柴,蟹黄的浓香包裹每一块肉。"/*::END:: */ }, /* ─── 贝 ─── */ "贝_明火烤": { name:/*::GEN::菜品模板名:: */"烤贝"/*::END:: */, hunger:14, water:2, life:3, power:1, san:4, magic:0, dur:18, sMin:4, sMax:16, pMin:7, pMax:13, open:/*::GEN::烹饪开场白:: */"贝类放上烤架,贝壳在高温中慢慢开口,汁水滋滋蒸发。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"贝肉微微焦化,鲜甜与炭香交织,是最简单的海边风味。"/*::END:: */ }, "贝_清蒸": { name:/*::GEN::菜品模板名:: */"清蒸贝"/*::END:: */, hunger:12, water:4, life:4, power:1, san:4, magic:0, dur:20, sMin:5, sMax:18, pMin:9, pMax:15, open:/*::GEN::烹饪开场白:: */"贝类入蒸格,蒸汽引导壳肉分离,贝汁在壳内积聚。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"贝肉Q弹,壳内积聚的原汁是最纯粹的海味。"/*::END:: */ }, "贝_铜锅炖": { name:/*::GEN::菜品模板名:: */"贝汤"/*::END:: */, hunger:12, water:13, life:4, power:0, san:3, magic:0, dur:25, sMin:6, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"贝类入锅,壳在沸腾中张开,将浓郁的贝汁释放进汤底。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底清澈而鲜甜,有一种宁静的满足感。"/*::END:: */ }, "贝_煎炒": { name:/*::GEN::菜品模板名:: */"炒贝"/*::END:: */, hunger:13, water:1, life:2, power:2, san:3, magic:0, dur:18, sMin:4, sMax:16, pMin:7, pMax:13, open:/*::GEN::烹饪开场白:: */"贝肉入热锅,高温迅速锁住水分,鲜味被封存在弹牙的肉质里。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"快炒出锅,口感爽脆,鲜甜中带着一丝锅气的焦香。"/*::END:: */ }, "贝_油炸": { name:/*::GEN::菜品模板名:: */"炸贝"/*::END:: */, hunger:16, water:-1, life:2, power:2, san:3, magic:0, dur:18, sMin:4, sMax:16, pMin:7, pMax:13, open:/*::GEN::烹饪开场白:: */"贝肉裹上薄粉,在热油里翻滚,外层迅速酥化。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"咬破酥脆的外壳,内里的贝肉依然软嫩多汁。"/*::END:: */ }, "贝_生食": { name:/*::GEN::菜品模板名:: */"生贝"/*::END:: */, hunger:10, water:3, life:2, power:0, san:6, magic:1, dur:12, sMin:3, sMax:11, pMin:5, pMax:9, open:/*::GEN::烹饪开场白:: */"撬开贝壳,新鲜的贝肉躺在壳内,带着海水的盐分。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"滑入喉咙,是最直接的海洋的味道。"/*::END:: */ }, /* ─── 腕足 ─── */ "腕足_明火烤": { name:/*::GEN::菜品模板名:: */"烤腕足"/*::END:: */, hunger:16, water:0, life:3, power:2, san:3, magic:0, dur:22, sMin:6, sMax:20, pMin:10, pMax:16, open:/*::GEN::烹饪开场白:: */"腕足放上烤架,吸盘在高温中卷曲收缩,表面迅速上色。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"焦香与弹牙并存,是别具一格的口感体验。"/*::END:: */ }, "腕足_清蒸": { name:/*::GEN::菜品模板名:: */"清蒸腕足"/*::END:: */, hunger:14, water:3, life:4, power:1, san:3, magic:0, dur:30, sMin:7, sMax:27, pMin:13, pMax:22, open:/*::GEN::烹饪开场白:: */"腕足入蒸格,蒸汽慢慢将热量渗透进厚实的肌肉层。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"肉质Q弹,蒸制时间是关键——过了就会韧如皮革。"/*::END:: */ }, "腕足_铜锅炖": { name:/*::GEN::菜品模板名:: */"墨汁腕足汤"/*::END:: */, hunger:15, water:10, life:4, power:1, san:3, magic:2, dur:35, sMin:9, sMax:32, pMin:16, pMax:27, open:/*::GEN::烹饪开场白:: */"腕足入锅,墨囊破裂,浓郁的墨汁将汤底染成深邃的黑色。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"漆黑的汤底带着独特的海鲜鲜味与矿物气息,令人难以忘怀。"/*::END:: */ }, "腕足_煎炒": { name:/*::GEN::菜品模板名:: */"炒腕足"/*::END:: */, hunger:15, water:0, life:3, power:3, san:2, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:/*::GEN::烹饪开场白:: */"腕足下热锅,大火快炒,吸盘在锅气中膨胀焦脆。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"火候要快,过了便老,恰到好处时弹牙鲜香。"/*::END:: */ }, "腕足_油炸": { name:/*::GEN::菜品模板名:: */"炸腕足"/*::END:: */, hunger:18, water:-1, life:2, power:3, san:2, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:/*::GEN::烹饪开场白:: */"腕足段裹粉入油,吸盘面朝下,在热油中逐渐酥化。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"咬下去外脆里Q,是最受欢迎的炸海鲜形态之一。"/*::END:: */ }, "腕足_生食": { name:/*::GEN::菜品模板名:: */"生腕足刺身"/*::END:: */, hunger:11, water:2, life:2, power:0, san:4, magic:1, dur:15, sMin:4, sMax:13, pMin:6, pMax:11, open:/*::GEN::烹饪开场白:: */"将腕足处理成薄切片,对刀工和食材新鲜度要求极高。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"晶莹剔透的切面,Q弹而带着淡淡的海水甜味。"/*::END:: */ }, /* ─── 海草 ─── */ "海草_铜锅炖": { name:/*::GEN::菜品模板名:: */"海草羹"/*::END:: */, hunger:10, water:10, life:2, power:0, san:3, magic:1, dur:20, sMin:5, sMax:18, pMin:8, pMax:14, open:/*::GEN::烹饪开场白:: */"海草入锅,在热水中舒展开来,释放出淡淡的海洋气息。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"羹汤滑润,带着海草独特的矿物鲜味,暖胃而清爽。"/*::END:: */ }, "海草_煎炒": { name:/*::GEN::菜品模板名:: */"炒海草"/*::END:: */, hunger:8, water:3, life:1, power:1, san:2, magic:1, dur:15, sMin:4, sMax:14, pMin:6, pMax:11, open:/*::GEN::烹饪开场白:: */"海草入热锅,水分迅速蒸发,叶片边缘开始变脆。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"口感介于脆爽与柔韧之间,有一种独特的海盐余味。"/*::END:: */ }, "海草_生食": { name:/*::GEN::菜品模板名:: */"海草沙拉"/*::END:: */, hunger:7, water:5, life:1, power:0, san:4, magic:1, dur:12, sMin:3, sMax:11, pMin:5, pMax:9, open:/*::GEN::烹饪开场白:: */"将海草漂洗干净,保留最原始的海洋风味。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"清脆爽口,海水的咸鲜与植物的清新完美融合。"/*::END:: */ }, /* ─── 块茎 ─── */ "块茎_明火烤": { name:/*::GEN::菜品模板名:: */"烤薯"/*::END:: */, hunger:18, water:-1, life:2, power:3, san:3, magic:0, dur:25, sMin:6, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"块茎裹泥放入炭火边缘,外皮在高温中逐渐焦化。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"外皮酥脆,内里绵软香甜,是朴素的满足感。"/*::END:: */ }, "块茎_铜锅炖": { name:/*::GEN::菜品模板名:: */"块茎浓汤"/*::END:: */, hunger:16, water:8, life:3, power:2, san:3, magic:0, dur:30, sMin:8, sMax:27, pMin:14, pMax:22, open:/*::GEN::烹饪开场白:: */"块茎切块入锅,淀粉逐渐析出,汤底变得浓稠。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"厚实的汤底充满饱腹感,是最能驱寒的食物之一。"/*::END:: */ }, "块茎_煎炒": { name:/*::GEN::菜品模板名:: */"煎薯块"/*::END:: */, hunger:17, water:0, life:2, power:3, san:2, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:/*::GEN::烹饪开场白:: */"块茎切片入热油锅,表面迅速焦化上色。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"外脆内软,吸足油脂的薯片带着令人愉悦的香气。"/*::END:: */ }, "块茎_油炸": { name:/*::GEN::菜品模板名:: */"炸薯"/*::END:: */, hunger:20, water:-2, life:1, power:3, san:3, magic:0, dur:18, sMin:4, sMax:16, pMin:7, pMax:13, open:/*::GEN::烹饪开场白:: */"薯条入滚油,淀粉在高温中脱水酥化。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"金黄酥脆,是高热量的简单享受。"/*::END:: */ }, /* ─── 谷物 ─── */ "谷物_铜锅炖": { name:/*::GEN::菜品模板名:: */"白粥"/*::END:: */, hunger:14, water:12, life:3, power:1, san:4, magic:0, dur:30, sMin:8, sMax:27, pMin:14, pMax:22, open:/*::GEN::烹饪开场白:: */"谷物入锅,在大量水中慢慢熬煮,淀粉逐渐释放。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"米粒开花,粥底浓稠,是病弱时最温柔的食物。"/*::END:: */ }, "谷物_煎炒": { name:/*::GEN::菜品模板名:: */"炒饭"/*::END:: */, hunger:18, water:0, life:2, power:3, san:3, magic:0, dur:20, sMin:5, sMax:18, pMin:9, pMax:15, open:/*::GEN::烹饪开场白:: */"熟饭入热锅,大火翻炒,每一粒米都在锅气中分离。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"粒粒分明,焦香扑鼻,是快餐中的经典。"/*::END:: */ }, "谷物_油炸": { name:/*::GEN::菜品模板名:: */"炸饭团"/*::END:: */, hunger:20, water:-1, life:1, power:3, san:2, magic:0, dur:15, sMin:4, sMax:14, pMin:6, pMax:11, open:/*::GEN::烹饪开场白:: */"饭团捏紧裹粉入油,外层迅速酥化定型。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"咬破酥壳,内里的米饭软糯,口感出人意料地丰富。"/*::END:: */ }, /* ─── 蔬菜 ─── */ "蔬菜_铜锅炖": { name:/*::GEN::菜品模板名:: */"蔬菜汤"/*::END:: */, hunger:10, water:10, life:2, power:1, san:3, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:14, open:/*::GEN::烹饪开场白:: */"蔬菜入锅,在热水中慢慢软化,叶绿素逐渐释放。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底清淡,带着蔬菜天然的甘甜,是轻盈的温暖。"/*::END:: */ }, "蔬菜_煎炒": { name:/*::GEN::菜品模板名:: */"炒蔬菜"/*::END:: */, hunger:9, water:2, life:2, power:2, san:3, magic:0, dur:15, sMin:4, sMax:14, pMin:6, pMax:11, open:/*::GEN::烹饪开场白:: */"蔬菜入热锅,大火翻炒,水分迅速蒸发。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"保留了脆爽的口感和鲜亮的色泽,清淡而不失风味。"/*::END:: */ }, "蔬菜_生食": { name:/*::GEN::菜品模板名:: */"生鲜沙拉"/*::END:: */, hunger:7, water:4, life:2, power:0, san:4, magic:1, dur:10, sMin:3, sMax:9, pMin:4, pMax:8, open:/*::GEN::烹饪开场白:: */"将蔬菜仔细洗净,保留最原始的状态。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"清脆爽口,最大程度保留了营养,适合作为其他料理的配餐。"/*::END:: */ } }>> /* ── 多类模板:2-3种食材,按优先级顺序匹配 ── 每条规则包含匹配条件和效果 seafoodTags = {鱼,虾,蟹,贝,腕足} 中任意一个 */ <<set $cookMultiTemplates = [ /* 优先级1:海鲜+谷物+蔬菜 = 杂炊 */ { id:"seafood_grain_veg", name:/*::GEN::菜品模板名:: */"海鲜杂炊"/*::END:: */, hasSeafood:true, requires:["谷物","蔬菜"], methods:["铜锅炖"], hunger:22, water:12, life:6, power:2, san:5, magic:0, dur:35, sMin:9, sMax:31, pMin:15, pMax:26, open:/*::GEN::烹饪开场白:: */"锅里放入了所有能用的食材,海鲜、谷物与蔬菜各自贡献着风味。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"一锅大杂烩,味道复杂而令人惊喜,有一种将就中诞生的满足感。"/*::END:: */ }, /* 优先级2:海鲜+谷物 */ { id:"seafood_grain_stew", name:/*::GEN::菜品模板名:: */"海鲜粥"/*::END:: */, hasSeafood:true, requires:["谷物"], methods:["铜锅炖"], hunger:20, water:14, life:5, power:1, san:5, magic:0, dur:32, sMin:8, sMax:29, pMin:14, pMax:24, open:/*::GEN::烹饪开场白:: */"谷物与海鲜同煮,淀粉逐渐释放,将汤底变得浓稠绵密。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"粥底融合了海鲜的鲜味,米粒开花,每一口都是温柔的满足。"/*::END:: */ }, { id:"seafood_grain_fry", name:/*::GEN::菜品模板名:: */"海鲜炒饭"/*::END:: */, hasSeafood:true, requires:["谷物"], methods:["煎炒"], hunger:22, water:0, life:4, power:3, san:4, magic:0, dur:22, sMin:5, sMax:20, pMin:9, pMax:16, open:/*::GEN::烹饪开场白:: */"熟饭与海鲜同入热锅,大火翻炒,锅气将两者的香气融合在一起。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"粒粒分明,海鲜的鲜甜渗透进每一粒米,是最有满足感的炒饭。"/*::END:: */ }, /* 优先级3:海鲜+块茎 */ { id:"seafood_tuber_stew", name:/*::GEN::菜品模板名:: */"海鲜浓汤"/*::END:: */, hasSeafood:true, requires:["块茎"], methods:["铜锅炖"], hunger:20, water:10, life:5, power:2, san:4, magic:0, dur:32, sMin:8, sMax:29, pMin:14, pMax:24, open:/*::GEN::烹饪开场白:: */"块茎的淀粉在炖煮中析出,与海鲜汁水融合,汤底越来越浓稠。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"浓郁厚实的奶白色汤底,海鲜的鲜与块茎的甜相互衬托。"/*::END:: */ }, /* 优先级4:海鲜+海草 */ { id:"seafood_seaweed_stew", name:/*::GEN::菜品模板名:: */"海草海鲜汤"/*::END:: */, hasSeafood:true, requires:["海草"], methods:["铜锅炖"], hunger:16, water:13, life:5, power:1, san:4, magic:1, dur:28, sMin:7, sMax:25, pMin:12, pMax:20, open:/*::GEN::烹饪开场白:: */"海草与海鲜同煮,海草的矿物气息与鲜味交织在一起。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底清澈,带着海洋深处的味道,令人心静。"/*::END:: */ }, /* 优先级5:海鲜+蔬菜 */ { id:"seafood_veg_fry", name:/*::GEN::菜品模板名:: */"海鲜炒蔬"/*::END:: */, hasSeafood:true, requires:["蔬菜"], methods:["煎炒"], hunger:17, water:2, life:4, power:3, san:4, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:/*::GEN::烹饪开场白:: */"海鲜与蔬菜同入热锅,各自的香气在锅气中短暂碰撞。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"蔬菜的清脆与海鲜的鲜嫩形成对比,是均衡而色彩丰富的一盘。"/*::END:: */ }, /* 优先级6:混合海鲜(纯海鲜多种) */ { id:"seafood_mix_stew", name:/*::GEN::菜品模板名:: */"海鲜锅"/*::END:: */, seafoodOnly:true, methods:["铜锅炖"], hunger:18, water:12, life:5, power:1, san:5, magic:0, dur:32, sMin:8, sMax:29, pMin:14, pMax:24, open:/*::GEN::烹饪开场白:: */"多种海鲜同入一锅,各自的鲜味在沸腾中慢慢融合。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"汤底集合了所有食材的精华,是一道需要耐心的料理。"/*::END:: */ }, { id:"seafood_mix_roast", name:/*::GEN::菜品模板名:: */"海鲜烤串"/*::END:: */, seafoodOnly:true, methods:["明火烤"], hunger:20, water:0, life:4, power:2, san:5, magic:0, dur:25, sMin:6, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"将不同的海鲜串在一起,架上炭火,各自散发着不同的香气。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"一串囊括了多种风味,每一口都有不同的惊喜。"/*::END:: */ }, { id:"seafood_mix_fry", name:/*::GEN::菜品模板名:: */"海鲜炒"/*::END:: */, seafoodOnly:true, methods:["煎炒"], hunger:18, water:0, life:4, power:3, san:4, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:/*::GEN::烹饪开场白:: */"多种海鲜同入热锅,大火翻炒,不同的质地在锅气中碰撞。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"层次丰富的海鲜炒,每一块都有不同的口感等待被发现。"/*::END:: */ }, { id:"seafood_mix_steam", name:/*::GEN::菜品模板名:: */"海鲜蒸"/*::END:: */, seafoodOnly:true, methods:["清蒸"], hunger:16, water:4, life:5, power:1, san:5, magic:0, dur:25, sMin:6, sMax:22, pMin:11, pMax:18, open:/*::GEN::烹饪开场白:: */"多种海鲜依口感厚薄分层摆放,让蒸汽均匀渗透每一种食材。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"各自保留原味,又在蒸汽中完成了一次温柔的交融。"/*::END:: */ }, { id:"seafood_mix_raw", name:/*::GEN::菜品模板名:: */"海鲜拼盘"/*::END:: */, seafoodOnly:true, methods:["生食"], hunger:14, water:3, life:3, power:0, san:7, magic:1, dur:15, sMin:4, sMax:13, pMin:6, pMax:11, open:/*::GEN::烹饪开场白:: */"将多种新鲜海鲜精心处理,各自切割成最适合生食的形态。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"一盘集合了不同形态与口感的生鲜,对食材新鲜度的极致考验。"/*::END:: */ }, /* 优先级7:非海鲜组合 */ { id:"seaweed_grain_stew", name:/*::GEN::菜品模板名:: */"海菜粥"/*::END:: */, requires:["海草","谷物"], noSeafood:true, methods:["铜锅炖"], hunger:13, water:11, life:2, power:1, san:4, magic:1, dur:28, sMin:7, sMax:25, pMin:12, pMax:20, open:/*::GEN::烹饪开场白:: */"谷物与海草同煮,粥底带着淡淡的海洋清香。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"清淡而养胃,是简单食材组合出的朴素美味。"/*::END:: */ }, { id:"grain_tuber_stew", name:/*::GEN::菜品模板名:: */"杂粮粥"/*::END:: */, requires:["谷物","块茎"], methods:["铜锅炖"], hunger:16, water:10, life:3, power:2, san:3, magic:0, dur:30, sMin:8, sMax:27, pMin:14, pMax:22, open:/*::GEN::烹饪开场白:: */"谷物与块茎同煮,两种淀粉质在炖煮中相互融合。"/*::END:: */, close:/*::GEN::烹饪结束语:: */"粥底浓稠,块茎的甘甜渗透其中,是填饱肚子的最实在选择。"/*::END:: */ } ]>>
<<nobr>> <<widget "cpDefs">> <<set $cps = {}>> <<set $activeCpIds = []>> /* ══════════════════════════════ 维奥娜 (主CP, 完整结构) ══════════════════════════════ */ <<set $cps.viona = {}>> <<set $cps.viona.id = "viona">> <<set $cps.viona.name = "维奥娜">> /* ── 生存值 ── */ <<set $cps.viona.hunger = 85>> <<set $cps.viona.water = 90>> <<set $cps.viona.energy = 70>> <<set $cps.viona.wet = false>> <<set $cps.viona.injured = 0>> <<set $cps.viona.sick = false>> <<set $cps.viona.hungerRate = 1.0>> <<set $cps.viona.waterRate = 1.0>> <<set $cps.viona.energyRates = {}>> <<set $cps.viona.energyRates.sleep = 0.18>> <<set $cps.viona.energyRates.rest = 0.06>> <<set $cps.viona.energyRates.normal = -0.025>> <<set $cps.viona.energyRates.heavy = -0.12>> /* ── 意图阈值 ── */ <<set $cps.viona.intentThresholds = {}>> <<set $cps.viona.intentThresholds.sleepAt = 22>> <<set $cps.viona.intentThresholds.napAt = 45>> <<set $cps.viona.intentThresholds.eatAt = 28>> <<set $cps.viona.intentThresholds.drinkAt = 28>> /* ── 自由活动权重 ── */ <<set $cps.viona.activityWeights = {}>> <<set $cps.viona.activityWeights.outside = 20>> <<set $cps.viona.activityWeights.watch = 20>> <<set $cps.viona.activityWeights.disassemble = 15>> <<set $cps.viona.activityWeights.exercise = 15>> <<set $cps.viona.activityWeights.cook = 15>> <<set $cps.viona.activityWeights.tidy = 10>> <<set $cps.viona.activityWeights.alchemy = 5>> <<set $cps.viona.activityWeights.bath = 5>> <<set $cps.viona.activityWeights.nap = 5>> <<set $cps.viona.cookMethods = ["明火烤", "铜锅炖", "煎炒"]>> <<set $cps.viona.foodPrefs = []>> <<set $cps.viona.drinkPrefs = []>> <<set $cps.viona.fishIds = ["fish_meat", "eel", "anglerfish", "kingcrab"]>> /* ── 场景/详情文本 ── */ <<set $cps.viona.sceneTexts = {}>> <<set $cps.viona.sceneTexts.sleep = "被子隆起卷成一团,轻轻起伏着,维奥娜睡着了。">> <<set $cps.viona.sceneTexts.nap = "维奥娜靠在角落里打盹,神情放松。">> <<set $cps.viona.sceneTexts.eat = ["维奥娜坐在桌边狼吞虎咽。","维奥娜端着碗,吃得挺专心的。"]>> <<set $cps.viona.sceneTexts.outside = "舱门半掩着,维奥娜出去了。">> <<set $cps.viona.sceneTexts.watch = ["维奥娜斜倚在驾驶台前,潜水艇尚未启动,她的轮廓模糊在微弱的海底荧光中。","维奥娜坐在一张矮凳上,随着发动机的嗡鸣和海潮涌动的节拍轻轻哼着一首你没听过的歌。","维奥娜伏在驾驶台的角落,脸颊埋在双臂中,看起来像是快要睡着了。"]>> <<set $cps.viona.sceneTexts.disassemble = "维奥娜蹲在角落里,正在处理今天的渔获。">> <<set $cps.viona.sceneTexts.exercise = "维奥娜在舱内做着某种训练,动作重复而专注。">> <<set $cps.viona.sceneTexts.cook = "厨房飘出一点气味,维奥娜在做饭。">> <<set $cps.viona.sceneTexts.tidy = "维奥娜在仓库里翻翻整整,搬动箱子的声音偶尔传出来。">> <<set $cps.viona.sceneTexts.alchemy = ["维奥娜依靠在环形舱门边,烦躁又无奈地打量向屋内,对于她不喜爱的领域,似乎仅仅是出现也是一种冒犯。","维奥娜安静地坐在你身边的椅子上——在你几十分钟之前安排她什么都别说,别吵到你炼金之后,她一直就这么做了。","维奥娜翘着二郎腿翻看着一本讲述炼金的书籍,这本书你读过……只能说,确实画着很多奇异的插图。"]>> <<set $cps.viona.sceneTexts.bath = ["你在水汽氤氲中看到了她的身影。"]>> <<set $cps.viona.sceneTexts.interact = "维奥娜在舱里,似乎正等着你开口。">> <<set $cps.viona.sceneLayers = { alchemy:{ good:["女孩很少主动炼金,但今天你如同往常一样打开炼金室的舱门时,维奥娜正在坩埚和瓶瓶罐罐之间忙碌。","在你第三次点酒精灯并第三次失败的时候,她对着你的背影笑出了声。","当然,你们都完全同意,炼金室是不可以吃巧克力的……恐怕今天对于某人来说是例外吧。","某一瞬间,你注意到她望着瓶子里沸腾的液体,神色充满了纯洁的好奇。"], neutral:["她似乎并不关注你在做什么。","她看上去昏昏欲睡,炼金术真的有这么助眠吗?","她最反感的就是读标签、写标签,可惜这间舱室已经没什么别的有趣的事可以让她打发时间了。"], bad:["这间舱室里并没有能勾起她好奇心的东西,包括你。","对于讲究效率和冷静的炼金来说,她烦躁得过头了。","她露出一种似乎在这个房间里发现恶魔的神情。"], wet:["她潮湿的时候可以不来这里吗?"], injured:["那道伤口并没有给她造成什么特别大的困扰,你有种感觉,阻止她饮酒的仅仅是炼金室的禁食令罢了。","你嗅到空气中一股淡淡的血腥味,搭配炼金物品的奇异味道,并不难闻。"], sick:["值得注意的是,她穿着一件厚实的外套。","她的脸红彤彤的,你感觉她的额头高温够煎一盘鸡蛋。"], memory:["……你还能教教我上次那个「{product}」是怎么做的吗?","一点意思也没有。快点把「{product}」做好,我们去别的地方吧。"] }, bath:{ good:["她正在唱歌,毫不令人惊讶的是,你从未听过这首轻快又欢乐的船歌。","大概是由于闷热的原因吧,你注意到她的脸颊浮现出淡淡的红色。"], neutral:["她正抬头迎接花洒喷出的热水,似乎并没有留意到你的出现。","你注意到她收拾的动作很麻利,不知道是由于不能容忍你的突然出现,还是其实她一点也不喜欢洗澡。","她身上的异味消失了,取而代之的是浴室里浓浓的海藻香型肥皂的味道。"], bad:["她狠狠剜了你一眼,把头扭过去不再看你,但至少她没有赶你走,哈哈?","她似乎有些难过。在浴室蔓延的水汽中,她的脸上似乎有着泪痕。","她始终没有看你,你很好奇她正在想什么。但现在似乎并不是一个好时机。"], wet:["她似乎对高度潮湿的浴室接受度良好,毕竟她也对海洋的接受度已经超越了良好。"], injured:["她似乎正保持着一种奇异的姿势,你知道这大概是由于她伤处上的伤口。","不幸中的万幸,你注意到她还是记得把自己的伤口用防水绷带裹住的。"], sick:["她看起来有些不舒服,像是被闷热的水汽压得头疼。"] }, watch:{ good:["她露出一个浅浅的笑容,对着你耸了耸肩。","她依偎在你的身上,你感受到了她的心跳声和微凉的脸颊。","她指了指窗外的某一条绮丽的彩色小鱼,在你分辨出那是什么鱼之前,它摆动尾巴离开了。"], neutral:["她并没有看向你,但你知道她在等你。","她往旁边让了一下,为你留出控制台的大部分空间。","她大概听到了你的脚步声,对着你随意挥了挥手,这就是打招呼了"], bad:["你们分享着同一片忧郁的平静,海洋对你们的影响都太深了。","尽管在如此昏暗的光线下有些难以察觉,但是你还是看清楚了,她的脸颊湿漉漉的。","她似乎并不是很高兴于你的出现,但又不好将你从自己的潜水艇里轰出去,一扭头望向了另一边的窗外。"], wet:["她小心地注意着,远离了所有会被她打湿的仪器,但面对你的目光依旧显得有些心虚。你觉得自己不想知道是哪一台出了问题。","她抓着一条毛巾擦着自己湿漉漉的头发,似乎有些烦躁。"], injured:["她的坐姿并不特别自然,你知道她承受着痛苦的困扰。","她并没有精细包扎过的伤口上有红色的血渗出来,血迹不新鲜,应该已经止血了。"], sick:["她似乎并不太爱搭理你,现在最好不要和她搭话比较好。","你注意到她打着喷嚏,劝说她去休息的尝试以失败告终。"], }, drivingMemory:{ catch:"我们现在要去抓一条新的「{catch}」,是不是?", destination:"我们是不是要去「{destination}」?那里可是抓「{catch}」的好地方,我爱吃你做的「{cooked}」。", cooked:"我爱吃你做的「{cooked}」。" } }>> <<set $cps.viona.detailTexts = {}>> <<set $cps.viona.detailTexts.sleep = "维奥娜蜷缩在铺位上,被子裹得严实,呼吸平稳绵长。">> <<set $cps.viona.detailTexts.nap = "维奥娜靠着墙角小睡,头微微低着,看起来睡得不深。">> <<set $cps.viona.detailTexts.eat = ["维奥娜坐在厨房的小桌旁,盘子里不知道盛了什么,吃得很认真。","维奥娜端着碗站在角落,一口一口吃得挺满足的样子。"]>> <<set $cps.viona.detailTexts.outside = "舱门通道只留下一片水渍,也不知道她现在在哪,但可以确定的是,她一定会回家的。">> <<set $cps.viona.detailTexts.watch = "维奥娜靠在驾驶舱的舷窗边,视线顺着黑暗的水流漫游,也不知道在想什么。">> <<set $cps.viona.detailTexts.disassemble = "维奥娜在仓库里处理渔获,刀工利落,偶尔把什么东西顺手扔进收纳箱里。">> <<set $cps.viona.detailTexts.exercise = "维奥娜正在舱内练习,汗珠沿着额边滑落,神情专注,不像打算搭理人的样子。">> <<set $cps.viona.detailTexts.cook = "维奥娜在厨房里忙活,锅铲碰撞声不时传来,她偶尔低头对着什么皱一下眉。">> <<set $cps.viona.detailTexts.tidy = "维奥娜把仓库里的箱子重新归置了一遍,虽说没什么实际效果,但看起来整齐多了。">> <<set $cps.viona.detailTexts.alchemy = "维奥娜守在炼金室一角,目光偶尔扫过仪器和材料。她没有碰任何东西,只是在安静地看着。">> <<set $cps.viona.detailTexts.bath = "浴室水汽未散,维奥娜刚整理好自己的洗漱用品,看起来终于放松了一些。">> <<set $cps.viona.detailTexts.interact = "维奥娜抬头看了你一眼,手里的活儿停了下来。">> /* ── 当前行动 ── */ <<set $cps.viona.location = "卧室">> <<set $cps.viona.action = "sleep">> <<set $cps.viona.actionEndTime = 0>> <<set $cps.viona.actionDetail = "">> /* ── 通知/主动 ── */ <<set $cps.viona.pendingNotify = { text: "", expire: -1 }>> <<set $cps.viona.notifyCooldown = 0>> <<set $cps.viona.proactiveCooldown = 0>> <<set $cps.viona.lastChatDay = 0>> <<set $cps.viona.pendingImportantEvent = null>> /* ── 三层情绪模型 (mood/calm 为 0-100 浮点, 显示分5档) ── */ <<set $cps.viona.mode = "auto">> /* auto(自主) / interact(待命) */ <<set $cps.viona.moodBase = 60>> /* 由生存值计算 */ <<set $cps.viona.moodMod = 0>> /* 事件修正, 每日衰减回0 */ <<set $cps.viona.mood = 60>> /* = moodBase + moodMod (clamp 0-100) */ <<set $cps.viona.calm = 60>> /* 0-100 浮点 */ <<set $cps.viona.bond = 50>> /* 长期好感 0-100 */ <<set $cps.viona.bondDrift = 0>> /* 当日 mood 趋势累积 */ /* ── 打断/退出 ── */ <<set $cps.viona.interactStart = 0>> /* 进入 interact 的时间(分钟) */ <<set $cps.viona.interactActivityEnd = 0>> /* 开始对话时正在做的事的结束时间(离开门槛) */ <<set $cps.viona.leaveRequested = false>> /* 是否已提过离开 */ <<set $cps.viona.leaveDeniedAt = 0>> /* 上次被拒绝的时间(分钟) */ /* ── 性格(细粒度字典, 角色差异化) ── */ <<set $cps.viona.quirks = { sleep_interrupt: -2, /* 打断睡觉不悦(起床气) */ craft_interrupt: 0, /* 打断制作无所谓 */ eat_interrupt: -1, /* 打断吃饭略不悦 */ talk_interrupt: 0, /* 打断聊天无所谓 */ explore_together: +1, /* 喜欢被叫一起探索 */ alone_time: +1 /* 喜欢独处(频繁互动微降) */ }>> <<set $cps.viona.foodAttitude = "open">> /* open / only_when_hungry / picky */ <<set $cps.viona.prefs = { /* 赠物好感偏好(按物品大类) */ fish_meat: 2, eel: 1, anglerfish: 1, kingcrab: 1, meat: 2, soup: 1, water: 0, wood: 0, metal: 0, fiber: 0, ore: 0, shell: 1, handcraft: 2, keepsake: 2 }>> /* ── 库存/一次性后果 ── */ <<set $cps.viona.inventory = {}>> /* CP 独立材料库存 {itemId: count} */ <<set $cps.viona.giftAftermath = null>> /* {item:"", triggered:false} */ <<set $cps.viona.giftCooldown = 0>> /* 礼物冷却到期天 */ /* ── 三层记忆 ── */ <<set $cps.viona.recentEvents = { ate: { tag:"", day:0, expire:-1 }, went_out: { tag:"", day:0, expire:-1 }, cooked: { tag:"", product:"", day:0, expire:-1 }, catch: { tag:"", product:"", day:0, expire:-1 }, destination: { tag:"", target:"", targetId:"", day:0, expire:-1 }, alchemy: { tag:"", product:"", day:0, expire:-1 }, driving: { tag:"", terrain:"", day:0, expire:-1 }, slept_with: { tag:"", day:0, expire:-1 }, intentFrustrated: { plan:"", reason:"", day:0, expire:-1 } }>> <<set $cps.viona.memories = []>> /* 中期记忆 tag 列表(永久) */ <<set $cps.viona.bondMilestones = {}>> /* 长期印记解锁开关 */ /* ── tick 计时 ── */ <<set $cps.viona.lastTickTime = 0>> /* 维奥娜启用:作为可攻略角色参与房间场景与互动。 */ <<run $activeCpIds.push("viona")>> /* ══════════════════════════════ 测试cp (占位/测试用) ══════════════════════════════ */ /* 本角色仅用于 CP 系统展示与测试, 数据为占位, 上线前删除或替换 */ <<set $cps.testcp = {}>> <<set $cps.testcp.id = "testcp">> <<set $cps.testcp.name = "测试人偶">> <<set $cps.testcp.hunger = 70>> <<set $cps.testcp.water = 75>> <<set $cps.testcp.energy = 65>> <<set $cps.testcp.wet = false>> <<set $cps.testcp.injured = 0>> <<set $cps.testcp.sick = false>> <<set $cps.testcp.hungerRate = 1.0>> <<set $cps.testcp.waterRate = 1.0>> <<set $cps.testcp.energyRates = { sleep:0.18, rest:0.06, normal:-0.025, heavy:-0.12 }>> <<set $cps.testcp.intentThresholds = { sleepAt:22, napAt:45, eatAt:28, drinkAt:28 }>> <<set $cps.testcp.activityWeights = { outside:20, watch:20, disassemble:15, exercise:15, cook:15, tidy:10, nap:5 }>> <<set $cps.testcp.cookMethods = ["明火烤", "铜锅炖", "煎炒"]>> <<set $cps.testcp.foodPrefs = []>> <<set $cps.testcp.drinkPrefs = []>> <<set $cps.testcp.fishIds = ["fish_meat", "eel", "anglerfish", "kingcrab"]>> <<set $cps.testcp.sceneTexts = { sleep:"测试cp 在角落里睡着了。", nap:"测试cp 在打盹。", eat:["测试cp 正在吃东西。","测试cp 端着碗。"], outside:"测试cp 出门了。", watch:"测试cp 望着舷窗。", disassemble:"测试cp 在处理渔获。", exercise:"测试cp 在做训练。", cook:"测试cp 在做饭。", tidy:"测试cp 在整理。", alchemy:"测试人偶坐在炼金室角落,安静记录着观察结果。", bath:"测试人偶在浴室中进行例行维护。", interact:"测试cp 在等你开口。" }>> <<set $cps.testcp.detailTexts = { sleep:"测试cp 蜷着睡着了(占位描述)。", nap:"测试cp 靠着墙角小睡(占位描述)。", eat:["测试cp 在吃东西(占位描述)。","测试cp 端着碗(占位描述)。"], outside:"测试cp 出去了(占位描述)。", watch:"测试cp 望着舷窗外(占位描述)。", disassemble:"测试cp 在处理渔获(占位描述)。", exercise:"测试cp 在训练(占位描述)。", cook:"测试cp 在做饭(占位描述)。", tidy:"测试cp 在整理(占位描述)。", alchemy:"测试人偶停在炼金室一角,等待下一项测试指令。", bath:"测试人偶位于浴室,等待下一项测试指令。", interact:"测试cp 抬头看你(占位描述)。" }>> <<set $cps.testcp.location = "驾驶舱">> <<set $cps.testcp.action = "watch">> <<set $cps.testcp.actionEndTime = 0>> <<set $cps.testcp.actionDetail = "">> <<set $cps.testcp.pendingNotify = { text:"", expire:-1 }>> <<set $cps.testcp.notifyCooldown = 0>> <<set $cps.testcp.proactiveCooldown = 0>> <<set $cps.testcp.lastChatDay = 0>> <<set $cps.testcp.pendingImportantEvent = null>> <<set $cps.testcp.mode = "auto">> <<set $cps.testcp.moodBase = 60>> <<set $cps.testcp.moodMod = 0>> <<set $cps.testcp.mood = 60>> <<set $cps.testcp.calm = 60>> <<set $cps.testcp.bond = 40>> <<set $cps.testcp.bondDrift = 0>> <<set $cps.testcp.interactStart = 0>> <<set $cps.testcp.interactActivityEnd = 0>> <<set $cps.testcp.leaveRequested = false>> <<set $cps.testcp.leaveDeniedAt = 0>> <<set $cps.testcp.quirks = { /* 测试cp = easygoing 全0, 怎么都行 */ sleep_interrupt: 0, craft_interrupt:0, eat_interrupt:0, talk_interrupt: 0, explore_together:0, alone_time:0 }>> <<set $cps.testcp.foodAttitude = "open">> <<set $cps.testcp.prefs = { fish_meat:1, eel:1, meat:1, wood:0, metal:0, fiber:0, ore:0, shell:1, handcraft:1, keepsake:1 }>> <<set $cps.testcp.inventory = {}>> <<set $cps.testcp.giftAftermath = null>> <<set $cps.testcp.giftCooldown = 0>> <<set $cps.testcp.recentEvents = { ate: { tag:"", day:0, expire:-1 }, went_out: { tag:"", day:0, expire:-1 }, cooked: { tag:"", day:0, expire:-1 }, slept_with: { tag:"", day:0, expire:-1 }, intentFrustrated: { plan:"", reason:"", day:0, expire:-1 } }>> <<set $cps.testcp.memories = []>> <<set $cps.testcp.bondMilestones = {}>> <<set $cps.testcp.lastTickTime = 0>> /* 测试人偶仅由 CP DEV 临时启用,不能进入正常场景渲染。 */ /* ════════════════════════════ 初始化 tick 计时 ════════════════════════════ */ <<set _cpInitNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<for _cpInitI = 0; _cpInitI < $activeCpIds.length; _cpInitI++>> <<set _cpInitId = $activeCpIds[_cpInitI]>> <<if $cps[_cpInitId] && !$cps[_cpInitId].actionEndTime>> <<set $cps[_cpInitId].actionEndTime = _cpInitNow + (($cps[_cpInitId].action === "sleep") ? 480 : 60)>> <</if>> <<set $cps[_cpInitId].lastTickTime = _cpInitNow>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpProactiveDefs">> /* Viona 主动事件定义表 字段说明: type : "chat" / "gift" passage : 跳转目标 passage 名 baseChance : 每次 tick 检测的触发概率 weight : 同批候选时的权重 cooldown : 触发后冷却天数 minBond : 最低好感要求(可选) minMood : 最低心情档位(可选) requireMemory : 触发所需记忆 tag(可选) */ <<set $cpProactiveDefs = {}>> <<set $cpProactiveDefs["viona"] = [ { type : "chat", passage : "viona主动闲聊", baseChance : 0.12, weight : 20, cooldown : 2, minBond : 30, minMood : 1 }, { type : "chat", passage : "viona心情好搭话", baseChance : 0.18, weight : 15, cooldown : 3, minBond : 50, minMood : 2 }, { type : "chat", passage : "viona记仇质问", baseChance : 0.35, weight : 30, cooldown : 1, requireMemory : "was_teased" }, { type : "gift", passage : "viona送礼物", baseChance : 0.10, weight : 10, cooldown : 5, minBond : 60, requireMemory : "cooked_for_player" } ]>> <</widget>> <</nobr>>
/* 各物品/分类的保质天数(日历天) */ <<set $spoilDays = { /* ── 鱼类(整条) ── */ salmon:3, seabass:3, tuna:3, sardine:2, herring:2, grouper:4, mahi:3, cod:3, eel:4, flounder:3, mackerel:2, bream:3, anchovy:2, barracuda:3, hairtail:2, sunfish:3, anglerfish:4, /* ── 贝/虾/蟹/头足 ── */ scallop:2, clam:2, oyster:1, mussel:2, conch:3, prawn:2, lobster:2, mantisshrimp:2, kingcrab:3, snowcrab:3, bluecrab:2, swimmingcrab:2, squid:2, cuttlefish:2, octopus:3, seahorse:5, /* ── 鱼肉(已处理) ── */ salmon_meat:2, seabass_meat:2, tuna_meat:1, sardine_meat:2, herring_meat:2, grouper_meat:2, mahi_meat:2, cod_meat:2, eel_meat:3, flounder_meat:2, mackerel_meat:2, bream_meat:2, anchovy_meat:2, barracuda_meat:2, hairtail_meat:2, sunfish_meat:2, anglerfish_meat:2, fish_meat:2, /* ── 贝肉/虾蟹肉/头足肉 ── */ scallop_meat:1, clam_meat:1, oyster_meat:1, mussel_meat:1, conch_meat:2, prawn_meat:1, lobster_meat:1, mantisshrimp_meat:1, kingcrab_meat:2, snowcrab_meat:2, bluecrab_meat:1, squid_meat:2, cuttlefish_meat:2, octopus_meat:2, shell_meat:1, shrimp_meat:1, crab_meat:2, /* ── 藻类食材 ── */ dried_kelp:30, dried_nori:30, seajelly:3, /* ── 其他食材 ── */ urchin_roe:1, octopus_meat:2, wheat_grain:60, seaweed_grain:60, potato_tuber:10, kelp_tuber:10, sealeaf:3, sprout:2, sea_berry:5, wild_berry:3, /* ── 菜品 ── */ fish_soup:2, seafood_hotpot:2, grilled_fish:2, steamed_fish:2, smoked_fish:5, sashimi:1, fish_porridge:2, seaweed_salad:2, mixed_seafood:2, char_mess:1, watery_stew:1, steamed_blob:1, raw_pile:1, fish_berry_grill:2 }>>
<<set $disassemblyRules = { /* ══ 鱼类 ══ */ "salmon": [ { id: "salmon_meat", minQty: 2, maxQty: 4 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_blood", minQty: 1, maxQty: 1 }, { id: "fish_scale", minQty: 1, maxQty: 3 }, { id: "fish_roe", minQty: 0, maxQty: 2, chance: 0.4 }, { id: "fish_liver", minQty: 0, maxQty: 1, chance: 0.3 }, /* 稀有产物 */ { id: "pearl_dust", minQty: 1, maxQty: 1, chance: 0.02, rare: true } ], "seabass": [ { id: "seabass_meat", minQty: 2, maxQty: 3 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_blood", minQty: 1, maxQty: 1 }, { id: "fish_scale", minQty: 1, maxQty: 2 }, { id: "gill_membrane", minQty: 0, maxQty: 1, chance: 0.5 } ], "tuna": [ { id: "tuna_meat", minQty: 4, maxQty: 7 }, { id: "fish_bone", minQty: 2, maxQty: 3 }, { id: "fish_blood", minQty: 2, maxQty: 3 }, { id: "fish_scale", minQty: 1, maxQty: 3 }, { id: "fish_liver", minQty: 1, maxQty: 1 }, { id: "swim_bladder", minQty: 0, maxQty: 1, chance: 0.6 }, /* 稀有 */ { id: "deep_eye", minQty: 1, maxQty: 1, chance: 0.015, rare: true } ], "sardine": [ { id: "sardine_meat", minQty: 1, maxQty: 1 }, { id: "fish_bone", minQty: 1, maxQty: 1 }, { id: "fish_blood", minQty: 0, maxQty: 1, chance: 0.5 } ], "herring": [ { id: "herring_meat", minQty: 1, maxQty: 1 }, { id: "fish_bone", minQty: 1, maxQty: 1 }, { id: "fish_roe", minQty: 0, maxQty: 1, chance: 0.35 } ], "grouper": [ { id: "grouper_meat", minQty: 2, maxQty: 4 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_blood", minQty: 1, maxQty: 2 }, { id: "gill_membrane", minQty: 1, maxQty: 1 }, { id: "fish_scale", minQty: 2, maxQty: 3 } ], "mahi": [ { id: "mahi_meat", minQty: 3, maxQty: 5 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_blood", minQty: 1, maxQty: 2 }, { id: "fin_membrane", minQty: 1, maxQty: 2 }, { id: "fish_scale", minQty: 2, maxQty: 4 } ], "cod": [ { id: "cod_meat", minQty: 2, maxQty: 4 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_liver", minQty: 1, maxQty: 1 }, { id: "swim_bladder", minQty: 0, maxQty: 1, chance: 0.55 } ], "eel": [ { id: "eel_meat", minQty: 1, maxQty: 3 }, { id: "fish_blood", minQty: 1, maxQty: 2 }, { id: "bile", minQty: 0, maxQty: 1, chance: 0.4 }, /* 稀有 */ { id: "current_stone", minQty: 1, maxQty: 1, chance: 0.025, rare: true } ], "flounder": [ { id: "flounder_meat", minQty: 2, maxQty: 3 }, { id: "fish_bone", minQty: 1, maxQty: 1 }, { id: "fish_scale", minQty: 2, maxQty: 4 }, { id: "sand_extract", minQty: 0, maxQty: 1, chance: 0.3 } ], "mackerel": [ { id: "mackerel_meat", minQty: 1, maxQty: 3 }, { id: "fish_bone", minQty: 1, maxQty: 1 }, { id: "fish_blood", minQty: 1, maxQty: 1 }, { id: "fish_scale", minQty: 1, maxQty: 2 } ], "bream": [ { id: "bream_meat", minQty: 2, maxQty: 3 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_scale", minQty: 2, maxQty: 3 }, { id: "fish_roe", minQty: 0, maxQty: 2, chance: 0.45 } ], "anchovy": [ { id: "anchovy_meat", minQty: 1, maxQty: 1 }, { id: "fish_bone", minQty: 1, maxQty: 1 } ], "barracuda": [ { id: "barracuda_meat", minQty: 2, maxQty: 4 }, { id: "fish_bone", minQty: 2, maxQty: 3 }, { id: "fish_blood", minQty: 2, maxQty: 3 }, { id: "bile", minQty: 1, maxQty: 1 } ], "hairtail": [ { id: "hairtail_meat", minQty: 2, maxQty: 3 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "fish_scale", minQty: 3, maxQty: 5 }, { id: "char_scale", minQty: 0, maxQty: 1, chance: 0.2 } ], "sunfish": [ { id: "sunfish_meat", minQty: 5, maxQty: 9 }, { id: "fish_bone", minQty: 2, maxQty: 3 }, { id: "fish_blood", minQty: 2, maxQty: 4 }, { id: "swim_bladder", minQty: 1, maxQty: 2 }, { id: "fin_membrane", minQty: 2, maxQty: 3 }, /* 稀有 */ { id: "deep_eye", minQty: 1, maxQty: 2, chance: 0.08, rare: true }, { id: "pearl_dust", minQty: 1, maxQty: 1, chance: 0.05, rare: true } ], "anglerfish": [ { id: "anglerfish_meat", minQty: 2, maxQty: 4 }, { id: "fish_bone", minQty: 1, maxQty: 2 }, { id: "bile", minQty: 1, maxQty: 2 }, { id: "fish_liver", minQty: 1, maxQty: 1 }, /* 稀有 */ { id: "deep_eye", minQty: 1, maxQty: 1, chance: 0.12, rare: true }, { id: "ember_crystal", minQty: 1, maxQty: 1, chance: 0.03, rare: true } ], "seahorse": [ { id: "fish_bone", minQty: 1, maxQty: 1 }, { id: "fish_blood", minQty: 1, maxQty: 1 }, /* 稀有 */ { id: "current_stone", minQty: 1, maxQty: 1, chance: 0.08, rare: true }, { id: "pearl_dust", minQty: 1, maxQty: 1, chance: 0.1, rare: true } ], /* ══ 贝类 ══ */ "scallop": [ { id: "scallop_meat", minQty: 1, maxQty: 2 }, { id: "shell_frag", minQty: 1, maxQty: 2 }, { id: "shell_powder",minQty: 0, maxQty: 1, chance: 0.4 } ], "clam": [ { id: "clam_meat", minQty: 1, maxQty: 1 }, { id: "shell_frag", minQty: 1, maxQty: 2 }, { id: "pearl", minQty: 1, maxQty: 1, chance: 0.05, rare: true } ], "oyster": [ { id: "oyster_meat", minQty: 1, maxQty: 1 }, { id: "shell_frag", minQty: 1, maxQty: 1 }, { id: "pearl", minQty: 1, maxQty: 1, chance: 0.08, rare: true }, { id: "blackpearl", minQty: 1, maxQty: 1, chance: 0.01, rare: true } ], "mussel": [ { id: "mussel_meat", minQty: 1, maxQty: 2 }, { id: "shell_frag", minQty: 1, maxQty: 2 } ], "conch": [ { id: "conch_meat", minQty: 1, maxQty: 2 }, { id: "shell_frag", minQty: 1, maxQty: 1 }, { id: "shell_powder",minQty: 1, maxQty: 2 } ], /* ══ 虾蟹类 ══ */ "prawn": [ { id: "prawn_meat", minQty: 1, maxQty: 2 }, { id: "shell_frag", minQty: 0, maxQty: 1, chance: 0.5 } ], "lobster": [ { id: "lobster_meat", minQty: 2, maxQty: 4 }, { id: "crab_shell", minQty: 1, maxQty: 2 }, { id: "shell_powder",minQty: 0, maxQty: 1, chance: 0.3 } ], "mantisshrimp": [ { id: "mantisshrimp_meat", minQty: 1, maxQty: 2 }, { id: "crab_shell", minQty: 1, maxQty: 1 } ], "sweetshrimp": [ { id: "shrimp_meat", minQty: 1, maxQty: 1 } ], "cherryshrimp": [ { id: "shrimp_meat", minQty: 1, maxQty: 1 } ], "kingcrab": [ { id: "kingcrab_meat", minQty: 3, maxQty: 5 }, { id: "crab_shell", minQty: 2, maxQty: 3 }, { id: "shell_powder",minQty: 1, maxQty: 2 }, /* 稀有 */ { id: "ember_crystal", minQty: 1, maxQty: 1, chance: 0.03, rare: true } ], "snowcrab": [ { id: "snowcrab_meat", minQty: 2, maxQty: 4 }, { id: "crab_shell", minQty: 2, maxQty: 3 }, { id: "shell_powder",minQty: 1, maxQty: 1 } ], "bluecrab": [ { id: "bluecrab_meat", minQty: 1, maxQty: 3 }, { id: "crab_shell", minQty: 1, maxQty: 2 } ], "swimmingcrab": [ { id: "crab_meat", minQty: 1, maxQty: 3 }, { id: "crab_shell", minQty: 1, maxQty: 2 } ], "flowercrab": [ { id: "crab_meat", minQty: 1, maxQty: 2 }, { id: "crab_shell", minQty: 1, maxQty: 2 }, { id: "coral_frag", minQty: 0, maxQty: 1, chance: 0.25 } ], "redcrab": [ { id: "crab_meat", minQty: 1, maxQty: 2 }, { id: "crab_shell", minQty: 1, maxQty: 2 }, { id: "coral_frag", minQty: 0, maxQty: 1, chance: 0.35 } ], /* ══ 头足类 ══ */ "squid": [ { id: "squid_meat",minQty: 1, maxQty: 3 }, { id: "fish_blood", minQty: 1, maxQty: 1 }, { id: "fin_membrane",minQty: 1, maxQty: 2 }, { id: "air_sac", minQty: 0, maxQty: 1, chance: 0.5 } ], "cuttlefish": [ { id: "cuttlefish_meat",minQty: 1, maxQty: 2 }, { id: "fish_blood", minQty: 1, maxQty: 2 }, { id: "shell_frag", minQty: 1, maxQty: 1 }, /* 乌贼骨 */ { id: "seawater_ext",minQty: 0, maxQty: 1, chance: 0.4 } ], "octopus": [ { id: "octopus_meat",minQty: 2, maxQty: 4 }, { id: "fish_blood", minQty: 1, maxQty: 2 }, { id: "gill_membrane",minQty:0, maxQty: 1, chance: 0.4 }, /* 稀有 */ { id: "deep_eye", minQty: 1, maxQty: 1, chance: 0.04, rare: true } ], /* ══ 棘皮/其他 ══ */ "seaurchin": [ { id: "urchin_roe", minQty: 1, maxQty: 2 }, { id: "urchin_spine_core", minQty: 1, maxQty: 1 }, { id: "shell_powder",minQty: 1, maxQty: 2 } ], "starfish": [ { id: "shell_frag", minQty: 1, maxQty: 2 }, { id: "bone_ash", minQty: 0, maxQty: 1, chance: 0.4 }, /* 稀有 */ { id: "current_stone",minQty:1, maxQty: 1, chance: 0.02, rare: true } ], "jellyfish": [ { id: "seajelly", minQty: 1, maxQty: 2 }, { id: "jellyfilm", minQty: 1, maxQty: 1 }, { id: "jellyfluid", minQty: 0, maxQty: 1, chance: 0.6 } ], /* ══ 藻类 ══ */ "kelp": [ { id: "dried_kelp", minQty: 1, maxQty: 3 }, { id: "kelp_fiber", minQty: 1, maxQty: 2 }, { id: "seawater_ext",minQty: 0, maxQty: 1, chance: 0.3 } ], "wakame": [ { id: "dried_kelp", minQty: 1, maxQty: 2 }, { id: "kelp_fiber", minQty: 1, maxQty: 1 } ], "nori": [ { id: "dried_nori", minQty: 1, maxQty: 2 }, { id: "seagrass_str",minQty: 0, maxQty: 1, chance: 0.5 } ], "agarcoral": [ { id: "dried_nori", minQty: 1, maxQty: 1 }, { id: "coral_frag", minQty: 1, maxQty: 1 }, { id: "shell_powder",minQty: 0, maxQty: 1, chance: 0.4 } ], /* ══ 残骸 ══ */ "wreck_steel": [ { id: "metal", minQty: 2, maxQty: 5 }, { id: "iron", minQty: 0, maxQty: 2, chance: 0.4 }, { id: "glass", minQty: 0, maxQty: 2, chance: 0.3 }, { id: "rubber_seal", minQty: 0, maxQty: 1, chance: 0.2 } ], "wreck_wood": [ { id: "wood", minQty: 2, maxQty: 5 }, { id: "rope", minQty: 0, maxQty: 2, chance: 0.5 }, { id: "coal", minQty: 0, maxQty: 2, chance: 0.3 } ], "god_bone_frag": [ { id: "bone_ash", minQty: 1, maxQty: 2 }, { id: "fish_bone", minQty: 1, maxQty: 3 }, /* 稀有 */ { id: "ember_crystal",minQty:1, maxQty: 1, chance: 0.06, rare: true }, { id: "god_ember", minQty: 1, maxQty: 1, chance: 0.008, rare: true } ], "creature_husk": [ { id: "crab_shell", minQty: 1, maxQty: 2 }, { id: "bone_ash", minQty: 1, maxQty: 2 }, { id: "bile", minQty: 0, maxQty: 1, chance: 0.5 }, /* 稀有 */ { id: "deep_eye", minQty: 1, maxQty: 1, chance: 0.05, rare: true } ] }>>
<<set $disassemblyFlavors = { "鱼类": /*::GEN::拆解描述::鱼类:: */"剖开鱼腹,依次取出鱼肉、内脏和骨架。手法熟练的话可以获得更多完整材料。"/*::END:: */, "贝类": /*::GEN::拆解描述::贝类:: */"敲碎外壳或撬开双壳,小心剥离内部的软体组织,避免损坏壳质材料。"/*::END:: */, "虾类": /*::GEN::拆解描述::虾类:: */"剥去虾壳,取出虾肉,壳质碎片也有一定的炼金价值。"/*::END:: */, "蟹类": /*::GEN::拆解描述::蟹类:: */"拆开蟹甲,挑出蟹肉和蟹黄,坚硬的甲壳粉碎后是上等的土系材料。"/*::END:: */, "头足": /*::GEN::拆解描述::头足:: */"分离外套膜和腕足,取出墨囊时需小心不要破裂,其中的液体有特殊用途。"/*::END:: */, "其他": /*::GEN::拆解描述::其他:: */"仔细处理这种特殊生物,提取可用的组织。"/*::END:: */, "藻类": /*::GEN::拆解描述::藻类:: */"晒干或直接压榨,提取纤维和矿物浓缩物。"/*::END:: */, "残骸": /*::GEN::拆解描述::残骸:: */"用工具撬开结构,分拣金属和木材,腐蚀部分可能带有毒性。"/*::END:: */, "炼金材料": /*::GEN::拆解描述::炼金材料:: */"使用炼金台进行进一步提炼,原始材料的处理需要谨慎。"/*::END:: */, "遗物": /*::GEN::拆解描述::遗物:: */"仔细翻阅或扫描,从中提取可用的知识与配方。"/*::END:: */ }>>
<<nobr>> <<widget "diveInteractDefs">> <<set $diveInteractDefs = { /* 珊瑚礁 */ "珊瑚": {text:/*::GEN::互动描述:: */"你小心地掰下几段珊瑚分枝,装进采集袋。"/*::END:: */, loot:[{id:"coral_frag", qty:[1,3]}]}, "海葵": {text:/*::GEN::互动描述:: */"触手轻轻贴住你的手套,海葵无害但难以采集完整。"/*::END:: */, loot:[{id:"kelp", qty:[0,1]}]}, "雀鲷": {text:/*::GEN::互动描述:: */"小鱼在你手边绕了一圈,留下一团金属光泽后溜走。"/*::END:: */, loot:[]}, "礁穴": {text:/*::GEN::互动描述:: */"你伸手探进礁穴,指尖碰到硬的东西——是一枚贝壳。"/*::END:: */, loot:[{id:"shell_frag", qty:[1,2]}]}, "裸胸鳝": {text:/*::GEN::互动描述:: */"保持距离,对视一会儿后它率先退回了穴里。"/*::END:: */, loot:[]}, "缝隙": {text:/*::GEN::互动描述:: */"缝隙深处有沙砾和几块小石,顺手捡了一些。"/*::END:: */, loot:[{id:"sand_extract", qty:[0,2]}]}, "管虫": {text:/*::GEN::互动描述:: */"管虫收起触须,你轻轻刮下几段空管,质地轻盈。"/*::END:: */, loot:[{id:"glass", qty:[0,1]}]}, /* 沙地 */ "沙海": {text:/*::GEN::互动描述:: */"把手插进沙里,细沙从指缝流过,什么也没找到。"/*::END:: */, loot:[]}, "沙鳐": {text:/*::GEN::互动描述:: */"沙鳐被光惊扰,拍打鳍掀起沙云,你趁机捡走了几块贝壳碎片。"/*::END:: */, loot:[{id:"shell_frag",qty:[1,2]}]}, "碎石": {text:/*::GEN::互动描述:: */"碎石里藏着一些不明金属碎片,来历不清。"/*::END:: */, loot:[{id:"metal", qty:[1,3]}]}, "金属残片": {text:/*::GEN::互动描述:: */"还算完整,切割断面有锈,但核心还保留着金属光泽。"/*::END:: */, loot:[{id:"metal", qty:[1,2]},{id:"iron",qty:[0,1]}]}, "沙纹": {text:/*::GEN::互动描述:: */"仔细观察波纹方向,能推断出这片区域的水流规律。"/*::END:: */, loot:[]}, "波纹": {text:/*::GEN::互动描述:: */"沙纹下方压着一枚完整的螺壳,你把它取了出来。"/*::END:: */, loot:[{id:"shell_frag", qty:[1,1]}]}, /* 岩床 */ "石脊": {text:/*::GEN::互动描述:: */"沿石脊摸索,发现一处空腔,里面藏着一团锈结块。"/*::END:: */, loot:[{id:"metal", qty:[1,2]}]}, "石蛏": {text:/*::GEN::互动描述:: */"掰下几只,装进采集瓶,气味刺鼻但是食材。"/*::END:: */, loot:[{id:"fish", qty:[1,2]}]}, "蟹": {text:/*::GEN::互动描述:: */"小蟹夹住了你的手套指头,你轻松拿走了它。"/*::END:: */, loot:[{id:"fish", qty:[1,1]}]}, "岩柱": {text:/*::GEN::互动描述:: */"岩柱根部沉积着厚厚一层细沙,里面有几块有棱角的矿石。"/*::END:: */, loot:[{id:"ore_frag", qty:[0,2]}]}, "棘皮动物": {text:/*::GEN::互动描述:: */"海星和海胆密密麻麻,你小心避开刺,捡了几颗。"/*::END:: */, loot:[{id:"creature_husk",qty:[1,2]}]}, "裂缝": {text:/*::GEN::互动描述:: */"裂缝边缘结有白色沉淀物,刮下来气味辛辣,是矿物结晶。"/*::END:: */, loot:[{id:"salt_refined",qty:[1,2]}]}, "冷泉": {text:/*::GEN::互动描述:: */"把采集瓶靠近泉眼,收集到一小瓶含硫的泉水。"/*::END:: */, loot:[{id:"sand_extract", qty:[1,2]}]}, /* 海藻森林 */ "海藻帘": {text:/*::GEN::互动描述:: */"拨开藻叶,发现一条窄道,叶片上有些附生小虾。"/*::END:: */, loot:[{id:"kelp", qty:[1,3]}]}, "叶片": {text:/*::GEN::互动描述:: */"你摘下几张宽大的藻叶,晒干可能有用。"/*::END:: */, loot:[{id:"kelp", qty:[2,4]}]}, "海藻开口": {text:/*::GEN::互动描述:: */"光柱里漂浮着大量浮游生物,你用滤网捞了一些。"/*::END:: */, loot:[{id:"creature_husk",qty:[0,2]}]}, "光柱": {text:/*::GEN::互动描述:: */"光柱中什么也没有,但很漂亮,你记录了下来。"/*::END:: */, loot:[]}, "礁石": {text:/*::GEN::互动描述:: */"礁石上的附生物很密集,刮下来一层有机质碎屑。"/*::END:: */, loot:[{id:"bone_ash", qty:[0,2]}]}, "附生生物": {text:/*::GEN::互动描述:: */"种类繁多,收集了几个样本装瓶。"/*::END:: */, loot:[{id:"creature_husk",qty:[1,2]}]}, "人工痕迹": {text:/*::GEN::互动描述:: */"像是凿过的切面,年代久远,留下了一个标记符号。"/*::END:: */, loot:[{id:"relic_etching",qty:[0,1]}]}, /* 峭壁 */ "峭壁": {text:/*::GEN::互动描述:: */"壁面上有些附着物,刮下来是彩色的软体动物碎片。"/*::END:: */, loot:[{id:"shell_frag", qty:[1,2]}]}, "悬岩": {text:/*::GEN::互动描述:: */"悬岩底部堆着落石,里面夹着几块有价值的矿石碎片。"/*::END:: */, loot:[{id:"ore_frag", qty:[1,2]}]}, "碎石": {text:/*::GEN::互动描述:: */"碎石里藏着一些不明金属碎片,来历不清。"/*::END:: */, loot:[{id:"metal", qty:[1,2]}]}, "岩架": {text:/*::GEN::互动描述:: */"岩架上积了薄薄一层细沙,翻开后发现几枚完整的海胆壳。"/*::END:: */, loot:[{id:"shell_frag",qty:[1,2]}]}, "海星": {text:/*::GEN::互动描述:: */"海星足部有粘液,掰下一条做样本,剩下的放回去了。"/*::END:: */, loot:[{id:"creature_husk",qty:[0,1]}]}, "海胆": {text:/*::GEN::互动描述:: */"小心取下一只,棘刺完好,内脏还在。"/*::END:: */, loot:[{id:"fish", qty:[1,1]}]}, /* 海草床 */ "海草": {text:/*::GEN::互动描述:: */"摘了一把,这种草晒干后可以用作填充材料。"/*::END:: */, loot:[{id:"kelp", qty:[2,3]}]}, "水流": {text:/*::GEN::互动描述:: */"顺着水流摸索,发现几块被冲来的碎屑。"/*::END:: */, loot:[{id:"sand_extract", qty:[0,2]}]}, "压痕": {text:/*::GEN::互动描述:: */"沿着压痕追了一段,什么都没找到,也许它跑得太快。"/*::END:: */, loot:[]}, "草丛": {text:/*::GEN::互动描述:: */"草丛里藏着一枚完整的蜗牛壳,质地光滑。"/*::END:: */, loot:[{id:"shell_frag", qty:[1,1]}]}, "孤石": {text:/*::GEN::互动描述:: */"刻痕旁边有一个浅坑,坑底压着一枚铸造的金属片。"/*::END:: */, loot:[{id:"metal", qty:[1,1]},{id:"relic_etching",qty:[0,1]}]}, "刻痕": {text:/*::GEN::互动描述:: */"符号的样式很陌生,你拓印了一份。"/*::END:: */, loot:[{id:"relic_etching",qty:[0,1]}]}, /* 沉船 */ "船壳": {text:/*::GEN::互动描述:: */"从锈层里抠出几块钢板碎片,还有分量。"/*::END:: */, loot:[{id:"metal", qty:[1,3]},{id:"wreck_steel",qty:[0,1]}]}, "锈层": {text:/*::GEN::互动描述:: */"锈层下藏着一截螺栓和一段铜管,价值有限但可用。"/*::END:: */, loot:[{id:"metal", qty:[1,2]}]}, "走廊": {text:/*::GEN::互动描述:: */"走廊尽头有个翻倒的金属柜,摸出两件东西。"/*::END:: */, loot:[{id:"metal", qty:[1,2]},{id:"relic_notebook",qty:[0,1]}]}, "管道": {text:/*::GEN::互动描述:: */"管道内还有残余油液,用小瓶收集了些。"/*::END:: */, loot:[{id:"oil", qty:[1,2]}]}, "货舱": {text:/*::GEN::互动描述:: */"货舱地板有几箱腐烂的货物,只有角落的金属箱还保持完好。"/*::END:: */, loot:[{id:"metal", qty:[2,4]},{id:"coal",qty:[0,3]}]}, "破洞": {text:/*::GEN::互动描述:: */"破洞边缘割手,你小心地检查了周围,收集了几块钢片。"/*::END:: */, loot:[{id:"wreck_steel", qty:[1,2]}]}, "金属框架": {text:/*::GEN::互动描述:: */"框架螺母已锈死,但你撬下了一段可用的钢条。"/*::END:: */, loot:[{id:"metal", qty:[2,3]}]}, "螺旋桨": {text:/*::GEN::互动描述:: */"贝类密布,你撬了几只吃食用或炼材都行。"/*::END:: */, loot:[{id:"fish", qty:[1,2]}]}, "贝类": {text:/*::GEN::互动描述:: */"贝类密布,你撬了几只。"/*::END:: */, loot:[{id:"fish", qty:[1,2]}]}, "推进器": {text:/*::GEN::互动描述:: */"你检查了推进器的机械结构,找到一块可拆下的橡胶密封件。"/*::END:: */, loot:[{id:"rubber_seal",qty:[1,1]}]} }>> <</widget>> <</nobr>>
<<nobr>> <<widget "diveSceneDefs">> /* ── 光照前缀池(按 _diveLightLevel 取一条) ── */ <<set $diveLightPfx = { bright: ["光线通透,","清亮的光穿透水体,","视线开阔,"], hazy: ["光线朦胧,","散射的光晕笼罩四周,","能见度尚可,"], dim: ["光线昏暗,","探照灯照出一片昏黄的锥形,","周围的轮廓若隐若现,"], dark: ["黑暗几乎是绝对的,","探照灯只能照亮眼前几米,","深渊的黑暗将一切吞没,"] }>> /* ── 光照后缀池(50%概率附加) ── */ <<set $diveLightSfx = { bright: ["水草随着微弱的水流轻轻摇曳。","远处的轮廓清晰可辨。"], hazy: ["细小颗粒在光柱里漂浮。","某些东西在光晕外若隐若现。"], dim: ["细沙被搅起后缓缓沉落。","光线边缘模糊成黑暗。"], dark: ["耳边只有自己的呼吸声。","什么都看不到,只能凭感觉前进。"] }>> /* ── 珊瑚礁场景池 ── */ <<set $diveSceneDefs = { reef: [ {id:"reef_narrow_passage", baseDesc:/*::GEN::潜水场景描述:: */"珊瑚群在两侧几乎触碰到肩膀,缝隙里偶有雀鲷快速穿过,你必须侧身通行。"/*::END:: */, elements:["珊瑚","雀鲷","缝隙"]}, {id:"reef_coral_arch", baseDesc:/*::GEN::潜水场景描述:: */"一道天然的珊瑚拱门横跨在前方,拱门内侧覆着海葵和管虫,细长的触手随水流微微颤动。"/*::END:: */, elements:["珊瑚拱门","海葵","管虫"]}, {id:"reef_fish_school", baseDesc:/*::GEN::潜水场景描述:: */"一大群小鱼突然从左侧涌来,密集到几乎遮住视线,它们绕过你继续前行,只留下水流扰动。"/*::END:: */, elements:["鱼群","扰动"]}, {id:"reef_sand_clearing", baseDesc:/*::GEN::潜水场景描述:: */"珊瑚群在这里让出了一片开阔的沙地,散落着碎贝壳和几根白色的细枝状珊瑚残骸。"/*::END:: */, elements:["沙地","贝壳","珊瑚残骸"]}, {id:"reef_eel_den", baseDesc:/*::GEN::潜水场景描述:: */"一条花斑裸胸鳝把脑袋伸出礁穴,黑色的眼睛盯着你看了片刻,然后缩回了黑暗。"/*::END:: */, elements:["礁穴","裸胸鳝"]} ], sand: [ {id:"sand_flat_expanse", baseDesc:/*::GEN::潜水场景描述:: */"无边无际的平坦沙海延伸到视线尽头,偶尔有沙鳐半埋在沙中,只露出眼睛。"/*::END:: */, elements:["沙海","沙鳐"]}, {id:"sand_debris_field", baseDesc:/*::GEN::潜水场景描述:: */"这片区域散落着大量碎石和锈蚀的金属残片,来源不明,也许曾经有东西在这里失事。"/*::END:: */, elements:["碎石","金属残片"]}, {id:"sand_ripple_field", baseDesc:/*::GEN::潜水场景描述:: */"规律的沙纹延伸数十米,像是被什么巨大的东西扫过,起伏的波纹依然清晰。"/*::END:: */, elements:["沙纹","波纹"]} ], flat: [ {id:"flat_rock_ledge", baseDesc:/*::GEN::潜水场景描述:: */"岩质海床在这里形成了一道低矮的石脊,石脊上长满了石蛏和藤壶,裂缝里不时有小蟹探出螯。"/*::END:: */, elements:["石脊","石蛏","蟹"]}, {id:"flat_pillar_cluster", baseDesc:/*::GEN::潜水场景描述:: */"几根天然的岩柱从海床直立而起,柱面上布满了棘皮动物留下的痕迹,颇为壮观。"/*::END:: */, elements:["岩柱","棘皮动物"]}, {id:"flat_dark_fissure", baseDesc:/*::GEN::潜水场景描述:: */"海床上有一道窄而深的裂缝,往下看不到底,有水流从里面涌出,温度比周围低了一截。"/*::END:: */, elements:["裂缝","冷泉"]} ], forest: [ {id:"forest_kelp_curtain", baseDesc:/*::GEN::潜水场景描述:: */"海藻形成的巨大帘幕将视线分成了两部分,穿过去需要拨开纠缠的叶片,里面有什么在动。"/*::END:: */, elements:["海藻帘","叶片"]}, {id:"forest_clearing_shaft", baseDesc:/*::GEN::潜水场景描述:: */"海藻丛在这里让出了一片圆形的开口,日光从正上方直射而下,形成完美的光柱。"/*::END:: */, elements:["海藻开口","光柱"]}, {id:"forest_hidden_rock", baseDesc:/*::GEN::潜水场景描述:: */"一块大礁石半掩在海藻里,石面上有大量附生生物,还有一些人工痕迹,也许是旧时捕鱼的标记。"/*::END:: */, elements:["礁石","附生生物","人工痕迹"]} ], cliff: [ {id:"cliff_wall_face", baseDesc:/*::GEN::潜水场景描述:: */"垂直的峭壁从海床延伸向上,壁面密布着管虫和苔藓虫的痕迹,一些小鱼贴着壁面来回巡游。"/*::END:: */, elements:["峭壁","管虫","苔藓虫"]}, {id:"cliff_overhang", baseDesc:/*::GEN::潜水场景描述:: */"峭壁在这里向外悬伸,形成了一片天然的庇护所,底部堆满了从上方落下的碎石。"/*::END:: */, elements:["悬岩","庇护所","碎石"]}, {id:"cliff_ledge_pool", baseDesc:/*::GEN::潜水场景描述:: */"峭壁上有一块宽阔的岩架,上面积了一层薄薄的细沙,还有几只海星和海胆静静地趴着。"/*::END:: */, elements:["岩架","海星","海胆"]} ], grass: [ {id:"grass_dense_meadow", baseDesc:/*::GEN::潜水场景描述:: */"海草密集地铺满海底,茎叶随着水流整齐地偏向同一方向,像是一片水下草原。"/*::END:: */, elements:["海草","水流"]}, {id:"grass_creature_trail", baseDesc:/*::GEN::潜水场景描述:: */"草丛里有明显的压痕,什么体型不小的东西刚刚经过,压倒的草还没有完全弹起来。"/*::END:: */, elements:["压痕","草丛"]}, {id:"grass_clearing_stone", baseDesc:/*::GEN::潜水场景描述:: */"海草在这里围绕着一块孤立的大石头,石头上刻着模糊的痕迹,和周围格格不入。"/*::END:: */, elements:["孤石","刻痕"]} ], wreck: [ {id:"wreck_outer_hull", baseDesc:/*::GEN::潜水场景描述:: */"你沿着锈蚀的船壳缓缓前进,甲板上的锈层已经剥落成碎片,钢板之间的缝隙塞满了珊瑚和藤壶。"/*::END:: */, elements:["船壳","锈层","珊瑚"]}, {id:"wreck_corridor", baseDesc:/*::GEN::潜水场景描述:: */"一条狭窄的走廊延伸到前方,墙面上的油漆早已剥落,管道从头顶横过,有几处已经断裂脱落。"/*::END:: */, elements:["走廊","管道","油漆"]}, {id:"wreck_hold", baseDesc:/*::GEN::潜水场景描述:: */"一个宽阔的货舱,顶部某处破了一个洞,透进来一缕光线,把漂浮的细尘照得清晰可见。"/*::END:: */, elements:["货舱","破洞","光线"]}, {id:"wreck_bridge_view", baseDesc:/*::GEN::潜水场景描述:: */"船桥的玻璃早已不见,只剩金属框架,从这里可以俯视整个船首区域,残骸的规模令人叹止。"/*::END:: */, elements:["船桥","金属框架","船首"]}, {id:"wreck_engine_exterior", baseDesc:/*::GEN::潜水场景描述:: */"船尾的推进器就在眼前,巨大的螺旋桨已经锈死,上面覆满了贝类,静止在水中。"/*::END:: */, elements:["推进器","螺旋桨","贝类"]}, {id:"wreck_jammed_hatch", baseDesc:/*::GEN::潜水场景描述:: */"一扇厚重的内舱门挡住了通道,铰链严重变形,锁死在半开的位置——靠人力完全无法移动。门缝里透出内舱的昏黄残影。"/*::END:: */, elements:["卡住的舱门","门缝残影","变形铰链"], blocked:["卡住的舱门"]}, {id:"wreck_collapsed_passage", baseDesc:/*::GEN::潜水场景描述:: */"走廊顶部有一段坍塌,大块舱壁斜压在通道上将前方完全堵死。只有机械外力才能移开。残骸缝隙里隐约可见更深处的内容。"/*::END:: */, elements:["坍塌的舱壁","残骸缝隙","深处残影"], blocked:["坍塌的舱壁"]} ] }>> /* ── 碎片文本池(per terrain,短小的环境描写) ── */ <<set $diveFragDefs = { reef: [ /*::GEN::潜水碎片:: */"一枚贝壳从珊瑚枝间滑落,在你脚边转了半圈,停了下来。"/*::END:: */, /*::GEN::潜水碎片:: */"远处有什么东西在黑暗里轻轻移动,但当你看过去时已经不见了。"/*::END:: */, /*::GEN::潜水碎片:: */"水温在这一片略微升高,珊瑚上的颜色也更鲜艳。"/*::END:: */, /*::GEN::潜水碎片:: */"你感到轻微的水流变化,某种生物刚刚从附近游过。"/*::END:: */, /*::GEN::潜水碎片:: */"一根长长的触手从礁穴里伸出来,试探了一下,又缩了回去。"/*::END:: */, /*::GEN::潜水碎片:: */"细沙从一个地方缓缓往下流,那里也许有什么空洞。"/*::END:: */, ], sand: [ /*::GEN::潜水碎片:: */"脚下的沙随着你的移动轻轻扰起,随后慢慢沉落。"/*::END:: */, /*::GEN::潜水碎片:: */"一只小虾从沙里一跳,消失在视野边缘。"/*::END:: */, /*::GEN::潜水碎片:: */"远处有什么闪了一下,也许是金属,也许是鱼鳞。"/*::END:: */, /*::GEN::潜水碎片:: */"水流在这里几乎察觉不到,寂静得有些不寻常。"/*::END:: */, /*::GEN::潜水碎片:: */"沙地上有一道细细的划痕,像是什么东西爬过去留下的。"/*::END:: */, ], flat: [ /*::GEN::潜水碎片:: */"岩面上有一道道平行的擦痕,像是被什么工具处理过。"/*::END:: */, /*::GEN::潜水碎片:: */"一只章鱼把自己伪装成岩石,但眼睛还是出卖了它。"/*::END:: */, /*::GEN::潜水碎片:: */"水流从岩石缝隙里涌出,带着一股淡淡的硫磺气味。"/*::END:: */, /*::GEN::潜水碎片:: */"几只管虫同时收起触须,像是察觉到了什么。"/*::END:: */, ], forest: [ /*::GEN::潜水碎片:: */"海藻的叶片贴着你的面罩滑过,遮挡了片刻的视线。"/*::END:: */, /*::GEN::潜水碎片:: */"什么在海藻丛里沙沙地移动,但太密集,看不清楚。"/*::END:: */, /*::GEN::潜水碎片:: */"光线在海藻叶片间分割成细碎的斑点,投影在你手上。"/*::END:: */, /*::GEN::潜水碎片:: */"一条细长的鱼悬浮在藻叶之间,和环境融为一体。"/*::END:: */, ], cliff: [ /*::GEN::潜水碎片:: */"峭壁上的一块岩石松动了,碎屑缓缓飘落。"/*::END:: */, /*::GEN::潜水碎片:: */"一只蟹横着从岩缝里爬出来,停了一下,又爬回去了。"/*::END:: */, /*::GEN::潜水碎片:: */"峭壁上某处有水在渗出,细流汇聚后缓缓飘散。"/*::END:: */, /*::GEN::潜水碎片:: */"这里的水流比外面复杂,峭壁影响了整个水域的流向。"/*::END:: */, ], grass: [ /*::GEN::潜水碎片:: */"海草叶片随着你的移动一起摆动,像是在迎接你。"/*::END:: */, /*::GEN::潜水碎片:: */"一只比手掌还大的螺从草丛里缓缓爬过,留下一道痕迹。"/*::END:: */, /*::GEN::潜水碎片:: */"草丛深处似乎有亮光,但那不太可能——你是唯一的光源。"/*::END:: */, /*::GEN::潜水碎片:: */"水草在这里长得特别高,几乎和你一样高。"/*::END:: */, ], wreck: [ /*::GEN::潜水碎片:: */"水从船壳的某个破口涌进,带起锈粉在水中弥漫。"/*::END:: */, /*::GEN::潜水碎片:: */"走道里有什么东西松动了,在水流里轻轻撞击着金属壁。"/*::END:: */, /*::GEN::潜水碎片:: */"一张褪色的图纸贴在壁面上,内容已经无法辨认。"/*::END:: */, /*::GEN::潜水碎片:: */"地板上有脚步的痕迹——当然,那是很久以前的事了。"/*::END:: */, /*::GEN::潜水碎片:: */"船上的某扇门还保持着半开的状态,门轴已经完全锈死。"/*::END:: */, /*::GEN::潜水碎片:: */"灯座还在,灯泡早已不知去向,金属圆环空悬在头顶。"/*::END:: */, ], default: [ /*::GEN::潜水碎片:: */"寂静的水中,只有探照灯的嗡鸣陪伴着你。"/*::END:: */, /*::GEN::潜水碎片:: */"你的气泡缓缓上浮,在黑暗里消失。"/*::END:: */, /*::GEN::潜水碎片:: */"水压变化让你耳朵轻微作响,调整一下深度就好了。"/*::END:: */, /*::GEN::潜水碎片:: */"什么东西从视野边缘一闪而过,但你没有追上去。"/*::END:: */, ] }>> <</widget>> <</nobr>>
<<nobr>> <<widget "exploreDefs">> /* ═══ ExploreDefs: 基础氛围碎片 + 环境采集定义 ═══ 基础氛围碎片:不含具体生物名,纯环境感知描述 搜索时抽取 1-2 条,与微型事件碎片合计 ≤ 3 条 */ <<set $exploreFragments = { sand: [ /*::GEN::探索碎片:: */"一片起伏的沙丘在灯光下显出柔和的波浪纹,远处的沙面消失在黑暗中。"/*::END:: */, /*::GEN::探索碎片:: */"细沙在潜艇引起的微弱水流中腾起,短暂悬浮后又缓缓落回海床。"/*::END:: */, /*::GEN::探索碎片:: */"沙床某处有一团轻微扰动留下的浑浊,某个东西刚刚离开这里。"/*::END:: */, /*::GEN::探索碎片:: */"一根石化的木桩斜插在沙地里,上面附生着几簇苔藓,来历不明。"/*::END:: */, /*::GEN::探索碎片:: */"沙面因地形微微凹陷,低洼处积着一层更细腻的淤泥,颜色比周围深。"/*::END:: */, ], flat: [ /*::GEN::探索碎片:: */"平整的岩床向深处延伸,轮廓在灯光边缘处变得模糊。"/*::END:: */, /*::GEN::探索碎片:: */"岩面覆着一层致密的附生物,偶有气泡从其中悄然冒出。"/*::END:: */, /*::GEN::探索碎片:: */"岩床上有一道被磨光的长痕,某种大型物体曾经拖曳过此处。"/*::END:: */, /*::GEN::探索碎片:: */"几条岩缝向深处延伸,宽窄不一,深处在灯光里看不到尽头。"/*::END:: */, /*::GEN::探索碎片:: */"突起的岩脊在水流中形成了背涡区,有机碎屑在此聚集沉降。"/*::END:: */, ], grass: [ /*::GEN::探索碎片:: */"海草随水流起伏,茎叶的摆动有某种规律,像是在对水流之外的东西做出反应。"/*::END:: */, /*::GEN::探索碎片:: */"草根处的泥沙比周围更细腻,长年不流动的积水在这里沉积了厚厚一层淤泥。"/*::END:: */, /*::GEN::探索碎片:: */"草丛里某处有轻微扰动,泥沙雾缓缓散开,什么已经躲回草里了。"/*::END:: */, /*::GEN::探索碎片:: */"草茎底部有些许发光的微生物,在灯光照不到的地方闪烁着蓝绿色微光。"/*::END:: */, /*::GEN::探索碎片:: */"海草床边缘处,水流方向有细微变化,带来远处的有机物碎屑。"/*::END:: */, ], reef: [ /*::GEN::探索碎片:: */"珊瑚礁的轮廓在灯光边缘显得复杂而密集,每一处突起都可能藏着什么。"/*::END:: */, /*::GEN::探索碎片:: */"礁石背面有一片深色阴影区,水流在这里分叉绕行,带着有机物碎屑漂散。"/*::END:: */, /*::GEN::探索碎片:: */"一片星珊瑚覆盖了整块礁石,珊瑚虫都伸出细小的触须在过滤水流。"/*::END:: */, /*::GEN::探索碎片:: */"海葵的触须在水流中缓慢张合,橘红色的簇丛在昏暗中格外鲜艳。"/*::END:: */, /*::GEN::探索碎片:: */"礁壁顶端有一块突出的岩架,下方形成庇护区,积聚了大量悬浮有机颗粒。"/*::END:: */, ], cliff: [ /*::GEN::探索碎片:: */"峭壁向下延伸,在灯光能触及的范围内没有底端,黑暗完整地包围着这里。"/*::END:: */, /*::GEN::探索碎片:: */"壁面有被侵蚀的凹槽,形状奇特,像是某种大型生物曾经在此摩擦过。"/*::END:: */, /*::GEN::探索碎片:: */"岩壁上偶有气泡从微小裂隙中涌出,缓缓升向看不见的水面。"/*::END:: */, /*::GEN::探索碎片:: */"峭壁上有黑色渗液缓缓流出,在岩面留下暗色条纹,气味浓烈。"/*::END:: */, /*::GEN::探索碎片:: */"壁面有处突出的岩台,岩台下方聚积着沉降物,已经形成了小型沙砾堆。"/*::END:: */, ], forest: [ /*::GEN::探索碎片:: */"茂密的巨藻从海床一直生长到视野所能触及的高度,光线穿透枝叶时呈现出斑驳的绿色。"/*::END:: */, /*::GEN::探索碎片:: */"藻林的树冠处聚集着大量微小气泡,光线穿透时将它们映成金色。"/*::END:: */, /*::GEN::探索碎片:: */"林底枯萎的巨藻茎已经开始腐化,成为无数附生生物的栖居之所。"/*::END:: */, /*::GEN::探索碎片:: */"藻林边缘有处缺口,开阔区域从缺口处可见,与林内的幽暗形成对比。"/*::END:: */, /*::GEN::探索碎片:: */"粗壮的藻茎之间留有天然的通道,水流在其中形成稳定的流向。"/*::END:: */, ], water: [ /*::GEN::探索碎片:: */"一只水母缓慢地漂过,半透明的伞盖轻轻收缩,触须垂落如丝。"/*::END:: */, /*::GEN::探索碎片:: */"一片细微的悬浮颗粒在灯光里漂浮,随推进水流散开又聚拢。"/*::END:: */, /*::GEN::探索碎片:: */"远处有什么发光体划过,在黑暗中留下短暂的蓝色轨迹,随即消失。"/*::END:: */, /*::GEN::探索碎片:: */"水中偶尔有深处涌上的冷流,温度计轻微下降了几度。"/*::END:: */, /*::GEN::探索碎片:: */"开放水域里看不到底端,只有灯光勉强照出面前这一小片水域的轮廓。"/*::END:: */, ] }>> /* ── 环境采集定义:不消耗丰富度,产量低但稳定 ── */ <<set $envHarvestDefs = { sand: { label:/*::GEN::采集标签:: */"翻找沙层"/*::END:: */, text:/*::GEN::采集描述:: */"在浅沙层翻找了一圈。"/*::END:: */, loot:[{id:"shell_frag",qty:[1,3]},{id:"sand_extract",qty:[0,1]}] }, flat: { label:/*::GEN::采集标签:: */"刮取岩面"/*::END:: */, text:/*::GEN::采集描述:: */"刮取了岩面的附生物和渗出物。"/*::END:: */, loot:[{id:"seawater_ext",qty:[1,2]},{id:"coral_frag",qty:[0,2]}] }, reef: { label:/*::GEN::采集标签:: */"采集礁面"/*::END:: */, text:/*::GEN::采集描述:: */"采集了礁面上松动的珊瑚碎片。"/*::END:: */, loot:[{id:"coral_frag",qty:[1,3]},{id:"shell_frag",qty:[0,2]}] }, grass: { label:/*::GEN::采集标签:: */"收割海草"/*::END:: */, text:/*::GEN::采集描述:: */"收割了附近的海草,整理成束。"/*::END:: */, loot:[{id:"kelp",qty:[2,4]},{id:"seagrass_str",qty:[1,2]}] }, forest:{ label:/*::GEN::采集标签:: */"采集巨藻"/*::END:: */, text:/*::GEN::采集描述:: */"采集了大量巨藻,还提取了一些藻纤维。"/*::END:: */, loot:[{id:"kelp",qty:[3,6]},{id:"kelp_fiber",qty:[1,2]}] }, cliff: { label:/*::GEN::采集标签:: */"收集渗出物"/*::END:: */,text:/*::GEN::采集描述:: */"收集了壁面渗液和矿物堆积物。"/*::END:: */, loot:[{id:"sand_extract",qty:[1,2]},{id:"sulfur_dust",qty:[0,1]}] }, water: { label:/*::GEN::采集标签:: */"过滤浮游物"/*::END:: */,text:/*::GEN::采集描述:: */"过滤了一些浮游生物和海水提取物。"/*::END:: */, loot:[{id:"seawater_ext",qty:[1,3]},{id:"jellyfluid",qty:[0,1]}] } }>> <<set $exploreSearchCost = { min: 3, max: 7 }>> <<set $lastExploreText = "">> <<set $exploreLog = []>> <</widget>> <</nobr>>
<<set $fishingConfig = { lightWeights: { "强光": { "日行性": 1.2, "夜行性": 0.2, "趋光性": 0.3 }, "朦胧": { "日行性": 1.0, "夜行性": 0.4, "趋光性": 0.4 }, "昏暗": { "日行性": 0.6, "夜行性": 0.8, "趋光性": 0.6 }, "无光": { "日行性": 0.2, "夜行性": 1.4, "趋光性": 0.8 } }, lightBonus: { "日行性": 1.1, "夜行性": 0.8, "趋光性": 2.0 }, gearTags: { "渔网": ["群居"], "垂钓": ["大型"] }, baitTags: { "血饵": ["肉食性"], "草饵": ["草食性"] }, depthWeights: { "0-50": { "浅层": 1.5, // 浅层鱼在0-50米权重高 "中层": 0.8, // 中层鱼在0-50米权重低 "深层": 0.1 // 深层鱼在0-50米几乎不出现 }, "50-150": { "浅层": 1.2, "中层": 1.0, "深层": 0.3 }, "150-300": { "浅层": 0.6, "中层": 1.3, "深层": 0.8 }, "300-1000": { "浅层": 0.1, "中层": 0.7, "深层": 1.5 }, "1000+": { "浅层": 0.0, "中层": 0.2, "深层": 1.8 } }, // 地形权重配置 terrainWeights: { "沙海床": { "底栖": 1.5, "沙海床": 1.3, "开阔水域": 0.7 }, "岩海床": { "岩海床": 1.4, "底栖": 1.2, "峭壁": 1.1 }, "珊瑚礁": { "珊瑚礁": 1.6, "岩海床": 1.2 }, "海草床": { "海草床": 1.5, "底栖": 1.1 }, "海藻森林": { "海藻森林": 1.4, "日行性": 1.2 }, "开阔水域": { "开阔水域": 1.5, "洄游性": 1.3 }, "峭壁": { "峭壁": 1.5, "岩海床": 1.2 }, "底栖": { "底栖": 1.6, "沙海床": 1.1, "岩海床": 1.1 } } }>> <<set $pools = { /* ========== 鱼类 ========== */ /* 鲑鱼 - 洄游性,喜欢冷水,浅中层 */ "salmon": { name: /*::GEN::渔获名::salmon:: */"鲑鱼"/*::END:: */, baseWeight: 5, tags: ["中层", "洄游性", "日行性", "肉食性"], customWeights: { depth: { "0-50": 1.3, "50-150": 1.5, "150-300": 0.8, "300-1000": 0.1, "1000+": 0.0 }, terrain: { "开阔水域": 1.4, "沙海床": 0.8, "岩海床": 1.0 }, light: { "明亮": 1.2, "朦胧": 1.0, "昏暗": 0.6, "无光": 0.2 } } }, /* 鲈鱼 - 适应性强,礁石区常见,伏击型 */ "seabass": { name: /*::GEN::渔获名::seabass:: */"鲈鱼"/*::END:: */, baseWeight: 6, tags: ["中层", "夜行性", "肉食性", "岩海床"], customWeights: { depth: { "0-50": 1.2, "50-150": 1.5, "150-300": 1.0, "300-1000": 0.2, "1000+": 0.0 }, terrain: { "岩海床": 1.5, "珊瑚礁": 1.3, "海草床": 1.1, "沙海床": 0.7, "开阔水域": 0.5 }, light: { "明亮": 0.8, "朦胧": 1.0, "昏暗": 1.3, "无光": 1.4 } } }, /* 金枪鱼 - 大型洄游,开阔水域,难钓 */ "tuna": { name: /*::GEN::渔获名::tuna:: */"金枪鱼"/*::END:: */, baseWeight: 2, tags: ["中层", "洄游性", "日行性", "肉食性", "大型", "开阔水域"], customWeights: { depth: { "0-50": 0.5, "50-150": 1.8, "150-300": 1.5, "300-1000": 0.4, "1000+": 0.0 }, terrain: { "开阔水域": 2.0, "沙海床": 0.4, "岩海床": 0.5, "珊瑚礁": 0.6 }, light: { "明亮": 1.3, "朦胧": 1.0, "昏暗": 0.5, "无光": 0.2 } } }, /* 沙丁鱼 - 极常见,群居,趋光 */ "sardine": { name: /*::GEN::渔获名::sardine:: */"沙丁鱼"/*::END:: */, baseWeight: 12, tags: ["浅层", "趋光性", "群居", "开阔水域", "草食性"], customWeights: { depth: { "0-50": 2.0, "50-150": 1.2, "150-300": 0.3, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "开阔水域": 1.6, "沙海床": 1.0, "海草床": 1.1, "岩海床": 0.7 }, light: { "明亮": 0.8, "朦胧": 1.0, "昏暗": 1.5, "无光": 2.0 } } }, /* 鲱鱼 - 群居,浅水,冷水偏好 */ "herring": { name: /*::GEN::渔获名::herring:: */"鲱鱼"/*::END:: */, baseWeight: 10, tags: ["浅层", "群居", "日行性", "开阔水域"], customWeights: { depth: { "0-50": 1.8, "50-150": 1.2, "150-300": 0.4, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "开阔水域": 1.5, "沙海床": 1.0, "海草床": 0.9 }, light: { "明亮": 1.2, "朦胧": 1.0, "昏暗": 0.7, "无光": 0.4 } } }, /* 石斑鱼 - 礁石区,夜行伏击 */ "grouper": { name: /*::GEN::渔获名::grouper:: */"石斑鱼"/*::END:: */, baseWeight: 4, tags: ["中层", "夜行性", "肉食性", "岩海床", "底栖", "大型"], customWeights: { depth: { "0-50": 0.6, "50-150": 1.2, "150-300": 1.5, "300-1000": 0.8, "1000+": 0.0 }, terrain: { "岩海床": 1.6, "峭壁": 1.4, "珊瑚礁": 1.3, "海草床": 0.5, "沙海床": 0.3 }, light: { "明亮": 0.7, "朦胧": 1.0, "昏暗": 1.3, "无光": 1.5 } } }, /* 鲯鳅 - 大型,开阔水域,高速洄游 */ "mahi": { name: /*::GEN::渔获名::mahi:: */"鲯鳅"/*::END:: */, baseWeight: 2, tags: ["中层", "洄游性", "日行性", "肉食性", "大型", "开阔水域"], customWeights: { depth: { "0-50": 1.0, "50-150": 2.0, "150-300": 1.2, "300-1000": 0.2, "1000+": 0.0 }, terrain: { "开阔水域": 2.2, "沙海床": 0.2, "岩海床": 0.3 }, light: { "明亮": 1.5, "朦胧": 1.0, "昏暗": 0.4, "无光": 0.1 } } }, /* 鳕鱼 - 冷深水,底栖 */ "cod": { name: /*::GEN::渔获名::cod:: */"鳕鱼"/*::END:: */, baseWeight: 5, tags: ["深层", "底栖", "日行性", "肉食性"], customWeights: { depth: { "0-50": 0.1, "50-150": 0.5, "150-300": 1.3, "300-1000": 1.8, "1000+": 0.8 }, terrain: { "沙海床": 1.4, "岩海床": 1.3, "开阔水域": 0.8, "峭壁": 0.9 }, light: { "明亮": 1.0, "朦胧": 1.1, "昏暗": 1.2, "无光": 0.9 } } }, /* 鳗鱼 - 底栖,夜行,善藏礁缝 */ "eel": { name: /*::GEN::渔获名::eel:: */"鳗鱼"/*::END:: */, baseWeight: 4, tags: ["底栖", "夜行性", "肉食性", "岩海床"], customWeights: { depth: { "0-50": 1.0, "50-150": 1.4, "150-300": 1.5, "300-1000": 0.8, "1000+": 0.2 }, terrain: { "岩海床": 1.7, "峭壁": 1.5, "珊瑚礁": 1.2, "海藻森林": 1.3, "沙海床": 0.4 }, light: { "明亮": 0.3, "朦胧": 0.7, "昏暗": 1.4, "无光": 1.8 } } }, /* 比目鱼 - 沙底伏击,底栖 */ "flounder": { name: /*::GEN::渔获名::flounder:: */"比目鱼"/*::END:: */, baseWeight: 5, tags: ["底栖", "日行性", "肉食性", "沙海床"], customWeights: { depth: { "0-50": 1.4, "50-150": 1.5, "150-300": 1.0, "300-1000": 0.4, "1000+": 0.0 }, terrain: { "沙海床": 2.0, "海草床": 1.2, "岩海床": 0.4, "开阔水域": 0.2 }, light: { "明亮": 1.2, "朦胧": 1.0, "昏暗": 0.8, "无光": 0.5 } } }, /* 鲭鱼 - 群居,中层,洄游 */ "mackerel": { name: /*::GEN::渔获名::mackerel:: */"鲭鱼"/*::END:: */, baseWeight: 8, tags: ["中层", "洄游性", "群居", "肉食性", "开阔水域"], customWeights: { depth: { "0-50": 1.0, "50-150": 1.8, "150-300": 1.2, "300-1000": 0.2, "1000+": 0.0 }, terrain: { "开阔水域": 1.8, "沙海床": 0.7, "岩海床": 0.8 }, light: { "明亮": 1.3, "朦胧": 1.1, "昏暗": 0.7, "无光": 0.3 } } }, /* 鲷鱼 - 礁石区,杂食 */ "bream": { name: /*::GEN::渔获名::bream:: */"鲷鱼"/*::END:: */, baseWeight: 5, tags: ["中层", "日行性", "岩海床", "珊瑚礁"], customWeights: { depth: { "0-50": 1.2, "50-150": 1.5, "150-300": 1.0, "300-1000": 0.3, "1000+": 0.0 }, terrain: { "岩海床": 1.5, "珊瑚礁": 1.6, "海草床": 1.2, "沙海床": 0.7 }, light: { "明亮": 1.3, "朦胧": 1.0, "昏暗": 0.7, "无光": 0.4 } } }, /* 凤尾鱼 - 极小,群居,浅水趋光 */ "anchovy": { name: /*::GEN::渔获名::anchovy:: */"凤尾鱼"/*::END:: */, baseWeight: 12, tags: ["浅层", "趋光性", "群居", "开阔水域"], customWeights: { depth: { "0-50": 2.2, "50-150": 1.0, "150-300": 0.2, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "开阔水域": 1.5, "沙海床": 1.0, "海草床": 1.2 }, light: { "明亮": 0.6, "朦胧": 1.0, "昏暗": 1.6, "无光": 2.2 } } }, /* 梭子鱼 - 凶猛,开阔水域伏击 */ "barracuda": { name: /*::GEN::渔获名::barracuda:: */"梭子鱼"/*::END:: */, baseWeight: 3, tags: ["中层", "日行性", "肉食性", "大型", "开阔水域"], customWeights: { depth: { "0-50": 1.0, "50-150": 1.8, "150-300": 1.2, "300-1000": 0.3, "1000+": 0.0 }, terrain: { "开阔水域": 1.8, "珊瑚礁": 1.4, "岩海床": 1.0, "沙海床": 0.5 }, light: { "明亮": 1.5, "朦胧": 1.2, "昏暗": 0.6, "无光": 0.3 } } }, /* 带鱼 - 深中层,夜间上浮,趋光 */ "hairtail": { name: /*::GEN::渔获名::hairtail:: */"带鱼"/*::END:: */, baseWeight: 6, tags: ["深层", "趋光性", "夜行性", "肉食性"], customWeights: { depth: { "0-50": 0.3, "50-150": 1.2, "150-300": 1.8, "300-1000": 1.5, "1000+": 0.3 }, terrain: { "沙海床": 1.3, "开阔水域": 1.4, "峭壁": 0.9 }, light: { "明亮": 0.3, "朦胧": 0.7, "昏暗": 1.4, "无光": 2.0 } } }, /* 翻车鱼 - 极稀有,开阔深水,独行 */ "sunfish": { name: /*::GEN::渔获名::sunfish:: */"翻车鱼"/*::END:: */, baseWeight: 1, tags: ["深层", "日行性", "大型", "开阔水域", "洄游性"], customWeights: { depth: { "0-50": 0.2, "50-150": 0.8, "150-300": 1.5, "300-1000": 2.0, "1000+": 0.5 }, terrain: { "开阔水域": 3.0, "沙海床": 0.1, "岩海床": 0.1 }, light: { "明亮": 1.5, "朦胧": 1.2, "昏暗": 0.5, "无光": 0.1 } } }, /* 鮟鱇 - 深海,极暗,独行,大型 */ "anglerfish": { name: /*::GEN::渔获名::anglerfish:: */"鮟鱇"/*::END:: */, baseWeight: 2, tags: ["深层", "底栖", "夜行性", "肉食性", "大型"], customWeights: { depth: { "0-50": 0.0, "50-150": 0.1, "150-300": 0.5, "300-1000": 1.8, "1000+": 3.0 }, terrain: { "沙海床": 1.0, "岩海床": 1.2, "峭壁": 1.5 }, light: { "明亮": 0.0, "朦胧": 0.2, "昏暗": 0.8, "无光": 2.5 } } }, /* 海马 - 极稀有,海草床,慢 */ "seahorse": { name: /*::GEN::渔获名::seahorse:: */"海马"/*::END:: */, baseWeight: 1, tags: ["浅层", "日行性", "海草床", "珊瑚礁"], customWeights: { depth: { "0-50": 2.5, "50-150": 1.0, "150-300": 0.1, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "海草床": 3.0, "珊瑚礁": 2.0, "岩海床": 0.3, "沙海床": 0.2 }, light: { "明亮": 1.5, "朦胧": 1.0, "昏暗": 0.4, "无光": 0.1 } } }, /* ========== 贝类 ========== */ /* 扇贝 - 沙底/海草床,浅中层 */ "scallop": { name: /*::GEN::渔获名::scallop:: */"扇贝"/*::END:: */, baseWeight: 6, tags: ["底栖", "沙海床", "海草床"], customWeights: { depth: { "0-50": 1.3, "50-150": 1.5, "150-300": 0.7, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "沙海床": 1.5, "海草床": 1.8, "岩海床": 0.3, "开阔水域": 0.0 }, light: { "明亮": 1.0, "朦胧": 1.0, "昏暗": 0.8, "无光": 0.6 } } }, /* 蛤蜊 - 沙底埋栖 */ "clam": { name: /*::GEN::渔获名::clam:: */"蛤蜊"/*::END:: */, baseWeight: 8, tags: ["底栖", "沙海床", "海草床"], customWeights: { depth: { "0-50": 1.8, "50-150": 1.2, "150-300": 0.3, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "沙海床": 2.0, "海草床": 1.3, "岩海床": 0.1, "开阔水域": 0.0 }, light: { "明亮": 1.0, "朦胧": 1.0, "昏暗": 0.9, "无光": 0.8 } } }, /* 牡蛎 - 附着岩礁,不移动 */ "oyster": { name: /*::GEN::渔获名::oyster:: */"牡蛎"/*::END:: */, baseWeight: 7, tags: ["底栖", "岩海床", "珊瑚礁"], customWeights: { depth: { "0-50": 2.0, "50-150": 1.2, "150-300": 0.4, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "岩海床": 2.0, "珊瑚礁": 1.8, "沙海床": 0.1, "海草床": 0.3 }, light: { "明亮": 1.0, "朦胧": 1.0, "昏暗": 0.9, "无光": 0.8 } } }, /* 贻贝 - 附岩,潮带到浅海 */ "mussel": { name: /*::GEN::渔获名::mussel:: */"贻贝"/*::END:: */, baseWeight: 8, tags: ["底栖", "岩海床"], customWeights: { depth: { "0-50": 2.2, "50-150": 1.0, "150-300": 0.2, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "岩海床": 2.2, "峭壁": 1.5, "珊瑚礁": 0.8, "沙海床": 0.0 }, light: { "明亮": 1.0, "朦胧": 1.0, "昏暗": 0.9, "无光": 0.7 } } }, /* 海螺 - 底栖爬行,多地形 */ "conch": { name: /*::GEN::渔获名::conch:: */"海螺"/*::END:: */, baseWeight: 6, tags: ["底栖", "岩海床", "沙海床"], customWeights: { depth: { "0-50": 1.5, "50-150": 1.3, "150-300": 0.8, "300-1000": 0.2, "1000+": 0.0 }, terrain: { "岩海床": 1.6, "沙海床": 1.4, "珊瑚礁": 1.5, "海草床": 1.2 }, light: { "明亮": 1.0, "朦胧": 1.0, "昏暗": 1.0, "无光": 0.8 } } }, /* ========== 虾类 ========== */ /* 对虾 - 海草床,夜行 */ "prawn": { name: /*::GEN::渔获名::prawn:: */"对虾"/*::END:: */, baseWeight: 7, tags: ["底栖", "夜行性", "海草床", "群居"], customWeights: { depth: { "0-50": 1.8, "50-150": 1.4, "150-300": 0.5, "300-1000": 0.1, "1000+": 0.0 }, terrain: { "海草床": 2.2, "沙海床": 1.2, "岩海床": 0.8, "珊瑚礁": 1.0 }, light: { "明亮": 0.5, "朦胧": 0.8, "昏暗": 1.5, "无光": 2.0 } } }, /* 龙虾 - 底栖,夜行,岩礁藏身 */ "lobster": { name: /*::GEN::渔获名::lobster:: */"龙虾"/*::END:: */, baseWeight: 3, tags: ["底栖", "夜行性", "岩海床", "大型"], customWeights: { depth: { "0-50": 0.8, "50-150": 1.5, "150-300": 1.8, "300-1000": 0.8, "1000+": 0.1 }, terrain: { "岩海床": 2.2, "峭壁": 1.8, "珊瑚礁": 1.3, "沙海床": 0.3 }, light: { "明亮": 0.2, "朦胧": 0.6, "昏暗": 1.5, "无光": 2.2 } } }, /* 皮皮虾(虾蛄)- 沙底底栖,昼行 */ "mantisshrimp": { name: /*::GEN::渔获名::mantisshrimp:: */"皮皮虾"/*::END:: */, baseWeight: 5, tags: ["底栖", "日行性", "沙海床", "肉食性"], customWeights: { depth: { "0-50": 1.8, "50-150": 1.5, "150-300": 0.5, "300-1000": 0.1, "1000+": 0.0 }, terrain: { "沙海床": 2.0, "岩海床": 1.0, "海草床": 1.2, "珊瑚礁": 0.8 }, light: { "明亮": 1.4, "朦胧": 1.0, "昏暗": 0.7, "无光": 0.4 } } }, /* 甜虾 - 深冷水,密集群居 */ "sweetshrimp": { name: /*::GEN::渔获名::sweetshrimp:: */"甜虾"/*::END:: */, baseWeight: 5, tags: ["深层", "群居", "夜行性"], customWeights: { depth: { "0-50": 0.0, "50-150": 0.3, "150-300": 1.2, "300-1000": 2.2, "1000+": 1.5 }, terrain: { "沙海床": 1.5, "开阔水域": 1.2, "岩海床": 1.0 }, light: { "明亮": 0.1, "朦胧": 0.4, "昏暗": 1.2, "无光": 2.0 } } }, /* 樱虾 - 开阔水域,昼夜垂直洄游,趋光 */ "cherryshrimp": { name: /*::GEN::渔获名::cherryshrimp:: */"樱虾"/*::END:: */, baseWeight: 6, tags: ["浅层", "趋光性", "群居", "开阔水域", "洄游性"], customWeights: { depth: { "0-50": 2.0, "50-150": 1.5, "150-300": 0.5, "300-1000": 0.1, "1000+": 0.0 }, terrain: { "开阔水域": 2.5, "沙海床": 0.8 }, light: { "明亮": 0.4, "朦胧": 0.8, "昏暗": 1.5, "无光": 2.5 } } }, /* ========== 蟹类 ========== */ /* 帝王蟹 - 海藻森林,深冷水 */ "kingcrab": { name: /*::GEN::渔获名::kingcrab:: */"帝王蟹"/*::END:: */, baseWeight: 2, tags: ["底栖", "夜行性", "海藻森林", "大型"], customWeights: { depth: { "0-50": 0.1, "50-150": 0.5, "150-300": 1.5, "300-1000": 2.5, "1000+": 0.5 }, terrain: { "海藻森林": 3.0, "岩海床": 1.2, "峭壁": 1.0, "沙海床": 0.2 }, light: { "明亮": 0.2, "朦胧": 0.6, "昏暗": 1.5, "无光": 2.2 } } }, /* 雪蟹 - 峭壁深水,冷水 */ "snowcrab": { name: /*::GEN::渔获名::snowcrab:: */"雪蟹"/*::END:: */, baseWeight: 2, tags: ["底栖", "夜行性", "峭壁", "大型"], customWeights: { depth: { "0-50": 0.0, "50-150": 0.3, "150-300": 1.2, "300-1000": 2.5, "1000+": 1.5 }, terrain: { "峭壁": 3.0, "岩海床": 1.5, "海藻森林": 1.2, "沙海床": 0.3 }, light: { "明亮": 0.1, "朦胧": 0.4, "昏暗": 1.2, "无光": 2.5 } } }, /* 蓝蟹 - 海草床,半咸水域,常见 */ "bluecrab": { name: /*::GEN::渔获名::bluecrab:: */"蓝蟹"/*::END:: */, baseWeight: 6, tags: ["底栖", "夜行性", "海草床", "肉食性"], customWeights: { depth: { "0-50": 2.0, "50-150": 1.5, "150-300": 0.4, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "海草床": 2.5, "沙海床": 1.3, "岩海床": 0.7 }, light: { "明亮": 0.6, "朦胧": 0.9, "昏暗": 1.4, "无光": 1.8 } } }, /* 梭子蟹 - 沙海床,善游泳 */ "swimmingcrab": { name: /*::GEN::渔获名::swimmingcrab:: */"梭子蟹"/*::END:: */, baseWeight: 7, tags: ["底栖", "夜行性", "沙海床", "肉食性"], customWeights: { depth: { "0-50": 1.8, "50-150": 1.5, "150-300": 0.6, "300-1000": 0.1, "1000+": 0.0 }, terrain: { "沙海床": 2.2, "海草床": 1.3, "岩海床": 0.6 }, light: { "明亮": 0.7, "朦胧": 0.9, "昏暗": 1.4, "无光": 1.7 } } }, /* 花蟹 - 礁石/珊瑚,颜色鲜艳 */ "flowercrab": { name: /*::GEN::渔获名::flowercrab:: */"花蟹"/*::END:: */, baseWeight: 4, tags: ["底栖", "日行性", "岩海床", "珊瑚礁"], customWeights: { depth: { "0-50": 1.5, "50-150": 1.5, "150-300": 0.8, "300-1000": 0.1, "1000+": 0.0 }, terrain: { "珊瑚礁": 2.0, "岩海床": 1.8, "沙海床": 0.5, "海草床": 0.8 }, light: { "明亮": 1.4, "朦胧": 1.1, "昏暗": 0.7, "无光": 0.4 } } }, /* 红蟹 - 珊瑚礁,颜色醒目 */ "redcrab": { name: /*::GEN::渔获名::redcrab:: */"红蟹"/*::END:: */, baseWeight: 3, tags: ["底栖", "日行性", "珊瑚礁"], customWeights: { depth: { "0-50": 1.8, "50-150": 1.5, "150-300": 0.5, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "珊瑚礁": 3.0, "岩海床": 1.2, "沙海床": 0.3 }, light: { "明亮": 1.5, "朦胧": 1.0, "昏暗": 0.6, "无光": 0.3 } } }, /* ========== 头足类 ========== */ /* 鱿鱼 - 夜间趋光,群居,中层 */ "squid": { name: /*::GEN::渔获名::squid:: */"鱿鱼"/*::END:: */, baseWeight: 8, tags: ["中层", "趋光性", "夜行性", "群居", "肉食性"], customWeights: { depth: { "0-50": 0.5, "50-150": 1.8, "150-300": 1.5, "300-1000": 0.8, "1000+": 0.2 }, terrain: { "开阔水域": 1.6, "沙海床": 1.0, "岩海床": 0.8 }, light: { "明亮": 0.2, "朦胧": 0.6, "昏暗": 1.6, "无光": 2.5 } } }, /* 墨鱼 - 浅中层,礁石区,白天可见 */ "cuttlefish": { name: /*::GEN::渔获名::cuttlefish:: */"墨鱼"/*::END:: */, baseWeight: 5, tags: ["中层", "日行性", "肉食性", "岩海床", "珊瑚礁"], customWeights: { depth: { "0-50": 1.3, "50-150": 1.6, "150-300": 1.2, "300-1000": 0.3, "1000+": 0.0 }, terrain: { "岩海床": 1.8, "珊瑚礁": 1.6, "海草床": 1.3, "沙海床": 0.9 }, light: { "明亮": 1.3, "朦胧": 1.0, "昏暗": 0.7, "无光": 0.4 } } }, /* 章鱼 - 底栖,夜行,藏礁缝,独行 */ "octopus": { name: /*::GEN::渔获名::octopus:: */"章鱼"/*::END:: */, baseWeight: 4, tags: ["底栖", "夜行性", "肉食性", "岩海床"], customWeights: { depth: { "0-50": 1.2, "50-150": 1.5, "150-300": 1.3, "300-1000": 0.6, "1000+": 0.1 }, terrain: { "岩海床": 2.0, "峭壁": 1.5, "珊瑚礁": 1.5, "海藻森林": 1.3, "沙海床": 0.5 }, light: { "明亮": 0.3, "朦胧": 0.7, "昏暗": 1.5, "无光": 2.0 } } }, /* ========== 棘皮/其他无脊椎 ========== */ /* 海胆 - 附岩,珊瑚/海藻,日行 */ "seaurchin": { name: /*::GEN::渔获名::seaurchin:: */"海胆"/*::END:: */, baseWeight: 6, tags: ["底栖", "日行性", "草食性", "海藻森林", "珊瑚礁"], customWeights: { depth: { "0-50": 1.5, "50-150": 1.8, "150-300": 1.2, "300-1000": 0.3, "1000+": 0.0 }, terrain: { "珊瑚礁": 2.2, "岩海床": 1.8, "海藻森林": 2.0, "沙海床": 0.3 }, light: { "明亮": 1.3, "朦胧": 1.0, "昏暗": 0.7, "无光": 0.4 } } }, /* 海星 - 底栖爬行,多地形 */ "starfish": { name: /*::GEN::渔获名::starfish:: */"海星"/*::END:: */, baseWeight: 5, tags: ["底栖", "日行性"], customWeights: { depth: { "0-50": 1.5, "50-150": 1.3, "150-300": 0.9, "300-1000": 0.3, "1000+": 0.0 }, terrain: { "岩海床": 1.6, "珊瑚礁": 1.5, "沙海床": 1.2, "海草床": 1.3 }, light: { "明亮": 1.2, "朦胧": 1.0, "昏暗": 0.8, "无光": 0.5 } } }, /* 水母 - 随流漂浮,中层,趋光,夜间聚集 */ "jellyfish": { name: /*::GEN::渔获名::jellyfish:: */"水母"/*::END:: */, baseWeight: 7, tags: ["中层", "趋光性", "开阔水域"], customWeights: { depth: { "0-50": 1.5, "50-150": 1.8, "150-300": 1.2, "300-1000": 0.5, "1000+": 0.2 }, terrain: { "开阔水域": 2.0, "沙海床": 0.8, "岩海床": 0.6 }, light: { "明亮": 0.5, "朦胧": 0.9, "昏暗": 1.5, "无光": 2.2 } } }, /* ========== 藻类 ========== */ /* 海带 - 冷水,岩礁附着,浅中层 */ "kelp": { name: /*::GEN::渔获名::kelp:: */"海带"/*::END:: */, baseWeight: 8, tags: ["底栖", "草食性", "岩海床", "海藻森林"], customWeights: { depth: { "0-50": 1.0, "50-150": 2.0, "150-300": 1.5, "300-1000": 0.2, "1000+": 0.0 }, terrain: { "岩海床": 2.0, "海藻森林": 3.0, "峭壁": 1.5, "沙海床": 0.1 }, light: { "明亮": 1.5, "朦胧": 1.2, "昏暗": 0.7, "无光": 0.2 } } }, /* 裙带菜 - 浅岩礁,常见 */ "wakame": { name: /*::GEN::渔获名::wakame:: */"裙带菜"/*::END:: */, baseWeight: 8, tags: ["底栖", "草食性", "岩海床"], customWeights: { depth: { "0-50": 2.0, "50-150": 1.5, "150-300": 0.5, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "岩海床": 2.0, "峭壁": 1.3, "珊瑚礁": 0.8, "沙海床": 0.1 }, light: { "明亮": 1.5, "朦胧": 1.2, "昏暗": 0.6, "无光": 0.1 } } }, /* 紫菜 - 极浅,礁石表面,阳光需求高 */ "nori": { name: /*::GEN::渔获名::nori:: */"紫菜"/*::END:: */, baseWeight: 7, tags: ["浅层", "草食性", "岩海床"], customWeights: { depth: { "0-50": 3.0, "50-150": 0.8, "150-300": 0.1, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "岩海床": 2.2, "珊瑚礁": 1.0, "沙海床": 0.1, "开阔水域": 0.0 }, light: { "明亮": 2.0, "朦胧": 1.2, "昏暗": 0.3, "无光": 0.0 } } }, /* 石花菜 - 珊瑚礁浅层,阳光充足 */ "agarcoral": { name: /*::GEN::渔获名::agarcoral:: */"石花菜"/*::END:: */, baseWeight: 5, tags: ["浅层", "草食性", "珊瑚礁", "岩海床"], customWeights: { depth: { "0-50": 2.5, "50-150": 1.2, "150-300": 0.2, "300-1000": 0.0, "1000+": 0.0 }, terrain: { "珊瑚礁": 2.5, "岩海床": 1.8, "沙海床": 0.1 }, light: { "明亮": 2.2, "朦胧": 1.0, "昏暗": 0.2, "无光": 0.0 } } } }>> <<set $fishingTime = 90>> <<set $fishingBait = "无">> <<set $fishingGear = "垂钓">> <<set $fishingLight = "关闭">> <<set $fishingPass = 0>>
<<set $items = { /* ══════════════════════════════════════════ 渔获 · 鱼类 ══════════════════════════════════════════ */ salmon: { size: 2, name: /*::GEN::物品名::salmon:: */"鲑鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 8, desc: /*::GEN::物品描述::salmon:: */"洄游性鱼类,身披银红斑纹。肉质丰腴,是上好的食材,骨骼中隐约含有某种微弱的元素响应。"/*::END:: */ }, seabass: { size: 2, name: /*::GEN::物品名::seabass:: */"鲈鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 9, desc: /*::GEN::物品描述::seabass:: */"常见的浅海鱼种,警觉性高。鱼鳃膜极薄,炼金师将其用于过滤微量元素。"/*::END:: */ }, tuna: { size: 3, name: /*::GEN::物品名::tuna:: */"金枪鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 3, desc: /*::GEN::物品描述::tuna:: */"体型巨大的掠食者,终生不停游动。深红色的肌肉中储存着大量血液,是血液系炼金原料的来源之一。"/*::END:: */ }, sardine: { size: 1, name: /*::GEN::物品名::sardine:: */"沙丁鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 12, desc: /*::GEN::物品描述::sardine:: */"成群结队的小型鱼类,在夜间会被灯光大量吸引。数量庞大,是大型掠食者的主要食物来源。"/*::END:: */ }, herring: { size: 1, name: /*::GEN::物品名::herring:: */"鲱鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 11, desc: /*::GEN::物品描述::herring:: */"银白色鱼群在浅海中形成壮观的队列。繁殖期会产大量鱼卵,可供食用或炼金提取。"/*::END:: */ }, grouper: { size: 2, name: /*::GEN::物品名::grouper:: */"石斑鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 6, desc: /*::GEN::物品描述::grouper:: */"礁岩地带的伏击者,色彩斑斓。鳃膜构造特殊,能在高压环境下正常呼吸。"/*::END:: */ }, mahi: { size: 2, name: /*::GEN::物品名::mahi:: */"鲯鳅"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 5, desc: /*::GEN::物品描述::mahi:: */"开阔水域的速游者,拥有艳丽的黄绿色泽。鳍膜宽大,晒干后可作为轻质炼金材料。"/*::END:: */ }, cod: { size: 2, name: /*::GEN::物品名::cod:: */"鳕鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 8, desc: /*::GEN::物品描述::cod:: */"冷水域常见食用鱼,鱼肝富含油脂。大航海时代各国船队的主要蛋白质来源,盐腌后可长期保存。"/*::END:: */ }, eel: { size: 2, name: /*::GEN::物品名::eel:: */"鳗鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 6, desc: /*::GEN::物品描述::eel:: */"修长光滑的深海过客,胆囊分泌的胆汁气味异常刺鼻。有报告指出在神域边缘附近捕获的鳗鱼体内出现不明结晶。"/*::END:: */ }, flounder: { size: 2, name: /*::GEN::物品名::flounder:: */"比目鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 7, desc: /*::GEN::物品描述::flounder:: */"扁平的底栖鱼类,双眼位于同侧。藏匿于沙层之中,鱼鳞颗粒细密,磨成粉末后带有轻微的土元素响应。"/*::END:: */ }, mackerel: { size: 1, name: /*::GEN::物品名::mackerel:: */"鲭鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 10, desc: /*::GEN::物品描述::mackerel:: */"中层水域的群游鱼类,背部有深色波纹。脂肪含量高,烟熏处理后风味极佳。"/*::END:: */ }, bream: { size: 2, name: /*::GEN::物品名::bream:: */"鲷鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 7, desc: /*::GEN::物品描述::bream:: */"礁岩区常见的中型鱼,因肉质鲜甜在贸易时代曾是贵族餐桌的常客。繁殖期鱼卵品质极高。"/*::END:: */ }, anchovy: { size: 1, name: /*::GEN::物品名::anchovy:: */"凤尾鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 12, desc: /*::GEN::物品描述::anchovy:: */"细小的滤食性鱼类,是整个海洋食物链的基石。个体虽小,大量聚集时形成的生物量不可忽视。"/*::END:: */ }, barracuda: { size: 2, name: /*::GEN::物品名::barracuda:: */"梭子鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 5, desc: /*::GEN::物品描述::barracuda:: */"凶猛的掠食性鱼类,牙齿锋利如刀。血液腥气浓重,胆汁中含有高浓度的火系催化成分。"/*::END:: */ }, hairtail: { size: 1, name: /*::GEN::物品名::hairtail:: */"带鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 8, desc: /*::GEN::物品描述::hairtail:: */"细长如银带,夜间受光源吸引浮出深层。鱼鳞极薄且密,经特殊处理后会产生轻微的灼烧性粉末。"/*::END:: */ }, sunfish: { size: 4, name: /*::GEN::物品名::sunfish:: */"翻车鱼"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 1, rarity: "稀有", desc: /*::GEN::物品描述::sunfish:: */"形态怪异的巨型硬骨鱼,像是海洋开了一个玩笑。体内含有大量海水提炼物,偶有深海目结构存在于其眼部。"/*::END:: */ }, anglerfish: { size: 3, name: /*::GEN::物品名::anglerfish:: */"鮟鱇"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 1, rarity: "稀有", desc: /*::GEN::物品描述::anglerfish:: */"黑暗深处的发光陷阱。额头的发光器官至今机制不明,但炼金师证实其中存在稳定的火系能量残留,胆汁毒性极强。"/*::END:: */ }, /* ══════════════════════════════════════════ 渔获 · 贝类 ══════════════════════════════════════════ */ scallop: { size: 1, name: /*::GEN::物品名::scallop:: */"扇贝"/*::END:: */, type: "渔获", subtype: "贝类", baseWeight: 9, desc: /*::GEN::物品描述::scallop:: */"双壳扇形,依靠喷水游动。闭壳肌肥厚鲜美,外壳磨碎后是常见的土系粉末原料。"/*::END:: */ }, clam: { size: 1, name: /*::GEN::物品名::clam:: */"蛤蜊"/*::END:: */, type: "渔获", subtype: "贝类", baseWeight: 10, desc: /*::GEN::物品描述::clam:: */"沙层中的隐居者,壳纹如年轮记录着岁月。偶有珍珠孕育其中,虽小却圆润光洁。"/*::END:: */ }, oyster: { size: 1, name: /*::GEN::物品名::oyster:: */"牡蛎"/*::END:: */, type: "渔获", subtype: "贝类", baseWeight: 8, desc: /*::GEN::物品描述::oyster:: */"礁石上的滤食者,其肉质被誉为海中之乳。孕育珍珠的概率高于其他贝类,黑珍珠极为罕见。"/*::END:: */ }, mussel: { size: 1, name: /*::GEN::物品名::mussel:: */"贻贝"/*::END:: */, type: "渔获", subtype: "贝类", baseWeight: 10, desc: /*::GEN::物品描述::mussel:: */"用足丝附着礁岩,成片聚生。肉质深色,味道浓郁,壳薄而坚,是常见的建造辅材。"/*::END:: */ }, conch: { size: 1, name: /*::GEN::物品名::conch:: */"海螺"/*::END:: */, type: "渔获", subtype: "贝类", baseWeight: 7, desc: /*::GEN::物品描述::conch:: */"旋涡状外壳内深藏肥美螺肉,磨碎后的螺粉具有较高的水系亲和性。空壳可用作简易信号器。"/*::END:: */ }, seaurchin: { size: 1, name: /*::GEN::物品名::seaurchin:: */"海胆"/*::END:: */, type: "渔获", subtype: "贝类", baseWeight: 7, desc: /*::GEN::物品描述::seaurchin:: */"棘刺密布的球形生物,卵巢(海胆黄)鲜美至极。棘刺核心密度极高,是土系核心材料之一。"/*::END:: */ }, /* ══════════════════════════════════════════ 渔获 · 虾类 ══════════════════════════════════════════ */ prawn: { size: 1, name: /*::GEN::物品名::prawn:: */"对虾"/*::END:: */, type: "渔获", subtype: "虾类", baseWeight: 9, desc: /*::GEN::物品描述::prawn:: */"常见的中型虾类,肉质弹嫩。外壳薄而半透明,整体食用价值高于炼金价值。"/*::END:: */ }, lobster: { size: 2, name: /*::GEN::物品名::lobster:: */"龙虾"/*::END:: */, type: "渔获", subtype: "虾类", baseWeight: 2, rarity: "稀有", desc: /*::GEN::物品描述::lobster:: */"礁岩区的甲壳霸主,夜间独自觅食。坚硬的甲壳富含结构性土元素,蟹甲粉末是常见炼金耗材。"/*::END:: */ }, mantisshrimp: { size: 1, name: /*::GEN::物品名::mantisshrimp:: */"皮皮虾"/*::END:: */, type: "渔获", subtype: "虾类", baseWeight: 7, desc: /*::GEN::物品描述::mantisshrimp:: */"拥有强力打击螯肢,能以极快速度破碎贝壳。捕捉时需谨慎——它们对玻璃制容器有天然的破坏欲。"/*::END:: */ }, sweetshrimp: { size: 1, name: /*::GEN::物品名::sweetshrimp:: */"甜虾"/*::END:: */, type: "渔获", subtype: "虾类", baseWeight: 10, desc: /*::GEN::物品描述::sweetshrimp:: */"小型浅粉色虾类,肉质甘甜细腻。通常成群出现,是浅海渔网的常见收获。"/*::END:: */ }, cherryshrimp: { size: 1, name: /*::GEN::物品名::cherryshrimp:: */"樱虾"/*::END:: */, type: "渔获", subtype: "虾类", baseWeight: 11, desc: /*::GEN::物品描述::cherryshrimp:: */"体色鲜红如樱花,群游时将海面染成一片艳色。体型极小,通常整体烹饪食用。"/*::END:: */ }, /* ══════════════════════════════════════════ 渔获 · 蟹类 ══════════════════════════════════════════ */ kingcrab: { size: 3, name: /*::GEN::物品名::kingcrab:: */"帝王蟹"/*::END:: */, type: "渔获", subtype: "蟹类", baseWeight: 2, rarity: "稀有", desc: /*::GEN::物品描述::kingcrab:: */"体型巨大的深冷水霸主,蟹腿张开可达一米以上。甲壳极度坚硬,偶尔内部会形成类似烬晶的结晶体,成因不明。"/*::END:: */ }, snowcrab: { size: 3, name: /*::GEN::物品名::snowcrab:: */"雪蟹"/*::END:: */, type: "渔获", subtype: "蟹类", baseWeight: 2, rarity: "稀有", desc: /*::GEN::物品描述::snowcrab:: */"峭壁地形的专属居民,洁白的甲壳如覆霜雪。只在极深的悬崖壁面活动,蟹肉鲜甜,甲壳粉末纯净。"/*::END:: */ }, bluecrab: { size: 2, name: /*::GEN::物品名::bluecrab:: */"蓝蟹"/*::END:: */, type: "渔获", subtype: "蟹类", baseWeight: 8, desc: /*::GEN::物品描述::bluecrab:: */"行动敏捷的中型蟹,蓝色螯足颇具辨识度。适应性强,从浅海到中层都有分布。"/*::END:: */ }, swimmingcrab: { size: 2, name: /*::GEN::物品名::swimmingcrab:: */"梭子蟹"/*::END:: */, type: "渔获", subtype: "蟹类", baseWeight: 8, desc: /*::GEN::物品描述::swimmingcrab:: */"善于游泳的蟹类,后足特化为桨状。是最常见的食用蟹种,肉质饱满,蟹黄丰腴。"/*::END:: */ }, flowercrab: { size: 2, name: /*::GEN::物品名::flowercrab:: */"花蟹"/*::END:: */, type: "渔获", subtype: "蟹类", baseWeight: 7, desc: /*::GEN::物品描述::flowercrab:: */"甲壳上有美丽的花纹,多见于珊瑚礁区域。因栖息环境的关系,甲壳中偶有珊瑚碎屑附着。"/*::END:: */ }, redcrab: { size: 2, name: /*::GEN::物品名::redcrab:: */"红蟹"/*::END:: */, type: "渔获", subtype: "蟹类", baseWeight: 5, desc: /*::GEN::物品描述::redcrab:: */"珊瑚礁的鲜艳住客,通体橙红。甲壳颜色来自特殊色素沉积,与珊瑚的矿物成分存在某种关联。"/*::END:: */ }, /* ══════════════════════════════════════════ 渔获 · 头足类 ══════════════════════════════════════════ */ squid: { size: 1, name: /*::GEN::物品名::squid:: */"鱿鱼"/*::END:: */, type: "渔获", subtype: "头足", baseWeight: 9, desc: /*::GEN::物品描述::squid:: */"高速游动的群居捕食者,夜间趋光性强。气囊能精确控制浮力,是风系炼金材料的重要来源。"/*::END:: */ }, cuttlefish: { size: 2, name: /*::GEN::物品名::cuttlefish:: */"墨鱼"/*::END:: */, type: "渔获", subtype: "头足", baseWeight: 8, desc: /*::GEN::物品描述::cuttlefish:: */"伪装大师,能瞬间改变体色。体内的乌贼骨是天然的水系晶体材料,墨汁有特殊的显影功效。"/*::END:: */ }, octopus: { size: 2, name: /*::GEN::物品名::octopus:: */"章鱼"/*::END:: */, type: "渔获", subtype: "头足", baseWeight: 7, desc: /*::GEN::物品描述::octopus:: */"极度智慧的八腕生物,据称能感知到神域的微弱波动。深眼腺体中偶有特殊结晶,成因尚待研究。"/*::END:: */ }, /* ══════════════════════════════════════════ 渔获 · 藻类 ══════════════════════════════════════════ */ kelp: { size: 1, name: /*::GEN::物品名::kelp:: */"海带"/*::END:: */, type: "渔获", subtype: "藻类", baseWeight: 10, foodtags: ["海草"], desc: /*::GEN::物品描述::kelp:: */"随洋流摇曳的宽叶藻类,纤维坚韧。晒干后可食用,提取的海水矿物盐带有水系亲和性。"/*::END:: */ }, wakame: { size: 1, name: /*::GEN::物品名::wakame:: */"裙带菜"/*::END:: */, type: "渔获", subtype: "藻类", baseWeight: 9, foodtags: ["海草"], desc: /*::GEN::物品描述::wakame:: */"叶缘如裙摆般舒展,质地柔滑。是汤品和腌渍食品的上等食材,纤维品质不亚于海带。"/*::END:: */ }, nori: { size: 1, name: /*::GEN::物品名::nori:: */"紫菜"/*::END:: */, type: "渔获", subtype: "藻类", baseWeight: 10, foodtags: ["海草"], desc: /*::GEN::物品描述::nori:: */"薄如蝉翼的暗紫色藻类,富含矿物质。晒干后体积大幅缩小,草丝状纤维可用于炼金。"/*::END:: */ }, agarcoral: { size: 1, name: /*::GEN::物品名::agarcoral:: */"石花菜"/*::END:: */, type: "渔获", subtype: "藻类", baseWeight: 5, foodtags: ["海草"], desc: /*::GEN::物品描述::agarcoral:: */"生长于珊瑚礁和岩面的红藻,结构坚硬。加热后释放胶质,是制作凝冻食品和炼金凝固剂的原料。"/*::END:: */ }, /* ══════════════════════════════════════════ 渔获 · 占位(事件可获取,不出现在主列表) ══════════════════════════════════════════ */ seahorse: { size: 1, name: /*::GEN::物品名::seahorse:: */"海马"/*::END:: */, type: "渔获", subtype: "鱼类", baseWeight: 1, rarity: "稀有", desc: /*::GEN::物品描述::seahorse:: */"微小的甲胄骑士,由雄性孵育后代。骨骼与普通鱼类截然不同,其流涌石亲和性已被多名炼金师证实。"/*::END:: */ }, starfish: { size: 1, name: /*::GEN::物品名::starfish:: */"海星"/*::END:: */, type: "渔获", subtype: "其他", baseWeight: 6, desc: /*::GEN::物品描述::starfish:: */"五辐对称的底栖生物,具有惊人的再生能力。骨骼碎烧后的骨灰纯度较高,偶有流涌石亲和性。"/*::END:: */ }, jellyfish: { size: 1, name: /*::GEN::物品名::jellyfish:: */"水母"/*::END:: */, type: "渔获", subtype: "其他", baseWeight: 8, desc: /*::GEN::物品描述::jellyfish:: */"漂浮于中层水域的半透明幽灵。体液富含水系元素,膜体经提炼可得到纯净的水系膜质材料。"/*::END:: */ }, /* ══════════════════════════════════════════ 食材 foodtags 用于烹饪系统匹配食谱 ══════════════════════════════════════════ */ /* ── 通用鱼肉 ── */ fish_meat: { size: 1, name: /*::GEN::物品名::fish_meat:: */"鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::fish_meat:: */"处理干净的鱼肉块,肉质紧实,适合多种烹饪方式。"/*::END:: */ }, fish_roe: { size: 1, name: /*::GEN::物品名::fish_roe:: */"鱼卵"/*::END:: */, type: "食材", foodtags: ["鱼", "腥"], desc: /*::GEN::物品描述::fish_roe:: */"新鲜的鱼卵,腥气浓重但营养丰富,盐腌后风味大变。"/*::END:: */ }, /* ── 各鱼专属肉 ── */ salmon_meat: { size: 1, name: /*::GEN::物品名::salmon_meat:: */"鲑鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::salmon_meat:: */"鲑鱼剔除的大块嫩肉,带着天然粉红色,油脂丰富,适合任何烹饪方式。"/*::END:: */ }, seabass_meat: { size: 1, name: /*::GEN::物品名::seabass_meat:: */"鲈鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::seabass_meat:: */"鲈鱼洁白细腻的肌肉,几乎无刺,是海鱼中食用价值最高的种类之一。"/*::END:: */ }, tuna_meat: { size: 1, name: /*::GEN::物品名::tuna_meat:: */"金枪鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::tuna_meat:: */"深红色大块肌肉,含大量血铁质,生食最能体现其价值。"/*::END:: */ }, sardine_meat: { size: 1, name: /*::GEN::物品名::sardine_meat:: */"沙丁鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::sardine_meat:: */"细碎的沙丁鱼肉,脂肪丰富,盐腌后风味转化为浓郁鲜香。"/*::END:: */ }, herring_meat: { size: 1, name: /*::GEN::物品名::herring_meat:: */"鲱鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::herring_meat:: */"鲱鱼银白色肌肉,油脂均匀,最适合腌制和烟熏处理。"/*::END:: */ }, grouper_meat: { size: 1, name: /*::GEN::物品名::grouper_meat:: */"石斑肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::grouper_meat:: */"石斑鱼厚实的白色肌肉,质感弹滑,是底层鱼中品质最高的食材。"/*::END:: */ }, mahi_meat: { size: 1, name: /*::GEN::物品名::mahi_meat:: */"鲯鳅肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::mahi_meat:: */"粉白色鱼肉,肉质较硬但风味独特,烤制时散发天然甜香。"/*::END:: */ }, cod_meat: { size: 1, name: /*::GEN::物品名::cod_meat:: */"鳕鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::cod_meat:: */"雪白厚实的鳕鱼肉,片状剥落,淡而鲜美,是船上最可靠的蛋白质来源。"/*::END:: */ }, eel_meat: { size: 1, name: /*::GEN::物品名::eel_meat:: */"鳗鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::eel_meat:: */"鳗鱼紧致细长的肌肉,脂肪均匀分布,烤制时渗出大量油脂。"/*::END:: */ }, flounder_meat: { size: 1, name: /*::GEN::物品名::flounder_meat:: */"比目鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::flounder_meat:: */"两侧对称的白色薄片鱼肉,肉质极嫩,生食或清蒸最能保留清甜。"/*::END:: */ }, mackerel_meat: { size: 1, name: /*::GEN::物品名::mackerel_meat:: */"鲭鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::mackerel_meat:: */"富含脂肪的深色鱼肉,腥气较重,腌制或烟熏后风味大变。"/*::END:: */ }, bream_meat: { size: 1, name: /*::GEN::物品名::bream_meat:: */"鲷鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::bream_meat:: */"鲷鱼细腻甘甜的白肉,是所有海鱼中最接近贵族料理的食材。"/*::END:: */ }, anchovy_meat: { size: 1, name: /*::GEN::物品名::anchovy_meat:: */"凤尾鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::anchovy_meat:: */"细小的凤尾鱼肉,腥而鲜,大量处理后可制成浓郁的鱼酱。"/*::END:: */ }, barracuda_meat: { size: 1, name: /*::GEN::物品名::barracuda_meat:: */"梭子鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::barracuda_meat:: */"梭子鱼结实的淡红鱼肉,处理干净后滋味浓郁。"/*::END:: */ }, hairtail_meat: { size: 1, name: /*::GEN::物品名::hairtail_meat:: */"带鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::hairtail_meat:: */"带鱼细长的白色肌肉,刺多但味道鲜甜,煎制时形成酥脆表层。"/*::END:: */ }, sunfish_meat: { size: 1, name: /*::GEN::物品名::sunfish_meat:: */"翻车鱼肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::sunfish_meat:: */"翻车鱼奇特的白色鱼肉,质地介于普通鱼肉和胶质之间,味道温和。"/*::END:: */ }, anglerfish_meat: { size: 1, name: /*::GEN::物品名::anglerfish_meat:: */"鮟鱇肉"/*::END:: */, type: "食材", foodtags: ["鱼"], desc: /*::GEN::物品描述::anglerfish_meat:: */"鮟鱇丰腴的深海鱼肉,胶质丰富,炖煮后化为浓郁鲜甜。"/*::END:: */ }, /* ── 贝类食材 ── */ urchin_roe: { size: 1, name: /*::GEN::物品名::urchin_roe:: */"海胆黄"/*::END:: */, type: "食材", foodtags: ["贝", "鲜"], desc: /*::GEN::物品描述::urchin_roe:: */"海胆的生殖腺,鲜黄色,入口即化。鲜度极为重要,需尽快食用。"/*::END:: */ }, scallop_meat: { size: 1, name: /*::GEN::物品名::scallop_meat:: */"扇贝肉"/*::END:: */, type: "食材", foodtags: ["贝"], desc: /*::GEN::物品描述::scallop_meat:: */"扇贝丰腴的闭壳肌,圆润洁白,口感弹嫩,鲜甜几乎不需要调味。"/*::END:: */ }, clam_meat: { size: 1, name: /*::GEN::物品名::clam_meat:: */"蛤蜊肉"/*::END:: */, type: "食材", foodtags: ["贝"], desc: /*::GEN::物品描述::clam_meat:: */"蛤蜊的软体,带着浓郁的海水咸鲜,是汤底提鲜的绝佳材料。"/*::END:: */ }, oyster_meat: { size: 1, name: /*::GEN::物品名::oyster_meat:: */"牡蛎肉"/*::END:: */, type: "食材", foodtags: ["贝", "鲜"], desc: /*::GEN::物品描述::oyster_meat:: */"牡蛎饱满的软体,被称为海中之乳。入口即化,带着浓烈的矿物鲜味。"/*::END:: */ }, mussel_meat: { size: 1, name: /*::GEN::物品名::mussel_meat:: */"贻贝肉"/*::END:: */, type: "食材", foodtags: ["贝"], desc: /*::GEN::物品描述::mussel_meat:: */"贻贝深色的肉质,鲜味浓郁,价格低廉但滋味不逊于高档贝类。"/*::END:: */ }, conch_meat: { size: 1, name: /*::GEN::物品名::conch_meat:: */"海螺肉"/*::END:: */, type: "食材", foodtags: ["贝"], desc: /*::GEN::物品描述::conch_meat:: */"海螺肥美的螺肉,质地偏硬但口感弹脆,炒制时需要大火快炒。"/*::END:: */ }, /* ── 虾类食材 ── */ prawn_meat: { size: 1, name: /*::GEN::物品名::prawn_meat:: */"对虾肉"/*::END:: */, type: "食材", foodtags: ["虾"], desc: /*::GEN::物品描述::prawn_meat:: */"对虾弹脆的白色虾肉,去壳后比例最高,是最实用的虾类食材。"/*::END:: */ }, lobster_meat: { size: 1, name: /*::GEN::物品名::lobster_meat:: */"龙虾肉"/*::END:: */, type: "食材", foodtags: ["虾"], desc: /*::GEN::物品描述::lobster_meat:: */"龙虾尾部与大钳中肥美的白肉,质地厚实,是虾类中最奢华的食材。"/*::END:: */ }, mantisshrimp_meat: { size: 1, name: /*::GEN::物品名::mantisshrimp_meat:: */"皮皮虾肉"/*::END:: */, type: "食材", foodtags: ["虾"], desc: /*::GEN::物品描述::mantisshrimp_meat:: */"皮皮虾甲壳下细密的白肉,鲜甜多汁,剥取费力但值得。"/*::END:: */ }, sweetshrimp_meat: { size: 1, name: /*::GEN::物品名::sweetshrimp_meat:: */"甜虾肉"/*::END:: */, type: "食材", foodtags: ["虾"], desc: "【占位】" }, cherryshrimp_meat: { size: 1, name: /*::GEN::物品名::cherryshrimp_meat:: */"樱虾肉"/*::END:: */, type: "食材", foodtags: ["虾"], desc: "【占位】" }, /* ── 蟹类食材 ── */ kingcrab_meat: { size: 1, name: /*::GEN::物品名::kingcrab_meat:: */"帝王蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: /*::GEN::物品描述::kingcrab_meat:: */"帝王蟹腿中厚实的白色蟹肉,纤维分明,是所有蟹类中品质最高的食材。"/*::END:: */ }, snowcrab_meat: { size: 1, name: /*::GEN::物品名::snowcrab_meat:: */"雪蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: /*::GEN::物品描述::snowcrab_meat:: */"雪蟹纤细的腿肉,洁白细嫩,汁水丰富,蟹黄金黄浓郁。"/*::END:: */ }, swimmingcrab_meat:{ size: 1, name: /*::GEN::物品名::swimmingcrab_meat:: */"梭子蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: /*::GEN::物品描述::swimmingcrab_meat:: */"梭子蟹扁平体内的白色蟹肉,鲜甜程度不输大型蟹类。"/*::END:: */ }, bluecrab_meat: { size: 1, name: /*::GEN::物品名::bluecrab_meat:: */"蓝蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: "【占位】" }, flowercrab_meat: { size: 1, name: /*::GEN::物品名::flowercrab_meat:: */"花蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: "【占位】" }, redcrab_meat: { size: 1, name: /*::GEN::物品名::redcrab_meat:: */"红蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: "【占位】" }, /* ── 头足类食材 ── */ octopus_meat: { size: 1, name: /*::GEN::物品名::octopus_meat:: */"八爪鱼肉"/*::END:: */, type: "食材", foodtags: ["腕足"], desc: /*::GEN::物品描述::octopus_meat:: */"章鱼或鱿鱼的腕足,含有特殊氨基酸,口感Q弹。烹饪时间不足会韧如皮革。"/*::END:: */ }, squid_meat: { size: 1, name: /*::GEN::物品名::squid_meat:: */"鱿鱼肉"/*::END:: */, type: "食材", foodtags: ["腕足"], desc: /*::GEN::物品描述::squid_meat:: */"鱿鱼筒状的外套膜肌肉,质地介于嫩滑和Q弹之间,高温快炒风味最佳。"/*::END:: */ }, cuttlefish_meat: { size: 1, name: /*::GEN::物品名::cuttlefish_meat:: */"墨鱼肉"/*::END:: */, type: "食材", foodtags: ["腕足"], desc: /*::GEN::物品描述::cuttlefish_meat:: */"墨鱼肥厚的外套膜,含有特殊的墨囊香气,炖煮时会将汤汁染成深色。"/*::END:: */ }, /* ── 兽肉 ── */ pork: { size: 1, name: /*::GEN::物品名::pork:: */"猪肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, lamb: { size: 1, name: /*::GEN::物品名::lamb:: */"羊肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, beef: { size: 1, name: /*::GEN::物品名::beef:: */"牛肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, turtle_meat: { size: 1, name: /*::GEN::物品名::turtle_meat:: */"海龟肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, manatee_meat: { size: 1, name: /*::GEN::物品名::manatee_meat:: */"海牛肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, whale_meat: { size: 1, name: /*::GEN::物品名::whale_meat:: */"鲸鱼肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, seal_meat: { size: 1, name: /*::GEN::物品名::seal_meat:: */"海豹肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, chicken_meat: { size: 1, name: /*::GEN::物品名::chicken_meat:: */"鸡肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, pigeon_meat: { size: 1, name: /*::GEN::物品名::pigeon_meat:: */"鸽肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, rabbit_meat: { size: 1, name: /*::GEN::物品名::rabbit_meat:: */"兔肉"/*::END:: */, type: "食材", foodtags: ["兽肉"], desc: "【占位】" }, /* ── 块茎 ── */ potato_tuber: { size: 1, name: /*::GEN::物品名::potato_tuber:: */"海薯"/*::END:: */, type: "食材", foodtags: ["块茎"], desc: "【占位】适应咸水环境的改良薯类,淀粉含量高,蒸煮后绵密。" }, kelp_tuber: { size: 1, name: /*::GEN::物品名::kelp_tuber:: */"海带茎"/*::END:: */, type: "食材", foodtags: ["块茎"], desc: "【占位】海带茎部的硬质组织,口感脆爽,含有丰富的矿物质。" }, potato: { size: 1, name: /*::GEN::物品名::potato:: */"土豆"/*::END:: */, type: "食材", foodtags: ["块茎"], desc: "【占位】" }, sweet_potato: { size: 1, name: /*::GEN::物品名::sweet_potato:: */"红薯"/*::END:: */, type: "食材", foodtags: ["块茎"], desc: "【占位】" }, carrot: { size: 1, name: /*::GEN::物品名::carrot:: */"胡萝卜"/*::END:: */, type: "食材", foodtags: ["块茎"], desc: "【占位】" }, taro: { size: 1, name: /*::GEN::物品名::taro:: */"芋头"/*::END:: */, type: "食材", foodtags: ["块茎"], desc: "【占位】" }, /* ── 谷物 ── */ wheat_grain: { size: 1, name: /*::GEN::物品名::wheat_grain:: */"麦子"/*::END:: */, type: "食材", foodtags: ["谷物"], desc: "【占位】干燥的小麦粒,磨粉后是制作面食的基础原料。" }, rice: { size: 1, name: /*::GEN::物品名::rice:: */"稻米"/*::END:: */, type: "食材", foodtags: ["谷物"], desc: "【占位】" }, corn: { size: 1, name: /*::GEN::物品名::corn:: */"玉米"/*::END:: */, type: "食材", foodtags: ["谷物"], desc: "【占位】" }, oats: { size: 1, name: /*::GEN::物品名::oats:: */"燕麦"/*::END:: */, type: "食材", foodtags: ["谷物"], desc: "【占位】" }, /* ── 蔬菜 ── */ tomato: { size: 1, name: /*::GEN::物品名::tomato:: */"番茄"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】" }, cabbage: { size: 1, name: /*::GEN::物品名::cabbage:: */"卷心菜"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】" }, pea: { size: 1, name: /*::GEN::物品名::pea:: */"豌豆"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】" }, mushroom: { size: 1, name: /*::GEN::物品名::mushroom:: */"蘑菇"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】" }, eggplant: { size: 1, name: /*::GEN::物品名::eggplant:: */"茄子"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】" }, spinach: { size: 1, name: /*::GEN::物品名::spinach:: */"菠菜"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】" }, /* ── 占位食材(事件可获取) ── */ seaweed_grain: { size: 1, name: /*::GEN::物品名::seaweed_grain:: */"海草籽"/*::END:: */, type: "食材", foodtags: ["谷物"], desc: "【占位】某种耐盐海草的种子,营养密度高,可磨成粗糙的粉末。" }, seajelly: { size: 1, name: /*::GEN::物品名::seajelly:: */"水母冻"/*::END:: */, type: "食材", foodtags: ["海草", "滑"], desc: /*::GEN::物品描述::seajelly:: */"经过处理去除毒素的水母凝冻,口感滑嫩,几乎无味,需要搭配调料才能出彩。"/*::END:: */ }, sealeaf: { size: 1, name: /*::GEN::物品名::sealeaf:: */"海叶菜"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】在农场水培槽中生长的叶菜,稍有咸味,口感清脆。" }, sprout: { size: 1, name: /*::GEN::物品名::sprout:: */"芽苗"/*::END:: */, type: "食材", foodtags: ["蔬菜"], desc: "【占位】各种植物的嫩芽,生长迅速,是船上最容易获得的绿色食物。" }, sea_berry: { size: 1, name: /*::GEN::物品名::sea_berry:: */"盐渍浆果"/*::END:: */, type: "食材", foodtags: ["浆果"], desc: "【占位】用海盐轻度腌渍的浆果,酸甜咸味交织,对安定值有独特的正面影响。" }, wild_berry: { size: 1, name: /*::GEN::物品名::wild_berry:: */"野生浆果"/*::END:: */, type: "食材", foodtags: ["浆果"], desc: "【占位】在登陆探索时偶尔能采集到的野生浆果,甜度高,种类不明。" }, shell_meat: { size: 1, name: /*::GEN::物品名::shell_meat:: */"贝肉"/*::END:: */, type: "食材", foodtags: ["贝"], desc: /*::GEN::物品描述::shell_meat:: */"从贝壳中取出的软体组织,鲜甜多汁,生食或轻烹均可。"/*::END:: */ }, shrimp_meat: { size: 1, name: /*::GEN::物品名::shrimp_meat:: */"虾肉"/*::END:: */, type: "食材", foodtags: ["虾"], desc: /*::GEN::物品描述::shrimp_meat:: */"弹嫩的虾体肌肉,去壳后呈半透明白色,加热后变为粉橙色。"/*::END:: */ }, crab_meat: { size: 1, name: /*::GEN::物品名::crab_meat:: */"蟹肉"/*::END:: */, type: "食材", foodtags: ["蟹"], desc: /*::GEN::物品描述::crab_meat:: */"细腻鲜甜的蟹腿与蟹身肌肉,分拆费时但价值颇高。"/*::END:: */ }, dried_kelp: { size: 1, name: /*::GEN::物品名::dried_kelp:: */"干海带"/*::END:: */, type: "食材", foodtags: ["海草"], desc: /*::GEN::物品描述::dried_kelp:: */"晒制或烘干的海带,体积大幅缩小,鲜味浓缩。泡发后可用于多种料理。"/*::END:: */ }, dried_nori: { size: 1, name: /*::GEN::物品名::dried_nori:: */"干紫菜"/*::END:: */, type: "食材", foodtags: ["海草"], desc: /*::GEN::物品描述::dried_nori:: */"压薄后干燥的紫菜片,可直接食用或用于包裹食材。"/*::END:: */ }, salt_refined: { size: 1, name: /*::GEN::物品名::salt_refined:: */"精盐"/*::END:: */, type: "食材", foodtags: ["调料"], desc: /*::GEN::物品描述::salt_refined:: */"经过精制的纯净食盐,是最基本的调味品,缺少它的食物会大幅降低食欲。"/*::END:: */ }, oil: { size: 1, name: /*::GEN::物品名::oil:: */"油脂"/*::END:: */, type: "食材", fuelVal: 40, foodtags: ["调料"], desc: /*::GEN::物品描述::oil:: */"从鱼肝或动物组织中提取的脂肪,用于煎炒时的热媒介质,也能改善口感。"/*::END:: */ }, /* ══════════════════════════════════════════ 菜品 ══════════════════════════════════════════ */ grilled_fish: { size: 1, name: /*::GEN::物品名::grilled_fish:: */"烤鱼"/*::END:: */, type: "菜品", hunger: 30, water: -5, life: 0, power: 5, san: 0, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, fish_soup: { size: 1, name: /*::GEN::物品名::fish_soup:: */"鱼汤"/*::END:: */, type: "菜品", hunger: 20, water: 15, life: 5, power: 0, san: 3, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, steamed_shellfish: { size: 1, name: /*::GEN::物品名::steamed_shellfish:: */"清蒸贝肉"/*::END:: */, type: "菜品", hunger: 25, water: 5, life: 0, power: 0, san: 5, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, seaweed_broth: { size: 1, name: /*::GEN::物品名::seaweed_broth:: */"海草羹"/*::END:: */, type: "菜品", hunger: 15, water: 20, life: 3, power: 0, san: 0, magic: 2, desc: "【占位】", eatDesc: "【占位】" }, raw_urchin: { size: 1, name: /*::GEN::物品名::raw_urchin:: */"生海胆"/*::END:: */, type: "菜品", hunger: 20, water: 0, life: 0, power: 0, san: 8, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, fishstew: { size: 1, name: /*::GEN::物品名::fishstew:: */"杂鱼炖"/*::END:: */, type: "菜品", hunger: 40, water: 10, life: 5, power: 5, san: 2, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, seafood_feast: { size: 1, name: /*::GEN::物品名::seafood_feast:: */"海鲜盛馔"/*::END:: */, type: "菜品", hunger: 60, water: 10, life: 10, power: 20, san: 10, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, medicinal_soup: { size: 1, name: /*::GEN::物品名::medicinal_soup:: */"草药鱼汤"/*::END:: */, type: "菜品", hunger: 25, water: 15, life: 20, power: 0, san: 5, magic: 5, desc: "【占位】", eatDesc: "【占位】" }, vegetable_soup: { size: 1, name: /*::GEN::物品名::vegetable_soup:: */"蔬菜浓汤"/*::END:: */, type: "菜品", hunger: 20, water: 18, life: 5, power: 0, san: 5, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, bread: { size: 1, name: /*::GEN::物品名::bread:: */"杂粮饼"/*::END:: */, type: "菜品", hunger: 35, water: -8, life: 0, power: 8, san: 0, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, fish_berry_grill: { size: 1, name: /*::GEN::物品名::fish_berry_grill:: */"浆果烤鱼"/*::END:: */, type: "菜品", hunger: 32, water: -2, life: 3, power: 6, san: 10, magic: 0, desc: /*::GEN::物品描述::fish_berry_grill:: */"鱼肉的焦香裹着浆果的酸甜,意外地和谐。"/*::END:: */, eatDesc: /*::GEN::食用描述::fish_berry_grill:: */"酸味让鱼腥气消散,两种截然不同的味道在口中融合,留下一种陌生而令人愉悦的感觉。"/*::END:: */ }, salt_fish: { size: 1, name: /*::GEN::物品名::salt_fish:: */"香煎咸鱼"/*::END:: */, type: "菜品", hunger: 28, water: -8, life: 2, power: 5, san: 5, magic: 0, desc: /*::GEN::物品描述::salt_fish:: */"盐粒在鱼皮上结晶,烤出一层硬脆的外壳。"/*::END:: */, eatDesc: /*::GEN::食用描述::salt_fish:: */"咸香直冲味蕾,鱼肉的油脂被盐提了出来,简单却令人满足。"/*::END:: */ }, fishroe_congee: { size: 1, name: /*::GEN::物品名::fishroe_congee:: */"鱼子粥"/*::END:: */, type: "菜品", hunger: 25, water: 18, life: 4, power: 3, san: 6, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, seafood_congee: { size: 1, name: /*::GEN::物品名::seafood_congee:: */"海鲜粥"/*::END:: */, type: "菜品", hunger: 30, water: 20, life: 5, power: 3, san: 7, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, kelp_octo: { size: 1, name: /*::GEN::物品名::kelp_octo:: */"章鱼海草煮"/*::END:: */, type: "菜品", hunger: 26, water: 15, life: 3, power: 4, san: 5, magic: 3, desc: "【占位】", eatDesc: "【占位】" }, crab_salt: { size: 1, name: /*::GEN::物品名::crab_salt:: */"盐焗蟹"/*::END:: */, type: "菜品", hunger: 35, water: -6, life: 3, power: 8, san: 9, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, shrimp_congee: { size: 1, name: /*::GEN::物品名::shrimp_congee:: */"虾仁粥"/*::END:: */, type: "菜品", hunger: 28, water: 18, life: 4, power: 3, san: 7, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, raw_sashimi: { size: 1, name: /*::GEN::物品名::raw_sashimi:: */"刺身"/*::END:: */, type: "菜品", hunger: 22, water: 0, life: 0, power: 2, san: 12, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, seafood_hotpot: { size: 1, name: /*::GEN::物品名::seafood_hotpot:: */"海鲜锅"/*::END:: */, type: "菜品", hunger: 40, water: 12, life: 5, power: 6, san: 8, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, braised_tentacle: { size: 1, name: /*::GEN::物品名::braised_tentacle:: */"炖腕足"/*::END:: */, type: "菜品", hunger: 30, water: 10, life: 2, power: 5, san: 4, magic: 2, desc: "【占位】", eatDesc: "【占位】" }, steamed_crab: { size: 1, name: /*::GEN::物品名::steamed_crab:: */"清蒸蟹"/*::END:: */, type: "菜品", hunger: 32, water: 5, life: 3, power: 5, san: 9, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, fish_congee: { size: 1, name: /*::GEN::物品名::fish_congee:: */"鱼粥"/*::END:: */, type: "菜品", hunger: 22, water: 20, life: 3, power: 2, san: 5, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, /* 失败保底 */ char_mess: { size: 1, name: /*::GEN::物品名::char_mess:: */"什锦烤"/*::END:: */, type: "菜品", hunger: 8, water: -3, life: -2, power: 0, san: -5, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, watery_stew: { size: 1, name: /*::GEN::物品名::watery_stew:: */"乱炖"/*::END:: */, type: "菜品", hunger: 10, water: 5, life: 0, power: 0, san: -4, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, steamed_blob: { size: 1, name: /*::GEN::物品名::steamed_blob:: */"拼蒸"/*::END:: */, type: "菜品", hunger: 8, water: 3, life: 0, power: 0, san: -3, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, raw_pile: { size: 1, name: /*::GEN::物品名::raw_pile:: */"刺身拼盘"/*::END:: */, type: "菜品", hunger: 5, water: 0, life: 0, power: 0, san: -6, magic: 0, desc: "【占位】", eatDesc: "【占位】" }, /* ══════════════════════════════════════════ 基础材料 ══════════════════════════════════════════ */ metal: { size: 2, name: /*::GEN::物品名::metal:: */"金属材料"/*::END:: */, type: "基础材料", desc: /*::GEN::物品描述::metal:: */"从残骸或沉积物中回收的金属碎块,边缘锈蚀,但本体依然坚固。"/*::END:: */ }, wood: { size: 3, name: /*::GEN::物品名::wood:: */"木材"/*::END:: */, type: "基础材料", fuelVal: 8, desc: /*::GEN::物品描述::wood:: */"被海水浸泡许久的木材,密度大幅降低,适合作为浮力材料或燃料。"/*::END:: */ }, gears: { size: 2, name: /*::GEN::物品名::gears:: */"零件"/*::END:: */, type: "基础材料", desc: "【占位】" }, glass: { size: 1, name: /*::GEN::物品名::glass:: */"玻璃"/*::END:: */, type: "基础材料", desc: /*::GEN::物品描述::glass:: */"破碎的透明玻璃,边缘锋利。来历不明,也许曾是某艘船的舷窗。"/*::END:: */ }, rubber: { size: 1, name: /*::GEN::物品名::rubber:: */"橡胶"/*::END:: */, type: "基础材料", desc: "【占位】" }, clothes: { size: 1, name: /*::GEN::物品名::clothes:: */"织物"/*::END:: */, type: "基础材料", desc: "【占位】" }, /* ── 燃料 ── */ coal: { size: 2, name: /*::GEN::物品名::coal:: */"煤块"/*::END:: */, type: "基础材料", subtype: "燃料", fuelVal: 15, desc: /*::GEN::物品描述::coal:: */"压缩有机物形成的固态燃料,热值稳定。是火炉和提炼装置的常用燃料。"/*::END:: */ }, fish_oil: { size: 1, name: /*::GEN::物品名::fish_oil:: */"鱼油"/*::END:: */, type: "基础材料", subtype: "燃料", fuelVal: 12, desc: /*::GEN::物品描述::fish_oil:: */"从鱼肝和深海鱼类内脏中提炼的油脂,热值尚可,是在燃料匮乏时的实用替代品。"/*::END:: */ }, algae_block: { size: 2, name: /*::GEN::物品名::algae_block:: */"海藻压缩块"/*::END:: */, type: "基础材料", subtype: "燃料", fuelVal: 5, desc: /*::GEN::物品描述::algae_block:: */"将大量海藻压制成的固态块,热值偏低但来源充足,适合作应急燃料。"/*::END:: */ }, mineral_fuel: { size: 1, name: /*::GEN::物品名::mineral_fuel:: */"矿物精炼燃料"/*::END:: */, type: "稀有资源", subtype: "燃料", fuelVal: 80, desc: /*::GEN::物品描述::mineral_fuel:: */"从热泉矿物中提炼的高能燃料,热值极高。深海长途航行的理想能源,但极其稀有。"/*::END:: */ }, /* ── 生物副产品 ── */ fish_bone: { size: 1, name: /*::GEN::物品名::fish_bone:: */"骨骼"/*::END:: */, type: "基础材料", subtype: "生物副产品", desc: /*::GEN::物品描述::fish_bone:: */"从鱼类骸骨中取出的骨段,钙质密集,可用于多种加工。"/*::END:: */ }, fish_organ: { size: 1, name: /*::GEN::物品名::fish_organ:: */"内脏"/*::END:: */, type: "基础材料", subtype: "生物副产品", desc: "【占位】" }, fish_scale: { size: 1, name: /*::GEN::物品名::fish_scale:: */"鳞甲"/*::END:: */, type: "基础材料", subtype: "生物副产品", desc: /*::GEN::物品描述::fish_scale:: */"从鱼体或甲壳类生物剥离的鳞片,排列有序,具有一定的防护性。"/*::END:: */ }, /* ── 其他占位 ── */ salt: { size: 1, name: /*::GEN::物品名::salt:: */"粗盐"/*::END:: */, type: "基础材料", desc: /*::GEN::物品描述::salt:: */"从海水蒸发后析出的粗颗粒盐,含有多种微量矿物。精制后可用于烹饪。"/*::END:: */ }, pearl: { size: 1, name: /*::GEN::物品名::pearl:: */"珍珠"/*::END:: */, type: "基础材料", rarity: "稀有", desc: /*::GEN::物品描述::pearl:: */"由贝类分泌物层层包裹异物而成,光泽温润。磨碎后是优质的水系晶体炼金材料。"/*::END:: */ }, /* ══════════════════════════════════════════ 炼金材料 · 特殊粗制(24种) ══════════════════════════════════════════ */ jellyfish_tissue: { size: 1, name: /*::GEN::物品名::jellyfish_tissue:: */"瑰丽水母组织"/*::END:: */, type: "炼金材料", tier: "粗制", element: "火", form: "固", desc: "【占位】" }, candle_jelly_core: { size: 1, name: /*::GEN::物品名::candle_jelly_core:: */"烛光水母核心"/*::END:: */, type: "炼金材料", tier: "粗制", element: "风", form: "固", desc: "【占位】" }, whale_relic_bone: { size: 1, name: /*::GEN::物品名::whale_relic_bone:: */"鲸鱼遗骨"/*::END:: */, type: "炼金材料", tier: "粗制", element: "水", form: "固", desc: "【占位】" }, parasite: { size: 1, name: /*::GEN::物品名::parasite:: */"寄生虫"/*::END:: */, type: "炼金材料", tier: "粗制", element: "土", form: "固", desc: "【占位】" }, mermaid_bone: { size: 1, name: /*::GEN::物品名::mermaid_bone:: */"人鱼遗骨"/*::END:: */, type: "炼金材料", tier: "粗制", element: "风", form: "固", desc: "【占位】" }, mermaid_blood: { size: 1, name: /*::GEN::物品名::mermaid_blood:: */"人鱼血液"/*::END:: */, type: "炼金材料", tier: "粗制", element: "风", form: "液", desc: "【占位】" }, vitality: { size: 1, name: /*::GEN::物品名::vitality:: */"生息"/*::END:: */, type: "炼金材料", tier: "粗制", element: "水", form: "离子", desc: "【占位】" }, phosphor_flame: { size: 1, name: /*::GEN::物品名::phosphor_flame:: */"磷火"/*::END:: */, type: "炼金材料", tier: "粗制", element: "风", form: "离子", desc: "【占位】" }, ambergris: { size: 1, name: /*::GEN::物品名::ambergris:: */"龙涎香"/*::END:: */, type: "炼金材料", tier: "粗制", element: "土", form: "固", desc: "【占位】" }, storm_flesh: { size: 1, name: /*::GEN::物品名::storm_flesh:: */"风暴血肉"/*::END:: */, type: "炼金材料", tier: "粗制", element: "火", form: "固", desc: "【占位】" }, glow_moss_juice: { size: 1, name: /*::GEN::物品名::glow_moss_juice:: */"发光苔藓汁液"/*::END:: */, type: "炼金材料", tier: "粗制", element: "水", form: "液", desc: "【占位】" }, salt_lake_crystal: { size: 1, name: /*::GEN::物品名::salt_lake_crystal:: */"盐湖结晶"/*::END:: */, type: "炼金材料", tier: "粗制", element: "土", form: "离子", desc: "【占位】" }, soul_sea_slime: { size: 1, name: /*::GEN::物品名::soul_sea_slime:: */"灵魂海黏液"/*::END:: */, type: "炼金材料", tier: "粗制", element: "水", form: "离子", desc: "【占位】" }, soul_sea_bone: { size: 1, name: /*::GEN::物品名::soul_sea_bone:: */"灵魂海骨骼"/*::END:: */, type: "炼金材料", tier: "粗制", element: "土", form: "固", desc: "【占位】" }, thaumas_blood: { size: 1, name: /*::GEN::物品名::thaumas_blood:: */"陶玛斯血液"/*::END:: */, type: "炼金材料", tier: "粗制", element: "土", form: "液", rarity: "稀有", desc: "【占位】" }, vent_glow_fluid: { size: 1, name: /*::GEN::物品名::vent_glow_fluid:: */"热泉发光液"/*::END:: */, type: "炼金材料", tier: "粗制", element: "火", form: "液", desc: "【占位】" }, tubeworm_fluid: { size: 1, name: /*::GEN::物品名::tubeworm_fluid:: */"管虫分泌物"/*::END:: */, type: "炼金材料", tier: "粗制", element: "火", form: "液", desc: "【占位】" }, glow_coral: { size: 1, name: /*::GEN::物品名::glow_coral:: */"发光的珊瑚"/*::END:: */, type: "炼金材料", tier: "粗制", element: "水", form: "固", desc: "【占位】" }, giant_ray_sac: { size: 1, name: /*::GEN::物品名::giant_ray_sac:: */"巨鳐气囊"/*::END:: */, type: "炼金材料", tier: "粗制", element: "风", form: "气", desc: "【占位】" }, inscription_frag: { size: 1, name: /*::GEN::物品名::inscription_frag:: */"铭文碎片"/*::END:: */, type: "炼金材料", tier: "粗制", element: "水", form: "气", desc: "【占位】" }, surface_light: { size: 1, name: /*::GEN::物品名::surface_light:: */"水面浮光"/*::END:: */, type: "炼金材料", tier: "粗制", element: "风", form: "气", desc: "【占位】" }, god_bone_raw: { size: 1, name: /*::GEN::物品名::god_bone_raw:: */"神骨"/*::END:: */, type: "炼金材料", tier: "粗制", element: "火", form: "气", rarity: "稀有", desc: "【占位】" }, ceto_breath: { size: 1, name: /*::GEN::物品名::ceto_breath:: */"刻托气息"/*::END:: */, type: "炼金材料", tier: "粗制", element: "土", form: "气", rarity: "稀有", desc: "【占位】" }, jade_feather: { size: 1, name: /*::GEN::物品名::jade_feather:: */"翡翠羽毛"/*::END:: */, type: "炼金材料", tier: "粗制", element: "火", form: "离子", desc: "【占位】" }, /* ══════════════════════════════════════════ 炼金材料 · 精炼(16种,4元素×4形态) ══════════════════════════════════════════ */ ref_water_solid: { size: 1, name: /*::GEN::物品名::ref_water_solid:: */"水·固"/*::END:: */, type: "炼金材料", tier: "精炼", element: "水", form: "固", desc: "【占位】" }, ref_water_liquid: { size: 1, name: /*::GEN::物品名::ref_water_liquid:: */"水·液"/*::END:: */, type: "炼金材料", tier: "精炼", element: "水", form: "液", desc: "【占位】" }, ref_water_gas: { size: 1, name: /*::GEN::物品名::ref_water_gas:: */"水·气"/*::END:: */, type: "炼金材料", tier: "精炼", element: "水", form: "气", desc: "【占位】" }, ref_water_ion: { size: 1, name: /*::GEN::物品名::ref_water_ion:: */"水·离"/*::END:: */, type: "炼金材料", tier: "精炼", element: "水", form: "离子", desc: "【占位】" }, ref_fire_solid: { size: 1, name: /*::GEN::物品名::ref_fire_solid:: */"火·固"/*::END:: */, type: "炼金材料", tier: "精炼", element: "火", form: "固", desc: "【占位】" }, ref_fire_liquid: { size: 1, name: /*::GEN::物品名::ref_fire_liquid:: */"火·液"/*::END:: */, type: "炼金材料", tier: "精炼", element: "火", form: "液", desc: "【占位】" }, ref_fire_gas: { size: 1, name: /*::GEN::物品名::ref_fire_gas:: */"火·气"/*::END:: */, type: "炼金材料", tier: "精炼", element: "火", form: "气", desc: "【占位】" }, ref_fire_ion: { size: 1, name: /*::GEN::物品名::ref_fire_ion:: */"火·离"/*::END:: */, type: "炼金材料", tier: "精炼", element: "火", form: "离子", desc: "【占位】" }, ref_earth_solid: { size: 1, name: /*::GEN::物品名::ref_earth_solid:: */"土·固"/*::END:: */, type: "炼金材料", tier: "精炼", element: "土", form: "固", desc: "【占位】" }, ref_earth_liquid: { size: 1, name: /*::GEN::物品名::ref_earth_liquid:: */"土·液"/*::END:: */, type: "炼金材料", tier: "精炼", element: "土", form: "液", desc: "【占位】" }, ref_earth_gas: { size: 1, name: /*::GEN::物品名::ref_earth_gas:: */"土·气"/*::END:: */, type: "炼金材料", tier: "精炼", element: "土", form: "气", desc: "【占位】" }, ref_earth_ion: { size: 1, name: /*::GEN::物品名::ref_earth_ion:: */"土·离"/*::END:: */, type: "炼金材料", tier: "精炼", element: "土", form: "离子", desc: "【占位】" }, ref_wind_solid: { size: 1, name: /*::GEN::物品名::ref_wind_solid:: */"风·固"/*::END:: */, type: "炼金材料", tier: "精炼", element: "风", form: "固", desc: "【占位】" }, ref_wind_liquid: { size: 1, name: /*::GEN::物品名::ref_wind_liquid:: */"风·液"/*::END:: */, type: "炼金材料", tier: "精炼", element: "风", form: "液", desc: "【占位】" }, ref_wind_gas: { size: 1, name: /*::GEN::物品名::ref_wind_gas:: */"风·气"/*::END:: */, type: "炼金材料", tier: "精炼", element: "风", form: "气", desc: "【占位】" }, ref_wind_ion: { size: 1, name: /*::GEN::物品名::ref_wind_ion:: */"风·离"/*::END:: */, type: "炼金材料", tier: "精炼", element: "风", form: "离子", desc: "【占位】" }, /* ══════════════════════════════════════════ 四化剂 ══════════════════════════════════════════ */ agent_white: { size: 1, name: /*::GEN::物品名::agent_white:: */"阳光"/*::END:: */, type: "炼金材料", tier: "化剂", subtype: "白化剂", desc: "【占位】" }, agent_black: { size: 1, name: /*::GEN::物品名::agent_black:: */"月光"/*::END:: */, type: "炼金材料", tier: "化剂", subtype: "黑化剂", desc: /*::GEN::物品描述::agent_black:: */"在晴朗夜晚位于海面时,可在炼金室收集。是形态转换和酊剂合成的核心消耗品。"/*::END:: */ }, agent_yellow: { size: 1, name: /*::GEN::物品名::agent_yellow:: */"星光"/*::END:: */, type: "炼金材料", tier: "化剂", subtype: "黄化剂", desc: "【占位】" }, agent_red: { size: 1, name: /*::GEN::物品名::agent_red:: */"以太"/*::END:: */, type: "炼金材料", tier: "化剂", subtype: "赤化剂", desc: "【占位】" }, /* ══════════════════════════════════════════ 纯粹酊剂(4种) 配方: 慈爱 = 水·液 + 风·液 + 月光 信标 = 火·气 + 土·气 + 月光 死寂 = 水·固 + 土·固 + 月光 变革 = 火·离 + 风·离 + 月光 ══════════════════════════════════════════ */ tinct_love: { size: 1, name: /*::GEN::物品名::tinct_love:: */"慈爱酊剂"/*::END:: */, type: "纯粹酊剂", element1: "水", element2: "风", form: "液", desc: "【占位】" }, tinct_beacon: { size: 1, name: /*::GEN::物品名::tinct_beacon:: */"信标酊剂"/*::END:: */, type: "纯粹酊剂", element1: "火", element2: "土", form: "气", desc: "【占位】" }, tinct_silence: { size: 1, name: /*::GEN::物品名::tinct_silence:: */"死寂酊剂"/*::END:: */, type: "纯粹酊剂", element1: "水", element2: "土", form: "固", desc: "【占位】" }, tinct_change: { size: 1, name: /*::GEN::物品名::tinct_change:: */"变革酊剂"/*::END:: */, type: "纯粹酊剂", element1: "火", element2: "风", form: "离子", desc: "【占位】" }, /* ══════════════════════════════════════════ 贤者之石 ══════════════════════════════════════════ */ philosophers_stone: { size: 1, name: /*::GEN::物品名::philosophers_stone:: */"贤者之石"/*::END:: */, type: "纯粹酊剂", rarity: "传说", desc: "【占位】" }, /* ══════════════════════════════════════════ 以太副产物 ══════════════════════════════════════════ */ ether_tainted: { size: 1, name: /*::GEN::物品名::ether_tainted:: */"污染以太"/*::END:: */, type: "以太副产物", desc: /*::GEN::物品描述::ether_tainted:: */"炼金过程中产生的不稳定副产物,对精神状态有一定的负面影响,需小心处理。"/*::END:: */ }, ether_blessed: { size: 1, name: /*::GEN::物品名::ether_blessed:: */"祝福以太"/*::END:: */, type: "以太副产物", rarity: "稀有", desc: /*::GEN::物品描述::ether_blessed:: */"极少数情况下精炼产生的纯净副产物,微弱的光芒令人感到安宁。"/*::END:: */ }, /* ══════════════════════════════════════════ 消耗品 ══════════════════════════════════════════ */ stabilizer: { size: 1, name: /*::GEN::物品名::stabilizer:: */"稳定剂"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::stabilizer:: */"使用后降低当前炼金台的以太污染度,是长期精炼的必备耗材。"/*::END:: */ }, calm_draft: { size: 1, name: /*::GEN::物品名::calm_draft:: */"深海镇定液"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::calm_draft:: */"服用后迅速恢复25点精神值,同时会产生短暂的感知迟钝。"/*::END:: */ }, corrode_agent: { size: 1, name: /*::GEN::物品名::corrode_agent:: */"腐蚀溶剂"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::corrode_agent:: */"强力的化学溶剂,能溶解大部分金属和有机物,用于处理特殊残骸材料。"/*::END:: */ }, silence_draft: { size: 1, name: /*::GEN::物品名::silence_draft:: */"沉默药剂"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::silence_draft:: */"服用后完全抑制元素感知能力约两小时,用于穿越部分神秘区域。"/*::END:: */ }, bearing_ink: { size: 1, name: /*::GEN::物品名::bearing_ink:: */"方位墨水"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::bearing_ink:: */"涂在航海图上能持续标注当前位置,持续时间约六小时。"/*::END:: */ }, sense_draft: { size: 1, name: /*::GEN::物品名::sense_draft:: */"感知剂"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::sense_draft:: */"服用后增强元素感知范围,可在导航界面看到隐藏的神秘生物信号。"/*::END:: */ }, catalyst: { size: 1, name: /*::GEN::物品名::catalyst:: */"不稳定催化剂"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::catalyst:: */"加入炼金配方后大幅提升反应速度,但成功率下降,失败时有副产物爆发风险。"/*::END:: */ }, heal_salve: { size: 1, name: /*::GEN::物品名::heal_salve:: */"创伤愈合膏"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::heal_salve:: */"外用型炼金制品,涂抹后加速皮肤和组织愈合,对深层内伤无效。"/*::END:: */ }, warmth_vial: { size: 1, name: /*::GEN::物品名::warmth_vial:: */"驱寒药剂"/*::END:: */, type: "消耗品", desc: /*::GEN::物品描述::warmth_vial:: */"服用后体感温度升高10度,效果持续约半小时,适合在极寒深海区域长期作业。"/*::END:: */ }, /* ══════════════════════════════════════════ 持久物品 ══════════════════════════════════════════ */ amulet_symb: { size: 1, name: /*::GEN::物品名::amulet_symb:: */"共生护符"/*::END:: */, type: "持久物品", desc: /*::GEN::物品描述::amulet_symb:: */"佩戴后与生命体征产生共振,自然生命恢复速度提升两倍。"/*::END:: */ }, rune_purify: { size: 1, name: /*::GEN::物品名::rune_purify:: */"净化符文"/*::END:: */, type: "持久物品", desc: /*::GEN::物品描述::rune_purify:: */"刻有净化纹路的金属片,激活后能自动将产生的污染以太分解为无害物质。"/*::END:: */ }, seal_nail: { size: 1, name: /*::GEN::物品名::seal_nail:: */"封印钉"/*::END:: */, type: "持久物品", desc: /*::GEN::物品描述::seal_nail:: */"钉入特定区域后会产生元素干扰场,阻止神秘生物在附近刷新。"/*::END:: */ }, beacon_stone: { size: 1, name: /*::GEN::物品名::beacon_stone:: */"信标石"/*::END:: */, type: "持久物品", desc: /*::GEN::物品描述::beacon_stone:: */"激活后记录当前坐标,之后可随时触发自动导航返回该位置。"/*::END:: */ }, sense_bone: { size: 1, name: /*::GEN::物品名::sense_bone:: */"感知骨"/*::END:: */, type: "持久物品", desc: /*::GEN::物品描述::sense_bone:: */"来自特殊生物的骨骼制品,持有者能在导航界面上看到海底地形的轮廓。"/*::END:: */ }, mutation_core: { size: 1, name: /*::GEN::物品名::mutation_core:: */"变质炉心"/*::END:: */, type: "持久物品", desc: /*::GEN::物品描述::mutation_core:: */"改装后的炼金台核心,解锁强制提纯功能——以更高的以太污染风险换取更高的提炼产量。"/*::END:: */ }, /* ══════════════════════════════════════════ 设备(潜艇升级) ══════════════════════════════════════════ */ engine_boost: { size: 2, name: /*::GEN::物品名::engine_boost:: */"强化驱动炉"/*::END:: */, type: "设备", slot: "发动机", desc: /*::GEN::物品描述::engine_boost:: */"提升最高航速上限,并降低高速航行时的燃料消耗率。"/*::END:: */ }, hull_coat: { size: 2, name: /*::GEN::物品名::hull_coat:: */"自愈船壳涂层"/*::END:: */, type: "设备", slot: "壳甲", desc: /*::GEN::物品描述::hull_coat:: */"在船壳受损时自动分泌修复物质,缓慢恢复船体完整度。"/*::END:: */ }, depth_sensor: { size: 2, name: /*::GEN::物品名::depth_sensor:: */"深度感应器"/*::END:: */, type: "设备", slot: "传感", desc: /*::GEN::物品描述::depth_sensor:: */"精确显示海底地形数据,提前预报地形变化,减少深度意外。"/*::END:: */ }, silent_hull: { size: 2, name: /*::GEN::物品名::silent_hull:: */"静默外壳"/*::END:: */, type: "设备", slot: "壳甲", desc: /*::GEN::物品描述::silent_hull:: */"大幅降低潜艇的声纹信号,减少神秘生物的感知半径。"/*::END:: */ }, fish_lure: { size: 2, name: /*::GEN::物品名::fish_lure:: */"生物诱引装置"/*::END:: */, type: "设备", slot: "外挂", desc: /*::GEN::物品描述::fish_lure:: */"向水中持续散布特定化学信号,被动提升附近渔获密度。"/*::END:: */ }, /* ══════════════════════════════════════════ 遗物(知识碎片,阅读后解锁配方) ══════════════════════════════════════════ */ relic_notebook: { size: 1, name: /*::GEN::物品名::relic_notebook:: */"泡水的笔记本"/*::END:: */, type: "遗物", unlock: "基础提炼配方", desc: /*::GEN::物品描述::relic_notebook:: */"字迹已经大半晕开,但仍能辨认出是某位炼金师的初学笔记。其中记录了最基础的元素分离流程。"/*::END:: */ }, relic_formula: { size: 1, name: /*::GEN::物品名::relic_formula:: */"残损配方册"/*::END:: */, type: "遗物", unlock: "稳定剂配方", desc: /*::GEN::物品描述::relic_formula:: */"皮革封面的小册子,多页粘连,解开后露出密密麻麻的配方注记。稳定剂的配方赫然在列。"/*::END:: */ }, relic_etching: { size: 1, name: /*::GEN::物品名::relic_etching:: */"铜板蚀刻图"/*::END:: */, type: "遗物", unlock: "炼金台升级图纸", desc: /*::GEN::物品描述::relic_etching:: */"精密的铜板蚀刻,线条清晰,是某种装置的改装图纸。看起来是炼金台的升级方案。"/*::END:: */ }, relic_log: { size: 1, name: /*::GEN::物品名::relic_log:: */"战争日志残页"/*::END:: */, type: "遗物", unlock: "腐蚀溶剂配方", rarity: "稀有", desc: /*::GEN::物品描述::relic_log:: */"来自伐神战争的亲历者。字里行间充斥着恐惧和狂热,记录了攻击神体时使用的特殊溶剂配方。"/*::END:: */ }, relic_god_frag: { size: 1, name: /*::GEN::物品名::relic_god_frag:: */"神域碎片"/*::END:: */, type: "遗物", unlock: "祝福以太提纯", rarity: "稀有", desc: /*::GEN::物品描述::relic_god_frag:: */"一片来历不明的金属碎块,对其施以炼金扫描后会产生短暂的幻觉。内含的信息最终化为一种祝福以太的提炼方法。"/*::END:: */ }, /* ══════════════════════════════════════════ 残骸(可拆解) ══════════════════════════════════════════ */ wreck_steel: { size: 4, name: /*::GEN::物品名::wreck_steel:: */"钢铁残骸"/*::END:: */, type: "残骸", desc: /*::GEN::物品描述::wreck_steel:: */"沉船或建筑留下的大块钢铁,锈蚀严重,但内部金属依然有用。"/*::END:: */ }, wreck_wood: { size: 5, name: /*::GEN::物品名::wreck_wood:: */"木质残骸"/*::END:: */, type: "残骸", desc: /*::GEN::物品描述::wreck_wood:: */"朽烂的木制结构件,有一定概率内藏绳索或煤块。"/*::END:: */ }, god_bone_frag: { size: 3, name: /*::GEN::物品名::god_bone_frag:: */"神骨碎块"/*::END:: */, type: "残骸", rarity: "稀有", desc: /*::GEN::物品描述::god_bone_frag:: */"神祇骸骨的碎片,密度异常,表面有难以解释的结晶生长。"/*::END:: */ }, creature_husk: { size: 3, name: /*::GEN::物品名::creature_husk:: */"异兽外壳"/*::END:: */, type: "残骸", desc: /*::GEN::物品描述::creature_husk:: */"来自不明生物的甲壳或骨骼碎片,成分复杂,适合拆解提取多种炼金材料。"/*::END:: */ }, /* ══════════════════════════════════════════ 资源(船体维修材料) ══════════════════════════════════════════ */ iron: { size: 2, name: /*::GEN::物品名::iron:: */"铁锭"/*::END:: */, type: "资源", desc: /*::GEN::物品描述::iron:: */"精炼后的铁金属,是各类设备和修理的基础材料。"/*::END:: */ }, copper: { size: 1, name: /*::GEN::物品名::copper:: */"铜板"/*::END:: */, type: "资源", desc: /*::GEN::物品描述::copper:: */"展平的铜质薄板,导热性好,是传感装置和炼金台部件的常用材料。"/*::END:: */ }, rubber_seal: { size: 1, name: /*::GEN::物品名::rubber_seal:: */"橡胶密封件"/*::END:: */, type: "资源", desc: /*::GEN::物品描述::rubber_seal:: */"来自船体的橡胶垫片,用于维持舱室气密性,定期需要更换。"/*::END:: */ }, fuel_cell: { size: 2, name: /*::GEN::物品名::fuel_cell:: */"燃料块"/*::END:: */, type: "资源", desc: /*::GEN::物品描述::fuel_cell:: */"压缩燃料的固态模块,能量密度高,直接投入发动机即可使用。"/*::END:: */ } }>>
<<nobr>> <<widget "largeSceneDefs">> /* ═══════════════════════════════════════════════ 大型场景定义表 $largeDefs 字段说明: id 唯一标识 name 显示名 viewDesc 舷窗描述(active 状态时) approachHint 接近提示文本数组(随机选1) leaveHint 离开提示文本 dMin / dMax 深度限制(海底深度范围) allowedMiddleTypes 允许作为 zone 的中型场景类型白名单 zoneList 完整 zone 池 [{name, wsType}](zonePool) boundZones 绑定 zone(必选,随机选 3-5 时一定包含) minZones/maxZones 随机选取数量范围(默认 3~5) 地形 → 大型区域(规范 §一): sand→沉船群 flat→城市废墟 cliff→残坑 grass→牧场 reef→永夜礁石 forest→人鱼狱 abyss→盐湖区+热液泉区 距离参数(原始值 / 可见坐标): 接近段 = 2000 / 40 离开段 = 2000 / 40 活跃段 = 15000 / 300(在 spawnLargeScene 中计算) 占位说明:描述文本为占位(带「占位」标记),zone 内部互动为 §八 占位结构, 后续由「文案人」按 GEN 标记填充;zonePool/boundZones 已就位。 ═══════════════════════════════════════════════ */ <<set $largeDefs = { /* ── 城市废墟:大型人造建筑群(flat / 岩海床)── */ sunken_city: { name: /*::GEN::场景名:: */"城市废墟"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(城市废墟占位)混凝土与钢筋骨架匍匐于海床,街道轮廓依稀可辨,已被淤泥与珊瑚吞没大半。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(城市废墟占位)建筑群的轮廓在身后逐渐模糊,沉没城市的痕迹终于消失。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(城市废墟占位)海床上出现规则的水泥碎块与锈蚀钢筋,前方似有人造建筑群。"/*::END:: */, /*::GEN::approachHint:: */"(城市废墟占位)声呐探测到大片规则排列的硬质结构,间距均匀,疑似沉没建筑群。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-2:zone = 公园/公寓/学校/工厂/商场/市政厅/研究所 餐厅/花店/面包房/民居 属 small 层级,独立散装(见 $wsDefs 的 independent 条目),不入 zonePool */ allowedMiddleTypes: ["ruin_park","ruin_apartment","ruin_school","ruin_factory","ruin_mall","ruin_cityhall","ruin_institute"], zoneList: [ {name:/*::GEN::场景名:: */"公园"/*::END:: */, wsType:"ruin_park"}, {name:/*::GEN::场景名:: */"公寓"/*::END:: */, wsType:"ruin_apartment"}, {name:/*::GEN::场景名:: */"学校"/*::END:: */, wsType:"ruin_school"}, {name:/*::GEN::场景名:: */"工厂"/*::END:: */, wsType:"ruin_factory"}, {name:/*::GEN::场景名:: */"商场"/*::END:: */, wsType:"ruin_mall"}, {name:/*::GEN::场景名:: */"市政厅"/*::END:: */, wsType:"ruin_cityhall"}, {name:/*::GEN::场景名:: */"研究所"/*::END:: */, wsType:"ruin_institute"} ], boundZones: ["研究所"], minZones: 3, maxZones: 5 }, /* ── 沉船坟场:大型沉船集群(sand / 沙海床)── */ wreck_graveyard: { name: /*::GEN::场景名:: */"沉船坟场"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(沉船坟场占位)大小不一的船体残骸密布海床,锈蚀船体与海床融为一体,形成金属与腐朽构成的奇异礁岛。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(沉船坟场占位)残骸密度开始减少,沉船坟场已逐渐落在身后。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(沉船坟场占位)海床上出现零散金属碎片与腐朽木料,像是某场灾难的余烬。"/*::END:: */, /*::GEN::approachHint:: */"(沉船坟场占位)声呐回波复杂,前方有密集的大型硬质结构,可能是大规模沉船区外缘。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-1:zone = 货轮/游轮/军舰/远洋渔船/三桅帆船/科考船(军舰·科考船=线索 zone,绑定必选) 游艇/渔船 属 small 层级,独立散装(见 $wsDefs 的 independent 条目),不入 zonePool */ allowedMiddleTypes: ["wreck_cargoship","wreck_cruise","wreck_warship","wreck_trawler","wreck_schooner","wreck_research"], zoneList: [ {name:/*::GEN::场景名:: */"货轮"/*::END:: */, wsType:"wreck_cargoship"}, {name:/*::GEN::场景名:: */"游轮"/*::END:: */, wsType:"wreck_cruise"}, {name:/*::GEN::场景名:: */"军舰"/*::END:: */, wsType:"wreck_warship"}, {name:/*::GEN::场景名:: */"远洋渔船"/*::END:: */, wsType:"wreck_trawler"}, {name:/*::GEN::场景名:: */"三桅帆船"/*::END:: */, wsType:"wreck_schooner"}, {name:/*::GEN::场景名:: */"科考船"/*::END:: */, wsType:"wreck_research"} ], boundZones: ["军舰","科考船"], minZones: 3, maxZones: 5 }, /* ── 残坑:峭壁大型区域(cliff)── */ cliff_pit: { name: /*::GEN::场景名:: */"残坑"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(残坑占位)巨大坑体与峭壁,是大地挣扎入海的伤疤,崖壁残留人类建筑。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(残坑占位)峭壁轮廓远去,残坑的痕迹被黑暗吞没。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(残坑占位)海床隆起成巨大坑体,崖壁上有规则的建筑残骸。"/*::END:: */, /*::GEN::approachHint:: */"(残坑占位)声呐显示异常巨大的腔体结构,似人造痕迹。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-3:zone 命名「待用户完善」。此处仅按要素①②④落位: ①峭壁人类建筑=限定 zone(绑定)/②寄居深海生物聚居=zone/④特殊采集物=限定 zone(名+机制待定) ③残魂、⑤危险敌人 归 small / 危险区,不作 zone */ allowedMiddleTypes: ["cliff_building","cliff_colony","cliff_relic"], zoneList: [ {name:/*::GEN::场景名:: */"峭壁人类建筑"/*::END:: */, wsType:"cliff_building"}, {name:/*::GEN::场景名:: */"寄居生物聚居"/*::END:: */, wsType:"cliff_colony"}, {name:/*::GEN::场景名:: */"特殊采集点"/*::END:: */, wsType:"cliff_relic"} ], boundZones: ["峭壁人类建筑"], minZones: 3, maxZones: 3 }, /* ── 牧场:海草床大型区域(grass)── */ pasture: { name: /*::GEN::场景名:: */"牧场"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(牧场占位)如同草原的场景与围栏,丰饶的草场上生物游弋。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(牧场占位)草场在身后远去,围栏的轮廓淡去。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(牧场占位)海流中浮现成片草甸与围栏的剪影。"/*::END:: */, /*::GEN::approachHint:: */"(牧场占位)声呐捕捉到密集的中型生物群回波。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-4:zone = 育幼场/小屋/兽群/花园(花园标注「可散装」,暂只作 zone) 海生花已按 §三 注移至 C 通用池,不作 zone */ allowedMiddleTypes: ["pasture_nursery","pasture_cabin","pasture_herd","pasture_garden"], zoneList: [ {name:/*::GEN::场景名:: */"育幼场"/*::END:: */, wsType:"pasture_nursery"}, {name:/*::GEN::场景名:: */"小屋"/*::END:: */, wsType:"pasture_cabin"}, {name:/*::GEN::场景名:: */"兽群"/*::END:: */, wsType:"pasture_herd"}, {name:/*::GEN::场景名:: */"花园"/*::END:: */, wsType:"pasture_garden"} ], boundZones: ["育幼场"], minZones: 3, maxZones: 4 }, /* ── 永夜礁石:珊瑚礁大型区域(reef)── */ reef_eternal: { name: /*::GEN::场景名:: */"永夜礁石"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(永夜礁石占位)巨大礁石生机盎然,墓火点缀,海豚集群巡游。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(永夜礁石占位)礁石轮廓没入黑暗,墓火渐熄。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(永夜礁石占位)前方礁石密布,生物活动异常密集。"/*::END:: */, /*::GEN::approachHint:: */"(永夜礁石占位)声呐显示巨大的生物集群聚集区。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-5:海豚岛/墓火「只有永夜礁石会出现,不散装」;陶玛斯 location 绑定永夜礁石 → 三者全绑定 */ allowedMiddleTypes: ["reef_dolphin","reef_gravefire","reef_thomas"], zoneList: [ {name:/*::GEN::场景名:: */"海豚岛"/*::END:: */, wsType:"reef_dolphin"}, {name:/*::GEN::场景名:: */"墓火"/*::END:: */, wsType:"reef_gravefire"}, {name:/*::GEN::场景名:: */"陶玛斯"/*::END:: */, wsType:"reef_thomas"} ], boundZones: ["海豚岛","墓火","陶玛斯"], minZones: 3, maxZones: 3 }, /* ── 人鱼狱:海藻森林大型区域(forest)── */ mermaid_prison: { name: /*::GEN::场景名:: */"人鱼狱"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(人鱼狱占位)海藻密林成漏斗状漩涡,黑色结晶覆盖鲸尸,阴绿恐怖。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(人鱼狱占位)密林在身后合拢,水雷区的危险远去。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(人鱼狱占位)海藻异常密集,形成不透水的干涸漩涡。"/*::END:: */, /*::GEN::approachHint:: */"(人鱼狱占位)声呐回波阴绿,漂浮水雷与骨骸提示危险。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-6:污染尸骸=核心 zone(绑定,通向下一 location);水雷区/骨骸林=限定 zone,不散装 */ allowedMiddleTypes: ["prison_carcass","prison_minefield","prison_bonewood"], zoneList: [ {name:/*::GEN::场景名:: */"污染尸骸"/*::END:: */, wsType:"prison_carcass"}, {name:/*::GEN::场景名:: */"水雷区"/*::END:: */, wsType:"prison_minefield"}, {name:/*::GEN::场景名:: */"骨骸林"/*::END:: */, wsType:"prison_bonewood"} ], boundZones: ["污染尸骸"], minZones: 3, maxZones: 3 }, /* ── 盐湖区:深渊子区域(abyss)── */ salt_lake: { name: /*::GEN::场景名:: */"盐湖区"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(盐湖区占位)幽绿盐湖中遍布巨大骨骸,气氛诡异而神秘。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(盐湖区占位)盐湖的幻象在身后消散,结晶滩涂远去。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(盐湖区占位)海床呈现异常高盐度光泽,巨大骨骸隐现。"/*::END:: */, /*::GEN::approachHint:: */"(盐湖区占位)声呐显示一片静谧而诡异的开阔区域。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-7:盐湖区 zone = 巨大骨骸/结晶滩涂/湖面幻象(湖面幻象按 $san 差分) */ allowedMiddleTypes: ["salt_bones","salt_crystal","salt_mirage"], zoneList: [ {name:/*::GEN::场景名:: */"巨大骨骸"/*::END:: */, wsType:"salt_bones"}, {name:/*::GEN::场景名:: */"结晶滩涂"/*::END:: */, wsType:"salt_crystal"}, {name:/*::GEN::场景名:: */"湖面幻象"/*::END:: */, wsType:"salt_mirage"} ], boundZones: ["巨大骨骸"], minZones: 3, maxZones: 3 }, /* ── 热液泉区:深渊子区域(abyss)── */ hydrothermal: { name: /*::GEN::场景名:: */"热液泉区"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"(热液泉区占位)热液喷涌,矿物堆积,废弃研究所与火山口并存。"/*::END:: */, leaveHint: /*::GEN::leaveHint:: */"(热液泉区占位)热羽流在身后冷却,喷口的光芒远去。"/*::END:: */, approachHint: [ /*::GEN::approachHint:: */"(热液泉区占位)水温骤升,前方有活跃热液喷口。"/*::END:: */, /*::GEN::approachHint:: */"(热液泉区占位)声呐捕捉到金属结构回波,疑似废弃设施。"/*::END:: */ ], dMin: 20, dMax: 10000, /* 附A-8:热液泉区 zone = 研究所废墟/火山口/神秘仪器/热泉生物群(研究所废墟需出舱探索进深处) */ allowedMiddleTypes: ["vent_lab","vent_crater","vent_device","vent_biota"], zoneList: [ {name:/*::GEN::场景名:: */"研究所废墟"/*::END:: */, wsType:"vent_lab"}, {name:/*::GEN::场景名:: */"火山口"/*::END:: */, wsType:"vent_crater"}, {name:/*::GEN::场景名:: */"神秘仪器"/*::END:: */, wsType:"vent_device"}, {name:/*::GEN::场景名:: */"热泉生物群"/*::END:: */, wsType:"vent_biota"} ], boundZones: ["研究所废墟"], minZones: 3, maxZones: 4 } }>> <</widget>> <</nobr>>
<<nobr>> <<widget "locationDefs">> /* ═══════════════════════════════════════════════ 地点定义表 $locationDefTable Location 已合并为 SmallScene 的固定实例型(type: "fixed")。 此表作为地形→Location ID 的映射索引, 供 sail.tw 在区域过渡时生成 $activeLocations。 完整定义在 SmallEventDefs.tw 的 $smallEventDefs 中(type: "fixed" 的条目)。 此处只保留索引结构,避免数据重复。 字段说明: [地形] = [ Location ID 列表 ] ═══════════════════════════════════════════════ */ <<if !$smallEventDefs>><<smallEventTable>><</if>> <<set $locationDefTable = { sand: [ "wreck_site_loc" ], flat: [], cliff: [], grass: [], reef: [], forest: [], vent: [], abyss: [] }>> /* 将 ID 映射为完整的定义对象(从 $smallEventDefs 提取) */ <<set _locRebuild = {}>> <<for _ltKey = 0; _ltKey < Object.keys($locationDefTable).length; _ltKey++>> <<set _ltTerrain = Object.keys($locationDefTable)[_ltKey]>> <<set _ltIds = $locationDefTable[_ltTerrain]>> <<set _ltDefs = []>> <<for _lti = 0; _lti < _ltIds.length; _lti++>> <<set _ltId = _ltIds[_lti]>> <<if $smallEventDefs[_ltId]>> <<run _ltDefs.push($smallEventDefs[_ltId])>> <</if>> <</for>> <<set _locRebuild[_ltTerrain] = _ltDefs>> <</for>> <<set $locationDefTable = _locRebuild>> <</widget>> <</nobr>>
<<nobr>> <<widget "microEventTable">> <<set $microEventDefs = { /* ── explore 类:发现物品/材料,触发不依赖丰富度 ── */ /* smallExplorePoint:可由锚定探索按钮从专用池强制发现;不改变事件层级。 */ "sand_glint": { tier:"B", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["sand"], depthRange:[0,500], baseChance:0.18, fragmentText:/*::GEN::事件碎片:: */"沙面深处透出一点金属光泽。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 挖掘查看"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"是一块锈蚀的金属碎片,勉强还能用。"/*::END:: */,loot:[{id:"metal",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"挖出了几块贝壳碎片,什么特别的都没有。"/*::END:: */,loot:[{id:"shell_frag",qty:[1,3]}]}, {weight:15,text:/*::GEN::事件结果:: */"是一枚完整的珍珠,大小适中,品相不错。"/*::END:: */,loot:[{id:"pearl",qty:[1,1]}]}, {weight:5, text:/*::GEN::事件结果:: */"是一块奇异的矿石晶体,表面有微弱发光。"/*::END:: */,loot:[{id:"current_stone",qty:[1,1]}]} ] }, "scallop_edge": { tier:"B", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["sand","reef","flat"], depthRange:[0,200], baseChance:0.15, fragmentText:/*::GEN::事件碎片:: */"礁缝里露出了一只扇贝的边角,纹理清晰,个头可观。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 撬起采集"/*::END:: */, outcomes:[ {weight:60,text:/*::GEN::事件结果:: */"成功采到一只扇贝,个头不小。"/*::END:: */,loot:[{id:"scallop",qty:[1,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"扇贝壳里藏了颗小珍珠,意外之喜。"/*::END:: */,loot:[{id:"scallop",qty:[1,1]},{id:"pearl",qty:[1,1]}]}, {weight:15,text:/*::GEN::事件结果:: */"用力过猛,壳碎了,只剩些贝肉和碎壳。"/*::END:: */,loot:[{id:"shell_meat",qty:[1,2]},{id:"shell_frag",qty:[1,2]}]} ] }, "drifting_debris": { tier:"C", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["water","sand","grass"], depthRange:[0,100], baseChance:0.12, regionVariants:{sunken_city:{name:"城市废墟漂流残骸(城市变体1)"},salt_lake:{name:"盐湖漂流残骸(盐湖变体1)"},pasture:{name:"牧场漂流残骸(牧场变体1)"}}, fragmentText:/*::GEN::事件碎片:: */"一小片木质残骸随流漂来,上面还绑着什么东西。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 打捞"/*::END:: */, outcomes:[ {weight:45,text:/*::GEN::事件结果:: */"是几段腐朽的木料,还能用。"/*::END:: */,loot:[{id:"wood",qty:[1,3]}]}, {weight:35,text:/*::GEN::事件结果:: */"木板上绑着一卷绳索,略有磨损但完整。"/*::END:: */,loot:[{id:"wood",qty:[1,1]},{id:"rope",qty:[1,2]}]}, {weight:15,text:/*::GEN::事件结果:: */"残骸里嵌着玻璃碎片和铁钉。"/*::END:: */,loot:[{id:"glass",qty:[1,1]},{id:"metal",qty:[1,2]}]}, {weight:5, text:/*::GEN::事件结果:: */"木板下压着一个防水皮革包,里面是几页泛黄的日志。"/*::END:: */,loot:[{id:"relic_log",qty:[1,1]}]} ] }, "kelp_tangle": { tier:"B", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["grass","forest"], depthRange:[0,400], baseChance:0.14, fragmentText:/*::GEN::事件碎片:: */"一团密集的海藻漂来,里面似乎卷着什么东西。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 清理查看"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"只是一团普通海藻,但量不少。"/*::END:: */,loot:[{id:"kelp",qty:[2,4]}]}, {weight:30,text:/*::GEN::事件结果:: */"藻团里夹着一只小章鱼,已经不动了。"/*::END:: */,loot:[{id:"octopus_meat",qty:[1,1]},{id:"kelp",qty:[1,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"藻团中间包裹着一枚完好的海胆。"/*::END:: */,loot:[{id:"seaurchin",qty:[1,1]}]}, {weight:10,text:/*::GEN::事件结果:: */"海藻里缠绕着一段奇异的致密纤维。"/*::END:: */,loot:[{id:"kelp_fiber",qty:[2,3]}]} ] }, "coral_fragment": { tier:"B", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["reef","flat"], depthRange:[10,300], baseChance:0.13, fragmentText:/*::GEN::事件碎片:: */"礁面上有一块松动的珊瑚,颜色鲜艳,已从主体断裂。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 采集"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"采到一块品相不错的珊瑚碎片。"/*::END:: */,loot:[{id:"coral_frag",qty:[1,3]}]}, {weight:30,text:/*::GEN::事件结果:: */"珊瑚内部有细小的土系结晶颗粒。"/*::END:: */,loot:[{id:"coral_frag",qty:[1,2]},{id:"tinct_earth_crystal",qty:[1,1]}]}, {weight:15,text:/*::GEN::事件结果:: */"珊瑚里钻出了一只甜虾,外壳鲜红。"/*::END:: */,loot:[{id:"coral_frag",qty:[1,1]},{id:"sweetshrimp",qty:[1,2]}]} ] }, "cliff_seep": { tier:"B", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["cliff"], depthRange:[100,10000], baseChance:0.10, fragmentText:/*::GEN::事件碎片:: */"壁面渗出一股黑色液体,在水中扩散,气味浓烈。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 采集样本"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"收集到硫磺渗液,成分待分析。"/*::END:: */,loot:[{id:"sulfur_dust",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"渗液中有结晶颗粒,散发微弱热量。"/*::END:: */,loot:[{id:"sulfur_dust",qty:[1,1]},{id:"ember_crystal",qty:[1,1]}]}, {weight:20,text:/*::GEN::事件结果:: */"渗液黏稠异常,像是某种生物分泌物。"/*::END:: */,loot:[{id:"thermal_ext",qty:[1,1]}]} ] }, "sand_creature": { tier:"B", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["sand"], depthRange:[0,300], baseChance:0.11, fragmentText:/*::GEN::事件碎片:: */"沙面有规律地微微鼓起,节律均匀,某种东西藏在浅沙层中。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 挖掘捕捉"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"是一只埋在沙里的蛤蜊,个头挺大。"/*::END:: */,loot:[{id:"clam",qty:[1,3]}]}, {weight:30,text:/*::GEN::事件结果:: */"挖出几只比目鱼,在沙里扑腾。"/*::END:: */,loot:[{id:"flounder",qty:[1,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"是一只濑尿虾,甲壳坚硬,挣扎有力。"/*::END:: */,loot:[{id:"mantisshrimp",qty:[1,1]}]}, {weight:10,text:/*::GEN::事件结果:: */"挖到一块岩质结构,里面有化石痕迹。"/*::END:: */,loot:[{id:"bone_ash",qty:[1,2]},{id:"shell_frag",qty:[1,2]}]} ] }, "floating_egg": { tier:"C", weight:1, subtype:"explore", smallExplorePoint:{weight:1}, terrain:["water","grass","reef"], depthRange:[0,200], baseChance:0.09, regionVariants:{reef_eternal:{name:"永夜礁石漂浮卵囊(礁石变体1)"},mermaid_prison:{name:"海藻森林漂浮卵囊(森林变体1)"},salt_lake:{name:"盐湖漂浮卵囊(盐湖变体1)"}}, fragmentText:/*::GEN::事件碎片:: */"水中漂着一串半透明的卵囊,内部有细小的形状蠕动。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 收集"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"收集到一些鱼卵,新鲜度尚可。"/*::END:: */,loot:[{id:"fish_roe",qty:[1,3]}]}, {weight:30,text:/*::GEN::事件结果:: */"卵囊内是虾的幼体,活性较强。"/*::END:: */,loot:[{id:"shrimp_meat",qty:[1,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"卵囊外壁有奇异的发光蛋白质,来源不明。"/*::END:: */,loot:[{id:"fish_roe",qty:[1,2]},{id:"jellyfluid",qty:[1,1]}]} ] }, /* ── hunt 类:目击描述 + 追猎行动,触发概率按丰富度缩放 ── */ "hunt_sand_eel": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["sand"], depthRange:[0,1000], baseChance:0.55, fragmentText:/*::GEN::事件碎片:: */"沙面留着一道新鲜的S形划痕——鳗鱼不会走远。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 追踪这条鳗鱼"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"沙层下果然有鳗鱼蜷缩其中,被灯光晃了一下来不及逃脱。"/*::END:: */,loot:[{id:"eel",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"追了一段,鳗鱼钻进了更深的沙缝,没能捉到。"/*::END:: */,loot:[]}, {weight:15,text:/*::GEN::事件结果:: */"鳗鱼不在,但挖到了藏在洞里的比目鱼。"/*::END:: */,loot:[{id:"flounder",qty:[1,1]}]} ] }, "hunt_sand_flatfish": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["sand"], depthRange:[0,500], baseChance:0.50, fragmentText:/*::GEN::事件碎片:: */"沙面有一块不自然的隆起,轮廓和周围的沙丘不同。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 挖开查看"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"是一条比目鱼,被惊起来在水里乱扑,轻松捞住。"/*::END:: */,loot:[{id:"flounder",qty:[1,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"挖出来的是个蛤蜊堆,比目鱼已经跑了。"/*::END:: */,loot:[{id:"clam",qty:[1,3]}]}, {weight:15,text:/*::GEN::事件结果:: */"一只濑尿虾突然猛地夹了机械臂一下,但还是被捉住了。"/*::END:: */,loot:[{id:"mantisshrimp",qty:[1,1]}]}, {weight:10,text:/*::GEN::事件结果:: */"翻开沙层只有几只小螃蟹,夹了夹空气,各自逃散。"/*::END:: */,loot:[{id:"swimmingcrab",qty:[0,1]}]} ] }, "hunt_flat_eel": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["flat"], depthRange:[0,1000], baseChance:0.52, fragmentText:/*::GEN::事件碎片:: */"一条细长的鳗鱼从岩缝里探出头,打量了一眼灯光,又缩了回去。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 诱引捕捉"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"用食物残渣引了几分钟,鳗鱼探出身来,被捕捉网一扣。"/*::END:: */,loot:[{id:"eel",qty:[1,1]}]}, {weight:30,text:/*::GEN::事件结果:: */"鳗鱼警觉,诱了几次都不出来,最后缩回更深处。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"鳗鱼缝里同时钻出来两只螃蟹,鳗鱼没捉到,但螃蟹到手了。"/*::END:: */,loot:[{id:"bluecrab",qty:[1,2]}]} ] }, "hunt_flat_urchin": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["flat","reef"], depthRange:[0,500], baseChance:0.60, fragmentText:/*::GEN::事件碎片:: */"几颗海胆附着在岩面上,棘刺随水流轻微颤动。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 撬取海胆"/*::END:: */, outcomes:[ {weight:60,text:/*::GEN::事件结果:: */"撬下几颗品相不错的海胆,卵巢饱满。"/*::END:: */,loot:[{id:"seaurchin",qty:[1,3]}]}, {weight:25,text:/*::GEN::事件结果:: */"棘刺太密,只取到碎片和少量卵。"/*::END:: */,loot:[{id:"urchin_roe",qty:[1,2]},{id:"urchin_spine_core",qty:[1,1]}]}, {weight:15,text:/*::GEN::事件结果:: */"岩面有五六颗,全都撬下来了。"/*::END:: */,loot:[{id:"seaurchin",qty:[2,5]}]} ] }, "hunt_grass_octopus": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["grass"], depthRange:[0,300], baseChance:0.48, fragmentText:/*::GEN::事件碎片:: */"草根处有一块颜色稍有不自然的区域,几乎和海草完全相同的绿色。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 突然捕捉"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"出其不意按住,章鱼喷了一口墨,但已经逃不掉了。"/*::END:: */,loot:[{id:"octopus",qty:[1,1]}]}, {weight:30,text:/*::GEN::事件结果:: */"章鱼喷墨遁逃,趁浑水溜走,没捉到。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"章鱼被捕,慌乱中附近草丛里窜出两只虾。"/*::END:: */,loot:[{id:"octopus",qty:[1,1]},{id:"prawn",qty:[1,2]}]} ] }, "hunt_grass_bream": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["grass","reef"], depthRange:[0,200], baseChance:0.45, fragmentText:/*::GEN::事件碎片:: */"一条鲷鱼在草茎间缓慢穿行,时不时停下来拱一拱草根。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 跟踪捕捞"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"靠近时撒网,鲷鱼入网,银红色的鳞片哗哗作响。"/*::END:: */,loot:[{id:"bream",qty:[1,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"鲷鱼察觉动静,一个急转猛地蹿出去,没能追上。"/*::END:: */,loot:[]}, {weight:25,text:/*::GEN::事件结果:: */"撒网捞到鲷鱼,草丛里还额外裹进来几条小鱼。"/*::END:: */,loot:[{id:"bream",qty:[1,1]},{id:"seabass",qty:[0,1]},{id:"sardine",qty:[0,2]}]} ] }, "hunt_reef_lobster": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["reef"], depthRange:[0,300], baseChance:0.42, fragmentText:/*::GEN::事件碎片:: */"珊瑚礁深处的缝隙里露出长长的龙虾触须,在水流里轻轻摆动。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 诱捕套索"/*::END:: */, outcomes:[ {weight:45,text:/*::GEN::事件结果:: */"用套索慢慢套住触须,猛地一拉,龙虾出洞,在机械臂里跑不掉。"/*::END:: */,loot:[{id:"lobster",qty:[1,1]}]}, {weight:30,text:/*::GEN::事件结果:: */"龙虾察觉异样,将触须完全缩回洞里。"/*::END:: */,loot:[]}, {weight:25,text:/*::GEN::事件结果:: */"龙虾出来了,但跑了一半,只带出些甲壳碎片。"/*::END:: */,loot:[{id:"crab_shell",qty:[1,2]}]} ] }, "hunt_reef_grouper": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["reef"], depthRange:[10,400], baseChance:0.44, fragmentText:/*::GEN::事件碎片:: */"礁石背面阴影区有几条石斑鱼悬浮不动,那是它们等待猎物的姿势。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 诱饵钓取"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"石斑鱼咬钩,挣扎了一会儿,被钓上来。体型不小,鱼肉肥厚。"/*::END:: */,loot:[{id:"grouper",qty:[1,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"石斑鱼刚探出身子,灯光扫过,立刻缩回阴影里。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"两条鱼同时上钩,差点拉不住,最终都收进船舱。"/*::END:: */,loot:[{id:"grouper",qty:[2,3]}]} ] }, "hunt_cliff_shadow": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["cliff"], depthRange:[50,10000], baseChance:0.46, fragmentText:/*::GEN::事件碎片:: */"悬空礁石的阴影区聚集着几条深水鱼,悬浮不动,不受打扰。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 投钩垂钓"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"鳕鱼咬钩,冷水鱼肉质紧实,分量十足。"/*::END:: */,loot:[{id:"cod",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"上来的是一条大鳗鱼,深水品种,体色更深。"/*::END:: */,loot:[{id:"eel",qty:[1,1]}]}, {weight:20,text:/*::GEN::事件结果:: */"什么都没咬钩,深水鱼对诱饵不感兴趣。"/*::END:: */,loot:[]}, {weight:10,text:/*::GEN::事件结果:: */"钩上来一条罕见的鮟鱇,发光器官在舱内隐隐发光。"/*::END:: */,loot:[{id:"anglerfish",qty:[1,1]}]} ] }, "hunt_cliff_crab": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["cliff","flat"], depthRange:[0,1000], baseChance:0.52, fragmentText:/*::GEN::事件碎片:: */"几只花蟹横着爬在壁面的凹槽里,专注于觅食,没有察觉到灯光。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 捞取捕捉"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"一网扫过去,捞到好几只花蟹,还有一只扁蟹凑了进来。"/*::END:: */,loot:[{id:"flowercrab",qty:[1,3]},{id:"swimmingcrab",qty:[0,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"花蟹感受到振动迅速横向逃窜,只抓到一只。"/*::END:: */,loot:[{id:"flowercrab",qty:[1,1]}]}, {weight:20,text:/*::GEN::事件结果:: */"壁面有帝王蟹,体型太大差点夹住机械臂,但最终还是被制服了。"/*::END:: */,loot:[{id:"kingcrab",qty:[1,1]}]} ] }, "hunt_forest_shadow": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["forest"], depthRange:[50,1000], baseChance:0.40, fragmentText:/*::GEN::事件碎片:: */"一个体型可观的鱼影在藻林深处穿梭,移动无声,动线有规律。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 前方埋伏"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"是一条大型鲈鱼,猛地扑向诱饵,被牢牢捉住。"/*::END:: */,loot:[{id:"seabass",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"鱼影太快,还没布好阵型就消失进了更深的林区。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"是金枪鱼!弹射力极强,挣扎中撕破了一个网眼,但终于收进了舱。"/*::END:: */,loot:[{id:"tuna",qty:[1,1]}]}, {weight:10,text:/*::GEN::事件结果:: */"鱼影在埋伏点附近徘徊,最终折返消失。"/*::END:: */,loot:[]} ] }, "hunt_forest_kelp": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["forest","grass"], depthRange:[0,600], baseChance:0.48, fragmentText:/*::GEN::事件碎片:: */"粗大的藻茎基部有不寻常的动静,藻体颤动不像是水流引起的。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 探查捕捉"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"章鱼被灯光照到,喷墨逃窜却被网兜堵住——完全没有退路。"/*::END:: */,loot:[{id:"octopus",qty:[1,1]}]}, {weight:30,text:/*::GEN::事件结果:: */"是鱿鱼,不是章鱼,被惊走时钻出一团墨云。"/*::END:: */,loot:[{id:"squid",qty:[1,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"洞里有只章鱼,还带着一窝卵,放走了,只带走些附生海藻。"/*::END:: */,loot:[{id:"kelp",qty:[1,2]}]} ] }, "hunt_water_school": { tier:"C", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["water","sand","grass"], depthRange:[0,200], baseChance:0.58, regionVariants:{sunken_city:{name:"城市废墟鱼群(城市变体1)"},pasture:{name:"牧场鱼群(牧场变体1)"},salt_lake:{name:"盐湖鱼群(盐湖变体1)"}}, fragmentText:/*::GEN::事件碎片:: */"几条小鱼拦截在探照灯光柱前,越来越多,光在把它们聚拢过来。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 趁势撒网"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"网里哗哗一片银光,主要是沙丁鱼和凤尾鱼,量不少。"/*::END:: */,loot:[{id:"sardine",qty:[2,5]},{id:"anchovy",qty:[1,3]}]}, {weight:30,text:/*::GEN::事件结果:: */"捞到鲭鱼为主的混合鱼获,还有几条带鱼凑了进来。"/*::END:: */,loot:[{id:"mackerel",qty:[1,3]},{id:"hairtail",qty:[0,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"光柱里混进来一条鯵鱼,个头挺大,是今天的意外收获。"/*::END:: */,loot:[{id:"mahi",qty:[1,1]},{id:"sardine",qty:[1,3]}]}, {weight:10,text:/*::GEN::事件结果:: */"下网太慢,鱼群绕过去了,只捞到零星几条。"/*::END:: */,loot:[{id:"anchovy",qty:[1,2]}]} ] }, "hunt_water_squid": { tier:"C", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["water","forest"], depthRange:[20,1000], baseChance:0.45, regionVariants:{mermaid_prison:{name:"人鱼狱发光鱿鱼群(森林变体1)"},hydrothermal:{name:"热液区发光鱿鱼群(热液变体1)"},reef_eternal:{name:"永夜礁石发光鱿鱼群(礁石变体1)"}}, fragmentText:/*::GEN::事件碎片:: */"水中有几道间歇性的蓝白色闪光——生物发光信号,靠近的话或许能捕捞到。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 接近捕捉"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"鱿鱼群还在,网一扫下去捞起好几条,触腕在网里缠来缠去。"/*::END:: */,loot:[{id:"squid",qty:[1,4]}]}, {weight:30,text:/*::GEN::事件结果:: */"靠近时鱿鱼集体熄灭了发光器,在黑暗中四散逃开。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"捞到几条墨鱼,不是鱿鱼,但同样是不错的渔获。"/*::END:: */,loot:[{id:"cuttlefish",qty:[1,3]}]} ] } , /* ── 追加变体:同地形不同行为/鱼种 ── */ "hunt_grass_seabass": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["grass","reef","sand"], depthRange:[0,300], baseChance:0.42, fragmentText:/*::GEN::事件碎片:: */"一条鲈鱼悬停在草缘水中,缓慢扫视猎物,尾鳍轻轻拨水保持位置。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 投饵钓取"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"鲈鱼果断咬钩,挣扎有力但技不如人,入舱。"/*::END:: */,loot:[{id:"seabass",qty:[1,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"鲈鱼吐钩逃脱,甩了个漂亮的转身钻进草丛。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"钓到一条,草缘还有另一条受了惊动,也被顺势捞住。"/*::END:: */,loot:[{id:"seabass",qty:[2,3]}]} ] }, "hunt_grass_shrimp": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["grass","sand"], depthRange:[0,200], baseChance:0.52, fragmentText:/*::GEN::事件碎片:: */"草根处有几道透明的身影在移动——对虾在贴地觅食,偶尔停下拨弄什么。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 撒网捕捞"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"一网下去压住草丛,捞起大把对虾,腿脚还在挥舞。"/*::END:: */,loot:[{id:"prawn",qty:[2,5]},{id:"sweetshrimp",qty:[0,2]}]}, {weight:25,text:/*::GEN::事件结果:: */"对虾感受到震动跳弹逃散,只捞到零星几只。"/*::END:: */,loot:[{id:"prawn",qty:[1,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"网里除了对虾,还裹进来几只小螃蟹凑热闹。"/*::END:: */,loot:[{id:"prawn",qty:[1,3]},{id:"swimmingcrab",qty:[1,2]}]} ] }, "hunt_reef_sweetshrimp": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["reef","flat"], depthRange:[0,200], baseChance:0.50, fragmentText:/*::GEN::事件碎片:: */"珊瑚缝隙里透出细长的触须,甜虾正在里面悠闲地进食。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 细网吸引捕捉"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"用细网缓慢靠近,甜虾未及反应就被一扫而入,鲜红甲壳整齐地堆在网底。"/*::END:: */,loot:[{id:"sweetshrimp",qty:[2,4]}]}, {weight:30,text:/*::GEN::事件结果:: */"甜虾有所察觉,后退进更深的缝隙里,无法跟进。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"除了甜虾,珊瑚洞里还有一只小章鱼同框出现,一起入网。"/*::END:: */,loot:[{id:"sweetshrimp",qty:[1,2]},{id:"octopus",qty:[1,1]}]} ] }, "hunt_flat_hermitcrab": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["flat","sand","reef"], depthRange:[0,300], baseChance:0.55, fragmentText:/*::GEN::事件碎片:: */"几只寄居蟹拖着螺壳在岩面上缓行,壳已经磨得发白,但它们还在固执地寻找食物。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 顺手采集"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"这种寄居蟹的螺壳本身也有价值,连蟹带壳一并收入。"/*::END:: */,loot:[{id:"hermitcrab",qty:[1,3]},{id:"shell_frag",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"寄居蟹缩进壳里装死,采到几只,另一些趁机夹缝里躲掉了。"/*::END:: */,loot:[{id:"hermitcrab",qty:[1,2]}]}, {weight:20,text:/*::GEN::事件结果:: */"在这片岩面发现大量寄居蟹,是难得的密集群落。"/*::END:: */,loot:[{id:"hermitcrab",qty:[3,6]},{id:"shell_frag",qty:[2,4]}]} ] }, "hunt_cliff_mantis": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["cliff","flat","reef"], depthRange:[20,500], baseChance:0.45, fragmentText:/*::GEN::事件碎片:: */"壁面凹槽里有濑尿虾在守株待兔,它挥舞着捕肢,颇有气势。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 夹取捕捉"/*::END:: */, outcomes:[ {weight:45,text:/*::GEN::事件结果:: */"机械臂从侧面接近,在它出拳前夹住——这东西打击力惊人,但终究被制服。"/*::END:: */,loot:[{id:"mantisshrimp",qty:[1,2]}]}, {weight:35,text:/*::GEN::事件结果:: */"濑尿虾反应极快,一击敲偏了夹臂,趁势蹦进更深裂缝。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"抓到两只,壳色不同,可能是不同亚种。"/*::END:: */,loot:[{id:"mantisshrimp",qty:[2,3]}]} ] }, "hunt_forest_tuna": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["forest","water"], depthRange:[30,400], baseChance:0.32, fragmentText:/*::GEN::事件碎片:: */"藻林里有道迅疾的鱼影——动线太快,只隐约看到侧身的蓝色光泽,不像寻常鱼类。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 弓网埋伏"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"金枪鱼扑入弓网的那一瞬间惊天动地,舱体都感受到了冲击,但鱼已入舱。"/*::END:: */,loot:[{id:"tuna",qty:[1,1]}]}, {weight:40,text:/*::GEN::事件结果:: */"鱼影转向极快,识破了埋伏方向,消失在林区深处。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"不是金枪鱼,是一条大型鲣鱼,速度稍慢但同样难以对付,最终制服。"/*::END:: */,loot:[{id:"bonito",qty:[1,1]}]} ] }, "hunt_water_mahi": { tier:"C", weight:0.8, subtype:"hunt", smallExplorePoint:{weight:0.8}, terrain:["water","grass"], depthRange:[0,100], baseChance:0.30, regionVariants:{pasture:{name:"牧场鬼头刀(牧场变体1)"},sunken_city:{name:"城市废墟鬼头刀(城市变体1)"}}, fragmentText:/*::GEN::事件碎片:: */"水面附近有大型鱼在高速巡游,灯光边缘捕捉到鲜艳的黄绿色侧身——是鬼头刀。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 拖钓追踪"/*::END:: */, outcomes:[ {weight:40,text:/*::GEN::事件结果:: */"鬼头刀速度极快,但咬饵之后挣扎方向可以预测,最终被拖进网兜。"/*::END:: */,loot:[{id:"mahi",qty:[1,1]}]}, {weight:35,text:/*::GEN::事件结果:: */"鬼头刀在高速中脱钩,溅起一片水花就消失了。"/*::END:: */,loot:[]}, {weight:25,text:/*::GEN::事件结果:: */"钓住一条,脱钩时引来另一条同伴凑近——顺势再下一网。"/*::END:: */,loot:[{id:"mahi",qty:[1,2]}]} ] }, "hunt_sand_clam": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["sand"], depthRange:[0,200], baseChance:0.58, fragmentText:/*::GEN::事件碎片:: */"沙面有几处细小的水流孔在向外喷水,节律均匀——沙蛤埋在下面呼吸。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 挖掘采集"/*::END:: */, outcomes:[ {weight:55,text:/*::GEN::事件结果:: */"顺着喷水孔挖下去,果然有蛤蜊,还不小。"/*::END:: */,loot:[{id:"clam",qty:[2,5]}]}, {weight:25,text:/*::GEN::事件结果:: */"挖到了几只,沙层里还有更多,但深度超出了机械臂范围。"/*::END:: */,loot:[{id:"clam",qty:[1,3]}]}, {weight:20,text:/*::GEN::事件结果:: */"蛤蜊不在喷水孔正下方,顺着侧向扩展挖出来一堆,大小不一。"/*::END:: */,loot:[{id:"clam",qty:[3,7]}]} ] }, "b_grass_shadow": { name:"人鱼的影子", tier:"B", weight:0.2, devOnly:true, subtype:"flavor", terrain:["grass"], depthRule:{type:"nearBottom",value:150}, fragmentText:"(人鱼的影子占位)远处海草摇动之间掠过一道无法确认的影子。", actionLabel:"◎ 远远观察", outcomes:[{weight:1,text:"(人鱼的影子占位)影子消失在海草深处。",loot:[]}] }, "hunt_reef_cuttlefish": { tier:"B", weight:1, subtype:"hunt", smallExplorePoint:{weight:1}, terrain:["reef","flat","grass"], depthRange:[10,300], baseChance:0.44, fragmentText:/*::GEN::事件碎片:: */"珊瑚背面有一只墨鱼停在那里,皮肤上的色彩纹路在缓缓变幻,模仿着礁石表面。"/*::END:: */, actionLabel:/*::GEN::行动标签:: */"◎ 快速包抄"/*::END:: */, outcomes:[ {weight:50,text:/*::GEN::事件结果:: */"墨鱼被围住来不及伪装,喷出一团墨云,但在黑暗里它已经离不开了。"/*::END:: */,loot:[{id:"cuttlefish",qty:[1,2]}]}, {weight:30,text:/*::GEN::事件结果:: */"墨鱼在喷墨的掩护下高速侧移,成功脱逃。"/*::END:: */,loot:[]}, {weight:20,text:/*::GEN::事件结果:: */"墨鱼被捕,墨云里顺带裹出来两只小虾。"/*::END:: */,loot:[{id:"cuttlefish",qty:[1,1]},{id:"prawn",qty:[1,2]}]} ] } }>> /* 所有微事件预留区域变体入口;微事件默认不占持续地图区间。 */ <<set _meKeys = Object.keys($microEventDefs)>> <<set $smallExplorePointDefs = {}>> <<for _mei = 0; _mei < _meKeys.length; _mei++>> <<set _meId = _meKeys[_mei]>><<set _meDef = $microEventDefs[_meId]>> <<if !_meDef.regionVariants>><<set _meDef.regionVariants = {}>><</if>> /* 从原始微型事件池派生探索页面专用池,只保存原事件引用。 */ <<if _meDef.smallExplorePoint && !_meDef.devOnly>> <<set $smallExplorePointDefs[_meId] = _meDef>> <</if>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "npcDefs">> /* ══════════════════════════════════ NPC 定义表 $npcDefTable 字段说明: id 唯一标识 name 显示名 type "trader" / "drifter" / "salvager" spawnCtx 出现上下文 ["sailing","anchored"] condition 出现条件(JS 字符串,返回 bool) cooldownDays 同一 NPC 再次出现的冷却天数 weight 出现权重 greeting 初次见面台词池 reGreeting 再次见面台词池 chat 闲聊台词池(随机取1) tradeComment 进入商店时台词池 buyComment 购买后台词池 shop 商品列表 [{id, name, price, qty}] price 单位:珍珠数量 sideQuestId 绑定的支线 ID(可选,触发 questCheck "npcMet") ══════════════════════════════════ */ <<set $npcDefTable = { /* ── 水面补给船:靠近水面时出现的小型贸易船 ── */ "supply_drifter": { id: "supply_drifter", name: /*::GEN::NPC名:: */"漂泊补给船"/*::END:: */, type: "trader", spawnCtx: ["sailing", "anchored"], condition: "$depth <= 100", cooldownDays: 3, weight: 20, greeting: [/*::GEN::greeting:: */"嘿,独自出海?真有胆量。我有些物资,看你需不需要。"/*::END:: */, /*::GEN::greeting:: */"哟,这片海域不常见到你这样的船。有兴趣交易吗?"/*::END:: */], reGreeting: [/*::GEN::reGreeting:: */"又见面了。东西还够不够用?"/*::END:: */, /*::GEN::reGreeting:: */"老朋友!我这次进了些新货。"/*::END:: */], chat: [/*::GEN::chat:: */"这片海最近不太平,听说南边有什么大家伙出没。"/*::END:: */, /*::GEN::chat:: */"珍珠越来越值钱了,有人在大量收购,也不知道干什么用。"/*::END:: */, /*::GEN::chat:: */"我在海上漂了二十年,什么稀奇古怪的东西都见过。"/*::END:: */], tradeComment: [/*::GEN::tradeComment:: */"都是实用的东西,价格公道。"/*::END:: */, /*::GEN::tradeComment:: */"挑吧,不合适的我不勉强。"/*::END:: */], buyComment: [/*::GEN::buyComment:: */"好眼光。"/*::END:: */, /*::GEN::buyComment:: */"这东西值。"/*::END:: */, /*::GEN::buyComment:: */"拿好,用得上的。"/*::END:: */], shop: [ { id: "fish_oil", name: "鱼油", price: 2, qty: 6 }, { id: "wreck_wood", name: /*::GEN::商品名:: */"沉船木材"/*::END:: */, price: 1, qty: 5 }, { id: "rubber_seal", name: /*::GEN::商品名:: */"橡胶密封件"/*::END:: */,price: 3, qty: 3 }, { id: "metal", name: /*::GEN::商品名:: */"金属材料"/*::END:: */, price: 1, qty: 8 } ], sideQuestId: null }, /* ── 深海废品商:只在深水区出现 ── */ "deep_salvager": { id: "deep_salvager", name: /*::GEN::NPC名:: */"深渊废品商"/*::END:: */, type: "salvager", spawnCtx: ["anchored"], condition: "$depth >= 150", cooldownDays: 5, weight: 10, greeting: [/*::GEN::greeting:: */"你也来这深处淘东西?我收购残骸零件,也卖些稀罕货。"/*::END:: */, /*::GEN::greeting:: */"黑暗里什么都有,就看你敢不敢捡。"/*::END:: */], reGreeting: [/*::GEN::reGreeting:: */"又下来了。深水让人上瘾,不是吗?"/*::END:: */, /*::GEN::reGreeting:: */"嘿,还活着。那就做生意吧。"/*::END:: */], chat: [/*::GEN::chat:: */"越深的地方,东西越好。也越危险。"/*::END:: */, /*::GEN::chat:: */"我在这里见过没有名字的东西。它没伤我,我也没惹它。"/*::END:: */, /*::GEN::chat:: */"据说最深处有一片发光的平原。没人能证实,但也没人否认。"/*::END:: */], tradeComment: [/*::GEN::tradeComment:: */"残骸出来的东西,各有各的故事。"/*::END:: */, /*::GEN::tradeComment:: */"不要问这些东西从哪来的。"/*::END:: */], buyComment: [/*::GEN::buyComment:: */"明智的选择。"/*::END:: */, /*::GEN::buyComment:: */"这东西在深处很难找的。"/*::END:: */], shop: [ { id: "wreck_steel", name: /*::GEN::商品名:: */"沉船钢材"/*::END:: */, price: 3, qty: 4 }, { id: "iron", name: "铁块", price: 2, qty: 6 }, { id: "glass", name: "玻璃", price: 2, qty: 4 }, { id: "relic_log", name: /*::GEN::商品名:: */"古旧航行日志"/*::END:: */,price: 8, qty: 2 } ], sideQuestId: null }, /* ── 维奥娜:肉铺 ── */ "viona_butcher": { id: "viona_butcher", name: /*::GEN::NPC名:: */"维奥娜"/*::END:: */, type: "trader", spawnCtx: ["sailing", "anchored"], condition: "always", cooldownDays: 4, weight: 15, greeting: [/*::GEN::greeting:: */"总之……请随便看。"/*::END:: */, /*::GEN::greeting:: */"今天不会给你优惠的。"/*::END:: */, /*::GEN::greeting:: */"我有闻到你身上的海腥味……抱歉,对我来说很恶心。"/*::END:: */, /*::GEN::greeting:: */"是不是有几天没来了?好好吃饭对每个人都很重要。"/*::END:: */, /*::GEN::greeting:: */"是不是来得太频繁了?没法做出好吃的东西的话,多多反思自己吧。"/*::END:: */], reGreeting: [/*::GEN::reGreeting:: */"总之……请随便看。"/*::END:: */, /*::GEN::reGreeting:: */"今天不会给你优惠的。"/*::END:: */, /*::GEN::reGreeting:: */"是不是有几天没来了?好好吃饭对每个人都很重要。"/*::END:: */, /*::GEN::reGreeting:: */"是不是来得太频繁了?没法做出好吃的东西的话,多多反思自己吧。"/*::END:: */], chat: [/*::GEN::chat:: */"越新鲜的东西,越考验厨师的手艺。刚好我很勤劳,而你很优秀。"/*::END:: */, /*::GEN::chat:: */"这些东西对你的资产来说,贵了吧?"/*::END:: */, /*::GEN::chat:: */"我有段时间非常、非常地饥饿,甚至连在吃肉之前去烹饪的耐心都没有……因此,我保证本店所售的肉,绝对地适合生食。"/*::END:: */, /*::GEN::chat:: */"你饿吗?饿了才来买食材,是不会规划时间的表现。"/*::END:: */], tradeComment: [/*::GEN::tradeComment:: */"越新鲜的东西,越考验厨师的手艺。刚好我很勤劳,而你很优秀。"/*::END:: */, /*::GEN::tradeComment:: */"这些东西对你的资产来说,贵了吧?"/*::END:: */, /*::GEN::tradeComment:: */"我有段时间非常、非常地饥饿,甚至连在吃肉之前去烹饪的耐心都没有……因此,我保证本店所售的肉,绝对地适合生食。"/*::END:: */, /*::GEN::tradeComment:: */"你饿吗?饿了才来买食材,是不会规划时间的表现。"/*::END:: */], buyComment: [/*::GEN::buyComment:: */"其实我很想尝尝你会做出什么样的食物……如果有机会的话。"/*::END:: */, /*::GEN::buyComment:: */"总得来说……就是这些。"/*::END:: */, /*::GEN::buyComment:: */"总感觉味道很香呢……它们会变成美味的食物的。"/*::END:: */, /*::GEN::buyComment:: */"你很需要的话……也不能给你赠品。我不是慈善家。"/*::END:: */, /*::GEN::buyComment:: */"再见。请规律且健康地来购物。"/*::END:: */], shop: [ { id: "pork", name: "猪肉", price: 2, qty: 5 }, { id: "lamb", name: "羊肉", price: 3, qty: 4 }, { id: "beef", name: "牛肉", price: 4, qty: 3 }, { id: "fish_bone", name: "鱼骨",price: 1, qty: 6 } ], sideQuestId: null } }>> <</widget>> <</nobr>>
<<nobr>> <<widget "questDefs">> /* ══════════════════════════════════ 主线任务链 $questChain 每个节点字段: id 唯一标识 title 日记标题 logEntry 触发时写入日记的文字(第一人称日记体) completedLog 完成后追加的文字 trigger 触发条件:{type, ...} type:"auto" — 满足 condition 后自动触发 type:"item" — 拾取指定物品 type:"wsChild" — 完成指定 wsChild type:"flag" — questFlags 中某个旗标为 true type:"npcMet" — 首次与指定 NPC 相遇 condition 前置条件检查字符串(JS 表达式,可用 $questProgress) worldHook 挂载到某个 worldScene/largeScene 作为触发点 {wsId:"wreck_site", childId:"mq_q01_wsChild"} reward 完成奖励 [{id,qty:[min,max]}] ══════════════════════════════════ */ <<set $questChain = [ /* ── 第0节:序章(自动触发,游戏开始时)── */ { id: "mq_00_prologue", title: /*::GEN::任务标题:: */"第1段主线"/*::END:: */, logEntry: /*::GEN::任务日记:: */"【占位】第1段主线日记文本。触发条件:auto(每次下水自动推进)。"/*::END:: */, completedLog: /*::GEN::完成日记:: */"【占位】第1段主线完成后追加文字。"/*::END:: */, trigger: { type: "auto" }, condition: "always", worldHook: null, reward: [] }, /* ── 第1节:漂流瓶(中型事件触发,需出仓)── */ { id: "mq_01_drift_bottle", title: /*::GEN::任务标题:: */"第2段主线"/*::END:: */, logEntry: /*::GEN::任务日记:: */"【占位】第2段主线日记文本。触发条件:wsChild(完成特定中型事件子节点 mq_q00_complete)。"/*::END:: */, completedLog: /*::GEN::完成日记:: */"【占位】第2段主线完成后追加文字。"/*::END:: */, trigger: { type: "wsChild", childId: "mq_q00_complete" }, condition: "$questProgress === 0", worldHook: null, reward: [] }, /* ── 第2节:占位节点 C(支线触发可以用同样结构)── */ { id: "mq_02_placeholder", title: /*::GEN::任务标题:: */"第3段主线"/*::END:: */, logEntry: /*::GEN::任务日记:: */"【占位】第3段主线日记文本。触发条件:flag(mq_01_found_ruin旗标)。"/*::END:: */, completedLog: /*::GEN::完成日记:: */"【占位】第3段主线完成后追加文字。"/*::END:: */, trigger: { type: "flag", flag: "mq_01_found_ruin" }, condition: "$questProgress === 1", worldHook: null, reward: [] } ]>> /* ══════════════════════════════════ 支线任务定义 $sideQuestDefs 每条支线绑定一个 NPC(或地点) nodes 数组结构与主线节点相同 ══════════════════════════════════ */ <<set $sideQuestDefs = { "sq_placeholder_npc": { npcId: "placeholder_npc", title: /*::GEN::任务标题:: */"【占位·支线·陌生商人】"/*::END:: */, nodes: [ { id: "sq_pnpc_00", title: /*::GEN::任务标题:: */"初次相遇"/*::END:: */, logEntry: /*::GEN::任务日记:: */"(施工中)支线第一节日记占位。第一次遇到了这个人,他说了些让我在意的话。"/*::END:: */, completedLog: /*::GEN::完成日记:: */"(施工中)支线第一节完成。"/*::END:: */, trigger: { type: "npcMet", npcId: "placeholder_npc" }, condition: "always", reward: [] }, { id: "sq_pnpc_01", title: "委托", logEntry: /*::GEN::任务日记:: */"(施工中)支线第二节日记占位。他托付给我一件事。"/*::END:: */, completedLog: /*::GEN::完成日记:: */"(施工中)支线第二节完成。"/*::END:: */, trigger: { type: "flag", flag: "sq_pnpc_met_twice" }, condition: "always", reward: [] } ] } }>> <</widget>> <</nobr>>
/* ── 特殊食谱标记(精确ID匹配,会影响模板名称标记,不覆盖模板) ── 这里的 specificRecipes 现在仅用于"记录",未来可扩展为特殊效果触发 */ <<set $specificRecipes = [ { id:"urchin_raw", name:/*::GEN::食谱名:: */"海胆生食"/*::END:: */, ingredients:["urchin_roe"], methods:["生食"], bonusSan:3 }, { id:"tuna_sashimi",name:/*::GEN::食谱名:: */"蓝鳍刺身"/*::END:: */, ingredients:["tuna_meat"], methods:["生食"], bonusSan:2 }, { id:"ink_stew", name:/*::GEN::食谱名:: */"墨汁海鲜锅"/*::END:: */, ingredients:["squid_meat"], methods:["铜锅炖"], bonusMagic:2 } ]>> /* ── 烹饪过程描述(六种方式) ── */ <<set $cookDesc = { "明火烤": [ { ratio:0, text:/*::GEN::烹饪描述:: */"食材刚放上烤架,几乎没有任何变化。"/*::END:: */ }, { ratio:0.1, text:/*::GEN::烹饪描述:: */"表面开始受热,油脂渗出,轻微的滋滋声传来。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::烹饪描述:: */"香气渐渐散开,外层开始变色。"/*::END:: */ }, { ratio:0.45, text:/*::GEN::烹饪描述:: */"色泽渐渐金黄,油脂在表面冒泡,香味浓郁——差不多了。"/*::END:: */ }, { ratio:0.6, text:/*::GEN::烹饪描述:: */"火候正好,这是完美的时机。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::烹饪描述:: */"边缘开始焦化,再不收手就会过了。"/*::END:: */ }, { ratio:0.88, text:/*::GEN::烹饪描述:: */"烟气变大,已经有点焦了。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::烹饪描述:: */"烤焦了,黑色的烟从烤架上升起。"/*::END:: */ } ], "铜锅炖": [ { ratio:0, text:/*::GEN::烹饪描述:: */"锅里还是冷的,食材沉在底部。"/*::END:: */ }, { ratio:0.1, text:/*::GEN::烹饪描述:: */"细小气泡从锅底涌起,食材的香气随热气飘散。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::烹饪描述:: */"汤汁开始沸腾,食材慢慢变软,鲜味融入汤底。"/*::END:: */ }, { ratio:0.45, text:/*::GEN::烹饪描述:: */"咕嘟声均匀,舱室里弥漫着温暖的香气——差不多了。"/*::END:: */ }, { ratio:0.6, text:/*::GEN::烹饪描述:: */"正是最佳时机,汤底鲜浓而不过分浓稠。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::烹饪描述:: */"食材开始软烂,汤汁越来越浓,要糊了。"/*::END:: */ }, { ratio:0.88, text:/*::GEN::烹饪描述:: */"已经能闻到焦糊味了,锅底快糊了。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::烹饪描述:: */"锅底已经糊了,焦糊味盖过一切。"/*::END:: */ } ], "清蒸": [ { ratio:0, text:/*::GEN::烹饪描述:: */"蒸汽刚开始上升,食材还是凉的。"/*::END:: */ }, { ratio:0.1, text:/*::GEN::烹饪描述:: */"蒸汽稳定,锅盖凝结水珠,食材颜色开始变化。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::烹饪描述:: */"食材外层已熟,蒸汽带着鲜香扑面而来。"/*::END:: */ }, { ratio:0.45, text:/*::GEN::烹饪描述:: */"鲜味完全锁在里面——差不多了。"/*::END:: */ }, { ratio:0.6, text:/*::GEN::烹饪描述:: */"恰好熟透,肉质紧实而嫩,正是最佳时机。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::烹饪描述:: */"开始过熟,食材变软塌,汁水流失。"/*::END:: */ }, { ratio:0.88, text:/*::GEN::烹饪描述:: */"已经蒸过头了,质地在退化。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::烹饪描述:: */"完全蒸烂了,失去了原本的鲜嫩。"/*::END:: */ } ], "煎炒": [ { ratio:0, text:/*::GEN::烹饪描述:: */"锅还没热,食材放进去也不会有任何反应。"/*::END:: */ }, { ratio:0.1, text:/*::GEN::烹饪描述:: */"锅底开始升温,油脂受热流动,香气初现。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::烹饪描述:: */"锅气升腾,食材开始变色,翻炒的声音越来越响。"/*::END:: */ }, { ratio:0.45, text:/*::GEN::烹饪描述:: */"外层已经上色,锅气将鲜香逼进了食材里——差不多了。"/*::END:: */ }, { ratio:0.6, text:/*::GEN::烹饪描述:: */"火候完美,食材外焦里嫩,香气达到顶峰。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::烹饪描述:: */"时间有点长了,食材开始变老变硬。"/*::END:: */ }, { ratio:0.88, text:/*::GEN::烹饪描述:: */"锅底开始冒烟,焦糊的气味渐渐盖过食材香气。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::烹饪描述:: */"锅底糊了,食材已经无法挽救。"/*::END:: */ } ], "油炸": [ { ratio:0, text:/*::GEN::烹饪描述:: */"油温还不够,食材放进去只会吸油而不会酥化。"/*::END:: */ }, { ratio:0.1, text:/*::GEN::烹饪描述:: */"油温上升,细小的气泡开始在食材周围涌现。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::烹饪描述:: */"气泡变密,食材外层开始酥化,颜色逐渐变黄。"/*::END:: */ }, { ratio:0.45, text:/*::GEN::烹饪描述:: */"外层已经金黄,内里差不多熟透——差不多了。"/*::END:: */ }, { ratio:0.6, text:/*::GEN::烹饪描述:: */"完美的金黄,酥脆而不焦糊,正是最佳时机。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::烹饪描述:: */"颜色开始加深,再不捞出就会变苦。"/*::END:: */ }, { ratio:0.88, text:/*::GEN::烹饪描述:: */"已经有点焦了,苦味会盖过食材本身的香气。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::烹饪描述:: */"炸焦了,已经没有挽救的可能。"/*::END:: */ } ], "生食": [ { ratio:0, text:/*::GEN::烹饪描述:: */"仔细检视食材,确认新鲜度与处理方式。"/*::END:: */ }, { ratio:0.25, text:/*::GEN::烹饪描述:: */"处理食材,去除不可食用的部分,刀工决定最终呈现。"/*::END:: */ }, { ratio:0.5, text:/*::GEN::烹饪描述:: */"细心切割,保留最鲜嫩的部分,摆盘初具雏形。"/*::END:: */ }, { ratio:0.75, text:/*::GEN::烹饪描述:: */"摆盘完成,看起来很不错——可以了。"/*::END:: */ }, { ratio:0.9, text:/*::GEN::烹饪描述:: */"已经处理好了,放置太久会影响新鲜度。"/*::END:: */ }, { ratio:1.0, text:/*::GEN::烹饪描述:: */"食材开始变质,应该早点结束。"/*::END:: */ } ] }>>
<<nobr>> <<widget "smallEventTable">> /* ═══════════════════════════════════════════════ 小型场景定义表 $smallEventDefs 统一数据结构(随机型 + 固定型 Location 合并): id 唯一标识 name 显示名 type "random"(概率触发)/ "fixed"(Location固定实例) terrain 适用地形数组 depthRange [min, max] 深度范围 context ["sailing","anchored","outside"] 触发上下文 baseChance 概率型事件的触发概率(fixed型不用) approachRange 接近范围(原始值,默认300=6可见坐标) spanLength 可锚定长度(原始值,默认400=8可见坐标) approachHint 接近提示(独立出现时) leaveHint 远离提示(独立出现时) stages 互动阶段 [{desc, actions}] resolve 选项结果 {action: {nextStage, loot, timeCost, text, ...}} 独立出现时三段距离:接近6 · 长度8 · 远离6(可见坐标) 作为中型内房间时:无距离,焦点内联 自定义接口(预留,注释状态): trigger "anchor"(锚定进入)/ "interrupt"(强制中断) instance 实例规则 {mode, key} gotoScene 可选:跳转独立passage(复杂Location用) onEnter 可选:进入时脚本 onResolve 可选:解析后脚本 ═══════════════════════════════════════════════ */ <<set $smallEventDefs = { /* ══ B 类占位 SmallScene:第一批只供 DEV 验证,正常航行待正式池开放 ══ */ "b_sand_ring": { name:"沙海床怪圈", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["sand"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, mapSpan:{approach:300,active:800,leave:300}, regionVariants:{}, danger:false, stages:[{desc:"(沙海床怪圈占位)海床上出现规则而巨大的圆环痕迹。",actions:["观察扫描","接近互动","绕行离开"]}], resolve:{"观察扫描":{nextStage:-1,loot:[],text:"(沙海床怪圈占位)扫描结果待填充。"},"接近互动":{nextStage:-1,loot:[],text:"(沙海床怪圈占位)互动结果待填充。"},"绕行离开":{nextStage:-1,loot:[],text:"(沙海床怪圈占位)你绕开了怪圈。"}} }, "b_sand_scene": { name:"沙海床小景", type:"random", tier:"B", weight:3, devOnly:true, sceneType:"small", terrain:["sand"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, mapSpan:{approach:200,active:900,leave:300}, regionVariants:{}, danger:false, stages:[{desc:"(沙海床小景占位)沙地上有一处值得短暂停留的细小景观。",actions:["查看","收集","离开"]}], resolve:{"查看":{nextStage:-1,loot:[],text:"(沙海床小景占位)景观细节待填充。"},"收集":{nextStage:-1,loot:[],text:"(沙海床小景占位)少量收集结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(沙海床小景占位)你继续航行。"}} }, "b_flat_ambusher": { name:"伏击者", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["flat"], context:["sailing"], depthRule:{type:"nearBottom",value:100}, mapSpan:{approach:200,active:1400,leave:500}, regionVariants:{}, danger:true, interrupt:true, stages:[{desc:"(伏击者占位)海床突然弹起,覆盖甲壳的扁平生物朝潜艇冲来。",actions:["紧急规避","反击猎杀","承受冲击撤离"]}], resolve:{"紧急规避":{nextStage:-1,loot:[],text:"(伏击者占位)你及时规避了冲刺。"},"反击猎杀":{nextStage:-1,loot:[],text:"(伏击者占位)猎杀结果待填充。"},"承受冲击撤离":{nextStage:-1,loot:[],text:"(伏击者占位)潜艇受到的损伤结果待填充。"}} }, "b_flat_flashbed": { name:"闪烁海床", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["flat"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(闪烁海床占位)海床上的软体动物同步张合,整片海床忽明忽暗。",actions:["观察","采集","离开"]}], resolve:{"观察":{nextStage:-1,loot:[],text:"(闪烁海床占位)观察结果待填充。"},"采集":{nextStage:-1,loot:[],text:"(闪烁海床占位)采集结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(闪烁海床占位)你离开了闪烁海床。"}} }, "b_flat_scene": { name:"岩海床小景", type:"random", tier:"B", weight:3, devOnly:true, sceneType:"small", terrain:["flat"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(岩海床小景占位)岩海床上有一处短暂吸引注意的景观。",actions:["查看","互动","离开"]}], resolve:{"查看":{nextStage:-1,loot:[],text:"(岩海床小景占位)查看结果待填充。"},"互动":{nextStage:-1,loot:[],text:"(岩海床小景占位)互动结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(岩海床小景占位)你继续航行。"}} }, "b_grass_manatee": { name:"海牛", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["grass"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(海牛占位)海草间出现一只体型庞大的海牛,正在缓慢觅食。",actions:["观察互动","尝试照料","猎取离开"]}], resolve:{"观察互动":{nextStage:-1,loot:[],text:"(海牛占位)互动结果待填充。"},"尝试照料":{nextStage:-1,loot:[],text:"(海牛占位)照料结果待填充。"},"猎取离开":{nextStage:-1,loot:[],text:"(海牛占位)猎取结果待填充。"}} }, "b_grass_scene": { name:"海草床小景", type:"random", tier:"B", weight:3, devOnly:true, sceneType:"small", terrain:["grass"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(海草床小景占位)海草在稳定水流中形成一片有秩序的景观。",actions:["查看","采集","离开"]}], resolve:{"查看":{nextStage:-1,loot:[],text:"(海草床小景占位)查看结果待填充。"},"采集":{nextStage:-1,loot:[],text:"(海草床小景占位)采集结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(海草床小景占位)你继续航行。"}} }, "b_reef_spawning": { name:"珊瑚产卵", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["reef"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, seasonRule:{enabled:false,include:[1]}, danger:false, stages:[{desc:"(珊瑚产卵占位)珊瑚礁进入年度同步产卵时段。",actions:["观察","采集样本","离开"]}], resolve:{"观察":{nextStage:-1,loot:[],text:"(珊瑚产卵占位)观察结果待填充。"},"采集样本":{nextStage:-1,loot:[],text:"(珊瑚产卵占位)采样结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(珊瑚产卵占位)你离开了产卵场。"}} }, "b_reef_cleaning": { name:"清洁站", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["reef"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(清洁站占位)小鱼围绕大型鱼类往返,形成一处繁忙的清洁站。",actions:["保持距离观察","靠近互动","离开"]}], resolve:{"保持距离观察":{nextStage:-1,loot:[],text:"(清洁站占位)观察结果待填充。"},"靠近互动":{nextStage:-1,loot:[],text:"(清洁站占位)互动结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(清洁站占位)你离开了清洁站。"}} }, "b_reef_scene": { name:"珊瑚礁小景", type:"random", tier:"B", weight:3, devOnly:true, sceneType:"small", terrain:["reef"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(珊瑚礁小景占位)珊瑚礁中有一处色彩和结构都很特别的景观。",actions:["查看","互动","离开"]}], resolve:{"查看":{nextStage:-1,loot:[],text:"(珊瑚礁小景占位)查看结果待填充。"},"互动":{nextStage:-1,loot:[],text:"(珊瑚礁小景占位)互动结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(珊瑚礁小景占位)你继续航行。"}} }, "b_forest_plant": { name:"特殊可采集植物", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["forest"], context:["sailing","anchored","outside"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(特殊可采集植物占位)海藻森林深处有一种不属于普通生态的植物。",actions:["观察","采集","谨慎离开"]}], resolve:{"观察":{nextStage:-1,loot:[],text:"(特殊可采集植物占位)观察结果待填充。"},"采集":{nextStage:-1,loot:[],text:"(特殊可采集植物占位)采集结果待填充。"},"谨慎离开":{nextStage:-1,loot:[],text:"(特殊可采集植物占位)你没有贸然接近。"}} }, "b_forest_urchin": { name:"海胆泛滥", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["forest"], context:["sailing","anchored","outside"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(海胆泛滥占位)海藻林下方铺满海胆,几乎没有可以落脚的空隙。",actions:["清理采集","绕行观察","离开"]}], resolve:{"清理采集":{nextStage:-1,loot:[],text:"(海胆泛滥占位)清理与收获结果待填充。"},"绕行观察":{nextStage:-1,loot:[],text:"(海胆泛滥占位)观察结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(海胆泛滥占位)你绕开了这片区域。"}} }, "b_forest_scene": { name:"海藻森林小景", type:"random", tier:"B", weight:4, devOnly:true, sceneType:"small", terrain:["forest"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(海藻森林小景占位)高大的海藻与水流构成一处幽暗景观。",actions:["查看","互动","离开"]}], resolve:{"查看":{nextStage:-1,loot:[],text:"(海藻森林小景占位)查看结果待填充。"},"互动":{nextStage:-1,loot:[],text:"(海藻森林小景占位)互动结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(海藻森林小景占位)你继续航行。"}} }, "b_cliff_monster": { name:"海怪逡巡", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["cliff"], context:["sailing"], depthRule:{type:"any"}, mapSpan:{approach:400,active:2400,leave:600}, regionVariants:{}, danger:true, interrupt:false, stages:[{desc:"(海怪逡巡占位)峭壁外侧有危险生物缓慢巡游,像是在寻找什么。",actions:["保持距离观察","尝试追踪","离开"]}], resolve:{"保持距离观察":{nextStage:-1,loot:[],text:"(海怪逡巡占位)观察结果待填充。"},"尝试追踪":{nextStage:-1,loot:[],text:"(海怪逡巡占位)追踪结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(海怪逡巡占位)你没有惊动它。"}} }, "b_cliff_nest": { name:"巢穴", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["cliff"], context:["sailing","anchored","outside"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(巢穴占位)峭壁凹陷里嵌着一个看不清内部的深巢。",actions:["观察","探查巢穴","离开"]}], resolve:{"观察":{nextStage:-1,loot:[],text:"(巢穴占位)观察结果待填充。"},"探查巢穴":{nextStage:-1,loot:[],text:"(巢穴占位)探查结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(巢穴占位)你离开了巢穴。"}} }, "b_cliff_scene": { name:"峭壁小景", type:"random", tier:"B", weight:1, devOnly:true, sceneType:"small", terrain:["cliff"], context:["sailing","anchored"], depthRule:{type:"nearBottom",value:100}, danger:false, stages:[{desc:"(峭壁小景占位)峭壁与悬浮碎石组成一处不稳定的景观。",actions:["查看","记录","离开"]}], resolve:{"查看":{nextStage:-1,loot:[],text:"(峭壁小景占位)查看结果待填充。"},"记录":{nextStage:-1,loot:[],text:"(峭壁小景占位)记录结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(峭壁小景占位)你继续航行。"}} }, "b_abyss_fish_scene": { name:"深海鱼小景", type:"random", tier:"B", weight:3, devOnly:true, sceneType:"small", terrain:["abyss"], context:["sailing","anchored"], depthRule:{type:"minDepth",value:500}, danger:false, stages:[{desc:"(深海鱼小景占位)深渊黑暗中有一群不属于浅海的鱼类缓慢游过。",actions:["观察","记录","离开"]}], resolve:{"观察":{nextStage:-1,loot:[],text:"(深海鱼小景占位)观察结果待填充。"},"记录":{nextStage:-1,loot:[],text:"(深海鱼小景占位)记录结果待填充。"},"离开":{nextStage:-1,loot:[],text:"(深海鱼小景占位)你继续航行。"}} }, /* ══ 随机型 SmallScene ══ */ "bream_school": { tier:"B", weight:1, sceneType:"small", name: /*::GEN::事件名:: */"鲷鱼群"/*::END:: */, type: "random", terrain: ["reef","grass"], depthRange: [0,150], context: ["sailing","anchored"], baseChance: 0.003, regionVariants:{reef_eternal:{name:"永夜礁石鲷鱼群(礁石变体1)"},pasture:{name:"牧场鲷鱼群(牧场变体1)"},salt_lake:{name:"盐湖鲷鱼群(盐湖变体1)"}}, approachRange: 300, spanLength: 400, approachHint: "声呐捕捉到密集的鱼群回波——前方是鲷鱼洄游群落。", leaveHint: "鱼群的回波在身后渐渐消散。", stages: [ { desc: /*::GEN::事件描述:: */"声呐捕捉到密集的鱼群回波,雷达确认是鲷鱼洄游群落,数量可观。停在这里可以展开渔网捕捞。"/*::END:: */, actions: [/*::GEN::行动选项:: */"展开渔网(第一轮)"/*::END:: */,/*::GEN::行动选项:: */"声呐标记后离开"/*::END:: */] }, { desc: /*::GEN::事件描述:: */"第一轮渔网收回,舱底多了些银光——鲷鱼还没散,还有机会再捞一次。"/*::END:: */, actions: [/*::GEN::行动选项:: */"再次捕捞(最后一轮)"/*::END:: */,/*::GEN::行动选项:: */"收网离开"/*::END:: */] }, { desc: /*::GEN::事件描述:: */"两轮捕捞后鱼群已经散开,只剩零星游鱼。这一片的收益已经见底了。"/*::END:: */, actions: [/*::GEN::行动选项:: */"收网离开"/*::END:: */] } ], resolve: { "展开渔网(第一轮)": { nextStage:1, loot:[{id:"bream",qty:[2,5]},{id:"seabass",qty:[0,2]}], timeCost:15, text:/*::GEN::事件结果:: */"第一轮渔获不错。"/*::END:: */ }, "声呐标记后离开": { nextStage:-1, loot:[], text:/*::GEN::事件结果:: */"在导航板上标记了此处坐标后离开。"/*::END:: */ }, "再次捕捞(最后一轮)":{ nextStage:2, loot:[{id:"bream",qty:[1,4]},{id:"grouper",qty:[0,2]}], text:/*::GEN::事件结果:: */"鱼群渐稀,但收获依然可观。"/*::END:: */ }, "收网离开": { nextStage:-1, loot:[], text:/*::GEN::事件结果:: */"收起渔网,离开了这片水域。"/*::END:: */ } } }, "crab_cluster": { tier:"B", weight:1, sceneType:"small", name: /*::GEN::事件名:: */"螃蟹聚集"/*::END:: */, type: "random", terrain: ["flat","sand"], depthRange: [0,200], context: ["sailing","anchored"], baseChance: 0.0025, regionVariants:{wreck_graveyard:{name:"沉船坟场螃蟹聚集(沉船变体1)"},sunken_city:{name:"城市废墟螃蟹聚集(城市变体1)"},salt_lake:{name:"盐湖螃蟹聚集(盐湖变体1)"}}, approachRange: 300, spanLength: 400, approachHint: "声呐探测到海底密集的小型移动目标——前方有螃蟹聚集。", leaveHint: "蟹群的信号在身后消失。", stages: [ { desc: /*::GEN::事件描述:: */"岩礁附近聚集着大量螃蟹,正在争抢什么腐食。放诱捕笼等候是个好主意。"/*::END:: */, actions: [/*::GEN::行动选项:: */"放置诱捕笼"/*::END:: */,/*::GEN::行动选项:: */"直接驱网捕捞"/*::END:: */,/*::GEN::行动选项:: */"观察后离开"/*::END:: */] }, { desc: /*::GEN::事件描述:: */"诱捕笼放下约十分钟后,里面已经聚满了贪吃的螃蟹。"/*::END:: */, actions: [/*::GEN::行动选项:: */"收取诱捕笼"/*::END:: */] } ], resolve: { "放置诱捕笼": { nextStage:1, loot:[], text:/*::GEN::事件结果:: */"诱捕笼已放置,静候片刻。"/*::END:: */ }, "直接驱网捕捞": { nextStage:-1, loot:[{id:"bluecrab",qty:[1,3]},{id:"swimmingcrab",qty:[0,2]}], text:/*::GEN::事件结果:: */"驱网捕到不少,但也惊散了一些。"/*::END:: */ }, "观察后离开": { nextStage:-1, loot:[], text:/*::GEN::事件结果:: */"观察了一会儿,记下了蟹群的迁徙规律。"/*::END:: */ }, "收取诱捕笼": { nextStage:-1, loot:[{id:"bluecrab",qty:[2,5]},{id:"flowercrab",qty:[0,2]},{id:"kingcrab",qty:[0,1]}], text:/*::GEN::事件结果:: */"诱捕笼的收获丰厚,甚至有一只帝王蟹挤了进来。"/*::END:: */ } } }, "vent_harvest": { tier:"B", weight:1, sceneType:"small", name: /*::GEN::事件名:: */"热液区采集"/*::END:: */, type: "random", terrain: ["flat","cliff"], depthRange: [300,10000], context: ["sailing","anchored","outside"], baseChance: 0.002, regionVariants:{hydrothermal:{name:"热液区采集(热液变体1)"},salt_lake:{name:"盐湖矿物采集(盐湖变体1)"}}, approachRange: 300, spanLength: 400, approachHint: "水温异常升高,前方有热液喷口活动。", leaveHint: "热液的温度在身后逐渐恢复正常。", stages: [ { desc: /*::GEN::事件描述:: */"探照灯照亮了一处活跃的热液喷口区域,周围遍布化学合成生物群落,矿物质堆积肉眼可见。"/*::END:: */, actions: [/*::GEN::行动选项:: */"采集表层样本"/*::END:: */,/*::GEN::行动选项:: */"靠近深入探查"/*::END:: */,/*::GEN::行动选项:: */"保持距离离开"/*::END:: */] }, { desc: /*::GEN::事件描述:: */"靠近后发现喷口内侧有更浓缩的矿物堆积,成分更为复杂。温度极高,需小心操作。"/*::END:: */, actions: [/*::GEN::行动选项:: */"采集浓缩矿物"/*::END:: */,/*::GEN::行动选项:: */"谨慎撤退"/*::END:: */] } ], resolve: { "采集表层样本": { nextStage:-1, loot:[{id:"sulfur_dust",qty:[1,3]},{id:"thermal_ext",qty:[1,2]}], text:/*::GEN::事件结果:: */"采集到表层矿物和热液提取物。"/*::END:: */ }, "靠近深入探查": { nextStage:1, loot:[{id:"sulfur_dust",qty:[1,2]}], text:/*::GEN::事件结果:: */"靠近了喷口,发现内层矿物更为稀有。"/*::END:: */ }, "保持距离离开": { nextStage:-1, loot:[], text:/*::GEN::事件结果:: */"谨慎起见,记录了坐标后离开。"/*::END:: */ }, "采集浓缩矿物": { nextStage:-1, loot:[{id:"ember_crystal",qty:[1,2]},{id:"thermal_ext",qty:[1,3]},{id:"sulfur_dust",qty:[1,2]}], timeCost:20, text:/*::GEN::事件结果:: */"采到浓缩火系结晶和高品质热液提取物,价值不菲。"/*::END:: */ }, "谨慎撤退": { nextStage:-1, loot:[{id:"thermal_ext",qty:[1,1]}], text:/*::GEN::事件结果:: */"撤退时顺手带走了一瓶热液样本。"/*::END:: */ } } }, "kelp_planting": { tier:"B", weight:1, sceneType:"small", name: /*::GEN::事件名:: */"海带种植点"/*::END:: */, type: "random", terrain: ["grass","reef"], depthRange: [5,80], context: ["anchored","outside"], baseChance: 0.004, regionVariants:{pasture:{name:"牧场海带种植点(牧场变体1)"},reef_eternal:{name:"永夜礁石海带种植点(礁石变体1)"}}, approachRange: 300, spanLength: 400, approachHint: "这片基底很适合海带附着——前方有种植点。", leaveHint: "种植点的位置在身后消失。", stages: [ { desc: /*::GEN::事件描述:: */"这片区域的基底很适合海带附着,水流稳定,光照充足——如果在这里种下海带,十天后就能有相当可观的收获。"/*::END:: */, actions: [/*::GEN::行动选项:: */"种植海带(消耗海带种子×2)"/*::END:: */,/*::GEN::行动选项:: */"采集现有零散海藻"/*::END:: */,/*::GEN::行动选项:: */"离开"/*::END:: */] } ], resolve: { "种植海带(消耗海带种子×2)": { nextStage: -1, loot: [], timeCost: 8, text: /*::GEN::事件结果:: */"你在基底插入了固定桩,将海带幼苗束缚在水流中。这里会记住这片种植点,十天后可以回来收获。"/*::END:: */, envEffect: { type:"kelp_farm", terrain:"auto", depthAuto:true, growDays:10, maxHarvest:5 } }, "采集现有零散海藻": { nextStage:-1, loot:[{id:"kelp",qty:[1,3]}], timeCost:5, text:/*::GEN::事件结果:: */"从周围收集了一些自然生长的海藻。"/*::END:: */ }, "离开": { nextStage:-1, loot:[], text:/*::GEN::事件结果:: */"记下了这里的位置,以后再说。"/*::END:: */ } } }, "kelp_harvest": { tier:"B", weight:1, sceneType:"small", name: /*::GEN::事件名:: */"海带收获"/*::END:: */, type: "random", terrain: ["grass","reef"], depthRange: [5,80], context: ["anchored","outside"], baseChance: 0, regionVariants:{pasture:{name:"牧场海带收获(牧场变体1)"},reef_eternal:{name:"永夜礁石海带收获(礁石变体1)"}}, approachRange: 300, spanLength: 400, stages: [ { desc: /*::GEN::事件描述:: */"你之前种下的海带已经成熟了,浓密的绿色叶片随水流轻摇,收获量可观。"/*::END:: */, actions: [/*::GEN::行动选项:: */"全面收割"/*::END:: */,/*::GEN::行动选项:: */"只收部分留种"/*::END:: */,/*::GEN::行动选项:: */"放弃"/*::END:: */] } ], resolve: { "全面收割": { nextStage:-1, loot:[{id:"kelp",qty:[8,15]},{id:"kelp_fiber",qty:[2,4]}], timeCost:20, text:/*::GEN::事件结果:: */"海带收割完毕,满载而归。这片种植点已枯竭。"/*::END:: */, harvestKelp: true }, "只收部分留种": { nextStage:-1, loot:[{id:"kelp",qty:[4,7]},{id:"kelp_fiber",qty:[1,2]}], timeCost:12, text:/*::GEN::事件结果:: */"收割了大部分,留下了一些让它继续生长。"/*::END:: */, harvestKelp: "partial" }, "放弃": { nextStage:-1, loot:[], text:/*::GEN::事件结果:: */"暂时不收,等它再长一段时间。"/*::END:: */ } } }, "bond_otter_family": { tier:"B", weight:0.8, sceneType:"small", name: /*::GEN::事件名:: */"海獭家族"/*::END:: */, type: "random", terrain: ["reef","grass"], depthRange: [0,40], context: ["sailing","anchored"], baseChance: 0.0015, regionVariants:{reef_eternal:{name:"永夜礁石海獭家族(礁石变体1)"},pasture:{name:"牧场海獭家族(牧场变体1)"}}, approachRange: 300, spanLength: 400, approachHint: "前方水面有海獭活动的迹象。", leaveHint: "海獭的嬉闹声在身后远去。", stages: [ { desc: /*::GEN::事件描述:: */"一群海獭在礁石间嬉戏,它们注意到了你,好奇地聚拢过来,用亮黑的眼睛打量着潜艇。"/*::END:: */, actions: [/*::GEN::行动选项:: */"投喂鱼类"/*::END:: */,/*::GEN::行动选项:: */"静静观察"/*::END:: */,/*::GEN::行动选项:: */"鸣笛打招呼"/*::END:: */] } ], resolve: { "投喂鱼类": { nextStage:-1, loot:[], timeCost:5, text:/*::GEN::事件结果:: */"海獭们争先恐后地游来,将鱼叼走后还在玻璃旁徘徊了好一会儿。"/*::END:: */, bondGain:{ key:"otter_family", amount:2, terrain:"auto", depthAuto:true } }, "静静观察": { nextStage:-1, loot:[], timeCost:3, text:/*::GEN::事件结果:: */"它们很快失去了兴趣,重新开始玩耍。你把这一幕记在了航行日志里。"/*::END:: */, bondGain:{ key:"otter_family", amount:1, terrain:"auto", depthAuto:true } }, "鸣笛打招呼": { nextStage:-1, loot:[], timeCost:1, text:/*::GEN::事件结果:: */"笛声响起,海獭们吓了一跳,迅速散开。也许下次轻一点。"/*::END:: */, bondGain:{ key:"otter_family", amount:0, terrain:"auto", depthAuto:true } } } }, /* ══ 固定型 SmallScene (Location) ══ */ /* 原 LocationDefs 的内容合并到此,type: "fixed" */ /* 每个定义带 gotoScene 指向独立 passage */ /* 独立出现时三段距离:接近6 · 长度8 · 远离6 */ "wreck_site_loc": { tier:"B", sceneType:"small", name: /*::GEN::事件名:: */"沉船残骸"/*::END:: */, type: "fixed", terrain: ["sand"], depthRange: [0, 10000], context: ["sailing"], weight:1, regionVariants:{wreck_graveyard:{name:"沉船坟场沉船残骸(沉船变体1)"},sunken_city:{name:"城市废墟沉船残骸(城市变体1)"}}, approachRange: 300, spanLength: 400, depthWindow: "mid", approachHint: "声呐出现异常金属反射信号——前方疑似有人造结构。", leaveHint: "残骸的轮廓在探照灯边缘逐渐模糊,重新回到黑暗中。", gotoScene: "地点_沉船残骸", stages: [ { desc: /*::GEN::事件描述:: */"一艘沉船的残骸横卧在海床上,锈蚀的船体已经和周围环境融为一体。可以从几个方向接近探索。"/*::END:: */, actions: [/*::GEN::行动选项:: */"进入残骸内部"/*::END:: */,/*::GEN::行动选项:: */"在外围搜刮"/*::END:: */] } ], resolve: { "进入残骸内部": { nextStage:-1, loot:[{id:"metal",qty:[1,3]},{id:"iron",qty:[0,2]}], timeCost:15, text:/*::GEN::事件结果:: */"在残骸内部摸索了一圈,找到了一些金属材料。"/*::END:: */ }, "在外围搜刮": { nextStage:-1, loot:[{id:"metal",qty:[0,2]},{id:"rope",qty:[0,1]}], timeCost:5, text:/*::GEN::事件结果:: */"在外围捡到了几样零碎,没有深入。"/*::END:: */ } } } /* 注:晶石洞穴(crystal_cave)为规范前的测试占位,规范未收录,已删除。 C 类通用池的完整重建(§5.x + §11.1 归一化公式)待规范确认后再补。 */ }>> /* 兼容旧定义并为所有小型事件预留持续地图段与区域变体入口。 新定义可覆写 mapSpan;regionVariants 可按大型区域 id 写入描述/权重变体。 */ <<set _seKeys = Object.keys($smallEventDefs)>> <<for _sei = 0; _sei < _seKeys.length; _sei++>> <<set _seDef = $smallEventDefs[_seKeys[_sei]]>> <<if !_seDef.mapSpan>><<set _seDef.mapSpan = {approach:(_seDef.approachRange || 300),active:(_seDef.spanLength || 400),leave:(_seDef.approachRange || 300)}>><</if>> <<if !_seDef.regionVariants>><<set _seDef.regionVariants = {}>><</if>> <</for>> <</widget>> <</nobr>>
/* 仓库初始结构(各分类从空开始,additem自动填充) */ <<set $storeCapacity = 500>> <<set $backpackCapacity = 50>> <<set $store = { 资源: [], 渔获: [], 食材: [], 菜品: [], 炼金材料: [], 纯粹酊剂: [], 以太副产物:[], 消耗品: [], 持久物品: [], 设备: [], 遗物: [], 残骸: [], 基础材料: [] }>> <<set $backpack = { 资源: [], 渔获: [], 食材: [], 菜品: [], 炼金材料: [], 消耗品: [] }>>
<<nobr>> <<widget "temporalEventDefs">> <<set $temporalDefs = { shadow_pursuit: { name: /*::GEN::事件名:: */"追踪的阴影"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"探照灯边缘有什么东西,速度和方向与你完全一致——它一直在跟着你。"/*::END:: */, chance: 0.006, dMin: 200, sanMax: 80, speed: 0.5, warnAt: 40, warnText: /*::GEN::warnText:: */"声呐后方持续出现移动信号,速度与你惊人地吻合,已跟了很长时间了。"/*::END:: */, endText: /*::GEN::endText:: */"那个信号突然加速——撞击!潜艇剧烈震动,安定值大幅下降。"/*::END:: */, effect: "san", amount: 20, terrain: "sand flat cliff water" }, pressure_anomaly: { name: /*::GEN::事件名:: */"压力异常区"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"外壳出现细小振动——是极不规律的水压波动,来自某个方向。"/*::END:: */, chance: 0.004, dMin: 500, sanMax: 999, speed: 0.8, warnAt: 50, warnText: /*::GEN::warnText:: */"压力读数开始不规律波动,幅度越来越大,船体发出金属应力声。"/*::END:: */, endText: /*::GEN::endText:: */"压力突然达到峰值,系统完整性下降,需要紧急维修。"/*::END:: */, effect: "sys", amount: 15, terrain: "flat cliff" }, deep_current: { name: /*::GEN::事件名:: */"深层洋流"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"水流方向开始变得混乱,仪表盘流速计急速跳动。"/*::END:: */, chance: 0.003, dMin: 300, sanMax: 999, speed: 1.2, warnAt: 35, warnText: /*::GEN::warnText:: */"水流突然变得异常强劲,方向不断改变,潜艇开始偏离航线。"/*::END:: */, endText: /*::GEN::endText:: */"强洋流将潜艇卷入,被迫偏转,坐标向前推进。"/*::END:: */, effect: "map", amount: 5000, terrain: "sand flat cliff" } }>> <</widget>> <</nobr>>
<<set $viewlight = { bright: { day_clear: /*::GEN::场景描述:: */"太阳高悬在空中,清澈温暖的光线慷慨地遍撒在每一处"/*::END:: */, day_hot: /*::GEN::场景描述:: */"日曜季的太阳在彰显它的威力,海水温蕴着热量,直射进水底的光线几乎让人睁不开眼睛"/*::END:: */, dusk_hot: /*::GEN::场景描述:: */"即使太阳已经西沉,阳光也没有收敛它的温度,水上像是燃着一层火,跳动的光线直刺进眼睛和水下的深处"/*::END:: */, dawn_clear: /*::GEN::场景描述:: */"难得可以看到太阳的日子,太阳逐渐把雪亮的光片撒在水面上,水体通透映着日出的光线"/*::END:: */, dawn_hot: /*::GEN::场景描述:: */"天空的火球正在爬升,灼热金红的阳光穿透进海水,浅层水体逐渐开始升温"/*::END:: */ }, hazy: { day_cloudy: /*::GEN::场景描述:: */"阴天的阳光融进了云层里,灰白发亮的云层阴暗而晃眼,大海寂静如昨"/*::END:: */, day_lightrain: /*::GEN::场景描述:: */"细密柔和的雨融化在灰色的空气里,海水规律而没有尽头地波荡着拍打在船身"/*::END:: */, day_windy: /*::GEN::场景描述:: */"凌冽的风在呼啸,在海面几乎听不到风以外的任何声音,海面被风掀起白浪层层而过"/*::END:: */, day_fog: /*::GEN::场景描述:: */"海面上满是没有尽头的雾气,白昼足够明亮,但灰白的天空上看不见太阳"/*::END:: */, dusk_clear: /*::GEN::场景描述:: */"昏暗的日光斜落在海面,一片猩红涌动,透下带着余温的光穿透海水"/*::END:: */, dusk_lightrain: /*::GEN::场景描述:: */"淅淅沥沥的小雨披上夕阳色,金线划落,水面烁金一片"/*::END:: */, dawn_cloudy: /*::GEN::场景描述:: */"天气有些阴霾,但太阳还是从东边的海平面上投来了朦胧的铂金色亮光,新的一天照常来临"/*::END:: */, dawn_lightrain: /*::GEN::场景描述:: */"细密的微小雨滴被日出时的阳光斜斜地照出一层亮色,晨光和细雨交织,空气里弥漫着湿润清凉的气味"/*::END:: */, dawn_windy: /*::GEN::场景描述:: */"狂风在凌晨灰蓝色暗淡的海上呼啸,撕扯着翻滚不息的海,光线昏沉而冰冷"/*::END:: */, dawn_fog: /*::GEN::场景描述:: */"初出的阳光透过海上不变的无尽雾气,投下变幻莫测的倾斜光线,一切都灰白寂静"/*::END:: */ }, dim: { day_heavyrain: /*::GEN::场景描述:: */"雨点拍打在海面,不过并没有阻断白昼光线充斥空气,灰白的天空高悬在海上,笼罩下又一层敲打在窗户的雨点"/*::END:: */, day_snow: /*::GEN::场景描述:: */"狂乱的雪和阴翳的天空遮挡了一切光线,就算是白昼也只留下一层勉强看清五指的晦暗光线,不时有尚未融化的细小冰球被打入水下,随着泡沫一起重新上浮"/*::END:: */, day_storm: /*::GEN::场景描述:: */"暗沉宛如泥浆的海面在暴风雨的搅动下翻滚着,暴雨云下仿佛连空间都被压缩一般,看不清一切细节,只有一层轮廓勉强可见"/*::END:: */, dusk_fog: /*::GEN::场景描述:: */"淡金色的光辉从日落的方向撒来,被海面笼罩的雾气折射得四散朦胧"/*::END:: */, dusk_cloudy: /*::GEN::场景描述:: */"阳光夕斜,云色也变得暗沉,不过仍然有亮光在远处,天色依然明亮"/*::END:: */, dusk_windy: /*::GEN::场景描述:: */"黄昏的天色格外暗沉,几乎看不见任何东西,只有风从海面上呼啸而过,就连水下也被搅得混乱一片"/*::END:: */, dusk_heavyrain: /*::GEN::场景描述:: */"暮色被沉重的雨云二次覆盖,只剩暗红的光线映照在模糊的船舱轮廓上,豆大的雨点砸在海面砸开一片昏暗"/*::END:: */, dawn_snow: /*::GEN::场景描述:: */"风裹挟着雪落入海面,云层死死遮住了太阳,就算是本该日出的时间点海面也一片昏沉,能见度堪堪十米"/*::END:: */, dusk_snow: /*::GEN::场景描述:: */"洁白的雪也在昏暗的黄昏里投下更多暗影,纷纷扬扬没有尽头,海面的一切都模糊不清"/*::END:: */, dawn_heavyrain: /*::GEN::场景描述:: */"雨帘浇驻在海面,水雾和厚重的云四处飘荡,但拦不住朦胧的日光从海平线上投过来"/*::END:: */, }, dark: { dusk_storm: /*::GEN::场景描述:: */"阳光即将消逝在无边的雷云中,狂风、暴雨、破碎的水面,大海犹如猛兽在咆哮,只有偶尔一点亮光撕破昏暗的天际"/*::END:: */, dawn_storm: /*::GEN::场景描述:: */"深黑的暴雨云积压在天空,只有闪电的光线才能偶尔照亮视线,初升的太阳根本无力穿透这样的风暴,汹涌的海水里满是激荡的泡沫"/*::END:: */, night_clear: /*::GEN::场景描述:: */"难得晴朗的夜晚,空中隐约可以看到星星,漫无边际的繁星从天际笼罩在海面,但大海依然是无尽的深黑色"/*::END:: */, night_hot: /*::GEN::场景描述:: */"黑夜闷热,不过至少比白天好上些许,泛着泡沫的海腥潮水波荡拍打在船体上,空气潮湿而温暗"/*::END:: */, night_cloudy: /*::GEN::场景描述:: */"即使是海面也只有阴冷的黑,船上的灯光也只亮在你的小窝一隅,无边的黑暗如过去数年一般统治着整个沉默的海面"/*::END:: */, night_lightrain: /*::GEN::场景描述:: */"淅淅沥沥的小雨敲打在海面,不是坏天气,不过当然也不美好,只是这样小的雨甚至没法打破海上黑夜的沉寂,只有细雨丝融化在潮湿的空气里"/*::END:: */, night_heavyrain: /*::GEN::场景描述:: */"雨点在海面激起涟漪,淅淅沥沥,从未停息,无边的黑暗笼罩着雨夜"/*::END:: */, night_windy: /*::GEN::场景描述:: */"狂风在海面呼啸,但无光的黑夜让一切都模糊不清,只有风依然在撕扯咆哮,海浪随着气流起伏不休,风声哭嚎着在黑夜盘旋"/*::END:: */,night_fog: "雾气笼罩了一切,夜晚的海洋黑暗无际,船上微弱的灯光也消融在仅仅伸手的范围,寂静的黑暗如水压般沉重", night_storm: /*::GEN::场景描述:: */"比狂风更暴烈,比大雨更窒息,只能用灾难来形容的气候在海上盘旋,本该比夜更黑暗的天空却被闪电照亮了几瞬,你的船在海水里颠簸,或许去深处会好一些"/*::END:: */, night_snow: /*::GEN::场景描述:: */"雪花在风中飘荡,风雪漫漫,深黑的天空让人看不清任何东西,但冰晶几乎随着海上无边无际的水声、和令人胆寒的黑暗一起钻进船舱里了"/*::END:: */ } }>> <<set $viewmap = { /* --- 地形描述 --- */ water: { bright: /*::GEN::场景描述:: */"明亮的光穿透海面、缓慢而轻柔地形成光柱,也穿透无边无际的海水,视线的尽头是一片茫茫的蓝色。"/*::END:: */, hazy: /*::GEN::场景描述:: */"果冻一样柔软的灰蓝色海水蔓延到视线的尽头。"/*::END:: */, dim: /*::GEN::场景描述:: */"幽暗的海水里晃悠着潜艇仅有的一点灯光,更远处被笼罩在一片深蓝中,恍惚望不到尽头"/*::END:: */, dark: /*::GEN::场景描述:: */"海水中缺乏参照物、几乎分不清远近,只剩潜艇偶尔扫过的短暂惨白灯光"/*::END:: */ }, sand: { bright: /*::GEN::场景描述:: */"起伏的沙床上隐约有水面透下的光斑,海水交织着金色的光,连扬起的沙尘都泛着金色。"/*::END:: */, hazy: /*::GEN::场景描述:: */"沙砾铺陈在海底,偶尔有缓慢的水流搅动,四周是一片朦胧的蓝色"/*::END:: */, dim: /*::GEN::场景描述:: */"微弱的光线偶尔落在海床沙丘的亮面,又随着海浪一晃消失,海床只在一片看不清晦暗里起伏"/*::END:: */, dark: /*::GEN::场景描述:: */"除了灯光扫过的起伏沙地看不清其他,偶尔有些小蟹从灯光里疯狂逃窜走"/*::END:: */ }, grass: { bright: /*::GEN::场景描述:: */"海草随着海水柔软地起伏,反射阳光、宛如风掠过草原"/*::END:: */, hazy: /*::GEN::场景描述:: */"海草浪一样起伏,偶尔有小鱼在其中穿行,静谧的蓝绿色草原望不到尽头。"/*::END:: */, dim: /*::GEN::场景描述:: */"昏暗的光线让你看不清细节,只看到一片起伏的草浪,宛如又一片汹涌的海面"/*::END:: */, dark: /*::GEN::场景描述:: */"潜艇灯光照亮了极小范围内交织的丝丝海草,更多只是在黑暗中起伏涌动,看不到尽头"/*::END:: */ }, reef: { bright: /*::GEN::场景描述:: */"阳光穿过繁杂的礁石,海葵轮流张合翕动,每一个角落都有不同的生物鱼贯四散,繁复结构的影子和反光都多彩得令人目眩。"/*::END:: */, hazy: /*::GEN::场景描述:: */"繁茂的礁石自顾自吞吐着海水,目之所及的每一处都有小生物在忙着自己的事,鱼群交错有如末日前最忙乱的十字路口。"/*::END:: */, dim: /*::GEN::场景描述:: */"昏暗错杂的光让你看不清那些小东西了,但珊瑚礁仍然令人眼花缭乱,偶尔几点光斑从失色的礁石尖端掠过,又躲进昏暗的影子里。"/*::END:: */, dark: /*::GEN::场景描述:: */"珊瑚礁在黑暗中成为剪影,珊瑚们反射着微弱的光,在不见五指的黑暗中点缀着荧光"/*::END:: */ }, forest: { bright: /*::GEN::场景描述:: */"再粗壮的海藻也没法遮挡所有光线,染着橄榄色的海藻森林一角被照亮了,阳光在巨大褐藻之间穿行,角落被映得生机盎然。"/*::END:: */, hazy: /*::GEN::场景描述:: */"海藻遮挡了光线,森林中比水面要昏暗些,但还是有浅黄的光线照在那些错落宽大的枝叶上"/*::END:: */, dim: /*::GEN::场景描述:: */"粗壮、庞大的海藻遮挡了几乎一切光线,只有缝隙里有些光漏下来,其余皆是一片阴森的晦暗"/*::END:: */, dark: /*::GEN::场景描述:: */"在黑暗中偶有粗壮的海藻从狭窄的灯光视野里拂过,层层叠叠的森林压缩了视距,比开阔海域更加压抑"/*::END:: */ }, rock: { bright: /*::GEN::场景描述:: */"崎岖起伏着的海底也被阳光照亮,死寂变得柔和了不少"/*::END:: */, hazy: /*::GEN::场景描述:: */"岩石嶙峋地铺在海底,光亮只落在尖处,几乎像要从海底开始搅碎一切的牙齿"/*::END:: */, dim: /*::GEN::场景描述:: */"嶙峋的石块在海底起伏,灰暗的海水压在海床上,目之所及只有压抑而茫茫的无尽深海"/*::END:: */, dark: /*::GEN::场景描述:: */"尖锐的岩石从黑暗中刺进灯光,又快速隐没进黑暗,其余一切也都不可见"/*::END:: */ }, cliff: { bright: /*::GEN::场景描述:: */"峭壁的岩面被光线照亮,清晰的层叠纹路和嶙峋突起投下浓厚的影,深邃的裂谷处仍是一片幽暗。"/*::END:: */, hazy: /*::GEN::场景描述:: */"峭壁在昏暗中轮廓模糊,起伏的岩面隐约向深处延伸,光线只落在最突出的棱角上。"/*::END:: */, dim: /*::GEN::场景描述:: */"周围只有嶙峋的石块构成尖锐的峡谷,光线在下发不远处就衰减了、只剩狭窄的空间通向看不见的深处。"/*::END:: */, dark: /*::GEN::场景描述:: */"深渊比往常更幽深,深不见底的黑暗吞噬了灯光,只有近旁崎岖的岩壁指向更深的裂谷。"/*::END:: */ }, flat: { bright: /*::GEN::场景描述:: */"平整的岩海床被光线清晰地照亮,硬实的地面几乎没有任何起伏,偶有藤壶和附生生物点缀其间。"/*::END:: */, hazy: /*::GEN::场景描述:: */"平坦的岩层向四周无尽地延伸,灰白的色调与昏暗的水色连成一片,显得空旷而单调。"/*::END:: */, dim: /*::GEN::场景描述:: */"岩海床在昏暗中显得冷硬而空旷,灯光照出的范围内几乎没有任何变化,只有偶尔一两处苔藓状的附生物。"/*::END:: */, dark: /*::GEN::场景描述:: */"黑暗中平坦的岩面只被灯光短暂地照亮一小片,四周死寂,几乎分辨不出任何细节。"/*::END:: */ } }>> <<set $viewevents = { /* --- 随机小场景 --- */ fish: { bright: /*::GEN::场景描述:: */"[鱼群 强光行为]"/*::END:: */, dim: /*::GEN::场景描述:: */"[鱼群 弱光行为]"/*::END:: */, dark: /*::GEN::场景描述:: */"[鱼群 无光行为]"/*::END:: */ }, bubble: { bright: /*::GEN::场景描述:: */"[气泡 强光行为]"/*::END:: */, dim: /*::GEN::场景描述:: */"[气泡 弱光行为]"/*::END:: */ } // 其他事件... }>>
<<nobr>> <<widget "worldSceneDefs">> /* ═══════════════════════════════════════════════ 中型场景定义表 $wsDefs + 子房间定义 $wsChildDefs 本表已按《地图系统_迁移规范》附A 用真名重建: 每个 A 类 zone 拥有独立 wsDef(不再共用 *_zone 通用占位)。 字段说明: id 唯一标识 name 显示名 modes "independent"(只散装)/ "zone_only"(只作大型区域 zone)/ "both" weight 散装生成权重(zone_only 恒为 0) terrain 地形白名单(散装生成时过滤;zone 生成不看此字段) spanMin/Max 场景段长度(原始值,默认1000=20可见坐标) viewDesc 舷窗描述 approachDesc 接近时描述 insideDesc 进入时描述 children 房间(SmallScene)ID列表 距离参数(原始值 / 可见坐标): 接近段 = 1000 / 20 场景段 = 1000 / 20 离开段 = 1000 / 20 占位规则(规范 §八): [事件标题] +(描述占位)+(地形变体占位)+ 占位互动键 [查看][互动][离开] 文本带 GEN 标记,后续由文案直接替换。 ═══════════════════════════════════════════════ */ <<set $wsDefs = { /* ── 建筑:C/中型家族占位;具体类型由区域变体库选择。── */ "building_family": { name: "建筑", modes: "tier_only", tier: "C", weight: 0.8, sceneType: "middle", terrain: [], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin:1000, spanMax:1000, regionVariants: { sunken_city: {weightMultiplier:1, variants:[{weight:4,name:"公寓建筑残骸"},{weight:2,name:"学校建筑残骸"},{weight:1,name:"图书馆建筑残骸"}]}, reef_eternal: {weightMultiplier:0.4, variants:[{weight:1,name:"珊瑚礁花店残骸"},{weight:1,name:"珊瑚礁餐厅残骸"}]}, mermaid_prison: {weightMultiplier:0.2, variants:[{weight:1,name:"海藻森林图书馆残骸"}]}, hydrothermal: {weightMultiplier:1.2, variants:[{weight:2,name:"热液研究设施残骸"},{weight:1,name:"热液工业建筑残骸"}]} }, viewDesc:"建筑残骸占据着前方视野。", approachDesc:"前方出现规则排列的人造结构轮廓。", insideDesc:"进入建筑残骸内部,损毁严重但仍有可探索空间。", children:[] }, /* ── 沉船:C/中型家族占位;具体船型由区域变体库选择。── */ "shipwreck_family": { name: "沉船", modes: "tier_only", tier: "C", weight: 0.8, sceneType: "middle", terrain: [], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin:1000, spanMax:1000, regionVariants: { wreck_graveyard: {weightMultiplier:1.5, variants:[{weight:4,name:"货轮残骸"},{weight:3,name:"远洋渔船残骸"},{weight:1,name:"科考船残骸"}]}, reef_eternal: {weightMultiplier:0.3, variants:[{weight:1,name:"珊瑚礁游艇残骸"}]}, hydrothermal: {weightMultiplier:0.8, variants:[{weight:1,name:"热液区科考船残骸"}]} }, viewDesc:"一艘沉船残骸横卧在海床上。", approachDesc:"声呐捕捉到大型船体残骸。", insideDesc:"船体近在眼前,几处破口可以进入。", children:["wreck_cargo","wreck_engine","wreck_logbook","wreck_mail"] }, /* ── 鲸落:C/中型。由统一 ABC 调度器插入,不再参与旧 independent 池。── */ "whale_fall": { name: /*::GEN::场景名:: */"鲸落"/*::END:: */, modes: "tier_only", tier: "C", weight: 0.2, sceneType: "middle", terrain: [], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: { salt_lake: { weightMultiplier: 2, name: /*::GEN::场景名:: */"盐湖鲸落"/*::END:: */, viewDesc: /*::GEN::viewDesc:: */"幽绿盐水在巨大的鲸骨之间缓慢流动,盐晶覆盖着肋骨与沉积层。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"盐湖边缘的声呐回波中混入大片骨质结构与异常有机物信号。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"巨大的鲸骨沉在盐湖边缘,盐晶与食腐生物共同构成了诡异的生态层。"/*::END:: */ }, sunken_city: {weightMultiplier:0.5,name:"城市废墟鲸落(城市变体1)",viewDesc:"(城市鲸落变体1)",approachDesc:"(城市鲸落变体1)",insideDesc:"(城市鲸落变体1)"}, mermaid_prison: {weightMultiplier:0.5,name:"海藻森林鲸落(森林变体1)",viewDesc:"【海藻森林变体】巨鲸骸骨被海藻森林的高大藻柱缠绕,阴绿的藻影间密布着发光生物。",approachDesc:"【海藻森林变体】前方藻林深处出现巨大的骨质回波,海藻与鲸骨正在形成一片独特生态层。",insideDesc:"【海藻森林变体】鲸骨沉在海藻根部,粗大的藻茎缠满肋骨,林下生物围绕尸骸活动。"}, hydrothermal: {weightMultiplier:0.8,name:"热液区鲸落(热液变体1)",viewDesc:"(热液鲸落变体1)",approachDesc:"(热液鲸落变体1)",insideDesc:"(热液鲸落变体1)"} }, viewDesc: /*::GEN::viewDesc:: */"一具巨大的白色骨架占据着视野——肋骨高耸如拱门,骨骸规模让人难以判断距离。这里是深海最独特的生命绿洲。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"有机物浓度骤升,水中弥漫着腐败的气息——前方有一具大型生物的尸骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"巨大的鲸鱼骸骨沉卧于此,骨架上密布着以此为生的小型生物群落,已经形成了一个完整的深海生态系。"/*::END:: */, children: ["whale_skull","whale_ribs","whale_tail","whale_scavengers"] }, /* ── 货轮(沉船群 zone) ── */ "wreck_cargoship": { name: /*::GEN::场景名:: */"货轮"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(货轮占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(货轮占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(货轮占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["wreck_cargo","wreck_engine","wreck_logbook","wreck_mail"] }, /* ── 游轮(沉船群 zone) ── */ "wreck_cruise": { name: /*::GEN::场景名:: */"游轮"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(游轮占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(游轮占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(游轮占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_cruise"] }, /* ── 军舰(沉船群 zone · 线索 zone,绑定必选) ── */ "wreck_warship": { name: /*::GEN::场景名:: */"军舰"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(军舰占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(军舰占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(军舰占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_warship"] }, /* ── 远洋渔船(沉船群 zone) ── */ "wreck_trawler": { name: /*::GEN::场景名:: */"远洋渔船"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(远洋渔船占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(远洋渔船占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(远洋渔船占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_trawler"] }, /* ── 三桅帆船(沉船群 zone) ── */ "wreck_schooner": { name: /*::GEN::场景名:: */"三桅帆船"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(三桅帆船占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(三桅帆船占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(三桅帆船占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_schooner"] }, /* ── 科考船(沉船群 zone · 线索 zone,绑定必选) ── */ "wreck_research": { name: /*::GEN::场景名:: */"科考船"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(科考船占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(科考船占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(科考船占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_research"] }, /* ── 游艇(沉船群 zone 变体占位) ── */ "wreck_yacht": { name: /*::GEN::场景名:: */"游艇"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(游艇占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(游艇占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(游艇占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_yacht"] }, /* ── 渔船(沉船群 zone 变体占位) ── */ "wreck_fishboat": { name: /*::GEN::场景名:: */"渔船"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["sand"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(渔船占位)锈蚀的船体轮廓在探照灯下缓缓展开,金属与腐朽在此凝固。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(渔船占位)声呐出现密集金属反射,前方有大型船体残骸。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(渔船占位)船体近在眼前,几处破口可以进入。"/*::END:: */, children: ["z_wreck_fishboat"] }, /* ── 公园(城市废墟 zone) ── */ "ruin_park": { name: /*::GEN::场景名:: */"公园"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(公园占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(公园占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(公园占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_park"] }, /* ── 公寓(城市废墟 zone) ── */ "ruin_apartment": { name: /*::GEN::场景名:: */"公寓"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(公寓占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(公寓占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(公寓占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_apartment"] }, /* ── 学校(城市废墟 zone) ── */ "ruin_school": { name: /*::GEN::场景名:: */"学校"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(学校占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(学校占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(学校占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_school"] }, /* ── 工厂(城市废墟 zone) ── */ "ruin_factory": { name: /*::GEN::场景名:: */"工厂"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(工厂占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(工厂占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(工厂占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_factory"] }, /* ── 商场(城市废墟 zone) ── */ "ruin_mall": { name: /*::GEN::场景名:: */"商场"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(商场占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(商场占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(商场占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_mall"] }, /* ── 市政厅(城市废墟 zone) ── */ "ruin_cityhall": { name: /*::GEN::场景名:: */"市政厅"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(市政厅占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(市政厅占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(市政厅占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_cityhall"] }, /* ── 研究所(城市废墟 zone · 绑定必选) ── */ "ruin_institute": { name: /*::GEN::场景名:: */"研究所"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(研究所占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(研究所占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(研究所占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_institute"] }, /* ── 餐厅(建筑 C 类变体占位) ── */ "ruin_restaurant": { name: /*::GEN::场景名:: */"餐厅"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(餐厅占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(餐厅占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(餐厅占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_restaurant"] }, /* ── 花店(建筑 C 类变体占位) ── */ "ruin_florist": { name: /*::GEN::场景名:: */"花店"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(花店占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(花店占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(花店占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_florist"] }, /* ── 面包房(建筑 C 类变体占位) ── */ "ruin_bakery": { name: /*::GEN::场景名:: */"面包房"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(面包房占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(面包房占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(面包房占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_bakery"] }, /* ── 民居(建筑 C 类变体占位) ── */ "ruin_house": { name: /*::GEN::场景名:: */"民居"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["flat"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(民居占位)建筑结构匍匐于海床,被淤泥与附生物吞没大半。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(民居占位)前方出现规则排列的人造结构轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(民居占位)进入建筑内部,损毁严重但仍有可探索空间。"/*::END:: */, children: ["z_ruin_house"] }, /* ── 峭壁人类建筑(残坑限定 zone · 要素① · 绑定必选) ── */ "cliff_building": { name: /*::GEN::场景名:: */"峭壁人类建筑"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["cliff"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(峭壁人类建筑占位)峭壁上的结构悬在坑体边缘,碎石在水中缓慢悬浮。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(峭壁人类建筑占位)崖壁上出现异常轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(峭壁人类建筑占位)贴近崖壁,结构与生物痕迹交错。"/*::END:: */, children: ["z_cliff_building"] }, /* ── 寄居深海生物聚居(残坑 zone · 要素②,可散装待定) ── */ "cliff_colony": { name: /*::GEN::场景名:: */"寄居生物聚居"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["cliff"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(寄居生物聚居占位)峭壁上的结构悬在坑体边缘,碎石在水中缓慢悬浮。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(寄居生物聚居占位)崖壁上出现异常轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(寄居生物聚居占位)贴近崖壁,结构与生物痕迹交错。"/*::END:: */, children: ["z_cliff_colony"] }, /* ── 特殊采集物(残坑限定 zone · 要素④ · 名称与机制待用户定) ── */ "cliff_relic": { name: /*::GEN::场景名:: */"特殊采集点"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["cliff"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(特殊采集点占位)峭壁上的结构悬在坑体边缘,碎石在水中缓慢悬浮。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(特殊采集点占位)崖壁上出现异常轮廓。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(特殊采集点占位)贴近崖壁,结构与生物痕迹交错。"/*::END:: */, children: ["z_cliff_relic"] }, /* ── 育幼场(牧场 zone · 绑定必选 · 信标/慈爱相关) ── */ "pasture_nursery": { name: /*::GEN::场景名:: */"育幼场"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["grass"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(育幼场占位)草场与围栏的剪影在海流中起伏。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(育幼场占位)前方浮现成片草甸与围栏。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(育幼场占位)进入草场范围,生物活动痕迹明显。"/*::END:: */, children: ["z_pasture_nursery"] }, /* ── 小屋(牧场 zone · 无人但生活痕迹新鲜) ── */ "pasture_cabin": { name: /*::GEN::场景名:: */"小屋"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["grass"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(小屋占位)草场与围栏的剪影在海流中起伏。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(小屋占位)前方浮现成片草甸与围栏。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(小屋占位)进入草场范围,生物活动痕迹明显。"/*::END:: */, children: ["z_pasture_cabin"] }, /* ── 兽群(牧场 zone · 可猎杀/可照顾) ── */ "pasture_herd": { name: /*::GEN::场景名:: */"兽群"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["grass"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(兽群占位)草场与围栏的剪影在海流中起伏。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(兽群占位)前方浮现成片草甸与围栏。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(兽群占位)进入草场范围,生物活动痕迹明显。"/*::END:: */, children: ["z_pasture_herd"] }, /* ── 花园(牧场 zone · 规范注可散装,暂仅作 zone) ── */ "pasture_garden": { name: /*::GEN::场景名:: */"花园"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["grass"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(花园占位)草场与围栏的剪影在海流中起伏。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(花园占位)前方浮现成片草甸与围栏。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(花园占位)进入草场范围,生物活动痕迹明显。"/*::END:: */, children: ["z_pasture_garden"] }, /* ── 海豚岛(永夜礁石限定 zone · 不散装) ── */ "reef_dolphin": { name: /*::GEN::场景名:: */"海豚岛"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["reef"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(海豚岛占位)巨大礁石生机盎然,光点在礁体间流动。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(海豚岛占位)前方礁石密布,生物活动异常密集。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(海豚岛占位)礁体近在眼前,可以靠近观察。"/*::END:: */, children: ["z_reef_dolphin"] }, /* ── 墓火(永夜礁石限定 zone · 不散装) ── */ "reef_gravefire": { name: /*::GEN::场景名:: */"墓火"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["reef"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(墓火占位)巨大礁石生机盎然,光点在礁体间流动。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(墓火占位)前方礁石密布,生物活动异常密集。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(墓火占位)礁体近在眼前,可以靠近观察。"/*::END:: */, children: ["z_reef_gravefire"] }, /* ── 陶玛斯 location(绑定永夜礁石 · 出舱探索可进岛) ── */ "reef_thomas": { name: /*::GEN::场景名:: */"陶玛斯"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["reef"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(陶玛斯占位)巨大礁石生机盎然,光点在礁体间流动。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(陶玛斯占位)前方礁石密布,生物活动异常密集。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(陶玛斯占位)礁体近在眼前,可以靠近观察。"/*::END:: */, children: ["z_reef_thomas"] }, /* ── 灰鲸入林(海藻森林 B 类中型 · 占位) ── */ "forest_whale": { name: /*::GEN::场景名:: */"灰鲸入林"/*::END:: */, modes: "independent", weight: 1, tier: "B", sceneType: "middle", devOnly: true, terrain: ["forest"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(灰鲸入林占位)海藻绞成漏斗状漩涡,阴绿的光线令人不安。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(灰鲸入林占位)海藻异常密集,前方水体呈阴绿色。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(灰鲸入林占位)进入密林内部,危险与材料并存。"/*::END:: */, children: ["z_forest_whale"] }, /* ── 污染尸骸(人鱼狱核心 zone · 绑定必选 · 通向下一 location) ── */ "prison_carcass": { name: /*::GEN::场景名:: */"污染尸骸"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["forest"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(污染尸骸占位)海藻绞成漏斗状漩涡,阴绿的光线令人不安。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(污染尸骸占位)海藻异常密集,前方水体呈阴绿色。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(污染尸骸占位)进入密林内部,危险与材料并存。"/*::END:: */, children: ["z_prison_carcass"] }, /* ── 水雷区(人鱼狱限定 zone · 高危) ── */ "prison_minefield": { name: /*::GEN::场景名:: */"水雷区"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["forest"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(水雷区占位)海藻绞成漏斗状漩涡,阴绿的光线令人不安。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(水雷区占位)海藻异常密集,前方水体呈阴绿色。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(水雷区占位)进入密林内部,危险与材料并存。"/*::END:: */, children: ["z_prison_minefield"] }, /* ── 骨骸林(人鱼狱限定 zone · 精神伤害) ── */ "prison_bonewood": { name: /*::GEN::场景名:: */"骨骸林"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["forest"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(骨骸林占位)海藻绞成漏斗状漩涡,阴绿的光线令人不安。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(骨骸林占位)海藻异常密集,前方水体呈阴绿色。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(骨骸林占位)进入密林内部,危险与材料并存。"/*::END:: */, children: ["z_prison_bonewood"] }, /* ── 巨大骨骸(盐湖区 zone · 绑定必选) ── */ "salt_bones": { name: /*::GEN::场景名:: */"巨大骨骸"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(巨大骨骸占位)幽绿盐湖静止如镜,巨大轮廓隐现其中。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(巨大骨骸占位)海床呈现异常高盐度光泽。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(巨大骨骸占位)进入盐湖范围,浮力与视野都变得诡异。"/*::END:: */, children: ["z_salt_bones"] }, /* ── 结晶滩涂(盐湖区 zone) ── */ "salt_crystal": { name: /*::GEN::场景名:: */"结晶滩涂"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(结晶滩涂占位)幽绿盐湖静止如镜,巨大轮廓隐现其中。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(结晶滩涂占位)海床呈现异常高盐度光泽。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(结晶滩涂占位)进入盐湖范围,浮力与视野都变得诡异。"/*::END:: */, children: ["z_salt_crystal"] }, /* ── 湖面幻象(盐湖区 zone · 按 $san 差分) ── */ "salt_mirage": { name: /*::GEN::场景名:: */"湖面幻象"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(湖面幻象占位)幽绿盐湖静止如镜,巨大轮廓隐现其中。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(湖面幻象占位)海床呈现异常高盐度光泽。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(湖面幻象占位)进入盐湖范围,浮力与视野都变得诡异。"/*::END:: */, children: ["z_salt_mirage"] }, /* ── 研究所废墟(热液泉区 zone · 绑定必选 · 需出舱探索进深处) ── */ "vent_lab": { name: /*::GEN::场景名:: */"研究所废墟"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(研究所废墟占位)热羽流不断升腾,矿物在喷口周围堆积成塔。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(研究所废墟占位)水温骤升,前方有活跃热液喷口。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(研究所废墟占位)逼近喷口区域,仪表读数持续攀升。"/*::END:: */, children: ["z_vent_lab"] }, /* ── 火山口(热液泉区 zone) ── */ "vent_crater": { name: /*::GEN::场景名:: */"火山口"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(火山口占位)热羽流不断升腾,矿物在喷口周围堆积成塔。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(火山口占位)水温骤升,前方有活跃热液喷口。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(火山口占位)逼近喷口区域,仪表读数持续攀升。"/*::END:: */, children: ["z_vent_crater"] }, /* ── 神秘仪器(热液泉区 zone · 仍在运行,略诡异) ── */ "vent_device": { name: /*::GEN::场景名:: */"神秘仪器"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(神秘仪器占位)热羽流不断升腾,矿物在喷口周围堆积成塔。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(神秘仪器占位)水温骤升,前方有活跃热液喷口。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(神秘仪器占位)逼近喷口区域,仪表读数持续攀升。"/*::END:: */, children: ["z_vent_device"] }, /* ── 热泉生物群(热液泉区 zone) ── */ "vent_biota": { name: /*::GEN::场景名:: */"热泉生物群"/*::END:: */, modes: "zone_only", weight: 0, terrain: ["abyss"], mapSpan: {approach:1000, activeMin:1000, activeMax:1000, leave:1000}, spanMin: 1000, spanMax: 1000, regionVariants: {}, viewDesc: /*::GEN::viewDesc:: */"(热泉生物群占位)热羽流不断升腾,矿物在喷口周围堆积成塔。"/*::END:: */, approachDesc: /*::GEN::approachDesc:: */"(热泉生物群占位)水温骤升,前方有活跃热液喷口。"/*::END:: */, insideDesc: /*::GEN::insideDesc:: */"(热泉生物群占位)逼近喷口区域,仪表读数持续攀升。"/*::END:: */, children: ["z_vent_biota"] } }>> /* ═══════════════════════════════════════════════ 子房间(SmallScene)定义 $wsChildDefs 作为中型场景内的房间时: - 无独立距离(不占地图长度) - 焦点内联显示:点击房间名 → 显示 stages/resolve ═══════════════════════════════════════════════ */ <<set $wsChildDefs = { /* ══ 沉没的货轮 · 房间 ══ */ "wreck_cargo": { name: /*::GEN::场景名:: */"货舱"/*::END:: */, desc: /*::GEN::场景描述:: */"船体中部的货舱已经破裂,变形的集装箱散落在周围,有的还半埋在淤泥里。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"货舱裂缝很大,可以侧身挤进去。里面有几个变形的集装箱,其中一个似乎还密封着。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"撬开密封集装箱"/*::END:: */, /*::GEN::行动选项:: */"搜查散落货物"/*::END:: */, /*::GEN::行动选项:: */"检查淤泥中的碎片"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] }, { desc: /*::GEN::场景描述:: */"集装箱被撬开了,里面还有一些保存完好的货物,但大部分已经被海水侵蚀。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"仔细分拣货物"/*::END:: */, /*::GEN::行动选项:: */"快速捞取表层物品"/*::END:: */ ] } ], resolve: { "撬开密封集装箱": { next:1, loot:[{id:"metal",qty:[1,3]}], text:/*::GEN::场景结果:: */"集装箱门被撬开,一股陈腐的空气涌出,里面的货物保存得比预期好。"/*::END:: */ }, "搜查散落货物": { next:-1, loot:[{id:"metal",qty:[1,4]},{id:"rope",qty:[0,2]},{id:"glass",qty:[0,2]},{id:"coal",qty:[1,3]}], text:/*::GEN::场景结果:: */"散落的货物大多已损坏,但翻找到了一些还能用的材料。"/*::END:: */ }, "检查淤泥中的碎片": { next:-1, loot:[{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[1,2]}], timeCost:10, text:/*::GEN::场景结果:: */"在淤泥里摸索了一阵,摸到了几块保存较好的合金碎片。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"货舱情况复杂,决定不冒险。"/*::END:: */ }, "仔细分拣货物": { next:-1, loot:[{id:"metal",qty:[2,5]},{id:"rope",qty:[1,3]},{id:"glass",qty:[1,3]},{id:"coal",qty:[1,4]},{id:"wreck_steel",qty:[1,2]}], timeCost:15, text:/*::GEN::场景结果:: */"花了些时间仔细分拣,收获颇丰。"/*::END:: */ }, "快速捞取表层物品": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"rope",qty:[0,2]}], text:/*::GEN::场景结果:: */"只拿了最容易取到的几样东西。"/*::END:: */ } } }, "wreck_engine": { name: /*::GEN::场景名:: */"引擎室"/*::END:: */, desc: /*::GEN::场景描述:: */"船尾的引擎舱还算完整,管道和机械交错在一起,锈迹中混着干涸的油污。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"引擎室内部结构复杂,大型管道弯延在头顶,有些零件看起来状态还不错。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"仔细拆卸零件"/*::END:: */, /*::GEN::行动选项:: */"搜刮油料管道"/*::END:: */, /*::GEN::行动选项:: */"检查控制台"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] } ], resolve: { "仔细拆卸零件": { next:-1, loot:[{id:"iron",qty:[2,4]},{id:"rubber_seal",qty:[1,2]},{id:"metal",qty:[1,3]},{id:"coal",qty:[0,2]}], timeCost:20, text:/*::GEN::场景结果:: */"拆卸耗时较长,但零件状态比预期好不少。"/*::END:: */ }, "搜刮油料管道": { next:-1, loot:[{id:"oil",qty:[1,3]},{id:"coal",qty:[1,2]}], text:/*::GEN::场景结果:: */"管道里还残留了一些可用的油料。"/*::END:: */ }, "检查控制台": { next:-1, loot:[{id:"relic_log",qty:[0,1]},{id:"glass",qty:[0,2]},{id:"metal",qty:[1,2]}], timeCost:10, text:/*::GEN::场景结果:: */"控制台早已失灵,但抽屉里找到了一份还看得清的航行日志残页。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"引擎室太暗太危险,决定不深入。"/*::END:: */ } } }, "wreck_logbook": { name: /*::GEN::场景名:: */"船长室"/*::END:: */, desc: /*::GEN::场景描述:: */"船桥后方的船长室,舱门已腐朽,书桌和柜子还在原位。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"船长室的舱门轻轻一推就开了。书桌的抽屉半开着,角落里有一个密封的金属盒。墙上的航海图已经褪色但还能辨认。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"打开金属盒"/*::END:: */, /*::GEN::行动选项:: */"搜索书桌抽屉"/*::END:: */, /*::GEN::行动选项:: */"取下航海图"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] } ], resolve: { "打开金属盒": { next:-1, loot:[{id:"relic_log",qty:[1,1]},{id:"relic_formula",qty:[0,1]},{id:"pearl",qty:[0,1]}], text:/*::GEN::场景结果:: */"金属盒防水性能出色,里面的文件保存完好——是一份航海日志和几张手写的配方笔记。"/*::END:: */ }, "搜索书桌抽屉": { next:-1, loot:[{id:"relic_notebook",qty:[0,1]},{id:"glass",qty:[0,2]},{id:"metal",qty:[1,2]}], timeCost:8, text:/*::GEN::场景结果:: */"抽屉里翻到了一本被水泡胀的笔记本,还有几件金属文具。"/*::END:: */ }, "取下航海图": { next:-1, loot:[{id:"relic_etching",qty:[0,1]},{id:"paper",qty:[1,2]}], text:/*::GEN::场景结果:: */"航海图一碰就碎,但还是勉强取下了一块较完整的部分,上面标注了一些海域信息。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"船长室的东西看起来不太值钱,没有浪费时间。"/*::END:: */ } } }, "wreck_mail": { name: /*::GEN::场景名:: */"邮件舱"/*::END:: */, desc: /*::GEN::场景描述:: */"船体上层的邮件舱,曾经存放着待投递的包裹和信件,如今只剩腐朽的纸浆和散落的金属箱。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"邮件舱门半开,里面一片狼藉。大部分纸质品已经化为纸浆,但角落里有几个金属邮箱还算完整。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"撬开金属邮箱"/*::END:: */, /*::GEN::行动选项:: */"翻找纸浆中的硬物"/*::END:: */, /*::GEN::行动选项:: */"检查邮袋"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] } ], resolve: { "撬开金属邮箱": { next:-1, loot:[{id:"relic_notebook",qty:[0,2]},{id:"pearl",qty:[0,1]},{id:"metal",qty:[1,2]}], timeCost:10, text:/*::GEN::场景结果:: */"邮箱里有几封被密封袋保护的信件,内容尚可辨认,还有一枚不知价值的珠子。"/*::END:: */ }, "翻找纸浆中的硬物": { next:-1, loot:[{id:"metal",qty:[1,2]},{id:"glass",qty:[0,2]},{id:"coal",qty:[0,1]}], timeCost:15, text:/*::GEN::场景结果:: */"在湿烂的纸浆里摸了半天,找到了几块金属扣件和玻璃碎片。"/*::END:: */ }, "检查邮袋": { next:-1, loot:[{id:"relic_formula",qty:[0,1]},{id:"rope",qty:[1,2]},{id:"paper",qty:[1,3]}], text:/*::GEN::场景结果:: */"邮袋里的包裹大多已损坏,但找到了一封附有配方标注的信和一些尚可使用的绳索。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"邮件舱的东西太潮湿了,不值得花时间。"/*::END:: */ } } }, /* ══ 鲸落 · 房间 ══ */ "whale_skull": { name: /*::GEN::场景名:: */"头颅"/*::END:: */, desc: /*::GEN::场景描述:: */"鲸鱼的巨大头骨朝向天空般仰望,颌骨张开着,足以让一个人走进去。颅腔内部已经被生物占据。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"头骨周围的沙地上散落着牙齿和碎骨,颅腔里有微弱的动静——有什么东西在里面活动。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"采集鲸齿"/*::END:: */, /*::GEN::行动选项:: */"探入颅腔"/*::END:: */, /*::GEN::行动选项:: */"搜索颌骨缝隙"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] } ], resolve: { "采集鲸齿": { next:-1, loot:[{id:"bone_ash",qty:[2,4]},{id:"god_bone_frag",qty:[0,1]}], timeCost:10, text:/*::GEN::场景结果:: */"撬下了几颗还嵌在颌骨上的鲸齿,骨质特殊,比普通骨头重得多。"/*::END:: */ }, "探入颅腔": { next:-1, loot:[{id:"creature_husk",qty:[1,2]},{id:"jellyfluid",qty:[0,2]},{id:"deep_eye",qty:[0,1]}], timeCost:15, text:/*::GEN::场景结果:: */"颅腔里住着一群等足类生物,被光线惊扰后四散奔逃,顺手抓了几只。"/*::END:: */ }, "搜索颌骨缝隙": { next:-1, loot:[{id:"bone_ash",qty:[1,3]},{id:"coral_frag",qty:[1,2]}], text:/*::GEN::场景结果:: */"颌骨缝隙里积攒了不少碎骨和附生的珊瑚碎片。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"头骨太大了,感觉不太安全,决定不深入。"/*::END:: */ } } }, "whale_ribs": { name: /*::GEN::场景名:: */"肋骨"/*::END:: */, desc: /*::GEN::场景描述:: */"鲸鱼的肋骨如同拱门般排列,形成了一个天然的遮蔽空间。骨骼表面覆盖着厚厚的细菌席。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"肋骨之间的缝隙里积聚着大量有机物质,白色的细菌席像地毯一样铺满了骨架表面。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"刮取细菌席"/*::END:: */, /*::GEN::行动选项:: */"切割肋骨段"/*::END:: */, /*::GEN::行动选项:: */"搜索肋骨间沉积物"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] } ], resolve: { "刮取细菌席": { next:-1, loot:[{id:"biomass",qty:[2,5]},{id:"sulfur_dust",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"刮下了厚厚一层细菌席,这种化能合成生物是珍贵的生物质来源。"/*::END:: */ }, "切割肋骨段": { next:-1, loot:[{id:"bone_ash",qty:[2,5]},{id:"god_bone_frag",qty:[1,2]},{id:"fish_bone",qty:[1,3]}], timeCost:20, text:/*::GEN::场景结果:: */"肋骨材质特殊,切割时火花四溅,最终还是割下了几段。"/*::END:: */ }, "搜索肋骨间沉积物": { next:-1, loot:[{id:"bone_ash",qty:[1,3]},{id:"coral_frag",qty:[0,2]},{id:"kelp",qty:[1,2]}], timeCost:10, text:/*::GEN::场景结果:: */"沉积物里有一些碎骨和附生材料。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"肋骨区域太滑了,不想冒险。"/*::END:: */ } } }, "whale_tail": { name: /*::GEN::场景名:: */"尾部"/*::END:: */, desc: /*::GEN::场景描述:: */"鲸鱼的尾椎骨延伸向远处,逐渐变小,末端埋入淤泥中。这里的肌肉组织残留最多。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"尾部区域的有机物保存得较好,深层的脂肪和肌肉组织还没有完全分解。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"提取鲸脂"/*::END:: */, /*::GEN::行动选项:: */"采集尾椎骨"/*::END:: */, /*::GEN::行动选项:: */"检查淤泥中的残骸"/*::END:: */, /*::GEN::行动选项:: */"放弃"/*::END:: */ ] } ], resolve: { "提取鲸脂": { next:-1, loot:[{id:"oil",qty:[3,6]},{id:"biomass",qty:[1,3]}], timeCost:15, text:/*::GEN::场景结果:: */"尾部的鲸脂保存得最好,提取了大量高品质油脂。"/*::END:: */ }, "采集尾椎骨": { next:-1, loot:[{id:"bone_ash",qty:[3,6]},{id:"god_bone_frag",qty:[1,2]}], timeCost:15, text:/*::GEN::场景结果:: */"尾椎骨较小但数量多,采集了一批。"/*::END:: */ }, "检查淤泥中的残骸": { next:-1, loot:[{id:"bone_ash",qty:[1,2]},{id:"biomass",qty:[0,2]},{id:"creature_husk",qty:[0,1]}], timeCost:10, text:/*::GEN::场景结果:: */"淤泥里有一些散碎的骨片和生物蜕壳。"/*::END:: */ }, "放弃": { next:-1, loot:[], text:/*::GEN::场景结果:: */"尾部埋得太深,不好挖掘。"/*::END:: */ } } }, "whale_scavengers": { name: /*::GEN::场景名:: */"巡游的食腐者"/*::END:: */, desc: /*::GEN::场景描述:: */"骨架周围的水域里,一群食腐生物在巡游,它们以鲸落为生,形成了一个临时但繁忙的群落。"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"几条深海鱼在骨架周围游弋,还有一些螃蟹和等足类在骨缝间爬行。它们似乎已经习惯了这里的环境。"/*::END:: */, actions: [ /*::GEN::行动选项:: */"用网捕捞鱼群"/*::END:: */, /*::GEN::行动选项:: */"抓捕螃蟹"/*::END:: */, /*::GEN::行动选项:: */"采集等足类"/*::END:: */, /*::GEN::行动选项:: */"静静观察"/*::END:: */ ] } ], resolve: { "用网捕捞鱼群": { next:-1, loot:[{id:"grouper",qty:[1,3]},{id:"seabass",qty:[0,2]},{id:"bream",qty:[0,1]}], timeCost:10, text:/*::GEN::场景结果:: */"这些鱼不太怕人,一网下去收获不少。"/*::END:: */ }, "抓捕螃蟹": { next:-1, loot:[{id:"bluecrab",qty:[2,4]},{id:"flowercrab",qty:[0,2]},{id:"kingcrab",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"骨缝里的螃蟹又大又肥,甚至有一只帝王蟹。"/*::END:: */ }, "采集等足类": { next:-1, loot:[{id:"creature_husk",qty:[1,3]},{id:"jellyfluid",qty:[0,2]},{id:"deep_eye",qty:[0,1]}], timeCost:8, text:/*::GEN::场景结果:: */"等足类动物行动缓慢,很容易采集。其中有一种外形极其怪异的。"/*::END:: */ }, "静静观察": { next:-1, loot:[], timeCost:5, text:/*::GEN::场景结果:: */"观察了一会儿这个临时生态系统的运作方式,记录了下来。"/*::END:: */ } } }, /* ══ 游轮(沉船群 zone) ══ */ "z_wreck_cruise": { name: /*::GEN::场景名:: */"游轮探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(游轮 占位:沉船群 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(游轮 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(游轮 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(游轮 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(游轮 占位:离开)"/*::END:: */ } } }, /* ══ 军舰(沉船群 zone · 线索 zone,绑定必选) ══ */ "z_wreck_warship": { name: /*::GEN::场景名:: */"军舰探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(军舰 占位:沉船群 zone · 线索 zone,绑定必选)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(军舰 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(军舰 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(军舰 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(军舰 占位:离开)"/*::END:: */ } } }, /* ══ 远洋渔船(沉船群 zone) ══ */ "z_wreck_trawler": { name: /*::GEN::场景名:: */"远洋渔船探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(远洋渔船 占位:沉船群 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(远洋渔船 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(远洋渔船 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(远洋渔船 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(远洋渔船 占位:离开)"/*::END:: */ } } }, /* ══ 三桅帆船(沉船群 zone) ══ */ "z_wreck_schooner": { name: /*::GEN::场景名:: */"三桅帆船探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(三桅帆船 占位:沉船群 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(三桅帆船 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(三桅帆船 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(三桅帆船 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(三桅帆船 占位:离开)"/*::END:: */ } } }, /* ══ 科考船(沉船群 zone · 线索 zone,绑定必选) ══ */ "z_wreck_research": { name: /*::GEN::场景名:: */"科考船探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(科考船 占位:沉船群 zone · 线索 zone,绑定必选)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(科考船 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(科考船 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(科考船 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(科考船 占位:离开)"/*::END:: */ } } }, /* ══ 游艇(沉船群 zone 变体占位) ══ */ "z_wreck_yacht": { name: /*::GEN::场景名:: */"游艇探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(游艇 占位:沉船群 zone 变体占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(游艇 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(游艇 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(游艇 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(游艇 占位:离开)"/*::END:: */ } } }, /* ══ 渔船(沉船群 zone 变体占位) ══ */ "z_wreck_fishboat": { name: /*::GEN::场景名:: */"渔船探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(渔船 占位:沉船群 zone 变体占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(渔船 占位描述)(sand 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(渔船 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"wreck_steel",qty:[0,2]},{id:"iron",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(渔船 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(渔船 占位:离开)"/*::END:: */ } } }, /* ══ 公园(城市废墟 zone) ══ */ "z_ruin_park": { name: /*::GEN::场景名:: */"公园探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(公园 占位:城市废墟 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(公园 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(公园 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(公园 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(公园 占位:离开)"/*::END:: */ } } }, /* ══ 公寓(城市废墟 zone) ══ */ "z_ruin_apartment": { name: /*::GEN::场景名:: */"公寓探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(公寓 占位:城市废墟 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(公寓 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(公寓 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(公寓 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(公寓 占位:离开)"/*::END:: */ } } }, /* ══ 学校(城市废墟 zone) ══ */ "z_ruin_school": { name: /*::GEN::场景名:: */"学校探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(学校 占位:城市废墟 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(学校 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(学校 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(学校 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(学校 占位:离开)"/*::END:: */ } } }, /* ══ 工厂(城市废墟 zone) ══ */ "z_ruin_factory": { name: /*::GEN::场景名:: */"工厂探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(工厂 占位:城市废墟 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(工厂 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(工厂 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(工厂 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(工厂 占位:离开)"/*::END:: */ } } }, /* ══ 商场(城市废墟 zone) ══ */ "z_ruin_mall": { name: /*::GEN::场景名:: */"商场探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(商场 占位:城市废墟 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(商场 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(商场 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(商场 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(商场 占位:离开)"/*::END:: */ } } }, /* ══ 市政厅(城市废墟 zone) ══ */ "z_ruin_cityhall": { name: /*::GEN::场景名:: */"市政厅探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(市政厅 占位:城市废墟 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(市政厅 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(市政厅 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(市政厅 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(市政厅 占位:离开)"/*::END:: */ } } }, /* ══ 研究所(城市废墟 zone · 绑定必选) ══ */ "z_ruin_institute": { name: /*::GEN::场景名:: */"研究所探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(研究所 占位:城市废墟 zone · 绑定必选)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(研究所 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(研究所 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(研究所 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(研究所 占位:离开)"/*::END:: */ } } }, /* ══ 餐厅(建筑 C 类变体占位) ══ */ "z_ruin_restaurant": { name: /*::GEN::场景名:: */"餐厅探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(餐厅 占位:建筑 C 类变体占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(餐厅 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(餐厅 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(餐厅 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(餐厅 占位:离开)"/*::END:: */ } } }, /* ══ 花店(建筑 C 类变体占位) ══ */ "z_ruin_florist": { name: /*::GEN::场景名:: */"花店探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(花店 占位:建筑 C 类变体占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(花店 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(花店 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(花店 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(花店 占位:离开)"/*::END:: */ } } }, /* ══ 面包房(建筑 C 类变体占位) ══ */ "z_ruin_bakery": { name: /*::GEN::场景名:: */"面包房探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(面包房 占位:建筑 C 类变体占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(面包房 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(面包房 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(面包房 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(面包房 占位:离开)"/*::END:: */ } } }, /* ══ 民居(建筑 C 类变体占位) ══ */ "z_ruin_house": { name: /*::GEN::场景名:: */"民居探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(民居 占位:建筑 C 类变体占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(民居 占位描述)(flat 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(民居 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"metal",qty:[1,3]},{id:"glass",qty:[0,2]},{id:"relic_log",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(民居 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(民居 占位:离开)"/*::END:: */ } } }, /* ══ 峭壁人类建筑(残坑限定 zone · 要素① · 绑定必选) ══ */ "z_cliff_building": { name: /*::GEN::场景名:: */"峭壁人类建筑探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(峭壁人类建筑 占位:残坑限定 zone · 要素① · 绑定必选)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(峭壁人类建筑 占位描述)(cliff 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(峭壁人类建筑 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"iron",qty:[1,2]},{id:"bone_ash",qty:[0,2]},{id:"sulfur_dust",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(峭壁人类建筑 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(峭壁人类建筑 占位:离开)"/*::END:: */ } } }, /* ══ 寄居深海生物聚居(残坑 zone · 要素②,可散装待定) ══ */ "z_cliff_colony": { name: /*::GEN::场景名:: */"寄居生物聚居探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(寄居生物聚居 占位:残坑 zone · 要素②,可散装待定)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(寄居生物聚居 占位描述)(cliff 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(寄居生物聚居 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"iron",qty:[1,2]},{id:"bone_ash",qty:[0,2]},{id:"sulfur_dust",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(寄居生物聚居 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(寄居生物聚居 占位:离开)"/*::END:: */ } } }, /* ══ 特殊采集物(残坑限定 zone · 要素④ · 名称与机制待用户定) ══ */ "z_cliff_relic": { name: /*::GEN::场景名:: */"特殊采集点探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(特殊采集点 占位:残坑限定 zone · 要素④ · 名称与机制待用户定)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(特殊采集点 占位描述)(cliff 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(特殊采集点 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"iron",qty:[1,2]},{id:"bone_ash",qty:[0,2]},{id:"sulfur_dust",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(特殊采集点 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(特殊采集点 占位:离开)"/*::END:: */ } } }, /* ══ 育幼场(牧场 zone · 绑定必选 · 信标/慈爱相关) ══ */ "z_pasture_nursery": { name: /*::GEN::场景名:: */"育幼场探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(育幼场 占位:牧场 zone · 绑定必选 · 信标/慈爱相关)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(育幼场 占位描述)(grass 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(育幼场 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"kelp",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(育幼场 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(育幼场 占位:离开)"/*::END:: */ } } }, /* ══ 小屋(牧场 zone · 无人但生活痕迹新鲜) ══ */ "z_pasture_cabin": { name: /*::GEN::场景名:: */"小屋探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(小屋 占位:牧场 zone · 无人但生活痕迹新鲜)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(小屋 占位描述)(grass 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(小屋 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"kelp",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(小屋 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(小屋 占位:离开)"/*::END:: */ } } }, /* ══ 兽群(牧场 zone · 可猎杀/可照顾) ══ */ "z_pasture_herd": { name: /*::GEN::场景名:: */"兽群探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(兽群 占位:牧场 zone · 可猎杀/可照顾)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(兽群 占位描述)(grass 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(兽群 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"kelp",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(兽群 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(兽群 占位:离开)"/*::END:: */ } } }, /* ══ 花园(牧场 zone · 规范注可散装,暂仅作 zone) ══ */ "z_pasture_garden": { name: /*::GEN::场景名:: */"花园探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(花园 占位:牧场 zone · 规范注可散装,暂仅作 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(花园 占位描述)(grass 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(花园 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"kelp",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(花园 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(花园 占位:离开)"/*::END:: */ } } }, /* ══ 海豚岛(永夜礁石限定 zone · 不散装) ══ */ "z_reef_dolphin": { name: /*::GEN::场景名:: */"海豚岛探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(海豚岛 占位:永夜礁石限定 zone · 不散装)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(海豚岛 占位描述)(reef 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(海豚岛 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"coral_frag",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(海豚岛 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(海豚岛 占位:离开)"/*::END:: */ } } }, /* ══ 墓火(永夜礁石限定 zone · 不散装) ══ */ "z_reef_gravefire": { name: /*::GEN::场景名:: */"墓火探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(墓火 占位:永夜礁石限定 zone · 不散装)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(墓火 占位描述)(reef 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(墓火 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"coral_frag",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(墓火 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(墓火 占位:离开)"/*::END:: */ } } }, /* ══ 陶玛斯 location(绑定永夜礁石 · 出舱探索可进岛) ══ */ "z_reef_thomas": { name: /*::GEN::场景名:: */"陶玛斯探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(陶玛斯 占位:绑定永夜礁石 · 出舱探索可进岛)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(陶玛斯 占位描述)(reef 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(陶玛斯 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"coral_frag",qty:[1,3]},{id:"biomass",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(陶玛斯 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(陶玛斯 占位:离开)"/*::END:: */ } } }, /* ══ 灰鲸入林(海藻森林 B 类中型 · 占位) ══ */ "z_forest_whale": { name: /*::GEN::场景名:: */"灰鲸入林探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(灰鲸入林 占位:海藻森林 B 类中型 · 占位)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(灰鲸入林 占位描述)(forest 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(灰鲸入林 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"bone_ash",qty:[1,3]},{id:"kelp_fiber",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(灰鲸入林 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(灰鲸入林 占位:离开)"/*::END:: */ } } }, /* ══ 污染尸骸(人鱼狱核心 zone · 绑定必选 · 通向下一 location) ══ */ "z_prison_carcass": { name: /*::GEN::场景名:: */"污染尸骸探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(污染尸骸 占位:人鱼狱核心 zone · 绑定必选 · 通向下一 location)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(污染尸骸 占位描述)(forest 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(污染尸骸 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"bone_ash",qty:[1,3]},{id:"kelp_fiber",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(污染尸骸 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(污染尸骸 占位:离开)"/*::END:: */ } } }, /* ══ 水雷区(人鱼狱限定 zone · 高危) ══ */ "z_prison_minefield": { name: /*::GEN::场景名:: */"水雷区探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(水雷区 占位:人鱼狱限定 zone · 高危)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(水雷区 占位描述)(forest 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(水雷区 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"bone_ash",qty:[1,3]},{id:"kelp_fiber",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(水雷区 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(水雷区 占位:离开)"/*::END:: */ } } }, /* ══ 骨骸林(人鱼狱限定 zone · 精神伤害) ══ */ "z_prison_bonewood": { name: /*::GEN::场景名:: */"骨骸林探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(骨骸林 占位:人鱼狱限定 zone · 精神伤害)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(骨骸林 占位描述)(forest 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(骨骸林 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"bone_ash",qty:[1,3]},{id:"kelp_fiber",qty:[0,2]}], timeCost:12, text:/*::GEN::场景结果:: */"(骨骸林 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(骨骸林 占位:离开)"/*::END:: */ } } }, /* ══ 巨大骨骸(盐湖区 zone · 绑定必选) ══ */ "z_salt_bones": { name: /*::GEN::场景名:: */"巨大骨骸探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(巨大骨骸 占位:盐湖区 zone · 绑定必选)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(巨大骨骸 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(巨大骨骸 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"ember_crystal",qty:[0,2]},{id:"seawater_ext",qty:[1,3]}], timeCost:12, text:/*::GEN::场景结果:: */"(巨大骨骸 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(巨大骨骸 占位:离开)"/*::END:: */ } } }, /* ══ 结晶滩涂(盐湖区 zone) ══ */ "z_salt_crystal": { name: /*::GEN::场景名:: */"结晶滩涂探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(结晶滩涂 占位:盐湖区 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(结晶滩涂 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(结晶滩涂 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"ember_crystal",qty:[0,2]},{id:"seawater_ext",qty:[1,3]}], timeCost:12, text:/*::GEN::场景结果:: */"(结晶滩涂 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(结晶滩涂 占位:离开)"/*::END:: */ } } }, /* ══ 湖面幻象(盐湖区 zone · 按 $san 差分) ══ */ "z_salt_mirage": { name: /*::GEN::场景名:: */"湖面幻象探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(湖面幻象 占位:盐湖区 zone · 按 $san 差分)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(湖面幻象 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(湖面幻象 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"ember_crystal",qty:[0,2]},{id:"seawater_ext",qty:[1,3]}], timeCost:12, text:/*::GEN::场景结果:: */"(湖面幻象 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(湖面幻象 占位:离开)"/*::END:: */ } } }, /* ══ 研究所废墟(热液泉区 zone · 绑定必选 · 需出舱探索进深处) ══ */ "z_vent_lab": { name: /*::GEN::场景名:: */"研究所废墟探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(研究所废墟 占位:热液泉区 zone · 绑定必选 · 需出舱探索进深处)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(研究所废墟 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(研究所废墟 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"thermal_ext",qty:[1,2]},{id:"ember_crystal",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(研究所废墟 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(研究所废墟 占位:离开)"/*::END:: */ } } }, /* ══ 火山口(热液泉区 zone) ══ */ "z_vent_crater": { name: /*::GEN::场景名:: */"火山口探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(火山口 占位:热液泉区 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(火山口 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(火山口 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"thermal_ext",qty:[1,2]},{id:"ember_crystal",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(火山口 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(火山口 占位:离开)"/*::END:: */ } } }, /* ══ 神秘仪器(热液泉区 zone · 仍在运行,略诡异) ══ */ "z_vent_device": { name: /*::GEN::场景名:: */"神秘仪器探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(神秘仪器 占位:热液泉区 zone · 仍在运行,略诡异)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(神秘仪器 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(神秘仪器 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"thermal_ext",qty:[1,2]},{id:"ember_crystal",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(神秘仪器 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(神秘仪器 占位:离开)"/*::END:: */ } } }, /* ══ 热泉生物群(热液泉区 zone) ══ */ "z_vent_biota": { name: /*::GEN::场景名:: */"热泉生物群探查"/*::END:: */, desc: /*::GEN::场景描述:: */"(热泉生物群 占位:热液泉区 zone)"/*::END:: */, stages: [ { desc: /*::GEN::场景描述:: */"(热泉生物群 占位描述)(abyss 地形限定变体 / 通用变体)"/*::END:: */, actions: [ /*::GEN::行动选项:: */"查看"/*::END:: */, /*::GEN::行动选项:: */"互动"/*::END:: */, /*::GEN::行动选项:: */"离开"/*::END:: */ ] } ], resolve: { "查看": { next:-1, loot:[], timeCost:3, text:/*::GEN::场景结果:: */"(热泉生物群 占位:查看结果)"/*::END:: */ }, "互动": { next:-1, loot:[{id:"thermal_ext",qty:[1,2]},{id:"ember_crystal",qty:[0,1]}], timeCost:12, text:/*::GEN::场景结果:: */"(热泉生物群 占位:互动结果,获得材料)"/*::END:: */ }, "离开": { next:-1, loot:[], text:/*::GEN::场景结果:: */"(热泉生物群 占位:离开)"/*::END:: */ } } } }>> <</widget>> <</nobr>>
<<nobr>> <<widget "additem">> <<set _ai_id = $args[0]>> <<set _ai_qty = $args[1]>> <<set _ai_def = State.variables.items[_ai_id]>> <<if !_ai_def>> <<print "错误:未知物品 " + _ai_id>> <<else>> <<set _ai_type = _ai_def.type>> <<if !$store[_ai_type]>><<set $store[_ai_type] = []>><</if>> /* 按当天日期分批(同日入库合并) */ <<set _ai_today = $day || 0>> <<set _ai_idx = -1>> <<for _ai_i = 0; _ai_i < $store[_ai_type].length; _ai_i++>> <<set _ai_e = $store[_ai_type][_ai_i]>> <<if _ai_e.id === _ai_id && (_ai_e.addedDay === _ai_today || (!_ai_e.addedDay && _ai_today === 0))>> <<set _ai_idx = _ai_i>> <<break>> <</if>> <</for>> <<if _ai_idx >= 0>> <<set $store[_ai_type][_ai_idx].quantity += _ai_qty>> <<else>> <<set _ai_newEntry = { id: _ai_id, quantity: _ai_qty, addedDay: _ai_today }>> <<run State.variables.store[_ai_type].push(_ai_newEntry)>> <</if>> <<print "获得 " + _ai_qty + " × " + _ai_def.name>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "assembleDish">> <<set _ad_t = $cookTemplate>> <<set _ad_ings = $cookIngredients>> <<set _ad_m = $cookMethod>> <<set _ad_q = $cookQuality>> /* 用纯 SugarCube for 循环收集碎片,不使用 <<run function>> */ <<set _ad_parts = []>> <<for _ad_i = 0; _ad_i < _ad_ings.length; _ad_i++>> <<set _ad_ingId = _ad_ings[_ad_i]>> <<set _ad_ingDef = State.variables.items[_ad_ingId]>> <<set _ad_fmap = $cookFragments ? $cookFragments[_ad_ingId] : null>> <<set _ad_frag = "">> /* 先查精确ID */ <<if _ad_fmap>> <<set _ad_frag = _ad_fmap[_ad_m] || _ad_fmap["_"] || "">> <</if>> /* 再查分类兜底 */ <<if !_ad_frag && _ad_ingDef && _ad_ingDef.foodtags>> <<for _ad_ti = 0; _ad_ti < _ad_ingDef.foodtags.length; _ad_ti++>> <<set _ad_catKey = "_" + _ad_ingDef.foodtags[_ad_ti] + "_">> <<set _ad_cmap = $cookFragments ? $cookFragments[_ad_catKey] : null>> <<if _ad_cmap>> <<set _ad_frag = _ad_cmap[_ad_m] || _ad_cmap["_"] || "">> <<if _ad_frag>><<break>><</if>> <</if>> <</for>> <</if>> <<if _ad_frag>><<run _ad_parts.push(_ad_frag)>><</if>> <</for>> <<set _ad_fragText = _ad_parts.join("")>> /* 品质修正 */ <<set _ad_mult = _ad_q === "完美" ? 1.3 : (_ad_q === "失败" ? 0.4 : 1.0)>> <<set _ad_sanBonus = _ad_q === "完美" ? 3 : (_ad_q === "失败" ? -3 : 0)>> <<set _ad_hunger = Math.round(_ad_t.hunger * _ad_mult)>> <<set _ad_water = Math.round(_ad_t.water * _ad_mult)>> <<set _ad_life = Math.round(_ad_t.life * _ad_mult)>> <<set _ad_power = Math.round(_ad_t.power * _ad_mult)>> <<set _ad_san = Math.round(_ad_t.san * _ad_mult) + _ad_sanBonus>> <<set _ad_magic = _ad_t.magic || 0>> /* 品质附加描述 */ <<set _ad_qualDesc = "">> <<if _ad_q === "完美">> <<set _ad_qualDesc = "火候拿捏得分毫不差,食材的所有潜力都被完整发挥了出来。">> <<elseif _ad_q === "失败">> <<set _ad_qualDesc = "火候没有控制好,最终结果差强人意,只能勉强果腹。">> <</if>> /* 拼接最终描述 */ <<set _ad_desc = (_ad_t.open || "") + _ad_fragText + (_ad_t.close || "") + (_ad_qualDesc ? " " + _ad_qualDesc : "")>> /* 食材名列表 */ <<set _ad_ingNames = []>> <<for _adi = 0; _adi < _ad_ings.length; _adi++>> <<set _ad_idef2 = State.variables.items[_ad_ings[_adi]]>> <<if _ad_idef2>><<run _ad_ingNames.push(_ad_idef2.name)>><</if>> <</for>> /* 构建实例 */ <<set _ad_dish = { template: _ad_t.id || "custom", name: _ad_t.name, method: _ad_m, ingredients: _ad_ings.slice(), ingNames: _ad_ingNames.slice(), quality: _ad_q, desc: _ad_desc, hunger: _ad_hunger, water: _ad_water, life: _ad_life, power: _ad_power, san: _ad_san, magic: _ad_magic, addedDay: $day || 0 }>> /* 找冰箱空位 */ <<if !$fridge>><<set $fridge = [null,null,null,null,null,null,null,null]>><</if>> <<set _ad_slot = -1>> <<for _ads = 0; _ads < $fridge.length; _ads++>> <<if $fridge[_ads] === null>> <<set _ad_slot = _ads>> <<break>> <</if>> <</for>> <<if _ad_slot < 0>> <<set $assembleResult = "full">> <<else>> <<set $fridge[_ad_slot] = _ad_dish>> <<set $assembleResult = "ok">> <<set $assembleSlot = _ad_slot>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "addBookmark">> <<set _bmL = $args[0] || ($mapinfo[$maptype] ? $mapinfo[$maptype].type : $maptype)>> <<set _bmT = $args[1] || "auto">> <<set _bmLg = ($largeScene && $largeScene !== 0 && $largeScene.state === "active") ? $largeScene.name : "">> <<run $bookmarks.unshift({label:_bmL, type:_bmT, mt:$maptype, depth:$depthdeep, day:$day, lg:_bmLg})>> <<if $bookmarks.length > 20>><<run $bookmarks.pop()>><</if>> <</widget>> <<widget "bookmarkPanel">> <<if $bookmarks.length === 0>><span style="opacity:0.4;font-size:0.75rem;">尚无记录</span><<return>><</if>> <<set _bmMax = Math.min($bookmarks.length, 8)>> <<for _bmi = 0; _bmi < _bmMax; _bmi++>> <<set _bm = $bookmarks[_bmi]>> <<capture _bm>> <div style="font-size:0.73rem;color:var(--bone-dim);line-height:1.6;border-bottom:1px solid var(--border-dim);padding:0.1rem 0;"> <span style="color:var(--bone);"><<print _bm.label>></span><span style="opacity:0.5;"> · <<print _bm.mt>> <<print _bm.depth>>m · 第<<print _bm.day>>日</span><<if _bm.lg>><span style="color:var(--amber);"> [<<print _bm.lg>>]</span><</if>> </div> <</capture>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "checkEnvEffects">> /* ────────────────────────────────────────── checkEnvEffects — 第四批 调用时机:每次 sail tick(checkEvent 前) 每次 exploreSearch 每次 diveStep 功能: ① envEffects 条目逐一推进生长周期 ② ecoBonds 条目记录最后访问日并控制冷却 ────────────────────────────────────────── */ /* ── envEffects:遍历所有持久环境效果 ── */ <<for _ceI = 0; _ceI < $envEffects.length; _ceI++>> <<set _ceEff = $envEffects[_ceI]>> /* 只处理当前地形+深度匹配的条目 */ <<set _ceTMatch = (_ceEff.terrain === $maptype)>> <<set _ceDMatch = ($depth >= _ceEff.depthMin && $depth <= _ceEff.depthMax)>> <<if !_ceTMatch || !_ceDMatch>><<continue>><</if>> /* kelp_farm:海带农场生长周期 */ <<if _ceEff.type === "kelp_farm">> <<set _ceAge = ($day || 0) - (_ceEff.plantedDay || 0)>> <<if _ceEff.state === "growing" && _ceAge >= 10>> <<set $envEffects[_ceI].state = "ready">> <</if>> /* ready 状态下提示玩家可收获(UI 在 smallEventTable 的影响类事件里处理) */ <</if>> /* 占位:其他影响类型后续扩展 */ <</for>> /* ── ecoBonds:冷却检查(不修改 bond 值,只做访问时间记录) ── */ <<set _ceBKeys = Object.keys($ecoBonds)>> <<for _ceBI = 0; _ceBI < _ceBKeys.length; _ceBI++>> <<set _ceBK = _ceBKeys[_ceBI]>> <<set _ceBnd = $ecoBonds[_ceBK]>> <<if !_ceBnd.active>><<continue>><</if>> /* 地形+深度匹配才处理 */ <<set _ceBTM = (_ceBnd.terrain === $maptype)>> <<set _ceBDM = ($depth >= _ceBnd.depthMin && $depth <= _ceBnd.depthMax)>> <<if !_ceBTM || !_ceBDM>><<continue>><</if>> /* 写入最后访问日(供好感类事件读取,不在此处修改 bond) */ <<set $ecoBonds[_ceBK].lastVisit = $day || 0>> <</for>> <</widget>> <</nobr>>
<<nobr>> /* 统一重置:每次总池尝试,或有长度事件完整离场后,从当前位置重新起算。 */ <<widget "resetEventDistance">> <<set $eventDistance = 0>> <<set _ecool = Number($eventCooldownDistance)>><<if !isFinite(_ecool) || _ecool < 0>><<set _ecool = 0>><</if>> <<set $eventDistanceCooldown = _ecool>> <<set _emin = Number($eventDistanceMin) || 2000>> <<set _emax = Number($eventDistanceMax) || 8000>> <<if _emax < _emin>><<set _etmp = _emin>><<set _emin = _emax>><<set _emax = _etmp>><</if>> <<set $eventDistanceThreshold = _emin + Math.floor(Math.random() * (_emax - _emin + 1))>> <</widget>> <<widget "checkEvent">> /* 航行途中的"底噪"调度器。 中型事件已全部迁移至 spawnWorldScene(世界场景,含接近/进入/离开状态机), 本 widget 只保留统一 ABC 总池与 NPC 遭遇。 */ <<set _eventGateBlocked = !!( $activeEvent || $activeSmallEvent || $activeMicroEvent || ($activeHuntItems && $activeHuntItems.length > 0) || ($temporalEvent && $temporalEvent !== 0) || ($worldScene && typeof $worldScene === "object" && $worldScene.state !== "done") )>> <<if !_eventGateBlocked && (Number($eventDistance) || 0) >= (Number($eventDistanceThreshold) || 2000) && (Number($eventDistanceCooldown) || 0) <= 0 && $sailspd > 0>> /* 达到随机实际距离门槛后只尝试一次;命中与否都进入距离冷却。 */ <<_resetEventDistance>> <<set $eventPass += 1>> /* 正常航行统一 ABC 总池:区域外 B:C=1:1,大型区域内 B:C=1:1。 */ <<devRandomTotal "normal">> /* 总池 widget 复用 DEV 的候选筛选与 sceneType 分发;正常模式不显示 DEV 回执。 */ <<set $devMsg = "">> <<if $activeSmallEvent && $smallEventDefs[$activeSmallEvent.id] && $smallEventDefs[$activeSmallEvent.id].interrupt>> <<set $sailspd = 0>> <</if>> /* ══ NPC 遭遇(轻量事件模板)══ */ <<if !$activeEvent && !$activeSmallEvent>> <<if !$npcDefTable>><<npcDefs>><</if>> <<set _npcCoolOk = (!$npcSpawnCooldown || $npcSpawnCooldown <= ($day||0))>> <<if _npcCoolOk && Math.random() < 0.0008>> <<set _npcPool = []>> <<set _npcKeys = Object.keys($npcDefTable)>> <<for _ni = 0; _ni < _npcKeys.length; _ni++>> <<set _nd = $npcDefTable[_npcKeys[_ni]]>> <<set _nOk = (_nd.condition === "always")>> <<set _nInCtx = false>> <<for _nci = 0; _nci < _nd.spawnCtx.length; _nci++>> <<if _nd.spawnCtx[_nci] === "sailing">><<set _nInCtx = true>><</if>> <</for>> <<if _nOk && _nInCtx>> <<for _nwi = 0; _nwi < _nd.weight; _nwi++>><<run _npcPool.push(_npcKeys[_ni])>><</for>> <</if>> <</for>> <<if _npcPool.length > 0>> <<set _npcPickId = _npcPool[Math.floor(Math.random() * _npcPool.length)]>> <<set $activeNpc = $npcDefTable[_npcPickId]>> <<set $activeEvent = {id:"npc_"+_npcPickId, name:$activeNpc.name, desc:"一艘不明船只靠近,对方发来接触信号。", type:"event", actions:["前去交谈","无视离开"]}>> <<set $sailspd = 0>> <<set $eventPass = 0>> <</if>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "combatExecRound">> /* 调用:<<combatExecRound "action">> 行动值:进攻 / 警戒 / 防御 / 观察 / 休息 / 逃跑 item_add_flaw / item_restore_hp / item_must_hit / item_lock_escape 结果写入:$activeCombat.result, $activeCombat.log */ <<set _act = String($args[0])>> <<set _p = $activeCombat.player>> <<set _e = $activeCombat.enemy>> <<set _log = "">> /* $weaponMult 默认值在 VarIndex 中初始化为1,这里保留安全回退 */ <<set _wm = ($weaponMult || 1)>> /* ══════════════════════════════════════ 玩家行动 ══════════════════════════════════════ */ <<if _act === "进攻">> /* 进攻消耗体力 */ <<set _p.alertness = Math.max(0, _p.alertness - 10)>> <<set _p.hp = Math.max(0, _p.hp - 10)>> /* miss 判定:无破绽20%,1层10%,2层以上必中;mustHit强制命中 */ <<set _missRate = _e.flaws >= 2 ? 0 : (_e.flaws === 1 ? 0.10 : 0.20)>> <<if _p.mustHit>><<set _missRate = 0>><</if>> <<set _p.mustHit = false>> <<if Math.random() < _missRate>> <<set _p.morale = Math.max(0, _p.morale - 5)>> <<set _e.morale = Math.min(100, _e.morale + 5)>> <<set _log += "你发动攻击,但落了空。">> <<else>> <<set _dmg = Math.floor((10 + Math.floor(Math.random() * 11)) * _wm * (1 + _e.flaws * 0.3))>> <<set _e.injury = Math.min(999, _e.injury + _dmg)>> <<set _e.hp = Math.max(0, _e.hp - _dmg)>> <<set _e.morale = Math.max(0, _e.morale - 8)>> <<set _p.morale = Math.min(100, _p.morale + 5)>> <<set _log += "你发起攻击,造成 "+_dmg+" 点伤势"+(_e.flaws > 0 ? "(破绽×"+_e.flaws+")" : "")+"。">> <</if>> <<elseif _act === "警戒">> <<set _p.alertness = Math.min(100, _p.alertness + 30)>> <<if Math.random() < _p.alertness / 100>> <<set _e.flaws = Math.min(3, _e.flaws + 1)>> <<set _p.flaws = Math.max(0, _p.flaws - 1)>> <<set _log += "你保持高度警觉,察觉敌方破绽(共 "+_e.flaws+" 层)。">> <<else>> <<set _log += "你提高警觉,暂未发现破绽。">> <</if>> <<elseif _act === "防御">> <<set _p.alertness = Math.max(0, _p.alertness - 5)>> <<set _p.nextDefend = true>> <<set _log += "你摆好防御姿态,准备格挡下一击。">> <<elseif _act === "观察">> <<set _p.alertness = Math.min(100, _p.alertness + 15)>> <<if _p.alertness > 50 && Math.random() < 0.4>> <<set _e.flaws = Math.min(3, _e.flaws + 1)>> <<set _log += "你仔细观察,发现敌方破绽(共 "+_e.flaws+" 层)。">> <<else>> <<set _log += "你审视敌人的动向,尚未找到可乘之机。">> <</if>> <<elseif _act === "休息">> <<set _p.hp = Math.min(_p.hpMax, _p.hp + 20)>> <<set _p.alertness = Math.max(0, _p.alertness - 25)>> <<set _p.morale = Math.min(100, _p.morale + 10)>> <<set _log += "你短暂休整,恢复体力(+20)。">> <<elseif _act === "逃跑">> /* 敌方警觉显著高于我方时有50%阻拦概率 */ <<set _fleeBlock = (_e.alertness > _p.alertness + 20) ? 0.5 : 0>> <<if Math.random() < _fleeBlock>> <<set _p.morale = Math.max(0, _p.morale - 10)>> <<set _log += "你试图撤退,被对��拦截!">> /* 继续走敌方回合 */ <<else>> <<set $activeCombat.result = "player_flee">> <<set $activeCombat.log = _log + "你趁隙脱身,撤出了战斗。">> <<set $power = Math.max(0, $power - Math.floor((_p.hpMax - _p.hp) / 2))>> <<return>> <</if>> /* ── 道具(测试用,占用一个回合,无数量消耗)── */ <<elseif _act === "item_add_flaw">> <<set _e.flaws = Math.min(3, _e.flaws + 2)>> <<set _log += "投出诱饵,强制暴露敌方破绽(+2层,共 "+_e.flaws+" 层)。">> <<elseif _act === "item_restore_hp">> <<set _p.hp = Math.min(_p.hpMax, _p.hp + 30)>> <<set _log += "使用恢复剂,体力恢复 +30。">> <<elseif _act === "item_must_hit">> <<set _p.mustHit = true>> <<set _log += "使用瞄准装置,下次攻击必定命中。">> <<elseif _act === "item_lock_escape">> <<set _e.lockedEscape = true>> <<set _log += "投出声爆弹,敌方本回合无法逃跑。">> <</if>> /* ══════════════════════════════════════ 敌方回合(仅在战斗未结束时执行) ══════════════════════════════════════ */ <<if !$activeCombat.result>> /* ── 敌方 AI 行动选择(2×2 状态矩阵)── */ <<set _aHigh = _e.alertness >= 50>> <<set _mHigh = _e.morale >= 40>> <<set _r = Math.random()>> <<set _eAct = "进攻">> <<if _aHigh && _mHigh>> /* 战术型:有破绽再打,否则蓄积 */ <<if _p.flaws >= 2>> <<set _eAct = _r < 0.70 ? "进攻" : "警戒">> <<else>> <<set _eAct = _r < 0.50 ? "警戒" : (_r < 0.80 ? "观察" : "防御")>> <</if>> <<elseif _aHigh && !_mHigh>> /* 保守型:防御/观察为主 */ <<set _eAct = _r < 0.40 ? "防御" : (_r < 0.70 ? "观察" : "休息")>> <<elseif !_aHigh && _mHigh>> /* 莽撞型:大量进攻 */ <<set _eAct = _r < 0.70 ? "进攻" : (_r < 0.90 ? "防御" : "警戒")>> <<else>> /* 慌乱型 */ <<set _eAct = _r < 0.40 ? "进攻" : (_r < 0.70 ? "休息" : "警戒")>> <</if>> /* ── 执行敌方行动 ── */ <<if _eAct === "进攻">> <<set _e.alertness = Math.max(0, _e.alertness - 10)>> <<set _e.hp = Math.max(0, _e.hp - 10)>> <<set _eMiss = _p.flaws >= 2 ? 0 : (_p.flaws === 1 ? 0.10 : 0.20)>> <<if Math.random() < _eMiss>> <<set _e.morale = Math.max(0, _e.morale - 5)>> <<set _p.morale = Math.min(100, _p.morale + 5)>> <<set _log += _e.name+"的攻击偏离了目标。">> <<else>> <<set _eDmg = Math.floor((8 + Math.floor(Math.random() * 8)) * (1 + _p.flaws * 0.3))>> <<if _p.nextDefend || _p.dmgHalf>><<set _eDmg = Math.floor(_eDmg / 2)>><</if>> <<set _p.injury = Math.min(100, _p.injury + _eDmg)>> <<set _p.morale = Math.max(0, _p.morale - 8)>> <<set _e.morale = Math.min(100, _e.morale + 5)>> <<set _log += _e.name+"发起攻击,你受到 "+_eDmg+" 点伤势"+(_p.flaws > 0 ? "(破绽×"+_p.flaws+")" : "")+"。">> <</if>> <<elseif _eAct === "警戒">> <<set _e.alertness = Math.min(100, _e.alertness + 30)>> <<if Math.random() < _e.alertness / 100>> <<set _p.flaws = Math.min(3, _p.flaws + 1)>> <<set _e.flaws = Math.max(0, _e.flaws - 1)>> <<set _log += _e.name+"警觉地观察,察觉了你的破绽("+_p.flaws+"层)。">> <<else>> <<set _log += _e.name+"提高了警觉。">> <</if>> <<elseif _eAct === "观察">> <<set _e.alertness = Math.min(100, _e.alertness + 15)>> <<if _e.alertness > 50 && Math.random() < 0.4>> <<set _p.flaws = Math.min(3, _p.flaws + 1)>> <<set _log += _e.name+"审视你的动作,发现你的破绽("+_p.flaws+"层)。">> <<else>> <<set _log += _e.name+"打量着你。">> <</if>> <<elseif _eAct === "防御">> <<set _e.alertness = Math.max(0, _e.alertness - 5)>> <<set _e.nextDefend = true>> <<set _log += _e.name+"摆好防御姿态。">> <<elseif _eAct === "休息">> <<set _e.hp = Math.min(_e.hpMax, _e.hp + 10)>> <<set _e.alertness = Math.max(0, _e.alertness - 15)>> <<set _log += _e.name+"暂时后退,恢复体力。">> <</if>> /* ── 回合末:破绽更新(警觉差值驱动)── */ <<set _alertDiff = _p.alertness - _e.alertness>> <<if _alertDiff > 20>> <<set _e.flaws = Math.min(3, _e.flaws + 1)>> <<set _log += " (你的警觉压制对方,敌方破绽+1)">> <<elseif _alertDiff < -20>> <<set _p.flaws = Math.min(3, _p.flaws + 1)>> <<set _log += " (你的警觉不足,己方破绽+1)">> <</if>> /* ── 敌方逃跑检定 ── */ <<if !_e.lockedEscape && _e.morale < 30>> <<set _escProb = (30 - _e.morale) / 40>> <<if Math.random() < _escProb>> <<set $activeCombat.result = "enemy_flee">> <<set _log += " "+_e.name+"丧失战意,仓皇逃去。">> <<else>> <<set _e.morale = Math.max(0, _e.morale - 15)>> <<set _p.morale = Math.min(100, _p.morale + 10)>> <<set _log += " "+_e.name+"试图逃跑,被你挡住了!">> <</if>> <</if>> /* ── 重置单回合标志 ── */ <<set _p.nextDefend = false>> <<set _e.nextDefend = false>> <<set _p.dmgHalf = false>> <<set _e.lockedEscape = false>> /* ── 终止条件 ── */ <<if !$activeCombat.result>> <<if _e.injury >= _e.injuryMax>> <<set $activeCombat.result = "kill">> <<set _log += " 【"+_e.name+"被击倒!】">> <<elseif _p.injury >= 100>> <<set $activeCombat.result = "player_hurt">> <<set _log += " 【你伤势过重,被迫撤退!】">> <<set $life = Math.max(0, $life - Math.floor(_p.injury / 2))>> <<elseif _p.morale <= 0>> <<set $activeCombat.result = "player_flee">> <<set _log += " 【士气崩溃,你本能地撤退!】">> <<set $san = Math.max(0, $san - 10)>> <<set $tre = Math.min(100, $tre + 10)>> <<elseif _e.morale <= 0>> <<set $activeCombat.result = "enemy_flee">> <<set _log += " "+_e.name+"斗志全无,转身逃去。">> <</if>> <</if>> <</if>> /* ── 写回 ── */ <<set $activeCombat.round += 1>> <<set $activeCombat.log = _log>> /* 战斗结束折算体力损耗(逃跑<<return>>路径已在上方处理,不会重复) */ <<if $activeCombat.result>> <<set $power = Math.max(0, $power - Math.floor((_p.hpMax - _p.hp) / 2))>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "combatInit">> /* 调用方式:<<combatInit "enemy_id" "return_passage">> */ <<if !$combatEnemyTable>><<combatEnemyDefs>><</if>> <<set _ciId = String($args[0])>> <<set _ciDef = $combatEnemyTable[_ciId] || $combatEnemyTable["jellyfish_swarm"]>> /* 士气随机 */ <<set _ciMorale = Array.isArray(_ciDef.morale) ? _ciDef.morale[0] + Math.floor(Math.random() * (_ciDef.morale[1] - _ciDef.morale[0] + 1)) : _ciDef.morale>> <<set $activeCombat = { enemy: { id: _ciId, name: _ciDef.name, alertness: _ciDef.alertness, morale: _ciMorale, hp: _ciDef.hp, hpMax: _ciDef.hp, injury: 0, flaws: 0, injuryMax: _ciDef.injuryMax, loot: _ciDef.loot || [], stateDesc: _ciDef.stateDesc, hpDesc: _ciDef.hpDesc, injuryDesc: _ciDef.injuryDesc, lockedEscape: false, nextDefend: false }, player: { alertness: 50, morale: 75, hp: $power * 2, hpMax: $power * 2, injury: 0, flaws: 0, nextDefend: false, mustHit: false, dmgHalf: false }, round: 0, phase: "main", log: "", result: null }>> <<set $combatReturn = ($args[1] ? String($args[1]) : "仓外探索")>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpActionResult">> /* 调用:<<cpActionResult "cp_id">> 在 cpTick 检测到行动到期、调用 cpIntent 之前自动执行 只处理世界行动的库存结算,生存行动(sleep/eat/nap)不触碰库存 */ <<set _carId = $args[0]>> <<set _carCp = $cps[_carId]>> <<if _carCp>> <<set _carPrev = _carCp.action>> /* ══ outside:外出返回,随机带回 1-3 件渔获 ══ */ <<if _carPrev === "outside">> <<set _carFishList = _carCp.fishIds>> <<set _carCatch = Math.floor(Math.random() * 3) + 1>> <<set _carLootLog = []>> <<for _carCI = 0; _carCI < _carCatch; _carCI++>> <<set _carFishId = _carFishList[Math.floor(Math.random() * _carFishList.length)]>> <<additem _carFishId 1>> <<set _carFishDef = State.variables.items[_carFishId]>> <<if _carFishDef>><<run _carLootLog.push(_carFishDef.name)>><</if>> <</for>> /* 写入返回记忆(多槽) */ <<cpMemory _carId "went_out" "went_outside" 1>> <<if _carLootLog.length > 0>> <<cpMemory _carId "catch" "caught_fish" 1 _carLootLog[0]>> <</if>> <<if $day >= _carCp.notifyCooldown && _carLootLog.length > 0>> <<set $cps[_carId].pendingNotify = { text : _carCp.name + " 带回来了:" + _carLootLog.join("、") + "。", expire : $day }>> <<set $cps[_carId].notifyCooldown = $day + 1>> <</if>> <</if>> /* ══ bath:洗漱结束,清除潮湿状态;不参与其他数值或炼金结算 ══ */ <<if _carPrev === "bath">> <<set $cps[_carId].wet = false>> <</if>> /* ══ disassemble:复用现有 widget,NPC 模式跳过玩家数值影响 ══ */ <<if _carPrev === "disassemble">> <<set _carFoundFish = "">> <<for _carFI = 0; _carFI < _carCp.fishIds.length; _carFI++>> <<finditem $store _carCp.fishIds[_carFI]>> <<if _foundItem && _foundItem.quantity > 0>> <<set _carFoundFish = _carCp.fishIds[_carFI]>> <<break>> <</if>> <</for>> <<if _carFoundFish>> /* 第二参数 true = NPC 模式,跳过时间/体力/划伤 */ <<disassemble _carFoundFish true>> <<if $day >= _carCp.notifyCooldown>> <<set $cps[_carId].pendingNotify = { text : _carCp.name + " 处理了渔获:" + $lastDisassembleText, expire : $day }>> <<set $cps[_carId].notifyCooldown = $day + 1>> <</if>> <</if>> <</if>> /* ══ cook:两轮筛选选食材,复用 matchRecipe + assembleDish ══ */ <<if _carPrev === "cook">> /* ── 收集候选食材:foodPrefs 优先,再补充其他有 foodtags 的仓库食材 ── */ <<set _carCands = []>> <<for _carPI = 0; _carPI < _carCp.foodPrefs.length; _carPI++>> <<finditem $store _carCp.foodPrefs[_carPI]>> <<if _foundItem && _foundItem.quantity > 0>> <<run _carCands.push({ id: _carCp.foodPrefs[_carPI], pref: true })>> <</if>> <</for>> <<set _carStoreKeys = Object.keys($store)>> <<for _carSKI = 0; _carSKI < _carStoreKeys.length; _carSKI++>> <<set _carCat = _carStoreKeys[_carSKI]>> <<if !Array.isArray($store[_carCat])>><<continue>><</if>> <<for _carSII = 0; _carSII < $store[_carCat].length; _carSII++>> <<set _carEntry = $store[_carCat][_carSII]>> <<set _carEntryDef = State.variables.items[_carEntry.id]>> <<if _carEntry.quantity <= 0>><<continue>><</if>> <<if !_carEntryDef || !_carEntryDef.foodtags || _carEntryDef.foodtags.length === 0>><<continue>><</if>> <<set _carAlready = false>> <<for _carCI2 = 0; _carCI2 < _carCands.length; _carCI2++>> <<if _carCands[_carCI2].id === _carEntry.id>><<set _carAlready = true>><<break>><</if>> <</for>> <<if !_carAlready>><<run _carCands.push({ id: _carEntry.id, pref: false })>><</if>> <</for>> <</for>> <<if _carCands.length > 0>> /* 随机烹饪方式:从该 CP 的 cookMethods 里取 */ <<set _carMethods = _carCp.cookMethods || ["明火烤","铜锅炖","煎炒"]>> <<set _carMethod = _carMethods[Math.floor(Math.random() * _carMethods.length)]>> /* ── 第一轮:只试 foodPrefs 食材 ── */ <<set _carPrefCands = []>> <<for _carCI = 0; _carCI < _carCands.length; _carCI++>> <<if _carCands[_carCI].pref>><<run _carPrefCands.push(_carCands[_carCI].id)>><</if>> <</for>> /* Fisher-Yates 乱序 */ <<for _carSI = _carPrefCands.length - 1; _carSI > 0; _carSI-->> <<set _carSJ = Math.floor(Math.random() * (_carSI + 1))>> <<set _carSTmp = _carPrefCands[_carSI]>> <<set _carPrefCands[_carSI] = _carPrefCands[_carSJ]>> <<set _carPrefCands[_carSJ] = _carSTmp>> <</for>> <<set _carChosenId = "">> <<for _carTI = 0; _carTI < _carPrefCands.length; _carTI++>> /* CP 烹饪使用独立变量,不侵入玩家烹饪变量 */ <<set $cpCookIngredients = [_carPrefCands[_carTI]]>> <<set $cpCookMethod = _carMethod>> <<matchRecipe>> <<if $cookTemplate && $cookTemplate.id && !$cookTemplate.id.includes("fallback")>> <<set _carChosenId = _carPrefCands[_carTI]>> <<break>> <</if>> <</for>> /* ── 第二轮:全部候选乱序试 ── */ <<if !_carChosenId>> <<for _carSI2 = _carCands.length - 1; _carSI2 > 0; _carSI2-->> <<set _carSJ2 = Math.floor(Math.random() * (_carSI2 + 1))>> <<set _carSTmp2 = _carCands[_carSI2]>> <<set _carCands[_carSI2] = _carCands[_carSJ2]>> <<set _carCands[_carSJ2] = _carSTmp2>> <</for>> <<for _carTI2 = 0; _carTI2 < _carCands.length; _carTI2++>> /* CP 烹饪使用独立变量,不侵入玩家烹饪变量 */ <<set $cpCookIngredients = [_carCands[_carTI2].id]>> <<set $cpCookMethod = _carMethod>> <<matchRecipe>> <<if $cookTemplate && $cookTemplate.id && !$cookTemplate.id.includes("fallback")>> <<set _carChosenId = _carCands[_carTI2].id>> <<break>> <</if>> <</for>> <</if>> /* ── 兜底:单品保底 ── */ <<if !_carChosenId>> <<set _carChosenId = (_carPrefCands.length > 0) ? _carPrefCands[0] : _carCands[0].id>> /* CP 烹饪使用独立变量,不侵入玩家烹饪变量 */ <<set $cpCookIngredients = [_carChosenId]>> <<set $cpCookMethod = _carMethod>> <<matchRecipe>> <</if>> /* ── 消耗食材,生成菜品 ── */ <<removeitem _carChosenId 1>> <<if _carCp.bond >= 70 && Math.random() < 0.3>> <<set $cookQuality = "完美">> <<else>> <<set $cookQuality = "成功">> <</if>> <<assembleDish>> /* 冰箱满了放仓库 */ <<if $assembleResult === "full">> <<if $cookTemplate>><<additem $cookTemplate.id 1>><</if>> <</if>> /* 写入记忆(多槽) + 重要通知 */ <<set _carDishName = $cookTemplate ? $cookTemplate.name : "一道菜">> <<cpMemory _carId "cooked" "cooked_for_player" 2 _carDishName>> <<set $cps[_carId].pendingNotify = { text : _carCp.name + " 做了" + _carDishName + ",放进冰箱了。", expire : $day + 1, important: true }>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpGift">> /* 调用: <<cpGift "cp_id" "item_id" "subtype">> subtype ∈ food(菜肴/食物) / material(材料) / gift(礼物,非消耗) 实现设计文档第五节"赠送系统(三子类)" */ <<set _cgId = $args[0]>> <<set _cgItem = $args[1]>> <<set _cgType = $args[2]>> <<set _cgCp = $cps[_cgId]>> <<set _cgDef = State.variables.items[_cgItem]>> <<if !_cgCp>> <<print "错误:找不到 CP " + _cgId>> <<elseif !_cgDef>> <<print "错误:找不到物品 " + _cgItem>> <<else>> <<finditem $store _cgItem>> <<if !_foundItem || _foundItem.quantity <= 0>> <<print _cgDef.name + " 数量不足,无法赠送。">> <<else>> <<set _cgReply = "">> <<set _cgAccept = false>> /* ══════════ 菜肴/食物 ══════════ */ <<if _cgType === "food">> <<set _cgHungry = _cgCp.hunger < 45>> <<set _cgPref = _cgCp.foodPrefs.includes(_cgItem)>> <<if _cgCp.foodAttitude === "open">> <<set _cgAccept = true>> <<elseif _cgCp.foodAttitude === "only_when_hungry">> <<if _cgHungry>> <<set _cgAccept = true>> <<else>> <<set _cgReply = _cgCp.name + ":现在还不饿,先放着吧。">> <</if>> <<elseif _cgCp.foodAttitude === "picky">> <<if _cgPref>> <<set _cgAccept = true>> <<else>> <<set _cgReply = _cgCp.name + " 挑剔地看了一眼:「这也能吃?」">> <</if>> <</if>> <<if _cgAccept>> <<removeitem _cgItem 1>> <<set _cgNutr = (_cgDef.nutrition !== undefined) ? _cgDef.nutrition : 20>> <<set _cgHydr = (_cgDef.hydration !== undefined) ? _cgDef.hydration : 0>> <<set $cps[_cgId].hunger = Math.min(100, _cgCp.hunger + _cgNutr)>> <<set $cps[_cgId].water = Math.min(100, _cgCp.water + _cgHydr)>> <<if _cgPref>> <<set $cps[_cgId].moodMod = Math.min(20, $cps[_cgId].moodMod + 1)>> <<set $cps[_cgId].bond = Math.min(100, $cps[_cgId].bond + 3)>> <<set _cgReply = _cgCp.name + " 眼睛亮了一下——这是她喜欢的。">> <<else>> <<set $cps[_cgId].bond = Math.min(100, $cps[_cgId].bond + 1)>> <<set _cgReply = _cgCp.name + " 接过去,道了声谢。">> <</if>> <<cpMemory _cgId "gift" "received_gift" 1>> <</if>> /* ══════════ 材料 ══════════ */ <<elseif _cgType === "material">> <<removeitem _cgItem 1>> <<set $cps[_cgId].inventory[_cgItem] = ($cps[_cgId].inventory[_cgItem] || 0) + 1>> <<set _cgPrefVal = (_cgCp.prefs && _cgCp.prefs[_cgItem] !== undefined) ? _cgCp.prefs[_cgItem] : 0>> <<if _cgPrefVal > 0>> <<set $cps[_cgId].bond = Math.min(100, $cps[_cgId].bond + _cgPrefVal)>> <<set _cgReply = _cgCp.name + " 把" + _cgDef.name + "收进了自己的箱子(她挺中意这类东西)。">> <<else>> <<set _cgReply = _cgCp.name + " 把" + _cgDef.name + "收进了自己的箱子。">> <</if>> <<cpMemory _cgId "gift" "received_material" 1>> /* ══════════ 礼物(非消耗) ══════════ */ <<elseif _cgType === "gift">> <<if $cps[_cgId].giftCooldown && $day < $cps[_cgId].giftCooldown>> <<set _cgReply = _cgCp.name + ":已经收过你的礼物啦,先好好收着。">> <<else>> <<removeitem _cgItem 1>> <<set _cgPrefVal = (_cgCp.prefs && _cgCp.prefs[_cgItem] !== undefined) ? _cgCp.prefs[_cgItem] : 1>> <<set $cps[_cgId].bond = Math.min(100, $cps[_cgId].bond + Math.max(1, _cgPrefVal))>> <<set $cps[_cgId].giftCooldown = $day + 3>> <<set _cgReply = _cgCp.name + " 小心收下了" + _cgDef.name + ",嘴角弯了一下。">> <<cpMemory _cgId "gift" "received_gift" 1>> /* 一次性后果场景(若物品登记, 标签可扩展) */ <<set _cgAftermap = { milkshake:"奶昔", blue_lobster:"蓝龙虾" }>> <<if _cgAftermap[_cgItem]>> <<set $cps[_cgId].giftAftermath = { item:_cgItem, label:_cgAftermap[_cgItem], triggered:false }>> <</if>> <</if>> <</if>> <<set $cpGiftReply = _cgReply>> <<print _cgReply>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpGiftFood">> /* 调用:<<cpGiftFood "cp_id" "item_id">> 玩家将仓库里的物品赠给 CP 输出一行反馈文字,调用处可直接显示 */ <<set _cgfId = $args[0]>> <<set _cgfItemId = $args[1]>> <<set _cgfCp = $cps[_cgfId]>> <<set _cgfDef = State.variables.items[_cgfItemId]>> <<if !_cgfCp>> <<print "错误:找不到 CP " + _cgfId>> <<elseif !_cgfDef>> <<print "错误:找不到物品 " + _cgfItemId>> <<else>> <<finditem $store _cgfItemId>> <<if !_foundItem || _foundItem.quantity <= 0>> <<print _cgfDef.name + " 数量不足,无法赠送。">> <<else>> <<removeitem _cgfItemId 1>> /* 数值回复:读物品定义的 nutrition / hydration,无则用默认值 */ <<set _cgfNutr = (_cgfDef.nutrition !== undefined) ? _cgfDef.nutrition : 20>> <<set _cgfHydr = (_cgfDef.hydration !== undefined) ? _cgfDef.hydration : 0>> <<set $cps[_cgfId].hunger = Math.min(100, _cgfCp.hunger + _cgfNutr)>> <<set $cps[_cgfId].water = Math.min(100, _cgfCp.water + _cgfHydr)>> /* 偏好检查 */ <<set _cgfPref = false>> <<for _cgfPI = 0; _cgfPI < _cgfCp.foodPrefs.length; _cgfPI++>> <<if _cgfCp.foodPrefs[_cgfPI] === _cgfItemId>> <<set _cgfPref = true>><<break>> <</if>> <</for>> <<if _cgfPref>> <<set $cps[_cgfId].mood = Math.min(2, _cgfCp.mood + 1)>> <<set $cps[_cgfId].bond = Math.min(100, _cgfCp.bond + 3)>> <<set _cgfReply = _cgfCp.name + " 的眼睛亮了一下——这是她喜欢的。">> <<else>> <<set $cps[_cgfId].bond = Math.min(100, _cgfCp.bond + 1)>> <<set _cgfReply = _cgfCp.name + " 接过去,道了声谢。">> <</if>> <<cpMemory _cgfId "gift" "received_gift" 1>> <<print _cgfReply>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpIntent">> /* 调用:<<cpIntent "cp_id">> */ <<set _ciId = $args[0]>> <<set _ciCp = $cps[_ciId]>> <<if !_ciCp>><<return>><</if>> <<set _ciNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<set _ciTh = _ciCp.intentThresholds>> /* ══ 生存优先级 ══ */ <<if _ciCp.energy <= _ciTh.sleepAt>> <<set $cps[_ciId].action = "sleep">> <<set $cps[_ciId].location = "卧室">> <<set $cps[_ciId].actionEndTime = _ciNow + 480>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciCp.hunger <= _ciTh.eatAt>> <<set $cps[_ciId].action = "eat">> <<set $cps[_ciId].location = "厨房">> <<set $cps[_ciId].actionEndTime = _ciNow + 35>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciCp.water <= _ciTh.drinkAt>> <<set $cps[_ciId].action = "eat">> <<set $cps[_ciId].location = "厨房">> <<set $cps[_ciId].actionEndTime = _ciNow + 20>> <<set $cps[_ciId].actionDetail = "倒了杯水">> <<else>> /* ══ 自由活动加权随机 只从该角色 activityWeights 里定义的行动里选 没有列出的行动永远不会触发 ══ */ <<set _ciW = clone(_ciCp.activityWeights)>> <<if _ciCp.energy <= _ciTh.napAt && _ciW.nap !== undefined>> <<set _ciW.nap = _ciW.nap * 3>> <</if>> <<set _ciTotal = 0>> <<set _ciKeys = Object.keys(_ciW)>> <<for _ciK = 0; _ciK < _ciKeys.length; _ciK++>> <<set _ciTotal += _ciW[_ciKeys[_ciK]]>> <</for>> <<set _ciRoll = Math.random() * _ciTotal>> <<set _ciChosen = _ciKeys[_ciKeys.length - 1]>> <<set _ciAcc = 0>> <<for _ciK = 0; _ciK < _ciKeys.length; _ciK++>> <<set _ciAcc += _ciW[_ciKeys[_ciK]]>> <<if _ciRoll < _ciAcc>> <<set _ciChosen = _ciKeys[_ciK]>> <<break>> <</if>> <</for>> /* ── 世界行动:库存检查 + 降级 ── */ <<if _ciChosen === "disassemble">> <<set _ciHasFish = false>> <<for _ciFI = 0; _ciFI < _ciCp.fishIds.length; _ciFI++>> <<finditem $store _ciCp.fishIds[_ciFI]>> <<if _foundItem && _foundItem.quantity > 0>> <<set _ciHasFish = true>><<break>> <</if>> <</for>> <<if _ciHasFish>> <<set $cps[_ciId].action = "disassemble">> <<set $cps[_ciId].location = "机械室">> <<set $cps[_ciId].actionEndTime = _ciNow + 40 + Math.floor(Math.random()*20)>> <<else>> <<set $cps[_ciId].action = "tidy">> <<set $cps[_ciId].location = "仓库">> <<set $cps[_ciId].actionEndTime = _ciNow + 30 + Math.floor(Math.random()*20)>> <</if>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciChosen === "cook">> <<set _ciHasIngredient = false>> <<set _ciStoreKeys = Object.keys($store)>> <<for _ciSKI = 0; _ciSKI < _ciStoreKeys.length; _ciSKI++>> <<set _ciCat = _ciStoreKeys[_ciSKI]>> <<if !Array.isArray($store[_ciCat])>><<continue>><</if>> <<for _ciSII = 0; _ciSII < $store[_ciCat].length; _ciSII++>> <<set _ciEntry = $store[_ciCat][_ciSII]>> <<set _ciEntryDef = State.variables.items[_ciEntry.id]>> <<if _ciEntry.quantity > 0 && _ciEntryDef && _ciEntryDef.foodtags && _ciEntryDef.foodtags.length > 0>> <<set _ciHasIngredient = true>><<break>> <</if>> <</for>> <<if _ciHasIngredient>><<break>><</if>> <</for>> <<if _ciHasIngredient>> <<set $cps[_ciId].action = "cook">> <<set $cps[_ciId].location = "厨房">> <<set $cps[_ciId].actionEndTime = _ciNow + 60 + Math.floor(Math.random()*30)>> <<else>> <<if $day >= _ciCp.notifyCooldown>> <<set $cps[_ciId].pendingNotify = { text : _ciCp.name + ":仓库里没有食材了,我去弄点东西回来。", expire : $day }>> <<set $cps[_ciId].notifyCooldown = $day + 2>> <</if>> <<set $cps[_ciId].action = "outside">> <<set $cps[_ciId].location = "舱外">> <<set $cps[_ciId].actionEndTime = _ciNow + 90 + Math.floor(Math.random()*60)>> <<set $cps[_ciId].wet = true>> <</if>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciChosen === "alchemy">> <<set $cps[_ciId].action = "alchemy">> <<set $cps[_ciId].location = "仓库">> <<set $cps[_ciId].actionEndTime = _ciNow + 45 + Math.floor(Math.random()*30)>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciChosen === "bath">> <<set $cps[_ciId].action = "bath">> <<set $cps[_ciId].location = "浴室">> <<set $cps[_ciId].actionEndTime = _ciNow + 30 + Math.floor(Math.random()*20)>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciChosen === "outside">> <<set $cps[_ciId].action = "outside">> <<set $cps[_ciId].location = "舱外">> <<set $cps[_ciId].actionEndTime = _ciNow + 90 + Math.floor(Math.random()*60)>> <<set $cps[_ciId].actionDetail = "">> <<set $cps[_ciId].wet = true>> <<elseif _ciChosen === "watch">> <<set $cps[_ciId].action = "watch">> <<set $cps[_ciId].location = "驾驶舱">> <<set $cps[_ciId].actionEndTime = _ciNow + 45 + Math.floor(Math.random()*30)>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciChosen === "exercise">> <<set $cps[_ciId].action = "exercise">> <<set $cps[_ciId].location = "走廊">> <<set $cps[_ciId].actionEndTime = _ciNow + 50 + Math.floor(Math.random()*20)>> <<set $cps[_ciId].actionDetail = "">> <<elseif _ciChosen === "nap">> <<set $cps[_ciId].action = "nap">> <<set $cps[_ciId].location = "卧室">> <<set $cps[_ciId].actionEndTime = _ciNow + 60 + Math.floor(Math.random()*60)>> <<set $cps[_ciId].actionDetail = "">> <<else>> /* tidy 及其他兜底:统一在仓库(炼金室)整理,方便玩家寻找。 */ <<set $cps[_ciId].action = "tidy">> <<set $cps[_ciId].location = "仓库">> <<set $cps[_ciId].actionEndTime = _ciNow + 30 + Math.floor(Math.random()*20)>> <<set $cps[_ciId].actionDetail = "">> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> /* 三层记忆系统: 短期 recentEvents(多槽) / 中期 memories[] / 长期 bondMilestones{} 以及玩家行为记录 $playerRecent(陪伴类点评用) */ <<widget "cpMemory">> /* 调用: <<cpMemory "cp_id" "slot" "tag" [expireDays=1] [product=""]>> 写入 recentEvents[slot] = {tag, product, day, expire} 预定义 slot: ate / went_out / cooked / alchemy / slept_with / intentFrustrated */ <<set _cmId = $args[0]>> <<set _cmSlot = $args[1]>> <<set _cmTag = $args[2]>> <<set _cmExp = ($args[3] !== undefined) ? Number($args[3]) : 1>> <<set _cmProduct = $args[4] || "">> <<set _cmCp = $cps[_cmId]>> <<if _cmCp && _cmCp.recentEvents && _cmCp.recentEvents[_cmSlot] !== undefined>> <<set $cps[_cmId].recentEvents[_cmSlot] = { tag:_cmTag, product:_cmProduct, day:$day, expire:$day + _cmExp }>> <</if>> <</widget>> <<widget "cpMemoryTag">> /* 兼容别名: 旧调用 <<cpMemoryTag id "tag" days>> 写入默认槽 "event" */ <<set _cmtId = $args[0]>> <<set _cmtTag = $args[1]>> <<set _cmtExp = ($args[2] !== undefined) ? Number($args[2]) : 1>> <<if $cps[_cmtId] && $cps[_cmtId].recentEvents>> <<set $cps[_cmtId].recentEvents.event = { tag:_cmtTag, day:$day, expire:$day + _cmtExp }>> <</if>> <</widget>> <<widget "cpIntentFrustrated">> /* 调用: <<cpIntentFrustrated "cp_id" "意图短句" "中断短句">> 记录意图落空(短期记忆), 对话引用: "本来想{意图}但是{中断}, 真扫兴" */ <<set _cifId = $args[0]>> <<if $cps[_cifId] && $cps[_cifId].recentEvents>> <<set $cps[_cifId].recentEvents.intentFrustrated = { plan: $args[1] || "", reason: $args[2] || "", day: $day, expire: $day + 1 }>> <</if>> <</widget>> <<widget "cpMemoryMid">> /* 调用: <<cpMemoryMid "cp_id" "tag">> 写入中期记忆(永久), 去重 */ <<set _cmmId = $args[0]>> <<set _cmmTag = $args[1]>> <<if $cps[_cmmId] && _cmmTag>> <<if !$cps[_cmmId].memories.includes(_cmmTag)>> <<run $cps[_cmmId].memories.push(_cmmTag)>> <</if>> <</if>> <</widget>> <<widget "cpRecordPlayer">> /* 调用: <<cpRecordPlayer "field" "value">> 记录玩家近期行为(陪伴类点评用) field ∈ caught / fought / lastAction / lastHarvest */ <<set _crpField = $args[0]>> <<set _crpVal = $args[1] || "">> <<if $playerRecent && $playerRecent[_crpField] !== undefined>> <<set $playerRecent[_crpField] = _crpVal>> <</if>> <</widget>> <</nobr>>
<<nobr>> /* 心情/安定档位与配色, 供 cp详情 / cp档案 复用 */ <<widget "cpMoodTier">> /* 输入: $args[0] = 0-100 数值; 输出中文档位 */ <<set _mt = Number($args[0]) || 0>> <<if _mt < 20>><<print "糟糕">> <<elseif _mt < 40>><<print "低落">> <<elseif _mt < 60>><<print "平常">> <<elseif _mt < 80>><<print "不错">> <<else>><<print "很好">> <</if>> <</widget>> <<widget "cpMoodColor">> <<set _mc = Number($args[0]) || 0>> <<if _mc < 20>><<print "var(--danger-bright,#e55)">> <<elseif _mc < 40>><<print "#e0a458">> <<elseif _mc < 60>><<print "var(--bone-dim,#9aa)">> <<elseif _mc < 80>><<print "var(--teal-bright,#4ecdc4)">> <<else>><<print "var(--amber-bright,#f0c674)">> <</if>> <</widget>> <<widget "cpCalmTier">> <<set _ct2 = Number($args[0]) || 0>> <<if _ct2 < 20>><<print "不安">> <<elseif _ct2 < 40>><<print "略躁">> <<elseif _ct2 < 60>><<print "平静">> <<elseif _ct2 < 80>><<print "安稳">> <<else>><<print "安心">> <</if>> <</widget>> <<widget "cpMoodBar">> /* 输入: $args[0]=cpId, $args[1]="mood"|"calm"; 渲染一条带档位文字的数值条 */ <<set _mbCp = $cps[$args[0]]>> <<set _mbKey = $args[1] || "mood">> <<if _mbCp>> <<set _mbVal = _mbCp[_mbKey]>> <<if _mbKey === "mood">> <<set _mbColor = (_mbVal < 20) ? "var(--danger-bright,#e55)" : ((_mbVal < 40) ? "#e0a458" : ((_mbVal < 60) ? "var(--bone-dim,#9aa)" : ((_mbVal < 80) ? "var(--teal-bright,#4ecdc4)" : "var(--amber-bright,#f0c674)")))>> <<set _mbTier = (_mbVal < 20) ? "糟糕" : ((_mbVal < 40) ? "低落" : ((_mbVal < 60) ? "平常" : ((_mbVal < 80) ? "不错" : "很好")))>> <<else>> <<set _mbColor = "var(--teal-bright,#4ecdc4)">> <<set _mbTier = (_mbVal < 20) ? "不安" : ((_mbVal < 40) ? "略躁" : ((_mbVal < 60) ? "平静" : ((_mbVal < 80) ? "安稳" : "安心")))>> <</if>> <div class="stat-row"> <span class="stat-label"><<print (_mbKey === "mood") ? "心情" : "安定">></span> <span class="stat-bar"> <span class="stat-fill" style="width:<<print Math.floor(_mbVal)>>%;background:<<print _mbColor>>;"></span> </span> <span class="stat-num-text"><<print _mbTier>></span> </div> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpNotifyDisplay">> /* 在 StoryCaption 的 <div id="sc-status"> 之后加:<<cpNotifyDisplay>> important=true 用金色醒目样式,普通通知用次要样式 */ <<if $activeCpIds && $activeCpIds.length > 0>> <<for _cndI = 0; _cndI < $activeCpIds.length; _cndI++>> <<set _cndId = $activeCpIds[_cndI]>> <<set _cndCp = $cps[_cndId]>> <<if !_cndCp>><<continue>><</if>> <<if !_cndCp.pendingNotify || !_cndCp.pendingNotify.text>><<continue>><</if>> <<if _cndCp.pendingNotify.expire >= 0 && $day > _cndCp.pendingNotify.expire>><<continue>><</if>> <<if _cndCp.pendingNotify.important === true>> <div class="cp-notify cp-notify-important"> <span class="cp-notify-icon">★</span><<print _cndCp.pendingNotify.text>> </div> <<else>> <div class="cp-notify"><<print _cndCp.pendingNotify.text>></div> <</if>> <</for>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpProactiveCheck">> <<set _cpcId = $args[0]>> <<set _cpcCp = $cps[_cpcId]>> <<if _cpcCp && $day >= _cpcCp.proactiveCooldown && _cpcCp.action !== "sleep" && _cpcCp.action !== "outside" && _cpcCp.action !== "exercise" && _cpcCp.mood !== 0 && (!_cpcCp.pendingImportantEvent || !_cpcCp.pendingImportantEvent.passage)>> <<if !$cpProactiveDefs>><<cpProactiveDefs>><</if>> <<set _cpcDefs = $cpProactiveDefs[_cpcId]>> <<if _cpcDefs && _cpcDefs.length > 0>> /* ── 过滤候选事件 ── */ <<set _cpcCands = []>> <<for _cpcI = 0; _cpcI < _cpcDefs.length; _cpcI++>> <<set _cpcDef = _cpcDefs[_cpcI]>> <<set _cpcOk = true>> <<if _cpcDef.minBond !== undefined && _cpcCp.bond < _cpcDef.minBond>> <<set _cpcOk = false>> <</if>> <<if _cpcOk && _cpcDef.minMood !== undefined && _cpcCp.mood < _cpcDef.minMood>> <<set _cpcOk = false>> <</if>> <<if _cpcOk && _cpcDef.type === "chat" && $day <= _cpcCp.lastChatDay>> <<set _cpcOk = false>> <</if>> <<if _cpcOk && _cpcDef.requireMemory>> <<set _cpcMemHit = false>> <<if _cpcCp.recentEvents>> <<set _cpcMemKeys = Object.keys(_cpcCp.recentEvents)>> <<for _cpcMKI = 0; _cpcMKI < _cpcMemKeys.length; _cpcMKI++>> <<set _cpcMK = _cpcMemKeys[_cpcMKI]>> <<set _cpcSlot = _cpcCp.recentEvents[_cpcMK]>> <<if _cpcSlot && _cpcSlot.tag === _cpcDef.requireMemory && $day < _cpcSlot.expire>> <<set _cpcMemHit = true>> <</if>> <</for>> <</if>> <<if !_cpcMemHit>><<set _cpcOk = false>><</if>> <</if>> <<if _cpcOk>><<run _cpcCands.push(_cpcDef)>><</if>> <</for>> <<if _cpcCands.length > 0>> /* ── 加权随机 ── */ <<set _cpcTotal = 0>> <<for _cpcWI = 0; _cpcWI < _cpcCands.length; _cpcWI++>> <<set _cpcTotal += (_cpcCands[_cpcWI].weight || 10)>> <</for>> <<set _cpcRoll = Math.random() * _cpcTotal>> <<set _cpcChosen = _cpcCands[_cpcCands.length - 1]>> <<set _cpcAcc = 0>> <<for _cpcWI = 0; _cpcWI < _cpcCands.length; _cpcWI++>> <<set _cpcAcc += (_cpcCands[_cpcWI].weight || 10)>> <<if _cpcRoll < _cpcAcc>> <<set _cpcChosen = _cpcCands[_cpcWI]>> <<break>> <</if>> <</for>> /* ── 概率掷骰,命中则写入事件和冷却 ── */ <<if Math.random() < (_cpcChosen.baseChance || 0.15)>> <<set $cps[_cpcId].pendingImportantEvent = { passage : _cpcChosen.passage, type : _cpcChosen.type, expire : $day + 2 }>> <<set $cps[_cpcId].proactiveCooldown = $day + (_cpcChosen.cooldown || 2)>> <</if>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpRoomCheck">> <<set _crcRoom = $args[0]>> <<set _crcTriggered = false>> <<if $activeCpIds && $activeCpIds.length > 0>> <<for _crcI = 0; _crcI < $activeCpIds.length && !_crcTriggered; _crcI++>> <<set _crcId = $activeCpIds[_crcI]>> <<set _crcCp = $cps[_crcId]>> <<if !_crcCp>><<continue>><</if>> <<if _crcCp.location !== _crcRoom>><<continue>><</if>> <<if !_crcCp.pendingImportantEvent || !_crcCp.pendingImportantEvent.passage>><<continue>><</if>> <<set _crcEvt = _crcCp.pendingImportantEvent>> <<if _crcEvt.expire >= 0 && $day > _crcEvt.expire>> <<set $cps[_crcId].pendingImportantEvent = null>> <<continue>> <</if>> <<set $cpEventReturn = _crcRoom>> <<set $cpEventCpId = _crcId>> <<set $cps[_crcId].pendingImportantEvent = null>> <<set _crcTriggered = true>> <<navigate "go" _crcEvt.passage>> <</for>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpScene">> /* 调用:<<cpScene "当前房间名">> 遍历所有激活 CP,在房间内匹配并渲染一行场景描述 */ <<if $activeCpIds && $activeCpIds.length > 0>> <<for _csI = 0; _csI < $activeCpIds.length; _csI++>> <<set _csId = $activeCpIds[_csI]>> <<set _csCp = $cps[_csId]>> <<if _csCp && _csCp.location === $args[0] && (_csId !== "testcp" || ($devMode && $devCpId === "testcp"))>> <<cpSceneRender _csId>> <</if>> <</for>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpSceneRender">> /* 调用:<<cpSceneRender "cp_id">> 从 CP 模板的 sceneTexts 读取当前行动对应文本 支持字符串或数组(数组随机取一条) actionDetail 非空时附加在描述后面 */ <<set _csr = $cps[$args[0]]>> <<set _csrId = $args[0]>> <<if _csr>> /* ── 从 sceneTexts 取文本 ── */ <<set _csrPool = _csr.sceneTexts ? _csr.sceneTexts[_csr.action] : null>> <<set _csrHint = "">> <<set _csrMoodBand = _csr.mood >= 75 ? "good" : (_csr.mood < 35 ? "bad" : "neutral")>> <<set _csrStatusBand = _csr.wet ? "wet" : (_csr.injured > 0 ? "injured" : (_csr.sick ? "sick" : "normal"))>> <<set _csrAlchemyMem = (_csr.recentEvents && _csr.recentEvents.alchemy && _csr.recentEvents.alchemy.product) ? _csr.recentEvents.alchemy.product : "">> <<set _csrCatchMem = (_csr.recentEvents && _csr.recentEvents.catch && _csr.recentEvents.catch.product) ? _csr.recentEvents.catch.product : "">> <<set _csrCookedMem = (_csr.recentEvents && _csr.recentEvents.cooked && _csr.recentEvents.cooked.product) ? _csr.recentEvents.cooked.product : "">> <<set _csrDestinationMem = (_csr.recentEvents && _csr.recentEvents.destination && _csr.recentEvents.destination.target) ? _csr.recentEvents.destination.target : "">> <<set _csrSignature = [_csr.action,_csrMoodBand,_csrStatusBand,_csrAlchemyMem,_csrCatchMem,_csrCookedMem,_csrDestinationMem].join("|")>> <<set _csrUseCache = _csr.sceneTextCache && _csr.sceneTextCache.signature === _csrSignature>> <<if _csrUseCache>><<set _csrHint = _csr.sceneTextCache.text>><</if>> <<if !_csrUseCache>> <<if !_csrPool>> /* 没有定义该行动的文本,兜底显示 */ <<set _csrHint = _csr.name + "在这里。">> <<elseif Array.isArray(_csrPool)>> <<set _csrHint = _csrPool[Math.floor(Math.random() * _csrPool.length)]>> <<else>> <<set _csrHint = _csrPool>> <</if>> /* 房间行动差分:主场景后最多叠加心情、一个状态与一条近期记忆。 */ <<set _csrLayer = _csr.sceneLayers && _csr.sceneLayers[_csr.action] ? _csr.sceneLayers[_csr.action] : null>> <<if _csrLayer>> <<set _csrMoodPool = _csr.mood >= 75 ? _csrLayer.good : (_csr.mood < 35 ? _csrLayer.bad : _csrLayer.neutral)>> <<if _csrMoodPool && _csrMoodPool.length > 0>><<set _csrHint += " " + _csrMoodPool[Math.floor(Math.random() * _csrMoodPool.length)]>><</if>> <<set _csrStatusPool = null>> <<if _csr.wet && _csrLayer.wet>><<set _csrStatusPool = _csrLayer.wet>> <<elseif _csr.injured > 0 && _csrLayer.injured>><<set _csrStatusPool = _csrLayer.injured>> <<elseif _csr.sick && _csrLayer.sick>><<set _csrStatusPool = _csrLayer.sick>><</if>> <<if _csrStatusPool && _csrStatusPool.length > 0>><<set _csrHint += " " + _csrStatusPool[Math.floor(Math.random() * _csrStatusPool.length)]>><</if>> <<if _csr.action === "alchemy" && _csrLayer.memory && _csr.recentEvents && _csr.recentEvents.alchemy && _csr.recentEvents.alchemy.product>> <<set _csrMemoryPool = Array.isArray(_csrLayer.memory) ? _csrLayer.memory : [_csrLayer.memory]>><<set _csrMemoryText = _csrMemoryPool[Math.floor(Math.random() * _csrMemoryPool.length)]>> <<set _csrHint += " " + _csrMemoryText.replace(/\{product\}/g, _csr.recentEvents.alchemy.product)>><</if>> <<if _csr.action === "watch" && _csr.sceneLayers && _csr.sceneLayers.drivingMemory && _csr.recentEvents>> <<set _csrDriveMem = _csr.sceneLayers.drivingMemory>> <<if _csr.recentEvents.destination && _csr.recentEvents.destination.target && _csr.recentEvents.catch && _csr.recentEvents.catch.product && _csr.recentEvents.cooked && _csr.recentEvents.cooked.product>> <<set _csrDriveText = _csrDriveMem.destination.replace(/\{destination\}/g, _csr.recentEvents.destination.target).replace(/\{catch\}/g, _csr.recentEvents.catch.product).replace(/\{cooked\}/g, _csr.recentEvents.cooked.product)>> <<set _csrHint += " " + _csrDriveText>> <<elseif _csr.recentEvents.catch && _csr.recentEvents.catch.product>> <<set _csrHint += " " + _csrDriveMem.catch.replace(/\{catch\}/g, _csr.recentEvents.catch.product)>> <<elseif _csr.recentEvents.cooked && _csr.recentEvents.cooked.product>> <<set _csrHint += " " + _csrDriveMem.cooked.replace(/\{cooked\}/g, _csr.recentEvents.cooked.product)>><</if>> <</if>> <<set $cps[_csrId].sceneTextCache = {signature:_csrSignature,text:_csrHint}>><</if>> <</if>> /* actionDetail 非空时附加 */ <<if _csr.actionDetail>> <<set _csrHint = _csrHint + "(" + _csr.actionDetail + ")">> <</if>> <<set _csrLinkText = "查看" + _csr.name>> <div class="cp-scene-hint"> <<print _csrHint>> @@.cp-scene-link;<<link _csrLinkText>> <<set $detailCpId = _csrId>> <<set $cpReturnPassage = passage()>> <<navigate "go" "cp详情">> <</link>>@@ </div> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "cpTick">> <<set _ctNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> /* ── 跨天结算(所有CP统一, 仅当天数变化时执行一次) ── */ <<if $day > $cpBondSettleDay>> <<for _ctSI = 0; _ctSI < $activeCpIds.length; _ctSI++>> <<set _ctSId = $activeCpIds[_ctSI]>> <<set _ctSCp = $cps[_ctSId]>> <<if _ctSCp>> /* mood 趋势缓慢渗入 bond */ <<set $cps[_ctSId].bond = Math.max(0, Math.min(100, _ctSCp.bond + (_ctSCp.bondDrift || 0)))>> <<set $cps[_ctSId].bondDrift = 0>> /* moodMod 每日衰减回 0 */ <<set $cps[_ctSId].moodMod = 0>> <</if>> <</for>> <<set $cpBondSettleDay = $day>> <</if>> <<for _ctI = 0; _ctI < $activeCpIds.length; _ctI++>> <<set _ctId = $activeCpIds[_ctI]>> <<set _ctCp = $cps[_ctId]>> <<if !_ctCp>><<continue>><</if>> /* ── 经过时间 ── */ <<set _ctElapsed = Math.max(0, _ctNow - (_ctCp.lastTickTime || _ctNow))>> <<set $cps[_ctId].lastTickTime = _ctNow>> <<if _ctElapsed <= 0>><<continue>><</if>> /* ── 精力速率 ── */ <<if _ctCp.action === "sleep">> <<set _ctERate = _ctCp.energyRates.sleep>> <<elseif _ctCp.action === "nap">> <<set _ctERate = _ctCp.energyRates.rest>> <<elseif _ctCp.action === "outside" || _ctCp.action === "exercise">> <<set _ctERate = _ctCp.energyRates.heavy>> <<else>> <<set _ctERate = _ctCp.energyRates.normal>> <</if>> /* ── 数值衰减 ── */ <<set $cps[_ctId].hunger = Math.max(0, Math.min(100, _ctCp.hunger + (-0.050 * _ctCp.hungerRate) * _ctElapsed))>> <<set $cps[_ctId].water = Math.max(0, Math.min(100, _ctCp.water + (-0.083 * _ctCp.waterRate) * _ctElapsed))>> <<set $cps[_ctId].energy = Math.max(0, Math.min(100, _ctCp.energy + _ctERate * _ctElapsed))>> /* ── eat 行动正向回复 ── */ <<if _ctCp.action === "eat">> <<set $cps[_ctId].hunger = Math.min(100, _ctCp.hunger + 1.5 * _ctElapsed)>> <<set $cps[_ctId].water = Math.min(100, _ctCp.water + 2.6 * _ctElapsed)>> <</if>> /* ── 三层记忆(多槽)过期 ── */ <<set _ctRE = $cps[_ctId].recentEvents>> <<if _ctRE>> <<set _ctKeys = Object.keys(_ctRE)>> <<for _ctKI = 0; _ctKI < _ctKeys.length; _ctKI++>> <<set _ctKey = _ctKeys[_ctKI]>> <<set _ctSlot = _ctRE[_ctKey]>> <<if _ctSlot && _ctSlot.expire !== undefined && _ctSlot.expire >= 0 && $day >= _ctSlot.expire>> <<if _ctKey === "intentFrustrated">> <<set $cps[_ctId].recentEvents[_ctKey] = { plan:"", reason:"", day:0, expire:-1 }>> <<elseif _ctKey === "alchemy">> <<set $cps[_ctId].recentEvents[_ctKey] = { tag:"", product:"", day:0, expire:-1 }>> <<elseif _ctKey === "driving">> <<set $cps[_ctId].recentEvents[_ctKey] = { tag:"", terrain:"", day:0, expire:-1 }>> <<elseif _ctKey === "catch" || _ctKey === "cooked">> <<set $cps[_ctId].recentEvents[_ctKey] = { tag:"", product:"", day:0, expire:-1 }>> <<elseif _ctKey === "destination">> <<set $cps[_ctId].recentEvents[_ctKey] = { tag:"", target:"", targetId:"", day:0, expire:-1 }>> <<else>> <<set $cps[_ctId].recentEvents[_ctKey] = { tag:"", day:0, expire:-1 }>> <</if>> <</if>> <</for>> <</if>> /* ── 通知过期 ── */ <<if _ctCp.pendingNotify && _ctCp.pendingNotify.expire >= 0 && $day > _ctCp.pendingNotify.expire>> <<set $cps[_ctId].pendingNotify = { text: "", expire: -1 }>> <</if>> /* ── 行动到期 → 结算上一行动 → 重算意图 ── */ <<if _ctNow >= _ctCp.actionEndTime>> <<cpActionResult _ctId>> <<cpIntent _ctId>> <</if>> /* ── 心情模型(moodBase 生存算 + moodMod 事件修正 = mood, 0-100 浮点) ── */ <<set _ctCp2 = $cps[_ctId]>> <<set _ctH = _ctCp2.hunger>> <<set _ctW = _ctCp2.water>> <<set _ctE = _ctCp2.energy>> <<if _ctH < 20 || _ctW < 20 || _ctE < 15>> <<set _ctBase = 5 + (_ctH + _ctW + _ctE) / 9>> <<elseif _ctH > 65 && _ctW > 65 && _ctE > 50>> <<set _ctBase = 65 + Math.min(20, ((_ctH + _ctW + _ctE) / 3) - 65)>> <<else>> <<set _ctBase = 40 + (((_ctH + _ctW + _ctE) / 3) - 40) * 0.5>> <</if>> <<if _ctBase >= 65 && _ctCp2.bond >= 65>><<set _ctBase = Math.min(100, _ctBase + 5)>><</if>> <<set $cps[_ctId].moodBase = Math.max(0, Math.min(100, _ctBase))>> /* moodMod 由事件在别处修改; 这里合成为 mood */ <<set $cps[_ctId].mood = Math.max(0, Math.min(100, $cps[_ctId].moodBase + $cps[_ctId].moodMod))>> /* ── 安定(同步5档) ── */ <<set _ctM = $cps[_ctId].mood>> <<if _ctM < 20>> <<set _ctCalm = _ctM>> <<elseif _ctM >= 65 && _ctCp2.bond >= 60>> <<set _ctCalm = 88>> <<else>> <<set _ctCalm = 45 + (_ctM - 50) * 0.3>> <</if>> <<set $cps[_ctId].calm = Math.max(0, Math.min(100, _ctCalm))>> /* ── bond 趋势累积(当日) ── */ <<set $cps[_ctId].bondDrift = ($cps[_ctId].bondDrift || 0) + (($cps[_ctId].mood - 50) * (_ctElapsed / 1440))>> /* ── 主动行动检测 ── */ <<cpProactiveCheck _ctId>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "decayItems">> /* 遍历仓库和背包,清除腐烂条目,为腐败条目打标 */ <<set _dc_pools = [ { name: "store", data: $store }, { name: "backpack", data: $backpack } ]>> <<for _dcp = 0; _dcp < _dc_pools.length; _dcp++>> <<set _dc_pool = _dc_pools[_dcp].data>> <<set _dc_cats = Object.keys(_dc_pool)>> <<for _dcc = 0; _dcc < _dc_cats.length; _dcc++>> <<set _dc_cat = _dc_cats[_dcc]>> <<if Array.isArray(_dc_pool[_dc_cat])>> <<set _dc_arr = _dc_pool[_dc_cat]>> <<for _dci = _dc_arr.length - 1; _dci >= 0; _dci-->> <<set _dc_e = _dc_arr[_dci]>> <<if _dc_e.addedDay !== undefined>> <<set _dc_sd = ($spoilDays && $spoilDays[_dc_e.id]) ? $spoilDays[_dc_e.id] : 0>> <<if _dc_sd > 0>> <<set _dc_age = $day - _dc_e.addedDay>> /* 腐烂阶段 0-3 */ <<set _dc_stage = Math.floor(_dc_age / _dc_sd * 3)>> <<if _dc_stage >= 3>> /* 完全腐烂:记录损失后移除 */ <<if !$decayLog>><<set $decayLog = []>><</if>> <<run $decayLog.push({ id: _dc_e.id, qty: _dc_e.quantity, day: $day })>> <<run _dc_arr.splice(_dci, 1)>> <<else>> <<set $dc_arr[_dci].stage = _dc_stage>> <</if>> <</if>> <</if>> <</for>> <</if>> <</for>> <</for>> <</widget>> <</nobr>>
<<nobr>> /* ═══════════════════════════════════════════════ DEV 工具 widget(供 航行.tw 底部 ⚡DEV 内联调试块使用,发布前可整体移除) 全部数据驱动:遍历 $largeDefs / $wsDefs / $smallEventDefs, 新增区域或 zone 后调试台自动出现按钮,无需改面板。 ═══════════════════════════════════════════════ */ /* ── 解析当前区域:大型区域 ID 优先,单独切换地形时用地形映射兜底 ── */ <<widget "devResolveRegion">> <<set _drr = ($largeScene && typeof $largeScene === "object") ? String($largeScene.id || "") : "">> <<if $maptype === "forest">><<set _drr = "mermaid_prison">> <<elseif $maptype === "reef">><<set _drr = "reef_eternal">> <<elseif $maptype === "grass">><<set _drr = "pasture">> <<elseif $maptype === "abyss" && ["salt_lake","hydrothermal"].indexOf(_drr) < 0>><<set _drr = "salt_lake">> <</if>> <<set $devRegionId = _drr>> <</widget>> /* ── 强制生成大型区域:以当前 $map 为起点,沿用真实 zone 选取规则 ── */ <<widget "devForceLarge">> <<if !$largeDefs>><<largeSceneDefs>><</if>> <<set _dId = $args[0]>> <<set _dDef = $largeDefs[_dId]>> <<if _dDef && _dDef.zoneList && _dDef.zoneList.length > 0>> <<set _dApprEnd = $map + 2000>> <<set _dActiveEnd = _dApprEnd + 15000>> <<set _dLeaveEnd = _dActiveEnd + 2000>> /* zone 池:绑定必选 + 随机补足到 min~max(与 spawnLargeScene 一致) */ <<set _dPool = _dDef.zoneList>> <<set _dBound = _dDef.boundZones || []>> <<set _dMinZ = _dDef.minZones || 3>> <<set _dMaxZ = _dDef.maxZones || 5>> <<set _dSelNames = []>><<set _dSel = []>> <<for _dBi = 0; _dBi < _dBound.length; _dBi++>> <<for _dPi = 0; _dPi < _dPool.length; _dPi++>> <<if _dPool[_dPi].name === _dBound[_dBi]>> <<set _dSel[_dSel.length] = _dPool[_dPi]>> <<set _dSelNames[_dSelNames.length] = _dPool[_dPi].name>> <</if>> <</for>> <</for>> <<set _dRemain = []>> <<for _dPi = 0; _dPi < _dPool.length; _dPi++>> <<set _dIn = false>> <<for _dSi = 0; _dSi < _dSelNames.length; _dSi++>> <<if _dSelNames[_dSi] === _dPool[_dPi].name>><<set _dIn = true>><</if>> <</for>> <<if !_dIn>><<set _dRemain[_dRemain.length] = _dPool[_dPi]>><</if>> <</for>> <<set _dTarget = _dMinZ + Math.floor(Math.random() * (_dMaxZ - _dMinZ + 1))>> <<if _dTarget > _dPool.length>><<set _dTarget = _dPool.length>><</if>> <<for _dFill = _dSel.length; _dFill < _dTarget && _dRemain.length > 0; _dFill++>> <<set _dRI = Math.floor(Math.random() * _dRemain.length)>> <<set _dSel[_dSel.length] = _dRemain[_dRI]>> <<set _dRemain.splice(_dRI, 1)>> <</for>> /* zone 坐标:均匀分布 ± 20% 抖动 */ <<set _dCount = _dSel.length>> <<set _dSpacing = Math.floor(15000 / Math.max(_dCount, 1))>> <<set _dArr = []>> <<for _dzi = 0; _dzi < _dCount; _dzi++>> <<set _dzBase = _dApprEnd + Math.floor(_dSpacing * (_dzi + 0.5))>> <<set _dzJit = Math.floor(_dSpacing * 0.2)>> <<set _dzAt = _dzBase + Math.floor(Math.random() * (_dzJit * 2 + 1)) - _dzJit>> <<set _dzAt = Math.max(_dApprEnd + 500, Math.min(_dActiveEnd - 500, _dzAt))>> <<set _dzd = _dSel[_dzi]>> <<set _dArr[_dArr.length] = {name:_dzd.name, zoneAt:_dzAt, wsType:_dzd.wsType, st:"pending"}>> <</for>> <<set _dHints = (_dDef.approachHint && _dDef.approachHint.length > 0) ? _dDef.approachHint : ["前方海域出现了异常。"]>> <<set $largeScene = { id:_dId, name:_dDef.name, viewDesc:_dDef.viewDesc, approachHint:_dHints[Math.floor(Math.random() * _dHints.length)], leaveHint:(_dDef.leaveHint || ""), state:"approaching", approachStart:$map, approachEnd:_dApprEnd, activeEnd:_dActiveEnd, leaveEnd:_dLeaveEnd, zones:_dArr, activeZone:-1 }>> <<set $worldScene = null>><<set $wsChild = null>> <<set $devMsg = "已生成大型区域:" + _dDef.name + "(zone ×" + _dCount + ")">> <<else>> <<set $devMsg = "⚠ 未找到大型区域定义:" + _dId>> <</if>> <</widget>> /* ── 强制生成中型场景:args[0]=wsId, args[1]=state("approaching"/"inside") ── */ <<widget "devForceWs">> <<worldSceneDefs>> <<set _dwId = $args[0]>> <<set _dwSt = $args[1] || "inside">> <<set _dwD = $wsDefs[_dwId]>> <<set _dwName = ($args.length > 2 && $args[2]) ? String($args[2]) : (_dwD ? _dwD.name : _dwId)>> <<set _dwApproach = ($args.length > 3 && $args[3]) ? String($args[3]) : (_dwD ? _dwD.approachDesc : "前方有异常。")>> <<set _dwInside = ($args.length > 4 && $args[4]) ? String($args[4]) : (_dwD ? _dwD.insideDesc : "进入异常场景。")>> <<set _dwView = ($args.length > 5 && $args[5]) ? String($args[5]) : (_dwD ? _dwD.viewDesc : "")>> <<if _dwD>> <<if _dwSt === "approaching">> <<set $worldScene = {id:_dwId, name:_dwName, state:"approaching", approachDesc:_dwApproach, insideDesc:_dwInside, viewDesc:_dwView, approachAt:$map + 100, mapStart:$map + 1000, mapEnd:$map + 2000, leaveEnd:$map + 3000, children:(_dwD.children || []), doneCids:[]}>> <<else>> <<set $worldScene = {id:_dwId, name:_dwName, state:"inside", approachDesc:_dwApproach, insideDesc:_dwInside, viewDesc:_dwView, approachAt:$map - 1500, mapStart:$map - 1000, mapEnd:$map + 1000, leaveEnd:$map + 2000, children:(_dwD.children || []), doneCids:[]}>> <</if>> <<set $wsChild = null>> <<if !($args.length > 6 && $args[6] === "normal")>><<set $sailspd = 0>><</if>> <<set $devMsg = "已生成中型场景:" + _dwName + "(" + _dwSt + " · 房间 ×" + (_dwD.children ? _dwD.children.length : 0) + ")">> <<else>> <<set $devMsg = "⚠ 未找到中型场景定义:" + _dwId>> <</if>> <</widget>> /* ── 强制触发指定 C 类小型事件 ── */ <<widget "devForceSmall">> <<if !$smallEventDefs>><<smallEventTable>><</if>> <<set _dsId = $args[0]>> <<set _dsD = $smallEventDefs[_dsId]>> <<if _dsD && _dsD.stages && _dsD.stages.length > 0>> <<makeSmallSceneInstance _dsId>> <<if $smallSceneInstance>> <<set $activeSmallEvent = $smallSceneInstance>> <<set $lastSmallEventText = "">> <<set $devMsg = "已强制触发小型事件:" + _dsD.name + "(持续 " + ($activeSmallEvent.mapEnd - $activeSmallEvent.mapStart) + ")">> <<else>> <<set $devMsg = "⚠ 当前里程与已预留场景冲突,未能放置:" + _dsD.name>> <</if>> <<else>> <<set $devMsg = "⚠ 未找到小型事件定义:" + _dsId>> <</if>> <</widget>> /* ── ABC 分层权重选择器:先抽 tier,再按 tier 内权重抽事件 ── args[0] = [{id, tier, weight}, ...] args[1] = 是否处于大型区域 active 状态 结果写入 $devPickId / $devPickTier / $devPickWeight 空 tier 自动剔除后,对剩余 tier 重新归一化。 */ <<widget "devPickTierWeighted">> <<set _tpItems = ($args && $args.length > 0 && $args[0]) ? $args[0] : []>> <<set _tpInside = ($args && $args.length > 1) ? !!$args[1] : false>> <<set _tpWeights = {A:0, B:0, C:0}>><<set _tpTiers = []>> <<set _tpValid = []>> <<for _tpi = 0; _tpi < _tpItems.length; _tpi++>> <<set _tpiItem = _tpItems[_tpi]>><<set _tpiTier = String(_tpiItem.tier || "C").toUpperCase()>> <<set _tpiW = Number(_tpiItem.weight)>><<if !isFinite(_tpiW) || _tpiW < 0>><<set _tpiW = 0>><</if>> <<if (_tpInside || _tpiTier !== "A") && (_tpiTier === "A" || _tpiTier === "B" || _tpiTier === "C") && _tpiItem.id>> <<set _tpValid[_tpValid.length] = {id:_tpiItem.id, tier:_tpiTier, weight:_tpiW}>><<set _tpWeights[_tpiTier] += _tpiW>> <</if>> <</for>> <<if _tpWeights.A > 0>><<set _tpTiers[_tpTiers.length] = "A">><</if>> <<if _tpWeights.B > 0>><<set _tpTiers[_tpTiers.length] = "B">><</if>> <<if _tpWeights.C > 0>><<set _tpTiers[_tpTiers.length] = "C">><</if>> <<set $devPickId = null>><<set $devPickTier = null>><<set $devPickWeight = 0>> <<if _tpTiers.length > 0>> <<set _tpTierBase = _tpInside ? {A:4, B:1, C:1} : {B:1, C:1}>><<set _tpTierTotal = 0>> <<for _tpi = 0; _tpi < _tpTiers.length; _tpi++>><<set _tpTierTotal += _tpTierBase[_tpTiers[_tpi]]>><</for>> <<set _tpTierRoll = Math.random() * _tpTierTotal>><<set _tpTierCum = 0>><<set _tpChosenTier = _tpTiers[_tpTiers.length - 1]>><<for _tpi = 0; _tpi < _tpTiers.length; _tpi++>><<set _tpTierCum += _tpTierBase[_tpTiers[_tpi]]>><<if _tpTierRoll < _tpTierCum>><<set _tpChosenTier = _tpTiers[_tpi]>><<break>><</if>><</for>> <<set _tpTierTotal = _tpWeights[_tpChosenTier]>><<set _tpRoll = Math.random() * _tpTierTotal>><<set _tpCum = 0>> <<for _tpi = 0; _tpi < _tpValid.length; _tpi++>><<if _tpValid[_tpi].tier === _tpChosenTier>><<set _tpCum += _tpValid[_tpi].weight>><<if _tpRoll < _tpCum>><<set $devPickId = _tpValid[_tpi].id>><<set $devPickTier = _tpChosenTier>><<set $devPickWeight = _tpValid[_tpi].weight>><<break>><</if>><</if>><</for>> <<if !$devPickId>><<for _tpi = 0; _tpi < _tpValid.length; _tpi++>><<if _tpValid[_tpi].tier === _tpChosenTier>><<set $devPickId = _tpValid[_tpi].id>><<set $devPickTier = _tpChosenTier>><<set $devPickWeight = _tpValid[_tpi].weight>><<break>><</if>><</for>><</if>> <</if>> <</widget>> /* ── DEV 强制随机小型事件:候选池非空即命中,先按 ABC tier 再按相对权重抽取 ── */ <<widget "devRandomSmall">> <<if !$smallEventDefs>><<smallEventTable>><</if>> <<set _drsCtx = ($args && $args.length > 0) ? String($args[0]) : "sailing">> <<set _drsCands = []>><<set _drsKeys = Object.keys($smallEventDefs)>> <<for _drsI = 0; _drsI < _drsKeys.length; _drsI++>> <<set _drsId = _drsKeys[_drsI]>><<set _drsD = $smallEventDefs[_drsId]>><<set _drsCtxOK = (!_drsD.context || _drsD.context.indexOf(_drsCtx) >= 0)>><<set _drsTerOK = (!_drsD.terrain || _drsD.terrain.indexOf($maptype) >= 0)>><<set _drsDepthOK = true>> <<if _drsD.depthRule>><<if _drsD.depthRule.type === "nearBottom">><<set _drsDepthOK = ($depthdeep - $depth <= _drsD.depthRule.value)>><<elseif _drsD.depthRule.type === "nearSurface">><<set _drsDepthOK = ($depth <= _drsD.depthRule.value)>><<elseif _drsD.depthRule.type === "minDepth">><<set _drsDepthOK = ($depth >= _drsD.depthRule.value)>><</if>><<elseif _drsD.depthRange>><<set _drsDepthOK = ($depth >= _drsD.depthRange[0] && $depth <= _drsD.depthRange[1])>><</if>> <<set _drsSeasonOK = true>><<if _drsD.seasonRule>><<if _drsD.seasonRule.enabled === false>><<set _drsSeasonOK = false>><</if>><<if _drsD.seasonRule.include && _drsD.seasonRule.include.indexOf($season) < 0>><<set _drsSeasonOK = false>><</if>><</if>> <<if _drsCtxOK && _drsTerOK && _drsDepthOK && _drsSeasonOK && _drsD.stages && _drsD.stages.length > 0>><<set _drsW = Number(_drsD.weight)>><<if !isFinite(_drsW) || _drsW <= 0>><<set _drsW = Number(_drsD.baseChance)>><</if>><<if !isFinite(_drsW) || _drsW <= 0>><<set _drsW = 1>><</if>><<set _drsCands[_drsCands.length] = {id:_drsId, tier:String(_drsD.tier || "C").toUpperCase(), weight:_drsW}>><</if>> <</for>> <<set _drsBCands = 0>><<set _drsCCands = 0>><<for _drsI = 0; _drsI < _drsCands.length; _drsI++>><<if _drsCands[_drsI].tier === "B">><<set _drsBCands += 1>><<elseif _drsCands[_drsI].tier === "C">><<set _drsCCands += 1>><</if>><</for>> <<set _drsInside = !!($largeScene && $largeScene.state === "active")>><<devPickTierWeighted _drsCands _drsInside>> <<if $devPickId>><<set _drsPick = $devPickId>><<set _drsD = $smallEventDefs[_drsPick]>><<makeSmallSceneInstance _drsPick>> <<if $smallSceneInstance>><<set $activeSmallEvent = $smallSceneInstance>><<set $lastSmallEventText = "">><<set $devMsg = "DEV 强制随机命中:" + _drsD.name + "(" + $devPickTier + "类 · B" + _drsBCands + "/C" + _drsCCands + " · 持续 " + ($activeSmallEvent.mapEnd - $activeSmallEvent.mapStart) + " · 距海底 " + Math.max(0, $depthdeep - $depth) + "m)">> <<else>><<set $devMsg = "⚠ 随机命中但当前里程无可用区间:" + _drsD.name>><</if>> <<else>><<set $devMsg = "⚠ 当前条件下没有可用小型事件">><</if>> <</widget>> /* ── DEV 强制随机微事件:候选池非空即命中,先按 ABC tier 再按相对权重抽取 ── */ <<widget "devRandomMicro">> <<devResolveRegion>> <<if !$microEventDefs>><<microEventTable>><</if>> <<set _drmCands = []>><<set _drmKeys = Object.keys($microEventDefs)>><<set _drmRich = Math.max(0, Number($regionRichness) || 0)>> <<for _drmI = 0; _drmI < _drmKeys.length; _drmI++>> <<set _drmId = _drmKeys[_drmI]>><<set _drmD = $microEventDefs[_drmId]>><<set _drmTerOK = (!_drmD.terrain || _drmD.terrain.indexOf($maptype) >= 0)>><<set _drmDepthOK = true>><<if _drmD.depthRule>><<if _drmD.depthRule.type === "nearBottom">><<set _drmDepthOK = ($depthdeep - $depth <= _drmD.depthRule.value)>><<elseif _drmD.depthRule.type === "nearSurface">><<set _drmDepthOK = ($depth <= _drmD.depthRule.value)>><<elseif _drmD.depthRule.type === "minDepth">><<set _drmDepthOK = ($depth >= _drmD.depthRule.value)>><</if>><<elseif _drmD.depthRange>><<set _drmDepthOK = ($depth >= _drmD.depthRange[0] && $depth <= _drmD.depthRange[1])>><</if>><<set _drmRichOK = (!_drmD.richnessBased || _drmRich > 0)>><<if _drmTerOK && _drmDepthOK && _drmRichOK>><<set _drmW = Number(_drmD.weight)>><<if !isFinite(_drmW) || _drmW <= 0>><<set _drmW = Number(_drmD.baseChance)>><</if>><<if !isFinite(_drmW) || _drmW <= 0>><<set _drmW = 1>><</if>><<set _drmCands[_drmCands.length] = {id:_drmId,tier:String(_drmD.tier || "C").toUpperCase(),weight:_drmW}>><</if>> <</for>> <<set _drmInside = !!($largeScene && $largeScene.state === "active")>><<devPickTierWeighted _drmCands _drmInside>> <<if $devPickId>><<set _drmPick = $devPickId>><<set _drmD = $microEventDefs[_drmPick]>><<set _drmRegion = $devRegionId || "">><<set _drmV = (_drmD.regionVariants && _drmRegion && _drmD.regionVariants[_drmRegion]) ? _drmD.regionVariants[_drmRegion] : null>><<set $activeMicroEvent = {id:_drmPick,name:(_drmV && _drmV.name) ? _drmV.name : (_drmD.name || _drmD.fragmentText),desc:(_drmV && _drmV.desc) ? _drmV.desc : (_drmD.desc || _drmD.fragmentText),action:(_drmV && _drmV.action) ? _drmV.action : (_drmD.action || _drmD.actionLabel),regionVariant:(_drmV ? _drmRegion : ""),mapAt:$map,leaveEnd:$map + 300}>> <<set $devMsg = "DEV 强制随机命中微事件:" + ($activeMicroEvent.name || _drmPick) + "(" + $devPickTier + "类 · 候选 " + _drmCands.length + ")">> <<else>><<set $devMsg = "⚠ 当前地形 / 深度下没有可用微事件">><</if>> <</widget>> /* ── DEV 总池分层抽取:合并 A/B/C 的 micro、small、middle,按 tier 后按 weight 命中 ── */ <<widget "devRandomTotal">> <<devResolveRegion>> <<if !$largeDefs>><<largeSceneDefs>><</if>><<if !$wsDefs>><<worldSceneDefs>><</if>><<if !$smallEventDefs>><<smallEventTable>><</if>><<if !$microEventDefs>><<microEventTable>><</if>> <<set _dttCands = []>><<set _dttRegion = $devRegionId || "">><<set _dttNow = Number($depth) || 0>><<set _dttBottom = Number($depthdeep) || 0>><<set _dttRich = Math.max(0, Number($regionRichness) || 0)>><<set _dttActiveLarge = !!($largeScene && typeof $largeScene === "object" && $largeScene.state !== "done")>> /* A:当前没有大型区域时,加入可由真实大型生成器命中的大型区域。 */ <<if !_dttActiveLarge>> <<set _dttLKeys = Object.keys($largeDefs)>><<for _dtti = 0; _dtti < _dttLKeys.length; _dtti++>><<set _dttLId = _dttLKeys[_dtti]>><<set _dttLD = $largeDefs[_dttLId]>><<set _dttLOK = false>><<if _dttLId === "sunken_city">><<set _dttLOK = _dttBottom >= 20 && _dttBottom <= 800 && ["sand","flat","cliff","grass","reef","forest"].indexOf($maptype) >= 0>><<elseif _dttLId === "wreck_graveyard">><<set _dttLOK = _dttBottom >= 20 && ["sand","flat","cliff","grass","reef","forest"].indexOf($maptype) >= 0>><<elseif _dttLId === "cliff_pit">><<set _dttLOK = _dttBottom >= 20 && $maptype === "cliff">><<elseif _dttLId === "pasture">><<set _dttLOK = _dttBottom >= 20 && $maptype === "grass">><<elseif _dttLId === "reef_eternal">><<set _dttLOK = _dttBottom >= 20 && $maptype === "reef">><<elseif _dttLId === "mermaid_prison">><<set _dttLOK = _dttBottom >= 20 && $maptype === "forest">><<elseif _dttLId === "salt_lake" || _dttLId === "hydrothermal">><<set _dttLOK = _dttBottom >= 20 && $maptype === "abyss">><</if>><<if _dttLOK>><<set _dttCands[_dttCands.length] = {id:"large:" + _dttLId,source:"large",rawId:_dttLId,tier:"A",weight:1,sceneType:"large"}>><</if>><</for>> <</if>> /* micro:复用当前地形、深度、丰富度过滤。 */ <<set _dttKeys = Object.keys($microEventDefs)>><<for _dtti = 0; _dtti < _dttKeys.length; _dtti++>><<set _dttId = _dttKeys[_dtti]>><<set _dttD = $microEventDefs[_dttId]>><<set _dttTerOK = (!_dttD.devOnly && (!_dttD.terrain || _dttD.terrain.length === 0 || _dttD.terrain.indexOf($maptype) >= 0))>><<set _dttDepthOK = true>><<if _dttD.depthRule>><<if _dttD.depthRule.type === "nearBottom">><<set _dttDepthOK = (_dttBottom - _dttNow <= _dttD.depthRule.value)>><<elseif _dttD.depthRule.type === "nearSurface">><<set _dttDepthOK = (_dttNow <= _dttD.depthRule.value)>><<elseif _dttD.depthRule.type === "minDepth">><<set _dttDepthOK = (_dttNow >= _dttD.depthRule.value)>><</if>><<elseif _dttD.depthRange>><<set _dttDepthOK = (_dttNow >= _dttD.depthRange[0] && _dttNow <= _dttD.depthRange[1])>><</if>><<set _dttRichOK = (!_dttD.richnessBased || _dttRich > 0)>><<if _dttTerOK && _dttDepthOK && _dttRichOK>><<set _dttW = Number(_dttD.weight)>><<if !isFinite(_dttW) || _dttW <= 0>><<set _dttW = 1>><</if>><<if !isFinite(_dttW) || _dttW <= 0>><<set _dttW = 1>><</if>><<set _dttCands[_dttCands.length] = {id:"micro:" + _dttId,source:"micro",rawId:_dttId,tier:String(_dttD.tier || "C").toUpperCase(),weight:_dttW,sceneType:"micro"}>><</if>><</for>> /* small:复用 sailing 上下文、地形、深度、季节过滤。 */ <<set _dttKeys = Object.keys($smallEventDefs)>><<for _dtti = 0; _dtti < _dttKeys.length; _dtti++>><<set _dttId = _dttKeys[_dtti]>><<set _dttD = $smallEventDefs[_dttId]>><<set _dttCtxOK = (!_dttD.devOnly && (!_dttD.context || _dttD.context.indexOf("sailing") >= 0))>><<set _dttTerOK = (!_dttD.terrain || _dttD.terrain.length === 0 || _dttD.terrain.indexOf($maptype) >= 0)>><<set _dttDepthOK = true>><<if _dttD.depthRule>><<if _dttD.depthRule.type === "nearBottom">><<set _dttDepthOK = (_dttBottom - _dttNow <= _dttD.depthRule.value)>><<elseif _dttD.depthRule.type === "nearSurface">><<set _dttDepthOK = (_dttNow <= _dttD.depthRule.value)>><<elseif _dttD.depthRule.type === "minDepth">><<set _dttDepthOK = (_dttNow >= _dttD.depthRule.value)>><</if>><<elseif _dttD.depthRange>><<set _dttDepthOK = (_dttNow >= _dttD.depthRange[0] && _dttNow <= _dttD.depthRange[1])>><</if>><<set _dttSeasonOK = true>><<if _dttD.seasonRule>><<if _dttD.seasonRule.enabled === false>><<set _dttSeasonOK = false>><</if>><<if _dttD.seasonRule.include && _dttD.seasonRule.include.indexOf($season) < 0>><<set _dttSeasonOK = false>><</if>><</if>><<if _dttCtxOK && _dttTerOK && _dttDepthOK && _dttSeasonOK && _dttD.stages && _dttD.stages.length > 0>><<set _dttW = Number(_dttD.weight)>><<if !isFinite(_dttW) || _dttW <= 0>><<set _dttW = 1>><</if>><<if !isFinite(_dttW) || _dttW <= 0>><<set _dttW = 1>><</if>><<set _dttCands[_dttCands.length] = {id:"small:" + _dttId,source:"small",rawId:_dttId,tier:String(_dttD.tier || "C").toUpperCase(),weight:_dttW,sceneType:"small"}>><</if>><</for>> /* middle:仅加入正式 B/C 插入式中型,按当前地形和区域变体修正权重。 */ <<set _dttKeys = Object.keys($wsDefs)>><<for _dtti = 0; _dtti < _dttKeys.length; _dtti++>><<set _dttId = _dttKeys[_dtti]>><<set _dttD = $wsDefs[_dttId]>><<set _dttTerOK = (!_dttD.devOnly && (!_dttD.terrain || _dttD.terrain.length === 0 || _dttD.terrain.indexOf($maptype) >= 0))>><<set _dttModesOK = (_dttD.modes === "tier_only" || _dttD.modes === "independent" || _dttD.modes === "both")>><<if _dttTerOK && _dttModesOK && _dttD.sceneType === "middle" && (_dttD.tier === "B" || _dttD.tier === "C")>><<set _dttW = Number(_dttD.weight) || 1>><<set _dttV = (_dttD.regionVariants && _dttRegion && _dttD.regionVariants[_dttRegion]) ? _dttD.regionVariants[_dttRegion] : null>><<if _dttV && _dttV.weightMultiplier>><<set _dttW *= Number(_dttV.weightMultiplier) >><</if>><<set _dttCands[_dttCands.length] = {id:"middle:" + _dttId,source:"middle",rawId:_dttId,tier:String(_dttD.tier).toUpperCase(),weight:_dttW,sceneType:"middle"}>><</if>><</for>> <<devPickTierWeighted _dttCands _dttActiveLarge>><<if $devPickId>><<set _dttPick = null>><<for _dtti = 0; _dtti < _dttCands.length; _dtti++>><<if _dttCands[_dtti].id === $devPickId>><<set _dttPick = _dttCands[_dtti]>><<break>><</if>><</for>><<if _dttPick>> <<if _dttPick.source === "large">><<devForceLarge _dttPick.rawId>><<elseif _dttPick.source === "small">><<devForceSmall _dttPick.rawId>><<elseif _dttPick.source === "micro">><<set _dttD = $microEventDefs[_dttPick.rawId]>><<set _dttV = (_dttD.regionVariants && _dttRegion && _dttD.regionVariants[_dttRegion]) ? _dttD.regionVariants[_dttRegion] : null>><<set $activeMicroEvent = {id:_dttPick.rawId,name:(_dttV && _dttV.name) ? _dttV.name : (_dttD.name || _dttD.fragmentText),desc:(_dttV && _dttV.desc) ? _dttV.desc : (_dttD.desc || _dttD.fragmentText),action:(_dttV && _dttV.action) ? _dttV.action : (_dttD.action || _dttD.actionLabel),regionVariant:(_dttV ? _dttRegion : ""),mapAt:$map,leaveEnd:$map + 300}>><<set $devMsg = "DEV 总池命中:" + $activeMicroEvent.name + "(" + $devPickTier + "类 / micro · B/C=1:1)">><<elseif _dttPick.source === "middle">><<set _dttMD = $wsDefs[_dttPick.rawId]>><<set _dttMV = (_dttMD && _dttMD.regionVariants && _dttRegion && _dttMD.regionVariants[_dttRegion]) ? _dttMD.regionVariants[_dttRegion] : null>><<set _dttMN = (_dttMV && _dttMV.name) ? _dttMV.name : (_dttMD ? _dttMD.name : _dttPick.rawId)>><<set _dttMA = (_dttMV && _dttMV.approachDesc) ? _dttMV.approachDesc : (_dttMD ? _dttMD.approachDesc : "前方有异常。")>><<set _dttMI = (_dttMV && _dttMV.insideDesc) ? _dttMV.insideDesc : (_dttMD ? _dttMD.insideDesc : "进入异常场景。")>><<set _dttMW = (_dttMV && _dttMV.viewDesc) ? _dttMV.viewDesc : (_dttMD ? _dttMD.viewDesc : "")>><<if $args && $args.length > 0 && $args[0] === "normal">><<devForceWs _dttPick.rawId "approaching" _dttMN _dttMA _dttMI _dttMW "normal">><<else>><<devForceWs _dttPick.rawId "approaching" _dttMN _dttMA _dttMI _dttMW>><</if>><<set $devMsg = "DEV 总池命中:" + $devPickTier + "类 / middle · " + $worldScene.name + "(区域 " + (_dttRegion || "无") + " · B/C=1:1)">><</if>> <<else>><<set $devMsg = "⚠ 总池抽取失败:命中事件无法放置或当前没有候选">><</if>><<else>><<set $devMsg = "⚠ 当前条件下总池没有可用事件">><</if>> <</widget>> /* ── 只读显示当前条件下的统一 B/C 事件池,不触发任何事件 ── */ <<widget "devShowEventPool">> <<devResolveRegion>> <<if !$largeDefs>><<largeSceneDefs>><</if>><<if !$wsDefs>><<worldSceneDefs>><</if>><<if !$smallEventDefs>><<smallEventTable>><</if>><<if !$microEventDefs>><<microEventTable>><</if>> <<set _dpoItems = []>><<set _dpoRegion = $devRegionId || "">><<set _dpoRich = Math.max(0, Number($regionRichness) || 0)>><<set _dpoKeys = Object.keys($microEventDefs)>><<set _dpoNow = Number($depth) || 0>><<set _dpoBottom = Number($depthdeep) || 0>> <<for _dpoi = 0; _dpoi < _dpoKeys.length; _dpoi++>> <<set _dpoId = _dpoKeys[_dpoi]>><<set _dpoD = $microEventDefs[_dpoId]>><<set _dpoOK = (!_dpoD.terrain || _dpoD.terrain.length === 0 || _dpoD.terrain.indexOf($maptype) >= 0)>><<set _dpoDepthOK = true>><<if _dpoD.depthRule>><<if _dpoD.depthRule.type === "nearBottom">><<set _dpoDepthOK = (_dpoBottom - _dpoNow <= _dpoD.depthRule.value)>><<elseif _dpoD.depthRule.type === "nearSurface">><<set _dpoDepthOK = (_dpoNow <= _dpoD.depthRule.value)>><<elseif _dpoD.depthRule.type === "minDepth">><<set _dpoDepthOK = (_dpoNow >= _dpoD.depthRule.value)>><</if>><<elseif _dpoD.depthRange>><<set _dpoDepthOK = (_dpoNow >= _dpoD.depthRange[0] && _dpoNow <= _dpoD.depthRange[1])>><</if>><<set _dpoRichOK = (!_dpoD.richnessBased || _dpoRich > 0)>><<if _dpoOK && _dpoDepthOK && _dpoRichOK>><<set _dpoW = Number(_dpoD.weight)>><<if !isFinite(_dpoW) || _dpoW <= 0>><<set _dpoW = 1>><</if>><<if !isFinite(_dpoW) || _dpoW <= 0>><<set _dpoW = 1>><</if>><<set _dpoV = (_dpoD.regionVariants && _dpoRegion && _dpoD.regionVariants[_dpoRegion]) ? _dpoD.regionVariants[_dpoRegion] : null>><<set _dpoVW = _dpoV && _dpoV.weightMultiplier ? _dpoW * Number(_dpoV.weightMultiplier) : _dpoW>><<set _dpoVN = []>><<if _dpoV && _dpoV.name>><<set _dpoVN[_dpoVN.length] = _dpoV.name>><</if>><<if _dpoV && _dpoV.variants && _dpoV.variants.length>><<for _dpoVi = 0; _dpoVi < _dpoV.variants.length; _dpoVi++>><<set _dpoVN[_dpoVN.length] = _dpoV.variants[_dpoVi].name + " ×" + (Number(_dpoV.variants[_dpoVi].weight) || 1)>><</for>><</if>><<set _dpoItems[_dpoItems.length] = {tier:String(_dpoD.tier || "C").toUpperCase(),name:(_dpoD.name || _dpoD.fragmentText || _dpoId),weight:_dpoW,currentWeight:_dpoVW,variants:_dpoVN}>><</if>> <</for>> <<set _dpoKeys = Object.keys($smallEventDefs)>><<for _dpoi = 0; _dpoi < _dpoKeys.length; _dpoi++>> <<set _dpoId = _dpoKeys[_dpoi]>><<set _dpoD = $smallEventDefs[_dpoId]>><<set _dpoOK = (!_dpoD.terrain || _dpoD.terrain.length === 0 || _dpoD.terrain.indexOf($maptype) >= 0)>><<set _dpoCtxOK = (!_dpoD.context || _dpoD.context.indexOf("sailing") >= 0)>><<set _dpoDepthOK = true>><<if _dpoD.depthRule>><<if _dpoD.depthRule.type === "nearBottom">><<set _dpoDepthOK = (_dpoBottom - _dpoNow <= _dpoD.depthRule.value)>><<elseif _dpoD.depthRule.type === "nearSurface">><<set _dpoDepthOK = (_dpoNow <= _dpoD.depthRule.value)>><<elseif _dpoD.depthRule.type === "minDepth">><<set _dpoDepthOK = (_dpoNow >= _dpoD.depthRule.value)>><</if>><<elseif _dpoD.depthRange>><<set _dpoDepthOK = (_dpoNow >= _dpoD.depthRange[0] && _dpoNow <= _dpoD.depthRange[1])>><</if>><<set _dpoSeasonOK = true>><<if _dpoD.seasonRule>><<if _dpoD.seasonRule.enabled === false>><<set _dpoSeasonOK = false>><</if>><<if _dpoD.seasonRule.include && _dpoD.seasonRule.include.indexOf($season) < 0>><<set _dpoSeasonOK = false>><</if>><</if>><<if _dpoOK && _dpoCtxOK && _dpoDepthOK && _dpoSeasonOK && _dpoD.stages && _dpoD.stages.length > 0>><<set _dpoW = Number(_dpoD.weight)>><<if !isFinite(_dpoW) || _dpoW <= 0>><<set _dpoW = 1>><</if>><<if !isFinite(_dpoW) || _dpoW <= 0>><<set _dpoW = 1>><</if>><<set _dpoV = (_dpoD.regionVariants && _dpoRegion && _dpoD.regionVariants[_dpoRegion]) ? _dpoD.regionVariants[_dpoRegion] : null>><<set _dpoVW = _dpoV && _dpoV.weightMultiplier ? _dpoW * Number(_dpoV.weightMultiplier) : _dpoW>><<set _dpoVN = []>><<if _dpoV && _dpoV.name>><<set _dpoVN[_dpoVN.length] = _dpoV.name>><</if>><<set _dpoItems[_dpoItems.length] = {tier:String(_dpoD.tier || "C").toUpperCase(),name:(_dpoD.name || _dpoId),weight:_dpoW,currentWeight:_dpoVW,variants:_dpoVN}>><</if>> <</for>> <<set _dpoKeys = Object.keys($wsDefs)>><<for _dpoi = 0; _dpoi < _dpoKeys.length; _dpoi++>> <<set _dpoId = _dpoKeys[_dpoi]>><<set _dpoD = $wsDefs[_dpoId]>><<set _dpoOK = (!_dpoD.terrain || _dpoD.terrain.length === 0 || _dpoD.terrain.indexOf($maptype) >= 0)>><<set _dpoV = (_dpoD.regionVariants && _dpoRegion && _dpoD.regionVariants[_dpoRegion]) ? _dpoD.regionVariants[_dpoRegion] : null>><<if _dpoD.sceneType === "middle" && (_dpoD.modes === "tier_only" || _dpoD.modes === "independent" || _dpoD.modes === "both") && (_dpoD.tier === "B" || _dpoD.tier === "C") && _dpoOK>><<set _dpoW = Number(_dpoD.weight) || 1>><<set _dpoVW = _dpoV && _dpoV.weightMultiplier ? _dpoW * Number(_dpoV.weightMultiplier) : _dpoW>><<set _dpoVN = []>><<if _dpoV && _dpoV.name>><<set _dpoVN[_dpoVN.length] = _dpoV.name>><</if>><<if _dpoV && _dpoV.variants && _dpoV.variants.length>><<for _dpoVi = 0; _dpoVi < _dpoV.variants.length; _dpoVi++>><<set _dpoVN[_dpoVN.length] = _dpoV.variants[_dpoVi].name + " ×" + (Number(_dpoV.variants[_dpoVi].weight) || 1)>><</for>><</if>><<set _dpoItems[_dpoItems.length] = {tier:String(_dpoD.tier).toUpperCase(),name:_dpoD.name,weight:_dpoW,currentWeight:_dpoVW,variants:_dpoVN}>><</if>> <</for>> <<set $devEventPoolOverview = {terrain:$maptype,depth:_dpoNow,seabed:_dpoBottom,region:_dpoRegion,items:_dpoItems}>><<set $devMsg = "已刷新当前事件池:" + _dpoItems.length + " 条(仅展示,未触发)">> <</widget>> /* ── 切换地形(同时把深度夹到该地形合法区间) ── */ <<widget "devSetTerrain">> <<set _dtT = $args[0]>> <<set _dtI = $mapinfo[_dtT]>> <<if _dtI>> <<set $maptype = _dtT>> <<set $depthdeep = _dtI.depthmin + Math.floor((_dtI.depthmax - _dtI.depthmin) * 0.3)>> <<if $depthdeep > 3000>><<set $depthdeep = 3000>><</if>> <<set $depth = Math.min($depth, $depthdeep)>> <<set $devEventPoolOverview = null>> <<set $devMsg = "地形切换为:" + _dtI.type + "(海底 " + $depthdeep + "m)">> <</if>> <</widget>> /* ── CP DEV:集中修改当前选中角色的展示状态,不改变普通玩法数值结算。 ── */ <<widget "devSelectCp">> <<set _dscId = String($args[0] || "viona")>> <<if $cps && $cps[_dscId]>> <<set $devCpId = _dscId>> <<set _dscTestIdx = $activeCpIds.indexOf("testcp")>> <<if _dscId === "testcp">> <<if _dscTestIdx < 0>><<run $activeCpIds.push("testcp")>><</if>> <<elseif _dscTestIdx >= 0>> <<run $activeCpIds.splice(_dscTestIdx, 1)>> <</if>> <<set $devMsg = "当前调试角色:" + $cps[_dscId].name>> <</if>> <</widget>> <<widget "devSetCpRoom">> <<set _dvrId = ($devCpId && $cps && $cps[$devCpId]) ? $devCpId : "viona">> <<if $cps && $cps[_dvrId]>> <<set _dvrNow = ($day || 1) * 1440 + ($hour || 0) * 60 + ($minute || 0)>> <<set $cps[_dvrId].location = $args[0]>> <<set $cps[_dvrId].action = $args[1] || "interact">> <<set $cps[_dvrId].mode = "interact">> <<set $cps[_dvrId].actionEndTime = _dvrNow + 720>> <<set $cps[_dvrId].actionDetail = "DEV 固定展示">> <<set $devMsg = $cps[_dvrId].name + "已移至:" + $cps[_dvrId].location + " / " + $cps[_dvrId].action>> <</if>> <</widget>> <<widget "devSetCpMood">> <<set _dvmId = ($devCpId && $cps && $cps[$devCpId]) ? $devCpId : "viona">> <<if $cps && $cps[_dvmId]>> <<set _dvmVal = Math.max(0, Math.min(100, Number($args[0]) || 0))>> <<if _dvmVal >= 75>><<set _dvmStat = 90>> <<elseif _dvmVal < 35>><<set _dvmStat = 10>> <<else>><<set _dvmStat = 50>><</if>> <<set $cps[_dvmId].hunger = _dvmStat>><<set $cps[_dvmId].water = _dvmStat>><<set $cps[_dvmId].energy = _dvmStat>> <<set $cps[_dvmId].moodBase = _dvmVal>><<set $cps[_dvmId].moodMod = 0>><<set $cps[_dvmId].mood = _dvmVal>> <<set $devMsg = $cps[_dvmId].name + "心情预设为:" + _dvmVal>> <</if>> <</widget>> <<widget "devSetCpStatus">> <<set _dvsId = ($devCpId && $cps && $cps[$devCpId]) ? $devCpId : "viona">> <<if $cps && $cps[_dvsId]>> <<set _dvsKey = String($args[0] || "")>><<set _dvsVal = $args[1]>> <<if _dvsKey === "wet">><<set $cps[_dvsId].wet = !!_dvsVal>> <<elseif _dvsKey === "injured">><<set $cps[_dvsId].injured = Number(_dvsVal) || 0>> <<elseif _dvsKey === "sick">><<set $cps[_dvsId].sick = !!_dvsVal>><</if>> <<set $devMsg = $cps[_dvsId].name + "状态已更新。">> <</if>> <</widget>> <<widget "devSetCpDrivingMemory">> <<set _dvmemId = ($devCpId && $cps && $cps[$devCpId]) ? $devCpId : "viona">> <<if $cps && $cps[_dvmemId]>> <<set _dvTerrain = ($mapinfo && $mapinfo[$maptype]) ? $mapinfo[$maptype].type : "前方海域">> <<if !$cps[_dvmemId].recentEvents>><<set $cps[_dvmemId].recentEvents = {}>><</if>> <<set $cps[_dvmemId].recentEvents.driving = {tag:"started_driving",terrain:_dvTerrain,day:$day,expire:$day + 1}>> <<set $devMsg = $cps[_dvmemId].name + "已写入驾驶记忆:" + _dvTerrain>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "doUpgrade">> /* 用法:<<doUpgrade "hull">> 检查材料是否足够,足够则扣除并升级,结果写入 $lastUpgradeText */ <<set _duId = $args[0]>> <<if !$upgradeDefs>><<upgradeDefs>><</if>> <<set _duDef = $upgradeDefs[_duId]>> <<if !_duDef>> <<set $lastUpgradeText = "未知升级项:" + _duId>> <<else>> <<set _duCur = Number($upgrades[_duId]) || 0>> <<if _duCur >= _duDef.maxLevel>> <<set $lastUpgradeText = _duDef.name + "已达最高等级。">> <<else>> <<set _duNext = _duCur + 1>> <<set _duLvlDef = _duDef.levels[_duNext]>> <<set _duCost = _duLvlDef.cost>> /* 检查材料 */ <<set _duCanAfford = true>> <<set _duMissing = []>> <<set _duCostKeys = Object.keys(_duCost)>> <<for _dci = 0; _dci < _duCostKeys.length; _dci++>> <<set _dcId = _duCostKeys[_dci]>> <<set _dcReq = _duCost[_dcId]>> <<set _dcType = ($items[_dcId] ? $items[_dcId].type : "")>> <<set _dcHave = 0>> <<if _dcType && $store[_dcType]>> <<for _dci2 = 0; _dci2 < $store[_dcType].length; _dci2++>> <<if $store[_dcType][_dci2].id === _dcId>><<set _dcHave += $store[_dcType][_dci2].quantity>><</if>> <</for>> <</if>> <<if _dcType && $backpack[_dcType]>> <<for _dci2 = 0; _dci2 < $backpack[_dcType].length; _dci2++>> <<if $backpack[_dcType][_dci2].id === _dcId>><<set _dcHave += $backpack[_dcType][_dci2].quantity>><</if>> <</for>> <</if>> <<if _dcHave < _dcReq>> <<set _duCanAfford = false>> <<set _duMissName = ($items[_dcId] ? $items[_dcId].name : _dcId)>> <<run _duMissing.push(_duMissName + "×" + (_dcReq - _dcHave))>> <</if>> <</for>> <<if !_duCanAfford>> <<set $lastUpgradeText = "材料不足:" + _duMissing.join(",")>> <<else>> /* 扣除材料 */ <<for _dci = 0; _dci < _duCostKeys.length; _dci++>> <<set _dcId = _duCostKeys[_dci]>> <<set _dcReq = _duCost[_dcId]>> <<set _dcType = ($items[_dcId] ? $items[_dcId].type : "")>> <<set _dcLeft = _dcReq>> <<if _dcType && $store[_dcType]>> <<for _dci2 = 0; _dci2 < $store[_dcType].length; _dci2++>> <<if $store[_dcType][_dci2].id === _dcId && _dcLeft > 0>> <<set _dcTake = Math.min($store[_dcType][_dci2].quantity, _dcLeft)>> <<set $store[_dcType][_dci2].quantity -= _dcTake>> <<set _dcLeft -= _dcTake>> <</if>> <</for>> <</if>> <<if _dcLeft > 0 && _dcType && $backpack[_dcType]>> <<for _dci2 = 0; _dci2 < $backpack[_dcType].length; _dci2++>> <<if $backpack[_dcType][_dci2].id === _dcId && _dcLeft > 0>> <<set _dcTake = Math.min($backpack[_dcType][_dci2].quantity, _dcLeft)>> <<set $backpack[_dcType][_dci2].quantity -= _dcTake>> <<set _dcLeft -= _dcTake>> <</if>> <</for>> <</if>> <</for>> /* 升级 */ <<set $upgrades[_duId] = _duNext>> /* 立即应用效果 */ <<applyUpgradeEffects _duId>> <<set $lastUpgradeText = _duDef.name + " 升至 Lv." + _duNext + "「" + _duLvlDef.label + "」">> <</if>> <</if>> <</if>> <</widget>> /* 应用升级效果到游戏变量 */ <<widget "applyUpgradeEffects">> <<set _aueId = $args[0]>> /* 推进器 → spdmax */ <<if _aueId === "thruster">> <<set _aueSpdTable = [100, 200, 350, 500]>> <<set $spdmax = _aueSpdTable[Number($upgrades.thruster)||0]>> <</if>> /* 燃料槽 → fuelMax */ <<if _aueId === "fuel_tank">> <<set _aueFuelTable = [300, 500, 800, 1400]>> <<set $fuelMax = _aueFuelTable[Number($upgrades.fuel_tank)||0]>> <</if>> /* 氧气 → diveOxygen上限(存入 $diveOxygenMax,diveInit时使用)*/ <<if _aueId === "oxygen_sys">> <<set _aueO2Table = [100, 160, 250, 400]>> <<set $diveOxygenMax = _aueO2Table[Number($upgrades.oxygen_sys)||0]>> <</if>> /* kitchen / alchemy: 无需更新数值变量,UI 直接读 $upgrades.kitchen/alchemy */ <</widget>> <</nobr>>
<<nobr>> <<widget "eatDish">> /* args[0] = 冰箱slot索引 */ <<set _ed_slot = $args[0]>> <<set _ed_dish = $fridge[_ed_slot]>> <<if _ed_dish>> <<set $hunger = Math.min(100, $hunger + (_ed_dish.hunger || 0))>> <<set $water = Math.min(100, $water + (_ed_dish.water || 0))>> <<set $life = Math.min(100, $life + (_ed_dish.life || 0))>> <<set $power = Math.min(100, $power + (_ed_dish.power || 0))>> <<set $san = Math.min(100, Math.max(0, $san + (_ed_dish.san || 0)))>> <<set $magic = Math.min(100, $magic + (_ed_dish.magic || 0))>> <<set $fridge[_ed_slot] = null>> <<set $lastEatDesc = _ed_dish.desc>> <<set $lastEatName = _ed_dish.name>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "exploreSearch">> /* ── 初始化 ── */ <<set _emin = ($exploreSearchCost && typeof $exploreSearchCost.min === "number") ? $exploreSearchCost.min : 3>> <<set _emax = ($exploreSearchCost && typeof $exploreSearchCost.max === "number") ? $exploreSearchCost.max : 7>> <<if !$exploreLog>><<set $exploreLog = []>><</if>> <<set _rich = Number($regionRichness) || 0>> /* 丰富度不足 */ <<if _rich < _emin>> <<set $lastExploreText = "这片区域已经被搜索得差不多了,暂时没有新的发现。">> <<return>> <</if>> /* 消耗丰富度 */ <<set _cost = _emin + Math.floor(Math.random() * (_emax - _emin + 1))>> <<set $regionRichness = Math.max(0, _rich - _cost)>> /* ── 选基础氛围(1-2 条,不含生物名)── */ <<if !$exploreFragments>><<exploreDefs>><</if>> <<set _pool = null>> <<if $exploreFragments[$maptype] && $exploreFragments[$maptype].length > 0>> <<set _pool = $exploreFragments[$maptype].slice()>> <<else>> <<set _pool = ["周围一片幽暗,灯光勉强照出面前这一小片水域的轮廓。","水流平静,没有特别的动静。"]>> <</if>> /* Fisher-Yates 局部乱序,取 1-2 条 */ <<set _baseN = Math.random() < 0.5 ? 1 : 2>> <<set _baseN = Math.min(_baseN, _pool.length)>> <<for _si = 0; _si < _baseN; _si++>> <<set _sj = _si + Math.floor(Math.random() * (_pool.length - _si))>> <<set _stmp = _pool[_si]>><<set _pool[_si] = _pool[_sj]>><<set _pool[_sj] = _stmp>> <</for>> <<set $lastExploreText = _pool.slice(0, _baseN).join(" ")>> <<run $exploreLog.unshift($lastExploreText)>> <<if $exploreLog.length > 5>><<run $exploreLog.pop()>><</if>> /* ── 构建微型事件候选池(hunt 优先,补充 explore) ── */ <<if !$microEventDefs>><<microEventTable>><</if>> <<set $activeHuntItems = []>> <<set $lastHuntText = "">> <<set $lastMicroText = "">> <<set _richFactor = Math.max(0, _rich) / 100>> <<set _slots = 3 - _baseN>> /* 剩余碎片槽数 */ <<set _maxItems = _slots>> <<set _mKeys = Object.keys($microEventDefs)>> <<set _spKeys = Object.keys($smallExplorePointDefs || {})>> /* ── 小探索点:从原微型事件池派生的专用池中强制发现一个合格点位 ── */ <<set _smallPointId = "">> <<set _smallPointPool = []>><<set _smallPointTotalW = 0>> <<for _spi = 0; _spi < _spKeys.length; _spi++>> <<set _spId = _spKeys[_spi]>><<set _spd = $smallExplorePointDefs[_spId]>> <<if _spd.terrain && _spd.depthRange>> <<set _spTerrainOK = _spd.terrain.indexOf($maptype) >= 0>> <<set _spDepthOK = ($depth >= _spd.depthRange[0] && $depth <= _spd.depthRange[1])>> <<if _spTerrainOK && _spDepthOK>> <<set _spW = Number(typeof _spd.smallExplorePoint === "object" ? _spd.smallExplorePoint.weight : _spd.weight)>><<if !isFinite(_spW)>><<set _spW = 0>><</if>> <<if _spW > 0>><<set _smallPointPool[_smallPointPool.length] = {id:_spId,weight:_spW}>><<set _smallPointTotalW += _spW>><</if>> <</if>> <</if>> <</for>> <<if _smallPointPool.length > 0 && _maxItems > 0>> <<set _spRoll = Math.random() * _smallPointTotalW>> <<set _spCum = 0>> <<for _spi = 0; _spi < _smallPointPool.length; _spi++>> <<set _spCum += _smallPointPool[_spi].weight>> <<if !_smallPointId && _spRoll < _spCum>><<set _smallPointId = _smallPointPool[_spi].id>><<break>><</if>> <</for>> <<if _smallPointId>><<set $activeHuntItems[$activeHuntItems.length] = _smallPointId>><</if>> <</if>> /* 先收集满足条件的 hunt 类 ID */ <<set _huntPool = []>> <<for _mi = 0; _mi < _mKeys.length; _mi++>> <<set _md = $microEventDefs[_mKeys[_mi]]>> <<if _md.subtype !== "hunt" || _mKeys[_mi] === _smallPointId>><<continue>><</if>> /* 地形 + 深度过滤 */ <<set _tOK = false>> <<for _ti = 0; _ti < _md.terrain.length; _ti++>> <<if _md.terrain[_ti] === $maptype>><<set _tOK = true>><<break>><</if>> <</for>> <<if _tOK && $depth >= _md.depthRange[0] && $depth <= _md.depthRange[1]>> <<set _huntPool[_huntPool.length] = _mKeys[_mi]>> <</if>> <</for>> /* 乱序后按概率×丰富度取最多 _slots 条 hunt */ <<for _si = _huntPool.length - 1; _si > 0; _si-->> <<set _sj = Math.floor(Math.random() * (_si + 1))>> <<set _stmp = _huntPool[_si]>><<set _huntPool[_si] = _huntPool[_sj]>><<set _huntPool[_sj] = _stmp>> <</for>> <<for _hi = 0; _hi < _huntPool.length && $activeHuntItems.length < _maxItems; _hi++>> <<set _hd = $microEventDefs[_huntPool[_hi]]>> <<if Math.random() < _hd.baseChance * _richFactor>> <<set $activeHuntItems[$activeHuntItems.length] = _huntPool[_hi]>> <</if>> <</for>> /* 若还有空槽,补充 explore 类 */ <<if $activeHuntItems.length < _maxItems>> <<set _expPool = []>> <<for _mi = 0; _mi < _mKeys.length; _mi++>> <<set _md = $microEventDefs[_mKeys[_mi]]>> <<if _md.subtype !== "explore" || _md.smallExplorePoint>><<continue>><</if>> <<set _tOK = false>> <<for _ti = 0; _ti < _md.terrain.length; _ti++>> <<if _md.terrain[_ti] === $maptype>><<set _tOK = true>><<break>><</if>> <</for>> <<if _tOK && $depth >= _md.depthRange[0] && $depth <= _md.depthRange[1]>> <<set _expPool[_expPool.length] = _mKeys[_mi]>> <</if>> <</for>> <<for _si = _expPool.length - 1; _si > 0; _si-->> <<set _sj = Math.floor(Math.random() * (_si + 1))>> <<set _stmp = _expPool[_si]>><<set _expPool[_si] = _expPool[_sj]>><<set _expPool[_sj] = _stmp>> <</for>> <<for _ei = 0; _ei < _expPool.length && $activeHuntItems.length < _maxItems; _ei++>> <<set _ed = $microEventDefs[_expPool[_ei]]>> <<if Math.random() < _ed.baseChance>> <<set $activeHuntItems[$activeHuntItems.length] = _expPool[_ei]>> <</if>> <</for>> <</if>> /* ── 持久效果检查 ── */ <<checkEnvEffects>> /* ── 触发小型事件(spawnSmallEvent 调度,6% 门控,概率×15) ── */ <<if !$activeSmallEvent && Math.random() < 0.06>> <<spawnSmallEvent "anchored" 15>> <<if $pendingEvent>> <<set $activeSmallEvent = $pendingEvent>> <<set $pendingEvent = null>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "finditem">> <<set _fi_container = $args[0]>> <<set _fi_itemId = $args[1]>> <<set _foundItem = null>> <<set _foundCategory = "">> <<set _fi_categories = Object.keys(_fi_container)>> <<for _fi_i = 0; _fi_i < _fi_categories.length; _fi_i++>> <<set _fi_cat = _fi_categories[_fi_i]>> <<set _fi_val = _fi_container[_fi_cat]>> /* 渔获是嵌套对象,需要再遍历一层 */ <<if _fi_cat === "渔获" && typeof _fi_val === "object" && !Array.isArray(_fi_val)>> <<set _fi_subs = Object.keys(_fi_val)>> <<for _fi_j = 0; _fi_j < _fi_subs.length; _fi_j++>> <<set _fi_sub = _fi_subs[_fi_j]>> <<set _fi_arr = _fi_val[_fi_sub]>> <<if Array.isArray(_fi_arr)>> <<set _fi_match = _fi_arr.find(x => x.id === _fi_itemId)>> <<if _fi_match>> <<set _foundItem = _fi_match>> <<set _foundCategory = "渔获." + _fi_sub>> <<break>> <</if>> <</if>> <</for>> <<elseif Array.isArray(_fi_val)>> <<set _fi_match = _fi_val.find(x => x.id === _fi_itemId)>> <<if _fi_match>> <<set _foundItem = _fi_match>> <<set _foundCategory = _fi_cat>> <<break>> <</if>> <</if>> <<if _foundItem !== null>> <<break>> <</if>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "fish">> <<set _catchResult = "">> <<set _catchItem = "">> <<if !$fishingConfig>> <<set _catchResult = "系统错误:fishingConfig 未定义">> <<set $lastCatchText = _catchResult>> <</if>> <<if !$lightCondition>> <<set $lightCondition = "朦胧">> <!--- 设置默认值 ---> <</if>> /* === 环境权重计算 === */ <<set _totalWeightMultiplier = 1>> /* 1. 水深权重 */ <<set _depthKey = "">> <<if $depth <= 50>> <<set _depthKey = "0-50">> <<elseif $depth <= 150>> <<set _depthKey = "50-150">> <<elseif $depth <= 300>> <<set _depthKey = "150-300">> <<elseif $depth <= 1000>> <<set _depthKey = "300-1000">> <<else>> <<set _depthKey = "1000+">> <</if>> /* 2. 地形权重 */ <<set _terrainKey = "">> <<if $depthdeep - $depth <= 20>> <<set _terrainKey = "底栖">> <<elseif $maptype == "sand">> <<set _terrainKey = "沙海床">> <<elseif $maptype == "flat">> <<set _terrainKey = "岩海床">> <<elseif $maptype == "cliff">> <<set _terrainKey = "峭壁">> <<elseif $maptype == "grass">> <<set _terrainKey = "海草床">> <<elseif $maptype == "reef">> <<set _terrainKey = "珊瑚礁">> <<elseif $maptype == "forest">> <<set _terrainKey = "海藻森林">> <<else>> <<set _terrainKey = "开阔水域">> <</if>> /* 3. 温度权重 */ <<set _tempWeight = 1>> <<if $worldtem >= 18 && $worldtem <= 26>> <<set _tempWeight = 1.2>> <!--- 最佳温度区间 ---> <<elseif $worldtem >= 14 && $worldtem < 18>> <<set _tempWeight = 0.9>> <<elseif $worldtem > 26 && $worldtem <= 30>> <<set _tempWeight = 0.9>> <<elseif $worldtem >= 10 && $worldtem < 14>> <<set _tempWeight = 0.7>> <<elseif $worldtem > 30 && $worldtem <= 34>> <<set _tempWeight = 0.7>> <<else>> <<set _tempWeight = 0.4>> <!--- 极端温度 ---> <</if>> <<set _totalWeightMultiplier = _totalWeightMultiplier * _tempWeight>> /* === 渔获池筛选 === */ <<set _fishingPool = []>> <<if $pools>> <<set _itemKeys = Object.keys($pools)>> <<for _i = 0; _i < _itemKeys.length; _i++>> <<set _itemKey = _itemKeys[_i]>> <<set _item = $pools[_itemKey]>> <<if !_item.tags>> <<set _item.tags = []>> <</if>> <<set _fishingPool.push(_itemKey)>> <</for>> <</if>> <<set _baseChance = 3>> <<if random(1, 100) <= _baseChance and _fishingPool.length > 0>> <<set _weightedPool = []>> <<set _totalWeight = 0>> <<for _i = 0; _i < _fishingPool.length; _i++>> <<set _itemKey = _fishingPool[_i]>> <<set _item = $pools[_itemKey]>> <<set _weight = _item.baseWeight>> /* 1. 水深权重计算 */ <<set _depthMultiplier = 1>> <<if _item.customWeights && _item.customWeights.depth && _item.customWeights.depth[_depthKey]>> /* 使用物种专属水深权重 */ <<set _depthMultiplier = _item.customWeights.depth[_depthKey]>> <<elseif $fishingConfig.depthWeights && $fishingConfig.depthWeights[_depthKey]>> /* Fallback: 使用通用水深权重 */ <<set _depthTags = ["浅层", "中层", "深层"]>> <<set _bestDepthWeight = 0.1>> <<for _j = 0; _j < _item.tags.length; _j++>> <<set _tag = _item.tags[_j]>> <<if _depthTags.includes(_tag) && $fishingConfig.depthWeights[_depthKey][_tag] > _bestDepthWeight>> <<set _bestDepthWeight = $fishingConfig.depthWeights[_depthKey][_tag]>> <</if>> <</for>> <<set _depthMultiplier = _bestDepthWeight>> <</if>> <<set _weight = _weight * _depthMultiplier>> /* 2. 地形权重计算 */ <<set _terrainMultiplier = 1>> <<if _item.customWeights && _item.customWeights.terrain && _item.customWeights.terrain[_terrainKey]>> /* 使用物种专属地形权重 */ <<set _terrainMultiplier = _item.customWeights.terrain[_terrainKey]>> <<elseif $fishingConfig.terrainWeights && $fishingConfig.terrainWeights[_terrainKey]>> /* Fallback: 使用通用地形权重 */ <<set _terrainTags = ["开阔水域", "沙海床", "岩海床", "珊瑚礁", "海草床", "海藻森林", "峭壁", "底栖"]>> <<set _bestTerrainWeight = 0.1>> <<for _j = 0; _j < _item.tags.length; _j++>> <<set _tag = _item.tags[_j]>> <<if _terrainTags.includes(_tag) && $fishingConfig.terrainWeights[_terrainKey][_tag] > _bestTerrainWeight>> <<set _bestTerrainWeight = $fishingConfig.terrainWeights[_terrainKey][_tag]>> <</if>> <</for>> <<set _terrainMultiplier = _bestTerrainWeight>> <</if>> <<set _weight = _weight * _terrainMultiplier>> /* 3. 光照权重计算 */ <<set _lightMultiplier = 1>> <<if _item.customWeights && _item.customWeights.light && _item.customWeights.light[_lightLevel]>> /* 使用物种专属光照权重 */ <<set _lightMultiplier = _item.customWeights.light[_lightLevel]>> <<elseif $fishingConfig.lightWeights && $fishingConfig.lightWeights[_lightLevel]>> /* Fallback: 使用通用光照权重 + 行为标签叠加 */ <<set _behaviorMultiplier = 1>> <<set _behaviorTags = ["日行性", "夜行性", "趋光性", "群居", "洄游性"]>> <<for _j = 0; _j < _item.tags.length; _j++>> <<set _tag = _item.tags[_j]>> <<if _behaviorTags.includes(_tag) && $fishingConfig.lightWeights[_lightLevel][_tag]>> <<set _behaviorMultiplier = _behaviorMultiplier * $fishingConfig.lightWeights[_lightLevel][_tag]>> <</if>> <</for>> <<set _lightMultiplier = _behaviorMultiplier>> <</if>> <<set _weight = _weight * _lightMultiplier>> /* 4. 温度权重(保持不变) */ <<set _weight = _weight * _tempWeight>> /* 5. 灯光加成(保持不变) */ <<if $fishingLight == "开启">> <<for _j = 0; _j < _item.tags.length; _j++>> <<set _tag = _item.tags[_j]>> <<if $fishingConfig.lightBonus && $fishingConfig.lightBonus[_tag]>> <<set _weight = _weight * $fishingConfig.lightBonus[_tag]>> <</if>> <</for>> <</if>> /* 6. 渔具匹配(保持不变) */ <<set _gearTags = $fishingConfig.gearTags ? $fishingConfig.gearTags[$fishingGear] : null>> <<if _gearTags>> <<for _j = 0; _j < _gearTags.length; _j++>> <<set _gearTag = _gearTags[_j]>> <<if _item.tags.includes(_gearTag)>> <<set _weight = _weight * 1.5>> <</if>> <</for>> <</if>> /* 6b. 渔具专属过滤 */ <<if $fishingGear === "垂钓">> <<set _hookDef = State.variables.items[_itemKey]>> <<if _hookDef && _hookDef.subtype === "鱼类">> <<elseif _hookDef && (_hookDef.subtype === "藻类" || _hookDef.subtype === "其他")>> <<set _weight = _weight * 0.05>> <<else>> <<set _weight = 0>> <</if>> <<elseif $fishingGear === "渔网">> <<set _netDef = State.variables.items[_itemKey]>> <<if _netDef && (_netDef.subtype === "贝类" || (_netDef.tags && _netDef.tags.includes("底栖")))>> <<if $depthdeep - $depth > 100>> <<set _weight = 0>> <</if>> <</if>> <</if>> /* 7. 鱼饵匹配(保持不变) */ <<set _baitTags = $fishingConfig.baitTags ? $fishingConfig.baitTags[$fishingBait] : null>> <<if _baitTags>> <<for _j = 0; _j < _baitTags.length; _j++>> <<set _baitTag = _baitTags[_j]>> <<if _item.tags.includes(_baitTag)>> <<set _weight = _weight * 2.0>> <</if>> <</for>> <</if>> /* 只有权重大于0的鱼种才加入池子 */ <<if _weight > 0>> <<set _weightedPool.push({key: _itemKey, weight: _weight})>> <<set _totalWeight = _totalWeight + _weight>> <</if>> <</for>> /* 按权重随机选择 */ <<if _totalWeight > 0>> <<set _randomWeight = random(0, _totalWeight)>> <<set _currentSum = 0>> <<for _i = 0; _i < _weightedPool.length; _i++>> <<set _weightedItem = _weightedPool[_i]>> <<set _currentSum = _currentSum + _weightedItem.weight>> <<if _randomWeight <= _currentSum>> <<set _catchItem = _weightedItem.key>> <<break>> <</if>> <</for>> <<set _caughtItem = $pools[_catchItem]>> <<set _catchResult = "收获!捕获了:" + _caughtItem.name>> <<additem _catchItem 1>> <<if $cps && $cps.viona && $cps.viona.recentEvents>> <<set $cps.viona.recentEvents.catch = {tag:"caught_fish",product:_caughtItem.name,day:$day,expire:$day + 1}>> <</if>> <</if>> <</if>> /* 如果没有捕获任何东西 */ <<if !_catchItem>> <<set _waitingTexts = ["水波轻轻晃动...", "似乎有影子游过...", "继续等待中..."]>> <<set _catchResult = _waitingTexts[random(0, _waitingTexts.length - 1)]>> <</if>> /* 设置结果 */ <<set $lastCatchText = _catchResult>> <</widget>> <</nobr>>
<<nobr>> <<widget "fishStatus">> <<set _fs_depthKey = "0-50">> <<if $depth <= 50>> <<set _fs_depthKey = "0-50">> <<elseif $depth <= 150>> <<set _fs_depthKey = "50-150">> <<elseif $depth <= 300>> <<set _fs_depthKey = "150-300">> <<elseif $depth <= 1000>> <<set _fs_depthKey = "300-1000">> <<else>> <<set _fs_depthKey = "1000+">> <</if>> <<set _fs_terrainKey = "开阔水域">> <<if $depthdeep - $depth <= 20>> <<set _fs_terrainKey = "底栖">> <<elseif $maptype === "sand">> <<set _fs_terrainKey = "沙海床">> <<elseif $maptype === "flat">> <<set _fs_terrainKey = "岩海床">> <<elseif $maptype === "cliff">> <<set _fs_terrainKey = "峭壁">> <<elseif $maptype === "grass">> <<set _fs_terrainKey = "海草床">> <<elseif $maptype === "reef">> <<set _fs_terrainKey = "珊瑚礁">> <<elseif $maptype === "forest">> <<set _fs_terrainKey = "海藻森林">> <</if>> <<set _fs_totalWeight = 0>> <<set _fs_topSpecies = []>> <<if $pools>> <<set _fs_keys = Object.keys($pools)>> <<for _fi = 0; _fi < _fs_keys.length; _fi++>> <<set _fs_sp = $pools[_fs_keys[_fi]]>> <<set _fs_w = Number(_fs_sp.baseWeight) || 1>> <<if _fs_sp.customWeights && _fs_sp.customWeights.depth>> <<set _fs_dm = _fs_sp.customWeights.depth[_fs_depthKey]>> <<if _fs_dm !== undefined>> <<set _fs_w *= Number(_fs_dm)>> <</if>> <</if>> <<if _fs_sp.customWeights && _fs_sp.customWeights.terrain>> <<set _fs_tm = _fs_sp.customWeights.terrain[_fs_terrainKey]>> <<if _fs_tm !== undefined>> <<set _fs_w *= Number(_fs_tm)>> <</if>> <</if>> <<if _fs_w > 0>> <<set _fs_totalWeight += _fs_w>> <<if _fs_w >= 5>> <<run _fs_topSpecies.push({ name: _fs_sp.name, weight: _fs_w, tags: (_fs_sp.tags || []) })>> <</if>> <</if>> <</for>> <</if>> /* ── 渔具状态描述 ── */ <<set _fs_gearDesc = "">> <<if $fishingGear === "渔网">> <<if _fs_terrainKey === "沙海床" || _fs_terrainKey === "底栖">> <<set _fs_gearDesc = "渔网沿海底拖行,卷起一团灰白色的沙尘,细小的生物随沉积物一同涌入网口。">> <<elseif _fs_terrainKey === "珊瑚礁">> <<set _fs_gearDesc = "渔网在礁盘间穿行,网绳与珊瑚枝桠轻轻碰擦,发出低沉的摩擦声。">> <<elseif _fs_terrainKey === "海草床">> <<set _fs_gearDesc = "渔网穿过密集的海草丛,叶片被网绳拂过,偶尔有小型生物慌乱地从网眼逃脱。">> <<elseif _fs_terrainKey === "岩海床">> <<set _fs_gearDesc = "渔网在岩面上磕磕绊绊地前行,石块碰撞的震动沿绳索传回船内。">> <<elseif _fs_terrainKey === "峭壁">> <<set _fs_gearDesc = "渔网悬于峭壁旁侧,随洋流起伏,壁面上附着的生物对它保持着警惕的距离。">> <<elseif _fs_terrainKey === "海藻森林">> <<set _fs_gearDesc = "渔网在巨藻林中铺展,大片藻叶缓慢飘过网面,辨别猎物的难度大幅上升。">> <<elseif $depth <= 50>> <<set _fs_gearDesc = "渔网在浅水中张开,能隐约看见网影下方涌动的鱼群轮廓。">> <<else>> <<set _fs_gearDesc = "渔网在深水中静静展开,四周一片漆黑,只有触碰网绳的生物才会引发细微震动。">> <</if>> <<else>> <<if $fishingBait === "内脏碎肉">> <<set _fs_gearDesc = "鱼线末端挂着腥气四溢的内脏碎肉,腥味在水中缓慢扩散。">> <<elseif $fishingBait === "血饵">> <<set _fs_gearDesc = "血饵在水中晕开暗红丝缕,随洋流向远处蔓延,嗅觉敏锐的猎手也许正在循迹而来。">> <<elseif $fishingBait === "草饵">> <<set _fs_gearDesc = "草饵静静悬在水中,颜色与周围植被相近,适合诱引藻类间觅食的草食性鱼类。">> <<else>> <<set _fs_gearDesc = "鱼钩空悬于水中,好奇的小鱼靠近嗅探后迅速游走。">> <</if>> <<if $fishingLight === "开启">> <<set _fs_gearDesc += "潜艇灯光在黑暗中晕开昏黄,趋光性生物正朝这里聚集。">> <</if>> <</if>> /* ── 生物密度描述 ── */ <<set _fs_spCount = $pools ? Math.max(Object.keys($pools).length, 1) : 1>> <<set _fs_avgW = _fs_totalWeight / _fs_spCount>> <<set _fs_density = "">> <<if _fs_avgW >= 6>> <<set _fs_density = "这片水域生机盎然——">> <<elseif _fs_avgW >= 3.5>> <<set _fs_density = "水中偶有生物的轮廓掠过——">> <<elseif _fs_avgW >= 1.5>> <<set _fs_density = "周围相当平静,偶尔才能捕捉到一丝生命的迹象——">> <<else>> <<set _fs_density = "这里如同死寂,水压将所有声音都压得沉默——">> <</if>> /* ── 标志性生物描述 ── */ <<set _fs_spDesc = "">> <<if _fs_topSpecies.length > 0>> <<set _fs_mi = Math.floor(Math.random() * _fs_topSpecies.length)>> <<set _fs_msp = _fs_topSpecies[_fs_mi]>> <<set _fs_beh = "在附近游弋。">> <<if _fs_msp.tags.includes("群居")>> <<set _fs_beh = "成群穿越视野,留下短暂的涡流。">> <<elseif _fs_msp.tags.includes("底栖")>> <<set _fs_beh = "紧贴海床缓慢移动,几乎与沉积物融为一体。">> <<elseif _fs_msp.tags.includes("掠食性") || _fs_msp.tags.includes("肉食性")>> <<set _fs_beh = "大幅度巡游,保持着掠食者特有的警觉与从容。">> <<elseif _fs_msp.tags.includes("趋光性") && $fishingLight === "开启">> <<set _fs_beh = "被灯光吸引,在光晕边缘徘徊。">> <<elseif _fs_msp.tags.includes("夜行性") && ($showhour >= 20 || $showhour <= 5)>> <<set _fs_beh = "趁着黑暗悄悄活跃,动作格外敏锐。">> <</if>> <<set _fs_spDesc = _fs_msp.name + _fs_beh>> <<if _fs_topSpecies.length >= 2 && Math.random() < 0.35>> <<set _fs_si2 = (_fs_mi + 1 + Math.floor(Math.random() * (_fs_topSpecies.length - 1))) % _fs_topSpecies.length>> <<set _fs_sp2 = _fs_topSpecies[_fs_si2]>> <<set _fs_spDesc += "远处还有" + _fs_sp2.name + "的身影一闪而过。">> <</if>> <<else>> <<set _fs_spDesc = "没有任何已知生物的踪迹。">> <</if>> <div class="fish-status"><div class="fish-status-gear"></div><div class="fish-status-density"><<print _fs_density>><<print _fs_gearDesc>></div></div> <</widget>> <</nobr>>
<<nobr>> <<widget "freshnessTag">> /* args[0] = entry(含 id, addedDay, stage) 输出一个带颜色的鲜度标签 */ <<set _ft_e = $args[0]>> <<if !_ft_e || !_ft_e.addedDay>> /* 无腐败记录,不显示标签 */ <<else>> <<set _ft_sd = $spoilDays ? ($spoilDays[_ft_e.id] || 0) : 0>> <<if _ft_sd > 0>> <<set _ft_age = $day - _ft_e.addedDay>> <<set _ft_stage = Math.floor(_ft_age / _ft_sd * 3)>> <<if _ft_stage <= 0>> <span style="color:#8bc4a0;font-size:0.68rem;margin-left:0.2rem;">新鲜</span> <<elseif _ft_stage === 1>> <span style="color:var(--amber);font-size:0.68rem;margin-left:0.2rem;">轻微变质</span> <<elseif _ft_stage === 2>> <span style="color:var(--danger-bright);font-size:0.68rem;margin-left:0.2rem;">⚠腐败</span> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "fuelDefs">> <<set $fuelDefs = {coal:15, wood:8, oil:40, fish_oil:12, algae_block:5, mineral_fuel:80}>> <</widget>> /* addFuel id [qty|"all"] qty 省略=1,"all"=全部可用数量 */ <<widget "addFuel">> <<set _afId = $args[0]>> <<set _afQArg = $args[1]>> <<if !$fuelDefs>><<fuelDefs>><</if>> <<set _afVal = $fuelDefs[_afId]>> <<if !_afVal>> <<set $lastFuelText = "无法使用该物品作为燃料。">> <<else>> /* 统计可用总量 */ <<set _afType = ($items[_afId] ? $items[_afId].type : "")>> <<set _afAvail = 0>> <<if _afType && $store[_afType]>> <<for _afi = 0; _afi < $store[_afType].length; _afi++>> <<if $store[_afType][_afi].id === _afId>><<set _afAvail += $store[_afType][_afi].quantity>><</if>> <</for>> <</if>> <<if _afType && $backpack[_afType]>> <<for _afi = 0; _afi < $backpack[_afType].length; _afi++>> <<if $backpack[_afType][_afi].id === _afId>><<set _afAvail += $backpack[_afType][_afi].quantity>><</if>> <</for>> <</if>> /* 确定本次加入数量 */ <<set _afNeed = (_afQArg === "all") ? _afAvail : (Number(_afQArg) > 0 ? Number(_afQArg) : 1)>> /* 可加燃料上限:不超过槽位剩余 */ <<set _afFuelSpace = $fuelMax - $fuel>> <<set _afMaxByFuel = (_afVal > 0) ? Math.ceil(_afFuelSpace / _afVal) : 0>> <<set _afUse = Math.min(_afNeed, _afAvail, _afMaxByFuel)>> <<if _afUse <= 0>> <<set $lastFuelText = "燃料槽已满或无可用物品。">> <<else>> /* 从 store 扣除,不足再扣 backpack */ <<set _afToUse = _afUse>> <<if _afType && $store[_afType]>> <<for _afi = 0; _afi < $store[_afType].length; _afi++>> <<if $store[_afType][_afi].id === _afId && _afToUse > 0>> <<set _afTake = Math.min($store[_afType][_afi].quantity, _afToUse)>> <<set $store[_afType][_afi].quantity -= _afTake>> <<set _afToUse -= _afTake>> <</if>> <</for>> <</if>> <<if _afToUse > 0 && _afType && $backpack[_afType]>> <<for _afi = 0; _afi < $backpack[_afType].length; _afi++>> <<if $backpack[_afType][_afi].id === _afId && _afToUse > 0>> <<set _afTake = Math.min($backpack[_afType][_afi].quantity, _afToUse)>> <<set $backpack[_afType][_afi].quantity -= _afTake>> <<set _afToUse -= _afTake>> <</if>> <</for>> <</if>> <<set _afActual = _afUse - _afToUse>> <<set $fuel = Math.min($fuelMax, $fuel + _afActual * _afVal)>> <<set _afName = ($items[_afId] ? $items[_afId].name : _afId)>> <<set $lastFuelText = _afName + "×" + _afActual + " → +" + (_afActual * _afVal) + "(当前:" + Math.floor($fuel) + "/" + $fuelMax + ")">> <<if $driftMode && $fuel > 5>><<set $driftMode = false>><</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "locationTrigger">> /* ═══════════════════════════════════════════════ 地点触发检查(三段式状态机) 在 sail widget 的每一步航行后调用 状态流转: distant → approaching → arrived → (玩家锚定+进入) → leaving → done 距离参数(原始值 / 可见坐标): approachRange 默认 300 / 6 spanLength 默认 400 / 8 distant: $map < mapAt - approachRange approaching: mapAt - approachRange ≤ $map < mapAt,持续显示接近提示 arrived: mapAt ≤ $map ≤ mapAt + spanLength,且深度匹配,停船 玩家锚定后进入探索页面,选择进入 leaving: 玩家从场景离开,恢复航行 done: $map > mapAt + spanLength + approachRange,归档 守卫:LargeScene 活跃时暂停 Location 检查 ═══════════════════════════════════════════════ */ /* LargeScene 活跃时暂停 Location 触发 */ <<if $largeScene && typeof $largeScene === "object" && $largeScene.state !== "done">> /* 不做任何事,让 LargeScene 状态机独占 */ <<elseif $activeLocations && $activeLocations.length > 0>> <<for _li = 0; _li < $activeLocations.length; _li++>> <<set _loc = $activeLocations[_li]>> /* 已经完成的跳过 */ <<if _loc.state === "done">> <<continue>> <</if>> <<set _approachRange = _loc.approachRange || 300>> <<set _spanLen = _loc.spanLength || 400>> /* ══ state: distant → approaching ══ */ <<if !_loc.state || _loc.state === "distant">> <<if $map >= _loc.mapAt - _approachRange>> <<set $activeLocations[_li].state = "approaching">> /* 自动刹车:开关开启时减速到 20 */ <<if $autoBrake && $sailspd > 20>> <<set $sailspd = 20>> <</if>> <</if>> /* ══ state: approaching → arrived ══ */ <<elseif _loc.state === "approaching">> /* 检查是否到达触发位置 */ <<if $map >= _loc.mapAt>> /* 位置到了,检查深度窗口 */ <<set _dw = _loc.depthWindow>> <<set _inWindow = false>> <<if _dw === "surface">> <<if $depth <= 5>> <<set _inWindow = true>> <</if>> <<elseif _dw === "seabed">> <<if $depthdeep - $depth <= 10>> <<set _inWindow = true>> <</if>> <<elseif typeof _dw === "object" && _dw.mid>> <<set _tolerance = _dw.tolerance || 30>> <<if Math.abs($depth - _dw.mid) <= _tolerance>> <<set _inWindow = true>> <</if>> <<else>> /* "mid" 或其他:默认总是满足 */ <<set _inWindow = true>> <</if>> <<if _inWindow>> /* 到达!标记状态,停船。不自动跳转。 玩家需要锚定后进入探索页面,再选择进入。 */ <<set $activeLocations[_li].state = "arrived">> <<set $activeLocations[_li].triggered = true>> <<if $cps && $cps.viona && $cps.viona.recentEvents>> <<set $cps.viona.recentEvents.destination = {tag:"arrived",target:(_loc.name || _loc.id),targetId:_loc.id,day:$day,expire:$day + 1}>> <</if>> <<set $sailspd = 0>> <</if>> /* 深度不匹配时不跳转,位置提示条会自动显示引导 */ <</if>> /* ══ state: arrived(等待玩家进入) ══ */ <<elseif _loc.state === "arrived">> /* 玩家未进入场景就开走了:驶出 spanLength + approachRange 则自动归档 */ <<if $map >= _loc.mapAt + _spanLen + _approachRange>> <<set $activeLocations[_li].state = "done">> <</if>> /* ══ state: leaving → done ══ */ <<elseif _loc.state === "leaving">> /* 玩家已从场景离开,继续航行直到超出范围 */ <<if $map >= _loc.mapAt + _spanLen + _approachRange>> <<set $activeLocations[_li].state = "done">> <</if>> <</if>> <</for>> <</if>> <</widget>> <</nobr>>
<<nobr>> /* ═══════════════════════════════════════════════ 地图区间预留与 C 类中型调度 所有需要持续存在的地图事件使用同一张 $mapReservations: - A-zone / B-C 中型:预留接近 + 主体 + 离开完整区间 - 小型:可声明 mapSpan;当前由触发器在运行时建立持续窗口 - 地点:在生成时调用同一预留器 container 类型仅作记录,不阻挡其内部 A-zone / B-C 插入场景。 ═══════════════════════════════════════════════ */ <<widget "reserveMapInterval">> <<set _mriStart = Math.max(0, Number($args[0]) || 0)>> <<set _mriEnd = Math.min($maplim, Number($args[1]) || 0)>> <<set _mriKind = String($args[2] || "scene")>> <<set _mriId = String($args[3] || "unknown")>> <<set _mriContainer = !!$args[4]>> <<set $mapReserveOK = (_mriEnd > _mriStart)>> <<if !$mapReservations>><<set $mapReservations = []>><</if>> <<for _mriI = 0; _mriI < $mapReservations.length; _mriI++>> <<set _mriOld = $mapReservations[_mriI]>> <<if !_mriOld.container && !_mriContainer && _mriStart < _mriOld.end && _mriEnd > _mriOld.start>> <<set $mapReserveOK = false>> <<break>> <</if>> <</for>> <<if $mapReserveOK>> <<run $mapReservations.push({start:_mriStart,end:_mriEnd,kind:_mriKind,id:_mriId,container:_mriContainer})>> <</if>> <</widget>> /* ── 将小型定义实例化为可持续地图事件。mapSpan 可按定义覆盖默认接近/主体/离开长度。 ── */ <<widget "makeSmallSceneInstance">> <<smallEventTable>> <<set _msId = String($args[0] || "")>><<set _msDef = $smallEventDefs[_msId]>><<set $smallSceneInstance = null>> <<if _msDef && _msDef.stages && _msDef.stages.length > 0>> <<set _msSpan = _msDef.mapSpan || {approach:(_msDef.approachRange || 300),active:(_msDef.spanLength || 400),leave:(_msDef.approachRange || 300)}>> <<set _msApproach = Number(_msSpan.approach) || 0>><<set _msActive = Number(_msSpan.active) || Number(_msDef.spanLength) || 400>><<set _msLeave = Number(_msSpan.leave) || 0>> <<set _msStart = $map>><<set _msEnd = _msStart + _msActive>><<reserveMapInterval _msStart-_msApproach _msEnd+_msLeave "small" _msId false>> <<if $mapReserveOK>> <<set _msRegion = ($largeScene && typeof $largeScene === "object") ? String($largeScene.id || "") : "">><<set _msVariant = (_msDef.regionVariants && _msRegion && _msDef.regionVariants[_msRegion]) ? _msDef.regionVariants[_msRegion] : null>> <<set _msName = (_msVariant && _msVariant.name) ? _msVariant.name : _msDef.name>><<set _msDesc = (_msVariant && _msVariant.desc) ? _msVariant.desc : _msDef.stages[0].desc>> <<set $smallSceneInstance = {id:_msId,name:_msName,stageIdx:0,stageDesc:_msDesc,actions:_msDef.stages[0].actions,lootLog:"",state:"inside",mapStart:_msStart,mapEnd:_msEnd,leaveEnd:_msEnd+_msLeave,approachAt:_msStart-_msApproach,regionVariant:(_msVariant ? _msRegion : "")}>> <</if>> <</if>> <</widget>> /* ── 统一调度:当前先接入 C 类中型(鲸落);B/C 完整池完成后扩展候选即可。 ── */ <<widget "spawnTierMiddleScene">> <<worldSceneDefs>> <<set _tmsCands = []>><<set _tmsKeys = Object.keys($wsDefs)>> <<set _tmsRegion = ($largeScene && typeof $largeScene === "object") ? String($largeScene.id || "") : "">> <<set _tmsTierBase = ($largeScene && typeof $largeScene === "object" && $largeScene.state !== "done") ? 0.5 : 4>> <<for _tmsI = 0; _tmsI < _tmsKeys.length; _tmsI++>> <<set _tmsId = _tmsKeys[_tmsI]>><<set _tmsDef = $wsDefs[_tmsId]>> <<set _tmsTerrainOK = (!_tmsDef.terrain || _tmsDef.terrain.length === 0 || _tmsDef.terrain.indexOf($maptype) >= 0)>> <<if !_tmsDef.devOnly && _tmsDef.sceneType === "middle" && String(_tmsDef.tier || "").toUpperCase() === "C" && _tmsTerrainOK>> <<set _tmsWeight = Number(_tmsDef.weight) || 1>> <<set _tmsVariant = (_tmsDef.regionVariants && _tmsRegion && _tmsDef.regionVariants[_tmsRegion]) ? _tmsDef.regionVariants[_tmsRegion] : null>> <<if _tmsVariant && _tmsVariant.weightMultiplier>><<set _tmsWeight *= Number(_tmsVariant.weightMultiplier)>><</if>> <<set _tmsCands[_tmsCands.length] = {id:_tmsId,weight:_tmsWeight,variant:_tmsVariant}>><</if>> <</for>> <<if _tmsCands.length > 0>> /* 低频中型门槛:大型区域内沿 C tier 的 0.5 权重压低出现率。 */ <<set _tmsChance = 0.01 * _tmsTierBase>> <<if Math.random() < _tmsChance>> <<set _tmsTotal = 0>><<for _tmsI = 0; _tmsI < _tmsCands.length; _tmsI++>><<set _tmsTotal += _tmsCands[_tmsI].weight>><</for>> <<set _tmsRoll = Math.random() * _tmsTotal>><<set _tmsCum = 0>><<set _tmsPick = _tmsCands[_tmsCands.length - 1]>> <<for _tmsI = 0; _tmsI < _tmsCands.length; _tmsI++>><<set _tmsCum += _tmsCands[_tmsI].weight>><<if _tmsRoll < _tmsCum>><<set _tmsPick = _tmsCands[_tmsI]>><<break>><</if>><</for>> <<set _tmsDef = $wsDefs[_tmsPick.id]>><<set _tmsSpan = _tmsDef.mapSpan || {approach:1000,activeMin:1000,activeMax:1000,leave:1000}>> <<set _tmsApproach = Number(_tmsSpan.approach) || 0>><<set _tmsActive = (Number(_tmsSpan.activeMin) || Number(_tmsDef.spanMin) || 1000) + Math.floor(Math.random() * Math.max(1, (Number(_tmsSpan.activeMax) || Number(_tmsDef.spanMax) || 1000) - (Number(_tmsSpan.activeMin) || Number(_tmsDef.spanMin) || 1000) + 1))>><<set _tmsLeave = Number(_tmsSpan.leave) || 0>> <<set _tmsMin = ($largeScene && $largeScene.state !== "done") ? $largeScene.approachEnd + 500 : 5000>> <<set _tmsMax = ($largeScene && $largeScene.state !== "done") ? $largeScene.activeEnd - 500 - _tmsActive : $maplim - 5000 - _tmsActive>> <<set _tmsPlaced = false>> <<for _tmsTry = 0; _tmsTry < 40 && !_tmsPlaced && _tmsMax > _tmsMin; _tmsTry++>> <<set _tmsStart = _tmsMin + Math.floor(Math.random() * (_tmsMax - _tmsMin + 1))>><<set _tmsEnd = _tmsStart + _tmsActive>><<reserveMapInterval _tmsStart - _tmsApproach _tmsEnd + _tmsLeave "tier_middle" _tmsPick.id false>> <<if $mapReserveOK>> <<set _tmsV = _tmsPick.variant>> <<set _tmsVariantName = (_tmsV && _tmsV.name) ? _tmsV.name : "">> <<if _tmsV && _tmsV.variants && _tmsV.variants.length > 0>> <<set _tmsVarTotal = 0>><<for _tmsVi = 0; _tmsVi < _tmsV.variants.length; _tmsVi++>><<set _tmsVarTotal += Number(_tmsV.variants[_tmsVi].weight) || 1>><</for>> <<set _tmsVarRoll = Math.random() * _tmsVarTotal>><<set _tmsVarCum = 0>> <<for _tmsVi = 0; _tmsVi < _tmsV.variants.length; _tmsVi++>><<set _tmsVarCum += Number(_tmsV.variants[_tmsVi].weight) || 1>><<if _tmsVarRoll < _tmsVarCum>><<set _tmsVariantName = _tmsV.variants[_tmsVi].name>><<break>><</if>><</for>> <</if>> <<set _tmsName = _tmsVariantName || _tmsDef.name>><<set _tmsAppr = (_tmsV && _tmsV.approachDesc) ? _tmsV.approachDesc : _tmsDef.approachDesc>><<set _tmsInside = (_tmsV && _tmsV.insideDesc) ? _tmsV.insideDesc : _tmsDef.insideDesc>> <<run $worldSceneQueue.push({id:_tmsPick.id,name:_tmsName,state:"pending",tier:"C",source:"tier",regionVariant:(_tmsV ? _tmsRegion : ""),approachDesc:_tmsAppr,insideDesc:_tmsInside,approachAt:_tmsStart-_tmsApproach,mapStart:_tmsStart,mapEnd:_tmsEnd,leaveEnd:_tmsEnd+_tmsLeave,children:_tmsDef.children || [],doneCids:[]})>> <<set _tmsPlaced = true>> <</if>> <</for>> <</if>> <</if>> <</widget>> <</nobr>>
<<widget "matchRecipe">> <<nobr>> /* 分类标签集合(用于判断类型) */ <<set _mr_SEAFOOD = ["鱼","虾","蟹","贝","腕足"]>> <<set _mr_CATALL = ["鱼","虾","蟹","贝","腕足","海草","蔬菜","块茎","谷物","兽肉"]>> /* 收集所有食材的分类标签 */ <<set _mr_catTags = []>> <<for _mri = 0; _mri < $cookIngredients.length; _mri++>> <<set _mr_def = State.variables.items[$cookIngredients[_mri]]>> <<if _mr_def && _mr_def.foodtags>> <<for _mrt = 0; _mrt < _mr_def.foodtags.length; _mrt++>> <<set _mr_tag = _mr_def.foodtags[_mrt]>> <<if _mr_CATALL.includes(_mr_tag) && !_mr_catTags.includes(_mr_tag)>> <<run _mr_catTags.push(_mr_tag)>> <</if>> <</for>> <</if>> <</for>> <<set _mr_hasSeafood = _mr_catTags.some(t => _mr_SEAFOOD.includes(t))>> <<set _mr_seafoodTags = _mr_catTags.filter(t => _mr_SEAFOOD.includes(t))>> <<set _mr_nonSeafood = _mr_catTags.filter(t => !_mr_SEAFOOD.includes(t))>> <<set _mr_found = false>> <<set $cookTemplate = null>> /* ── 1. 单食材路径(1种食材,使用单类模板) ── */ <<if $cookIngredients.length === 1 && _mr_catTags.length > 0>> <<set _mr_priTag = _mr_catTags[0]>> <<set _mr_sKey = _mr_priTag + "_" + $cookMethod>> <<set _mr_sTpl = $cookSingleTemplates ? $cookSingleTemplates[_mr_sKey] : null>> <<if _mr_sTpl>> <<set $cookTemplate = _mr_sTpl>> <<set $cookTemplate.id = _mr_sKey>> <<set _mr_found = true>> <</if>> <</if>> /* ── 2. 多食材路径(使用多类模板,按优先级) ── */ <<if !_mr_found && $cookIngredients.length > 1 && $cookMultiTemplates>> <<for _mrm = 0; _mrm < $cookMultiTemplates.length; _mrm++>> <<set _mr_mt = $cookMultiTemplates[_mrm]>> /* 检查方式匹配 */ <<if !_mr_mt.methods.includes($cookMethod)>><<continue>><</if>> /* 检查 seafoodOnly */ <<if _mr_mt.seafoodOnly>> <<if !_mr_hasSeafood || _mr_nonSeafood.length > 0>><<continue>><</if>> <<if _mr_seafoodTags.length < 2>><<continue>><</if>> <</if>> /* 检查 noSeafood */ <<if _mr_mt.noSeafood && _mr_hasSeafood>><<continue>><</if>> /* 检查 hasSeafood */ <<if _mr_mt.hasSeafood && !_mr_hasSeafood>><<continue>><</if>> /* 检查 requires 标签全部存在 */ <<if _mr_mt.requires>> <<set _mr_reqOk = true>> <<for _mrr = 0; _mrr < _mr_mt.requires.length; _mrr++>> <<if !_mr_catTags.includes(_mr_mt.requires[_mrr])>> <<set _mr_reqOk = false>><<break>> <</if>> <</for>> <<if !_mr_reqOk>><<continue>><</if>> <</if>> /* 命中 */ <<set $cookTemplate = _mr_mt>> <<set _mr_found = true>> <<break>> <</for>> <</if>> /* ── 3. 保底:使用方式对应的保底模板 ── */ <<if !_mr_found>> <<set _mr_fallbacks = { "明火烤": { id:"fallback_roast", name:"焦糊一团", hunger:5, water:-2, life:-1, power:0, san:-5, magic:0, dur:25, sMin:6, sMax:22, pMin:10, pMax:18, open:"火候没有控制好,", close:"最终留下一团说不清楚是什么的焦糊物。" }, "铜锅炖": { id:"fallback_stew", name:"稀烂糊", hunger:8, water:4, life:0, power:0, san:-4, magic:0, dur:35, sMin:9, sMax:31, pMin:15, pMax:26, open:"锅底开始冒出焦糊味,", close:"食材已经炖烂失去了所有形状,漂浮在浑浊的汤底里。" }, "清蒸": { id:"fallback_steam", name:"软塌蒸物", hunger:6, water:2, life:0, power:0, san:-3, magic:0, dur:28, sMin:7, sMax:25, pMin:12, pMax:21, open:"蒸汽带走了所有的水分,", close:"食材瘪缩成一团,失去了应有的形态与鲜味。" }, "煎炒": { id:"fallback_fry", name:"糊底炒物", hunger:6, water:-1, life:0, power:0, san:-4, magic:0, dur:20, sMin:5, sMax:18, pMin:8, pMax:15, open:"锅底已经糊了,", close:"焦糊味盖过了食材本身的香气,勉强能入口。" }, "油炸": { id:"fallback_deepfry",name:"炸焦一团", hunger:5, water:-2, life:-1, power:0, san:-4, magic:0, dur:22, sMin:5, sMax:19, pMin:9, pMax:16, open:"油温过高,", close:"食材在热油中迅速炭化,留下一团苦涩的焦糊物。" }, "生食": { id:"fallback_raw", name:"生拼残食", hunger:4, water:0, life:0, power:0, san:-5, magic:0, dur:15, sMin:4, sMax:13, pMin:6, pMax:11, open:"处理得不够仔细,", close:"随便拼凑的生食,入口的生腥气让人皱眉。" } }>> <<set $cookTemplate = _mr_fallbacks[$cookMethod] || _mr_fallbacks["生食"]>> <</if>> /* ── 从 template 设置计时参数 ── */ <<set $cookRecipeName = $cookTemplate.name>> <<set $cookDuration = $cookTemplate.dur || 25>> <<set $cookSuccessMin = $cookTemplate.sMin || 5>> <<set $cookSuccessMax = $cookTemplate.sMax || 20>> <<set $cookPerfectMin = $cookTemplate.pMin || 8>> <<set $cookPerfectMax = $cookTemplate.pMax || 16>> <</nobr>> <</widget>>
<<nobr>> <<widget "put">> <<set _pt_id = $args[0]>> <<set _pt_qty = $args[1]>> <<set _pt_def = State.variables.items[_pt_id]>> <<if !_pt_def>> <<print "错误:未知物品 " + _pt_id>> <<else>> <<set _pt_type = _pt_def.type>> /* 在背包中找索引 */ <<set _pt_bpIdx = -1>> <<if $backpack[_pt_type]>> <<for _pt_i = 0; _pt_i < $backpack[_pt_type].length; _pt_i++>> <<if $backpack[_pt_type][_pt_i].id === _pt_id>> <<set _pt_bpIdx = _pt_i>> <<break>> <</if>> <</for>> <</if>> <<if _pt_bpIdx < 0 || $backpack[_pt_type][_pt_bpIdx].quantity < _pt_qty>> <<print "背包中 " + _pt_def.name + " 数量不足">> <<else>> /* 从背包扣除 */ <<set $backpack[_pt_type][_pt_bpIdx].quantity -= _pt_qty>> /* 直接向仓库添加(不经过 additem,避免 $storeUsed 未初始化问题) */ <<if !$store[_pt_type]>> <<set $store[_pt_type] = []>> <</if>> <<set _pt_stIdx = -1>> <<for _pt_i = 0; _pt_i < $store[_pt_type].length; _pt_i++>> /* 同天入库的批次合并,否则新建(支持腐败分批) */ <<set _pt_ent = $store[_pt_type][_pt_i]>> <<if _pt_ent.id === _pt_id && (!_pt_ent.addedDay || !$backpack[_pt_type][_pt_bpIdx].addedDay || _pt_ent.addedDay === $backpack[_pt_type][_pt_bpIdx].addedDay)>> <<set _pt_stIdx = _pt_i>> <<break>> <</if>> <</for>> <<if _pt_stIdx >= 0>> <<set $store[_pt_type][_pt_stIdx].quantity += _pt_qty>> <<else>> <<set _pt_newEntry = { id: _pt_id, quantity: _pt_qty }>> <<if $backpack[_pt_type][_pt_bpIdx].addedDay>> <<set _pt_newEntry.addedDay = $backpack[_pt_type][_pt_bpIdx].addedDay>> <</if>> <<run State.variables.store[_pt_type].push(_pt_newEntry)>> <</if>> <<print "放回 " + _pt_qty + " × " + _pt_def.name>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "putAll">> <<set _pa_id = $args[0]>> <<set _pa_def = State.variables.items[_pa_id]>> <<if !_pa_def>> <<set $lastTakeText = "未知物品。">> <<else>> <<set _pa_type = _pa_def.type>> <<set _pa_idx = -1>> <<if $backpack[_pa_type]>> <<for _pa_i = 0; _pa_i < $backpack[_pa_type].length; _pa_i++>> <<if $backpack[_pa_type][_pa_i].id === _pa_id>> <<set _pa_idx = _pa_i>> <<break>> <</if>> <</for>> <</if>> <<if _pa_idx < 0 || $backpack[_pa_type][_pa_idx].quantity <= 0>> <<set $lastTakeText = "背包中已经没有" + _pa_def.name + "了。">> <<else>> <<set _pa_qty = $backpack[_pa_type][_pa_idx].quantity>> <<put _pa_id _pa_qty>> <<set $lastTakeText = "已放回 " + _pa_qty + " × " + _pa_def.name>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "questCheck">> /* 调用:<> type: "wsChild" — 完成 wsChild,id 为 childId "flag" — 设置旗标后检查,id 为 flag key "item" — 拾取物品,id 为 itemId "npcMet" — 遇见 NPC,id 为 npcId "auto" — 每次进入新场景时自动检查 结果:命中则写日记、推进进度、设 $questNotify */ <<if !$questChain>><<questDefs>><</if>> <<set _qcType = ($args && $args[0]) ? String($args[0]) : "auto">> <<set _qcId = ($args && $args[1]) ? String($args[1]) : "">> /* ── 主线检查 ── */ <<if $questProgress < $questChain.length>> <<set _qcNode = $questChain[$questProgress]>> <<set _qcMatch = false>> <<if _qcNode.trigger.type === _qcType>> <<if _qcType === "auto">><<set _qcMatch = true>> <<elseif _qcType === "wsChild" && _qcId === _qcNode.trigger.childId>><<set _qcMatch = true>> <<elseif _qcType === "flag" && _qcId === _qcNode.trigger.flag>><<set _qcMatch = true>> <<elseif _qcType === "item" && _qcId === _qcNode.trigger.itemId>><<set _qcMatch = true>> <<elseif _qcType === "npcMet" && _qcId === _qcNode.trigger.npcId>><<set _qcMatch = true>> <</if>> <</if>> <<if _qcMatch>> /* 追加日记条目 */ <<run $questLog.push({ id: _qcNode.id, title: _qcNode.title, text: _qcNode.logEntry, day: $day || 0, type: "main" })>> <<set $questNotify = "✦ 日记已更新:" + _qcNode.title>> <<set $questProgress = $questProgress + 1>> /* 主线触发中型事件通知(优先级低:不覆盖已有事件)*/ <<if !$activeEvent>> <<set $activeEvent = {id:"quest_"+_qcNode.id, name:"✦ "+_qcNode.title, desc:"主线日记已更新,前往书桌查看。", type:"event", actions:["查看日志","稍后再看"]}>> <<set $sailspd = 0>> <</if>> <</if>> <</if>> /* ── 支线检查 ── */ <<if $sideQuestDefs>> <<set _sqKeys = Object.keys($sideQuestDefs)>> <<for _sqi = 0; _sqi < _sqKeys.length; _sqi++>> <<set _sqId = _sqKeys[_sqi]>> <<set _sqDef = $sideQuestDefs[_sqId]>> <<set _sqProg = (typeof $sideQuestProgress[_sqId] === "number") ? $sideQuestProgress[_sqId] : 0>> <<if _sqProg < _sqDef.nodes.length>> <<set _sqNode = _sqDef.nodes[_sqProg]>> <<set _sqMatch = false>> <<if _sqNode.trigger.type === _qcType>> <<if _qcType === "auto">><<set _sqMatch = false>>/* auto不触发支线,由npcMet/flag触发 */ <<elseif _qcType === "wsChild" && _qcId === _sqNode.trigger.childId>><<set _sqMatch = true>> <<elseif _qcType === "flag" && _qcId === _sqNode.trigger.flag>><<set _sqMatch = true>> <<elseif _qcType === "item" && _qcId === _sqNode.trigger.itemId>><<set _sqMatch = true>> <<elseif _qcType === "npcMet" && _qcId === _sqNode.trigger.npcId>><<set _sqMatch = true>> <</if>> <</if>> <<if _sqMatch>> <<if typeof $sideQuestLog[_sqId] !== "object">><<set $sideQuestLog[_sqId] = []>><</if>> <<run $sideQuestLog[_sqId].push({ id: _sqNode.id, title: _sqNode.title, text: _sqNode.logEntry, day: $day || 0 })>> <<set $sideQuestProgress[_sqId] = _sqProg + 1>> <<set $questNotify = ($questNotify || "") + " ✧ 支线更新:" + _sqDef.title>> <</if>> <</if>> <</for>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "removeitem">> <<set _ri_id = $args[0]>> <<set _ri_qty = $args[1]>> <<set _ri_def = State.variables.items[_ri_id]>> <<if !_ri_def>> <<print "错误:未知物品 " + _ri_id>> <<else>> <<set _ri_type = _ri_def.type>> <<set _ri_idx = -1>> <<if $store[_ri_type]>> <<for _ri_i = 0; _ri_i < $store[_ri_type].length; _ri_i++>> <<if $store[_ri_type][_ri_i].id === _ri_id>> <<set _ri_idx = _ri_i>> <<break>> <</if>> <</for>> <</if>> <<if _ri_idx < 0>> <<print "仓库中没有:" + _ri_def.name>> <<elseif $store[_ri_type][_ri_idx].quantity < _ri_qty>> <<print _ri_def.name + " 数量不足(现有 " + $store[_ri_type][_ri_idx].quantity + ")">> <<else>> <<set $store[_ri_type][_ri_idx].quantity -= _ri_qty>> <<print "消耗 " + _ri_qty + " × " + _ri_def.name>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "resolveEvent">> /* 轻量事件结算器。 旧 $eventDefs 中型事件(sealed_container / thermal_vent / salt_lake / ...)已迁移到 世界场景(ResolveWsChild)与 C 类小型事件(ResolveSmallEvent),相关分支已删除。 此处只保留仍在使用 $activeEvent 模板的:NPC 遭遇、主线日记通知。 */ <<set _re_action = $args[0]>> <<if !$activeEvent>> <<return>> <</if>> <<set _re_id = $activeEvent.id>> <<set _re_name = $activeEvent.name>> <<if _re_id.indexOf("npc_") === 0 && _re_action === "前去交谈">> <<set $activeEvent = 0>> <<set $eventTimer = 0>> <<set $eventPass = 0>> <<set $npcReturn = "航行">> <<goto "NPC_对话">> <<elseif _re_id.indexOf("npc_") === 0 && _re_action === "无视离开">> <<set $activeNpc = null>> <<set $npcSpawnCooldown = ($day||0) + 3>> <<set $lastEventText = "无视了对方的信号,对方船只渐渐远去。">> <<elseif _re_id.indexOf("quest_") === 0 && _re_action === "查看日志">> /* 主线通知 → 跳转书桌 */ <<set $activeEvent = 0>> <<set $eventTimer = 0>> <<set $eventPass = 0>> <<goto "书桌">> <<elseif _re_id.indexOf("quest_") === 0 && _re_action === "稍后再看">> <<set $lastEventText = "日记待查阅。">> <<else>> <<set $lastEventText = "已处理。">> <</if>> <<run $eventLog.push({ id: _re_id, name: _re_name, outcome: _re_action })>> <<set $activeEvent = 0>> <<set $eventTimer = 0>> <<set $eventPass = 0>> <</widget>> <</nobr>>
<<nobr>> <<widget "resolveMicroEvent">> /* $args[0] = 微型事件 ID 结果写入 $lastHuntText,清除该 ID 出 $activeHuntItems */ <<microEventTable>> <<set _rmeId = $args[0]>> <<if !_rmeId || !$microEventDefs[_rmeId]>> <<set $lastHuntText = "(事件数据丢失)">> <<return>> <</if>> <<set _rmeDef = $microEventDefs[_rmeId]>> /* 加权随机结果 */ <<set _rmeTotalW = 0>> <<for _oi = 0; _oi < _rmeDef.outcomes.length; _oi++>> <<set _rmeTotalW += _rmeDef.outcomes[_oi].weight>> <</for>> <<set _rmeRoll = Math.random() * _rmeTotalW>> <<set _rmeCum = 0>> <<set _rmeResult = _rmeDef.outcomes[0]>> <<for _oi = 0; _oi < _rmeDef.outcomes.length; _oi++>> <<set _rmeCum += _rmeDef.outcomes[_oi].weight>> <<if _rmeRoll < _rmeCum>> <<set _rmeResult = _rmeDef.outcomes[_oi]>> <<break>> <</if>> <</for>> /* 发放战利品 */ <<set _rmeLog = "">> <<if _rmeResult.loot>> <<for _rli = 0; _rli < _rmeResult.loot.length; _rli++>> <<set _rl = _rmeResult.loot[_rli]>> <<set _rlo = _rl.qty[0]>> <<set _rhi = _rl.qty[1]>> <<set _rq = _rlo + Math.floor(Math.random() * (_rhi - _rlo + 1))>> <<if _rq > 0>> <<additem _rl.id _rq>> <<if $items && $items[_rl.id]>> <<set _rmeLog = _rmeLog + $items[_rl.id].name + "×" + _rq + " ">> <</if>> <</if>> <</for>> <</if>> /* 写结果文本 */ <<set $lastHuntText = _rmeResult.text>> <<if _rmeLog>><<set $lastHuntText = $lastHuntText + " " + _rmeLog>><</if>> /* 从 $activeHuntItems 中移除该 ID */ <<set _newHuntItems = []>> <<for _hi = 0; _hi < $activeHuntItems.length; _hi++>> <<if $activeHuntItems[_hi] !== _rmeId>> <<set _newHuntItems[_newHuntItems.length] = $activeHuntItems[_hi]>> <</if>> <</for>> <<set $activeHuntItems = _newHuntItems>> <</widget>> <</nobr>>
<<nobr>> <<widget "resolveSmallEvent">> /* 始终重新初始化定义,避免跨状态步骤后对象损坏 */ <<smallEventTable>> <<if !$activeSmallEvent>><<return>><</if>> <<set _rsId = $activeSmallEvent.id>> <<set _rsAct = $args[0]>> <<if !$smallEventDefs[_rsId]>> <<set $lastSmallEventText = "(事件数据丢失)">> <<set $activeSmallEvent = null>> <<return>> <</if>> <<set _rsDef = $smallEventDefs[_rsId]>> <<if !_rsDef.resolve[_rsAct]>> <<set $lastSmallEventText = "(未知操作)">> <<set $activeSmallEvent = null>> <<return>> <</if>> <<set _rsResult = _rsDef.resolve[_rsAct]>> /* 发放战利品 */ <<set _rsLog = $activeSmallEvent.lootLog>> <<if _rsResult.loot>> <<for _rli = 0; _rli < _rsResult.loot.length; _rli++>> <<set _rl = _rsResult.loot[_rli]>> <<set _rlo = _rl.qty[0]>> <<set _rhi = _rl.qty[1]>> <<set _rq = _rlo + Math.floor(Math.random() * (_rhi - _rlo + 1))>> <<if _rq > 0>> <<additem _rl.id _rq>> <<if $items && $items[_rl.id]>> <<set _rsLog = _rsLog + $items[_rl.id].name + "×" + _rq + " ">> <</if>> <</if>> <</for>> <</if>> /* 进入下一阶段或结束 */ <<set _rsNext = _rsResult.nextStage>> <<if _rsNext < 0 || _rsNext >= _rsDef.stages.length>> /* 事件走完最后阶段:标记完成,不清空。 玩家起锚离开后事件仍在,可重新锚定重入。 下次进入时探索页面会显示"重新探索"入口。 */ <<set $lastSmallEventText = _rsResult.text>> <<if _rsLog>><<set $lastSmallEventText = $lastSmallEventText + " 收获:" + _rsLog>><</if>> <<set $activeSmallEvent.finished = true>> <<set $activeSmallEvent.lootLog = _rsLog>> <<else>> <<set _rsNs = _rsDef.stages[_rsNext]>> <<set $activeSmallEvent.stageIdx = _rsNext>> <<set $activeSmallEvent.stageDesc = _rsResult.text + " " + _rsNs.desc>> <<set $activeSmallEvent.actions = _rsNs.actions>> <<set $activeSmallEvent.lootLog = _rsLog>> <</if>> /* timeCost:若选项定义了时间消耗,推进游戏时间 */ <<if _rsResult.timeCost && _rsResult.timeCost > 0>> <<set $timepass = _rsResult.timeCost>> <<time>> <</if>> /* questTrigger:选项完成后推进任务 */ <<if _rsResult.questTrigger>> <<questCheck _rsResult.questTrigger.type (_rsResult.questTrigger.id || "")>> <</if>> /* goto:选项可以跳转到战斗/NPC/主线占位 passage */ <<if _rsResult.goto>> <<if _rsResult.goto === "战斗" || _rsResult.goto === "战斗">> <<set $combatReturn = ($currentContext === "outside") ? "仓外探索" : ($currentContext === "anchored") ? "探索" : "航行">> <<set $combatState = { enemy: _rsResult.enemy || "未知生物", enemyHP: _rsResult.enemyHP || 30, reward: _rsResult.reward || [], sourceEvent: $activeSmallEvent ? $activeSmallEvent.id : "unknown" }>> <<set $activeSmallEvent = null>> <<goto _rsResult.goto>> <<elseif _rsResult.goto === "NPC_商店_占位" || _rsResult.goto === "NPC_对话_占位" || _rsResult.goto === "主线入口_占位">> <<set $npcReturn = ($currentContext === "outside") ? "仓外探索" : ($currentContext === "anchored") ? "探索" : "航行">> <<set $npcState = { npcId: _rsResult.npcId || "unknown_npc", npcName: _rsResult.npcName || "陌生人", shopId: _rsResult.shopId || null, sourceEvent: $activeSmallEvent ? $activeSmallEvent.id : "unknown" }>> <<set $activeSmallEvent = null>> <<goto _rsResult.goto>> <</if>> <</if>> /* envEffect:影响类事件写入 $envEffects */ <<if _rsResult.envEffect>> <<set _rsEff = _rsResult.envEffect>> <<set _rsNewEff = { type: _rsEff.type, terrain: (_rsEff.terrain === "auto") ? $maptype : _rsEff.terrain, depthMin: _rsEff.depthAuto ? Math.max(0, $depth - 20) : (_rsEff.depthMin || 0), depthMax: _rsEff.depthAuto ? $depth + 20 : (_rsEff.depthMax || 9999), plantedDay: $day || 0, harvestCount: 0, state: "growing" }>> <<run $envEffects.push(_rsNewEff)>> <</if>> /* harvestKelp:海带农场收获处理 */ <<if _rsResult.harvestKelp>> <<for _rsKi = $envEffects.length - 1; _rsKi >= 0; _rsKi-->> <<set _rsKEff = $envEffects[_rsKi]>> <<if _rsKEff.type === "kelp_farm" && _rsKEff.terrain === $maptype && $depth >= _rsKEff.depthMin && $depth <= _rsKEff.depthMax>> <<if _rsResult.harvestKelp === "partial">> <<set $envEffects[_rsKi].harvestCount += 1>> <<set $envEffects[_rsKi].plantedDay = $day || 0>> <<set $envEffects[_rsKi].state = "growing">> <<else>> /* 全面收割:超过最大次数则枯竭移除 */ <<set $envEffects[_rsKi].harvestCount += 1>> <<if $envEffects[_rsKi].harvestCount >= 5>> <<set $envEffects[_rsKi].state = "depleted">> <<run $envEffects.splice(_rsKi, 1)>> <<else>> <<set $envEffects[_rsKi].plantedDay = $day || 0>> <<set $envEffects[_rsKi].state = "growing">> <</if>> <</if>> <<break>> <</if>> <</for>> <</if>> /* bondGain:好感类事件写入 / 更新 $ecoBonds */ <<if _rsResult.bondGain>> <<set _rsBG = _rsResult.bondGain>> <<set _rsBK = _rsBG.key>> <<if !$ecoBonds[_rsBK]>> /* 首次相遇:建立档案 */ <<set $ecoBonds[_rsBK] = { terrain: (_rsBG.terrain === "auto") ? $maptype : _rsBG.terrain, depthMin: _rsBG.depthAuto ? Math.max(0, $depth - 30) : (_rsBG.depthMin || 0), depthMax: _rsBG.depthAuto ? $depth + 30 : (_rsBG.depthMax || 9999), met: true, bond: _rsBG.amount || 0, lastVisit: $day || 0, stage: 0, active: true }>> <<else>> /* 再次相遇:累加好感(冷却检查:同一天只加一次)*/ <<if ($ecoBonds[_rsBK].lastVisit || 0) < ($day || 0)>> <<set $ecoBonds[_rsBK].bond += _rsBG.amount || 0>> <<set $ecoBonds[_rsBK].lastVisit = $day || 0>> <</if>> /* stage 晋级(每10点升一阶,最高3)*/ <<if $ecoBonds[_rsBK].bond >= ($ecoBonds[_rsBK].stage + 1) * 10 && $ecoBonds[_rsBK].stage < 3>> <<set $ecoBonds[_rsBK].stage += 1>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "resolveTemporalEvent">> <<if !$temporalEvent>><<return>><</if>> <<set _tep = $temporalEvent.prog + $temporalEvent.speed>> <<if _tep > 100>><<set _tep = 100>><</if>> <<set $temporalEvent.prog = _tep>> <<if $temporalEvent.warned === 0 && _tep >= $temporalEvent.warnAt>> <<set $temporalEvent.warned = 1>> <<set $temporalLog = "Warning: " + $temporalEvent.warnText>> <</if>> <<if _tep >= 100>> <<set $temporalLog = $temporalEvent.endText>> <<if $temporalEvent.effect === "san">><<set $san = Math.max(0, $san - $temporalEvent.amount)>> <<elseif $temporalEvent.effect === "sys">><<set $sys = Math.max(0, $sys - $temporalEvent.amount)>> <<elseif $temporalEvent.effect === "map">><<set $map = $map + $temporalEvent.amount>> <</if>> <<set $temporalEvent = 0>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "resolveWsChild">> /* 始终重新初始化,防止序列化损坏 */ <<worldSceneDefs>> <<if !$wsChild>><<return>><</if>> <<set _action = $args[0]>> <<set _cid = $wsChild.id>> <<if !$wsChildDefs[_cid]>> <<set $wsChild = null>><<return>> <</if>> <<set _cDef = $wsChildDefs[_cid]>> <<if !_cDef.resolve[_action]>> <<set $wsChild = null>><<return>> <</if>> <<set _result = _cDef.resolve[_action]>> /* 发放战利品 */ <<set _wsLog = $wsChild.lootLog>> <<if _result.loot>> <<for _rli = 0; _rli < _result.loot.length; _rli++>> <<set _rl = _result.loot[_rli]>> <<set _rlo = _rl.qty[0]>> <<set _rhi = _rl.qty[1]>> <<set _rq = _rlo + Math.floor(Math.random() * (_rhi - _rlo + 1))>> <<if _rq > 0>> <<additem _rl.id _rq>> <<if $items && $items[_rl.id]>> <<set _wsLog = _wsLog + $items[_rl.id].name + "×" + _rq + " ">> <</if>> <</if>> <</for>> <</if>> /* 将结果文本同时写入持久变量(null后依然可读)*/ <<set $wsLastActionText = _result.text>> <<set $wsLastActionLoot = _wsLog>> /* 进入下一阶段或关闭 */ <<set _nextIdx = _result.next>> <<if _nextIdx < 0 || _nextIdx >= _cDef.stages.length>> <<if $worldScene>> <<if !$worldScene.doneCids>><<set $worldScene.doneCids = []>><</if>> <<set _alreadyDone = false>> <<for _dci = 0; _dci < $worldScene.doneCids.length; _dci++>> <<if $worldScene.doneCids[_dci] === _cid>><<set _alreadyDone = true>><</if>> <</for>> <<if !_alreadyDone>><<run $worldScene.doneCids.push(_cid)>><</if>> <</if>> <<set $wsChild = null>> <<else>> <<set _ns = _cDef.stages[_nextIdx]>> <<set $wsChild.stageIdx = _nextIdx>> <<set $wsChild.stageDesc = _result.text + " " + _ns.desc>> <<set $wsChild.actions = _ns.actions>> <<set $wsChild.lootLog = _wsLog>> <<set $wsChild.actionText = _result.text>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "sail">> <<set _sailMapBefore = Number($map) || 0>> <<set _sailMove = Math.max(0, Number($sailspd) || 0)>> <<set $map += _sailMove>> <<set $sailpass += 1>> /* 只按实际地图前进距离累计;速度为0或停车时不增加遭遇距离。 */ <<if _sailMove > 0>> <<set $eventDistance = Math.max(0, Number($eventDistance) || 0) + _sailMove>> <<set $eventDistanceCooldown = Math.max(0, (Number($eventDistanceCooldown) || 0) - _sailMove)>> <</if>> <<set $depthpass += $sailspd>> <<set $timepass += 1>> /* 更新跨度显示 */ <<set $mapspan = Math.floor($map / 50)>> <<set $maplimspan = Math.floor($maplim / 50)>> /* ═══ 预生成下一区域选项(3个方向) ═══ */ <<if $maplim - $map < 2000 && $nextAreasReady != 1>> <<set $nextAreas = []>> <<set _keys = Object.keys($mapinfo)>> <<set _usedTypes = [$maptype]>> /* 初始即排除当前地形 */ /* ── 方向0·直行:只从深度兼容地形加权随机 ── */ <<set _compat = []>><<set _compatW = []>><<set _compatTotalW = 0>> <<for _ki = 0; _ki < _keys.length; _ki++>> <<set _kinfo = $mapinfo[_keys[_ki]]>> <<if $depthdeep >= _kinfo.depthmin && $depthdeep <= _kinfo.depthmax>> <<run _compat.push(_keys[_ki])>> <<run _compatW.push(_kinfo.weight)>> <<set _compatTotalW += _kinfo.weight>> <</if>> <</for>> /* 过滤掉当前地形,避免直行也重复 */ <<set _compat2 = []>><<set _compatW2 = []>><<set _compatTotalW2 = 0>> <<for _ki = 0; _ki < _compat.length; _ki++>> <<if _compat[_ki] !== $maptype>> <<set _compat2[_compat2.length] = _compat[_ki]>> <<set _compatW2[_compatW2.length] = _compatW[_ki]>> <<set _compatTotalW2 += _compatW[_ki]>> <</if>> <</for>> /* 若过滤后为空(极端情况),回退到含当前地形 */ <<if _compat2.length === 0>><<set _compat2 = _compat>><<set _compatW2 = _compatW>><<set _compatTotalW2 = _compatTotalW>><</if>> <<if _compatTotalW2 <= 0>><<run _compat2.push("sand")>><<run _compatW2.push(1)>><<set _compatTotalW2 = 1>><</if>> <<set _r0 = Math.random() * _compatTotalW2>><<set _cw = 0>><<set _t0 = _compat2[0]>> <<for _ki = 0; _ki < _compat2.length; _ki++>> <<set _cw += _compatW2[_ki]>> <<if _r0 < _cw>><<set _t0 = _compat2[_ki]>><<break>><</if>> <</for>> <<set _i0 = $mapinfo[_t0]>> <<set _d0 = Math.min(_i0.depthmax, Math.max(_i0.depthmin, $depthdeep + Math.floor(Math.random()*201)-100))>> <<set _ml0 = _i0.spanmin + Math.floor(Math.random()*(_i0.spanmax-_i0.spanmin+1))>> <<run $nextAreas.push({type:_t0,depth:_d0,maplim:_ml0,label:_i0.type,dir:"直行",transition:false})>> <<run _usedTypes.push(_t0)>> /* ── 方向1·左转 / 方向2·右转:所有地形可选,深度取最接近当前的合法值 ── */ <<set _dirs = ["向左转舵","向右转舵"]>> <<for _di = 0; _di < 2; _di++>> /* 加权随机,跳过已用地形 */ <<set _altW = 0>> <<for _ki = 0; _ki < _keys.length; _ki++>> <<set _inU = false>> <<for _ui = 0; _ui < _usedTypes.length; _ui++>><<if _usedTypes[_ui]===_keys[_ki]>><<set _inU=true>><<break>><</if>><</for>> <<if !_inU>><<set _altW += $mapinfo[_keys[_ki]].weight>><</if>> <</for>> <<if _altW <= 0>><<break>><</if>> <<set _ralt = Math.random() * _altW>><<set _calt = 0>><<set _talt = "">> <<for _ki = 0; _ki < _keys.length; _ki++>> <<set _inU = false>> <<for _ui = 0; _ui < _usedTypes.length; _ui++>><<if _usedTypes[_ui]===_keys[_ki]>><<set _inU=true>><<break>><</if>><</for>> <<if !_inU>><<set _calt += $mapinfo[_keys[_ki]].weight>><<if _ralt < _calt>><<set _talt = _keys[_ki]>><<break>><</if>><</if>> <</for>> <<if !_talt>><<break>><</if>> <<set _ialt = $mapinfo[_talt]>> /* 深度:夹到合法范围内,尽量靠近当前深度 */ <<set _dalt = Math.min(_ialt.depthmax, Math.max(_ialt.depthmin, $depthdeep + Math.floor(Math.random()*401)-200))>> <<set _trans = ($depthdeep < _ialt.depthmin || $depthdeep > _ialt.depthmax)>> <<set _mlalt = _ialt.spanmin + Math.floor(Math.random()*(_ialt.spanmax-_ialt.spanmin+1))>> <<set _dirLabel = _dirs[_di]>> <<run $nextAreas.push({type:_talt,depth:_dalt,maplim:_mlalt,label:_ialt.type,dir:_dirLabel,transition:_trans})>> <<run _usedTypes.push(_talt)>> <</for>> <<set $nextAreasReady = 1>> <<set $selectedNextArea = 0>> <</if>> /* ═══ 区域过渡 ═══ */ <<if $map >= $maplim>> /* 存档当前区域为"上一区域"(用于返回功能) */ <<set $prevArea = { type:$maptype, depth:$depthdeep, maplim:$maplim }>> <<if $selectedNextArea === -1 && $prevArea !== null>> /* 返回上一区域 */ <<set $maptype = $prevArea.type>> <<set $depthdeep = $prevArea.depth>> <<set $maplim = $prevArea.maplim>> <<elseif $nextAreasReady === 1 && $nextAreas.length > 0>> /* 进入玩家选择(或默认选中)的区域 */ <<set _chosen = $nextAreas[$selectedNextArea] || $nextAreas[0]>> <<set $maptype = _chosen.type>> <<set $maplim = _chosen.maplim>> <<if $cps && $cps.viona && $cps.viona.recentEvents>> <<set _chosenLabel = _chosen.label || (($mapinfo[_chosen.type] && $mapinfo[_chosen.type].type) ? $mapinfo[_chosen.type].type : _chosen.type)>> <<set $cps.viona.recentEvents.destination = {tag:"destination",target:_chosenLabel,targetId:_chosen.type,day:$day,expire:$day + 1}>> <</if>> /* 深度过渡:将depthnoc夹到新地形合法范围内 */ <<set _cInfo = $mapinfo[_chosen.type]>> <<if _cInfo>> <<if $depthnoc < _cInfo.depthmin>><<set $depthnoc = _cInfo.depthmin>><</if>> <<if $depthnoc > _cInfo.depthmax>><<set $depthnoc = _cInfo.depthmax>><</if>> <</if>> <<set $depthdeep = Math.floor($depthnoc)>> <<else>> /* 后备方案 */ <<set $maptype = "sand">> <<set $depthdeep = Math.min(Math.max($depthdeep,20),10000)>> <<set $maplim = 80000>> <</if>> <<set $map = 0>> <<set $depthnoc = $depthdeep>> <<set $nextAreasReady = 0>> <<set $nextAreas = []>> /* 进入新区域时设置初始丰富度 */ <<set _richBase = { sand:20, flat:30, cliff:35, grass:55, reef:70, vent:60, abyss:10 }>> <<set $regionRichness = (_richBase[$maptype] || 30) + Math.floor(Math.random() * 20)>> /* 进入新区域:重置事件队列,生成大/中型场景 */ <<set $worldScene = null>> <<set $wsChild = null>> <<set $activeMicroEvent = null>> <<set $wsLastActionText = "">> <<set $wsLastActionLoot = "">> <<set $largeScene = 0>> <<set $worldSceneQueue = []>> <<set $worldSceneQueueIdx = 0>> <<set $mapReservations = []>> <<set _bmAutoL = ($mapinfo[$maptype] ? $mapinfo[$maptype].type : $maptype) + " " + $depthdeep + "m">> <<addBookmark _bmAutoL "auto">> <<spawnLargeScene>> /* 旧 independent 中型池继续服务既有散装地点;tier_only 中型(鲸落)由统一 ABC 调度插入。 */ <<if !$largeScene || $largeScene === 0>><<spawnWorldScene>><</if>> <<spawnTierMiddleScene>> <<if $worldSceneQueue.length > 0>><<set $worldSceneQueue.sort(function(a,b){return a.mapStart-b.mapStart})>><<set $worldScene = $worldSceneQueue[0]>><<set $worldSceneQueueIdx = 0>><</if>> /* ══ 生成地点触发列表 ══ */ <<if !$locationDefTable>><<locationDefs>><</if>> <<set $activeLocations = []>> <<set _locPool = $locationDefTable[$maptype]>> <<if _locPool && _locPool.length > 0>> <<set _locCount = 1 + Math.floor(Math.random() * Math.min(3, _locPool.length))>> <<set _locPicked = []>> <<for _locI = 0; _locI < _locPool.length; _locI++>> <<set _locPicked[_locI] = _locI>> <</for>> <<for _locI = _locPicked.length - 1; _locI > 0; _locI-->> <<set _locJ = Math.floor(Math.random() * (_locI + 1))>> <<set _locTmp = _locPicked[_locI]>> <<set _locPicked[_locI] = _locPicked[_locJ]>> <<set _locPicked[_locJ] = _locTmp>> <</for>> <<for _locI = 0; _locI < _locCount && _locI < _locPicked.length; _locI++>> <<set _locDef = _locPool[_locPicked[_locI]]>> <<set _locRange = _locDef.approachRange || 300>><<set _locSpan = _locDef.spanLength || 400>> /* 地点也接入统一预留表;失败即少生成一个,不再强行重叠。 */ <<set _locMapAt = 0>> <<for _locTry = 0; _locTry < 40 && _locMapAt === 0; _locTry++>> <<set _locCandidate = 1000 + Math.floor(Math.random() * Math.max(1, $maplim - 2000))>><<reserveMapInterval _locCandidate-_locRange _locCandidate+_locSpan+_locRange "location" _locDef.id false>> <<if $mapReserveOK>><<set _locMapAt = _locCandidate>><</if>> <</for>> <<if _locMapAt > 0>> <<set _newLoc = { id: _locDef.id, name: _locDef.name, mapAt: _locMapAt, depthWindow: _locDef.depthWindow, scene: _locDef.scene, approachHint: _locDef.approachHint || "前方探测到异常信号。", arriveHint: _locDef.arriveHint || "", leaveHint: _locDef.leaveHint || "信号在身后消失。", approachRange: _locDef.approachRange || 300, spanLength: _locDef.spanLength || 400, gotoScene: _locDef.gotoScene || "", state: "distant", triggered: false, warned: false }>> <<set $activeLocations[$activeLocations.length] = _newLoc>> <</if>> <</for>> <</if>> <</if>> /* regionRichness 被动缓慢恢复(每秒+0.02,约83分钟从0回到100) */ <<if $regionRichness < 100>> <<set $regionRichness = Math.min(100, (Number($regionRichness)||0) + 0.02)>> <</if>> /* 深度变化 */ <<set _depthSpd = Number($depthspd)>> <<if isNaN(_depthSpd)>> <<set _depthSpd = 0>> /* 或者设置一个默认值 */ <</if>> <<set $depthnoc = Number($depthnoc) + _depthSpd * Math.floor($sailspd / 50)>> /* 硬截断:不允许突破当前地形的深度范围 */ <<set _dMin = $mapinfo[$maptype] ? $mapinfo[$maptype].depthmin : 20>> <<set _dMax = $mapinfo[$maptype] ? $mapinfo[$maptype].depthmax : 10000>> <<if $depthnoc < _dMin>><<set $depthnoc = _dMin>><</if>> <<if $depthnoc > _dMax>><<set $depthnoc = _dMax>><</if>> <<set $depthdeep = Math.floor($depthnoc)>> <<if $depth > $depthdeep>> <<set $depth = $depthdeep>> <</if>> /* 判断是否需要重置 depthwave 和 depthspd */ <<if $depthpass > $depthwave || $depthdeep >= $mapinfo[$maptype].depthmax || $depthdeep <= $mapinfo[$maptype].depthmin>> <<set $depthwave = Math.floor(Math.random() * 4001) + 1000>> /* 根据 $nav.slopeDir 决定深度速度取值范围 */ <<set _spdmax = $mapinfo[$maptype].spdmax>> <<set _spdmin = $mapinfo[$maptype].spdmin>> <<if $nav.slopeDir === "downhill">> /* 下坡:只取正速度 */ <<set $depthspd = (Math.random() * (_spdmax - 0) + 0).toFixed(1)>> <<elseif $nav.slopeDir === "uphill">> /* 上坡:只取负速度 */ <<set $depthspd = (Math.random() * (0 - (-_spdmax)) + (-_spdmax)).toFixed(1)>> <<else>> /* natural:原逻辑不变 */ <<set $depthspd = (Math.random() * (_spdmax - _spdmin) + _spdmin).toFixed(1)>> <</if>> <<set $depthpass = 0>> <</if>> /* ═══ WorldScene 队列检测 ═══ */ /* 检查当前 $worldScene 状态转换 */ <<if $worldScene && typeof $worldScene === "object">> <<if $worldScene.state === "pending" && $map >= $worldScene.approachAt>> <<set $worldScene.state = "approaching">> <</if>> <<if $worldScene.state === "approaching" && $map >= $worldScene.mapStart>> <<set $worldScene.state = "inside">> <<set $sailspd = 0>> <</if>> /* inside → leaving:驶过 mapEnd 进入离开段 */ <<if $map > $worldScene.mapEnd && $worldScene.state === "inside">> <<set $worldScene.state = "leaving">> <<set $wsChild = null>> <</if>> /* leaving → done:驶过 leaveEnd 完成归档 */ <<if $worldScene.state === "leaving" && $worldScene.leaveEnd && $map >= $worldScene.leaveEnd>> <<set $worldScene.state = "done">> /* 有地图长度的中型事件完整离场后,遭遇距离从当前位置重新起算。 */ <<resetEventDistance>> /* 同步写回队列 */ <<if $worldSceneQueue && $worldSceneQueueIdx < $worldSceneQueue.length>> <<set $worldSceneQueue[$worldSceneQueueIdx].state = "done">> <</if>> /* 推进到队列中的下一个 */ <<if $worldSceneQueue && $worldSceneQueueIdx + 1 < $worldSceneQueue.length>> <<set $worldSceneQueueIdx = $worldSceneQueueIdx + 1>> <<set $worldScene = $worldSceneQueue[$worldSceneQueueIdx]>> <</if>> <</if>> <</if>> /* ═══ LargeScene 状态机 ═══ */ <<if $largeScene && typeof $largeScene === "object" && $largeScene.state !== "done">> /* pending → approaching:仅进入接近段后才显示大型区域提示。 */ <<if $largeScene.state === "pending" && $map >= $largeScene.approachStart>> <<set $largeScene.state = "approaching">> <</if>> /* approaching → active */ <<if $largeScene.state === "approaching" && $map >= $largeScene.approachEnd>> <<set $largeScene.state = "active">> <</if>> /* active 期间 zone 触发 */ <<if $largeScene.state === "active">> <<for _lzi = 0; _lzi < $largeScene.zones.length; _lzi++>> <<set _lz = $largeScene.zones[_lzi]>> <<if _lz.st === "pending" && $map >= _lz.zoneAt>> <<set $largeScene.zones[_lzi].st = "arriving">> <<set $largeScene.activeZone = _lzi>> <<if !$worldScene || $worldScene.state === "done">> <<worldSceneDefs>> <<set _lzDef = $wsDefs[_lz.wsType]>> <<if _lzDef>> /* 使用生成阶段已预留的区间,避免触发时因当前位置漂移破坏排布。 */ <<set _lzStart = _lz.mapStart || $map>> <<set _lzEnd = _lz.mapEnd || (_lzStart + _lzDef.spanMin + Math.floor(Math.random()*(_lzDef.spanMax-_lzDef.spanMin+1)))>> <<set _lzAppr = _lz.approachAt || Math.max(0, _lzStart - 800)>> <<set _lzLeave = _lz.leaveEnd || (_lzEnd + 1000)>> <<set $worldScene = {id:_lz.wsType,name:_lz.name,state:"inside",approachDesc:"前方出现"+_lz.name,approachAt:_lzAppr,mapStart:_lzStart,mapEnd:_lzEnd,leaveEnd:_lzLeave,children:_lzDef.children,doneCids:[]}>> <<set $sailspd = 0>> <</if>> <</if>> <</if>> <<if _lz.st === "arriving" && $worldScene && $worldScene.state === "done">> <<set $largeScene.zones[_lzi].st = "done">> <</if>> <</for>> /* 所有 zone 完成 → leaving */ <<set _lzAllDone = 1>> <<for _lzi = 0; _lzi < $largeScene.zones.length; _lzi++>> <<if $largeScene.zones[_lzi].st !== "done">><<set _lzAllDone = 0>><<break>><</if>> <</for>> <<if _lzAllDone>><<set $largeScene.state = "leaving">><</if>> <</if>> /* leaving → done */ <<if $largeScene.state === "leaving" && $map >= $largeScene.leaveEnd>> <<set $largeScene.state = "done">> <</if>> <</if>> /* 持续小型事件:驶出其长度后自动结束;interupt=false 的观景/追逐事件可在行驶中保留。 */ <<if $activeSmallEvent && $activeSmallEvent.leaveEnd && $map >= $activeSmallEvent.leaveEnd>> <<if !$activeSmallEvent.finished>><<set $lastSmallEventText = $activeSmallEvent.name + " 已在身后消失。">><</if>> <<set $activeSmallEvent = null>> /* 有地图长度的小型事件完整离场后,遭遇距离从当前位置重新起算。 */ <<resetEventDistance>> <</if>> /* temporal event tick */ <<if $temporalEvent && $temporalEvent !== 0>><<resolveTemporalEvent>><</if>> <<if !$temporalEvent && $sailspd > 0>><<spawnTemporalEvent>><</if>> /* ══ 燃料消耗 ══ */ <<if !$fuelDefs>><<fuelDefs>><</if>> <<set _fDepth = $depth>> /* 隔热层减少燃料深度系数 */ <<set _fHullLv = Number($upgrades ? $upgrades.hull : 0) || 0>> <<set _fHullMod = [0, 0.3, 0.6, 1.0][_fHullLv] || 0>> <<set _fDepthBase = (_fDepth > 800) ? 4.0 : (_fDepth > 300) ? 2.5 : (_fDepth > 100) ? 1.5 : 1.0>> <<set _fDepthFactor = Math.max(1.0, _fDepthBase - _fHullMod)>> <<set _fSpdFactor = ($spdmax > 0 && $sailspd > 0) ? ($sailspd / $spdmax) : 0>> <<set _fBurn = 0.05 + _fSpdFactor * 0.15 * _fDepthFactor>> /* 加压舱安全深度:超限时额外损耗 $shell */ <<set _fPressLv = Number($upgrades ? $upgrades.pressure : 0) || 0>> <<set _fSafeDepth = [300, 600, 1500, 5000][_fPressLv] || 300>> <<if $depth > _fSafeDepth>> <<set _fOverDepth = $depth - _fSafeDepth>> <<set _fHullDmg = Math.max(0, 0.02 * (1 - _fHullLv * 0.2) * (_fOverDepth / 100))>> <<set $shell = Math.max(0, ($shell||100) - _fHullDmg)>> <</if>> <<set $fuel = Math.max(0, $fuel - _fBurn)>> /* 燃料耗尽:进入漂流状态 */ <<if $fuel <= 0 && !$driftMode>> <<set $driftMode = true>> <<set $sailspd = 0>> <</if>> /* 漂流状态:强制停止,禁用下潜(UI层控制),不强制上浮 */ <<if $driftMode>> <<set $sailspd = 0>> <</if>> /* 加了燃料后自动解除漂流 */ <<if $driftMode && $fuel > 5>><<set $driftMode = false>><</if>> /* ══ 地点触发检查(占位)══ */ <<locationTrigger>> /* 普通航行微事件只在发现点附近有效;起锚驶离后自动消失。 */ <<if $activeMicroEvent && $sailMode === "travel" && Number($activeMicroEvent.leaveEnd) > 0 && $map >= Number($activeMicroEvent.leaveEnd)>> <<set $activeMicroEvent = null>> <</if>> <<checkEnvEffects>> <<checkEvent>> <<tickEvent>> <</widget>> <</nobr>>
<<nobr>> <<widget "smallEventPanel">> /* 渲染当前 $activeSmallEvent 的描述+选项 $args[0] = "sailing" | "anchored"(决定跳转目标,默认 anchored) 在 <<repeat>> 环境中必须通过 widget 间接调用,不能内联 <<for>> */ <<if !$smallEventDefs>><<smallEventTable>><</if>> <<if $activeSmallEvent>> <<set _spId = String($activeSmallEvent.id)>> <<set _spDef = $smallEventDefs[_spId]>> <<if _spDef>> <<set _spCtxSail = ($args && $args[0] === "sailing")>> <div style="border:1px solid var(--teal-bright);border-radius:3px;padding:0.3rem 0.5rem;margin-bottom:0.25rem;background:rgba(0,180,150,0.04);"> <div style="font-size:0.74rem;color:var(--teal-bright);margin-bottom:0.08rem;">⚑ <<print _spDef.name>></div> <div style="font-size:0.8rem;color:var(--bone);line-height:1.75;margin-bottom:0.12rem;"><<print $activeSmallEvent.stageDesc>></div> <div style="font-size:0.76rem;"> <<for _spai = 0; _spai < $activeSmallEvent.actions.length; _spai++>> <<set _spaAct = $activeSmallEvent.actions[_spai]>> <<capture _spaAct, _spCtxSail>> <<if _spCtxSail>> <<link _spaAct>><<resolveSmallEvent _spaAct>><</link>> · <<else>> <div style="margin-bottom:0.05rem;"><<link _spaAct>><<resolveSmallEvent _spaAct>><</link>></div> <</if>> <</capture>> <</for>> </div> </div> <<if $lastSmallEventText>> <div style="border-left:2px solid var(--teal-bright);padding:0.15rem 0.4rem;margin-bottom:0.15rem;font-size:0.78rem;color:var(--bone);"><<print $lastSmallEventText>></div> <<set $lastSmallEventText = "">> <</if>> <<else>> <<set $activeSmallEvent = null>> <</if>> <<else>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnCombat">> /* 调用:<<spawnCombat [forceid]>> 无参数=随机,有forceid=强制 */ <<if !$combatEnemyTable>><<combatEnemyDefs>><</if>> <<set _scForce = ($args && $args[0]) ? String($args[0]) : "">> <<set _scDef = _scForce ? $combatEnemyTable[_scForce] : null>> <<set _scId = _scForce ? _scForce : "">> <<if !_scDef>> /* 深度分层随机池 */ <<set _scPool = []>> <<if $depth <= 80>> <<run _scPool.push("jellyfish_swarm", "jellyfish_swarm", "armored_crab")>> <<elseif $depth <= 200>> <<run _scPool.push("armored_crab", "armored_crab", "deep_eel", "patrol_shark")>> <<else>> <<run _scPool.push("patrol_shark", "deep_eel", "angler_lurker", "angler_lurker")>> <</if>> <<set _scId = _scPool[Math.floor(Math.random() * _scPool.length)]>> <<set _scDef = $combatEnemyTable[_scId]>> <</if>> <<if !_scDef>><<return>><</if>> <<combatInit _scId "仓外探索">> <<goto "战斗">> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnLargeScene">> /* ═══════════════════════════════════════════════ 大型场景生成 距离参数(原始值 / 可见坐标): 接近段 = 2000 / 40 活跃段 = 15000 / 300 离开段 = 2000 / 40 前后缓冲 = 10000 / 200 生成概率:15% 候选池:sunken_city(浅水沙/岩)、wreck_graveyard(通用) ═══════════════════════════════════════════════ */ <<if !$largeScene || $largeScene === 0>> <<largeSceneDefs>> <<set _lsCands = []>> /* 沉没城市(城市废墟):浅中水深,放宽到多种地形小概率出现(规范:城市废墟可小概率跨地形生成) */ <<if $depthdeep >= 20 && $depthdeep <= 800 && ($maptype === "sand" || $maptype === "flat" || $maptype === "cliff" || $maptype === "grass" || $maptype === "reef" || $maptype === "forest")>> <<set _lsCands[_lsCands.length] = "sunken_city">> <</if>> /* 沉船坟场(沉船群):通用,大部分地形(规范:沉船群可小概率跨地形生成,已放宽) */ <<if $depthdeep >= 20 && ($maptype === "sand" || $maptype === "flat" || $maptype === "cliff" || $maptype === "grass" || $maptype === "reef" || $maptype === "forest")>> <<set _lsCands[_lsCands.length] = "wreck_graveyard">> <</if>> /* 残坑(峭壁) */ <<if $depthdeep >= 20 && $maptype === "cliff">> <<set _lsCands[_lsCands.length] = "cliff_pit">> <</if>> /* 牧场(海草床) */ <<if $depthdeep >= 20 && $maptype === "grass">> <<set _lsCands[_lsCands.length] = "pasture">> <</if>> /* 永夜礁石(珊瑚礁) */ <<if $depthdeep >= 20 && $maptype === "reef">> <<set _lsCands[_lsCands.length] = "reef_eternal">> <</if>> /* 人鱼狱(海藻森林) */ <<if $depthdeep >= 20 && $maptype === "forest">> <<set _lsCands[_lsCands.length] = "mermaid_prison">> <</if>> /* 深渊:盐湖区 / 热液泉区 */ <<if $depthdeep >= 20 && $maptype === "abyss">> <<set _lsCands[_lsCands.length] = "salt_lake">> <<set _lsCands[_lsCands.length] = "hydrothermal">> <</if>> <<if _lsCands.length > 0 && Math.random() <= 0.15>> <<set _lsId = _lsCands[Math.floor(Math.random() * _lsCands.length)]>> <<set _lsDef = $largeDefs ? $largeDefs[_lsId] : null>> <<if _lsDef && _lsDef.zoneList && _lsDef.zoneList.length > 0>> /* 固定距离参数 */ <<set _lsApprRaw = 2000>> <<set _lsLeaveRaw = 2000>> <<set _lsValidRaw = 15000>> <<set _lsTotalRaw = _lsApprRaw + _lsValidRaw + _lsLeaveRaw>> <<set _lsBufRaw = 10000>> <<set _lsPlaceMax = $maplim - _lsTotalRaw - _lsBufRaw>> <<if _lsPlaceMax > _lsBufRaw>> <<set _lsOrigin = _lsBufRaw + Math.floor(Math.random() * (_lsPlaceMax - _lsBufRaw + 1))>> <<set _lsApprEnd = _lsOrigin + _lsApprRaw>> <<set _lsActiveEnd = _lsApprEnd + _lsValidRaw>> <<set _lsLeaveEnd = _lsActiveEnd + _lsLeaveRaw>> /* 大型区域记录为 container;其内部 zone 与 B/C 插入中型仍可独立预留。 */ <<reserveMapInterval _lsOrigin _lsLeaveEnd "large" _lsId true>> /* Zone 池随机选 3-5(含绑定 zone 必选,规范 §七) */ <<set _lsPool = _lsDef.zoneList>> <<set _lsBound = _lsDef.boundZones || []>> <<set _lsMinZ = _lsDef.minZones || 3>> <<set _lsMaxZ = _lsDef.maxZones || 5>> <<set _lsSelNames = []>> <<set _lsSel = []>> /* 先放绑定 zone(必选) */ <<for _lsBi = 0; _lsBi < _lsBound.length; _lsBi++>> <<for _lsPi = 0; _lsPi < _lsPool.length; _lsPi++>> <<if _lsPool[_lsPi].name === _lsBound[_lsBi]>> <<set _lsSel[_lsSel.length] = _lsPool[_lsPi]>> <<set _lsSelNames[_lsSelNames.length] = _lsPool[_lsPi].name>> <</if>> <</for>> <</for>> /* 剩余池(去重) */ <<set _lsRemain = []>> <<for _lsPi = 0; _lsPi < _lsPool.length; _lsPi++>> <<set _lsIn = false>> <<for _lsSi = 0; _lsSi < _lsSelNames.length; _lsSi++>> <<if _lsSelNames[_lsSi] === _lsPool[_lsPi].name>><<set _lsIn = true>><</if>> <</for>> <<if !_lsIn>><<set _lsRemain[_lsRemain.length] = _lsPool[_lsPi]>><</if>> <</for>> /* 随机补足到 min~max。SugarCube 不支持 while 循环宏,最多补满剩余池即可。 */ <<set _lsTarget = _lsMinZ + Math.floor(Math.random() * (_lsMaxZ - _lsMinZ + 1))>> <<if _lsTarget > _lsPool.length>><<set _lsTarget = _lsPool.length>><</if>> <<for _lsFill = _lsSel.length; _lsFill < _lsTarget && _lsRemain.length > 0; _lsFill++>> <<set _lsRI = Math.floor(Math.random() * _lsRemain.length)>> <<set _lsSel[_lsSel.length] = _lsRemain[_lsRI]>> <<set _lsRemain.splice(_lsRI, 1)>> <</for>> /* Zone 坐标:在 active 段随机落点;完整区间预留成功才写入,避免重叠。 */ <<worldSceneDefs>><<set _lzCount = _lsSel.length>><<set _lzArr = []>> <<for _lzi = 0; _lzi < _lzCount; _lzi++>> <<set _lzd = _lsSel[_lzi]>><<set _lzDef = $wsDefs[_lzd.wsType]>> <<set _lzSpan = (_lzDef && _lzDef.mapSpan) ? _lzDef.mapSpan : {approach:800,activeMin:1000,activeMax:1000,leave:1000}>><<set _lzApproach = Number(_lzSpan.approach) || 800>><<set _lzActive = Number(_lzSpan.activeMin) || (_lzDef ? _lzDef.spanMin : 1000)>><<set _lzLeave = Number(_lzSpan.leave) || 1000>> <<set _lzPlaced = false>> <<for _lzTry = 0; _lzTry < 40 && !_lzPlaced; _lzTry++>> <<set _lzAt = _lsApprEnd + 500 + Math.floor(Math.random() * Math.max(1, _lsActiveEnd - _lsApprEnd - _lzActive - _lzLeave - 1000))>><<reserveMapInterval _lzAt - _lzApproach _lzAt + _lzActive + _lzLeave "zone" _lzd.wsType false>> <<if $mapReserveOK>><<set _lzArr[_lzArr.length] = {name:_lzd.name,zoneAt:_lzAt,wsType:_lzd.wsType,st:"pending",mapStart:_lzAt,mapEnd:_lzAt+_lzActive,approachAt:_lzAt-_lzApproach,leaveEnd:_lzAt+_lzActive+_lzLeave}>><<set _lzPlaced = true>><</if>> <</for>> <</for>> <<set _lsHints = (_lsDef.approachHint && _lsDef.approachHint.length > 0) ? _lsDef.approachHint : ["前方海域出现了异常。"]>> <<set _lsPickHint = _lsHints[Math.floor(Math.random() * _lsHints.length)]>> <<set $largeScene = { id:_lsId, name:_lsDef.name, viewDesc:_lsDef.viewDesc, approachHint:_lsPickHint, leaveHint:(_lsDef.leaveHint || ""), state:"pending", approachStart:_lsOrigin, approachEnd:_lsApprEnd, activeEnd:_lsActiveEnd, leaveEnd:_lsLeaveEnd, zones:_lzArr, activeZone:-1 }>> <</if>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnMicroEvent">> <<if !$microEventDefs>><<microEventTable>><</if>> /* 构建当前有效候选列表(只存 id 字符串,避免复杂对象进入 <<run>>) */ <<set _mcIds = []>> <<set _mKeys = Object.keys($microEventDefs)>> <<set _curRich = Math.max(0, Number($regionRichness) || 0)>> <<for _mi = 0; _mi < _mKeys.length; _mi++>> <<set _md = $microEventDefs[_mKeys[_mi]]>> <<if _md.devOnly>><<continue>><</if>> /* 地形检查 */ <<set _tOK = false>> <<for _ti = 0; _ti < _md.terrain.length; _ti++>> <<if _md.terrain[_ti] === $maptype>><<set _tOK = true>><<break>><</if>> <</for>> /* 深度检查:新定义优先 depthRule,旧定义兼容 depthRange */ <<set _dOK = true>> <<if _md.depthRule>> <<if _md.depthRule.type === "nearBottom">><<set _dOK = ($depthdeep - $depth <= _md.depthRule.value)>><<elseif _md.depthRule.type === "nearSurface">><<set _dOK = ($depth <= _md.depthRule.value)>><<elseif _md.depthRule.type === "minDepth">><<set _dOK = ($depth >= _md.depthRule.value)>><</if>> <<elseif _md.depthRange>> <<set _dOK = ($depth >= _md.depthRange[0] && $depth <= _md.depthRange[1])>> <</if>> /* richnessBased:丰富度归零则跳过 */ <<set _rOK = true>> <<if _md.richnessBased && _curRich <= 0>><<set _rOK = false>><</if>> <<if _tOK && _dOK && _rOK>> <<run _mcIds.push(_mKeys[_mi])>> <</if>> <</for>> /* 逐一掷骰,第一个成功的生效 */ <<for _mi = 0; _mi < _mcIds.length; _mi++>> <<set _cId = _mcIds[_mi]>> <<set _cDef = $microEventDefs[_cId]>> /* richnessBased 事件概率随丰富度线性缩放 */ <<set _cChance = _cDef.baseChance>> <<if _cDef.richnessBased>> <<set _cChance = _cDef.baseChance * (_curRich / 100)>> <</if>> <<if Math.random() < _cChance>> <<set _cmRegion = ($largeScene && typeof $largeScene === "object") ? String($largeScene.id || "") : "">> <<set _cmVariant = (_cDef.regionVariants && _cmRegion && _cDef.regionVariants[_cmRegion]) ? _cDef.regionVariants[_cmRegion] : null>> <<set $activeMicroEvent = {id:_cId,name:(_cmVariant && _cmVariant.name) ? _cmVariant.name : (_cDef.name || _cDef.fragmentText),desc:(_cmVariant && _cmVariant.desc) ? _cmVariant.desc : (_cDef.desc || _cDef.fragmentText),action:(_cmVariant && _cmVariant.action) ? _cmVariant.action : (_cDef.action || _cDef.actionLabel),regionVariant:(_cmVariant ? _cmRegion : ""),mapAt:$map,leaveEnd:$map + 300}>> <<break>> <</if>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnNpc">> /* 调用:<> ctx = "sailing" / "anchored" 结果:命中则写入 $activeNpc,否则为 null */ <<if !$npcDefTable>><<npcDefs>><</if>> <<set _snCtx = ($args && $args[0]) ? String($args[0]) : "sailing">> /* 冷却检查(tick冷却优先)*/ <<if ($npcCooldownTicks || 0) > 0>><<return>><</if>> <<if ($npcSpawnCooldown || 0) > ($day || 0)>><<return>><</if>> /* 已有 NPC 则不再生成 */ <<if $activeNpc>><<return>><</if>> /* 构建候选池 */ <<set _snPool = []>> <<set _snKeys = Object.keys($npcDefTable)>> <<for _sni = 0; _sni < _snKeys.length; _sni++>> <<set _snDef = $npcDefTable[_snKeys[_sni]]>> <<if _snDef.spawnCtx.includes(_snCtx)>> /* 条件检查(字符串 eval 包裹在 try) */ <<set _snOk = false>> <<if _snDef.condition === "always">> <<set _snOk = true>> <<elseif _snDef.condition === "\$depth <= 100">> <<set _snOk = ($depth <= 100)>> <<elseif _snDef.condition === "\$depth >= 150">> <<set _snOk = ($depth >= 150)>> <</if>> <<if _snOk>> <<for _snW = 0; _snW < _snDef.weight; _snW++>> <<run _snPool.push(_snKeys[_sni])>> <</for>> <</if>> <</if>> <</for>> <<if _snPool.length === 0>><<return>><</if>> /* 基础触发概率:每次 sail tick 约 0.1% */ <<set _snRoll = Math.random()>> <<if _snRoll > 0.001>><<return>><</if>> /* 抽取 NPC */ <<set _snId = _snPool[Math.floor(Math.random() * _snPool.length)]>> <<set _snDef = $npcDefTable[_snId]>> <<set $activeNpc = _snDef>> /* 航速归零,强制玩家处理遭遇 */ <<set $sailspd = 0>> /* 触发支线(首次相遇)*/ <<if _snDef.sideQuestId>> <<questCheck "npcMet" _snId>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnSmallEvent">> /* ────────────────────────────────────────── spawnSmallEvent — 第二批实装 调用:<<spawnSmallEvent ctx [mult]>> ctx = "sailing" / "anchored" / "outside" mult = 概率倍数(可选,默认 1) 结果:命中则写入 $pendingEvent,否则置 null ────────────────────────────────────────── */ /* 参数读取(安全访问 $args,修复启动期 Warning) */ <<set _spCtx = ($args && $args.length > 0) ? String($args[0]) : $currentContext>> <<set _spMult = ($args && $args.length > 1) ? Number($args[1]) : 1>> /* 上下文校验 */ <<if _spCtx !== "sailing" && _spCtx !== "anchored" && _spCtx !== "outside">> <<set _spCtx = $currentContext>> <</if>> /* 初始化事件池定义 */ <<if !$smallEventDefs>><<smallEventTable>><</if>> /* ── 优先:就近 kelp_farm 成熟检查 ── */ <<set _spKelpReady = false>> <<for _spKI = 0; _spKI < $envEffects.length; _spKI++>> <<set _spKEff = $envEffects[_spKI]>> <<if _spKEff.type === "kelp_farm" && _spKEff.state === "ready" && _spKEff.terrain === $maptype && $depth >= _spKEff.depthMin && $depth <= _spKEff.depthMax>> <<set _spKelpReady = true>> <<break>> <</if>> <</for>> <<if _spKelpReady && !$activeSmallEvent>> <<set _spKD = $smallEventDefs["kelp_harvest"]>> <<if _spKD>> <<set $pendingEvent = {id:"kelp_harvest", name:_spKD.name, stageIdx:0, stageDesc:_spKD.stages[0].desc, actions:_spKD.stages[0].actions, lootLog:""}>> <<return>> <</if>> <</if>> /* ── 过滤候选池 ── */ <<set _spCands = []>> <<set _spKeys = Object.keys($smallEventDefs)>> <<for _spI = 0; _spI < _spKeys.length; _spI++>> <<set _spId = _spKeys[_spI]>> <<set _spDef = $smallEventDefs[_spId]>> <<if _spDef.devOnly>><<continue>><</if>> /* 上下文过滤 */ <<set _spCtxOK = false>> <<if _spDef.context>> <<for _spCI = 0; _spCI < _spDef.context.length; _spCI++>> <<if _spDef.context[_spCI] === _spCtx>> <<set _spCtxOK = true>> <<break>> <</if>> <</for>> <<else>> <<set _spCtxOK = true>> <</if>> <<if !_spCtxOK>><<continue>><</if>> /* 地形过滤 */ <<set _spTOK = false>> <<if _spDef.terrain>> <<for _spTI = 0; _spTI < _spDef.terrain.length; _spTI++>> <<if _spDef.terrain[_spTI] === $maptype>> <<set _spTOK = true>> <<break>> <</if>> <</for>> <<else>> <<set _spTOK = true>> <</if>> <<if !_spTOK>><<continue>><</if>> /* 深度过滤:新定义优先 depthRule,旧定义兼容 depthRange */ <<set _spDOK = true>> <<if _spDef.depthRule>> <<if _spDef.depthRule.type === "nearBottom">><<set _spDOK = ($depthdeep - $depth <= _spDef.depthRule.value)>><<elseif _spDef.depthRule.type === "nearSurface">><<set _spDOK = ($depth <= _spDef.depthRule.value)>><<elseif _spDef.depthRule.type === "minDepth">><<set _spDOK = ($depth >= _spDef.depthRule.value)>><</if>> <<elseif _spDef.depthRange>> <<if $depth < _spDef.depthRange[0] || $depth > _spDef.depthRange[1]>><<set _spDOK = false>><</if>> <</if>> <<if !_spDOK>><<continue>><</if>> <<set _spCands[_spCands.length] = _spId>> <</for>> /* Fisher-Yates 乱序 */ <<for _spI = _spCands.length - 1; _spI > 0; _spI-->> <<set _spJ = Math.floor(Math.random() * (_spI + 1))>> <<set _spTmp = _spCands[_spI]>> <<set _spCands[_spI] = _spCands[_spJ]>> <<set _spCands[_spJ] = _spTmp>> <</for>> /* 逐一掷骰,首中写入 $pendingEvent */ <<set $pendingEvent = null>> <<for _spI = 0; _spI < _spCands.length; _spI++>> <<set _spD2 = $smallEventDefs[_spCands[_spI]]>> <<if _spD2 && Math.random() < _spD2.baseChance * _spMult>> <<set $pendingEvent = {id:_spCands[_spI], name:_spD2.name, stageIdx:0, stageDesc:_spD2.stages[0].desc, actions:_spD2.stages[0].actions, lootLog:""}>> <<break>> <</if>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnTemporalEvent">> <<if $temporalEvent>><<return>><</if>> <<temporalEventDefs>> <<set _tKeys = Object.keys($temporalDefs)>> <<for _ti = 0; _ti < _tKeys.length; _ti++>> <<set _tid = _tKeys[_ti]>> <<set _td = $temporalDefs[_tid]>> <<if _td.terrain.indexOf($maptype) < 0>><<continue>><</if>> <<if $depth < _td.dMin>><<continue>><</if>> <<if $san > _td.sanMax>><<continue>><</if>> <<if Math.random() >= _td.chance>><<continue>><</if>> <<set $temporalEvent = {id:_tid, name:_td.name, prog:0, speed:_td.speed, warnAt:_td.warnAt, warnText:_td.warnText, endText:_td.endText, effect:_td.effect, amount:_td.amount, warned:0}>> <<break>> <</for>> <</widget>> <</nobr>>
<<nobr>> <<widget "spawnWorldScene">> /* ═══════════════════════════════════════════════ 中型场景(独立)生成 距离参数(原始值 / 可见坐标): 接近段 = 1000 / 20(approachAt = mapStart - 1000) 场景段 = 1000 / 20(spanMin=spanMax=1000) 离开段 = 1000 / 20(leaveEnd = mapEnd + 1000) 只生成 modes 包含 "independent" 或 "both" 的类型 生成数量:min(3, floor(budget/70)) ═══════════════════════════════════════════════ */ <<if !$largeScene || $largeScene === 0 || $largeScene.state === "done">> <<worldSceneDefs>> <<set _wsCands = []>> <<set _wsKeys = Object.keys($wsDefs)>> <<for _wfi = 0; _wfi < _wsKeys.length; _wfi++>> <<set _wfd = $wsDefs[_wsKeys[_wfi]]>> <<set _wfMode = _wfd.modes || "both">> /* 只独立 和 二者皆可 的才能独立生成;devOnly 占位仅供 DEV 手动验证 */ <<if !_wfd.devOnly && (_wfMode === "independent" || _wfMode === "both")>> /* 地形过滤:terrain 为空数组 / 未定义 = 不限地形(向后兼容,如鲸落) */ <<set _wfTer = _wfd.terrain || []>> <<set _wfTerOk = (_wfTer.length === 0)>> <<for _wti = 0; _wti < _wfTer.length; _wti++>> <<if _wfTer[_wti] === $maptype>><<set _wfTerOk = true>><</if>> <</for>> /* 深度过滤 */ <<if _wfTerOk && _wfd.spanMin && $depthdeep >= 20>> <<set _wsCands[_wsCands.length] = _wsKeys[_wfi]>> <</if>> <</if>> <</for>> <<if _wsCands.length > 0>> /* 生成数量:基于地形长度 */ <<set _wsTerrainUnits = Math.floor($maplim / 50)>> <<set _wsBudget = Math.floor(_wsTerrainUnits * 0.4)>> <<set _wsCount = Math.min(3, Math.floor(_wsBudget / 70))>> <<if _wsCount > 0>> <<set _wsBufRaw = 5000>> <<set _wsSlotRaw = Math.max(3500, Math.floor(($maplim - _wsBufRaw * 2) / _wsCount))>> <<set $worldSceneQueue = []>> <<for _qsi = 0; _qsi < _wsCount; _qsi++>> /* 加权随机选类型 */ <<set _wsW = {}>> <<for _wi = 0; _wi < _wsCands.length; _wi++>> <<set _wsW[_wsCands[_wi]] = $wsDefs[_wsCands[_wi]].weight || 10>> <</for>> <<set _wsTotalW = 0>> <<for _wi = 0; _wi < _wsCands.length; _wi++>><<set _wsTotalW += _wsW[_wsCands[_wi]]>><</for>> <<set _wsRoll = Math.random() * _wsTotalW>> <<set _wsCumW = 0>><<set _wsChosen = _wsCands[0]>> <<for _wi = 0; _wi < _wsCands.length; _wi++>> <<set _wsCumW += _wsW[_wsCands[_wi]]>> <<if _wsRoll < _wsCumW>><<set _wsChosen = _wsCands[_wi]>><<break>><</if>> <</for>> /* 内联字段 */ <<set _wsDef2 = $wsDefs[_wsChosen]>> <<set _wsName = _wsDef2.name>> <<set _wsAppr = _wsDef2.approachDesc || "前方有异常。">> <<set _wsSpan = _wsDef2.mapSpan || {approach:1000,activeMin:(_wsDef2.spanMin || 1000),activeMax:(_wsDef2.spanMax || 1000),leave:1000}>><<set _wsSpanMin = Number(_wsSpan.activeMin) || _wsDef2.spanMin || 1000>><<set _wsSpanMax = Number(_wsSpan.activeMax) || _wsDef2.spanMax || 1000>><<set _wsApproach = Number(_wsSpan.approach) || 0>><<set _wsLeave = Number(_wsSpan.leave) || 0>> <<set _wsKids = _wsDef2.children || []>> <<if _wsName>> <<set _wsPlaced = false>> <<for _wsTry = 0; _wsTry < 40 && !_wsPlaced; _wsTry++>> <<set _wsStart = _wsBufRaw + Math.floor(Math.random() * Math.max(1, $maplim - _wsBufRaw*2 - _wsSpanMax))>><<set _wsLen = _wsSpanMin + Math.floor(Math.random() * (_wsSpanMax - _wsSpanMin + 1))>><<set _wsEnd = _wsStart + _wsLen>><<reserveMapInterval _wsStart-_wsApproach _wsEnd+_wsLeave "independent_middle" _wsChosen false>> <<if $mapReserveOK>> <<run $worldSceneQueue.push({id:_wsChosen,name:_wsName,approachDesc:_wsAppr,state:"pending",mapStart:_wsStart,mapEnd:_wsEnd,leaveEnd:_wsEnd+_wsLeave,approachAt:_wsStart-_wsApproach,children:_wsKids,doneCids:[]})>><<set _wsPlaced = true>> <</if>> <</for>> <</if>> <</for>> <<if $worldSceneQueue.length > 0>> <<set $worldScene = $worldSceneQueue[0]>> <<set $worldSceneQueueIdx = 0>> <</if>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "take">> <<set _tk_id = $args[0]>> <<set _tk_qty = $args[1]>> <<set _tk_def = State.variables.items[_tk_id]>> <<if !_tk_def>> <<print "错误:未知物品 " + _tk_id>> <<else>> <<set _tk_type = _tk_def.type>> /* 在仓库找索引 */ <<set _tk_stIdx = -1>> <<if $store[_tk_type]>> <<for _tk_i = 0; _tk_i < $store[_tk_type].length; _tk_i++>> <<if $store[_tk_type][_tk_i].id === _tk_id>> <<set _tk_stIdx = _tk_i>> <<break>> <</if>> <</for>> <</if>> <<if _tk_stIdx < 0 || $store[_tk_type][_tk_stIdx].quantity < _tk_qty>> <<print "仓库中 " + _tk_def.name + " 数量不足">> <<else>> /* 记录来源条目的 addedDay */ <<set _tk_srcDay = $store[_tk_type][_tk_stIdx].addedDay>> /* 从仓库扣除 */ <<set $store[_tk_type][_tk_stIdx].quantity -= _tk_qty>> /* 向背包添加:按 addedDay 分批 */ <<if !$backpack[_tk_type]>><<set $backpack[_tk_type] = []>><</if>> <<set _tk_bpIdx = -1>> <<for _tk_i = 0; _tk_i < $backpack[_tk_type].length; _tk_i++>> <<set _tk_bpe = $backpack[_tk_type][_tk_i]>> <<if _tk_bpe.id === _tk_id>> <<if (!_tk_srcDay && !_tk_bpe.addedDay) || _tk_bpe.addedDay === _tk_srcDay>> <<set _tk_bpIdx = _tk_i>> <<break>> <</if>> <</if>> <</for>> <<if _tk_bpIdx >= 0>> <<set $backpack[_tk_type][_tk_bpIdx].quantity += _tk_qty>> <<else>> <<set _tk_newEntry = { id: _tk_id, quantity: _tk_qty }>> <<if _tk_srcDay>><<set _tk_newEntry.addedDay = _tk_srcDay>><</if>> <<run State.variables.backpack[_tk_type].push(_tk_newEntry)>> <</if>> <<print "取出 " + _tk_qty + " × " + _tk_def.name>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "takeAll">> <<set _ta_id = $args[0]>> <<set _ta_def = State.variables.items[_ta_id]>> <<if !_ta_def>> <<set $lastTakeText = "未知物品。">> <<else>> <<set _ta_type = _ta_def.type>> <<set _ta_idx = -1>> <<if $store[_ta_type]>> <<for _ta_i = 0; _ta_i < $store[_ta_type].length; _ta_i++>> <<if $store[_ta_type][_ta_i].id === _ta_id>> <<set _ta_idx = _ta_i>> <<break>> <</if>> <</for>> <</if>> <<if _ta_idx < 0 || $store[_ta_type][_ta_idx].quantity <= 0>> <<set $lastTakeText = "仓库中已经没有" + _ta_def.name + "了。">> <<else>> <<set _ta_qty = $store[_ta_type][_ta_idx].quantity>> <<take _ta_id _ta_qty>> <<set $lastTakeText = "已取出全部 " + _ta_qty + " × " + _ta_def.name>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "tickEvent">> <<if $activeEvent && $activeEvent.type === "unstable">> <<set $eventTimer -= 1>> <<if $eventTimer <= 0>> <<run $eventLog.push({ id: $activeEvent.id, name: $activeEvent.name, outcome: "消散" })>> <<set $activeEvent = 0>> <<set $eventTimer = 0>> <<set $eventPass = 0>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "upgradeDefs">> <<set $upgradeDefs = { hull: { name: "船体隔热层", desc: "强化船体外壳的隔热材料,降低深海水压和温度造成的结构损耗。", maxLevel: 3, levels: [ { label:"无防护", effect:"深海损耗基准×1.0,燃料深度系数基准" }, { label:"基础隔热", effect:"300m以深损耗-20%,深度燃料系数-0.3", cost:{metal:4, gears:2} }, { label:"复合隔热", effect:"600m以深损耗-40%,深度燃料系数-0.6", cost:{metal:8, gears:4, wood:3} }, { label:"深渊隔热", effect:"全深度损耗-60%,深度燃料系数-1.0", cost:{metal:15, gears:8, glass:3} } ] }, pressure: { name: "加压舱改造", desc: "改造压力舱结构,扩展潜艇安全作业的深度范围。", maxLevel: 3, levels: [ { label:"标准压力舱", effect:"安全深度上限300m" }, { label:"加强压力舱", effect:"安全深度上限600m", cost:{metal:6, gears:3} }, { label:"深海压力舱", effect:"安全深度上限1500m", cost:{metal:12, gears:6, glass:4} }, { label:"极深压力舱", effect:"安全深度上限5000m", cost:{metal:20, gears:12, coal:5} } ] }, thruster: { name: "推进器", desc: "升级推进系统,提升最高航行速度上限。", maxLevel: 3, levels: [ { label:"基础推进器", effect:"最高速度100" }, { label:"改良推进器", effect:"最高速度200", cost:{metal:5, gears:3} }, { label:"高效推进器", effect:"最高速度350", cost:{metal:10, gears:6, coal:4} }, { label:"涡轮推进器", effect:"最高速度500", cost:{metal:18, gears:10, coal:8} } ] }, arm: { name: "机械臂", desc: "为潜艇安装机械臂,解锁仓外探索的操作权限。", maxLevel: 2, levels: [ { label:"未安装", effect:"仓外探索只能观察,无法操作元素" }, { label:"基础机械臂", effect:"解锁粗操作:大型物品拆卸、环境资源采集", cost:{metal:8, gears:5, glass:2} }, { label:"精密机械臂", effect:"解锁精细操作:捕捉生物、拾取细小物品", cost:{metal:15, gears:10, glass:4} } ] }, oxygen_sys: { name: "氧气循环系统", desc: "升级仓外氧气装备,增加出仓可携带的氧气上限。", maxLevel: 3, levels: [ { label:"基础气瓶", effect:"出仓氧气上限100" }, { label:"扩容气瓶", effect:"出仓氧气上限160", cost:{metal:4, gears:3} }, { label:"循环呼吸器", effect:"出仓氧气上限250", cost:{metal:8, gears:5, glass:3} }, { label:"深海压力服", effect:"出仓氧气上限400", cost:{metal:15, gears:8, glass:6} } ] }, fuel_tank: { name: "燃料槽扩容", desc: "扩大燃料储存槽容积,延长续航里程。", maxLevel: 3, levels: [ { label:"标准燃料槽", effect:"燃料上限300" }, { label:"扩容燃料槽", effect:"燃料上限500", cost:{metal:4, wood:5} }, { label:"大型燃料槽", effect:"燃料上限800", cost:{metal:8, wood:8, gears:3} }, { label:"超大型燃料槽", effect:"燃料上限1400", cost:{metal:15, wood:12, gears:6} } ] }, kitchen: { name: "厨房设备扩充", desc: "扩建厨房设备,解锁更多烹饪方式。", maxLevel: 3, levels: [ { label:"基础灶台", effect:"可用:明火烤、生食", cost:{} }, { label:"铜锅安装", effect:"新增:铜锅炖", cost:{metal:3, coal:4} }, { label:"蒸笼与铁锅", effect:"新增:清蒸、煎炒", cost:{metal:6, wood:5, coal:6} }, { label:"深油炸台", effect:"新增:油炸", cost:{metal:10, wood:8, coal:8, glass:3} } ] }, alchemy: { name: "炼金台扩充", desc: "扩建炼金工作台,解锁更多相变操作。", maxLevel: 3, levels: [ { label:"精炼台", effect:"可用:精炼台(原料→精质)", cost:{} }, { label:"溶解皿", effect:"新增:溶解皿(黑化,固→液)", cost:{metal:4, glass:3} }, { label:"蒸馏器·凝结炉", effect:"新增:蒸馏器(白化)、凝结炉(黄化)", cost:{metal:8, glass:5, gears:4} }, { label:"赤化炉", effect:"新增:赤化炉(赤化,→离子态)", cost:{metal:15, glass:8, gears:8} } ] } }>> <</widget>> <</nobr>>
<<nobr>> <<widget "view">> /* 时段判定 */ <<if $showhour >= 5 && $showhour < 7>> <<set _time = "dusk">> <<elseif $showhour >= 7 && $showhour < 17>> <<set _time = "day">> <<elseif $showhour >= 17 && $showhour < 19>> <<set _time = "dawn">> <<else>> <<set _time = "night">> <</if>> <<set _weather = $viewweather[$weather]>> <<set _depth = $depth>> /* 地形判定:靠近海底100米内显示地形,否则显示水中 */ <<set _rawTerrain = ($depthdeep - _depth <= 100) ? $maptype : "water">> /* 安全fallback:若viewmap中没有该地形则使用sand */ <<set _terrain = ($viewmap[_rawTerrain] !== undefined) ? _rawTerrain : "sand">> /* 光照等级判定 */ <<set _lightKey = _time + "_" + _weather>> <<if $viewlight.bright.hasOwnProperty(_lightKey)>> <<set _lightLevel = "bright">> <<elseif $viewlight.hazy.hasOwnProperty(_lightKey)>> <<set _lightLevel = "hazy">> <<elseif $viewlight.dim.hasOwnProperty(_lightKey)>> <<set _lightLevel = "dim">> <<else>> <<set _lightLevel = "dark">> <</if>> /* 安全fallback:若该地形缺少当前光照等级的描述,降级到dim或dark */ <<if $viewmap[_terrain][_lightLevel] === undefined>> <<if $viewmap[_terrain].dim !== undefined>> <<set _lightLevel = "dim">> <<else>> <<set _lightLevel = "dark">> <</if>> <</if>> <<set _output = "">> /* 表层(0-80米):显示天气光照 + 地形 */ <<if _depth <= 80>> <<set _output = $viewlight[_lightLevel][_lightKey] || "">> <<set _output += "。" + $viewmap[_terrain][_lightLevel]>> /* 中层(80-300米):看不清海面,只显示地形 */ <<elseif _depth <= 300>> <<set _output = "这里有些难以看清海面的状况," + $viewmap[_terrain][_lightLevel]>> /* 深层(300-1000米):光照强制降为dim,deep强制降为dark */ <<elseif _depth <= 1000>> <<if _lightLevel === "bright" || _lightLevel === "hazy">> <<set _lightLevel = "dim">> <</if>> /* 降级后再次安全检查 */ <<if $viewmap[_terrain][_lightLevel] === undefined>> <<set _lightLevel = "dark">> <</if>> <<set _output = "光线难以企及," + $viewmap[_terrain][_lightLevel]>> /* 深渊(1000米+):永夜 */ <<else>> <<set _output = $viewmap[_terrain].dark || "无边的黑暗吞噬了一切,深渊在船底沉默延伸。">> <</if>> /* ── 提取纯天色句(不含地形)供场景覆盖态使用 ── */ <<if _depth > 1000>> <<set _lightOnly = "">> <<elseif _depth > 300>> <<set _lightOnly = "光线难以企及,深处只有探照灯的光锥。">> <<elseif _depth > 80>> <<set _lightOnly = "这里看不到海面,探照灯是唯一的光源。">> <<else>> <<set _lightOnly = ($viewlight[_lightLevel] && $viewlight[_lightLevel][_lightKey]) ? $viewlight[_lightLevel][_lightKey] + "。" : "">> <</if>> /* ── 四状态渲染逻辑 ── */ <<set _vOut = _output>> /* 状态1:worldScene 锚定中(次级中型事件) */ <<if $worldScene && $worldScene.state === "inside">> <<if !$wsDefs>><<worldSceneDefs>><</if>> <<set _wsViewD = ($worldScene.viewDesc) ? $worldScene.viewDesc : (($wsDefs[$worldScene.id] && $wsDefs[$worldScene.id].viewDesc) ? $wsDefs[$worldScene.id].viewDesc : "")>> <<if $largeScene && typeof $largeScene === "object" && $largeScene.state === "active" && $largeScene.viewDesc>> /* 大型场景内的次级场景:天色 + 大场景氛围 + 次级场景特写 */ <<set _vOut = _lightOnly + $largeScene.viewDesc + (_wsViewD ? " " + _wsViewD : "")>> <<else>> /* 独立 worldScene:天色 + 场景描述 */ <<set _vOut = _lightOnly + (_wsViewD ? _wsViewD : _output)>> <</if>> /* 状态2:大型场景内巡航(无锚定子场景) */ <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "active">> <<set _vOut = _lightOnly + ($largeScene.viewDesc ? $largeScene.viewDesc : "")>> /* 状态2b:大型场景淡出(leaving)— 恢复地形描述,附加淡显离开提示 */ <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "leaving">> <<set _lsLeaveHint = (typeof $largeScene.leaveHint === "string" && $largeScene.leaveHint) ? $largeScene.leaveHint : "">> <<set _vOut = _output + (_lsLeaveHint ? "<br><span style=\"opacity:0.55;font-style:italic\">" + _lsLeaveHint + "</span>" : "")>> /* 状态3:正在接近大型场景(approachHint 在 spawn 时已固定为字符串)*/ <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "approaching">> <<set _lsHint = (typeof $largeScene.approachHint === "string") ? $largeScene.approachHint : "">> <<set _vOut = _output + (_lsHint ? "<br><span style=\"opacity:0.75;font-style:italic\">" + _lsHint + "</span>" : "")>> /* 状态4:轻量事件(NPC / 主线通知,无大型场景)—— 保持地形描述不覆盖 */ <</if>> <<print _vOut>> <</widget>> <</nobr>>
<<nobr>> /* ══════════════════════════════════════════════ diveInit:进入仓外时按当前深度初始化消耗参数 ══════════════════════════════════════════════ */ <<widget "diveInit">> <<set $diveOxygen = ($diveOxygenMax || 100)>> <<set $diveCold = 0>> <<set $diveStepsOut = 0>> <<set $diveLog = "">> <<set $diveChainSub = []>> <<set $diveIdx = 0>> <<set $divingMode = true>> <<set $diveArmBlocked = {}>> <<set $diveArmCleared = {}>> /* 恢复持久化链条(worldScene 内)或重新生成 */ <<if $worldScene && $worldScene.state === "inside" && $worldScene.savedChain && $worldScene.savedChain.length > 1>> <<set $diveChain = $worldScene.savedChain>> <<set $diveIdx = 0>> <<set $diveChainTerrain = $maptype>> <<else>> <<diveChainGen>> <</if>> /* 场景简介:描述玩家从哪种环境出舱 */ <<set _diTerrainName = $mapinfo[$maptype] ? $mapinfo[$maptype].type : "未知地形">> <<set _diDepthDesc = ($depth <= 10) ? "水面附近" : ($depth <= 50) ? "浅水区" : ($depth <= 200) ? "中深水域" : "深海">> <<set _diSceneCtx = "">> <<if $largeScene && typeof $largeScene === "object" && $largeScene.state === "active">> <<set _diSceneCtx = ",正处于" + $largeScene.name + "范围内">> <<elseif $worldScene && $worldScene.state === "inside">> <<set _diSceneCtx = ",锚定于" + $worldScene.name>> <</if>> <<set $diveIntro = "你推开出仓舱门,进入" + _diDepthDesc + "(" + $depth + "m)的" + _diTerrainName + _diSceneCtx + "。" + ($diveOxygen < 120 ? "氧气有限,需要尽快行动。" : "探照灯在黑暗中划出一道光锥,周围轮廓逐渐清晰。")>> <<set $diveShowIntro = true>> /* 按深度设定每步消耗: ≤50m → ~33步 约99分钟 ≤300m → ~10步 约30分钟 >300m → 极速消耗(无装备不可出) */ <<if $depth <= 50>> <<set $diveStepCostO2 = 3>> <<set $diveStepTime = 3>> <<elseif $depth <= 300>> <<set $diveStepCostO2 = 10>> <<set $diveStepTime = 3>> <<else>> <<set $diveStepCostO2 = 30>> <<set $diveStepTime = 3>> <</if>> /* 主线 auto 触发检查(每次下水)*/ <<if !$questChain>><<questDefs>><</if>> <<if $questProgress < $questChain.length && $questChain[$questProgress].trigger.type === "auto">> <<questCheck "auto">> <</if>> <</widget>> /* ══════════════════════════════════════════════ diveStep:深入一步的消耗结算 ══════════════════════════════════════════════ */ <<widget "diveStep">> /* 氧气消耗 */ <<set $diveOxygen = Math.max(0, $diveOxygen - $diveStepCostO2)>> /* 步数计数 */ <<set $diveStepsOut = $diveStepsOut + 1>> /* 时间流逝 */ <<set $timepass = $diveStepTime>> <<time>> /* 水温估算(浅水用环境温度,深水大幅下降) */ <<if $depth <= 50>> <<set _dwt = $worldtem>> <<elseif $depth <= 200>> <<set _dwt = Math.floor($worldtem * 0.6)>> <<else>> <<set _dwt = Math.max(0, Math.floor($worldtem / 5))>> <</if>> /* 冷压积累 */ <<if _dwt <= 0>> <<set $diveCold = Math.min(100, $diveCold + 20)>> <<elseif _dwt <= 5>> <<set $diveCold = Math.min(100, $diveCold + 12)>> <<elseif _dwt <= 15>> <<set $diveCold = Math.min(100, $diveCold + 6)>> <<elseif _dwt <= 20>> <<set $diveCold = Math.min(100, $diveCold + 2)>> <</if>> /* 冷压造成的实际效果 */ <<if $diveCold >= 80>> <<set $life = Math.max(0, $life - 5)>> <<set $power = Math.max(0, $power - 5)>> <<elseif $diveCold >= 50>> <<set $power = Math.max(0, $power - 3)>> <</if>> /* 氧气耗尽标记(UI 层捕获并强制显示返回)*/ <<if $diveOxygen <= 0>><<set $diveO2Dead = true>><</if>> /* 持久效果检查 */ <<checkEnvEffects>> /* 小型事件调度(无活跃事件时尝试触发) */ <<if !$activeSmallEvent>> <<spawnSmallEvent "outside">> <<if $pendingEvent>> <<set $activeSmallEvent = $pendingEvent>> <<set $pendingEvent = null>> <</if>> <</if>> /* 战斗触发(约3%/步,无小型事件且无战斗时)*/ <<if !$activeSmallEvent && !$activeCombat>> <<if Math.random() < 0.03>> <<spawnCombat>> <</if>> <</if>> <</widget>> /* ══════════════════════════════════════════════ diveReturn:返回消耗一次性结算(0.6倍去程) ══════════════════════════════════════════════ */ <<widget "diveReturn">> <<set _retO2 = Math.ceil($diveStepsOut * $diveStepCostO2 * 0.6)>> <<set _retTime = Math.max(1, Math.ceil($diveStepsOut * $diveStepTime * 0.6))>> /* 持久化:将当前 diveChain 状态(含已完成节点)同步回 worldScene */ <<if $worldScene && $worldScene.state === "inside">> <<set $worldScene.savedChain = $diveChain>> <</if>> <<set $diveOxygen = Math.max(0, $diveOxygen - _retO2)>> <<set $timepass = _retTime>> <<time>> /* 氧气耗尽惩罚 */ <<if $diveOxygen <= 0>> <<set $life = Math.max(0, $life - 25)>> <<set $san = Math.max(0, $san - 15)>> <</if>> /* 冷压结算 */ <<if $diveCold >= 80>> <<set $life = Math.max(0, $life - 10)>> <<elseif $diveCold >= 50>> <<set $power = Math.max(0, $power - 8)>> <</if>> /* 重置状态 */ <<set $divingMode = false>> <<set $diveStepsOut = 0>> <<set $diveOxygen = 100>> <<set $diveCold = 0>> <<set $diveChain = []>> <<set $diveChainSub = []>> <<set $diveIdx = 0>> <<set $diveInteractResult = "">> <<set $diveO2Dead = false>> <<set $wsLastActionText = "">> <<set $wsLastActionLoot = "">> <</widget>> /* ══════════════════════════════════════════════ diveWarn:计算预警等级,存入 _diveWarn 0=安全 1=黄色(2步冗余) 2=红色(仅剩返程量) ══════════════════════════════════════════════ */ <<widget "diveWarn">> <<set _retNeeded = Math.ceil($diveStepsOut * $diveStepCostO2 * 0.6)>> <<set _bufferO2 = _retNeeded + ($diveStepCostO2 * 2)>> <<if $diveOxygen <= _retNeeded>> <<set _diveWarn = 2>> <<elseif $diveOxygen <= _bufferO2>> <<set _diveWarn = 1>> <<else>> <<set _diveWarn = 0>> <</if>> <</widget>> /* ══════════════════════════════════════════════ diveLight:计算潜水环境光照等级 → _diveLightLevel (深度覆盖水面光照;结合 view widget 的时段/天气逻辑) ══════════════════════════════════════════════ */ <<widget "diveLight">> /* 深度优先判定(与 view widget 逻辑保持一致)*/ <<if $depth > 1000>> <<set _diveLightLevel = "dark">> <<elseif $depth > 300>> <<set _diveLightLevel = "dim">> <<if Math.random() < 0.3>><<set _diveLightLevel = "dark">><</if>> <<elseif $depth > 80>> <<set _diveLightLevel = "dim">> <<else>> /* 浅水:继承表面光照计算 */ <<if $showhour >= 7 && $showhour < 17>> <<set _dlTime = "day">> <<elseif ($showhour >= 5 && $showhour < 7) || ($showhour >= 17 && $showhour < 19)>> <<set _dlTime = "dusk">> <<elseif $showhour >= 5 && $showhour < 7>> <<set _dlTime = "dawn">> <<else>> <<set _dlTime = "night">> <</if>> <<set _dlKey = _dlTime + "_" + $viewweather[$weather]>> <<if $viewlight && $viewlight.bright && $viewlight.bright.hasOwnProperty(_dlKey)>> <<set _diveLightLevel = "bright">> <<elseif $viewlight && $viewlight.hazy && $viewlight.hazy.hasOwnProperty(_dlKey)>> <<set _diveLightLevel = "hazy">> <<elseif $viewlight && $viewlight.dim && $viewlight.dim.hasOwnProperty(_dlKey)>> <<set _diveLightLevel = "dim">> <<else>> <<set _diveLightLevel = "dark">> <</if>> <</if>> <</widget>> /* ══════════════════════════════════════════════ diveChainGen:进入时预生成 $diveChain 结构:[{type,id,desc?,terrain?,visited}] type: "frag" | "scene" | "fork" ══════════════════════════════════════════════ */ <<widget "diveChainGen">> <<diveSceneDefs>> <<diveLight>> /* 确定当前地形键:优先 worldScene,其次 largeScene 区域,最后地图地形 */ <<set _dct = $maptype>> <<if $worldScene && $worldScene.state === "inside">> <<set _dct = $maptype>> /* 先取地图基础地形 */ <<if $worldScene.id === "wreck_site">><<set _dct = "wreck">><</if>> <<if $worldScene.id === "whale_fall">><<set _dct = "sand">><</if>> <</if>> /* largeScene 额外覆盖:处于大场景中时在链开头插入场景描述节点 */ <<set _dcLargeDesc = "">> <<if $largeScene && typeof $largeScene === "object" && $largeScene.state === "active" && $largeScene.viewDesc>> <<set _dcLargeDesc = $largeScene.viewDesc>> <</if>> /* 取场景池和碎片池,找不到则用 default */ <<set _dcScenes = $diveSceneDefs[_dct] ? clone($diveSceneDefs[_dct]) : []>> <<set _dcFrags = $diveFragDefs[_dct] ? clone($diveFragDefs[_dct]) : clone($diveFragDefs.default)>> /* 洗牌碎片池 */ <<set _dcFragShuf = []>> <<for _dsi = _dcFrags.length - 1; _dsi > 0; _dsi-->> <<set _dsr = Math.floor(Math.random() * (_dsi + 1))>> <<set _dstmp = _dcFrags[_dsi]>> <<set _dcFrags[_dsi] = _dcFrags[_dsr]>> <<set _dcFrags[_dsr] = _dstmp>> <</for>> /* 洗牌场景池 */ <<for _dsi = _dcScenes.length - 1; _dsi > 0; _dsi-->> <<set _dsr = Math.floor(Math.random() * (_dsi + 1))>> <<set _dstmp = _dcScenes[_dsi]>> <<set _dcScenes[_dsi] = _dcScenes[_dsr]>> <<set _dcScenes[_dsr] = _dstmp>> <</for>> /* 场景数量:2-3个(深度越深越少)*/ <<if $depth > 300>> <<set _dcSceneCount = 1>> <<elseif $depth > 100>> <<set _dcSceneCount = 2>> <<else>> <<set _dcSceneCount = 2 + Math.floor(Math.random() * 2)>> <</if>> <<if _dcSceneCount > _dcScenes.length>><<set _dcSceneCount = _dcScenes.length>><</if>> /* 碎片数量:4-6个,分散在场景之间 */ <<set _dcFragCount = 4 + Math.floor(Math.random() * 3)>> <<if _dcFragCount > _dcFrags.length>><<set _dcFragCount = _dcFrags.length>><</if>> /* 构建 chain:frag→scene→frag→[scene→frag] 交替 */ <<set $diveChain = []>> <<set _dcFi = 0>> <<set _dcSi = 0>> /* 开头放2-3个碎片 */ <<set _dcLeadFrags = 2 + Math.floor(Math.random() * 2)>> <<if _dcLeadFrags > _dcFragCount>><<set _dcLeadFrags = _dcFragCount>><</if>> <<for _dcx = 0; _dcx < _dcLeadFrags; _dcx++>> <<if _dcFi < _dcFrags.length>> <<run $diveChain.push({type:"frag", id:"frag_"+_dcFi, text:_dcFrags[_dcFi], visited:false})>> <<set _dcFi++>> <</if>> <</for>> /* 交替放置:场景→2-3碎片 */ <<for _dcsi = 0; _dcsi < _dcSceneCount; _dcsi++>> <<if _dcSi < _dcScenes.length>> <<set _dcScene = _dcScenes[_dcSi]>> <<set _dcPfxPool = $diveLightPfx[_diveLightLevel] || $diveLightPfx.dim>> <<set _dcPfx = _dcPfxPool[Math.floor(Math.random() * _dcPfxPool.length)]>> <<set _dcSfxPool = $diveLightSfx[_diveLightLevel] || $diveLightSfx.dim>> <<set _dcComposed = _dcPfx + _dcScene.baseDesc>> <<if Math.random() < 0.5>> <<set _dcComposed += _dcSfxPool[Math.floor(Math.random() * _dcSfxPool.length)]>> <</if>> <<set _dcBlocked = _dcScene.blocked ? _dcScene.blocked : []>> <<run $diveChain.push({type:"scene", id:_dcScene.id, desc:_dcComposed, elements:_dcScene.elements, blocked:_dcBlocked, visited:false})>> <<if _dcBlocked.length > 0>> <<if !$diveArmBlocked>><<set $diveArmBlocked = {}>><</if>> <<set $diveArmBlocked[_dcScene.id] = _dcBlocked>> <</if>> <<set _dcSi++>> <</if>> <<set _dcAfterFrags = 2 + Math.floor(Math.random() * 2)>> <<for _dcx = 0; _dcx < _dcAfterFrags; _dcx++>> <<if _dcFi < _dcFrags.length>> <<run $diveChain.push({type:"frag", id:"frag_"+_dcFi, text:_dcFrags[_dcFi], visited:false})>> <<set _dcFi++>> <</if>> <</for>> <</for>> /* 大型场景描述节点:作为第一个节点 */ <<if _dcLargeDesc>> <<run $diveChain.unshift({type:"scene", id:"large_overview", desc:_dcLargeDesc, elements:[], visited:false})>> <</if>> /* ── worldScene 子事件注入:固定在第3、6、9节(0-based: 2,5,8)── */ <<if $worldScene && $worldScene.state === "inside" && $worldScene.children && $worldScene.children.length > 0>> <<if !$wsChildDefs>><<worldSceneDefs>><</if>> /* 确定待注入的 children(排除已完成的)*/ <<set _dcWsCh = []>> <<for _dcWi = 0; _dcWi < $worldScene.children.length; _dcWi++>> <<set _dcWCid = $worldScene.children[_dcWi]>> <<set _dcWDone = false>> <<if $worldScene.doneCids>> <<for _dcWdi = 0; _dcWdi < $worldScene.doneCids.length; _dcWdi++>> <<if $worldScene.doneCids[_dcWdi] === _dcWCid>><<set _dcWDone = true>><</if>> <</for>> <</if>> <<if !_dcWDone>><<run _dcWsCh.push(_dcWCid)>><</if>> <</for>> /* 在第 3、6、9 节位置(目标0-based索引 2,5,8)插入 wschild 节点 */ <<set _dcSlots = [2, 5, 8]>> <<for _dcSli = 0; _dcSli < _dcSlots.length && _dcSli < _dcWsCh.length; _dcSli++>> <<set _dcSlot = _dcSlots[_dcSli]>> <<set _dcWCid = _dcWsCh[_dcSli]>> <<set _dcWDef = $wsChildDefs[_dcWCid]>> <<if _dcWDef>> <<set _dcWNode = {type:"wschild", id:_dcWCid, name:_dcWDef.name, desc:_dcWDef.desc, stageIdx:0, stageDesc:_dcWDef.stages[0].desc, actions:_dcWDef.stages[0].actions, done:false, visited:false}>> /* splice 插入:如果链条够长就插,否则 push */ <<if _dcSlot < $diveChain.length>> <<run $diveChain.splice(_dcSlot, 0, _dcWNode)>> <<else>> <<run $diveChain.push(_dcWNode)>> <</if>> <</if>> <</for>> <</if>> /* 末尾终点标记 */ <<run $diveChain.push({type:"end", id:"end", visited:false})>> <<set $diveIdx = 0>> <<set $diveChainTerrain = _dct>> /* ── 持久化:将链条保存到 worldScene(下次下水恢复)── */ <<if $worldScene && $worldScene.state === "inside">> <<set $worldScene.savedChain = $diveChain>> <<set $worldScene.savedDoneNodes = $worldScene.savedDoneNodes || {}>> <</if>> <</widget>> /* ══════════════════════════════════════════════ diveInteract:与当前场景节点的元素交互 args[0] = element name (string) 结果写入 $diveChain[$diveIdx].done[] 全部元素完成后 → 写入 $worldScene.doneCids ══════════════════════════════════════════════ */ <<widget "diveInteract">> <<diveInteractDefs>> <<set _diElem = $args[0]>> <<set _diNode = $diveChain[$diveIdx]>> <<if !_diNode>><<return>><</if>> /* 标记该元素已处理 */ <<if !_diNode.done>><<set $diveChain[$diveIdx].done = []>><</if>> <<run $diveChain[$diveIdx].done.push(_diElem)>> /* 发放战利品 */ <<set _diDef = $diveInteractDefs[_diElem]>> <<set _diLog = "">> <<if _diDef && _diDef.loot>> <<for _dili = 0; _dili < _diDef.loot.length; _dili++>> <<set _dil = _diDef.loot[_dili]>> <<set _dilq = _dil.qty[0] + Math.floor(Math.random() * (_dil.qty[1] - _dil.qty[0] + 1))>> <<if _dilq > 0>> <<additem _dil.id _dilq>> <<if $items && $items[_dil.id]>> <<set _diLog = _diLog + $items[_dil.id].name + "×" + _dilq + " ">> <</if>> <</if>> <</for>> <</if>> /* 记录行动文本 → 写入 diveInteractResult(持续显示直到玩家确认)*/ <<set _diText = (_diDef && _diDef.text) ? _diDef.text : "你检查了" + _diElem + ",没有发现特别的东西。">> <<if _diLog>><<set _diText = _diText + " → 获得:" + _diLog>><</if>> <<set $diveInteractResult = _diText>> <<set $diveLog = "">> /* 小量额外氧气消耗(每次交互 +1 步)*/ <<set $diveOxygen = Math.max(0, $diveOxygen - 1)>> /* 检查是否全部元素都已处理 → 写入 worldScene.doneCids */ <<if $worldScene && $worldScene.state === "inside" && _diNode.elements>> <<set _diAllDone = true>> <<for _daei = 0; _daei < _diNode.elements.length; _daei++>> <<set _daElem = _diNode.elements[_daei]>> <<set _daFound = false>> <<if _diNode.done>> <<for _dadi = 0; _dadi < _diNode.done.length; _dadi++>> <<if _diNode.done[_dadi] === _daElem>><<set _daFound = true>><</if>> <</for>> <</if>> <<if !_daFound>><<set _diAllDone = false>><</if>> <</for>> <<if _diAllDone>> <<if !$worldScene.doneCids>><<set $worldScene.doneCids = []>><</if>> <<set _dcAlready = false>> <<for _dcdi = 0; _dcdi < $worldScene.doneCids.length; _dcdi++>> <<if $worldScene.doneCids[_dcdi] === _diNode.id>><<set _dcAlready = true>><</if>> <</for>> <<if !_dcAlready>><<run $worldScene.doneCids.push(_diNode.id)>><</if>> <</if>> <</if>> <</widget>> <</nobr>>
描写当前天气状况与海况。 [[← 返回|驾驶舱]]
<<nobr>> <<widget "disassemble">> <<set _ds_id = $args[0]>> <<set _ds_isNpc = ($args[1] === true)>> <<set _ds_def = State.variables.items[_ds_id]>> <<if !_ds_def>> <<set $lastDisassembleText = "未知物品。">> <<else>> <<set _ds_type = _ds_def.type>> <<set _ds_idx = -1>> <<if $store[_ds_type]>> <<for _ds_i = 0; _ds_i < $store[_ds_type].length; _ds_i++>> <<if $store[_ds_type][_ds_i].id === _ds_id>> <<set _ds_idx = _ds_i>> <<break>> <</if>> <</for>> <</if>> <<if _ds_idx < 0 || $store[_ds_type][_ds_idx].quantity <= 0>> <<set $lastDisassembleText = "仓库中没有 " + _ds_def.name + "。">> <<else>> <<set _ds_rules = State.variables.disassemblyRules[_ds_id]>> <<if !_ds_rules>> <<set $lastDisassembleText = _ds_def.name + " 无法分解。">> <<else>> /* 直接扣除 */ <<set $store[_ds_type][_ds_idx].quantity -= 1>> <<set _ds_log = "分解 " + _ds_def.name + ",获得:">> <<set _ds_got = false>> <<set _ds_rares = []>> <<for _di = 0; _di < _ds_rules.length; _di++>> <<set _dr = _ds_rules[_di]>> <<set _dq = 0>> <<if _dr.chance !== undefined>> <<if Math.random() < _dr.chance>> <<if _dr.minQty !== undefined && _dr.maxQty !== undefined>> <<set _dq = Math.floor(Math.random() * (_dr.maxQty - _dr.minQty + 1)) + _dr.minQty>> <<else>> <<set _dq = 1>> <</if>> <</if>> <<else>> <<set _dq = Math.floor(Math.random() * (_dr.maxQty - _dr.minQty + 1)) + _dr.minQty>> <</if>> <<if _dq > 0>> <<additem _dr.id _dq>> <<set _ds_got = true>> <<set _out_name = State.variables.items[_dr.id] ? State.variables.items[_dr.id].name : _dr.id>> <<if _dr.rare>> <<run _ds_rares.push(_out_name + "×" + _dq)>> <<else>> <<set _ds_log += _out_name + "×" + _dq + " ">> <</if>> <</if>> <</for>> <<if !_ds_got>> <<set _ds_log += "(无)">> <</if>> <<if _ds_rares.length > 0>> <<set _ds_log += " ★稀有:" + _ds_rares.join("、")>> <</if>> /* 时间消耗:拆解耗时 15-30 分钟 */ <<set _ds_time = Math.floor(Math.random() * 16) + 15>> <<if !_ds_isNpc>><<set $timepass += _ds_time>><<time>><</if>> /* 体力消耗:消耗 2-5 点体力 */ <<set _ds_pow = Math.floor(Math.random() * 4) + 2>> <<if !_ds_isNpc>> <<set $power -= _ds_pow>> <<if $power < 0>><<set $power = 0>><</if>> <</if>> <<set _ds_log += "(耗时" + _ds_time + "分钟,消耗体力" + _ds_pow + "点">> /* 小概率划伤 15% */ <<if !_ds_isNpc && Math.random() < 0.15>> <<set _ds_cut = Math.floor(Math.random() * 4) + 1>> <<set $life -= _ds_cut>> <<if $life < 0>><<set $life = 0>><</if>> <<set _ds_log += ",操作时被划伤失去" + _ds_cut + "点生命">> <</if>> <<set _ds_log += ")">> <<set $lastDisassembleText = _ds_log>> <</if>> <</if>> <</if>> <</widget>> <</nobr>>
<<nobr>> <<widget "time" >> <<set $hourpass =Math.floor($timepass/60)>> /*饥饿扣血*/ <<if $hunger==0>> <<set $hungerlim+=$timepass>> <<if $hungerlim>0>> <<set $life-=Math.floor($hungerlim/60)>> <<set $hungerlim=$hungerlim%60>> <<endif>> <<endif>> <<if $hunger>0>> <<set $hungerlim=-4320>> <<endif>> /*口渴扣血*/ <<if $water==0>> <<set $waterlim+=$timepass>> <<if $waterlim>0>> <<set $life-=Math.floor($waterlim/60)>> <<set $waterlim=$waterlim%60>> <<endif>> <<endif>> <<if $water>0>> <<set $waterlim=-1440>> <<endif>> /*食水时间变化*/ <<set $hungerpass +=$timepass>> <<set $waterpass +=$timepass>> <<set $hunger -=Math.floor($hungerpass/15)>> <<set $water -=Math.floor($waterpass/15)>> /*食水上下限控制*/ <<if $hunger <0 >> <<set $hunger = 0>> <<endif>> <<if $water <0 >> <<set $water = 0>> <<endif>> <<if $hunger>100>> <<set $hunger = 100>> <<endif>> <<if $water>100>> <<set $water = 100>> <<endif>> <<set $hungerpass =$hungerpass%15>> <<set $waterpass =$waterpass%15>> /*体力变化上下限*/ <<if $power <0>> <<set $power =0>> <<endif>> <<if $hunger>0 && $water>0 >> <<set $powerpass+= $timepass>> <<set $power +=Math.floor($powerpass/5)>> <<set $powerpass= $powerpass%5>> <<if $power >100 >> <<set $power=100>> <<endif>> <<endif>> <<if $hunger<10 || $water<10 || $life<50 >> <<if $power >20 >> <<set $power=20>> <<endif>> <<endif>> <<set $powerpass=0>> /*生命恢复*/ <<if $hunger>0 && $water>0 >> <<set $lifepass+=$timepass>> <<set $life +=Math.floor($lifepass/360)>> <<set $lifepass=$lifepass%360>> <<if $life >100 >> <<set $life=100>> <<endif>> <<endif>> /*时间进制*/ <<set $minute += $timepass%60>> <<set $hour += $hourpass>> <<if $minute >= 60>> <<set $hour += 1>> <<set $minute = $minute - 60>> <<endif>> <<if $minute < 10 >> <<set $showminute = '0'+$minute>> <<else>> <<set $showminute = $minute>> <<endif>> <<if $hour >= 24 >> <<set $hour = $hour - 24>> <<set $day += 1>> <<set $showday += 1>> <<decayItems>> <<set $wavetem to random(-1,3)>> <<set $weather to random(1,9)>> <<endif>> <<if $hour < 10 >> <<set $showhour = '0' + $hour>> <<else>> <<set $showhour = $hour>> <<endif>> <<if $showday >= 34 && $season <4 >> <<set $showday = $showday - 33>> <<set $season += 1>> <<endif>> <<if $season==4 && $showday>=2>> <<set $showday = $showday - 1>> <<set $season = 1>> <<endif>> <<if $season == 1>> <<set $showseason = '丰饶'>> <<else>> <<if $season == 2>> <<set $showseason = '日曜'>> <<else>> <<if $season == 3>> <<set $showseason = '凛冬'>> <<else>> <<set $showseason='冰封'>> <<endif>> <<endif>> <<endif>> /*天气*/ <<if $season==4>> <<set $weather=0>> <<else>> <<if $season ==2 && $weather==1 >> <<set $weather = 2>> <<else>> <<if $season ==3 && $weather==2 >> <<set $weather =1>> <<else>> <<if $season ==1 && $weather<3 >> <<set $weather +=2 >> <<endif>> <<endif>> <<endif>> <<endif>> /*环境温度判定*/ <<if $season==1 >> <<if $showday==1>> <<set $seasontem=15>> <<else>> <<set $seasontem=15+Math.floor($showday/3)>> <<endif>> <</if>> <<if $season==2 >> <<if $showday==1>> <<set $seasontem=26>> <<else>> <<if $showday<21>> <<set $seasontem=26+Math.floor($showday/2)>> <<else>> <<if $showday==21>> <<set $seasontem=35>> <<else>> <<set $seasontem=35-($showday-21)*2>> <<endif>> <<endif>> <</if>> <</if>> <<if $season==3 >> <<if $showday==1>> <<set $seasontem=10>> <<else>> <<set $seasontem=10-Math.floor($showday/3)>> <<endif>> <</if>> <<if $season==3 && $seasontem <0 >> <<set $seasontem=0>> <</if>> <<if $depth == -1 >> <<set _worldtem=$weatem[$weather]+$seasontem+$wavetem>> <<else>> <<if $depth<200>> <<set _worldtem=$seasontem+$wavetem>> <<else>> <<if $depth<1000>> <<set _worldtem = Math.floor($seasontem / 5)>> <<else>> <<set _worldtem=0>> <<endif>> <<endif>> <<endif>> <<if $outdoor==0 && _worldtem < 10>> <<set $worldtem=_worldtem+3>> <<else>> <<if $outdoor==0 && _worldtem >30 >> <<set $worldtem=_worldtem-3>> <<else>> <<set $worldtem= _worldtem>> <<endif>> <<endif>> /*湿度判定*/ <<if $outdoor == 1>> <<if $weather == 6>> <<set $wetpass += $timepass>> <<set $wet += Math.floor($wetpass / 3)>> <<set $wetpass = $wetpass % 3>> <<elseif $weather == 7>> <<set $wetpass += $timepass>> <<set $wet += $wetpass>> <<set $wetpass = 0>> <<elseif $weather == 9>> <<set $wetpass += $timepass * 2>> <<set $wet += $wetpass>> <<set $wetpass = 0>> <<endif>> <</if>> <<if $outdoor == 1 && $weather == 2>> <<set $wetpass += $timepass>> <<set $wet -= Math.floor($wetpass / 2)>> <<set $wetpass = $wetpass % 2>> <<elseif $outdoor == 1 && $weather == 4>> <<set $wetpass += $timepass>> <<set $wet -= Math.floor($wetpass / 4)>> <<set $wetpass = $wetpass % 4>> <<elseif $worldtem >= 30>> <<set $wetpass += $timepass>> <<set $wet -= Math.floor($wetpass / 3)>> <<set $wetpass = $wetpass % 3>> <</if>> <<if $inwater==1>> <<set $wet=100>> <</if>> <<if $fire == 1>> <<set $wetpass += $timepass>> <<set $wet -= Math.floor($wetpass / 3)>> <<set $wetpass = $wetpass % 3>> <</if>> <<set $wetpass=0>> <<if $wet<0>> <<set $wet=0>> <</if>> <<if $wet>100>> <<set $wet=100>> <</if>> <<if $wet>50>> <<set $wettem=$cloth+Math.floor($wet/10)>> <<else>> <<if $wet>20>> <<set $wettem=Math.floor($wet/8)>> <<else>> <<set $wettem=0>> <<endif>> <</if>> /*自身温度*/ <<set $tem=$worldtem+$cloth-$wettem+$addtem>> <<if $bath>0>> <<set $tem=$bath>> <</if>> <<set _cozy=0>> <<if $tem >= 18 && $tem <= 26>> <<set _cozy = -5>> <<set $heatpass -=$timepass*2 >> <<set $coldpass-=$timepass*2>> <<elseif $tem >= 32>> <<set _cozy = 5>> <<set $coldpass-=$timepass*3>> <<set $water-=$timepass/20>> <<if $tem>37>> <<set $heatpass += $timepass*2>> <<else>> <<set $heatpass+= $timepass>> <<endif>> <<if $heatpass >= 0>> <<set $life -= $timepass>> <<endif>> <<elseif $tem <= 10>> <<set _cozy = 5>> <<set $heatpass -=$timepass*3 >> <<if $power>50>> <<set $power=50>> <<endif>> <<if $tem<=0>> <<set $coldpass += $timepass*2>> <<else>> <<set $coldpass+= $timepass>> <<endif>> <<set $coldpass += $timepass>> <<if $coldpass >= 0>> <<set $life -=$timepass>> <<endif>> <<else>> <<set _cozy = 0>> <<set $heatpass -= $timepass>> <<set $coldpass-=$timepass>> <<endif>> <<if $heatpass<-120>> <<set $heatpass=-120>> <</if>> <<if $coldpass<-120>> <<set $coldpass=-120>> <</if>> <<if $life <0 >> <<set $life = 0>> <<endif>> /*压力变化*/ <<set _tre to random(20,25)>> <<if $life<25>> <<set _life=Math.floor((100-$life)/2)>> <<else>> <<if $life<50>> <<set _life=8+Math.floor((100-$life)/7)>> <<else>> <<if $life<90>> <<set _life=3+Math.floor((100-$life)/10)>> <<else>> <<if $life==100>> <<set _life=-5>> <<else>> <<set _life=0>> <<endif>> <<endif>> <<endif>> <<endif>> <<if $hunger<25>> <<set _hun=5+Math.floor((100-$hunger)/10)>> <<else>> <<if $hunger<50>> <<set _hun=Math.floor((100-$hunger)/10)>> <<else>> <<if $hunger>80>> <<set _hun=-5>> <<else>> <<set _hun=0>> <<endif>> <<endif>> <<endif>> <<if $water<25>> <<set _wat=5+Math.floor((100-$water)/10)>> <<else>> <<if $water<50>> <<set _wat=Math.floor((100-$water)/10)>> <<else>> <<if $water>80>> <<set _wat=-5>> <<else>> <<set _wat=0>> <<endif>> <<endif>> <<endif>> <<set $tre=_tre+_hun+_wat+_life+_cozy>> <<if $tre <0>> <<set $tre =0>> <<endif>> <<if $tre >100>> <<set $tre =100>> <<endif>> /*san check*/ <<if $tre>80 && $tre<100>> <<set $sanpass+=$timepass>> <<set $san -=Math.floor($sanpass/60)>> <<set $sanpass=$sanpass%60>> <<else>> <<if $tre==100>> <<set $sanpass+=$timepass>> <<set $san-=10>> <<set $san -=Math.floor($sanpass/30)>> <<set $sanpass=$sanpass%30>> <<else>> <<if $tre<=15>> <<set $sanpass+=$timepass>> <<set $san +=Math.floor($sanpass/30)>> <<set $sanpass=$sanpass%30>> <<endif>> <<endif>> <<endif>> <<if $san <0 >> <<set $san=0>> <<endif>> <<if $san >100 >> <<set $san = 100>> <<endif>> <<cpTick>> <<set $hourpass = 0>> <<set $timepass =0>> <</widget>> <</nobr>>
<<widget "navigate">> <<nobr>> <<if $args[0] === "go">> /* 如果目标片段不是特殊片段,则记录当前片段 */ <<if !$specialPassages.includes(passage())>> <<set $returnPassage = passage()>> /* 记录当前片段 */ <</if>> <<goto $args[1]>> /* 跳转到目标片段 */ <<elseif $args[0] === "back">> /* 返回记录的片段 */ <<if $returnPassage>> <<goto $returnPassage>> /* 返回记录的片段 */ <<else>> <<print "无法返回,未记录原片段。">> <<endif>> <<else>> <<print "无效的导航指令。">> <<endif>> <</nobr>> <</widget>>
<<nobr>> <<set _bp = State.variables.backpack>> <<set _bpitems = State.variables.items>> <<set _bp_cats = Object.keys(_bp)>> <<set _bp_anyContent = false>> <<for _bci = 0; _bci < _bp_cats.length; _bci++>> <<set _bc = _bp_cats[_bci]>> <<set _bval = _bp[_bc]>> <<set _bHas = false>> <<if Array.isArray(_bval)>> <<if _bval.filter(x => x.quantity > 0).length > 0>> <<set _bHas = true>> <</if>> <</if>> <<if _bHas>> <<set _bp_anyContent = true>> <div class="inv-category"><<print _bc>></div> <<set _bfilled = _bval.filter(x => x.quantity > 0)>> <div class="inv-grid"> <<for _bii = 0; _bii < _bfilled.length; _bii++>> <<capture _bii, _bfilled>> <<set _bentry = _bfilled[_bii]>> <<set _bdef = _bpitems[_bentry.id]>> <<if _bdef>> <span class="inv-item"><<link _bdef.name>> <<set $selectitem = _bentry.id>> <<set $selectsource = "backpack">> <<goto "背包物品页面">> <</link>><span class="item-qty">×<<print _bentry.quantity>><<freshnessTag _bentry>></span></span> <<else>> <span class="inv-item" style="color:var(--bone-dim);font-size:0.75rem;">?未知(<<print _bentry.id>>)×<<print _bentry.quantity>></span> <</if>> <</capture>> <</for>> </div> <</if>> <</for>> <<if !_bp_anyContent>> <p style="color:var(--bone-dim);font-size:0.85rem;">背包是空的。</p> <</if>> <</nobr>> <<link "关闭背包">><<navigate "back">><</link>>
<<nobr>> <<set _cpDevId = ($devCpId && $cps && $cps[$devCpId]) ? $devCpId : "viona">> <<set $devCpId = _cpDevId>> <<set _cpd = $cps[_cpDevId]>><<set _cpdIsViona = _cpDevId === "viona">> <<set _cpdStatusText = "正常">> <<if _cpd>> <<set _cpdStatusParts = []>> <<if _cpd.wet>><<run _cpdStatusParts.push("潮湿")>><</if>> <<if _cpd.injured > 0>><<run _cpdStatusParts.push("受伤")>><</if>> <<if _cpd.sick>><<run _cpdStatusParts.push("生病")>><</if>> <<if _cpdStatusParts.length > 0>><<set _cpdStatusText = _cpdStatusParts.join(" ")>><</if>> <</if>> <<if !_cpd>> <p>CP 数据未加载。</p> [[返回走廊|走廊]] <<else>> <div style="font-size:1rem;color:var(--amber-bright);margin:0.3rem 0 0.5rem;">CP DEV · <<print _cpd.name>></div> <div style="font-size:0.75rem;color:var(--bone-dim);line-height:1.65;margin-bottom:0.55rem;"> 位置:<<print _cpd.location>> 行动:<<print _cpd.action>> 心情:<<print Math.floor(_cpd.mood)>><br> 状态:<<print _cpdStatusText>><br> 环境:<<print $mapinfo[$maptype] ? $mapinfo[$maptype].type : $maptype>> · <<print $showweather[$weather] || "未知天气">> · 深度 <<print $depth>>m · 航速 <<print $sailspd>> </div> <div style="font-size:0.82rem;color:var(--teal-bright);margin-top:0.45rem;">调试角色</div> <<link "维奥娜">><<devSelectCp "viona">><<goto "CP DEV">><</link>> <<link "测试人偶">><<devSelectCp "testcp">><<goto "CP DEV">><</link>> <div style="font-size:0.82rem;color:var(--teal-bright);margin-top:0.7rem;">位置 / 场景</div> <<link "驾驶舱 · 观察">><<devSetCpRoom "驾驶舱" "watch">><<goto "CP DEV">><</link>> <<link "走廊 · 待命">><<devSetCpRoom "走廊" "interact">><<goto "CP DEV">><</link>> <<link "炼金室 · 整理">><<devSetCpRoom "仓库" "tidy">><<goto "CP DEV">><</link>> <<link "炼金室 · 旁观">><<devSetCpRoom "仓库" "alchemy">><<goto "CP DEV">><</link>> <<link "浴室 · 洗漱">><<devSetCpRoom "浴室" "bath">><<goto "CP DEV">><</link>> <div style="font-size:0.82rem;color:var(--teal-bright);margin-top:0.7rem;">心情预设</div> <<link "好心情 85">><<devSetCpMood 85>><<goto "CP DEV">><</link>> <<link "中等心情 55">><<devSetCpMood 55>><<goto "CP DEV">><</link>> <<link "坏心情 20">><<devSetCpMood 20>><<goto "CP DEV">><</link>> <div style="font-size:0.82rem;color:var(--teal-bright);margin-top:0.7rem;">状态</div> <<set _cpdWetLabel = _cpd.wet ? "清除潮湿" : "设为潮湿">><<set _cpdWetNext = !_cpd.wet>> <<set _cpdInjuredLabel = _cpd.injured > 0 ? "清除受伤" : "设为受伤">><<set _cpdInjuredNext = _cpd.injured > 0 ? 0 : 1>> <<set _cpdSickLabel = _cpd.sick ? "清除生病" : "设为生病">><<set _cpdSickNext = !_cpd.sick>> <<link _cpdWetLabel>><<devSetCpStatus "wet" _cpdWetNext>><<goto "CP DEV">><</link>> <<link _cpdInjuredLabel>><<devSetCpStatus "injured" _cpdInjuredNext>><<goto "CP DEV">><</link>> <<link _cpdSickLabel>><<devSetCpStatus "sick" _cpdSickNext>><<goto "CP DEV">><</link>> <<if $devMsg>><div style="margin-top:0.7rem;font-size:0.72rem;color:var(--amber);"><<print $devMsg>></div><</if>> <div style="margin-top:0.8rem;">[[去驾驶舱验证|驾驶舱]] | [[返回走廊|走廊]]</div> <</if>> <</nobr>>
<<nobr>> /* 协同行动过渡页:你和 CP 一起来到某处 */ <<set _ctgCp = $cps[$detailCpId]>> <<set _ctgTarget = $cpTogetherTarget || "走廊">> <<set _ctgLabel = $cpTogetherLabel || _ctgTarget>> <<if !_ctgCp>> <p>找不到角色数据。</p> <<link "返回走廊">><<goto "走廊">><</link>> <<else>> <<set _ctgNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> /* 移动 CP 到目标地点并进入 interact 模式 */ <<set $cps[$detailCpId].location = _ctgTarget>> <<set $cps[$detailCpId].action = "interact">> <<set $cps[$detailCpId].mode = "interact">> <<set $cps[$detailCpId].actionEndTime = _ctgNow>> <<set $cps[$detailCpId].interactStart = _ctgNow>> <<set $cps[$detailCpId].interactActivityEnd = _ctgNow>> <<set $cps[$detailCpId].actionDetail = "">> <<set $cps[$detailCpId].leaveRequested = false>> <<set $cps[$detailCpId].leaveDeniedAt = 0>> /* 记录一起行动的记忆 */ <<cpMemory $detailCpId "slept_with" "went_together" 1>> <div class="cp-together"> <div class="cp-together-line">你和 <<print _ctgCp.name>> 一起来到了<<print _ctgLabel>>。</div> <div class="cp-together-line"><<print _ctgCp.name>> 在你身边停下,等着你下一步打算。</div> </div> <div class="cp-together-actions"> <div class="cp-together-option"> <<link "进入" + _ctgLabel>> <<set $cpReturnPassage = "走廊">> <<goto _ctgTarget>> <</link>> </div> </div> <</if>> <</nobr>>
<<nobr>> /* CP 档案页: 纯查看, 不改动状态。从 cp详情 的「档案」按钮进入。 */ <<set _ca = $cps[$detailCpId]>> <<if !_ca>> <p>找不到角色数据。</p> <<link "返回">><<goto "cp详情">><</link>> <<else>> <div id="cp-archive"> <div class="cp-detail-name"><<print _ca.name>> 的档案</div> <div class="cp-arch-section"> <div class="cp-arch-h">数值详情</div> <div class="cp-arch-row">心情:<<cpMoodTier _ca.mood>>(moodBase <<print Math.floor(_ca.moodBase)>> + moodMod <<print _ca.moodMod>>)</div> <div class="cp-arch-row">安定:<<cpCalmTier _ca.calm>>(<<print Math.floor(_ca.calm)>>)</div> <div class="cp-arch-row">好感 bond:<<print Math.floor(_ca.bond)>> 当日趋势 bondDrift:<<print (_ca.bondDrift||0).toFixed(1)>></div> <div class="cp-arch-row">模式 mode:<<print _ca.mode>></div> </div> <div class="cp-arch-section"> <div class="cp-arch-h">近期时间线(recentEvents)</div> <<set _caEventKeys = Object.keys(_ca.recentEvents)>> <<for _caKI = 0; _caKI < _caEventKeys.length; _caKI++>> <<set _caK = _caEventKeys[_caKI]>> <<set _caSlot = _ca.recentEvents[_caK]>> <<if _caSlot && _caK === "intentFrustrated" && _caSlot.plan>> <div class="cp-arch-row">意图落空:本来想「<<print _caSlot.plan>>」,但是「<<print _caSlot.reason>>」(剩 <<print Math.max(0, _caSlot.expire - $day)>> 天)</div> <<elseif _caSlot && _caSlot.tag>> <div class="cp-arch-row"><<print _caK>>:「<<print _caSlot.tag>>」(第 <<print _caSlot.day>> 天,剩 <<print Math.max(0, _caSlot.expire - $day)>> 天)</div> <</if>> <</for>> </div> <div class="cp-arch-section"> <div class="cp-arch-h">物品库(inventory)</div> <<set _caHasInv = false>> <<set _caInvKeys = Object.keys(_ca.inventory)>> <<for _caIKI = 0; _caIKI < _caInvKeys.length; _caIKI++>> <<set _caIK = _caInvKeys[_caIKI]>> <<if _ca.inventory[_caIK] > 0>> <<set _caHasInv = true>> <<set _caInvDef = State.variables.items[_caIK]>> <div class="cp-arch-row"><<print _caInvDef ? _caInvDef.name : _caIK>> ×<<print _ca.inventory[_caIK]>></div> <</if>> <</for>> <<if !_caHasInv>><div class="cp-arch-row">(空)</div><</if>> </div> <div class="cp-arch-section"> <div class="cp-arch-h">中期记忆(memories)</div> <<if _ca.memories.length === 0>><div class="cp-arch-row">(暂无)</div> <<else>> <<for _caM = 0; _caM < _ca.memories.length; _caM++>> <div class="cp-arch-row">· <<print _ca.memories[_caM]>></div> <</for>> <</if>> </div> <div class="cp-arch-section"> <div class="cp-arch-h">性格(quirks)</div> <<set _caQuirkKeys = Object.keys(_ca.quirks)>> <<for _caQI = 0; _caQI < _caQuirkKeys.length; _caQI++>> <<set _caQK = _caQuirkKeys[_caQI]>> <<if _ca.quirks[_caQK] !== 0>> <div class="cp-arch-row"><<print _caQK>>:<<print _ca.quirks[_caQK]>></div> <</if>> <</for>> <div class="cp-arch-row">foodAttitude:<<print _ca.foodAttitude>></div> </div> <div class="cp-arch-section"> <div class="cp-arch-h">玩家近期行为($playerRecent)</div> <div class="cp-arch-row">捕获:<<print $playerRecent.caught || "(空)">></div> <div class="cp-arch-row">战斗:<<print $playerRecent.fought || "(空)">></div> <div class="cp-arch-row">最近动作:<<print $playerRecent.lastAction || "(空)">></div> <div class="cp-arch-row">最近收获:<<print $playerRecent.lastHarvest || "(空)">></div> </div> <div class="cp-detail-return"> <<link "返回">><<goto "cp详情">><</link>> </div> </div> <</if>> <</nobr>>
<<nobr>> /* 物品: 赠礼三入口(菜肴/材料/礼物), 调用 cpGift。 $cpGiftTab 控制当前展示的分类(food/material/gift)。 */ <<set _cgCp = $cps[$detailCpId]>> <<if !_cgCp>> <p>找不到角色数据。</p> <<link "返回">><<goto "cp详情">><</link>> <<else>> <<if $cpGiftReply>><div class="cp-gift-reply"><<print $cpGiftReply>></div><</if>> <div class="cp-gift-h">你想送给 <<print _cgCp.name>> 什么?</div> <<if !$cpGiftTab>> <<link "🍽 菜肴 / 食物">><<set $cpGiftTab = "food">><<goto "cp物品">><</link>> <<link "📦 材料">><<set $cpGiftTab = "material">><<goto "cp物品">><</link>> <<link "🎁 礼物(非消耗)">><<set $cpGiftTab = "gift">><<goto "cp物品">><</link>> <<link "返回">><<goto "cp详情">><</link>> <<else>> <<set _cgList = []>> <<set _cgStoreKeys = Object.keys($store)>> <<for _cgKI = 0; _cgKI < _cgStoreKeys.length; _cgKI++>> <<set _cgCat = _cgStoreKeys[_cgKI]>> <<if Array.isArray($store[_cgCat])>> <<for _cgE = 0; _cgE < $store[_cgCat].length; _cgE++>> <<set _cgItem = $store[_cgCat][_cgE]>> <<set _cgDef = State.variables.items[_cgItem.id]>> <<if _cgItem.quantity > 0 && _cgDef>> <<if $cpGiftTab === "food" && _cgDef.foodtags && _cgDef.foodtags.length > 0>> <<run _cgList.push(_cgItem.id)>> <<elseif $cpGiftTab === "material" && (!_cgDef.foodtags || _cgDef.foodtags.length === 0) && !_cgDef.gift>> <<run _cgList.push(_cgItem.id)>> <<elseif $cpGiftTab === "gift" && _cgDef.gift>> <<run _cgList.push(_cgItem.id)>> <</if>> <</if>> <</for>> <</if>> <</for>> <<if _cgList.length === 0>> <p>仓库里没有可用的<<print ($cpGiftTab === "food" ? "菜肴" : ($cpGiftTab === "gift" ? "礼物" : "材料"))>>。</p> <</if>> <<for _cgI = 0; _cgI < _cgList.length; _cgI++>> <<set _cgId2 = _cgList[_cgI]>> <<set _cgDef = State.variables.items[_cgId2]>> <<set _cgQty = 0>> <<set _cgStoreKeys2 = Object.keys($store)>> <<for _cgKI2 = 0; _cgKI2 < _cgStoreKeys2.length; _cgKI2++>> <<set _cgCat2 = _cgStoreKeys2[_cgKI2]>> <<if Array.isArray($store[_cgCat2])>> <<for _cgE2 = 0; _cgE2 < $store[_cgCat2].length; _cgE2++>> <<set _cgItem2 = $store[_cgCat2][_cgE2]>> <<if _cgItem2.id === _cgId2>><<set _cgQty = _cgItem2.quantity>><</if>> <</for>> <</if>> <</for>> <<capture _cgId2 _cgQty _cgDef>> <<link _cgDef.name + " ×" + _cgQty>> <<cpGift $detailCpId _cgId2 $cpGiftTab>> <<goto "cp物品">> <</link>> <</capture>> <</for>> <<link "← 返回分类">><<set $cpGiftTab = undefined>><<goto "cp物品">><</link>> <<link "返回">><<goto "cp详情">><</link>> <</if>> <</if>> <</nobr>>
<<nobr>> /* 聊聊: 随机一句环境/状态短句, 标记当日已聊。文案占位, 待文案人扩充到 15-20 条。 */ <<set _cl = $cps[$detailCpId]>> <<if !_cl>> <p>找不到角色数据。</p> <<link "返回">><<goto "cp详情">><</link>> <<else>> <<set $cps[$detailCpId].lastChatDay = $day>> <<if _cl.mode !== "interact">> <<set _clNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<set $cps[$detailCpId].mode = "interact">> <<set $cps[$detailCpId].interactStart = _clNow>> /* 记录"开始对话时 CP 正在做的事"的结束时间, 作为允许提离开的门槛 */ <<set $cps[$detailCpId].interactActivityEnd = _cl.actionEndTime>> <</if>> <<set $minute += 1>> <<if $minute >= 60>><<set $minute = $minute - 60>><<set $hour += 1>><</if>> <<if $hour >= 24>><<set $hour = $hour - 24>><<set $day += 1>><</if>> <<cpTick>> <<if _cl.mood >= 80>><<set _clMoodTier = "很好">> <<elseif _cl.mood >= 60>><<set _clMoodTier = "不错">> <<elseif _cl.mood >= 40>><<set _clMoodTier = "平常">> <<elseif _cl.mood >= 20>><<set _clMoodTier = "低落">> <<else>><<set _clMoodTier = "糟糕">> <</if>> <<set _clGenericLines = [ "(" + _cl.name + " 望了你一眼,没说话,又转回头去。)", _cl.name + ":今天水流挺平的。", _cl.name + ":你刚才跑哪去了?", _cl.name + ":有点想吃口热乎的。", _cl.name + ":这潜艇待久了,倒也安稳。", _cl.name + ":外头黑漆漆的,你别乱跑。", "(" + _cl.name + " 打了个哈欠,看起来" + _clMoodTier + "。)" ]>> <<set _clLines = _cl.id === "viona" ? [] : _clGenericLines>> <<if _cl.id === "viona" && _cl.location === "仓库">> <<run _clLines.push("维奥娜:我不喜欢炼金。这很难理解吗?")>> <<run _clLines.push("维奥娜:这种地方让人感觉有些焦虑。")>> <<run _clLines.push("维奥娜:抱歉,但你是怎么做到保证每次炼金都成功的呢?")>> <<run _clLines.push("维奥娜:其实炼金很神奇,如果我能学会的话就更好了。")>> <<run _clLines.push("维奥娜:你有没有感觉有什么东西快要爆炸了?")>> <<run _clLines.push("维奥娜:这味道好难闻……")>> <<run _clLines.push("维奥娜:额,刚刚那一锅东西像一堆撒着辣椒面的……咖喱?")>> <</if>> <<if _cl.id === "viona" && _cl.location === "浴室">> <<run _clLines.push("维奥娜:你好过分哦。")>> <<run _clLines.push("维奥娜:洗完澡之后最好的就是来一杯果汁了。")>> <<run _clLines.push("维奥娜:我有跟你说过我其实不喜欢我们的肥皂吗?")>> <<run _clLines.push("维奥娜:好闷热啊,这里有没有排风扇之类的东西?")>> <<run _clLines.push("维奥娜:我感觉头有点疼……不是生病的那种,我没关系。")>> <<run _clLines.push("维奥娜:你这个坏蛋。")>> <</if>> <<if _cl.id === "viona" && _cl.location === "驾驶舱">> <<if _cl.mood >= 75>> <<run _clLines.push("维奥娜:很高兴你来了!这里的海好漂亮。")>> <<run _clLines.push("维奥娜:我们今天要去哪里?只是好奇,船长老大。")>> <<run _clLines.push("维奥娜:嗯哼,我没有在这里等你哦?")>> <<elseif _cl.mood < 35>> <<run _clLines.push("维奥娜:抱歉。我只是……感觉有些不舒服。")>> <<run _clLines.push("维奥娜:不要烦我了,给我一点时间,好吗?")>> <<run _clLines.push("维奥娜:好想吃巧克力……不,当你没听到。")>> <<else>> <<run _clLines.push("维奥娜:好无聊,你有没有这种感觉?")>> <<run _clLines.push("维奥娜:在很久很久以前的陆地上……好吧,那我不讲了。")>> <<run _clLines.push("维奥娜:我宣布,我其实有些饿……不,不用,我没有饿到马上就要吃的程度。")>> <</if>> <<if $maptype === "flat">> <<run _clLines.push("维奥娜:你好不好奇,这些人类在这里曾经如何生活?")>> <<run _clLines.push("维奥娜:这种地方让人觉得好痛苦。")>> <<elseif $maptype === "grass">> <<run _clLines.push("维奥娜:我喜欢这里,很舒服;有很多生命生活在这里。")>> <<run _clLines.push("维奥娜:这个时候就不要出门了,海草很难缠,你知道的。")>> <<elseif $maptype === "forest">> <<run _clLines.push("维奥娜:陆地上的森林也是这样的吗?")>> <<run _clLines.push("维奥娜:我刚看到一种很美味的藻类,是辣的。")>> <<elseif $maptype === "reef">> <<run _clLines.push("维奥娜:我的手在这种地方被扎破过,噫,真恶心。")>> <<run _clLines.push("维奥娜:如果那边的洞里冒出某种鬼魂,我也丝毫都不会意外。")>> <<elseif $maptype === "sand">> <<run _clLines.push("维奥娜:我们的所有鱼枪在这里都会卷刃的。")>> <<run _clLines.push("维奥娜:我心都碎了,这地方好丑。")>> <<elseif $maptype === "cliff">> <<run _clLines.push("维奥娜:有点吓人,是不是?")>> <<run _clLines.push("维奥娜:我赌十个贝壳,这底下准得有一千米。")>> <</if>> <<if $weather === 6 || $weather === 7>> <<run _clLines.push("维奥娜:下雨了?但我们在海里哎,莫非空气湿度还能提高吗,哈哈!")>> <<run _clLines.push("维奥娜:把船停到海面上吧,我想听雨的声音。")>> <<elseif $weather === 4 || $weather === 2>> <<run _clLines.push("维奥娜:哦,不行,我们得下潜,别问为什么,我要被烤成灰烬了。")>> <<run _clLines.push("维奥娜:这会影响我们的气压吗?")>> <<elseif $weather === 5 || $weather === 3>> <<run _clLines.push("维奥娜:说真的,我最喜欢这种场景,你不觉得这时候的海面很美吗?")>> <<run _clLines.push("维奥娜:要刮大风了,海浪要涌起来了。")>> <</if>> <<if $sailspd > 0>> <<run _clLines.push("维奥娜:所以……你好不好奇往另一边拐一下会发生什么?")>> <<run _clLines.push("维奥娜:我们刚刚那一路至少错过十万条大肥鱼。")>> <<run _clLines.push("维奥娜:噫,你要撞到石壁上了!")>> <<run _clLines.push("维奥娜:你刚刚把船开得很烂。")>> <<run _clLines.push("维奥娜:我有些想吐了,抱歉。")>> <<run _clLines.push("维奥娜:你来带我去兜风?那就快些,别磨磨唧唧的!")>> <</if>> <<if _cl.recentEvents && _cl.recentEvents.catch && _cl.recentEvents.catch.product>> <<run _clLines.push("维奥娜:我们现在要去抓一条新的「" + _cl.recentEvents.catch.product + "」,是不是?")>> <</if>> <<if _cl.recentEvents && _cl.recentEvents.destination && _cl.recentEvents.destination.target && _cl.recentEvents.catch && _cl.recentEvents.catch.product && _cl.recentEvents.cooked && _cl.recentEvents.cooked.product>> <<run _clLines.push("维奥娜:我们是不是要去「" + _cl.recentEvents.destination.target + "」?那里可是抓「" + _cl.recentEvents.catch.product + "」的好地方,我爱吃你做的「" + _cl.recentEvents.cooked.product + "」。")>> <</if>> <</if>> <<if _cl.id === "viona" && _cl.recentEvents && _cl.recentEvents.alchemy && _cl.recentEvents.alchemy.product>> <<run _clLines.push("维奥娜:上次炼出的「" + _cl.recentEvents.alchemy.product + "」,你还能教教我吗?")>> <</if>> <<set _clLine = _clLines[Math.floor(Math.random() * _clLines.length)]>> <div class="cp-chat"> <<print _clLine>> <div class="cp-chat-note">(闲聊了一会儿,时间悄悄流过。)</div> </div> <div class="cp-detail-return"> <<link "返回">><<goto "cp详情">><</link>> </div> <</if>> <</nobr>>
<<nobr>> /* 询问: 关键词话题(记忆驱动) + 邀ta一起做(协同行动过渡页) */ <<set _cq = $cps[$detailCpId]>> <<if !_cq>> <p>找不到角色数据。</p> <<link "返回">><<goto "cp详情">><</link>> <<else>> /* ── 重置状态机(如果从其他页面回来时处于 done) ── */ <<if $cpAskState === "done">> <<set $cpAskState = "select">> <<set $cpAskTopic = "">> <<set $cpAskRound = 0>> <<set $cpAskReply = "">> <</if>> <<if !$cpAskState>><<set $cpAskState = "select">><</if>> /* ── 显示当前回复 ── */ <<if $cpAskReply>><div class="cp-ask-reply"><<print $cpAskReply>></div><</if>> <<if $cpAskState === "select">> <div class="cp-ask-h">你想问点什么?</div> <<set _cqTopics = []>> <<if _cq.recentEvents.went_out.tag>><<run _cqTopics.push({t:"你刚才出去都见到什么了?",r1:"也没见着什么特别的,就几尾鱼从灯影里游过去。",r2:"倒是水色比前几天清些。"})>><</if>> <<if _cq.recentEvents.cooked.tag>><<run _cqTopics.push({t:"今天做的菜还合胃口吗?",r1:"还行,盐放少了点。",r2:"下次你可以尝尝。"})>><</if>> <<if _cq.memories.includes("made_breakfast_first")>><<run _cqTopics.push({t:"我还记得你第一次给我做早饭。",r1:"……那么久的事你还记得。",r2:"当时火候没掌握好,你别嫌弃就行。"})>><</if>> <<if _cq.recentEvents.intentFrustrated.plan>><<run _cqTopics.push({t:"你之前说想" + _cq.recentEvents.intentFrustrated.plan + ",后来呢?",r1:"后来?后来你不是有事吗。",r2:"也没什么,都过去了。"})>><</if>> <<run _cqTopics.push({t:"最近海域有什么新鲜事?",r1:"听说东北方向的水温有点异常,可能是热液活动。",r2:"具体我也不清楚,反正小心点总没错。"})>> <<run _cqTopics.push({t:"你这会儿在想什么呢?",r1:"没想什么,就发呆。",r2:"……在想今天吃什么。"})>> <<run _cqTopics.push({t:"还习惯待在船上吗?",r1:"比我想象中安静。",r2:"就是地方小了点,转个身都怕撞到头。"})>> <<for _cqI = 0; _cqI < _cqTopics.length; _cqI++>> <<capture _cqI>> <div class="cp-ask-option"> <<link _cqTopics[_cqI].t>> /* 首次互动: 切到 interact, 记录当前行动结束时间为离开门槛 */ <<if _cq.mode !== "interact">> <<set _cqNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<set $cps[$detailCpId].mode = "interact">> <<set $cps[$detailCpId].interactStart = _cqNow>> <<set $cps[$detailCpId].interactActivityEnd = _cq.actionEndTime>> <</if>> /* 询问耗时 1 分钟 */ <<set $minute += 1>> <<if $minute >= 60>><<set $minute = $minute - 60>><<set $hour += 1>><</if>> <<if $hour >= 24>><<set $hour = $hour - 24>><<set $day += 1>><</if>> <<cpTick>> <<set $cpAskState = "talking">> <<set $cpAskTopic = _cqTopics[_cqI]>> <<set $cpAskRound = 1>> <<set $cpAskReply = _cq.name + " 偏头想了想:「" + _cqTopics[_cqI].r1 + "」">> <<goto "cp询问">> <</link>> </div> <</capture>> <</for>> <div class="cp-ask-h">邀ta一起做点什么(会打断当前安排)</div> <div class="cp-ask-option"><<link "一起做饭">><<set $cpTogetherTarget = "厨房">><<set $cpTogetherLabel = "厨房">><<goto "cp一起去做">><</link>></div> <div class="cp-ask-option"><<link "一起看舱外">><<set $cpTogetherTarget = "驾驶舱">><<set $cpTogetherLabel = "驾驶舱">><<goto "cp一起去做">><</link>></div> <div class="cp-ask-option"><<link "一起吃点">><<set $cpTogetherTarget = "厨房">><<set $cpTogetherLabel = "厨房">><<goto "cp一起去做">><</link>></div> <<elseif $cpAskState === "talking">> <<if $cpAskRound === 1>> <div class="cp-ask-h">要继续问下去吗?</div> <div class="cp-ask-option"> <<link "继续问">> <<set $cpAskRound = 2>> <<set $cpAskReply = _cq.name + ":「" + $cpAskTopic.r2 + "」">> <<goto "cp询问">> <</link>> </div> <div class="cp-ask-option"> <<link "到此为止">> <<set $cpAskState = "done">> <<set $cpAskReply = "">> <<goto "cp详情">> <</link>> </div> <<else>> <div class="cp-ask-h">对话结束了。</div> <div class="cp-ask-option"> <<link "返回">> <<set $cpAskState = "done">> <<set $cpAskReply = "">> <<goto "cp详情">> <</link>> </div> <</if>> <</if>> <div class="cp-detail-return"> <<link "返回 cp详情">> <<set $cpAskState = "done">> <<set $cpAskReply = "">> <<goto "cp详情">> <</link>> </div> <</if>> <</nobr>>
<<nobr>> <<cpRoomCheck passage()>> <<set _cd = $cps[$detailCpId]>> <<if !_cd>> <p>找不到对应的角色数据。</p> <<link "返回">><<navigate "back">><</link>> <<else>> /* ── 进入前: 同步 mood(浮点), 处理退出机制 ── */ <<set $cps[$detailCpId].mood = Math.max(0, Math.min(100, _cd.moodBase + _cd.moodMod))>> <<set _cdNow = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<if _cd.mode === "interact">> <<set _cdElap = _cdNow - _cd.interactStart>> <<set _cdMinSurv = Math.min(_cd.hunger, _cd.water, _cd.energy)>> /* 约束: 只有"开始对话时它正在做的事"已经结束, 且生存值确实偏低, 才提离开 */ <<set _cdActEnd = (_cd.interactActivityEnd !== undefined && _cd.interactActivityEnd > 0) ? _cd.interactActivityEnd : _cd.actionEndTime>> <<if !_cd.leaveRequested && _cdElap >= 10 && _cdMinSurv < 50 && _cdNow >= _cdActEnd>> <<set $cps[$detailCpId].leaveRequested = true>> <</if>> <<if _cd.leaveRequested && _cd.leaveDeniedAt > 0 && (_cdNow - _cd.leaveDeniedAt) >= 10>> /* 再陪10分钟后直接走(恢复自主) */ <<set $cps[$detailCpId].mode = "auto">> <<set $cps[$detailCpId].leaveRequested = false>> <<set $cps[$detailCpId].leaveDeniedAt = 0>> <</if>> <</if>> <<set _cd = $cps[$detailCpId]>> /* ── 行动剩余时间 ── */ <<set _cdRemain = Math.max(0, _cd.actionEndTime - _cdNow)>> <<set _cdRemH = Math.floor(_cdRemain / 60)>> <<set _cdRemM = _cdRemain % 60>> /* ── 描述(从 detailTexts) ── */ <<set _cdPool = _cd.detailTexts ? _cd.detailTexts[_cd.action] : null>> <<set _cdDesc = "">> <<if !_cdPool>> <<set _cdDesc = _cd.name + "在这里,没做什么特别的事。">> <<elseif Array.isArray(_cdPool)>> <<set _cdDesc = _cdPool[Math.floor(Math.random() * _cdPool.length)]>> <<else>> <<set _cdDesc = _cdPool>> <</if>> <<if _cd.actionDetail>><<set _cdDesc = _cdDesc + "(" + _cd.actionDetail + ")">><</if>> /* ── 状态 tag ── */ <<set _cdTags = []>> <<if _cd.wet>><<run _cdTags.push("潮湿")>><</if>> <<if _cd.sick>><<run _cdTags.push("生病")>><</if>> <<if _cd.injured === 1>><<run _cdTags.push("轻伤")>> <<elseif _cd.injured === 2>><<run _cdTags.push("重伤")>><</if>> /* ── 一次性后果场景(giftAftermath) ── */ <<if _cd.giftAftermath && !_cd.giftAftermath.triggered>> <div class="cp-aftermath">你看到 <<print _cd.name>> 正就着舷窗慢条斯理地享用着<<print _cd.giftAftermath.label>>。</div> <<set $cps[$detailCpId].giftAftermath.triggered = true>> <</if>> <div id="cp-detail"> <div class="cp-detail-name"><<print _cd.name>></div> <div class="cp-detail-desc"><<print _cdDesc>></div> <div class="cp-detail-timer"> 当前行动还有 <<if _cdRemH > 0>><<print _cdRemH>> 小时 <</if>><<print _cdRemM>> 分钟结束 </div> <div class="cp-detail-stats"> <div class="stat-row"> <span class="stat-label">饥饿</span> <span class="stat-bar"><span class="stat-fill" style="width:<<print Math.floor(_cd.hunger)>>%;background:<<print (_cd.hunger < 20) ? 'var(--danger-bright,#e55)' : 'var(--teal-bright,#4ecdc4)'>;"></span></span> <span class="stat-num"><<print Math.floor(_cd.hunger)>></span> </div> <div class="stat-row"> <span class="stat-label">饮水</span> <span class="stat-bar"><span class="stat-fill" style="width:<<print Math.floor(_cd.water)>>%;background:<<print (_cd.water < 20) ? 'var(--danger-bright,#e55)' : 'var(--teal-bright,#4ecdc4)'>;"></span></span> <span class="stat-num"><<print Math.floor(_cd.water)>></span> </div> <div class="stat-row"> <span class="stat-label">精力</span> <span class="stat-bar"><span class="stat-fill" style="width:<<print Math.floor(_cd.energy)>>%;background:<<print (_cd.energy < 20) ? 'var(--danger-bright,#e55)' : 'var(--teal-bright,#4ecdc4)'>;"></span></span> <span class="stat-num"><<print Math.floor(_cd.energy)>></span> </div> <<cpMoodBar $detailCpId "mood">> <<cpMoodBar $detailCpId "calm">> <div class="stat-row"> <span class="stat-label">好感</span> <span class="stat-bar"><span class="stat-fill" style="width:<<print Math.floor(_cd.bond)>>%;"></span></span> <span class="stat-num"><<print Math.floor(_cd.bond)>></span> </div> </div> <<if _cdTags.length > 0>> <div class="cp-detail-tags"> <<for _cdTI = 0; _cdTI < _cdTags.length; _cdTI++>> <span class="cp-tag"><<print _cdTags[_cdTI]>></span> <</for>> </div> <</if>> /* ══════════ 独立信息按钮(档案, 纯查看) ══════════ */ <div class="cp-detail-info"> <<link "📋 档案 / 时间线">><<goto "cp档案">><</link>> </div> /* ══════════ 打断提示(不可中断行动) ══════════ */ <<set _cdNonInt = ["sleep","nap","outside","cook","disassemble","eat"].includes(_cd.action)>> <<if _cd.mode === "auto" && _cdNonInt>> <div class="cp-interrupt-hint"> <<print _cd.name>> 正在<<print (_cd.action === "sleep" || _cd.action === "nap") ? "休息" : (_cd.action === "outside" ? "舱外" : _cd.action)>>,暂时走不开。 <<link "打断">> <<set _cdNow2 = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<set $cps[$detailCpId].mode = "interact">> <<set $cps[$detailCpId].action = "interact">> <<set $cps[$detailCpId].actionDetail = "">> <<set $cps[$detailCpId].actionEndTime = _cdNow2>> <<set $cps[$detailCpId].interactActivityEnd = _cdNow2>> <<set $cps[$detailCpId].interactStart = _cdNow2>> /* 打断惩罚(按 quirks) */ <<set _cdIrqKey = (_cd.action === "sleep" || _cd.action === "nap") ? "sleep_interrupt" : (_cd.action === "cook" ? "craft_interrupt" : (_cd.action === "eat" ? "eat_interrupt" : null))>> <<if _cdIrqKey && _cd.quirks && _cd.quirks[_cdIrqKey]>> <<set $cps[$detailCpId].moodMod = Math.max(-20, _cd.moodMod + _cd.quirks[_cdIrqKey])>> <</if>> <<goto "cp详情">> <</link>> </div> <</if>> /* ══════════ 退出提示(≥10分钟且生存值<50) ══════════ */ <<if _cd.mode === "interact" && _cd.leaveRequested>> <<set _cdLowName = (_cd.hunger <= _cd.water && _cd.hunger <= _cd.energy) ? "吃点东西" : (_cd.water <= _cd.energy ? "喝口水" : "歇一会儿")>> <div class="cp-leave-hint"> <<print _cd.name>> :我想去<<print _cdLowName>>了。 <<link "允许">> <<set $cps[$detailCpId].mode = "auto">> <<set $cps[$detailCpId].leaveRequested = false>> <<set $cps[$detailCpId].leaveDeniedAt = 0>> <<goto "cp详情">> <</link>> <<link "再陪会儿">> <<set $cps[$detailCpId].leaveDeniedAt = ($day || 1) * 1440 + ($hour || 7) * 60 + ($minute || 0)>> <<goto "cp详情">> <</link>> </div> <</if>> /* ══════════ 互动区(顺序: ★特殊 / 聊聊 / 询问 / 物品 / 离开) ══════════ */ <div class="cp-interact"> <<if _cd.pendingImportantEvent && _cd.pendingImportantEvent.passage>> <<link "★ 她似乎有话要说">> <<set $cpEventReturn = passage()>> <<set _cdEvt = _cd.pendingImportantEvent>> <<set $cps[$detailCpId].pendingImportantEvent = null>> <<navigate "go" _cdEvt.passage>> <</link>> <</if>> <<link "聊聊">><<goto "cp聊聊">><</link>> <<link "询问">> <<set $cpAskState = "select">> <<set $cpAskTopic = "">> <<set $cpAskRound = 0>> <<set $cpAskReply = "">> <<goto "cp询问">> <</link>> <<link "物品">><<goto "cp物品">><</link>> <<link "离开">> <<if !$cpReturnPassage>><<set $cpReturnPassage = "走廊">><</if>> <<goto $cpReturnPassage>> <</link>> </div> </div> <</if>> <</nobr>>
<<nobr>> <<if !$npcDefTable>><<npcDefs>><</if>> <<if !$npcState || !$npcState.npcId>><<goto ($npcReturn || "航行")>><</if>> <<set _nsId = $npcState.npcId>> <<set _nsDef = $npcDefTable[_nsId]>> <<set _nsRet = $npcReturn || "航行">> <<if !_nsDef>><<goto _nsRet>><</if>> /* 进入商店台词 */ <<set _nsEntryLine = _nsDef.tradeComment[Math.floor(Math.random()*_nsDef.tradeComment.length)]>> /* 珍珠数量(store里) */ <<set _nsPearl = 0>> <<if $store && $store["基础材料"]>> <<for _nsPi = 0; _nsPi < $store["基础材料"].length; _nsPi++>> <<if $store["基础材料"][_nsPi].id === "pearl">> <<set _nsPearl = $store["基础材料"][_nsPi].quantity || 0>> <</if>> <</for>> <</if>> <div style="max-width:520px;margin:0 auto;padding:0.5rem 0.6rem;"> <div style="border:1px solid var(--amber-bright);border-radius:4px;padding:0.5rem 0.8rem;margin-bottom:0.4rem;"> <div style="color:var(--amber-bright);font-size:0.8rem;margin-bottom:0.2rem;">🏪 <<print _nsDef.name>> 的货物</div> <div style="font-size:0.78rem;color:var(--bone-dim);font-style:italic;margin-bottom:0.3rem;">「<<print _nsEntryLine>>」</div> <div style="font-size:0.74rem;color:var(--bone-dim);margin-bottom:0.3rem;">💠 持有珍珠:<<print _nsPearl>> 颗</div> /* 商品列表 */ <<for _nsGi = 0; _nsGi < _nsDef.shop.length; _nsGi++>> <<set _nsGoods = _nsDef.shop[_nsGi]>> <<set _nsCanBuy = (_nsPearl >= _nsGoods.price)>> <<capture _nsGoods, _nsCanBuy, _nsPearl>> <div style="display:flex;justify-content:space-between;align-items:center;padding:0.18rem 0;border-bottom:1px solid var(--border-dim);"> <span style="font-size:0.82rem;color:var(--bone);"><<print _nsGoods.name>></span> <span> <span style="font-size:0.76rem;color:var(--amber-bright);margin-right:0.5rem;">💠×<<print _nsGoods.price>></span> <<if _nsCanBuy>> <<link "购买">> <<removeitem "pearl" _nsGoods.price>> <<additem _nsGoods.id 1>> <<set _nsBuyLine = _nsDef.buyComment[Math.floor(Math.random()*_nsDef.buyComment.length)]>> <<set $lastSmallEventText = _nsDef.name + ":「" + _nsBuyLine + "」">> <<goto "NPC_商店">> <</link>> <<else>> <span style="font-size:0.75rem;opacity:0.35;">珍珠不足</span> <</if>> </span> </div> <</capture>> <</for>> <div style="margin-top:0.35rem;"> <<link "结束交易">> <<set $lastSmallEventText = _nsDef.name + "收起了货物,道了声再见。">> <<set $activeNpc = null>> <<set $npcCooldownTicks = _nsDef.cooldownDays * 600>> <<set $npcSpawnCooldown = ($day||0) + _nsDef.cooldownDays>> <<goto _nsRet>> <</link>> <<link "回到对话">><<goto "NPC_对话">><</link>> </div> </div> </div> <</nobr>>
<<nobr>> <<set _npcN = ($npcState && $npcState.npcName) ? $npcState.npcName : "陌生商人">> <<set _npcRet = $npcReturn || "航行">> <div style="max-width:520px;margin:0 auto;padding:0.6rem;"> <div style="border:1px solid var(--amber-bright);border-radius:4px;padding:0.5rem 0.8rem;"> <div style="color:var(--amber-bright);font-size:0.8rem;margin-bottom:0.2rem;">🏪 <<print _npcN>> 的商店</div> <div style="background:rgba(180,140,60,0.08);border:1px dashed #876;border-radius:3px;padding:0.25rem 0.5rem;font-size:0.72rem;color:#a98;margin-bottom:0.25rem;">🔧 施工中 — NPC 商店 v0(占位)<br>NPC ID:<<print ($npcState && $npcState.npcId) ? $npcState.npcId : "unknown">></div> <div style="font-size:0.82rem;color:var(--bone);line-height:1.8;margin-bottom:0.25rem;"><<print _npcN>>向你展示了一些货物。购买系统尚在建设中。</div> <<link "离开商店">> <<set $lastSmallEventText = "和" + _npcN + "打了个招呼,暂时没有交易。">> <<set $npcState = null>><<goto _npcRet>> <</link>> </div></div> <</nobr>>
<<nobr>> <<if !$npcDefTable>><<npcDefs>><</if>> <<if !$activeNpc>><<goto ($npcReturn || "航行")>><</if>> <<set _ntDef = $activeNpc>> <<set _ntRet = $npcReturn || "航行">> /* 判断是否首次见面 */ <<set _ntMet = $metNpcs[_ntDef.id]>> <<set _ntIsFirst = !_ntMet>> /* 更新见面记录 */ <<if _ntIsFirst>> <<set $metNpcs[_ntDef.id] = { firstDay: ($day||0), meetCount: 1 }>> <<else>> <<set $metNpcs[_ntDef.id].meetCount += 1>> <</if>> /* 随机台词 */ <<set _ntGreetPool = _ntIsFirst ? _ntDef.greeting : _ntDef.reGreeting>> <<set _ntGreet = _ntGreetPool[Math.floor(Math.random() * _ntGreetPool.length)]>> <<set _ntChatLine = _ntDef.chat[Math.floor(Math.random() * _ntDef.chat.length)]>> <div style="max-width:520px;margin:0 auto;padding:0.5rem 0.6rem;"> <div style="border:1px solid var(--teal-bright);border-radius:4px;padding:0.5rem 0.8rem;margin-bottom:0.4rem;"> <div style="color:var(--teal-bright);font-size:0.8rem;margin-bottom:0.3rem;">💬 <<print _ntDef.name>></div> <div style="font-size:0.85rem;color:var(--bone);line-height:1.9;margin-bottom:0.35rem;font-style:italic;">「<<print _ntGreet>>」</div> /* 闲聊选项 */ <<link "闲聊一句">> <<set $npcState = {npcId: _ntDef.id, npcName: _ntDef.name, chatLine: _ntChatLine}>> <<goto "NPC_闲聊">> <</link>><br> /* 商店选项 */ <<if _ntDef.shop && _ntDef.shop.length > 0>> <<link "查看货物">> <<set $npcState = {npcId: _ntDef.id, npcName: _ntDef.name}>> <<set $npcReturn = _ntRet>> <<goto "NPC_商店">> <</link>><br> <</if>> /* 离开 */ <<link "道别离开">> <<set $lastSmallEventText = "和" + _ntDef.name + "道了别。">> <<set $activeNpc = null>> <<set $npcCooldownTicks = _ntDef.cooldownDays * 600>> <<set $npcSpawnCooldown = ($day||0) + _ntDef.cooldownDays>> <<goto _ntRet>> <</link>> </div> </div> <</nobr>>
<<nobr>> <<set _npcN = ($npcState && $npcState.npcName) ? $npcState.npcName : "陌生人">> <<set _npcRet = $npcReturn || "航行">> <div style="max-width:520px;margin:0 auto;padding:0.6rem;"> <div style="border:1px solid var(--teal-bright);border-radius:4px;padding:0.5rem 0.8rem;"> <div style="color:var(--teal-bright);font-size:0.8rem;margin-bottom:0.2rem;">💬 与 <<print _npcN>> 对话</div> <div style="background:rgba(0,180,150,0.05);border:1px dashed #466;border-radius:3px;padding:0.25rem 0.5rem;font-size:0.72rem;color:#8aa;margin-bottom:0.25rem;">🔧 施工中 — NPC 对话 v0(占位)<br>NPC ID:<<print ($npcState && $npcState.npcId) ? $npcState.npcId : "unknown">></div> <div style="font-size:0.82rem;color:var(--bone);line-height:1.8;margin-bottom:0.25rem;"><<print _npcN>>打量了你一会儿,若有所思。对话系统尚在建设中。</div> <<link "结束对话">> <<set $lastSmallEventText = "和" + _npcN + "简短地交谈了几句。">> <<set $npcState = null>><<goto _npcRet>> <</link>> </div></div> <</nobr>>
<<nobr>> <<if !$npcState>><<goto ($npcReturn || "航行")>><</if>> <<set _ncRet = $npcReturn || "航行">> <<set _ncName = $npcState.npcName || "陌生人">> <<set _ncLine = $npcState.chatLine || "……">> <div style="max-width:520px;margin:0 auto;padding:0.5rem 0.6rem;"> <div style="border:1px solid var(--teal-bright);border-radius:4px;padding:0.5rem 0.8rem;margin-bottom:0.4rem;"> <div style="color:var(--teal-bright);font-size:0.8rem;margin-bottom:0.3rem;">💬 <<print _ncName>></div> <div style="font-size:0.85rem;color:var(--bone);line-height:1.9;margin-bottom:0.35rem;font-style:italic;">「<<print _ncLine>>」</div> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.3rem;">你点了点头,没有多说什么。</div> <<link "回到对话">><<goto "NPC_对话">><</link>> </div> </div> <</nobr>>
<<nobr>> <<if !$shipSystems>> <<set $shipSystems = { propulsion:true, fishing:true, oxygen:true, heating:true, storage:true }>> <</if>> <<if !$shipUpgrades>> <<set $shipUpgrades = { speed:0, armor:0, insulation:0, capacity:0, sonar:0 }>> <</if>> <<if !$shipOxygen>><<set $shipOxygen = 100>><</if>> <<set _sh_hcol = $shell < 25 ? "var(--danger-bright)" : $shell < 50 ? "var(--amber)" : "var(--teal-bright)">> <<set _sh_fcol = $fuel < 5000 ? "var(--danger-bright)" : $fuel < 15000 ? "var(--amber)" : "var(--bone-dim)">> <<set _sh_ocol = $shipOxygen < 20 ? "var(--danger-bright)" : $shipOxygen < 50 ? "var(--amber)" : "var(--bone-dim)">> <<set _sh_fpct = Math.floor($fuel / ($fuelMax||300) * 100)>> <div style="font-size:0.9rem;color:var(--amber-bright);margin-bottom:0.7rem;letter-spacing:0.05em;">载具状态</div> <div style="font-size:0.82rem;line-height:2;color:var(--bone-dim);"> <div> 船体耐久 <span style="color:<<print _sh_hcol>>;"><<print Math.round($shell*10)/10>></span>/100 <span style="display:inline-block;background:var(--bg-panel);border:1px solid var(--border);width:80px;height:8px;border-radius:4px;vertical-align:middle;overflow:hidden;margin-left:0.4rem;"> <span style="display:block;height:100%;width:<<print $shell>>%;background:<<print _sh_hcol>>;"></span> </span> </div> <div> 燃料储量 <span style="color:<<print _sh_fcol>>;"><<print _sh_fpct>>%</span> (<<print Math.floor($fuel/1000)>>k) <span style="display:inline-block;background:var(--bg-panel);border:1px solid var(--border);width:80px;height:8px;border-radius:4px;vertical-align:middle;overflow:hidden;margin-left:0.4rem;"> <span style="display:block;height:100%;width:<<print _sh_fpct>>%;background:<<print _sh_fcol>>;"></span> </span> </div> <div> 供氧储备 <span style="color:<<print _sh_ocol>>;"><<print $shipOxygen>></span>/100 </div> </div> <div style="height:1px;background:var(--border-dim);margin:0.6rem 0;"></div> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.3rem;">子系统</div> <div style="font-size:0.8rem;line-height:1.9;"> <<set _sys_names = [["propulsion","推进系统"],["fishing","捕鱼系统"],["oxygen","供氧系统"],["heating","供暖系统"],["storage","仓储系统"]]>> <<for _shi = 0; _shi < _sys_names.length; _shi++>> <<set _syk = _sys_names[_shi][0]>> <<set _syn = _sys_names[_shi][1]>> <<set _syok = $shipSystems[_syk]>> <div> <span style="color:<<print _syok ? 'var(--teal-bright)' : 'var(--danger-bright)'>>;"><<print _syok ? "●" : "✕">></span> <<capture _syk, _syn>><<link _syn>><<set $selectShipSystem = _syk>><<goto "船只系统详情">><</link>><</capture>> </div> <</for>> </div> <div style="height:1px;background:var(--border-dim);margin:0.6rem 0;"></div> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.3rem;">升级等级</div> <div style="font-size:0.78rem;line-height:1.9;color:var(--bone-dim);"> <<set _upg_names = [["speed","航速"],["armor","装甲"],["insulation","隔热"],["capacity","容量"],["sonar","声呐"]]>> <<for _upi = 0; _upi < _upg_names.length; _upi++>> <<set _upk = _upg_names[_upi][0]>> <<set _uln = _upg_names[_upi][1]>> <<set _ulv = $shipUpgrades[_upk] || 0>> <div> <<capture _upk, _uln, _ulv>><<link _uln>><<set $selectShipUpgrade = _upk>><<goto "船只升级详情">><</link>><</capture>> <<for _ulvi = 0; _ulvi < 3; _ulvi++>><<print _ulvi < _ulv ? "◆" : "◇">><</for>> <span style="opacity:0.6;font-size:0.72rem;"> Lv.<<print _ulv>></span> </div> <</for>> </div> <<if $shell < 50>> <div style="margin-top:0.6rem;font-size:0.78rem;color:var(--danger-bright);border:1px solid var(--danger-bright);padding:0.3rem 0.6rem;border-radius:4px;"> ⚠ 船体耐久不足,需要尽快进行维修。 </div> <</if>> <<if $fuel < 5000>> <div style="margin-top:0.4rem;font-size:0.78rem;color:var(--amber);border:1px solid var(--amber-dim);padding:0.3rem 0.6rem;border-radius:4px;"> ⚠ 燃料不足,无法长途航行。 </div> <</if>> <div class="action-row" style="margin-top:1rem;"> <<link "关闭">><<navigate "back">><</link>> </div> <</nobr>>
<<nobr>> <<set _vChat = $cps["viona"]>> <div id="cp-event"> <div class="cp-event-name"><<print _vChat.name>></div> <<if _vChat.mood === 2>> <div class="cp-event-desc">「心情愉快时的闲聊开场」</div> <<else>> <div class="cp-event-desc">「普通心情时的闲聊开场」</div> <</if>> <div class="cp-event-options"> <<link "随便聊聊">> <<set $cps.viona.bond = Math.min(100, $cps.viona.bond + 1)>> <<set $cps.viona.lastChatDay = $day>> <<cpMemoryTag "viona" "had_chat" 1>> <<set $detailCpId = "viona">> <<goto "cp聊聊">> <</link>> <<link "现在没空">> <<set $cps.viona.lastChatDay = $day>> <<navigate "go" $cpEventReturn>> <</link>> </div> </div> <</nobr>>
<<nobr>> <<set _vGood = $cps["viona"]>> <div id="cp-event"> <div class="cp-event-name"><<print _vGood.name>></div> <div class="cp-event-desc">「心情愉快时主动找玩家说话,语气可以比普通闲聊更活泼」</div> <div class="cp-event-options"> <<link "陪她说一会儿">> <<set $cps.viona.bond = Math.min(100, $cps.viona.bond + 2)>> <<set $cps.viona.lastChatDay = $day>> <<cpMemoryTag "viona" "had_chat" 1>> <<set $detailCpId = "viona">> <<goto "cp聊聊">> <</link>> <<link "让她自己玩">> <<set $cps.viona.lastChatDay = $day>> <<navigate "go" $cpEventReturn>> <</link>> </div> </div> <</nobr>>
<<nobr>> <<set _vMad = $cps["viona"]>> <div id="cp-event"> <div class="cp-event-name"><<print _vMad.name>></div> <div class="cp-event-desc">「被捉弄后来找玩家算账,语气不善」</div> <div class="cp-event-options"> <<link "道歉">> <<set $cps.viona.recentMemory = { tag: "", day: 0, expire: -1 }>> <<set $cps.viona.bond = Math.min(100, $cps.viona.bond + 1)>> <div class="cp-event-reply">「道歉后 Viona 勉强接受的反应」</div> <<link "好的">><<navigate "go" $cpEventReturn>><</link>> <</link>> <<link "死不承认">> <<set $cps.viona.recentMemory.expire = $day + 2>> <<set $cps.viona.mood = Math.max(0, $cps.viona.mood - 1)>> <div class="cp-event-reply">「死不承认后 Viona 更生气的反应,记仇延长一天」</div> <<link "行吧">><<navigate "go" $cpEventReturn>><</link>> <</link>> </div> </div> <</nobr>>
<<nobr>> <<set _vGift = $cps["viona"]>> /* 礼物 id:替换为实际物品 id */ <<set _vGiftId = "fish_bone">> <<set _vGiftDef = State.variables.items[_vGiftId]>> <div id="cp-event"> <div class="cp-event-name"><<print _vGift.name>></div> <div class="cp-event-desc">「Viona 拿出礼物时的场景描述」</div> <<if _vGiftDef>> <div class="cp-event-item"> <span class="cp-event-item-name"><<print _vGiftDef.name>></span> <<if _vGiftDef.desc>> <span class="cp-event-item-desc"><<print _vGiftDef.desc>></span> <</if>> </div> <</if>> <div class="cp-event-options"> <<link "收下">> <<if _vGiftDef>><<additem _vGiftId 1>><</if>> <<set $cps.viona.bond = Math.min(100, $cps.viona.bond + 2)>> <<cpMemoryTag "viona" "received_gift_from_cp" 2>> <div class="cp-event-reply">「收下礼物后 Viona 的反应」</div> <<link "好的">><<navigate "go" $cpEventReturn>><</link>> <</link>> <<link "婉拒">> <<set $cps.viona.bond = Math.max(0, $cps.viona.bond - 1)>> <div class="cp-event-reply">「拒绝礼物后 Viona 有点尴尬的反应」</div> <<link "行吧">><<navigate "go" $cpEventReturn>><</link>> <</link>> </div> </div> <</nobr>>
描写出舱下水的准备流程与风险评估。 [[← 返回|出舱]]
<<nobr>> <<for _category range Object.keys($store)>> <<set _item = $store[_category].find(item => $selectitem===_itemId)>> <<if _item>> <<set _quantity=_item.quantity>> <<break>> <<endif>> <</for>> <</nobr>> <<for _i = 0; _i < _keys.length; _i++>> <<set _totalWeight += $mapinfo[_keys[_i]].weight>> <</for>> <<set _randomNum = Math.random() * _totalWeight>> <<set _cumulativeWeight = 0>> <<set _randomKey = "">> <<for _i = 0; _i < _keys.length; _i++>> <<set _cumulativeWeight += $mapinfo[_keys[_i]].weight>> <<if _randomNum < _cumulativeWeight>> <<set $maptype = _keys[_i]>> <<set $mapnow = 0>> <<set $map = 0>> <<break>> <</if>> <</for>>
<<nobr>> <div style="max-width:520px;margin:0 auto;padding:0.6rem;"> <div style="border:1px solid #88f;border-radius:4px;padding:0.5rem 0.8rem;"> <div style="color:#aaf;font-size:0.8rem;margin-bottom:0.2rem;">✦ 主线触发点</div> <div style="background:rgba(100,100,255,0.06);border:1px dashed #558;border-radius:3px;padding:0.25rem 0.5rem;font-size:0.72rem;color:#99c;margin-bottom:0.25rem;">🔧 施工中 — 主线系统 v0(占位)<br>questFlags:<<print JSON.stringify($questFlags)>></div> <div style="font-size:0.82rem;color:var(--bone);line-height:1.8;margin-bottom:0.25rem;">某种更深的力量在此处留下了印记。主线系统尚在建设中,你记录下了这个地点的坐标。</div> <<set _mqRet = $npcReturn || $combatReturn || "航行">> <<link "离开">> <<set $lastSmallEventText = "在此处感受到了某种异常,记录了坐标。">> <<set $npcReturn = null>><<set $combatReturn = null>><<goto _mqRet>> <</link>> </div></div> <</nobr>>
<<nobr>> <<if !$questChain>><<questDefs>><</if>> <div style="max-width:520px;padding:0.5rem 0.6rem;"> <div style="font-size:0.9rem;color:var(--bone);margin-bottom:0.4rem;border-bottom:1px solid var(--border-dim);padding-bottom:0.2rem;">📓 航行日记</div> <<if $questLog && $questLog.length > 0>> <div style="margin-bottom:0.5rem;"> <div style="font-size:0.72rem;color:var(--bone-dim);margin-bottom:0.15rem;letter-spacing:0.05em;">── 主线 ──</div> <<for _dki = $questLog.length - 1; _dki >= 0; _dki-->> <<set _dke = $questLog[_dki]>> <div style="margin-bottom:0.4rem;border-left:2px solid var(--teal-bright);padding:0.2rem 0.45rem;"> <div style="font-size:0.74rem;color:var(--teal-bright);margin-bottom:0.06rem;"><<print _dke.title>><span style="color:var(--bone-dim);font-size:0.68rem;"> · 第<<print _dke.day>>日</span></div> <div style="font-size:0.82rem;color:var(--bone);line-height:1.85;"><<print _dke.text>></div> </div> <</for>> </div> <<else>> <div style="font-size:0.82rem;color:var(--bone-dim);font-style:italic;margin-bottom:0.4rem;">日记本是空的。也许等你出海探索之后,会有些值得记录的事。</div> <</if>> <<set _dkSqKeys = $sideQuestLog ? Object.keys($sideQuestLog) : []>> <<if _dkSqKeys.length > 0>> <div style="border-top:1px solid var(--border-dim);padding-top:0.3rem;margin-top:0.2rem;"> <div style="font-size:0.72rem;color:var(--bone-dim);margin-bottom:0.15rem;letter-spacing:0.05em;">── 支线 ──</div> <<for _dksi = 0; _dksi < _dkSqKeys.length; _dksi++>> <<set _dkSqId = _dkSqKeys[_dksi]>> <<set _dkSqDef = $sideQuestDefs ? $sideQuestDefs[_dkSqId] : null>> <<set _dkSqLog = $sideQuestLog[_dkSqId]>> <<if _dkSqLog && _dkSqLog.length > 0>> <div style="margin-bottom:0.4rem;"> <div style="font-size:0.72rem;color:var(--amber-bright);margin-bottom:0.08rem;"><<print _dkSqDef ? _dkSqDef.title : _dkSqId>></div> <<for _dkni = _dkSqLog.length - 1; _dkni >= 0; _dkni-->> <<set _dkne = _dkSqLog[_dkni]>> <div style="margin-bottom:0.25rem;border-left:2px solid var(--amber-bright);padding:0.15rem 0.4rem;"> <div style="font-size:0.72rem;color:var(--amber-bright);margin-bottom:0.04rem;"><<print _dkne.title>><span style="color:var(--bone-dim);font-size:0.68rem;"> · 第<<print _dkne.day>>日</span></div> <div style="font-size:0.8rem;color:var(--bone);line-height:1.8;"><<print _dkne.text>></div> </div> <</for>> </div> <</if>> <</for>> </div> <</if>> <<nobr>> <div id="cheat-panel"> <input id="cheat-input" type="text" placeholder="写点什么…" /> <<link "确认">> <<set _cheatVal = document.getElementById("cheat-input").value.trim().toLowerCase()>> <<if _cheatVal === "viona">> <<if !$activeCpIds.includes("viona")>> <<set _cpInitNow = $day * 1440 + $hour * 60 + $minute>> <<set $cps.viona.lastTickTime = _cpInitNow>> <<set $cps.viona.actionEndTime = _cpInitNow + 480>> <<run $activeCpIds.push("viona")>> <div class="cheat-result">维奥娜加入了。</div> <<else>> <div class="cheat-result">她已经在船上了。</div> <</if>> <<else>> <div class="cheat-result">无效代码。</div> <</if>> <</link>> </div> <</nobr>> </div> [[返回|卧室]] <</nobr>>
<<nobr>> <<replace "#sc-status">><<include "侧边栏状态">><</replace>> /* ══ 场景进入简介(仅初次进入时显示)══ */ <<if $diveShowIntro>> <div style="border-left:3px solid var(--teal-bright);padding:0.3rem 0.55rem;margin-bottom:0.35rem;font-size:0.82rem;color:var(--bone);line-height:1.75;background:rgba(0,180,150,0.04);border-radius:0 3px 3px 0;"> <<print $diveIntro>> </div> <<set $diveShowIntro = false>> <</if>> /* ══ 顶部状态行 ══ */ <<diveWarn>> <<set _o2c = $diveOxygen <= 20 ? "var(--danger-bright)" : $diveOxygen <= 40 ? "var(--amber)" : "var(--teal-bright)">> <<set _cdc = $diveCold >= 80 ? "var(--danger-bright)" : $diveCold >= 50 ? "var(--amber)" : "var(--bone-dim)">> <div style="font-size:0.73rem;color:var(--bone-dim);margin-bottom:0.2rem;"> ⚓ <<print $mapinfo[$maptype].type>> · <<print $depth>>m · <<print $showseason>>季 第<<print $showday>>日 <<print $showhour>>:<<print $showminute>> <<if $worldScene && $worldScene.state === "inside">> <span style="color:var(--amber-bright);"> · <<print $worldScene.name>></span> <</if>> </div> /* 氧气 + 冷压条 */ <div style="display:flex;justify-content:space-between;font-size:0.68rem;margin-bottom:0.04rem;"> <span style="color:<<print _o2c>>;">氧气</span> <span style="color:<<print _o2c>>;"><<print $diveOxygen>>/100</span> </div> <div style="background:var(--bg-panel);border:1px solid var(--border-dim);height:5px;border-radius:2px;overflow:hidden;margin-bottom:0.12rem;"> <div style="height:100%;width:<<print $diveOxygen>>%;background:<<print _o2c>>;transition:width 0.3s;"></div> </div> <div style="display:flex;justify-content:space-between;font-size:0.68rem;margin-bottom:0.04rem;"> <span style="color:<<print _cdc>>;">水温冷压</span> <span style="color:<<print _cdc>>;"><<print $diveCold>>/100</span> </div> <div style="background:var(--bg-panel);border:1px solid var(--border-dim);height:3px;border-radius:2px;overflow:hidden;margin-bottom:0.3rem;"> <div style="height:100%;width:<<print $diveCold>>%;background:<<print _cdc>>;transition:width 0.3s;"></div> </div> /* ══ 预警横幅 ══ */ <<if $diveO2Dead>> <div style="border:2px solid var(--danger-bright);padding:0.3rem 0.5rem;margin-bottom:0.3rem;font-size:0.84rem;color:var(--danger-bright);background:rgba(180,30,30,0.08);border-radius:3px;"> ‼ 氧气耗尽——你开始窒息。必须立刻返回。 </div> <div style="font-size:0.82rem;margin-bottom:0.3rem;"> <<link "⚠ 立即返回潜艇">> <<diveReturn>> <<set $diveO2Dead = false>> <<set $diveLog = "">> <<goto "出舱">> <</link>> </div> <<elseif _diveWarn === 2>> <div style="border-left:3px solid var(--danger-bright);padding:0.25rem 0.5rem;margin-bottom:0.3rem;font-size:0.8rem;color:var(--danger-bright);"> ⚠ 氧气仅剩返程量——必须立即返回 </div> <<elseif _diveWarn === 1>> <div style="border-left:3px solid var(--amber);padding:0.25rem 0.5rem;margin-bottom:0.3rem;font-size:0.8rem;color:var(--amber);"> ⚠ 氧气有限,建议尽快返回(约剩2步余量) </div> <</if>> /* ══ 舷窗区域 ══ */ <div style="border:1px solid var(--border-dim);border-radius:3px;padding:0.45rem 0.55rem;margin-bottom:0.35rem;font-size:0.84rem;color:var(--bone);line-height:1.9;"> /* diveLog 已停用(v37+)*/ /* 交互结果面板(持续显示,需手动确认)*/ <<if $diveInteractResult>> <div style="border-left:3px solid var(--teal-bright);padding:0.25rem 0.5rem;margin-bottom:0.3rem;background:rgba(0,180,150,0.05);border-radius:0 3px 3px 0;"> <div style="font-size:0.78rem;color:var(--teal-bright);margin-bottom:0.12rem;">▸ 行动结果</div> <div style="color:var(--bone);font-size:0.84rem;line-height:1.8;"><<print $diveInteractResult>></div> </div> <div style="font-size:0.78rem;margin-bottom:0.2rem;"><<link "[ 确认 ]">><<set $diveInteractResult = "">><<goto "仓外探索">><</link>></div> <</if>> /* ══ 舱外小型事件面板 ══ */ <<if $activeSmallEvent && !$diveInteractResult>> <div style="border:1px solid var(--amber);border-radius:3px;padding:0.35rem 0.55rem;margin-bottom:0.3rem;background:rgba(180,140,60,0.05);"> <div style="font-size:0.74rem;color:var(--amber-bright);margin-bottom:0.12rem;">⚑ <<print $activeSmallEvent.name>></div> <div style="font-size:0.82rem;color:var(--bone);line-height:1.8;margin-bottom:0.2rem;"><<print $activeSmallEvent.stageDesc>></div> <div style="font-size:0.78rem;"> <<for _seai = 0; _seai < $activeSmallEvent.actions.length; _seai++>> <<set _seaAct = $activeSmallEvent.actions[_seai]>> <<capture _seaAct>> <div><<link _seaAct>> <<resolveSmallEvent _seaAct>> <<set $diveOxygen = Math.max(0, $diveOxygen - 2)>> <<if !$activeSmallEvent && $lastSmallEventText>> <<set $diveInteractResult = $lastSmallEventText>> <<set $lastSmallEventText = "">> <</if>> <<goto "仓外探索">> <</link>></div> <</capture>> <</for>> </div> </div> <</if>> /* 当前节点内容(小型事件活跃时隐藏,避免界面重叠)*/ <<if $diveChain.length > 0 && $diveIdx < $diveChain.length && !$activeSmallEvent>> <<set _dcNode = $diveChain[$diveIdx]>> <<if _dcNode.type === "frag">> /* 碎片节点:简短环境描写 */ <<if $diveIdx > 0>> <<set _dcTransPool = ["你继续向前,呼出的气泡缓缓上浮。","探照灯在黑暗中划出新的弧线,你迈出下一步。","你向前摸索,水流从身侧轻轻拂过。","脚步搅起细沙,随后重归沉寂。","你继续深入,身后的来路逐渐模糊。"]>> <<set _dcTrans = _dcTransPool[Math.floor(Math.random() * _dcTransPool.length)]>> <div style="color:var(--bone-dim);font-size:0.78rem;margin-bottom:0.08rem;"><<print _dcTrans>></div> <</if>> <div style="color:var(--bone-dim);font-style:italic;font-size:0.82rem;"><<print _dcNode.text>></div> <<elseif _dcNode.type === "scene">> /* 场景节点:完整光照合成描述 + 可交互元素 */ <<if $diveIdx > 0>> <<set _dcTransPool = ["你继续向前,呼出的气泡缓缓上浮。","探照灯在黑暗中划出新的弧线,你迈出下一步。","你向前摸索,水流从身侧轻轻拂过。","脚步搅起细沙,随后重归沉寂。","你继续深入,身后的来路逐渐模糊。"]>> <<set _dcTrans = _dcTransPool[Math.floor(Math.random() * _dcTransPool.length)]>> <div style="color:var(--bone-dim);font-size:0.78rem;margin-bottom:0.1rem;"><<print _dcTrans>></div> <</if>> <div style="color:var(--bone);margin-bottom:0.15rem;"><<print _dcNode.desc>></div> <<if _dcNode.elements && _dcNode.elements.length > 0>> <div style="font-size:0.75rem;margin-top:0.08rem;"> <<for _diei = 0; _diei < _dcNode.elements.length; _diei++>> <<set _dieElem = _dcNode.elements[_diei]>> <<set _dieDone = false>> <<if _dcNode.done>> <<for _diedi = 0; _diedi < _dcNode.done.length; _diedi++>> <<if _dcNode.done[_diedi] === _dieElem>><<set _dieDone = true>><</if>> <</for>> <</if>> <<capture _dieElem, _dieDone>> <<if _dieDone>> <span style="opacity:0.35;margin-right:0.4rem;">✓ <<print _dieElem>></span> <<else>> /* blocked 检测:舱壁/舱门等需机械臂从仓内清除后才能交互 */ <<set _dieBlocked = false>> <<if _dcNode.blocked && _dcNode.blocked.indexOf(_dieElem) >= 0>> <<set _dieClearedList = ($diveArmCleared && $diveArmCleared[_dcNode.id]) ? $diveArmCleared[_dcNode.id] : []>> <<if _dieClearedList.indexOf(_dieElem) < 0>><<set _dieBlocked = true>><</if>> <</if>> <<if _dieBlocked>> <span style="opacity:0.38;font-size:0.78rem;">🔒 <<print _dieElem>><span style="font-size:0.65rem;color:var(--amber-dim);"> [需机械臂清除·返回舱内操作]</span></span> <<else>> <<capture _dieElem>> <<set _dieLinkLabel = "◉ " + _dieElem>> <<link _dieLinkLabel>><<diveInteract _dieElem>><<goto "仓外探索">><</link>> <</capture>> <</if>> <</if>> <</capture>> <</for>> </div> <</if>> <<elseif _dcNode.type === "wschild">> /* worldScene 子事件节点 */ <<if _dcNode.done>> <div style="color:var(--bone-dim);font-size:0.82rem;">✓ <<print _dcNode.name>> — 已完成</div> <<else>> <div style="border-left:3px solid var(--amber-bright);padding:0.25rem 0.5rem;margin-bottom:0.2rem;background:rgba(180,140,60,0.05);"> <div style="font-size:0.74rem;color:var(--amber-bright);margin-bottom:0.1rem;">◈ <<print _dcNode.name>></div> <div style="font-size:0.82rem;color:var(--bone);line-height:1.8;margin-bottom:0.15rem;"><<print _dcNode.stageDesc>></div> <div style="font-size:0.78rem;"> <<for _wcai = 0; _wcai < _dcNode.actions.length; _wcai++>> <<set _wcAct = _dcNode.actions[_wcai]>> <<capture _wcAct>> <div><<link _wcAct>> <<if !$wsChildDefs>><<worldSceneDefs>><</if>> <<set _wcDef = $wsChildDefs[_dcNode.id]>> <<set _wcRes = _wcDef ? _wcDef.resolve[_wcAct] : null>> <<if _wcRes>> /* 发放战利品 */ <<set _wcLog = "">> <<if _wcRes.loot>> <<for _wcli = 0; _wcli < _wcRes.loot.length; _wcli++>> <<set _wcL = _wcRes.loot[_wcli]>> <<set _wcQ = _wcL.qty[0] + Math.floor(Math.random() * (_wcL.qty[1]-_wcL.qty[0]+1))>> <<if _wcQ > 0>> <<additem _wcL.id _wcQ>> <<if $items && $items[_wcL.id]>> <<set _wcLog = _wcLog + $items[_wcL.id].name + "×" + _wcQ + " ">> <</if>> <</if>> <</for>> <</if>> <<set _wcText = _wcRes.text + (_wcLog ? " 获得:" + _wcLog : "")>> /* 下一阶段或结束 */ <<if _wcRes.next >= 0 && _wcRes.next < _wcDef.stages.length>> <<set $diveChain[$diveIdx].stageIdx = _wcRes.next>> <<set $diveChain[$diveIdx].stageDesc = _wcText + " " + _wcDef.stages[_wcRes.next].desc>> <<set $diveChain[$diveIdx].actions = _wcDef.stages[_wcRes.next].actions>> <<else>> <<set $diveChain[$diveIdx].done = true>> /* 记录完成到 worldScene.doneCids */ <<if $worldScene && $worldScene.state === "inside">> <<if !$worldScene.doneCids>><<set $worldScene.doneCids = []>><</if>> <<set _wcAlready = false>> <<for _wcdi = 0; _wcdi < $worldScene.doneCids.length; _wcdi++>> <<if $worldScene.doneCids[_wcdi] === _dcNode.id>><<set _wcAlready = true>><</if>> <</for>> <<if !_wcAlready>><<run $worldScene.doneCids.push(_dcNode.id)>><</if>> <</if>> <</if>> <<set $diveInteractResult = _wcText>> <<set $diveOxygen = Math.max(0, $diveOxygen - 2)>> /* 同步保存到 worldScene */ <<if $worldScene && $worldScene.state === "inside">> <<set $worldScene.savedChain = $diveChain>> <</if>> <</if>> <<goto "仓外探索">> <</link>></div> <</capture>> <</for>> </div> </div> <</if>> <<elseif _dcNode.type === "end">> /* 路线终点 */ <div style="color:var(--bone-dim);font-style:italic;">探照灯扫过一片开阔的海域,这条路已经走到尽头了。前方没有更多可探索的内容,是时候考虑返回了。</div> <div style="margin-top:0.2rem;font-size:0.8rem;color:var(--amber);">← 建议返回潜艇</div> <<else>> <div style="color:var(--bone-dim);">四周一片寂静。</div> <</if>> <<else>> /* chain 为空时的兜底(不应该触发)*/ <div style="color:var(--bone-dim);"> <<diveLight>> <<if $depth <= 50>> 出仓后,海水将你轻轻托起,探照灯扫过周围的环境。 <<elseif $depth <= 150>> 探照灯光在黑暗中延伸,照出一片昏黄的锥形区域。 <<else>> 深海的压力无处不在,黑暗在探照灯的边缘等候。 <</if>> </div> <</if>> </div> /* ══ 分叉选择(批次三接入)══ */ <<if $diveChainSub.length > 0>> <div style="border:1px solid var(--amber-dim);border-radius:3px;padding:0.3rem 0.5rem;margin-bottom:0.3rem;font-size:0.8rem;"> <div style="color:var(--amber-bright);font-size:0.74rem;margin-bottom:0.15rem;">⑂ 路线分叉——选择一条继续</div> <<for _dcbi = 0; _dcbi < $diveChainSub.length; _dcbi++>> <<set _dcbr = $diveChainSub[_dcbi]>> <<capture _dcbi, _dcbr>> <div style="margin-bottom:0.08rem;"> <<link _dcbr.label>> <<set $diveChain = _dcbr.chain>> <<set $diveChainSub = []>> <<set $diveIdx = 0>> <<set $diveLog = "你选择了:" + _dcbr.label>> <<goto "仓外探索">> <</link>> </div> <</capture>> <</for>> </div> <</if>> /* ══ 操作台 ══ */ <div style="font-size:0.82rem;margin-bottom:0.15rem;"> <<if _diveWarn < 2 && !$activeSmallEvent && ($diveIdx >= $diveChain.length || !$diveChain[$diveIdx] || $diveChain[$diveIdx].type !== "end")>> <<if $diveIdx < $diveChain.length - 1>> <<set _dcCurNode = $diveChain[$diveIdx]>> <<set _dcContinueLabel = _dcCurNode && _dcCurNode.type === "scene" ? "→ 前进(场景区域)" : _dcCurNode && _dcCurNode.type === "frag" ? "→ 继续前进" : "→ 前进">> <<link _dcContinueLabel>> <<diveStep>> <<set $diveLog = "">> <<set $diveInteractResult = "">> <<set $diveChain[$diveIdx].visited = true>> <<set $diveIdx = $diveIdx + 1>> <<goto "仓外探索">> <</link>> <</if>> <</if>> <<link "← 返回潜艇">><<diveReturn>><<set $diveLog = "">><<set $currentContext = "anchored">><<goto "出舱">><</link>> </div> <div style="font-size:0.72rem;color:var(--bone-dim);margin-bottom:0.2rem;"> 已深入 <<print $diveStepsOut>> 步 · 进度 <<print $diveIdx>>/<<print $diveChain.length - 1>> · 返程消耗约 <<print Math.ceil($diveStepsOut * $diveStepCostO2 * 0.6)>> 氧气 </div> /* ══ DEV 测试面板 ══ */ <<if $devMode>> <div style="margin-top:0.5rem;border:1px dashed #555;border-radius:3px;padding:0.3rem 0.5rem;font-size:0.71rem;color:#888;"> <div style="color:#aaa;margin-bottom:0.2rem;">🔧 DEV · 仓外探索</div> /* 氧气/冷压 */ <<link "+20氧">><<set $diveOxygen=Math.min(100,$diveOxygen+20)>><<goto "仓外探索">><</link>> · <<link "-20氧">><<set $diveOxygen=Math.max(0,$diveOxygen-20)>><<goto "仓外探索">><</link>> · <<link "氧满">><<set $diveOxygen=100>><<goto "仓外探索">><</link>> · <<link "氧空">><<set $diveOxygen=0>><<goto "仓外探索">><</link>><br> <<link "+20冷压">><<set $diveCold=Math.min(100,$diveCold+20)>><<goto "仓外探索">><</link>> · <<link "-20冷压">><<set $diveCold=Math.max(0,$diveCold-20)>><<goto "仓外探索">><</link>> · <<link "冷压清零">><<set $diveCold=0>><<goto "仓外探索">><</link>><br> /* Chain */ <<link "↻ 重生成">><<diveChainGen>><<set $diveIdx=0>><<goto "仓外探索">><</link>> · <<link "← 后退">><<if $diveIdx>0>><<set $diveIdx=$diveIdx-1>><</if>><<goto "仓外探索">><</link>> · <<link "→ 末尾">><<set $diveIdx=Math.max(0,$diveChain.length-1)>><<goto "仓外探索">><</link>><br> /* WorldScene */ <<link "模拟沉船">><<set $worldScene={id:"wreck_site",name:"沉船区",state:"inside",children:["wreck_cargo","wreck_engine"],doneCids:[]}>><<diveInit>><<goto "仓外探索">><</link>> · <<link "清除WS">><<set $worldScene=null>><<diveInit>><<goto "仓外探索">><</link>><br> /* 六维 */ <<link "生命+30">><<set $life=Math.min(100,$life+30)>><<goto "仓外探索">><</link>> · <<link "生命-30">><<set $life=Math.max(0,$life-30)>><<goto "仓外探索">><</link>> · <<link "体力满">><<set $power=100>><<goto "仓外探索">><</link>><br> /* 小型事件 */ <div style="color:#b8a;margin:0.15rem 0 0.08rem;">⚑ 小型事件(outside)</div> <<link "测试遭遇">><<if !$smallEventDefs>><<smallEventTable>><</if>><<set _dv=$smallEventDefs["placeholder_outside_1"]>><<if _dv>><<set $activeSmallEvent={id:"placeholder_outside_1",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><<set $diveInteractResult="">><</if>><<goto "仓外探索">><</link>> · <<link "海带种植">><<if !$smallEventDefs>><<smallEventTable>><</if>><<set _dv=$smallEventDefs["kelp_planting"]>><<if _dv>><<set $activeSmallEvent={id:"kelp_planting",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><<set $diveInteractResult="">><</if>><<goto "仓外探索">><</link>> · <<link "✕清除">><<set $activeSmallEvent=null>><<goto "仓外探索">><</link>><br> /* 任务 */ <div style="color:#aaf;margin:0.15rem 0 0.08rem;">✦ 任务</div> <<link "▶ 触发主线">><<if !$questChain>><<questDefs>><</if>><<if $questProgress < $questChain.length>><<run $questLog.push({id:$questChain[$questProgress].id,title:$questChain[$questProgress].title,text:$questChain[$questProgress].logEntry,day:$day||0,type:"main"})>><<set $questNotify="✦ 日记已更新:"+$questChain[$questProgress].title>><<set $questProgress=$questProgress+1>><</if>><<goto "仓外探索">><</link>> <span style="color:#aaf;font-size:0.68rem;">[<<if !$questChain>><<questDefs>><</if>><<print $questProgress>>/<<print $questChain.length>>]</span> · <<link "重置主线">><<set $questProgress=0>><<set $questLog=[]>><<set $questNotify="">><<goto "仓外探索">><</link>><br> <div style="color:#8cc;margin:0.15rem 0 0.08rem;">🛥 NPC</div> <<if !$npcDefTable>><<npcDefs>><</if>> <<link "补给船">><<set $activeNpc=$npcDefTable["supply_drifter"]>><<set $npcReturn="仓外探索">><<goto "NPC_对话">><</link>> · <<link "废品商">><<set $activeNpc=$npcDefTable["deep_salvager"]>><<set $npcReturn="仓外探索">><<goto "NPC_对话">><</link>> · <<link "✕清除NPC">><<set $activeNpc=null>><</link>> <<link "💠珍珠+5">><<additem "pearl" 5>><</link>> <div style="color:#f88;margin:0.15rem 0 0.08rem;">⚔ 战斗</div> <<link "水母群">><<spawnCombat "jellyfish_swarm">><</link>> · <<link "深甲蟹">><<spawnCombat "armored_crab">><</link>> · <<link "巡游鲨">><<spawnCombat "patrol_shark">><</link>> · <<link "深渊鳗">><<spawnCombat "deep_eel">><</link>> · <<link "灯笼鱼">><<spawnCombat "angler_lurker">><</link>> /* Chain 信息 */ <div style="opacity:0.6;margin-top:0.15rem;"> chain:<<print $diveChain.length>>节/idx:<<print $diveIdx>>/地形:<<print $diveChainTerrain>> <<if $diveChain[$diveIdx]>> / <<print $diveChain[$diveIdx].type>>(<<print $diveChain[$diveIdx].id>>)<</if>> </div> /* envEffects */ <div style="border-top:1px dashed #444;margin-top:0.2rem;padding-top:0.15rem;"> <div style="color:#ab8;margin-bottom:0.06rem;">🌿 envEffects[<<print $envEffects.length>>]</div> <<if $envEffects.length === 0>><span style="opacity:0.5;">(空)</span> <<else>> <<for _devEi = 0; _devEi < $envEffects.length; _devEi++>> <<set _devE = $envEffects[_devEi]>> <div style="opacity:0.7;font-size:0.65rem;">[<<print _devEi>>]<<print _devE.type>>·<<print _devE.state>> <<capture _devEi>><<link "成熟">><<set $envEffects[_devEi].state="ready">><<goto "仓外探索">><</link>> <<link "删">><<run $envEffects.splice(_devEi,1)>><<goto "仓外探索">><</link>><</capture>></div> <</for>> <</if>> <<link "[DEV]直接种植">><<run $envEffects.push({type:"kelp_farm",terrain:$maptype,depthMin:Math.max(0,$depth-20),depthMax:$depth+20,plantedDay:$day||0,harvestCount:0,state:"growing"})>><<goto "仓外探索">><</link>> </div> </div> <</if>> <</nobr>>
<<nobr>> <<set _vDef = State.variables.items[$selectitem]>> <<finditem State.variables.store $selectitem>> <<set _vEntry = _foundItem>> <<if !$lastTakeText>><<set $lastTakeText = "">><</if>> <div class="item-detail"> <div class="item-detail-name"><<print _vDef.name>></div> <div class="item-detail-meta"> <<if _vDef.element>><span class="ether-badge <<print _vDef.element === '水' ? 'water' : (_vDef.element === '火' ? 'fire' : (_vDef.element === '土' ? 'earth' : 'wind'))>>"><<print _vDef.element>></span><</if>> <<if _vDef.form>><span class="form-badge"><<print _vDef.form>></span><</if>> <<if _vDef.rarity>><span class="item-tag rare"><<print _vDef.rarity>></span><</if>> <span style="color:var(--bone-dim);font-size:0.72rem;"><<print _vDef.type>><<if _vDef.subtype>> · <<print _vDef.subtype>><</if>></span> </div> <<if _vDef.desc>> <p style="font-size:0.85rem;line-height:1.7;color:var(--bone-dim);margin:0.6rem 0 0.4rem;border-left:2px solid var(--border);padding-left:0.8rem;"><<print _vDef.desc>></p> <</if>> <<if _vEntry>> <p style="font-size:0.82rem;color:var(--bone-dim);">库存:<strong><<print _vEntry.quantity>></strong></p> <</if>> </div> <<set _canDisassemble = State.variables.disassemblyRules[$selectitem] !== undefined>> <<if _canDisassemble>> <<set _dsFlav = State.variables.disassemblyFlavors>> <<if _dsFlav>> <<set _flav_key = (_vDef.subtype && _dsFlav[_vDef.subtype]) ? _vDef.subtype : (_dsFlav[_vDef.type] ? _vDef.type : "")>> <<if _flav_key>> <p style="font-size:0.8rem;color:var(--bone-dim);font-style:italic;margin:0.3rem 0;"><<print _dsFlav[_flav_key]>></p> <</if>> <</if>> <<link "分解一个">> <<set $lastTakeText = "">> <<disassemble $selectitem>> <<goto "仓库物品页面">> <</link>> <</if>> <<if $lastDisassembleText>> <div class="event-result"><<print $lastDisassembleText>></div> <<set $lastDisassembleText = "">> <</if>> <<if $lastTakeText>> <div class="event-result"><<print $lastTakeText>></div> <<set $lastTakeText = "">> <</if>> <div class="action-row"> <<link "取出 1 份">><<take $selectitem 1>><<goto "仓库物品页面">><</link>> <<link "取出全部">><<takeAll $selectitem>><<goto "仓库物品页面">><</link>> </div> [[返回仓库|store]] <</nobr>>
<div style="font-size:0.8rem;color:var(--bone-dim);line-height:1.7;margin:0.35rem 0 0.5rem;">透过舷窗——<<view>></div> <<if $worldScene>> <<if $worldScene.state === "approaching">><div style="font-size:0.72rem;color:var(--amber);margin-bottom:0.25rem;">⚠ <<print $worldScene.approachDesc>></div> <<elseif $worldScene.state === "inside">><div style="font-size:0.72rem;color:var(--amber-bright);margin-bottom:0.25rem;">◆ 正处于:<<print $worldScene.name>></div> <</if>> <</if>> <<link 休息1h>> <<set $timepass=60>> <<time>> <<goto "卧室">> <</link>> <<link 休息8h>> <<set $timepass=480>> <<time>> <<goto "卧室">> <</link>> [[起床|卧室]]
<<nobr>> <<if !$fuelDefs>><<fuelDefs>><</if>> /* ── 标题 ── */ <div style="font-size:0.9rem;color:var(--amber-bright);margin-bottom:0.3rem;">⚙ 供能室</div> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.4rem;line-height:1.7;"> 嗡嗡的低频震动从机壁传来。仪表板上密密麻麻排列着压力计和温度表,正中央是一块厚重的铸铁舱门——燃料槽的注入口。 </div> /* ── 燃料槽状态 ── */ <<set _gfPct = Math.max(0,Math.min(100,Math.floor(($fuel||0)/$fuelMax*100)))>> <<set _gfCol = _gfPct > 40 ? "var(--teal-bright)" : _gfPct > 15 ? "var(--amber)" : "var(--danger-bright)">> <div style="border:1px solid var(--border-dim);border-radius:3px;padding:0.3rem 0.5rem;margin-bottom:0.4rem;"> <div style="display:flex;justify-content:space-between;font-size:0.72rem;color:var(--bone-dim);margin-bottom:0.15rem;"> <span>⛽ 燃料槽</span> <span style="color:<<print _gfCol>>;"><<print Math.floor($fuel||0)>> / <<print $fuelMax>></span> </div> <div style="background:var(--bg-panel);border:1px solid var(--border-dim);height:6px;border-radius:3px;overflow:hidden;"> <div style="height:100%;width:<<print _gfPct>>%;background:<<print _gfCol>>;transition:width 0.4s;"></div> </div> <<if $driftMode>> <div style="font-size:0.72rem;color:var(--danger-bright);margin-top:0.15rem;">‼ 燃料耗尽——引擎停转中</div> <</if>> </div> /* ── 可用燃料物品 ── */ <<set _gFuelIds = ["coal","wood","oil","fish_oil","algae_block","mineral_fuel"]>> <<set _gFuelList = []>> <<for _gfi = 0; _gfi < _gFuelIds.length; _gfi++>> <<set _gfId = _gFuelIds[_gfi]>> <<set _gfType = ($items[_gfId] ? $items[_gfId].type : "")>> <<set _gfQty = 0>> <<if _gfType && $store[_gfType]>> <<for _gfj = 0; _gfj < $store[_gfType].length; _gfj++>> <<if $store[_gfType][_gfj].id === _gfId>><<set _gfQty += $store[_gfType][_gfj].quantity>><</if>> <</for>> <</if>> <<if _gfType && $backpack[_gfType]>> <<for _gfj = 0; _gfj < $backpack[_gfType].length; _gfj++>> <<if $backpack[_gfType][_gfj].id === _gfId>><<set _gfQty += $backpack[_gfType][_gfj].quantity>><</if>> <</for>> <</if>> <<if _gfQty > 0>> <<run _gFuelList.push({id:_gfId, qty:_gfQty, val:$fuelDefs[_gfId]})>> <</if>> <</for>> <<if _gFuelList.length === 0>> <div style="font-size:0.78rem;color:var(--bone-dim);opacity:0.55;margin-bottom:0.4rem;"> 货舱和背包中没有可用的燃料物品。 </div> <<else>> <div style="font-size:0.72rem;color:var(--bone-dim);margin-bottom:0.15rem;">可用燃料:</div> <<for _gli = 0; _gli < _gFuelList.length; _gli++>> <<set _gl = _gFuelList[_gli]>> <<capture _gl>> <<set _glName = ($items[_gl.id] ? $items[_gl.id].name : _gl.id)>> <div style="border-left:2px solid var(--amber-dim);padding:0.15rem 0.4rem;margin-bottom:0.2rem;font-size:0.76rem;"> <span style="color:var(--bone);"><<print _glName>></span> <span style="font-size:0.69rem;color:var(--bone-dim);margin-left:0.3rem;">热值+<<print _gl.val>>/个 · 库存<<print _gl.qty>>个</span><br> /* +1 */ <<set _gl1Label = "加入×1">> <<link _gl1Label>><<addFuel _gl.id 1>><<goto "供能室">><</link>> <span style="opacity:0.4;margin:0 0.2rem;">·</span> /* +10 */ <<if _gl.qty >= 10>> <<set _gl10Label = "×10">> <<link _gl10Label>><<addFuel _gl.id 10>><<goto "供能室">><</link>> <<else>> <span style="opacity:0.25;">×10</span> <</if>> <span style="opacity:0.4;margin:0 0.2rem;">·</span> /* +100 */ <<if _gl.qty >= 100>> <<set _gl100Label = "×100">> <<link _gl100Label>><<addFuel _gl.id 100>><<goto "供能室">><</link>> <<else>> <span style="opacity:0.25;">×100</span> <</if>> <span style="opacity:0.4;margin:0 0.2rem;">·</span> /* 全部 */ <<set _glAllLabel = "全部加入(×" + _gl.qty + ")">> <<link _glAllLabel>><<addFuel _gl.id "all">><<goto "供能室">><</link>> </div> <</capture>> <</for>> <</if>> /* ── 操作结果 ── */ <<if $lastFuelText>> <div style="font-size:0.74rem;color:var(--teal-bright);border-left:2px solid var(--teal-bright);padding:0.1rem 0.35rem;margin-bottom:0.3rem;"> <<print $lastFuelText>> </div> <<set $lastFuelText = "">> <</if>> <div style="border-top:1px solid var(--border-dim);margin-top:0.35rem;padding-top:0.3rem;"> <span style="font-size:0.72rem;color:var(--bone-dim);">设备升级请前往 </span> [[机械室]] </div> <div style="margin-top:0.5rem;font-size:0.75rem;">[[← 返回走廊|走廊]]</div> <</nobr>>
<<nobr>> <<time widget>> $showseason季 第$showday日 $showhour:$showminute<br> $showweather[$weather] / 环境 $worldtem° 体温 $tem° ———————————— /* 颜色阈值 */ <<set _c_h = $hunger < 25 ? "var(--danger-bright)" : $hunger < 50 ? "var(--amber)" : "var(--bone-dim)">> <<set _c_w = $water < 20 ? "var(--danger-bright)" : $water < 45 ? "var(--amber)" : "var(--bone-dim)">> <<set _c_p = $power < 20 ? "var(--danger-bright)" : $power < 45 ? "var(--amber)" : "var(--bone-dim)">> <<set _c_l = $life < 25 ? "var(--danger-bright)" : $life < 60 ? "var(--amber)" : "var(--bone-dim)">> <<set _c_tr = $tre >= 80 ? "var(--danger-bright)" : $tre >= 50 ? "var(--amber)" : "var(--bone-dim)">> <<set _c_tem = $tem > 37 ? "var(--danger-bright)" : $tem >= 32 ? "var(--amber)" : $tem <= 0 ? "var(--danger-bright)" : $tem <= 10 ? "var(--amber)" : "var(--bone-dim)">> /* 数值栏 */ <div style="font-size:0.78rem;line-height:1.85;color:var(--bone-dim);"> <span style="color:<<print _c_h>>;">饱腹</span> <<print $hunger>> <span style="color:<<print _c_w>>;">饮水</span> <<print $water>><br> <span style="color:<<print _c_p>>;">体力</span> <<print $power>> <span style="color:<<print _c_l>>;">生命</span> <<print $life>><br> <span style="color:<<print _c_tem>>;">体感</span> <<print $tem>>° <span style="color:<<print _c_tr>>;">压力</span> <<print $tre>><br> 安定 <<print $san>> 魔力 <<print $magic>><br> <span style="font-size:0.7rem;opacity:0.6;">潮湿 <<print $wet>></span> </div> /* 燃料条(仅在航行/出发时显示)*/ <<if $passage === "航行" || $passage === "探索" || $divingMode>> <<set _sbFuel = Math.max(0,Math.min(100,Math.floor(($fuel||0)/($fuelMax||300)*100)))>> <<set _sbFC = _sbFuel > 40 ? "var(--teal-bright)" : _sbFuel > 15 ? "var(--amber)" : "var(--danger-bright)">> <div style="display:flex;align-items:center;gap:0.25rem;font-size:0.66rem;color:var(--bone-dim);margin-bottom:0.18rem;"> <span>⛽</span> <div style="flex:1;height:3px;background:var(--bg-panel);border:1px solid var(--border-dim);border-radius:2px;"><div style="height:100%;width:<<print _sbFuel>>%;background:<<print _sbFC>>;"></div></div> <span style="color:<<print _sbFC>>;"><<print Math.floor($fuel||0)>></span> </div> <</if>> <div style="height:1px;background:var(--border-dim);margin:0.55rem 0;"></div> /* 散文描述 */ <<set _desc_parts = []>> /* 饥饿/饮水 */ <<if $hunger < 25 && $water < 20>> <<run _desc_parts.push("腹中空空如也,喉咙干得快要冒烟。")>> <<elseif $hunger < 25>> <<run _desc_parts.push("饥饿感像钝刀一样磨着胃,难以集中精神。")>> <<elseif $water < 20>> <<run _desc_parts.push("严重脱水,嘴唇皲裂,连吞口水都变得困难。")>> <<elseif $hunger < 50 && $water < 45>> <<run _desc_parts.push("有些饿,也有些渴。")>> <<elseif $hunger < 50>> <<run _desc_parts.push("胃里开始咕咕作响。")>> <<elseif $water < 45>> <<run _desc_parts.push("喉咙有点发干。")>> <<elseif $hunger >= 80 && $water >= 80>> <<run _desc_parts.push("吃饱喝足,身体舒适。")>> <</if>> /* 体力 */ <<if $power < 20>> <<run _desc_parts.push("几乎没有力气再迈出一步。")>> <<elseif $power < 45>> <<run _desc_parts.push("四肢沉重,疲惫感渗进了骨头里。")>> <<elseif $power < 70>> <<run _desc_parts.push("略感疲惫。")>> <</if>> /* 生命 */ <<if $life < 25>> <<run _desc_parts.push("伤势严峻,每次呼吸都带着刺痛,随时可能倒下。")>> <<elseif $life < 50>> <<run _desc_parts.push("身上的伤口还没愈合,行动受限。")>> <<elseif $life < 90 && $life > 60>> <<run _desc_parts.push("有些轻伤,但尚在可控范围。")>> <</if>> /* 体感温度(对齐六维阈值) */ <<if $tem > 37>> <<run _desc_parts.push("体表滚烫,头晕目眩,已经到了危险的高温极限。")>> <<elseif $tem >= 32>> <<run _desc_parts.push("热浪蒸腾,汗水不停渗出,消耗着仅剩的水分。")>> <<elseif $tem <= 0>> <<run _desc_parts.push("严寒侵骨,四肢麻木,寒冷正在蚕食生命力。")>> <<elseif $tem <= 10>> <<run _desc_parts.push("寒意透过衣物渗入,手指已经开始失去灵活。")>> <<elseif $tem >= 18 && $tem <= 26>> /* 舒适区不显示温度描述 */ <</if>> /* 压力/安定 */ <<if $tre >= 80>> <<run _desc_parts.push("神经紧绷到了极限,思维开始扭曲。")>> <<elseif $tre >= 50>> <<run _desc_parts.push("心头压着什么,难以放松。")>> <<elseif $san < 30>> <<run _desc_parts.push("精神状态堪忧,现实与幻想的边界开始模糊。")>> <</if>> /* 全好时的正面描述 */ <<if _desc_parts.length === 0>> <<if $life === 100 && $hunger >= 80 && $water >= 80 && $power >= 70 && $tem >= 18 && $tem <= 26>> <<run _desc_parts.push("身体状态绝佳,精神饱满,做好了应对一切的准备。")>> <<else>> <<run _desc_parts.push("状态尚可,没有特别需要注意的问题。")>> <</if>> <</if>> <div style="font-size:0.77rem;line-height:1.75;color:var(--bone-dim);font-style:italic;"><<print _desc_parts.join(" ")>></div> <<if $questNotify>> <div style="margin-top:0.15rem;padding:0.12rem 0.4rem;background:rgba(0,180,150,0.08);border-left:2px solid var(--teal-bright);font-size:0.71rem;color:var(--teal-bright);"> <<print $questNotify>> </div> <<set $questNotify = "">> <</if>> <</nobr>>
一段描述 [[种植箱]] [[鱼缸]] [[返回|走廊]]
<<nobr>> <<if !$fridge>><<set $fridge = [null,null,null,null,null,null,null,null]>><</if>> <<set _fr_count = $fridge.filter(x => x !== null).length>> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.6rem;"> 冰箱储藏 <span style="color:var(--amber-bright);"><<print _fr_count>>/8</span> </div> <div class="inv-grid" style="grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:0.4rem;"> <<for _fri = 0; _fri < $fridge.length; _fri++>> <<capture _fri>> <<set _fd = $fridge[_fri]>> <<if _fd === null>> <span class="inv-item" style="opacity:0.25;font-size:0.75rem;justify-content:center;">— 空 —</span> <<else>> <<set _fd_age = ($day || 0) - (_fd.addedDay || 0)>> <<set _fd_sd = 3>>/* 冰箱内腐败速度为普通的1/3 */ <<set _fd_rawSd = $spoilDays ? ($spoilDays[_fd.template] || 2) : 2>> <<set _fd_fridgeSd = _fd_rawSd * 3>> <<set _fd_stage = _fd_fridgeSd > 0 ? Math.floor(_fd_age / _fd_fridgeSd * 3) : 0>> <<set _fd_qcol = _fd.quality === "完美" ? "#f0c060" : (_fd.quality === "失败" ? "var(--bone-dim)" : "var(--teal-bright)")>> <<set _fd_stcol = _fd_stage <= 0 ? "#8bc4a0" : (_fd_stage === 1 ? "var(--amber)" : "var(--danger-bright)")>> <<set _fd_stxt = _fd_stage <= 0 ? "新鲜" : (_fd_stage === 1 ? "变质" : "⚠腐败")>> <span class="inv-item" style="flex-direction:column;align-items:flex-start;height:auto;padding:0.4rem 0.65rem;cursor:pointer;"><<link _fd.name>> <<set $selectFridgeSlot = _fri>> <<goto "冰箱物品">> <</link>> <span style="font-size:0.7rem;color:var(--bone-dim);margin-top:0.18rem;"> <<print _fd.ingNames ? _fd.ingNames.slice(0,2).join("·") + (_fd.ingNames.length > 2 ? "…" : "") : "">> </span> <span style="font-size:0.7rem;margin-top:0.1rem;"> <span style="color:<<print _fd_qcol>>;"><<print _fd.quality>></span> <span style="color:<<print _fd_stcol>>;margin-left:0.4rem;"><<print _fd_stxt>></span> </span> </span> <</if>> <</capture>> <</for>> </div> <div class="action-row" style="margin-top:1rem;"> [[← 返回厨房|厨房]] </div> <</nobr>>
<<nobr>> <<if !$fridge || $selectFridgeSlot === undefined>><<goto "冰箱">><</if>> <<set _fi_slot = $selectFridgeSlot>> <<set _fi_d = $fridge[_fi_slot]>> <<if !_fi_d>><<goto "冰箱">><</if>> <<set _fi_age = ($day || 0) - (_fi_d.addedDay || 0)>> <<set _fi_rawSd = $spoilDays ? ($spoilDays[_fi_d.template] || 2) : 2>> <<set _fi_fridgeSd = _fi_rawSd * 3>> <<set _fi_stage = _fi_fridgeSd > 0 ? Math.floor(_fi_age / _fi_fridgeSd * 3) : 0>> <<set _fi_left = _fi_fridgeSd - _fi_age>> <<set _fi_qcol = _fi_d.quality === "完美" ? "#f0c060" : (_fi_d.quality === "失败" ? "var(--danger-bright)" : "var(--teal-bright)")>> <div class="item-detail"> <div class="item-detail-name"><<print _fi_d.name>></div> <div class="item-detail-meta" style="margin-top:0.3rem;"> <span style="color:<<print _fi_qcol>>;font-size:0.8rem;"><<print _fi_d.quality>></span> <span style="color:var(--bone-dim);font-size:0.72rem;margin-left:0.6rem;"><<print _fi_d.method>></span> <<if _fi_stage <= 0>> <span style="color:#8bc4a0;font-size:0.72rem;margin-left:0.6rem;">新鲜 · 约<<print Math.max(_fi_left,0)>>天后变质</span> <<elseif _fi_stage === 1>> <span style="color:var(--amber);font-size:0.72rem;margin-left:0.6rem;">⚠ 轻微变质 · 约<<print Math.max(_fi_left,0)>>天后腐败</span> <<else>> <span style="color:var(--danger-bright);font-size:0.72rem;margin-left:0.6rem;">⚠ 已腐败</span> <</if>> </div> <<if _fi_d.ingNames && _fi_d.ingNames.length > 0>> <p style="font-size:0.75rem;color:var(--bone-dim);margin:0.4rem 0;"> 食材:<<print _fi_d.ingNames.join("、")>> </p> <</if>> <p style="font-size:0.85rem;line-height:1.75;color:var(--bone-dim);margin:0.6rem 0;border-left:2px solid var(--border);padding-left:0.8rem;"><<print _fi_d.desc>></p> <div style="font-size:0.78rem;color:var(--bone-dim);margin:0.5rem 0;"> 食用效果: <<if _fi_d.hunger > 0>><span style="color:#8bc4a0;">饱腹+<<print _fi_d.hunger>></span> <</if>> <<if _fi_d.water > 0>><span style="color:#6ab4d0;">饮水+<<print _fi_d.water>></span> <</if>> <<if _fi_d.life > 0>><span style="color:var(--teal-bright);">生命+<<print _fi_d.life>></span> <</if>> <<if _fi_d.power > 0>><span style="color:var(--amber-bright);">体力+<<print _fi_d.power>></span> <</if>> <<if _fi_d.san !== 0>><span style="color:<<if _fi_d.san > 0>>var(--amber)<<else>>var(--danger-bright)<</if>>;">安定<<if _fi_d.san > 0>>+<</if>><<print _fi_d.san>></span> <</if>> <<if _fi_d.magic > 0>><span style="color:#a080d0;">魔力+<<print _fi_d.magic>></span><</if>> </div> </div> <div class="action-row" style="margin-top:0.8rem;"> <<link "▶ 食用">> <<eatDish _fi_slot>> <<goto "厨房">> <</link>> <<link "丢弃">> <<set $fridge[_fi_slot] = null>> <<goto "冰箱">> <</link>> [[← 返回冰箱|冰箱]] </div> <</nobr>>
<<nobr>> <<cpRoomCheck "舱外">> /* 深度阈值判断 */ <<if $depth <= 0>> <<set _diveZone = "surface">> <<set _canDive = true>> <<elseif $depth <= 50>> <<set _diveZone = "shallow">> <<set _canDive = true>> <<elseif $depth <= 300>> <<set _diveZone = "mid">> <<set _canDive = true>> <<else>> <<set _diveZone = "deep">> <<set _canDive = false>> <</if>> /* 舱门描述 */ <div style="font-size:0.84rem;color:var(--bone);line-height:1.85;margin-bottom:0.4rem;"> <<if _diveZone === "surface">> 舱门开启后是开放的海面,水面平静或翻涌,取决于当前天气。 <<elseif _diveZone === "shallow">> 舷窗外水压尚在可承受范围,轮廓清晰可辨。<br> <span style="font-size:0.78rem;color:var(--bone-dim);"><<print $mapinfo[$maptype].type>> · $depth m · 约 <<print Math.floor(100/3*3)>> 分钟可用时间</span> <<elseif _diveZone === "mid">> 水压明显,视线有限,氧气消耗较快,出仓需做好准备。<br> <span style="font-size:0.78rem;color:var(--amber);"><<print $mapinfo[$maptype].type>> · $depth m · 约 <<print Math.floor(100/10*3)>> 分钟可用时间</span> <<else>> <span style="color:var(--danger-bright);">当前深度 <<print $depth>>m 超出无装备出仓限制(≤300m),无法安全出仓。</span> <</if>> </div> <<cpScene "舱外">> <<if _canDive>> <div style="font-size:0.8rem;"><<link "▶ 出仓下水">><<diveInit>><<set $currentContext = "outside">><<goto "仓外探索">><</link>></div> <<else>> <div style="opacity:0.45;font-size:0.8rem;">▶ 出仓下水(深度超限)</div> <</if>> <<if $devMode>> <div style="margin-top:0.5rem;border:1px dashed #555;padding:0.3rem 0.5rem;font-size:0.72rem;color:#888;"> 🔧 DEV · 出舱 <<link "深度0m">><<set $depth = 0>><</link>> ·<<link "深度30m">><<set $depth = 30>><</link>> ·<<link "深度150m">><<set $depth = 150>><</link>> ·<<link "深度280m">><<set $depth = 280>><</link>> ·<<link "深度400m">><<set $depth = 400>><</link>> </div> <</if>> [[← 返回走廊|走廊]] <</nobr>>
<<cpRoomCheck "卧室">> 一段描述 <<cpScene "卧室">> [[书桌]] [[床铺]] [[返回|走廊]]
<<cpRoomCheck "厨房">> <div style="font-size:0.8rem;color:var(--bone-dim);line-height:1.7;margin:0.35rem 0 0.5rem;">透过舷窗——<<view>></div> <<if $worldScene>> <<if $worldScene.state === "approaching">><div style="font-size:0.72rem;color:var(--amber);margin-bottom:0.25rem;">⚠ <<print $worldScene.approachDesc>></div> <<elseif $worldScene.state === "inside">><div style="font-size:0.72rem;color:var(--amber-bright);margin-bottom:0.25rem;">◆ 正处于:<<print $worldScene.name>></div> <</if>> <</if>> <<nobr>> <div style="margin-bottom:0.8rem;"> 在厨房里,铜锅和烤架整整齐齐地摆放着,炉火的余温还在。 </div> <<cpScene "厨房">> <div style="font-size:0.82rem;color:var(--bone-dim);margin-bottom:0.5rem;">选择烹饪方式:</div> <<set _kLv = Number($upgrades ? $upgrades.kitchen : 0) || 0>> <div class="action-row" style="flex-wrap:wrap;gap:0.4rem;margin-bottom:0.6rem;"> /* Lv0+ 始终可用 */ <<link "明火烤">><<set $cookMethod = "明火烤">><<set $cookIngredients = []>><<goto "烹饪选材">><</link>> <<link "生食">><<set $cookMethod = "生食">><<set $cookIngredients = []>><<goto "烹饪选材">><</link>> /* Lv1+ */ <<if _kLv >= 1>> <<link "铜锅炖">><<set $cookMethod = "铜锅炖">><<set $cookIngredients = []>><<goto "烹饪选材">><</link>> <<else>><span style="opacity:0.3;font-size:0.8rem;" title="需要厨房设备 Lv1">铜锅炖🔒</span><</if>> /* Lv2+ */ <<if _kLv >= 2>> <<link "清蒸">><<set $cookMethod = "清蒸">><<set $cookIngredients = []>><<goto "烹饪选材">><</link>> <<link "煎炒">><<set $cookMethod = "煎炒">><<set $cookIngredients = []>><<goto "烹饪选材">><</link>> <<else>><span style="opacity:0.3;font-size:0.8rem;" title="需要厨房设备 Lv2">清蒸🔒</span> <span style="opacity:0.3;font-size:0.8rem;" title="需要厨房设备 Lv2">煎炒🔒</span><</if>> /* Lv3 */ <<if _kLv >= 3>> <<link "油炸">><<set $cookMethod = "油炸">><<set $cookIngredients = []>><<goto "烹饪选材">><</link>> <<else>><span style="opacity:0.3;font-size:0.8rem;" title="需要厨房设备 Lv3">油炸🔒</span><</if>> </div> <<if _kLv < 3>> <div style="font-size:0.7rem;color:var(--bone-dim);opacity:0.55;margin-bottom:0.5rem;">🔒 可在机械室升级「厨房设备」解锁更多烹饪方式</div> <</if>> <div style="height:1px;background:var(--border-dim);margin:0.5rem 0;"></div> /* 测试用喝水按钮 */ <div style="font-size:0.8rem;margin-bottom:0.4rem;"> <span style="color:var(--bone-dim);">水分:</span><span style="color:<<print ($water > 50 ? 'var(--teal-bright)' : ($water > 20 ? 'var(--amber)' : 'var(--danger-bright)'))>>;">$water/100</span> <<link "喝水">><<set $water = Math.min(100, $water + 30)>><</link>> </div> <<nobr>> <<set _ki_count = $fridge ? $fridge.filter(x => x !== null).length : 0>> <</nobr>> <span style="font-size:0.82rem;color:var(--bone-dim);">冰箱 <span style="color:var(--amber-bright);"><<print _ki_count>>/8</span></span> [[查看冰箱|冰箱]] [[返回|走廊]] <</nobr>>
/*::GEN::地点场景::wreck_site:: */ 声呐在沙海床上扫到了一片不规则的金属反射。 残骸半埋在泥沙中,锈蚀的龙骨依稀可辨——这曾是一艘比你的潜艇大得多的船。 【占位:后续补充探索、拾取、剧情内容】 <<link "离开">><<set $sailspd to 0>><<goto "航行">><</link>>
描写天窗外的水下景象与光线变化。 [[← 返回|炼金室]]
一段描述 [[休息]] [[算了|卧室]]
<<nobr>> <<if !$activeCombat>><<goto ($combatReturn || "仓外探索")>><</if>> <<if $activeCombat.result>><<goto "战斗结算">><</if>> <<set _p = $activeCombat.player>> <<set _e = $activeCombat.enemy>> /* 敌方状态描述 key */ <<set _eStateKey = (_e.alertness >= 50 ? "high" : "low")+"_"+(_e.morale >= 40 ? "high" : "low")>> <<set _eStateText = _e.stateDesc[_eStateKey] || "">> /* 体力阶段文本 */ <<set _eHpPct = _e.hpMax > 0 ? Math.floor(_e.hp / _e.hpMax * 100) : 0>> <<set _eHpDesc = "">> <<if _eHpPct <= 25>> <<set _eHpDesc = _e.hpDesc[25] || _e.hpDesc[50] || "">> <<elseif _eHpPct <= 50>> <<set _eHpDesc = _e.hpDesc[50] || "">> <</if>> /* 伤势阶段文本 */ <<set _eInjPct = _e.injuryMax > 0 ? Math.floor(_e.injury / _e.injuryMax * 100) : 0>> <<set _eInjDesc = "">> <<if _eInjPct >= 70>> <<set _eInjDesc = _e.injuryDesc[70] || _e.injuryDesc[40] || "">> <<elseif _eInjPct >= 40>> <<set _eInjDesc = _e.injuryDesc[40] || "">> <</if>> <<set _hpCrisis = _p.hp <= 0>> <div style="max-width:520px;margin:0 auto;padding:0.5rem 0.4rem;font-size:0.82rem;"> <!-- ══ 敌方信息 ══ --> <div style="border:1px solid var(--teal-dim,#2a5a5a);border-radius:4px;padding:0.5rem 0.75rem;margin-bottom:0.35rem;"> <div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:0.2rem;"> <span style="color:var(--teal-bright,#4ecdc4);font-size:0.9rem;font-weight:bold;"><<print _e.name>></span> <span style="color:var(--muted,#8a8070);font-size:0.74rem;">回合 <<print $activeCombat.round>></span> </div> <div style="color:var(--bone,#d4c9a8);font-size:0.8rem;line-height:1.65;margin-bottom:0.2rem;"><<print _eStateText>></div> <<if _eHpDesc || _eInjDesc>> <div style="color:var(--muted,#8a8070);font-size:0.76rem;font-style:italic;margin-bottom:0.2rem;"> <<if _eHpDesc>><<print _eHpDesc>><<if _eInjDesc>> <</if>><</if>><<if _eInjDesc>><<print _eInjDesc>><</if>> </div> <</if>> <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:0.1rem;font-size:0.73rem;color:var(--muted,#8a8070);text-align:center;"> <div>伤势<br><span style="color:var(--danger-bright,#e74c3c);"><<print _e.injury>>/<<print _e.injuryMax>></span></div> <div>体力<br><span style="color:var(--teal-bright,#4ecdc4);"><<print _e.hp>></span></div> <div>警觉<br><span style="color:var(--bone,#d4c9a8);"><<print _e.alertness>></span></div> <div>士气<br><span style="color:var(--bone,#d4c9a8);"><<print _e.morale>></span></div> <div>破绽<br><span style="color:var(--accent,#f39c12);"><<print "◆".repeat(_e.flaws)>><<print "◇".repeat(3-_e.flaws)>></span></div> </div> </div> <!-- ══ 玩家状态 ══ --> <div style="border:1px solid var(--bone-dim,#3a3025);border-radius:4px;padding:0.35rem 0.75rem;margin-bottom:0.35rem;"> <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:0.1rem;font-size:0.73rem;color:var(--muted,#8a8070);text-align:center;"> <div>体力<br><span style="color:<<print _p.hp <= 0 ? 'var(--danger-bright,#e74c3c)' : 'var(--teal-bright,#4ecdc4)'>>;font-size:0.76rem;"><<print _p.hp>>/<<print _p.hpMax>></span></div> <div>伤势<br><span style="color:<<print _p.injury >= 70 ? 'var(--danger-bright,#e74c3c)' : 'var(--bone,#d4c9a8)'>>;"><<print _p.injury>>/100</span></div> <div>警觉<br><span style="color:var(--bone,#d4c9a8);"><<print _p.alertness>></span></div> <div>士气<br><span style="color:<<print _p.morale <= 20 ? 'var(--danger-bright,#e74c3c)' : 'var(--bone,#d4c9a8)'>>;"><<print _p.morale>></span></div> <div>破绽<br><span style="color:<<print _p.flaws > 0 ? 'var(--danger-bright,#e74c3c)' : 'var(--muted,#8a8070)'>>;"><<print "◆".repeat(_p.flaws)>><<print "◇".repeat(3-_p.flaws)>></span></div> </div> </div> <!-- ══ 回合日志 ══ --> <<if $activeCombat.log>> <div style="border-left:2px solid var(--teal-dim,#2a5a5a);padding:0.2rem 0.5rem;margin-bottom:0.35rem;font-size:0.78rem;color:var(--bone,#d4c9a8);line-height:1.75;"><<print $activeCombat.log>></div> <</if>> <!-- ══ 行动宫格 ══ --> <<set _btnBase = "border-radius:3px;padding:0.55rem 0.3rem;text-align:center;cursor:pointer;">> <<set _btnTeal = "border:1px solid var(--teal-dim,#2a5a5a);">> <<set _btnBone = "border:1px solid var(--bone-dim,#3a3025);">> <<set _btnDim = "border:1px solid var(--bone-dim,#3a3025);opacity:0.38;color:var(--muted,#8a8070);">> <<if _hpCrisis>> <!-- 体力危机面板 --> <div style="color:var(--danger-bright,#e74c3c);font-size:0.77rem;text-align:center;margin-bottom:0.3rem;">⚠ 体力耗尽,行动受限</div> <div style="display:grid;grid-template-columns:1fr 1fr;gap:0.35rem;"> <div style="<<print _btnBase>><<print _btnBone>>"><<link "休息">><<combatExecRound "休息">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<goto "战斗">><</if>><</link>></div> <div style="<<print _btnBase>><<print _btnBone>>"><<link "道具">><<set $activeCombat.phase = "item">><<goto "战斗">><</link>></div> <div style="<<print _btnBase>><<print _btnBone>>"><<link "逃跑">><<combatExecRound "逃跑">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<goto "战斗">><</if>><</link>></div> <div style="<<print _btnBase>><<print _btnDim>>">行动不可用</div> </div> <<elseif $activeCombat.phase === "main">> <div style="display:grid;grid-template-columns:1fr 1fr;gap:0.35rem;"> <div style="<<print _btnBase>><<print _btnTeal>>"><<link "行动">><<set $activeCombat.phase = "action">><<goto "战斗">><</link>></div> <div style="<<print _btnBase>><<print _btnTeal>>"><<link "道具">><<set $activeCombat.phase = "item">><<goto "战斗">><</link>></div> <div style="<<print _btnBase>><<print _btnBone>>"><<link "休息">><<combatExecRound "休息">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<goto "战斗">><</if>><</link>></div> <div style="<<print _btnBase>><<print _btnBone>>"><<link "逃跑">><<combatExecRound "逃跑">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<goto "战斗">><</if>><</link>></div> </div> <<elseif $activeCombat.phase === "action">> <div style="text-align:right;margin-bottom:0.2rem;font-size:0.75rem;"><<link "← 返回">><<set $activeCombat.phase = "main">><<goto "战斗">><</link>></div> <div style="display:grid;grid-template-columns:1fr 1fr;gap:0.35rem;"> <div style="<<print _btnBase>><<print _btnTeal>>"><<link "进攻">><<combatExecRound "进攻">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>></div> <div style="<<print _btnBase>><<print _btnTeal>>"><<link "警戒">><<combatExecRound "警戒">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>></div> <div style="<<print _btnBase>><<print _btnBone>>"><<link "防御">><<combatExecRound "防御">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>></div> <div style="<<print _btnBase>><<print _btnBone>>"><<link "观察">><<combatExecRound "观察">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>></div> </div> <<elseif $activeCombat.phase === "item">> <div style="text-align:right;margin-bottom:0.2rem;font-size:0.75rem;"><<link "← 返回">><<set $activeCombat.phase = "main">><<goto "战斗">><</link>></div> <div style="display:grid;grid-template-columns:1fr 1fr;gap:0.35rem;"> <!-- 攻势:暴露破绽 --> <div style="<<print _btnBase>><<print _btnTeal>>"> <<link "诱饵[测]">><<combatExecRound "item_add_flaw">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>> <div style="font-size:0.68rem;color:var(--muted,#8a8070);margin-top:0.1rem;">敌方破绽+2</div> </div> <!-- 恢复:体力 --> <div style="<<print _btnBase>><<print _btnBone>>"> <<link "恢复剂[测]">><<combatExecRound "item_restore_hp">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>> <div style="font-size:0.68rem;color:var(--muted,#8a8070);margin-top:0.1rem;">体力+30</div> </div> <!-- 辅助1:必中 --> <div style="<<print _btnBase>><<print _btnBone>>"> <<link "瞄准镜[测]">><<combatExecRound "item_must_hit">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>> <div style="font-size:0.68rem;color:var(--muted,#8a8070);margin-top:0.1rem;">下击必中</div> </div> <!-- 辅助2:锁定逃跑 --> <div style="<<print _btnBase>><<print _btnBone>>"> <<link "声爆弹[测]">><<combatExecRound "item_lock_escape">><<if $activeCombat.result>><<goto "战斗结算">><<else>><<set $activeCombat.phase = "main">><<goto "战斗">><</if>><</link>> <div style="font-size:0.68rem;color:var(--muted,#8a8070);margin-top:0.1rem;">锁定逃跑</div> </div> </div> <</if>> </div> <</nobr>>
<<nobr>> <<if !$activeCombat>><<goto ($combatReturn || "仓外探索")>><</if>> <<set _p = $activeCombat.player>> <<set _e = $activeCombat.enemy>> <<set _res = $activeCombat.result>> <<set _hpLost = _p.hpMax - _p.hp>> <<set _pwrDeduct = Math.floor(_hpLost / 2)>> <div style="max-width:520px;margin:0 auto;padding:0.6rem 0.4rem;font-size:0.82rem;"> <<if _res === "kill">> <div style="border:1px solid var(--teal-bright,#4ecdc4);border-radius:4px;padding:0.6rem 0.85rem;margin-bottom:0.5rem;"> <div style="color:var(--teal-bright,#4ecdc4);font-size:0.9rem;margin-bottom:0.3rem;">✓ 战斗胜利</div> <div style="color:var(--bone,#d4c9a8);line-height:1.8;"> 你击倒了<<print _e.name>>,历经 <<print $activeCombat.round>> 回合。 /* TODO: 战利品结算 — 遍历 _e.loot,调用 addItem widget */ </div> </div> <<elseif _res === "enemy_flee">> <div style="border:1px solid var(--teal-dim,#2a5a5a);border-radius:4px;padding:0.6rem 0.85rem;margin-bottom:0.5rem;"> <div style="color:var(--bone,#d4c9a8);font-size:0.9rem;margin-bottom:0.3rem;">— 敌人逃跑</div> <div style="color:var(--bone,#d4c9a8);line-height:1.8;"><<print _e.name>>丧失了战斗意志,消失在黑暗中。</div> </div> <<elseif _res === "player_flee">> <div style="border:1px solid var(--bone-dim,#3a3025);border-radius:4px;padding:0.6rem 0.85rem;margin-bottom:0.5rem;"> <div style="color:var(--muted,#8a8070);font-size:0.9rem;margin-bottom:0.3rem;">↩ 撤退</div> <div style="color:var(--bone,#d4c9a8);line-height:1.8;"><<print $activeCombat.log>></div> </div> <<elseif _res === "player_hurt">> <div style="border:1px solid var(--danger-bright,#e74c3c);border-radius:4px;padding:0.6rem 0.85rem;margin-bottom:0.5rem;"> <div style="color:var(--danger-bright,#e74c3c);font-size:0.9rem;margin-bottom:0.3rem;">✗ 重伤撤退</div> <div style="color:var(--bone,#d4c9a8);line-height:1.8;"> 你伤势过重,勉强撤出战斗。 生命值已损失 <span style="color:var(--danger-bright,#e74c3c);">−<<print Math.floor(_p.injury / 2)>></span>。 </div> </div> <</if>> <!-- 体力损耗小结 --> <<if _hpLost > 0>> <div style="color:var(--muted,#8a8070);font-size:0.76rem;margin-bottom:0.6rem;padding:0.2rem 0;"> 体力消耗 <<print _hpLost>>,主体体力 −<<print _pwrDeduct>> </div> <</if>> <<link "离开">> <<set $activeCombat = null>> <<goto $combatReturn>> <</link>> </div> <</nobr>>
<<nobr>> <<set $fishingBait = "内脏碎肉">> <<set $fishingGear = "垂钓">> <<set $fishingLight = "关闭">> <div id="fishing-info">捕鱼信息将显示在这里...</div> <<repeat 1s>> <<fish>> <<time>> <<replace "#fishing-info">> $showseason季 第$showday日 $showhour:$showminute<br> 地形:$mapinfo[$maptype].type 船舱温度:$worldtem<br><br> 当前坐标:$mapspan 单位<br> 当前深度:$depth米<br> 海底深度:$depthdeep米 <br> <br> 最新情况:<<print $lastCatchText >><br> <br> 饱腹:$hunger <br> 饮水:$water<br> 体力:$power<br> 生命:$life<br> 压力:$tre<br> 安定:$san<br> 魔力:$magic<br> <br> <<if $fishingLight == "关闭">> <<link "开启灯光">> <<set $fishingLight = "开启">> <</link>> <<else>> <<link "关闭灯光">> <<set $fishingLight = "关闭">> <</link>> <</if>> <<link "切换渔具">> <<if $fishingGear == "垂钓">> <<set $fishingGear = "渔网">> <<else>> <<set $fishingGear = "垂钓">> <</if>> <</link>> <<link "更换鱼饵">> <<if $fishingBait == "内脏碎肉">> <<set $fishingBait = "血饵">> <<elseif $fishingBait == "血饵">> <<set $fishingBait = "草饵">> <<else>> <<set $fishingBait = "内脏碎肉">> <</if>> <</link>> <br> <<if $depth > -1>> <<link "排水上浮">> <<set $depth -= 1>> <</link>> <<else>> <<print "目前位于水面">> <</if>> <<if $depth < $depthdeep>> <<link "加压下潜">> <<set $depth += 1>> <</link>> <<else>> <<print "目前位于海底">> <</if>> <</replace>> <</repeat>> [[终止捕鱼|驾驶舱]] <</nobr>>
<<nobr>> <div id="sail-info">⚓ 锚定探索中…</div> <<repeat 1s>> <<time>> <<replace "#sc-status">><<include "侧边栏状态">><</replace>> <<replace "#sail-info">> <span style="font-size:0.73rem;color:var(--bone-dim);">$showseason季 第$showday日 $showhour:$showminute 船舱$worldtem°</span><br> /* ══ 舷窗 ══ */ <div style="border:1px solid var(--border-dim);border-radius:3px;padding:0.4rem 0.5rem;margin-bottom:0.35rem;font-size:0.84rem;color:var(--bone);line-height:1.85;"> /* 基础环境描述 */ <div style="margin-bottom:0.2rem;"><<view>></div> /* 中型场景子事件——焦点显示模式 */ <<if $worldScene && $worldScene.state === "inside">> <<if !$wsChildDefs>><<worldSceneDefs>><</if>> <div style="margin-top:0.3rem;border-top:1px solid var(--amber-dim);padding-top:0.25rem;"> /* ── 子事件状态行 ── */ <div style="display:flex;flex-wrap:wrap;gap:0.25rem 0.3rem;font-size:0.74rem;margin-bottom:0.2rem;"> <<for _wci = 0; _wci < $worldScene.children.length; _wci++>> <<set _wcid = $worldScene.children[_wci]>> <<set _wcd = $wsChildDefs[_wcid]>> <<if _wcd>> /* 判断状态 */ <<set _wcDone = false>> <<if $worldScene.doneCids>> <<for _dci2=0; _dci2 < $worldScene.doneCids.length; _dci2++>> <<if $worldScene.doneCids[_dci2] === _wcid>><<set _wcDone = true>><</if>> <</for>> <</if>> <<set _wcActive = ($wsChild && $wsChild.id === _wcid)>> <<if _wcActive>> <span style="color:var(--teal-bright);">▸ <<print _wcd.name>></span> <<elseif _wcDone>> <<capture _wcid, _wcd>> <<set _wcLinkLabel = "✓ " + _wcd.name>> <<link _wcLinkLabel>><<set $wsChild = {id:_wcid,name:_wcd.name,stageIdx:0,stageDesc:_wcd.stages[0].desc,actions:_wcd.stages[0].actions,lootLog:""}>><<set $wsLastActionText = "">><<set $wsLastActionLoot = "">><<goto "探索">><</link>> <</capture>> <<else>> <<capture _wcid, _wcd>> <<set _wcLinkLabel = _wcd.name>> <<link _wcLinkLabel>><<set $wsChild = {id:_wcid,name:_wcd.name,stageIdx:0,stageDesc:_wcd.stages[0].desc,actions:_wcd.stages[0].actions,lootLog:""}>><<goto "探索">><</link>> <</capture>> <</if>> <</if>> <</for>> </div> /* ── 当前焦点详情块 ── */ <<if $wsChild>> <<worldSceneDefs>> <<set _wcFocusDef = $wsChildDefs[$wsChild.id]>> <<if _wcFocusDef>> <<set _wcFocusStage = _wcFocusDef.stages[Number($wsChild.stageIdx)||0] || _wcFocusDef.stages[0]>> <div style="border-top:1px solid var(--border-dim);padding-top:0.2rem;margin-top:0.05rem;"> <div style="font-size:0.73rem;color:var(--bone-dim);margin-bottom:0.06rem;">── 焦点:<<print _wcFocusDef.name>></div> <div style="color:var(--bone-dim);font-size:0.82rem;margin-bottom:0.1rem;"><<print _wcFocusStage.desc>></div> /* 进行中:显示当前阶段结果 */ <<if $wsChild.actionText>> <div style="border-left:2px solid var(--teal-bright);padding:0.12rem 0.4rem;margin-bottom:0.1rem;font-size:0.8rem;color:var(--bone);"><<print $wsChild.actionText>></div> <</if>> <<if $wsChild.lootLog>> <div style="font-size:0.73rem;opacity:0.75;margin-bottom:0.08rem;">累计收获:<<print $wsChild.lootLog>></div> <</if>> <div style="font-size:0.8rem;"> <<set _wcArmLv = Number($upgrades ? $upgrades.arm : 0) || 0>> <<for _wcai = 0; _wcai < _wcFocusStage.actions.length; _wcai++>> <<set _wca = _wcFocusStage.actions[_wcai]>> /* 关键词判断需臂等级 */ <<set _wcaNeedFine = (_wca.indexOf("精密") >= 0 || _wca.indexOf("精细") >= 0)>> <<set _wcaNeedBasic = (!_wcaNeedFine && (_wca.indexOf("机械臂") >= 0 || _wca.indexOf("撬开") >= 0 || _wca.indexOf("拆卸") >= 0 || _wca.indexOf("清除障碍") >= 0))>> <<if _wcaNeedFine && _wcArmLv < 2>> <div style="opacity:0.35;font-size:0.8rem;margin-bottom:0.06rem;"><<print _wca>><span style="font-size:0.67rem;color:var(--amber-dim);"> [需精密机械臂 — 机械室升至Lv2]</span></div> <<elseif _wcaNeedBasic && _wcArmLv < 1>> <div style="opacity:0.35;font-size:0.8rem;margin-bottom:0.06rem;"><<print _wca>><span style="font-size:0.67rem;color:var(--bone-dim);"> [需加装机械臂 — 机械室Lv1]</span></div> <<else>> <<capture _wca>><<link _wca>><<resolveWsChild _wca>><</link>> <</capture>> <</if>> <</for>> /* ── 机械臂远程清除面板(障碍物列表) ── */ <<if _wcArmLv >= 1 && $diveArmBlocked>> <<set _rcp_ids = Object.keys($diveArmBlocked)>> <<set _rcp_any = false>> <<for _rcpi = 0; _rcpi < _rcp_ids.length; _rcpi++>> <<set _rcp_sid = _rcp_ids[_rcpi]>> <<for _rcpj = 0; _rcpj < $diveArmBlocked[_rcp_sid].length; _rcpj++>> <<set _rcp_elem = $diveArmBlocked[_rcp_sid][_rcpj]>> <<set _rcp_cleared = ($diveArmCleared && $diveArmCleared[_rcp_sid] && $diveArmCleared[_rcp_sid].indexOf(_rcp_elem) >= 0)>> <<if !_rcp_cleared>><<set _rcp_any = true>><</if>> <</for>> <</for>> <<if _rcp_any>> <div style="border-top:1px dashed var(--amber-dim);margin-top:0.25rem;padding-top:0.2rem;"> <div style="font-size:0.71rem;color:var(--amber-dim);margin-bottom:0.1rem;">🦾 机械臂可清除的仓外障碍:</div> <<for _rcpi = 0; _rcpi < _rcp_ids.length; _rcpi++>> <<set _rcp_sid = _rcp_ids[_rcpi]>> <<for _rcpj = 0; _rcpj < $diveArmBlocked[_rcp_sid].length; _rcpj++>> <<set _rcp_elem = $diveArmBlocked[_rcp_sid][_rcpj]>> <<set _rcp_cleared = ($diveArmCleared && $diveArmCleared[_rcp_sid] && $diveArmCleared[_rcp_sid].indexOf(_rcp_elem) >= 0)>> <<if !_rcp_cleared>> <<capture _rcp_sid, _rcp_elem>> <<link "清除障碍:" + _rcp_elem>> <<if !$diveArmCleared>><<set $diveArmCleared = {}>><</if>> <<if !$diveArmCleared[_rcp_sid]>><<set $diveArmCleared[_rcp_sid] = []>><</if>> <<run $diveArmCleared[_rcp_sid].push(_rcp_elem)>> <<goto "探索">> <</link>><br> <</capture>> <</if>> <</for>> <</for>> </div> <</if>> <</if>> <<link "[收起]">><<set $wsChild = null>><<goto "探索">><</link>> </div> </div> <</if>> <</if>> /* 最后一次行动结果(事件结束后持续显示)*/ <<if !$wsChild && $wsLastActionText>> <div style="border-left:2px solid var(--teal-bright);padding:0.15rem 0.45rem;margin:0.1rem 0 0.15rem;font-size:0.8rem;color:var(--bone);"><<print $wsLastActionText>></div> <<if $wsLastActionLoot>> <div style="font-size:0.73rem;opacity:0.75;margin-bottom:0.1rem;">获得:<<print $wsLastActionLoot>></div> <</if>> <div style="font-size:0.72rem;"><<link "[ 确认 ]">><<set $wsLastActionText = "">><<set $wsLastActionLoot = "">><<goto "探索">><</link>></div> <</if>> </div> <</if>> /* 小型事件(如有)*/ <<if $activeSmallEvent>> <<smallEventTable>> <<set _seId3 = String($activeSmallEvent.id)>> <<set _seIdx3 = Number($activeSmallEvent.stageIdx)>> <<set _seDef3 = $smallEventDefs[_seId3]>> <<if _seDef3>> <<set _seStg3 = _seDef3.stages[_seIdx3] || _seDef3.stages[0]>> <div style="margin-top:0.3rem;border-top:1px solid var(--border-dim);padding-top:0.2rem;"> <div style="color:var(--teal-bright);font-size:0.76rem;margin-bottom:0.05rem;">— <<print _seDef3.name>></div> <<if $activeSmallEvent.finished>> /* 事件已完成,可重入 */ <div style="color:var(--bone-dim);font-size:0.75rem;">该事件已告一段落。</div> <<if $activeSmallEvent.lootLog>><div style="font-size:0.73rem;opacity:0.6;margin-top:0.05rem;">上次收获:<<print $activeSmallEvent.lootLog>></div><</if>> <div style="margin-top:0.1rem;font-size:0.76rem;"><<link "↻ 重新探索">><<set $activeSmallEvent.finished = false>><<set $activeSmallEvent.stageIdx = 0>><<set $activeSmallEvent.lootLog = "">><<set $activeSmallEvent.stageDesc = _seDef3.stages[0].desc>><<set $activeSmallEvent.actions = _seDef3.stages[0].actions>><<goto "探索">><</link>> <span style="font-size:0.72rem;opacity:0.45;"><<link "[放弃此事件]">><<set $activeSmallEvent = null>><<goto "探索">><</link>></span></div> <<else>> <div style="color:var(--bone-dim);"><<print _seStg3.desc>></div> <<if $activeSmallEvent.lootLog>><div style="font-size:0.75rem;opacity:0.75;margin-top:0.05rem;">收获:<<print $activeSmallEvent.lootLog>></div><</if>> <<if _seStg3.actions>> <div style="margin-top:0.12rem;"><<for _sa3i = 0; _sa3i < _seStg3.actions.length; _sa3i++>><<set _sa3 = _seStg3.actions[_sa3i]>><<capture _sa3>><<link _sa3>><<resolveSmallEvent _sa3>><</link>> <</capture>><</for>></div> <</if>> <</if>> </div> <<else>> <<set $activeSmallEvent = null>> <</if>> <</if>> /* 航行中发现的微型事件:锚定后在此处理。 */ <<if $activeMicroEvent>> <<if !$microEventDefs>><<microEventTable>><</if>> <<set _amId = String($activeMicroEvent.id)>> <<set _amDef = $microEventDefs[_amId]>> <<if _amDef>> <div style="margin-top:0.2rem;color:var(--bone-dim);">✦ <<print $activeMicroEvent.desc || _amDef.fragmentText>> <span style="white-space:nowrap;"><<set _amAction = $activeMicroEvent.action || _amDef.actionLabel || "◎ 处理">><<link _amAction>><<resolveMicroEvent _amId>><<set $activeMicroEvent = null>><</link>> <span style="opacity:0.4;font-size:0.72rem;"><<link "[略过]">><<set $activeMicroEvent = null>><</link>></span></span></div> <<else>><<set $activeMicroEvent = null>><</if>> <</if>> /* 微型事件碎片 + 探索结果文本 */ <<if $activeHuntItems && $activeHuntItems.length > 0>> <<if !$microEventDefs>><<microEventTable>><</if>> <<for _hii = 0; _hii < $activeHuntItems.length; _hii++>> <<set _hid = $activeHuntItems[_hii]>> <<set _hdef = $microEventDefs[_hid]>> <<if _hdef>> <<capture _hid, _hdef>> <div style="margin-top:0.2rem;color:var(--bone-dim);"><<print _hdef.fragmentText>> <span style="white-space:nowrap;"><<link _hdef.actionLabel>><<resolveMicroEvent _hid>><</link>> <span style="opacity:0.4;font-size:0.72rem;"><<link "[略过]">><<set _ignoreNew = []>><<for _ignI = 0; _ignI < $activeHuntItems.length; _ignI++>><<if $activeHuntItems[_ignI] !== _hid>><<set _ignoreNew[_ignoreNew.length] = $activeHuntItems[_ignI]>><</if>><</for>><<set $activeHuntItems = _ignoreNew>><</link>></span></span></div> <</capture>> <</if>> <</for>> <</if>> <<if $lastHuntText>><div style="margin-top:0.15rem;color:var(--bone-dim);opacity:0.85;"><<print $lastHuntText>></div><<set $lastHuntText = "">><</if>> <<if $lastExploreText>><div style="margin-top:0.15rem;color:var(--bone-dim);"><<print $lastExploreText>></div><</if>> <<if $lastSmallEventText>><div style="margin-top:0.15rem;color:var(--bone-dim);"><<print $lastSmallEventText>></div><<set $lastSmallEventText = "">><</if>> </div> /* ══ 位置提示条(仪表盘上方)══ */ <<set _exState = "normal">> <<if $largeScene && typeof $largeScene === "object" && $largeScene.state === "approaching">> <<set _exState = "ls_approach">> <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "leaving">> <<set _exState = "ls_leaving">> <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "active">> <<if $worldScene && $worldScene.state === "inside">> <<set _exState = "ls_zone">> <<elseif $worldScene && $worldScene.state === "approaching">> <<set _exState = "ls_zone_approach">> <<else>> <<set _exState = "ls_active">> <</if>> <<elseif $worldScene && $worldScene.state === "inside">> <<set _exState = "ws_only">> <<elseif $worldScene && $worldScene.state === "approaching">> <<set _exState = "ws_approach">> <<elseif $worldScene && $worldScene.state === "leaving">> <<set _exState = "ws_leaving">> <</if>> /* ── 地点入口:arrived 状态时显示 ── */ <<if $activeLocations>> <<for _exLocI = 0; _exLocI < $activeLocations.length; _exLocI++>> <<if $activeLocations[_exLocI].state === "arrived">> <<set _exLocName = $activeLocations[_exLocI].name>> <<set _exLocGoto = $activeLocations[_exLocI].gotoScene || $activeLocations[_exLocI].scene>> <<break>> <</if>> <</for>> <</if>> <<if _exLocName>> <div style="margin-top:0.3rem;border:1px solid var(--teal-bright);border-radius:3px;padding:0.35rem 0.5rem;background:rgba(60,180,160,0.06);"> <div style="color:var(--teal-bright);font-size:0.78rem;margin-bottom:0.1rem;">◈ 抵达:<<print _exLocName>></div> <<if _exLocGoto>> <div style="font-size:0.76rem;"> <<link "▶ 进入「" + _exLocName + "」">><<set $sailMode = "travel">><<set $currentContext = "sailing">><<goto _exLocGoto>><</link>> </div> <</if>> <div style="font-size:0.72rem;color:var(--bone-dim);opacity:0.6;margin-top:0.05rem;">或起锚离开,之后可再返回</div> </div> <</if>> <<if _exState !== "normal">> <div style="display:flex;align-items:center;gap:0.3rem;font-size:0.72rem;padding:0.18rem 0.4rem;margin-bottom:0.2rem;border-radius:2px;background:rgba(180,140,60,0.07);border:1px solid var(--amber-dim);"> <<if _exState === "ls_leaving">> <span style="color:var(--bone-dim);opacity:0.4;">←</span> <span style="color:var(--bone-dim);opacity:0.5;">已离开 <b style="color:var(--bone-dim);"><<print $largeScene.name>></b></span> <<elseif _exState === "ls_approach">> <span style="color:var(--amber);opacity:0.8;">▷</span> <span style="color:var(--amber-dim);">正在接近 <b style="color:var(--amber);"><<print $largeScene.name>></b></span> <<elseif _exState === "ls_active">> <span style="color:var(--amber);">◈</span> <span style="color:var(--bone-dim);">当前位于 <b style="color:var(--amber);"><<print $largeScene.name>></b></span> <<elseif _exState === "ls_zone" || _exState === "ls_zone_approach">> <span style="color:var(--amber);">◈</span> <span style="color:var(--bone-dim);"> 当前位于 <b style="color:var(--amber);"><<print $largeScene.name>></b> <span style="opacity:0.5;margin:0 0.2rem;">·</span> <b style="color:var(--teal-bright);"><<print $worldScene.name>></b> <<if _exState === "ls_zone">><span style="opacity:0.6;font-size:0.69rem;"> 锚定以进行探索</span><</if>> </span> <<elseif _exState === "ws_only">> <span style="color:var(--teal-bright);">◈</span> <span style="color:var(--bone-dim);">当前位于 <b style="color:var(--teal-bright);"><<print $worldScene.name>></b> <span style="opacity:0.6;font-size:0.69rem;">锚定以进行探索</span></span> <<elseif _exState === "ws_approach">> <span style="color:var(--teal-bright);opacity:0.7;">▷</span> <span style="color:var(--bone-dim);">正在接近 <b style="color:var(--teal-bright);"><<print $worldScene.name>></b></span> <<elseif _exState === "ws_leaving">> <span style="color:var(--bone-dim);opacity:0.4;">←</span> <span style="color:var(--bone-dim);opacity:0.5;">已离开 <b style="color:var(--bone-dim);"><<print $worldScene.name>></b></span> <</if>> </div> <</if>> /* ══ 操作台 ══ */ <span style="font-size:0.73rem;color:var(--bone-dim);">⚓ $mapinfo[$maptype].type 深$depth m / 底$depthdeep m</span><br> <<set _ri = Math.max(0, Math.min(100, Math.floor(Number($regionRichness)||0)))>> <<set _ric = _ri > 50 ? "var(--teal-bright)" : _ri > 20 ? "var(--amber)" : "var(--danger-bright)">> <div style="display:flex;justify-content:space-between;font-size:0.68rem;color:var(--bone-dim);margin:0.15rem 0 0.05rem;"> <span>区域丰富度</span><span style="color:<<print _ric>>;"><<print _ri>>/100</span> </div> <div style="background:var(--bg-panel);border:1px solid var(--border-dim);height:4px;border-radius:2px;overflow:hidden;margin-bottom:0.3rem;"><div style="height:100%;width:<<print _ri>>%;background:<<print _ric>>;"></div></div> <<set _emin = ($exploreSearchCost && typeof $exploreSearchCost.min === "number") ? $exploreSearchCost.min : 3>> <<if _ri >= _emin>> <div style="margin-bottom:0.2rem;"><<link "🔍 搜索周围环境">><<exploreSearch>><</link>></div> <<else>> <div style="margin-bottom:0.2rem;opacity:0.4;">🔍 区域已无新发现</div> <</if>> <<if !$envHarvestDefs>><<exploreDefs>><</if>> <<set _ehd = $envHarvestDefs[$maptype]>> <<if _ehd>> <<set _eLabel = "⛏ " + _ehd.label>> <div style="font-size:0.78rem;margin-bottom:0.2rem;"><<link _eLabel>><<exploreDefs>><<set _ehd2 = $envHarvestDefs[$maptype]>><<set _ehLog = "">><<if _ehd2 && _ehd2.loot>><<for _eli = 0; _eli < _ehd2.loot.length; _eli++>><<set _el = _ehd2.loot[_eli]>><<set _elq = _el.qty[0] + Math.floor(Math.random() * (_el.qty[1] - _el.qty[0] + 1))>><<if _elq > 0>><<additem _el.id _elq>><<if $items && $items[_el.id]>><<set _ehLog = _ehLog + $items[_el.id].name + "×" + _elq + " ">><</if>><</if>><</for>><</if>><<set $lastEnvText = (_ehd2 ? _ehd2.text : "") + (_ehLog ? " " + _ehLog : "")>><</link>></div> <</if>> <<if $lastEnvText>><div style="font-size:0.76rem;color:var(--bone-dim);opacity:0.75;margin-bottom:0.2rem;"><<print $lastEnvText>></div><<set $lastEnvText = "">><</if>> /* ── DEV 探索面板 ── */ <<if $devMode>> <div style="margin-top:0.5rem;border:1px dashed #555;border-radius:3px;padding:0.3rem 0.5rem;font-size:0.71rem;color:#888;"> <div style="color:#aaa;margin-bottom:0.2rem;">🔧 DEV · 探索</div> <<link "模拟沉没的货轮">><<set $worldScene={id:"wreck_site",name:"沉没的货轮",state:"inside",children:["wreck_cargo","wreck_engine","wreck_logbook","wreck_mail"],doneCids:[]}>><<goto "探索">><</link>> · <<link "模拟鲸落">><<set $worldScene={id:"whale_fall",name:"鲸落",state:"inside",children:["whale_skull","whale_ribs","whale_tail","whale_scavengers"],doneCids:[]}>><<goto "探索">><</link>> · <<link "清除场景">><<set $worldScene=null>><<set $wsChild=null>><<goto "探索">><</link>><br> <<link "模拟LargeScene(active)">><<set $largeScene={id:"wreck_graveyard",name:"沉船墓场",state:"active",viewDesc:"这片海床密布大小不一的船体残骸。",approachHint:"(已进入)",zones:[]}>><</link>> · <<link "清除LargeScene">><<set $largeScene=0>><</link>><br> <div style="color:#b8a;margin:0.15rem 0 0.08rem;">⚑ 小型事件触发</div> <<if !$smallEventDefs>><<smallEventTable>><</if>> <<link "鲷鱼群">><<set _dv=$smallEventDefs["bream_school"]>><<if _dv>><<set $activeSmallEvent={id:"bream_school",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><<set $diveInteractResult="">><</if>><<goto "探索">><</link>> · <<link "螃蟹聚集">><<set _dv=$smallEventDefs["crab_cluster"]>><<if _dv>><<set $activeSmallEvent={id:"crab_cluster",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><<set $diveInteractResult="">><</if>><<goto "探索">><</link>> · <<link "热液采集">><<set _dv=$smallEventDefs["vent_harvest"]>><<if _dv>><<set $activeSmallEvent={id:"vent_harvest",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><<set $diveInteractResult="">><</if>><<goto "探索">><</link>> · <<link "✕清除">><<set $activeSmallEvent=null>><<goto "探索">><</link>><br> <div style="color:#aaf;margin:0.15rem 0 0.08rem;">✦ 任务</div> <<link "▶ 触发主线">><<if !$questChain>><<questDefs>><</if>><<if $questProgress < $questChain.length>><<run $questLog.push({id:$questChain[$questProgress].id,title:$questChain[$questProgress].title,text:$questChain[$questProgress].logEntry,day:$day||0,type:"main"})>><<set $questNotify="✦ 日记已更新:"+$questChain[$questProgress].title>><<set $questProgress=$questProgress+1>><</if>><<goto "探索">><</link>> <span style="color:#aaf;font-size:0.68rem;">[<<if !$questChain>><<questDefs>><</if>><<print $questProgress>>/<<print $questChain.length>>]</span> · <<link "重置主线">><<set $questProgress=0>><<set $questLog=[]>><<set $questNotify="">><<goto "探索">><</link>> <div style="color:#8cc;margin:0.15rem 0 0.08rem;">🛥 NPC</div> <<if !$npcDefTable>><<npcDefs>><</if>> <<link "补给船">><<set $activeNpc=$npcDefTable["supply_drifter"]>><<set $npcReturn="探索">><<goto "NPC_对话">><</link>> · <<link "废品商">><<set $activeNpc=$npcDefTable["deep_salvager"]>><<set $npcReturn="探索">><<goto "NPC_对话">><</link>> · <<link "✕清除NPC">><<set $activeNpc=null>><</link>> <<link "💠珍珠+5">><<additem "pearl" 5>><</link>> </div> <</if>> <div style="color:#b8a;margin:0.25rem 0 0.1rem;">⚑ 小型事件触发</div> <<if !$smallEventDefs>><<smallEventTable>><</if>> <<link "鲷鱼群">><<set _dv=$smallEventDefs["bream_school"]>><<if _dv>><<set $activeSmallEvent={id:"bream_school",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><</if>><<goto "探索">><</link>> · <<link "螃蟹聚集">><<set _dv=$smallEventDefs["crab_cluster"]>><<if _dv>><<set $activeSmallEvent={id:"crab_cluster",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><</if>><<goto "探索">><</link>> · <<link "热液采集">><<set _dv=$smallEventDefs["vent_harvest"]>><<if _dv>><<set $activeSmallEvent={id:"vent_harvest",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><</if>><<goto "探索">><</link>> · <<link "海獭家族">><<set _dv=$smallEventDefs["bond_otter_family"]>><<if _dv>><<set $activeSmallEvent={id:"bond_otter_family",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><</if>><<goto "探索">><</link>> · <<link "海带种植">><<set _dv=$smallEventDefs["kelp_planting"]>><<if _dv>><<set $activeSmallEvent={id:"kelp_planting",name:_dv.name,stageIdx:0,stageDesc:_dv.stages[0].desc,actions:_dv.stages[0].actions,lootLog:""}>><</if>><<goto "探索">><</link>> · <<link "✕清除">><<set $activeSmallEvent=null>><<goto "探索">><</link>> <div style="font-size:0.76rem;margin-bottom:0.4rem;"><<link "▶ 起锚,恢复航行">><<set $sailMode = "travel">><<set $lastExploreText = "">><<set $activeHuntItems = []>><<set $lastHuntText = "">><<set $currentContext = "sailing">><<goto "航行">><</link>></div> /* ── 书签 ── */ <div style="font-size:0.74rem;margin-top:0.2rem;"> <<set _bmLabel = $showBookmarks ? "▾ 航行记录" : "▸ 航行记录">><<link _bmLabel>><<set $showBookmarks = !$showBookmarks>><</link>> <<if $showBookmarks>><div style="margin-top:0.2rem;max-height:10rem;overflow-y:auto;"><<bookmarkPanel>></div><</if>> </div> <</replace>> <</repeat>> [[终止航行|驾驶舱][$sailspd to 0]] <</nobr>>
<<nobr>> <<upgradeDefs>> <<if !$lastUpgradeText>><<set $lastUpgradeText = "">><</if>> <div style="font-size:0.9rem;color:var(--amber-bright);margin-bottom:0.25rem;">🔧 机械室</div> <div style="font-size:0.77rem;color:var(--bone-dim);margin-bottom:0.4rem;line-height:1.65;"> 满是工具和零件的舱室,各种管道和电路在隔板上交错延伸。操作台旁边贴着几张手绘的改装图纸。 </div> /* ── 升级结果提示 ── */ <<if $lastUpgradeText>> <div style="border-left:2px solid var(--teal-bright);padding:0.1rem 0.4rem;font-size:0.75rem;color:var(--teal-bright);margin-bottom:0.3rem;"> <<print $lastUpgradeText>> </div> <<set $lastUpgradeText = "">> <</if>> /* ── 升级项列表 ── */ <<set _mechKeys = ["hull","pressure","thruster","arm","oxygen_sys","fuel_tank","kitchen","alchemy"]>> <<for _mki = 0; _mki < _mechKeys.length; _mki++>> <<set _mkId = _mechKeys[_mki]>> <<set _mkDef = $upgradeDefs[_mkId]>> <<set _mkCur = Number($upgrades[_mkId]) || 0>> <<set _mkMax = _mkDef.maxLevel>> <<set _mkCurLvl = _mkDef.levels[_mkCur]>> <<capture _mkId, _mkDef, _mkCur, _mkMax, _mkCurLvl>> <div style="border:1px solid var(--border-dim);border-radius:3px;padding:0.25rem 0.4rem;margin-bottom:0.2rem;"> /* 名称 + 等级点 */ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:0.05rem;"> <span style="font-size:0.8rem;color:var(--bone);"><<print _mkDef.name>></span> <span style="font-size:0.68rem;color:var(--bone-dim);"> <<for _lpi = 0; _lpi <= _mkMax; _lpi++>><<if _lpi <= _mkCur>><span style="color:var(--amber);">●</span><<else>><span style="opacity:0.3;">○</span><</if>><</for>> </span> </div> /* 当前等级描述 */ <div style="font-size:0.72rem;color:var(--bone-dim);margin-bottom:0.08rem;"> <<print _mkCurLvl.label>> <span style="opacity:0.6;margin-left:0.3rem;">— <<print _mkCurLvl.effect>></span> </div> /* 升级按钮 */ <<if _mkCur < _mkMax>> <<set _mkNextLvl = _mkDef.levels[_mkCur + 1]>> <<set _mkCostStr = "">> <<set _mkCostKeys = Object.keys(_mkNextLvl.cost)>> <<for _mci = 0; _mci < _mkCostKeys.length; _mci++>> <<set _mcId = _mkCostKeys[_mci]>> <<if _mci > 0>><<set _mkCostStr += " + ">><</if>> <<set _mkCostStr += ($items[_mcId] ? $items[_mcId].name : _mcId) + "×" + _mkNextLvl.cost[_mcId]>> <</for>> <div style="font-size:0.71rem;color:var(--amber-dim);margin-bottom:0.06rem;"> → <<print _mkNextLvl.label>>:<<print _mkCostStr>> </div> <<set _mkUpLabel = "⬆ 升级(" + _mkNextLvl.label + ")">> <<link _mkUpLabel>><<doUpgrade _mkId>><<goto "机械室">><</link>> <<else>> <div style="font-size:0.71rem;color:var(--teal-bright);opacity:0.7;">✓ 已达最高等级</div> <</if>> </div> <</capture>> <</for>> <div style="margin-top:0.4rem;font-size:0.75rem;">[[← 返回走廊|走廊]]</div> <</nobr>>
描写水面出舱后的环境,可进行水面相关活动。 [[← 返回|出舱]]
<<nobr>> /* 测试cp 占位房间: 仅用于 CP 系统展示与测试。 测试cp 已在 $activeCpIds 中, 会出现在匹配房间的场景里; 这里提供一个直达入口。 */ 这是为【测试cp】预留的占位房间,仅用于系统展示与测试。 <<cpScene "休息室">> <<if $activeCpIds.includes("testcp")>> <<link "直接查看测试cp">><<set $detailCpId = "testcp">><<goto "cp详情">><</link>> <</if>> <<link "返回">><<navigate "back">><</link>> <</nobr>>
<<nobr>> <<cpRoomCheck "浴室">> <div style="font-size:0.85rem;color:var(--bone-dim);margin-bottom:0.8rem;line-height:1.7;"> 浴室里水汽未散,管道的低鸣混着淡淡的海藻香型肥皂味。这里终于暂时隔开了舱外的潮气与噪声。 </div> <<cpScene "浴室">> [[镜子]] [[浴缸]] [[返回|走廊]] <</nobr>>
描写浴缸使用体验与状态变化。 [[← 返回|浴室]]
<<nobr>> <<cpRoomCheck "仓库">> <div style="font-size:0.85rem;color:var(--bone-dim);margin-bottom:0.8rem;line-height:1.7;"> 你的工作室兼仓库。仪器在昏黄的灯光下静静等待,架子上的材料散发着微弱的元素气息。 </div> <<cpScene "仓库">> <div style="font-size:0.82rem;color:var(--bone-dim);margin-bottom:0.4rem;">仪器</div> <<set _aLv = Number($upgrades ? $upgrades.alchemy : 0) || 0>> <div class="action-row" style="flex-wrap:wrap;gap:0.4rem;margin-bottom:0.6rem;"> /* Lv0+ 始终可用 */ <<link "精炼台">><<set $alchemyInstrument="精炼台">><<set $alchemyMaterials=[]>><<goto "精炼台">><</link>> /* Lv1+ 溶解皿(黑化)*/ <<if _aLv >= 1>> <<link "溶解皿(黑化)">><<set $alchemyInstrument="溶解皿">><<set $alchemyMaterials=[]>><<goto "炼金选材">><</link>> <<else>><span style="opacity:0.3;font-size:0.8rem;" title="需要炼金台 Lv1">溶解皿🔒</span><</if>> /* Lv2+ 蒸馏器 + 凝结炉 */ <<if _aLv >= 2>> <<link "蒸馏器(白化)">><<set $alchemyInstrument="蒸馏器">><<set $alchemyMaterials=[]>><<goto "炼金选材">><</link>> <<link "凝结炉(黄化)">><<set $alchemyInstrument="凝结炉">><<set $alchemyMaterials=[]>><<goto "炼金选材">><</link>> <<else>> <span style="opacity:0.3;font-size:0.8rem;" title="需要炼金台 Lv2">蒸馏器🔒</span> <span style="opacity:0.3;font-size:0.8rem;" title="需要炼金台 Lv2">凝结炉🔒</span> <</if>> /* Lv3 赤化炉 */ <<if _aLv >= 3>> <<link "赤化炉(赤化)">><<set $alchemyInstrument="赤化炉">><<set $alchemyMaterials=[]>><<goto "炼金选材">><</link>> <<else>><span style="opacity:0.3;font-size:0.8rem;" title="需要炼金台 Lv3">赤化炉🔒</span><</if>> </div> <<if _aLv < 3>> <div style="font-size:0.7rem;color:var(--bone-dim);opacity:0.55;margin-bottom:0.5rem;">🔒 可在机械室升级「炼金台扩充」解锁更多仪器</div> <</if>> <div style="height:1px;background:var(--border-dim);margin:0.5rem 0;"></div> [[仓库|store]] [[天窗|天窗]] [[返回走廊|走廊]] <</nobr>>
<<nobr>> <<set _ar_idef = $alchemyInstrumentDefs ? $alchemyInstrumentDefs[$alchemyInstrument] : null>> <<set _ar_outputs = []>> <<set _ar_msgs = []>> <<if $alchemyInstrument === "精炼台" && $alchemyMaterials.length === 1>> <<set _ar_matId = $alchemyMaterials[0]>> <<set _ar_rule = $refineRules ? $refineRules[_ar_matId] : null>> <<if _ar_rule>> <<set _ar_ek = _ar_rule.element === "水" ? "water" : _ar_rule.element === "火" ? "fire" : _ar_rule.element === "土" ? "earth" : "wind">> <<set _ar_fk = _ar_rule.form === "固" ? "s" : _ar_rule.form === "液" ? "l" : _ar_rule.form === "气" ? "g" : "i">> <<set _ar_outId = "alch_" + _ar_ek + "_" + _ar_fk>> <<run _ar_outputs.push({ id:_ar_outId, qty:1 })>> <<run _ar_msgs.push("精炼完成,获得" + (State.variables.items[_ar_outId] ? State.variables.items[_ar_outId].name : _ar_outId) + "。")>> <<if _ar_rule.ether > 0 && Math.random() < _ar_rule.ether>> <<set _ar_ethId = _ar_rule.etherType === "blessed" ? "ether_blessed" : "ether_corrupt">> <<run _ar_outputs.push({ id:_ar_ethId, qty:1 })>> <<run _ar_msgs.push("同时析出了" + (State.variables.items[_ar_ethId] ? State.variables.items[_ar_ethId].name : _ar_ethId) + "。")>> <</if>> <<removeitem _ar_matId 1>> <<else>> <<run _ar_msgs.push("没有找到对应的精炼规则,材料未被消耗。")>> <</if>> <<elseif $alchemyMaterials.length === 1>> <<set _ar_m1id = $alchemyMaterials[0]>> <<set _ar_m1def = State.variables.items[_ar_m1id]>> <<if _ar_m1def>> <<set _ar_ek2 = _ar_m1def.element === "水" ? "water" : _ar_m1def.element === "火" ? "fire" : _ar_m1def.element === "土" ? "earth" : "wind">> <<if $alchemyInstrument === "赤化炉">> <<set _ar_outId2 = "alch_" + _ar_ek2 + "_i">> <<run _ar_outputs.push({ id:_ar_outId2, qty:1 })>> <<run _ar_msgs.push("赤化完成,获得" + (State.variables.items[_ar_outId2] ? State.variables.items[_ar_outId2].name : _ar_outId2) + "。")>> <<elseif _ar_idef && _ar_idef.single>> <<set _ar_expectForm = _ar_idef.single.input + "态">> <<if _ar_m1def.form === _ar_expectForm>> <<set _ar_outFk2 = _ar_idef.single.output === "固" ? "s" : _ar_idef.single.output === "液" ? "l" : _ar_idef.single.output === "气" ? "g" : "i">> <<set _ar_outId3 = "alch_" + _ar_ek2 + "_" + _ar_outFk2>> <<run _ar_outputs.push({ id:_ar_outId3, qty:1 })>> <<run _ar_msgs.push((_ar_idef ? _ar_idef.stage : "操作") + "完成,获得" + (State.variables.items[_ar_outId3] ? State.variables.items[_ar_outId3].name : _ar_outId3) + "。")>> <<if Math.random() < 0.3>> <<run _ar_outputs.push({ id:"alch_residue", qty:1 })>> <<run _ar_msgs.push("同时产生了少量炼金杂质。")>> <</if>> <<else>> <<run _ar_outputs.push({ id:"alch_mixed", qty:1 })>> <<run _ar_msgs.push("形态不匹配,产生了混杂精质。")>> <</if>> <</if>> <<removeitem _ar_m1id 1>> <</if>> <<elseif $alchemyMaterials.length === 2>> <<set _ar_d1 = State.variables.items[$alchemyMaterials[0]]>> <<set _ar_d2 = State.variables.items[$alchemyMaterials[1]]>> <<if _ar_d1 && _ar_d2>> <<set _ar_pairKey = _ar_d1.element + "_" + _ar_d2.element>> <<set _ar_tinRes = $tincturePairs ? $tincturePairs[_ar_pairKey] : null>> <<set _ar_tinInst = $tincturePairInstrument ? $tincturePairInstrument[_ar_pairKey] : null>> <<if _ar_tinRes && _ar_tinInst === $alchemyInstrument>> <<set _ar_tinName = State.variables.items[_ar_tinRes] ? State.variables.items[_ar_tinRes].name : _ar_tinRes>> <<run _ar_outputs.push({ id:_ar_tinRes, qty:1 })>> <<run _ar_msgs.push("✦ 元素共鸣成功!获得" + _ar_tinName + "。")>> <<elseif _ar_d1.element === _ar_d2.element>> <<set _ar_ek3 = _ar_d1.element === "水" ? "water" : _ar_d1.element === "火" ? "fire" : _ar_d1.element === "土" ? "earth" : "wind">> <<set _ar_fk3 = _ar_d1.form === "固态" ? "s" : _ar_d1.form === "液态" ? "l" : _ar_d1.form === "气态" ? "g" : "i">> <<set _ar_sameOut = "alch_" + _ar_ek3 + "_" + _ar_fk3>> <<run _ar_outputs.push({ id:_ar_sameOut, qty:2 })>> <<run _ar_msgs.push("同元素强化,获得" + (State.variables.items[_ar_sameOut] ? State.variables.items[_ar_sameOut].name : _ar_sameOut) + "×2。")>> <<else>> <<run _ar_outputs.push({ id:"alch_mixed", qty:1 })>> <<run _ar_msgs.push("元素不相容,产生了混杂精质。请在正确的仪器中尝试元素共鸣。")>> <</if>> <<removeitem $alchemyMaterials[0] 1>> <<removeitem $alchemyMaterials[1] 1>> <</if>> <</if>> /* 写入背包/仓库 */ <<for _aro = 0; _aro < _ar_outputs.length; _aro++>> <<set _arDef = State.variables.items[_ar_outputs[_aro].id]>> <<if _arDef>><<additem _ar_outputs[_aro].id _ar_outputs[_aro].qty>><</if>> <</for>> /* 拼接消息 HTML(在 nobr 内完成,不混入任何裸 HTML) */ <<set _ar_msgHtml = "">> <<for _arm = 0; _arm < _ar_msgs.length; _arm++>> <<set _ar_isGold = _ar_msgs[_arm].slice(0,1) === "✦">> <<set _ar_msgHtml += "<p style='margin:0.25rem 0;" + (_ar_isGold ? "color:#f0c060;" : "") + "'>" + _ar_msgs[_arm] + "</p>">> <</for>> /* 拼接产出列表 HTML,并记录第一项主产物供角色记忆引用。 */ <<set _ar_outHtml = "">> <<set _ar_recentProduct = "">> <<for _aro2 = 0; _aro2 < _ar_outputs.length; _aro2++>> <<set _ar_od = State.variables.items[_ar_outputs[_aro2].id]>> <<set _ar_nm = _ar_od ? _ar_od.name : _ar_outputs[_aro2].id>> <<if !_ar_recentProduct>><<set _ar_recentProduct = _ar_nm>><</if>> <<set _ar_qt = _ar_outputs[_aro2].qty>> <<set _ar_dest = (_ar_od && (_ar_od.type === "纯粹酊剂" || _ar_od.type === "以太副产物")) ? "已存入仓库" : "已存入背包">> <<set _ar_outHtml += "<div style='padding:0.1rem 0;color:var(--amber-bright);'>" + _ar_nm + " ×" + _ar_qt + "<span style='color:var(--bone-dim);font-size:0.75rem;'> → " + _ar_dest + "</span></div>">> <</for>> <<set _ar_stageLabel = _ar_idef ? _ar_idef.stage : "炼金">> <<if _ar_recentProduct && $cps && $cps.viona>><<cpMemory "viona" "alchemy" "recent_alchemy" 1 _ar_recentProduct>><</if>> <<set $alchemyMaterials = []>> <</nobr>><div style="color:var(--teal-bright);font-size:1rem;margin-bottom:0.5rem;"><<print _ar_stageLabel>>完成</div><div style="font-size:0.87rem;"><<print _ar_msgHtml>></div><<if _ar_outHtml>><div style="margin-top:0.5rem;font-size:0.78rem;border-top:1px solid var(--border-dim);padding-top:0.4rem;"><<print _ar_outHtml>></div><</if>><div style="margin-top:0.9rem;">[[继续炼金|炼金室]]</div>
<<nobr>><div style="font-size:1rem;color:var(--amber-bright);margin-bottom:0.3rem;"><<set _ah_idef = $alchemyInstrumentDefs ? $alchemyInstrumentDefs[$alchemyInstrument] : null>><<print $alchemyInstrument>> — <<print _ah_idef ? _ah_idef.stage : "">></div><div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.8rem;"><<if !$alchemyTimer>><<set $alchemyTimer = 0>><</if>><<for _apmi = 0; _apmi < $alchemyMaterials.length; _apmi++>><<set _apmd = State.variables.items[$alchemyMaterials[_apmi]]>><<if _apmd>><<print _apmd.name>><<if _apmi < $alchemyMaterials.length-1>>、<</if>><</if>><</for>></div><div id="alch-view" style="min-height:100px;">准备开始……</div><<repeat 1s>><<set _ap_idef2 = $alchemyInstrumentDefs ? $alchemyInstrumentDefs[$alchemyInstrument] : null>><<set _ap_dur = _ap_idef2 ? _ap_idef2.dur : 10>><<set $alchemyTimer += 1>><<set $timepass += 1>><<time>><<set _ap_ratio = $alchemyTimer / _ap_dur>><<set _ap_descs = _ap_idef2 ? _ap_idef2.desc : []>><<set _ap_text = _ap_descs.length > 0 ? _ap_descs[0].text : "处理中……">><<for _apdi = _ap_descs.length - 1; _apdi >= 0; _apdi-->><<if _ap_ratio >= _ap_descs[_apdi].ratio>><<set _ap_text = _ap_descs[_apdi].text>><<break>><</if>><</for>><<set _ap_pct = Math.min(Math.floor(_ap_ratio * 100), 100)>><<replace "#alch-view">><p style="font-size:0.88rem;color:var(--bone-dim);font-style:italic;min-height:2.5em;line-height:1.7;"><<print _ap_text>></p><div style="font-size:0.75rem;color:var(--bone-dim);margin:0.3rem 0;"><<print $alchemyTimer>>s / <<print _ap_dur>>s</div><div style="background:var(--bg-panel);border:1px solid var(--border-dim);height:10px;border-radius:5px;overflow:hidden;margin-bottom:0.6rem;"><div style="height:100%;width:<<print _ap_pct>>%;background:var(--amber);transition:width 0.85s linear;"></div></div><<if _ap_pct >= 100>><div><<link "▶ 完成炼金">><<goto "炼金结果">><</link>></div><</if>><</replace>><<if $alchemyTimer >= _ap_dur>><<stop>><</if>><</repeat>><</nobr>>
<<nobr>> <<if !$alchemyMaterials>><<set $alchemyMaterials = []>><</if>> <<set _as_idef = $alchemyInstrumentDefs[$alchemyInstrument]>> /* 扫描背包炼金材料 */ <<set _as_mats = []>> <<set _as_cats = Object.keys($store)>> <<for _asc = 0; _asc < _as_cats.length; _asc++>> <<set _asl = $store[_as_cats[_asc]]>> <<if Array.isArray(_asl)>> <<for _asi = 0; _asi < _asl.length; _asi++>> <<if _asl[_asi].quantity > 0>> <<set _asd = State.variables.items[_asl[_asi].id]>> <<if _asd && _asd.type === "炼金材料" && _asd.element>> <<run _as_mats.push({ id:_asl[_asi].id, qty:_asl[_asi].quantity, name:_asd.name, element:_asd.element, form:_asd.form })>> <</if>> <</if>> <</for>> <</if>> <</for>> /* 预测结果 */ <<set _as_predicted = "">> <<if $alchemyMaterials.length === 1>> <<set _as_m1def = State.variables.items[$alchemyMaterials[0]]>> <<if _as_idef && _as_idef.single>> <<if _as_m1def && _as_m1def.form === _as_idef.single.input + "态">> <<set _as_outid = "alch_" + (_as_m1def.element === "水" ? "water" : _as_m1def.element === "火" ? "fire" : _as_m1def.element === "土" ? "earth" : "wind") + "_" + (_as_idef.single.output === "固" ? "s" : _as_idef.single.output === "液" ? "l" : _as_idef.single.output === "气" ? "g" : "i")>> <<set _as_outn = State.variables.items[_as_outid] ? State.variables.items[_as_outid].name : _as_outid>> <<set _as_predicted = "→ " + _as_outn>> <<else>> <<set _as_predicted = "⚠ 形态不匹配,将产生混杂精质">> <</if>> <<elseif $alchemyInstrument === "赤化炉">> <<if _as_m1def>> <<set _as_outid2 = "alch_" + (_as_m1def.element === "水" ? "water" : _as_m1def.element === "火" ? "fire" : _as_m1def.element === "土" ? "earth" : "wind") + "_i">> <<set _as_outn2 = State.variables.items[_as_outid2] ? State.variables.items[_as_outid2].name : _as_outid2>> <<set _as_predicted = "→ " + _as_outn2>> <</if>> <</if>> <<elseif $alchemyMaterials.length === 2>> <<set _as_m1d = State.variables.items[$alchemyMaterials[0]]>> <<set _as_m2d = State.variables.items[$alchemyMaterials[1]]>> <<if _as_m1d && _as_m2d>> <<set _as_pairKey = _as_m1d.element + "_" + _as_m2d.element>> <<set _as_tinRes = $tincturePairs ? $tincturePairs[_as_pairKey] : null>> <<set _as_tinInst = $tincturePairInstrument ? $tincturePairInstrument[_as_pairKey] : null>> <<if _as_tinRes && _as_tinInst === $alchemyInstrument>> <<set _as_tinName = State.variables.items[_as_tinRes] ? State.variables.items[_as_tinRes].name : _as_tinRes>> <<set _as_predicted = "→ ✦ " + _as_tinName>> <<elseif _as_m1d.element === _as_m2d.element>> <<set _as_predicted = "→ 同元素强化(产出高纯度精质)">> <<else>> <<set _as_predicted = "→ ⚠ 元素不相容,将产生混杂精质">> <</if>> <</if>> <</if>> <div style="font-size:0.82rem;color:var(--bone-dim);margin-bottom:0.4rem;"> <span style="color:var(--amber-bright);"><<print $alchemyInstrument>></span> <span style="margin-left:0.5rem;opacity:0.7;"><<print _as_idef ? _as_idef.stage : "">>阶段</span> </div> <div style="min-height:2rem;margin:0.4rem 0 0.7rem;font-size:0.82rem;"> 已选(<<print $alchemyMaterials.length>>/2): <<if $alchemyMaterials.length > 0>> <<for _assi = 0; _assi < $alchemyMaterials.length; _assi++>> <<capture _assi>> <<set _assdef = State.variables.items[$alchemyMaterials[_assi]]>> <span style="display:inline-block;background:var(--bg-panel);border:1px solid var(--amber-dim);padding:0.1rem 0.4rem;margin:0.1rem;font-size:0.8rem;color:var(--amber-bright);"> <<print _assdef ? _assdef.name : $alchemyMaterials[_assi]>> <<link "✕">><<run State.variables.alchemyMaterials.splice(_assi,1)>><<goto "炼金选材">><</link>> </span> <</capture>> <</for>> <<else>> <span style="color:var(--bone-dim);font-style:italic;">尚未选择</span> <</if>> <<if _as_predicted>> <span style="margin-left:0.5rem;color:var(--teal-bright);font-size:0.8rem;"><<print _as_predicted>></span> <</if>> </div> <div class="inv-grid" style="grid-template-columns:repeat(auto-fill,minmax(145px,1fr));gap:0.35rem;"> <<if _as_mats.length === 0>> <p style="color:var(--bone-dim);font-style:italic;font-size:0.85rem;grid-column:1/-1;">背包中没有炼金材料。</p> <<else>> <<for _asgi = 0; _asgi < _as_mats.length; _asgi++>> <<set _asgm = _as_mats[_asgi]>> <<set _asgSel = $alchemyMaterials.includes(_asgm.id)>> <<set _asgFull = $alchemyMaterials.length >= 2>> <<capture _asgi, _asgm, _asgSel, _asgFull>> <span class="inv-item" style="flex-direction:column;align-items:flex-start;height:auto;padding:0.35rem 0.6rem;<<if _asgSel>>border-color:var(--amber-bright);<</if>>"> <<if !_asgSel && !_asgFull>> <<link _asgm.name>><<run State.variables.alchemyMaterials.push(_asgm.id)>><<goto "炼金选材">><</link>> <<else>> <span style="color:<<print _asgSel ? 'var(--amber-bright)' : 'var(--bone-dim)'>>;"><<print _asgm.name>></span> <</if>> <span style="font-size:0.7rem;color:var(--bone-dim);margin-top:0.1rem;"><<print _asgm.element>>·<<print _asgm.form>> ×<<print _asgm.qty>></span> </span> <</capture>> <</for>> <</if>> </div> <div class="action-row" style="margin-top:0.8rem;"> <<if $alchemyMaterials.length > 0>> <<link "▶ 开始<<print _as_idef ? _as_idef.stage : '操作'>>">> <<set $alchemyTimer = 0>> <<goto "炼金进行">> <</link>> <</if>> <<link "← 返回">><<set $alchemyMaterials = []>><<goto "炼金室">><</link>> </div> <</nobr>>
<<nobr>> /* 品质判定 */ <<set $cookQuality = "失败">> <<if $cookFinalTime >= $cookSuccessMin && $cookFinalTime <= $cookSuccessMax>> <<set $cookQuality = "成功">> <<if $cookFinalTime >= $cookPerfectMin && $cookFinalTime <= $cookPerfectMax>> <<set $cookQuality = "完美">> <</if>> <</if>> /* 消耗背包食材(每种消耗1份) */ <<for _rci = 0; _rci < $cookIngredients.length; _rci++>> <<set _rc_id = $cookIngredients[_rci]>> <<set _rc_idef = State.variables.items[_rc_id]>> <<set _rc_type = _rc_idef ? _rc_idef.type : "食材">> <<set _rc_idx = -1>> <<if $backpack[_rc_type]>> <<for _rbi = 0; _rbi < $backpack[_rc_type].length; _rbi++>> <<if $backpack[_rc_type][_rbi].id === _rc_id>> <<set _rc_idx = _rbi>><<break>> <</if>> <</for>> <</if>> <<if _rc_idx >= 0 && $backpack[_rc_type][_rc_idx].quantity > 0>> <<set $backpack[_rc_type][_rc_idx].quantity -= 1>> <</if>> <</for>> /* 构建菜品实例并存入冰箱 */ <<assembleDish>> <<if $assembleResult === "full">> <div style="color:var(--danger-bright);font-size:0.9rem;margin-bottom:0.6rem;">冰箱已满</div> <p style="font-size:0.85rem;color:var(--bone-dim);"> <span style="color:var(--amber-bright);"><<print $cookRecipeName>></span>(<<print $cookQuality>>)做好了,但冰箱已经没有空位了。这道菜只能丢弃。 </p> <div class="action-row" style="margin-top:0.8rem;"> [[继续烹饪|厨房]] [[查看冰箱|冰箱]] </div> <<else>> <<set _cr_dish = $fridge[$assembleSlot]>> <<if $cps && $cps.viona && $cps.viona.recentEvents && _cr_dish>> <<set $cps.viona.recentEvents.cooked = {tag:"cooked_by_player",product:_cr_dish.name,day:$day,expire:$day + 2}>> <</if>> <div style="margin-bottom:0.6rem;"> <<if $cookQuality === "完美">> <div style="color:#f0c060;font-size:1.05rem;letter-spacing:0.1em;">★ 完美烹饪</div> <<elseif $cookQuality === "成功">> <div style="color:var(--teal-bright);font-size:1rem;">烹饪完成</div> <<else>> <div style="color:var(--danger-bright);font-size:1rem;">烹饪失败</div> <</if>> </div> <div class="item-detail"> <div class="item-detail-name"><<print _cr_dish.name>></div> <p style="font-size:0.85rem;line-height:1.75;color:var(--bone-dim);margin:0.5rem 0;border-left:2px solid var(--border);padding-left:0.8rem;"><<print _cr_dish.desc>></p> <div style="font-size:0.78rem;color:var(--bone-dim);margin-top:0.4rem;"> <<if _cr_dish.hunger > 0>><span style="color:#8bc4a0;">饱腹+<<print _cr_dish.hunger>></span> <</if>> <<if _cr_dish.water > 0>><span style="color:#6ab4d0;">饮水+<<print _cr_dish.water>></span> <</if>> <<if _cr_dish.life > 0>><span style="color:var(--teal-bright);">生命+<<print _cr_dish.life>></span> <</if>> <<if _cr_dish.power > 0>><span style="color:var(--amber-bright);">体力+<<print _cr_dish.power>></span> <</if>> <<if _cr_dish.san !== 0>><span style="color:<<if _cr_dish.san > 0>>var(--amber)<<else>>var(--danger-bright)<</if>>;">安定<<if _cr_dish.san > 0>>+<</if>><<print _cr_dish.san>></span> <</if>> </div> </div> <p style="font-size:0.8rem;color:var(--bone-dim);margin-top:0.5rem;">已存入冰箱(格位 <<print $assembleSlot + 1>>/8)。</p> <div class="action-row" style="margin-top:0.8rem;"> [[继续烹饪|厨房]] [[查看冰箱|冰箱]] [[离开厨房|走廊]] </div> <</if>> <</nobr>>
<<nobr>> <<if !$cookTimer>><<set $cookTimer = 0>><</if>> <div style="margin-bottom:0.8rem;"> <div style="font-size:1rem;color:var(--amber-bright);"><<print $cookMethod>> — <<print $cookRecipeName>></div> <div style="font-size:0.8rem;color:var(--bone-dim);margin-top:0.2rem;"><<nobr>><<for _cci = 0; _cci < $cookIngredients.length; _cci++>><<set _cn = State.variables.items[$cookIngredients[_cci]]>><<if _cn>><<print _cn.name>><<if _cci < $cookIngredients.length-1>>、<</if>><</if>><</for>><</nobr>></div> </div> <div id="cook-view" style="min-height:160px;">等待烹饪开始……</div> <<repeat 1s>> <<set $cookTimer += 1>><<set $timepass += 1>><<time>> <<set _cv_ratio = $cookTimer / $cookDuration>> <<set _cv_desc = $cookDesc[$cookMethod]>> <<set _cv_text = _cv_desc[0].text>> <<for _cdi = _cv_desc.length - 1; _cdi >= 0; _cdi-->> <<if _cv_ratio >= _cv_desc[_cdi].ratio>> <<set _cv_text = _cv_desc[_cdi].text>> <<break>> <</if>> <</for>> <<set _cv_zone = 0>> <<if $cookTimer >= $cookSuccessMin && $cookTimer < $cookPerfectMin>> <<set _cv_zone = 1>> <<elseif $cookTimer >= $cookPerfectMin && $cookTimer <= $cookPerfectMax>> <<set _cv_zone = 2>> <<elseif $cookTimer > $cookPerfectMax && $cookTimer <= $cookSuccessMax>> <<set _cv_zone = 1>> <<elseif $cookTimer > $cookSuccessMax>> <<set _cv_zone = -1>> <</if>> <<set _pct = Math.min(Math.floor(_cv_ratio * 100), 100)>> <<set _succ_left = Math.floor($cookSuccessMin / $cookDuration * 100)>> <<set _succ_right = Math.floor($cookSuccessMax / $cookDuration * 100)>> <<set _perf_left = Math.floor($cookPerfectMin / $cookDuration * 100)>> <<set _perf_right = Math.floor($cookPerfectMax / $cookDuration * 100)>> <<set _succ_w = _succ_right - _succ_left>> <<set _perf_w = _perf_right - _perf_left>> <<replace "#cook-view">> <p style="font-size:0.88rem;color:var(--bone-dim);font-style:italic;min-height:2.5em;line-height:1.7;"><<print _cv_text>></p> <div style="font-size:0.75rem;color:var(--bone-dim);margin:0.5rem 0 0.3rem;"> <<print $cookTimer>>s / <<print $cookDuration>>s <<if _cv_zone === 2>><span style="color:#f0c060;margin-left:0.8rem;">★ 完美区间</span> <<elseif _cv_zone === 1>><span style="color:#8bc4a0;margin-left:0.8rem;">▸ 成功区间</span> <<elseif _cv_zone === -1>><span style="color:#c47070;margin-left:0.8rem;">✕ 已过时机</span> <</if>> </div> <div style="position:relative;height:10px;background:var(--bg-panel);border:1px solid var(--border-dim);border-radius:3px;margin-bottom:0.4rem;"> <div style="position:absolute;top:0;left:<<print _succ_left>>%;width:<<print _succ_w>>%;height:100%;background:rgba(139,196,160,0.18);"></div> <div style="position:absolute;top:0;left:<<print _perf_left>>%;width:<<print _perf_w>>%;height:100%;background:rgba(240,192,96,0.28);"></div> <div style="position:absolute;top:0;left:0;width:<<print _pct>>%;height:100%;background:<<if _cv_zone === 2>>var(--amber)<<elseif _cv_zone === 1>>var(--teal)<<elseif _cv_zone === -1>>var(--danger-bright)<<else>>var(--bone-dim)<</if>>;border-radius:2px;transition:width 0.85s linear;"></div> <div style="position:absolute;top:-2px;left:<<print _succ_left>>%;width:1px;height:14px;background:rgba(139,196,160,0.7);"></div> <div style="position:absolute;top:-2px;left:<<print _perf_left>>%;width:1px;height:14px;background:rgba(240,192,96,0.9);"></div> <div style="position:absolute;top:-2px;left:<<print _perf_right>>%;width:1px;height:14px;background:rgba(240,192,96,0.9);"></div> <div style="position:absolute;top:-2px;left:<<print _succ_right>>%;width:1px;height:14px;background:rgba(139,196,160,0.7);"></div> </div> <div style="font-size:0.7rem;color:var(--bone-dim);margin-bottom:0.8rem;"> <span style="color:rgba(240,192,96,0.9);">■</span> 完美 <span style="color:rgba(139,196,160,0.9);">■</span> 成功 </div> /* <<link>> 替代 <<button>>:跳转页面会自动停止 repeat,无需 <<stop>> */ <<link "■ 完成烹饪">> <<set $cookFinalTime = $cookTimer>> <<goto "烹饪结果">> <</link>> <</replace>> <</repeat>> <</nobr>>
<<nobr>> <<if !$cookIngredients>><<set $cookIngredients = []>><</if>> /* 扫描背包可用食材 */ <<set _cs_food = []>> <<set _cs_bpCats = Object.keys($backpack)>> <<for _cs_ci = 0; _cs_ci < _cs_bpCats.length; _cs_ci++>> <<set _cs_cat = _cs_bpCats[_cs_ci]>> <<set _cs_list = $backpack[_cs_cat]>> <<if Array.isArray(_cs_list)>> <<for _cs_i = 0; _cs_i < _cs_list.length; _cs_i++>> <<if _cs_list[_cs_i].quantity > 0>> <<set _cs_def = State.variables.items[_cs_list[_cs_i].id]>> <<if _cs_def && _cs_def.type === "食材" && _cs_def.foodtags && !_cs_def.foodtags.includes("调料")>> <<run _cs_food.push({ id: _cs_list[_cs_i].id, qty: _cs_list[_cs_i].quantity, name: _cs_def.name })>> <</if>> <</if>> <</for>> <</if>> <</for>> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.4rem;"> 烹饪方式:<span style="color:var(--amber-bright);"><<print $cookMethod>></span> </div> <!-- 已选食材区 --> <div style="min-height:2.2rem;margin:0.5rem 0 0.8rem;"> <span style="font-size:0.78rem;color:var(--bone-dim);">已选(<<print $cookIngredients.length>>/3):</span> <<if $cookIngredients.length > 0>> <<for _si = 0; _si < $cookIngredients.length; _si++>> /* 关键:先在 capture 外赋值,再把两个变量都列进 capture 参数 */ <<set _sid = $cookIngredients[_si]>> <<set _sdef = State.variables.items[_sid]>> <<set _sname_cap = _sdef ? _sdef.name : _sid>> <<capture _si, _sname_cap>> <span style="display:inline-block;background:var(--bg-panel);border:1px solid var(--amber-dim);padding:0.12rem 0.45rem;margin:0.12rem;font-size:0.82rem;color:var(--amber-bright);"><<print _sname_cap>> <<link "✕">> <<run State.variables.cookIngredients.splice(_si, 1)>> <<goto "烹饪选材">> <</link>></span> <</capture>> <</for>> <<else>> <span style="color:var(--bone-dim);font-size:0.82rem;font-style:italic;">尚未选择食材</span> <</if>> </div> <hr style="border-color:var(--border-dim);margin:0.4rem 0 0.7rem;"> <!-- 可选食材区 --> <<if _cs_food.length === 0>> <p style="color:var(--bone-dim);font-size:0.85rem;">背包中没有可用食材。</p> <<else>> <div class="inv-grid"> <<for _fi = 0; _fi < _cs_food.length; _fi++>> /* 同样先赋值再 capture */ <<set _fitem_cap = _cs_food[_fi]>> <<set _fsel_cap = $cookIngredients.includes(_fitem_cap.id)>> <<capture _fi, _fitem_cap, _fsel_cap>> <<if _fsel_cap>> <span class="inv-item" style="border-color:var(--amber-dim);color:var(--amber-bright);"> <<print _fitem_cap.name>><span class="item-qty">×<<print _fitem_cap.qty>></span> </span> <<elseif $cookIngredients.length >= 3>> <span class="inv-item" style="opacity:0.4;"> <<print _fitem_cap.name>><span class="item-qty">×<<print _fitem_cap.qty>></span> </span> <<else>> <span class="inv-item"><<link _fitem_cap.name>> <<run State.variables.cookIngredients.push(_fitem_cap.id)>> <<goto "烹饪选材">> <</link>><span class="item-qty">×<<print _fitem_cap.qty>></span></span> <</if>> <</capture>> <</for>> </div> <</if>> <div class="action-row" style="margin-top:1rem;"> <<if $cookIngredients.length > 0>> <span class="btn-primary"><<link "▶ 开始烹饪">> <<matchRecipe>> <<set $cookTimer = 0>> <<goto "烹饪进行">> <</link>></span> <</if>> [[← 返回|厨房]] </div> <</nobr>>
描写水培种植系统,可种植蔬菜与海草类作物。 [[← 返回|农场]]
<<nobr>> <<set _rf_cats = Object.keys($store)>> <<set _rf_mats = []>> <<for _rfc = 0; _rfc < _rf_cats.length; _rfc++>> <<set _rfl = $store[_rf_cats[_rfc]]>> <<if Array.isArray(_rfl)>> <<for _rfi = 0; _rfi < _rfl.length; _rfi++>> <<if _rfl[_rfi].quantity > 0>> <<set _rfd = State.variables.items[_rfl[_rfi].id]>> <<if $refineRules && $refineRules[_rfl[_rfi].id]>> <<run _rf_mats.push({ id:_rfl[_rfi].id, qty:_rfl[_rfi].quantity, name:_rfd ? _rfd.name : _rfl[_rfi].id })>> <</if>> <</if>> <</for>> <</if>> <</for>> <div style="font-size:0.82rem;color:var(--bone-dim);margin-bottom:0.6rem;"> 精炼台 <span style="font-size:0.75rem;opacity:0.7;">将原始材料提炼为炼金精质,同步分离以太属性</span> </div> <<if _rf_mats.length === 0>> <p style="color:var(--bone-dim);font-style:italic;font-size:0.85rem;">背包中没有可精炼的原始材料。</p> <<else>> <div class="inv-grid" style="grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:0.35rem;"> <<for _rfi2 = 0; _rfi2 < _rf_mats.length; _rfi2++>> <<capture _rfi2>> <<set _rfm = _rf_mats[_rfi2]>> <<set _rfrule = $refineRules[_rfm.id]>> <<set _rfout = "alch_" + (_rfrule.element === "水" ? "water" : _rfrule.element === "火" ? "fire" : _rfrule.element === "土" ? "earth" : "wind") + "_" + (_rfrule.form === "固" ? "s" : _rfrule.form === "液" ? "l" : _rfrule.form === "气" ? "g" : "i")>> <<set _rfoutn = State.variables.items[_rfout] ? State.variables.items[_rfout].name : _rfout>> <span class="inv-item" style="flex-direction:column;align-items:flex-start;height:auto;padding:0.4rem 0.65rem;"> <span style="color:var(--amber-bright);font-size:0.85rem;"><<print _rfm.name>></span> <span style="font-size:0.7rem;color:var(--bone-dim);margin-top:0.1rem;">×<<print _rfm.qty>> → <<print _rfoutn>></span> <<if _rfrule.ether > 0>> <span style="font-size:0.68rem;color:#a080d0;">可能析出<<print _rfrule.etherType === "blessed" ? "祝福" : "污染">>以太</span> <</if>> <<link "精炼">> <<set $alchemyInstrument = "精炼台">> <<set $alchemyMaterials = [_rfm.id]>> <<set $alchemyTimer = 0>> <<goto "炼金进行">> <</link>> </span> <</capture>> <</for>> </div> <</if>> <div class="action-row" style="margin-top:1rem;">[[← 返回炼金室|炼金室]]</div> <</nobr>>
<<nobr>> <<set _bvDef = State.variables.items[$selectitem]>> <<finditem State.variables.backpack $selectitem>> <<set _bvEntry = _foundItem>> <<if !$lastTakeText>><<set $lastTakeText = "">><</if>> <<if !_bvDef>> <p style="color:var(--danger-bright);">物品数据缺失(ID:<<print $selectitem>>)</p> [[返回背包|backpack]] <<else>> <div class="item-detail"> <div class="item-detail-name"><<print _bvDef.name>></div> <div class="item-detail-meta"> <<if _bvDef.element>><span class="ether-badge <<print _bvDef.element === '水' ? 'water' : (_bvDef.element === '火' ? 'fire' : (_bvDef.element === '土' ? 'earth' : 'wind'))>>"><<print _bvDef.element>></span><</if>> <<if _bvDef.form>><span class="form-badge"><<print _bvDef.form>></span><</if>> <<if _bvDef.rarity>><span class="item-tag rare"><<print _bvDef.rarity>></span><</if>> <span style="color:var(--bone-dim);font-size:0.72rem;"><<print _bvDef.type>><<if _bvDef.subtype>> · <<print _bvDef.subtype>><</if>></span> </div> <<if _bvDef.desc>> <p style="font-size:0.85rem;line-height:1.7;color:var(--bone-dim);margin:0.6rem 0 0.4rem;border-left:2px solid var(--border);padding-left:0.8rem;"><<print _bvDef.desc>></p> <</if>> <<if _bvEntry>> <p style="font-size:0.82rem;color:var(--bone-dim);">持有:<strong><<print _bvEntry.quantity>></strong></p> <</if>> </div> <<if $lastTakeText>> <div class="event-result"><<print $lastTakeText>></div> <<set $lastTakeText = "">> <</if>> <div class="action-row"> <<link "放回仓库 1 份">><<put $selectitem 1>><<goto "背包物品页面">><</link>> <<link "全部放回">><<putAll $selectitem>><<goto "背包物品页面">><</link>> </div> <<if _bvEntry && _bvEntry.addedDay !== undefined>> <<set _fi_sd = $spoilDays ? ($spoilDays[$selectitem] || 0) : 0>> <<if _fi_sd > 0>> <<set _fi_age = $day - _bvEntry.addedDay>> <<set _fi_stage = Math.floor(_fi_age / _fi_sd * 3)>> <<set _fi_left = _fi_sd - _fi_age>> <<if _fi_stage <= 0>> <p style="font-size:0.78rem;color:#8bc4a0;">✦ 新鲜 剩余约 <<print Math.max(_fi_left, 0)>> 天</p> <<elseif _fi_stage === 1>> <p style="font-size:0.78rem;color:var(--amber);">⚠ 开始变质 约 <<print Math.max(_fi_left, 0)>> 天后腐烂</p> <<elseif _fi_stage === 2>> <p style="font-size:0.78rem;color:var(--danger-bright);">⚠ 严重腐败 已超过最佳食用期</p> <</if>> <</if>> <</if>> [[返回背包|backpack]] <</if>> <</nobr>>
<<nobr>> <div id="sail-info">随着引擎轰鸣,潜艇开始了运作…</div> <<repeat 1s>> <<sail>> <<time>> <<replace "#sc-status">><<include "侧边栏状态">><</replace>> <<replace "#sail-info">> <span style="font-size:0.73rem;color:var(--bone-dim);">$showseason季 第$showday日 $showhour:$showminute 船舱$worldtem°</span><br> <<cpRoomCheck "驾驶舱">> /* ════════════════════════════════════════════════ 1. 舷窗 + 雷达提示 ════════════════════════════════════════════════ */ /* ── 舷窗 ── */ <div style="border:1px solid var(--border-dim);border-radius:3px;padding:0.4rem 0.5rem;margin-bottom:0.35rem;font-size:0.84rem;color:var(--bone);line-height:1.85;"> <div style="margin-bottom:0.15rem;"><<view>></div> <<if $activeEvent>> <div style="margin-top:0.25rem;border-top:1px solid var(--border-dim);padding-top:0.2rem;"> <span style="color:var(--amber-bright);font-size:0.72rem;">▲ <<print $activeEvent.name>></span><<if $activeEvent.type === "unstable">><span style="color:var(--danger-bright);font-size:0.7rem;"> · 剩余<<print $eventTimer>>秒</span><</if>><br> <span style="color:var(--bone-dim);font-size:0.8rem;"><<print $activeEvent.desc>></span><br> <<for _eai = 0; _eai < $activeEvent.actions.length; _eai++>><<set _ea = $activeEvent.actions[_eai]>><<capture _ea>><<link _ea>><<resolveEvent _ea>><</link>> <</capture>><</for>> <<if $lastEventText>><div style="color:var(--teal-bright);font-size:0.75rem;margin-top:0.08rem;"><<print $lastEventText>></div><<set $lastEventText = "">><</if>> </div> <</if>> <<if $activeSmallEvent>> <<if !$smallEventDefs>><<smallEventTable>><</if>> <<set _snId = String($activeSmallEvent.id)>> <<set _snDef = $smallEventDefs[_snId]>> <<if _snDef>> <div style="margin-top:0.15rem;border-top:1px solid var(--border-dim);padding-top:0.12rem;font-size:0.76rem;"> ⚑ <<print _snDef.name>><span style="color:var(--bone-dim);font-size:0.68rem;"> · <<if $activeSmallEvent.finished>>已完成,可重新探索<<else>>锚定后可在探索模式处理<</if>></span> </div> <<else>><<set $activeSmallEvent = null>> <</if>> <</if>> <<if $lastSmallEventText>> <div style="margin-top:0.15rem;color:var(--bone-dim);font-size:0.78rem;"><<print $lastSmallEventText>></div> <<set $lastSmallEventText = "">> <</if>> <<if $activeMicroEvent>> <div style="margin-top:0.15rem;border-top:1px solid var(--border-dim);padding-top:0.12rem;font-size:0.76rem;"> <span style="color:var(--teal-bright);">✦ 附近发现:<<print $activeMicroEvent.name>></span><br> <span style="color:var(--bone-dim);"><<print $activeMicroEvent.desc>></span><br> <span style="color:var(--bone-dim);font-size:0.72rem;">锚定后可在探索模式处理。</span> </div> <</if>> <<if $fishing == 1>><<fish>><<fishStatus>><</if>> </div> /* ── 雷达/传感器提示(含时间事件 + temporalLog) ── */ <<if ($temporalEvent && $temporalEvent !== 0) || $temporalLog>> <div style="font-size:0.73rem;color:var(--bone-dim);margin-bottom:0.25rem;"> <<if $temporalEvent && $temporalEvent !== 0>> <<set _teP = Math.min(100, Math.floor($temporalEvent.prog))>> ⚑ <<print $temporalEvent.name>> <span style="display:inline-block;width:3.5rem;height:3px;background:var(--bg-panel);border:1px solid var(--border-dim);vertical-align:middle;"><span style="display:block;height:100%;width:<<print _teP>>%;background:var(--amber);"></span></span> <</if>> <<if $temporalLog>><div style="color:var(--amber);margin-top:0.05rem;"><<print $temporalLog>></div><<set $temporalLog = "">><</if>> </div> <</if>> /* ════════════════════════════════════════════════ 2. 位置提示条(统一大中型事件 + 地点) ════════════════════════════════════════════════ */ <<set _navState = "normal">> <<if $largeScene && typeof $largeScene === "object" && $largeScene.state === "approaching">> <<set _navState = "ls_approach">> <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "leaving">> <<set _navState = "ls_leaving">> <<elseif $largeScene && typeof $largeScene === "object" && $largeScene.state === "active">> <<if $worldScene && $worldScene.state === "inside">> <<set _navState = "ls_zone">> <<elseif $worldScene && $worldScene.state === "approaching">> <<set _navState = "ls_zone_approach">> <<else>> <<set _navState = "ls_active">> <</if>> <<elseif $worldScene && $worldScene.state === "inside">> <<set _navState = "ws_only">> <<elseif $worldScene && $worldScene.state === "approaching">> <<set _navState = "ws_approach">> <<elseif $worldScene && $worldScene.state === "leaving">> <<set _navState = "ws_leaving">> <<elseif $activeLocations>> <<set _locApproaching = false>> <<set _locLeaving = false>> <<set _locArrived = false>> <<for _nli = 0; _nli < $activeLocations.length; _nli++>> <<if $activeLocations[_nli].state === "arrived">> <<set _locArrived = true>> <<set _locName = $activeLocations[_nli].name>> <<set _locScene = $activeLocations[_nli].scene>> <<break>> <<elseif $activeLocations[_nli].state === "approaching">> <<set _locApproaching = true>> <<set _locName = $activeLocations[_nli].name>> <<set _locHint = $activeLocations[_nli].approachHint>> <<set _locDepthWindow = $activeLocations[_nli].depthWindow>> <<set _locMapAt = $activeLocations[_nli].mapAt>> <<break>> <<elseif $activeLocations[_nli].state === "leaving">> <<set _locLeaving = true>> <<set _locName = $activeLocations[_nli].name>> <<set _locHint = $activeLocations[_nli].leaveHint>> <<break>> <</if>> <</for>> <<if _locArrived>> <<set _navState = "loc_arrived">> <<elseif _locApproaching>> <<set _navState = "loc_approach">> <<elseif _locLeaving>> <<set _navState = "loc_leaving">> <</if>> <</if>> <<if _navState !== "normal">> <div style="font-size:0.72rem;padding:0.18rem 0.4rem;margin-bottom:0.2rem;border-radius:2px;background:rgba(180,140,60,0.07);border:1px solid var(--amber-dim);"> <<if _navState === "ls_leaving">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--bone-dim);opacity:0.4;">←</span> <span style="color:var(--bone-dim);opacity:0.5;">已离开 <b style="color:var(--bone-dim);"><<print $largeScene.name>></b></span> </div> <<elseif _navState === "ls_approach">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--amber);opacity:0.8;">▷</span> <span style="color:var(--amber-dim);">正在接近 <b style="color:var(--amber);"><<print $largeScene.name>></b></span> </div> <<elseif _navState === "ls_active">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--amber);">◈</span> <span style="color:var(--bone-dim);">当前位于 <b style="color:var(--amber);"><<print $largeScene.name>></b></span> </div> /* zone 标签行 */ <div style="display:flex;gap:0.25rem;flex-wrap:wrap;margin-left:0.3rem;margin-top:0.1rem;"> <<for _lzui=0; _lzui<$largeScene.zones.length; _lzui++>> <<set _lzU=$largeScene.zones[_lzui]>><<set _lzSt=_lzU.st>> <<capture _lzU,_lzSt>> <<set _lzIsExp = (_lzSt==="arriving" && $largeScene.activeZone === _lzui && $worldScene && $worldScene.state === "inside")>> <<if _lzSt==="done">><span style="font-size:0.67rem;color:var(--bone-dim);border:1px solid var(--bone-dim);padding:0 0.18rem;border-radius:2px;opacity:0.45;">·<<print _lzU.name>></span> <<elseif _lzIsExp>><span style="font-size:0.67rem;color:var(--teal-bright);border:1px solid var(--teal-bright);padding:0 0.18rem;border-radius:2px;">◆<<print _lzU.name>></span> <<elseif _lzSt==="arriving">><span style="font-size:0.67rem;color:var(--bone);border:1px solid var(--bone);padding:0 0.18rem;border-radius:2px;">▸<<print _lzU.name>></span> <<else>><span style="font-size:0.67rem;color:var(--border-dim);border:1px solid var(--border-dim);padding:0 0.18rem;border-radius:2px;opacity:0.7;"><<print _lzU.name>></span><</if>> <</capture>> <</for>> </div> <<elseif _navState === "ls_zone" || _navState === "ls_zone_approach">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--amber);">◈</span> <span style="color:var(--bone-dim);"> 当前位于 <b style="color:var(--amber);"><<print $largeScene.name>></b> <span style="opacity:0.5;margin:0 0.2rem;">·</span> <b style="color:var(--teal-bright);"><<print $worldScene.name>></b> </span> </div> <<elseif _navState === "ws_only">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--teal-bright);">◈</span> <span style="color:var(--bone-dim);">当前位于 <b style="color:var(--teal-bright);"><<print $worldScene.name>></b></span> </div> <<elseif _navState === "ws_approach">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--amber-dim);">▷</span> <span style="color:var(--bone-dim);">正在接近 <b style="color:var(--amber);"><<print $worldScene.name>></b> <span style="opacity:0.6;font-size:0.69rem;"> <<print $worldScene.approachDesc>></span></span> </div> <<elseif _navState === "ws_leaving">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--bone-dim);opacity:0.4;">←</span> <span style="color:var(--bone-dim);opacity:0.5;">已离开 <b style="color:var(--bone-dim);"><<print $worldScene.name>></b></span> </div> <<elseif _navState === "loc_arrived">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--teal-bright);">◈</span> <span style="color:var(--bone-dim);">已抵达 <b style="color:var(--teal-bright);"><<print _locName>></b> <span style="opacity:0.7;font-size:0.69rem;">锚定后可进入探索</span></span> </div> <<elseif _navState === "loc_approach">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--teal-dim);opacity:0.8;">▷</span> <span style="color:var(--bone-dim);">雷达探测到信号——正在接近 <b style="color:var(--teal-bright);"><<print _locName>></b></span> </div> <<if _locHint>> <div style="color:var(--teal-dim);font-size:0.68rem;margin-left:0.5rem;margin-top:0.05rem;opacity:0.8;">「<<print _locHint>>」</div> <</if>> /* 深度不匹配引导:approaching 且 $map >= mapAt(位置到了但深度不对) */ <<if _locMapAt && $map >= _locMapAt>> <<set _dw = _locDepthWindow>> <<set _depthOk = false>> <<if _dw === "surface">> <<if $depth <= 5>><<set _depthOk = true>><</if>> <<elseif _dw === "seabed">> <<if $depthdeep - $depth <= 10>><<set _depthOk = true>><</if>> <<elseif typeof _dw === "object" && _dw.mid>> <<set _tol = _dw.tolerance || 30>> <<if Math.abs($depth - _dw.mid) <= _tol>><<set _depthOk = true>><</if>> <<else>> <<set _depthOk = true>> <</if>> <<if !_depthOk>> <<set _depthGuide = "">> <<if _dw === "surface">> <<set _depthGuide = "信号在海面附近,需要上浮至表层">> <<elseif _dw === "seabed">> <<set _depthGuide = "信号在海底附近,需要下潜至贴底">> <<elseif typeof _dw === "object" && _dw.mid>> <<if $depth < _dw.mid - (_dw.tolerance || 30)>> <<set _depthGuide = "前方更深处有「" + _locName + "」的痕迹,需继续下潜约" + Math.floor(_dw.mid - $depth) + "m">> <<elseif $depth > _dw.mid + (_dw.tolerance || 30)>> <<set _depthGuide = "前方更浅处有「" + _locName + "」的痕迹,需上浮约" + Math.floor($depth - _dw.mid) + "m">> <</if>> <</if>> <<if _depthGuide !== "">> <div style="color:var(--amber-bright);font-size:0.68rem;margin-left:0.5rem;margin-top:0.03rem;">⚠ <<print _depthGuide>></div> <</if>> <</if>> <</if>> <<elseif _navState === "loc_leaving">> <div style="display:flex;align-items:center;gap:0.3rem;"> <span style="color:var(--bone-dim);opacity:0.4;">←</span> <span style="color:var(--bone-dim);opacity:0.5;">已离开 <b style="color:var(--bone-dim);"><<print _locName>></b></span> </div> <<if _locHint>> <div style="color:var(--bone-dim);font-size:0.68rem;margin-left:0.5rem;margin-top:0.05rem;opacity:0.6;">「<<print _locHint>>」</div> <</if>> <</if>> </div> <</if>> /* ════════════════════════════════════════════════ 3. 地形 + 坐标 ════════════════════════════════════════════════ */ <div style="font-size:0.73rem;color:var(--bone-dim);margin-bottom:0.2rem;"> 地形:$mapinfo[$maptype].type · 坐标:$mapspan / $maplimspan </div> /* ════════════════════════════════════════════════ 4. 当前深度 + 海底深度 ════════════════════════════════════════════════ */ <div style="font-size:0.73rem;color:var(--bone-dim);margin-bottom:0.2rem;"> 当前深度:<span style="color:var(--amber-bright);"><<print $depth>> m</span> · 海底深度:<<print $depthdeep>> m </div> /* ════════════════════════════════════════════════ 5. 燃料 ════════════════════════════════════════════════ */ <<set _fPct = Math.max(0,Math.min(100,Math.floor(($fuel||0)/$fuelMax*100)))>> <<set _fCol = _fPct > 40 ? "var(--teal-bright)" : _fPct > 15 ? "var(--amber)" : "var(--danger-bright)">> <div style="display:flex;align-items:center;gap:0.35rem;font-size:0.68rem;color:var(--bone-dim);margin-bottom:0.25rem;"> <span>⛽ 燃料</span> <div style="flex:1;height:3px;background:var(--bg-panel);border:1px solid var(--border-dim);border-radius:2px;"><div style="height:100%;width:<<print _fPct>>%;background:<<print _fCol>>;transition:width 0.5s;"></div></div> <span style="color:<<print _fCol>>;"><<print Math.floor($fuel||0)>>/<<print $fuelMax>></span> </div> /* ════════════════════════════════════════════════ 6. 操作面板 ════════════════════════════════════════════════ */ /* ── 漂流警告 ── */ <<if $driftMode>> <div style="border:2px solid var(--danger-bright);padding:0.3rem 0.5rem;margin-bottom:0.25rem;font-size:0.8rem;color:var(--danger-bright);background:rgba(180,30,30,0.08);border-radius:3px;"> ‼ 燃料耗尽,引擎停转。 <span style="font-size:0.72rem;opacity:0.8;display:block;margin-top:0.06rem;">下潜已禁用。可前往供能室补充燃料后恢复航行。</span> </div> <</if>> /* ── 深度/速度/航向 ── */ <div style="font-size:0.82rem;margin-bottom:0.25rem;"> /* 上浮:漂流时也可用 */ <<if $depth > -1>><<link "上浮">><<set $depth -= 1>><</link>><<else>><span style="opacity:0.35;">上浮</span><</if>> · <span style="color:var(--amber-bright);">$depth m</span> · <<if !$driftMode && $depth < $depthdeep>><<link "下潜">><<set $depth += 1>><</link>><<elseif $driftMode>><span style="opacity:0.25;text-decoration:line-through;">下潜</span><<else>><span style="opacity:0.35;">下潜</span><</if>> <br> <<if $sailspd > 0>><<link "减速">><<set $sailspd = Math.max($sailspd-5, 0)>><</link>><<else>><span style="opacity:0.35;">减速</span><</if>> · <span style="color:var(--amber-bright);">×$sailspd</span> · <<if $sailspd < $spdmax>><<link "加速">><<set $sailspd = Math.min($sailspd+5, $spdmax)>><</link>><<else>><span style="opacity:0.35;">加速</span><</if>> <br> 航向: <<if $nav.slopeDir === "natural">><span style="color:var(--amber-bright);">▶自然</span><<else>><<link "自然">><<set $nav.slopeDir = "natural">><</link>><</if>> · <<if $nav.slopeDir === "downhill">><span style="color:var(--amber-bright);">▶下潜倾向</span><<else>><<link "下潜倾向">><<set $nav.slopeDir = "downhill">><</link>><</if>> · <<if $nav.slopeDir === "uphill">><span style="color:var(--amber-bright);">▶上潜倾向</span><<else>><<link "上潜倾向">><<set $nav.slopeDir = "uphill">><</link>><</if>> <span style="font-size:0.66rem;color:var(--bone-dim);opacity:0.5;"><<if $autoBrake>><span style="color:var(--teal-bright);">◆自动刹车</span><<else>><<link "◇自动刹车">><<set $autoBrake = true>><</link>><</if>></span> </div> /* ── 雷达:转向选择 ── */ <<if $nextAreasReady === 1>> <div style="border-left:2px solid var(--amber-dim);padding:0.25rem 0.5rem;margin-bottom:0.3rem;font-size:0.78rem;"> <div style="color:var(--amber-bright);margin-bottom:0.15rem;">雷达:前方$mapinfo[$maptype].type边缘在即</div> <<set _btnLabels = []>> <<for _nai = 0; _nai < $nextAreas.length; _nai++>> <<set _na = $nextAreas[_nai]>> <<set _btnLabels[_nai] = _na.dir + ":" + _na.label + "(" + _na.depth + "m)">> <</for>> <<for _nai = 0; _nai < $nextAreas.length; _nai++>> <<set _bl = _btnLabels[_nai]>> <<capture _nai, _bl>> <div style="line-height:1.7;"><<if $selectedNextArea === _nai>><span style="color:var(--amber-bright);">▶ <<print _bl>></span><<else>><<link _bl>><<set $selectedNextArea = _nai>><</link>><</if>></div> <</capture>> <</for>> <<if $prevArea !== null>> <<set _retLabel = "返回:" + ($mapinfo[$prevArea.type] ? $mapinfo[$prevArea.type].type : $prevArea.type)>> <div style="border-top:1px solid var(--border-dim);margin-top:0.1rem;padding-top:0.1rem;line-height:1.7;"> <<if $selectedNextArea === -1>><span style="color:var(--teal-bright);">▶ <<print _retLabel>></span><<else>><<link _retLabel>><<set $selectedNextArea = -1>><</link>><</if>> </div> <</if>> </div> <</if>> /* ── 渔具 ── */ <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.3rem;"> <<if $fishing == 0>><<link "投渔具">><<set $fishing = 1>><</link>><<else>><<link "收渔具">><<set $fishing = 0>><</link>><</if>> · <<if $fishingLight == "关闭">><<link "开灯">><<set $fishingLight = "开启">><</link>><<else>><<link "关灯">><<set $fishingLight = "关闭">><</link>><</if>> · <<link $fishingGear>><<if $fishingGear == "垂钓">><<set $fishingGear = "渔网">><<else>><<set $fishingGear = "垂钓">><</if>><</link>> · <<link $fishingBait>><<if $fishingBait == "内脏碎肉">><<set $fishingBait = "血饵">><<elseif $fishingBait == "血饵">><<set $fishingBait = "草饵">><<else>><<set $fishingBait = "内脏碎肉">><</if>><</link>> </div> /* ── 锚定按钮(中型场景inside时附加提示) ── */ <<if $worldScene && $worldScene.state === "inside">> <div style="font-size:0.73rem;color:var(--bone-dim);margin-bottom:0.1rem;">场景内有 <<print $worldScene.children.length>> 个可互动点 · 锚定后进入</div> <</if>> <div style="font-size:0.76rem;margin-bottom:0.4rem;"><<link "⚓ 锚定,切换探索模式">><<set $sailMode = "explore">><<set $sailspd = 0>><<set $lastSmallEventText = "">><<set $currentContext = "anchored">><<goto "探索">><</link>></div> /* ── 书签 ── */ <div style="font-size:0.74rem;margin-top:0.2rem;"> <<set _bmLabel = $showBookmarks ? "▾ 航行记录" : "▸ 航行记录">><<link _bmLabel>><<set $showBookmarks = !$showBookmarks>><</link>> <<if $showBookmarks>><div style="margin-top:0.2rem;max-height:10rem;overflow-y:auto;"><<bookmarkPanel>></div><</if>> </div> <<cpScene "驾驶舱">> /* ── 终止航行 ── */ <div style="margin-top:0.3rem;">[[终止航行|驾驶舱][$sailspd to 0]]</div> <<if $devMode>> <<if !$largeDefs>><<largeSceneDefs>><</if>> <<if !$wsDefs>><<worldSceneDefs>><</if>> <<if !$smallEventDefs>><<smallEventTable>><</if>> <<if !$microEventDefs>><<microEventTable>><</if>> <<if !$npcDefTable>><<npcDefs>><</if>> <<if !$locationDefTable>><<locationDefs>><</if>> <div style="margin-top:0.5rem;border:1px dashed #555;border-radius:3px;padding:0.35rem 0.55rem;font-size:0.72rem;color:#888;"> <div style="color:var(--amber-bright);font-size:0.78rem;letter-spacing:0.08em;">🛰 DEV · 地图 / 事件调试台</div> <div style="font-size:0.65rem;color:#666;margin-bottom:0.25rem;">按《地图系统_迁移规范》A/B/C 分级 · 数据驱动,新增定义自动出现</div> <<if $devMsg>> <div style="font-size:0.7rem;color:var(--amber);background:rgba(200,160,80,0.08);padding:0.18rem 0.45rem;border-radius:3px;margin-bottom:0.28rem;">▸ <<print $devMsg>></div> <</if>> /* ══════════ 0. 场景状态明细 ══════════ */ <div style="font-size:0.69rem;color:#888;line-height:1.7;border-left:2px solid var(--teal);padding-left:0.45rem;margin-bottom:0.3rem;"> 大型 <<if $largeScene && typeof $largeScene === "object">><span style="color:var(--amber-bright);"><<print $largeScene.name>></span> · <<print $largeScene.state>> <span style="color:#555;">[预<<print $largeScene.approachStart>>/接<<print $largeScene.approachEnd>>/活<<print $largeScene.activeEnd>>/离<<print $largeScene.leaveEnd>>]</span><br> <<for _dvi = 0; _dvi < $largeScene.zones.length; _dvi++>><<set _dvz = $largeScene.zones[_dvi]>><<if _dvz.st === "done">><span style="color:#666;">✔ <<print _dvz.name>></span><<elseif _dvz.st === "arriving">><span style="color:var(--amber-bright);">◆ <<print _dvz.name>></span><<else>><span style="color:#888;">○ <<print _dvz.name>></span><</if>><span style="color:#555;">(@<<print _dvz.zoneAt>>·<<print _dvz.wsType>>)</span> <</for>><br> <<else>><span style="color:#666;">无</span><br><</if>> 中型 <<if $worldScene>><span style="color:var(--teal-bright);"><<print $worldScene.name>></span> · <<print $worldScene.state>> · 房间×<<print $worldScene.children ? $worldScene.children.length : 0>><<else>><span style="color:#666;">无</span><</if>><br> 小型 <<if $activeSmallEvent>><span style="color:#b8a;"><<print $activeSmallEvent.name>></span><<else>><span style="color:#666;">无</span><</if>> · 微 <<if $activeMicroEvent>><span style="color:#8ac;"><<print $activeMicroEvent.name>></span><<else>><span style="color:#666;">无</span><</if>><br> 遭遇距离 <span style="color:var(--teal-bright);"><<print Math.floor(Number($eventDistance) || 0)>></span> / <<print Number($eventDistanceThreshold) || 4000>> · 冷却剩余 <span style="color:var(--amber);"><<print Math.floor(Number($eventDistanceCooldown) || 0)>></span> </div> /* ══════════ 1. 地形切换 ══════════ */ <div style="color:#8ca;margin:0.3rem 0 0.1rem;">① 地形切换(同步调整海底深度 / 限速)</div> <div style="font-size:0.72rem;line-height:1.85;"> <<set _tKeys = Object.keys($mapinfo)>> <<for _ti = 0; _ti < _tKeys.length; _ti++>> <<set _tk = _tKeys[_ti]>> <<capture _tk>> <<if $maptype === _tk>><span style="color:var(--teal-bright);">[<<print $mapinfo[_tk].type>>]</span><<else>><<link $mapinfo[_tk].type>><<devSetTerrain _tk>><</link>><</if>> <</capture>> <<if _ti < _tKeys.length - 1>><span style="color:#444;"> · </span><</if>> <</for>> </div> /* ══════════ 2. A 类:大型区域 ══════════ */ <div style="color:#ca8;margin:0.35rem 0 0.1rem;">② A 类 · 大型区域(以当前里程为起点,zone 按真实规则随机选)</div> <div style="font-size:0.72rem;line-height:1.9;"> <<set _lKeys = Object.keys($largeDefs)>> <<for _li = 0; _li < _lKeys.length; _li++>> <<set _lk = _lKeys[_li]>> <<set _ld = $largeDefs[_lk]>> <<capture _lk, _ld>> <<link "▶ " + _ld.name>><<devForceLarge _lk>><</link>><span style="color:#555;font-size:0.64rem;">(<<print _ld.zoneList.length>>z/<<print _ld.minZones>>-<<print _ld.maxZones>>)</span> <</capture>> <<if _li < _lKeys.length - 1>><span style="color:#444;"> · </span><</if>> <</for>> </div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "⏩ 推进到 active">> <<if $largeScene && $largeScene.state === "approaching">> <<set $map = $largeScene.approachEnd + 50>><<set $largeScene.state = "active">> <<set $devMsg = "已推进到 active">> <<else>><<set $devMsg = "⚠ 当前无 approaching 状态的大型区域">><</if>> <</link>> · <<link "⏩ 跳到下一个 zone">> <<if $largeScene && $largeScene.zones>> <<set _nz = -1>> <<for _nzi = 0; _nzi < $largeScene.zones.length; _nzi++>> <<if $largeScene.zones[_nzi].st === "pending" && _nz < 0>><<set _nz = _nzi>><</if>> <</for>> <<if _nz >= 0>> <<set $map = $largeScene.zones[_nz].zoneAt>> <<if $largeScene.state === "approaching">><<set $largeScene.state = "active">><</if>> <<set $devMsg = "已跳到 zone:" + $largeScene.zones[_nz].name>> <<else>><<set $devMsg = "⚠ 没有待触发的 zone 了">><</if>> <<else>><<set $devMsg = "⚠ 当前无大型区域">><</if>> <</link>> · <<link "⏩ 推进到 leaving">> <<if $largeScene>><<set $map = $largeScene.activeEnd + 50>><<set $largeScene.state = "leaving">> <<set $devMsg = "已推进到 leaving">><</if>> <</link>> · <<link "✕ 清除大型">><<set $largeScene = 0>><<set $devMsg = "已清除大型区域">><</link>> </div> /* ══════════ 3. 中型场景 · zone_only ══════════ */ <div style="color:#8ac;margin:0.35rem 0 0.1rem;">③ 中型 · zone_only(大型区域专属,点击直接 inside)</div> <div style="font-size:0.71rem;line-height:1.9;"> <<set _wKeys = Object.keys($wsDefs)>> <<set _wZFirst = true>> <<for _wi = 0; _wi < _wKeys.length; _wi++>> <<set _wk = _wKeys[_wi]>> <<set _wd = $wsDefs[_wk]>> <<if _wd.modes === "zone_only">> <<if !_wZFirst>><span style="color:#444;"> · </span><</if>><<set _wZFirst = false>> <<capture _wk, _wd>><<link _wd.name>><<devForceWs _wk "inside">><</link>><</capture>> <</if>> <</for>> </div> /* ══════════ 4. 中型场景 · ABC 插入式 ══════════ */ <div style="color:#8ac;margin:0.35rem 0 0.1rem;">④ 中型 · ABC 插入式(按 tier 调度;可在大型区域内作为变体出现)</div> <div style="font-size:0.71rem;line-height:1.9;"> <<set _wIFirst = true>> <<for _wi = 0; _wi < _wKeys.length; _wi++>> <<set _wk = _wKeys[_wi]>> <<set _wd = $wsDefs[_wk]>> <<if _wd.modes === "independent" || _wd.modes === "both" || _wd.modes === "tier_only">> <<if !_wIFirst>><span style="color:#444;"> · </span><</if>><<set _wIFirst = false>> <<set _wTerOk = (!_wd.terrain || _wd.terrain.length === 0)>> <<for _wti = 0; _wti < (_wd.terrain ? _wd.terrain.length : 0); _wti++>> <<if _wd.terrain[_wti] === $maptype>><<set _wTerOk = true>><</if>> <</for>> <<capture _wk, _wd, _wTerOk>> <<link _wd.name>><<devForceWs _wk "approaching">><</link>><<if !_wTerOk>><span style="color:#744;font-size:0.62rem;">✕地形</span><</if>> <</capture>> <</if>> <</for>> </div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "⏩ 中型转 inside">> <<if $worldScene>><<set $worldScene.state = "inside">><<set $map = $worldScene.mapStart>><<set $devMsg = "中型已转 inside">><</if>> <</link>> · <<link "✕ 清除中型">><<set $worldScene = null>><<set $wsChild = null>><<set $devMsg = "已清除中型场景">><</link>> </div> /* ══════════ 5. ABC 小型事件 ══════════ */ <div style="color:#b8a;margin:0.35rem 0 0.1rem;">⑤ ABC · 小型事件(DEV 按层级比例抽取;B 类占位池已接入)</div> <div style="font-size:0.71rem;line-height:1.9;"> <<set _sKeys = Object.keys($smallEventDefs)>> <<for _sei = 0; _sei < _sKeys.length; _sei++>> <<set _sk = _sKeys[_sei]>> <<set _sd = $smallEventDefs[_sk]>> <<capture _sk, _sd>> <<link _sd.name>><<devForceSmall _sk>><</link>><<if _sd.type === "fixed">><span style="color:#666;font-size:0.62rem;">·定点</span><</if>> <</capture>> <<if _sei < _sKeys.length - 1>><span style="color:#444;"> · </span><</if>> <</for>> </div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "🎲 强制随机小型(按权重)">><<devRandomSmall "sailing">><</link>> · <<link "✕ 清除小型">><<set $activeSmallEvent = null>><<set $devMsg = "已清除小型事件">><</link>> </div> /* ══════════ 6. 微事件 ══════════ */ <div style="color:#8cc;margin:0.35rem 0 0.1rem;">⑥ 微事件(瞬时,无状态机 · 共 <<print Object.keys($microEventDefs).length>> 条)</div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "🎲 强制随机微事件(按权重)">><<set $activeMicroEvent = null>><<devRandomMicro>><</link>> · <<link "✕ 清除微">><<set $activeMicroEvent = null>><</link>> </div> <div style="font-size:0.72rem;line-height:1.85;margin-top:0.15rem;"> <<link "▤ 展示当前全事件池(含变体)">><<devShowEventPool>><</link>> · <<link "🎲 总池随机遭遇(B:C=1:1)">><<devRandomTotal>><</link>> </div> <<if $devEventPoolOverview>> <div style="margin-top:0.2rem;border:1px solid #444;padding:0.3rem 0.45rem;color:#aaa;font-size:0.68rem;line-height:1.75;"> <div style="color:var(--teal-bright);">当前全事件池 · <<print $devEventPoolOverview.terrain>> · 深度 <<print $devEventPoolOverview.depth>>/<<print $devEventPoolOverview.seabed>>m · 共 <<print $devEventPoolOverview.items.length>> 条</div> <<if $devEventPoolOverview.region>><div style="color:#777;">当前大型区域:<<print $devEventPoolOverview.region>></div><</if>> <<if $devEventPoolOverview.items.length > 0>> <<for _dpoi = 0; _dpoi < $devEventPoolOverview.items.length; _dpoi++>> <<set _dpoIt = $devEventPoolOverview.items[_dpoi]>> <<set _dpoTierColor = _dpoIt.tier === "B" ? "var(--amber)" : "var(--teal-bright)">> <div><span style="color:<<print _dpoTierColor>>;">[<<print _dpoIt.tier>>]</span> <<print _dpoIt.name>> <span style="color:#888;">权重 <<print _dpoIt.weight>><<if _dpoIt.currentWeight !== _dpoIt.weight>> → 当前 <<print _dpoIt.currentWeight>><</if>></span> <<if _dpoIt.variants && _dpoIt.variants.length > 0>><div style="margin-left:1.4rem;color:#777;">变体:<<print _dpoIt.variants.join(" / ")>></div><</if>> </div> <</for>> <<else>><div style="color:var(--danger-bright);">当前条件下没有可用事件。</div><</if>> </div> <</if>> /* ══════════ 7. 航行辅助 ══════════ */ <div style="color:#aaa;margin:0.35rem 0 0.1rem;">⑦ 航行辅助</div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "停止">><<set $sailspd = 0>><</link>> · <<link "全速">><<set $spdmax = 500>><<set $sailspd = 500>><</link>> · <<link "满燃料">><<set $fuel = $fuelMax>><<set $driftMode = false>><<set $devMsg = "燃料已满">><</link>> · <<link "里程归零">><<set $map = 0>><<set $devMsg = "里程归零">><</link>> · <<link "里程 +5000">><<set $map = Math.min($maplim - 10, $map + 5000)>><</link>> · <<link "贴海底">><<set $depth = $depthdeep>><</link>> · <<link "上浮水面">><<set $depth = 0>><</link>> · <<link "安定值满">><<set $san = 100>><</link>> · <<link "安定值 30">><<set $san = 30>><</link>> </div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "强制区域过渡">><<set $map = $maplim - 10>><<set $nextAreasReady = 0>><<set $devMsg = "已推到区域末端">><</link>> · <<link "重置倾向">><<set $nav.slopeDir = "natural">><</link>> · <<link "💠珍珠+5">><<additem "pearl" 5>><</link>> · <<link "♻ 重置全部场景">><<set $largeScene = 0>><<set $worldScene = null>><<set $wsChild = null>><<set $activeSmallEvent = null>><<set $activeMicroEvent = null>><<set $activeEvent = 0>><<set $devMsg = "全部场景已重置">><</link>> </div> /* ══════════ 8. NPC(数据驱动) ══════════ */ <div style="color:#8cc;margin:0.35rem 0 0.1rem;">⑧ NPC</div> <div style="font-size:0.71rem;line-height:1.9;"> <<set _nKeys = Object.keys($npcDefTable)>> <<for _ni = 0; _ni < _nKeys.length; _ni++>> <<set _nk = _nKeys[_ni]>> <<set _nd = $npcDefTable[_nk]>> <<capture _nk, _nd>> <<link _nd.name>><<set $activeNpc = $npcDefTable[_nk]>><<set $npcReturn = "航行">><<goto "NPC_对话">><</link>> <</capture>> <span style="color:#444;"> · </span> <</for>> <<link "✕清除NPC">><<set $activeNpc = null>><</link>> </div> /* ══════════ 9. 任务 ══════════ */ <div style="color:#aaf;margin:0.35rem 0 0.1rem;">⑨ 任务</div> <div style="font-size:0.72rem;line-height:1.85;"> <<if !$questChain>><<questDefs>><</if>> <<link "▶ 触发主线">><<if $questProgress < $questChain.length>><<run $questLog.push({id:$questChain[$questProgress].id,title:$questChain[$questProgress].title,text:$questChain[$questProgress].logEntry,day:$day||0,type:"main"})>><<set $questNotify="✦ 日记已更新:"+$questChain[$questProgress].title>><<set $questProgress=$questProgress+1>><<else>><<set $devMsg="⚠ 主线已到末尾">><</if>><</link>> <span style="color:#aaf;font-size:0.66rem;">[<<print $questProgress>>/<<print $questChain.length>>]</span> · <<link "重置主线">><<set $questProgress=0>><<set $questLog=[]>><<set $questNotify="">><<set $devMsg="主线已重置">><</link>> </div> /* ══════════ 10. 导航 / 地点 ══════════ */ <div style="color:#8ca;margin:0.35rem 0 0.1rem;">⑩ 导航 / 地点 <span style="color:#666;font-size:0.64rem;">[<<if $activeLocations>><<print $activeLocations.length>><<else>>0<</if>> 个]</span></div> <div style="font-size:0.72rem;line-height:1.85;"> <<link "接近最近地点">> <<if $activeLocations && $activeLocations.length > 0>> <<set _nearestMapAt = 999999>> <<set _nearestRange = 800>> <<for _ali = 0; _ali < $activeLocations.length; _ali++>> <<set _aloc = $activeLocations[_ali]>> <<if _aloc.state !== "done" && _aloc.mapAt < _nearestMapAt>> <<set _nearestMapAt = _aloc.mapAt>> <<set _nearestRange = _aloc.approachRange || 300>> <</if>> <</for>> <<if _nearestMapAt < 999999>> <<set $map = Math.max(0, _nearestMapAt - _nearestRange - 50)>> <</if>> <</if>> <</link>> · <<link "直接到达">> <<if $activeLocations && $activeLocations.length > 0>> <<set _nearestMapAt = 999999>> <<for _ali = 0; _ali < $activeLocations.length; _ali++>> <<set _aloc = $activeLocations[_ali]>> <<if _aloc.state !== "done" && _aloc.state !== "arrived" && _aloc.mapAt < _nearestMapAt>> <<set _nearestMapAt = _aloc.mapAt>> <</if>> <</for>> <<if _nearestMapAt < 999999>> <<set $map = _nearestMapAt>> <</if>> <</if>> <</link>> · <<link "贴合深度窗">> <<if $activeLocations && $activeLocations.length > 0>> <<for _ali = 0; _ali < $activeLocations.length; _ali++>> <<set _aloc = $activeLocations[_ali]>> <<if !_aloc.triggered>> <<if _aloc.depthWindow === "surface">> <<set $depth = 0>> <<elseif _aloc.depthWindow === "seabed">> <<set $depth = $depthdeep>> <<elseif typeof _aloc.depthWindow === "object" && _aloc.depthWindow.mid>> <<set $depth = _aloc.depthWindow.mid>> <</if>> <<break>> <</if>> <</for>> <</if>> <</link>> · <<link "清除地点">><<set $activeLocations = []>><<set $devMsg = "地点已清空">><</link>> · <<link "重灌地点">> <<set $activeLocations = []>> <<set _locPool = $locationDefTable[$maptype]>> <<if _locPool && _locPool.length > 0>> <<set _locCount = 1 + Math.floor(Math.random() * Math.min(3, _locPool.length))>> <<set _locPicked = []>> <<for _locI = 0; _locI < _locPool.length; _locI++>><<set _locPicked[_locI] = _locI>><</for>> <<for _locI = _locPicked.length - 1; _locI > 0; _locI-->> <<set _locJ = Math.floor(Math.random() * (_locI + 1))>> <<set _locTmp = _locPicked[_locI]>> <<set _locPicked[_locI] = _locPicked[_locJ]>> <<set _locPicked[_locJ] = _locTmp>> <</for>> <<for _locI = 0; _locI < _locCount && _locI < _locPicked.length; _locI++>> <<set _locDef = _locPool[_locPicked[_locI]]>> <<set _locRange = _locDef.approachRange || 300>> <<set _locMapAt = 0>> <<for _locTry = 0; _locTry < 20; _locTry++>> <<set _locCandidate = 1000 + Math.floor(Math.random() * Math.max(1, $maplim - 2000))>> <<set _locOK = true>> <<for _locCheckI = 0; _locCheckI < $activeLocations.length; _locCheckI++>> <<set _locExistRange = $activeLocations[_locCheckI].approachRange || 300>> <<set _locNeedGap = _locRange + _locExistRange + 500>> <<if Math.abs(_locCandidate - $activeLocations[_locCheckI].mapAt) < _locNeedGap>> <<set _locOK = false>> <<break>> <</if>> <</for>> <<if _locOK>> <<set _locMapAt = _locCandidate>> <<break>> <</if>> <</for>> <<if _locMapAt === 0>> <<set _locMapAt = 1000 + Math.floor(Math.random() * Math.max(1, $maplim - 2000))>> <</if>> <<set $activeLocations[$activeLocations.length] = { id: _locDef.id, name: _locDef.name, mapAt: _locMapAt, depthWindow: _locDef.depthWindow, scene: _locDef.scene, approachHint: _locDef.approachHint || "前方探测到异常信号。", arriveHint: _locDef.arriveHint || "", leaveHint: _locDef.leaveHint || "信号在身后消失。", approachRange: _locDef.approachRange || 300, spanLength: _locDef.spanLength || 400, gotoScene: _locDef.gotoScene || "", state: "distant", triggered: false, warned: false }>> <</for>> <<set $devMsg = "已重灌地点 ×" + $activeLocations.length>> <<else>><<set $devMsg = "⚠ 当前地形无地点池">><</if>> <</link>> · <<link "✕ 清空提示">><<set $devMsg = "">><</link>> </div> </div> <</if>> <</replace>> <</repeat>> <<link "⚡DEV">><<if $devMode>><<set $devMode = false>><<else>><<set $devMode = true>><</if>><</link>> <</nobr>>
<<nobr>> <<if !$selectShipUpgrade>> <div style="font-size:0.88rem;color:var(--amber-bright);margin-bottom:0.5rem;">升级系统</div> <div style="font-size:0.8rem;color:var(--bone-dim);">未选择升级项目。</div> <<else>> <<set _upg_defs = { speed: { name:"航速推进", desc:"提升引擎推力,增加最高航速上限。", mats:[ ["metal",3],["gears",2],["coal",2] ] }, armor: { name:"装甲加固", desc:"强化船体外壳,增强耐久与抗压能力。", mats:[ ["metal",5],["fish_scale",3] ] }, insulation:{ name:"隔热层", desc:"减少深海环境对燃料消耗的影响。", mats:[ ["glass",2],["fish_organ",2],["ruber",2] ] }, capacity: { name:"仓储扩容", desc:"增加船内存储空间。", mats:[ ["wood",4],["metal",2],["gears",1] ] }, sonar: { name:"声呐升级", desc:"提升声呐探测范围与精度。", mats:[ ["gears",3],["glass",2],["fish_bone",2] ] } }>> <<set _ud = _upg_defs[$selectShipUpgrade]>> <<set _ulv = $shipUpgrades[$selectShipUpgrade] || 0>> <<if _ud>> <div style="font-size:0.88rem;color:var(--amber-bright);margin-bottom:0.4rem;"><<print _ud.name>></div> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.5rem;"><<print _ud.desc>></div> <div style="font-size:0.78rem;margin-bottom:0.3rem;"> 当前等级:<<for _lv=0;_lv<3;_lv++>><<print _lv < _ulv ? "◆" : "◇">><</for>> Lv.<<print _ulv>> </div> <<if _ulv >= 3>> <div style="font-size:0.8rem;color:var(--teal-bright);">已达最高等级。</div> <<else>> <div style="font-size:0.78rem;color:var(--bone-dim);margin-bottom:0.3rem;">升级所需材料:</div> <<for _mi=0; _mi < _ud.mats.length; _mi++>> <<set _mId = _ud.mats[_mi][0]>> <<set _mQty = _ud.mats[_mi][1]>> <<set _mDef = $items[_mId]>> <<set _mHave = 0>> <<finditem _mId "backpack">><<set _mHave += _found_qty>> <<finditem _mId "store">><<set _mHave += _found_qty>> <<set _mEnough = _mHave >= _mQty>> <div style="font-size:0.78rem;<<print _mEnough ? 'color:var(--teal-bright)' : 'color:var(--danger-bright)'>>;"> <<print _mDef ? _mDef.name : _mId>> ×<<print _mQty>>(持有:<<print _mHave>>) </div> <</for>> <div style="margin-top:0.5rem;"> <<link "确认升级">> <<set _canUpgrade = true>> <<for _cmi=0; _cmi < _ud.mats.length; _cmi++>> <<set _cmId = _ud.mats[_cmi][0]>> <<set _cmQty = _ud.mats[_cmi][1]>> <<set _cmHave = 0>> <<finditem _cmId "backpack">><<set _cmHave += _found_qty>> <<finditem _cmId "store">><<set _cmHave += _found_qty>> <<if _cmHave < _cmQty>><<set _canUpgrade = false>><</if>> <</for>> <<if _canUpgrade>> <<for _rmi=0; _rmi < _ud.mats.length; _rmi++>> <<set _rmId = _ud.mats[_rmi][0]>> <<set _rmQty = _ud.mats[_rmi][1]>> <<removeitem _rmId _rmQty "backpack">> <<removeitem _rmId _rmQty "store">> <</for>> <<set $shipUpgrades[$selectShipUpgrade] += 1>> <<else>> <<set $upgradeFailMsg = "材料不足,无法升级。">> <</if>> <<goto "船只升级详情">> <</link>> </div> <<if $upgradeFailMsg>><div style="color:var(--danger-bright);font-size:0.78rem;margin-top:0.3rem;"><<print $upgradeFailMsg>><<set $upgradeFailMsg = "">></div><</if>> <</if>> <<else>> <div style="font-size:0.8rem;color:var(--bone-dim);">未知升级项目。</div> <</if>> <</if>> <div style="margin-top:1rem;">[[← 返回载具|ship]]</div> <</nobr>>
描写子系统详情与维修操作(占位)。 [[← 返回载具|ship]]
<<cpRoomCheck "走廊">> <<nobr>> <div style="font-size:0.8rem;color:var(--bone-dim);line-height:1.7;margin:0.35rem 0 0.5rem;">透过舷窗——<<view>></div> <<if $worldScene>> <<if $worldScene.state === "approaching">><div style="font-size:0.72rem;color:var(--amber);margin-bottom:0.25rem;">⚠ <<print $worldScene.approachDesc>></div> <<elseif $worldScene.state === "inside">><div style="font-size:0.72rem;color:var(--amber-bright);margin-bottom:0.25rem;">◆ 正处于:<<print $worldScene.name>></div> <</if>> <</if>> <</nobr>> 一段对走廊的描述 <<cpScene "走廊">> 移动 [[驾驶舱]] | [[炼金室]] | [[浴室]] [[卧室]] | [[厨房]] | [[农场]] [[供能室]] | [[机械室]] | [[出舱]] <br><<set _devLabel = $devMode ? "关闭 DEV" : "开启 DEV">><<link _devLabel>><<set $devMode = !$devMode>><<goto "走廊">><</link>><<if $devMode>> [[CP DEV|CP DEV]]<</if>>
<<nobr>> <<if !$cookIngredients>><<set $cookIngredients = []>><</if>> /* 扫描背包中所有食材(type=食材,排除调料) */ <<set _cs_food = []>> <<set _cs_bpCats = Object.keys($backpack)>> <<for _cs_ci = 0; _cs_ci < _cs_bpCats.length; _cs_ci++>> <<set _cs_cat = _cs_bpCats[_cs_ci]>> <<set _cs_list = $backpack[_cs_cat]>> <<if Array.isArray(_cs_list)>> <<for _cs_i = 0; _cs_i < _cs_list.length; _cs_i++>> <<if _cs_list[_cs_i].quantity > 0>> <<set _cs_def = State.variables.items[_cs_list[_cs_i].id]>> <<if _cs_def && _cs_def.type === "食材" && _cs_def.foodtags && !_cs_def.foodtags.includes("调料")>> <<run _cs_food.push({ id: _cs_list[_cs_i].id, qty: _cs_list[_cs_i].quantity, name: _cs_def.name, tags: _cs_def.foodtags })>> <</if>> <</if>> <</for>> <</if>> <</for>> **烹饪方式:**<<print $cookMethod>> **已选食材(<<print $cookIngredients.length>>/3):** <<if $cookIngredients.length > 0>> <<for _si = 0; _si < $cookIngredients.length; _si++>> <<capture _si>> <<set _sid = $cookIngredients[_si]>> <<link "[ ✕ " + State.variables.items[_sid].name + " ]" "烹饪选材">> <<run State.variables.cookIngredients.splice(_si, 1)>> <</link>> <</capture>> <</for>> <<else>> (还未选择任何食材) <</if>> --- **可用食材:** <<if _cs_food.length === 0>> 背包里没有可用的食材。 <<else>> <<for _fi = 0; _fi < _cs_food.length; _fi++>> <<capture _fi, _cs_food>> <<set _fitem = _cs_food[_fi]>> <<set _fsel = $cookIngredients.includes(_fitem.id)>> <<if _fsel>> ●<<print _fitem.name>> ×<<print _fitem.qty>> _(已选)_ <<elseif $cookIngredients.length >= 3>> ○<<print _fitem.name>> ×<<print _fitem.qty>>(已选满3种) <<else>> <<link "○ " + _fitem.name + " ×" + _fitem.qty + " [+]" "烹饪选材">> <<run State.variables.cookIngredients.push(_fitem.id)>> <</link>> <</if>> <</capture>> <</for>> <</if>> --- <<if $cookIngredients.length > 0>> <<link "▶ 开始烹饪" "烹饪进行">> <<matchRecipe>> <<set $cookTimer = 0>> <</link>> <</if>> [[← 返回选方式|厨房]] <</nobr>>
描写镜中映像与角色状态反馈。 [[← 返回|浴室]]
<<cpRoomCheck "驾驶舱">> <<view>> 黄铜的操作台在你面前。 <<cpScene "驾驶舱">> <<link "开始">> <<goto "航行">> <</link>> [[返回|走廊]]
描写鱼缸养殖系统,可暂养活体渔获。 [[← 返回|农场]]