From 4f846edb9b75d9c1815ff2fa6af7194636b6d299 Mon Sep 17 00:00:00 2001 From: tobspr Date: Mon, 3 May 2021 23:02:33 +0200 Subject: [PATCH] New difficulty --- res/ui/building_icons/block.png | Bin 0 -> 2212 bytes res/ui/building_tutorials/block.png | Bin 0 -> 56110 bytes res/ui/icons/puzzle_completion_rate.png | Bin 0 -> 680 bytes res_raw/sprites/blueprints/block.png | Bin 0 -> 1954 bytes res_raw/sprites/buildings/block.png | Bin 0 -> 2040 bytes .../puzzle_complete_notification.scss | 99 ++++-------------- src/css/resources.scss | 4 +- src/css/states/puzzle_menu.scss | 31 ++++-- src/js/game/buildings/block.js | 30 ++++++ src/js/game/hud/parts/buildings_toolbar.js | 2 + .../hud/parts/puzzle_complete_notification.js | 82 +-------------- src/js/game/hud/parts/puzzle_play_metadata.js | 21 +--- src/js/game/key_action_mapper.js | 1 + src/js/game/meta_building_registry.js | 5 + src/js/game/modes/puzzle_play.js | 7 +- src/js/game/modes/regular.js | 3 +- src/js/platform/api.js | 1 - src/js/platform/browser/game_analytics.js | 5 + src/js/savegame/puzzle_serializer.js | 27 +++++ src/js/savegame/savegame_typedefs.js | 9 +- src/js/states/puzzle_menu.js | 18 ++-- translations/base-en.yaml | 14 ++- 22 files changed, 142 insertions(+), 217 deletions(-) create mode 100644 res/ui/building_icons/block.png create mode 100644 res/ui/building_tutorials/block.png create mode 100644 res/ui/icons/puzzle_completion_rate.png create mode 100644 res_raw/sprites/blueprints/block.png create mode 100644 res_raw/sprites/buildings/block.png create mode 100644 src/js/game/buildings/block.js diff --git a/res/ui/building_icons/block.png b/res/ui/building_icons/block.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d914f632d6c26d3c19782b7769e5bc400348fd GIT binary patch literal 2212 zcmc&$eOMFs9gj>AWK@fEpq-dS8lVly12O4z*@sXqR5mnO|Xs$G61GV zP8eBtJ{RND!(fcX!jvEnLLu6MKJtV7z3NkvL&l+7bVq=|JRU2P3()xp0MYp%2O_h{ z!AM9FiwE)$j0ez|q>D^<>-?aV7FlF}x{t31gCt&$7OExZNly+=Ow-<23T0`tR3es} z1|};-345~qEi3N?M{}=tNBeTV=mw&82C|Y5o(x^Ly7`bi_sr&|^qPOl>LU9?6=m_h zP7gTvy(G_`yzI690To5GJJ)4Pc*RwRhn6UYx11c^mu?9!dA@pt+dgfqdO6g;y)z)a zkpB2lk93(A<<09s1>#dZkz{YdA`HpwGdDnwken3mFDv)kSKE7^(agRx2keTt%3rwh*k}Z>tk@d z+Q0l+V%?{%D_t`|y^|L^*4(Wc77p*b_V{sf@to(@j?Rwi-#ri11-JCSWx2Y`9^3I* z^~29f80qlGznJvwJLMSf`1OP+WyzJCmeU)PSOj|HWx+>&snvZsY?n3795U5jdr;i$ z^3pD!=Omiv$0ThrQtdbDqS#$sICO;AXueHibIWTne)Ts??Pn4PqUyS%=^xAYL)1N=3ZLAr#w=A8u+s?PO zb}LJ zZ5iX8gc*l!)oIH0hM}X5rsTT*iP%ud+1pJ`@3dKhuDcGH*T0+aB{#(X>EMcp!5N>M z&a!>K9dG;2W489vl;W(q0!7i2<44VoRI=_t7lzWW(alfJ1y3nLwXNkJ79RWln|IYO z`>Gvd9b4>SaCkzXhn$n{+*Y&oo8zLn(#$7Z>k+ov*;nDfT+1>FEKjSpuIah$N;T|e zPZV5@ub=b(clilN@{Rj5_giC2h+IXfeDkJbl0#b*4aCHmG+}9xqoDB8PKI$#Ri<;2M@_+B)?0V=E0H2Z8a*3P&go@X zIrl2P?H^&XGG$-p4p*|({{8yA$=x=ebNNpZpY*XqHxs%p7u-#6Uq$&}>(-VzZ-5fL WkD)l6G`-UO-yn^Om()jO9QqG4rg!%M literal 0 HcmV?d00001 diff --git a/res/ui/building_tutorials/block.png b/res/ui/building_tutorials/block.png new file mode 100644 index 0000000000000000000000000000000000000000..73925265aa8204acf78697704e2d80c9f8b8a5bd GIT binary patch literal 56110 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%0DNjb0b<3 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 S#c%Bu9SHCV zasB`QKae?eK~s3bXQ1otOM?7@85o&ZSUEWPg@mP~Wz^ISj7&_eJ^Z5M5(}zp8k<|% zd;6x%m^pvpx{W(_A3T2I)akPqZ{2nA*;OZ{u=&CBg*_7h5qJib&@Bj6ztgWgB3lG1(bNr@N`s%V>@1=x=7klg~SamR; zjlu0`i-3RW#&gwf$Mz>po;Qg-Z>o)zmz=X||HetjCr@(sJXtUI`p5gGN&EZ$s7>$P zzW({GnN#ew&WF2Cwto0q{-57!CA;6v4T>NBM*W{3!g~KdbDi^tf6G2d9r}L1{k+4B z`D!+7r~b@6e~0bXpL>T>70&&4yql=-zW?xn8}_Rkx9%4^tepQ}mo2THh4{` zPfaKMI-jiYZTV$~ck%6w7w?BLuLdf(_dogmfhXU2a_WvNJlM{oRF}Ep&$^!%rwXcl p-xT6=TitD5%D+b!jvSe=nZY5J!SRaLZdXtm@pScbS?83{1OVD)+DiZc literal 0 HcmV?d00001 diff --git a/res_raw/sprites/blueprints/block.png b/res_raw/sprites/blueprints/block.png new file mode 100644 index 0000000000000000000000000000000000000000..ff6107cf9a950b49b62682b09ec7a7d28458f081 GIT binary patch literal 1954 zcmc(g>s!(X6vuyvikfIkoymrmZKy4+ys#oQOl=lkV%qeXQ=?2-Wx~9YS1@&tt7w_x zN?05Kcey56{R9VGx zysmrXWDGG&6hzFL`c`j@|M1HbT`wT}?;Qi|#sTLm5Z_=Z{xj?53Hxxi8#N*bsLuMY z7nd>}<@*(xj-I_)(@;vqpo3?mY+K1jTIPuD(AEk2m6W5skTD zeF{Lx?a6N7xxnRQU!r-Gd-XTE+P2&Qgzn%(k)3+s?TJS$(bf|Hk=Bp*HpA*`u@ldn zhqDY-1OR`#X`G=a$JVAjlYyd9A;m^-_4?BaF zpfiYCJtYe~=j&6qAXwaD=tXpQ0L0%*rf-Ks8<4+n8eGe|cD1A?m0Ooug<_|?OjRfB z2)NTTd9-TDquA&tqnQX%Wa7g@54Qc~ZL72ID9WhspMj=+vN6)s_2fE+8tTX zj^F3|gpTJ2UruL-iVUtUtO0rw6i$r3^nAGWWM}wVCCdgOoqQf3ayOI2CiX zS_)Bf7Yh|e0Q?4*RGDHiQV(5)qpHFZWE~bB9=hflzg5$4y_1m6Y+^ou63*iok4A67 z$W_HSpp$kf{I({E&*Eu?pM~;q52e-f`rH~YuhHx2;p>wX!B=HHI{xSl67hl;HcbT5 z)8imr0w~UsNPRx1d*#}?xGhrSqndg7E@LN+L^HoA;l!ks9M#+<9d6;5M4%eOyW^?~ zlH&KYUP)}apWe|i*CabwuxRX{-S7vfaJhA6E#JB{d|H%}173)+;4vTIu#!{> z<@IV~S%_h~3(Le70f9>vAZ*D7bndlm$NyMV($rMlj}&VYS#)N!z_&m>nxj=s&70k4 z)spG35y#f-)%F0u7nTPFcP_b*A?vQO{|BQ7b8# z=45ZAx^wKa1C~r^B>?2gE*co6%E5{3y*XRn07q8To4&V-YjM*Kb{&CD2q;evVXTmR z;CIYT^yY!4?8Dk)S87Iut$VTfoIU+PQWrlTB{3SUTitWT`fuyb4^X-^yA3E5x1!lz toxm9fVDpMd{0g4`xQ<@)KSxiO8Cr=^o$HPw9a_&`;K084C~gFy@=u1Sc`N_` literal 0 HcmV?d00001 diff --git a/res_raw/sprites/buildings/block.png b/res_raw/sprites/buildings/block.png new file mode 100644 index 0000000000000000000000000000000000000000..3596f682b695c6bc18a3096fb964f99f74a59304 GIT binary patch literal 2040 zcmb_dc~BE)6kqUwqEwlpQ?18N&{mX9Hk->01PBQf!~~4AA|9~WY(fgjhGd0+7gah` zyrn1@0j-KC9(aIN4nay0jJ1s8iAw3TSZx%QBBC7K2vPrVoc`hN?0(<(_Wj=Rd+*Jz zie} z0-g+(86-r!HZ;vh%uka?;b{pts$vBAgMMZqZ9qp*7--fd>PW zg-Q@H27`*0MS>F2NPv7M4B;@$2L&jT&F2bu93K#Y5jG1(SZp4|W(#?Ukj(*yE(Yz* zs8S0R(vTrv^hv~srznGv#Y#y@VWx1Hq*23SqbO>(fgljA0hvCNGBtDPh8m zS_7pe^`PA%rX-h9A_g7lUybCWzIIx&Q-&_P?vx9@gQW%k-Fd~+q zY*fq(c3{KwCJNKzgu}O%_C16}-isAVj08rJ#we0ZbaX*vJV}wJc+vn$By`o;C^%z* zR<9ycOy2e~4Q4GRjM`*E6=EcH;47Ym+IPf&vvEWqP^uu9k7E#*fVmLLN0ksvD7mu* z1Q!#`CKy9_)m!`x_9-o)^DsEV5uyT^&nDCe#OJGUNR4pSkdoja5D()CFjOhPxEwBn zMTf|;x6WIwS=PAgUJiHu3}aWCHTsdQ`Q#~!^F)ybPy zd7<}}a9@i$`^F=`&YqghTV%{mYiE9=ttjVSswI!Lqkyht zf9oZ<;o-x{c|O-|D|-6o)RqNDwy#@lJb8OyT=8dII*v3b_f$cCBWg}I@^{Iy{fcjPfp$C|Ib{eNpZ z;d8%>zpXYdvTN3Xrqo9t!v#f|y8gz-y0D!^`~iMenfJBg=o00nkcGI@h9saqr}dYq zP=@?~SNg=A2h)x}KbhHls^xxYf=@d8C&P4!f7`OI);mk$zCSqa$JNuHTsClbzG1Nj z-aO^5uW{hf!*U>gU*eXP9@UfFJ?6Tm7tQn^ZSe$T$$o2+jZ`#qUAI-)!Pp(wRQ1tj|i!J(VbS+ zRM_>>;#|B4SX&D&jExO1FMkpAe8vt{aG=;Z)XO(B;{4$Zbly1e z>6WsK-QeN2^|7map5*w}m@Q>r1#BKO_3ovHha%gRUJyd^4tK|S^Ddmy2{e;Qu+h~Pc4FDm+Q~=;MK!= z|4Pcu#^jlKOwH%k9px$eyX#-})-TGhuMo9;+fCS9cJcrGnYqJM(p%lt9s9h$HveEz zM}Mw=+qjx%PqVTEirv;WUu)(BZe*oz-<_Ip?a<3F_8z%bz2sC2w(0CBTkiza+VDq0 ze)krje?sjZ*d?R%VWFr#XLZ#E&?C^#sno*wrZQ8pJ|a8SHRQw1(BL@QtW%vw0|gg; V7o1{-d}jX_hXu=}M}y+l{0AF$+rt0= literal 0 HcmV?d00001 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 {

${puzzle.meta.shortKey}
-
- - ${ - puzzle.meta.difficulty - ? puzzle.meta.difficulty.toFixed(2) + - " (" + - T.ingame.puzzleCompletion.difficulties[Math.round(puzzle.meta.difficulty)] + - ")" - : T.puzzleMenu.difficultyNotDetermined - } -
- ${ - puzzle.meta.averageTime - ? formatSeconds(puzzle.meta.averageTime) - : T.puzzleMenu.difficultyNotDetermined - } + ${puzzle.meta.averageTime ? formatSeconds(puzzle.meta.averageTime) : "-"}
${ - puzzle.meta.downloads > 10 + puzzle.meta.downloads > 0 ? ((puzzle.meta.completions / puzzle.meta.downloads) * 100.0).toFixed(1) + "%" - : T.puzzleMenu.difficultyNotDetermined + : "-" }
diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 52ba4ad6..41208d13 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -52,6 +52,7 @@ export const KEYMAPPINGS = { // Puzzle buildings constant_producer: { keyCode: key("H") }, goal_acceptor: { keyCode: key("N") }, + block: { keyCode: key("4") }, // Primary Toolbar belt: { keyCode: key("1") }, diff --git a/src/js/game/meta_building_registry.js b/src/js/game/meta_building_registry.js index 90a253f0..0c93153d 100644 --- a/src/js/game/meta_building_registry.js +++ b/src/js/game/meta_building_registry.js @@ -4,6 +4,7 @@ import { T } from "../translations"; import { MetaAnalyzerBuilding } from "./buildings/analyzer"; import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer"; import { MetaBeltBuilding } from "./buildings/belt"; +import { MetaBlockBuilding } from "./buildings/block"; import { MetaComparatorBuilding } from "./buildings/comparator"; import { MetaConstantProducerBuilding } from "./buildings/constant_producer"; import { MetaConstantSignalBuilding } from "./buildings/constant_signal"; @@ -63,6 +64,7 @@ export function initMetaBuildingRegistry() { gMetaBuildingRegistry.register(MetaComparatorBuilding); gMetaBuildingRegistry.register(MetaItemProducerBuilding); gMetaBuildingRegistry.register(MetaConstantProducerBuilding); + gMetaBuildingRegistry.register(MetaBlockBuilding); // Belt registerBuildingVariant(1, MetaBeltBuilding, defaultBuildingVariant, 0); @@ -175,6 +177,9 @@ export function initMetaBuildingRegistry() { // Goal acceptor registerBuildingVariant(63, MetaGoalAcceptorBuilding); + // Block + registerBuildingVariant(64, MetaBlockBuilding); + // Propagate instances for (const key in gBuildingVariants) { gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass( diff --git a/src/js/game/modes/puzzle_play.js b/src/js/game/modes/puzzle_play.js index e5f0da03..e4d05076 100644 --- a/src/js/game/modes/puzzle_play.js +++ b/src/js/game/modes/puzzle_play.js @@ -21,13 +21,13 @@ import { MetaComparatorBuilding } from "../buildings/comparator"; import { MetaTransistorBuilding } from "../buildings/transistor"; import { MetaConstantProducerBuilding } from "../buildings/constant_producer"; import { MetaGoalAcceptorBuilding } from "../buildings/goal_acceptor"; -import { HUDConstantSignalEdit } from "../hud/parts/constant_signal_edit"; import { PuzzleSerializer } from "../../savegame/puzzle_serializer"; import { T } from "../../translations"; import { HUDPuzzlePlayMetadata } from "../hud/parts/puzzle_play_metadata"; import { createLogger } from "../../core/logging"; import { HUDPuzzleCompleteNotification } from "../hud/parts/puzzle_complete_notification"; import { HUDPuzzlePlaySettings } from "../hud/parts/puzzle_play_settings"; +import { MetaBlockBuilding } from "../buildings/block"; const logger = createLogger("puzzle-play"); const copy = require("clipboard-copy"); @@ -48,6 +48,7 @@ export class PuzzlePlayGameMode extends PuzzleGameMode { this.hiddenBuildings = [ MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, + MetaBlockBuilding, MetaStorageBuilding, MetaReaderBuilding, @@ -106,16 +107,14 @@ export class PuzzlePlayGameMode extends PuzzleGameMode { /** * * @param {boolean} liked - * @param {number} difficulty * @param {number} time */ - trackCompleted(liked, difficulty, time) { + trackCompleted(liked, time) { const closeLoading = this.root.hud.parts.dialogs.showLoadingDialog(); return this.root.app.clientApi .apiCompletePuzzle(this.puzzle.meta.id, { time, - difficulty, liked, }) .catch(err => { diff --git a/src/js/game/modes/regular.js b/src/js/game/modes/regular.js index ce66eea6..ee76ba84 100644 --- a/src/js/game/modes/regular.js +++ b/src/js/game/modes/regular.js @@ -36,6 +36,7 @@ import { HUDPartTutorialHints } from "../hud/parts/tutorial_hints"; import { HUDInteractiveTutorial } from "../hud/parts/interactive_tutorial"; import { HUDSandboxController } from "../hud/parts/sandbox_controller"; import { queryParamOptions } from "../../core/query_parameters"; +import { MetaBlockBuilding } from "../buildings/block"; /** @typedef {{ * shape: string, @@ -581,7 +582,7 @@ export class RegularGameMode extends GameMode { this.additionalHudParts.sandboxController = HUDSandboxController; } - this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding]; + this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, MetaBlockBuilding]; } /** diff --git a/src/js/platform/api.js b/src/js/platform/api.js index 0933ac2a..cbecfb15 100644 --- a/src/js/platform/api.js +++ b/src/js/platform/api.js @@ -168,7 +168,6 @@ export class ClientAPI { * @param {number} puzzleId * @param {object} payload * @param {number} payload.time - * @param {number} payload.difficulty * @param {boolean} payload.liked * @returns {Promise<{ success: true }>} */ diff --git a/src/js/platform/browser/game_analytics.js b/src/js/platform/browser/game_analytics.js index a3947be6..65fc5080 100644 --- a/src/js/platform/browser/game_analytics.js +++ b/src/js/platform/browser/game_analytics.js @@ -3,6 +3,7 @@ import { createLogger } from "../../core/logging"; import { queryParamOptions } from "../../core/query_parameters"; import { BeltComponent } from "../../game/components/belt"; import { StaticMapEntityComponent } from "../../game/components/static_map_entity"; +import { RegularGameMode } from "../../game/modes/regular"; import { GameRoot } from "../../game/root"; import { InGameState } from "../../states/ingame"; import { GameAnalyticsInterface } from "../game_analytics"; @@ -163,6 +164,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface { return; } + if (!(root.gameMode instanceof RegularGameMode)) { + return; + } + logger.log("Sending event", category, value); this.sendToApi("/v1/game-event", { diff --git a/src/js/savegame/puzzle_serializer.js b/src/js/savegame/puzzle_serializer.js index d94f1e9f..49dd4ef6 100644 --- a/src/js/savegame/puzzle_serializer.js +++ b/src/js/savegame/puzzle_serializer.js @@ -16,6 +16,7 @@ import trim from "trim"; import { enumColors } from "../game/colors"; import { COLOR_ITEM_SINGLETONS } from "../game/items/color_item"; import { ShapeDefinition } from "../game/shape_definition"; +import { MetaBlockBuilding } from "../game/buildings/block"; const logger = createLogger("puzzle-serializer"); @@ -67,6 +68,17 @@ export class PuzzleSerializer { }); continue; } + + if (staticComp.getMetaBuilding().id === gMetaBuildingRegistry.findByClass(MetaBlockBuilding).id) { + buildings.push({ + type: "block", + pos: { + x: staticComp.origin.x, + y: staticComp.origin.y, + r: staticComp.rotation, + }, + }); + } } const mode = /** @type {PuzzleGameMode} */ (root.gameMode); @@ -160,6 +172,21 @@ export class PuzzleSerializer { entity.components.GoalAcceptor.item = item; break; } + case "block": { + const entity = root.logic.tryPlaceBuilding({ + origin: new Vector(building.pos.x, building.pos.y), + building: gMetaBuildingRegistry.findByClass(MetaBlockBuilding), + originalRotation: building.pos.r, + rotation: building.pos.r, + rotationVariant: 0, + variant: defaultBuildingVariant, + }); + if (!entity) { + logger.warn("Failed to place block:", building); + return "failed-to-place-block"; + } + break; + } default: { // @ts-ignore return "invalid-building-type: " + building.type; diff --git a/src/js/savegame/savegame_typedefs.js b/src/js/savegame/savegame_typedefs.js index 27898b68..64a06dac 100644 --- a/src/js/savegame/savegame_typedefs.js +++ b/src/js/savegame/savegame_typedefs.js @@ -73,11 +73,18 @@ * }} PuzzleGameBuildingGoal */ +/** + * @typedef {{ + * type: "block"; + * pos: { x: number; y: number; r: number } + * }} PuzzleGameBuildingBlock + */ + /** * @typedef {{ * version: number; * bounds: { w: number; h: number; }, - * buildings: (PuzzleGameBuildingGoal | PuzzleGameBuildingConstantProducer)[] + * buildings: (PuzzleGameBuildingGoal | PuzzleGameBuildingConstantProducer | PuzzleGameBuildingBlock)[] * }} PuzzleGameData */ diff --git a/src/js/states/puzzle_menu.js b/src/js/states/puzzle_menu.js index 979091f3..eb5595f6 100644 --- a/src/js/states/puzzle_menu.js +++ b/src/js/states/puzzle_menu.js @@ -51,6 +51,8 @@ const BUILTIN_PUZZLES = G_IS_DEV const logger = createLogger("puzzle-menu"); +let lastCategory = categories[0]; + export class PuzzleMenuState extends TextualGameState { constructor() { super("PuzzleMenuState"); @@ -104,6 +106,7 @@ export class PuzzleMenuState extends TextualGameState { } selectCategory(category) { + lastCategory = category; if (category === this.activeCategory) { return; } @@ -180,19 +183,10 @@ export class PuzzleMenuState extends TextualGameState { stats.classList.add("stats"); elem.appendChild(stats); - if (puzzle.difficulty !== null) { + if (puzzle.downloads > 0) { const difficulty = document.createElement("div"); difficulty.classList.add("difficulty"); - - const canvas = document.createElement("canvas"); - canvas.width = 32; - canvas.height = 32; - const context = canvas.getContext("2d"); - PUZZLE_RATINGS[ - clamp(Math.round(puzzle.difficulty), 0, PUZZLE_RATINGS.length - 1) - ].drawFullSizeOnCanvas(context, 32); - difficulty.appendChild(canvas); - + difficulty.innerText = Math.round((puzzle.completions / puzzle.downloads) * 100.0) + "%"; stats.appendChild(difficulty); } @@ -284,7 +278,7 @@ export class PuzzleMenuState extends TextualGameState { } onEnter(payload) { - this.selectCategory(categories[0]); + this.selectCategory(lastCategory); if (payload && payload.error) { this.dialogs.showWarning(payload.error.title, payload.error.desc); diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 2349ac31..b9ea9d77 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -130,7 +130,6 @@ puzzleMenu: validatingPuzzle: Validating Puzzle submittingPuzzle: Submitting Puzzle noPuzzles: There are currently no puzzles in this section. - difficultyNotDetermined: Not yet determined categories: levels: Levels @@ -627,13 +626,6 @@ ingame: buttonSubmit: Continue - difficulties: - - No challenge - - Easy - - Medium - - Hard - - Impossible - puzzleMetadata: author: Author shortKey: Short Key @@ -875,6 +867,11 @@ buildings: name: &goal_acceptor Goal Acceptor description: Deliver shapes to the goal acceptor to set them as a goal. + block: + default: + name: &block Block + description: Allows you to block a tile. + storyRewards: # Those are the rewards gained from completing the store reward_cutter_and_trash: @@ -1304,6 +1301,7 @@ keybindings: item_producer: Item Producer (Sandbox) constant_producer: *constant_producer goal_acceptor: *goal_acceptor + block: *block # --- pipette: Pipette