From b3d1204d9c3c9274248fabd1cecd4ae36bd30916 Mon Sep 17 00:00:00 2001 From: tobspr Date: Tue, 25 May 2021 09:19:57 +0200 Subject: [PATCH] Wegame version & DLC Translation in Chinese --- .gitignore | 1 + gulp/gulpfile.js | 60 +++- gulp/js.js | 47 ++++ gulp/standalone.js | 5 + gulp/webpack.config.js | 3 +- gulp/webpack.production.config.js | 2 + res/logo_wegame.png | Bin 0 -> 40555 bytes src/js/core/background_resources_loader.js | 7 +- src/js/game/modes/regular.js | 18 +- src/js/globals.d.ts | 1 + src/js/platform/api.js | 5 +- src/js/platform/browser/game_analytics.js | 8 + src/js/states/about.js | 5 +- src/js/states/main_menu.js | 57 ++-- src/js/states/mobile_warning.js | 5 +- src/js/states/preload.js | 15 +- src/js/states/settings.js | 8 +- translations/base-zh-CN.yaml | 307 ++++++++++----------- 18 files changed, 332 insertions(+), 222 deletions(-) create mode 100644 res/logo_wegame.png diff --git a/.gitignore b/.gitignore index be6071af..cdade93f 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ res_built gulp/runnable-texturepacker.jar tmp_standalone_files tmp_standalone_files_china +tmp_standalone_files_wegame # Local config config.local.js diff --git a/gulp/gulpfile.js b/gulp/gulpfile.js index 06bb627b..b1ef8817 100644 --- a/gulp/gulpfile.js +++ b/gulp/gulpfile.js @@ -139,7 +139,12 @@ gulp.task("main.webserver", () => { ); }); -function serve({ standalone, chineseVersion = false }) { +/** + * + * @param {object} param0 + * @param {"web"|"standalone"|"china"|"wegame"} param0.version + */ +function serve({ version = "web" }) { browserSync.init({ server: buildFolder, port: 3005, @@ -163,7 +168,7 @@ function serve({ standalone, chineseVersion = false }) { gulp.watch(["../src/**/*.scss"], gulp.series("css.dev")); // Watch .html files, those trigger a html rebuild - gulp.watch("../src/**/*.html", gulp.series(standalone ? "html.standalone-dev" : "html.dev")); + gulp.watch("../src/**/*.html", gulp.series(version === "web" ? "html.dev" : "html.standalone-dev")); // Watch sound files // gulp.watch(["../res_raw/sounds/**/*.mp3", "../res_raw/sounds/**/*.wav"], gulp.series("sounds.dev")); @@ -199,14 +204,25 @@ function serve({ standalone, chineseVersion = false }) { return gulp.src(path).pipe(browserSync.reload({ stream: true })); }); - // Start the webpack watching server (Will never return) - if (standalone) { - gulp.series("js.standalone-dev.watch")(() => true); - } else { - if (chineseVersion) { - gulp.series("china.js.dev.watch")(() => true); - } else { + switch (version) { + case "web": { gulp.series("js.dev.watch")(() => true); + break; + } + case "standalone": { + gulp.series("js.standalone-dev.watch")(() => true); + break; + } + case "china": { + gulp.series("china.js.dev.watch")(() => true); + break; + } + case "wegame": { + gulp.series("wegame.js.dev.watch")(() => true); + break; + } + default: { + throw new Error("Unknown version " + version); } } } @@ -294,7 +310,7 @@ gulp.task( // Builds everything (standalone-prod) -for (const prefix of ["", "china."]) { +for (const prefix of ["", "china.", "wegame."]) { gulp.task( prefix + "step.standalone-prod.code", gulp.series("sounds.fullbuildHQ", "translations.fullBuild", prefix + "js.standalone-prod") @@ -327,25 +343,41 @@ gulp.task( ); gulp.task("main.deploy.prod", gulp.series("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod")); gulp.task("main.deploy.all", gulp.series("main.deploy.staging", "main.deploy.prod")); + +// steam gulp.task("regular.main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod")); + +// china gulp.task( "china.main.standalone", gulp.series("china.build.standalone-prod", "china.standalone.package.prod") ); -gulp.task("standalone.all", gulp.series("regular.main.standalone", "china.main.standalone")); + +// wegame +gulp.task( + "wegame.main.standalone", + gulp.series("wegame.build.standalone-prod", "wegame.standalone.package.prod") +); + +// all (except wegame) +gulp.task("standalone.all", gulp.series("regular.main.standalone", "wegame.main.standalone")); // Live-development gulp.task( "main.serveDev", - gulp.series("build.dev", () => serve({ standalone: false })) + gulp.series("build.dev", () => serve({ version: "web" })) ); gulp.task( "main.serveStandalone", - gulp.series("build.standalone.dev", () => serve({ standalone: true })) + gulp.series("build.standalone.dev", () => serve({ version: "standalone" })) ); gulp.task( "china.main.serveDev", - gulp.series("build.dev", () => serve({ standalone: false, chineseVersion: true })) + gulp.series("build.dev", () => serve({ version: "china" })) +); +gulp.task( + "wegame.main.serveDev", + gulp.series("build.dev", () => serve({ version: "wegame" })) ); gulp.task("default", gulp.series("main.serveDev")); diff --git a/gulp/js.js b/gulp/js.js index cfaedb8c..b6e3ce16 100644 --- a/gulp/js.js +++ b/gulp/js.js @@ -59,6 +59,36 @@ function gulptasksJS($, gulp, buildFolder, browserSync) { .pipe(gulp.dest(buildFolder)); }); + //// DEV WEGAME + + gulp.task("wegame.js.dev.watch", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + watch: true, + wegameVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("wegame.js.dev", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + wegameVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + //// STAGING gulp.task("js.staging.transpiled", () => { @@ -208,6 +238,23 @@ function gulptasksJS($, gulp, buildFolder, browserSync) { ) .pipe(gulp.dest(buildFolder)); }); + + gulp.task("wegame.js.standalone-prod", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: false, + environment: "prod", + es6: true, + standalone: true, + wegameVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); } module.exports = { diff --git a/gulp/standalone.js b/gulp/standalone.js index ffec8539..914fb95a 100644 --- a/gulp/standalone.js +++ b/gulp/standalone.js @@ -21,6 +21,11 @@ function gulptasksStandalone($, gulp) { suffix: "china", taskPrefix: "china.", }, + { + tempDestDir: path.join(__dirname, "..", "tmp_standalone_files_wegame"), + suffix: "wegame", + taskPrefix: "wegame.", + }, ]; for (const { tempDestDir, suffix, taskPrefix } of targets) { diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js index 3f666e73..14987cfa 100644 --- a/gulp/webpack.config.js +++ b/gulp/webpack.config.js @@ -6,7 +6,7 @@ const { getRevision, getVersion, getAllResourceImages } = require("./buildutils" const lzString = require("lz-string"); const CircularDependencyPlugin = require("circular-dependency-plugin"); -module.exports = ({ watch = false, standalone = false, chineseVersion = false }) => { +module.exports = ({ watch = false, standalone = false, chineseVersion = false, wegameVersion = false }) => { return { mode: "development", devtool: "cheap-source-map", @@ -35,6 +35,7 @@ module.exports = ({ watch = false, standalone = false, chineseVersion = false }) lzString.compressToEncodedURIComponent("http://localhost:10005/v1") ), G_CHINA_VERSION: JSON.stringify(chineseVersion), + G_WEGAME_VERSION: JSON.stringify(wegameVersion), G_IS_DEV: "true", G_IS_RELEASE: "false", G_IS_MOBILE_APP: "false", diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js index dc9559b4..fd7551e0 100644 --- a/gulp/webpack.production.config.js +++ b/gulp/webpack.production.config.js @@ -17,6 +17,7 @@ module.exports = ({ isBrowser = true, mobileApp = false, chineseVersion = false, + wegameVersion = false, }) => { const globalDefs = { assert: enableAssert ? "window.assert" : "false && window.assert", @@ -25,6 +26,7 @@ module.exports = ({ G_IS_DEV: "false", G_CHINA_VERSION: JSON.stringify(chineseVersion), + G_WEGAME_VERSION: JSON.stringify(wegameVersion), G_IS_RELEASE: environment === "prod" ? "true" : "false", G_IS_STANDALONE: standalone ? "true" : "false", G_IS_BROWSER: isBrowser ? "true" : "false", diff --git a/res/logo_wegame.png b/res/logo_wegame.png new file mode 100644 index 0000000000000000000000000000000000000000..eb7d35fe569a43e9a0ed427cc7dbcfc8e10ef269 GIT binary patch literal 40555 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 E03k4*{Qv*} literal 0 HcmV?d00001 diff --git a/src/js/core/background_resources_loader.js b/src/js/core/background_resources_loader.js index 46ec20e6..316619c4 100644 --- a/src/js/core/background_resources_loader.js +++ b/src/js/core/background_resources_loader.js @@ -12,8 +12,13 @@ import { cachebust } from "./cachebust"; const logger = createLogger("background_loader"); +export function getLogoSprite() { + // @todo: ugh, in a hurry + return G_WEGAME_VERSION ? "logo_wegame.png" : G_CHINA_VERSION ? "logo_cn.png" : "logo.png"; +} + const essentialMainMenuSprites = [ - G_CHINA_VERSION ? "logo_cn.png" : "logo.png", + getLogoSprite(), ...G_ALL_UI_IMAGES.filter(src => src.startsWith("ui/") && src.indexOf(".gif") < 0), ]; const essentialMainMenuSounds = [ diff --git a/src/js/game/modes/regular.js b/src/js/game/modes/regular.js index 8153dca9..6a939d1a 100644 --- a/src/js/game/modes/regular.js +++ b/src/js/game/modes/regular.js @@ -66,6 +66,8 @@ const preparementShape = "CpRpCp--:SwSwSwSw"; // Tiers need % of the previous tier as requirement too const tierGrowth = 2.5; +const chinaShapes = G_WEGAME_VERSION || G_CHINA_VERSION; + /** * Generates all upgrades * @returns {Object} */ @@ -144,7 +146,7 @@ function generateUpgrades(limitedVersion = false) { { required: [ { - shape: G_CHINA_VERSION + shape: chinaShapes ? "CyCyCyCy:CyCyCyCy:RyRyRyRy:RuRuRuRu" : "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 50000, @@ -205,7 +207,7 @@ function generateUpgrades(limitedVersion = false) { { required: [ { - shape: G_CHINA_VERSION ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", + shape: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", amount: 6500, }, ], @@ -382,7 +384,7 @@ export function generateLevelDefinitions(limitedVersion = false) { // 13 // Tunnel Tier 2 { - shape: G_CHINA_VERSION ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", // painting t3 + shape: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", // painting t3 required: 3800, reward: enumHubGoalRewards.reward_underground_belt_tier_2, }, @@ -391,7 +393,7 @@ export function generateLevelDefinitions(limitedVersion = false) { ...(limitedVersion ? [ { - shape: G_CHINA_VERSION ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", + shape: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", required: 0, reward: enumHubGoalRewards.reward_demo_end, }, @@ -425,7 +427,7 @@ export function generateLevelDefinitions(limitedVersion = false) { // 17 // Double painter { - shape: G_CHINA_VERSION + shape: chinaShapes ? "CyCyCyCy:CyCyCyCy:RyRyRyRy:RuRuRuRu" : "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants) required: 20000, @@ -467,7 +469,7 @@ export function generateLevelDefinitions(limitedVersion = false) { // 22 // Constant signal { - shape: G_CHINA_VERSION + shape: chinaShapes ? "RrSySrSy:RyCrCwCr:CyCyRyCy" : "Cg----Cr:Cw----Cw:Sy------:Cy----Cy", required: 25000, @@ -477,7 +479,7 @@ export function generateLevelDefinitions(limitedVersion = false) { // 23 // Display { - shape: G_CHINA_VERSION + shape: chinaShapes ? "CrCrCrCr:CwCwCwCw:WwWwWwWw:CrCrCrCr" : "CcSyCcSy:SyCcSyCc:CcSyCcSy", required: 25000, @@ -486,7 +488,7 @@ export function generateLevelDefinitions(limitedVersion = false) { // 24 Logic gates { - shape: G_CHINA_VERSION + shape: chinaShapes ? "Su----Su:RwRwRwRw:Cu----Cu:CwCwCwCw" : "CcRcCcRc:RwCwRwCw:Sr--Sw--:CyCyCyCy", required: 25000, diff --git a/src/js/globals.d.ts b/src/js/globals.d.ts index 5bb3bbba..bf870fab 100644 --- a/src/js/globals.d.ts +++ b/src/js/globals.d.ts @@ -20,6 +20,7 @@ declare const G_ALL_UI_IMAGES: Array; declare const G_IS_RELEASE: boolean; declare const G_CHINA_VERSION: boolean; +declare const G_WEGAME_VERSION: boolean; // Polyfills declare interface String { diff --git a/src/js/platform/api.js b/src/js/platform/api.js index 2219541e..99c61a20 100644 --- a/src/js/platform/api.js +++ b/src/js/platform/api.js @@ -101,7 +101,10 @@ export class ClientAPI { */ apiTryLogin() { if (!G_IS_STANDALONE) { - return Promise.reject("Not possible outside of standalone."); + const token = window.prompt( + "Please enter the auth token for the puzzle DLC (If you have none, you can't login):" + ); + return Promise.resolve({ token }); } const renderer = getIPCRenderer(); diff --git a/src/js/platform/browser/game_analytics.js b/src/js/platform/browser/game_analytics.js index 65fc5080..e4226ae0 100644 --- a/src/js/platform/browser/game_analytics.js +++ b/src/js/platform/browser/game_analytics.js @@ -53,6 +53,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface { initialize() { this.syncKey = null; + if (G_WEGAME_VERSION) { + return; + } + setInterval(() => this.sendTimePoints(), 60 * 1000); // Retrieve sync key from player @@ -136,6 +140,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface { * @param {string} value */ sendGameEvent(category, value) { + if (G_WEGAME_VERSION) { + return; + } + if (!this.syncKey) { logger.warn("Can not send event due to missing sync key"); return; diff --git a/src/js/states/about.js b/src/js/states/about.js index b8f465b7..4380b02c 100644 --- a/src/js/states/about.js +++ b/src/js/states/about.js @@ -2,6 +2,7 @@ import { TextualGameState } from "../core/textual_game_state"; import { T } from "../translations"; import { THIRDPARTY_URLS } from "../core/config"; import { cachebust } from "../core/cachebust"; +import { getLogoSprite } from "../core/background_resources_loader"; export class AboutState extends TextualGameState { constructor() { @@ -15,9 +16,7 @@ export class AboutState extends TextualGameState { getMainContentHTML() { return `

- shapez.io Logo + shapez.io Logo
${T.about.body diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index 49fae145..38a22d4e 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -1,3 +1,4 @@ +import { getLogoSprite } from "../core/background_resources_loader"; import { cachebust } from "../core/cachebust"; import { A_B_TESTING_LINK_TYPE, globalConfig, THIRDPARTY_URLS } from "../core/config"; import { GameState } from "../core/game_state"; @@ -49,7 +50,7 @@ export class MainMenuState extends GameState { return `
${ - G_CHINA_VERSION + G_CHINA_VERSION || G_WEGAME_VERSION ? "" : `` } @@ -69,10 +70,12 @@ export class MainMenuState extends GameState {
+ ${ + G_WEGAME_VERSION + ? "" + : ` +
+ ` + } `; } @@ -263,7 +272,7 @@ export class MainMenuState extends GameState { this.trackClicks(qs(".settingsButton"), this.onSettingsButtonClicked); - if (!G_CHINA_VERSION) { + if (!G_CHINA_VERSION && !G_WEGAME_VERSION) { this.trackClicks(qs(".languageChoose"), this.onLanguageChooseClicked); this.trackClicks(qs(".redditLink"), this.onRedditClicked); this.trackClicks(qs(".changelog"), this.onChangelogClicked); @@ -283,14 +292,16 @@ export class MainMenuState extends GameState { } const discordLink = this.htmlElement.querySelector(".discordLink"); - this.trackClicks( - discordLink, - () => { - this.app.analytics.trackUiClick("main_menu_link_discord"); - this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.discord); - }, - { preventClick: true } - ); + if (discordLink) { + this.trackClicks( + discordLink, + () => { + this.app.analytics.trackUiClick("main_menu_link_discord"); + this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.discord); + }, + { preventClick: true } + ); + } const githubLink = this.htmlElement.querySelector(".githubLink"); if (githubLink) { @@ -305,9 +316,15 @@ export class MainMenuState extends GameState { } const producerLink = this.htmlElement.querySelector(".producerLink"); - this.trackClicks(producerLink, () => this.app.platformWrapper.openExternalLink("https://tobspr.io"), { - preventClick: true, - }); + if (producerLink) { + this.trackClicks( + producerLink, + () => this.app.platformWrapper.openExternalLink("https://tobspr.io"), + { + preventClick: true, + } + ); + } const puzzleModeButton = qs(".puzzleDlcPlayButton"); if (puzzleModeButton) { diff --git a/src/js/states/mobile_warning.js b/src/js/states/mobile_warning.js index ce29b68b..0a54aa5a 100644 --- a/src/js/states/mobile_warning.js +++ b/src/js/states/mobile_warning.js @@ -1,6 +1,7 @@ import { GameState } from "../core/game_state"; import { cachebust } from "../core/cachebust"; import { THIRDPARTY_URLS } from "../core/config"; +import { getLogoSprite } from "../core/background_resources_loader"; export class MobileWarningState extends GameState { constructor() { @@ -10,9 +11,7 @@ export class MobileWarningState extends GameState { getInnerHTML() { return ` - +

I'm sorry, but shapez.io is not available on mobile devices yet! diff --git a/src/js/states/preload.js b/src/js/states/preload.js index 40261b7d..b0dbda86 100644 --- a/src/js/states/preload.js +++ b/src/js/states/preload.js @@ -1,4 +1,5 @@ import { CHANGELOG } from "../changelog"; +import { getLogoSprite } from "../core/background_resources_loader"; import { cachebust } from "../core/cachebust"; import { globalConfig } from "../core/config"; import { GameState } from "../core/game_state"; @@ -19,7 +20,7 @@ export class PreloadState extends GameState { return `

- ${G_CHINA_VERSION ? "加载中" : "Booting"} + ${G_CHINA_VERSION || G_WEGAME_VERSION ? "加载中" : "Booting"}
@@ -112,7 +113,7 @@ export class PreloadState extends GameState { .then(() => this.setStatus("Initializing language")) .then(() => { - if (G_CHINA_VERSION) { + if (G_CHINA_VERSION || G_WEGAME_VERSION) { return this.app.settings.updateLanguage("zh-CN"); } @@ -164,7 +165,7 @@ export class PreloadState extends GameState { return; } - if (G_CHINA_VERSION) { + if (G_CHINA_VERSION || G_WEGAME_VERSION) { return; } @@ -227,7 +228,7 @@ export class PreloadState extends GameState { } update() { - if (G_CHINA_VERSION) { + if (G_CHINA_VERSION || G_WEGAME_VERSION) { return; } const now = performance.now(); @@ -260,7 +261,7 @@ export class PreloadState extends GameState { */ setStatus(text) { logger.log("✅ " + text); - if (G_CHINA_VERSION) { + if (G_CHINA_VERSION || G_WEGAME_VERSION) { return Promise.resolve(); } this.currentStatus = text; @@ -278,9 +279,7 @@ export class PreloadState extends GameState { subElement.innerHTML = `
diff --git a/src/js/states/settings.js b/src/js/states/settings.js index a817de47..85b31fbb 100644 --- a/src/js/states/settings.js +++ b/src/js/states/settings.js @@ -30,7 +30,7 @@ export class SettingsState extends TextualGameState {
${ - G_CHINA_VERSION + G_CHINA_VERSION || G_WEGAME_VERSION ? "" : ` @@ -74,7 +74,7 @@ export class SettingsState extends TextualGameState { for (let i = 0; i < allApplicationSettings.length; ++i) { const setting = allApplicationSettings[i]; - if (G_CHINA_VERSION && setting.id === "language") { + if ((G_CHINA_VERSION || G_WEGAME_VERSION) && setting.id === "language") { continue; } @@ -105,7 +105,7 @@ export class SettingsState extends TextualGameState { onEnter(payload) { this.renderBuildText(); - if (!G_CHINA_VERSION) { + if (!G_CHINA_VERSION && !G_WEGAME_VERSION) { this.trackClicks(this.htmlElement.querySelector(".about"), this.onAboutClicked, { preventDefault: false, }); @@ -144,7 +144,7 @@ export class SettingsState extends TextualGameState { initSettings() { allApplicationSettings.forEach(setting => { - if (G_CHINA_VERSION && setting.id === "language") { + if ((G_CHINA_VERSION || G_WEGAME_VERSION) && setting.id === "language") { return; } diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index 42bb60d9..8cf6d1fd 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -68,11 +68,10 @@ mainMenu: madeBy: 作者: subreddit: Reddit savegameUnnamed: 存档未命名 - puzzleMode: Puzzle Mode - back: Back - puzzleDlcText: Do you enjoy compacting and optimizing factories? Get the Puzzle - DLC now on Steam for even more fun! - puzzleDlcWishlist: Wishlist now! + puzzleMode: 谜题模式 + back: 返回 + puzzleDlcText: 持续优化,追求极致效率。在限定空间内使用有限的设施来创造图形!《异形工厂》(Shapez.io)的首个DLC“谜题挑战者”将会给大家带来更烧脑、更自由的全新挑战! + puzzleDlcWishlist: 添加愿望单! dialogs: buttons: ok: 确认 @@ -86,9 +85,9 @@ dialogs: viewUpdate: 查看更新 showUpgrades: 显示设施升级 showKeybindings: 显示按键设置 - retry: Retry - continue: Continue - playOffline: Play Offline + retry: 重试 + continue: 继续 + playOffline: 离线游戏 importSavegameError: title: 读取错误 text: 未能读取您的存档: @@ -136,13 +135,15 @@ dialogs: desc: 您还没有解锁蓝图功能!通过第12关的挑战后可解锁蓝图。 keybindingsIntroduction: title: 实用快捷键 - desc: "这个游戏有很多有用的快捷键设定。 以下是其中的一些介绍,记得在按键设置中查看其他按键设定!

+ desc: + "这个游戏有很多有用的快捷键设定。 以下是其中的一些介绍,记得在按键设置中查看其他按键设定!

CTRL键 + 拖动:选择区域以复制或删除。
SHIFT键: 按住以放置多个同一种设施。
ALT键: 反向放置传送带。
" createMarker: title: 创建地图标记 - desc: 填写一个有意义的名称, 还可以同时包含一个形状的 短代码 (您可以 点击这里 + desc: + 填写一个有意义的名称, 还可以同时包含一个形状的 短代码 (您可以 点击这里 生成短代码) titleEdit: 编辑地图标记 markerDemoLimit: @@ -170,66 +171,59 @@ dialogs: title: 教程 desc: 这个关卡有英语版本的视频攻略! 您想查看这个视频攻略吗?? editConstantProducer: - title: Set Item + title: 设置项目 puzzleLoadFailed: - title: Puzzles failed to load - desc: "Unfortunately the puzzles could not be loaded:" + title: 谜题载入失败 + desc: "很遗憾,谜题未能载入:" submitPuzzle: - title: Submit Puzzle - descName: "Give your puzzle a name:" - descIcon: "Please enter a unique short key, which will be shown as the icon of - your puzzle (You can generate them here, or choose one - of the randomly suggested shapes below):" - placeholderName: Puzzle Title + title: 提交谜题 + descName: "给您的谜题设定名称:" + descIcon: + "请输入唯一的短代码,它将显示为标志您的谜题的图标( 在此生成,或者从以下随机推荐的图形中选择一个): + " + placeholderName: 谜题标题 puzzleResizeBadBuildings: - title: Resize not possible - desc: You can't make the zone any smaller, because then some buildings would be - outside the zone. + title: 无法调整大小 + desc: 您无法使这块区域变得更小,否则有些设施将会超出区域范围。 puzzleLoadError: - title: Bad Puzzle - desc: "The puzzle failed to load:" + title: 谜题出错 + desc: "谜题载入失败:" offlineMode: - title: Offline Mode - desc: We couldn't reach the servers, so the game has to run in offline mode. - Please make sure you have an active internect connection. + title: 离线模式 + desc: 访问服务器失败,游戏只能在离线模式下进行。请确认您的网络连接正常。 puzzleDownloadError: - title: Download Error - desc: "Failed to download the puzzle:" + title: 下载出错 + desc: "无法下载谜题:" puzzleSubmitError: - title: Submission Error - desc: "Failed to submit your puzzle:" + title: 提交出错 + desc: "无法提交您的谜题:" puzzleSubmitOk: - title: Puzzle Published - desc: Congratulations! Your puzzle has been published and can now be played by - others. You can now find it in the "My puzzles" section. + title: 谜题已发布 + desc: 恭喜!您所创造的谜题已成功发布,别的玩家已经可以对您的谜题发起挑战!您可以在"我的谜题"部分找到您发布的谜题。 puzzleCreateOffline: - title: Offline Mode - desc: Since you are offline, you will not be able to save and/or publish your - puzzle. Would you still like to continue? + title: 离线模式 + desc: 由于您现在没有连接互联网,所以您将无法保存或发布您的谜题。是否仍要继续? puzzlePlayRegularRecommendation: - title: Recommendation - desc: I strongly recommend playing the normal game to level 12 - before attempting the puzzle DLC, otherwise you may encounter - mechanics not yet introduced. Do you still want to continue? + title: 游戏建议 + desc: 强烈建议您在至少完成本体第12关后再尝试体验“谜题挑战者”DLC,否则您可能在游戏过程中遇到困难,您是否仍要继续? puzzleShare: - title: Short Key Copied - desc: The short key of the puzzle () has been copied to your clipboard! It - can be entered in the puzzle menu to access the puzzle. + title: 短代码已复制 + desc: 此谜题的短代码()已经复制到了您的剪贴板!您可以在谜题菜单中输入短代码以快速访问对应谜题。 puzzleReport: - title: Report Puzzle + title: 上报谜题 options: - profane: Profane - unsolvable: Not solvable + profane: 污言秽语 + unsolvable: 无法完成 trolling: Trolling puzzleReportComplete: - title: Thank you for your feedback! - desc: The puzzle has been flagged. + title: 感谢您的反馈! + desc: 此谜题已标记! puzzleReportError: - title: Failed to report - desc: "Your report could not get processed:" + title: 上报失败 + desc: "无法处理您的上报:" puzzleLoadShortKey: - title: Enter short key - desc: Enter the short key of the puzzle to load it. + title: 输入短代码 + desc: 输入此谜题的短代码以载入。 ingame: keybindingsOverlay: moveMap: 移动地图 @@ -251,7 +245,7 @@ ingame: clearSelection: 取消选择 pipette: 吸取器 switchLayers: 切换层 - clearBelts: Clear belts + clearBelts: 清除传送带 buildingPlacement: cycleBuildingVariants: 按 键以选择设施的变型体。 hotkeyLabel: "快捷键: " @@ -315,15 +309,18 @@ ingame: hints: 1_1_extractor: 在圆形上放置一个开采器来获取圆形!

提示:按下鼠标左键选中开采器 1_2_conveyor: 用传送带将您的开采器连接到中心基地上!

提示:选中传送带按下鼠标左键可拖动布置传送带! - 1_3_expand: 您可以放置更多的开采器传送带来更有效率地完成关卡目标。

+ 1_3_expand: + 您可以放置更多的开采器传送带来更有效率地完成关卡目标。

提示:按住 SHIFT 键可放置多个开采器,注意用R 键可旋转开采器的出口方向,确保开采的图形可以顺利传送。 2_1_place_cutter: 现在放置一个切割器,这个设施可把圆形切成两半!

注意:无论如何放置,切割机总是从上到下切割。 - 2_2_place_trash: 使用切割机后产生的废弃图形会导致堵塞

注意使用垃圾桶清除当前 + 2_2_place_trash: + 使用切割机后产生的废弃图形会导致堵塞

注意使用垃圾桶清除当前 (!) 不需要的废物。 2_3_more_cutters: 干的好!现在放置2个以上的切割机来加快当前缓慢的过程!

提示:用快捷键0-9可以快速选择各项设施! - 3_1_rectangles: 现在让我们开采一些矩形!找到矩形地带放置4个开采器并将它们用传送带连接到中心基地。

+ 3_1_rectangles: + 现在让我们开采一些矩形!找到矩形地带放置4个开采器并将它们用传送带连接到中心基地。

提示:选中传送带后按住SHIFT键可快速准确地规划传送带路线! 21_1_place_quad_painter: 放置四口上色器并且获取一些圆形白色红色! 21_2_switch_to_wires: 按 E 键选择电线层

@@ -381,43 +378,35 @@ ingame: title: 成就 desc: 挑战全成就解锁! puzzleEditorSettings: - zoneTitle: Zone - zoneWidth: Width - zoneHeight: Height - trimZone: Trim - clearItems: Clear Items - share: Share - report: Report + zoneTitle: 区域 + zoneWidth: 宽度 + zoneHeight: 高度 + trimZone: 整理 + clearItems: 清除项目 + share: 共享 + report: 上报 puzzleEditorControls: - title: Puzzle Creator + title: 谜题编辑器 instructions: - - 1. Place Constant Producers to provide shapes and - colors to the player - - 2. Build one or more shapes you want the player to build later and - deliver it to one or more Goal Acceptors - - 3. Once a Goal Acceptor receives a shape for a certain amount of - time, it saves it as a goal that the player must - produce later (Indicated by the green badge). - - 4. Click the lock button on a building to disable - it. - - 5. Once you click review, your puzzle will be validated and you - can publish it. - - 6. Upon release, all buildings will be removed - except for the Producers and Goal Acceptors - That's the part that - the player is supposed to figure out for themselves, after all :) + - 1.放置常量生成器,为玩家提供此谜题的初始图形和颜色。 + - 2.建造您希望玩家稍后建造的一个或多个图形,并将其交付给一个或多个目标接收器。 + - 3.当一个目标接收器接收到一个图形一段时间后,会将其保存为此玩家稍后必须建造的目标(由绿色充能条表示)。 + - 4.单击设施上的锁定按钮即可将其禁用。 + - 5.单击审阅后,您的谜题将通过验证,您可以正式发布它。 + - 6.谜题发布后,所有设施都将被拆除,除了常量生成器目标接收器。然后,等着其他玩家对您创造的谜题发起挑战吧! puzzleCompletion: - title: Puzzle Completed! - titleLike: "Click the heart if you liked the puzzle:" - titleRating: How difficult did you find the puzzle? - titleRatingDesc: Your rating will help me to make you better suggestions in the future - continueBtn: Keep Playing - menuBtn: Menu + title: 谜题挑战成功! + titleLike: "喜欢此谜题的话,请为它点赞:" + titleRating: 您觉得此谜题难度如何? + titleRatingDesc: 您的评分将帮助作者在未来创作出更好的谜题! + continueBtn: 继续游戏 + menuBtn: 菜单 puzzleMetadata: - author: Author - shortKey: Short Key - rating: Difficulty score - averageDuration: Avg. Duration - completionRate: Completion rate + author: 作者 + shortKey: 短代码 + rating: 难度评分 + averageDuration: 平均挑战时间 + completionRate: 挑战完成率 shopUpgrades: belt: name: 传送、分发、隧道 @@ -495,7 +484,7 @@ buildings: hub: deliver: 交付 toUnlock: 解锁 - levelShortcut: LVL + levelShortcut: 关卡 endOfDemo: 试玩版结束 wire: default: @@ -601,16 +590,16 @@ buildings: description: 仅在沙盒模式下可用,在常规层上输出电线层给定的信号。 constant_producer: default: - name: Constant Producer - description: Constantly outputs a specified shape or color. + name: 常量生成器 + description: 不断输出指定的图形或颜色。 goal_acceptor: default: - name: Goal Acceptor - description: Deliver shapes to the goal acceptor to set them as a goal. + name: 目标接收器 + description: 将图状传递给目标接收器,以将它们设置为谜题挑战目标。 block: default: - name: Block - description: Allows you to block a tile. + name: 方块 + description: 放置了方块的格子将无法再进行其他放置。 storyRewards: reward_cutter_and_trash: title: 切割图形 @@ -622,7 +611,8 @@ storyRewards: desc: 恭喜!您解锁了旋转机。它会顺时针将输入的图形旋转90度。 reward_painter: title: 上色 - desc: 恭喜!您解锁了上色器。开采一些颜色 (就像您开采图形一样),将其在上色器中与图形结合来将图形上色! + desc: + 恭喜!您解锁了上色器。开采一些颜色 (就像您开采图形一样),将其在上色器中与图形结合来将图形上色!
注意:如果您不幸患有色盲,可以在设置中启用色盲模式 reward_mixer: title: 混合颜色 @@ -639,11 +629,13 @@ storyRewards: desc: 恭喜!您解锁了隧道。它可放置在传送带设施下方以运送物品。 reward_rotater_ccw: title: 逆时针旋转 - desc: 恭喜!您解锁了旋转机逆时针变体。它可以逆时针旋转图形。 + desc: + 恭喜!您解锁了旋转机逆时针变体。它可以逆时针旋转图形
选择旋转机然后按"T"键来选取这个变体。 reward_miner_chainable: title: 链式开采器 - desc: 您已经解锁了链式开采器!它能转发资源给其他的开采器,这样您就能更有效率的开采各类资源了!

+ desc: + 您已经解锁了链式开采器!它能转发资源给其他的开采器,这样您就能更有效率的开采各类资源了!

注意:新的开采器已替换了工具栏里旧的开采器! reward_underground_belt_tier_2: title: 二级隧道 @@ -660,12 +652,14 @@ storyRewards:
优先从左边输出,这样您就可以用它做一个溢流门了! reward_freeplay: title: 自由模式 - desc: 成功了!您解锁了自由模式!挑战升级!这意味着现在将随机生成图形! + desc: + 成功了!您解锁了自由模式!挑战升级!这意味着现在将随机生成图形! 从现在起,中心基地最为需要的是产量,我强烈建议您去制造一台能够自动交付所需图形的机器!

基地会在电线层输出需要的图形,您需要去分析图形并在此基础上自动配置您的工厂。 reward_blueprints: title: 蓝图 - desc: 您现在可以复制粘贴您的工厂的一部分了!按住 CTRL键并拖动鼠标来选择一块区域,然后按C键复制。 + desc: + 您现在可以复制粘贴您的工厂的一部分了!按住 CTRL键并拖动鼠标来选择一块区域,然后按C键复制。

粘贴并不是免费的,您需要制造蓝图图形来负担。蓝图图形是您刚刚交付的图形。 no_reward: title: 下一关 @@ -693,7 +687,8 @@ storyRewards:
注意:您注意到传送读取器存储器输出的他们最后读取的物品了吗?试着在显示屏上展示一下!" reward_constant_signal: title: 恒定信号 - desc: 恭喜!您解锁了生成于电线层之上的恒定信号,把它连接到过滤器时非常有用。 + desc: + 恭喜!您解锁了生成于电线层之上的恒定信号,把它连接到过滤器时非常有用。
比如,它能发出图形、颜色、开关值(1 / 0)的固定信号。 reward_logic_gates: title: 逻辑门 @@ -712,7 +707,8 @@ storyRewards: 提示:可在设置中打开电线层教程!" reward_filter: title: 物品过滤器 - desc: 恭喜!您解锁了物品过滤器!它会根据在电线层上输入的信号决定是从上面还是右边输出物品。

+ desc: + 恭喜!您解锁了物品过滤器!它会根据在电线层上输入的信号决定是从上面还是右边输出物品。

您也可以输入开关值(1 / 0)信号来激活或者禁用它。 reward_demo_end: title: 试玩结束 @@ -927,10 +923,10 @@ keybindings: rotateToDown: 向下旋转 rotateToRight: 向右旋转 rotateToLeft: 向左旋转 - constant_producer: Constant Producer - goal_acceptor: Goal Acceptor - block: Block - massSelectClear: Clear belts + constant_producer: 常量生成器 + goal_acceptor: 目标接收器 + block: 方块 + massSelectClear: 清除传送带 about: title: 关于游戏 body: >- @@ -1010,58 +1006,51 @@ tips: - 按F4显示FPS。 - 按两次F4显示您鼠标和镜头所在的块。 - 您可以点击被固定在屏幕左侧的图形来解除固定。 - - You can click a pinned shape on the left side to unpin it. + - 您可以单击左侧的固定形状将其取消固定。 puzzleMenu: - play: Play - edit: Edit - title: Puzzle Mode - createPuzzle: Create Puzzle - loadPuzzle: Load - reviewPuzzle: Review & Publish - validatingPuzzle: Validating Puzzle - submittingPuzzle: Submitting Puzzle - noPuzzles: There are currently no puzzles in this section. + play: 游戏 + edit: 编辑 + title: 谜题模式 + createPuzzle: 创建谜题 + loadPuzzle: 载入 + reviewPuzzle: 审阅 & 发布 + validatingPuzzle: 验证谜题 + submittingPuzzle: 提交谜题 + noPuzzles: 暂无满足此部分条件的谜题。 categories: - levels: Levels - new: New - top-rated: Top Rated - mine: My Puzzles - short: Short - easy: Easy - hard: Hard - completed: Completed + levels: 关卡 + new: 最新 + top-rated: 最受好评 + mine: 我的谜题 + short: 速通 + easy: 简单 + hard: 困难 + completed: 完成 validation: - title: Invalid Puzzle - noProducers: Please place a Constant Producer! - noGoalAcceptors: Please place a Goal Acceptor! - goalAcceptorNoItem: One or more Goal Acceptors have not yet assigned an item. - Deliver a shape to them to set a goal. - goalAcceptorRateNotMet: One or more Goal Acceptors are not getting enough items. - Make sure that the indicators are green for all acceptors. - buildingOutOfBounds: One or more buildings are outside of the buildable area. - Either increase the area or remove them. - autoComplete: Your puzzle autocompletes itself! Please make sure your constant - producers are not directly delivering to your goal acceptors. + title: 无效谜题 + noProducers: 请放置常量生成器! + noGoalAcceptors: 请放置目标接收器! + goalAcceptorNoItem: 一个或多个目标接收器尚未被分配图形目标。请向它们传递图形以设置目标。 + goalAcceptorRateNotMet: 一个或多个目标接收器没有获得足够数量的图形。请确保所有接收器的充能条指示器均为绿色。 + buildingOutOfBounds: 一个或多个设施位于可建造区域之外。请增加区域面积,或将超出区域的设施移除。 + autoComplete: 请确保您的常量生成器不会直接向目标接收器传递目标图形。否则您的谜题会自动完成。 backendErrors: - ratelimit: You are performing your actions too frequent. Please wait a bit. - invalid-api-key: Failed to communicate with the backend, please try to - update/restart the game (Invalid Api Key). - unauthorized: Failed to communicate with the backend, please try to - update/restart the game (Unauthorized). - bad-token: Failed to communicate with the backend, please try to update/restart - the game (Bad Token). - bad-id: Invalid puzzle identifier. - not-found: The given puzzle could not be found. - bad-category: The given category could not be found. - bad-short-key: The given short key is invalid. - profane-title: Your puzzle title contains profane words. - bad-title-too-many-spaces: Your puzzle title is too short. - bad-shape-key-in-emitter: A constant producer has an invalid item. - bad-shape-key-in-goal: A goal acceptor has an invalid item. - no-emitters: Your puzzle does not contain any constant producers. - no-goals: Your puzzle does not contain any goal acceptors. - short-key-already-taken: This short key is already taken, please use another one. - can-not-report-your-own-puzzle: You can not report your own puzzle. - bad-payload: The request contains invalid data. - bad-building-placement: Your puzzle contains invalid placed buildings. - timeout: The request timed out. + ratelimit: 你的操作太频繁了。请稍等。 + invalid-api-key: 与后台通信失败,请尝试更新或重新启动游戏(无效的Api密钥)。 + unauthorized: 与后台通信失败,请尝试更新或重新启动游戏(未经授权)。 + bad-token: 与后台通信失败,请尝试更新或重新启动游戏(令牌错误)。 + bad-id: 谜题标识符无效。 + not-found: 找不到给定的谜题。 + bad-category: 找不到给定的类别。 + bad-short-key: 给定的短代码错误。 + profane-title: 您的谜题标题包含污言秽语。 + bad-title-too-many-spaces: 您的谜题标题过短。 + bad-shape-key-in-emitter: 常量生成器包含无效项目。 + bad-shape-key-in-goal: 目标接收器包含无效项目。 + no-emitters: 您的谜题没有任何常量生成器。 + no-goals: 您的谜题没有任何目标接收器。 + short-key-already-taken: 此短代码已被使用,请使用其他短代码。 + can-not-report-your-own-puzzle: 您无法上报您自己的谜题问题。 + bad-payload: 此请求包含无效数据。 + bad-building-placement: 您的谜题包含放置错误的设施。 + timeout: 请求超时。