mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Add multiple performance settings
This commit is contained in:
parent
9e76606674
commit
9085f32ec3
@ -12,6 +12,7 @@ export const CHANGELOG = [
|
||||
"Fix rare crash regarding the buildings toolbar (by isaisstillalive)",
|
||||
"Fixed some phrases (by EnderDoom77)",
|
||||
"Zoom towards mouse cursor (by Dimava)",
|
||||
"Added multiple settings to optimize the performance",
|
||||
"Updated the soundtrack again, it is now 40 minutes in total!",
|
||||
"Updated and added new translations (Thanks to all contributors!)",
|
||||
"Allow editing waypoints (by isaisstillalive)",
|
||||
|
@ -46,6 +46,7 @@ export const globalConfig = {
|
||||
// Map
|
||||
mapChunkSize: 16,
|
||||
mapChunkOverviewMinZoom: 0.9,
|
||||
mapChunkWorldSize: null, // COMPUTED
|
||||
|
||||
// Belt speeds
|
||||
// NOTICE: Update webpack.production.config too!
|
||||
@ -110,6 +111,8 @@ export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
||||
// Automatic calculations
|
||||
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
|
||||
|
||||
globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;
|
||||
|
||||
// Dynamic calculations
|
||||
if (globalConfig.debug.disableMapOverview) {
|
||||
globalConfig.mapChunkOverviewMinZoom = 0;
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* typehints:start */
|
||||
import { InGameState } from "../states/ingame";
|
||||
import { Application } from "../application";
|
||||
/* typehints:end */
|
||||
|
||||
import { BufferMaintainer } from "../core/buffer_maintainer";
|
||||
import { disableImageSmoothing, enableImageSmoothing, registerCanvas } from "../core/buffer_utils";
|
||||
import { globalConfig } from "../core/config";
|
||||
@ -10,12 +8,16 @@ import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager";
|
||||
import { DrawParameters } from "../core/draw_parameters";
|
||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { Rectangle } from "../core/rectangle";
|
||||
import { randomInt } from "../core/utils";
|
||||
import { Vector } from "../core/vector";
|
||||
import { Savegame } from "../savegame/savegame";
|
||||
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
||||
import { InGameState } from "../states/ingame";
|
||||
import { AutomaticSave } from "./automatic_save";
|
||||
import { MetaHubBuilding } from "./buildings/hub";
|
||||
import { Camera } from "./camera";
|
||||
import { DynamicTickrate } from "./dynamic_tickrate";
|
||||
import { EntityManager } from "./entity_manager";
|
||||
import { GameSystemManager } from "./game_system_manager";
|
||||
import { HubGoals } from "./hub_goals";
|
||||
@ -23,15 +25,12 @@ import { GameHUD } from "./hud/hud";
|
||||
import { KeyActionMapper } from "./key_action_mapper";
|
||||
import { GameLogic } from "./logic";
|
||||
import { MapView } from "./map_view";
|
||||
import { GameRoot, enumLayer } from "./root";
|
||||
import { defaultBuildingVariant } from "./meta_building";
|
||||
import { ProductionAnalytics } from "./production_analytics";
|
||||
import { enumLayer, GameRoot } from "./root";
|
||||
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
||||
import { SoundProxy } from "./sound_proxy";
|
||||
import { GameTime } from "./time/game_time";
|
||||
import { ProductionAnalytics } from "./production_analytics";
|
||||
import { randomInt } from "../core/utils";
|
||||
import { defaultBuildingVariant } from "./meta_building";
|
||||
import { DynamicTickrate } from "./dynamic_tickrate";
|
||||
import { Rectangle } from "../core/rectangle";
|
||||
|
||||
const logger = createLogger("ingame/core");
|
||||
|
||||
@ -233,10 +232,6 @@ export class GameCore {
|
||||
tick(deltaMs) {
|
||||
const root = this.root;
|
||||
|
||||
if (root.hud.parts.processingOverlay.hasTasks() || root.hud.parts.processingOverlay.isRunning()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Extract current real time
|
||||
root.time.updateRealtimeNow();
|
||||
|
||||
@ -326,14 +321,6 @@ export class GameCore {
|
||||
const root = this.root;
|
||||
const systems = root.systemMgr.systems;
|
||||
|
||||
const taskRunner = root.hud.parts.processingOverlay;
|
||||
if (taskRunner.hasTasks()) {
|
||||
if (!taskRunner.isRunning()) {
|
||||
taskRunner.process();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.root.dynamicTickrate.onFrameRendered();
|
||||
|
||||
if (!this.shouldRender()) {
|
||||
@ -357,15 +344,16 @@ export class GameCore {
|
||||
|
||||
// Compute optimal zoom level and atlas scale
|
||||
const zoomLevel = root.camera.zoomLevel;
|
||||
const lowQuality = root.app.settings.getAllSettings().lowQualityTextures;
|
||||
const effectiveZoomLevel =
|
||||
(zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness;
|
||||
|
||||
let desiredAtlasScale = "0.1";
|
||||
if (effectiveZoomLevel > 0.75) {
|
||||
if (effectiveZoomLevel > 0.75 && !lowQuality) {
|
||||
desiredAtlasScale = "1";
|
||||
} else if (effectiveZoomLevel > 0.5) {
|
||||
} else if (effectiveZoomLevel > 0.5 && !lowQuality) {
|
||||
desiredAtlasScale = "0.75";
|
||||
} else if (effectiveZoomLevel > 0.25) {
|
||||
} else if (effectiveZoomLevel > 0.25 && !lowQuality) {
|
||||
desiredAtlasScale = "0.5";
|
||||
} else if (effectiveZoomLevel > 0.1) {
|
||||
desiredAtlasScale = "0.25";
|
||||
@ -380,7 +368,7 @@ export class GameCore {
|
||||
root: root,
|
||||
});
|
||||
|
||||
if (G_IS_DEV && (globalConfig.debug.testCulling || globalConfig.debug.hideFog)) {
|
||||
if (G_IS_DEV && globalConfig.debug.testCulling) {
|
||||
context.clearRect(0, 0, root.gameWidth, root.gameHeight);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import { TrailerMaker } from "./trailer_maker";
|
||||
|
||||
import { Signal } from "../../core/signal";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { HUDProcessingOverlay } from "./parts/processing_overlay";
|
||||
import { HUDBuildingsToolbar } from "./parts/buildings_toolbar";
|
||||
import { HUDBuildingPlacer } from "./parts/building_placer";
|
||||
import { HUDBlueprintPlacer } from "./parts/blueprint_placer";
|
||||
@ -57,7 +56,6 @@ export class GameHUD {
|
||||
*/
|
||||
initialize() {
|
||||
this.parts = {
|
||||
processingOverlay: new HUDProcessingOverlay(this.root),
|
||||
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
||||
wiresToolbar: new HUDWiresToolbar(this.root),
|
||||
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
||||
|
@ -1,112 +0,0 @@
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { Signal } from "../../../core/signal";
|
||||
import { InputReceiver } from "../../../core/input_receiver";
|
||||
import { createLogger } from "../../../core/logging";
|
||||
|
||||
const logger = createLogger("hud/processing_overlay");
|
||||
|
||||
export class HUDProcessingOverlay extends BaseHUDPart {
|
||||
constructor(root) {
|
||||
super(root);
|
||||
this.tasks = [];
|
||||
this.computeTimeout = null;
|
||||
|
||||
this.root.signals.performAsync.add(this.queueTask, this);
|
||||
|
||||
this.allTasksFinished = new Signal();
|
||||
this.inputReceiver = new InputReceiver("processing-overlay");
|
||||
|
||||
this.root.signals.aboutToDestruct.add(() =>
|
||||
this.root.app.inputMgr.destroyReceiver(this.inputReceiver)
|
||||
);
|
||||
}
|
||||
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(
|
||||
parent,
|
||||
"rg_HUD_ProcessingOverlay",
|
||||
["hudElement"],
|
||||
`
|
||||
<span class="prefab_LoadingTextWithAnim">
|
||||
Computing
|
||||
</span>
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.domWatcher = new DynamicDomAttach(this.root, this.element, {
|
||||
timeToKeepSeconds: 0,
|
||||
});
|
||||
}
|
||||
|
||||
queueTask(task, name) {
|
||||
if (!this.root.gameInitialized) {
|
||||
// Tasks before the game started can be done directlry
|
||||
task();
|
||||
return;
|
||||
}
|
||||
task.__name = name;
|
||||
this.tasks.push(task);
|
||||
}
|
||||
|
||||
hasTasks() {
|
||||
return this.tasks.length > 0;
|
||||
}
|
||||
|
||||
isRunning() {
|
||||
return this.computeTimeout !== null;
|
||||
}
|
||||
|
||||
processSync() {
|
||||
const now = performance.now();
|
||||
while (this.tasks.length > 0) {
|
||||
const workload = this.tasks[0];
|
||||
workload.call();
|
||||
this.tasks.shift();
|
||||
}
|
||||
const duration = performance.now() - now;
|
||||
if (duration > 100) {
|
||||
logger.log("Tasks done slow (SYNC!) within", (performance.now() - now).toFixed(2), "ms");
|
||||
}
|
||||
}
|
||||
|
||||
process() {
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReceiver);
|
||||
|
||||
this.domWatcher.update(true);
|
||||
if (this.tasks.length === 0) {
|
||||
logger.warn("No tasks but still called process");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.computeTimeout) {
|
||||
assert(false, "Double compute queued");
|
||||
clearTimeout(this.computeTimeout);
|
||||
}
|
||||
|
||||
this.computeTimeout = setTimeout(() => {
|
||||
const now = performance.now();
|
||||
while (this.tasks.length > 0) {
|
||||
const workload = this.tasks[0];
|
||||
workload.call();
|
||||
this.tasks.shift();
|
||||
}
|
||||
const duration = performance.now() - now;
|
||||
if (duration > 100) {
|
||||
logger.log("Tasks done slow within", (performance.now() - now).toFixed(2), "ms");
|
||||
}
|
||||
|
||||
this.domWatcher.update(false);
|
||||
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReceiver);
|
||||
|
||||
clearTimeout(this.computeTimeout);
|
||||
this.computeTimeout = null;
|
||||
|
||||
this.allTasksFinished.dispatch();
|
||||
});
|
||||
}
|
||||
}
|
@ -63,7 +63,7 @@ export class HUDScreenshotExporter extends BaseHUDPart {
|
||||
}
|
||||
logger.log("ChunkSizePixels:", chunkSizePixels);
|
||||
|
||||
const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize);
|
||||
const chunkScale = chunkSizePixels / globalConfig.mapChunkWorldSize;
|
||||
logger.log("Scale:", chunkScale);
|
||||
|
||||
logger.log("Allocating buffer, if the factory grew too big it will crash here");
|
||||
@ -79,10 +79,10 @@ export class HUDScreenshotExporter extends BaseHUDPart {
|
||||
logger.log("Got buffer, rendering now ...");
|
||||
|
||||
const visibleRect = new Rectangle(
|
||||
minChunk.x * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
minChunk.y * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
dimensions.x * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
dimensions.y * globalConfig.mapChunkSize * globalConfig.tileSize
|
||||
minChunk.x * globalConfig.mapChunkWorldSize,
|
||||
minChunk.y * globalConfig.mapChunkWorldSize,
|
||||
dimensions.x * globalConfig.mapChunkWorldSize,
|
||||
dimensions.y * globalConfig.mapChunkWorldSize
|
||||
);
|
||||
const parameters = new DrawParameters({
|
||||
context,
|
||||
|
@ -1,7 +1,12 @@
|
||||
import { GameRoot, enumLayer } from "./root";
|
||||
import { globalConfig } from "../core/config";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { clamp, fastArrayDeleteValueIfContained, make2DUndefinedArray } from "../core/utils";
|
||||
import {
|
||||
clamp,
|
||||
fastArrayDeleteValueIfContained,
|
||||
make2DUndefinedArray,
|
||||
fastArrayDeleteValue,
|
||||
} from "../core/utils";
|
||||
import { Vector } from "../core/vector";
|
||||
import { BaseItem } from "./base_item";
|
||||
import { enumColors } from "./colors";
|
||||
@ -39,6 +44,15 @@ export class MapChunk {
|
||||
/** @type {Array<Entity>} */
|
||||
this.containedEntities = [];
|
||||
|
||||
/**
|
||||
* Which entities this chunk contains, sorted by layer
|
||||
* @type {Object<enumLayer, Array<Entity>>}
|
||||
*/
|
||||
this.containedEntitiesByLayer = {
|
||||
[enumLayer.regular]: [],
|
||||
[enumLayer.wires]: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Store which patches we have so we can render them in the overview
|
||||
* @type {Array<{pos: Vector, item: BaseItem, size: number }>}
|
||||
@ -403,8 +417,9 @@ export class MapChunk {
|
||||
assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY);
|
||||
|
||||
if (oldContents) {
|
||||
// Remove from list
|
||||
// Remove from list (the old contents must be reigstered)
|
||||
fastArrayDeleteValueIfContained(this.containedEntities, oldContents);
|
||||
fastArrayDeleteValueIfContained(this.containedEntitiesByLayer[layer], oldContents);
|
||||
}
|
||||
|
||||
if (layer === enumLayer.regular) {
|
||||
@ -417,6 +432,10 @@ export class MapChunk {
|
||||
if (this.containedEntities.indexOf(contents) < 0) {
|
||||
this.containedEntities.push(contents);
|
||||
}
|
||||
|
||||
if (this.containedEntitiesByLayer[layer].indexOf(contents) < 0) {
|
||||
this.containedEntitiesByLayer[layer].push(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,13 +69,14 @@ export class MapChunkView extends MapChunk {
|
||||
redrawMethod: this.generateOverlayBuffer.bind(this),
|
||||
});
|
||||
|
||||
const dims = globalConfig.mapChunkSize * globalConfig.tileSize;
|
||||
const dims = globalConfig.mapChunkWorldSize;
|
||||
|
||||
// Draw chunk "pixel" art
|
||||
parameters.context.imageSmoothingEnabled = false;
|
||||
|
||||
parameters.context.drawImage(sprite, this.x * dims, this.y * dims, dims, dims);
|
||||
parameters.context.imageSmoothingEnabled = true;
|
||||
|
||||
// Draw patch items
|
||||
if (this.root.currentLayer === enumLayer.regular) {
|
||||
for (let i = 0; i < this.patches.length; ++i) {
|
||||
const patch = this.patches[i];
|
||||
|
@ -195,17 +195,19 @@ export class MapView extends BaseMap {
|
||||
);
|
||||
}
|
||||
|
||||
const dpi = this.backgroundCacheDPI;
|
||||
parameters.context.scale(1 / dpi, 1 / dpi);
|
||||
if (!this.root.app.settings.getAllSettings().disableTileGrid) {
|
||||
const dpi = this.backgroundCacheDPI;
|
||||
parameters.context.scale(1 / dpi, 1 / dpi);
|
||||
|
||||
parameters.context.fillStyle = this.cachedBackgroundPattern;
|
||||
parameters.context.fillRect(
|
||||
parameters.visibleRect.x * dpi,
|
||||
parameters.visibleRect.y * dpi,
|
||||
parameters.visibleRect.w * dpi,
|
||||
parameters.visibleRect.h * dpi
|
||||
);
|
||||
parameters.context.scale(dpi, dpi);
|
||||
parameters.context.fillStyle = this.cachedBackgroundPattern;
|
||||
parameters.context.fillRect(
|
||||
parameters.visibleRect.x * dpi,
|
||||
parameters.visibleRect.y * dpi,
|
||||
parameters.visibleRect.w * dpi,
|
||||
parameters.visibleRect.h * dpi
|
||||
);
|
||||
parameters.context.scale(dpi, dpi);
|
||||
}
|
||||
|
||||
this.drawVisibleChunks(parameters, MapChunkView.prototype.drawBackgroundLayer);
|
||||
|
||||
@ -233,16 +235,16 @@ export class MapView extends BaseMap {
|
||||
for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) {
|
||||
parameters.context.fillStyle = "#ffaaaa";
|
||||
parameters.context.fillRect(
|
||||
chunkX * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
chunkY * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
chunkX * globalConfig.mapChunkWorldSize,
|
||||
chunkY * globalConfig.mapChunkWorldSize,
|
||||
globalConfig.mapChunkWorldSize,
|
||||
3
|
||||
);
|
||||
parameters.context.fillRect(
|
||||
chunkX * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
chunkY * globalConfig.mapChunkSize * globalConfig.tileSize,
|
||||
chunkX * globalConfig.mapChunkWorldSize,
|
||||
chunkY * globalConfig.mapChunkWorldSize,
|
||||
3,
|
||||
globalConfig.mapChunkSize * globalConfig.tileSize
|
||||
globalConfig.mapChunkWorldSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -162,9 +162,6 @@ export class GameRoot {
|
||||
// Called right after game is initialized
|
||||
postLoadHook: /** @type {TypedSignal<[]>} */ (new Signal()),
|
||||
|
||||
// Can be used to trigger an async task
|
||||
performAsync: /** @type {TypedSignal<[function]>} */ (new Signal()),
|
||||
|
||||
shapeDelivered: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||
itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new Signal()),
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item
|
||||
import { MapChunkView } from "../map_chunk_view";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { enumLayer } from "../root";
|
||||
|
||||
export class LeverSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
@ -31,23 +32,19 @@ export class LeverSystem extends GameSystemWithFilter {
|
||||
* @param {MapChunkView} chunk
|
||||
*/
|
||||
drawChunk(parameters, chunk) {
|
||||
const contents = chunk.contents;
|
||||
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||
const entity = contents[x][y];
|
||||
|
||||
if (entity && entity.components.Lever) {
|
||||
const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff;
|
||||
|
||||
const origin = entity.components.StaticMapEntity.origin;
|
||||
sprite.drawCached(
|
||||
parameters,
|
||||
origin.x * globalConfig.tileSize,
|
||||
origin.y * globalConfig.tileSize,
|
||||
globalConfig.tileSize,
|
||||
globalConfig.tileSize
|
||||
);
|
||||
}
|
||||
const contents = chunk.containedEntitiesByLayer[enumLayer.regular];
|
||||
for (let i = 0; i < contents.length; ++i) {
|
||||
const entity = contents[i];
|
||||
if (entity && entity.components.Lever) {
|
||||
const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff;
|
||||
const origin = entity.components.StaticMapEntity.origin;
|
||||
sprite.drawCached(
|
||||
parameters,
|
||||
origin.x * globalConfig.tileSize,
|
||||
origin.y * globalConfig.tileSize,
|
||||
globalConfig.tileSize,
|
||||
globalConfig.tileSize
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { GameSystem } from "../game_system";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { GameSystem } from "../game_system";
|
||||
import { MapChunkView } from "../map_chunk_view";
|
||||
import { THEME } from "../theme";
|
||||
|
||||
export class MapResourcesSystem extends GameSystem {
|
||||
/**
|
||||
@ -10,39 +11,106 @@ export class MapResourcesSystem extends GameSystem {
|
||||
* @param {MapChunkView} chunk
|
||||
*/
|
||||
drawChunk(parameters, chunk) {
|
||||
const basicChunkBackground = this.root.buffers.getForKey({
|
||||
key: "chunkres",
|
||||
subKey: chunk.renderKey,
|
||||
w: globalConfig.mapChunkSize,
|
||||
h: globalConfig.mapChunkSize,
|
||||
dpi: 1,
|
||||
redrawMethod: this.generateChunkBackground.bind(this, chunk),
|
||||
});
|
||||
|
||||
parameters.context.imageSmoothingEnabled = false;
|
||||
parameters.context.drawImage(
|
||||
basicChunkBackground,
|
||||
chunk.tileX * globalConfig.tileSize,
|
||||
chunk.tileY * globalConfig.tileSize,
|
||||
globalConfig.mapChunkWorldSize,
|
||||
globalConfig.mapChunkWorldSize
|
||||
);
|
||||
parameters.context.imageSmoothingEnabled = true;
|
||||
|
||||
parameters.context.globalAlpha = 0.5;
|
||||
|
||||
const layer = chunk.lowerLayer;
|
||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||
const row = layer[x];
|
||||
const worldX = (chunk.tileX + x) * globalConfig.tileSize;
|
||||
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||
const lowerItem = row[y];
|
||||
if (lowerItem) {
|
||||
const worldY = (chunk.tileY + y) * globalConfig.tileSize;
|
||||
if (this.root.app.settings.getAllSettings().lowQualityMapResources) {
|
||||
// LOW QUALITY: Draw patch items only
|
||||
for (let i = 0; i < chunk.patches.length; ++i) {
|
||||
const patch = chunk.patches[i];
|
||||
|
||||
if (
|
||||
!parameters.visibleRect.containsRect4Params(
|
||||
worldX,
|
||||
worldY,
|
||||
globalConfig.tileSize,
|
||||
globalConfig.tileSize
|
||||
)
|
||||
) {
|
||||
// Clipped
|
||||
continue;
|
||||
patch.item.draw(
|
||||
chunk.x * globalConfig.mapChunkWorldSize + patch.pos.x * globalConfig.tileSize,
|
||||
chunk.y * globalConfig.mapChunkWorldSize + patch.pos.y * globalConfig.tileSize,
|
||||
parameters,
|
||||
Math.min(80, 40 / parameters.zoomLevel)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// HIGH QUALITY: Draw all items
|
||||
const layer = chunk.lowerLayer;
|
||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||
const row = layer[x];
|
||||
const worldX = (chunk.tileX + x) * globalConfig.tileSize;
|
||||
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||
const lowerItem = row[y];
|
||||
if (lowerItem) {
|
||||
const worldY = (chunk.tileY + y) * globalConfig.tileSize;
|
||||
|
||||
if (
|
||||
!parameters.visibleRect.containsRect4Params(
|
||||
worldX,
|
||||
worldY,
|
||||
globalConfig.tileSize,
|
||||
globalConfig.tileSize
|
||||
)
|
||||
) {
|
||||
// Clipped
|
||||
continue;
|
||||
}
|
||||
|
||||
// parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource();
|
||||
// parameters.context.fillRect(worldX, worldY, globalConfig.tileSize, globalConfig.tileSize);
|
||||
lowerItem.draw(
|
||||
worldX + globalConfig.halfTileSize,
|
||||
worldY + globalConfig.halfTileSize,
|
||||
parameters
|
||||
);
|
||||
}
|
||||
|
||||
parameters.context.fillStyle = lowerItem.getBackgroundColorAsResource();
|
||||
parameters.context.fillRect(worldX, worldY, globalConfig.tileSize, globalConfig.tileSize);
|
||||
lowerItem.draw(
|
||||
worldX + globalConfig.halfTileSize,
|
||||
worldY + globalConfig.halfTileSize,
|
||||
parameters
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
parameters.context.globalAlpha = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {MapChunkView} chunk
|
||||
* @param {HTMLCanvasElement} canvas
|
||||
* @param {CanvasRenderingContext2D} context
|
||||
* @param {number} w
|
||||
* @param {number} h
|
||||
* @param {number} dpi
|
||||
*/
|
||||
generateChunkBackground(chunk, canvas, context, w, h, dpi) {
|
||||
if (this.root.app.settings.getAllSettings().disableTileGrid) {
|
||||
// The map doesn't draw a background, so we have to
|
||||
|
||||
context.fillStyle = THEME.map.background;
|
||||
context.fillRect(0, 0, w, h);
|
||||
} else {
|
||||
context.clearRect(0, 0, w, h);
|
||||
}
|
||||
|
||||
context.globalAlpha = 0.5;
|
||||
const layer = chunk.lowerLayer;
|
||||
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||
const row = layer[x];
|
||||
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||
const item = row[y];
|
||||
if (item) {
|
||||
context.fillStyle = item.getBackgroundColorAsResource();
|
||||
context.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,11 +153,6 @@ export class GameTime extends BasicSerializableObject {
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// If we queued async tasks, perform them next frame and do not update anymore
|
||||
if (this.root.hud.parts.processingOverlay.hasTasks()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ const logger = createLogger("application_settings");
|
||||
export const enumCategories = {
|
||||
general: "general",
|
||||
userInterface: "userInterface",
|
||||
performance: "performance",
|
||||
advanced: "advanced",
|
||||
};
|
||||
|
||||
@ -147,20 +148,6 @@ export const allApplicationSettings = [
|
||||
(app, id) => app.updateAfterUiScaleChanged(),
|
||||
}),
|
||||
|
||||
new BoolSetting(
|
||||
"fullscreen",
|
||||
enumCategories.general,
|
||||
/**
|
||||
* @param {Application} app
|
||||
*/
|
||||
(app, value) => {
|
||||
if (app.platformWrapper.getSupportsFullscreen()) {
|
||||
app.platformWrapper.setFullscreen(value);
|
||||
}
|
||||
},
|
||||
!IS_DEMO
|
||||
),
|
||||
|
||||
new BoolSetting(
|
||||
"soundsMuted",
|
||||
enumCategories.general,
|
||||
@ -178,6 +165,20 @@ export const allApplicationSettings = [
|
||||
(app, value) => app.sound.setMusicMuted(value)
|
||||
),
|
||||
|
||||
new BoolSetting(
|
||||
"fullscreen",
|
||||
enumCategories.general,
|
||||
/**
|
||||
* @param {Application} app
|
||||
*/
|
||||
(app, value) => {
|
||||
if (app.platformWrapper.getSupportsFullscreen()) {
|
||||
app.platformWrapper.setFullscreen(value);
|
||||
}
|
||||
},
|
||||
!IS_DEMO
|
||||
),
|
||||
|
||||
new BoolSetting(
|
||||
"enableColorBlindHelper",
|
||||
enumCategories.general,
|
||||
@ -187,7 +188,6 @@ export const allApplicationSettings = [
|
||||
(app, value) => null
|
||||
),
|
||||
|
||||
// GAME
|
||||
new BoolSetting("offerHints", enumCategories.userInterface, (app, value) => {}),
|
||||
|
||||
new EnumSetting("theme", {
|
||||
@ -220,16 +220,6 @@ export const allApplicationSettings = [
|
||||
(app, id) => null,
|
||||
}),
|
||||
|
||||
new EnumSetting("refreshRate", {
|
||||
options: ["60", "75", "100", "120", "144", "165", "250", G_IS_DEV ? "10" : "500"],
|
||||
valueGetter: rate => rate,
|
||||
textGetter: rate => rate + " Hz",
|
||||
category: enumCategories.advanced,
|
||||
restartRequired: false,
|
||||
changeCb: (app, id) => {},
|
||||
enabled: !IS_DEMO,
|
||||
}),
|
||||
|
||||
new EnumSetting("scrollWheelSensitivity", {
|
||||
options: scrollWheelSensitivities.sort((a, b) => a.scale - b.scale),
|
||||
valueGetter: scale => scale.id,
|
||||
@ -258,6 +248,20 @@ export const allApplicationSettings = [
|
||||
new BoolSetting("compactBuildingInfo", enumCategories.userInterface, (app, value) => {}),
|
||||
new BoolSetting("disableCutDeleteWarnings", enumCategories.advanced, (app, value) => {}),
|
||||
new BoolSetting("rotationByBuilding", enumCategories.advanced, (app, value) => {}),
|
||||
|
||||
new EnumSetting("refreshRate", {
|
||||
options: ["60", "75", "100", "120", "144", "165", "250", "500"],
|
||||
valueGetter: rate => rate,
|
||||
textGetter: rate => rate + " Hz",
|
||||
category: enumCategories.performance,
|
||||
restartRequired: false,
|
||||
changeCb: (app, id) => {},
|
||||
enabled: !IS_DEMO,
|
||||
}),
|
||||
|
||||
new BoolSetting("lowQualityMapResources", enumCategories.performance, (app, value) => {}),
|
||||
new BoolSetting("disableTileGrid", enumCategories.performance, (app, value) => {}),
|
||||
new BoolSetting("lowQualityTextures", enumCategories.performance, (app, value) => {}),
|
||||
];
|
||||
|
||||
export function getApplicationSettingById(id) {
|
||||
@ -288,6 +292,10 @@ class SettingsStorage {
|
||||
|
||||
this.enableColorBlindHelper = false;
|
||||
|
||||
this.lowQualityMapResources = false;
|
||||
this.disableTileGrid = false;
|
||||
this.lowQualityTextures = false;
|
||||
|
||||
/**
|
||||
* @type {Object.<string, number>}
|
||||
*/
|
||||
@ -487,7 +495,7 @@ export class ApplicationSettings extends ReadWriteProxy {
|
||||
}
|
||||
|
||||
getCurrentVersion() {
|
||||
return 18;
|
||||
return 21;
|
||||
}
|
||||
|
||||
/** @param {{settings: SettingsStorage, version: number}} data */
|
||||
@ -565,6 +573,21 @@ export class ApplicationSettings extends ReadWriteProxy {
|
||||
data.version = 18;
|
||||
}
|
||||
|
||||
if (data.version < 19) {
|
||||
data.settings.lowQualityMapResources = false;
|
||||
data.version = 19;
|
||||
}
|
||||
|
||||
if (data.version < 20) {
|
||||
data.settings.disableTileGrid = false;
|
||||
data.version = 20;
|
||||
}
|
||||
|
||||
if (data.version < 21) {
|
||||
data.settings.lowQualityTextures = false;
|
||||
data.version = 21;
|
||||
}
|
||||
|
||||
return ExplainedResult.good();
|
||||
}
|
||||
}
|
||||
|
@ -381,17 +381,6 @@ export class InGameState extends GameState {
|
||||
}
|
||||
}
|
||||
|
||||
// // Check if we can show an ad
|
||||
// // DISABLED
|
||||
// if (this.stage === stages.s10_gameRunning && !this.core.root.hud.parts.processingOverlay.hasTasks()) {
|
||||
// if (this.app.isRenderable() && this.app.adProvider.getCanShowVideoAd()) {
|
||||
// this.saveThenGoToState("WatchAdState", {
|
||||
// nextStateId: "RunningGameState",
|
||||
// nextStatePayload: this.creationPayload,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
if (this.stage === stages.s10_gameRunning) {
|
||||
this.core.tick(dt);
|
||||
}
|
||||
|
@ -670,6 +670,7 @@ settings:
|
||||
general: General
|
||||
userInterface: User Interface
|
||||
advanced: Advanced
|
||||
performance: Performance
|
||||
|
||||
versionBadges:
|
||||
dev: Development
|
||||
@ -759,9 +760,9 @@ settings:
|
||||
light: Light
|
||||
|
||||
refreshRate:
|
||||
title: Simulation Target
|
||||
title: Tick Rate
|
||||
description: >-
|
||||
If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow.
|
||||
The game will automatically adjust the tickrate to be between this target tickrate and half of it. For example, with a tickrate of 60hz, the game will try to stay at 60hz, and if your computer can't handle it it will go down until it eventually reaches 30hz.
|
||||
|
||||
alwaysMultiplace:
|
||||
title: Multiplace
|
||||
@ -798,6 +799,22 @@ settings:
|
||||
description: >-
|
||||
Disables the warning dialogs brought up when cutting/deleting more than 100 entities.
|
||||
|
||||
lowQualityMapResources:
|
||||
title: Low Quality Map Resources
|
||||
description: >-
|
||||
Simplifies the rendering of resources on the map when zoomed in to improve performance.
|
||||
It even looks cleaner, so be sure to try it out!
|
||||
|
||||
disableTileGrid:
|
||||
title: Disable Grid
|
||||
description: >-
|
||||
Disabling the tile grid can help with the performance. This also makes the game look cleaner!
|
||||
|
||||
lowQualityTextures:
|
||||
title: Low quality textures (Ugly)
|
||||
description: >-
|
||||
Uses low quality textures to save performance. This will make the game look very ugly!
|
||||
|
||||
keybindings:
|
||||
title: Keybindings
|
||||
hint: >-
|
||||
|
Loading…
Reference in New Issue
Block a user