Add potato mode

This commit is contained in:
tobspr 2020-09-19 10:34:46 +02:00
parent 7bc45d8959
commit 47443058e0
17 changed files with 834 additions and 583 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 278 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 KiB

After

Width:  |  Height:  |  Size: 690 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -5,6 +5,8 @@ import { round3Digits } from "./utils";
export const ORIGINAL_SPRITE_SCALE = "0.75";
export const FULL_CLIP_RECT = new Rectangle(0, 0, 1, 1);
const EXTRUDE = 0.1;
export class BaseSprite {
/**
* Returns the raw handle
@ -211,10 +213,10 @@ export class AtlasSprite extends BaseSprite {
srcH,
// dest pos and size
destX,
destY,
destW,
destH
destX - EXTRUDE,
destY - EXTRUDE,
destW + 2 * EXTRUDE,
destH + 2 * EXTRUDE
);
}
@ -267,10 +269,10 @@ export class AtlasSprite extends BaseSprite {
srcH,
// dest pos and size
destX,
destY,
destW,
destH
destX - EXTRUDE,
destY - EXTRUDE,
destW + 2 * EXTRUDE,
destH + 2 * EXTRUDE
);
}

View File

@ -2,7 +2,7 @@ import { globalConfig } from "../core/config";
import { DrawParameters } from "../core/draw_parameters";
import { createLogger } from "../core/logging";
import { Rectangle } from "../core/rectangle";
import { epsilonCompare, round4Digits, clamp } from "../core/utils";
import { clamp, epsilonCompare, round4Digits } from "../core/utils";
import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
import { BasicSerializableObject, types } from "../savegame/serialization";
import { BaseItem } from "./base_item";
@ -1069,12 +1069,14 @@ export class BeltPath extends BasicSerializableObject {
// Trigger animation on the acceptor comp
const targetAcceptorComp = this.acceptorTarget.entity.components.ItemAcceptor;
if (targetAcceptorComp) {
targetAcceptorComp.onItemAccepted(
this.acceptorTarget.slot,
this.acceptorTarget.direction,
item,
remainingProgress
);
if (!this.root.app.settings.getAllSettings().simplifiedBelts) {
targetAcceptorComp.onItemAccepted(
this.acceptorTarget.slot,
this.acceptorTarget.direction,
item,
remainingProgress
);
}
}
return true;
@ -1179,6 +1181,35 @@ export class BeltPath extends BasicSerializableObject {
parameters.context.fillRect(firstItemIndicator.x - 3, firstItemIndicator.y - 1, 6, 2);
}
/**
* Checks if this belt path should render simplified
*/
checkIsPotatoMode() {
// POTATO Mode: Only show items when belt is hovered
if (!this.root.app.settings.getAllSettings().simplifiedBelts) {
return false;
}
const mousePos = this.root.app.mousePosition;
if (!mousePos) {
// Mouse not registered
return true;
}
const tile = this.root.camera.screenToWorld(mousePos).toTileSpace();
const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular");
if (!contents || !contents.components.Belt) {
// Nothing below
return true;
}
if (contents.components.Belt.assignedPath !== this) {
// Not this path
return true;
}
return false;
}
/**
* Draws the path
* @param {DrawParameters} parameters
@ -1193,6 +1224,29 @@ export class BeltPath extends BasicSerializableObject {
return;
}
if (this.checkIsPotatoMode()) {
const firstItem = this.items[0];
if (this.entityPath.length > 1 && firstItem) {
const medianBeltIndex = clamp(
Math.round(this.entityPath.length / 2 - 1),
0,
this.entityPath.length - 1
);
const medianBelt = this.entityPath[medianBeltIndex];
const staticComp = medianBelt.components.StaticMapEntity;
const centerPosLocal = medianBelt.components.Belt.transformBeltToLocalSpace(
this.entityPath.length % 2 === 0 ? 1 : 0.5
);
const centerPos = staticComp.localTileToWorld(centerPosLocal).toWorldSpaceCenterOfTile();
parameters.context.globalAlpha = 0.5;
firstItem[_item].drawItemCenteredClipped(centerPos.x, centerPos.y, parameters);
parameters.context.globalAlpha = 1;
}
return;
}
let currentItemPos = this.spacingToFirstItem;
let currentItemIndex = 0;

View File

@ -88,16 +88,17 @@ export class MapChunkView extends MapChunk {
});
const dims = globalConfig.mapChunkWorldSize;
const extrude = 0.05;
// Draw chunk "pixel" art
parameters.context.imageSmoothingEnabled = false;
drawSpriteClipped({
parameters,
sprite,
x: this.x * dims,
y: this.y * dims,
w: dims,
h: dims,
x: this.x * dims - extrude,
y: this.y * dims - extrude,
w: dims + 2 * extrude,
h: dims + 2 * extrude,
originalW: overlaySize,
originalH: overlaySize,
});

View File

@ -7,13 +7,13 @@ import { AtlasSprite } from "../../core/sprites";
import { fastArrayDeleteValue } from "../../core/utils";
import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../../core/vector";
import { BeltPath } from "../belt_path";
import { arrayBeltVariantToRotation, MetaBeltBuilding } from "../buildings/belt";
import { getCodeFromBuildingData } from "../building_codes";
import { BeltComponent } from "../components/belt";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { MapChunkView } from "../map_chunk_view";
import { defaultBuildingVariant } from "../meta_building";
import { getCodeFromBuildingData } from "../building_codes";
import { arrayBeltVariantToRotation, MetaBeltBuilding } from "../buildings/belt";
export const BELT_ANIM_COUNT = 14;
@ -43,6 +43,16 @@ export class BeltSystem extends GameSystemWithFilter {
[enumDirection.right]: [],
};
/**
* Stores simplified sprites of a belt
* @type {Object<enumDirection, AtlasSprite>}
*/
this.potatoBeltSprites = {
[enumDirection.top]: Loader.getSprite("sprites/belt/potato_mode/forward.png"),
[enumDirection.right]: Loader.getSprite("sprites/belt/potato_mode/right.png"),
[enumDirection.left]: Loader.getSprite("sprites/belt/potato_mode/left.png"),
};
for (let i = 0; i < BELT_ANIM_COUNT; ++i) {
this.beltAnimations[enumDirection.top].push(
Loader.getSprite("sprites/belt/built/forward_" + i + ".png")
@ -496,14 +506,43 @@ export class BeltSystem extends GameSystemWithFilter {
globalConfig.itemSpacingOnBelts
);
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
if (entity.components.Belt) {
const direction = entity.components.Belt.direction;
const sprite = this.beltAnimations[direction][animationIndex % BELT_ANIM_COUNT];
// Culling happens within the static map entity component
entity.components.StaticMapEntity.drawSpriteOnBoundsClipped(parameters, sprite, 0);
if (this.root.app.settings.getAllSettings().simplifiedBelts) {
// POTATO Mode: Only show items when belt is hovered
let hoveredBeltPath = null;
const mousePos = this.root.app.mousePosition;
if (mousePos) {
const tile = this.root.camera.screenToWorld(mousePos).toTileSpace();
const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular");
if (contents && contents.components.Belt) {
hoveredBeltPath = contents.components.Belt.assignedPath;
}
}
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
if (entity.components.Belt) {
const direction = entity.components.Belt.direction;
let sprite = this.potatoBeltSprites[direction];
if (entity.components.Belt.assignedPath === hoveredBeltPath) {
sprite = this.beltAnimations[direction][animationIndex % BELT_ANIM_COUNT];
}
// Culling happens within the static map entity component
entity.components.StaticMapEntity.drawSpriteOnBoundsClipped(parameters, sprite, 0);
}
}
} else {
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
if (entity.components.Belt) {
const direction = entity.components.Belt.direction;
const sprite = this.beltAnimations[direction][animationIndex % BELT_ANIM_COUNT];
// Culling happens within the static map entity component
entity.components.StaticMapEntity.drawSpriteOnBoundsClipped(parameters, sprite, 0);
}
}
}
}

View File

@ -15,6 +15,11 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
}
update() {
if (this.root.app.settings.getAllSettings().simplifiedBelts) {
// Disabled in potato mode
return;
}
// This system doesn't render anything while in map overview,
// so simply accumulate ticks
if (this.root.camera.getIsMapOverlayActive()) {
@ -56,6 +61,11 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
if (this.root.app.settings.getAllSettings().simplifiedBelts) {
// Disabled in potato mode
return;
}
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];

View File

@ -202,7 +202,13 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
// Try to hand over the item
if (this.tryPassOverItem(item, destEntity, destSlot.index)) {
// Handover successful, clear slot
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item);
if (!this.root.app.settings.getAllSettings().simplifiedBelts) {
targetAcceptorComp.onItemAccepted(
destSlot.index,
destSlot.acceptedDirection,
item
);
}
sourceSlot.item = null;
continue;
}
@ -284,6 +290,11 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
if (this.root.app.settings.getAllSettings().simplifiedBelts) {
// Disabled in potato mode
return;
}
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {

View File

@ -276,6 +276,7 @@ export const allApplicationSettings = [
new BoolSetting("lowQualityMapResources", enumCategories.performance, (app, value) => {}),
new BoolSetting("disableTileGrid", enumCategories.performance, (app, value) => {}),
new BoolSetting("lowQualityTextures", enumCategories.performance, (app, value) => {}),
new BoolSetting("simplifiedBelts", enumCategories.performance, (app, value) => {}),
];
export function getApplicationSettingById(id) {
@ -313,6 +314,7 @@ class SettingsStorage {
this.lowQualityMapResources = false;
this.disableTileGrid = false;
this.lowQualityTextures = false;
this.simplifiedBelts = false;
/**
* @type {Object.<string, number>}
@ -523,7 +525,7 @@ export class ApplicationSettings extends ReadWriteProxy {
}
getCurrentVersion() {
return 26;
return 27;
}
/** @param {{settings: SettingsStorage, version: number}} data */
@ -646,6 +648,11 @@ export class ApplicationSettings extends ReadWriteProxy {
data.version = 26;
}
if (data.version < 27) {
data.settings.simplifiedBelts = false;
data.version = 27;
}
return ExplainedResult.good();
}
}

View File

@ -898,6 +898,11 @@ settings:
description: >-
Enabled by default, selects the miner if you use the pipette when hovering a resource patch.
simplifiedBelts:
title: Simplified Belts (Ugly)
description: >-
Does not render belt items except when hovering the belt, to save performance.
keybindings:
title: Keybindings
hint: >-
@ -1004,3 +1009,53 @@ demo:
exportingBase: Exporting whole Base as Image
settingNotAvailable: Not available in the demo.
tips:
- The hub accepts input of any kind, not just the current shape!
- Make sure your factories are stackable - it will pay out!
- Don't build too close to the hub, or it will be a huge chaos!
- If stacking does not work, try switching the inputs.
- You can toggle the belt planner direction by pressing <b>R</b>.
- Holding <b>CTRL</b> allows dragging of belts without auto-orientation.
- Ratios stay the same, as long as all upgrades are on the same Tier.
- Serial execution is more efficient than parallel.
- You will unlock more variants of buildings later in the game!
- You can use <b>T</b> to switch between different variants.
- Symmetry is key!
- You can weave different tiers of tunnels.
- Try to build compact factories - it will pay out!
- The painter has a mirrored variant which you can select with <b>T</b>
- Having the right building ratios will maximize efficiency.
- At maximum level, 5 extractors will fill a single belt.
- Don't forget about tunnels!
- You don't need to divide up items evenly for full efficiency.
- Holding <b>SHIFT</b> will activate the belt planner, letting you place long lines of belts easily.
- Cutters always cut vertically, regardless of their orientation.
- To get white mix all three colors.
- The storage buffer priorities the first output.
- Invest time to build repeatable designs - it's worth it!
- Holding <b>CTRL</b> allows to place multiple buildings.
- You can hold <b>ALT</b> to invert the direction of placed belts.
- Efficiency is key!
- Shape patches that are further away from the hub are more complex.
- Machines have a limited speed, divide them up for maximum efficiency.
- Use balancers to maximize your efficiency.
- Organization is important. Try not to cross conveyors too much.
- Plan in advance, or it will be a huge chaos!
- Don't remove your old factories! You'll need them to unlock upgrades.
- Try beating level 18 on your own before seeking for help!
- Don't complicate things, try to stay simple and you'll go far.
- You may need to re-use factories later in the game. Plan your factories to be re-usable.
- Sometimes, you can find a needed shape in the map without creating it with stackers.
- Full windmills / pinwheels can never spawn naturally.
- Color your shapes before cutting for maximum efficiency.
- With modules, space is merely a perception; a concern for mortal men.
- Make a separate blueprint factory. They're important for modules.
- Have a closer look on the color mixer, and your questions will be answered.
- Use <b>CTRL</b> + Click to select an area.
- Building too close to the hub can get in the way of later projects.
- The pin icon next to each shape in the upgrade list pins it to the screen.
- Mix all primary colours together to make white!
- You have an infinite map, don't cramp your factory, expand!
- Also try Factorio! It's my favourite game.
- The quad cutter cuts counter-clockwise starting from the top right!