mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-21 12:36:15 -04:00
wip
This commit is contained in:
parent
11c797bc59
commit
64a85200b9
23 changed files with 1849 additions and 329 deletions
|
@ -24,13 +24,14 @@ languages, I may add features again.
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
## To do
|
## To do
|
||||||
|
- redo video
|
||||||
- allow loading newer save in outdated app (for rollback)
|
|
||||||
- level editor :english only, web only, link to test level, same link needs to be shared to discord
|
|
||||||
- auto-detect device performance at first startup and adjust settings accordingly
|
- auto-detect device performance at first startup and adjust settings accordingly
|
||||||
|
- demo mode that shows device name (for phone shops to catch attention)
|
||||||
|
|
||||||
## Done
|
## Done
|
||||||
|
|
||||||
|
- level editor
|
||||||
|
- allow loading newer save in outdated app (for rollback)
|
||||||
- game crashes when reaching level 12 (no level info in runLevels)
|
- game crashes when reaching level 12 (no level info in runLevels)
|
||||||
|
|
||||||
## 29074385
|
## 29074385
|
||||||
|
|
|
@ -29,8 +29,8 @@ android {
|
||||||
applicationId = "me.lecaro.breakout"
|
applicationId = "me.lecaro.breakout"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 29075517
|
versionCode = 29077162
|
||||||
versionName = "29075517"
|
versionName = "29077162"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary = true
|
useSupportLibrary = true
|
||||||
|
|
File diff suppressed because one or more lines are too long
348
dist/index.html
vendored
348
dist/index.html
vendored
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
// The version of the cache.
|
// The version of the cache.
|
||||||
const VERSION = "29075517";
|
const VERSION = "29077162";
|
||||||
|
|
||||||
// The name of the cache
|
// The name of the cache
|
||||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GameState, Level, PerkId, Upgrade } from "./types";
|
import { GameState, Level, PerkId, RawLevel, Upgrade } from "./types";
|
||||||
import { allLevels, icons, upgrades } from "./loadGameData";
|
import { allLevels, icons, transformRawLevel, upgrades } from "./loadGameData";
|
||||||
import { t } from "./i18n/i18n";
|
import { t } from "./i18n/i18n";
|
||||||
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
|
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
|
||||||
import {
|
import {
|
||||||
|
@ -17,6 +17,7 @@ import {
|
||||||
} from "./game_utils";
|
} from "./game_utils";
|
||||||
import { getHistory } from "./gameOver";
|
import { getHistory } from "./gameOver";
|
||||||
import { noCreative } from "./upgrades";
|
import { noCreative } from "./upgrades";
|
||||||
|
import { levelIconHTML } from "./levelIcon";
|
||||||
|
|
||||||
export function creativeMode(gameState: GameState) {
|
export function creativeMode(gameState: GameState) {
|
||||||
return {
|
return {
|
||||||
|
@ -39,7 +40,9 @@ export async function openCreativeModePerksPicker() {
|
||||||
{},
|
{},
|
||||||
),
|
),
|
||||||
choice: Upgrade | Level | "reset" | void;
|
choice: Upgrade | Level | "reset" | void;
|
||||||
|
const customLevels = (getSettingValue("custom_levels", []) as RawLevel[]).map(
|
||||||
|
transformRawLevel,
|
||||||
|
);
|
||||||
while (
|
while (
|
||||||
(choice = await asyncAlert<Upgrade | Level | "reset">({
|
(choice = await asyncAlert<Upgrade | Level | "reset">({
|
||||||
title: t("lab.menu_entry"),
|
title: t("lab.menu_entry"),
|
||||||
|
@ -78,6 +81,13 @@ export async function openCreativeModePerksPicker() {
|
||||||
tooltip: problem || describeLevel(l),
|
tooltip: problem || describeLevel(l),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
...customLevels.map((l) => ({
|
||||||
|
icon: levelIconHTML(l.bricks, l.size, l.color),
|
||||||
|
text: l.name,
|
||||||
|
value: l,
|
||||||
|
disabled: !l.bricks.filter((b) => b !== "_").length,
|
||||||
|
tooltip: describeLevel(l),
|
||||||
|
})),
|
||||||
],
|
],
|
||||||
}))
|
}))
|
||||||
) {
|
) {
|
||||||
|
@ -88,7 +98,7 @@ export async function openCreativeModePerksPicker() {
|
||||||
} else if ("bricks" in choice) {
|
} else if ("bricks" in choice) {
|
||||||
setSettingValue("creativeModePerks", creativeModePerks);
|
setSettingValue("creativeModePerks", creativeModePerks);
|
||||||
if (await confirmRestart(gameState)) {
|
if (await confirmRestart(gameState)) {
|
||||||
restart({ perks: creativeModePerks, level: choice.name });
|
restart({ perks: creativeModePerks, level: choice });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (choice) {
|
} else if (choice) {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1 +1 @@
|
||||||
"29075517"
|
"29077162"
|
||||||
|
|
|
@ -70,6 +70,7 @@ canvas:not(#game) {
|
||||||
color: gold;
|
color: gold;
|
||||||
transition: color 0.01s;
|
transition: color 0.01s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -477,6 +478,7 @@ h2.histogram-title strong {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: black;
|
background: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
|
@ -488,11 +490,13 @@ h2.histogram-title strong {
|
||||||
td:first-child {
|
td:first-child {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: auto;
|
height: auto;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(2n) {
|
tr:nth-child(2n) {
|
||||||
background: rgba(0, 0, 0, 0.58);
|
background: rgba(0, 0, 0, 0.58);
|
||||||
}
|
}
|
||||||
|
@ -508,6 +512,7 @@ h2.histogram-title strong {
|
||||||
height: 7px;
|
height: 7px;
|
||||||
bottom: 2px;
|
bottom: 2px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 1px;
|
inset: 1px;
|
||||||
|
@ -544,3 +549,40 @@ h2.histogram-title strong {
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gridEdit > div > span,
|
||||||
|
.palette > span {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 1px solid;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
border-color: gold;
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: inset 2px 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.gridEdit {
|
||||||
|
& > div {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
width: calc(min(500px, 100vw, 100vh - 200px) / var(--grid-size));
|
||||||
|
height: calc(min(500px, 100vw, 100vh - 200px) / var(--grid-size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.palette {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
& > span {
|
||||||
|
&[data-selected="true"] {
|
||||||
|
border: 2px solid white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
src/game.ts
17
src/game.ts
|
@ -1,4 +1,10 @@
|
||||||
import { allLevels, appVersion, icons, upgrades } from "./loadGameData";
|
import {
|
||||||
|
allLevels,
|
||||||
|
allLevelsAndIcons,
|
||||||
|
appVersion,
|
||||||
|
icons,
|
||||||
|
upgrades,
|
||||||
|
} from "./loadGameData";
|
||||||
import {
|
import {
|
||||||
Ball,
|
Ball,
|
||||||
Coin,
|
Coin,
|
||||||
|
@ -89,6 +95,7 @@ import { generateSaveFileContent } from "./generateSaveFileContent";
|
||||||
import { runHistoryViewerMenuEntry } from "./runHistoryViewer";
|
import { runHistoryViewerMenuEntry } from "./runHistoryViewer";
|
||||||
import { getNearestUnlockHTML, openScorePanel } from "./openScorePanel";
|
import { getNearestUnlockHTML, openScorePanel } from "./openScorePanel";
|
||||||
import { monitorLevelsUnlocks } from "./monitorLevelsUnlocks";
|
import { monitorLevelsUnlocks } from "./monitorLevelsUnlocks";
|
||||||
|
import { levelEditorMenuEntry } from "./levelEditor";
|
||||||
|
|
||||||
export async function play() {
|
export async function play() {
|
||||||
if (await applyFullScreenChoice()) return;
|
if (await applyFullScreenChoice()) return;
|
||||||
|
@ -518,6 +525,7 @@ export async function openMainMenu() {
|
||||||
},
|
},
|
||||||
creativeMode(gameState),
|
creativeMode(gameState),
|
||||||
runHistoryViewerMenuEntry(),
|
runHistoryViewerMenuEntry(),
|
||||||
|
levelEditorMenuEntry(),
|
||||||
{
|
{
|
||||||
icon: icons["icon:unlocks"],
|
icon: icons["icon:unlocks"],
|
||||||
text: t("main_menu.unlocks"),
|
text: t("main_menu.unlocks"),
|
||||||
|
@ -849,7 +857,10 @@ async function openUnlocksList() {
|
||||||
.map(({ name, id, threshold, icon, help }) => ({
|
.map(({ name, id, threshold, icon, help }) => ({
|
||||||
text: name,
|
text: name,
|
||||||
disabled: ts < threshold,
|
disabled: ts < threshold,
|
||||||
value: { perks: { [id]: 1 }, level: "icon:" + id } as RunParams,
|
value: {
|
||||||
|
perks: { [id]: 1 },
|
||||||
|
level: allLevelsAndIcons.find((l) => l.name === "icon:" + id),
|
||||||
|
} as RunParams,
|
||||||
icon,
|
icon,
|
||||||
[hintField]:
|
[hintField]:
|
||||||
ts < threshold
|
ts < threshold
|
||||||
|
@ -871,7 +882,7 @@ async function openUnlocksList() {
|
||||||
return {
|
return {
|
||||||
text: l.name + percentUnlocked,
|
text: l.name + percentUnlocked,
|
||||||
disabled: !!lockedBecause,
|
disabled: !!lockedBecause,
|
||||||
value: { level: l.name } as RunParams,
|
value: { level: l } as RunParams,
|
||||||
icon: icons[l.name],
|
icon: icons[l.name],
|
||||||
[hintField]: lockedBecause?.text || describeLevel(l),
|
[hintField]: lockedBecause?.text || describeLevel(l),
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,11 +9,12 @@ import {
|
||||||
pickedUpgradesHTMl,
|
pickedUpgradesHTMl,
|
||||||
reasonLevelIsLocked,
|
reasonLevelIsLocked,
|
||||||
} from "./game_utils";
|
} from "./game_utils";
|
||||||
import { getTotalScore } from "./settings";
|
import { getSettingValue, getTotalScore } from "./settings";
|
||||||
import { stopRecording } from "./recording";
|
import { stopRecording } from "./recording";
|
||||||
import { asyncAlert } from "./asyncAlert";
|
import { asyncAlert } from "./asyncAlert";
|
||||||
import { rawUpgrades } from "./upgrades";
|
import { rawUpgrades } from "./upgrades";
|
||||||
import { run } from "jest";
|
import { run } from "jest";
|
||||||
|
import { editRawLevelList } from "./levelEditor";
|
||||||
|
|
||||||
export function addToTotalPlayTime(ms: number) {
|
export function addToTotalPlayTime(ms: number) {
|
||||||
try {
|
try {
|
||||||
|
@ -30,11 +31,18 @@ export function addToTotalPlayTime(ms: number) {
|
||||||
export function gameOver(title: string, intro: string) {
|
export function gameOver(title: string, intro: string) {
|
||||||
if (!gameState.running) return;
|
if (!gameState.running) return;
|
||||||
if (gameState.isGameOver) return;
|
if (gameState.isGameOver) return;
|
||||||
|
|
||||||
gameState.isGameOver = true;
|
gameState.isGameOver = true;
|
||||||
pause(true);
|
pause(true);
|
||||||
stopRecording();
|
stopRecording();
|
||||||
addToTotalPlayTime(gameState.runStatistics.runTime);
|
addToTotalPlayTime(gameState.runStatistics.runTime);
|
||||||
|
|
||||||
|
if (typeof gameState.isEditorTrialRun === "number") {
|
||||||
|
editRawLevelList(gameState.isEditorTrialRun);
|
||||||
|
restart({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// unlocks
|
// unlocks
|
||||||
const endTs = getTotalScore();
|
const endTs = getTotalScore();
|
||||||
const startTs = endTs - gameState.score;
|
const startTs = endTs - gameState.score;
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "أنت على وشك بدء لعبة جديدة. هل أنت متأكد من رغبتك في المتابعة؟",
|
"confirmRestart.text": "أنت على وشك بدء لعبة جديدة. هل أنت متأكد من رغبتك في المتابعة؟",
|
||||||
"confirmRestart.title": "بدء لعبة جديدة؟",
|
"confirmRestart.title": "بدء لعبة جديدة؟",
|
||||||
"confirmRestart.yes": "إعادة تشغيل اللعبة",
|
"confirmRestart.yes": "إعادة تشغيل اللعبة",
|
||||||
|
"editor.editing.bigger": "زيادة حجم المستوى",
|
||||||
|
"editor.editing.color": "اختر لونًا من قائمة الألوان (بحد أقصى 5 لكل مستوى)",
|
||||||
|
"editor.editing.copy": "نسخ رمز المستوى",
|
||||||
|
"editor.editing.copy_help": "ألصقه في قناة #levels في Discord الخاص بنا",
|
||||||
|
"editor.editing.credit": "الاعتمادات والمصدر",
|
||||||
|
"editor.editing.credit_prompt": "أدخل عنوان URL المصدر أو شرحًا لمستواك.",
|
||||||
|
"editor.editing.delete": "حذف المستوى",
|
||||||
|
"editor.editing.down": "انزل كل الطوب إلى الأسفل",
|
||||||
|
"editor.editing.help": "ثم انقر على البلاط لتلوينه.",
|
||||||
|
"editor.editing.left": "نقل جميع الطوب إلى اليسار",
|
||||||
|
"editor.editing.play": "العب هذا المستوى",
|
||||||
|
"editor.editing.rename": "اسم المستوى",
|
||||||
|
"editor.editing.rename_prompt": "الرجاء إدخال اسم جديد للمستوى",
|
||||||
|
"editor.editing.right": "حرك كل الطوب إلى اليمين",
|
||||||
|
"editor.editing.smaller": "تقليل حجم المستوى",
|
||||||
|
"editor.editing.title": "مستوى التحرير: {{name}}",
|
||||||
|
"editor.editing.up": "حرك كل الطوب لأعلى",
|
||||||
|
"editor.help": "إنشاء مستويات مخصصة ومشاركتها لتضمينها في اللعبة.",
|
||||||
|
"editor.import": "استيراد المستوى",
|
||||||
|
"editor.import_instruction": "الصق رمز المستوى لاستيراده في قائمة المستويات الخاصة بك",
|
||||||
|
"editor.locked": "احصل على مجموع نقاط قدره {{min}} لفتح القفل",
|
||||||
|
"editor.new_level": "مستوى جديد",
|
||||||
|
"editor.title": "محرر المستويات",
|
||||||
"gameOver.creative": "لن يتم تسجيل هذا التشغيل.",
|
"gameOver.creative": "لن يتم تسجيل هذا التشغيل.",
|
||||||
"gameOver.cumulative_total": "لقد ارتفع مجموع درجاتك التراكمية من {{startTs}} إلى {{endTs}}.",
|
"gameOver.cumulative_total": "لقد ارتفع مجموع درجاتك التراكمية من {{startTs}} إلى {{endTs}}.",
|
||||||
"gameOver.lost.summary": "لقد أسقطت الكرة بعد التقاط {{score}} قطعة نقدية.",
|
"gameOver.lost.summary": "لقد أسقطت الكرة بعد التقاط {{score}} قطعة نقدية.",
|
||||||
|
|
|
@ -164,6 +164,821 @@
|
||||||
</concept_node>
|
</concept_node>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>editor</name>
|
||||||
|
<children>
|
||||||
|
<folder_node>
|
||||||
|
<name>editing</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>bigger</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>color</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>copy</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>copy_help</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>credit</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>credit_prompt</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>delete</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>down</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>help</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>left</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>play</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>rename</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>rename_prompt</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>right</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>smaller</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>title</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>up</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>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>help</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>import</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>import_instruction</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>locked</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>new_level</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>title</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>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
<name>gameOver</name>
|
<name>gameOver</name>
|
||||||
<children>
|
<children>
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "Sie sind dabei, ein neues Spiel zu beginnen. Sind Sie sicher, dass Sie weitermachen wollen?",
|
"confirmRestart.text": "Sie sind dabei, ein neues Spiel zu beginnen. Sind Sie sicher, dass Sie weitermachen wollen?",
|
||||||
"confirmRestart.title": "Ein neues Spiel beginnen?",
|
"confirmRestart.title": "Ein neues Spiel beginnen?",
|
||||||
"confirmRestart.yes": "Spiel neu starten",
|
"confirmRestart.yes": "Spiel neu starten",
|
||||||
|
"editor.editing.bigger": "Levelgröße erhöhen",
|
||||||
|
"editor.editing.color": "Wählen Sie eine Farbe aus der Farbliste (max. 5 pro Level)",
|
||||||
|
"editor.editing.copy": "Levelcode kopieren",
|
||||||
|
"editor.editing.copy_help": "Fügen Sie es in den Kanal #levels in unserem Discord ein",
|
||||||
|
"editor.editing.credit": "Credits und Quelle",
|
||||||
|
"editor.editing.credit_prompt": "Geben Sie die Quell-URL oder Erklärung Ihres Levels ein.",
|
||||||
|
"editor.editing.delete": "Ebene löschen",
|
||||||
|
"editor.editing.down": "Bewegen Sie alle Steine nach unten",
|
||||||
|
"editor.editing.help": "Klicken Sie dann auf eine Kachel, um sie einzufärben.",
|
||||||
|
"editor.editing.left": "Bewege alle Steine nach links",
|
||||||
|
"editor.editing.play": "Spiele dieses Level",
|
||||||
|
"editor.editing.rename": "Ebenenname",
|
||||||
|
"editor.editing.rename_prompt": "Bitte geben Sie einen neuen Namen für das Level ein",
|
||||||
|
"editor.editing.right": "Bewege alle Steine nach rechts",
|
||||||
|
"editor.editing.smaller": "Verringern der Levelgröße",
|
||||||
|
"editor.editing.title": "Bearbeitungsebene: {{name}}",
|
||||||
|
"editor.editing.up": "Bewegen Sie alle Steine nach oben",
|
||||||
|
"editor.help": "Erstellen Sie benutzerdefinierte Level und geben Sie sie frei, um sie in das Spiel aufzunehmen.",
|
||||||
|
"editor.import": "Importieren einer Ebene",
|
||||||
|
"editor.import_instruction": "Fügen Sie einen Levelcode ein, um ihn in Ihre Levelliste zu importieren",
|
||||||
|
"editor.locked": "Erreichen Sie eine Gesamtpunktzahl von {{min}} , um freizuschalten",
|
||||||
|
"editor.new_level": "Neues Level",
|
||||||
|
"editor.title": "Level-Editor",
|
||||||
"gameOver.creative": "Dieser Lauf wird nicht aufgezeichnet.",
|
"gameOver.creative": "Dieser Lauf wird nicht aufgezeichnet.",
|
||||||
"gameOver.cumulative_total": "Ihre kumulative Gesamtpunktzahl ist von {{startTs}} auf {{endTs}}gestiegen.",
|
"gameOver.cumulative_total": "Ihre kumulative Gesamtpunktzahl ist von {{startTs}} auf {{endTs}}gestiegen.",
|
||||||
"gameOver.lost.summary": "Du hast den Ball fallen lassen, nachdem du {{score}} Münzen gefangen hast.",
|
"gameOver.lost.summary": "Du hast den Ball fallen lassen, nachdem du {{score}} Münzen gefangen hast.",
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "You're about to start a new game. Are you sure you want to continue?",
|
"confirmRestart.text": "You're about to start a new game. Are you sure you want to continue?",
|
||||||
"confirmRestart.title": "Start a new game?",
|
"confirmRestart.title": "Start a new game?",
|
||||||
"confirmRestart.yes": "Restart game",
|
"confirmRestart.yes": "Restart game",
|
||||||
|
"editor.editing.bigger": "Increase level size",
|
||||||
|
"editor.editing.color": "Pick a color in the color list (max 5 per level)",
|
||||||
|
"editor.editing.copy": "Copy level code",
|
||||||
|
"editor.editing.copy_help": "Paste it in the #levels channel in our discord",
|
||||||
|
"editor.editing.credit": "Credits and source",
|
||||||
|
"editor.editing.credit_prompt": "Enter the source url or explanation of your level.",
|
||||||
|
"editor.editing.delete": "Delete level",
|
||||||
|
"editor.editing.down": "Move down all the bricks",
|
||||||
|
"editor.editing.help": "Then click a tile to color it.",
|
||||||
|
"editor.editing.left": "Move all bricks to the left",
|
||||||
|
"editor.editing.play": "Play this level",
|
||||||
|
"editor.editing.rename": "Level name",
|
||||||
|
"editor.editing.rename_prompt": "Please enter a new name for the level",
|
||||||
|
"editor.editing.right": "Move all bricks to the right",
|
||||||
|
"editor.editing.smaller": "Decrease level size",
|
||||||
|
"editor.editing.title": "Editing level : {{name}}",
|
||||||
|
"editor.editing.up": "Move up all the bricks",
|
||||||
|
"editor.help": "Create custom levels and share them for inclusion in the game.",
|
||||||
|
"editor.import": "Import a level",
|
||||||
|
"editor.import_instruction": "Paste a level code to import it in your level list",
|
||||||
|
"editor.locked": "Reach a total score of {{min}} to unlock",
|
||||||
|
"editor.new_level": "New level",
|
||||||
|
"editor.title": "Level Editor",
|
||||||
"gameOver.creative": "This run will not be recorded. ",
|
"gameOver.creative": "This run will not be recorded. ",
|
||||||
"gameOver.cumulative_total": "Your total cumulative score went from {{startTs}} to {{endTs}}.",
|
"gameOver.cumulative_total": "Your total cumulative score went from {{startTs}} to {{endTs}}.",
|
||||||
"gameOver.lost.summary": "You dropped the ball after catching {{score}} coins.",
|
"gameOver.lost.summary": "You dropped the ball after catching {{score}} coins.",
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "Estás a punto de empezar un nuevo partido: ¿es esto realmente lo que querías?",
|
"confirmRestart.text": "Estás a punto de empezar un nuevo partido: ¿es esto realmente lo que querías?",
|
||||||
"confirmRestart.title": "¿Empezar una nueva partida?",
|
"confirmRestart.title": "¿Empezar una nueva partida?",
|
||||||
"confirmRestart.yes": "Empezar una nueva partida",
|
"confirmRestart.yes": "Empezar una nueva partida",
|
||||||
|
"editor.editing.bigger": "Aumentar el tamaño del nivel",
|
||||||
|
"editor.editing.color": "Elige un color de la lista de colores (máximo 5 por nivel)",
|
||||||
|
"editor.editing.copy": "Copiar código de nivel",
|
||||||
|
"editor.editing.copy_help": "Pégalo en el canal #levels en nuestro discord",
|
||||||
|
"editor.editing.credit": "Créditos y fuente",
|
||||||
|
"editor.editing.credit_prompt": "Introduce la URL de origen o la explicación de tu nivel.",
|
||||||
|
"editor.editing.delete": "Eliminar nivel",
|
||||||
|
"editor.editing.down": "Baja todos los ladrillos",
|
||||||
|
"editor.editing.help": "Luego haz clic en un mosaico para colorearlo.",
|
||||||
|
"editor.editing.left": "Mueve todos los ladrillos hacia la izquierda",
|
||||||
|
"editor.editing.play": "Juega este nivel",
|
||||||
|
"editor.editing.rename": "Nombre del nivel",
|
||||||
|
"editor.editing.rename_prompt": "Por favor, introduzca un nuevo nombre para el nivel",
|
||||||
|
"editor.editing.right": "Mueve todos los ladrillos hacia la derecha",
|
||||||
|
"editor.editing.smaller": "Disminuir el tamaño del nivel",
|
||||||
|
"editor.editing.title": "Nivel de edición: {{name}}",
|
||||||
|
"editor.editing.up": "Mueve todos los ladrillos hacia arriba",
|
||||||
|
"editor.help": "Crea niveles personalizados y compártelos para incluirlos en el juego.",
|
||||||
|
"editor.import": "Importar un nivel",
|
||||||
|
"editor.import_instruction": "Pegue un código de nivel para importarlo en su lista de niveles",
|
||||||
|
"editor.locked": "Alcanza una puntuación total de {{min}} para desbloquear",
|
||||||
|
"editor.new_level": "Nuevo nivel",
|
||||||
|
"editor.title": "Editor de niveles",
|
||||||
"gameOver.creative": "Esta parte de la prueba no se grabará.",
|
"gameOver.creative": "Esta parte de la prueba no se grabará.",
|
||||||
"gameOver.cumulative_total": "Su puntuación total acumulada ha pasado de {{startTs}} a {{endTs}}.",
|
"gameOver.cumulative_total": "Su puntuación total acumulada ha pasado de {{startTs}} a {{endTs}}.",
|
||||||
"gameOver.lost.summary": "Se te ha caído la bola después de coger {{score}} monedas.",
|
"gameOver.lost.summary": "Se te ha caído la bola después de coger {{score}} monedas.",
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "Vous êtes sur le point de commencer une nouvelle partie, est-ce vraiment ce que vous vouliez ?",
|
"confirmRestart.text": "Vous êtes sur le point de commencer une nouvelle partie, est-ce vraiment ce que vous vouliez ?",
|
||||||
"confirmRestart.title": "Démarrer une nouvelle partie ?",
|
"confirmRestart.title": "Démarrer une nouvelle partie ?",
|
||||||
"confirmRestart.yes": "Commencer une nouvelle partie",
|
"confirmRestart.yes": "Commencer une nouvelle partie",
|
||||||
|
"editor.editing.bigger": "Augmenter la taille du niveau",
|
||||||
|
"editor.editing.color": "Choisissez une couleur dans la liste des couleurs (max 5 par niveau)",
|
||||||
|
"editor.editing.copy": "Copier le code du niveau",
|
||||||
|
"editor.editing.copy_help": "Collez-le dans le canal #levels de notre discord",
|
||||||
|
"editor.editing.credit": "Crédits et source",
|
||||||
|
"editor.editing.credit_prompt": "Entrez l'url source ou l'explication de votre niveau.",
|
||||||
|
"editor.editing.delete": "Supprimer le niveau",
|
||||||
|
"editor.editing.down": "Déplacez toutes les briques vers le bas",
|
||||||
|
"editor.editing.help": "Cliquez ensuite sur une tuile pour la colorier.",
|
||||||
|
"editor.editing.left": "Déplacer toutes les briques vers la gauche",
|
||||||
|
"editor.editing.play": "Jouez à ce niveau",
|
||||||
|
"editor.editing.rename": "Nom du niveau",
|
||||||
|
"editor.editing.rename_prompt": "Veuillez saisir un nouveau nom pour le niveau",
|
||||||
|
"editor.editing.right": "Déplacer toutes les briques vers la droite",
|
||||||
|
"editor.editing.smaller": "Diminuer la taille du niveau",
|
||||||
|
"editor.editing.title": "Niveau d'édition : {{name}}",
|
||||||
|
"editor.editing.up": "Déplacez toutes les briques",
|
||||||
|
"editor.help": "Créez des niveaux personnalisés et partagez-les pour les inclure dans le jeu.",
|
||||||
|
"editor.import": "Importer un niveau",
|
||||||
|
"editor.import_instruction": "Collez un code de niveau pour l'importer dans votre liste de niveaux",
|
||||||
|
"editor.locked": "Atteignez un score total de {{min}} pour débloquer",
|
||||||
|
"editor.new_level": "Nouveau niveau",
|
||||||
|
"editor.title": "Éditeur de niveau",
|
||||||
"gameOver.creative": "Cette partie de test ne sera pas enregistrée.",
|
"gameOver.creative": "Cette partie de test ne sera pas enregistrée.",
|
||||||
"gameOver.cumulative_total": "Votre score total cumulé est passé de {{startTs}} à {{endTs}}.",
|
"gameOver.cumulative_total": "Votre score total cumulé est passé de {{startTs}} à {{endTs}}.",
|
||||||
"gameOver.lost.summary": "Vous avez fait tomber la balle après avoir attrapé {{score}} pièces.",
|
"gameOver.lost.summary": "Vous avez fait tomber la balle après avoir attrapé {{score}} pièces.",
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "Вы собираетесь начать новую игру. Вы уверены, что хотите продолжить?",
|
"confirmRestart.text": "Вы собираетесь начать новую игру. Вы уверены, что хотите продолжить?",
|
||||||
"confirmRestart.title": "Начать новую игру?",
|
"confirmRestart.title": "Начать новую игру?",
|
||||||
"confirmRestart.yes": "Перезапустите игру",
|
"confirmRestart.yes": "Перезапустите игру",
|
||||||
|
"editor.editing.bigger": "Увеличить размер уровня",
|
||||||
|
"editor.editing.color": "Выберите цвет из списка цветов (максимум 5 на уровень)",
|
||||||
|
"editor.editing.copy": "Скопировать код уровня",
|
||||||
|
"editor.editing.copy_help": "Вставьте его в канал #levels в нашем Discord",
|
||||||
|
"editor.editing.credit": "Кредиты и источник",
|
||||||
|
"editor.editing.credit_prompt": "Введите исходный URL-адрес или пояснение вашего уровня.",
|
||||||
|
"editor.editing.delete": "Удалить уровень",
|
||||||
|
"editor.editing.down": "Сдвиньте все кирпичи вниз.",
|
||||||
|
"editor.editing.help": "Затем щелкните по плитке, чтобы раскрасить ее.",
|
||||||
|
"editor.editing.left": "Переместите все кирпичи влево.",
|
||||||
|
"editor.editing.play": "Пройти этот уровень",
|
||||||
|
"editor.editing.rename": "Название уровня",
|
||||||
|
"editor.editing.rename_prompt": "Введите новое название уровня.",
|
||||||
|
"editor.editing.right": "Переместите все кирпичи вправо.",
|
||||||
|
"editor.editing.smaller": "Уменьшить размер уровня",
|
||||||
|
"editor.editing.title": "Уровень редактирования: {{name}}",
|
||||||
|
"editor.editing.up": "Поднимите все кирпичи.",
|
||||||
|
"editor.help": "Создавайте собственные уровни и делитесь ими для включения в игру.",
|
||||||
|
"editor.import": "Импортировать уровень",
|
||||||
|
"editor.import_instruction": "Вставьте код уровня, чтобы импортировать его в список уровней.",
|
||||||
|
"editor.locked": "Наберите в общей сложности {{min}} очков, чтобы разблокировать",
|
||||||
|
"editor.new_level": "Новый уровень",
|
||||||
|
"editor.title": "Редактор уровней",
|
||||||
"gameOver.creative": "Этот забег не будет записываться.",
|
"gameOver.creative": "Этот забег не будет записываться.",
|
||||||
"gameOver.cumulative_total": "Ваш общий суммарный балл увеличился с {{startTs}} до {{endTs}}.",
|
"gameOver.cumulative_total": "Ваш общий суммарный балл увеличился с {{startTs}} до {{endTs}}.",
|
||||||
"gameOver.lost.summary": "Вы уронили мяч, поймав {{score}} монет.",
|
"gameOver.lost.summary": "Вы уронили мяч, поймав {{score}} монет.",
|
||||||
|
|
|
@ -3,6 +3,29 @@
|
||||||
"confirmRestart.text": "Yeni bir oyuna başlamak üzeresiniz. Devam etmek istediğinizden emin misiniz?",
|
"confirmRestart.text": "Yeni bir oyuna başlamak üzeresiniz. Devam etmek istediğinizden emin misiniz?",
|
||||||
"confirmRestart.title": "Yeni bir oyuna mı başlasam?",
|
"confirmRestart.title": "Yeni bir oyuna mı başlasam?",
|
||||||
"confirmRestart.yes": "Oyunu yeniden başlat",
|
"confirmRestart.yes": "Oyunu yeniden başlat",
|
||||||
|
"editor.editing.bigger": "Seviye boyutunu artır",
|
||||||
|
"editor.editing.color": "Renk listesinden bir renk seçin (seviye başına en fazla 5)",
|
||||||
|
"editor.editing.copy": "Kopyalama seviyesi kodu",
|
||||||
|
"editor.editing.copy_help": "Bunu Discord'umuzdaki #levels kanalına yapıştırın",
|
||||||
|
"editor.editing.credit": "Krediler ve kaynak",
|
||||||
|
"editor.editing.credit_prompt": "Seviyenizin kaynak URL'sini veya açıklamasını girin.",
|
||||||
|
"editor.editing.delete": "Seviyeyi Sil",
|
||||||
|
"editor.editing.down": "Tüm tuğlaları aşağı doğru hareket ettirin",
|
||||||
|
"editor.editing.help": "Daha sonra renklendirmek istediğiniz kutucuğa tıklayın.",
|
||||||
|
"editor.editing.left": "Tüm tuğlaları sola taşı",
|
||||||
|
"editor.editing.play": "Bu seviyeyi oyna",
|
||||||
|
"editor.editing.rename": "Seviye Adı",
|
||||||
|
"editor.editing.rename_prompt": "Lütfen seviye için yeni bir ad girin",
|
||||||
|
"editor.editing.right": "Tüm tuğlaları sağa taşı",
|
||||||
|
"editor.editing.smaller": "Seviye boyutunu azalt",
|
||||||
|
"editor.editing.title": "Düzenleme düzeyi : {{name}}",
|
||||||
|
"editor.editing.up": "Tüm tuğlaları yukarı taşı",
|
||||||
|
"editor.help": "Özel seviyeler yaratın ve bunları oyuna dahil etmek için paylaşın.",
|
||||||
|
"editor.import": "Bir seviyeyi içe aktar",
|
||||||
|
"editor.import_instruction": "Seviye listenize aktarmak için bir seviye kodunu yapıştırın",
|
||||||
|
"editor.locked": "Kilidi açmak için toplam {{min}} puanına ulaşın",
|
||||||
|
"editor.new_level": "Yeni seviye",
|
||||||
|
"editor.title": "Seviye Editörü",
|
||||||
"gameOver.creative": "Bu koşu kaydedilmeyecek.",
|
"gameOver.creative": "Bu koşu kaydedilmeyecek.",
|
||||||
"gameOver.cumulative_total": "Toplam kümülatif puanınız {{startTs}} 'dan {{endTs}}'e çıktı.",
|
"gameOver.cumulative_total": "Toplam kümülatif puanınız {{startTs}} 'dan {{endTs}}'e çıktı.",
|
||||||
"gameOver.lost.summary": " {{score}} jeton yakaladıktan sonra topu düşürdün.",
|
"gameOver.lost.summary": " {{score}} jeton yakaladıktan sonra topu düşürdün.",
|
||||||
|
@ -320,7 +343,7 @@
|
||||||
"upgrades.pierce_color.name": "Renk delme",
|
"upgrades.pierce_color.name": "Renk delme",
|
||||||
"upgrades.pierce_color.tooltip": "+{{lvl}} topun rengindeki tuğlalara hasar",
|
"upgrades.pierce_color.tooltip": "+{{lvl}} topun rengindeki tuğlalara hasar",
|
||||||
"upgrades.pierce_color.verbose_description": "Bir top aynı renkteki bir tuğlaya çarptığında, engellenmeden geçecektir. \n\nFarklı renkteki bir tuğlaya ulaştığında, onu kıracak, rengini alacak ve sekecektir.\n\nSağlam tuğlalarınız varsa, top yine de aynı renkteki bir tuğladan sekebilir.",
|
"upgrades.pierce_color.verbose_description": "Bir top aynı renkteki bir tuğlaya çarptığında, engellenmeden geçecektir. \n\nFarklı renkteki bir tuğlaya ulaştığında, onu kıracak, rengini alacak ve sekecektir.\n\nSağlam tuğlalarınız varsa, top yine de aynı renkteki bir tuğladan sekebilir.",
|
||||||
"upgrades.puck_repulse_ball.help_plural": "",
|
"upgrades.puck_repulse_ball.help_plural": "Daha güçlü itme kuvveti",
|
||||||
"upgrades.puck_repulse_ball.name": "Yumuşak iniş",
|
"upgrades.puck_repulse_ball.name": "Yumuşak iniş",
|
||||||
"upgrades.puck_repulse_ball.tooltip": "Kürek topları iter",
|
"upgrades.puck_repulse_ball.tooltip": "Kürek topları iter",
|
||||||
"upgrades.puck_repulse_ball.verbose_description": "Bir top küreğe yaklaştığında yavaşlamaya başlayacak ve hatta küreğe değmeden bile zıplamaya başlayacaktır.",
|
"upgrades.puck_repulse_ball.verbose_description": "Bir top küreğe yaklaştığında yavaşlamaya başlayacak ve hatta küreğe değmeden bile zıplamaya başlayacaktır.",
|
||||||
|
|
292
src/levelEditor.ts
Normal file
292
src/levelEditor.ts
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
import { icons, transformRawLevel } from "./loadGameData";
|
||||||
|
import { t } from "./i18n/i18n";
|
||||||
|
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
|
||||||
|
import { asyncAlert } from "./asyncAlert";
|
||||||
|
import { Palette, RawLevel } from "./types";
|
||||||
|
import { levelIconHTML } from "./levelIcon";
|
||||||
|
|
||||||
|
import _palette from "./data/palette.json";
|
||||||
|
import { restart } from "./game";
|
||||||
|
import { describeLevel } from "./game_utils";
|
||||||
|
|
||||||
|
const palette = _palette as Palette;
|
||||||
|
|
||||||
|
export function levelEditorMenuEntry() {
|
||||||
|
const min = 10000;
|
||||||
|
const disabled = getTotalScore() < min;
|
||||||
|
return {
|
||||||
|
icon: icons["icon:editor"],
|
||||||
|
text: t("editor.title"),
|
||||||
|
disabled,
|
||||||
|
help: disabled ? t("editor.locked", { min }) : t("editor.help"),
|
||||||
|
async value() {
|
||||||
|
openLevelEditorLevelsList().then();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openLevelEditorLevelsList() {
|
||||||
|
const rawList = getSettingValue("custom_levels", []) as RawLevel[];
|
||||||
|
const customLevels = rawList.map(transformRawLevel);
|
||||||
|
|
||||||
|
let choice = await asyncAlert({
|
||||||
|
title: t("editor.title"),
|
||||||
|
content: [
|
||||||
|
...customLevels.map((l, li) => ({
|
||||||
|
text: l.name,
|
||||||
|
icon: levelIconHTML(l.bricks, l.size, l.color),
|
||||||
|
value() {
|
||||||
|
editRawLevelList(li);
|
||||||
|
},
|
||||||
|
help: l.credit || describeLevel(l),
|
||||||
|
})),
|
||||||
|
{
|
||||||
|
text: t("editor.new_level"),
|
||||||
|
icon: icons["icon:editor"],
|
||||||
|
value() {
|
||||||
|
rawList.push({
|
||||||
|
color: "",
|
||||||
|
size: 6,
|
||||||
|
bricks: "____________________________________",
|
||||||
|
name: "custom level" + (rawList.length + 1),
|
||||||
|
credit: "",
|
||||||
|
});
|
||||||
|
setSettingValue("custom_levels", rawList);
|
||||||
|
editRawLevelList(rawList.length - 1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.import"),
|
||||||
|
help: t("editor.import_instruction"),
|
||||||
|
value() {
|
||||||
|
const code = prompt(t("editor.import_instruction"))?.trim();
|
||||||
|
if (code) {
|
||||||
|
let [name, credit] = code.match(/\[([^\]]+)]/gi);
|
||||||
|
|
||||||
|
let bricks = code
|
||||||
|
.split(name)[1]
|
||||||
|
.split(credit)[0]
|
||||||
|
.replace(/\s/gi, "");
|
||||||
|
name = name.slice(1, -1);
|
||||||
|
credit = credit.slice(1, -1);
|
||||||
|
name ||= "Imported on " + new Date().toISOString().slice(0, 10);
|
||||||
|
credit ||= "";
|
||||||
|
const size = Math.sqrt(bricks.length);
|
||||||
|
if (Math.floor(size) === size && size >= 2 && size <= 20) {
|
||||||
|
rawList.push({
|
||||||
|
color: automaticBackgroundColor(bricks.split("")),
|
||||||
|
size,
|
||||||
|
bricks,
|
||||||
|
name,
|
||||||
|
credit,
|
||||||
|
});
|
||||||
|
setSettingValue("custom_levels", rawList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
openLevelEditorLevelsList();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
if (typeof choice == "function") choice();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function editRawLevelList(nth: number, color = "W") {
|
||||||
|
let rawList = getSettingValue("custom_levels", []) as RawLevel[];
|
||||||
|
const level = rawList[nth];
|
||||||
|
const bricks = level.bricks.split("");
|
||||||
|
let grid = "";
|
||||||
|
for (let y = 0; y < level.size; y++) {
|
||||||
|
grid += '<div style="background: ' + (level.color || "black") + ';">';
|
||||||
|
for (let x = 0; x < level.size; x++) {
|
||||||
|
const c = bricks[y * level.size + x];
|
||||||
|
grid += `<span data-resolve-to="paint_brick:${x}:${y}" style="background: ${palette[c]}">${c == "B" ? "💣" : ""}</span>`;
|
||||||
|
}
|
||||||
|
grid += "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
const levelColors = new Set(bricks);
|
||||||
|
levelColors.delete("_");
|
||||||
|
levelColors.delete("B");
|
||||||
|
|
||||||
|
let colorList =
|
||||||
|
'<div class="palette">' +
|
||||||
|
Object.entries(palette)
|
||||||
|
.filter(([key, value]) => key !== "_")
|
||||||
|
.filter(
|
||||||
|
([key, value]) =>
|
||||||
|
levelColors.size < 5 || levelColors.has(key) || key === "B",
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
([key, value]) =>
|
||||||
|
`<span data-resolve-to="set_color:${key}" data-selected="${key == color}" style="background: ${value}">${key == "B" ? "💣" : ""}</span>`,
|
||||||
|
)
|
||||||
|
.join("") +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
const clicked = await asyncAlert<string | null>({
|
||||||
|
title: t("editor.editing.title", { name: level.name }),
|
||||||
|
content: [
|
||||||
|
t("editor.editing.color"),
|
||||||
|
colorList,
|
||||||
|
t("editor.editing.help"),
|
||||||
|
`<div class="gridEdit" style="--grid-size:${level.size};">${grid}</div>`,
|
||||||
|
|
||||||
|
{
|
||||||
|
icon: icons["icon:new_run"],
|
||||||
|
text: t("editor.editing.play"),
|
||||||
|
value: "play",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.rename"),
|
||||||
|
value: "rename",
|
||||||
|
help: level.name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.credit"),
|
||||||
|
value: "credit",
|
||||||
|
help: level.credit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.delete"),
|
||||||
|
value: "delete",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.copy"),
|
||||||
|
value: "copy",
|
||||||
|
help: t("editor.editing.copy_help"),
|
||||||
|
disabled:
|
||||||
|
!level.name ||
|
||||||
|
!level.credit ||
|
||||||
|
bricks.filter((b) => b !== "_").length < 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.bigger"),
|
||||||
|
value: "size:+1",
|
||||||
|
disabled: level.size > 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.smaller"),
|
||||||
|
value: "size:-1",
|
||||||
|
disabled: level.size < 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.left"),
|
||||||
|
value: "move:-1:0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.right"),
|
||||||
|
value: "move:1:0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.up"),
|
||||||
|
value: "move:0:-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("editor.editing.down"),
|
||||||
|
value: "move:0:1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
if (!clicked) return;
|
||||||
|
if (typeof clicked === "string") {
|
||||||
|
const [action, a, b] = clicked.split(":");
|
||||||
|
if (action == "paint_brick") {
|
||||||
|
const x = parseInt(a),
|
||||||
|
y = parseInt(b);
|
||||||
|
bricks[y * level.size + x] =
|
||||||
|
bricks[y * level.size + x] === color ? "_" : color;
|
||||||
|
level.bricks = bricks.join("");
|
||||||
|
}
|
||||||
|
if (action == "set_color") {
|
||||||
|
color = a;
|
||||||
|
}
|
||||||
|
if (action == "size") {
|
||||||
|
const newSize = level.size + parseInt(a);
|
||||||
|
const newBricks = [];
|
||||||
|
for (let y = 0; y < newSize; y++) {
|
||||||
|
for (let x = 0; x < newSize; x++) {
|
||||||
|
newBricks.push(
|
||||||
|
(x < level.size && y < level.size && bricks[y * level.size + x]) ||
|
||||||
|
"_",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level.size = newSize;
|
||||||
|
level.bricks = newBricks.join("");
|
||||||
|
}
|
||||||
|
if (action == "move") {
|
||||||
|
const dx = parseInt(a),
|
||||||
|
dy = parseInt(b);
|
||||||
|
const newBricks = [];
|
||||||
|
for (let y = 0; y < level.size; y++) {
|
||||||
|
for (let x = 0; x < level.size; x++) {
|
||||||
|
const tx = x - dx;
|
||||||
|
const ty = y - dy;
|
||||||
|
if (tx < 0 || tx >= level.size || ty < 0 || ty >= level.size) {
|
||||||
|
newBricks.push("_");
|
||||||
|
} else {
|
||||||
|
newBricks.push(bricks[ty * level.size + tx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level.bricks = newBricks.join("");
|
||||||
|
}
|
||||||
|
if (action === "play") {
|
||||||
|
restart({
|
||||||
|
level: transformRawLevel(level),
|
||||||
|
isEditorTrialRun: nth,
|
||||||
|
perks: {
|
||||||
|
base_combo: 7,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action === "copy") {
|
||||||
|
let text = "```\n[" + level.name?.replace(/\[|\]/gi, " ") + "]";
|
||||||
|
bricks.forEach((b, bi) => {
|
||||||
|
if (!(bi % level.size)) text += "\n";
|
||||||
|
text += b;
|
||||||
|
});
|
||||||
|
text +=
|
||||||
|
"\n[" +
|
||||||
|
(level.credit?.replace(/\[|\]/gi, " ") || "Missing credits!") +
|
||||||
|
"]\n```";
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
// return
|
||||||
|
}
|
||||||
|
if (action === "rename") {
|
||||||
|
const name = prompt(t("editor.editing.rename_prompt"), level.name);
|
||||||
|
if (name) {
|
||||||
|
level.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action === "credit") {
|
||||||
|
const credit = prompt(
|
||||||
|
t("editor.editing.credit_prompt"),
|
||||||
|
level.credit || "",
|
||||||
|
);
|
||||||
|
if (credit !== "null") {
|
||||||
|
level.credit = credit || "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action === "delete") {
|
||||||
|
rawList = rawList.filter((l, li) => li !== nth);
|
||||||
|
setSettingValue("custom_levels", rawList);
|
||||||
|
openLevelEditorLevelsList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level.color = automaticBackgroundColor(bricks);
|
||||||
|
|
||||||
|
setSettingValue("custom_levels", rawList);
|
||||||
|
editRawLevelList(nth, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function automaticBackgroundColor(bricks: string[]) {
|
||||||
|
return bricks.filter((b) => b === "g").length >
|
||||||
|
bricks.filter((b) => b !== "_").length * 0.05
|
||||||
|
? "#115988"
|
||||||
|
: "";
|
||||||
|
}
|
|
@ -13,28 +13,29 @@ const rawLevelsList = _rawLevelsList as RawLevel[];
|
||||||
export const appVersion = _appVersion as string;
|
export const appVersion = _appVersion as string;
|
||||||
|
|
||||||
export const icons = {} as { [k: string]: string };
|
export const icons = {} as { [k: string]: string };
|
||||||
export const allLevelsAndIcons = rawLevelsList
|
|
||||||
.map((level, i) => {
|
export function transformRawLevel(level: RawLevel) {
|
||||||
const bricks = level.bricks
|
const bricks = level.bricks
|
||||||
.split("")
|
.split("")
|
||||||
.map((c) => palette[c])
|
.map((c) => palette[c])
|
||||||
.slice(0, level.size * level.size);
|
.slice(0, level.size * level.size);
|
||||||
const bricksCount = bricks.filter((i) => i).length;
|
const bricksCount = bricks.filter((i) => i).length;
|
||||||
const icon = levelIconHTML(bricks, level.size, level.color);
|
const icon = levelIconHTML(bricks, level.size, level.color);
|
||||||
icons[level.name] = icon;
|
icons[level.name] = icon;
|
||||||
return {
|
return {
|
||||||
...level,
|
...level,
|
||||||
bricks,
|
bricks,
|
||||||
bricksCount,
|
bricksCount,
|
||||||
icon,
|
icon,
|
||||||
color: level.color || "#000000",
|
color: level.color || "#000000",
|
||||||
svg: getLevelBackground(level),
|
svg: getLevelBackground(level),
|
||||||
};
|
sortKey: ((Math.random() + 3) / 3.5) * bricksCount,
|
||||||
})
|
};
|
||||||
.map((l, li) => ({
|
}
|
||||||
...l,
|
|
||||||
sortKey: ((Math.random() + 3) / 3.5) * l.bricksCount,
|
export const allLevelsAndIcons = rawLevelsList.map(
|
||||||
})) as Level[];
|
transformRawLevel,
|
||||||
|
) as Level[];
|
||||||
|
|
||||||
export const allLevels = allLevelsAndIcons.filter(
|
export const allLevels = allLevelsAndIcons.filter(
|
||||||
(l) => !l.name.startsWith("icon:"),
|
(l) => !l.name.startsWith("icon:"),
|
||||||
|
|
|
@ -28,12 +28,12 @@ export function getRunLevels(
|
||||||
(l, li) =>
|
(l, li) =>
|
||||||
unlockedBefore.has(l.name) || !reasonLevelIsLocked(li, history, false),
|
unlockedBefore.has(l.name) || !reasonLevelIsLocked(li, history, false),
|
||||||
);
|
);
|
||||||
const firstLevel = allLevelsAndIcons.filter(
|
const firstLevel = params?.level
|
||||||
(l) => l.name == (params?.level || "icon:" + randomGift),
|
? [params.level]
|
||||||
);
|
: allLevelsAndIcons.filter((l) => l.name == "icon:" + randomGift);
|
||||||
|
|
||||||
const restInRandomOrder = unlocked
|
const restInRandomOrder = unlocked
|
||||||
.filter((l) => l.name !== params?.level)
|
.filter((l) => l.name !== params?.level?.name)
|
||||||
.filter((l) => l.name !== params?.levelToAvoid)
|
.filter((l) => l.name !== params?.levelToAvoid)
|
||||||
.sort(() => Math.random() - 0.5);
|
.sort(() => Math.random() - 0.5);
|
||||||
|
|
||||||
|
@ -141,8 +141,9 @@ export function newGameState(params: RunParams): GameState {
|
||||||
creative:
|
creative:
|
||||||
params?.computer_controlled ||
|
params?.computer_controlled ||
|
||||||
sumOfValues(params.perks) > 1 ||
|
sumOfValues(params.perks) > 1 ||
|
||||||
(params.level && !params.level.startsWith("icon:")),
|
(params.level && !params.level.name.startsWith("icon:")),
|
||||||
computer_controlled: params?.computer_controlled || false,
|
computer_controlled: params?.computer_controlled || false,
|
||||||
|
isEditorTrialRun: params?.isEditorTrialRun,
|
||||||
};
|
};
|
||||||
resetBalls(gameState);
|
resetBalls(gameState);
|
||||||
|
|
||||||
|
|
5
src/types.d.ts
vendored
5
src/types.d.ts
vendored
|
@ -7,7 +7,6 @@ export type RawLevel = {
|
||||||
name: string;
|
name: string;
|
||||||
size: number;
|
size: number;
|
||||||
bricks: string;
|
bricks: string;
|
||||||
svg: number | null;
|
|
||||||
color: string;
|
color: string;
|
||||||
credit?: string;
|
credit?: string;
|
||||||
};
|
};
|
||||||
|
@ -282,14 +281,16 @@ export type GameState = {
|
||||||
rerolls: number;
|
rerolls: number;
|
||||||
creative: boolean;
|
creative: boolean;
|
||||||
computer_controlled: boolean;
|
computer_controlled: boolean;
|
||||||
|
isEditorTrialRun?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RunParams = {
|
export type RunParams = {
|
||||||
level?: string;
|
level?: Level;
|
||||||
levelToAvoid?: string;
|
levelToAvoid?: string;
|
||||||
perkToAvoid?: PerkId;
|
perkToAvoid?: PerkId;
|
||||||
perks?: Partial<PerksMap>;
|
perks?: Partial<PerksMap>;
|
||||||
computer_controlled?: boolean;
|
computer_controlled?: boolean;
|
||||||
|
isEditorTrialRun?: number;
|
||||||
};
|
};
|
||||||
export type OptionDef = {
|
export type OptionDef = {
|
||||||
default: boolean;
|
default: boolean;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue