This commit is contained in:
Renan LE CARO 2025-04-29 17:53:35 +02:00
parent d17eba50e5
commit 99930cb77f
13 changed files with 256 additions and 104 deletions

115
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -184,7 +184,7 @@ body:not(.has-alert-open) #popup {
cursor: not-allowed;
}
&.no-border{
&.no-border {
border-color: transparent;
}
@ -214,6 +214,7 @@ body:not(.has-alert-open) #popup {
}
> button[data-help-content] {
user-select: none;
border-radius: 4px;
outline: none;
align-self: center;
@ -432,10 +433,10 @@ h2.histogram-title strong {
line-height: 12px;
display: inline-block;
position: relative;
top: -3px;
//top: -3px;
font-weight: bold;
border: 1px solid #FFF;
margin-left: 5px;
//margin-left: 5px;
> span {
display: inline-block;
@ -488,12 +489,39 @@ h2.histogram-title strong {
}
&.free {
opacity: 0.8;
//opacity: 0.8;
img {
opacity: 0.5;
}
}
&.banned {
opacity: 0.8;
}
&.greyed-out {
opacity: 0.2;
}
button {
color: #fff;
background: gold;
align-self: flex-start;
font-weight: bold;
padding: 5px;
border-radius: 5px;
box-shadow: 0 4px 0 gold, 0 4px 10px black;
border: 2px solid white;
cursor: pointer;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
user-select: none;
&:active{
transform: translate(0,4px);
box-shadow: 0 0px 0 gold, 0 0px 10px black;
}
transition: transform 0.2s, box-shadow 0.2s;
}
}
#tooltip {

View file

@ -319,3 +319,7 @@ export function hoursSpentPlaying() {
return 0;
}
}
export function escapeAttribute(str:String){
return str.replace(/&/gi,'&amp;').replace(/</gi,'&lt;').replace(/"/gi,'&quot;').replace(/'/gi,'&#39;')
}

View file

@ -72,8 +72,10 @@
"level_up.instructions": "",
"level_up.maxed_upgrade": "",
"level_up.no_points": "",
"level_up.pick": "",
"level_up.pick_upgrade": "",
"level_up.title": "لقد انتهيت للتو من المستوى {{level}}/{{max}}.",
"level_up.upgrade": "",
"level_up.upgrade_perk_to_level": "",
"main_menu.basic": "",
"main_menu.basic_help": "",

View file

@ -2632,6 +2632,41 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>pick</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>pick_upgrade</name>
<description/>
@ -2702,6 +2737,41 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>upgrade</name>
<description/>
<comment/>
<translations>
<translation>
<language>ar-LB</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-CL</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>upgrade_perk_to_level</name>
<description/>

View file

@ -72,8 +72,10 @@
"level_up.instructions": "",
"level_up.maxed_upgrade": "",
"level_up.no_points": "",
"level_up.pick": "",
"level_up.pick_upgrade": "",
"level_up.title": "Du hast gerade Level {{level}}/{{max}} beendet.",
"level_up.upgrade": "",
"level_up.upgrade_perk_to_level": "",
"main_menu.basic": "",
"main_menu.basic_help": "",

View file

@ -69,11 +69,13 @@
"lab.select_level": "Select a level to play on",
"lab.unlocks_at": "Unlocks at total score {{score}}",
"level_up.go": "Continue to level \"{{name}}\"",
"level_up.instructions": "You can upgrade perks below using your {{count}} extra lives. ",
"level_up.instructions": "You gained {{gain}} extra lives. You can use your {{count}} extra lives to buy upgrades below, or keep them to be safe. ",
"level_up.maxed_upgrade": "\"{{name}}\" is at max level",
"level_up.no_points": "You've spent all your extra lives.",
"level_up.pick": "Pick",
"level_up.pick_upgrade": "Get \"{{name}}\"",
"level_up.title": "You just finished level {{level}}/{{max}}.",
"level_up.title": "Level {{level}}/{{max}} cleared",
"level_up.upgrade": "Upgrade",
"level_up.upgrade_perk_to_level": "Upgrade \"{{name}}\" to level {{level}}",
"main_menu.basic": "",
"main_menu.basic_help": "",

View file

@ -72,8 +72,10 @@
"level_up.instructions": "",
"level_up.maxed_upgrade": "",
"level_up.no_points": "",
"level_up.pick": "",
"level_up.pick_upgrade": "",
"level_up.title": "Acabas de completar el nivel {{level}}/{{max}}.",
"level_up.upgrade": "",
"level_up.upgrade_perk_to_level": "",
"main_menu.basic": "Gráficos simplificados",
"main_menu.basic_help": "Mejor rendimiento.",

View file

@ -72,8 +72,10 @@
"level_up.instructions": "",
"level_up.maxed_upgrade": "",
"level_up.no_points": "",
"level_up.pick": "",
"level_up.pick_upgrade": "",
"level_up.title": "Vous venez de terminer le niveau {{level}}/{{max}}.",
"level_up.upgrade": "",
"level_up.upgrade_perk_to_level": "",
"main_menu.basic": "",
"main_menu.basic_help": "",

View file

@ -72,8 +72,10 @@
"level_up.instructions": "",
"level_up.maxed_upgrade": "",
"level_up.no_points": "",
"level_up.pick": "",
"level_up.pick_upgrade": "",
"level_up.title": "Вы только что закончили уровень {{level}}/{{max}}.",
"level_up.upgrade": "",
"level_up.upgrade_perk_to_level": "",
"main_menu.basic": "",
"main_menu.basic_help": "",

View file

@ -72,8 +72,10 @@
"level_up.instructions": "",
"level_up.maxed_upgrade": "",
"level_up.no_points": "",
"level_up.pick": "",
"level_up.pick_upgrade": "",
"level_up.title": " {{level}}/{{max}}seviyesini yeni bitirdiniz.",
"level_up.upgrade": "",
"level_up.upgrade_perk_to_level": "",
"main_menu.basic": "",
"main_menu.basic_help": "",

View file

@ -13,10 +13,10 @@ import {t} from "./i18n/i18n";
import {icons, upgrades} from "./loadGameData";
import {asyncAlert} from "./asyncAlert";
import {
escapeAttribute,
getPossibleUpgrades,
levelsListHTMl,
max_levels,
pickedUpgradesHTMl,
upgradeLevelAndMaxDisplay
} from "./game_utils";
import {getNearestUnlockHTML} from "./openScorePanel";
@ -25,12 +25,13 @@ export async function openUpgradesPicker(gameState: GameState) {
const catchRate =
gameState.levelCoughtCoins / (gameState.levelSpawnedCoins || 1);
gameState.extra_lives++
let choices = 3 + gameState.perks.one_more_choice
let choices = 3
let livesWon=1
if (gameState.levelWallBounces < wallBouncedGood) {
choices++;
gameState.extra_lives++;
livesWon++;
if (gameState.levelWallBounces < wallBouncedBest) {
choices++;
}
@ -38,100 +39,104 @@ export async function openUpgradesPicker(gameState: GameState) {
if (gameState.levelTime < levelTimeGood * 1000) {
choices++;
gameState.extra_lives++;
livesWon++;
if (gameState.levelTime < levelTimeBest * 1000) {
choices++;
}
}
if (catchRate > catchRateGood / 100) {
choices++;
gameState.extra_lives++;
livesWon++;
if (catchRate > catchRateBest / 100) {
choices++;
}
}
if (gameState.levelMisses < missesGood) {
choices++;
gameState.extra_lives++;
livesWon++;
if (gameState.levelMisses < missesBest) {
choices++;
}
}
let offered:PerkId[]= getPossibleUpgrades(gameState)
gameState.extra_lives+=livesWon
let offered: PerkId[] = getPossibleUpgrades(gameState)
.map((u) => ({
...u,
score: Math.random() + (gameState.lastOffered[u.id] || 0),
}))
.sort((a, b) => a.score - b.score)
.filter((u) => gameState.perks[u.id] < u.max + gameState.perks.limitless)
.slice(0, choices)
.map(u=>u.id)
.map(u => u.id)
offered.forEach((id) => {
dontOfferTooSoon(gameState, id);
});
let list = upgrades.filter(u=>offered.includes(u.id)||gameState.perks[u.id])
const fromStart = upgrades.map(u => u.id).filter(id => gameState.perks[id])
while (true) {
let actions: Array<{
text: string;
icon: string;
value: PerkId | null;
help: string;
className: string;
tooltip: string;
}> = list.map((u) => {
const disabled= !gameState.extra_lives || gameState.perks[u.id] >= u.max + gameState.perks.limitless
const lvl= gameState.perks[u.id]
return ({
text: u.name + (lvl ? upgradeLevelAndMaxDisplay(u, gameState):''),
help: u.help(Math.max(1, lvl)),
tooltip: u.fullHelp(Math.max(1, lvl)),
icon: icons["icon:" + u.id],
value: u.id as PerkId,
className: "upgrade " + (disabled && lvl ? 'no-border ':' ') + ( lvl ? '':'grey-out-unless-hovered ') ,
disabled:disabled ,
})
})
actions = [
...actions.filter(a=>gameState.perks[a.value]),
...actions.filter(a=>!gameState.perks[a.value]),
]
const updatedChoices = gameState.perks.one_more_choice + choices
let list = upgrades.filter(u => offered.slice(0, updatedChoices).includes(u.id) || gameState.perks[u.id])
list = list.filter(u => fromStart.includes(u.id))
.concat(list.filter(u => !fromStart.includes(u.id)))
list.forEach((u) => {
dontOfferTooSoon(gameState, u.id);
});
const upgradeId = await asyncAlert<PerkId | null>({
title:
t("level_up.title", {
level: gameState.currentLevel ,
t("level_up.title", {
level: gameState.currentLevel,
max: max_levels(gameState),
}),
content: [
{
text: t('level_up.go',{name:gameState.level.name}),
icon: icons[gameState.level.name],
value:null,
text: t('level_up.go', {name: gameState.level.name}),
icon: icons[gameState.level.name],
value: null,
},
// pickedUpgradesHTMl(gameState),
gameState.extra_lives ? `<p>${t("level_up.instructions", {
count:gameState.extra_lives
})}</p>` :`<p>${t("level_up.no_points")}</p>` ,
...actions,
levelsListHTMl(gameState, gameState.currentLevel ),
gameState.extra_lives ? `<p>${t("level_up.instructions", {
count: gameState.extra_lives,
gain:livesWon
})}</p>` : `<p>${t("level_up.no_points")}</p>`,
...list.map((u) => {
const max = u.max + gameState.perks.limitless
const lvl = gameState.perks[u.id]
const button = !gameState.extra_lives || gameState.perks[u.id] >= max ?
'' : ` <button data-resolve-to="${u.id}">${
lvl ? t('level_up.upgrade') : t('level_up.pick')
}</button>`
const lvlInfo = lvl ? upgradeLevelAndMaxDisplay(u, gameState) : ''
return `<div class="upgrade choice ${
(!lvl && gameState.extra_lives && 'free') ||
(lvl && 'used') ||
'greyed-out'
}" >
${icons["icon:" + u.id]}
<p data-tooltip="${escapeAttribute(u.fullHelp(Math.max(1, lvl)))}">
<strong>${u.name}</strong> ${lvlInfo}
${u.help(Math.max(1, lvl))}
</p>
${button}
</div>`
})
,
levelsListHTMl(gameState, gameState.currentLevel),
getNearestUnlockHTML(gameState),
`<div id="level-recording-container"></div>`,
],
});
if (upgradeId ) {
if (upgradeId) {
gameState.perks[upgradeId]++;
gameState.runStatistics.upgrades_picked++;
gameState.extra_lives--
}else{
} else {
return
}
}

View file

@ -914,10 +914,10 @@ export const rawUpgrades = [
max: 4,
name: t("upgrades.passive_income.name"),
help: (lvl: number) =>
t("upgrades.passive_income.tooltip", { time: lvl * 0.1 - 0.05, lvl }),
t("upgrades.passive_income.tooltip", { time: (lvl * 0.1 - 0.05).toFixed(2), lvl }),
fullHelp: (lvl: number) =>
t("upgrades.passive_income.verbose_description", {
time: lvl * 0.1 - 0.05,
time: (lvl * 0.1 - 0.05).toFixed(2),
lvl,
}),
},