mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Merge branch 'tobspr:master' into zone_indicators
This commit is contained in:
commit
bb0c58e784
@ -39,7 +39,7 @@ You can use [Gitpod](https://www.gitpod.io/) (an Online Open Source VS Code-like
|
|||||||
- install all of the dependencies.
|
- install all of the dependencies.
|
||||||
- start `gulp` in `gulp/` directory.
|
- start `gulp` in `gulp/` directory.
|
||||||
|
|
||||||
[](https://gitpod.io/from-referrer/)
|
[](https://gitpod.io/#https://github.com/tobspr/shapez.io)
|
||||||
|
|
||||||
## Helping translate
|
## Helping translate
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const railsdk = require("./wegame_sdk/railsdk.js");
|
const railsdk = require("./wegame_sdk/railsdk.js");
|
||||||
const { dialog, remote } = require("electron");
|
const { dialog, app, remote, ipcMain } = require("electron");
|
||||||
|
|
||||||
function init(isDev) {
|
function init(isDev) {
|
||||||
console.log("Step 1: wegame: init");
|
console.log("Step 1: wegame: init");
|
||||||
@ -39,7 +39,7 @@ function init(isDev) {
|
|||||||
event.state === railsdk.RailSystemState.kSystemStatePlatformExit ||
|
event.state === railsdk.RailSystemState.kSystemStatePlatformExit ||
|
||||||
event.state === railsdk.RailSystemState.kSystemStateGameExitByAntiAddiction
|
event.state === railsdk.RailSystemState.kSystemStateGameExitByAntiAddiction
|
||||||
) {
|
) {
|
||||||
remote.app.exit();
|
app.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -47,6 +47,17 @@ function init(isDev) {
|
|||||||
|
|
||||||
function listen() {
|
function listen() {
|
||||||
console.log("wegame: listen");
|
console.log("wegame: listen");
|
||||||
|
ipcMain.handle("profanity-check", async (event, data) => {
|
||||||
|
if (data.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const result = railsdk.RailUtils.DirtyWordsFilter(data, true);
|
||||||
|
if (result.check_result.dirty_type !== 0 /** kRailDirtyWordsTypeNormalAllowWords */) {
|
||||||
|
return result.check_result.replace_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { init, listen };
|
module.exports = { init, listen };
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 37 KiB |
BIN
res/ui/wegame_isbn_rating.jpg
Normal file
BIN
res/ui/wegame_isbn_rating.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
@ -21,6 +21,7 @@
|
|||||||
@import "adinplay";
|
@import "adinplay";
|
||||||
@import "changelog_skins";
|
@import "changelog_skins";
|
||||||
|
|
||||||
|
@import "states/wegame_splash";
|
||||||
@import "states/preload";
|
@import "states/preload";
|
||||||
@import "states/main_menu";
|
@import "states/main_menu";
|
||||||
@import "states/ingame";
|
@import "states/ingame";
|
||||||
|
@ -550,6 +550,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#crosspromo {
|
||||||
|
position: absolute;
|
||||||
|
@include S(bottom, 50px);
|
||||||
|
@include S(right, 20px);
|
||||||
|
@include S(width, 190px);
|
||||||
|
@include S(height, 100px);
|
||||||
|
pointer-events: all;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
display: grid;
|
display: grid;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
@ -565,6 +575,40 @@
|
|||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.wegameDisclaimer {
|
||||||
|
@include SuperSmallText;
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
grid-template-columns: 1fr auto 1fr;
|
||||||
|
|
||||||
|
> .disclaimer {
|
||||||
|
grid-column: 2 / 3;
|
||||||
|
|
||||||
|
@include DarkThemeOverride {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .rating {
|
||||||
|
grid-column: 3 / 4;
|
||||||
|
justify-self: end;
|
||||||
|
align-self: end;
|
||||||
|
|
||||||
|
@include S(width, 32px);
|
||||||
|
@include S(height, 40px);
|
||||||
|
background: green;
|
||||||
|
cursor: pointer !important;
|
||||||
|
pointer-events: all;
|
||||||
|
@include S(border-radius, 4px);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
& {
|
||||||
|
/* @load-async */
|
||||||
|
background: #fff uiResource("wegame_isbn_rating.jpg") center center / contain no-repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.author {
|
.author {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
38
src/css/states/wegame_splash.scss
Normal file
38
src/css/states/wegame_splash.scss
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#state_WegameSplashState {
|
||||||
|
background: #000 !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
opacity: 0;
|
||||||
|
@include InlineAnimation(5.9s ease-in-out) {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
@include Heading;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
display: block;
|
||||||
|
@include SuperHeading;
|
||||||
|
@include S(margin-bottom, 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
@include S(margin-bottom, 10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ import { RestrictionManager } from "./core/restriction_manager";
|
|||||||
import { PuzzleMenuState } from "./states/puzzle_menu";
|
import { PuzzleMenuState } from "./states/puzzle_menu";
|
||||||
import { ClientAPI } from "./platform/api";
|
import { ClientAPI } from "./platform/api";
|
||||||
import { LoginState } from "./states/login";
|
import { LoginState } from "./states/login";
|
||||||
|
import { WegameSplashState } from "./states/wegame_splash";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface
|
* @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface
|
||||||
@ -155,6 +156,7 @@ export class Application {
|
|||||||
registerStates() {
|
registerStates() {
|
||||||
/** @type {Array<typeof GameState>} */
|
/** @type {Array<typeof GameState>} */
|
||||||
const states = [
|
const states = [
|
||||||
|
WegameSplashState,
|
||||||
PreloadState,
|
PreloadState,
|
||||||
MobileWarningState,
|
MobileWarningState,
|
||||||
MainMenuState,
|
MainMenuState,
|
||||||
@ -330,8 +332,12 @@ export class Application {
|
|||||||
|
|
||||||
Loader.linkAppAfterBoot(this);
|
Loader.linkAppAfterBoot(this);
|
||||||
|
|
||||||
|
if (G_WEGAME_VERSION) {
|
||||||
|
this.stateMgr.moveToState("WegameSplashState");
|
||||||
|
}
|
||||||
|
|
||||||
// Check for mobile
|
// Check for mobile
|
||||||
if (IS_MOBILE) {
|
else if (IS_MOBILE) {
|
||||||
this.stateMgr.moveToState("MobileWarningState");
|
this.stateMgr.moveToState("MobileWarningState");
|
||||||
} else {
|
} else {
|
||||||
this.stateMgr.moveToState("PreloadState");
|
this.stateMgr.moveToState("PreloadState");
|
||||||
|
@ -1,4 +1,16 @@
|
|||||||
export const CHANGELOG = [
|
export const CHANGELOG = [
|
||||||
|
// Not finished yet
|
||||||
|
{
|
||||||
|
version: "1.4.3",
|
||||||
|
date: "preview",
|
||||||
|
entries: [
|
||||||
|
"Edit signal dialog now has the previous signal filled (Thanks to EmeraldBlock)",
|
||||||
|
"Further performance improvements (Thanks to PFedak)",
|
||||||
|
"Improved puzzle validation (Thanks to Sense101)",
|
||||||
|
"Input fields in dialogs should now automatically focus",
|
||||||
|
"Updated translations",
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
version: "1.4.2",
|
version: "1.4.2",
|
||||||
date: "24.06.2021",
|
date: "24.06.2021",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { BaseItem } from "../game/base_item";
|
import { BaseItem } from "../game/base_item";
|
||||||
import { ClickDetector } from "./click_detector";
|
import { ClickDetector } from "./click_detector";
|
||||||
import { Signal } from "./signal";
|
import { Signal } from "./signal";
|
||||||
|
import { getIPCRenderer } from "./utils";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ***************************************************
|
* ***************************************************
|
||||||
@ -107,6 +108,19 @@ export class FormElementInput extends FormElement {
|
|||||||
|
|
||||||
updateErrorState() {
|
updateErrorState() {
|
||||||
this.element.classList.toggle("errored", !this.isValid());
|
this.element.classList.toggle("errored", !this.isValid());
|
||||||
|
|
||||||
|
// profanity filter
|
||||||
|
if (G_WEGAME_VERSION) {
|
||||||
|
const value = String(this.element.value);
|
||||||
|
|
||||||
|
getIPCRenderer()
|
||||||
|
.invoke("profanity-check", value)
|
||||||
|
.then(newValue => {
|
||||||
|
if (value !== newValue && this.element) {
|
||||||
|
this.element.value = newValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isValid() {
|
isValid() {
|
||||||
@ -124,6 +138,7 @@ export class FormElementInput extends FormElement {
|
|||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
this.element.focus();
|
this.element.focus();
|
||||||
|
this.element.select();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,12 @@ export class ItemProcessorComponent extends Component {
|
|||||||
// Type of processing requirement
|
// Type of processing requirement
|
||||||
this.processingRequirement = processingRequirement;
|
this.processingRequirement = processingRequirement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our current inputs
|
||||||
|
* @type {Map<number, BaseItem>}
|
||||||
|
*/
|
||||||
|
this.inputSlots = new Map();
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,11 +88,13 @@ export class ItemProcessorComponent extends Component {
|
|||||||
// sure the outputs always match
|
// sure the outputs always match
|
||||||
this.nextOutputSlot = 0;
|
this.nextOutputSlot = 0;
|
||||||
|
|
||||||
|
this.inputSlots.clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our current inputs
|
* Current input count
|
||||||
* @type {Array<{ item: BaseItem, sourceSlot: number }>}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
this.inputSlots = [];
|
this.inputCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What we are currently processing, empty if we don't produce anything rn
|
* What we are currently processing, empty if we don't produce anything rn
|
||||||
@ -115,19 +123,17 @@ export class ItemProcessorComponent extends Component {
|
|||||||
this.type === enumItemProcessorTypes.goal
|
this.type === enumItemProcessorTypes.goal
|
||||||
) {
|
) {
|
||||||
// Hub has special logic .. not really nice but efficient.
|
// Hub has special logic .. not really nice but efficient.
|
||||||
this.inputSlots.push({ item, sourceSlot });
|
this.inputSlots.set(this.inputCount, item);
|
||||||
|
this.inputCount++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that we only take one item per slot
|
// Check that we only take one item per slot
|
||||||
for (let i = 0; i < this.inputSlots.length; ++i) {
|
if (this.inputSlots.has(sourceSlot)) {
|
||||||
const slot = this.inputSlots[i];
|
|
||||||
if (slot.sourceSlot === sourceSlot) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
this.inputSlots.set(sourceSlot, item);
|
||||||
|
this.inputCount++;
|
||||||
this.inputSlots.push({ item, sourceSlot });
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ export class HUDPuzzleEditorReview extends BaseHUDPart {
|
|||||||
closeLoading();
|
closeLoading();
|
||||||
|
|
||||||
//if it took so little ticks that it must have autocompeted
|
//if it took so little ticks that it must have autocompeted
|
||||||
if (simulatedTicks <= 300) {
|
if (simulatedTicks <= 500) {
|
||||||
this.root.hud.parts.dialogs.showWarning(
|
this.root.hud.parts.dialogs.showWarning(
|
||||||
T.puzzleMenu.validation.title,
|
T.puzzleMenu.validation.title,
|
||||||
T.puzzleMenu.validation.autoComplete
|
T.puzzleMenu.validation.autoComplete
|
||||||
|
@ -585,12 +585,12 @@ export class RegularGameMode extends GameMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @type {(typeof MetaBuilding)[]} */
|
/** @type {(typeof MetaBuilding)[]} */
|
||||||
this.hiddenBuildings = [
|
this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, MetaBlockBuilding];
|
||||||
MetaConstantProducerBuilding,
|
|
||||||
MetaGoalAcceptorBuilding,
|
// @ts-expect-error
|
||||||
MetaBlockBuilding,
|
if (!(G_IS_DEV || window.sandboxMode || queryParamOptions.sandboxMode)) {
|
||||||
MetaItemProducerBuilding,
|
this.hiddenBuildings.push(MetaItemProducerBuilding);
|
||||||
];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,11 +49,12 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
|
|||||||
// Ok, query, but also save the uid because it could get stale
|
// Ok, query, but also save the uid because it could get stale
|
||||||
const uid = entity.uid;
|
const uid = entity.uid;
|
||||||
|
|
||||||
|
const signal = entity.components.ConstantSignal.signal;
|
||||||
const signalValueInput = new FormElementInput({
|
const signalValueInput = new FormElementInput({
|
||||||
id: "signalValue",
|
id: "signalValue",
|
||||||
label: fillInLinkIntoTranslation(T.dialogs.editSignal.descShortKey, THIRDPARTY_URLS.shapeViewer),
|
label: fillInLinkIntoTranslation(T.dialogs.editSignal.descShortKey, THIRDPARTY_URLS.shapeViewer),
|
||||||
placeholder: "",
|
placeholder: "",
|
||||||
defaultValue: "",
|
defaultValue: signal ? signal.getAsCopyableKey() : "",
|
||||||
validator: val => this.parseSignalCode(entity, val),
|
validator: val => this.parseSignalCode(entity, val),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ const MAX_QUEUED_CHARGES = 2;
|
|||||||
* Type of a processor implementation
|
* Type of a processor implementation
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* entity: Entity,
|
* entity: Entity,
|
||||||
* items: Array<{ item: BaseItem, sourceSlot: number }>,
|
* items: Map<number, BaseItem>,
|
||||||
* itemsBySlot: Object<number, BaseItem>,
|
* inputCount: number,
|
||||||
* outItems: Array<ProducedItem>
|
* outItems: Array<ProducedItem>
|
||||||
* }} ProcessorImplementationPayload
|
* }} ProcessorImplementationPayload
|
||||||
*/
|
*/
|
||||||
@ -189,7 +189,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
// DEFAULT
|
// DEFAULT
|
||||||
// By default, we can start processing once all inputs are there
|
// By default, we can start processing once all inputs are there
|
||||||
case null: {
|
case null: {
|
||||||
return processorComp.inputSlots.length >= processorComp.inputsPerCharge;
|
return processorComp.inputCount >= processorComp.inputsPerCharge;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QUAD PAINTER
|
// QUAD PAINTER
|
||||||
@ -197,18 +197,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
case enumItemProcessorRequirements.painterQuad: {
|
case enumItemProcessorRequirements.painterQuad: {
|
||||||
const pinsComp = entity.components.WiredPins;
|
const pinsComp = entity.components.WiredPins;
|
||||||
|
|
||||||
/** @type {Object.<number, { item: BaseItem, sourceSlot: number }>} */
|
|
||||||
const itemsBySlot = {};
|
|
||||||
for (let i = 0; i < processorComp.inputSlots.length; ++i) {
|
|
||||||
itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// First slot is the shape, so if it's not there we can't do anything
|
// First slot is the shape, so if it's not there we can't do anything
|
||||||
if (!itemsBySlot[0]) {
|
const shapeItem = /** @type {ShapeItem} */ (processorComp.inputSlots.get(0));
|
||||||
|
if (!shapeItem) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
|
|
||||||
const slotStatus = [];
|
const slotStatus = [];
|
||||||
|
|
||||||
// Check which slots are enabled
|
// Check which slots are enabled
|
||||||
@ -233,7 +227,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
// Check if all colors of the enabled slots are there
|
// Check if all colors of the enabled slots are there
|
||||||
for (let i = 0; i < slotStatus.length; ++i) {
|
for (let i = 0; i < slotStatus.length; ++i) {
|
||||||
if (slotStatus[i] && !itemsBySlot[1 + i]) {
|
if (slotStatus[i] && !processorComp.inputSlots.get(1 + i)) {
|
||||||
// A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant,
|
// A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant,
|
||||||
// it is not possible to paint, but if there is nothing we can ignore it
|
// it is not possible to paint, but if there is nothing we can ignore it
|
||||||
for (let j = 0; j < 4; ++j) {
|
for (let j = 0; j < 4; ++j) {
|
||||||
@ -262,13 +256,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
// First, take items
|
// First, take items
|
||||||
const items = processorComp.inputSlots;
|
const items = processorComp.inputSlots;
|
||||||
processorComp.inputSlots = [];
|
|
||||||
|
|
||||||
/** @type {Object<string, BaseItem>} */
|
|
||||||
const itemsBySlot = {};
|
|
||||||
for (let i = 0; i < items.length; ++i) {
|
|
||||||
itemsBySlot[items[i].sourceSlot] = items[i].item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {Array<ProducedItem>} */
|
/** @type {Array<ProducedItem>} */
|
||||||
const outItems = [];
|
const outItems = [];
|
||||||
@ -281,8 +268,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
handler({
|
handler({
|
||||||
entity,
|
entity,
|
||||||
items,
|
items,
|
||||||
itemsBySlot,
|
|
||||||
outItems,
|
outItems,
|
||||||
|
inputCount: processorComp.inputCount,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Track produced items
|
// Track produced items
|
||||||
@ -304,6 +291,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
items: outItems,
|
items: outItems,
|
||||||
remainingTime: timeToProcess,
|
remainingTime: timeToProcess,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
processorComp.inputSlots.clear();
|
||||||
|
processorComp.inputCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,9 +309,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const nextSlot = processorComp.nextOutputSlot++ % availableSlots;
|
const nextSlot = processorComp.nextOutputSlot++ % availableSlots;
|
||||||
|
|
||||||
for (let i = 0; i < payload.items.length; ++i) {
|
// Hardcoded to 2, to avoid accessing the length
|
||||||
|
for (let i = 0; i < 2; ++i) {
|
||||||
|
const item = payload.items.get(i);
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
payload.outItems.push({
|
payload.outItems.push({
|
||||||
item: payload.items[i].item,
|
item,
|
||||||
preferredSlot: (nextSlot + i) % availableSlots,
|
preferredSlot: (nextSlot + i) % availableSlots,
|
||||||
doNotTrack: true,
|
doNotTrack: true,
|
||||||
});
|
});
|
||||||
@ -333,7 +328,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_CUTTER(payload) {
|
process_CUTTER(payload) {
|
||||||
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
|
const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
|
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
|
||||||
const inputDefinition = inputItem.definition;
|
const inputDefinition = inputItem.definition;
|
||||||
|
|
||||||
@ -354,7 +349,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_CUTTER_QUAD(payload) {
|
process_CUTTER_QUAD(payload) {
|
||||||
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
|
const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
|
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
|
||||||
const inputDefinition = inputItem.definition;
|
const inputDefinition = inputItem.definition;
|
||||||
|
|
||||||
@ -375,7 +370,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_ROTATER(payload) {
|
process_ROTATER(payload) {
|
||||||
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
|
const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
|
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
|
||||||
const inputDefinition = inputItem.definition;
|
const inputDefinition = inputItem.definition;
|
||||||
|
|
||||||
@ -389,7 +384,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_ROTATER_CCW(payload) {
|
process_ROTATER_CCW(payload) {
|
||||||
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
|
const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
|
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
|
||||||
const inputDefinition = inputItem.definition;
|
const inputDefinition = inputItem.definition;
|
||||||
|
|
||||||
@ -403,7 +398,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_ROTATER_180(payload) {
|
process_ROTATER_180(payload) {
|
||||||
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item);
|
const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
|
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
|
||||||
const inputDefinition = inputItem.definition;
|
const inputDefinition = inputItem.definition;
|
||||||
|
|
||||||
@ -417,8 +412,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_STACKER(payload) {
|
process_STACKER(payload) {
|
||||||
const lowerItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
|
const lowerItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
const upperItem = /** @type {ShapeItem} */ (payload.itemsBySlot[1]);
|
const upperItem = /** @type {ShapeItem} */ (payload.items.get(1));
|
||||||
|
|
||||||
assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape");
|
assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape");
|
||||||
assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape");
|
assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape");
|
||||||
@ -444,8 +439,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
*/
|
*/
|
||||||
process_MIXER(payload) {
|
process_MIXER(payload) {
|
||||||
// Find both colors and combine them
|
// Find both colors and combine them
|
||||||
const item1 = /** @type {ColorItem} */ (payload.items[0].item);
|
const item1 = /** @type {ColorItem} */ (payload.items.get(0));
|
||||||
const item2 = /** @type {ColorItem} */ (payload.items[1].item);
|
const item2 = /** @type {ColorItem} */ (payload.items.get(1));
|
||||||
assert(item1 instanceof ColorItem, "Input for color mixer is not a color");
|
assert(item1 instanceof ColorItem, "Input for color mixer is not a color");
|
||||||
assert(item2 instanceof ColorItem, "Input for color mixer is not a color");
|
assert(item2 instanceof ColorItem, "Input for color mixer is not a color");
|
||||||
|
|
||||||
@ -467,8 +462,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_PAINTER(payload) {
|
process_PAINTER(payload) {
|
||||||
const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
|
const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[1]);
|
const colorItem = /** @type {ColorItem} */ (payload.items.get(1));
|
||||||
|
|
||||||
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith(
|
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith(
|
||||||
shapeItem.definition,
|
shapeItem.definition,
|
||||||
@ -484,9 +479,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_PAINTER_DOUBLE(payload) {
|
process_PAINTER_DOUBLE(payload) {
|
||||||
const shapeItem1 = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
|
const shapeItem1 = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
const shapeItem2 = /** @type {ShapeItem} */ (payload.itemsBySlot[1]);
|
const shapeItem2 = /** @type {ShapeItem} */ (payload.items.get(1));
|
||||||
const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[2]);
|
const colorItem = /** @type {ColorItem} */ (payload.items.get(2));
|
||||||
|
|
||||||
assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape");
|
assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape");
|
||||||
assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape");
|
assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape");
|
||||||
@ -514,14 +509,15 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
* @param {ProcessorImplementationPayload} payload
|
* @param {ProcessorImplementationPayload} payload
|
||||||
*/
|
*/
|
||||||
process_PAINTER_QUAD(payload) {
|
process_PAINTER_QUAD(payload) {
|
||||||
const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]);
|
const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0));
|
||||||
assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape");
|
assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape");
|
||||||
|
|
||||||
/** @type {Array<enumColors>} */
|
/** @type {Array<enumColors>} */
|
||||||
const colors = [null, null, null, null];
|
const colors = [null, null, null, null];
|
||||||
for (let i = 0; i < 4; ++i) {
|
for (let i = 0; i < 4; ++i) {
|
||||||
if (payload.itemsBySlot[i + 1]) {
|
const colorItem = /** @type {ColorItem} */ (payload.items.get(i + 1));
|
||||||
colors[i] = /** @type {ColorItem} */ (payload.itemsBySlot[i + 1]).color;
|
if (colorItem) {
|
||||||
|
colors[i] = colorItem.color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +536,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
*/
|
*/
|
||||||
process_READER(payload) {
|
process_READER(payload) {
|
||||||
// Pass through the item
|
// Pass through the item
|
||||||
const item = payload.itemsBySlot[0];
|
const item = payload.items.get(0);
|
||||||
payload.outItems.push({
|
payload.outItems.push({
|
||||||
item,
|
item,
|
||||||
doNotTrack: true,
|
doNotTrack: true,
|
||||||
@ -559,8 +555,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
const hubComponent = payload.entity.components.Hub;
|
const hubComponent = payload.entity.components.Hub;
|
||||||
assert(hubComponent, "Hub item processor has no hub component");
|
assert(hubComponent, "Hub item processor has no hub component");
|
||||||
|
|
||||||
for (let i = 0; i < payload.items.length; ++i) {
|
// Hardcoded
|
||||||
const item = /** @type {ShapeItem} */ (payload.items[i].item);
|
for (let i = 0; i < payload.inputCount; ++i) {
|
||||||
|
const item = /** @type {ShapeItem} */ (payload.items.get(i));
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
this.root.hubGoals.handleDefinitionDelivered(item.definition);
|
this.root.hubGoals.handleDefinitionDelivered(item.definition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -570,7 +570,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
*/
|
*/
|
||||||
process_GOAL(payload) {
|
process_GOAL(payload) {
|
||||||
const goalComp = payload.entity.components.GoalAcceptor;
|
const goalComp = payload.entity.components.GoalAcceptor;
|
||||||
const item = payload.items[0].item;
|
const item = payload.items.get(0);
|
||||||
const now = this.root.time.now();
|
const now = this.root.time.now();
|
||||||
|
|
||||||
if (goalComp.item && !item.equals(goalComp.item)) {
|
if (goalComp.item && !item.equals(goalComp.item)) {
|
||||||
@ -584,7 +584,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
if (this.root.gameMode.getIsEditor()) {
|
if (this.root.gameMode.getIsEditor()) {
|
||||||
// while playing in editor, assign the item
|
// while playing in editor, assign the item
|
||||||
goalComp.item = payload.items[0].item;
|
goalComp.item = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
goalComp.lastDelivery = {
|
goalComp.lastDelivery = {
|
||||||
|
@ -111,6 +111,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
|
|||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
sendToApi(endpoint, data) {
|
sendToApi(endpoint, data) {
|
||||||
|
if (G_WEGAME_VERSION) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timeout = setTimeout(() => reject("Request to " + endpoint + " timed out"), 20000);
|
const timeout = setTimeout(() => reject("Request to " + endpoint + " timed out"), 20000);
|
||||||
|
|
||||||
|
@ -130,7 +130,17 @@ export class MainMenuState extends GameState {
|
|||||||
|
|
||||||
${
|
${
|
||||||
G_WEGAME_VERSION
|
G_WEGAME_VERSION
|
||||||
? "<div class='footer wegame'></div>"
|
? `<div class='footer wegameDisclaimer'>
|
||||||
|
<div class="disclaimer">
|
||||||
|
健康游戏忠告
|
||||||
|
<br>
|
||||||
|
抵制不良游戏,拒绝盗版游戏。注意自我保护,谨防受骗上当。<br>
|
||||||
|
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rating"></div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
: `
|
: `
|
||||||
<div class="footer ${G_CHINA_VERSION ? "china" : ""} ">
|
<div class="footer ${G_CHINA_VERSION ? "china" : ""} ">
|
||||||
|
|
||||||
@ -163,6 +173,15 @@ export class MainMenuState extends GameState {
|
|||||||
'<a class="producerLink" target="_blank">Tobias Springer</a>'
|
'<a class="producerLink" target="_blank">Tobias Springer</a>'
|
||||||
)}</div>
|
)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
${
|
||||||
|
G_IS_STANDALONE
|
||||||
|
? ""
|
||||||
|
: `
|
||||||
|
<iframe id="crosspromo" src="https://crosspromo.tobspr.io?src=shapez_web"></iframe>
|
||||||
|
|
||||||
|
`
|
||||||
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -341,6 +360,11 @@ export class MainMenuState extends GameState {
|
|||||||
if (puzzleWishlistButton) {
|
if (puzzleWishlistButton) {
|
||||||
this.trackClicks(puzzleWishlistButton, () => this.onPuzzleWishlistButtonClicked());
|
this.trackClicks(puzzleWishlistButton, () => this.onPuzzleWishlistButtonClicked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wegameRating = qs(".wegameDisclaimer > .rating");
|
||||||
|
if (wegameRating) {
|
||||||
|
this.trackClicks(wegameRating, () => this.onWegameRatingClicked());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMainMenu() {
|
renderMainMenu() {
|
||||||
@ -675,6 +699,22 @@ export class MainMenuState extends GameState {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onWegameRatingClicked() {
|
||||||
|
this.dialogs.showInfo(
|
||||||
|
"",
|
||||||
|
`
|
||||||
|
1)本游戏是一款休闲建造类单机游戏,适用于年满8周岁及以上的用户。<br>
|
||||||
|
2)本游戏模拟简单的生产流水线,剧情简单且积极向上,没有基于真实
|
||||||
|
历史和现实事件的改编内容。游戏玩法为摆放简单的部件,完成生产目标。
|
||||||
|
游戏为单机作品,没有基于文字和语音的陌生人社交系统。<br>
|
||||||
|
3)游戏中有用户实名认证系统,认证为未成年人的用户将接受以下管理:
|
||||||
|
游戏为买断制,不存在后续充值付费内容。未成年人用户每日22点到次日
|
||||||
|
8点不得使用,法定节假日每天不得使用超过3小时,其它时间每天使用游
|
||||||
|
戏不得超过1.5小时。
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
onContinueButtonClicked() {
|
onContinueButtonClicked() {
|
||||||
let latestLastUpdate = 0;
|
let latestLastUpdate = 0;
|
||||||
let latestInternalId;
|
let latestInternalId;
|
||||||
|
27
src/js/states/wegame_splash.js
Normal file
27
src/js/states/wegame_splash.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { GameState } from "../core/game_state";
|
||||||
|
|
||||||
|
export class WegameSplashState extends GameState {
|
||||||
|
constructor() {
|
||||||
|
super("WegameSplashState");
|
||||||
|
}
|
||||||
|
|
||||||
|
getInnerHTML() {
|
||||||
|
return `
|
||||||
|
<div class="wrapper">
|
||||||
|
<strong>健康游戏忠告</strong>
|
||||||
|
<div>抵制不良游戏,拒绝盗版游戏。</div>
|
||||||
|
<div>注意自我保护,谨防受骗上当。</div>
|
||||||
|
<div>适度游戏益脑,沉迷游戏伤身。</div>
|
||||||
|
<div>适度游戏益脑,沉迷游戏伤身。</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
onEnter() {
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
this.app.stateMgr.moveToState("PreloadState");
|
||||||
|
},
|
||||||
|
G_IS_DEV ? 1 : 6000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -11,14 +11,14 @@ steamPage:
|
|||||||
Et en plus, vous devrez aussi produire de plus en plus pour satisfaire la demande. La seule solution est de construire en plus grand ! Au début vous ne ferez que découper les formes, mais plus tard vous devrez les peindre — et pour ça vous devrez extraire et mélanger des couleurs !
|
Et en plus, vous devrez aussi produire de plus en plus pour satisfaire la demande. La seule solution est de construire en plus grand ! Au début vous ne ferez que découper les formes, mais plus tard vous devrez les peindre — et pour ça vous devrez extraire et mélanger des couleurs !
|
||||||
|
|
||||||
En achetant le jeu sur Steam, vous aurez accès à la version complète, mais vous pouvez aussi jouer à une démo sur shapez.io et vous décider ensuite !
|
En achetant le jeu sur Steam, vous aurez accès à la version complète, mais vous pouvez aussi jouer à une démo sur shapez.io et vous décider ensuite !
|
||||||
what_others_say: Ce que les gens pensent de shapez.io
|
what_others_say: Ce que les gens pensent de Shapez.io
|
||||||
nothernlion_comment: This game is great - I'm having a wonderful time playing,
|
nothernlion_comment: Ce jeu est génial - Je passe un merveilleux moment à jouer,
|
||||||
and time has flown by.
|
et le temps s'est envolé.
|
||||||
notch_comment: Mince ! Je devrais vraiment me coucher, mais je crois que j'ai
|
notch_comment: Mince ! Je devrais vraiment me coucher, mais je crois que j'ai trouvé
|
||||||
trouvé comment faire un ordinateur dans shapez.io
|
comment faire un ordinateur dans Shapez.io
|
||||||
steam_review_comment: This game has stolen my life and I don't want it back.
|
steam_review_comment: Ce jeu a volé ma vie et je ne veux pas la récupérer.
|
||||||
Very chill factory game that won't let me stop making my lines more
|
Jeu d'usine très cool qui ne me laissera pas arrêter de rendre mes lignes plus
|
||||||
efficient.
|
efficaces.
|
||||||
global:
|
global:
|
||||||
loading: Chargement
|
loading: Chargement
|
||||||
error: Erreur
|
error: Erreur
|
||||||
@ -71,11 +71,11 @@ mainMenu:
|
|||||||
savegameLevel: Niveau <x>
|
savegameLevel: Niveau <x>
|
||||||
savegameLevelUnknown: Niveau inconnu
|
savegameLevelUnknown: Niveau inconnu
|
||||||
savegameUnnamed: Sans titre
|
savegameUnnamed: Sans titre
|
||||||
puzzleMode: Puzzle Mode
|
puzzleMode: Mode Puzzle
|
||||||
back: Back
|
back: Retour
|
||||||
puzzleDlcText: Vous aimez compacter et optimiser vos usines ? Achetez le DLC sur
|
puzzleDlcText: Vous aimez compacter et optimiser vos usines ? Achetez le DLC
|
||||||
Steam dés maintenant pour encore plus d'amusement !
|
sur Steam dès maintenant pour encore plus d'amusement!
|
||||||
puzzleDlcWishlist: Wishlist now!
|
puzzleDlcWishlist: Ajoute à ta liste de souhaits maintenant !
|
||||||
puzzleDlcViewNow: View Dlc
|
puzzleDlcViewNow: View Dlc
|
||||||
dialogs:
|
dialogs:
|
||||||
buttons:
|
buttons:
|
||||||
@ -90,7 +90,7 @@ dialogs:
|
|||||||
viewUpdate: Voir les mises à jour
|
viewUpdate: Voir les mises à jour
|
||||||
showUpgrades: Montrer les améliorations
|
showUpgrades: Montrer les améliorations
|
||||||
showKeybindings: Montrer les raccourcis
|
showKeybindings: Montrer les raccourcis
|
||||||
retry: Réesayer
|
retry: Réessayer
|
||||||
continue: Continuer
|
continue: Continuer
|
||||||
playOffline: Jouer Hors-ligne
|
playOffline: Jouer Hors-ligne
|
||||||
importSavegameError:
|
importSavegameError:
|
||||||
@ -200,63 +200,61 @@ dialogs:
|
|||||||
desc: "Malheuresement, le puzzle n'a pas pu être chargé :"
|
desc: "Malheuresement, le puzzle n'a pas pu être chargé :"
|
||||||
submitPuzzle:
|
submitPuzzle:
|
||||||
title: Envoyer le Puzzle
|
title: Envoyer le Puzzle
|
||||||
descName: "Donnez un nom à votre puzzle :"
|
descName: "Donnez un nom à votre puzzle:"
|
||||||
descIcon: "Please enter a unique short key, which will be shown as the icon of
|
descIcon: "Veuillez entrer un raccourci de forme unique, qui sera affichée comme icône de
|
||||||
your puzzle (You can generate them <link>here</link>, or choose one
|
votre puzzle (Vous pouvez générer le raccourci d'une forme <link>ici</link>, ou en choisir une
|
||||||
of the randomly suggested shapes below):"
|
parmi les formes suggérées alétoirement ci-dessous):"
|
||||||
placeholderName: Puzzle Title
|
placeholderName: Titre du Puzzle
|
||||||
puzzleResizeBadBuildings:
|
puzzleResizeBadBuildings:
|
||||||
title: Resize not possible
|
title: Impossible de redimensionner
|
||||||
desc: You can't make the zone any smaller, because then some buildings would be
|
desc: Vous ne pouvez pas rétrécir la zone, car certains bâtiments seraient en dehors de la zone
|
||||||
outside the zone.
|
|
||||||
puzzleLoadError:
|
puzzleLoadError:
|
||||||
title: Mauvais Puzzle
|
title: Mauvais Puzzle
|
||||||
desc: "Le chargement du puzzle a échoué :"
|
desc: "Le chargement du puzzle a échoué:"
|
||||||
offlineMode:
|
offlineMode:
|
||||||
title: Mode hors-ligne
|
title: Mode hors-ligne
|
||||||
desc: We couldn't reach the servers, so the game has to run in offline mode.
|
desc: Nous n'avons pas pu atteindre les serveurs, donc le jeu doit être mis en mode hors ligne.
|
||||||
Please make sure you have an active internet connection.
|
Veuillez vous assurez que vous disposez d'une connexion Internet active.
|
||||||
puzzleDownloadError:
|
puzzleDownloadError:
|
||||||
title: Erreur de téléchargment
|
title: Erreur de téléchargment
|
||||||
desc: "Le téléchargement à échoué :"
|
desc: "Le téléchargement a échoué:"
|
||||||
puzzleSubmitError:
|
puzzleSubmitError:
|
||||||
title: Erreur d'envoi
|
title: Erreur d'envoi
|
||||||
desc: "L'envoi à échoué :"
|
desc: "L'envoi a échoué:"
|
||||||
puzzleSubmitOk:
|
puzzleSubmitOk:
|
||||||
title: Puzzle envoyé
|
title: Puzzle envoyé
|
||||||
desc: Félicitation ! Votre puzzle à été envoyé et peut maintenant être joué.
|
desc: Félicitations ! Votre puzzle a été envoyé et peut maintenant être joué.
|
||||||
Vous pouvez maintenant le retrouver dans la section "Mes Puzzles".
|
Vous pouvez maintenant le retrouver dans la section "Mes Puzzles".
|
||||||
puzzleCreateOffline:
|
puzzleCreateOffline:
|
||||||
title: Mode Hors-ligne
|
title: Mode Hors-ligne
|
||||||
desc: Since you are offline, you will not be able to save and/or publish your
|
desc: Puisque vous êtes hors ligne, vous ne pourrez pas enregistrer et/ou publier votre puzzle. Souhaitez-vous toujours continuer ?
|
||||||
puzzle. Would you still like to continue?
|
|
||||||
puzzlePlayRegularRecommendation:
|
puzzlePlayRegularRecommendation:
|
||||||
title: Recommendation
|
title: Recommandation
|
||||||
desc: I <strong>strongly</strong> recommend playing the normal game to level 12
|
desc: Je recommande <strong>fortement</strong> de jouer au jeu normal jusqu'au niveau 12
|
||||||
before attempting the puzzle DLC, otherwise you may encounter
|
avant d'essayer le Puzzle DLC, sinon vous risqez de rencontrer
|
||||||
mechanics not yet introduced. Do you still want to continue?
|
des méchanismes pas encore introduits. Voulez-vous toujours continuer ?
|
||||||
puzzleShare:
|
puzzleShare:
|
||||||
title: Short Key Copied
|
title: Code copié
|
||||||
desc: The short key of the puzzle (<key>) has been copied to your clipboard! It
|
desc: Le code du puzzle (<key>) a été copié dans ton presse-papiers ! Il
|
||||||
can be entered in the puzzle menu to access the puzzle.
|
peut être entré dans le menu des puzzles pour accéder au puzzle.
|
||||||
puzzleReport:
|
puzzleReport:
|
||||||
title: Report Puzzle
|
title: Signaler le Puzzle
|
||||||
options:
|
options:
|
||||||
profane: Profane
|
profane: Profane
|
||||||
unsolvable: Not solvable
|
unsolvable: Irrésolvable
|
||||||
trolling: Trolling
|
trolling: Troll
|
||||||
puzzleReportComplete:
|
puzzleReportComplete:
|
||||||
title: Merci pour votre retour !
|
title: Merci pour votre retour!
|
||||||
desc: Le puzzle a été marqué.
|
desc: Le puzzle a été marqué.
|
||||||
puzzleReportError:
|
puzzleReportError:
|
||||||
title: Failed to report
|
title: Échec du signalement
|
||||||
desc: "Your report could not get processed:"
|
desc: "Votre signalement n'a pas pu être effectué:"
|
||||||
puzzleLoadShortKey:
|
puzzleLoadShortKey:
|
||||||
title: Enter short key
|
title: Entrer un code
|
||||||
desc: Enter the short key of the puzzle to load it.
|
desc: Entrer le code du puzzle pour le charger.
|
||||||
puzzleDelete:
|
puzzleDelete:
|
||||||
title: Delete Puzzle?
|
title: Supprimer le puzzle ?
|
||||||
desc: Are you sure you want to delete '<title>'? This can not be undone!
|
desc: Êtes-vous sûr de vouloir supprimer '<title>' ? Cela sera irréversible !
|
||||||
ingame:
|
ingame:
|
||||||
keybindingsOverlay:
|
keybindingsOverlay:
|
||||||
moveMap: Déplacer
|
moveMap: Déplacer
|
||||||
@ -430,28 +428,26 @@ ingame:
|
|||||||
title: Me soutenir
|
title: Me soutenir
|
||||||
desc: Je le développe pendant mon temps libre !
|
desc: Je le développe pendant mon temps libre !
|
||||||
achievements:
|
achievements:
|
||||||
title: Achievements
|
title: Succès
|
||||||
desc: Hunt them all!
|
desc: Débloquez-les tous !
|
||||||
puzzleEditorSettings:
|
puzzleEditorSettings:
|
||||||
zoneTitle: Zone
|
zoneTitle: Zone
|
||||||
zoneWidth: Width
|
zoneWidth: Largeur
|
||||||
zoneHeight: Height
|
zoneHeight: Hauteur
|
||||||
trimZone: Trim
|
trimZone: Optimiser la taille
|
||||||
clearItems: Clear Items
|
clearItems: Supprimer les objets
|
||||||
share: Share
|
share: Partager
|
||||||
report: Report
|
report: Signaler
|
||||||
clearBuildings: Clear Buildings
|
|
||||||
resetPuzzle: Reset Puzzle
|
|
||||||
puzzleEditorControls:
|
puzzleEditorControls:
|
||||||
title: Puzzle Creator
|
title: Créateur de Puzzles
|
||||||
instructions:
|
instructions:
|
||||||
- 1. Place <strong>Constant Producers</strong> to provide shapes and
|
- 1. Placez des <strong>Producteurs Constants</strong> pour fournir des formes et
|
||||||
colors to the player
|
des couleurs au joueur
|
||||||
- 2. Build one or more shapes you want the player to build later and
|
- 2. Fabriquez une ou plusieurs formes que vous voulez que le joueur fabrique plus tard et
|
||||||
deliver it to one or more <strong>Goal Acceptors</strong>
|
délivrez-la/les à un ou plusieurs <strong>Récepteurs d'Objectif</strong>
|
||||||
- 3. Once a Goal Acceptor receives a shape for a certain amount of
|
- 3. Une fois qu'un Récépteur d'Objectif a reçu une forme pendant un certain
|
||||||
time, it <strong>saves it as a goal</strong> that the player must
|
temps, il <strong>l'enregistre zn tant qu'objectif</strong> que le joueur devra
|
||||||
produce later (Indicated by the <strong>green badge</strong>).
|
produire plus tard (Indiqué par le <strong>badge vert</strong>).
|
||||||
- 4. Click the <strong>lock button</strong> on a building to disable
|
- 4. Click the <strong>lock button</strong> on a building to disable
|
||||||
it.
|
it.
|
||||||
- 5. Once you click review, your puzzle will be validated and you
|
- 5. Once you click review, your puzzle will be validated and you
|
||||||
@ -460,18 +456,18 @@ ingame:
|
|||||||
except for the Producers and Goal Acceptors - That's the part that
|
except for the Producers and Goal Acceptors - That's the part that
|
||||||
the player is supposed to figure out for themselves, after all :)
|
the player is supposed to figure out for themselves, after all :)
|
||||||
puzzleCompletion:
|
puzzleCompletion:
|
||||||
title: Puzzle Completed!
|
title: Puzzle Résolu !
|
||||||
titleLike: "Click the heart if you liked the puzzle:"
|
titleLike: "Cliquez sur le cœur si vous avez aimé le Puzzle:"
|
||||||
titleRating: How difficult did you find the puzzle?
|
titleRating: À quel point avez-vous trouvé le puzzle diffcile ?
|
||||||
titleRatingDesc: Your rating will help me to make you better suggestions in the future
|
titleRatingDesc: Votre note m'aidera à vous faire de meilleures suggestions à l'avenir
|
||||||
continueBtn: Keep Playing
|
continueBtn: Continuer à jouer
|
||||||
menuBtn: Menu
|
menuBtn: Menu
|
||||||
puzzleMetadata:
|
puzzleMetadata:
|
||||||
author: Author
|
author: Auteur
|
||||||
shortKey: Short Key
|
shortKey: Short Key
|
||||||
rating: Difficulty score
|
rating: Niveau de difficulté
|
||||||
averageDuration: Avg. Duration
|
averageDuration: Durée moyenne
|
||||||
completionRate: Completion rate
|
completionRate: Taux de réussite
|
||||||
shopUpgrades:
|
shopUpgrades:
|
||||||
belt:
|
belt:
|
||||||
name: Convoyeurs, distributeurs et tunnels
|
name: Convoyeurs, distributeurs et tunnels
|
||||||
@ -691,25 +687,25 @@ buildings:
|
|||||||
calque de câblage sur le calque normal.
|
calque de câblage sur le calque normal.
|
||||||
constant_producer:
|
constant_producer:
|
||||||
default:
|
default:
|
||||||
name: Constant Producer
|
name: Producteur Constabnt
|
||||||
description: Constantly outputs a specified shape or color.
|
description: Sort constamment une forme ou une couleur spécifiée.
|
||||||
goal_acceptor:
|
goal_acceptor:
|
||||||
default:
|
default:
|
||||||
name: Goal Acceptor
|
name: Récepteur d'Objetcif
|
||||||
description: Deliver shapes to the goal acceptor to set them as a goal.
|
description: Délivrez des formes au récepteur d'objectif pour les définir comme objectif.
|
||||||
block:
|
block:
|
||||||
default:
|
default:
|
||||||
name: Block
|
name: Bloc
|
||||||
description: Allows you to block a tile.
|
description: Permet de bloquer une case.
|
||||||
storyRewards:
|
storyRewards:
|
||||||
reward_cutter_and_trash:
|
reward_cutter_and_trash:
|
||||||
title: Découpage de formes
|
title: Découpage de formes
|
||||||
desc: You just unlocked the <strong>cutter</strong>, which cuts shapes in half
|
desc: Vous venez de déverrouiller le <strong>découpeur</strong>, qui coupe les formes en deux
|
||||||
from top to bottom <strong>regardless of its
|
de haut en bas <strong>indépendamment de son
|
||||||
orientation</strong>!<br><br>Be sure to get rid of the waste, or
|
orientation</strong>!<br><br>Assurez-vous de vous débarrasser des déchets, ou
|
||||||
otherwise <strong>it will clog and stall</strong> - For this purpose
|
sinon <strong>il se bouchera et se bloquera</strong> - À cet effet,
|
||||||
I have given you the <strong>trash</strong>, which destroys
|
Je vous ai donné la <strong>poubelle</strong>, qui détruit
|
||||||
everything you put into it!
|
tout ce que vous mettez dedans !
|
||||||
reward_rotater:
|
reward_rotater:
|
||||||
title: Rotation
|
title: Rotation
|
||||||
desc: Le <strong>pivoteur</strong> a été débloqué ! Il pivote les formes de 90
|
desc: Le <strong>pivoteur</strong> a été débloqué ! Il pivote les formes de 90
|
||||||
@ -735,9 +731,9 @@ storyRewards:
|
|||||||
<strong>placée au-dessus</strong> de la forme de gauche.
|
<strong>placée au-dessus</strong> de la forme de gauche.
|
||||||
reward_balancer:
|
reward_balancer:
|
||||||
title: Répartiteur
|
title: Répartiteur
|
||||||
desc: The multifunctional <strong>balancer</strong> has been unlocked - It can
|
desc: Le <strong>répartiteur</strong> multifonctionnel a été débloqué - Il peut
|
||||||
be used to build bigger factories by <strong>splitting and merging
|
être utilisé pour construire de plus grandes usines en <strong>divisant et en rassemblant
|
||||||
items</strong> onto multiple belts!
|
des objets</strong> sur plusieurs convoyeurs !
|
||||||
reward_tunnel:
|
reward_tunnel:
|
||||||
title: Tunnel
|
title: Tunnel
|
||||||
desc: Le <strong>tunnel</strong> a été débloqué. Vous pouvez maintenant faire
|
desc: Le <strong>tunnel</strong> a été débloqué. Vous pouvez maintenant faire
|
||||||
@ -843,14 +839,14 @@ storyRewards:
|
|||||||
gâteau : je vous donne aussi le <strong>transistor</strong> !"
|
gâteau : je vous donne aussi le <strong>transistor</strong> !"
|
||||||
reward_virtual_processing:
|
reward_virtual_processing:
|
||||||
title: Traitement virtuel
|
title: Traitement virtuel
|
||||||
desc: I just gave a whole bunch of new buildings which allow you to
|
desc: Je viens de vous donner tout un tas de nouveaux bâtiments qui vous permettent de
|
||||||
<strong>simulate the processing of shapes</strong>!<br><br> You can
|
<strong>simuler le traitement des formes</strong>!<br><br> Vous pouvez
|
||||||
now simulate a cutter, rotator, stacker and more on the wires layer!
|
maintenant simuler un découpeur, un pivoteur, un assembleur et plus encore sur la couche des fils !
|
||||||
With this you now have three options to continue the game:<br><br> -
|
Avec cela vous avez maintenant trois options pour continuer le jeu:<br><br> -
|
||||||
Build an <strong>automated machine</strong> to create any possible
|
Construire une <strong>machine automatique</strong> pour créer toute forme
|
||||||
shape requested by the HUB (I recommend to try it!).<br><br> - Build
|
possible demandée par le HUB (Je recommande d'essayer de le faire !).<br><br> - Construire
|
||||||
something cool with wires.<br><br> - Continue to play
|
quelque chose de cool avec les fils.<br><br> - Continuer à jouer
|
||||||
normally.<br><br> Whatever you choose, remember to have fun!
|
normalement.<br><br> Quoi que vous choisissiez, n'oubliez pas de vous amuser !
|
||||||
no_reward:
|
no_reward:
|
||||||
title: Niveau suivant
|
title: Niveau suivant
|
||||||
desc: "Ce niveau n’a pas de récompense mais le prochain, si !<br><br> PS : Ne
|
desc: "Ce niveau n’a pas de récompense mais le prochain, si !<br><br> PS : Ne
|
||||||
@ -1127,10 +1123,10 @@ keybindings:
|
|||||||
rotateToDown: "Rotate: Point Down"
|
rotateToDown: "Rotate: Point Down"
|
||||||
rotateToRight: "Rotate: Point Right"
|
rotateToRight: "Rotate: Point Right"
|
||||||
rotateToLeft: "Rotate: Point Left"
|
rotateToLeft: "Rotate: Point Left"
|
||||||
constant_producer: Constant Producer
|
constant_producer: Producteur Constant
|
||||||
goal_acceptor: Goal Acceptor
|
goal_acceptor: Récepteur d'Objectif
|
||||||
block: Block
|
block: Bloc
|
||||||
massSelectClear: Clear belts
|
massSelectClear: Vider les convoyeurs
|
||||||
about:
|
about:
|
||||||
title: À propos de ce jeu
|
title: À propos de ce jeu
|
||||||
body: >-
|
body: >-
|
||||||
@ -1156,7 +1152,7 @@ demo:
|
|||||||
exportingBase: Exporter une image de toute la base
|
exportingBase: Exporter une image de toute la base
|
||||||
settingNotAvailable: Indisponible dans la démo.
|
settingNotAvailable: Indisponible dans la démo.
|
||||||
tips:
|
tips:
|
||||||
- Le centre n’importe quelle forme, pas seulement la forme actuelle !
|
- Le centre accepte n’importe quelle forme, pas seulement la forme actuelle !
|
||||||
- Assurez-vous que vos usines soient modulaires, cela paiera !
|
- Assurez-vous que vos usines soient modulaires, cela paiera !
|
||||||
- Ne construisez pas trop près du centre, ou ce sera un énorme chaos !
|
- Ne construisez pas trop près du centre, ou ce sera un énorme chaos !
|
||||||
- Si l’empilement ne fonctionne pas, essayez d’échanger les entrées.
|
- Si l’empilement ne fonctionne pas, essayez d’échanger les entrées.
|
||||||
@ -1237,7 +1233,7 @@ puzzleMenu:
|
|||||||
edit: Éditer
|
edit: Éditer
|
||||||
title: Mode Puzzle
|
title: Mode Puzzle
|
||||||
createPuzzle: Créer un Puzzle
|
createPuzzle: Créer un Puzzle
|
||||||
loadPuzzle: charger
|
loadPuzzle: Charger
|
||||||
reviewPuzzle: Revoir & Publier
|
reviewPuzzle: Revoir & Publier
|
||||||
validatingPuzzle: Validation du Puzzle
|
validatingPuzzle: Validation du Puzzle
|
||||||
submittingPuzzle: Publication du Puzzle
|
submittingPuzzle: Publication du Puzzle
|
||||||
@ -1245,19 +1241,19 @@ puzzleMenu:
|
|||||||
categories:
|
categories:
|
||||||
levels: Niveaux
|
levels: Niveaux
|
||||||
new: Nouveau
|
new: Nouveau
|
||||||
top-rated: Les-mieux notés
|
top-rated: Les mieux notés
|
||||||
mine: Mes puzzles
|
mine: Mes puzzles
|
||||||
easy: Facile
|
easy: Facile
|
||||||
hard: Difficile
|
hard: Difficile
|
||||||
completed: Complété
|
completed: Complété
|
||||||
medium: Medium
|
medium: Medium
|
||||||
official: Official
|
official: Officiel
|
||||||
trending: Trending today
|
trending: Trending today
|
||||||
trending-weekly: Trending weekly
|
trending-weekly: Trending weekly
|
||||||
categories: Categories
|
categories: Catégories
|
||||||
difficulties: By Difficulty
|
difficulties: Par Difficulté
|
||||||
account: My Puzzles
|
account: Mes Puzzles
|
||||||
search: Search
|
search: Rechercher
|
||||||
validation:
|
validation:
|
||||||
title: Puzzle invalide
|
title: Puzzle invalide
|
||||||
noProducers: Veuillez placer un producteur constant !
|
noProducers: Veuillez placer un producteur constant !
|
||||||
@ -1302,6 +1298,6 @@ backendErrors:
|
|||||||
bad-payload: La demande contient des données invalides.
|
bad-payload: La demande contient des données invalides.
|
||||||
bad-building-placement: Votre puzzle contient des bâtiments placés non valides.
|
bad-building-placement: Votre puzzle contient des bâtiments placés non valides.
|
||||||
timeout: La demande a expiré.
|
timeout: La demande a expiré.
|
||||||
too-many-likes-already: The puzzle alreay got too many likes. If you still want
|
too-many-likes-already: The puzzle already got too many likes. If you still want
|
||||||
to remove it, please contact support@shapez.io!
|
to remove it, please contact support@shapez.io!
|
||||||
no-permission: You do not have the permission to perform this action.
|
no-permission: You do not have the permission to perform this action.
|
||||||
|
@ -14,7 +14,7 @@ steamPage:
|
|||||||
Ondanks het feit dat je in het begin alleen vormen maakt, komt er een punt waarop je ze gaat kleuren. Deze kleuren kun je vinden en mengen!
|
Ondanks het feit dat je in het begin alleen vormen maakt, komt er een punt waarop je ze gaat kleuren. Deze kleuren kun je vinden en mengen!
|
||||||
|
|
||||||
Door het spel op Steam te kopen kun je de volledige versie spelen. Je kunt echter ook een demo versie spelen op shapez.io en later beslissen om over te schakelen zonder voortgang te verliezen.
|
Door het spel op Steam te kopen kun je de volledige versie spelen. Je kunt echter ook een demo versie spelen op shapez.io en later beslissen om over te schakelen zonder voortgang te verliezen.
|
||||||
what_others_say: What people say about shapez.io
|
what_others_say: Wat anderen vinden van shapez.io
|
||||||
nothernlion_comment: This game is great - I'm having a wonderful time playing,
|
nothernlion_comment: This game is great - I'm having a wonderful time playing,
|
||||||
and time has flown by.
|
and time has flown by.
|
||||||
notch_comment: Oh crap. I really should sleep, but I think I just figured out
|
notch_comment: Oh crap. I really should sleep, but I think I just figured out
|
||||||
@ -1166,7 +1166,6 @@ tips:
|
|||||||
wordt de planner geactiveerd, zodat je gemakkelijk lange rijen kunt
|
wordt de planner geactiveerd, zodat je gemakkelijk lange rijen kunt
|
||||||
plaatsen.
|
plaatsen.
|
||||||
- Knippers knippen altijd verticaal, ongeacht hun oriëntatie.
|
- Knippers knippen altijd verticaal, ongeacht hun oriëntatie.
|
||||||
- Meng alle drie de kleuren om wit te krijgen.
|
|
||||||
- De opslagbuffer geeft prioriteit aan de eerste uitvoer.
|
- De opslagbuffer geeft prioriteit aan de eerste uitvoer.
|
||||||
- Investeer tijd om herhaalbare ontwerpen te maken - het is het waard!
|
- Investeer tijd om herhaalbare ontwerpen te maken - het is het waard!
|
||||||
- Door <b>SHIFT</b> ingedrukt te houden, kunnen meerdere gebouwen worden
|
- Door <b>SHIFT</b> ingedrukt te houden, kunnen meerdere gebouwen worden
|
||||||
|
@ -1108,10 +1108,10 @@ keybindings:
|
|||||||
placementDisableAutoOrientation: Отключить автоопределение направления
|
placementDisableAutoOrientation: Отключить автоопределение направления
|
||||||
placeMultiple: Оставаться в режиме размещения
|
placeMultiple: Оставаться в режиме размещения
|
||||||
placeInverse: Инвертировать автоопределение направления конвейеров
|
placeInverse: Инвертировать автоопределение направления конвейеров
|
||||||
constant_producer: Constant Producer
|
constant_producer: Постоянный генератор
|
||||||
goal_acceptor: Goal Acceptor
|
goal_acceptor: Приёмник предметов
|
||||||
block: Block
|
block: Блок
|
||||||
massSelectClear: Clear belts
|
massSelectClear: Очистить конвейеры
|
||||||
about:
|
about:
|
||||||
title: Об игре
|
title: Об игре
|
||||||
body: >-
|
body: >-
|
||||||
@ -1245,11 +1245,11 @@ puzzleMenu:
|
|||||||
постоянные производители не доставляют фигуры напрямую приемникам
|
постоянные производители не доставляют фигуры напрямую приемникам
|
||||||
цели.
|
цели.
|
||||||
difficulties:
|
difficulties:
|
||||||
easy: Лего
|
easy: Легко
|
||||||
medium: Средне
|
medium: Средне
|
||||||
hard: Сложно
|
hard: Сложно
|
||||||
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
|
dlcHint: Уже купили DLC? Проверьте, что оно активировано, нажав правый клик на
|
||||||
shapez.io in your library, selecting Properties > DLCs.
|
shapez.io в своей библиотеке, и далее Свойства > Доп. Контент
|
||||||
backendErrors:
|
backendErrors:
|
||||||
ratelimit: Вы слишком часто выполняете свои действия. Подождите немного.
|
ratelimit: Вы слишком часто выполняете свои действия. Подождите немного.
|
||||||
invalid-api-key: Не удалось связаться с сервером, попробуйте
|
invalid-api-key: Не удалось связаться с сервером, попробуйте
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user