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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 HDWM4fAuyi( 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: 请求超时。