diff --git a/res/ui/building_icons/block.png b/res/ui/building_icons/block.png new file mode 100644 index 00000000..a6d914f6 Binary files /dev/null and b/res/ui/building_icons/block.png differ diff --git a/res/ui/building_tutorials/block.png b/res/ui/building_tutorials/block.png new file mode 100644 index 00000000..73925265 Binary files /dev/null and b/res/ui/building_tutorials/block.png differ diff --git a/res/ui/icons/puzzle_completion_rate.png b/res/ui/icons/puzzle_completion_rate.png new file mode 100644 index 00000000..2b07ce22 Binary files /dev/null and b/res/ui/icons/puzzle_completion_rate.png differ diff --git a/res_raw/sprites/blueprints/block.png b/res_raw/sprites/blueprints/block.png new file mode 100644 index 00000000..ff6107cf Binary files /dev/null and b/res_raw/sprites/blueprints/block.png differ diff --git a/res_raw/sprites/buildings/block.png b/res_raw/sprites/buildings/block.png new file mode 100644 index 00000000..3596f682 Binary files /dev/null and b/res_raw/sprites/buildings/block.png differ diff --git a/src/css/ingame_hud/puzzle_complete_notification.scss b/src/css/ingame_hud/puzzle_complete_notification.scss index eb7ddf6f..b3b7bf14 100644 --- a/src/css/ingame_hud/puzzle_complete_notification.scss +++ b/src/css/ingame_hud/puzzle_complete_notification.scss @@ -61,8 +61,6 @@ } > .contents { - @include S(width, 400px); - @include S(height, 170px); @include InlineAnimation(0.5s ease-in-out) { 0% { transform: translateX(-100vw); @@ -75,6 +73,7 @@ transform: translateX(-2vw); } } + display: flex; flex-direction: column; align-items: center; @@ -84,6 +83,7 @@ display: flex; flex-direction: column; @include S(margin-bottom, 10px); + @include SuperSmallText; > .buttons { display: flex; @@ -92,8 +92,8 @@ @include S(margin, 10px, 0); > button { - @include S(width, 40px); - @include S(height, 40px); + @include S(width, 60px); + @include S(height, 60px); @include S(margin, 0, 10px); box-sizing: border-box; @include S(border-radius, $globalBorderRadius); @@ -101,12 +101,7 @@ &.liked-yes { /* @load-async */ - background: uiResource("icons/puzzle_action_liked_yes.png") center center / 60% - no-repeat; - } - &.liked-no { - /* @load-async */ - background: uiResource("icons/puzzle_action_liked_no.png") center center / 60% + background: uiResource("icons/puzzle_action_liked_yes.png") center center / 70% no-repeat; } @@ -124,88 +119,30 @@ } } - > .stepDifficulty { - display: flex; - flex-direction: column; - align-items: center; - @include S(margin-bottom, 10px); + > .actions { + position: absolute; + @include S(bottom, 40px); - > .desc { + display: grid; + @include S(grid-gap, 15px); + grid-auto-flow: column; + + button { @include SuperSmallText; - opacity: 0.4; - @include S(margin-bottom, 4px); } - - > .shapes { - @include S(margin-top, 10px); - display: flex; - align-items: center; - - > .rating { - @include S(border-radius, $globalBorderRadius); - pointer-events: all; - cursor: pointer; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - - @include S(margin, 0, 5px); - @include S(width, 65px); - @include S(height, 50px); - - > canvas { - @include S(width, 30px); - @include S(height, 30px); - transition: opacity 0.12s ease-in-out, background-color 0.12s ease-in-out, - box-shadow 0.12s ease-in-out; - } - - > .description { - @include SuperSmallText; - white-space: nowrap; - } - - &.active { - background-color: #151118 !important; - box-shadow: 0 0 0 D(2px) #151118; - } - - &:not(.active) { - opacity: 0.4; - } - } + .report { + background-color: $accentColorDark; } } } - > .actions { - position: absolute; - @include S(bottom, 40px); - - display: grid; - @include S(grid-gap, 15px); - grid-auto-flow: column; - - button { - @include SuperSmallText; - } - .report { - background-color: $accentColorDark; - } - } - button.close { border: 0; position: relative; - @include S(margin-top, 30px); + @include S(margin-top, 15px); background: $colorGreenBright; - @include S(padding, 10px, 40px); - - &:not(.visible) { - opacity: 0; - pointer-events: none; - } + @include Heading; + @include S(padding, 14px, 40px); } } } diff --git a/src/css/resources.scss b/src/css/resources.scss index 158db23d..c3c6ea88 100644 --- a/src/css/resources.scss +++ b/src/css/resources.scss @@ -1,6 +1,6 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, trash, underground_belt, wire, constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, storage, - transistor, analyzer, comparator, item_producer, constant_producer, goal_acceptor; + transistor, analyzer, comparator, item_producer, constant_producer, goal_acceptor, block; @each $building in $buildings { [data-icon="building_icons/#{$building}.png"] { @@ -14,7 +14,7 @@ $buildingsAndVariants: belt, balancer, underground_belt, underground_belt-tier2, reader, rotater-rotate180, display, constant_signal, wire, wire_tunnel, logic_gate-or, logic_gate-not, logic_gate-xor, analyzer, virtual_processor-rotater, virtual_processor-unstacker, item_producer, constant_producer, virtual_processor-stacker, virtual_processor-painter, wire-second, painter, - painter-mirrored, comparator, goal_acceptor; + painter-mirrored, comparator, goal_acceptor, block; @each $building in $buildingsAndVariants { [data-icon="building_tutorials/#{$building}.png"] { /* @load-async */ diff --git a/src/css/states/puzzle_menu.scss b/src/css/states/puzzle_menu.scss index a5b4b509..9cc5a093 100644 --- a/src/css/states/puzzle_menu.scss +++ b/src/css/states/puzzle_menu.scss @@ -158,7 +158,6 @@ > .downloads { @include SuperSmallText; color: #000; - justify-self: start; font-weight: bold; @include S(margin-right, 5px); @include S(padding-left, 12px); @@ -170,8 +169,9 @@ & { /* @load-async */ - background: uiResource("icons/puzzle_plays.png") #{D(2px)} center / #{D(8px)} - #{D(8px)} no-repeat; + background: uiResource("icons/puzzle_plays.png") #{D(2px)} #{D(2.5px)} / #{D( + 8px + )} #{D(8px)} no-repeat; } } @@ -180,26 +180,35 @@ align-items: center; justify-content: center; color: #000; - justify-self: start; font-weight: bold; - @include S(padding-left, 12px); + @include S(padding-left, 14px); opacity: 0.7; @include DarkThemeInvert; & { /* @load-async */ - background: uiResource("icons/puzzle_upvotes.png") #{D(2px)} center / #{D( - 8px - )} #{D(8px)} no-repeat; + background: uiResource("icons/puzzle_upvotes.png") #{D(2px)} #{D(2.4px)} / #{D( + 9px + )} #{D(9px)} no-repeat; } } > .difficulty { - @include S(margin-top, 1px); - @include S(margin-right, 7px); - display: inline-flex; + @include SuperSmallText; align-items: center; justify-content: center; + color: #000; + font-weight: bold; + @include S(margin-right, 3px); + @include S(padding-left, 14px); + opacity: 0.7; + @include DarkThemeInvert; + + & { + /* @load-async */ + background: uiResource("icons/puzzle_completion_rate.png") #{D(1px)} #{D(2px)} / + #{D(10px)} #{D(10px)} no-repeat; + } } } diff --git a/src/js/game/buildings/block.js b/src/js/game/buildings/block.js new file mode 100644 index 00000000..d6499648 --- /dev/null +++ b/src/js/game/buildings/block.js @@ -0,0 +1,30 @@ +/* typehints:start */ +import { Entity } from "../entity"; +/* typehints:end */ + +import { MetaBuilding } from "../meta_building"; + +export class MetaBlockBuilding extends MetaBuilding { + constructor() { + super("block"); + } + + getSilhouetteColor() { + return "#333"; + } + + /** + * + * @param {import("../../savegame/savegame_serializer").GameRoot} root + * @returns + */ + getIsRemovable(root) { + return root.gameMode.getIsEditor(); + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) {} +} diff --git a/src/js/game/hud/parts/buildings_toolbar.js b/src/js/game/hud/parts/buildings_toolbar.js index 2881eece..994a70ed 100644 --- a/src/js/game/hud/parts/buildings_toolbar.js +++ b/src/js/game/hud/parts/buildings_toolbar.js @@ -17,6 +17,7 @@ import { MetaStorageBuilding } from "../../buildings/storage"; import { MetaItemProducerBuilding } from "../../buildings/item_producer"; import { MetaConstantProducerBuilding } from "../../buildings/constant_producer"; import { MetaGoalAcceptorBuilding } from "../../buildings/goal_acceptor"; +import { MetaBlockBuilding } from "../../buildings/block"; export class HUDBuildingsToolbar extends HUDBaseToolbar { constructor(root) { @@ -28,6 +29,7 @@ export class HUDBuildingsToolbar extends HUDBaseToolbar { MetaBalancerBuilding, MetaUndergroundBeltBuilding, MetaMinerBuilding, + MetaBlockBuilding, MetaCutterBuilding, MetaRotaterBuilding, MetaStackerBuilding, diff --git a/src/js/game/hud/parts/puzzle_complete_notification.js b/src/js/game/hud/parts/puzzle_complete_notification.js index 4b366243..4d68daa9 100644 --- a/src/js/game/hud/parts/puzzle_complete_notification.js +++ b/src/js/game/hud/parts/puzzle_complete_notification.js @@ -14,14 +14,6 @@ import { DynamicDomAttach } from "../dynamic_dom_attach"; import { ShapeItem } from "../../items/shape_item"; import { ShapeDefinition } from "../../shape_definition"; -export const PUZZLE_RATINGS = [ - new ColorItem(enumColors.red), - new ShapeItem(ShapeDefinition.fromShortKey("CuCuCuCu")), - new ShapeItem(ShapeDefinition.fromShortKey("WwWwWwWw")), - new ShapeItem(ShapeDefinition.fromShortKey(finalGameShape)), - new ShapeItem(ShapeDefinition.fromShortKey(rocketShape)), -]; - export class HUDPuzzleCompleteNotification extends BaseHUDPart { initialize() { this.visible = false; @@ -32,8 +24,7 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { this.root.signals.puzzleComplete.add(this.show, this); - this.selectionLiked = false; - this.selectionDifficulty = null; + this.userDidLikePuzzle = false; this.timeOfCompletion = 0; } @@ -48,18 +39,6 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { this.elemContents = makeDiv(dialog, null, ["contents"]); this.elemActions = makeDiv(dialog, null, ["actions"]); - const reportBtn = document.createElement("button"); - reportBtn.classList.add("styledButton", "report"); - reportBtn.innerHTML = T.ingame.puzzleEditorSettings.report; - this.elemActions.appendChild(reportBtn); - this.trackClicks(reportBtn, this.report); - - const shareBtn = document.createElement("button"); - shareBtn.classList.add("styledButton", "share"); - shareBtn.innerHTML = T.ingame.puzzleEditorSettings.share; - this.elemActions.appendChild(shareBtn); - this.trackClicks(shareBtn, this.share); - const stepLike = makeDiv(this.elemContents, null, ["step", "stepLike"]); makeDiv(stepLike, null, ["title"], T.ingame.puzzleCompletion.titleLike); @@ -69,45 +48,10 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { this.buttonLikeYes.classList.add("liked-yes"); likeButtons.appendChild(this.buttonLikeYes); this.trackClicks(this.buttonLikeYes, () => { - this.selectionLiked = !this.selectionLiked; + this.userDidLikePuzzle = !this.userDidLikePuzzle; this.updateState(); }); - const stepDifficulty = makeDiv(this.elemContents, null, ["step", "stepDifficulty"]); - makeDiv(stepDifficulty, null, ["title"], T.ingame.puzzleCompletion.titleRating); - makeDiv(stepDifficulty, null, ["desc"], T.ingame.puzzleCompletion.titleRatingDesc); - - const shapeContainer = makeDiv(stepDifficulty, null, ["shapes"]); - - this.difficultyElements = []; - let index = 0; - for (const shape of PUZZLE_RATINGS) { - const localIndex = index; - - const elem = document.createElement("div"); - elem.classList.add("rating"); - shapeContainer.appendChild(elem); - - const canvas = document.createElement("canvas"); - canvas.width = 128; - canvas.height = 128; - const context = canvas.getContext("2d"); - shape.drawFullSizeOnCanvas(context, 128); - elem.appendChild(canvas); - - this.trackClicks(elem, () => { - this.selectionDifficulty = localIndex; - this.updateState(); - }); - this.difficultyElements.push(elem); - - const desc = document.createElement("div"); - desc.classList.add("description"); - desc.innerText = T.ingame.puzzleCompletion.difficulties[localIndex]; - elem.appendChild(desc); - ++index; - } - this.btnClose = document.createElement("button"); this.btnClose.classList.add("close", "styledButton"); this.btnClose.innerText = T.ingame.puzzleCompletion.buttonSubmit; @@ -116,26 +60,8 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { this.trackClicks(this.btnClose, this.close); } - share() { - const mode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode); - mode.sharePuzzle(); - } - - report() { - const mode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode); - mode.reportPuzzle().then(() => this.close()); - } - updateState() { - this.buttonLikeYes.classList.toggle("active", this.selectionLiked === true); - this.difficultyElements.forEach((canvas, index) => - canvas.classList.toggle("active", index === this.selectionDifficulty) - ); - - this.btnClose.classList.toggle( - "visible", - typeof this.selectionDifficulty === "number" && typeof this.selectionLiked === "boolean" - ); + this.buttonLikeYes.classList.toggle("active", this.userDidLikePuzzle === true); } show() { @@ -155,7 +81,7 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { close() { /** @type {PuzzlePlayGameMode} */ (this.root.gameMode) - .trackCompleted(this.selectionLiked, this.selectionDifficulty, Math.round(this.timeOfCompletion)) + .trackCompleted(this.userDidLikePuzzle, Math.round(this.timeOfCompletion)) .then(() => { // this.root.gameState.moveToState("PuzzleMenuState"); this.visible = false; diff --git a/src/js/game/hud/parts/puzzle_play_metadata.js b/src/js/game/hud/parts/puzzle_play_metadata.js index a29f9779..3550a1e6 100644 --- a/src/js/game/hud/parts/puzzle_play_metadata.js +++ b/src/js/game/hud/parts/puzzle_play_metadata.js @@ -32,31 +32,16 @@ export class HUDPuzzlePlayMetadata extends BaseHUDPart {