diff --git a/artwork/steam/announcement-cover.png b/artwork/steam/announcement-cover.png new file mode 100644 index 00000000..60af9100 Binary files /dev/null and b/artwork/steam/announcement-cover.png differ diff --git a/artwork/steam/announcement.png b/artwork/steam/announcement.png index 9a6b79f5..1aacc62e 100644 Binary files a/artwork/steam/announcement.png and b/artwork/steam/announcement.png differ diff --git a/artwork/steam/announcement.psd b/artwork/steam/announcement.psd index 6f0b201c..30dce1e6 100644 --- a/artwork/steam/announcement.psd +++ b/artwork/steam/announcement.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c91adcd4e00006ffa4aed4db19d1530bf8c58935b1624d1640fc8e9465a2824 -size 176993 +oid sha256:ebde52e75e54d2f4add0cf498c85f059082a0745212a23c4de7328a7d78b00a5 +size 238170 diff --git a/gulp/sounds.js b/gulp/sounds.js index 1b18278d..0e8dee12 100644 --- a/gulp/sounds.js +++ b/gulp/sounds.js @@ -29,7 +29,7 @@ function gulptasksSounds($, gulp, buildFolder) { .audioChannels(1) .audioFrequency(22050) .audioCodec("libmp3lame") - .audioFilters(["volume=0.3"]); + .audioFilters(["volume=0.15"]); }), { name: "music", diff --git a/src/css/common.scss b/src/css/common.scss index f616eace..6a87012e 100644 --- a/src/css/common.scss +++ b/src/css/common.scss @@ -40,7 +40,7 @@ html { background: #dee1ea; @include DarkThemeOverride { - background: #5c606c; + background: $darkModeGameBackground; } } diff --git a/src/css/ingame_hud/building_placer.scss b/src/css/ingame_hud/building_placer.scss index 99c4d654..e63868ab 100644 --- a/src/css/ingame_hud/building_placer.scss +++ b/src/css/ingame_hud/building_placer.scss @@ -75,6 +75,15 @@ @include StyleBelowWidth(700px) { display: none !important; } + + &.compact { + width: unset !important; + grid-template-columns: 1fr; + .buildingImage, + .description > .text { + display: none; + } + } } #ingame_HUD_PlacerVariants { @@ -86,6 +95,10 @@ flex-direction: column; align-items: flex-end; + &.compact { + @include S(top, 150px); + } + .explanation { text-transform: uppercase; grid-row: 1 / 2; diff --git a/src/css/ingame_hud/dialogs.scss b/src/css/ingame_hud/dialogs.scss index cd681a9e..d72265e7 100644 --- a/src/css/ingame_hud/dialogs.scss +++ b/src/css/ingame_hud/dialogs.scss @@ -21,15 +21,17 @@ } } + $darkModeDialogBg: darken($darkModeGameBackground, 10); + @include DarkThemeOverride { - background: rgba(#33363d, 0.9); + background: rgba($darkModeDialogBg, 0.9); @include InlineAnimation(0.12s ease-in-out) { 0% { background-color: transparent; opacity: 0.5; } 100% { - background-color: rgba(#33363d, 0.9); + background-color: rgba($darkModeDialogBg, 0.9); } } diff --git a/src/css/ingame_hud/waypoints.scss b/src/css/ingame_hud/waypoints.scss index ab8fed39..fecb2c66 100644 --- a/src/css/ingame_hud/waypoints.scss +++ b/src/css/ingame_hud/waypoints.scss @@ -29,7 +29,7 @@ #ingame_HUD_Waypoints { position: absolute; @include S(right, 10px); - @include S(top, 60px); + @include S(top, 45px); display: flex; flex-direction: column; @include DarkThemeInvert(); diff --git a/src/css/main.scss b/src/css/main.scss index 598e9e92..178f398b 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -112,6 +112,6 @@ body.modalDialogActive, body.externalAdOpen, body.ingameDialogOpen { > *:not(.ingameDialog):not(.modalDialogParent):not(.loadingDialog):not(.gameLoadingOverlay):not(#ingame_HUD_ModalDialogs):not(.noBlur) { - filter: blur(5px) !important; + // filter: blur(5px) !important; } } diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss index 614cdf6a..3f220a5d 100644 --- a/src/css/states/ingame.scss +++ b/src/css/states/ingame.scss @@ -31,7 +31,7 @@ @include DarkThemeOverride { .gameLoadingOverlay { - background: #56565c; + background: $darkModeGameBackground; } } } diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index f2cf120e..fa9d430c 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -403,7 +403,7 @@ } @include DarkThemeOverride { - background: #53565e center center / cover !important; + background: $darkModeGameBackground center center / cover !important; .topButtons { filter: invert(1); @@ -414,17 +414,17 @@ } .mainContainer { - background: #4b4c50; + background: darken($darkModeGameBackground, 10); .savegames .savegame { - background: #62646a; + background: darken($darkModeGameBackground, 15); color: white; } } .footer { > a { - background: #4b4c50; + background: darken($darkModeGameBackground, 10); color: #eee; } diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss index 6c3df736..f06c9b31 100644 --- a/src/css/states/settings.scss +++ b/src/css/states/settings.scss @@ -92,11 +92,11 @@ @include DarkThemeOverride { .content { .setting { - background: #424345; + background: darken($darkModeGameBackground, 10); .value.enum { // dirty but works - filter: invert(0.8); + filter: invert(0.85); color: #222; } @@ -104,7 +104,7 @@ background-color: #74767b; &.checked { - background-color: #605b7d; + background-color: $colorBlueBright; } } } diff --git a/src/css/textual_game_state.scss b/src/css/textual_game_state.scss index 1f9dc356..a8d7a31f 100644 --- a/src/css/textual_game_state.scss +++ b/src/css/textual_game_state.scss @@ -65,7 +65,7 @@ @include DarkThemeOverride { .headerBar { h1 { - color: #cfceca; + color: #e2e0db; } .backButton { @@ -74,7 +74,7 @@ } > .container > .content { - background: #4b4c50; + background: darken($darkModeGameBackground, 3); color: #eee; } } diff --git a/src/css/variables.scss b/src/css/variables.scss index 5f056a00..c1c69371 100644 --- a/src/css/variables.scss +++ b/src/css/variables.scss @@ -38,6 +38,8 @@ $ingameHudBg: rgba(#333438, 0.9); $text3dColor: #f4ffff; +$darkModeGameBackground: #5c606c; + // Dialog properties $modalDialogBg: rgba(160, 165, 180, 0.8); $dialogBgColor: lighten($mainBgColor, 10); diff --git a/src/js/changelog.js b/src/js/changelog.js index c5be2056..fa41760b 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -1,18 +1,23 @@ export const CHANGELOG = [ { version: "1.1.16", - date: "unreleased", + date: "21.06.2020", entries: [ + "You can now pickup buildings below your cursor with 'Q'!", "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen!", "Refactor keybindings overlay to show more appropriate keybindings", "Show keybindings for area-select in the upper left instead", "Automatically deselect area when selecting a new building", "Raise markers limit from 14 characters to 71 (by Joker-vD)", - "Optimize performance by caching miner items (by Phlosioneer)", + "Optimize performance by caching extractor items (by Phlosioneer)", + "Added setting to enable compact building infos, which only show ratios and hide the image / description", + "Apply dark theme to menu as well (by dengr1065)", "Fix belt planner not placing the last belt", "Fix buildings getting deleted when right clicking while placing a blueprint", "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)", "Fix buttons not responding when using right click directly after left click (by davidburhans)", + "Fix hub marker being hidden by building info panel", + "Disable dialog background blur since it can cause performance issues", "Added simplified chinese translations", "Update translations (Thanks to all translators!)", ], diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index 40338600..c322c707 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -34,6 +34,7 @@ import { HUDPartTutorialHints } from "./parts/tutorial_hints"; import { HUDWaypoints } from "./parts/waypoints"; import { HUDInteractiveTutorial } from "./parts/interactive_tutorial"; import { HUDScreenshotExporter } from "./parts/screenshot_exporter"; +import { Entity } from "../entity"; export class GameHUD { /** diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index fa9faca2..ef46f101 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -1,15 +1,15 @@ import { DrawParameters } from "../../../core/draw_parameters"; import { STOP_PROPAGATION } from "../../../core/signal"; import { TrackedState } from "../../../core/tracked_state"; +import { makeDiv } from "../../../core/utils"; import { Vector } from "../../../core/vector"; +import { T } from "../../../translations"; import { enumMouseButton } from "../../camera"; import { KEYMAPPINGS } from "../../key_action_mapper"; -import { BaseHUDPart } from "../base_hud_part"; -import { Blueprint } from "./blueprint"; -import { makeDiv } from "../../../core/utils"; -import { DynamicDomAttach } from "../dynamic_dom_attach"; import { blueprintShape } from "../../upgrades"; -import { T } from "../../../translations"; +import { BaseHUDPart } from "../base_hud_part"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { Blueprint } from "./blueprint"; export class HUDBlueprintPlacer extends BaseHUDPart { createElements(parent) { @@ -34,9 +34,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const keyActionMapper = this.root.keyMapper; keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); - keyActionMapper - .getBinding(KEYMAPPINGS.placement.abortBuildingPlacement) - .add(this.abortPlacement, this); + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this); keyActionMapper.getBinding(KEYMAPPINGS.massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this); @@ -62,10 +60,9 @@ export class HUDBlueprintPlacer extends BaseHUDPart { } update() { - this.domAttach.update(this.currentBlueprint.get()); - this.trackedCanAfford.set( - this.currentBlueprint.get() && this.currentBlueprint.get().canAfford(this.root) - ); + const currentBlueprint = this.currentBlueprint.get(); + this.domAttach.update(currentBlueprint && currentBlueprint.getCost() > 0); + this.trackedCanAfford.set(currentBlueprint && currentBlueprint.canAfford(this.root)); } /** diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 3a8ed0db..5faec6ab 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -38,6 +38,10 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { this.buildingInfoElements.tutorialImage = makeDiv(this.element, null, ["buildingImage"]); this.variantsElement = makeDiv(parent, "ingame_HUD_PlacerVariants"); + + const compact = this.root.app.settings.getAllSettings().compactBuildingInfo; + this.element.classList.toggle("compact", compact); + this.variantsElement.classList.toggle("compact", compact); } initialize() { diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 647fe5b9..0da81d4a 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -1,5 +1,6 @@ import { Math_abs, Math_degrees, Math_round } from "../../../core/builtins"; import { globalConfig } from "../../../core/config"; +import { gMetaBuildingRegistry } from "../../../core/global_registries"; import { Signal, STOP_PROPAGATION } from "../../../core/signal"; import { TrackedState } from "../../../core/tracked_state"; import { Vector } from "../../../core/vector"; @@ -9,7 +10,6 @@ import { Entity } from "../../entity"; import { KEYMAPPINGS } from "../../key_action_mapper"; import { defaultBuildingVariant, MetaBuilding } from "../../meta_building"; import { BaseHUDPart } from "../base_hud_part"; -import { lerp } from "../../../core/utils"; /** * Contains all logic for the building placer - this doesn't include the rendering @@ -97,10 +97,8 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { keyActionMapper .getBinding(KEYMAPPINGS.placement.switchDirectionLockSide) .add(this.switchDirectionLockSide, this); - keyActionMapper - .getBinding(KEYMAPPINGS.placement.abortBuildingPlacement) - .add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.startPipette, this); this.root.gameState.inputReciever.keyup.add(this.checkForDirectionLockSwitch, this); // BINDINGS TO GAME EVENTS @@ -220,6 +218,125 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { } } + /** + * Starts the pipette function + */ + startPipette() { + // Disable in overview + if (this.root.camera.getIsMapOverlayActive()) { + return; + } + + const mousePosition = this.root.app.mousePosition; + if (!mousePosition) { + // Not on screen + return; + } + + const worldPos = this.root.camera.screenToWorld(mousePosition); + const tile = worldPos.toTileSpace(); + const contents = this.root.map.getTileContent(tile); + + if (!contents) { + this.currentMetaBuilding.set(null); + return; + } + + // Try to extract the building + const extracted = this.hack_reconstructMetaBuildingAndVariantFromBuilding(contents); + if (!extracted) { + this.currentMetaBuilding.set(null); + return; + } + + this.currentMetaBuilding.set(extracted.metaBuilding); + this.currentVariant.set(extracted.variant); + this.currentBaseRotation = contents.components.StaticMapEntity.rotation; + + // Make sure we selected something, and also make sure it's not a special entity + // if (contents && !contents.components.Unremovable) { + + // } + } + + /** + * HACK! + * + * This attempts to reconstruct the meta building and its variant from a given entity + * @param {Entity} entity + * @returns {{ metaBuilding: MetaBuilding, variant: string }} + */ + hack_reconstructMetaBuildingAndVariantFromBuilding(entity) { + if (entity.components.Hub) { + // Hub is not copyable + return null; + } + + const matches = []; + const metaBuildings = gMetaBuildingRegistry.entries; + for (let i = 0; i < metaBuildings.length; ++i) { + const metaBuilding = metaBuildings[i]; + const availableVariants = metaBuilding.getAvailableVariants(this.root); + checkVariant: for (let k = 0; k < availableVariants.length; ++k) { + const variant = availableVariants[k]; + let unplaced = metaBuilding.createEntity({ + root: this.root, + variant, + origin: new Vector(0, 0), + rotation: 0, + originalRotation: 0, + rotationVariant: 0, + }); + + // Compare if both entities share the same components + for (let component in entity.components) { + if ((entity.components[component] == null) !== (unplaced.components[component] == null)) { + continue checkVariant; + } + } + + // Check for same item processor + if ( + entity.components.ItemProcessor && + entity.components.ItemProcessor.type != unplaced.components.ItemProcessor.type + ) { + continue checkVariant; + } + + // Check for underground belt + if ( + entity.components.UndergroundBelt && + entity.components.UndergroundBelt.tier != unplaced.components.UndergroundBelt.tier + ) { + continue checkVariant; + } + + // Check for same sprite key - except for underground belts + // since the sprite may vary here + if ( + !entity.components.UndergroundBelt && + entity.components.StaticMapEntity.spriteKey != + unplaced.components.StaticMapEntity.spriteKey + ) { + continue checkVariant; + } + matches.push({ metaBuilding, variant }); + } + } + + if (matches.length == 1) { + const staticEntity = entity.components.StaticMapEntity; + const key = staticEntity.spriteKey || staticEntity.blueprintSpriteKey; + assert( + key && + key.includes(matches[0].metaBuilding.id) && + (matches[0].variant === defaultBuildingVariant || key.includes(matches[0].variant)) + ); + return matches[0]; + } + return null; + } + switchDirectionLockSide() { this.currentDirectionLockSide = 1 - this.currentDirectionLockSide; } @@ -237,18 +354,6 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { } } - /** - * Canvas click handler - * @param {Vector} mousePos - * @param {boolean} cancelAction - */ - onCanvasClick(mousePos, cancelAction = false) { - // Prevent any other canvas clicks - if (this.currentMetaBuilding.get()) { - return STOP_PROPAGATION; - } - } - /** * Tries to place the current building at the given tile * @param {Vector} tile @@ -473,7 +578,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { this.currentlyDragging = true; this.currentlyDeleting = true; this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); - this.currentMetaBuilding.set(null); + this.deleteBelowCursor(); return STOP_PROPAGATION; } diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js index 7aca3722..5b7f4a9d 100644 --- a/src/js/game/hud/parts/keybinding_overlay.js +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -44,7 +44,7 @@ export class HUDKeybindingOverlay extends BaseHUDPart { * it supports the belt planner * @returns {boolean} */ - get buildingPlacementBeltPlanner() { + get buildingPlacementSupportsBeltPlanner() { const placer = this.root.hud.parts.buildingPlacer; return ( !this.mapOverviewActive && @@ -164,10 +164,17 @@ export class HUDKeybindingOverlay extends BaseHUDPart { condition: () => this.mapOverviewActive && !this.blueprintPlacementActive, }, + { + // Pipette + label: T.ingame.keybindingsOverlay.pipette, + keys: [k.placement.pipette], + condition: () => !this.mapOverviewActive, + }, + { // Cancel placement label: T.ingame.keybindingsOverlay.stopPlacement, - keys: [KEYCODE_RMB, DIVIDER_TOKEN, k.placement.abortBuildingPlacement], + keys: [KEYCODE_RMB], condition: () => this.anyPlacementActive, }, @@ -218,7 +225,7 @@ export class HUDKeybindingOverlay extends BaseHUDPart { // Belt planner label: T.ingame.keybindingsOverlay.lockBeltDirection, keys: [k.placementModifiers.lockBeltDirection], - condition: () => this.buildingPlacementActive && !this.beltPlannerActive, + condition: () => this.buildingPlacementSupportsBeltPlanner && !this.beltPlannerActive, }, { diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 659f01e6..c514446d 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -24,7 +24,7 @@ export const KEYMAPPINGS = { menuOpenStats: { keyCode: key("G") }, toggleHud: { keyCode: 113 }, // F2 - exportScreenshot: { keyCode: 114 }, // F3 + exportScreenshot: { keyCode: 114 }, // F3PS toggleFPSInfo: { keyCode: 115 }, // F4 }, @@ -56,7 +56,7 @@ export const KEYMAPPINGS = { }, placement: { - abortBuildingPlacement: { keyCode: key("Q") }, + pipette: { keyCode: key("Q") }, rotateWhilePlacing: { keyCode: key("R") }, rotateInverseModifier: { keyCode: 16 }, // SHIFT cycleBuildingVariants: { keyCode: key("T") }, diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js index 723e854b..11da28f3 100644 --- a/src/js/game/meta_building.js +++ b/src/js/game/meta_building.js @@ -147,10 +147,32 @@ export class MetaBuilding { * @param {string} param0.variant */ createAndPlaceEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) { + const entity = this.createEntity({ + root, + origin, + rotation, + originalRotation, + rotationVariant, + variant, + }); + root.map.placeStaticEntity(entity); + root.entityMgr.registerEntity(entity); + return entity; + } + + /** + * Creates the entity without placing it + * @param {object} param0 + * @param {GameRoot} param0.root + * @param {Vector} param0.origin Origin tile + * @param {number=} param0.rotation Rotation + * @param {number} param0.originalRotation Original Rotation + * @param {number} param0.rotationVariant Rotation variant + * @param {string} param0.variant + */ + createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) { const entity = new Entity(root); - const blueprintSprite = this.getBlueprintSprite(rotationVariant, variant); - entity.addComponent( new StaticMapEntityComponent({ spriteKey: @@ -166,12 +188,8 @@ export class MetaBuilding { blueprintSpriteKey: blueprintSprite ? blueprintSprite.spriteName : "", }) ); - this.setupEntityComponents(entity, root); this.updateVariants(entity, rotationVariant, variant); - - root.map.placeStaticEntity(entity); - root.entityMgr.registerEntity(entity); return entity; } diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index d1216c60..964fb885 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -200,6 +200,7 @@ export const allApplicationSettings = [ new BoolSetting("alwaysMultiplace", categoryGame, (app, value) => {}), new BoolSetting("enableTunnelSmartplace", categoryGame, (app, value) => {}), new BoolSetting("vignette", categoryGame, (app, value) => {}), + new BoolSetting("compactBuildingInfo", categoryGame, (app, value) => {}), ]; export function getApplicationSettingById(id) { @@ -223,6 +224,7 @@ class SettingsStorage { this.offerHints = true; this.enableTunnelSmartplace = true; this.vignette = true; + this.compactBuildingInfo = false; /** * @type {Object.} @@ -412,7 +414,7 @@ export class ApplicationSettings extends ReadWriteProxy { } getCurrentVersion() { - return 12; + return 13; } /** @param {{settings: SettingsStorage, version: number}} data */ @@ -459,6 +461,11 @@ export class ApplicationSettings extends ReadWriteProxy { data.version = 12; } + if (data.version < 13) { + data.settings.compactBuildingInfo = false; + data.version = 13; + } + return ExplainedResult.good(); } } diff --git a/translations/base-en.yaml b/translations/base-en.yaml index afe4907d..0b754e4b 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -288,6 +288,7 @@ ingame: cutSelection: Cut copySelection: Copy clearSelection: Clear Selection + pipette: Pipette # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -686,6 +687,11 @@ settings: description: >- Enables the vignette which darkens the screen corners and makes text easier to read. + compactBuildingInfo: + title: Compact Building Infos + description: >- + Shortens info boxes for buildings by only showing their ratios. Otherwise a description and image is shown. + keybindings: title: Keybindings hint: >- @@ -733,7 +739,7 @@ keybindings: painter: *painter trash: *trash - abortBuildingPlacement: Abort Placement + pipette: Pipette rotateWhilePlacing: Rotate rotateInverseModifier: >- Modifier: Rotate CCW instead