1// ââââââââââââââââââââââââââââââââââââââââââââââ 2// unlockableDefs.js â Content gating definitions 3// 4// Items NOT listed here â always in the base pool. 5// Items listed here â locked until condition met. 6// 7// Pools: joker | consumable | mutator | shop_variant 8// 9// BASE POOLS (always available, no unlock needed): 10// Jokers (6): piano_fingers, rubber_hands, tempo, 11// piggy_bank, rubber_soul, lucky_star 12// Consumables (5): time_freeze, key_insight, erase_strike, 13// emergency_fund, compass 14// Mutators (12): speedup, fragile, slow_mo, merciful, 15// quick_hold, double_points, generosity, 16// momentum, golden_floor, second_chance_mut, 17// warmup, tailwind 18// 19// 7 TIERS â gradual unlock across many runs: 20// T1 Primeros Pasos (runs 2-3) 9 items 21// T2 Aprendiz (runs 4-7) 12 items 22// T3 Competente (runs 7-12) 16 items 23// T4 Veterano (runs 12-20) 18 items 24// T5 Experto (runs 20-30) 22 items 25// T6 Maestro (runs 30-50) 22 items 26// T7 Exótico (runs 50+) 16 items 27// Total gated: 115 (45J + 30C + 38M + 2SV) 28// ââââââââââââââââââââââââââââââââââââââââââââââ 29 30import { t } from '../i18n.js'; 31 32/** @type {UnlockableDef[]} */ 33const UNLOCKABLE_DEFS = [ 34 35 // âââââââââââââââââââââââââââââââââââââââââââ 36 // TIER 1 â PRIMEROS PASOS (runs 2-3) 37 // First unlocks, rewarding early play 38 // âââââââââââââââââââââââââââââââââââââââââââ 39 40 // ââ Jokers T1 ââ 41 { id:"velocity", pool:"joker", 42 condition:(d)=>(d.totalRuns??0)>=2, 43 get hint(){ return t('unlock_hints.velocity_hint','Juega un par de runs...'); }, 44 get reason(){ return t('unlock_reasons.velocity','¡Velocidad desbloqueada! Speed bonus amplificado.'); } }, 45 46 { id:"slow_starter", pool:"joker", 47 condition:(d)=>(d.totalRounds??0)>=25, 48 get hint(){ return t('unlock_hints.slow_starter_hint','Supera varias rondas...'); }, 49 get reason(){ return t('unlock_reasons.slow_starter','¡Arranque Lento! Más tiempo en la primera ronda.'); } }, 50 51 { id:"penny_pincher", pool:"joker", 52 condition:(d)=>(d.totalCoins??0)>=150, 53 get hint(){ return t('unlock_hints.penny_pincher_hint','Gana algunas coins...'); }, 54 get reason(){ return t('unlock_reasons.penny_pincher','¡Tacaño desbloqueado! Rerolls más baratos.'); } }, 55 56 // ââ Consumables T1 ââ 57 { id:"coin_burst", pool:"consumable", 58 condition:(d)=>(d.totalFloors??0)>=8, 59 get hint(){ return t('unlock_hints.coin_burst_hint','Completa algunos pisos...'); }, 60 get reason(){ return t('unlock_reasons.coin_burst','¡Lluvia de Coins! Gana coins al instante.'); } }, 61 62 { id:"power_check", pool:"consumable", 63 condition:(d)=>(d.totalChecksPassed??0)>=50, 64 get hint(){ return t('unlock_hints.power_check_hint','Pasa tus primeros checks...'); }, 65 get reason(){ return t('unlock_reasons.power_check','¡Pulso Preciso! Ventana de check ampliada.'); } }, 66 67 { id:"anchor", pool:"consumable", 68 condition:(d)=>(d.records?.bestStreak??0)>=5&&(d.totalRuns??0)>=2, 69 get hint(){ return t('unlock_hints.anchor_hint','Consigue una pequeña racha...'); }, 70 get reason(){ return t('unlock_reasons.anchor','¡Ancla desbloqueada! Protege tu racha.'); } }, 71 72 // ââ Mutators T1 ââ 73 { id:"jackpot", pool:"mutator", 74 condition:(d)=>(d.totalPerfectRounds??0)>=6, 75 get hint(){ return t('unlock_hints.jackpot_hint','Logra rondas perfectas...'); }, 76 get reason(){ return t('unlock_reasons.jackpot','¡Jackpot! Perfectas pueden dar coins bonus.'); } }, 77 78 { id:"treasure_floor", pool:"mutator", 79 condition:(d)=>(d.totalRuns??0)>=3, 80 get hint(){ return t('unlock_hints.treasure_floor_hint','Juega algunas runs...'); }, 81 get reason(){ return t('unlock_reasons.treasure_floor','¡Piso del Tesoro! Cada ronda da coins.'); } }, 82 83 { id:"phantom", pool:"mutator", 84 condition:(d)=>(d.totalFloors??0)>=12, 85 get hint(){ return t('unlock_hints.phantom_hint','Completa más pisos...'); }, 86 get reason(){ return t('unlock_reasons.phantom','¡Fantasma! Aparecen teclas falsas.'); } }, 87 88 // âââââââââââââââââââââââââââââââââââââââââââ 89 // TIER 2 â APRENDIZ (runs 4-7) 90 // Expanding the toolkit 91 // âââââââââââââââââââââââââââââââââââââââââââ 92 93 // ââ Jokers T2 ââ 94 { id:"coin_magnet", pool:"joker", 95 condition:(d)=>(d.totalFloors??0)>=25, 96 get hint(){ return t('unlock_hints.coin_magnet_hint','Completa bastantes pisos...'); }, 97 get reason(){ return t('unlock_reasons.coin_magnet','¡Imán de Coins! +20% coins por ronda.'); } }, 98 99 { id:"lucky_dice", pool:"joker", 100 condition:(d)=>(d.totalCoins??0)>=400, 101 get hint(){ return t('unlock_hints.lucky_dice_hint','Acumula coins...'); }, 102 get reason(){ return t('unlock_reasons.lucky_dice','¡Dado de la Suerte! Chance de duplicar coins.'); } }, 103 104 { id:"pain_lover", pool:"joker", 105 condition:(d)=>(d.totalRuns??0)>=5, 106 get hint(){ return t('unlock_hints.pain_lover_hint','Persiste varias runs...'); }, 107 get reason(){ return t('unlock_reasons.pain_lover','¡Amante del Dolor! Bonus por dificultad alta.'); } }, 108 109 { id:"turbo", pool:"joker", 110 condition:(d)=>(d.totalChecksPassed??0)>=150, 111 get hint(){ return t('unlock_hints.turbo_hint','Pasa más checks...'); }, 112 get reason(){ return t('unlock_reasons.turbo','¡Turbo desbloqueado! Construye rápido para checks extra.'); } }, 113 114 // ââ Consumables T2 ââ 115 { id:"shield", pool:"consumable", 116 condition:(d)=>(d.totalRuns??0)>=4, 117 get hint(){ return t('unlock_hints.shield_hint','Juega más runs...'); }, 118 get reason(){ return t('unlock_reasons.shield','¡Escudo desbloqueado! Ignora un fallo.'); } }, 119 120 { id:"simplify", pool:"consumable", 121 condition:(d)=>(d.totalRounds??0)>=55, 122 get hint(){ return t('unlock_hints.simplify_hint','Supera muchas rondas...'); }, 123 get reason(){ return t('unlock_reasons.simplify','¡Simplificar! Quita una tecla del combo.'); } }, 124 125 { id:"double_next", pool:"consumable", 126 condition:(d)=>(d.records?.bestFloor??0)>=5, 127 get hint(){ return t('unlock_hints.double_next_hint','Alcanza cierto piso...'); }, 128 get reason(){ return t('unlock_reasons.double_next','¡Doble o Nada! Arriesga por puntos dobles.'); } }, 129 130 { id:"safety_bubble", pool:"consumable", 131 condition:(d)=>(d.totalStrikeRepairs??0)>=4, 132 get hint(){ return t('unlock_hints.safety_bubble_hint','Repara strikes...'); }, 133 get reason(){ return t('unlock_reasons.safety_bubble','¡Burbuja Segura! Absorbe checks fallidos.'); } }, 134 135 // ââ Mutators T2 ââ 136 { id:"fog", pool:"mutator", 137 condition:(d)=>(d.records?.bestFloor??0)>=6, 138 get hint(){ return t('unlock_hints.fog_hint','Avanza más pisos...'); }, 139 get reason(){ return t('unlock_reasons.fog','¡Niebla! Una tecla se oculta.'); } }, 140 141 { id:"mirror", pool:"mutator", 142 condition:(d)=>(d.totalFloors??0)>=35, 143 get hint(){ return t('unlock_hints.mirror_hint','Explora más pisos...'); }, 144 get reason(){ return t('unlock_reasons.mirror','¡Espejo! El teclado se inv
144ierte.'); } }, 145 146 { id:"sprint", pool:"mutator", 147 condition:(d)=>(d.totalRuns??0)>=6, 148 get hint(){ return t('unlock_hints.sprint_hint','Más experiencia...'); }, 149 get reason(){ return t('unlock_reasons.sprint','¡Sprint! Construye rápido o sufre penalización.'); } }, 150 151 { id:"iron_fingers", pool:"mutator", 152 condition:(d)=>(d.totalChecksPassed??0)>=180, 153 get hint(){ return t('unlock_hints.iron_fingers_hint','Pasa muchos checks...'); }, 154 get reason(){ return t('unlock_reasons.iron_fingers','¡Dedos de Hierro! Check window reducida.'); } }, 155 156 // âââââââââââââââââââââââââââââââââââââââââââ 157 // TIER 3 â COMPETENTE (runs 7-12) 158 // Unlocking real strategy options 159 // âââââââââââââââââââââââââââââââââââââââââââ 160 161 // ââ Jokers T3 ââ 162 { id:"hot_hand", pool:"joker", 163 condition:(d)=>(d.records?.bestStreak??0)>=10&&(d.totalRuns??0)>=7, 164 get hint(){ return t('unlock_hints.hot_hand_hint','Consigue una buena racha...'); }, 165 get reason(){ return t('unlock_reasons.hot_hand','¡Mano Caliente! Rachas largas mejoran tus checks.'); } }, 166 167 { id:"flash_typist", pool:"joker", 168 condition:(d)=>(d.records?.bestFloor??0)>=7, 169 get hint(){ return t('unlock_hints.flash_typist_hint','Pisos avanzados...'); }, 170 get reason(){ return t('unlock_reasons.flash_typist','¡Mecanógrafo Veloz! Construye rápido, gana más.'); } }, 171 172 { id:"streak_master", pool:"joker", 173 condition:(d)=>(d.records?.bestStreak??0)>=12, 174 get hint(){ return t('unlock_hints.streak_master_hint','Racha impresionante...'); }, 175 get reason(){ return t('unlock_reasons.streak_master','¡Maestro de Rachas desbloqueado!'); } }, 176 177 { id:"golden_touch", pool:"joker", 178 condition:(d)=>(d.totalFlawlessFloors??0)>=6, 179 get hint(){ return t('unlock_hints.golden_touch_hint','Completa pisos sin fallos...'); }, 180 get reason(){ return t('unlock_reasons.golden_touch','¡Toque Dorado! Bonus por pisos flawless.'); } }, 181 182 { id:"quicksilver", pool:"joker", 183 condition:(d)=>(d.totalCoins??0)>=600, 184 get hint(){ return t('unlock_hints.quicksilver_hint','Acumula riqueza...'); }, 185 get reason(){ return t('unlock_reasons.quicksilver','¡Mercurio! Velocidad genera coins.'); } }, 186 187 // ââ Consumables T3 ââ 188 { id:"echo", pool:"consumable", 189 condition:(d)=>(d.totalChecksPassed??0)>=280, 190 get hint(){ return t('unlock_hints.echo_hint','Pasa muchos checks...'); }, 191 get reason(){ return t('unlock_reasons.echo','¡Eco! Auto-pasa checks.'); } }, 192 193 { id:"slow_mo_potion", pool:"consumable", 194 condition:(d)=>(d.totalRounds??0)>=100, 195 get hint(){ return t('unlock_hints.slow_mo_potion_hint','Supera rondas y rondas...'); }, 196 get reason(){ return t('unlock_reasons.slow_mo_potion','¡Poción Lenta! +1.5 s durante 3 rondas.'); } }, 197 198 { id:"quick_fix", pool:"consumable", 199 condition:(d)=>(d.totalStrikeRepairs??0)>=7, 200 get hint(){ return t('unlock_hints.quick_fix_hint','Repara varios strikes...'); }, 201 get reason(){ return t('unlock_reasons.quick_fix','¡Parche Rápido! Cura + tiempo.'); } }, 202 203 { id:"score_surge", pool:"consumable", 204 condition:(d)=>d.bestRuns?.some(r=>r.score>=2500), 205 get hint(){ return t('unlock_hints.score_surge_hint','Buen score en una run...'); }, 206 get reason(){ return t('unlock_reasons.score_surge','¡Subidón! Puntos gratis.'); } }, 207 208 // ââ Mutators T3 ââ 209 { id:"no_extras", pool:"mutator", 210 condition:(d)=>(d.totalRuns??0)>=8, 211 get hint(){ return t('unlock_hints.no_extras_hint','Veterano de runs...'); }, 212 get reason(){ return t('unlock_reasons.no_extras','¡Sin Extras! Teclas extra = fallo.'); } }, 213 214 { id:"growing", pool:"mutator", 215 condition:(d)=>(d.totalRounds??0)>=110, 216 get hint(){ return t('unlock_hints.growing_hint','Muchas rondas superadas...'); }, 217 get reason(){ return t('unlock_reasons.growing','¡Creciente! Combos cada vez más grandes.'); } }, 218 219 { id:"pulse", pool:"mutator", 220 condition:(d)=>(d.totalFloors??0)>=55, 221 get hint(){ return t('unlock_hints.pulse_hint','Explora muchos pisos...'); }, 222 get reason(){ return t('unlock_reasons.pulse','¡Pulso! El timer se congela periódicamente.'); } }, 223 224 { id:"acceleration", pool:"mutator", 225 condition:(d)=>(d.totalFloors??0)>=70,
226 get hint(){ return t('unlock_hints.acceleration_hint','Pisos y más pisos...'); }, 227 get reason(){ return t('unlock_reasons.acceleration','¡Aceleración! El timer se acelera.'); } }, 228 229 { id:"blink", pool:"mutator", 230 condition:(d)=>(d.totalRuns??0)>=10, 231 get hint(){ return t('unlock_hints.blink_hint','Persiste jugando...'); }, 232 get reason(){ return t('unlock_reasons.blink','¡Parpadeo! El teclado visual parpadea.'); } }, 233 234 { id:"bonanza", pool:"mutator", 235 condition:(d)=>(d.totalItemsBought??0)>=16, 236 get hint(){ return t('unlock_hints.bonanza_hint','Compra items en la tienda...'); }, 237 get reason(){ return t('unlock_reasons.bonanza','¡Bonanza! Más puntos, pero tienda más cara.'); } }, 238 239 { id:"pain_plus", pool:"mutator", 240 condition:(d)=>(d.records?.bestFloor??0)>=8, 241 get hint(){ return t('unlock_hints.pain_plus_hint','Llega a pisos altos...'); }, 242 get reason(){ return t('unlock_reasons.pain_plus','¡Dolor+! Combos más difÃciles.'); } }, 243 244 // âââââââââââââââââââââââââââââââââââââââââââ 245 // TIER 4 â VETERANO (runs 12-20) 246 // Powerful items, deeper strategy 247 // âââââââââââââââââââââââââââââââââââââââââââ 248 249 // ââ Jokers T4 ââ 250 { id:"safety_net", pool:"joker", 251 condition:(d)=>(d.totalRuns??0)>=14, 252 get hint(){ return t('unlock_hints.safety_net_hint','Mucha experiencia...'); }, 253 get reason(){ return t('unlock_reasons.safety_net','¡Red de Seguridad! +1 strike máximo.'); } }, 254 255 { id:"unstoppable", pool:"joker", 256 condition:(d)=>(d.totalFloors??0)>=100, 257 get hint(){ return t('unlock_hints.unstoppable_hint','Completa muchos pisos...'); }, 258 get reason(){ return t('unlock_reasons.unstoppable','¡Imparable! Conserva parte de tu racha al fallar.'); } }, 259 260 { id:"virtuoso", pool:"joker", 261 condition:(d)=>(d.totalChecksPassed??0)>=500, 262 get hint(){ return t('unlock_hints.virtuoso_hint','Pasa cientos de checks...'); }, 263 get reason(){ return t('unlock_reasons.virtuoso','¡Dedo Virtuoso! Tus checks valen más.'); } }, 264 265 { id:"metronome_heart", pool:"joker", 266 condition:(d)=>(d.totalRounds??0)>=220, 267 get hint(){ return t('unlock_hints.metronome_heart_hint','Supera muchas rondas...'); }, 268 get reason(){ return t('unlock_reasons.metronome_heart','¡Corazón Metrónomo! Timer mÃnimo garantizado.'); } }, 269 270 { id:"fever", pool:"joker", 271 condition:(d)=>(d.records?.bestStreak??0)>=15, 272 get hint(){ return t('unlock_hints.fever_hint','Racha increÃble...'); }, 273 get reason(){ return t('unlock_reasons.fever','¡Fiebre! Rachas amplifican tus checks.'); } }, 274 275 { id:"perfectionist", pool:"joker", 276 condition:(d)=>(d.totalPerfectRounds??0)>=45, 277 get hint(){ return t('unlock_hints.perfectionist_hint','Muchas rondas perfectas...'); }, 278 get reason(){ return t('unlock_reasons.perfectionist','¡Perfeccionista! Bonus por rondas sin fallo.'); } }, 279 280 { id:"catalyst", pool:"joker", 281 condition:(d)=>(d.seenMutators?.length??0)>=14, 282 get hint(){ return t('unlock_hints.catalyst_hint','Descubre mutadores...'); }, 283 get reason(){ return t('unlock_reasons.catalyst','¡Catalizador! Bonus bajo mutadores nerf.'); } }, 284 285 // ââ Consumables T4 ââ 286 { id:"adrenaline", pool:"consumable", 287 condition:(d)=>(d.records?.bestStreak??0)>=13&&(d.totalRuns??0)>=12, 288 get hint(){ return t('unlock_hints.adrenaline_hint','Racha intensa...'); }, 289 get reason(){ return t('unlock_reasons.adrenaline','¡Adrenalina! Checks fáciles... luego difÃciles.'); } }, 290 291 { id:"skip_round", pool:"consumable", 292 condition:(d)=>(d.records?.bestFloor??0)>=9, 293 get hint(){ return t('unlock_hints.skip_round_hint','Avanza pisos...'); }, 294 get reason(){ return t('unlock_reasons.skip_round','¡Saltar Ronda! Autocompleta la próxima.'); } }, 295 296 { id:"transfusion", pool:"consumable", 297 condition:(d)=>(d.totalStrikeRepairs??0)>=12, 298 get hint(){ return t('unlock_hints.transfusion_hint','Repara muchos strikes...'); }, 299 get reason(){ return t('unlock_reasons.transfusion','¡Transfusión! Convierte strikes en puntos.'); } }, 300 301 { id:"gold_rush", pool:"consumable", 302 condition:(d)=>(d.totalCoins??0)>=900, 303 get hint(){ return t('unlock_hints.gold_rush_hint','Acumula riqueza...'); }, 304 get reason(){ return t('unlock_reasons.gold_rush','¡Fiebre del Oro! Piso lucrativo.'); } }, 305 306 { id:"lucky_coin", pool:"consumable", 307 condition:(d)=>(d.totalItemsBought??0)>=28, 308 get hint(){ return t('unlock_hints.lucky_coin_hint','Compra items...'); }, 309 get reason(){ return t('unlock_reasons.lucky_coin','¡Moneda de la Suerte! Descuento garantizado.'); } }, 310 311 // ââ Mutators T4 ââ 312 { id:"recycle", pool:"mutator", 313 condition:(d)=>(d.totalCoins??0)>=700, 314 get hint(){ return t('unlock_hints.recycle_hint','Acumula coins...'); }, 315 get reason(){ return t('unlock_reasons.recycle','¡Reciclaje! Fallos dan coins, pero menos puntos.'); } }, 316 317 { id:"overflow", pool:"mutator", 318 condition:(d)=>(d.totalChecksPassed??0)>=450, 319 get hint(){ return t('unlock_hints.overflow_hint','Pasa cientos de checks...'); }, 320 get reason(){ return t('unlock_reasons.overflow','¡Desbordamiento! Checks extra dan puntos bonus.'); } }, 321 322 { id:"boomerang", pool:"mutator", 323 condition:(d)=>(d.totalRuns??0)>=16, 324 get hint(){ return t('unlock_hints.boomerang_hint','Veterano...'); }, 325 get reason(){ return t('unlock_reasons.boomerang','¡Boomerang! Checks alternan fácil/difÃcil.'); } }, 326 327 { id:"mutation", pool:"mutator", 328 condition:(d)=>(d.seenMutators?.length??0)>=13, 329 get hint(){ return t('unlock_hints.mutation_hint','Descubre mutadores...'); }, 330 get reason(){ return t('unlock_reasons.mutation','¡Mutación! Doble intercambio de teclas.'); } }, 331 332 { id:"combustion", pool:"mutator", 333 condition:(d)=>(d.totalPerfectRounds??0)>=40, 334 get hint(){ return t('unlock_hints.combustion_hint','Rondas perfectas...'); }, 335 get reason(){ return t('unlock_reasons.combustion','¡Combustión! Racha Ã1.5, pero romperla duele.'); } }, 336 337 { id:"crescendo", pool:"mutator", 338 condition:(d)=>(d.totalRounds??0)>=260, 339 get hint(){ return t('unlock_hints.crescendo_hint','Muchas rondas...'); }, 340 get reason(){ return t('unlock_reasons.crescendo','¡Crescendo! Menos tiempo, más puntos.'); } }, 341 342 // âââââââââââââââââââââââââââââââââââââââââââ 343 // TIER 5 â EXPERTO (runs 20-30) 344 // Advanced synergies and hard mutators 345 // âââââââââââââââââââââââââââââââââââââââââââ 346 347 // ââ Jokers T5 ââ 348 { id:"free_spirit", pool:"joker", 349 condition:(d)=>(d.totalRuns??0)>=20, 350 get hint(){ return t('unlock_hints.free_spirit_hint','Veterano de muchas runs...'); }, 351 get reason(){ return t('unlock_reasons.free_spirit','¡EspÃritu Libre! Sin supervivencia = más score.'); } }, 352 353 { id:"opportunist", pool:"joker", 354 condition:(d)=>(d.seenMutators?.length??0)>=18, 355 get hint(){ return t('unlock_hints.opportunist_hint','Descubre muchos mutadores...'); }, 356 get reason(){ return t('unlock_reasons.opportunist','¡Oportunista! Bonus bajo chaos.'); } }, 357 358 { id:"alchemist", pool:"joker", 359 condition:(d)=>(d.totalCoins??0)>=1800, 360 get hint(){ return t('unlock_hints.alchemist_hint','Gran riqueza acumulada...'); }, 361 get reason(){ return t('unlock_reasons.alchemist','¡Alquimista! Tus ahorros potencian tu score.'); } }, 362 363 { id:"investor", pool:"joker", 364 condition:(d)=>(d.totalCoins??0)>=3000,
365 get hint(){ return t('unlock_hints.investor_hint','Fortuna inmensa...'); }, 366 get reason(){ return t('unlock_reasons.investor','¡Inversor! Tus ahorros generan interés.'); } }, 367 368 { id:"time_thief", pool:"joker", 369 condition:(d)=>(d.totalChecksPassed??0)>=900, 370 get hint(){ return t('unlock_hints.time_thief_hint','Miles de checks...'); }, 371 get reason(){ return t('unlock_reasons.time_thief','¡Ladrón de Tiempo! Cada check te da tiempo.'); } }, 372 373 { id:"recycler", pool:"joker", 374 condition:(d)=>(d.totalConsumablesUsed??0)>=35, 375 get hint(){ return t('unlock_hints.recycler_hint','Usa muchos consumibles...'); }, 376 get reason(){ return t('unlock_reasons.recycler','¡Reciclador! Descartar = coins.'); } }, 377 378 { id:"medic", pool:"joker", 379 condition:(d)=>(d.totalStrikeRepairs??0)>=16, 380 get hint(){ return t('unlock_hints.medic_hint','Repara muchos strikes...'); }, 381 get reason(){ return t('unlock_reasons.medic','¡Médico! Perfección cura strikes.'); } }, 382 383 { id:"tax_collector", pool:"joker", 384 condition:(d)=>(d.totalItemsBought??0)>=50, 385 get hint(){ return t('unlock_hints.tax_collector_hint','Compra mucho...'); }, 386 get reason(){ return t('unlock_reasons.tax_collector','¡Recaudador! Las compras reembolsan.'); } }, 387 388 { id:"mutant", pool:"joker", 389 condition:(d)=>(d.seenMutators?.length??0)>=22, 390 get hint(){ return t('unlock_hints.mutant_hint','Coleccionista de mutadores...'); }, 391 get reason(){ return t('unlock_reasons.mutant','¡Mutante! Variedad de mutadores = score.'); } }, 392 393 // ââ Consumables T5 ââ 394 { id:"rewind", pool:"consumable", 395 condition:(d)=>(d.records?.bestFloor??0)>=10,
396 get hint(){ return t('unlock_hints.rewind_hint','Pisos avanzados...'); }, 397 get reason(){ return t('unlock_reasons.rewind','¡Rewind! Repite rondas fallidas.'); } }, 398 399 { id:"banish", pool:"consumable", 400 condition:(d)=>(d.seenMutators?.length??0)>=18, 401 get hint(){ return t('unlock_hints.banish_hint','Conoce muchos mutadores...'); }, 402 get reason(){ return t('unlock_reasons.banish','¡Destierro! Silencia mutadores.'); } }, 403 404 { id:"oracle", pool:"consumable", 405 condition:(d)=>(d.totalFlawlessFloors??0)>=12, 406 get hint(){ return t('unlock_hints.oracle_hint','Pisos flawless...'); }, 407 get reason(){ return t('unlock_reasons.oracle','¡Oráculo! Ve el futuro.'); } }, 408 409 { id:"extra_checks", pool:"consumable", 410 condition:(d)=>(d.totalChecksPassed??0)>=750, 411 get hint(){ return t('unlock_hints.extra_checks_hint','Pasa cientos de checks...'); }, 412 get reason(){ return t('unlock_reasons.extra_checks','¡Checks Extra! Más oportunidades.'); } }, 413 414 { id:"restock", pool:"consumable", 415 condition:(d)=>(d.totalItemsBought??0)>=42, 416 get hint(){ return t('unlock_hints.restock_hint','Compra bastante...'); }, 417 get reason(){ return t('unlock_reasons.restock','¡Reabastecimiento! Renueva la tienda.'); } }, 418 419 // ââ Mutators T5 ââ 420 { id:"zen", pool:"mutator", 421 condition:(d)=>(d.totalRuns??0)>=22, 422 get hint(){ return t('unlock_hints.zen_hint','Mucha experiencia...'); }, 423 get reason(){ return t('unlock_reasons.zen','¡Zen! Sin timer en BUILD, checks duros.'); } }, 424 425 { id:"metronome", pool:"mutator", 426 condition:(d)=>(d.totalRounds??0)>=350, 427 get hint(){ return t('unlock_hints.metronome_hint','Cientos de rondas...'); }, 428 get reason(){ return t('unlock_reasons.metronome','¡Metrónomo! Checks automáticos.'); } }, 429 430 { id:"duality", pool:"mutator", 431 condition:(d)=>(d.totalFloors??0)>=150, 432 get hint(){ return t('unlock_hints.duality_hint','Muchos pisos explorados...'); }, 433 get reason(){ return t('unlock_reasons.duality','¡Dualidad! Rondas pares/impares diferentes.'); } }, 434 435 { id:"precision_mut", pool:"mutator", 436 condition:(d)=>(d.totalFlawlessFloors??0)>=10, 437 get hint(){ return t('unlock_hints.precision_mut_hint','Pisos perfectos...'); }, 438 get reason(){ return t('unlock_reasons.precision_mut','¡Precisión! Menos checks pero más fáciles.'); } }, 439 440 { id:"revenge", pool:"mutator", 441 condition:(d)=>(d.totalRuns??0)>=22, 442 get hint(){ return t('unlock_hints.revenge_hint','Persiste jugando...'); }, 443 get reason(){ return t('unlock_reasons.revenge','¡Venganza! Strikes reducen tu check window.'); } }, 444 445 { id:"amnesia", pool:"mutator", 446 condition:(d)=>(d.records?.bestFloor??0)>=11, 447 get hint(){ return t('unlock_hints.amnesia_hint','Llega a pisos altos...'); }, 448 get reason(){ return t('unlock_reasons.amnesia','¡Amnesia! Memoriza el combo antes de que desaparezca.'); } }, 449 450 { id:"shrinking", pool:"mutator", 451 condition:(d)=>(d.totalPerfectRounds??0)>=55, 452 get hint(){ return t('unlock_hints.shrinking_hint','Rondas perfectas...'); }, 453 get reason(){ return t('unlock_reasons.shrinking','¡Encogimiento! Timer se reduce cada ronda.'); } }, 454 455 // ââ Shop Variant T5 ââ 456 { id:"shop_free_reroll", pool:"shop_variant", 457 condition:(d)=>(d.totalRuns??0)>=25, 458 get hint(){ return t('unlock_hints.shop_free_reroll_hint','Muchas runs...'); }, 459 get reason(){ return t('unlock_reasons.shop_free_reroll','¡Primer reroll gratis en cada tienda!'); } }, 460 461 // âââââââââââââââââââââââââââââââââââââââââââ 462 // TIER 6 â MAESTRO (runs 30-50) 463 // Endgame builds and dangerous mutators 464 // âââââââââââââââââââââââââââââââââââââââââââ 465 466 // ââ Jokers T6 ââ 467 { id:"masochist", pool:"joker", 468 condition:(d)=>(d.records?.bestFloor??0)>=12, 469 get hint(){ return t('unlock_hints.masochist_hint','Piso 10+...'); }, 470 get reason(){ return t('unlock_reasons.masochist','¡Masoquista! Más teclas = más puntos.'); } }, 471 472 { id:"late_bloomer", pool:"joker", 473 condition:(d)=>(d.records?.bestFloor??0)>=13, 474 get hint(){ return t('unlock_hints.late_bloomer_hint','Llega muy lejos...'); }, 475 get reason(){ return t('unlock_reasons.late_bloomer','¡Flor TardÃa! Pisos avanzados dan más.'); } }, 476 477 { id:"combo_king", pool:"joker", 478 condition:(d)=>(d.usedJokers?.length??0)>=22, 479 get hint(){ return t('unlock_hints.combo_king_hint','Usa muchos jokers distintos...'); }, 480 get reason(){ return t('unlock_reasons.combo_king','¡Rey del Combo! Más jokers = más score.'); } }, 481 482 { id:"gambler", pool:"joker", 483 condition:(d)=>(d.totalRuns??0)>=30, 484 get hint(){ return t('unlock_hints.gambler_hint','Muchas runs...'); }, 485 get reason(){ return t('unlock_reasons.gambler','¡Apostador! Arriésgate por la gloria.'); } }, 486 487 { id:"daredevil", pool:"joker", 488 condition:(d)=>(d.totalRuns??0)>=28, 489 get hint(){ return t('unlock_hints.daredevil_hint','Veterano curtido...'); }, 490 get reason(){ return t('unlock_reasons.daredevil','¡Temerario! Al borde del abismo ganas más.'); } }, 491 492 { id:"scavenger", pool:"joker", 493 condition:(d)=>(d.totalItemsBought??0)>=65, 494 get hint(){ return t('unlock_hints.scavenger_hint','Comprador compulsivo...'); }, 495 get reason(){ return t('unlock_reasons.scavenger','¡Carroñero! Encuentra items gratis.'); } }, 496 497 { id:"hoarder", pool:"joker", 498 condition:(d)=>(d.totalConsumablesUsed??0)>=55, 499 get hint(){ return t('unlock_hints.hoarder_hint','Maestro de consumibles...'); }, 500 get reason(){ return t('unlock_reasons.hoarder','¡Acumulador! +1 slot de consumible.'); } }, 501 502 { id:"all_in", pool:"joker", 503 condition:(d)=>(d.totalConsumablesUsed??0)>=45, 504 get hint(){ return t('unlock_hints.all_in_hint','Usa muchos consumibles...'); }, 505 get reason(){ return t('unlock_reasons.all_in','¡Todo o Nada! Sin consumibles = más puntos.'); } }, 506 507 { id:"overachiever", pool:"joker", 508 condition:(d)=>(d.totalFlawlessFloors??0)>=18,
509 get hint(){ return t('unlock_hints.overachiever_hint','Pisos perfectos...'); }, 510 get reason(){ return t('unlock_reasons.overachiever','¡Sobresaliente! Flawless acumulativo.'); } }, 511 512 { id:"berserker", pool:"joker", 513 condition:(d)=>(d.totalRuns??0)>=35, 514 get hint(){ return t('unlock_hints.berserker_hint','Persiste mucho...'); }, 515 get reason(){ return t('unlock_reasons.berserker','¡Berserker! Strikes potencian tu score.'); } }, 516 517 // ââ Consumables T6 ââ 518 { id:"overcharge", pool:"consumable", 519 condition:(d)=>d.bestRuns?.some(r=>r.score>=6000), 520 get hint(){ return t('unlock_hints.overcharge_hint','Score muy alto...'); }, 521 get reason(){ return t('unlock_reasons.overcharge','¡Sobrecarga! Ã3 puntos... con un coste.'); } }, 522 523 { id:"perfect_gem", pool:"consumable", 524 condition:(d)=>(d.totalPerfectRounds??0)>=80, 525 get hint(){ return t('unlock_hints.perfect_gem_hint','Muchas rondas perfectas...'); }, 526 get reason(){ return t('unlock_reasons.perfect_gem','¡Gema Perfecta! Perfección amplificada.'); } }, 527 528 { id:"elixir", pool:"consumable", 529 condition:(d)=>(d.totalItemsBought??0)>=58, 530 get hint(){ return t('unlock_hints.elixir_hint','Comprador frecuente...'); }, 531 get reason(){ return t('unlock_reasons.elixir','¡Elixir! Potencia jokers permanentemente.'); } }, 532 533 { id:"mirror_break", pool:"consumable", 534 condition:(d)=>(d.seenMutators?.length??0)>=26, 535 get hint(){ return t('unlock_hints.mirror_break_hint','Experto en mutadores...'); }, 536 get reason(){ return t('unlock_reasons.mirror_break','¡Rompe-Espejos! Cancela mutadores permanentemente.'); } }, 537 538 { id:"second_wind", pool:"consumable", 539 condition:(d)=>(d.totalRuns??0)>=32, 540 get hint(){ return t('unlock_hints.second_wind_hint','Superviviente nato...'); }, 541 get reason(){ return t('unlock_reasons.second_wind','¡Segundo Aire! Una vida extra.'); } }, 542 543 // ââ Mutators T6 ââ 544 { id:"cascade", pool:"mutator", 545 condition:(d)=>(d.totalChecksPassed??0)>=1100, 546 get hint(){ return t('unlock_hints.cascade_hint','Miles de checks...'); }, 547 get reason(){ return t('unlock_reasons.cascade','¡Cascada! Cada check reduce la ventana.'); } }, 548 549 { id:"double_tap", pool:"mutator", 550 condition:(d)=>(d.totalRounds??0)>=450, 551 get hint(){ return t('unlock_hints.double_tap_hint','Cientos de rondas...'); }, 552 get reason(){ return t('unlock_reasons.double_tap','¡Doble Toque! Cada check requiere pulsar dos veces.'); } }, 553 554 { id:"sequential", pool:"mutator", 555 condition:(d)=>(d.totalFloors??0)>=200, 556 get hint(){ return t('unlock_hints.sequential_hint','Muchos pisos recorridos...'); }, 557 get reason(){ return t('unlock_reasons.sequential','¡Secuencial! Teclas en orden obligatorio.'); } }, 558 559 { id:"last_breath", pool:"mutator", 560 condition:(d)=>(d.totalRuns??0)>=36, 561 get hint(){ return t('unlock_hints.last_breath_hint','Persiste sin rendirte...'); }, 562 get reason(){ return t('unlock_reasons.last_breath','¡Ãltimo Aliento! 2 strikes, pero curas al superar.'); } }, 563 564 { id:"gravity", pool:"mutator", 565 condition:(d)=>(d.totalChecksPassed??0)>=1200, 566 get hint(){ return t('unlock_hints.gravity_hint','Checks por miles...'); }, 567 get reason(){ return t('unlock_reasons.gravity','¡Gravedad! Checks fallidos roban tiempo.'); } }, 568 569 { id:"naked", pool:"mutator", 570 condition:(d)=>(d.records?.bestFloor??0)>=14, 571 get hint(){ return t('unlock_hints.naked_hint','Llega a pisos muy altos...'); }, 572 get reason(){ return t('unlock_reasons.naked','¡Desnudo! Sin teclado visual, solo texto.'); } }, 573 574 { id:"echo_round", pool:"mutator", 575 condition:(d)=>(d.totalRuns??0)>=34, 576 get hint(){ return t('unlock_hints.echo_round_hint','Experiencia prolongada...'); }, 577 get reason(){ return t('unlock_reasons.echo_round','¡Eco de Ronda! Combos repetidos.'); } }, 578 579 // âââââââââââââââââââââââââââââââââââââââââââ 580 // TIER 7 â EXÃTICO (runs 50+, extreme) 581 // Endgame rewards for dedicated players 582 // âââââââââââââââââââââââââââââââââââââââââââ 583 584 // ââ Jokers T7 (exotic) ââ 585 { id:"chameleon", pool:"joker", 586 condition:(d)=>(d.seenMutators?.length??0)>=32, 587 get hint(){ return t('unlock_hints.chameleon_hint','Maestro de todos los mutadores...'); }, 588 get reason(){ return t('unlock_reasons.chameleon','¡Camaleón! Domina cualquier mutador.'); } }, 589 590 { id:"momentum_rider", pool:"joker", 591 condition:(d)=>(d.records?.bestStreak??0)>=20, 592 get hint(){ return t('unlock_hints.momentum_rider_hint','Racha legendaria...'); }, 593 get reason(){ return t('unlock_reasons.momentum_rider','¡Jinete del Impulso! Rachas dan tiempo.'); } }, 594 595 { id:"thick_skin", pool:"joker", 596 condition:(d)=>(d.records?.bestFloor??0)>=16,
597 get hint(){ return t('unlock_hints.thick_skin_hint','Pisos altÃsimos...'); }, 598 get reason(){ return t('unlock_reasons.thick_skin','¡Piel Dura! Chance de ignorar strikes.'); } }, 599 600 { id:"phoenix", pool:"joker", 601 condition:(d)=>(d.totalRuns??0)>=50&&(d.records?.bestFloor??0)>=14, 602 get hint(){ return t('unlock_hints.phoenix_hint','Muchas muertes, muchos renacimientos...'); }, 603 get reason(){ return t('unlock_reasons.phoenix','¡Fénix desbloqueado! Una segunda vida.'); } }, 604 605 { id:"glass_cannon", pool:"joker", 606 condition:(d)=>d.bestRuns?.some(r=>r.score>=10000), 607 get hint(){ return t('unlock_hints.glass_cannon_hint','Score legendario...'); }, 608 get reason(){ return t('unlock_reasons.glass_cannon','¡Cañón de Cristal! Poder máximo, fragilidad máxima.'); } }, 609 610 { id:"cursed_crown", pool:"joker", 611 condition:(d)=>(d.records?.bestFloor??0)>=18, 612 get hint(){ return t('unlock_hints.cursed_crown_hint','Llega a los pisos finales...'); }, 613 get reason(){ return t('unlock_reasons.cursed_crown','¡Corona Maldita! Poder con un precio.'); } }, 614 615 { id:"soul_bargain", pool:"joker", 616 condition:(d)=>(d.records?.bestStreak??0)>=25, 617 get hint(){ return t('unlock_hints.soul_bargain_hint','Racha divina...'); }, 618 get reason(){ return t('unlock_reasons.soul_bargain','¡Pacto de Almas! Checks valen... pero un golpe mata.'); } }, 619 620 // ââ Consumables T7 ââ 621 { id:"liquidate", pool:"consumable", 622 condition:(d)=>(d.totalItemsBought??0)>=75, 623 get hint(){ return t('unlock_hints.liquidate_hint','Comerciante experto...'); }, 624 get reason(){ return t('unlock_reasons.liquidate','¡Liquidar! Sacrifica jokers por coins.'); } }, 625 626 { id:"forge", pool:"consumable", 627 condition:(d)=>(d.usedJokers?.length??0)>=30, 628 get hint(){ return t('unlock_hints.forge_hint','Coleccionista de jokers...'); }, 629 get reason(){ return t('unlock_reasons.forge','¡Forja! Mejora todos tus jokers.'); } }, 630 631 { id:"clone_potion", pool:"consumable", 632 condition:(d)=>(d.totalConsumablesUsed??0)>=70, 633 get hint(){ return t('unlock_hints.clone_potion_hint','Maestro de consumibles...'); }, 634 get reason(){ return t('unlock_reasons.clone_potion','¡Poción Clónica! Duplica consumibles.'); } }, 635 636 { id:"amplifier", pool:"consumable", 637 condition:(d)=>(d.totalConsumablesUsed??0)>=80, 638 get hint(){ return t('unlock_hints.amplifier_hint','Experto absoluto en consumibles...'); }, 639 get reason(){ return t('unlock_reasons.amplifier','¡Amplificador! Doble efecto.'); } }, 640 641 // ââ Mutators T7 ââ 642 { id:"volatile", pool:"mutator", 643 condition:(d)=>(d.totalRuns??0)>=45, 644 get hint(){ return t('unlock_hints.volatile_hint','Veterano extremo...'); }, 645 get reason(){ return t('unlock_reasons.volatile','¡Volátil! Eventos aleatorios cada ronda.'); } }, 646 647 { id:"feast_famine", pool:"mutator", 648 condition:(d)=>(d.totalPerfectRounds??0)>=100, 649 get hint(){ return t('unlock_hints.feast_famine_hint','Perfección absoluta...'); }, 650 get reason(){ return t('unlock_reasons.feast_famine','¡FestÃn y Hambruna! Alto riesgo, alta recompensa.'); } }, 651 652 { id:"shuffle", pool:"mutator", 653 condition:(d)=>(d.seenMutators?.length??0)>=30, 654 get hint(){ return t('unlock_hints.shuffle_hint','Descubre casi todos los mutadores...'); }, 655 get reason(){ return t('unlock_reasons.shuffle','¡Barajar desbloqueado! El teclado cambia.'); } }, 656 657 { id:"ricochet", pool:"mutator", 658 condition:(d)=>(d.totalChecksPassed??0)>=1600, 659 get hint(){ return t('unlock_hints.ricochet_hint','Miles y miles de checks...'); }, 660 get reason(){ return t('unlock_reasons.ricochet','¡Rebote! Segunda oportunidad en checks.'); } }, 661 662 // ââ Shop Variant T7 ââ 663 { id:"shop_rare_sight", pool:"shop_variant", 664 condition:(d)=>(d.records?.bestFloor??0)>=15, 665 get hint(){ return t('unlock_hints.shop_rare_sight_hint','Llega a pisos extremos...'); }, 666 get reason(){ return t('unlock_reasons.shop_rare_sight','¡Items raros aparecen más en tienda!'); } }, 667]; 668 669export default UNLOCKABLE_DEFS; 670 671/** 672 * Set of IDs gated behind unlock conditions. 673 * Items NOT in this set are always available. 674 */ 675export const GATED_IDS = new Set(UNLOCKABLE_DEFS.map(d => d.id));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.