From f76d73fdb7d264c184f684df89f0a6682294c091 Mon Sep 17 00:00:00 2001 From: Simon Naarmann Date: Sat, 17 Feb 2024 00:19:54 +0100 Subject: [PATCH] Rewind to the tick before previous assignment Rename "Replay" options to "Game Controls". --- data/images/rewindprevply/1.5.png | Bin 0 -> 4949 bytes data/images/rewindprevply/1.png | Bin 0 -> 5326 bytes data/images/rewindprevply/2.png | Bin 0 -> 5293 bytes data/transl/catalan.txt | 18 +++---- data/transl/english.txt | 16 ++++--- data/transl/german.txt | 16 ++++--- data/transl/swedish.txt | 18 +++---- src/file/lang/enum_.d | 16 ++++--- src/file/option/allopts.d | 23 +++++---- src/game/core/speed.d | 75 +++++++++++++++++++----------- src/game/panel/base.d | 5 +- src/game/panel/rightbut.d | 18 +++---- src/game/panel/taperec.d | 46 +++++++++--------- src/game/panel/tooltip.d | 20 ++++---- src/graphic/internal/names.d | 3 ++ src/menu/options.d | 70 +++++++++++++--------------- 16 files changed, 190 insertions(+), 154 deletions(-) create mode 100644 data/images/rewindprevply/1.5.png create mode 100644 data/images/rewindprevply/1.png create mode 100644 data/images/rewindprevply/2.png diff --git a/data/images/rewindprevply/1.5.png b/data/images/rewindprevply/1.5.png new file mode 100644 index 0000000000000000000000000000000000000000..1311e1116bc62eb20b76e943f20f6c5cecc3485b GIT binary patch literal 4949 zcmeHLdvFuS89x~tWAXAh3`u!}izr~@oOE|OS-Oj5Y%CiIEMvgMu8mvnu_s?`JH0Z(1VN^|oQ}1yUIt55;v{(Qcfa-Edz~loNE55Y_63u%tm*)lthFU6NM61m(GLxdqDUah(Jx z6S@RsI;`7ZA)!1A*1v#7`cZ7GccH9aQ?!p0N-FYDy~5=#K}jQl8_ikJ9w#XVCmF(u z;y44pW*Tbi+DAN6k)E^NxB*diN%{FDuKav75cG>uEkKZP+t!!u&Ys+P=fA)1xZ&E; z`qWJqN)F#UX4w0tzTiaa4_;V5zsNYSWASv??me&dR|M|!r|$IMc)eq12Rh~Xi0wIB z#@o)O=qf$N*=>LC?QCrB3`I&z=F4|>>soz>e(u77x+AB(3)#d;Q$pbLK;DoozT`yR`d_m0OCl+4qy07MwX5 z{^GZ1`rqg__lS&T^}NNir+QyMO=Pyt`3JShaZS1SB>8kl+plajx0crQ?eD@5UM)Lt zrdXbp@+_B<=14zrY!_MUkgmB-?K?IQPL95K_tgu>_jM!|?oBFf&#NEk-*&&VGIN>b zlSN54b3fm6bIVJ*?N#k-5h8)Z@hgxqp|ze z4Ezh>!cXt5e7<#g&dhg?{N4(-AFXT;UB3IvGtF0%QFqlMe`II=#&>c*xI4e^&sY0C z?DDh@3?TMX!Ivu*Ji3V>GjpWUa;4l|#PEKvkrn(LFowMWb;6MBW#ItJ*8m0OfJgG# z4WD&(8Bj^E8_Fzh+#SdV)sk~_5Ukr=T*_~*;c3CJEJvRmW*~qUC@dQG*7{^7Y&U4Q z43yPolL6IKlp4FC9OhBJKL}9DNEvagAS~6Bh8#Vb9TY@nt)nmw0iW!KYDEb!CQ~RB zGKS1Xf6!whXqqotwGkd=aZ2oiVbD=p;Gh5#_F1+u>`$b*7<;8PZk zh7kB+`#@c=RtrbqO`sNdp{fi=CB_V?uDD?fl>(3C4QN)7>@k{(B#w|Z#y7P`3um+= z(0mwojP_9MnljXKyBUX{uT$M~IqU{?d`9r|lE7#pO_(VXP-cw8DGNpkSt3T0bQT6k znxHuxh@90j3d-e^71qZC6$*kIC5VG(k)j3XM2xhtRtO=on2ocTF+$)8f#WEe%*q-C zu{tQhtYm9Pd!<4N5DKs~E7%~EO|-Mtr2Dq?T1gXka%KNxr)9NJpvU1?v=6Ws|VtHiD!mGfm*Q zjgAeZ;jITj8D^r2sqLMbxjHQj3szzums-!DjF!~fD&7Y~{pn{uZl!|@xmrr3&F2R6l?Vvn_w zwvG0RK{3eLe)T>1xOf%lNf=kgb_GH znd5|+9)F0eNLV<5#4!K>i%~edu@rPB3lKO9fSC|+>sY71euxyskhcF{h!)yx;Q>!z zEJ<+~C1#m1ng?c#6F9MVZH9^<77#NrGM0QQkH7*9mr96>c-xyu` zk(XlNgTG}%@Rj$@$5Sfc>++J4qS69b=jP@{5F~;`;MLvT{XT-+zKui?BwAP)jUv(L zfoL?k?@fk>syc4f3J3CH(tP!gm6U+=?ESRGKBEVn_QK(#b0^)S9Y5KCI+gbjtMSmx?|k@Z=jp?Yg4xMdY6K3lH-TCd(&~ z#*bW;JI{WrXwiNBlHAI{r)rRoQX+FdnY?3ZcgqK{ee$XQ> zPtGkmr+1c>$*W&U*<8{Qvgn9E5bvEl@UOFL@UrvSo!5Wd^zU5_2@j;d{A}xyhg+|I e4uyg2t-80Kus2uLhYXMj#8pu2IJtb|j{gAaUyalN literal 0 HcmV?d00001 diff --git a/data/images/rewindprevply/1.png b/data/images/rewindprevply/1.png new file mode 100644 index 0000000000000000000000000000000000000000..0f41db49adbe395877f6b79ac8f353fd7cea2058 GIT binary patch literal 5326 zcmeHLdr(x@8NUz_f?_a_h8i>7F10b}-Mz2fz4s0)2#d1DMFJazG-2V%?51EjNr9s~W zjRN{X=yyO5Hdu{%HC6bc6wwGv@iwCVX*oP|eor?x*=`j+{j$rD~;<)0T- zKlw_JcW3d6)HfFT-am5jjMaChVcUK-wIwMz=W9DBSx&vj?@xX4Lh_p3%h$j8gAJdy zHg}khE&t$!g9mQzuTM_7L7m;zlCkA)`+hp_*X{GGpPG0uuMJz3-oESPOsS}`@#@s) zZeG21!}6=$2Ty;--Rf*=$2J#El~$<_1k+Dfc8$OMd{6p}6Is`|Yb)Fjf9r*d@AX`N ztf_{r22SsFw`a`@NRXBw z%_O1e7BAbWsgz}M3EvyTp(z+tARJTOpWOL4})a)n^0Dhzirl`L% z5aFXvvw_P4txsFcCWA#=;xv~*9OVbY$i!F}3xO9z)oRK-E7g=8mKDClH75=MBd6J? zX(8Tft*NQ8)XHr9;U8g#=EJSy91R#U=riK;Qzc2slSelBg)G$kCJmB}@FA zVAwB!J5|3>fvllGg|VO;oS$9ncA6;*F*H+LDQF68aGK|-sUQccjUNjeCY zBJFmEouWw2#tbnnMBxZTqK;|QPGd!P3lGYGVFf)-0l=6CUHJSk60~608w^%D&4X2U zaM=UtBnz705;O#$gLT+DP={v#LBzz@;XFZERcikqx1KzvY~Tl%7pf6Bzt)(FWmG9z z8XLuim8y|SCX0VM?72y=G89=1sg*tvgjai2pa}x zNWzYDBC>)12#zAarY!jd^hi+AYJ@PFT>*9kTS0glZz$7r!%>fql%>XpbT5FxaDu`~ z!b=c5N$?CEH<O_V7DM+gZxL%@%~fG~DM5&}XrsSu8lLVtA?8HT6WyQd

(c=H@QLuw~dXc-q?9&S2Q3OISaK_0O5p-;ee8|D?aazhN&g0c(Qz#9SA) zCh5^a7~C5wERSH=ga`DNfNgBbfXQUd?I}p^O}rnQ##Z;dng>(wxLvco?C-8LIwu`9 zO-b^5_wPyK+K;xo0_z;#*zwxtORG=5ot3ov>b2|ZzB}>dtw}Y#=WhJR zo3U5!>gWwVy&$pa`m=BR!N(cd&bPAzJ0t`DYu^GDtFC1mf^`=yS@R+-x$kmd!_{IMMf;;|t literal 0 HcmV?d00001 diff --git a/data/images/rewindprevply/2.png b/data/images/rewindprevply/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5db32f9deacad351795b5db45e9cff9376e6aeea GIT binary patch literal 5293 zcmeHLdsGuw8lTuI4~ycfx>mPipp~smGBcTw%q)>tK(Z1L68_rwmBd6a;td!G59&Eu5AYFj)6jpV6i-h zM8X%Ssd^kyK}ptAh2;t;4^TaZ$g7sYHXO>bj@-to1}golP<|>buYqzxSVvw%s0JW0 zun)jSLU|WC$Zl;0%Q` za8QM)HuhK~BUR2tFF^a2h#47qmW&M4<8=$710aY$@N$hQyCrp8>zsnO)uV6()S|EVq4!olE~$*TJ_Di zIk&#Kc2o1w_NMmx^xczzR%Ao=IBuCZ!X4Z0I5X(t%N?zH&=OI;%RZ;aYVC%1`NAwfKD2(;qa`%B*6GytUg486OCd*HXr!hC0-6> zmI9X)*BgT8y4QP3ybi@3p3?#ca6(ld+?D9FrCf2{D`X0aM5jkt1Vi#R%o)>64 zVI+;Dp%=t7uL!e}b@aAMhTX9VT`6 zsoOnmh2_Mv5^H89071LYVO!TZJP9WlJY>EMXLa+UQ2zh4<>En;p*{?Gw&;WVmn%b| ziYfr}LvNv1hp3biiYi6Huw2LmA6p7|#ZHJ7n&OICR}p}xM>t)(#>F2>1&S1Sy8*{w z+E5rp;7J&52YMJkoF;KvPZ^2tq5Ir|RK|KiS`p+Cas|^I7K*1{z>=5)PxN2e2OX1|6n@=XMfr;Az?}^o`4pa?vP9ks{$Yke|^-9Z$e` z=`cOaSd0R|0FON=@jOQuj64Ah0{BT?{9a{;6E#^YUv6EcnXLVv;teVEx(#81hsNM7 z3omVL_pKeye3*5Q@(CXrk8%qX?cd~~`0b~wpRR{u;GvZJv#X!3hhpHNl>4*mC!;I6 z=XXDF!LRFO@K^n$lDI|iKLQi;a%`EfPfbl-h#(7*h49(Cckgio`SMF7h#+Nuj&tguq6}DViYkGY@`oz)|GfqrTC1wxVdVD=P{Oq)}-6q#1EPStQ#BKExX;wNL*8gUvObtS z`ER#>SH1s8#e>%ZO=Xp@4YRyCL04aYZ_&6X?(sFLV&U{nJZFx5qE99k*~re8H+2uIM!}@!y);tozo$PIGER-M_Ye{GXb2 zD;p=}-;Rnr95`E<-nI@LwWc_U<^0b3{PEc}AGPP7oBjOg%C!@BKijTpMIt`9S~UNk zH|{5X(%D$UR9=soKe|47!xvT6$By3FU!VBbD-&~P){RfOW-Y37zERwk?yg?DBwa{* zU@IGs#n(+=wRz9wD)Z{6(^hTWbGfa#c-t+<&7D(D%{~}kn;f|<(X`~Vs?J}Izq ply.when <= now) + .map!(ply => ply.when) + .fold!max(Phyu(now - game.nurse.updatesSinceZero)); + return now - target + 1; // The +1 goes back to the phyu before that ply. +} diff --git a/src/game/panel/base.d b/src/game/panel/base.d index a6261b9c..30acc458 100644 --- a/src/game/panel/base.d +++ b/src/game/panel/base.d @@ -64,8 +64,9 @@ public: // Copy-pasted function names from RightButtons. static foreach (field; ["paused", "speedIsNormal", "speedIsFast", "speedIsTurbo", "restart", "saveState", "loadState", - "framestepBackOne", "framestepBackMany", "framestepAheadOne", - "framestepAheadMany", "splatRulerIsOn", "tweakerIsOn", + "rewindPrevPly", "rewindOneSecond", "rewindOneTick", + "skipOneTick", "skipTenSeconds", + "splatRulerIsOn", "tweakerIsOn", "highlightGoalsExecute", "nukeDoubleclicked"] ) { import std.format; diff --git a/src/game/panel/rightbut.d b/src/game/panel/rightbut.d index 33a5e2d4..b0d6350a 100644 --- a/src/game/panel/rightbut.d +++ b/src/game/panel/rightbut.d @@ -35,10 +35,11 @@ public: bool restart() { return false; } bool saveState() { return false; } bool loadState() { return false; } - bool framestepBackOne() { return false; } - bool framestepBackMany() { return false; } - bool framestepAheadOne() { return false; } - bool framestepAheadMany() { return false; } + bool rewindPrevPly() { return false; } + bool rewindOneTick() { return false; } + bool rewindOneSecond() { return false; } + bool skipOneTick() { return false; } + bool skipTenSeconds() { return false; } bool splatRulerIsOn() { return false; } bool tweakerIsOn() { return false; } @@ -191,10 +192,11 @@ mixin template TapeRecorderMixin() { bool speedIsFast() { return _trbs.speedIsFast; } bool speedIsTurbo() { return _trbs.speedIsTurbo; } bool restart() { return _trbs.restart; } - bool framestepBackOne() { return _trbs.framestepBackOne; } - bool framestepBackMany() { return _trbs.framestepBackMany; } - bool framestepAheadOne() { return _trbs.framestepAheadOne; } - bool framestepAheadMany() { return _trbs.framestepAheadMany; } + bool rewindPrevPly() { return _trbs.rewindPrevPly; } + bool rewindOneTick() { return _trbs.rewindOneTick; } + bool rewindOneSecond() { return _trbs.rewindOneSecond; } + bool skipOneTick() { return _trbs.skipOneTick; } + bool skipTenSeconds() { return _trbs.skipTenSeconds; } } private void makeTapeRecorder(Geom g) diff --git a/src/game/panel/taperec.d b/src/game/panel/taperec.d index ac90e69b..ee488a15 100644 --- a/src/game/panel/taperec.d +++ b/src/game/panel/taperec.d @@ -33,34 +33,35 @@ private: enum frameTurbo = 5; // All the buttons are non-null, always - BitmapButton _pause, _restart; + BitmapButton _pause, _restart, _rewindPrevPly; NukeButton _nuke; - TwoTasksButton _speedBack, _speedAhead, _speedFast; + TwoTasksButton _rewind, _skip, _speedFast; public: this(Geom g) { super(g); - void newBut(T)(ref T b, int x, int y, int frame, + void newBut(T)(ref T b, int x, int y, InternalImage img, int frame, in UserOption!KeySet keyLeft = null, in UserOption!KeySet keyRight = null) if (is(T : BitmapButton)) { b = new T(new Geom(x * xlg/4f, y * ylg/2f, xlg/4f, ylg/2f), - InternalImage.gamePanel.toCutbit); + img.toCutbit); b.xf = frame; b.hotkey = keyLeft ? keyLeft.value : KeySet(); static if (is (T == TwoTasksButton)) b.hotkeyRight = keyRight ? keyRight.value : KeySet(); addChild(b); } - newBut(_restart, 0, 0, 8, opt.keyRestart); - _restart.resize(xlg/2f, ylg/2f); // Until we have a better layout idea. - - newBut(_speedBack, 0, 1, 10, opt.keyFrameBackOne, opt.keyFrameBackMany); - newBut(_speedAhead, 1, 1, 3, - opt.keyFrameAheadOne, opt.keyFrameAheadMany); - newBut(_speedFast, 2, 1, frameFast, + newBut(_rewindPrevPly, 0, 0, InternalImage.rewindPrevPly, 0, + opt.keyRewindPrevPly); + newBut(_restart, 1, 0, InternalImage.gamePanel, 8, opt.keyRestart); + newBut(_rewind, 0, 1, InternalImage.gamePanel, 10, + opt.keyRewindOneTick, opt.keyRewindOneSecond); + newBut(_skip, 1, 1, InternalImage.gamePanel, 3, + opt.keySkipOneTick, opt.keySkipTenSeconds); + newBut(_speedFast, 2, 1, InternalImage.gamePanel, frameFast, opt.keySpeedFast, opt.keySpeedTurbo); _nuke = new NukeButton(new Geom(2 * xlg/4f, 0, xlg/4f, ylg/2f), @@ -82,10 +83,11 @@ public: bool speedIsTurbo() { return ! paused && _speedFast.on && _speedFast.xf == frameTurbo;} bool restart() { return _restart.execute; } - bool framestepBackOne() { return _speedBack.executeLeft; } - bool framestepBackMany() { return _speedBack.executeRight; } - bool framestepAheadOne() { return _speedAhead.executeLeft; } - bool framestepAheadMany() { return _speedAhead.executeRight; } + bool rewindOneTick() { return _rewind.executeLeft; } + bool rewindOneSecond() { return _rewind.executeRight; } + bool rewindPrevPly() { return _rewindPrevPly.execute; } + bool skipOneTick() { return _skip.executeLeft; } + bool skipTenSeconds() { return _skip.executeRight; } bool nukeDoubleclicked() { return _nuke.doubleclicked; } } @@ -100,8 +102,9 @@ public: do { return _pause.isMouseHere ? Tooltip.ID.pause : _nuke.isMouseHere ? Tooltip.ID.nuke - : _speedBack.isMouseHere ? Tooltip.ID.framestepBack - : _speedAhead.isMouseHere ? Tooltip.ID.framestepAhead + : _rewindPrevPly.isMouseHere ? Tooltip.ID.rewindPrevPly + : _rewind.isMouseHere ? Tooltip.ID.rewindOneTick + : _skip.isMouseHere ? Tooltip.ID.skipOneTick : _restart.isMouseHere ? Tooltip.ID.restart : Tooltip.ID.fastForward; } @@ -121,20 +124,13 @@ public: protected: override void calcSelf() { - assert (!!_pause && !!_speedBack && !!_speedAhead && !!_speedFast); if (_pause.execute) setSpeedTo(paused ? 1 : 0); else if (_speedFast.executeLeft) setSpeedTo(_speedFast.on ? 1 : 2); else if (_speedFast.executeRight) setSpeedTo(_speedFast.xf == frameTurbo ? 1 : 3); - else if (_speedBack.executeLeft || _speedBack.executeRight - || _speedAhead.executeLeft) - setSpeedTo(0); - // We don't handle (speed back to normal) on level restart. - // Game will tell us to set the speed. Reason: Not only we can - // restart the level, but the game can get that command from - // the end-of-level dialog. + // See game.core.speed for pausing/unpausing on framestepping. } private: diff --git a/src/game/panel/tooltip.d b/src/game/panel/tooltip.d index 283242c2..bed59180 100644 --- a/src/game/panel/tooltip.d +++ b/src/game/panel/tooltip.d @@ -32,13 +32,14 @@ struct Tooltip { // When several are requested, only the most important is shown. enum ID : IdSet { pause = 0x1, - showSplatRuler = 0x4, - highlightGoals = 0x8, - stateSave = 0x10, - stateLoad = 0x20, - showTweaker = 0x40, - framestepBack = 0x80, - framestepAhead = 0x100, + showSplatRuler = 0x2, + highlightGoals = 0x4, + stateSave = 0x8, + stateLoad = 0x10, + showTweaker = 0x20, + rewindPrevPly = 0x40, + rewindOneTick = 0x80, + skipOneTick = 0x100, fastForward = 0x200, restart = 0x400, nuke = 0x800, @@ -116,8 +117,9 @@ Tooltip makeTooltip(Tooltip.ID id) nothrow @nogc @safe case ID.stateSave: return none(Lang.gameStateSave); case ID.stateLoad: return none(Lang.gameStateLoad); case ID.showTweaker: return none(Lang.gameShowTweaker); - case ID.framestepBack: return mouse(Lang.gameFramestepBack); - case ID.framestepAhead: return mouse(Lang.gameFramestepAhead); + case ID.rewindPrevPly: return none(Lang.gameRewindPrevPly); + case ID.rewindOneTick: return mouse(Lang.gameRewindOneTick); + case ID.skipOneTick: return mouse(Lang.gameSkipOneTick); case ID.fastForward: return mouse(Lang.gameFastForward); case ID.restart: return none(Lang.gameRestart); case ID.nuke: return none(Lang.gameNuke); diff --git a/src/graphic/internal/names.d b/src/graphic/internal/names.d index 8dc5b327..255f07d9 100644 --- a/src/graphic/internal/names.d +++ b/src/graphic/internal/names.d @@ -35,6 +35,7 @@ enum InternalImage { menuCheckmark, mouse, previewIcon, + rewindPrevPly, skillsInPanel, skillsInTweaker, } @@ -78,6 +79,7 @@ string toBasenameNoExt(in InternalImage id) @nogc case menuCheckmark: return "checkbox"; case mouse: return "mouse"; case previewIcon: return "toruspreview"; + case rewindPrevPly: return "rewindprevply"; case skillsInPanel: return "skillsinpanel"; case skillsInTweaker: return "tweakerskills"; } @@ -96,6 +98,7 @@ bool needGuiRecoloring(in InternalImage id) @nogc case lobbySpec: case menuCheckmark: case previewIcon: + case rewindPrevPly: case skillsInTweaker: return true; default: diff --git a/src/menu/options.d b/src/menu/options.d index aaa35592..6732aebb 100644 --- a/src/menu/options.d +++ b/src/menu/options.d @@ -27,7 +27,8 @@ private: Explainer explainer; enum OptionGroup { - general, graphics, controls, replay, gameKeys, editorKeys, menuKeys + general, graphics, controls, gameControls, + gameKeys, editorKeys, menuKeys } Enumap!(OptionGroup, TextButton) groupButtons; @@ -65,7 +66,7 @@ public this() mkGrpButton(OptionGroup.general, Lang.optionGroupGeneral); mkGrpButton(OptionGroup.graphics, Lang.optionGroupGraphics); mkGrpButton(OptionGroup.controls, Lang.optionGroupControls); - mkGrpButton(OptionGroup.replay, Lang.optionGroupReplay); + mkGrpButton(OptionGroup.gameControls, Lang.optionGroupGameControls); mkGrpButton(OptionGroup.gameKeys, Lang.optionGroupGameKeys); mkGrpButton(OptionGroup.editorKeys, Lang.optionGroupEditorKeys); mkGrpButton(OptionGroup.menuKeys, Lang.optionGroupMenuKeys); @@ -163,7 +164,7 @@ void populateOptionGroups() populateGeneral(); populateGraphics(); populateControls(); - populateReplayOptions(); + populateGameControls(); populateGameKeys(); populateEditorKeys(); populateMenuKeys(); @@ -221,7 +222,6 @@ void populateGraphics() fac.y = bottomHalfY; grp ~= [ fac.factory!BoolOption(paintTorusSeams), - fac.factory!BoolOption(ingameTooltips), fac.factory!BoolOption(showFPS), ]; fac = facRight(); @@ -233,20 +233,6 @@ void populateGraphics() fac.factory!ResolutionOption(screenHardwareFullscreenX, screenHardwareFullscreenY), ]; - fac.y = bottomHalfY; - auto cfg = NumPickConfig(); - cfg.digits = 3; - cfg.min = 0; - cfg.max = 300; - cfg.stepSmall = 2; - cfg.stepMedium = 20; - grp ~= [ - fac.factory!RadioIntOption(splatRulerDesign, - Lang.optionSplatRulerDesign2Bars, - Lang.optionSplatRulerDesign094, - Lang.optionSplatRulerDesign3Bars), - fac.factory!NumPickOption(cfg, splatRulerSnapPixels), - ]; } void populateControls() @@ -277,10 +263,10 @@ void populateControls() addNumPick(holdToScrollSpeed, 1); } -void populateReplayOptions() +void populateGameControls() { auto fac = facLeft(); - groups[OptionGroup.replay] ~= [ + groups[OptionGroup.gameControls] ~= [ fac.factory!RadioBoolOption(replayAfterFrameBack, Lang.optionRewindIsBrowse, true, Lang.optionRewindIsUndo, false), @@ -289,6 +275,27 @@ void populateReplayOptions() fac.factory!HeadingAndBoolOptions(Lang.optionWhenTweakerShown, insertAssignmentsWhenTweakerShown), ]; + fac = facRight(); + groups[OptionGroup.gameControls] ~= [ + fac.factory!BoolOption(unpauseOnAssign), + fac.factory!BoolOption(avoidBuilderQueuing), + fac.factory!BoolOption(avoidBatterToExploder), + fac.factory!BoolOption(ingameTooltips), + ]; + fac.y += 20 + fac.spaceBelow; + auto cfg = NumPickConfig(); + cfg.digits = 3; + cfg.min = 0; + cfg.max = 300; + cfg.stepSmall = 2; + cfg.stepMedium = 20; + groups[OptionGroup.gameControls] ~= [ + fac.factory!RadioIntOption(splatRulerDesign, + Lang.optionSplatRulerDesign2Bars, + Lang.optionSplatRulerDesign094, + Lang.optionSplatRulerDesign3Bars), + fac.factory!NumPickOption(cfg, splatRulerSnapPixels), + ]; } void populateGameKeys() @@ -326,10 +333,11 @@ void populateGameKeys() ]; fac.y += 10f; groups[OptionGroup.gameKeys] ~= [ - fac.factory!HotkeyOption(keyFrameBackMany, watcher), - fac.factory!HotkeyOption(keyFrameBackOne, watcher), - fac.factory!HotkeyOption(keyFrameAheadOne, watcher), - fac.factory!HotkeyOption(keyFrameAheadMany, watcher), + fac.factory!HotkeyOption(keyRewindPrevPly, watcher), + fac.factory!HotkeyOption(keyRewindOneSecond, watcher), + fac.factory!HotkeyOption(keyRewindOneTick, watcher), + fac.factory!HotkeyOption(keySkipOneTick, watcher), + fac.factory!HotkeyOption(keySkipTenSeconds, watcher), ]; fac = facKeys!2; @@ -345,20 +353,6 @@ void populateGameKeys() fac.factory!HotkeyOption(keyShowSplatRuler, watcher), fac.factory!HotkeyOption(keyShowTweaker, watcher), ]; - - fac = facLeft(); - fac.y = 310f; - fac.xl = fac.xl - 10; // Mouse hover area shouldn't obscure other options - groups[OptionGroup.gameKeys] ~= [ - fac.factory!BoolOption(unpauseOnAssign), - ]; - fac = facRight(); - fac.x = xForBoolOptionsBelowHotkeys + keyButtonXl - 20f; - fac.y = 310f; - groups[OptionGroup.gameKeys] ~= [ - fac.factory!BoolOption(avoidBuilderQueuing), - fac.factory!BoolOption(avoidBatterToExploder), - ]; } void populateEditorKeys()