From d879ff83938afbe1b31cb5fa06bb7b4d3cc13f7b Mon Sep 17 00:00:00 2001 From: plastmastick <> Date: Mon, 8 Dec 2025 14:39:37 +0300 Subject: [PATCH 1/6] fix bug with v.1.6 in LoadFolders.xml --- LoadFolders.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LoadFolders.xml b/LoadFolders.xml index 6faf68c..4800341 100644 --- a/LoadFolders.xml +++ b/LoadFolders.xml @@ -29,7 +29,8 @@
  • /
  • -
  • 1.5
  • +
  • 1.6
  • +
  • Languages
  • Mods and Shit/VFE Mechanoids
  • Mods and Shit/VE Psycasts
  • Mods and Shit/VFE Pirates
  • From d976f3f22db76f5723c1aa8bd7851a77c4ada561 Mon Sep 17 00:00:00 2001 From: plastmastick <> Date: Mon, 8 Dec 2025 14:44:19 +0300 Subject: [PATCH 2/6] feat: add translation Keyed and adaptive text interface doc: .gitignore upd --- .gitignore | 7 + .vscode/settings.json | 3 - 1.5/.vscode/settings.json | 3 - 1.5/.vscode/tasks.json | 27 -- 1.5/Source/.vscode/settings.json | 3 - 1.5/Source/.vscode/tasks.json | 19 - ....GeneratedMSBuildEditorConfig.editorconfig | 2 +- .../ProgressionStorytellers.assets.cache | Bin 15007 -> 56 bytes ...torytellers.csproj.AssemblyReference.cache | Bin 59105 -> 5623 bytes 1.6/.vscode/settings.json | 3 - 1.6/.vscode/tasks.json | 27 -- 1.6/Assemblies/ProgressionStorytellers.dll | Bin 16384 -> 16896 bytes 1.6/Source/.vscode/settings.json | 3 - 1.6/Source/.vscode/tasks.json | 19 - 1.6/Source/DebugStartup.cs | 31 ++ 1.6/Source/Page_SelectStorytellerCategory.cs | 401 ++++++++++++------ About/About.xml | 8 +- About/PublishedFileId.txt | 1 - .../English/Keyed/ProgressionStorytellers.xml | 24 ++ Languages/Keyed/ProgressionStorytellers.xml | 21 + .../Russian/Keyed/ProgressionStorytellers.xml | 24 ++ 21 files changed, 372 insertions(+), 254 deletions(-) create mode 100644 .gitignore delete mode 100644 .vscode/settings.json delete mode 100644 1.5/.vscode/settings.json delete mode 100644 1.5/.vscode/tasks.json delete mode 100644 1.5/Source/.vscode/settings.json delete mode 100644 1.5/Source/.vscode/tasks.json delete mode 100644 1.6/.vscode/settings.json delete mode 100644 1.6/.vscode/tasks.json delete mode 100644 1.6/Source/.vscode/settings.json delete mode 100644 1.6/Source/.vscode/tasks.json create mode 100644 1.6/Source/DebugStartup.cs delete mode 100644 About/PublishedFileId.txt create mode 100644 Languages/English/Keyed/ProgressionStorytellers.xml create mode 100644 Languages/Keyed/ProgressionStorytellers.xml create mode 100644 Languages/Russian/Keyed/ProgressionStorytellers.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14b1261 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# Exclude "obj" folders in source folder +1.5/source/obj/ +1.6/source/obj/ + +# Exclude everything .vs folders anywhere in the project +**/.vs/ +**/.vscode/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f9d27dc..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "dotnet.defaultSolution": "1.6/Source/ProgressionStorytellers.sln" -} \ No newline at end of file diff --git a/1.5/.vscode/settings.json b/1.5/.vscode/settings.json deleted file mode 100644 index 013007b..0000000 --- a/1.5/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "dotnet.preferCSharpExtension": true -} \ No newline at end of file diff --git a/1.5/.vscode/tasks.json b/1.5/.vscode/tasks.json deleted file mode 100644 index 333df64..0000000 --- a/1.5/.vscode/tasks.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "SaveAllFiles", - "command": "${command:workbench.action.files.saveAll}", - "type": "shell", - "problemMatcher": [] - }, - { - "label": "build", - "type": "process", - "command": "dotnet", - "args": [ - "build", - "${workspaceFolder}/Source/ProgressionStorytellers.csproj" - ], - "problemMatcher": "$msCompile", - "group": { - "kind": "build", - "isDefault": true - }, - "dependsOrder": "sequence", // need this, "parallel" is the default otherwise - "dependsOn": "Save All Files" // Add this line to ensure saving happens before build - } - ] -} diff --git a/1.5/Source/.vscode/settings.json b/1.5/Source/.vscode/settings.json deleted file mode 100644 index 013007b..0000000 --- a/1.5/Source/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "dotnet.preferCSharpExtension": true -} \ No newline at end of file diff --git a/1.5/Source/.vscode/tasks.json b/1.5/Source/.vscode/tasks.json deleted file mode 100644 index 6656e6d..0000000 --- a/1.5/Source/.vscode/tasks.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "type": "process", - "command": "dotnet", - "args": [ - "build", - "${workspaceFolder}/ProgressionStorytellers.csproj" - ], - "problemMatcher": "$msCompile", - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} diff --git a/1.5/Source/obj/Debug/ProgressionStorytellers.GeneratedMSBuildEditorConfig.editorconfig b/1.5/Source/obj/Debug/ProgressionStorytellers.GeneratedMSBuildEditorConfig.editorconfig index 25c6838..b7d19eb 100644 --- a/1.5/Source/obj/Debug/ProgressionStorytellers.GeneratedMSBuildEditorConfig.editorconfig +++ b/1.5/Source/obj/Debug/ProgressionStorytellers.GeneratedMSBuildEditorConfig.editorconfig @@ -1,6 +1,6 @@ is_global = true build_property.RootNamespace = ProgressionStorytellers -build_property.ProjectDir = c:\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\Progression-Storytellers\1.5\Source\ +build_property.ProjectDir = C:\Users\Nikita\Documents\Rimworld_workspace\Progression-Storytellers-Rus\1.5\Source\ build_property.EnableComHosting = build_property.EnableGeneratedComInterfaceComImportInterop = build_property.CsWinRTUseWindowsUIXamlProjections = false diff --git a/1.5/Source/obj/Debug/ProgressionStorytellers.assets.cache b/1.5/Source/obj/Debug/ProgressionStorytellers.assets.cache index 4712e42aa12d3012e7e7810683b4d65a4407fef8..e98cf92be92331a15457af29eb93c65614246e06 100644 GIT binary patch literal 56 zcmZQzU})fBU|=}7VuMT~$F61S1sR9<4`@xBbyT%+Tk3kDyjkV#;zv5)0+loXF$^>S E02VJ16951J literal 15007 zcmcIr*>V#{6eR%y2}@W4gf;A89fNIRmTX4YMqnEuS+W7Kj7BYM;#ow`jDx9E@|e%a zTdGpYGar%{s*;CPz965FoF0v!rJ0_YR9&fR$|X&ApVQs9@9n#|ba!TQ>$-L8e*gZ# zPg{Qc`8Vy=53m1y{m-$DJATs60&uU>Ok z^}6N+%gnELbYn$dW?p@T>n%^?rv0tUt)|9VtA1I#qK%J^kJZH&hxy|ZqxDJ8V|K$@ zyI82Sb>6wyGP&n>bkEb8mbE^Ddk25t#Us9Nz_St0(lFrDK;Hvsl?1dHPW7SLnKc_} zh?{^|AwisT9ak&4p7|mTZ!_>}ba)kJ1l;u3(jeal3Om>6@;THfM3LAJfusTIO=V^(^FVKwh9l z<}7Wh+X2WZ0n35on>N!bjGMY;zRaBRhhVTc3ag6t2&ydDp+%=nb=5uVo5in@dFN0%>W9B;9OYjK@&={z` zC4jHu-wd3lB`j5j5FQ1EXY^|zF1gv@$A$u4uw1{L4SpQp%j7dJSOMZW;qn{;cna7iJvP_9cA0ft?wihX_6nQ^3xk}+ ztx9Qz>zy3J_~~%)P0kG8%^?A2fKRWCXLOqt;0xxF!LwjMFM~7OY-aENIbhQpg4?cN zW|phxARuB^^jf$$H&e}F1}^}dUI`U##McV0vx?ALE@OBRH0X_CsEB9TvTo$Kl4!%( zhJ3bQ1mN_SvOAS~^S#JG4sCo1B`<#Jnh4E8^)(-^qW>!(tC&4V{MdMkS|#zBB4kS^a-A_Cd)R{&3MoqJAcHvVV8 zr$3q%gEQt7^o}3oxhPG51ihLTF@Dy36U)k8i>shPe^aP*5Q1lOy0?8^{Pgw^IHZEa;W8h}so$IgXRSr&r1Xzw0>XI)^twVhECe zSgEadvIVgKc$!p>Y?rIWw1DX?VA30aYHtTq!HC{v3YSJ=lrOYA2QKut68@~&LBkB8q7Rrx_H{0if8RnO| zrMbms!Yb~TThzLlh0VRWZY!b0rRYTc&!BpDq+7i^l3KlcMBPvb#X;%yU`6bH>0N*A z>Y>3ma=qFf>E+vc(7p1nZ!0%1Nk2#BQRy|7Cz3i0R6`y}YSXP-JRg6htS~&RZi|(Z z7dB!pufm0RXLWsD!dP-8oV*bcR8+GjuXXeW)Q(Bm;hip42PUtO+yb4C#yStwR>?ci z?HjLxiVreSuM``kSKuOL^ptHR%OpzLd*>h|(;FwbT1VdgzUB#aHRn`A$17mu&F&jE z$-g+Q8n^%IuWB|>|8Y?`pS+@w zg!D|JYG)F1ezKvIB|a7iR!LeskEU8cMaE0D>B`)cN|KYZNGbtI%=f64Eg>_bY#Ps@ zDCs6-J5DOLyDu-H+Ok*%K_zUeSifqE<579l7AxZCO2&hcZuv?fOJg@Cty;;X=&{N; z%5h$mn(L3qs?^3n>{PYb;WQGWoGQH$wvWXlM-_q*woZ;5-bm{rMbwgPuuAQOa8loX zldL+)1HIk`X(sYfj77M{^7ZSBMX8QfU(`q?HFA7MbxPuq7?tD<#7tCT*dN_cQIq2k zv1{wwh=HsKGkyDg()!9?xa`7i41L7C@TJ51<<$|{m)e$>&P1Jw+LHn=4T4@EzrM=jJ(0VE}4nxdHKa9naPtC+4Uw1XbXUh1iC(E^JK1% Fi~#PiSndD- literal 59105 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 S$=@pcncBlv-IuJtTK_*my*ZHp delta 7609 zcmZ`;3wRV&mOl4ZbyanBrz_Q+2k&$sAr%s0coR@a06`Q4M1;sQKnO8FpaU`ylIn;$ zjI-kM)##3n&H^qzcl=}+e0=jcgUiBBc19NV;V!$rP;_;6MnHG;Q%BtY-0A?c-!~oV zzvrBL?m6e4bLv)glf6e|v*Isz5B>Cu`HxZV^DYfd$3!jBLIfIsu|Iu8G0@qDo8(UKAB#O7ONA+W!S8^5+Iz zk|H#xny8?PNCbx_PYCAAVt5##owmdqpA#WVp{UVArtN-S9i!bn34`%y%;^|)@p{cwp@p6c~ zi0YTRdHt5QHM%i3ug#wc@s3#l6}cNPE-p@{E*08D{y;b7p;PRU@$T6e+HV9@CuI9g zJQ}in4n}U22z8>GD732;ch7~;yBVNGJj7(%NxGc=__Riqenau?#- z1h$8^GCUKtteztM;`W7*b=(R_>8>t!pwfERBCsLp>Rq>i!HgO`G&h*`B^auTij>t% zBhu0hKq7AkhE-0AD`~kZrAW@cX^l%Tr^@MbJw2|DDRmDCF;qdre5WrUlUJZ)Db!Mt zWW-wr!dnhdg)e?IZmCAf3)$#_Xo-7uBf)37VM$VWE3kwEsK4A!qrf#ZLUzNnu&Z=0 z))z!*%{t(%>~qKWQc!Ps{whdDbTCEXhUeCvr#DygJgu9dm;6miYMyqNw=are7 z%tFEDhG*VTJk93} zFHzG)S`lW}g`Cv7aOUBVxdSV^psd5~Kx6}ri1QRjW$<`(d~6`Byh(4H(i;@K9i1eM zpuas{EDq+|%f-OpdHb)E$g&{|y86RHkoLjC-AML%4DW zJ1)62rk~uwepLixVzMX<$gVPrI(WynA$RbWyNUq@?;;K9Rq>-V9Dh(7A0#5d+;~ND z33ji}+|1j^b3uW(DY!3QlE8Vc#4bo*iVV=-6x+9kzB=bjqEI zjw^+tA|mfkBN`k=#2GD7mcx|d&I?nzgB5I}#QCPiFp3+C$Jr{iBZIYh^&%P^%)72w z#X1_XdhKimu5@X&Zw|i98!Wa2#fb@J8OW>aWOoO~Q@D@9r%YyAZhw$=Yz;Dr%Awmp zPP*gUZ@*O2Jh%ft<+XkHn?56 zR@|;#C{b9eQNdEDa*CcH8rF?_2ICC$>ac}dGp(Ci5IWJ%;BW)(&tZ!eQW~LQnug6< zG#f`h)q+1~27l)auUrNek7O#tH5wP+lsIMyyW@7ENw{!mlO4GEmHvGu(};-fiacZ+ z^xp~{{bt*tSFt05=IT+)py3flQ{hR4k19N@@NT73r{4(+|D-XVRFcQ_J%&MFnHypT z{g2N0mNqKipr2{%>+8sY8q=T;V+Vj=Xa`K2<`^UmO2?VLQ_-W9ygZ*|f(nA)=NJ2v zW31Cgtn*!~OH0zgc$rp27iF1d&^5Q00xfDKXrRUPTFDU>MR#KZ-}Px1L`x(yFCtH%t*GVGcw}n` zHOd3X(`L2cUmP|)(_v@dCK%t2F~*{dPa7Q8C&Yn{!d7is4~b1DmFD$=>E*<@NLh%g zpy!$!S(H`_8r6b-w%O3v*l`gxV3#&EsLZ`&u>0*Wk)U%9@8hpjUcZv;tOsiisfm_pf7P50p69-CPQ*GvM--QkCt^QAd&Nn>td)Nvb_86WntRJU5qpIa;MmG9 zd}YRgfZb15?(@;(T4_G{Slk5T$*Z^|6_N%`UCk9xKgHFe%bW0c8mhQoD{e3zQ^V;~ z^F5@lRxX!CbjDdOOXUnjQ5=e6-PLVN~Vpu3sIiBJ7WM_dnR@4>-qiRBU~m`*zh-JpR$L61?SWjJ?;dgyWIc3r1)eCE(zI%2NX zO}YWkU7lNIZqO~-oZ}j-4SJN`P#oLbfnNONGG|bXK3CkswBF9>G5WR~FBU`()AQC& zu+DHc`Y;`eJ)p;_L~*-dCLhgGp}4*MX4wy-k;f=5+%nYpU#Q`yAhKyW^=)~RIa!%m?YKa zI1VOBFNa+8*}RwZBpuDovBM<&LvD^8Ch1geZfNvXXqtFBQO;kI9L4$J?vqrVo8;Z6 zXm^fdhbj6EzYyehpP~;HcQ!gJ@hd$=pM;#+Z;Jkqn`8HQC&L#*c6cm$5}MO<9B&tM zXwBc)*gxNk%v8h~`vLK`iszq3^OT%vp(K4c1CKgE`(lh~JpKd~Ym6@{I>ZN*qz@hR zhC^p?8Mt1@by}S(IAhL$NZ@)M*J+et0IoB*ig3M->oi4)`@;nqxWgN4n<|0%G)iHe z!Ul!26)sTNsIUoGNUe(AqOeop_kaU%H#PV$`Un_<4gu5jilWZ~hm$K<&a{E=Vh#34 z9GOf%BDSGO`vn&#PDc_`LC-_=_lqM)djXBH=g}cC25Ejp=?_vmWlCPH=&_3456iwm zr$vFYhpq+l9GD#x}OdA8Lzb zFSWsCk8Bdl`%uHS*ER_@B3;9nSlD4 zyXZ%dJV60XHILB~bc6XmZpkw3eR_^H#bMws5zsHqCj=WhDt=DyM2?DMppPlZyO7K@ z-d8lqpVPC3CRuZsLeez6Mx_<*1Ntzbn0FPDuBH{%D_o^;pTeUG-&IHvrKzx9;VOkk z6~3#G45g#6UZI5pXqwhT)#4w;c6pz?-9YViD&D6xaT(I}dO zLXQJZ!q-sW!JS_RW(rLP*3)&sX*3mK%!Fz_epDO>ypg5@=Rh-`ZiZ$)&8O>uw?Nay z*JOT1E`g>?%V-vG1vFh+1x=S$(`?{cXik8&m9(BVQzuG$h%V7Hi-jgzoUqgXhdB(yqf}fUtc7XS|7> z#Sn80(Zpyj{g@WfDO!wcC4EV2a5dvPNG0;$=}~!xo|JRxj68hTkp9}?eWg!n!OeB! zf^7M^;6nM@V8!q!gCP}V!MqADxUXW_;g2dl6Nk@LE*6JpR_&MZj^?c^XSQ$JO0$|a z29cU6!L2pP3^P}*a2xfWssvZ-tgP; zce{EV~+g}esW8pt*wglmWj7s5_E!W@aBatO@`Rjg@X z%UIvHjVpH9>sHM51)t^+eHGJpAY84cw*#BuB261%^bTbv4auEK%F7W>w&(wQ*^XVX zr!-;-lf*_iQ5#`mV{Y*_P}Pt%A<{dLKE&y(?YBV4A@_xr0ks}8EkF*q3C6fe;f7TV zt$#j*Fy|ab3sz>-%5}M&^d+#BokPRlgv@oSsJ1~67C8+WSED`L?#4gwD%|Z_gt`W6 zn~=n?wi(cDi-Qka>*^F<*%0=hQTuFxawc@QlHIYPcKoeXy%?I}bcV*b;9Iedlgx$Z zq;{xo-hg#sio=ZYF8hLMfh|;T+d{~=J$Sv(5i)zF(Ya}x(N}5Q60F9Jz=dbC?4E<+ z23d!(8SD7w-~w`LH=_PwpYaUeMxiaZ9kvK`8!qlyUa$H*4ilFfJ;)n6nCueCPAi%1aq@*=ZV0Sw1L`&=*w?)x>32rbQVi+` zPpodI1>3q;q$sXdv3@dpCW0l|o)|=ZMhq;oQaJw*yPN$zkJ*dKR@ipS*u*o^EtAFh zLWVy35b_};+4f*%DQFmbo%k~F#}eo_C$lf z9Xrf-3rqtl_?OJ?RsSA$v-@=;nLTKe#;dXSgLq(tN^ww3LWZsP3`SaU#&cLHvJp-$ zPR>oUW+Xc!_#v#P(%{bt&(mx1^9U!oXHf)XSR+q2Me^DN>B;Qb zWNTt@vK9YWR&N!$^RgendT-3sBwV3(*SLQq%-!QcJH=0L%=KcL)40V% z2{8;}lQV*4CjOKilA5XD4}~;1Y%Gm1`0}yy@#)# zxJO1u*Nv+gJ#J!cUGV0lmSD!@{N&%@zmNJpzhFAOx3oyUusG*YyKZfW9PmA diff --git a/1.6/Source/.vscode/settings.json b/1.6/Source/.vscode/settings.json deleted file mode 100644 index 013007b..0000000 --- a/1.6/Source/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "dotnet.preferCSharpExtension": true -} \ No newline at end of file diff --git a/1.6/Source/.vscode/tasks.json b/1.6/Source/.vscode/tasks.json deleted file mode 100644 index 6656e6d..0000000 --- a/1.6/Source/.vscode/tasks.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "type": "process", - "command": "dotnet", - "args": [ - "build", - "${workspaceFolder}/ProgressionStorytellers.csproj" - ], - "problemMatcher": "$msCompile", - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} diff --git a/1.6/Source/DebugStartup.cs b/1.6/Source/DebugStartup.cs new file mode 100644 index 0000000..d024074 --- /dev/null +++ b/1.6/Source/DebugStartup.cs @@ -0,0 +1,31 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using HarmonyLib; +using RimWorld; +using Verse; + +namespace ProgressionStorytellers +{ + [StaticConstructorOnStartup] + public static class DebugStartup + { + static DebugStartup() + { + Log.Message("[ProgressionStorytellers] Mod starting for RimWorld 1.6"); + + // Проверим, загружен ли наш тип + var type = GenTypes.GetTypeInAnyAssembly("ProgressionStorytellers.StorytellerExtension"); + if (type != null) + { + Log.Message($"[ProgressionStorytellers] Type found: {type.FullName}"); + } + else + { + Log.Error("[ProgressionStorytellers] Type NOT found!"); + } + } + } +} diff --git a/1.6/Source/Page_SelectStorytellerCategory.cs b/1.6/Source/Page_SelectStorytellerCategory.cs index 4c66896..3403f36 100644 --- a/1.6/Source/Page_SelectStorytellerCategory.cs +++ b/1.6/Source/Page_SelectStorytellerCategory.cs @@ -6,145 +6,264 @@ namespace ProgressionStorytellers { - [HotSwappable] - [StaticConstructorOnStartup] - public class Page_SelectStorytellerCategory : Page - { - public override string PageTitle => "What kind of story would interest you?"; - private readonly StorytellerCategory[] storytellerCategories = Enum.GetValues(typeof(StorytellerCategory)) - .Cast().Where(x => x != StorytellerCategory.Undefined).ToArray(); - private Page_CreateWorldParams nextPage; - public Page_SelectStorytellerCategory(Page_CreateWorldParams nextPage) - { - this.nextPage = nextPage; - } - - public override void DoWindowContents(Rect rect) - { - Text.Anchor = TextAnchor.UpperCenter; - rect.y += 45; - rect.height -= 45; - Text.Font = GameFont.Medium; - - var fontIndex = 2; - var oldStyle = Text.fontStyles[fontIndex]; - var newStyle = new GUIStyle(oldStyle); - Text.fontStyles[fontIndex] = newStyle; - newStyle.fontSize = 20; - Widgets.Label(new Rect(rect.x, rect.y - 30, rect.width, 30f), PageTitle); - Text.fontStyles[fontIndex] = oldStyle; - Text.Font = GameFont.Small; - Text.Anchor = TextAnchor.MiddleCenter; - - Widgets.BeginGroup(rect); - var scale = 0.9f; - float boxWidth = 300 * scale; - float boxHeight = 350 * scale; - float xSpacing = 60; - float ySpacing = 15; - - Text.Font = GameFont.Medium; - var yOffset = 55 - 50; - float boxScale = 30; - int columns = 3; - for (int i = 0; i < storytellerCategories.Length; i++) - { - int row = i / columns; - int column = i % columns; - float xOffset = (row == 1) ? 20 : 0; - if (row == 1) - { - xSpacing = 40; - boxHeight = 300 * scale; - yOffset = 110 - 50; - boxScale = 45; - } - Rect boxRect = new Rect(column * (boxWidth + xSpacing) + 20 + xOffset, - yOffset + row * (boxHeight + ySpacing) + 10, boxWidth, boxHeight); - DrawStorytellerCategoryBox(boxRect, storytellerCategories[i], boxScale); - } - - Text.Font = GameFont.Small; - Text.Anchor = TextAnchor.UpperLeft; - Widgets.EndGroup(); - - float y = rect.y + rect.height - 38f; - Text.Font = GameFont.Small; - string label = "Back".Translate(); - var backSize = 200; - if ((Widgets.ButtonText(new Rect(((rect.x + rect.width) / 2f) - (backSize / 2), y, backSize, BottomButSize.y), label) || KeyBindingDefOf.Cancel.KeyDownEvent) && CanDoBack()) - { - DoBack(); - } - } - - private void DrawStorytellerCategoryBox(Rect boxRect, StorytellerCategory category, float boxScale) - { - Widgets.DrawBox(boxRect, 1, BaseContent.GreyTex); - var iconRect = boxRect.ContractedBy(boxScale); - iconRect.y -= 35; - if (Widgets.ButtonImageFitted(iconRect, GetIcon(category))) - { - StorytellerUI_DrawStorytellerSelectionInterface_Patch.selectedCategory = category; - if (StorytellerUI_DrawStorytellerSelectionInterface_Patch.FilteredStorytellers(DefDatabase.AllDefs).Any()) - { - this.Close(); - var page = new Page_SelectStoryteller(); - page.next = nextPage; - nextPage.prev = page; - page.prev = this; - Find.WindowStack.Add(page); - } - else - { - StorytellerUI_DrawStorytellerSelectionInterface_Patch.selectedCategory = StorytellerCategory.Undefined; - Messages.Message("There are no available storytellers in that category.", MessageTypeDefOf.RejectInput, historical: false); - } - } - Text.Font = GameFont.Medium; - var categoryLabel = new Rect(boxRect.x, boxRect.y + (boxRect.height - 80), boxRect.width, 30); - Widgets.Label(categoryLabel, GetCategoryLabel(category)); - Text.Font = GameFont.Small; - GUI.color = new ColorInt(240, 240, 240).ToColor; - var oldStyle = Text.fontStyles[1]; - var newStyle = new GUIStyle(oldStyle); - Text.fontStyles[1] = newStyle; - newStyle.fontSize = 17; - Widgets.Label(new Rect(boxRect.x + 10, categoryLabel.yMax - 5, boxRect.width - 20, 50), GetCategoryDescription(category)); - Text.fontStyles[1] = oldStyle; - GUI.color = Color.white; - } - - private static Texture2D GetIcon(StorytellerCategory category) - { - switch (category) - { - case StorytellerCategory.SlowPaced: return DefsOf.Phoebe.portraitLargeTex; - case StorytellerCategory.Engaging: return StorytellerDefOf.Cassandra.portraitLargeTex; - case StorytellerCategory.Chaotic: return DefsOf.Randy.portraitLargeTex; - } - return ContentFinder.Get("UI/Icons/" + category.ToString()); - } - private string GetCategoryLabel(StorytellerCategory category) - { - return category switch - { - StorytellerCategory.SlowPaced => "Slow-paced", - _ => category.ToString() - }; - } - private string GetCategoryDescription(StorytellerCategory category) - { - return category switch - { - StorytellerCategory.SlowPaced => "A story that lets you relax between major events.", - StorytellerCategory.Engaging => "A story with present momentum, adjusting to your highs and lows.", - StorytellerCategory.Chaotic => "A story with no regard for consistency, utter chaos.", - StorytellerCategory.Consistent => "A story with predictable rates of events and triggers.", - StorytellerCategory.Brutal => "A bloody test of patience, skill, and strategy.", - StorytellerCategory.Bizarre => "Stories told in new formats, often feeling completely new.", - _ => "Unknown category." - }; - } - } + /// + /// Custom page for selecting storyteller categories in the game setup flow. + /// Replaces the standard storyteller selection page with a category-based approach. + /// + [HotSwappable] + [StaticConstructorOnStartup] + public class Page_SelectStorytellerCategory : Page + { + // Gets the page title from translation keys for localization support + public override string PageTitle => "ProgressionStorytellers.PageTitle".Translate(); + + // All available storyteller categories (excluding Undefined) + private readonly StorytellerCategory[] storytellerCategories = Enum.GetValues(typeof(StorytellerCategory)) + .Cast() + .Where(x => x != StorytellerCategory.Undefined) + .ToArray(); + + private Page_CreateWorldParams nextPage; + + /// + /// Initializes a new instance with reference to the next page in the setup flow + /// + public Page_SelectStorytellerCategory(Page_CreateWorldParams nextPage) + { + this.nextPage = nextPage; + } + + /// + /// Main method for rendering the window contents + /// + public override void DoWindowContents(Rect rect) + { + // Setup title area + Text.Anchor = TextAnchor.UpperCenter; + rect.y += 45; + rect.height -= 45; + Text.Font = GameFont.Medium; + + // Custom font styling for page title + var fontIndex = 2; // Medium font index + var oldStyle = Text.fontStyles[fontIndex]; + var newStyle = new GUIStyle(oldStyle); + Text.fontStyles[fontIndex] = newStyle; + newStyle.fontSize = 20; + + Widgets.Label(new Rect(rect.x, rect.y - 30, rect.width, 30f), PageTitle); + + Text.fontStyles[fontIndex] = oldStyle; + Text.Font = GameFont.Small; + Text.Anchor = TextAnchor.MiddleCenter; + + // Begin category grid layout + Widgets.BeginGroup(rect); + + // Grid layout parameters + var scale = 0.9f; + float boxWidth = 300 * scale; + float boxHeight = 350 * scale; + float xSpacing = 60; + float ySpacing = 15; + + Text.Font = GameFont.Medium; + var yOffset = 55 - 50; // Base vertical offset + float boxScale = 30; // Icon scaling factor + int columns = 3; // 3-column grid layout + + // Render each category in a grid + for (int i = 0; i < storytellerCategories.Length; i++) + { + int row = i / columns; + int column = i % columns; + float xOffset = (row == 1) ? 20 : 0; + + // Adjust layout for middle row (different category count arrangement) + if (row == 1) + { + xSpacing = 40; + boxHeight = 300 * scale; + yOffset = 110 - 50; + boxScale = 45; + } + + // Calculate position for this category box + Rect boxRect = new Rect( + column * (boxWidth + xSpacing) + 20 + xOffset, + yOffset + row * (boxHeight + ySpacing) + 10, + boxWidth, + boxHeight + ); + + DrawStorytellerCategoryBox(boxRect, storytellerCategories[i], boxScale); + } + + // Reset UI state + Text.Font = GameFont.Small; + Text.Anchor = TextAnchor.UpperLeft; + Widgets.EndGroup(); + + // Add back button at the bottom + float y = rect.y + rect.height - 38f; + Text.Font = GameFont.Small; + string label = "Back".Translate(); + var backSize = 200; + + if ((Widgets.ButtonText(new Rect(((rect.x + rect.width) / 2f) - (backSize / 2), y, backSize, BottomButSize.y), label) || + KeyBindingDefOf.Cancel.KeyDownEvent) && CanDoBack()) + { + DoBack(); + } + } + + /// + /// Renders an individual category selection box + /// + private void DrawStorytellerCategoryBox(Rect boxRect, StorytellerCategory category, float boxScale) + { + // Draw background box + Widgets.DrawBox(boxRect, 1, BaseContent.GreyTex); + + // Calculate icon position and size + var iconRect = boxRect.ContractedBy(boxScale); + iconRect.y -= 35; + + // Make the icon clickable to select this category + if (Widgets.ButtonImageFitted(iconRect, GetIcon(category))) + { + StorytellerUI_DrawStorytellerSelectionInterface_Patch.selectedCategory = category; + + // Check if there are storytellers in this category + if (StorytellerUI_DrawStorytellerSelectionInterface_Patch.FilteredStorytellers(DefDatabase.AllDefs).Any()) + { + // Proceed to storyteller selection within this category + this.Close(); + var page = new Page_SelectStoryteller(); + page.next = nextPage; + nextPage.prev = page; + page.prev = this; + Find.WindowStack.Add(page); + } + else + { + // No storytellers in this category - show error message + StorytellerUI_DrawStorytellerSelectionInterface_Patch.selectedCategory = StorytellerCategory.Undefined; + Messages.Message( + "ProgressionStorytellers.NoStorytellersInCategory".Translate(), + MessageTypeDefOf.RejectInput, + historical: false + ); + } + } + + // Display category name + Text.Font = GameFont.Medium; + var categoryLabel = new Rect(boxRect.x, boxRect.y + (boxRect.height - 80), boxRect.width, 30); + Widgets.Label(categoryLabel, GetCategoryLabel(category)); + + // Display category description with adaptive text sizing + Text.Font = GameFont.Small; + GUI.color = new ColorInt(240, 240, 240).ToColor; + + Rect descriptionRect = new Rect( + boxRect.x + 10, + categoryLabel.yMax + 5, + boxRect.width - 20, + boxRect.y + boxRect.height - categoryLabel.yMax - 15 + ); + + DrawAdaptiveText(descriptionRect, GetCategoryDescription(category), GameFont.Small); + + GUI.color = Color.white; + } + + /// + /// Renders text that automatically adjusts font size to fit within the given rectangle + /// Falls back to smaller fonts (Medium -> Small -> Tiny) if text doesn't fit + /// + private void DrawAdaptiveText(Rect rect, string text, GameFont baseFont = GameFont.Small) + { + // Save current text settings + GameFont originalFont = Text.Font; + bool originalWordWrap = Text.WordWrap; + var originalStyle = Text.fontStyles[(int)GameFont.Small]; // Style for Small font + + Text.WordWrap = true; + + // Try different font sizes: Medium -> Small -> Tiny + GameFont selectedFont = GameFont.Small; + foreach (var fontSize in new[] { GameFont.Medium, GameFont.Small, GameFont.Tiny }) + { + Text.Font = fontSize; + float textHeight = Text.CalcHeight(text, rect.width); + + // Use this font if text fits or if we've reached the smallest font + if (textHeight <= rect.height || fontSize == GameFont.Tiny) + { + selectedFont = fontSize; + break; + } + } + + // Adjust style for the selected font + if (selectedFont == GameFont.Small) + { + var newStyle = new GUIStyle(Text.fontStyles[(int)GameFont.Small]); + newStyle.fontSize = 15; // Slightly smaller than default for better fit + Text.fontStyles[(int)GameFont.Small] = newStyle; + } + + // Draw the text with selected font + Text.Font = selectedFont; + Widgets.Label(rect, text); + + // Add tooltip with full text if it doesn't fit completely + if (Text.CalcHeight(text, rect.width) > rect.height) + { + TooltipHandler.TipRegion(rect, text); + } + + // Restore original text settings + Text.fontStyles[(int)GameFont.Small] = originalStyle; + Text.Font = originalFont; + Text.WordWrap = originalWordWrap; + } + + /// + /// Returns the appropriate icon texture for a given storyteller category + /// Uses vanilla storyteller portraits for some categories, custom icons for others + /// + private static Texture2D GetIcon(StorytellerCategory category) + { + switch (category) + { + case StorytellerCategory.SlowPaced: + return DefsOf.Phoebe.portraitLargeTex; + case StorytellerCategory.Engaging: + return StorytellerDefOf.Cassandra.portraitLargeTex; + case StorytellerCategory.Chaotic: + return DefsOf.Randy.portraitLargeTex; + default: + // Fall back to custom icons in UI/Icons folder + return ContentFinder.Get("UI/Icons/" + category.ToString()); + } + } + + /// + /// Gets the translated display name for a storyteller category + /// + private string GetCategoryLabel(StorytellerCategory category) + { + return ("ProgressionStorytellers.Category." + category.ToString()).Translate(); + } + + /// + /// Gets the translated description for a storyteller category + /// + private string GetCategoryDescription(StorytellerCategory category) + { + return ("ProgressionStorytellers.Category." + category.ToString() + ".Description").Translate(); + } + } } \ No newline at end of file diff --git a/About/About.xml b/About/About.xml index 842fbdf..0102657 100644 --- a/About/About.xml +++ b/About/About.xml @@ -1,9 +1,9 @@ - Progression: Storytellers - ferny - ferny.ProgressionStorytellers - Integrate many storytellers in modded Rimworld. + Progression: Storytellers [RUS] + ferny | plastmastick + ferny.ProgressionStorytellers.rus + Integrate many storytellers in modded Rimworld. Include Russian and English Translation for 1.6
  • 1.5
  • 1.6
  • diff --git a/About/PublishedFileId.txt b/About/PublishedFileId.txt deleted file mode 100644 index 8c23b3c..0000000 --- a/About/PublishedFileId.txt +++ /dev/null @@ -1 +0,0 @@ -3361425712 \ No newline at end of file diff --git a/Languages/English/Keyed/ProgressionStorytellers.xml b/Languages/English/Keyed/ProgressionStorytellers.xml new file mode 100644 index 0000000..c5d397b --- /dev/null +++ b/Languages/English/Keyed/ProgressionStorytellers.xml @@ -0,0 +1,24 @@ + + + + What kind of story would interest you? + + + Slow-paced + Engaging + Chaotic + Consistent + Brutal + Bizarre + + + A story that lets you relax between major events. + A story with present momentum, adjusting to your highs and lows. + A story with no regard for consistency, utter chaos. + A story with predictable rates of events and triggers. + A bloody test of patience, skill, and strategy. + Stories told in new formats, often feeling completely new. + + + There are no available storytellers in that category. + \ No newline at end of file diff --git a/Languages/Keyed/ProgressionStorytellers.xml b/Languages/Keyed/ProgressionStorytellers.xml new file mode 100644 index 0000000..0d8d1d1 --- /dev/null +++ b/Languages/Keyed/ProgressionStorytellers.xml @@ -0,0 +1,21 @@ + + + + What kind of story would interest you? + + Slow-paced + Engaging + Chaotic + Consistent + Brutal + Bizarre + + A story that lets you relax between major events. + A story with present momentum, adjusting to your highs and lows. + A story with no regard for consistency, utter chaos. + A story with predictable rates of events and triggers. + A bloody test of patience, skill, and strategy. + Stories told in new formats, often feeling completely new. + + There are no available storytellers in that category. + \ No newline at end of file diff --git a/Languages/Russian/Keyed/ProgressionStorytellers.xml b/Languages/Russian/Keyed/ProgressionStorytellers.xml new file mode 100644 index 0000000..19d8743 --- /dev/null +++ b/Languages/Russian/Keyed/ProgressionStorytellers.xml @@ -0,0 +1,24 @@ + + + + Какую историю вы хотите? + + + Неторопливая + Захватывающая + Хаотичная + Последовательная + Безжалостная + Причудливая + + + История, которая позволяет расслабиться между важными событиями. + История развития, адаптирующаяся к вашим успехам и неудачам. + История без правил и последовательности, полный хаос. + История с предсказуемыми событиями и триггерами. + Кровавое испытание терпения, навыков и стратегии. + Истории, рассказанные в новых форматах, часто ощущающиеся совершенно новыми. + + + В этой категории нет доступных рассказчиков. + \ No newline at end of file From a7baede9e34751f14820b3e51ada698de0139dd2 Mon Sep 17 00:00:00 2001 From: plastmastick <> Date: Mon, 8 Dec 2025 14:53:48 +0300 Subject: [PATCH 3/6] feat: add incompability with original mod --- About/About.xml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/About/About.xml b/About/About.xml index 0102657..98caec3 100644 --- a/About/About.xml +++ b/About/About.xml @@ -1,13 +1,16 @@ - Progression: Storytellers [RUS] - ferny | plastmastick - ferny.ProgressionStorytellers.rus - Integrate many storytellers in modded Rimworld. Include Russian and English Translation for 1.6 - -
  • 1.5
  • -
  • 1.6
  • -
    + Progression: Storytellers [RUS] + ferny | plastmastick + ferny.ProgressionStorytellers.rus + Integrate many storytellers in modded Rimworld. Include Russian and English Translation for 1.6 + +
  • 1.5
  • +
  • 1.6
  • +
    + +
  • ferny.ProgressionStorytellers
  • +
  • brrainz.harmony From 233c8198939782dfba8118332d87569733b174cc Mon Sep 17 00:00:00 2001 From: plastmastick <83970559+plastmastick@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:28:47 +0300 Subject: [PATCH 4/6] sync: return original about and steam id with incompability for fork (check about_for_fork) --- About/About.xml | 8 ++++---- About/PublishedFileId.txt | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 About/PublishedFileId.txt diff --git a/About/About.xml b/About/About.xml index 98caec3..fdfd069 100644 --- a/About/About.xml +++ b/About/About.xml @@ -1,15 +1,15 @@ - Progression: Storytellers [RUS] - ferny | plastmastick - ferny.ProgressionStorytellers.rus + Progression: Storytellers + ferny + ferny.ProgressionStorytellers Integrate many storytellers in modded Rimworld. Include Russian and English Translation for 1.6
  • 1.5
  • 1.6
  • -
  • ferny.ProgressionStorytellers
  • +
  • ferny.ProgressionStorytellers.plastmastick_fork
  • diff --git a/About/PublishedFileId.txt b/About/PublishedFileId.txt new file mode 100644 index 0000000..8c23b3c --- /dev/null +++ b/About/PublishedFileId.txt @@ -0,0 +1 @@ +3361425712 \ No newline at end of file From 6ff2da99925306fbbaf39deca8a457c9631ebe08 Mon Sep 17 00:00:00 2001 From: plastmastick <83970559+plastmastick@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:38:44 +0300 Subject: [PATCH 5/6] upd : dll rebuild --- 1.6/Assemblies/ProgressionStorytellers.dll | Bin 16896 -> 16896 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/1.6/Assemblies/ProgressionStorytellers.dll b/1.6/Assemblies/ProgressionStorytellers.dll index f6fbc0ddd47aecb1d9d32e77f4810340502e4877..33dcaa8cdb847b944df5c7197bbb0b46020018d1 100644 GIT binary patch delta 1955 zcmYk7du$X{6vn@MW@cx1yW8EC?$X*8`T)9=3YGFMft3j!Z{w(4@ zf`Q^Ef$I|hVVx}B?0A9J+WVO6G;i4Ux{w9M!UozR>spTJkB_MFi*oX(f75wrZC>pF_Z zCfpU@CEbL7oOCU?ZhoV?u|>H?)SEqe5?XEdlCwwm;GA-ArXP0qkQd(%IR}z)OS%2H z>i#LJC*zK7U9LOq{;^%A=f3WPQ6L94@iKn+;Z?3B{kZ$0NI`~ja)bjZ$W0{ShGC?j zXjn28GlnHo5w??gNHU_SSTNKS7=eg#x5Z}7fi(2m?t-s`-LmoWVj6J_vR7-n`^q&d zciUB)oMNP*HQ_|NMU=W*Z zCkF;`x=8jCcOS&p%H4LIOMc1-;=6=X_Z!4byC=s7(Qo(0xTkZnfcLkYAjb!R_@t4Y z6n!LeX|i9VXQ$dHPS*(Kh4Rt%nH{AYN1uG&6FYj^X(RI(?{Ai%Ak$DR^~2eJ9D42V;UbW zdX7*V^?Ew#L;AryO*i56KN6i(ExM>1mmKX_hy9)_bXU}Su5p#$YirLF+0k1({;D}Z z-_oDvL%K=w67SM@a%*>Kf@_vmhgSCzZ4(N8b1_I((sJzq9W*0a8?UgQ>+*l=L>B5b zCvp&Dj=>w6fwAad9l|@zBD~8iMk{j)+Oz^Rak2oZm=|?UL=sjS6ZzF$$IL_%Gat>& z3Fu^&D3&Ugsrq7^;`$4!vQn`ISGckfgUqdXWRzhy4=Cfk6w_*yuCcX+MzaYAxPAmj zn9<9yaNO*}Nt`h?k;f%X$aa&6%aE`Ta$Xj4xjseE7g*!~U6x6b^&GC8a^x!=WoZ#uN`J!l5#XVa14IOwq~P`jFO$ zqlk!m;&tk!eloNStw4L3AA{geBjQh;Njg6T2fxwp(>(qvTJK%J{MWmfneJUWq(AXi zCbZR)b>7UQ3p7eAv)Z!r#jDo&?Cs2{qo#W2&;b6XK|rg*l=${htJC~e4YM;{B8F30I0~q{Q~{Z~W&eH4bZjsoy)_{vMUPYmHT1nkg!*hSC=6%hDO~ SGp=I))j zn_MrF>&4bKeb(iI9qG-5;!wJCwwPfHQD%&501EA5Dz_U%nfSm?i9~)I$K>A>{wEk{ z9u8a@1_(P}JUjG#el3_xGk$Tlm3#=0gp zoKe@_`6MH+!|Pg6&BB+p?tSi};L;ingmnA7`E+SeCq3o^ z%)FR~nXPi|i!I<1HO)|7cc#*6c8M98wEwi0sMVvWq;860b)cJyF)^o37kG@O>ZaKs zYV}#k>!P0dv*I>W>fK5|@0WU|B{@s0*G+sEsOQ;sGsj@4n9W+CQR(@t^Rb9$?$BzP zWBlDDa9Y&PU~}02Di7Yr6xf9~9x7^O%|#DI+8#ta-Yq=JUtF`zYL5=a%iG2s^n!o=IFe+i~)CqkPovM>{E@Q!$MQxT%h22EwfW5dEnM z%W^8ISEK{useu-25sVjd``pDfe;wV$@635L$9j$y(?wBF%jskP97@q-dXb*s%0}#6~)(t)+Zg;_qO#x%M!(yAF)u%PDUs?VzjPqqLVUS)bBnxB@zL z(mc^kr}2f^f%$0no~IjPjrRgad0*ReAL*C)h1;LA{-Ph~PYc>*l1scnLnxr#pkeN~ zwi54nUeI2_Q2*oTB|E1{yGy&Qh1w3DVF}0Ock4nSQkn|`uz@)Un=}KZIKVoFt;}+4 zXIAp7!G%$HPb)(!SC%1!DG65vaxl-R;H~>Ivj7{JCD_IshNH}pidBl$D*g<*I9{(J zjfyQe&ygkgo4EqIS&dEHpqkIp2CYTu7DwB7+iJy5j_=2QX5tKNd}Lk2`#5fCVjzb! zA=9lQBa4KM3fCDSr@N*I`V3P|&>2}tGCqJKU1o{Wan|`(byo9C8?YudIgzj^ Date: Mon, 8 Dec 2025 19:34:27 +0300 Subject: [PATCH 6/6] fix : incompatibleWith packageId --- About/About.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/About/About.xml b/About/About.xml index fdfd069..77ce274 100644 --- a/About/About.xml +++ b/About/About.xml @@ -9,7 +9,7 @@
  • 1.6
  • -
  • ferny.ProgressionStorytellers.plastmastick_fork
  • +
  • ferny.ProgressionStorytellers.plastmastick.fork